V4L/DVB (9375): Add STB0899 support

Signed-off-by: Manu Abraham <manu@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb/frontends/stb0899_algo.c
new file mode 100644
index 0000000..0ae9649
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_algo.c
@@ -0,0 +1,1542 @@
+/*
+	STB0899 Multistandard Frontend driver
+	Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+	Copyright (C) ST Microelectronics
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; either version 2 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the Free Software
+	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "stb0899_drv.h"
+#include "stb0899_priv.h"
+#include "stb0899_reg.h"
+
+/*
+ * BinaryFloatDiv
+ * float division with integer
+ */
+static long BinaryFloatDiv(long n1, long n2, int precision)
+{
+	int i = 0;
+	long result = 0;
+
+	while (i <= precision) {
+		if (n1 < n2) {
+			result *= 2;
+			n1 *= 2;
+		} else {
+			result = result * 2 + 1;
+			n1 = (n1 - n2) * 2;
+		}
+		i++;
+	}
+
+	return result;
+}
+
+/*
+ * stb0899_calc_srate
+ * Compute symbol rate
+ */
+static u32 stb0899_calc_srate(u32 master_clk, u8 *sfr)
+{
+	u32 tmp, tmp2, mclk;
+
+	mclk  =  master_clk / 4096L; /* MasterClock * 10 / 2^20	*/
+	tmp  = (((u32) sfr[0] << 12) + ((u32) sfr[1] << 4)) / 16;
+
+	tmp *= mclk;
+	tmp /= 16;
+	tmp2 = ((u32) sfr[2] * mclk) / 256;
+	tmp += tmp2;
+
+	return tmp;
+}
+
+/*
+ * stb0899_get_srate
+ * Get the current symbol rate
+ */
+u32 stb0899_get_srate(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+	u8 sfr[4];
+
+	stb0899_read_regs(state, STB0899_SFRH, sfr, 3);
+
+	return stb0899_calc_srate(internal->master_clk, sfr);
+}
+
+/*
+ * stb0899_set_srate
+ * Set symbol frequency
+ * MasterClock: master clock frequency (hz)
+ * SymbolRate: symbol rate (bauds)
+ * return symbol frequency
+ */
+static u32 stb0899_set_srate(struct stb0899_state *state, u32 master_clk, u32 srate)
+{
+	u32 tmp, tmp_up, srate_up;
+	u8 sfr_up[3], sfr[3];
+
+	srate_up = srate;
+	dprintk(state->verbose, FE_DEBUG, 1, "-->");
+	/*
+	 * in order to have the maximum precision, the symbol rate entered into
+	 * the chip is computed as the closest value of the "true value".
+	 * In this purpose, the symbol rate value is rounded (1 is added on the bit
+	 * below the LSB )
+	 */
+	srate_up += (srate_up * 3) / 100;
+
+	tmp = BinaryFloatDiv(srate, master_clk, 20);
+	tmp_up = BinaryFloatDiv(srate_up, master_clk, 20);
+
+	sfr_up[0] = (tmp_up >> 12) & 0xff;
+	sfr_up[1] = (tmp_up >>  4) & 0xff;
+	sfr_up[2] =  tmp_up & 0x0f;
+
+	sfr[0] = (tmp >> 12) & 0xff;
+	sfr[1] = (tmp >>  4) & 0xff;
+	sfr[2] =  tmp & 0x0f;
+
+	stb0899_write_regs(state, STB0899_SFRUPH, sfr_up, 3);
+	stb0899_write_regs(state, STB0899_SFRH, sfr, 3);
+
+	return srate;
+}
+
+/*
+ * stb0899_calc_loop_time
+ * Compute the amount of time needed by the timing loop to lock
+ * SymbolRate: Symbol rate
+ * return: timing loop time constant (ms)
+ */
+static long stb0899_calc_loop_time(long srate)
+{
+	if (srate > 0)
+		return (100000 / (srate / 1000));
+	else
+		return 0;
+}
+
+/*
+ * stb0899_calc_derot_time
+ * Compute the amount of time needed by the derotator to lock
+ * SymbolRate: Symbol rate
+ * return: derotator time constant (ms)
+ */
+static long stb0899_calc_derot_time(long srate)
+{
+	if (srate > 0)
+		return (100000 / (srate / 1000));
+	else
+		return 0;
+}
+
+/*
+ * stb0899_carr_width
+ * Compute the width of the carrier
+ * return: width of carrier (kHz or Mhz)
+ */
+long stb0899_carr_width(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+
+	return (internal->srate + (internal->srate * internal->rolloff) / 100);
+}
+
+/*
+ * stb0899_first_subrange
+ * Compute the first subrange of the search
+ */
+static void stb0899_first_subrange(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal	= &state->internal;
+	struct stb0899_params *params		= &state->params;
+	struct stb0899_config *config		=  state->config;
+
+	int range = 0;
+	u32 bandwidth = 0;
+
+	if (config->tuner_get_bandwidth) {
+		config->tuner_get_bandwidth(&state->frontend, &bandwidth);
+		range = bandwidth - stb0899_carr_width(state) / 2;
+	}
+
+	if (range > 0)
+		internal->sub_range = MIN(internal->srch_range, range);
+	else
+		internal->sub_range = 0;
+
+	internal->freq = params->freq;
+	internal->tuner_offst = 0L;
+	internal->sub_dir = 1;
+}
+
+/*
+ * stb0899_check_tmg
+ * check for timing lock
+ * internal.Ttiming: time to wait for loop lock
+ */
+static enum stb0899_status stb0899_check_tmg(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+	int lock, timing;
+	u8 reg;
+
+	msleep(internal->t_timing);
+
+	reg = stb0899_read_reg(state, STB0899_RTF);
+	STB0899_SETFIELD_VAL(RTF_TIMING_LOOP_FREQ, reg, 0xf2);
+	stb0899_write_reg(state, STB0899_RTF, reg);
+	reg = stb0899_read_reg(state, STB0899_TLIR);
+	lock = STB0899_GETFIELD(TLIR_TMG_LOCK_IND, reg);
+	timing = stb0899_read_reg(state, STB0899_RTF);
+
+	if (lock >= 42) {
+		if ((lock > 48) && (timing >= 110)) {
+			internal->status = ANALOGCARRIER;
+			dprintk(state->verbose, FE_DEBUG, 1, "-->ANALOG Carrier !");
+		} else {
+			internal->status = TIMINGOK;
+			dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK !");
+		}
+	} else {
+		internal->status = NOTIMING;
+		dprintk(state->verbose, FE_DEBUG, 1, "-->NO TIMING !");
+	}
+	return internal->status;
+}
+
+/*
+ * stb0899_search_tmg
+ * perform a fs/2 zig-zag to find timing
+ */
+static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+	struct stb0899_params *params = &state->params;
+
+	short int derot_step, derot_freq = 0, derot_limit, next_loop = 3;
+	int index = 0;
+	u8 cfr[2];
+
+	internal->status = NOTIMING;
+
+	/* timing loop computation & symbol rate optimisation	*/
+	derot_limit = (internal->sub_range / 2L) / internal->mclk;
+	derot_step = (params->srate / 2L) / internal->mclk;
+
+	while ((stb0899_check_tmg(state) != TIMINGOK) && next_loop) {
+		index++;
+		derot_freq += index * internal->direction * derot_step;	/* next derot zig zag position	*/
+
+		if (ABS(derot_freq) > derot_limit)
+			next_loop--;
+
+		if (next_loop) {
+			STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
+			STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+			stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency		*/
+		}
+		internal->direction = -internal->direction;	/* Change zigzag direction		*/
+	}
+
+	if (internal->status == TIMINGOK) {
+		stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency		*/
+		internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+		dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK ! Derot Freq = %d", internal->derot_freq);
+	}
+
+	return internal->status;
+}
+
+/*
+ * stb0899_check_carrier
+ * Check for carrier found
+ */
+static enum stb0899_status stb0899_check_carrier(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+	u8 reg;
+
+	msleep(internal->t_derot); /* wait for derotator ok	*/
+
+	reg = stb0899_read_reg(state, STB0899_CFD);
+	STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
+	stb0899_write_reg(state, STB0899_RTF, reg);
+
+	reg = stb0899_read_reg(state, STB0899_DSTATUS);
+	dprintk(state->verbose, FE_DEBUG, 1, "--------------------> STB0899_DSTATUS=[0x%02x]", reg);
+	if (STB0899_GETFIELD(CARRIER_FOUND, reg)) {
+		internal->status = CARRIEROK;
+		dprintk(state->verbose, FE_DEBUG, 1, "-------------> CARRIEROK !");
+	} else {
+		internal->status = NOCARRIER;
+		dprintk(state->verbose, FE_DEBUG, 1, "-------------> NOCARRIER !");
+	}
+
+	return internal->status;
+}
+
+/*
+ * stb0899_search_carrier
+ * Search for a QPSK carrier with the derotator
+ */
+static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+
+	short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3;
+	int index = 0;
+	u8 cfr[2];
+	u8 reg;
+
+	internal->status = NOCARRIER;
+	derot_limit = (internal->sub_range / 2L) / internal->mclk;
+	derot_freq = internal->derot_freq;
+
+	reg = stb0899_read_reg(state, STB0899_CFD);
+	STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
+	stb0899_write_reg(state, STB0899_RTF, reg);
+
+	do {
+		dprintk(state->verbose, FE_DEBUG, 1, "Derot Freq=%d, mclk=%d", derot_freq, internal->mclk);
+		if (stb0899_check_carrier(state) == NOCARRIER) {
+			index++;
+			last_derot_freq = derot_freq;
+			derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position	*/
+
+			if(ABS(derot_freq) > derot_limit)
+				next_loop--;
+
+			if (next_loop) {
+				reg = stb0899_read_reg(state, STB0899_CFD);
+				STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
+				stb0899_write_reg(state, STB0899_RTF, reg);
+
+				STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
+				STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+				stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency	*/
+			}
+		}
+
+		internal->direction = -internal->direction; /* Change zigzag direction	*/
+	} while ((internal->status != CARRIEROK) && next_loop);
+
+	if (internal->status == CARRIEROK) {
+		stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency	*/
+		internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+		dprintk(state->verbose, FE_DEBUG, 1, "----> CARRIER OK !, Derot Freq=%d", internal->derot_freq);
+	} else {
+		internal->derot_freq = last_derot_freq;
+	}
+
+	return internal->status;
+}
+
+/*
+ * stb0899_check_data
+ * Check for data found
+ */
+static enum stb0899_status stb0899_check_data(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+	struct stb0899_params *params = &state->params;
+
+	int lock = 0, index = 0, dataTime = 500, loop;
+	u8 reg;
+
+	internal->status = NODATA;
+
+	/* RESET FEC	*/
+	reg = stb0899_read_reg(state, STB0899_TSTRES);
+	STB0899_SETFIELD_VAL(FRESACS, reg, 1);
+	stb0899_write_reg(state, STB0899_TSTRES, reg);
+	msleep(1);
+	reg = stb0899_read_reg(state, STB0899_TSTRES);
+	STB0899_SETFIELD_VAL(FRESACS, reg, 0);
+	stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+	if (params->srate <= 2000000)
+		dataTime = 2000;
+	else if (params->srate <= 5000000)
+		dataTime = 1500;
+	else if (params->srate <= 15000000)
+		dataTime = 1000;
+	else
+		dataTime = 500;
+
+	stb0899_write_reg(state, STB0899_DSTATUS2, 0x00); /* force search loop	*/
+	while (1) {
+		/* WARNING! VIT LOCKED has to be tested before VIT_END_LOOOP	*/
+		reg = stb0899_read_reg(state, STB0899_VSTATUS);
+		lock = STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg);
+		loop = STB0899_GETFIELD(VSTATUS_END_LOOPVIT, reg);
+
+		if (lock || loop || (index > dataTime))
+			break;
+		index++;
+	}
+
+	if (lock) {	/* DATA LOCK indicator	*/
+		internal->status = DATAOK;
+		dprintk(state->verbose, FE_DEBUG, 1, "-----------------> DATA OK !");
+	}
+
+	return internal->status;
+}
+
+/*
+ * stb0899_search_data
+ * Search for a QPSK carrier with the derotator
+ */
+static enum stb0899_status stb0899_search_data(struct stb0899_state *state)
+{
+	short int derot_freq, derot_step, derot_limit, next_loop = 3;
+	u8 cfr[2];
+	u8 reg;
+	int index = 1;
+
+	struct stb0899_internal *internal = &state->internal;
+	struct stb0899_params *params = &state->params;
+
+	derot_step = (params->srate / 4L) / internal->mclk;
+	derot_limit = (internal->sub_range / 2L) / internal->mclk;
+	derot_freq = internal->derot_freq;
+
+	do {
+		if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) {
+
+			derot_freq += index * internal->direction * derot_step;	/* next zig zag derotator position	*/
+			if (ABS(derot_freq) > derot_limit)
+				next_loop--;
+
+			if (next_loop) {
+				dprintk(state->verbose, FE_DEBUG, 1, "Derot freq=%d, mclk=%d", derot_freq, internal->mclk);
+				reg = stb0899_read_reg(state, STB0899_CFD);
+				STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
+				stb0899_write_reg(state, STB0899_RTF, reg);
+
+				STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
+				STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+				stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency	*/
+
+				stb0899_check_carrier(state);
+				index++;
+			}
+		}
+		internal->direction = -internal->direction; /* change zig zag direction		*/
+	} while ((internal->status != DATAOK) && next_loop);
+
+	if (internal->status == DATAOK) {
+		stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency	*/
+		internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+		dprintk(state->verbose, FE_DEBUG, 1, "------> DATAOK ! Derot Freq=%d", internal->derot_freq);
+	}
+
+	return internal->status;
+}
+
+/*
+ * stb0899_check_range
+ * check if the found frequency is in the correct range
+ */
+static enum stb0899_status stb0899_check_range(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+	struct stb0899_params *params = &state->params;
+
+	int range_offst, tp_freq;
+
+	range_offst = internal->srch_range / 2000;
+	tp_freq = internal->freq + (internal->derot_freq * internal->mclk) / 1000;
+
+	if ((tp_freq >= params->freq - range_offst) && (tp_freq <= params->freq + range_offst)) {
+		internal->status = RANGEOK;
+		dprintk(state->verbose, FE_DEBUG, 1, "----> RANGEOK !");
+	} else {
+		internal->status = OUTOFRANGE;
+		dprintk(state->verbose, FE_DEBUG, 1, "----> OUT OF RANGE !");
+	}
+
+	return internal->status;
+}
+
+/*
+ * NextSubRange
+ * Compute the next subrange of the search
+ */
+static void next_sub_range(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+	struct stb0899_params *params = &state->params;
+
+	long old_sub_range;
+
+	if (internal->sub_dir > 0) {
+		old_sub_range = internal->sub_range;
+		internal->sub_range = MIN((internal->srch_range / 2) -
+					  (internal->tuner_offst + internal->sub_range / 2),
+					   internal->sub_range);
+
+		if (internal->sub_range < 0)
+			internal->sub_range = 0;
+
+		internal->tuner_offst += (old_sub_range + internal->sub_range) / 2;
+	}
+
+	internal->freq = params->freq + (internal->sub_dir * internal->tuner_offst) / 1000;
+	internal->sub_dir = -internal->sub_dir;
+}
+
+/*
+ * stb0899_dvbs_algo
+ * Search for a signal, timing, carrier and data for a
+ * given frequency in a given range
+ */
+enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state)
+{
+	struct stb0899_params *params		= &state->params;
+	struct stb0899_internal *internal	= &state->internal;
+	struct stb0899_config *config		= state->config;
+
+	u8 bclc, reg;
+	u8 cfr[1];
+	u8 eq_const[10];
+	s32 clnI = 3;
+	u32 bandwidth = 0;
+
+	/* BETA values rated @ 99MHz	*/
+	s32 betaTab[5][4] = {
+	       /*  5   10   20   30MBps */
+		{ 37,  34,  32,  31 }, /* QPSK 1/2	*/
+		{ 37,  35,  33,  31 }, /* QPSK 2/3	*/
+		{ 37,  35,  33,  31 }, /* QPSK 3/4	*/
+		{ 37,  36,  33,	 32 }, /* QPSK 5/6	*/
+		{ 37,  36,  33,	 32 }  /* QPSK 7/8	*/
+	};
+
+	internal->direction = 1;
+
+	stb0899_set_srate(state, internal->master_clk, params->srate);
+	/* Carrier loop optimization versus symbol rate for acquisition*/
+	if (params->srate <= 5000000) {
+		stb0899_write_reg(state, STB0899_ACLC, 0x89);
+		bclc = stb0899_read_reg(state, STB0899_BCLC);
+		STB0899_SETFIELD_VAL(BETA, bclc, 0x1c);
+		stb0899_write_reg(state, STB0899_BCLC, bclc);
+		clnI = 0;
+	} else if (params->srate <= 15000000) {
+		stb0899_write_reg(state, STB0899_ACLC, 0xc9);
+		bclc = stb0899_read_reg(state, STB0899_BCLC);
+		STB0899_SETFIELD_VAL(BETA, bclc, 0x22);
+		stb0899_write_reg(state, STB0899_BCLC, bclc);
+		clnI = 1;
+	} else if(params->srate <= 25000000) {
+		stb0899_write_reg(state, STB0899_ACLC, 0x89);
+		bclc = stb0899_read_reg(state, STB0899_BCLC);
+		STB0899_SETFIELD_VAL(BETA, bclc, 0x27);
+		stb0899_write_reg(state, STB0899_BCLC, bclc);
+		clnI = 2;
+	} else {
+		stb0899_write_reg(state, STB0899_ACLC, 0xc8);
+		bclc = stb0899_read_reg(state, STB0899_BCLC);
+		STB0899_SETFIELD_VAL(BETA, bclc, 0x29);
+		stb0899_write_reg(state, STB0899_BCLC, bclc);
+		clnI = 3;
+	}
+
+	dprintk(state->verbose, FE_DEBUG, 1, "Set the timing loop to acquisition");
+	/* Set the timing loop to acquisition	*/
+	stb0899_write_reg(state, STB0899_RTC, 0x46);
+	stb0899_write_reg(state, STB0899_CFD, 0xee);
+
+	/* !! WARNING !!
+	 * Do not read any status variables while acquisition,
+	 * If any needed, read before the acquisition starts
+	 * querying status while acquiring causes the
+	 * acquisition to go bad and hence no locks.
+	 */
+	dprintk(state->verbose, FE_DEBUG, 1, "Derot Percent=%d Srate=%d mclk=%d",
+		internal->derot_percent, params->srate, internal->mclk);
+
+	/* Initial calculations	*/
+	internal->derot_step = internal->derot_percent * (params->srate / 1000L) / internal->mclk; /* DerotStep/1000 * Fsymbol	*/
+	internal->t_timing = stb0899_calc_loop_time(params->srate);
+	internal->t_derot = stb0899_calc_derot_time(params->srate);
+	internal->t_data = 500;
+
+	dprintk(state->verbose, FE_DEBUG, 1, "RESET stream merger");
+	/* RESET Stream merger	*/
+	reg = stb0899_read_reg(state, STB0899_TSTRES);
+	STB0899_SETFIELD_VAL(FRESRS, reg, 1);
+	stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+	/*
+	 * Set KDIVIDER to an intermediate value between
+	 * 1/2 and 7/8 for acquisition
+	 */
+	reg = stb0899_read_reg(state, STB0899_DEMAPVIT);
+	STB0899_SETFIELD_VAL(DEMAPVIT_KDIVIDER, reg, 60);
+	stb0899_write_reg(state, STB0899_DEMAPVIT, reg);
+
+	stb0899_write_reg(state, STB0899_EQON, 0x01); /* Equalizer OFF while acquiring	*/
+	stb0899_write_reg(state, STB0899_VITSYNC, 0x19);
+
+	stb0899_first_subrange(state);
+	do {
+		/* Initialisations	*/
+		cfr[0] = cfr[1] = 0;
+		stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* RESET derotator frequency	*/
+
+		reg = stb0899_read_reg(state, STB0899_RTF);
+		STB0899_SETFIELD_VAL(RTF_TIMING_LOOP_FREQ, reg, 0);
+		stb0899_write_reg(state, STB0899_RTF, reg);
+		reg = stb0899_read_reg(state, STB0899_CFD);
+		STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
+		stb0899_write_reg(state, STB0899_RTF, reg);
+
+		internal->derot_freq = 0;
+		internal->status = NOAGC1;
+
+		/* Move tuner to frequency	*/
+		dprintk(state->verbose, FE_DEBUG, 1, "Tuner set frequency");
+		if (state->config->tuner_set_frequency)
+			state->config->tuner_set_frequency(&state->frontend, internal->freq);
+
+		msleep(100);
+
+		if (state->config->tuner_get_frequency)
+			state->config->tuner_get_frequency(&state->frontend, &internal->freq);
+
+		msleep(internal->t_agc1 + internal->t_agc2 + internal->t_timing); /* AGC1, AGC2 and timing loop	*/
+		dprintk(state->verbose, FE_DEBUG, 1, "current derot freq=%d", internal->derot_freq);
+		internal->status = AGC1OK;
+
+		/* There is signal in the band	*/
+		if (config->tuner_get_bandwidth)
+			config->tuner_get_bandwidth(&state->frontend, &bandwidth);
+		if (params->srate <= bandwidth / 2)
+			stb0899_search_tmg(state); /* For low rates (SCPC)	*/
+		else
+			stb0899_check_tmg(state); /* For high rates (MCPC)	*/
+
+		if (internal->status == TIMINGOK) {
+			dprintk(state->verbose, FE_DEBUG, 1,
+				"TIMING OK ! Derot freq=%d, mclk=%d",
+				internal->derot_freq, internal->mclk);
+
+			if (stb0899_search_carrier(state) == CARRIEROK) {	/* Search for carrier	*/
+				dprintk(state->verbose, FE_DEBUG, 1,
+					"CARRIER OK ! Derot freq=%d, mclk=%d",
+					internal->derot_freq, internal->mclk);
+
+				if (stb0899_search_data(state) == DATAOK) {	/* Check for data	*/
+					dprintk(state->verbose, FE_DEBUG, 1,
+						"DATA OK ! Derot freq=%d, mclk=%d",
+						internal->derot_freq, internal->mclk);
+
+					if (stb0899_check_range(state) == RANGEOK) {
+						dprintk(state->verbose, FE_DEBUG, 1,
+							"RANGE OK ! derot freq=%d, mclk=%d",
+							internal->derot_freq, internal->mclk);
+
+						internal->freq = params->freq + ((internal->derot_freq * internal->mclk) / 1000);
+						reg = stb0899_read_reg(state, STB0899_PLPARM);
+						internal->fecrate = STB0899_GETFIELD(VITCURPUN, reg);
+						dprintk(state->verbose, FE_DEBUG, 1,
+							"freq=%d, internal resultant freq=%d",
+							params->freq, internal->freq);
+
+						dprintk(state->verbose, FE_DEBUG, 1,
+							"internal puncture rate=%d",
+							internal->fecrate);
+					}
+				}
+			}
+		}
+		if (internal->status != RANGEOK)
+			next_sub_range(state);
+
+	} while (internal->sub_range && internal->status != RANGEOK);
+
+	/* Set the timing loop to tracking	*/
+	stb0899_write_reg(state, STB0899_RTC, 0x33);
+	stb0899_write_reg(state, STB0899_CFD, 0xf7);
+	reg = 0;
+	/* if locked and range ok, set Kdiv	*/
+	if (internal->status == RANGEOK) {
+		dprintk(state->verbose, FE_DEBUG, 1, "Locked & Range OK !");
+		stb0899_write_reg(state, STB0899_EQON, 0x41);		/* Equalizer OFF while acquiring	*/
+		stb0899_write_reg(state, STB0899_VITSYNC, 0x39);	/* SN to b'11 for acquisition		*/
+
+		/*
+		 * Carrier loop optimization versus
+		 * symbol Rate/Puncture Rate for Tracking
+		 */
+		switch (internal->fecrate) {
+		case STB0899_FEC_1_2:		/* 13	*/
+			STB0899_SETFIELD_VAL(DEMAPVIT_KDIVIDER, reg, 0x1a);
+			stb0899_write_reg(state, STB0899_DEMAPVIT, reg);
+			STB0899_SETFIELD_VAL(BETA, reg, betaTab[0][clnI]);
+			stb0899_write_reg(state, STB0899_BCLC, reg);
+			break;
+		case STB0899_FEC_2_3:		/* 18	*/
+			STB0899_SETFIELD_VAL(DEMAPVIT_KDIVIDER, reg, 44);
+			stb0899_write_reg(state, STB0899_DEMAPVIT, reg);
+			STB0899_SETFIELD_VAL(BETA, reg, betaTab[1][clnI]);
+			stb0899_write_reg(state, STB0899_BCLC, reg);
+			break;
+		case STB0899_FEC_3_4:		/* 21	*/
+			STB0899_SETFIELD_VAL(DEMAPVIT_KDIVIDER, reg, 60);
+			stb0899_write_reg(state, STB0899_DEMAPVIT, reg);
+			STB0899_SETFIELD_VAL(BETA, reg, betaTab[2][clnI]);
+			stb0899_write_reg(state, STB0899_BCLC, reg);
+			break;
+		case STB0899_FEC_5_6:		/* 24	*/
+			STB0899_SETFIELD_VAL(DEMAPVIT_KDIVIDER, reg, 75);
+			stb0899_write_reg(state, STB0899_DEMAPVIT, reg);
+			STB0899_SETFIELD_VAL(BETA, reg, betaTab[3][clnI]);
+			stb0899_write_reg(state, STB0899_BCLC, reg);
+			break;
+		case STB0899_FEC_6_7:		/* 25	*/
+			STB0899_SETFIELD_VAL(DEMAPVIT_KDIVIDER, reg, 88);
+			stb0899_write_reg(state, STB0899_DEMAPVIT, reg);
+			stb0899_write_reg(state, STB0899_ACLC, 0x88);
+			stb0899_write_reg(state, STB0899_BCLC, 0x9a);
+			break;
+		case STB0899_FEC_7_8:		/* 26	*/
+			STB0899_SETFIELD_VAL(DEMAPVIT_KDIVIDER, reg, 94);
+			stb0899_write_reg(state, STB0899_DEMAPVIT, reg);
+			STB0899_SETFIELD_VAL(BETA, reg, betaTab[4][clnI]);
+			stb0899_write_reg(state, STB0899_BCLC, reg);
+			break;
+		default:
+			dprintk(state->verbose, FE_DEBUG, 1, "Unsupported Puncture Rate");
+			break;
+		}
+		/* release stream merger RESET	*/
+		reg = stb0899_read_reg(state, STB0899_TSTRES);
+		STB0899_SETFIELD_VAL(FRESRS, reg, 0);
+		stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+		/* disable carrier detector	*/
+		reg = stb0899_read_reg(state, STB0899_CFD);
+		STB0899_SETFIELD_VAL(CFD_ON, reg, 0);
+		stb0899_write_reg(state, STB0899_RTF, reg);
+
+		stb0899_read_regs(state, STB0899_EQUAI1, eq_const, 10);
+	}
+
+	return internal->status;
+}
+
+/*
+ * stb0899_dvbs2_config_uwp
+ * Configure UWP state machine
+ */
+static void stb0899_dvbs2_config_uwp(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+	struct stb0899_config *config = state->config;
+	u32 uwp1, uwp2, uwp3, reg;
+
+	uwp1 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1);
+	uwp2 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL2);
+	uwp3 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL3);
+
+	STB0899_SETFIELD_VAL(UWP_ESN0_AVE, uwp1, config->esno_ave);
+	STB0899_SETFIELD_VAL(UWP_ESN0_QUANT, uwp1, config->esno_quant);
+	STB0899_SETFIELD_VAL(UWP_TH_SOF, uwp1, config->uwp_threshold_sof);
+
+	STB0899_SETFIELD_VAL(FE_COARSE_TRK, uwp2, internal->av_frame_coarse);
+	STB0899_SETFIELD_VAL(FE_FINE_TRK, uwp2, internal->av_frame_fine);
+	STB0899_SETFIELD_VAL(UWP_MISS_TH, uwp2, config->miss_threshold);
+
+	STB0899_SETFIELD_VAL(UWP_TH_ACQ, uwp3, config->uwp_threshold_acq);
+	STB0899_SETFIELD_VAL(UWP_TH_TRACK, uwp3, config->uwp_threshold_track);
+
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL1, STB0899_OFF0_UWP_CNTRL1, uwp1);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL2, STB0899_OFF0_UWP_CNTRL2, uwp2);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL3, STB0899_OFF0_UWP_CNTRL3, uwp3);
+
+	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, SOF_SRCH_TO);
+	STB0899_SETFIELD_VAL(SOF_SEARCH_TIMEOUT, reg, config->sof_search_timeout);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_SOF_SRCH_TO, STB0899_OFF0_SOF_SRCH_TO, reg);
+}
+
+/*
+ * stb0899_dvbs2_config_csm_auto
+ * Set CSM to AUTO mode
+ */
+static void stb0899_dvbs2_config_csm_auto(struct stb0899_state *state)
+{
+	u32 reg;
+
+	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
+	STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, reg, 1);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, reg);
+}
+
+long Log2Int(int number)
+{
+	int i;
+
+	i = 0;
+	while ((1 << i) <= ABS(number))
+		i++;
+
+	if (number == 0)
+		i = 1;
+
+	return i - 1;
+}
+
+/*
+ * stb0899_dvbs2_calc_srate
+ * compute BTR_NOM_FREQ for the symbol rate
+ */
+static u32 stb0899_dvbs2_calc_srate(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal	= &state->internal;
+	struct stb0899_config *config		= state->config;
+
+	u32 dec_ratio, dec_rate, decim, remain, intval, btr_nom_freq;
+	u32 master_clk, srate;
+
+	dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
+	dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
+	dec_rate = Log2Int(dec_ratio);
+	decim = 1 << dec_rate;
+	master_clk = internal->master_clk / 1000;
+	srate = internal->srate / 1000;
+
+	if (decim <= 4) {
+		intval = (decim * (1 << (config->btr_nco_bits - 1))) / master_clk;
+		remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk;
+	} else {
+		intval = (1 << (config->btr_nco_bits - 1)) / (master_clk / 100) * decim / 100;
+		remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk;
+	}
+	btr_nom_freq = (intval * srate) + ((remain * srate) / master_clk);
+
+	return btr_nom_freq;
+}
+
+/*
+ * stb0899_dvbs2_calc_dev
+ * compute the correction to be applied to symbol rate
+ */
+static u32 stb0899_dvbs2_calc_dev(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+	u32 dec_ratio, correction, master_clk, srate;
+
+	dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
+	dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
+
+	master_clk = internal->master_clk / 1000;	/* for integer Caculation*/
+	srate = internal->srate / 1000;	/* for integer Caculation*/
+	correction = (512 * master_clk) / (2 * dec_ratio * srate);
+
+	return	correction;
+}
+
+/*
+ * stb0899_dvbs2_set_srate
+ * Set DVBS2 symbol rate
+ */
+static void stb0899_dvbs2_set_srate(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+
+	u32 dec_ratio, dec_rate, win_sel, decim, f_sym, btr_nom_freq;
+	u32 correction, freq_adj, band_lim, decim_cntrl, reg;
+	u8 anti_alias;
+
+	/*set decimation to 1*/
+	dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
+	dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
+	dec_rate = Log2Int(dec_ratio);
+
+	win_sel = 0;
+	if (dec_rate >= 5)
+		win_sel = dec_rate - 4;
+
+	decim = (1 << dec_rate);
+	/* (FSamp/Fsymbol *100) for integer Caculation */
+	f_sym = internal->master_clk / ((decim * internal->srate) / 1000);
+
+	if (f_sym <= 2250)	/* don't band limit signal going into btr block*/
+		band_lim = 1;
+	else
+		band_lim = 0;	/* band limit signal going into btr block*/
+
+	decim_cntrl = ((win_sel << 3) & 0x18) + ((band_lim << 5) & 0x20) + (dec_rate & 0x7);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DECIM_CNTRL, STB0899_OFF0_DECIM_CNTRL, decim_cntrl);
+
+	if (f_sym <= 3450)
+		anti_alias = 0;
+	else if (f_sym <= 4250)
+		anti_alias = 1;
+	else
+		anti_alias = 2;
+
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ANTI_ALIAS_SEL, STB0899_OFF0_ANTI_ALIAS_SEL, anti_alias);
+	btr_nom_freq = stb0899_dvbs2_calc_srate(state);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_NOM_FREQ, STB0899_OFF0_BTR_NOM_FREQ, btr_nom_freq);
+
+	correction = stb0899_dvbs2_calc_dev(state);
+	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL);
+	STB0899_SETFIELD_VAL(BTR_FREQ_CORR, reg, correction);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg);
+
+	/* scale UWP+CSM frequency to sample rate*/
+	freq_adj =  internal->srate / (internal->master_clk / 4096);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_FREQ_ADJ_SCALE, STB0899_OFF0_FREQ_ADJ_SCALE, freq_adj);
+}
+
+/*
+ * stb0899_dvbs2_set_btr_loopbw
+ * set bit timing loop bandwidth as a percentage of the symbol rate
+ */
+static void stb0899_dvbs2_set_btr_loopbw(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal	= &state->internal;
+	struct stb0899_config *config		= state->config;
+
+	u32 sym_peak = 23, zeta = 707, loopbw_percent = 60;
+	s32 dec_ratio, dec_rate, k_btr1_rshft, k_btr1, k_btr0_rshft;
+	s32 k_btr0, k_btr2_rshft, k_direct_shift, k_indirect_shift;
+	u32 decim, K, wn, k_direct, k_indirect;
+	u32 reg;
+
+	dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
+	dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
+	dec_rate = Log2Int(dec_ratio);
+	decim = (1 << dec_rate);
+
+	sym_peak *= 576000;
+	K = (1 << config->btr_nco_bits) / (internal->master_clk / 1000);
+	K *= (internal->srate / 1000000) * decim; /*k=k 10^-8*/
+	K = sym_peak / K;
+
+	if (K != 0) {
+		wn = (4 * zeta * zeta) + 1000000;
+		wn = (2 * (loopbw_percent * 1000) * 40 * zeta) /wn;  /*wn =wn 10^-8*/
+
+		k_indirect = (wn * wn) / K;
+		k_indirect = k_indirect;	  /*kindirect = kindirect 10^-6*/
+		k_direct   = (2 * wn * zeta) / K;	/*kDirect = kDirect 10^-2*/
+		k_direct  *= 100;
+
+		k_direct_shift = Log2Int(k_direct) - Log2Int(10000) - 2;
+		k_btr1_rshft = (-1 * k_direct_shift) + config->btr_gain_shift_offset;
+		k_btr1 = k_direct / (1 << k_direct_shift);
+		k_btr1 /= 10000;
+
+		k_indirect_shift = Log2Int(k_indirect + 15) - 20 /*- 2*/;
+		k_btr0_rshft = (-1 * k_indirect_shift) + config->btr_gain_shift_offset;
+		k_btr0 = k_indirect * (1 << (-k_indirect_shift));
+		k_btr0 /= 1000000;
+
+		k_btr2_rshft = 0;
+		if (k_btr0_rshft > 15) {
+			k_btr2_rshft = k_btr0_rshft - 15;
+			k_btr0_rshft = 15;
+		}
+		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_LOOP_GAIN);
+		STB0899_SETFIELD_VAL(KBTR0_RSHFT, reg, k_btr0_rshft);
+		STB0899_SETFIELD_VAL(KBTR0, reg, k_btr0);
+		STB0899_SETFIELD_VAL(KBTR1_RSHFT, reg, k_btr1_rshft);
+		STB0899_SETFIELD_VAL(KBTR1, reg, k_btr1);
+		STB0899_SETFIELD_VAL(KBTR2_RSHFT, reg, k_btr2_rshft);
+		stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, reg);
+	} else
+		stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, 0xc4c4f);
+}
+
+/*
+ * stb0899_dvbs2_set_carr_freq
+ * set nominal frequency for carrier search
+ */
+static void stb0899_dvbs2_set_carr_freq(struct stb0899_state *state, s32 carr_freq, u32 master_clk)
+{
+	struct stb0899_config *config = state->config;
+	s32 crl_nom_freq;
+	u32 reg;
+
+	crl_nom_freq = (1 << config->crl_nco_bits) / master_clk;
+	crl_nom_freq *= carr_freq;
+	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
+	STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, crl_nom_freq);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
+}
+
+/*
+ * stb0899_dvbs2_init_calc
+ * Initialize DVBS2 UWP, CSM, carrier and timing loops
+ */
+static void stb0899_dvbs2_init_calc(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+	s32 steps, step_size;
+	u32 range, reg;
+
+	/* config uwp and csm */
+	stb0899_dvbs2_config_uwp(state);
+	stb0899_dvbs2_config_csm_auto(state);
+
+	/* initialize BTR	*/
+	stb0899_dvbs2_set_srate(state);
+	stb0899_dvbs2_set_btr_loopbw(state);
+
+	if (internal->srate / 1000000 >= 15)
+		step_size = (1 << 17) / 5;
+	else if (internal->srate / 1000000 >= 10)
+		step_size = (1 << 17) / 7;
+	else if (internal->srate / 1000000 >= 5)
+		step_size = (1 << 17) / 10;
+	else
+		step_size = (1 << 17) / 4;
+
+	range = internal->srch_range / 1000000;
+	steps = (10 * range * (1 << 17)) / (step_size * (internal->srate / 1000000));
+	steps = (steps + 6) / 10;
+	steps = (steps == 0) ? 1 : steps;
+	if (steps % 2 == 0)
+		stb0899_dvbs2_set_carr_freq(state, internal->center_freq -
+					   (internal->step_size * (internal->srate / 20000000)),
+					   (internal->master_clk) / 1000000);
+	else
+		stb0899_dvbs2_set_carr_freq(state, internal->center_freq, (internal->master_clk) / 1000000);
+
+	/*Set Carrier Search params (zigzag, num steps and freq step size*/
+	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, ACQ_CNTRL2);
+	STB0899_SETFIELD_VAL(ZIGZAG, reg, 1);
+	STB0899_SETFIELD_VAL(NUM_STEPS, reg, steps);
+	STB0899_SETFIELD_VAL(FREQ_STEPSIZE, reg, step_size);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQ_CNTRL2, STB0899_OFF0_ACQ_CNTRL2, reg);
+}
+
+/*
+ * stb0899_dvbs2_btr_init
+ * initialize the timing loop
+ */
+static void stb0899_dvbs2_btr_init(struct stb0899_state *state)
+{
+	u32 reg;
+
+	/* set enable BTR loopback	*/
+	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL);
+	STB0899_SETFIELD_VAL(INTRP_PHS_SENSE, reg, 1);
+	STB0899_SETFIELD_VAL(BTR_ERR_ENA, reg, 1);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg);
+
+	/* fix btr freq accum at 0	*/
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x10000000);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x00000000);
+
+	/* fix btr freq accum at 0	*/
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x10000000);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x00000000);
+}
+
+/*
+ * stb0899_dvbs2_reacquire
+ * trigger a DVB-S2 acquisition
+ */
+static void stb0899_dvbs2_reacquire(struct stb0899_state *state)
+{
+	u32 reg = 0;
+
+	/* demod soft reset	*/
+	STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 1);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg);
+
+	/*Reset Timing Loop	*/
+	stb0899_dvbs2_btr_init(state);
+
+	/* reset Carrier loop	*/
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, (1 << 30));
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, 0);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_LOOP_GAIN, STB0899_OFF0_CRL_LOOP_GAIN, 0);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, (1 << 30));
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, 0);
+
+	/*release demod soft reset	*/
+	reg = 0;
+	STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 0);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg);
+
+	/* start acquisition process	*/
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQUIRE_TRIG, STB0899_OFF0_ACQUIRE_TRIG, 1);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_LOCK_LOST, STB0899_OFF0_LOCK_LOST, 0);
+
+	/* equalizer Init	*/
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 1);
+
+	/*Start equilizer	*/
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 0);
+
+	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
+	STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0);
+	STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 0);
+	STB0899_SETFIELD_VAL(EQ_DELAY, reg, 0x05);
+	STB0899_SETFIELD_VAL(EQ_ADAPT_MODE, reg, 0x01);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
+
+	/* RESET Packet delineator	*/
+	stb0899_write_reg(state, STB0899_PDELCTRL, 0x4a);
+}
+
+/*
+ * stb0899_dvbs2_get_dmd_status
+ * get DVB-S2 Demod LOCK status
+ */
+static enum stb0899_status stb0899_dvbs2_get_dmd_status(struct stb0899_state *state, int timeout)
+{
+	int time = -10, lock = 0, uwp, csm;
+	u32 reg;
+
+	do {
+		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STATUS);
+		dprintk(state->verbose, FE_DEBUG, 1, "DMD_STATUS=[0x%02x]", reg);
+		if (STB0899_GETFIELD(IF_AGC_LOCK, reg))
+			dprintk(state->verbose, FE_DEBUG, 1, "------------->IF AGC LOCKED !");
+		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2);
+		dprintk(state->verbose, FE_DEBUG, 1, "----------->DMD STAT2=[0x%02x]", reg);
+		uwp = STB0899_GETFIELD(UWP_LOCK, reg);
+		csm = STB0899_GETFIELD(CSM_LOCK, reg);
+		if (uwp && csm)
+			lock = 1;
+
+		time += 10;
+		msleep(10);
+
+	} while ((!lock) && (time <= timeout));
+
+	if (lock) {
+		dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 LOCK !");
+		return DVBS2_DEMOD_LOCK;
+	} else {
+		return DVBS2_DEMOD_NOLOCK;
+	}
+}
+
+/*
+ * stb0899_dvbs2_get_data_lock
+ * get FEC status
+ */
+static int stb0899_dvbs2_get_data_lock(struct stb0899_state *state, int timeout)
+{
+	int time = 0, lock = 0;
+	u8 reg;
+
+	while ((!lock) && (time < timeout)) {
+		reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1);
+		dprintk(state->verbose, FE_DEBUG, 1, "---------> CFGPDELSTATUS=[0x%02x]", reg);
+		lock = STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg);
+		time++;
+	}
+
+	return lock;
+}
+
+/*
+ * stb0899_dvbs2_get_fec_status
+ * get DVB-S2 FEC LOCK status
+ */
+static enum stb0899_status stb0899_dvbs2_get_fec_status(struct stb0899_state *state, int timeout)
+{
+	int time = 0, Locked;
+
+	do {
+		Locked = stb0899_dvbs2_get_data_lock(state, 1);
+		time++;
+		msleep(1);
+
+	} while ((!Locked) && (time < timeout));
+
+	if (Locked) {
+		dprintk(state->verbose, FE_DEBUG, 1, "---------->DVB-S2 FEC LOCK !");
+		return DVBS2_FEC_LOCK;
+	} else {
+		return DVBS2_FEC_NOLOCK;
+	}
+}
+
+
+/*
+ * stb0899_dvbs2_init_csm
+ * set parameters for manual mode
+ */
+static void stb0899_dvbs2_init_csm(struct stb0899_state *state, int pilots, enum stb0899_modcod modcod)
+{
+	struct stb0899_internal *internal = &state->internal;
+
+	s32 dvt_tbl = 1, two_pass = 0, agc_gain = 6, agc_shift = 0, loop_shift = 0, phs_diff_thr = 0x80;
+	s32 gamma_acq, gamma_rho_acq, gamma_trk, gamma_rho_trk, lock_count_thr;
+	u32 csm1, csm2, csm3, csm4;
+
+	if (((internal->master_clk / internal->srate) <= 4) && (modcod <= 11) && (pilots == 1)) {
+		switch (modcod) {
+		case STB0899_QPSK_12:
+			gamma_acq		= 25;
+			gamma_rho_acq		= 2700;
+			gamma_trk		= 12;
+			gamma_rho_trk		= 180;
+			lock_count_thr		= 8;
+			break;
+		case STB0899_QPSK_35:
+			gamma_acq		= 38;
+			gamma_rho_acq		= 7182;
+			gamma_trk		= 14;
+			gamma_rho_trk		= 308;
+			lock_count_thr		= 8;
+			break;
+		case STB0899_QPSK_23:
+			gamma_acq		= 42;
+			gamma_rho_acq		= 9408;
+			gamma_trk		= 17;
+			gamma_rho_trk		= 476;
+			lock_count_thr		= 8;
+			break;
+		case STB0899_QPSK_34:
+			gamma_acq		= 53;
+			gamma_rho_acq		= 16642;
+			gamma_trk		= 19;
+			gamma_rho_trk		= 646;
+			lock_count_thr		= 8;
+			break;
+		case STB0899_QPSK_45:
+			gamma_acq		= 53;
+			gamma_rho_acq		= 17119;
+			gamma_trk		= 22;
+			gamma_rho_trk		= 880;
+			lock_count_thr		= 8;
+			break;
+		case STB0899_QPSK_56:
+			gamma_acq		= 55;
+			gamma_rho_acq		= 19250;
+			gamma_trk		= 23;
+			gamma_rho_trk		= 989;
+			lock_count_thr		= 8;
+			break;
+		case STB0899_QPSK_89:
+			gamma_acq		= 60;
+			gamma_rho_acq		= 24240;
+			gamma_trk		= 24;
+			gamma_rho_trk		= 1176;
+			lock_count_thr		= 8;
+			break;
+		case STB0899_QPSK_910:
+			gamma_acq		= 66;
+			gamma_rho_acq		= 29634;
+			gamma_trk		= 24;
+			gamma_rho_trk		= 1176;
+			lock_count_thr		= 8;
+			break;
+		default:
+			gamma_acq		= 66;
+			gamma_rho_acq		= 29634;
+			gamma_trk		= 24;
+			gamma_rho_trk		= 1176;
+			lock_count_thr		= 8;
+			break;
+		}
+
+		csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
+		STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, csm1, 0);
+		stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
+
+		csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
+		csm2 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL2);
+		csm3 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL3);
+		csm4 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL4);
+
+		STB0899_SETFIELD_VAL(CSM_DVT_TABLE, csm1, dvt_tbl);
+		STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, two_pass);
+		STB0899_SETFIELD_VAL(CSM_AGC_GAIN, csm1, agc_gain);
+		STB0899_SETFIELD_VAL(CSM_AGC_SHIFT, csm1, agc_shift);
+		STB0899_SETFIELD_VAL(FE_LOOP_SHIFT, csm1, loop_shift);
+		STB0899_SETFIELD_VAL(CSM_GAMMA_ACQ, csm2, gamma_acq);
+		STB0899_SETFIELD_VAL(CSM_GAMMA_RHOACQ, csm2, gamma_rho_acq);
+		STB0899_SETFIELD_VAL(CSM_GAMMA_TRACK, csm3, gamma_trk);
+		STB0899_SETFIELD_VAL(CSM_GAMMA_RHOTRACK, csm3, gamma_rho_trk);
+		STB0899_SETFIELD_VAL(CSM_LOCKCOUNT_THRESH, csm4, lock_count_thr);
+		STB0899_SETFIELD_VAL(CSM_PHASEDIFF_THRESH, csm4, phs_diff_thr);
+
+		stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
+		stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL2, STB0899_OFF0_CSM_CNTRL2, csm2);
+		stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL3, STB0899_OFF0_CSM_CNTRL3, csm3);
+		stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL4, STB0899_OFF0_CSM_CNTRL4, csm4);
+	}
+}
+
+/*
+ * stb0899_dvbs2_get_srate
+ * get DVB-S2 Symbol Rate
+ */
+static u32 stb0899_dvbs2_get_srate(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+	struct stb0899_config *config = state->config;
+
+	u32 bTrNomFreq, srate, decimRate, intval1, intval2, reg;
+	int div1, div2, rem1, rem2;
+
+	div1 = config->btr_nco_bits / 2;
+	div2 = config->btr_nco_bits - div1 - 1;
+
+	bTrNomFreq = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_NOM_FREQ);
+
+	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DECIM_CNTRL);
+	decimRate = STB0899_GETFIELD(DECIM_RATE, reg);
+	decimRate = (1 << decimRate);
+
+	intval1 = internal->master_clk / (1 << div1);
+	intval2 = bTrNomFreq / (1 << div2);
+
+	rem1 = internal->master_clk % (1 << div1);
+	rem2 = bTrNomFreq % (1 << div2);
+	/* only for integer calculation	*/
+	srate = (intval1 * intval2) + ((intval1 * rem2) / (1 << div2)) + ((intval2 * rem1) / (1 << div1));
+	srate /= decimRate;	/*symbrate = (btrnomfreq_register_val*MasterClock)/2^(27+decim_rate_field) */
+
+	return	srate;
+}
+
+/*
+ * stb0899_dvbs2_algo
+ * Search for signal, timing, carrier and data for a given
+ * frequency in a given range
+ */
+enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+	enum stb0899_modcod modcod;
+
+	s32 offsetfreq, searchTime, FecLockTime, pilots, iqSpectrum;
+	int i = 0;
+	u32 reg, csm1;
+
+	if (internal->srate <= 2000000) {
+		searchTime	= 5000;	/* 5000 ms max time to lock UWP and CSM, SYMB <= 2Mbs		*/
+		FecLockTime	= 350;	/* 350  ms max time to lock FEC, SYMB <= 2Mbs			*/
+	} else if (internal->srate <= 5000000) {
+		searchTime	= 2500;	/* 2500 ms max time to lock UWP and CSM, 2Mbs < SYMB <= 5Mbs	*/
+		FecLockTime	= 170;	/* 170  ms max time to lock FEC, 2Mbs< SYMB <= 5Mbs		*/
+	} else if (internal->srate <= 10000000) {
+		searchTime	= 1500;	/* 1500 ms max time to lock UWP and CSM, 5Mbs <SYMB <= 10Mbs	*/
+		FecLockTime	= 80;	/* 80  ms max time to lock FEC, 5Mbs< SYMB <= 10Mbs		*/
+	} else if (internal->srate <= 15000000) {
+		searchTime	= 500;	/* 500 ms max time to lock UWP and CSM, 10Mbs <SYMB <= 15Mbs	*/
+		FecLockTime	= 50;	/* 50  ms max time to lock FEC, 10Mbs< SYMB <= 15Mbs		*/
+	} else if (internal->srate <= 20000000) {
+		searchTime	= 300;	/* 300 ms max time to lock UWP and CSM, 15Mbs < SYMB <= 20Mbs	*/
+		FecLockTime	= 30;	/* 50  ms max time to lock FEC, 15Mbs< SYMB <= 20Mbs		*/
+	} else if (internal->srate <= 25000000) {
+		searchTime	= 250;	/* 250 ms max time to lock UWP and CSM, 20 Mbs < SYMB <= 25Mbs	*/
+		FecLockTime	= 25;	/* 25 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs		*/
+	} else {
+		searchTime	= 150;	/* 150 ms max time to lock UWP and CSM, SYMB > 25Mbs		*/
+		FecLockTime	= 20;	/* 20 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs		*/
+	}
+
+	/* Maintain Stream Merger in reset during acquisition	*/
+	reg = stb0899_read_reg(state, STB0899_TSTRES);
+	STB0899_SETFIELD_VAL(FRESRS, reg, 1);
+	stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+	/* Move tuner to frequency	*/
+	if (state->config->tuner_set_frequency)
+		state->config->tuner_set_frequency(&state->frontend, internal->freq);
+	if (state->config->tuner_get_frequency)
+		state->config->tuner_get_frequency(&state->frontend, &internal->freq);
+
+	/* Set IF AGC to acquisition	*/
+	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
+	STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg,  4);
+	STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 32);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
+
+	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2);
+	STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 0);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg);
+
+	/* Initialisation	*/
+	stb0899_dvbs2_init_calc(state);
+
+	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
+	switch (internal->inversion) {
+	case IQ_SWAP_OFF:
+		STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 0);
+		break;
+	case IQ_SWAP_ON:
+		STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
+		break;
+	case IQ_SWAP_AUTO:	/* use last successful search first	*/
+		STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
+		break;
+	}
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
+	stb0899_dvbs2_reacquire(state);
+
+	/* Wait for demod lock (UWP and CSM)	*/
+	internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
+
+	if (internal->status == DVBS2_DEMOD_LOCK) {
+		dprintk(state->verbose, FE_DEBUG, 1, "------------> DVB-S2 DEMOD LOCK !");
+		i = 0;
+		/* Demod Locked, check FEC status	*/
+		internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
+
+		/*If false lock (UWP and CSM Locked but no FEC) try 3 time max*/
+		while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
+			/*	Read the frequency offset*/
+			offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
+
+			/* Set the Nominal frequency to the found frequency offset for the next reacquire*/
+			reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
+			STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
+			stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, offsetfreq);
+			stb0899_dvbs2_reacquire(state);
+			internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
+			i++;
+		}
+	}
+
+	if (internal->status != DVBS2_FEC_LOCK) {
+		if (internal->inversion == IQ_SWAP_AUTO) {
+			reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
+			iqSpectrum = STB0899_GETFIELD(SPECTRUM_INVERT, reg);
+			/* IQ Spectrum Inversion	*/
+			STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, !iqSpectrum);
+			stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
+			/* start acquistion process	*/
+			stb0899_dvbs2_reacquire(state);
+
+			/* Wait for demod lock (UWP and CSM)	*/
+			internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
+			if (internal->status == DVBS2_DEMOD_LOCK) {
+				i = 0;
+				/* Demod Locked, check FEC	*/
+				internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
+				/*try thrice for false locks, (UWP and CSM Locked but no FEC)	*/
+				while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
+					/*	Read the frequency offset*/
+					offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
+
+					/* Set the Nominal frequency to the found frequency offset for the next reacquire*/
+					reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
+					STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
+					stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, offsetfreq);
+
+					stb0899_dvbs2_reacquire(state);
+					internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
+					i++;
+				}
+			}
+/*
+			if (pParams->DVBS2State == FE_DVBS2_FEC_LOCKED)
+				pParams->IQLocked = !iqSpectrum;
+*/
+		}
+	}
+	if (internal->status == DVBS2_FEC_LOCK) {
+		dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 FEC Lock !");
+		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
+		modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2;
+		pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01;
+
+		if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) &&
+		      (INRANGE(STB0899_QPSK_23, modcod, STB0899_QPSK_910)) &&
+		      (pilots == 1)) {
+
+			stb0899_dvbs2_init_csm(state, pilots, modcod);
+			/* Wait for UWP,CSM and data LOCK 20ms max	*/
+			internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
+
+			i = 0;
+			while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
+				csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
+				STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 1);
+				stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
+				csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
+				STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 0);
+				stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
+
+				internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
+				i++;
+			}
+		}
+
+		if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) &&
+		      (INRANGE(STB0899_QPSK_12, modcod, STB0899_QPSK_35)) &&
+		      (pilots == 1)) {
+
+			/* Equalizer Disable update	 */
+			reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
+			STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 1);
+			stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
+		}
+
+		/* slow down the Equalizer once locked	*/
+		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
+		STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0x02);
+		stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
+
+		/* Store signal parameters	*/
+		offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
+
+		offsetfreq = offsetfreq / ((1 << 30) / 1000);
+		offsetfreq *= (internal->master_clk / 1000000);
+		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
+		if (STB0899_GETFIELD(SPECTRUM_INVERT, reg))
+			offsetfreq *= -1;
+
+		internal->freq = internal->freq - offsetfreq;
+		internal->srate = stb0899_dvbs2_get_srate(state);
+
+		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
+		internal->modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2;
+		internal->pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01;
+		internal->frame_length = (STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 1) & 0x01;
+
+		 /* Set IF AGC to tracking	*/
+		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
+		STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg,  3);
+
+		/* if QPSK 1/2,QPSK 3/5 or QPSK 2/3 set IF AGC reference to 16 otherwise 32*/
+		if (INRANGE(STB0899_QPSK_12, internal->modcod, STB0899_QPSK_23))
+			STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 16);
+
+		stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
+
+		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2);
+		STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 7);
+		stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg);
+	}
+
+	/* Release Stream Merger Reset		*/
+	reg = stb0899_read_reg(state, STB0899_TSTRES);
+	STB0899_SETFIELD_VAL(FRESRS, reg, 0);
+	stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+	return internal->status;
+}
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c
new file mode 100644
index 0000000..3cb9b48
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_drv.c
@@ -0,0 +1,1963 @@
+/*
+	STB0899 Multistandard Frontend driver
+	Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+	Copyright (C) ST Microelectronics
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; either version 2 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the Free Software
+	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+#include "stb0899_drv.h"
+#include "stb0899_priv.h"
+#include "stb0899_reg.h"
+
+static unsigned int verbose = 5;
+module_param(verbose, int, 0644);
+
+/* C/N in dB/10, NIRM/NIRL */
+static const struct stb0899_tab stb0899_cn_tab[] = {
+	{ 200,	2600 },
+	{ 190,	2700 },
+	{ 180,	2860 },
+	{ 170,	3020 },
+	{ 160,	3210 },
+	{ 150,	3440 },
+	{ 140,	3710 },
+	{ 130,	4010 },
+	{ 120,	4360 },
+	{ 110,	4740 },
+	{ 100,	5190 },
+	{ 90,	5670 },
+	{ 80,	6200 },
+	{ 70,	6770 },
+	{ 60,	7360 },
+	{ 50,	7970 },
+	{ 40,	8250 },
+	{ 30,	9000 },
+	{ 20,	9450 },
+	{ 15,	9600 },
+};
+
+/* DVB-S AGCIQ_VALUE vs. signal level in dBm/10.
+ * As measured, connected to a modulator.
+ * -8.0 to -50.0 dBm directly connected,
+ * -52.0 to -74.8 with extra attenuation.
+ * Cut-off to AGCIQ_VALUE = 0x80 below -74.8dBm.
+ * Crude linear extrapolation below -84.8dBm and above -8.0dBm.
+ */
+static const struct stb0899_tab stb0899_dvbsrf_tab[] = {
+	{ -950,	-128 },
+	{ -748,	 -94 },
+	{ -745,	 -92 },
+	{ -735,	 -90 },
+	{ -720,	 -87 },
+	{ -670,	 -77 },
+	{ -640,	 -70 },
+	{ -610,	 -62 },
+	{ -600,	 -60 },
+	{ -590,	 -56 },
+	{ -560,	 -41 },
+	{ -540,	 -25 },
+	{ -530,	 -17 },
+	{ -520,	 -11 },
+	{ -500,	   1 },
+	{ -490,	   6 },
+	{ -480,	  10 },
+	{ -440,	  22 },
+	{ -420,	  27 },
+	{ -400,	  31 },
+	{ -380,	  34 },
+	{ -340,	  40 },
+	{ -320,	  43 },
+	{ -280,	  48 },
+	{ -250,	  52 },
+	{ -230,	  55 },
+	{ -180,	  61 },
+	{ -140,	  66 },
+	{  -90,	  73 },
+	{  -80,	  74 },
+	{  500,	 127 }
+};
+
+/* DVB-S2 IF_AGC_GAIN vs. signal level in dBm/10.
+ * As measured, connected to a modulator.
+ * -8.0 to -50.1 dBm directly connected,
+ * -53.0 to -76.6 with extra attenuation.
+ * Cut-off to IF_AGC_GAIN = 0x3fff below -76.6dBm.
+ * Crude linear extrapolation below -76.6dBm and above -8.0dBm.
+ */
+static const struct stb0899_tab stb0899_dvbs2rf_tab[] = {
+	{  700,	    0 },
+	{  -80,	 3217 },
+	{ -150,	 3893 },
+	{ -190,	 4217 },
+	{ -240,	 4621 },
+	{ -280,	 4945 },
+	{ -320,	 5273 },
+	{ -350,	 5545 },
+	{ -370,	 5741 },
+	{ -410,	 6147 },
+	{ -450,	 6671 },
+	{ -490,	 7413 },
+	{ -501,	 7665 },
+	{ -530,	 8767 },
+	{ -560,	10219 },
+	{ -580,	10939 },
+	{ -590,	11518 },
+	{ -600,	11723 },
+	{ -650,	12659 },
+	{ -690,	13219 },
+	{ -730,	13645 },
+	{ -750,	13909 },
+	{ -766,	14153 },
+	{ -999,	16383 }
+};
+
+/* DVB-S2 Es/N0 quant in dB/100 vs read value * 100*/
+struct stb0899_tab stb0899_quant_tab[] = {
+	{    0,	    0 },
+	{    0,	  100 },
+	{  600,	  200 },
+	{  950,	  299 },
+	{ 1200,	  398 },
+	{ 1400,	  501 },
+	{ 1560,	  603 },
+	{ 1690,	  700 },
+	{ 1810,	  804 },
+	{ 1910,	  902 },
+	{ 2000,	 1000 },
+	{ 2080,	 1096 },
+	{ 2160,	 1202 },
+	{ 2230,	 1303 },
+	{ 2350,	 1496 },
+	{ 2410,	 1603 },
+	{ 2460,	 1698 },
+	{ 2510,	 1799 },
+	{ 2600,	 1995 },
+	{ 2650,	 2113 },
+	{ 2690,  2213 },
+	{ 2720,	 2291 },
+	{ 2760,	 2399 },
+	{ 2800,	 2512 },
+	{ 2860,	 2692 },
+	{ 2930,	 2917 },
+	{ 2960,	 3020 },
+	{ 3010,	 3199 },
+	{ 3040,	 3311 },
+	{ 3060,	 3388 },
+	{ 3120,	 3631 },
+	{ 3190,	 3936 },
+	{ 3400,	 5012 },
+	{ 3610,	 6383 },
+	{ 3800,	 7943 },
+	{ 4210,	12735 },
+	{ 4500,	17783 },
+	{ 4690,	22131 },
+	{ 4810,	25410 }
+};
+
+/* DVB-S2 Es/N0 estimate in dB/100 vs read value */
+struct stb0899_tab stb0899_est_tab[] = {
+	{    0,	     0 },
+	{    0,	     1 },
+	{  301,	     2 },
+	{ 1204,	    16 },
+	{ 1806,	    64 },
+	{ 2408,	   256 },
+	{ 2709,	   512 },
+	{ 3010,	  1023 },
+	{ 3311,	  2046 },
+	{ 3612,	  4093 },
+	{ 3823,	  6653 },
+	{ 3913,	  8185 },
+	{ 4010,	 10233 },
+	{ 4107,	 12794 },
+	{ 4214,	 16368 },
+	{ 4266,	 18450 },
+	{ 4311,	 20464 },
+	{ 4353,	 22542 },
+	{ 4391,	 24604 },
+	{ 4425,	 26607 },
+	{ 4457,	 28642 },
+	{ 4487,	 30690 },
+	{ 4515,	 32734 },
+	{ 4612,	 40926 },
+	{ 4692,	 49204 },
+	{ 4816,	 65464 },
+	{ 4913,	 81846 },
+	{ 4993,	 98401 },
+	{ 5060,	114815 },
+	{ 5118,	131220 },
+	{ 5200,	158489 },
+	{ 5300,	199526 },
+	{ 5400,	251189 },
+	{ 5500,	316228 },
+	{ 5600,	398107 },
+	{ 5720,	524807 },
+	{ 5721,	526017 },
+};
+
+int _stb0899_read_reg(struct stb0899_state *state, unsigned int reg)
+{
+	int ret;
+
+	u8 b0[] = { reg >> 8, reg & 0xff };
+	u8 buf;
+
+	struct i2c_msg msg[] = {
+		{
+			.addr	= state->config->demod_address,
+			.flags	= 0,
+			.buf	= b0,
+			.len	= 2
+		},{
+			.addr	= state->config->demod_address,
+			.flags	= I2C_M_RD,
+			.buf	= &buf,
+			.len	= 1
+		}
+	};
+
+	ret = i2c_transfer(state->i2c, msg, 2);
+	if (ret != 2) {
+		if (ret != -ERESTARTSYS)
+			dprintk(verbose, FE_ERROR, 1,
+				"Read error, Reg=[0x%02x], Status=%d",
+				reg, ret);
+
+		return ret < 0 ? ret : -EREMOTEIO;
+	}
+	if (unlikely(verbose >= FE_DEBUGREG))
+		dprintk(verbose, FE_ERROR, 1, "Reg=[0x%02x], data=%02x",
+			reg, buf);
+
+
+	return (unsigned int)buf;
+}
+
+int stb0899_read_reg(struct stb0899_state *state, unsigned int reg)
+{
+	int result;
+
+	result = _stb0899_read_reg(state, reg);
+	/*
+	 * Bug ID 9:
+	 * access to 0xf2xx/0xf6xx
+	 * must be followed by read from 0xf2ff/0xf6ff.
+	 */
+	if ((reg != 0xf2ff) && (reg != 0xf6ff) &&
+	    (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
+		_stb0899_read_reg(state, (reg | 0x00ff));
+
+	return result;
+}
+
+u32 _stb0899_read_s2reg(struct stb0899_state *state,
+		        u32 stb0899_i2cdev,
+		        u32 stb0899_base_addr,
+		        u16 stb0899_reg_offset)
+{
+	int status;
+	u32 data;
+	u8 buf[7] = { 0 };
+	u16 tmpaddr;
+
+	u8 buf_0[] = {
+		GETBYTE(stb0899_i2cdev, BYTE1),		/* 0xf3	S2 Base Address (MSB)	*/
+		GETBYTE(stb0899_i2cdev, BYTE0),		/* 0xfc	S2 Base Address (LSB)	*/
+		GETBYTE(stb0899_base_addr, BYTE0),	/* 0x00	Base Address (LSB)	*/
+		GETBYTE(stb0899_base_addr, BYTE1),	/* 0x04	Base Address (LSB)	*/
+		GETBYTE(stb0899_base_addr, BYTE2),	/* 0x00	Base Address (MSB)	*/
+		GETBYTE(stb0899_base_addr, BYTE3),	/* 0x00	Base Address (MSB)	*/
+	};
+	u8 buf_1[] = {
+		0x00,	/* 0xf3	Reg Offset	*/
+		0x00,	/* 0x44	Reg Offset	*/
+	};
+
+	struct i2c_msg msg_0 = {
+		.addr	= state->config->demod_address,
+		.flags	= 0,
+		.buf	= buf_0,
+		.len	= 6
+	};
+
+	struct i2c_msg msg_1 = {
+		.addr	= state->config->demod_address,
+		.flags	= 0,
+		.buf	= buf_1,
+		.len	= 2
+	};
+
+	struct i2c_msg msg_r = {
+		.addr	= state->config->demod_address,
+		.flags	= I2C_M_RD,
+		.buf	= buf,
+		.len	= 4
+	};
+
+	tmpaddr = stb0899_reg_offset & 0xff00;
+	if (!(stb0899_reg_offset & 0x8))
+		tmpaddr = stb0899_reg_offset | 0x20;
+
+	buf_1[0] = GETBYTE(tmpaddr, BYTE1);
+	buf_1[1] = GETBYTE(tmpaddr, BYTE0);
+
+	status = i2c_transfer(state->i2c, &msg_0, 1);
+	if (status < 1) {
+		if (status != -ERESTARTSYS)
+			printk(KERN_ERR "%s ERR(1), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
+			       __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
+
+		goto err;
+	}
+
+	/* Dummy	*/
+	status = i2c_transfer(state->i2c, &msg_1, 1);
+	if (status < 1)
+		goto err;
+
+	status = i2c_transfer(state->i2c, &msg_r, 1);
+	if (status < 1)
+		goto err;
+
+	buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1);
+	buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0);
+
+	/* Actual	*/
+	status = i2c_transfer(state->i2c, &msg_1, 1);
+	if (status < 1) {
+		if (status != -ERESTARTSYS)
+			printk(KERN_ERR "%s ERR(2), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
+			       __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
+		goto err;
+	}
+
+	status = i2c_transfer(state->i2c, &msg_r, 1);
+	if (status < 1) {
+		if (status != -ERESTARTSYS)
+			printk(KERN_ERR "%s ERR(3), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
+			       __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
+		return status < 0 ? status : -EREMOTEIO;
+	}
+
+	data = MAKEWORD32(buf[3], buf[2], buf[1], buf[0]);
+	if (unlikely(state->verbose >= FE_DEBUGREG))
+		printk(KERN_DEBUG "%s Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n",
+		       __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, data);
+
+	return data;
+
+err:
+	return status < 0 ? status : -EREMOTEIO;
+}
+
+int stb0899_write_s2reg(struct stb0899_state *state,
+			u32 stb0899_i2cdev,
+			u32 stb0899_base_addr,
+			u16 stb0899_reg_offset,
+			u32 stb0899_data)
+{
+	int status;
+
+	/* Base Address Setup	*/
+	u8 buf_0[] = {
+		GETBYTE(stb0899_i2cdev, BYTE1),		/* 0xf3	S2 Base Address (MSB)	*/
+		GETBYTE(stb0899_i2cdev, BYTE0),		/* 0xfc	S2 Base Address (LSB)	*/
+		GETBYTE(stb0899_base_addr, BYTE0),	/* 0x00	Base Address (LSB)	*/
+		GETBYTE(stb0899_base_addr, BYTE1),	/* 0x04	Base Address (LSB)	*/
+		GETBYTE(stb0899_base_addr, BYTE2),	/* 0x00	Base Address (MSB)	*/
+		GETBYTE(stb0899_base_addr, BYTE3),	/* 0x00	Base Address (MSB)	*/
+	};
+	u8 buf_1[] = {
+		0x00,	/* 0xf3	Reg Offset	*/
+		0x00,	/* 0x44	Reg Offset	*/
+		0x00,	/* data			*/
+		0x00,	/* data			*/
+		0x00,	/* data			*/
+		0x00,	/* data			*/
+	};
+
+	struct i2c_msg msg_0 = {
+		.addr	= state->config->demod_address,
+		.flags	= 0,
+		.buf	= buf_0,
+		.len	= 6
+	};
+
+	struct i2c_msg msg_1 = {
+		.addr	= state->config->demod_address,
+		.flags	= 0,
+		.buf	= buf_1,
+		.len	= 6
+	};
+
+	buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1);
+	buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0);
+	buf_1[2] = GETBYTE(stb0899_data, BYTE0);
+	buf_1[3] = GETBYTE(stb0899_data, BYTE1);
+	buf_1[4] = GETBYTE(stb0899_data, BYTE2);
+	buf_1[5] = GETBYTE(stb0899_data, BYTE3);
+
+	if (unlikely(state->verbose >= FE_DEBUGREG))
+		printk(KERN_DEBUG "%s Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n",
+		       __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data);
+
+	status = i2c_transfer(state->i2c, &msg_0, 1);
+	if (unlikely(status < 1)) {
+		if (status != -ERESTARTSYS)
+			printk(KERN_ERR "%s ERR (1), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n",
+			       __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status);
+		goto err;
+	}
+	status = i2c_transfer(state->i2c, &msg_1, 1);
+	if (unlikely(status < 1)) {
+		if (status != -ERESTARTSYS)
+			printk(KERN_ERR "%s ERR (2), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n",
+			       __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status);
+
+		return status < 0 ? status : -EREMOTEIO;
+	}
+
+	return 0;
+
+err:
+	return status < 0 ? status : -EREMOTEIO;
+}
+
+int stb0899_read_regs(struct stb0899_state *state, unsigned int reg, u8 *buf, size_t count)
+{
+	int status;
+
+	u8 b0[] = { reg >> 8, reg & 0xff };
+
+	struct i2c_msg msg[] = {
+		{
+			.addr	= state->config->demod_address,
+			.flags	= 0,
+			.buf	= b0,
+			.len	= 2
+		},{
+			.addr	= state->config->demod_address,
+			.flags	= I2C_M_RD,
+			.buf	= buf,
+			.len	= count
+		}
+	};
+
+	status = i2c_transfer(state->i2c, msg, 2);
+	if (status != 2) {
+		if (status != -ERESTARTSYS)
+			printk(KERN_ERR "%s Read error, Reg=[0x%04x], Count=%u, Status=%d\n",
+			       __func__, reg, count, status);
+		goto err;
+	}
+	/*
+	 * Bug ID 9:
+	 * access to 0xf2xx/0xf6xx
+	 * must be followed by read from 0xf2ff/0xf6ff.
+	 */
+	if ((reg != 0xf2ff) && (reg != 0xf6ff) &&
+	    (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
+		_stb0899_read_reg(state, (reg | 0x00ff));
+
+	if (unlikely(state->verbose >= FE_DEBUGREG)) {
+		int i;
+
+		printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
+		for (i = 0; i < count; i++) {
+			printk(" %02x", buf[i]);
+		}
+		printk("\n");
+	}
+
+	return 0;
+err:
+	return status < 0 ? status : -EREMOTEIO;
+}
+
+int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data, size_t count)
+{
+	int ret;
+	u8 buf[2 + count];
+	struct i2c_msg i2c_msg = {
+		.addr	= state->config->demod_address,
+		.flags	= 0,
+		.buf	= buf,
+		.len	= 2 + count
+	};
+
+	buf[0] = reg >> 8;
+	buf[1] = reg & 0xff;
+	memcpy(&buf[2], data, count);
+
+	if (unlikely(state->verbose >= FE_DEBUGREG)) {
+		int i;
+
+		printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
+		for (i = 0; i < count; i++)
+			printk(" %02x", data[i]);
+		printk("\n");
+	}
+	ret = i2c_transfer(state->i2c, &i2c_msg, 1);
+
+	/*
+	 * Bug ID 9:
+	 * access to 0xf2xx/0xf6xx
+	 * must be followed by read from 0xf2ff/0xf6ff.
+	 */
+	if ((((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
+		stb0899_read_reg(state, (reg | 0x00ff));
+
+	if (ret != 1) {
+		if (ret != -ERESTARTSYS)
+			dprintk(verbose, FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d",
+				reg, data[0], count, ret);
+		return ret < 0 ? ret : -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data)
+{
+	return stb0899_write_regs(state, reg, &data, 1);
+}
+
+/*
+ * stb0899_get_mclk
+ * Get STB0899 master clock frequency
+ * ExtClk: external clock frequency (Hz)
+ */
+static u32 stb0899_get_mclk(struct stb0899_state *state)
+{
+	u32 mclk = 90000000, div = 0;
+
+	div = stb0899_read_reg(state, STB0899_NCOARSE);
+	mclk = (div + 1) * state->config->xtal_freq / 6;
+	dprintk(verbose, FE_DEBUG, 1, "div=%d, mclk=%d", div, mclk);
+
+	return mclk;
+}
+
+/*
+ * stb0899_set_mclk
+ * Set STB0899 master Clock frequency
+ * Mclk: demodulator master clock
+ * ExtClk: external clock frequency (Hz)
+ */
+static void stb0899_set_mclk(struct stb0899_state *state, u32 Mclk)
+{
+	struct stb0899_internal *internal = &state->internal;
+	u8 mdiv = 0;
+
+	dprintk(verbose, FE_DEBUG, 1, "state->config=%p", state->config);
+	mdiv = ((6 * Mclk) / state->config->xtal_freq) - 1;
+	dprintk(verbose, FE_DEBUG, 1, "mdiv=%d", mdiv);
+
+	stb0899_write_reg(state, STB0899_NCOARSE, mdiv);
+	internal->master_clk = stb0899_get_mclk(state);
+
+	dprintk(verbose, FE_DEBUG, 1, "MasterCLOCK=%d", internal->master_clk);
+}
+
+static void stb0899_release(struct dvb_frontend *fe)
+{
+	struct stb0899_state *state = fe->demodulator_priv;
+
+	dprintk(verbose, FE_DEBUG, 1, "Release Frontend");
+	kfree(state);
+}
+
+/*
+ * stb0899_get_alpha
+ * return: rolloff
+ */
+static int stb0899_get_alpha(struct stb0899_state *state)
+{
+	u8 mode_coeff;
+
+	mode_coeff = stb0899_read_reg(state, STB0899_DEMOD);
+
+	if (STB0899_GETFIELD(MODECOEFF, mode_coeff) == 1)
+		return 20;
+	else
+		return 35;
+}
+
+/*
+ * stb0899_init_calc
+ */
+static void stb0899_init_calc(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+	int master_clk;
+	u8 agc[1];
+	u8 agc1cn;
+	u32 reg;
+
+	/* Read registers (in burst mode)	*/
+	agc1cn = stb0899_read_reg(state, STB0899_AGC1CN);
+	stb0899_read_regs(state, STB0899_AGC1REF, agc, 2); /* AGC1R and AGC2O	*/
+
+	/* Initial calculations	*/
+	master_clk			= stb0899_get_mclk(state);
+	internal->t_agc1		= 0;
+	internal->t_agc2		= 0;
+	internal->master_clk		= master_clk;
+	internal->mclk			= master_clk / 65536L;
+	internal->rolloff		= stb0899_get_alpha(state);
+
+	/* DVBS2 Initial calculations	*/
+	/* Set AGC value to the middle	*/
+	internal->agc_gain		= 8154;
+	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
+	STB0899_SETFIELD_VAL(IF_GAIN_INIT, reg, internal->agc_gain);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
+
+	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, RRC_ALPHA);
+	internal->rrc_alpha		= STB0899_GETFIELD(RRC_ALPHA, reg);
+
+	internal->center_freq		= 0;
+	internal->av_frame_coarse	= 10;
+	internal->av_frame_fine		= 20;
+	internal->step_size		= 2;
+/*
+	if ((pParams->SpectralInv == FE_IQ_NORMAL) || (pParams->SpectralInv == FE_IQ_AUTO))
+		pParams->IQLocked = 0;
+	else
+		pParams->IQLocked = 1;
+*/
+}
+
+static int stb0899_wait_diseqc_fifo_empty(struct stb0899_state *state, int timeout)
+{
+	u8 reg = 0;
+	unsigned long start = jiffies;
+
+	while (1) {
+		reg = stb0899_read_reg(state, STB0899_DISSTATUS);
+		if (!STB0899_GETFIELD(FIFOFULL, reg))
+			break;
+		if ((jiffies - start) > timeout) {
+			dprintk(verbose, FE_ERROR, 1, "timed out !!");
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int stb0899_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
+{
+	struct stb0899_state *state = fe->demodulator_priv;
+	u8 reg, i;
+
+	if (cmd->msg_len > 8)
+		return -EINVAL;
+
+	/* enable FIFO precharge	*/
+	reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+	STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 1);
+	stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+	for (i = 0; i < cmd->msg_len; i++) {
+		/* wait for FIFO empty	*/
+		if (stb0899_wait_diseqc_fifo_empty(state, 10) < 0)
+			return -ETIMEDOUT;
+
+		stb0899_write_reg(state, STB0899_DISFIFO, cmd->msg[i]);
+	}
+	reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+	STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0);
+	stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+
+	return 0;
+}
+
+static int stb0899_wait_diseqc_rxidle(struct stb0899_state *state, int timeout)
+{
+	u8 reg = 0;
+	unsigned long start = jiffies;
+
+	while (!STB0899_GETFIELD(RXEND, reg)) {
+		reg = stb0899_read_reg(state, STB0899_DISRX_ST0);
+		if (jiffies - start > timeout) {
+			dprintk(verbose, FE_ERROR, 1, "timed out!!");
+			return -ETIMEDOUT;
+		}
+		msleep(10);
+	}
+
+	return 0;
+}
+
+static int stb0899_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply)
+{
+	struct stb0899_state *state = fe->demodulator_priv;
+	u8 reg, length = 0, i;
+	int result;
+
+	if (stb0899_wait_diseqc_rxidle(state, 100) < 0)
+		return -ETIMEDOUT;
+
+	reg = stb0899_read_reg(state, STB0899_DISRX_ST0);
+	if (STB0899_GETFIELD(RXEND, reg)) {
+
+		reg = stb0899_read_reg(state, STB0899_DISRX_ST1);
+		length = STB0899_GETFIELD(FIFOBYTENBR, reg);
+
+		if (length > sizeof (reply->msg)) {
+			result = -EOVERFLOW;
+			goto exit;
+		}
+		reply->msg_len = length;
+
+		/* extract data */
+		for (i = 0; i < length; i++)
+			reply->msg[i] = stb0899_read_reg(state, STB0899_DISFIFO);
+	}
+
+	return 0;
+exit:
+
+	return result;
+}
+
+static int stb0899_wait_diseqc_txidle(struct stb0899_state *state, int timeout)
+{
+	u8 reg = 0;
+	unsigned long start = jiffies;
+
+	while (!STB0899_GETFIELD(TXIDLE, reg)) {
+		reg = stb0899_read_reg(state, STB0899_DISSTATUS);
+		if (jiffies - start > timeout) {
+			dprintk(verbose, FE_ERROR, 1, "timed out!!");
+			return -ETIMEDOUT;
+		}
+		msleep(10);
+	}
+	return 0;
+}
+
+static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
+{
+	struct stb0899_state *state = fe->demodulator_priv;
+	u8 reg, old_state;
+
+	/* wait for diseqc idle	*/
+	if (stb0899_wait_diseqc_txidle(state, 100) < 0)
+		return -ETIMEDOUT;
+
+	reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+	old_state = reg;
+	/* set to burst mode	*/
+	STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x02);
+	STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x01);
+	stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+	switch (burst) {
+	case SEC_MINI_A:
+		/* unmodulated	*/
+		stb0899_write_reg(state, STB0899_DISFIFO, 0x00);
+		break;
+	case SEC_MINI_B:
+		/* modulated	*/
+		stb0899_write_reg(state, STB0899_DISFIFO, 0xff);
+		break;
+	}
+	reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+	STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x00);
+	stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+	/* wait for diseqc idle	*/
+	if (stb0899_wait_diseqc_txidle(state, 100) < 0)
+		return -ETIMEDOUT;
+
+	/* restore state	*/
+	stb0899_write_reg(state, STB0899_DISCNTRL1, old_state);
+
+	return 0;
+}
+
+
+static int stb0899_sleep(struct dvb_frontend *fe)
+{
+	struct stb0899_state *state = fe->demodulator_priv;
+	u8 reg;
+
+	dprintk(verbose, FE_DEBUG, 1, "Going to Sleep .. (Really tired .. :-))");
+
+	reg = stb0899_read_reg(state, STB0899_SYNTCTRL);
+	STB0899_SETFIELD_VAL(STANDBY, reg, 1);
+	stb0899_write_reg(state, STB0899_SYNTCTRL, reg);
+
+	return 0;
+}
+
+static int stb0899_wakeup(struct dvb_frontend *fe)
+{
+	int rc;
+	struct stb0899_state *state = fe->demodulator_priv;
+
+	if ((rc = stb0899_write_reg(state, STB0899_SYNTCTRL, STB0899_SELOSCI)))
+		return rc;
+	/* Activate all clocks; DVB-S2 registers are inaccessible otherwise. */
+	if ((rc = stb0899_write_reg(state, STB0899_STOPCLK1, 0x00)))
+		return rc;
+	if ((rc = stb0899_write_reg(state, STB0899_STOPCLK2, 0x00)))
+		return rc;
+
+	return 0;
+}
+
+static int stb0899_init(struct dvb_frontend *fe)
+{
+	int i;
+	struct stb0899_state *state = fe->demodulator_priv;
+	struct stb0899_config *config = state->config;
+
+	dprintk(verbose, FE_DEBUG, 1, "Initializing STB0899 ... ");
+//	mutex_init(&state->search_lock);
+
+	/* init device		*/
+	dprintk(verbose, FE_DEBUG, 1, "init device");
+	for (i = 0; config->init_dev[i].address != 0xffff; i++)
+		stb0899_write_reg(state, config->init_dev[i].address, config->init_dev[i].data);
+
+	dprintk(verbose, FE_DEBUG, 1, "init S2 demod");
+	/* init S2 demod	*/
+	for (i = 0; config->init_s2_demod[i].offset != 0xffff; i++)
+		stb0899_write_s2reg(state, STB0899_S2DEMOD,
+				    config->init_s2_demod[i].base_address,
+				    config->init_s2_demod[i].offset,
+				    config->init_s2_demod[i].data);
+
+	dprintk(verbose, FE_DEBUG, 1, "init S1 demod");
+	/* init S1 demod	*/
+	for (i = 0; config->init_s1_demod[i].address != 0xffff; i++)
+		stb0899_write_reg(state, config->init_s1_demod[i].address, config->init_s1_demod[i].data);
+
+	dprintk(verbose, FE_DEBUG, 1, "init S2 FEC");
+	/* init S2 fec		*/
+	for (i = 0; config->init_s2_fec[i].offset != 0xffff; i++)
+		stb0899_write_s2reg(state, STB0899_S2FEC,
+				    config->init_s2_fec[i].base_address,
+				    config->init_s2_fec[i].offset,
+				    config->init_s2_fec[i].data);
+
+	dprintk(verbose, FE_DEBUG, 1, "init TST");
+	/* init test		*/
+	for (i = 0; config->init_tst[i].address != 0xffff; i++)
+		stb0899_write_reg(state, config->init_tst[i].address, config->init_tst[i].data);
+
+	stb0899_init_calc(state);
+//	stb0899_diseqc_init(state);
+
+	return 0;
+}
+
+static int stb0899_table_lookup(const struct stb0899_tab *tab, int max, int val)
+{
+	int res = 0;
+	int min = 0, med;
+
+	if (val < tab[min].read)
+		res = tab[min].real;
+	else if (val >= tab[max].read)
+		res = tab[max].real;
+	else {
+		while ((max - min) > 1) {
+			med = (max + min) / 2;
+			if (val >= tab[min].read && val < tab[med].read)
+				max = med;
+			else
+				min = med;
+		}
+		res = ((val - tab[min].read) *
+		       (tab[max].real - tab[min].real) /
+		       (tab[max].read - tab[min].read)) +
+			tab[min].real;
+	}
+
+	return res;
+}
+
+static int stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+	struct stb0899_state *state		= fe->demodulator_priv;
+	struct stb0899_internal *internal	= &state->internal;
+
+	int val;
+	u32 reg;
+	switch (state->delsys) {
+	case DVBFE_DELSYS_DVBS:
+	case DVBFE_DELSYS_DSS:
+		if (internal->lock) {
+			reg  = stb0899_read_reg(state, STB0899_VSTATUS);
+			if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
+
+				reg = stb0899_read_reg(state, STB0899_AGCIQIN);
+				val = (s32)(s8)STB0899_GETFIELD(AGCIQVALUE, reg);
+
+				*strength = stb0899_table_lookup(stb0899_dvbsrf_tab, ARRAY_SIZE(stb0899_dvbsrf_tab) - 1, val);
+				*strength += 750;
+				dprintk(verbose, FE_DEBUG, 1, "AGCIQVALUE = 0x%02x, C = %d * 0.1 dBm",
+					val & 0xff, *strength);
+			}
+		}
+		break;
+	case DVBFE_DELSYS_DVBS2:
+		if (internal->lock) {
+			reg = STB0899_READ_S2REG(STB0899_DEMOD, IF_AGC_GAIN);
+			val = STB0899_GETFIELD(IF_AGC_GAIN, reg);
+
+			*strength = stb0899_table_lookup(stb0899_dvbs2rf_tab, ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1, val);
+			*strength += 750;
+			dprintk(verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm",
+				val & 0x3fff, *strength);
+		}
+		break;
+	default:
+		dprintk(verbose, FE_DEBUG, 1, "Unsupported delivery system");
+		break;
+	}
+
+	return 0;
+}
+
+static int stb0899_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	struct stb0899_state *state		= fe->demodulator_priv;
+	struct stb0899_internal *internal	= &state->internal;
+
+	unsigned int val, quant, quantn = -1, est, estn = -1;
+	u8 buf[2];
+	u32 reg;
+
+	reg  = stb0899_read_reg(state, STB0899_VSTATUS);
+	switch (state->delsys) {
+	case DVBFE_DELSYS_DVBS:
+	case DVBFE_DELSYS_DSS:
+		if (internal->lock) {
+			if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
+
+				stb0899_read_regs(state, STB0899_NIRM, buf, 2);
+				val = MAKEWORD16(buf[0], buf[1]);
+
+				*snr = stb0899_table_lookup(stb0899_cn_tab, ARRAY_SIZE(stb0899_cn_tab) - 1, val);
+				dprintk(verbose, FE_DEBUG, 1, "NIR = 0x%02x%02x = %u, C/N = %d * 0.1 dBm\n",
+					buf[0], buf[1], val, *snr);
+			}
+		}
+		break;
+	case DVBFE_DELSYS_DVBS2:
+		if (internal->lock) {
+			reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1);
+			quant = STB0899_GETFIELD(UWP_ESN0_QUANT, reg);
+			reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
+			est = STB0899_GETFIELD(ESN0_EST, reg);
+			if (est == 1)
+				val = 301; /* C/N = 30.1 dB */
+			else if (est == 2)
+				val = 270; /* C/N = 27.0 dB */
+			else {
+				/* quantn = 100 * log(quant^2) */
+				quantn = stb0899_table_lookup(stb0899_quant_tab, ARRAY_SIZE(stb0899_quant_tab) - 1, quant * 100);
+				/* estn = 100 * log(est) */
+				estn = stb0899_table_lookup(stb0899_est_tab, ARRAY_SIZE(stb0899_est_tab) - 1, est);
+				/* snr(dBm/10) = -10*(log(est)-log(quant^2)) => snr(dBm/10) = (100*log(quant^2)-100*log(est))/10 */
+				val = (quantn - estn) / 10;
+			}
+			*snr = val;
+			dprintk(verbose, FE_DEBUG, 1, "Es/N0 quant = %d (%d) estimate = %u (%d), C/N = %d * 0.1 dBm",
+				quant, quantn, est, estn, val);
+		}
+		break;
+	default:
+		dprintk(verbose, FE_DEBUG, 1, "Unsupported delivery system");
+		break;
+	}
+
+	return 0;
+}
+
+static int stb0899_read_status(struct dvb_frontend *fe, enum fe_status *status)
+{
+	struct stb0899_state *state		= fe->demodulator_priv;
+	struct stb0899_internal *internal	= &state->internal;
+	u8 reg;
+	*status = 0;
+
+	switch (state->delsys) {
+	case DVBFE_DELSYS_DVBS:
+	case DVBFE_DELSYS_DSS:
+		dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S/DSS");
+		if (internal->lock) {
+			reg  = stb0899_read_reg(state, STB0899_VSTATUS);
+			if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
+				dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_CARRIER | FE_HAS_LOCK");
+				*status |= FE_HAS_CARRIER | FE_HAS_LOCK;
+
+				reg = stb0899_read_reg(state, STB0899_PLPARM);
+				if (STB0899_GETFIELD(VITCURPUN, reg)) {
+					dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_VITERBI | FE_HAS_SYNC");
+					*status |= FE_HAS_VITERBI | FE_HAS_SYNC;
+				}
+			}
+		}
+		break;
+	case DVBFE_DELSYS_DVBS2:
+		dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S2");
+		if (internal->lock) {
+			reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2);
+			if (STB0899_GETFIELD(UWP_LOCK, reg) && STB0899_GETFIELD(CSM_LOCK, reg)) {
+				*status |= FE_HAS_CARRIER;
+				dprintk(state->verbose, FE_DEBUG, 1,
+					"UWP & CSM Lock ! ---> DVB-S2 FE_HAS_CARRIER");
+
+				reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1);
+				if (STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg)) {
+					*status |= FE_HAS_LOCK;
+					dprintk(state->verbose, FE_DEBUG, 1,
+						"Packet Delineator Locked ! -----> DVB-S2 FE_HAS_LOCK");
+
+				}
+				if (STB0899_GETFIELD(CONTINUOUS_STREAM, reg)) {
+					*status |= FE_HAS_VITERBI;
+					dprintk(state->verbose, FE_DEBUG, 1,
+						"Packet Delineator found VITERBI ! -----> DVB-S2 FE_HAS_VITERBI");
+				}
+				if (STB0899_GETFIELD(ACCEPTED_STREAM, reg)) {
+					*status |= FE_HAS_SYNC;
+					dprintk(state->verbose, FE_DEBUG, 1,
+						"Packet Delineator found SYNC ! -----> DVB-S2 FE_HAS_SYNC");
+				}
+			}
+		}
+		break;
+	default:
+		dprintk(verbose, FE_DEBUG, 1, "Unsupported delivery system");
+		break;
+	}
+	return 0;
+}
+
+/*
+ * stb0899_get_error
+ * viterbi error for DVB-S/DSS
+ * packet error for DVB-S2
+ * Bit Error Rate or Packet Error Rate * 10 ^ 7
+ */
+static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	struct stb0899_state *state		= fe->demodulator_priv;
+	struct stb0899_internal *internal	= &state->internal;
+
+	u8  lsb, msb;
+	u32 i;
+
+	*ber = 0;
+
+	switch (state->delsys) {
+	case DVBFE_DELSYS_DVBS:
+	case DVBFE_DELSYS_DSS:
+		if (internal->lock) {
+			/* average 5 BER values	*/
+			for (i = 0; i < 5; i++) {
+				msleep(100);
+				lsb = stb0899_read_reg(state, STB0899_ECNT1L);
+				msb = stb0899_read_reg(state, STB0899_ECNT1M);
+				*ber += MAKEWORD16(msb, lsb);
+			}
+			*ber /= 5;
+			/* Viterbi Check	*/
+			if (STB0899_GETFIELD(VSTATUS_PRFVIT, internal->v_status)) {
+				/* Error Rate		*/
+				*ber *= 9766;
+				/* ber = ber * 10 ^ 7	*/
+				*ber /= (-1 + (1 << (2 * STB0899_GETFIELD(NOE, internal->err_ctrl))));
+				*ber /= 8;
+			}
+		}
+		break;
+	case DVBFE_DELSYS_DVBS2:
+		if (internal->lock) {
+			/* Average 5 PER values	*/
+			for (i = 0; i < 5; i++) {
+				msleep(100);
+				lsb = stb0899_read_reg(state, STB0899_ECNT1L);
+				msb = stb0899_read_reg(state, STB0899_ECNT1M);
+				*ber += MAKEWORD16(msb, lsb);
+			}
+			/* ber = ber * 10 ^ 7	*/
+			*ber *= 10000000;
+			*ber /= (-1 + (1 << (4 + 2 * STB0899_GETFIELD(NOE, internal->err_ctrl))));
+		}
+		break;
+	default:
+		dprintk(verbose, FE_DEBUG, 1, "Unsupported delivery system");
+	}
+
+	return 0;
+}
+
+static int stb0899_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+	struct stb0899_state *state = fe->demodulator_priv;
+
+	switch (voltage) {
+	case SEC_VOLTAGE_13:
+		stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82);
+		stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02);
+		stb0899_write_reg(state, STB0899_GPIO02CFG, 0x00);
+		break;
+	case SEC_VOLTAGE_18:
+		stb0899_write_reg(state, STB0899_GPIO00CFG, 0x02);
+		stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02);
+		stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82);
+		break;
+	case SEC_VOLTAGE_OFF:
+		stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82);
+		stb0899_write_reg(state, STB0899_GPIO01CFG, 0x82);
+		stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+	struct stb0899_state *state = fe->demodulator_priv;
+	struct stb0899_internal *internal = &state->internal;
+
+	u8 div;
+
+	/* wait for diseqc idle	*/
+	if (stb0899_wait_diseqc_txidle(state, 100) < 0)
+		return -ETIMEDOUT;
+
+	switch (tone) {
+	case SEC_TONE_ON:
+		div = (internal->master_clk / 100) / 5632;
+		div = (div + 5) / 10;
+		stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x66);
+		stb0899_write_reg(state, STB0899_ACRPRESC, 0x31);
+		stb0899_write_reg(state, STB0899_ACRDIV1, div);
+		break;
+	case SEC_TONE_OFF:
+		stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x20);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+	int i2c_stat;
+	struct stb0899_state *state = fe->demodulator_priv;
+
+	i2c_stat = stb0899_read_reg(state, STB0899_I2CRPT);
+	if (i2c_stat < 0)
+		goto err;
+
+	if (enable) {
+		dprintk(state->verbose, FE_DEBUG, 1, "Enabling I2C Repeater ...");
+		i2c_stat |=  STB0899_I2CTON;
+		if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0)
+			goto err;
+	}
+	return 0;
+err:
+	dprintk(state->verbose, FE_ERROR, 1, "I2C Repeater enable failed");
+	return -EREMOTEIO;
+}
+
+
+static inline void CONVERT32(u32 x, char *str)
+{
+	*str++	= (x >> 24) & 0xff;
+	*str++	= (x >> 16) & 0xff;
+	*str++	= (x >>  8) & 0xff;
+	*str++	= (x >>  0) & 0xff;
+	*str	= '\0';
+}
+
+int stb0899_get_dev_id(struct stb0899_state *state)
+{
+	u8 chip_id, release;
+	u16 id;
+	u32 demod_ver = 0, fec_ver = 0;
+	char demod_str[4] = { 0 };
+	char fec_str[4] = { 0 };
+
+	id = stb0899_read_reg(state, STB0899_DEV_ID);
+	dprintk(state->verbose, FE_DEBUG, 1, "ID reg=[0x%02x]", id);
+	chip_id = STB0899_GETFIELD(CHIP_ID, id);
+	release = STB0899_GETFIELD(CHIP_REL, id);
+
+	dprintk(state->verbose, FE_ERROR, 1, "Device ID=[%d], Release=[%d]",
+		chip_id, release);
+
+	CONVERT32(STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CORE_ID), (char *)&demod_str);
+
+	demod_ver = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_VERSION_ID);
+	dprintk(state->verbose, FE_ERROR, 1, "Demodulator Core ID=[%s], Version=[%d]", (char *) &demod_str, demod_ver);
+	CONVERT32(STB0899_READ_S2REG(STB0899_S2FEC, FEC_CORE_ID_REG), (char *)&fec_str);
+	fec_ver = STB0899_READ_S2REG(STB0899_S2FEC, FEC_VER_ID_REG);
+	if (! (chip_id > 0)) {
+		dprintk(state->verbose, FE_ERROR, 1, "couldn't find a STB 0899");
+
+		return -ENODEV;
+	}
+	dprintk(state->verbose, FE_ERROR, 1, "FEC Core ID=[%s], Version=[%d]", (char*) &fec_str, fec_ver);
+
+	return 0;
+}
+
+static const struct dvbfe_info dvbs_info	= {
+	.name					= "STB0899 DVB-S",
+	.delivery				= DVBFE_DELSYS_DVBS,
+	.delsys					= {
+		.dvbs.modulation		= DVBFE_MOD_QPSK,
+		.dvbs.fec			= DVBFE_FEC_1_2	| DVBFE_FEC_2_3 |
+						  DVBFE_FEC_3_4	| DVBFE_FEC_5_6 |
+						  DVBFE_FEC_6_7
+	},
+
+	.frequency_min				= 950000,
+	.frequency_max				= 2150000,
+	.frequency_step				= 0,
+	.symbol_rate_min			= 1000000,
+	.symbol_rate_max			= 45000000,
+	.symbol_rate_tolerance			= 0
+};
+
+static const struct dvbfe_info dss_info		= {
+	.name					= "STB0899 DSS",
+	.delivery				= DVBFE_DELSYS_DSS,
+	.delsys					= {
+		.dss.modulation			= DVBFE_MOD_BPSK | DVBFE_MOD_QPSK,
+		.dss.fec			= DVBFE_FEC_1_2	 | DVBFE_FEC_2_3 |
+						  DVBFE_FEC_3_4	 | DVBFE_FEC_5_6 |
+						  DVBFE_FEC_6_7
+	},
+
+	.frequency_min				= 950000,
+	.frequency_max				= 2150000,
+	.frequency_step				= 0,
+	.symbol_rate_min			= 1000000,
+	.symbol_rate_max			= 45000000,
+	.symbol_rate_tolerance			= 0
+};
+
+static const struct dvbfe_info dvbs2_info	= {
+	.name					= "STB0899 DVB-S2",
+	.delivery				= DVBFE_DELSYS_DVBS2,
+	.delsys					= {
+		.dvbs2.modulation		= DVBFE_MOD_QPSK   | DVBFE_MOD_8PSK |
+						  DVBFE_MOD_16APSK | DVBFE_MOD_32APSK,
+
+		.dvbs2.fec			= DVBFE_FEC_1_4	| DVBFE_FEC_1_3 |
+						  DVBFE_FEC_2_5	| DVBFE_FEC_1_2 |
+						  DVBFE_FEC_3_5	| DVBFE_FEC_2_3 |
+						  DVBFE_FEC_3_4	| DVBFE_FEC_4_5 |
+						  DVBFE_FEC_5_6	| DVBFE_FEC_8_9 |
+						  DVBFE_FEC_9_10,
+	},
+
+	.frequency_min		= 950000,
+	.frequency_max		= 2150000,
+	.frequency_step		= 0,
+	.symbol_rate_min	= 1000000,
+	.symbol_rate_max	= 45000000,
+	.symbol_rate_tolerance	= 0
+};
+
+static int stb0899_get_info(struct dvb_frontend *fe, struct dvbfe_info *fe_info)
+{
+	struct stb0899_state *state = fe->demodulator_priv;
+
+	dprintk(verbose, FE_DEBUG, 1, "Get Info");
+
+	state->delsys = fe_info->delivery;
+	switch (state->delsys) {
+	case DVBFE_DELSYS_DVBS:
+		dprintk(verbose, FE_ERROR, 1, "Querying DVB-S info");
+		memcpy(fe_info, &dvbs_info, sizeof (struct dvbfe_info));
+		break;
+	case DVBFE_DELSYS_DSS:
+		dprintk(verbose, FE_ERROR, 1, "Querying DSS info");
+		memcpy(fe_info, &dss_info, sizeof (struct dvbfe_info));
+		break;
+	case DVBFE_DELSYS_DVBS2:
+		dprintk(verbose, FE_ERROR, 1, "Querying DVB-S2 info");
+		memcpy(fe_info, &dvbs2_info, sizeof (struct dvbfe_info));
+		break;
+	default:
+		dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system");
+		return -EINVAL;
+	}
+	dprintk(verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys);
+
+	return 0;
+}
+
+static int stb0899_get_delsys(struct dvb_frontend *fe, enum dvbfe_delsys *fe_delsys)
+{
+	*fe_delsys = DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DSS | DVBFE_DELSYS_DVBS2;
+
+	return 0;
+}
+
+void stb0899_set_delsys(struct stb0899_state *state)
+{
+	u8 reg;
+	u8 stop_clk[2];
+
+	stop_clk[0] = stb0899_read_reg(state, STB0899_STOPCLK1);
+	stop_clk[1] = stb0899_read_reg(state, STB0899_STOPCLK2);
+
+	switch (state->delsys) {
+	case DVBFE_DELSYS_DVBS:
+		dprintk(verbose, FE_DEBUG, 1, "Delivery System -- DVB-S");
+		/* FECM/Viterbi ON	*/
+		reg = stb0899_read_reg(state, STB0899_FECM);
+		STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0);
+		STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1);
+		stb0899_write_reg(state, STB0899_FECM, reg);
+
+		stb0899_write_reg(state, STB0899_RSULC, 0xb1);
+		stb0899_write_reg(state, STB0899_TSULC, 0x40);
+		stb0899_write_reg(state, STB0899_RSLLC, 0x42);
+		stb0899_write_reg(state, STB0899_TSLPL, 0x12);
+
+		reg = stb0899_read_reg(state, STB0899_TSTRES);
+		STB0899_SETFIELD_VAL(FRESLDPC, reg, 1);
+		stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+		STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
+		STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1);
+		STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1);
+
+		STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1);
+		STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1);
+
+		STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 1);
+		STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 1);
+
+		STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1);
+		break;
+	case DVBFE_DELSYS_DVBS2:
+		/* FECM/Viterbi OFF	*/
+		reg = stb0899_read_reg(state, STB0899_FECM);
+		STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0);
+		STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 0);
+		stb0899_write_reg(state, STB0899_FECM, reg);
+
+		stb0899_write_reg(state, STB0899_RSULC, 0xb1);
+		stb0899_write_reg(state, STB0899_TSULC, 0x42);
+		stb0899_write_reg(state, STB0899_RSLLC, 0x40);
+		stb0899_write_reg(state, STB0899_TSLPL, 0x02);
+
+		reg = stb0899_read_reg(state, STB0899_TSTRES);
+		STB0899_SETFIELD_VAL(FRESLDPC, reg, 0);
+		stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+		STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
+		STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 0);
+		STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 0);
+
+		STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 0);
+		STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 0);
+
+		STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 0);
+		STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
+
+		STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 0);
+		break;
+	case DVBFE_DELSYS_DSS:
+		/* FECM/Viterbi ON	*/
+		reg = stb0899_read_reg(state, STB0899_FECM);
+		STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 1);
+		STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1);
+		stb0899_write_reg(state, STB0899_FECM, reg);
+
+		stb0899_write_reg(state, STB0899_RSULC, 0xa1);
+		stb0899_write_reg(state, STB0899_TSULC, 0x61);
+		stb0899_write_reg(state, STB0899_RSLLC, 0x42);
+
+		reg = stb0899_read_reg(state, STB0899_TSTRES);
+		STB0899_SETFIELD_VAL(FRESLDPC, reg, 1);
+		stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+		STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
+		STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1);
+		STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1);
+
+		STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1);
+		STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1);
+
+		STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
+
+		STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1);
+		break;
+	default:
+		dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system");
+		break;
+	}
+	STB0899_SETFIELD_VAL(STOP_CKADCI108, stop_clk[0], 0);
+	stb0899_write_regs(state, STB0899_STOPCLK1, stop_clk, 2);
+}
+
+/*
+ * stb0899_set_iterations
+ * set the LDPC iteration scale function
+ */
+static void stb0899_set_iterations(struct stb0899_state *state)
+{
+	struct stb0899_internal *internal = &state->internal;
+	struct stb0899_config *config = state->config;
+
+	s32 iter_scale;
+	u32 reg;
+
+	iter_scale = 17 * (internal->master_clk / 1000);
+	iter_scale += 410000;
+	iter_scale /= (internal->srate / 1000000);
+	iter_scale /= 1000;
+
+	if (iter_scale > config->ldpc_max_iter)
+		iter_scale = config->ldpc_max_iter;
+
+	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, MAX_ITER);
+	STB0899_SETFIELD_VAL(MAX_ITERATIONS, reg, iter_scale);
+	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_MAX_ITER, STB0899_OFF0_MAX_ITER, reg);
+}
+
+static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvbfe_params *params)
+{
+	struct stb0899_state *state = fe->demodulator_priv;
+	struct stb0899_params *i_params = &state->params;
+	struct stb0899_internal *internal = &state->internal;
+
+	u32 SearchRange, gain;
+
+	switch (state->delsys) {
+	case DVBFE_DELSYS_DVBS:
+		dprintk(verbose, FE_ERROR, 1, "set DVB-S params");
+		i_params->freq	= params->frequency;
+		i_params->srate	= params->delsys.dvbs.symbol_rate;
+		break;
+	case DVBFE_DELSYS_DSS:
+		dprintk(verbose, FE_ERROR, 1, "set DSS params");
+		i_params->freq	= params->frequency;
+		i_params->srate	= params->delsys.dss.symbol_rate;
+		break;
+	case DVBFE_DELSYS_DVBS2:
+		dprintk(verbose, FE_ERROR, 1, "set DVB-S2 params");
+		i_params->freq	= params->frequency;
+		i_params->srate	= params->delsys.dvbs2.symbol_rate;
+		break;
+	default:
+		dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system");
+		return -EINVAL;
+	}
+	dprintk(verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys);
+
+//	SearchRange = 3000000; /* Search Bandwidth (3 Mhz, was initially 10  Mhz)	*/
+	SearchRange = 10000000; /* Search Bandwidth (3 Mhz, was initially 10  Mhz)	*/
+	dprintk(verbose, FE_DEBUG, 1, "Frequency=%d, Srate=%d", i_params->freq, i_params->srate);
+	/* checking Search Range is meaningless for a fixed 3 Mhz			*/
+	if (INRANGE(i_params->srate, 1000000, 45000000)) {
+		dprintk(verbose, FE_DEBUG, 1, "Parameters IN RANGE");
+		stb0899_set_delsys(state);
+
+		if (state->config->tuner_set_rfsiggain) {
+			if (internal->srate > 15000000)
+				gain =  8;	/* 15Mb < srate < 45Mb, gain = 8dB	*/
+			else if (internal->srate > 5000000)
+				gain = 12;	/*  5Mb < srate < 15Mb, gain = 12dB	*/
+			else
+				gain = 14;	/*  1Mb < srate <  5Mb, gain = 14db	*/
+			state->config->tuner_set_rfsiggain(fe, gain);
+		}
+
+		if (i_params->srate <= 5000000)
+			stb0899_set_mclk(state, 76500000);
+		else
+			stb0899_set_mclk(state, 99000000);
+
+		switch (state->delsys) {
+		case DVBFE_DELSYS_DVBS:
+		case DVBFE_DELSYS_DSS:
+			dprintk(verbose, FE_DEBUG, 1, "DVB-S delivery system");
+			internal->freq	= i_params->freq;
+			internal->srate	= i_params->srate;
+			/*
+			 * search = user search range +
+			 *	    500Khz +
+			 *	    2 * Tuner_step_size +
+			 *	    10% of the symbol rate
+			 */
+			internal->srch_range	= SearchRange + 1500000 + (i_params->srate / 5);
+			internal->derot_percent	= 30;
+
+			/* What to do for tuners having no bandwidth setup ?	*/
+			if (state->config->tuner_set_bandwidth)
+				state->config->tuner_set_bandwidth(fe, (13 * (stb0899_carr_width(state) + 10000000)) / 10);
+			if (state->config->tuner_get_bandwidth)
+				state->config->tuner_get_bandwidth(fe, &internal->tuner_bw);
+			/* Set DVB-S1 AGC		*/
+			stb0899_write_reg(state, STB0899_AGCRFCFG, 0x11);
+
+			/* Run the search algorithm	*/
+			dprintk(verbose, FE_DEBUG, 1, "running DVB-S search algo ..");
+			if (stb0899_dvbs_algo(state)	== RANGEOK) {
+				internal->lock		= 1;
+				dprintk(verbose, FE_DEBUG, 1,
+					"-------------------------------------> DVB-S LOCK !");
+
+//				stb0899_write_reg(state, STB0899_ERRCTRL1, 0x3d); /* Viterbi Errors	*/
+//				internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS);
+//				internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1);
+//				dprintk(verbose, FE_DEBUG, 1, "VSTATUS=0x%02x", internal->v_status);
+//				dprintk(verbose, FE_DEBUG, 1, "ERR_CTRL=0x%02x", internal->err_ctrl);
+
+				return DVBFE_ALGO_SEARCH_SUCCESS;
+			} else {
+				internal->lock		= 0;
+
+				return DVBFE_ALGO_SEARCH_FAILED;
+			}
+			break;
+		case DVBFE_DELSYS_DVBS2:
+			internal->freq			= i_params->freq;
+			internal->srate			= i_params->srate;
+			internal->srch_range		= SearchRange;
+
+			if (state->config->tuner_set_bandwidth)
+				state->config->tuner_set_bandwidth(fe, (stb0899_carr_width(state) + 10000000));
+			if (state->config->tuner_get_bandwidth)
+				state->config->tuner_get_bandwidth(fe, &internal->tuner_bw);
+
+//			pParams->SpectralInv		= pSearch->IQ_Inversion;
+
+			/* Set DVB-S2 AGC		*/
+			stb0899_write_reg(state, STB0899_AGCRFCFG, 0x1c);
+
+			/* Set IterScale =f(MCLK,SYMB)	*/
+			stb0899_set_iterations(state);
+
+			/* Run the search algorithm	*/
+			dprintk(verbose, FE_DEBUG, 1, "running DVB-S2 search algo ..");
+			if (stb0899_dvbs2_algo(state)	== DVBS2_FEC_LOCK) {
+				internal->lock		= 1;
+				dprintk(verbose, FE_DEBUG, 1,
+					"-------------------------------------> DVB-S2 LOCK !");
+
+//				stb0899_write_reg(state, STB0899_ERRCTRL1, 0xb6); /* Packet Errors	*/
+//				internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS);
+//				internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1);
+
+				return DVBFE_ALGO_SEARCH_SUCCESS;
+			} else {
+				internal->lock		= 0;
+
+				return DVBFE_ALGO_SEARCH_FAILED;
+			}
+			break;
+		default:
+			dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system");
+			return DVBFE_ALGO_SEARCH_INVALID;
+		}
+	}
+
+	return DVBFE_ALGO_SEARCH_ERROR;
+}
+
+static enum stb0899_status stb0899_track_carrier(struct stb0899_state *state)
+{
+	u8 reg;
+
+	reg = stb0899_read_reg(state, STB0899_DSTATUS);
+	dprintk(verbose, FE_DEBUG, 1, "--------------------> STB0899_DSTATUS=[0x%02x]", reg);
+	if (STB0899_GETFIELD(CARRIER_FOUND, reg)) {
+		dprintk(verbose, FE_DEBUG, 1, "-------------> CARRIEROK !");
+		return CARRIEROK;
+	} else {
+		dprintk(verbose, FE_DEBUG, 1, "-------------> NOCARRIER !");
+		return NOCARRIER;
+	}
+
+	return NOCARRIER;
+}
+
+static enum stb0899_status stb0899_get_ifagc(struct stb0899_state *state)
+{
+	u8 reg;
+
+	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STATUS);
+	dprintk(verbose, FE_DEBUG, 1, "DMD_STATUS=[0x%02x]", reg);
+	if (STB0899_GETFIELD(IF_AGC_LOCK, reg)) {
+		dprintk(verbose, FE_DEBUG, 1, "------------->IF AGC LOCKED !");
+		return AGC1OK;
+	} else {
+		dprintk(verbose, FE_DEBUG, 1, "------------->IF AGC LOCK LOST !");
+		return NOAGC1;
+	}
+
+	return NOAGC1;
+}
+
+static int stb0899_get_s1fec(struct stb0899_internal *internal, enum dvbfe_fec *fec)
+{
+	switch (internal->fecrate) {
+	case STB0899_FEC_1_2:
+		*fec = DVBFE_FEC_1_2;
+		break;
+	case STB0899_FEC_2_3:
+		*fec = DVBFE_FEC_2_3;
+		break;
+	case STB0899_FEC_3_4:
+		*fec = DVBFE_FEC_3_4;
+		break;
+	case STB0899_FEC_5_6:
+		*fec = DVBFE_FEC_5_6;
+		break;
+	case STB0899_FEC_6_7:
+		*fec = DVBFE_FEC_6_7;
+		break;
+	case STB0899_FEC_7_8:
+		*fec = DVBFE_FEC_7_8;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int stb0899_get_modcod(struct stb0899_internal *internal, struct dvbs2_params *params)
+{
+	switch (internal->modcod) {
+	case STB0899_DUMMY_PLF:
+		params->modulation	= DVBFE_MOD_NONE;
+		params->fec		= DVBFE_FEC_NONE;
+		break;
+	case STB0899_QPSK_14:
+		params->modulation	= DVBFE_MOD_QPSK;
+		params->fec		= DVBFE_FEC_1_4;
+		break;
+	case STB0899_QPSK_13:
+		params->modulation	= DVBFE_MOD_QPSK;
+		params->fec		= DVBFE_FEC_1_3;
+		break;
+	case STB0899_QPSK_25:
+		params->modulation	= DVBFE_MOD_QPSK;
+		params->fec		= DVBFE_FEC_2_5;
+		break;
+	case STB0899_QPSK_12:
+		params->modulation	= DVBFE_MOD_QPSK;
+		params->fec		= DVBFE_FEC_1_2;
+		break;
+	case STB0899_QPSK_35:
+		params->modulation	= DVBFE_MOD_QPSK;
+		params->fec		= DVBFE_FEC_3_5;
+		break;
+	case STB0899_QPSK_23:
+		params->modulation	= DVBFE_MOD_QPSK;
+		params->fec		= DVBFE_FEC_2_3;
+		break;
+	case STB0899_QPSK_34:
+		params->modulation	= DVBFE_MOD_QPSK;
+		params->fec		= DVBFE_FEC_3_4;
+		break;
+	case STB0899_QPSK_45:
+		params->modulation	= DVBFE_MOD_QPSK;
+		params->fec		= DVBFE_FEC_4_5;
+		break;
+	case STB0899_QPSK_56:
+		params->modulation	= DVBFE_MOD_QPSK;
+		params->fec		= DVBFE_FEC_5_6;
+		break;
+	case STB0899_QPSK_89:
+		params->modulation	= DVBFE_MOD_QPSK;
+		params->fec		= DVBFE_FEC_8_9;
+		break;
+	case STB0899_QPSK_910:
+		params->modulation	= DVBFE_MOD_QPSK;
+		params->fec		= DVBFE_FEC_9_10;
+		break;
+	case STB0899_8PSK_35:
+		params->modulation	= DVBFE_MOD_8PSK;
+		params->fec		= DVBFE_FEC_3_5;
+		break;
+	case STB0899_8PSK_23:
+		params->modulation	= DVBFE_MOD_8PSK;
+		params->fec		= DVBFE_FEC_2_3;
+		break;
+	case STB0899_8PSK_34:
+		params->modulation	= DVBFE_MOD_8PSK;
+		params->fec		= DVBFE_FEC_3_4;
+		break;
+	case STB0899_8PSK_56:
+		params->modulation	= DVBFE_MOD_8PSK;
+		params->fec		= DVBFE_FEC_5_6;
+		break;
+	case STB0899_8PSK_89:
+		params->modulation	= DVBFE_MOD_8PSK;
+		params->fec		= DVBFE_FEC_8_9;
+		break;
+	case STB0899_8PSK_910:
+		params->modulation	= DVBFE_MOD_8PSK;
+		params->fec		= DVBFE_FEC_9_10;
+		break;
+	case STB0899_16APSK_23:
+		params->modulation	= DVBFE_MOD_16APSK;
+		params->fec		= DVBFE_FEC_2_3;
+		break;
+	case STB0899_16APSK_34:
+		params->modulation	= DVBFE_MOD_16APSK;
+		params->fec		= DVBFE_FEC_3_4;
+		break;
+	case STB0899_16APSK_45:
+		params->modulation	= DVBFE_MOD_16APSK;
+		params->fec		= DVBFE_FEC_4_5;
+		break;
+	case STB0899_16APSK_56:
+		params->modulation	= DVBFE_MOD_16APSK;
+		params->fec		= DVBFE_FEC_5_6;
+		break;
+	case STB0899_16APSK_89:
+		params->modulation	= DVBFE_MOD_16APSK;
+		params->fec		= DVBFE_FEC_8_9;
+		break;
+	case STB0899_16APSK_910:
+		params->modulation	= DVBFE_MOD_16APSK;
+		params->fec		= DVBFE_FEC_9_10;
+		break;
+	case STB0899_32APSK_34:
+		params->modulation	= DVBFE_MOD_32APSK;
+		params->fec		= DVBFE_FEC_3_4;
+		break;
+	case STB0899_32APSK_45:
+		params->modulation	= DVBFE_MOD_32APSK;
+		params->fec		= DVBFE_FEC_4_5;
+		break;
+	case STB0899_32APSK_56:
+		params->modulation	= DVBFE_MOD_32APSK;
+		params->fec		= DVBFE_FEC_5_6;
+		break;
+	case STB0899_32APSK_89:
+		params->modulation	= DVBFE_MOD_32APSK;
+		params->fec		= DVBFE_FEC_8_9;
+		break;
+	case STB0899_32APSK_910:
+		params->modulation	= DVBFE_MOD_32APSK;
+		params->fec		= DVBFE_FEC_9_10;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+ * stb0899_track
+ * periodically check the signal level against a specified
+ * threshold level and perform derotator centering.
+ * called once we have a lock from a succesful search
+ * event.
+ *
+ * Will be called periodically called to maintain the
+ * lock.
+ *
+ * Will be used to get parameters as well as info from
+ * the decoded baseband header
+ *
+ * Once a new lock has established, the internal state
+ * frequency (internal->freq) is updated
+ */
+static int stb0899_track(struct dvb_frontend *fe, struct dvbfe_params *params)
+{
+	struct stb0899_state *state		= fe->demodulator_priv;
+	struct stb0899_internal *internal	= &state->internal;
+
+	switch (state->delsys) {
+	case DVBFE_DELSYS_DVBS:
+		dprintk(verbose, FE_DEBUG, 1, "Tracking DVB-S state");
+		if (stb0899_track_carrier(state) == CARRIEROK) {
+			params->frequency			= internal->freq;
+			params->inversion			= internal->inversion;
+			params->delivery			= state->delsys;
+			params->delsys.dvbs.symbol_rate		= internal->srate;
+			params->delsys.dvbs.modulation		= DVBFE_MOD_QPSK;
+			stb0899_get_s1fec(internal, &params->delsys.dvbs.fec);
+		}
+		break;
+	case DVBFE_DELSYS_DSS:
+		dprintk(verbose, FE_DEBUG, 1, "Tracking DSS state");
+		if (stb0899_track_carrier(state) == CARRIEROK) {
+			params->frequency			= internal->freq;
+			params->inversion			= internal->inversion;
+			params->delivery			= state->delsys;
+			params->delsys.dss.symbol_rate		= internal->srate;
+			params->delsys.dss.modulation		= DVBFE_MOD_QPSK;
+			stb0899_get_s1fec(internal, &params->delsys.dss.fec);
+		}
+		break;
+	case DVBFE_DELSYS_DVBS2:
+		dprintk(verbose, FE_DEBUG, 1, "Tracking DVB-S2 state");
+		if (stb0899_get_ifagc(state) == AGC1OK) {
+			params->frequency			= internal->freq;
+			params->inversion			= internal->inversion;
+			params->delivery			= state->delsys;
+			params->delsys.dvbs2.symbol_rate	= internal->srate;
+			stb0899_get_modcod(internal, &params->delsys.dvbs2);
+			params->delsys.dvbs2.rolloff		= internal->rolloff;
+			params->delsys.dvbs2.matype_1		= stb0899_read_reg(state, STB0899_MATSTRL);
+			params->delsys.dvbs2.matype_2		= stb0899_read_reg(state, STB0899_MATSTRM);
+			params->delsys.dvbs2.upl_1		= stb0899_read_reg(state, STB0899_UPLSTRL);
+			params->delsys.dvbs2.upl_2		= stb0899_read_reg(state, STB0899_UPLSTRM);
+			params->delsys.dvbs2.dfl_1		= stb0899_read_reg(state, STB0899_DFLSTRL);
+			params->delsys.dvbs2.dfl_2		= stb0899_read_reg(state, STB0899_DFLSTRM);
+			params->delsys.dvbs2.sync		= stb0899_read_reg(state, STB0899_SYNCSTR);
+			params->delsys.dvbs2.syncd_1		= stb0899_read_reg(state, STB0899_SYNCDSTRL);
+			params->delsys.dvbs2.syncd_2		= stb0899_read_reg(state, STB0899_SYNCDSTRM);
+		}
+		break;
+	default:
+		dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int stb0899_get_params(struct dvb_frontend *fe, struct dvbfe_params *params)
+{
+	struct stb0899_state *state		= fe->demodulator_priv;
+	struct stb0899_internal *internal	= &state->internal;
+
+	params->frequency			= internal->freq;
+	params->inversion			= internal->inversion;
+	params->delivery			= state->delsys;
+	switch (state->delsys) {
+	case DVBFE_DELSYS_DVBS:
+		dprintk(verbose, FE_DEBUG, 1, "Get DVB-S params");
+		params->delsys.dvbs.symbol_rate		= internal->srate;
+		params->delsys.dvbs.modulation		= DVBFE_MOD_QPSK;
+		break;
+	case DVBFE_DELSYS_DSS:
+		dprintk(verbose, FE_DEBUG, 1, "Get DSS params");
+		params->delsys.dss.symbol_rate		= internal->srate;
+		params->delsys.dss.modulation		= DVBFE_MOD_QPSK;
+
+		break;
+	case DVBFE_DELSYS_DVBS2:
+		dprintk(verbose, FE_DEBUG, 1, "Get DVB-S2 params");
+		params->delsys.dvbs2.symbol_rate	= internal->srate;
+		break;
+	default:
+		dprintk(verbose, FE_ERROR, 1, "Unsupported delivery system");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe)
+{
+	return DVBFE_ALGO_CUSTOM;
+}
+
+static struct dvb_frontend_ops stb0899_ops = {
+
+	.info = {
+		.name			= "STB0899 Multistandard",
+	},
+
+	.release			= stb0899_release,
+	.init				= stb0899_init,
+	.sleep				= stb0899_sleep,
+//	.wakeup				= stb0899_wakeup,
+
+	.i2c_gate_ctrl			= stb0899_i2c_gate_ctrl,
+	.get_info			= stb0899_get_info,
+	.get_delsys			= stb0899_get_delsys,
+
+	.get_frontend_algo		= stb0899_frontend_algo,
+	.search				= stb0899_search,
+	.track				= stb0899_track,
+	.get_params			= stb0899_get_params,
+
+	.read_status			= stb0899_read_status,
+	.read_snr			= stb0899_read_snr,
+	.read_signal_strength		= stb0899_read_signal_strength,
+	.read_status			= stb0899_read_status,
+	.read_ber			= stb0899_read_ber,
+
+	.set_voltage			= stb0899_set_voltage,
+	.set_tone			= stb0899_set_tone,
+
+	.diseqc_send_master_cmd		= stb0899_send_diseqc_msg,
+	.diseqc_recv_slave_reply	= stb0899_recv_slave_reply,
+	.diseqc_send_burst		= stb0899_send_diseqc_burst,
+};
+
+struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c)
+{
+	struct stb0899_state *state = NULL;
+
+	state = kzalloc(sizeof (struct stb0899_state), GFP_KERNEL);
+	if (state == NULL)
+		goto error;
+
+	state->verbose				= verbose;
+	state->config				= config;
+	state->i2c				= i2c;
+	state->frontend.ops			= stb0899_ops;
+	state->frontend.demodulator_priv	= state;
+
+	stb0899_wakeup(&state->frontend);
+	if (stb0899_get_dev_id(state) == -ENODEV) {
+		printk("%s: Exiting .. !\n", __func__);
+		goto error;
+	}
+
+	printk("%s: Attaching STB0899 \n", __func__);
+	return &state->frontend;
+
+error:
+	kfree(state);
+	return NULL;
+}
+EXPORT_SYMBOL(stb0899_attach);
+MODULE_PARM_DESC(verbose, "Set Verbosity level");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_DESCRIPTION("STB0899 Multi-Std frontend");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stb0899_drv.h b/drivers/media/dvb/frontends/stb0899_drv.h
new file mode 100644
index 0000000..52c2ce1
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_drv.h
@@ -0,0 +1,94 @@
+/*
+	STB0899 Multistandard Frontend driver
+	Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+	Copyright (C) ST Microelectronics
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; either version 2 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the Free Software
+	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STB0899_DRV_H
+#define __STB0899_DRV_H
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "dvb_frontend.h"
+
+#define STB0899_TSMODE_SERIAL		1
+#define STB0899_CLKPOL_FALLING		2
+#define STB0899_CLKNULL_PARITY		3
+#define STB0899_SYNC_FORCED		4
+#define STB0899_FECMODE_DSS		5
+
+struct stb0899_s1_reg {
+	u16	address;
+	u8	data;
+};
+
+struct stb0899_s2_reg {
+	u16	offset;
+	u32	base_address;
+	u32	data;
+};
+
+struct stb0899_config {
+	const struct stb0899_s1_reg	*init_dev;
+	const struct stb0899_s2_reg	*init_s2_demod;
+	const struct stb0899_s1_reg	*init_s1_demod;
+	const struct stb0899_s2_reg	*init_s2_fec;
+	const struct stb0899_s1_reg	*init_tst;
+
+	u32	xtal_freq;
+
+	u8	demod_address;
+	u8	ts_output_mode;
+	u8	block_sync_mode;
+	u8	ts_pfbit_toggle;
+
+	u8	clock_polarity;
+	u8	data_clk_parity;
+	u8	fec_mode;
+	u8	data_output_ctl;
+	u8	data_fifo_mode;
+	u8	out_rate_comp;
+	u8	i2c_repeater;
+	int	inversion;
+
+	u32	esno_ave;
+	u32	esno_quant;
+	u32	avframes_coarse;
+	u32	avframes_fine;
+	u32	miss_threshold;
+	u32	uwp_threshold_acq;
+	u32	uwp_threshold_track;
+	u32	uwp_threshold_sof;
+	u32	sof_search_timeout;
+
+	u32	btr_nco_bits;
+	u32	btr_gain_shift_offset;
+	u32	crl_nco_bits;
+	u32	ldpc_max_iter;
+
+	int (*tuner_set_frequency)(struct dvb_frontend *fe, u32 frequency);
+	int (*tuner_get_frequency)(struct dvb_frontend *fe, u32 *frequency);
+	int (*tuner_set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
+	int (*tuner_get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
+	int (*tuner_set_rfsiggain)(struct dvb_frontend *fe, u32 rf_gain);
+};
+
+extern struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c);
+
+#endif
diff --git a/drivers/media/dvb/frontends/stb0899_priv.h b/drivers/media/dvb/frontends/stb0899_priv.h
new file mode 100644
index 0000000..47e533d
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_priv.h
@@ -0,0 +1,272 @@
+/*
+	STB0899 Multistandard Frontend driver
+	Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+	Copyright (C) ST Microelectronics
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; either version 2 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the Free Software
+	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STB0899_PRIV_H
+#define __STB0899_PRIV_H
+
+#include "dvb_frontend.h"
+#include "stb0899_drv.h"
+
+#define FE_ERROR				0
+#define FE_NOTICE				1
+#define FE_INFO					2
+#define FE_DEBUG				3
+#define FE_DEBUGREG				4
+
+#define dprintk(x, y, z, format, arg...) do {						\
+	if (z) {									\
+		if	((x > FE_ERROR) && (x > y))					\
+			printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);		\
+		else if	((x > FE_NOTICE) && (x > y))					\
+			printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);	\
+		else if ((x > FE_INFO) && (x > y))					\
+			printk(KERN_INFO "%s: " format "\n", __func__ , ##arg);		\
+		else if ((x > FE_DEBUG) && (x > y))					\
+			printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);	\
+	} else {									\
+		if (x > y)								\
+			printk(format, ##arg);						\
+	}										\
+} while(0)
+
+#define INRANGE(val, x, y)			(((x <= val) && (val <= y)) ||		\
+						 ((y <= val) && (val <= x)) ? 1 : 0)
+
+#define BYTE0					0
+#define BYTE1					8
+#define BYTE2					16
+#define BYTE3					24
+
+#define GETBYTE(x, y)				(((x) >> (y)) & 0xff)
+#define MAKEWORD32(a, b, c, d)			(((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
+#define MAKEWORD16(a, b)			(((a) << 8) | (b))
+
+#define MIN(x, y)				((x) <= (y) ? (x) : (y))
+#define MAX(x, y)				((x) >= (y) ? (x) : (y))
+#define ABS(x)					((x) >= 0 ? (x) : -(x))
+
+#define LSB(x)					((x & 0xff))
+#define MSB(y)					((y >> 8) & 0xff)
+
+
+#define STB0899_GETFIELD(bitf, val)		((val >> STB0899_OFFST_##bitf) & ((1 << STB0899_WIDTH_##bitf) - 1))
+
+
+#define STB0899_SETFIELD(mask, val, width, offset)      (mask & (~(((1 << width) - 1) <<	\
+							 offset))) | ((val &			\
+							 ((1 << width) - 1)) << offset)
+
+#define STB0899_SETFIELD_VAL(bitf, mask, val)	(mask = (mask & (~(((1 << STB0899_WIDTH_##bitf) - 1) <<\
+							 STB0899_OFFST_##bitf))) | \
+							 (val << STB0899_OFFST_##bitf))
+
+
+enum stb0899_status {
+	NOAGC1	= 0,
+	AGC1OK,
+	NOTIMING,
+	ANALOGCARRIER,
+	TIMINGOK,
+	NOAGC2,
+	AGC2OK,
+	NOCARRIER,
+	CARRIEROK,
+	NODATA,
+	FALSELOCK,
+	DATAOK,
+	OUTOFRANGE,
+	RANGEOK,
+	DVBS2_DEMOD_LOCK,
+	DVBS2_DEMOD_NOLOCK,
+	DVBS2_FEC_LOCK,
+	DVBS2_FEC_NOLOCK
+};
+
+enum stb0899_modcod {
+	STB0899_DUMMY_PLF,
+	STB0899_QPSK_14,
+	STB0899_QPSK_13,
+	STB0899_QPSK_25,
+	STB0899_QPSK_12,
+	STB0899_QPSK_35,
+	STB0899_QPSK_23,
+	STB0899_QPSK_34,
+	STB0899_QPSK_45,
+	STB0899_QPSK_56,
+	STB0899_QPSK_89,
+	STB0899_QPSK_910,
+	STB0899_8PSK_35,
+	STB0899_8PSK_23,
+	STB0899_8PSK_34,
+	STB0899_8PSK_56,
+	STB0899_8PSK_89,
+	STB0899_8PSK_910,
+	STB0899_16APSK_23,
+	STB0899_16APSK_34,
+	STB0899_16APSK_45,
+	STB0899_16APSK_56,
+	STB0899_16APSK_89,
+	STB0899_16APSK_910,
+	STB0899_32APSK_34,
+	STB0899_32APSK_45,
+	STB0899_32APSK_56,
+	STB0899_32APSK_89,
+	STB0899_32APSK_910
+};
+
+enum stb0899_frame {
+	STB0899_LONG_FRAME,
+	STB0899_SHORT_FRAME
+};
+
+enum stb0899_inversion {
+	IQ_SWAP_OFF	= 0,
+	IQ_SWAP_ON,
+	IQ_SWAP_AUTO
+};
+
+enum stb0899_alpha {
+	RRC_20,
+	RRC_25,
+	RRC_35
+};
+
+struct stb0899_tab {
+	s32 real;
+	s32 read;
+};
+
+enum stb0899_fec {
+	STB0899_FEC_1_2			= 13,
+	STB0899_FEC_2_3			= 18,
+	STB0899_FEC_3_4			= 21,
+	STB0899_FEC_5_6			= 24,
+	STB0899_FEC_6_7			= 25,
+	STB0899_FEC_7_8			= 26
+};
+
+struct stb0899_params {
+	u32	freq;					/* Frequency	*/
+	u32	srate;					/* Symbol rate	*/
+	enum dvbfe_fec fecrate;
+};
+
+struct stb0899_internal {
+	u32			master_clk;
+	u32			freq;			/* Demod internal Frequency		*/
+	u32			srate;			/* Demod internal Symbol rate		*/
+	enum stb0899_fec	fecrate;		/* Demod internal FEC rate		*/
+	u32			srch_range;		/* Demod internal Search Range		*/
+	u32			sub_range;		/* Demod current sub range (Hz)		*/
+	u32			tuner_step;		/* Tuner step (Hz)			*/
+	u32			tuner_offst;		/* Relative offset to carrier (Hz)	*/
+	u32			tuner_bw;		/* Current bandwidth of the tuner (Hz)	*/
+
+	s32			mclk;			/* Masterclock Divider factor (binary)	*/
+	s32			rolloff;		/* Current RollOff of the filter (x100)	*/
+
+	s16			derot_freq;		/* Current derotator frequency (Hz)	*/
+	s16			derot_percent;
+
+	s16			direction;		/* Current derotator search direction	*/
+	s16			derot_step;		/* Derotator step (binary value)	*/
+	s16			t_timing;		/* Timing loop time constant (ms)	*/
+	s16			t_derot;		/* Derotator time constant (ms)		*/
+	s16			t_data;			/* Data recovery time constant (ms)	*/
+	s16			sub_dir;		/* Direction of the next sub range	*/
+
+	s16			t_agc1;			/* Agc1 time constant (ms)		*/
+	s16			t_agc2;			/* Agc2 time constant (ms)		*/
+
+	u32			lock;			/* Demod internal lock state		*/
+	enum stb0899_status	status;			/* Demod internal status		*/
+
+	/* DVB-S2 */
+	s32			agc_gain;		/* RF AGC Gain				*/
+	s32			center_freq;		/* Nominal carrier frequency		*/
+	s32			av_frame_coarse;	/* Coarse carrier freq search frames	*/
+	s32			av_frame_fine;		/* Fine carrier freq search frames	*/
+
+	s16			step_size;		/* Carrier frequency search step size	*/
+
+	enum stb0899_alpha	rrc_alpha;
+	enum stb0899_inversion	inversion;
+	enum stb0899_modcod	modcod;
+	u8			pilots;			/* Pilots found				*/
+
+	enum stb0899_frame	frame_length;
+	u8			v_status;		/* VSTATUS				*/
+	u8			err_ctrl;		/* ERRCTRLn				*/
+};
+
+struct stb0899_state {
+	struct i2c_adapter		*i2c;
+	struct stb0899_config		*config;
+	struct dvb_frontend		frontend;
+
+	u32				verbose;	/* Cached module verbosity level	*/
+
+	struct stb0899_internal		internal;	/* Device internal parameters		*/
+
+	/*	cached params from API	*/
+	enum dvbfe_delsys		delsys;
+	struct stb0899_params		params;
+
+	u32				rx_freq;	/* DiSEqC 2.0 receiver freq		*/
+	struct mutex			search_lock;
+};
+/* stb0899.c		*/
+extern int stb0899_read_reg(struct stb0899_state *state,
+			    unsigned int reg);
+
+extern u32 _stb0899_read_s2reg(struct stb0899_state *state,
+			       u32 stb0899_i2cdev,
+			       u32 stb0899_base_addr,
+			       u16 stb0899_reg_offset);
+
+extern int stb0899_read_regs(struct stb0899_state *state,
+			     unsigned int reg, u8 *buf,
+			     size_t count);
+
+extern int stb0899_write_regs(struct stb0899_state *state,
+			      unsigned int reg, u8 *data,
+			      size_t count);
+
+extern int stb0899_write_reg(struct stb0899_state *state,
+			     unsigned int reg,
+			     u8 data);
+
+extern int stb0899_write_s2reg(struct stb0899_state *state,
+			       u32 stb0899_i2cdev,
+			       u32 stb0899_base_addr,
+			       u16 stb0899_reg_offset,
+			       u32 stb0899_data);
+
+
+#define STB0899_READ_S2REG(DEVICE, REG) 	(_stb0899_read_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG))
+//#define STB0899_WRITE_S2REG(DEVICE, REG, DATA)	(_stb0899_write_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG, DATA))
+
+/* stb0899_algo.c	*/
+extern enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state);
+extern enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state);
+extern long stb0899_carr_width(struct stb0899_state *state);
+
+#endif //__STB0899_PRIV_H
diff --git a/drivers/media/dvb/frontends/stb0899_reg.h b/drivers/media/dvb/frontends/stb0899_reg.h
new file mode 100644
index 0000000..6d2dc79
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_reg.h
@@ -0,0 +1,2018 @@
+/*
+	STB0899 Multistandard Frontend driver
+	Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+	Copyright (C) ST Microelectronics
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; either version 2 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the Free Software
+	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STB0899_REG_H
+#define __STB0899_REG_H
+
+/*	S1	*/
+#define STB0899_DEV_ID				0xf000
+#define STB0899_CHIP_ID				(0x0f << 4)
+#define STB0899_OFFST_CHIP_ID			4
+#define STB0899_WIDTH_CHIP_ID			4
+#define STB0899_CHIP_REL			(0x0f << 0)
+#define STB0899_OFFST_CHIP_REL			0
+#define STB0899_WIDTH_CHIP_REL			4
+
+#define STB0899_DEMOD				0xf40e
+#define STB0899_MODECOEFF			(0x01 << 0)
+#define STB0899_OFFST_MODECOEFF			0
+#define STB0899_WIDTH_MODECOEFF			1
+
+#define STB0899_RCOMPC				0xf410
+#define STB0899_AGC1CN				0xf412
+#define STB0899_AGC1REF				0xf413
+#define STB0899_RTC				0xf417
+#define STB0899_TMGCFG				0xf418
+#define STB0899_AGC2REF				0xf419
+#define STB0899_TLSR				0xf41a
+
+#define STB0899_CFD				0xf41b
+#define STB0899_CFD_ON				(0x01 << 7)
+#define STB0899_OFFST_CFD_ON			7
+#define STB0899_WIDTH_CFD_ON			1
+
+#define STB0899_ACLC				0xf41c
+
+#define STB0899_BCLC				0xf41d
+#define STB0899_OFFST_ALGO			6
+#define STB0899_WIDTH_ALGO_QPSK2		2
+#define STB0899_ALGO_QPSK2			(2 << 6)
+#define STB0899_ALGO_QPSK1			(1 << 6)
+#define STB0899_ALGO_BPSK			(0 << 6)
+#define STB0899_OFFST_BETA			0
+#define STB0899_WIDTH_BETA			6
+
+#define STB0899_EQON				0xf41e
+#define STB0899_LDT				0xf41f
+#define STB0899_LDT2				0xf420
+#define STB0899_EQUALREF			0xf425
+#define STB0899_TMGRAMP				0xf426
+#define STB0899_TMGTHD				0xf427
+#define STB0899_IDCCOMP				0xf428
+#define STB0899_QDCCOMP				0xf429
+#define STB0899_POWERI				0xf42a
+#define STB0899_POWERQ				0xf42b
+#define STB0899_RCOMP				0xf42c
+
+#define STB0899_AGCIQIN				0xf42e
+#define STB0899_AGCIQVALUE			(0xff << 0)
+#define STB0899_OFFST_AGCIQVALUE		0
+#define STB0899_WIDTH_AGCIQVALUE		8
+
+#define STB0899_AGC2I1				0xf436
+#define STB0899_AGC2I2				0xf437
+
+#define STB0899_TLIR				0xf438
+#define STB0899_TLIR_TMG_LOCK_IND		(0xff << 0)
+#define STB0899_OFFST_TLIR_TMG_LOCK_IND		0
+#define STB0899_WIDTH_TLIR_TMG_LOCK_IND		8
+
+#define STB0899_RTF				0xf439
+#define STB0899_RTF_TIMING_LOOP_FREQ		(0xff << 0)
+#define STB0899_OFFST_RTF_TIMING_LOOP_FREQ	0
+#define STB0899_WIDTH_RTF_TIMING_LOOP_FREQ	8
+
+#define STB0899_DSTATUS				0xf43a
+#define STB0899_CARRIER_FOUND			(0x01 << 7)
+#define STB0899_OFFST_CARRIER_FOUND		7
+#define STB0899_WIDTH_CARRIER_FOUND		1
+#define STB0899_TMG_LOCK			(0x01 << 6)
+#define STB0899_OFFST_TMG_LOCK			6
+#define STB0899_WIDTH_TMG_LOCK			1
+#define STB0899_DEMOD_LOCK			(0x01 << 5)
+#define STB0899_OFFST_DEMOD_LOCK		5
+#define STB0899_WIDTH_DEMOD_LOCK		1
+#define STB0899_TMG_AUTO			(0x01 << 4)
+#define STB0899_OFFST_TMG_AUTO			4
+#define STB0899_WIDTH_TMG_AUTO			1
+#define STB0899_END_MAIN			(0x01 << 3)
+#define STB0899_OFFST_END_MAIN			3
+#define STB0899_WIDTH_END_MAIN			1
+
+#define STB0899_LDI				0xf43b
+#define STB0899_OFFST_LDI			0
+#define STB0899_WIDTH_LDI			8
+
+#define STB0899_CFRM				0xf43e
+#define STB0899_OFFST_CFRM			0
+#define STB0899_WIDTH_CFRM			8
+
+#define STB0899_CFRL				0xf43f
+#define STB0899_OFFST_CFRL			0
+#define STB0899_WIDTH_CFRL			8
+
+#define STB0899_NIRM				0xf440
+#define STB0899_OFFST_NIRM			0
+#define STB0899_WIDTH_NIRM			8
+
+#define STB0899_NIRL				0xf441
+#define STB0899_OFFST_NIRL			0
+#define STB0899_WIDTH_NIRL			8
+
+#define STB0899_ISYMB				0xf444
+#define STB0899_QSYMB				0xf445
+
+#define STB0899_SFRH				0xf446
+#define STB0899_OFFST_SFRH			0
+#define STB0899_WIDTH_SFRH			8
+
+#define STB0899_SFRM				0xf447
+#define STB0899_OFFST_SFRM			0
+#define STB0899_WIDTH_SFRM			8
+
+#define STB0899_SFRL				0xf448
+#define STB0899_OFFST_SFRL			4
+#define STB0899_WIDTH_SFRL			4
+
+#define STB0899_SFRUPH				0xf44c
+#define STB0899_SFRUPM				0xf44d
+#define STB0899_SFRUPL				0xf44e
+
+#define STB0899_EQUAI1				0xf4e0
+#define STB0899_EQUAQ1				0xf4e1
+#define STB0899_EQUAI2				0xf4e2
+#define STB0899_EQUAQ2				0xf4e3
+#define STB0899_EQUAI3				0xf4e4
+#define STB0899_EQUAQ3				0xf4e5
+#define STB0899_EQUAI4				0xf4e6
+#define STB0899_EQUAQ4				0xf4e7
+#define STB0899_EQUAI5				0xf4e8
+#define STB0899_EQUAQ5				0xf4e9
+
+#define STB0899_DSTATUS2			0xf50c
+#define STB0899_DS2_TMG_AUTOSRCH		(0x01 << 7)
+#define STB8999_OFFST_DS2_TMG_AUTOSRCH		7
+#define STB0899_WIDTH_DS2_TMG_AUTOSRCH		1
+#define STB0899_DS2_END_MAINLOOP		(0x01 << 6)
+#define STB0899_OFFST_DS2_END_MAINLOOP		6
+#define STB0899_WIDTH_DS2_END_MAINLOOP		1
+#define STB0899_DS2_CFSYNC			(0x01 << 5)
+#define STB0899_OFFST_DS2_CFSYNC		5
+#define STB0899_WIDTH_DS2_CFSYNC		1
+#define STB0899_DS2_TMGLOCK			(0x01 << 4)
+#define STB0899_OFFST_DS2_TMGLOCK		4
+#define STB0899_WIDTH_DS2_TMGLOCK		1
+#define STB0899_DS2_DEMODWAIT			(0x01 << 3)
+#define STB0899_OFFST_DS2_DEMODWAIT		3
+#define STB0899_WIDTH_DS2_DEMODWAIT		1
+#define STB0899_DS2_FECON			(0x01 << 1)
+#define STB0899_OFFST_DS2_FECON			1
+#define STB0899_WIDTH_DS2_FECON			1
+
+/*	S1 FEC	*/
+#define STB0899_VSTATUS				0xf50d
+#define STB0899_VSTATUS_VITERBI_ON		(0x01 << 7)
+#define STB0899_OFFST_VSTATUS_VITERBI_ON	7
+#define STB0899_WIDTH_VSTATUS_VITERBI_ON	1
+#define STB0899_VSTATUS_END_LOOPVIT		(0x01 << 6)
+#define STB0899_OFFST_VSTATUS_END_LOOPVIT	6
+#define STB0899_WIDTH_VSTATUS_END_LOOPVIT	1
+#define STB0899_VSTATUS_PRFVIT			(0x01 << 4)
+#define STB0899_OFFST_VSTATUS_PRFVIT		4
+#define STB0899_WIDTH_VSTATUS_PRFVIT		1
+#define STB0899_VSTATUS_LOCKEDVIT		(0x01 << 3)
+#define STB0899_OFFST_VSTATUS_LOCKEDVIT		3
+#define STB0899_WIDTH_VSTATUS_LOCKEDVIT		1
+
+#define STB0899_VERROR				0xf50f
+
+#define STB0899_IQSWAP				0xf523
+#define STB0899_SYM				(0x01 << 3)
+#define STB0899_OFFST_SYM			3
+#define STB0899_WIDTH_SYM			1
+
+#define STB0899_FECAUTO1			0xf530
+#define STB0899_DSSSRCH				(0x01 << 3)
+#define STB0899_OFFST_DSSSRCH			3
+#define STB0899_WIDTH_DSSSRCH			1
+#define STB0899_SYMSRCH				(0x01 << 2)
+#define STB0899_OFFST_SYMSRCH			2
+#define STB0899_WIDTH_SYMSRCH			1
+#define STB0899_QPSKSRCH			(0x01 << 1)
+#define STB0899_OFFST_QPSKSRCH			1
+#define STB0899_WIDTH_QPSKSRCH			1
+#define STB0899_BPSKSRCH			(0x01 << 0)
+#define STB0899_OFFST_BPSKSRCH			0
+#define STB0899_WIDTH_BPSKSRCH			1
+
+#define STB0899_FECM				0xf533
+#define STB0899_FECM_NOT_DVB			(0x01 << 7)
+#define STB0899_OFFST_FECM_NOT_DVB		7
+#define STB0899_WIDTH_FECM_NOT_DVB		1
+#define STB0899_FECM_RSVD1			(0x07 << 4)
+#define STB0899_OFFST_FECM_RSVD1		4
+#define STB0899_WIDTH_FECM_RSVD1		3
+#define STB0899_FECM_VITERBI_ON			(0x01 << 3)
+#define STB0899_OFFST_FECM_VITERBI_ON		3
+#define STB0899_WIDTH_FECM_VITERBI_ON		1
+#define STB0899_FECM_RSVD0			(0x01 << 2)
+#define STB0899_OFFST_FECM_RSVD0		2
+#define STB0899_WIDTH_FECM_RSVD0		1
+#define STB0899_FECM_SYNCDIS			(0x01 << 1)
+#define STB0899_OFFST_FECM_SYNCDIS		1
+#define STB0899_WIDTH_FECM_SYNCDIS		1
+#define STB0899_FECM_SYMI			(0x01 << 0)
+#define STB0899_OFFST_FECM_SYMI			1
+#define STB0899_WIDTH_FECM_SYMI			1
+
+#define STB0899_VTH12				0xf534
+#define STB0899_VTH23				0xf535
+#define STB0899_VTH34				0xf536
+#define STB0899_VTH56				0xf537
+#define STB0899_VTH67				0xf538
+#define STB0899_VTH78				0xf539
+
+#define STB0899_PRVIT				0xf53c
+#define STB0899_PR_7_8				(0x01 << 5)
+#define STB0899_OFFST_PR_7_8			5
+#define STB0899_WIDTH_PR_7_8			1
+#define STB0899_PR_6_7				(0x01 << 4)
+#define STB0899_OFFST_PR_6_7			4
+#define STB0899_WIDTH_PR_6_7			1
+#define STB0899_PR_5_6				(0x01 << 3)
+#define STB0899_OFFST_PR_5_6			3
+#define STB0899_WIDTH_PR_5_6			1
+#define STB0899_PR_3_4				(0x01 << 2)
+#define STB0899_OFFST_PR_3_4			2
+#define STB0899_WIDTH_PR_3_4			1
+#define STB0899_PR_2_3				(0x01 << 1)
+#define STB0899_OFFST_PR_2_3			1
+#define STB0899_WIDTH_PR_2_3			1
+#define STB0899_PR_1_2				(0x01 << 0)
+#define STB0899_OFFST_PR_1_2			0
+#define STB0899_WIDTH_PR_1_2			1
+
+#define STB0899_VITSYNC				0xf53d
+#define STB0899_AM				(0x01 << 7)
+#define STB0899_OFFST_AM			7
+#define STB0899_WIDTH_AM			1
+#define STB0899_FREEZE				(0x01 << 6)
+#define STB0899_OFFST_FREEZE			6
+#define STB0899_WIDTH_FREEZE			1
+#define STB0899_SN_65536			(0x03 << 4)
+#define STB0899_OFFST_SN_65536			4
+#define STB0899_WIDTH_SN_65536			2
+#define STB0899_SN_16384			(0x01 << 5)
+#define STB0899_OFFST_SN_16384			5
+#define STB0899_WIDTH_SN_16384			1
+#define STB0899_SN_4096				(0x01 << 4)
+#define STB0899_OFFST_SN_4096			4
+#define STB0899_WIDTH_SN_4096			1
+#define STB0899_SN_1024				(0x00 << 4)
+#define STB0899_OFFST_SN_1024			4
+#define STB0899_WIDTH_SN_1024			0
+#define STB0899_TO_128				(0x03 << 2)
+#define STB0899_OFFST_TO_128			2
+#define STB0899_WIDTH_TO_128			2
+#define STB0899_TO_64				(0x01 << 3)
+#define STB0899_OFFST_TO_64			3
+#define STB0899_WIDTH_TO_64			1
+#define STB0899_TO_32				(0x01 << 2)
+#define STB0899_OFFST_TO_32			2
+#define STB0899_WIDTH_TO_32			1
+#define STB0899_TO_16				(0x00 << 2)
+#define STB0899_OFFST_TO_16			2
+#define STB0899_WIDTH_TO_16			0
+#define STB0899_HYST_128			(0x03 << 1)
+#define STB0899_OFFST_HYST_128			1
+#define STB0899_WIDTH_HYST_128			2
+#define STB0899_HYST_64				(0x01 << 1)
+#define STB0899_OFFST_HYST_64			1
+#define STB0899_WIDTH_HYST_64			1
+#define STB0899_HYST_32				(0x01 << 0)
+#define STB0899_OFFST_HYST_32			0
+#define STB0899_WIDTH_HYST_32			1
+#define STB0899_HYST_16				(0x00 << 0)
+#define STB0899_OFFST_HYST_16			0
+#define STB0899_WIDTH_HYST_16			0
+
+#define STB0899_RSULC				0xf548
+#define STB0899_ULDIL_ON			(0x01 << 7)
+#define STB0899_OFFST_ULDIL_ON			7
+#define STB0899_WIDTH_ULDIL_ON			1
+#define STB0899_ULAUTO_ON			(0x01 << 6)
+#define STB0899_OFFST_ULAUTO_ON			6
+#define STB0899_WIDTH_ULAUTO_ON			1
+#define STB0899_ULRS_ON				(0x01 << 5)
+#define STB0899_OFFST_ULRS_ON			5
+#define STB0899_WIDTH_ULRS_ON			1
+#define STB0899_ULDESCRAM_ON			(0x01 << 4)
+#define STB0899_OFFST_ULDESCRAM_ON		4
+#define STB0899_WIDTH_ULDESCRAM_ON		1
+#define STB0899_UL_DISABLE			(0x01 << 2)
+#define STB0899_OFFST_UL_DISABLE		2
+#define STB0899_WIDTH_UL_DISABLE		1
+#define STB0899_NOFTHRESHOLD			(0x01 << 0)
+#define STB0899_OFFST_NOFTHRESHOLD		0
+#define STB0899_WIDTH_NOFTHRESHOLD		1
+
+#define STB0899_RSLLC				0xf54a
+#define STB0899_DEMAPVIT			0xf583
+#define STB0899_DEMAPVIT_RSVD			(0x01 << 7)
+#define STB0899_OFFST_DEMAPVIT_RSVD		7
+#define STB0899_WIDTH_DEMAPVIT_RSVD		1
+#define STB0899_DEMAPVIT_KDIVIDER		(0x7f << 0)
+#define STB0899_OFFST_DEMAPVIT_KDIVIDER		0
+#define STB0899_WIDTH_DEMAPVIT_KDIVIDER		7
+
+#define STB0899_PLPARM				0xf58c
+#define STB0899_VITMAPPING			(0x07 << 5)
+#define STB0899_OFFST_VITMAPPING		5
+#define STB0899_WIDTH_VITMAPPING		3
+#define STB0899_VITMAPPING_BPSK			(0x01 << 5)
+#define STB0899_OFFST_VITMAPPING_BPSK		5
+#define STB0899_WIDTH_VITMAPPING_BPSK		1
+#define STB0899_VITMAPPING_QPSK			(0x00 << 5)
+#define STB0899_OFFST_VITMAPPING_QPSK		5
+#define STB0899_WIDTH_VITMAPPING_QPSK		0
+#define STB0899_VITCURPUN			(0x1f << 0)
+#define STB0899_OFFST_VITCURPUN			0
+#define STB0899_WIDTH_VITCURPUN			5
+#define STB0899_VITCURPUN_1_2			(0x0d << 0)
+#define STB0899_VITCURPUN_2_3			(0x12 << 0)
+#define STB0899_VITCURPUN_3_4			(0x15 << 0)
+#define STB0899_VITCURPUN_5_6			(0x18 << 0)
+#define STB0899_VITCURPUN_6_7			(0x19 << 0)
+#define STB0899_VITCURPUN_7_8			(0x1a << 0)
+
+/*	S2 DEMOD	*/
+#define STB0899_OFF0_DMD_STATUS			0xf300
+#define STB0899_BASE_DMD_STATUS			0x00000000
+#define STB0899_IF_AGC_LOCK			(0x01 << 0)
+#define STB0899_OFFST_IF_AGC_LOCK		0
+#define STB0899_WIDTH_IF_AGC_LOCK		1
+
+#define STB0899_OFF0_CRL_FREQ			0xf304
+#define STB0899_BASE_CRL_FREQ			0x00000000
+#define STB0899_CARR_FREQ			(0x1fffffff << 0)
+#define STB0899_OFFST_CARR_FREQ			0
+#define STB0899_WIDTH_CARR_FREQ			30
+
+#define STB0899_OFF0_BTR_FREQ			0xf308
+#define STB0899_BASE_BTR_FREQ			0x00000000
+#define STB0899_BTR_FREQ			(0xfffffff << 0)
+#define STB0899_OFFST_BTR_FREQ			0
+#define STB0899_WIDTH_BTR_FREQ			28
+
+#define STB0899_OFF0_IF_AGC_GAIN		0xf30c
+#define STB0899_BASE_IF_AGC_GAIN		0x00000000
+#define STB0899_IF_AGC_GAIN			(0x3fff < 0)
+#define STB0899_OFFST_IF_AGC_GAIN		0
+#define STB0899_WIDTH_IF_AGC_GAIN		14
+
+#define STB0899_OFF0_BB_AGC_GAIN		0xf310
+#define STB0899_BASE_BB_AGC_GAIN		0x00000000
+#define STB0899_BB_AGC_GAIN			(0x3fff < 0)
+#define STB0899_OFFST_BB_AGC_GAIN		0
+#define STB0899_WIDTH_BB_AGC_GAIN		14
+
+#define STB0899_OFF0_DC_OFFSET			0xf314
+#define STB0899_BASE_DC_OFFSET			0x00000000
+#define STB0899_I				(0xff < 8)
+#define STB0899_OFFST_I				8
+#define STB0899_WIDTH_I				8
+#define STB0899_Q				(0xff < 0)
+#define STB0899_OFFST_Q				8
+#define STB0899_WIDTH_Q				8
+
+#define STB0899_OFF0_DMD_CNTRL			0xf31c
+#define STB0899_BASE_DMD_CNTRL			0x00000000
+#define STB0899_ADC0_PINS1IN			(0x01 << 6)
+#define STB0899_OFFST_ADC0_PINS1IN              6
+#define STB0899_WIDTH_ADC0_PINS1IN              1
+#define STB0899_IN2COMP1_OFFBIN0		(0x01 << 3)
+#define STB0899_OFFST_IN2COMP1_OFFBIN0          3
+#define STB0899_WIDTH_IN2COMP1_OFFBIN0          1
+#define STB0899_DC_COMP				(0x01 << 2)
+#define STB0899_OFFST_DC_COMP			2
+#define STB0899_WIDTH_DC_COMP			1
+#define STB0899_MODMODE				(0x03 << 0)
+#define STB0899_OFFST_MODMODE			0
+#define STB0899_WIDTH_MODMODE			2
+
+#define STB0899_OFF0_IF_AGC_CNTRL		0xf320
+#define STB0899_BASE_IF_AGC_CNTRL		0x00000000
+#define STB0899_IF_GAIN_INIT			(0x3fff << 13)
+#define STB0899_OFFST_IF_GAIN_INIT		13
+#define STB0899_WIDTH_IF_GAIN_INIT		14
+#define STB0899_IF_GAIN_SENSE			(0x01 << 12)
+#define STB0899_OFFST_IF_GAIN_SENSE		12
+#define STB0899_WIDTH_IF_GAIN_SENSE		1
+#define STB0899_IF_LOOP_GAIN			(0x0f << 8)
+#define STB0899_OFFST_IF_LOOP_GAIN		8
+#define STB0899_WIDTH_IF_LOOP_GAIN		4
+#define STB0899_IF_LD_GAIN_INIT			(0x01 << 7)
+#define STB0899_OFFST_IF_LD_GAIN_INIT		7
+#define STB0899_WIDTH_IF_LD_GAIN_INIT		1
+#define STB0899_IF_AGC_REF			(0x7f << 0)
+#define STB0899_OFFST_IF_AGC_REF		0
+#define STB0899_WIDTH_IF_AGC_REF		7
+
+#define STB0899_OFF0_BB_AGC_CNTRL		0xf324
+#define STB0899_BASE_BB_AGC_CNTRL		0x00000000
+#define STB0899_BB_GAIN_INIT			(0x3fff << 12)
+#define STB0899_OFFST_BB_GAIN_INIT		12
+#define STB0899_WIDTH_BB_GAIN_INIT		14
+#define STB0899_BB_LOOP_GAIN			(0x0f << 8)
+#define STB0899_OFFST_BB_LOOP_GAIN		8
+#define STB0899_WIDTH_BB_LOOP_GAIN		4
+#define STB0899_BB_LD_GAIN_INIT			(0x01 << 7)
+#define STB0899_OFFST_BB_LD_GAIN_INIT		7
+#define STB0899_WIDTH_BB_LD_GAIN_INIT		1
+#define STB0899_BB_AGC_REF			(0x7f << 0)
+#define STB0899_OFFST_BB_AGC_REF		0
+#define STB0899_WIDTH_BB_AGC_REF		7
+
+#define STB0899_OFF0_CRL_CNTRL			0xf328
+#define STB0899_BASE_CRL_CNTRL			0x00000000
+#define STB0899_CRL_LOCK_CLEAR			(0x01 << 5)
+#define STB0899_OFFST_CRL_LOCK_CLEAR		5
+#define STB0899_WIDTH_CRL_LOCK_CLEAR		1
+#define STB0899_CRL_SWPR_CLEAR			(0x01 << 4)
+#define STB0899_OFFST_CRL_SWPR_CLEAR		4
+#define STB0899_WIDTH_CRL_SWPR_CLEAR		1
+#define STB0899_CRL_SWP_ENA			(0x01 << 3)
+#define STB0899_OFFST_CRL_SWP_ENA		3
+#define STB0899_WIDTH_CRL_SWP_ENA		1
+#define STB0899_CRL_DET_SEL			(0x01 << 2)
+#define STB0899_OFFST_CRL_DET_SEL		2
+#define STB0899_WIDTH_CRL_DET_SEL		1
+#define STB0899_CRL_SENSE			(0x01 << 1)
+#define STB0899_OFFST_CRL_SENSE			1
+#define STB0899_WIDTH_CRL_SENSE			1
+#define STB0899_CRL_PHSERR_CLEAR		(0x01 << 0)
+#define STB0899_OFFST_CRL_PHSERR_CLEAR		0
+#define STB0899_WIDTH_CRL_PHSERR_CLEAR		1
+
+#define STB0899_OFF0_CRL_PHS_INIT		0xf32c
+#define STB0899_BASE_CRL_PHS_INIT		0x00000000
+#define STB0899_CRL_PHS_INIT_31			(0x1 << 30)
+#define STB0899_OFFST_CRL_PHS_INIT_31		30
+#define STB0899_WIDTH_CRL_PHS_INIT_31		1
+#define STB0899_CRL_LD_INIT_PHASE		(0x1 << 24)
+#define STB0899_OFFST_CRL_LD_INIT_PHASE		24
+#define STB0899_WIDTH_CRL_LD_INIT_PHASE		1
+#define STB0899_CRL_INIT_PHASE			(0xffffff << 0)
+#define STB0899_OFFST_CRL_INIT_PHASE		0
+#define STB0899_WIDTH_CRL_INIT_PHASE		24
+
+#define STB0899_OFF0_CRL_FREQ_INIT		0xf330
+#define STB0899_BASE_CRL_FREQ_INIT		0x00000000
+#define STB0899_CRL_FREQ_INIT_31		(0x1 << 30)
+#define STB0899_OFFST_CRL_FREQ_INIT_31		30
+#define STB0899_WIDTH_CRL_FREQ_INIT_31		1
+#define STB0899_CRL_LD_FREQ_INIT		(0x1 << 24)
+#define STB0899_OFFST_CRL_LD_FREQ_INIT		24
+#define STB0899_WIDTH_CRL_LD_FREQ_INIT		1
+#define STB0899_CRL_FREQ_INIT			(0xffffff << 0)
+#define STB0899_OFFST_CRL_FREQ_INIT		0
+#define STB0899_WIDTH_CRL_FREQ_INIT		24
+
+#define STB0899_OFF0_CRL_LOOP_GAIN		0xf334
+#define STB0899_BASE_CRL_LOOP_GAIN		0x00000000
+#define STB0899_KCRL2_RSHFT			(0xf << 16)
+#define STB0899_OFFST_KCRL2_RSHFT		16
+#define STB0899_WIDTH_KCRL2_RSHFT		4
+#define STB0899_KCRL1				(0xf << 12)
+#define STB0899_OFFST_KCRL1			12
+#define STB0899_WIDTH_KCRL1			4
+#define STB0899_KCRL1_RSHFT			(0xf << 8)
+#define STB0899_OFFST_KCRL1_RSHFT		8
+#define STB0899_WIDTH_KCRL1_RSHFT		4
+#define STB0899_KCRL0				(0xf << 4)
+#define STB0899_OFFST_KCRL0			4
+#define STB0899_WIDTH_KCRL0			4
+#define STB0899_KCRL0_RSHFT			(0xf << 0)
+#define STB0899_OFFST_KCRL0_RSHFT		0
+#define STB0899_WIDTH_KCRL0_RSHFT		4
+
+#define STB0899_OFF0_CRL_NOM_FREQ		0xf338
+#define STB0899_BASE_CRL_NOM_FREQ		0x00000000
+#define STB0899_CRL_NOM_FREQ			(0x3fffffff << 0)
+#define STB0899_OFFST_CRL_NOM_FREQ		0
+#define STB0899_WIDTH_CRL_NOM_FREQ		30
+
+#define STB0899_OFF0_CRL_SWP_RATE		0xf33c
+#define STB0899_BASE_CRL_SWP_RATE		0x00000000
+#define STB0899_CRL_SWP_RATE			(0x3fffffff << 0)
+#define STB0899_OFFST_CRL_SWP_RATE		0
+#define STB0899_WIDTH_CRL_SWP_RATE		30
+
+#define STB0899_OFF0_CRL_MAX_SWP		0xf340
+#define STB0899_BASE_CRL_MAX_SWP		0x00000000
+#define STB0899_CRL_MAX_SWP			(0x3fffffff << 0)
+#define STB0899_OFFST_CRL_MAX_SWP		0
+#define STB0899_WIDTH_CRL_MAX_SWP		30
+
+#define STB0899_OFF0_CRL_LK_CNTRL		0xf344
+#define STB0899_BASE_CRL_LK_CNTRL		0x00000000
+
+#define STB0899_OFF0_DECIM_CNTRL		0xf348
+#define STB0899_BASE_DECIM_CNTRL		0x00000000
+#define STB0899_BAND_LIMIT_B			(0x01 << 5)
+#define STB0899_OFFST_BAND_LIMIT_B		5
+#define STB0899_WIDTH_BAND_LIMIT_B		1
+#define STB0899_WIN_SEL				(0x03 << 3)
+#define STB0899_OFFST_WIN_SEL			3
+#define STB0899_WIDTH_WIN_SEL			2
+#define STB0899_DECIM_RATE			(0x07 << 0)
+#define STB0899_OFFST_DECIM_RATE		0
+#define STB0899_WIDTH_DECIM_RATE		3
+
+#define STB0899_OFF0_BTR_CNTRL			0xf34c
+#define STB0899_BASE_BTR_CNTRL			0x00000000
+#define STB0899_BTR_FREQ_CORR			(0x7ff << 4)
+#define STB0899_OFFST_BTR_FREQ_CORR		4
+#define STB0899_WIDTH_BTR_FREQ_CORR		11
+#define STB0899_BTR_CLR_LOCK			(0x01 << 3)
+#define STB0899_OFFST_BTR_CLR_LOCK		3
+#define STB0899_WIDTH_BTR_CLR_LOCK		1
+#define STB0899_BTR_SENSE			(0x01 << 2)
+#define STB0899_OFFST_BTR_SENSE			2
+#define STB0899_WIDTH_BTR_SENSE			1
+#define STB0899_BTR_ERR_ENA			(0x01 << 1)
+#define STB0899_OFFST_BTR_ERR_ENA		1
+#define STB0899_WIDTH_BTR_ERR_ENA		1
+#define STB0899_INTRP_PHS_SENSE			(0x01 << 0)
+#define STB0899_OFFST_INTRP_PHS_SENSE		0
+#define STB0899_WIDTH_INTRP_PHS_SENSE		1
+
+#define STB0899_OFF0_BTR_LOOP_GAIN		0xf350
+#define STB0899_BASE_BTR_LOOP_GAIN		0x00000000
+#define STB0899_KBTR2_RSHFT			(0x0f << 16)
+#define STB0899_OFFST_KBTR2_RSHFT		16
+#define STB0899_WIDTH_KBTR2_RSHFT		4
+#define STB0899_KBTR1				(0x0f << 12)
+#define STB0899_OFFST_KBTR1			12
+#define STB0899_WIDTH_KBTR1			4
+#define STB0899_KBTR1_RSHFT			(0x0f << 8)
+#define STB0899_OFFST_KBTR1_RSHFT		8
+#define STB0899_WIDTH_KBTR1_RSHFT		4
+#define STB0899_KBTR0				(0x0f << 4)
+#define STB0899_OFFST_KBTR0			4
+#define STB0899_WIDTH_KBTR0			4
+#define STB0899_KBTR0_RSHFT			(0x0f << 0)
+#define STB0899_OFFST_KBTR0_RSHFT		0
+#define STB0899_WIDTH_KBTR0_RSHFT		4
+
+#define STB0899_OFF0_BTR_PHS_INIT		0xf354
+#define STB0899_BASE_BTR_PHS_INIT		0x00000000
+#define STB0899_BTR_LD_PHASE_INIT		(0x01 << 28)
+#define STB0899_OFFST_BTR_LD_PHASE_INIT		28
+#define STB0899_WIDTH_BTR_LD_PHASE_INIT		1
+#define STB0899_BTR_INIT_PHASE			(0xfffffff << 0)
+#define STB0899_OFFST_BTR_INIT_PHASE		0
+#define STB0899_WIDTH_BTR_INIT_PHASE		28
+
+#define STB0899_OFF0_BTR_FREQ_INIT		0xf358
+#define STB0899_BASE_BTR_FREQ_INIT		0x00000000
+#define STB0899_BTR_LD_FREQ_INIT		(1 << 28)
+#define STB0899_OFFST_BTR_LD_FREQ_INIT		28
+#define STB0899_WIDTH_BTR_LD_FREQ_INIT		1
+#define STB0899_BTR_FREQ_INIT			(0xfffffff << 0)
+#define STB0899_OFFST_BTR_FREQ_INIT		0
+#define STB0899_WIDTH_BTR_FREQ_INIT		28
+
+#define STB0899_OFF0_BTR_NOM_FREQ		0xf35c
+#define STB0899_BASE_BTR_NOM_FREQ		0x00000000
+#define STB0899_BTR_NOM_FREQ			(0xfffffff << 0)
+#define STB0899_OFFST_BTR_NOM_FREQ		0
+#define STB0899_WIDTH_BTR_NOM_FREQ		28
+
+#define STB0899_OFF0_BTR_LK_CNTRL		0xf360
+#define STB0899_BASE_BTR_LK_CNTRL		0x00000000
+#define STB0899_BTR_MIN_ENERGY			(0x0f << 24)
+#define STB0899_OFFST_BTR_MIN_ENERGY		24
+#define STB0899_WIDTH_BTR_MIN_ENERGY		4
+#define STB0899_BTR_LOCK_TH_LO			(0xff << 16)
+#define STB0899_OFFST_BTR_LOCK_TH_LO		16
+#define STB0899_WIDTH_BTR_LOCK_TH_LO		8
+#define STB0899_BTR_LOCK_TH_HI			(0xff << 8)
+#define STB0899_OFFST_BTR_LOCK_TH_HI		8
+#define STB0899_WIDTH_BTR_LOCK_TH_HI		8
+#define STB0899_BTR_LOCK_GAIN			(0x03 << 6)
+#define STB0899_OFFST_BTR_LOCK_GAIN		6
+#define STB0899_WIDTH_BTR_LOCK_GAIN		2
+#define STB0899_BTR_LOCK_LEAK			(0x3f << 0)
+#define STB0899_OFFST_BTR_LOCK_LEAK		0
+#define STB0899_WIDTH_BTR_LOCK_LEAK		6
+
+#define STB0899_OFF0_DECN_CNTRL			0xf364
+#define STB0899_BASE_DECN_CNTRL			0x00000000
+
+#define STB0899_OFF0_TP_CNTRL			0xf368
+#define STB0899_BASE_TP_CNTRL			0x00000000
+
+#define STB0899_OFF0_TP_BUF_STATUS		0xf36c
+#define STB0899_BASE_TP_BUF_STATUS		0x00000000
+#define STB0899_TP_BUFFER_FULL                  (1 << 0)
+
+#define STB0899_OFF0_DC_ESTIM			0xf37c
+#define STB0899_BASE_DC_ESTIM			0x0000
+#define STB0899_I_DC_ESTIMATE			(0xff << 8)
+#define STB0899_OFFST_I_DC_ESTIMATE		8
+#define STB0899_WIDTH_I_DC_ESTIMATE		8
+#define STB0899_Q_DC_ESTIMATE			(0xff << 0)
+#define STB0899_OFFST_Q_DC_ESTIMATE		0
+#define STB0899_WIDTH_Q_DC_ESTIMATE		8
+
+#define STB0899_OFF0_FLL_CNTRL			0xf310
+#define STB0899_BASE_FLL_CNTRL			0x00000020
+#define STB0899_CRL_FLL_ACC			(0x01 << 4)
+#define STB0899_OFFST_CRL_FLL_ACC		4
+#define STB0899_WIDTH_CRL_FLL_ACC		1
+#define STB0899_FLL_AVG_PERIOD			(0x0f << 0)
+#define STB0899_OFFST_FLL_AVG_PERIOD		0
+#define STB0899_WIDTH_FLL_AVG_PERIOD		4
+
+#define STB0899_OFF0_FLL_FREQ_WD		0xf314
+#define STB0899_BASE_FLL_FREQ_WD		0x00000020
+#define STB0899_FLL_FREQ_WD			(0xffffffff << 0)
+#define STB0899_OFFST_FLL_FREQ_WD		0
+#define STB0899_WIDTH_FLL_FREQ_WD		32
+
+#define STB0899_OFF0_ANTI_ALIAS_SEL		0xf358
+#define STB0899_BASE_ANTI_ALIAS_SEL		0x00000020
+#define STB0899_ANTI_ALIAS_SELB			(0x03 << 0)
+#define STB0899_OFFST_ANTI_ALIAS_SELB		0
+#define STB0899_WIDTH_ANTI_ALIAS_SELB		2
+
+#define STB0899_OFF0_RRC_ALPHA			0xf35c
+#define STB0899_BASE_RRC_ALPHA			0x00000020
+#define STB0899_RRC_ALPHA			(0x03 << 0)
+#define STB0899_OFFST_RRC_ALPHA			0
+#define STB0899_WIDTH_RRC_ALPHA			2
+
+#define STB0899_OFF0_DC_ADAPT_LSHFT		0xf360
+#define STB0899_BASE_DC_ADAPT_LSHFT		0x00000020
+#define STB0899_DC_ADAPT_LSHFT			(0x077 << 0)
+#define STB0899_OFFST_DC_ADAPT_LSHFT		0
+#define STB0899_WIDTH_DC_ADAPT_LSHFT		3
+
+#define STB0899_OFF0_IMB_OFFSET			0xf364
+#define STB0899_BASE_IMB_OFFSET			0x00000020
+#define STB0899_PHS_IMB_COMP			(0xff << 8)
+#define STB0899_OFFST_PHS_IMB_COMP		8
+#define STB0899_WIDTH_PHS_IMB_COMP		8
+#define STB0899_AMPL_IMB_COMP			(0xff << 0)
+#define STB0899_OFFST_AMPL_IMB_COMP		0
+#define STB0899_WIDTH_AMPL_IMB_COMP		8
+
+#define STB0899_OFF0_IMB_ESTIMATE		0xf368
+#define STB0899_BASE_IMB_ESTIMATE		0x00000020
+#define STB0899_PHS_IMB_ESTIMATE		(0xff << 8)
+#define STB0899_OFFST_PHS_IMB_ESTIMATE		8
+#define STB0899_WIDTH_PHS_IMB_ESTIMATE		8
+#define STB0899_AMPL_IMB_ESTIMATE		(0xff << 0)
+#define STB0899_OFFST_AMPL_IMB_ESTIMATE		0
+#define STB0899_WIDTH_AMPL_IMB_ESTIMATE		8
+
+#define STB0899_OFF0_IMB_CNTRL			0xf36c
+#define STB0899_BASE_IMB_CNTRL			0x00000020
+#define STB0899_PHS_ADAPT_LSHFT			(0x07 << 4)
+#define STB0899_OFFST_PHS_ADAPT_LSHFT		4
+#define STB0899_WIDTH_PHS_ADAPT_LSHFT		3
+#define STB0899_AMPL_ADAPT_LSHFT		(0x07 << 1)
+#define STB0899_OFFST_AMPL_ADAPT_LSHFT		1
+#define STB0899_WIDTH_AMPL_ADAPT_LSHFT		3
+#define STB0899_IMB_COMP			(0x01 << 0)
+#define STB0899_OFFST_IMB_COMP			0
+#define STB0899_WIDTH_IMB_COMP			1
+
+#define STB0899_OFF0_IF_AGC_CNTRL2		0xf374
+#define STB0899_BASE_IF_AGC_CNTRL2		0x00000020
+#define STB0899_IF_AGC_LOCK_TH			(0xff << 11)
+#define STB0899_OFFST_IF_AGC_LOCK_TH		11
+#define STB0899_WIDTH_IF_AGC_LOCK_TH		8
+#define STB0899_IF_AGC_SD_DIV			(0xff << 3)
+#define STB0899_OFFST_IF_AGC_SD_DIV		3
+#define STB0899_WIDTH_IF_AGC_SD_DIV		8
+#define STB0899_IF_AGC_DUMP_PER			(0x07 << 0)
+#define STB0899_OFFST_IF_AGC_DUMP_PER		0
+#define STB0899_WIDTH_IF_AGC_DUMP_PER		3
+
+#define STB0899_OFF0_DMD_CNTRL2			0xf378
+#define STB0899_BASE_DMD_CNTRL2			0x00000020
+#define STB0899_SPECTRUM_INVERT			(0x01 << 2)
+#define STB0899_OFFST_SPECTRUM_INVERT		2
+#define STB0899_WIDTH_SPECTRUM_INVERT		1
+#define STB0899_AGC_MODE			(0x01 << 1)
+#define STB0899_OFFST_AGC_MODE			1
+#define STB0899_WIDTH_AGC_MODE			1
+#define STB0899_CRL_FREQ_ADJ			(0x01 << 0)
+#define STB0899_OFFST_CRL_FREQ_ADJ		0
+#define STB0899_WIDTH_CRL_FREQ_ADJ		1
+
+#define STB0899_OFF0_TP_BUFFER			0xf300
+#define STB0899_BASE_TP_BUFFER			0x00000040
+#define STB0899_TP_BUFFER_IN			(0xffff << 0)
+#define STB0899_OFFST_TP_BUFFER_IN		0
+#define STB0899_WIDTH_TP_BUFFER_IN		16
+
+#define STB0899_OFF0_TP_BUFFER1			0xf304
+#define STB0899_BASE_TP_BUFFER1			0x00000040
+#define STB0899_OFF0_TP_BUFFER2			0xf308
+#define STB0899_BASE_TP_BUFFER2			0x00000040
+#define STB0899_OFF0_TP_BUFFER3			0xf30c
+#define STB0899_BASE_TP_BUFFER3			0x00000040
+#define STB0899_OFF0_TP_BUFFER4			0xf310
+#define STB0899_BASE_TP_BUFFER4			0x00000040
+#define STB0899_OFF0_TP_BUFFER5			0xf314
+#define STB0899_BASE_TP_BUFFER5			0x00000040
+#define STB0899_OFF0_TP_BUFFER6			0xf318
+#define STB0899_BASE_TP_BUFFER6			0x00000040
+#define STB0899_OFF0_TP_BUFFER7			0xf31c
+#define STB0899_BASE_TP_BUFFER7			0x00000040
+#define STB0899_OFF0_TP_BUFFER8			0xf320
+#define STB0899_BASE_TP_BUFFER8			0x00000040
+#define STB0899_OFF0_TP_BUFFER9			0xf324
+#define STB0899_BASE_TP_BUFFER9			0x00000040
+#define STB0899_OFF0_TP_BUFFER10		0xf328
+#define STB0899_BASE_TP_BUFFER10		0x00000040
+#define STB0899_OFF0_TP_BUFFER11		0xf32c
+#define STB0899_BASE_TP_BUFFER11		0x00000040
+#define STB0899_OFF0_TP_BUFFER12		0xf330
+#define STB0899_BASE_TP_BUFFER12		0x00000040
+#define STB0899_OFF0_TP_BUFFER13		0xf334
+#define STB0899_BASE_TP_BUFFER13		0x00000040
+#define STB0899_OFF0_TP_BUFFER14		0xf338
+#define STB0899_BASE_TP_BUFFER14		0x00000040
+#define STB0899_OFF0_TP_BUFFER15		0xf33c
+#define STB0899_BASE_TP_BUFFER15		0x00000040
+#define STB0899_OFF0_TP_BUFFER16		0xf340
+#define STB0899_BASE_TP_BUFFER16		0x00000040
+#define STB0899_OFF0_TP_BUFFER17		0xf344
+#define STB0899_BASE_TP_BUFFER17		0x00000040
+#define STB0899_OFF0_TP_BUFFER18		0xf348
+#define STB0899_BASE_TP_BUFFER18		0x00000040
+#define STB0899_OFF0_TP_BUFFER19		0xf34c
+#define STB0899_BASE_TP_BUFFER19		0x00000040
+#define STB0899_OFF0_TP_BUFFER20		0xf350
+#define STB0899_BASE_TP_BUFFER20		0x00000040
+#define STB0899_OFF0_TP_BUFFER21		0xf354
+#define STB0899_BASE_TP_BUFFER21		0x00000040
+#define STB0899_OFF0_TP_BUFFER22		0xf358
+#define STB0899_BASE_TP_BUFFER22		0x00000040
+#define STB0899_OFF0_TP_BUFFER23		0xf35c
+#define STB0899_BASE_TP_BUFFER23		0x00000040
+#define STB0899_OFF0_TP_BUFFER24		0xf360
+#define STB0899_BASE_TP_BUFFER24		0x00000040
+#define STB0899_OFF0_TP_BUFFER25		0xf364
+#define STB0899_BASE_TP_BUFFER25		0x00000040
+#define STB0899_OFF0_TP_BUFFER26		0xf368
+#define STB0899_BASE_TP_BUFFER26		0x00000040
+#define STB0899_OFF0_TP_BUFFER27		0xf36c
+#define STB0899_BASE_TP_BUFFER27		0x00000040
+#define STB0899_OFF0_TP_BUFFER28		0xf370
+#define STB0899_BASE_TP_BUFFER28		0x00000040
+#define STB0899_OFF0_TP_BUFFER29		0xf374
+#define STB0899_BASE_TP_BUFFER29		0x00000040
+#define STB0899_OFF0_TP_BUFFER30		0xf378
+#define STB0899_BASE_TP_BUFFER30		0x00000040
+#define STB0899_OFF0_TP_BUFFER31		0xf37c
+#define STB0899_BASE_TP_BUFFER31		0x00000040
+#define STB0899_OFF0_TP_BUFFER32		0xf300
+#define STB0899_BASE_TP_BUFFER32		0x00000060
+#define STB0899_OFF0_TP_BUFFER33		0xf304
+#define STB0899_BASE_TP_BUFFER33		0x00000060
+#define STB0899_OFF0_TP_BUFFER34		0xf308
+#define STB0899_BASE_TP_BUFFER34		0x00000060
+#define STB0899_OFF0_TP_BUFFER35		0xf30c
+#define STB0899_BASE_TP_BUFFER35		0x00000060
+#define STB0899_OFF0_TP_BUFFER36		0xf310
+#define STB0899_BASE_TP_BUFFER36		0x00000060
+#define STB0899_OFF0_TP_BUFFER37		0xf314
+#define STB0899_BASE_TP_BUFFER37		0x00000060
+#define STB0899_OFF0_TP_BUFFER38		0xf318
+#define STB0899_BASE_TP_BUFFER38		0x00000060
+#define STB0899_OFF0_TP_BUFFER39		0xf31c
+#define STB0899_BASE_TP_BUFFER39		0x00000060
+#define STB0899_OFF0_TP_BUFFER40		0xf320
+#define STB0899_BASE_TP_BUFFER40		0x00000060
+#define STB0899_OFF0_TP_BUFFER41		0xf324
+#define STB0899_BASE_TP_BUFFER41		0x00000060
+#define STB0899_OFF0_TP_BUFFER42		0xf328
+#define STB0899_BASE_TP_BUFFER42		0x00000060
+#define STB0899_OFF0_TP_BUFFER43		0xf32c
+#define STB0899_BASE_TP_BUFFER43		0x00000060
+#define STB0899_OFF0_TP_BUFFER44		0xf330
+#define STB0899_BASE_TP_BUFFER44		0x00000060
+#define STB0899_OFF0_TP_BUFFER45		0xf334
+#define STB0899_BASE_TP_BUFFER45		0x00000060
+#define STB0899_OFF0_TP_BUFFER46		0xf338
+#define STB0899_BASE_TP_BUFFER46		0x00000060
+#define STB0899_OFF0_TP_BUFFER47		0xf33c
+#define STB0899_BASE_TP_BUFFER47		0x00000060
+#define STB0899_OFF0_TP_BUFFER48		0xf340
+#define STB0899_BASE_TP_BUFFER48		0x00000060
+#define STB0899_OFF0_TP_BUFFER49		0xf344
+#define STB0899_BASE_TP_BUFFER49		0x00000060
+#define STB0899_OFF0_TP_BUFFER50		0xf348
+#define STB0899_BASE_TP_BUFFER50		0x00000060
+#define STB0899_OFF0_TP_BUFFER51		0xf34c
+#define STB0899_BASE_TP_BUFFER51		0x00000060
+#define STB0899_OFF0_TP_BUFFER52		0xf350
+#define STB0899_BASE_TP_BUFFER52		0x00000060
+#define STB0899_OFF0_TP_BUFFER53		0xf354
+#define STB0899_BASE_TP_BUFFER53		0x00000060
+#define STB0899_OFF0_TP_BUFFER54		0xf358
+#define STB0899_BASE_TP_BUFFER54		0x00000060
+#define STB0899_OFF0_TP_BUFFER55		0xf35c
+#define STB0899_BASE_TP_BUFFER55		0x00000060
+#define STB0899_OFF0_TP_BUFFER56		0xf360
+#define STB0899_BASE_TP_BUFFER56		0x00000060
+#define STB0899_OFF0_TP_BUFFER57		0xf364
+#define STB0899_BASE_TP_BUFFER57		0x00000060
+#define STB0899_OFF0_TP_BUFFER58		0xf368
+#define STB0899_BASE_TP_BUFFER58		0x00000060
+#define STB0899_OFF0_TP_BUFFER59		0xf36c
+#define STB0899_BASE_TP_BUFFER59		0x00000060
+#define STB0899_OFF0_TP_BUFFER60		0xf370
+#define STB0899_BASE_TP_BUFFER60		0x00000060
+#define STB0899_OFF0_TP_BUFFER61		0xf374
+#define STB0899_BASE_TP_BUFFER61		0x00000060
+#define STB0899_OFF0_TP_BUFFER62		0xf378
+#define STB0899_BASE_TP_BUFFER62		0x00000060
+#define STB0899_OFF0_TP_BUFFER63		0xf37c
+#define STB0899_BASE_TP_BUFFER63		0x00000060
+
+#define STB0899_OFF0_RESET_CNTRL		0xf300
+#define STB0899_BASE_RESET_CNTRL		0x00000400
+#define STB0899_DVBS2_RESET			(0x01 << 0)
+#define STB0899_OFFST_DVBS2_RESET		0
+#define STB0899_WIDTH_DVBS2_RESET		1
+
+#define STB0899_OFF0_ACM_ENABLE			0xf304
+#define STB0899_BASE_ACM_ENABLE			0x00000400
+#define STB0899_ACM_ENABLE			1
+
+#define STB0899_OFF0_DESCR_CNTRL		0xf30c
+#define STB0899_BASE_DESCR_CNTRL		0x00000400
+#define STB0899_OFFST_DESCR_CNTRL               0
+#define STB0899_WIDTH_DESCR_CNTRL               16
+
+#define STB0899_OFF0_UWP_CNTRL1			0xf320
+#define STB0899_BASE_UWP_CNTRL1			0x00000400
+#define STB0899_UWP_TH_SOF			(0x7fff << 11)
+#define STB0899_OFFST_UWP_TH_SOF		11
+#define STB0899_WIDTH_UWP_TH_SOF		15
+#define STB0899_UWP_ESN0_QUANT			(0xff << 3)
+#define STB0899_OFFST_UWP_ESN0_QUANT		3
+#define STB0899_WIDTH_UWP_ESN0_QUANT		8
+#define STB0899_UWP_ESN0_AVE			(0x03 << 1)
+#define STB0899_OFFST_UWP_ESN0_AVE		1
+#define STB0899_WIDTH_UWP_ESN0_AVE		2
+#define STB0899_UWP_START			(0x01 << 0)
+#define STB0899_OFFST_UWP_START			0
+#define STB0899_WIDTH_UWP_START			1
+
+#define STB0899_OFF0_UWP_CNTRL2			0xf324
+#define STB0899_BASE_UWP_CNTRL2			0x00000400
+#define STB0899_UWP_MISS_TH			(0xff << 16)
+#define STB0899_OFFST_UWP_MISS_TH		16
+#define STB0899_WIDTH_UWP_MISS_TH		8
+#define STB0899_FE_FINE_TRK			(0xff << 8)
+#define STB0899_OFFST_FE_FINE_TRK		8
+#define STB0899_WIDTH_FE_FINE_TRK		8
+#define STB0899_FE_COARSE_TRK			(0xff << 0)
+#define STB0899_OFFST_FE_COARSE_TRK		0
+#define STB0899_WIDTH_FE_COARSE_TRK		8
+
+#define STB0899_OFF0_UWP_STAT1			0xf328
+#define STB0899_BASE_UWP_STAT1			0x00000400
+#define STB0899_UWP_STATE			(0x03ff << 15)
+#define STB0899_OFFST_UWP_STATE			15
+#define STB0899_WIDTH_UWP_STATE			10
+#define STB0899_UW_MAX_PEAK			(0x7fff << 0)
+#define STB0899_OFFST_UW_MAX_PEAK		0
+#define STB0899_WIDTH_UW_MAX_PEAK		15
+
+#define STB0899_OFF0_UWP_STAT2			0xf32c
+#define STB0899_BASE_UWP_STAT2			0x00000400
+#define STB0899_ESNO_EST			(0x07ffff << 7)
+#define STB0899_OFFST_ESN0_EST			7
+#define STB0899_WIDTH_ESN0_EST			19
+#define STB0899_UWP_DECODE_MOD			(0x7f << 0)
+#define STB0899_OFFST_UWP_DECODE_MOD		0
+#define STB0899_WIDTH_UWP_DECODE_MOD		7
+
+#define STB0899_OFF0_DMD_CORE_ID		0xf334
+#define STB0899_BASE_DMD_CORE_ID		0x00000400
+#define STB0899_CORE_ID				(0xffffffff << 0)
+#define STB0899_OFFST_CORE_ID			0
+#define STB0899_WIDTH_CORE_ID			32
+
+#define STB0899_OFF0_DMD_VERSION_ID		0xf33c
+#define STB0899_BASE_DMD_VERSION_ID		0x00000400
+#define STB0899_VERSION_ID			(0xff << 0)
+#define STB0899_OFFST_VERSION_ID		0
+#define STB0899_WIDTH_VERSION_ID		8
+
+#define STB0899_OFF0_DMD_STAT2			0xf340
+#define STB0899_BASE_DMD_STAT2			0x00000400
+#define STB0899_CSM_LOCK			(0x01 << 1)
+#define STB0899_OFFST_CSM_LOCK			1
+#define STB0899_WIDTH_CSM_LOCK			1
+#define STB0899_UWP_LOCK			(0x01 << 0)
+#define STB0899_OFFST_UWP_LOCK			0
+#define STB0899_WIDTH_UWP_LOCK			1
+
+#define STB0899_OFF0_FREQ_ADJ_SCALE		0xf344
+#define STB0899_BASE_FREQ_ADJ_SCALE		0x00000400
+#define STB0899_FREQ_ADJ_SCALE			(0x0fff << 0)
+#define STB0899_OFFST_FREQ_ADJ_SCALE		0
+#define STB0899_WIDTH_FREQ_ADJ_SCALE		12
+
+#define STB0899_OFF0_UWP_CNTRL3			0xf34c
+#define STB0899_BASE_UWP_CNTRL3			0x00000400
+#define STB0899_UWP_TH_TRACK			(0x7fff << 15)
+#define STB0899_OFFST_UWP_TH_TRACK		15
+#define STB0899_WIDTH_UWP_TH_TRACK		15
+#define STB0899_UWP_TH_ACQ			(0x7fff << 0)
+#define STB0899_OFFST_UWP_TH_ACQ		0
+#define STB0899_WIDTH_UWP_TH_ACQ		15
+
+#define STB0899_OFF0_SYM_CLK_SEL		0xf350
+#define STB0899_BASE_SYM_CLK_SEL		0x00000400
+#define STB0899_SYM_CLK_SEL			(0x03 << 0)
+#define STB0899_OFFST_SYM_CLK_SEL		0
+#define STB0899_WIDTH_SYM_CLK_SEL		2
+
+#define STB0899_OFF0_SOF_SRCH_TO		0xf354
+#define STB0899_BASE_SOF_SRCH_TO		0x00000400
+#define STB0899_SOF_SEARCH_TIMEOUT		(0x3fffff << 0)
+#define STB0899_OFFST_SOF_SEARCH_TIMEOUT	0
+#define STB0899_WIDTH_SOF_SEARCH_TIMEOUT	22
+
+#define STB0899_OFF0_ACQ_CNTRL1			0xf358
+#define STB0899_BASE_ACQ_CNTRL1			0x00000400
+#define STB0899_FE_FINE_ACQ			(0xff << 8)
+#define STB0899_OFFST_FE_FINE_ACQ		8
+#define STB0899_WIDTH_FE_FINE_ACQ		8
+#define STB0899_FE_COARSE_ACQ			(0xff << 0)
+#define STB0899_OFFST_FE_COARSE_ACQ		0
+#define STB0899_WIDTH_FE_COARSE_ACQ		8
+
+#define STB0899_OFF0_ACQ_CNTRL2			0xf35c
+#define STB0899_BASE_ACQ_CNTRL2			0x00000400
+#define STB0899_ZIGZAG				(0x01 << 25)
+#define STB0899_OFFST_ZIGZAG			25
+#define STB0899_WIDTH_ZIGZAG			1
+#define STB0899_NUM_STEPS			(0xff << 17)
+#define STB0899_OFFST_NUM_STEPS			17
+#define STB0899_WIDTH_NUM_STEPS			8
+#define STB0899_FREQ_STEPSIZE			(0x1ffff << 0)
+#define STB0899_OFFST_FREQ_STEPSIZE		0
+#define STB0899_WIDTH_FREQ_STEPSIZE		17
+
+#define STB0899_OFF0_ACQ_CNTRL3			0xf360
+#define STB0899_BASE_ACQ_CNTRL3			0x00000400
+#define STB0899_THRESHOLD_SCL			(0x3f << 23)
+#define STB0899_OFFST_THRESHOLD_SCL		23
+#define STB0899_WIDTH_THRESHOLD_SCL		6
+#define STB0899_UWP_TH_SRCH			(0x7fff << 8)
+#define STB0899_OFFST_UWP_TH_SRCH		8
+#define STB0899_WIDTH_UWP_TH_SRCH		15
+#define STB0899_AUTO_REACQUIRE			(0x01 << 7)
+#define STB0899_OFFST_AUTO_REACQUIRE		7
+#define STB0899_WIDTH_AUTO_REACQUIRE		1
+#define STB0899_TRACK_LOCK_SEL			(0x01 << 6)
+#define STB0899_OFFST_TRACK_LOCK_SEL		6
+#define STB0899_WIDTH_TRACK_LOCK_SEL		1
+#define STB0899_ACQ_SEARCH_MODE			(0x03 << 4)
+#define STB0899_OFFST_ACQ_SEARCH_MODE		4
+#define STB0899_WIDTH_ACQ_SEARCH_MODE		2
+#define STB0899_CONFIRM_FRAMES			(0x0f << 0)
+#define STB0899_OFFST_CONFIRM_FRAMES		0
+#define STB0899_WIDTH_CONFIRM_FRAMES		4
+
+#define STB0899_OFF0_FE_SETTLE			0xf364
+#define STB0899_BASE_FE_SETTLE			0x00000400
+#define STB0899_SETTLING_TIME			(0x3fffff << 0)
+#define STB0899_OFFST_SETTLING_TIME		0
+#define STB0899_WIDTH_SETTLING_TIME		22
+
+#define STB0899_OFF0_AC_DWELL			0xf368
+#define STB0899_BASE_AC_DWELL			0x00000400
+#define STB0899_DWELL_TIME			(0x3fffff << 0)
+#define STB0899_OFFST_DWELL_TIME		0
+#define STB0899_WIDTH_DWELL_TIME		22
+
+#define STB0899_OFF0_ACQUIRE_TRIG		0xf36c
+#define STB0899_BASE_ACQUIRE_TRIG		0x00000400
+#define STB0899_ACQUIRE				(0x01 << 0)
+#define STB0899_OFFST_ACQUIRE			0
+#define STB0899_WIDTH_ACQUIRE			1
+
+#define STB0899_OFF0_LOCK_LOST			0xf370
+#define STB0899_BASE_LOCK_LOST			0x00000400
+#define STB0899_LOCK_LOST			(0x01 << 0)
+#define STB0899_OFFST_LOCK_LOST			0
+#define STB0899_WIDTH_LOCK_LOST			1
+
+#define STB0899_OFF0_ACQ_STAT1			0xf374
+#define STB0899_BASE_ACQ_STAT1			0x00000400
+#define STB0899_STEP_FREQ			(0x1fffff << 11)
+#define STB0899_OFFST_STEP_FREQ			11
+#define STB0899_WIDTH_STEP_FREQ			21
+#define STB0899_ACQ_STATE			(0x07 << 8)
+#define STB0899_OFFST_ACQ_STATE			8
+#define STB0899_WIDTH_ACQ_STATE			3
+#define STB0899_UW_DETECT_COUNT			(0xff << 0)
+#define STB0899_OFFST_UW_DETECT_COUNT		0
+#define STB0899_WIDTH_UW_DETECT_COUNT		8
+
+#define STB0899_OFF0_ACQ_TIMEOUT		0xf378
+#define STB0899_BASE_ACQ_TIMEOUT		0x00000400
+#define STB0899_ACQ_TIMEOUT			(0x3fffff << 0)
+#define STB0899_OFFST_ACQ_TIMEOUT		0
+#define STB0899_WIDTH_ACQ_TIMEOUT		22
+
+#define STB0899_OFF0_ACQ_TIME			0xf37c
+#define STB0899_BASE_ACQ_TIME			0x00000400
+#define STB0899_ACQ_TIME_SYM			(0xffffff << 0)
+#define STB0899_OFFST_ACQ_TIME_SYM		0
+#define STB0899_WIDTH_ACQ_TIME_SYM		24
+
+#define STB0899_OFF0_FINAL_AGC_CNTRL		0xf308
+#define STB0899_BASE_FINAL_AGC_CNTRL		0x00000440
+#define STB0899_FINAL_GAIN_INIT			(0x3fff << 12)
+#define STB0899_OFFST_FINAL_GAIN_INIT		12
+#define STB0899_WIDTH_FINAL_GAIN_INIT		14
+#define STB0899_FINAL_LOOP_GAIN			(0x0f << 8)
+#define STB0899_OFFST_FINAL_LOOP_GAIN		8
+#define STB0899_WIDTH_FINAL_LOOP_GAIN		4
+#define STB0899_FINAL_LD_GAIN_INIT		(0x01 << 7)
+#define STB0899_OFFST_FINAL_LD_GAIN_INIT	7
+#define STB0899_WIDTH_FINAL_LD_GAIN_INIT	1
+#define STB0899_FINAL_AGC_REF			(0x7f << 0)
+#define STB0899_OFFST_FINAL_AGC_REF		0
+#define STB0899_WIDTH_FINAL_AGC_REF		7
+
+#define STB0899_OFF0_FINAL_AGC_GAIN		0xf30c
+#define STB0899_BASE_FINAL_AGC_GAIN		0x00000440
+#define STB0899_FINAL_AGC_GAIN			(0x3fff << 0)
+#define STB0899_OFFST_FINAL_AGC_GAIN		0
+#define STB0899_WIDTH_FINAL_AGC_GAIN		14
+
+#define STB0899_OFF0_EQUALIZER_INIT		0xf310
+#define STB0899_BASE_EQUALIZER_INIT		0x00000440
+#define STB0899_EQ_SRST				(0x01 << 1)
+#define STB0899_OFFST_EQ_SRST			1
+#define STB0899_WIDTH_EQ_SRST			1
+#define STB0899_EQ_INIT				(0x01 << 0)
+#define STB0899_OFFST_EQ_INIT			0
+#define STB0899_WIDTH_EQ_INIT			1
+
+#define STB0899_OFF0_EQ_CNTRL			0xf314
+#define STB0899_BASE_EQ_CNTRL			0x00000440
+#define STB0899_EQ_ADAPT_MODE			(0x01 << 18)
+#define STB0899_OFFST_EQ_ADAPT_MODE		18
+#define STB0899_WIDTH_EQ_ADAPT_MODE		1
+#define STB0899_EQ_DELAY			(0x0f << 14)
+#define STB0899_OFFST_EQ_DELAY			14
+#define STB0899_WIDTH_EQ_DELAY			4
+#define STB0899_EQ_QUANT_LEVEL			(0xff << 6)
+#define STB0899_OFFST_EQ_QUANT_LEVEL		6
+#define STB0899_WIDTH_EQ_QUANT_LEVEL		8
+#define STB0899_EQ_DISABLE_UPDATE		(0x01 << 5)
+#define STB0899_OFFST_EQ_DISABLE_UPDATE		5
+#define STB0899_WIDTH_EQ_DISABLE_UPDATE		1
+#define STB0899_EQ_BYPASS			(0x01 << 4)
+#define STB0899_OFFST_EQ_BYPASS			4
+#define STB0899_WIDTH_EQ_BYPASS			1
+#define STB0899_EQ_SHIFT			(0x0f << 0)
+#define STB0899_OFFST_EQ_SHIFT			0
+#define STB0899_WIDTH_EQ_SHIFT			4
+
+#define STB0899_OFF0_EQ_I_INIT_COEFF_0		0xf320
+#define STB0899_OFF1_EQ_I_INIT_COEFF_1		0xf324
+#define STB0899_OFF2_EQ_I_INIT_COEFF_2		0xf328
+#define STB0899_OFF3_EQ_I_INIT_COEFF_3		0xf32c
+#define STB0899_OFF4_EQ_I_INIT_COEFF_4		0xf330
+#define STB0899_OFF5_EQ_I_INIT_COEFF_5		0xf334
+#define STB0899_OFF6_EQ_I_INIT_COEFF_6		0xf338
+#define STB0899_OFF7_EQ_I_INIT_COEFF_7		0xf33c
+#define STB0899_OFF8_EQ_I_INIT_COEFF_8		0xf340
+#define STB0899_OFF9_EQ_I_INIT_COEFF_9		0xf344
+#define STB0899_OFFa_EQ_I_INIT_COEFF_10		0xf348
+#define STB0899_BASE_EQ_I_INIT_COEFF_N		0x00000440
+#define STB0899_EQ_I_INIT_COEFF_N		(0x0fff << 0)
+#define STB0899_OFFST_EQ_I_INIT_COEFF_N		0
+#define STB0899_WIDTH_EQ_I_INIT_COEFF_N		12
+
+#define STB0899_OFF0_EQ_Q_INIT_COEFF_0		0xf350
+#define STB0899_OFF1_EQ_Q_INIT_COEFF_1		0xf354
+#define STB0899_OFF2_EQ_Q_INIT_COEFF_2		0xf358
+#define STB0899_OFF3_EQ_Q_INIT_COEFF_3		0xf35c
+#define STB0899_OFF4_EQ_Q_INIT_COEFF_4		0xf360
+#define STB0899_OFF5_EQ_Q_INIT_COEFF_5		0xf364
+#define STB0899_OFF6_EQ_Q_INIT_COEFF_6		0xf368
+#define STB0899_OFF7_EQ_Q_INIT_COEFF_7		0xf36c
+#define STB0899_OFF8_EQ_Q_INIT_COEFF_8		0xf370
+#define STB0899_OFF9_EQ_Q_INIT_COEFF_9		0xf374
+#define STB0899_OFFa_EQ_Q_INIT_COEFF_10		0xf378
+#define STB0899_BASE_EQ_Q_INIT_COEFF_N		0x00000440
+#define STB0899_EQ_Q_INIT_COEFF_N		(0x0fff << 0)
+#define STB0899_OFFST_EQ_Q_INIT_COEFF_N		0
+#define STB0899_WIDTH_EQ_Q_INIT_COEFF_N		12
+
+#define STB0899_OFF0_EQ_I_OUT_COEFF_0		0xf300
+#define STB0899_OFF1_EQ_I_OUT_COEFF_1		0xf304
+#define STB0899_OFF2_EQ_I_OUT_COEFF_2		0xf308
+#define STB0899_OFF3_EQ_I_OUT_COEFF_3		0xf30c
+#define STB0899_OFF4_EQ_I_OUT_COEFF_4		0xf310
+#define STB0899_OFF5_EQ_I_OUT_COEFF_5		0xf314
+#define STB0899_OFF6_EQ_I_OUT_COEFF_6		0xf318
+#define STB0899_OFF7_EQ_I_OUT_COEFF_7		0xf31c
+#define STB0899_OFF8_EQ_I_OUT_COEFF_8		0xf320
+#define STB0899_OFF9_EQ_I_OUT_COEFF_9		0xf324
+#define STB0899_OFFa_EQ_I_OUT_COEFF_10		0xf328
+#define STB0899_BASE_EQ_I_OUT_COEFF_N		0x00000460
+#define STB0899_EQ_I_OUT_COEFF_N		(0x0fff << 0)
+#define STB0899_OFFST_EQ_I_OUT_COEFF_N		0
+#define STB0899_WIDTH_EQ_I_OUT_COEFF_N		12
+
+#define STB0899_OFF0_EQ_Q_OUT_COEFF_0		0xf330
+#define STB0899_OFF1_EQ_Q_OUT_COEFF_1		0xf334
+#define STB0899_OFF2_EQ_Q_OUT_COEFF_2		0xf338
+#define STB0899_OFF3_EQ_Q_OUT_COEFF_3		0xf33c
+#define STB0899_OFF4_EQ_Q_OUT_COEFF_4		0xf340
+#define STB0899_OFF5_EQ_Q_OUT_COEFF_5		0xf344
+#define STB0899_OFF6_EQ_Q_OUT_COEFF_6		0xf348
+#define STB0899_OFF7_EQ_Q_OUT_COEFF_7		0xf34c
+#define STB0899_OFF8_EQ_Q_OUT_COEFF_8		0xf350
+#define STB0899_OFF9_EQ_Q_OUT_COEFF_9		0xf354
+#define STB0899_OFFa_EQ_Q_OUT_COEFF_10		0xf358
+#define STB0899_BASE_EQ_Q_OUT_COEFF_N		0x00000460
+#define STB0899_EQ_Q_OUT_COEFF_N		(0x0fff << 0)
+#define STB0899_OFFST_EQ_Q_OUT_COEFF_N		0
+#define STB0899_WIDTH_EQ_Q_OUT_COEFF_N		12
+
+/*	S2 FEC	*/
+#define STB0899_OFF0_BLOCK_LNGTH		0xfa04
+#define STB0899_BASE_BLOCK_LNGTH		0x00000000
+#define STB0899_BLOCK_LENGTH			(0xff << 0)
+#define STB0899_OFFST_BLOCK_LENGTH		0
+#define STB0899_WIDTH_BLOCK_LENGTH		8
+
+#define STB0899_OFF0_ROW_STR			0xfa08
+#define STB0899_BASE_ROW_STR			0x00000000
+#define STB0899_ROW_STRIDE			(0xff << 0)
+#define STB0899_OFFST_ROW_STRIDE		0
+#define STB0899_WIDTH_ROW_STRIDE		8
+
+#define STB0899_OFF0_MAX_ITER			0xfa0c
+#define STB0899_BASE_MAX_ITER			0x00000000
+#define STB0899_MAX_ITERATIONS			(0xff << 0)
+#define STB0899_OFFST_MAX_ITERATIONS		0
+#define STB0899_WIDTH_MAX_ITERATIONS		8
+
+#define STB0899_OFF0_BN_END_ADDR		0xfa10
+#define STB0899_BASE_BN_END_ADDR		0x00000000
+#define STB0899_BN_END_ADDR			(0x0fff << 0)
+#define STB0899_OFFST_BN_END_ADDR		0
+#define STB0899_WIDTH_BN_END_ADDR		12
+
+#define STB0899_OFF0_CN_END_ADDR		0xfa14
+#define STB0899_BASE_CN_END_ADDR		0x00000000
+#define STB0899_CN_END_ADDR			(0x0fff << 0)
+#define STB0899_OFFST_CN_END_ADDR		0
+#define STB0899_WIDTH_CN_END_ADDR		12
+
+#define STB0899_OFF0_INFO_LENGTH		0xfa1c
+#define STB0899_BASE_INFO_LENGTH		0x00000000
+#define STB0899_INFO_LENGTH			(0xff << 0)
+#define STB0899_OFFST_INFO_LENGTH		0
+#define STB0899_WIDTH_INFO_LENGTH		8
+
+#define STB0899_OFF0_BOT_ADDR			0xfa20
+#define STB0899_BASE_BOT_ADDR			0x00000000
+#define STB0899_BOTTOM_BASE_ADDR		(0x03ff << 0)
+#define STB0899_OFFST_BOTTOM_BASE_ADDR		0
+#define STB0899_WIDTH_BOTTOM_BASE_ADDR		10
+
+#define STB0899_OFF0_BCH_BLK_LN			0xfa24
+#define STB0899_BASE_BCH_BLK_LN			0x00000000
+#define STB0899_BCH_BLOCK_LENGTH		(0xffff << 0)
+#define STB0899_OFFST_BCH_BLOCK_LENGTH		0
+#define STB0899_WIDTH_BCH_BLOCK_LENGTH		16
+
+#define STB0899_OFF0_BCH_T			0xfa28
+#define STB0899_BASE_BCH_T			0x00000000
+#define STB0899_BCH_T				(0x0f << 0)
+#define STB0899_OFFST_BCH_T			0
+#define STB0899_WIDTH_BCH_T			4
+
+#define STB0899_OFF0_CNFG_MODE			0xfa00
+#define STB0899_BASE_CNFG_MODE			0x00000800
+#define STB0899_MODCOD				(0x1f << 2)
+#define STB0899_OFFST_MODCOD			2
+#define STB0899_WIDTH_MODCOD			5
+#define STB0899_MODCOD_SEL			(0x01 << 1)
+#define STB0899_OFFST_MODCOD_SEL		1
+#define STB0899_WIDTH_MODCOD_SEL		1
+#define STB0899_CONFIG_MODE			(0x01 << 0)
+#define STB0899_OFFST_CONFIG_MODE		0
+#define STB0899_WIDTH_CONFIG_MODE		1
+
+#define STB0899_OFF0_LDPC_STAT			0xfa04
+#define STB0899_BASE_LDPC_STAT			0x00000800
+#define STB0899_ITERATION			(0xff << 3)
+#define STB0899_OFFST_ITERATION			3
+#define STB0899_WIDTH_ITERATION			8
+#define STB0899_LDPC_DEC_STATE			(0x07 << 0)
+#define STB0899_OFFST_LDPC_DEC_STATE		0
+#define STB0899_WIDTH_LDPC_DEC_STATE		3
+
+#define STB0899_OFF0_ITER_SCALE			0xfa08
+#define STB0899_BASE_ITER_SCALE			0x00000800
+#define STB0899_ITERATION_SCALE			(0xff << 0)
+#define STB0899_OFFST_ITERATION_SCALE		0
+#define STB0899_WIDTH_ITERATION_SCALE		8
+
+#define STB0899_OFF0_INPUT_MODE			0xfa0c
+#define STB0899_BASE_INPUT_MODE			0x00000800
+#define STB0899_SD_BLOCK1_STREAM0		(0x01 << 0)
+#define STB0899_OFFST_SD_BLOCK1_STREAM0		0
+#define STB0899_WIDTH_SD_BLOCK1_STREAM0		1
+
+#define STB0899_OFF0_LDPCDECRST			0xfa10
+#define STB0899_BASE_LDPCDECRST			0x00000800
+#define STB0899_LDPC_DEC_RST			(0x01 << 0)
+#define STB0899_OFFST_LDPC_DEC_RST		0
+#define STB0899_WIDTH_LDPC_DEC_RST		1
+
+#define STB0899_OFF0_CLK_PER_BYTE_RW		0xfa14
+#define STB0899_BASE_CLK_PER_BYTE_RW		0x00000800
+#define STB0899_CLKS_PER_BYTE			(0x0f << 0)
+#define STB0899_OFFST_CLKS_PER_BYTE		0
+#define STB0899_WIDTH_CLKS_PER_BYTE		5
+
+#define STB0899_OFF0_BCH_ERRORS			0xfa18
+#define STB0899_BASE_BCH_ERRORS			0x00000800
+#define STB0899_BCH_ERRORS			(0x0f << 0)
+#define STB0899_OFFST_BCH_ERRORS		0
+#define STB0899_WIDTH_BCH_ERRORS		4
+
+#define STB0899_OFF0_LDPC_ERRORS		0xfa1c
+#define STB0899_BASE_LDPC_ERRORS		0x00000800
+#define STB0899_LDPC_ERRORS			(0xffff << 0)
+#define STB0899_OFFST_LDPC_ERRORS		0
+#define STB0899_WIDTH_LDPC_ERRORS		16
+
+#define STB0899_OFF0_BCH_MODE			0xfa20
+#define STB0899_BASE_BCH_MODE			0x00000800
+#define STB0899_BCH_CORRECT_N			(0x01 << 1)
+#define STB0899_OFFST_BCH_CORRECT_N		1
+#define STB0899_WIDTH_BCH_CORRECT_N		1
+#define STB0899_FULL_BYPASS			(0x01 << 0)
+#define STB0899_OFFST_FULL_BYPASS		0
+#define STB0899_WIDTH_FULL_BYPASS		1
+
+#define STB0899_OFF0_ERR_ACC_PER		0xfa24
+#define STB0899_BASE_ERR_ACC_PER		0x00000800
+#define STB0899_BCH_ERR_ACC_PERIOD		(0x0f << 0)
+#define STB0899_OFFST_BCH_ERR_ACC_PERIOD	0
+#define STB0899_WIDTH_BCH_ERR_ACC_PERIOD	4
+
+#define STB0899_OFF0_BCH_ERR_ACC		0xfa28
+#define STB0899_BASE_BCH_ERR_ACC		0x00000800
+#define STB0899_BCH_ERR_ACCUM			(0xff << 0)
+#define STB0899_OFFST_BCH_ERR_ACCUM		0
+#define STB0899_WIDTH_BCH_ERR_ACCUM		8
+
+#define STB0899_OFF0_FEC_CORE_ID_REG		0xfa2c
+#define STB0899_BASE_FEC_CORE_ID_REG		0x00000800
+#define STB0899_FEC_CORE_ID			(0xffffffff << 0)
+#define STB0899_OFFST_FEC_CORE_ID		0
+#define STB0899_WIDTH_FEC_CORE_ID		32
+
+#define STB0899_OFF0_FEC_VER_ID_REG		0xfa34
+#define STB0899_BASE_FEC_VER_ID_REG		0x00000800
+#define STB0899_FEC_VER_ID			(0xff << 0)
+#define STB0899_OFFST_FEC_VER_ID		0
+#define STB0899_WIDTH_FEC_VER_ID		8
+
+#define STB0899_OFF0_FEC_TP_SEL			0xfa38
+#define STB0899_BASE_FEC_TP_SEL			0x00000800
+
+#define STB0899_OFF0_CSM_CNTRL1			0xf310
+#define STB0899_BASE_CSM_CNTRL1			0x00000400
+#define STB0899_CSM_FORCE_FREQLOCK		(0x01 << 19)
+#define STB0899_OFFST_CSM_FORCE_FREQLOCK	19
+#define STB0899_WIDTH_CSM_FORCE_FREQLOCK	1
+#define STB0899_CSM_FREQ_LOCKSTATE		(0x01 << 18)
+#define STB0899_OFFST_CSM_FREQ_LOCKSTATE	18
+#define STB0899_WIDTH_CSM_FREQ_LOCKSTATE	1
+#define STB0899_CSM_AUTO_PARAM			(0x01 << 17)
+#define STB0899_OFFST_CSM_AUTO_PARAM		17
+#define STB0899_WIDTH_CSM_AUTO_PARAM		1
+#define STB0899_FE_LOOP_SHIFT			(0x07 << 14)
+#define STB0899_OFFST_FE_LOOP_SHIFT		14
+#define STB0899_WIDTH_FE_LOOP_SHIFT		3
+#define STB0899_CSM_AGC_SHIFT			(0x07 << 11)
+#define STB0899_OFFST_CSM_AGC_SHIFT		11
+#define STB0899_WIDTH_CSM_AGC_SHIFT		3
+#define STB0899_CSM_AGC_GAIN			(0x09 << 2)
+#define STB0899_OFFST_CSM_AGC_GAIN		2
+#define STB0899_WIDTH_CSM_AGC_GAIN		9
+#define STB0899_CSM_TWO_PASS			(0x01 << 1)
+#define STB0899_OFFST_CSM_TWO_PASS		1
+#define STB0899_WIDTH_CSM_TWO_PASS		1
+#define STB0899_CSM_DVT_TABLE			(0x01 << 0)
+#define STB0899_OFFST_CSM_DVT_TABLE		0
+#define STB0899_WIDTH_CSM_DVT_TABLE		1
+
+#define STB0899_OFF0_CSM_CNTRL2			0xf314
+#define STB0899_BASE_CSM_CNTRL2			0x00000400
+#define STB0899_CSM_GAMMA_RHO_ACQ		(0x09 << 9)
+#define STB0899_OFFST_CSM_GAMMA_RHOACQ		9
+#define STB0899_WIDTH_CSM_GAMMA_RHOACQ		9
+#define STB0899_CSM_GAMMA_ACQ			(0x09 << 0)
+#define STB0899_OFFST_CSM_GAMMA_ACQ		0
+#define STB0899_WIDTH_CSM_GAMMA_ACQ		9
+
+#define STB0899_OFF0_CSM_CNTRL3			0xf320
+#define STB0899_BASE_CSM_CNTRL3			0x00000400
+#define STB0899_CSM_GAMMA_RHO_TRACK		(0x09 << 9)
+#define STB0899_OFFST_CSM_GAMMA_RHOTRACK	9
+#define STB0899_WIDTH_CSM_GAMMA_RHOTRACK	9
+#define STB0899_CSM_GAMMA_TRACK			(0x09 << 0)
+#define STB0899_OFFST_CSM_GAMMA_TRACK		0
+#define STB0899_WIDTH_CSM_GAMMA_TRACK		9
+
+#define STB0899_OFF0_CSM_CNTRL4			0xf324
+#define STB0899_BASE_CSM_CNTRL4			0x00000400
+#define STB0899_CSM_PHASEDIFF_THRESH		(0x0f << 8)
+#define STB0899_OFFST_CSM_PHASEDIFF_THRESH	8
+#define STB0899_WIDTH_CSM_PHASEDIFF_THRESH	4
+#define STB0899_CSM_LOCKCOUNT_THRESH		(0xff << 0)
+#define STB0899_OFFST_CSM_LOCKCOUNT_THRESH	0
+#define STB0899_WIDTH_CSM_LOCKCOUNT_THRESH	8
+
+/*	Check on chapter 8 page 42	*/
+#define STB0899_ERRCTRL1			0xf574
+#define STB0899_ERRCTRL2			0xf575
+#define STB0899_ERRCTRL3			0xf576
+#define STB0899_ERR_SRC_S1			(0x1f << 3)
+#define STB0899_OFFST_ERR_SRC_S1		3
+#define STB0899_WIDTH_ERR_SRC_S1		5
+#define STB0899_ERR_SRC_S2			(0x0f << 0)
+#define STB0899_OFFST_ERR_SRC_S2		0
+#define STB0899_WIDTH_ERR_SRC_S2		4
+#define STB0899_NOE				(0x07 << 0)
+#define STB0899_OFFST_NOE			0
+#define STB0899_WIDTH_NOE			3
+
+#define STB0899_ECNT1M				0xf524
+#define STB0899_ECNT1L				0xf525
+#define STB0899_ECNT2M				0xf526
+#define STB0899_ECNT2L				0xf527
+#define STB0899_ECNT3M				0xf528
+#define STB0899_ECNT3L				0xf529
+
+#define STB0899_DMONMSK1			0xf57b
+#define STB0899_DMONMSK1_WAIT_1STEP		(1 << 7)
+#define STB0899_DMONMSK1_FREE_14		(1 << 6)
+#define STB0899_DMONMSK1_AVRGVIT_CALC		(1 << 5)
+#define STB0899_DMONMSK1_FREE_12		(1 << 4)
+#define STB0899_DMONMSK1_FREE_11		(1 << 3)
+#define STB0899_DMONMSK1_B0DIV_CALC		(1 << 2)
+#define STB0899_DMONMSK1_KDIVB1_CALC		(1 << 1)
+#define STB0899_DMONMSK1_KDIVB2_CALC		(1 << 0)
+
+#define STB0899_DMONMSK0			0xf57c
+#define STB0899_DMONMSK0_SMOTTH_CALC		(1 << 7)
+#define STB0899_DMONMSK0_FREE_6			(1 << 6)
+#define STB0899_DMONMSK0_SIGPOWER_CALC		(1 << 5)
+#define STB0899_DMONMSK0_QSEUIL_CALC		(1 << 4)
+#define STB0899_DMONMSK0_FREE_3			(1 << 3)
+#define STB0899_DMONMSK0_FREE_2			(1 << 2)
+#define STB0899_DMONMSK0_KVDIVB1_CALC		(1 << 1)
+#define STB0899_DMONMSK0_KVDIVB2_CALC		(1 << 0)
+
+#define STB0899_TSULC				0xf549
+#define STB0899_ULNOSYNCBYTES			(0x01 << 7)
+#define STB0899_OFFST_ULNOSYNCBYTES		7
+#define STB0899_WIDTH_ULNOSYNCBYTES		1
+#define STB0899_ULPARITY_ON			(0x01 << 6)
+#define STB0899_OFFST_ULPARITY_ON		6
+#define STB0899_WIDTH_ULPARITY_ON		1
+#define STB0899_ULSYNCOUTRS			(0x01 << 5)
+#define STB0899_OFFST_ULSYNCOUTRS		5
+#define STB0899_WIDTH_ULSYNCOUTRS		1
+#define STB0899_ULDSS_PACKETS			(0x01 << 0)
+#define STB0899_OFFST_ULDSS_PACKETS		0
+#define STB0899_WIDTH_ULDSS_PACKETS		1
+
+#define STB0899_TSLPL				0xf54b
+#define STB0899_LLDVBS2_MODE			(0x01 << 4)
+#define STB0899_OFFST_LLDVBS2_MODE		4
+#define STB0899_WIDTH_LLDVBS2_MODE		1
+#define STB0899_LLISSYI_ON			(0x01 << 3)
+#define STB0899_OFFST_LLISSYI_ON		3
+#define STB0899_WIDTH_LLISSYI_ON		1
+#define STB0899_LLNPD_ON			(0x01 << 2)
+#define STB0899_OFFST_LLNPD_ON			2
+#define STB0899_WIDTH_LLNPD_ON			1
+#define STB0899_LLCRC8_ON			(0x01 << 1)
+#define STB0899_OFFST_LLCRC8_ON			1
+#define STB0899_WIDTH_LLCRC8_ON			1
+
+#define STB0899_TSCFGH				0xf54c
+#define STB0899_OUTRS_PS			(0x01 << 6)
+#define STB0899_OFFST_OUTRS_PS			6
+#define STB0899_WIDTH_OUTRS_PS			1
+#define STB0899_SYNCBYTE			(0x01 << 5)
+#define STB0899_OFFST_SYNCBYTE			5
+#define STB0899_WIDTH_SYNCBYTE			1
+#define STB0899_PFBIT				(0x01 << 4)
+#define STB0899_OFFST_PFBIT			4
+#define STB0899_WIDTH_PFBIT			1
+#define STB0899_ERR_BIT				(0x01 << 3)
+#define STB0899_OFFST_ERR_BIT			3
+#define STB0899_WIDTH_ERR_BIT			1
+#define STB0899_MPEG				(0x01 << 2)
+#define STB0899_OFFST_MPEG			2
+#define STB0899_WIDTH_MPEG			1
+#define STB0899_CLK_POL				(0x01 << 1)
+#define STB0899_OFFST_CLK_POL			1
+#define STB0899_WIDTH_CLK_POL			1
+#define STB0899_FORCE0				(0x01 << 0)
+#define STB0899_OFFST_FORCE0			0
+#define STB0899_WIDTH_FORCE0			1
+
+#define STB0899_TSCFGM				0xf54d
+#define STB0899_LLPRIORITY			(0x01 << 3)
+#define STB0899_OFFST_LLPRIORIY			3
+#define STB0899_WIDTH_LLPRIORITY		1
+#define STB0899_EN188				(0x01 << 2)
+#define STB0899_OFFST_EN188			2
+#define STB0899_WIDTH_EN188			1
+
+#define STB0899_TSCFGL				0xf54e
+#define STB0899_DEL_ERRPCK			(0x01 << 7)
+#define STB0899_OFFST_DEL_ERRPCK		7
+#define STB0899_WIDTH_DEL_ERRPCK		1
+#define STB0899_ERRFLAGSTD			(0x01 << 5)
+#define STB0899_OFFST_ERRFLAGSTD		5
+#define STB0899_WIDTH_ERRFLAGSTD		1
+#define STB0899_MPEGERR				(0x01 << 4)
+#define STB0899_OFFST_MPEGERR			4
+#define STB0899_WIDTH_MPEGERR			1
+#define STB0899_BCH_CHK				(0x01 << 3)
+#define STB0899_OFFST_BCH_CHK			5
+#define STB0899_WIDTH_BCH_CHK			1
+#define STB0899_CRC8CHK				(0x01 << 2)
+#define STB0899_OFFST_CRC8CHK			2
+#define STB0899_WIDTH_CRC8CHK			1
+#define STB0899_SPEC_INFO			(0x01 << 1)
+#define STB0899_OFFST_SPEC_INFO			1
+#define STB0899_WIDTH_SPEC_INFO			1
+#define STB0899_LOW_PRIO_CLK			(0x01 << 0)
+#define STB0899_OFFST_LOW_PRIO_CLK		0
+#define STB0899_WIDTH_LOW_PRIO_CLK		1
+#define STB0899_ERROR_NORM			(0x00 << 0)
+#define STB0899_OFFST_ERROR_NORM		0
+#define STB0899_WIDTH_ERROR_NORM		0
+
+#define STB0899_TSOUT				0xf54f
+#define STB0899_RSSYNCDEL			0xf550
+#define STB0899_TSINHDELH			0xf551
+#define STB0899_TSINHDELM			0xf552
+#define STB0899_TSINHDELL			0xf553
+#define STB0899_TSLLSTKM			0xf55a
+#define STB0899_TSLLSTKL			0xf55b
+#define STB0899_TSULSTKM			0xf55c
+#define STB0899_TSULSTKL			0xf55d
+#define STB0899_TSSTATUS			0xf561
+
+#define STB0899_PDELCTRL			0xf600
+#define STB0899_INVERT_RES			(0x01 << 7)
+#define STB0899_OFFST_INVERT_RES		7
+#define STB0899_WIDTH_INVERT_RES		1
+#define STB0899_FORCE_ACCEPTED			(0x01 << 6)
+#define STB0899_OFFST_FORCE_ACCEPTED		6
+#define STB0899_WIDTH_FORCE_ACCEPTED		1
+#define STB0899_FILTER_EN			(0x01 << 5)
+#define STB0899_OFFST_FILTER_EN			5
+#define STB0899_WIDTH_FILTER_EN			1
+#define STB0899_LOCKFALL_THRESH			(0x01 << 4)
+#define STB0899_OFFST_LOCKFALL_THRESH		4
+#define STB0899_WIDTH_LOCKFALL_THRESH		1
+#define STB0899_HYST_EN				(0x01 << 3)
+#define STB0899_OFFST_HYST_EN			3
+#define STB0899_WIDTH_HYST_EN			1
+#define STB0899_HYST_SWRST			(0x01 << 2)
+#define STB0899_OFFST_HYST_SWRST		2
+#define STB0899_WIDTH_HYST_SWRST		1
+#define STB0899_ALGO_EN				(0x01 << 1)
+#define STB0899_OFFST_ALGO_EN			1
+#define STB0899_WIDTH_ALGO_EN			1
+#define STB0899_ALGO_SWRST			(0x01 << 0)
+#define STB0899_OFFST_ALGO_SWRST		0
+#define STB0899_WIDTH_ALGO_SWRST		1
+
+#define STB0899_PDELCTRL2			0xf601
+#define STB0899_BBHCTRL1			0xf602
+#define STB0899_BBHCTRL2			0xf603
+#define STB0899_HYSTTHRESH			0xf604
+
+#define STB0899_MATCSTM				0xf605
+#define STB0899_MATCSTL				0xf606
+#define STB0899_UPLCSTM				0xf607
+#define STB0899_UPLCSTL				0xf608
+#define STB0899_DFLCSTM				0xf609
+#define STB0899_DFLCSTL				0xf60a
+#define STB0899_SYNCCST				0xf60b
+#define STB0899_SYNCDCSTM			0xf60c
+#define STB0899_SYNCDCSTL			0xf60d
+#define STB0899_ISI_ENTRY			0xf60e
+#define STB0899_ISI_BIT_EN			0xf60f
+#define STB0899_MATSTRM				0xf610
+#define STB0899_MATSTRL				0xf611
+#define STB0899_UPLSTRM				0xf612
+#define STB0899_UPLSTRL				0xf613
+#define STB0899_DFLSTRM				0xf614
+#define STB0899_DFLSTRL				0xf615
+#define STB0899_SYNCSTR				0xf616
+#define STB0899_SYNCDSTRM			0xf617
+#define STB0899_SYNCDSTRL			0xf618
+
+#define STB0899_CFGPDELSTATUS1			0xf619
+#define STB0899_BADDFL				(0x01 << 6)
+#define STB0899_OFFST_BADDFL			6
+#define STB0899_WIDTH_BADDFL			1
+#define STB0899_CONTINUOUS_STREAM		(0x01 << 5)
+#define STB0899_OFFST_CONTINUOUS_STREAM		5
+#define STB0899_WIDTH_CONTINUOUS_STREAM		1
+#define STB0899_ACCEPTED_STREAM			(0x01 << 4)
+#define STB0899_OFFST_ACCEPTED_STREAM		4
+#define STB0899_WIDTH_ACCEPTED_STREAM		1
+#define STB0899_BCH_ERRFLAG			(0x01 << 3)
+#define STB0899_OFFST_BCH_ERRFLAG		3
+#define STB0899_WIDTH_BCH_ERRFLAG		1
+#define STB0899_CRCRES				(0x01 << 2)
+#define STB0899_OFFST_CRCRES			2
+#define STB0899_WIDTH_CRCRES			1
+#define STB0899_CFGPDELSTATUS_LOCK		(0x01 << 1)
+#define STB0899_OFFST_CFGPDELSTATUS_LOCK	1
+#define STB0899_WIDTH_CFGPDELSTATUS_LOCK	1
+#define STB0899_1STLOCK				(0x01 << 0)
+#define STB0899_OFFST_1STLOCK			0
+#define STB0899_WIDTH_1STLOCK			1
+
+#define STB0899_CFGPDELSTATUS2			0xf61a
+#define STB0899_BBFERRORM			0xf61b
+#define STB0899_BBFERRORL			0xf61c
+#define STB0899_UPKTERRORM			0xf61d
+#define STB0899_UPKTERRORL			0xf61e
+
+#define STB0899_TSTCK				0xff10
+
+#define STB0899_TSTRES				0xff11
+#define STB0899_FRESLDPC			(0x01 << 7)
+#define STB0899_OFFST_FRESLDPC			7
+#define STB0899_WIDTH_FRESLDPC			1
+#define STB0899_FRESRS				(0x01 << 6)
+#define STB0899_OFFST_FRESRS			6
+#define STB0899_WIDTH_FRESRS			1
+#define STB0899_FRESVIT				(0x01 << 5)
+#define STB0899_OFFST_FRESVIT			5
+#define STB0899_WIDTH_FRESVIT			1
+#define STB0899_FRESMAS1_2			(0x01 << 4)
+#define STB0899_OFFST_FRESMAS1_2		4
+#define STB0899_WIDTH_FRESMAS1_2		1
+#define STB0899_FRESACS				(0x01 << 3)
+#define STB0899_OFFST_FRESACS			3
+#define STB0899_WIDTH_FRESACS			1
+#define STB0899_FRESSYM				(0x01 << 2)
+#define STB0899_OFFST_FRESSYM			2
+#define STB0899_WIDTH_FRESSYM			1
+#define STB0899_FRESMAS				(0x01 << 1)
+#define STB0899_OFFST_FRESMAS			1
+#define STB0899_WIDTH_FRESMAS			1
+#define STB0899_FRESINT				(0x01 << 0)
+#define STB0899_OFFST_FRESINIT			0
+#define STB0899_WIDTH_FRESINIT			1
+
+#define STB0899_TSTOUT				0xff12
+#define STB0899_EN_SIGNATURE			(0x01 << 7)
+#define STB0899_OFFST_EN_SIGNATURE		7
+#define STB0899_WIDTH_EN_SIGNATURE		1
+#define STB0899_BCLK_CLK			(0x01 << 6)
+#define STB0899_OFFST_BCLK_CLK			6
+#define STB0899_WIDTH_BCLK_CLK			1
+#define STB0899_SGNL_OUT			(0x01 << 5)
+#define STB0899_OFFST_SGNL_OUT			5
+#define STB0899_WIDTH_SGNL_OUT			1
+#define STB0899_TS				(0x01 << 4)
+#define STB0899_OFFST_TS			4
+#define STB0899_WIDTH_TS			1
+#define STB0899_CTEST				(0x01 << 0)
+#define STB0899_OFFST_CTEST			0
+#define STB0899_WIDTH_CTEST			1
+
+#define STB0899_TSTIN				0xff13
+#define STB0899_TEST_IN				(0x01 << 7)
+#define STB0899_OFFST_TEST_IN			7
+#define STB0899_WIDTH_TEST_IN			1
+#define STB0899_EN_ADC				(0x01 << 6)
+#define STB0899_OFFST_EN_ADC			6
+#define STB0899_WIDTH_ENADC			1
+#define STB0899_SGN_ADC				(0x01 << 5)
+#define STB0899_OFFST_SGN_ADC			5
+#define STB0899_WIDTH_SGN_ADC			1
+#define STB0899_BCLK_IN				(0x01 << 4)
+#define STB0899_OFFST_BCLK_IN			4
+#define STB0899_WIDTH_BCLK_IN			1
+#define STB0899_JETONIN_MODE			(0x01 << 3)
+#define STB0899_OFFST_JETONIN_MODE		3
+#define STB0899_WIDTH_JETONIN_MODE		1
+#define STB0899_BCLK_VALUE			(0x01 << 2)
+#define STB0899_OFFST_BCLK_VALUE		2
+#define STB0899_WIDTH_BCLK_VALUE		1
+#define STB0899_SGNRST_T12			(0x01 << 1)
+#define STB0899_OFFST_SGNRST_T12		1
+#define STB0899_WIDTH_SGNRST_T12		1
+#define STB0899_LOWSP_ENAX			(0x01 << 0)
+#define STB0899_OFFST_LOWSP_ENAX		0
+#define STB0899_WIDTH_LOWSP_ENAX		1
+
+#define STB0899_TSTSYS				0xff14
+#define STB0899_TSTCHIP				0xff15
+#define STB0899_TSTFREE				0xff16
+#define STB0899_TSTI2C				0xff17
+#define STB0899_BITSPEEDM			0xff1c
+#define STB0899_BITSPEEDL			0xff1d
+#define STB0899_TBUSBIT				0xff1e
+#define STB0899_TSTDIS				0xff24
+#define STB0899_TSTDISRX			0xff25
+#define STB0899_TSTJETON			0xff28
+#define STB0899_TSTDCADJ			0xff40
+#define STB0899_TSTAGC1				0xff41
+#define STB0899_TSTAGC1N			0xff42
+#define STB0899_TSTPOLYPH			0xff48
+#define STB0899_TSTR				0xff49
+#define STB0899_TSTAGC2				0xff4a
+#define STB0899_TSTCTL1				0xff4b
+#define STB0899_TSTCTL2				0xff4c
+#define STB0899_TSTCTL3				0xff4d
+#define STB0899_TSTDEMAP			0xff50
+#define STB0899_TSTDEMAP2			0xff51
+#define STB0899_TSTDEMMON			0xff52
+#define STB0899_TSTRATE				0xff53
+#define STB0899_TSTSELOUT			0xff54
+#define STB0899_TSYNC				0xff55
+#define STB0899_TSTERR				0xff56
+#define STB0899_TSTRAM1				0xff58
+#define STB0899_TSTVSELOUT			0xff59
+#define STB0899_TSTFORCEIN			0xff5a
+#define STB0899_TSTRS1				0xff5c
+#define STB0899_TSTRS2				0xff5d
+#define STB0899_TSTRS3				0xff53
+
+#define STB0899_INTBUFSTATUS			0xf200
+#define STB0899_INTBUFCTRL			0xf201
+#define STB0899_PCKLENUL			0xf55e
+#define STB0899_PCKLENLL			0xf55f
+#define STB0899_RSPCKLEN			0xf560
+
+/*	2 registers	*/
+#define STB0899_SYNCDCST			0xf60c
+
+/*	DiSEqC	*/
+#define STB0899_DISCNTRL1			0xf0a0
+#define STB0899_TIMOFF				(0x01 << 7)
+#define STB0899_OFFST_TIMOFF			7
+#define STB0899_WIDTH_TIMOFF			1
+#define STB0899_DISEQCRESET			(0x01 << 6)
+#define STB0899_OFFST_DISEQCRESET		6
+#define STB0899_WIDTH_DISEQCRESET		1
+#define STB0899_TIMCMD				(0x03 << 4)
+#define STB0899_OFFST_TIMCMD			4
+#define STB0899_WIDTH_TIMCMD			2
+#define STB0899_DISPRECHARGE			(0x01 << 2)
+#define STB0899_OFFST_DISPRECHARGE		2
+#define STB0899_WIDTH_DISPRECHARGE		1
+#define STB0899_DISEQCMODE			(0x01 << 0)
+#define STB0899_OFFST_DISEQCMODE		0
+#define STB0899_WIDTH_DISEQCMODE		2
+
+#define STB0899_DISCNTRL2			0xf0a1
+#define STB0899_RECEIVER_ON			(0x01 << 7)
+#define STB0899_OFFST_RECEIVER_ON		7
+#define STB0899_WIDTH_RECEIVER_ON		1
+#define STB0899_IGNO_SHORT_22K			(0x01 << 6)
+#define STB0899_OFFST_IGNO_SHORT_22K		6
+#define STB0899_WIDTH_IGNO_SHORT_22K		1
+#define STB0899_ONECHIP_TRX			(0x01 << 5)
+#define STB0899_OFFST_ONECHIP_TRX		5
+#define STB0899_WIDTH_ONECHIP_TRX		1
+#define STB0899_EXT_ENVELOP			(0x01 << 4)
+#define STB0899_OFFST_EXT_ENVELOP		4
+#define STB0899_WIDTH_EXT_ENVELOP		1
+#define STB0899_PIN_SELECT			(0x03 << 2)
+#define STB0899_OFFST_PIN_SELCT			2
+#define STB0899_WIDTH_PIN_SELCT			2
+#define STB0899_IRQ_RXEND			(0x01 << 1)
+#define STB0899_OFFST_IRQ_RXEND			1
+#define STB0899_WIDTH_IRQ_RXEND			1
+#define STB0899_IRQ_4NBYTES			(0x01 << 0)
+#define STB0899_OFFST_IRQ_4NBYTES		0
+#define STB0899_WIDTH_IRQ_4NBYTES		1
+
+#define STB0899_DISRX_ST0			0xf0a4
+#define STB0899_RXEND				(0x01 << 7)
+#define STB0899_OFFST_RXEND			7
+#define STB0899_WIDTH_RXEND			1
+#define STB0899_RXACTIVE			(0x01 << 6)
+#define STB0899_OFFST_RXACTIVE			6
+#define STB0899_WIDTH_RXACTIVE			1
+#define STB0899_SHORT22K			(0x01 << 5)
+#define STB0899_OFFST_SHORT22K			5
+#define STB0899_WIDTH_SHORT22K			1
+#define STB0899_CONTTONE			(0x01 << 4)
+#define STB0899_OFFST_CONTTONE			4
+#define STB0899_WIDTH_CONTONE			1
+#define STB0899_4BFIFOREDY			(0x01 << 3)
+#define STB0899_OFFST_4BFIFOREDY		3
+#define STB0899_WIDTH_4BFIFOREDY		1
+#define STB0899_FIFOEMPTY			(0x01 << 2)
+#define STB0899_OFFST_FIFOEMPTY			2
+#define STB0899_WIDTH_FIFOEMPTY			1
+#define STB0899_ABORTTRX			(0x01 << 0)
+#define STB0899_OFFST_ABORTTRX			0
+#define STB0899_WIDTH_ABORTTRX			1
+
+#define STB0899_DISRX_ST1			0xf0a5
+#define STB0899_RXFAIL				(0x01 << 7)
+#define STB0899_OFFST_RXFAIL			7
+#define STB0899_WIDTH_RXFAIL			1
+#define STB0899_FIFOPFAIL			(0x01 << 6)
+#define STB0899_OFFST_FIFOPFAIL			6
+#define STB0899_WIDTH_FIFOPFAIL			1
+#define STB0899_RXNONBYTES			(0x01 << 5)
+#define STB0899_OFFST_RXNONBYTES		5
+#define STB0899_WIDTH_RXNONBYTES		1
+#define STB0899_FIFOOVF				(0x01 << 4)
+#define STB0899_OFFST_FIFOOVF			4
+#define STB0899_WIDTH_FIFOOVF			1
+#define STB0899_FIFOBYTENBR			(0x0f << 0)
+#define STB0899_OFFST_FIFOBYTENBR		0
+#define STB0899_WIDTH_FIFOBYTENBR		4
+
+#define STB0899_DISPARITY			0xf0a6
+
+#define STB0899_DISFIFO				0xf0a7
+
+#define STB0899_DISSTATUS			0xf0a8
+#define STB0899_FIFOFULL			(0x01 << 6)
+#define STB0899_OFFST_FIFOFULL			6
+#define STB0899_WIDTH_FIFOFULL			1
+#define STB0899_TXIDLE				(0x01 << 5)
+#define STB0899_OFFST_TXIDLE			5
+#define STB0899_WIDTH_TXIDLE			1
+#define STB0899_GAPBURST			(0x01 << 4)
+#define STB0899_OFFST_GAPBURST			4
+#define STB0899_WIDTH_GAPBURST			1
+#define STB0899_TXFIFOBYTES			(0x0f << 0)
+#define STB0899_OFFST_TXFIFOBYTES		0
+#define STB0899_WIDTH_TXFIFOBYTES		4
+#define STB0899_DISF22				0xf0a9
+
+#define STB0899_DISF22RX			0xf0aa
+
+/*	General Purpose	*/
+#define STB0899_SYSREG				0xf101
+#define STB0899_ACRPRESC			0xf110
+#define STB0899_ACRDIV1				0xf111
+#define STB0899_ACRDIV2				0xf112
+#define STB0899_DACR1				0xf113
+#define STB0899_DACR2				0xf114
+#define STB0899_OUTCFG				0xf11c
+#define STB0899_MODECFG				0xf11d
+#define STB0899_NCOARSE				0xf1b3
+
+#define STB0899_SYNTCTRL			0xf1b6
+#define STB0899_STANDBY				(0x01 << 7)
+#define STB0899_OFFST_STANDBY			7
+#define STB0899_WIDTH_STANDBY			1
+#define STB0899_BYPASSPLL			(0x01 << 6)
+#define STB0899_OFFST_BYPASSPLL			6
+#define STB0899_WIDTH_BYPASSPLL			1
+#define STB0899_SEL1XRATIO			(0x01 << 5)
+#define STB0899_OFFST_SEL1XRATIO		5
+#define STB0899_WIDTH_SEL1XRATIO		1
+#define STB0899_SELOSCI				(0x01 << 1)
+#define STB0899_OFFST_SELOSCI			1
+#define STB0899_WIDTH_SELOSCI			1
+
+#define STB0899_FILTCTRL			0xf1b7
+#define STB0899_SYSCTRL				0xf1b8
+
+#define STB0899_STOPCLK1			0xf1c2
+#define STB0899_STOP_CKINTBUF108		(0x01 << 7)
+#define STB0899_OFFST_STOP_CKINTBUF108		7
+#define STB0899_WIDTH_STOP_CKINTBUF108		1
+#define STB0899_STOP_CKINTBUF216		(0x01 << 6)
+#define STB0899_OFFST_STOP_CKINTBUF216		6
+#define STB0899_WIDTH_STOP_CKINTBUF216		1
+#define STB0899_STOP_CHK8PSK			(0x01 << 5)
+#define STB0899_OFFST_STOP_CHK8PSK		5
+#define STB0899_WIDTH_STOP_CHK8PSK		1
+#define STB0899_STOP_CKFEC108			(0x01 << 4)
+#define STB0899_OFFST_STOP_CKFEC108		4
+#define STB0899_WIDTH_STOP_CKFEC108		1
+#define STB0899_STOP_CKFEC216			(0x01 << 3)
+#define STB0899_OFFST_STOP_CKFEC216		3
+#define STB0899_WIDTH_STOP_CKFEC216		1
+#define STB0899_STOP_CKCORE216			(0x01 << 2)
+#define STB0899_OFFST_STOP_CKCORE216		2
+#define STB0899_WIDTH_STOP_CKCORE216		1
+#define STB0899_STOP_CKADCI108			(0x01 << 1)
+#define STB0899_OFFST_STOP_CKADCI108		1
+#define STB0899_WIDTH_STOP_CKADCI108		1
+#define STB0899_STOP_INVCKADCI108		(0x01 << 0)
+#define STB0899_OFFST_STOP_INVCKADCI108		0
+#define STB0899_WIDTH_STOP_INVCKADCI108		1
+
+#define STB0899_STOPCLK2			0xf1c3
+#define STB0899_STOP_CKS2DMD108			(0x01 << 2)
+#define STB0899_OFFST_STOP_CKS2DMD108		2
+#define STB0899_WIDTH_STOP_CKS2DMD108		1
+#define STB0899_STOP_CKPKDLIN108		(0x01 << 1)
+#define STB0899_OFFST_STOP_CKPKDLIN108		1
+#define STB0899_WIDTH_STOP_CKPKDLIN108		1
+#define STB0899_STOP_CKPKDLIN216		(0x01 << 0)
+#define STB0899_OFFST_STOP_CKPKDLIN216		0
+#define STB0899_WIDTH_STOP_CKPKDLIN216		1
+
+#define STB0899_TSTTNR1				0xf1e0
+#define STB0899_BYPASS_ADC			(0x01 << 7)
+#define STB0899_OFFST_BYPASS_ADC		7
+#define STB0899_WIDTH_BYPASS_ADC		1
+#define STB0899_INVADCICKOUT			(0x01 << 6)
+#define STB0899_OFFST_INVADCICKOUT		6
+#define STB0899_WIDTH_INVADCICKOUT		1
+#define STB0899_ADCTEST_VOLTAGE			(0x03 << 4)
+#define STB0899_OFFST_ADCTEST_VOLTAGE		4
+#define STB0899_WIDTH_ADCTEST_VOLTAGE		1
+#define STB0899_ADC_RESET			(0x01 << 3)
+#define STB0899_OFFST_ADC_RESET			3
+#define STB0899_WIDTH_ADC_RESET			1
+#define STB0899_TSTTNR1_2			(0x01 << 2)
+#define STB0899_OFFST_TSTTNR1_2			2
+#define STB0899_WIDTH_TSTTNR1_2			1
+#define STB0899_ADCPON				(0x01 << 1)
+#define STB0899_OFFST_ADCPON			1
+#define STB0899_WIDTH_ADCPON			1
+#define STB0899_ADCIN_MODE			(0x01 << 0)
+#define STB0899_OFFST_ADCIN_MODE		0
+#define STB0899_WIDTH_ADCIN_MODE		1
+
+#define STB0899_TSTTNR2				0xf1e1
+#define STB0899_TSTTNR2_7			(0x01 << 7)
+#define STB0899_OFFST_TSTTNR2_7			7
+#define STB0899_WIDTH_TSTTNR2_7			1
+#define STB0899_NOT_DISRX_WIRED			(0x01 << 6)
+#define STB0899_OFFST_NOT_DISRX_WIRED		6
+#define STB0899_WIDTH_NOT_DISRX_WIRED		1
+#define STB0899_DISEQC_DCURRENT			(0x01 << 5)
+#define STB0899_OFFST_DISEQC_DCURRENT		5
+#define STB0899_WIDTH_DISEQC_DCURRENT		1
+#define STB0899_DISEQC_ZCURRENT			(0x01 << 4)
+#define STB0899_OFFST_DISEQC_ZCURRENT		4
+#define STB0899_WIDTH_DISEQC_ZCURRENT		1
+#define STB0899_DISEQC_SINC_SOURCE		(0x03 << 2)
+#define STB0899_OFFST_DISEQC_SINC_SOURCE	2
+#define STB0899_WIDTH_DISEQC_SINC_SOURCE	2
+#define STB0899_SELIQSRC			(0x03 << 0)
+#define STB0899_OFFST_SELIQSRC			0
+#define STB0899_WIDTH_SELIQSRC			2
+
+#define STB0899_TSTTNR3				0xf1e2
+
+#define STB0899_I2CCFG				0xf129
+#define STB0899_I2CCFGRSVD			(0x0f << 4)
+#define STB0899_OFFST_I2CCFGRSVD		4
+#define STB0899_WIDTH_I2CCFGRSVD		4
+#define STB0899_I2CFASTMODE			(0x01 << 3)
+#define STB0899_OFFST_I2CFASTMODE		3
+#define STB0899_WIDTH_I2CFASTMODE		1
+#define STB0899_STATUSWR			(0x01 << 2)
+#define STB0899_OFFST_STATUSWR			2
+#define STB0899_WIDTH_STATUSWR			1
+#define STB0899_I2CADDRINC			(0x03 << 0)
+#define STB0899_OFFST_I2CADDRINC		0
+#define STB0899_WIDTH_I2CADDRINC		2
+
+#define STB0899_I2CRPT				0xf12a
+#define STB0899_I2CTON				(0x01 << 7)
+#define STB0899_OFFST_I2CTON			7
+#define STB0899_WIDTH_I2CTON			1
+#define STB0899_ENARPTLEVEL			(0x01 << 6)
+#define STB0899_OFFST_ENARPTLEVEL		6
+#define STB0899_WIDTH_ENARPTLEVEL		2
+#define STB0899_SCLTDELAY			(0x01 << 3)
+#define STB0899_OFFST_SCLTDELAY			3
+#define STB0899_WIDTH_SCLTDELAY			1
+#define STB0899_STOPENA				(0x01 << 2)
+#define STB0899_OFFST_STOPENA			2
+#define STB0899_WIDTH_STOPENA			1
+#define STB0899_STOPSDAT2SDA			(0x01 << 1)
+#define STB0899_OFFST_STOPSDAT2SDA		1
+#define STB0899_WIDTH_STOPSDAT2SDA		1
+
+#define STB0899_IOPVALUE8			0xf136
+#define STB0899_IOPVALUE7			0xf137
+#define STB0899_IOPVALUE6			0xf138
+#define STB0899_IOPVALUE5			0xf139
+#define STB0899_IOPVALUE4			0xf13a
+#define STB0899_IOPVALUE3			0xf13b
+#define STB0899_IOPVALUE2			0xf13c
+#define STB0899_IOPVALUE1			0xf13d
+#define STB0899_IOPVALUE0			0xf13e
+
+#define STB0899_GPIO00CFG			0xf140
+
+#define STB0899_GPIO01CFG			0xf141
+#define STB0899_GPIO02CFG			0xf142
+#define STB0899_GPIO03CFG			0xf143
+#define STB0899_GPIO04CFG			0xf144
+#define STB0899_GPIO05CFG			0xf145
+#define STB0899_GPIO06CFG			0xf146
+#define STB0899_GPIO07CFG			0xf147
+#define STB0899_GPIO08CFG			0xf148
+#define STB0899_GPIO09CFG			0xf149
+#define STB0899_GPIO10CFG			0xf14a
+#define STB0899_GPIO11CFG			0xf14b
+#define STB0899_GPIO12CFG			0xf14c
+#define STB0899_GPIO13CFG			0xf14d
+#define STB0899_GPIO14CFG			0xf14e
+#define STB0899_GPIO15CFG			0xf14f
+#define STB0899_GPIO16CFG			0xf150
+#define STB0899_GPIO17CFG			0xf151
+#define STB0899_GPIO18CFG			0xf152
+#define STB0899_GPIO19CFG			0xf153
+#define STB0899_GPIO20CFG			0xf154
+
+#define STB0899_SDATCFG				0xf155
+#define STB0899_SCLTCFG				0xf156
+#define STB0899_AGCRFCFG			0xf157
+#define STB0899_GPIO22				0xf158	/* AGCBB2CFG	*/
+#define STB0899_GPIO21				0xf159  /* AGCBB1CFG	*/
+#define STB0899_DIRCLKCFG			0xf15a
+#define STB0899_CLKOUT27CFG			0xf15b
+#define STB0899_STDBYCFG			0xf15c
+#define STB0899_CS0CFG				0xf15d
+#define STB0899_CS1CFG				0xf15e
+#define STB0899_DISEQCOCFG			0xf15f
+
+#define STB0899_GPIO32CFG			0xf160
+#define STB0899_GPIO33CFG			0xf161
+#define STB0899_GPIO34CFG			0xf162
+#define STB0899_GPIO35CFG			0xf163
+#define STB0899_GPIO36CFG			0xf164
+#define STB0899_GPIO37CFG			0xf165
+#define STB0899_GPIO38CFG			0xf166
+#define STB0899_GPIO39CFG			0xf167
+
+#define STB0899_IRQSTATUS_3			0xf120
+#define STB0899_IRQSTATUS_2			0xf121
+#define STB0899_IRQSTATUS_1			0xf122
+#define STB0899_IRQSTATUS_0			0xf123
+
+#define STB0899_IRQMSK_3			0xf124
+#define STB0899_IRQMSK_2			0xf125
+#define STB0899_IRQMSK_1			0xf126
+#define STB0899_IRQMSK_0			0xf127
+
+#define STB0899_IRQCFG				0xf128
+
+#define STB0899_GHOSTREG			0xf000
+
+#define STB0899_S2DEMOD				0xf3fc
+#define STB0899_S2FEC				0xfafc
+
+
+#endif