V4L/DVB (9375): Add STB0899 support
authorManu Abraham <abraham.manu@gmail.com>
Tue, 3 Jul 2007 12:53:42 +0000 (09:53 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 29 Dec 2008 19:53:13 +0000 (17:53 -0200)
Signed-off-by: Manu Abraham <manu@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/dvb/frontends/stb0899_algo.c [new file with mode: 0644]
drivers/media/dvb/frontends/stb0899_drv.c [new file with mode: 0644]
drivers/media/dvb/frontends/stb0899_drv.h [new file with mode: 0644]
drivers/media/dvb/frontends/stb0899_priv.h [new file with mode: 0644]
drivers/media/dvb/frontends/stb0899_reg.h [new file with mode: 0644]

diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb/frontends/stb0899_algo.c
new file mode 100644 (file)
index 0000000..0ae9649
--- /dev/null
@@ -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 (file)
index 0000000..3cb9b48
--- /dev/null
@@ -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 (file)
index 0000000..52c2ce1
--- /dev/null
@@ -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 (file)
index 0000000..47e533d
--- /dev/null
@@ -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 (file)
index 0000000..6d2dc79
--- /dev/null
@@ -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