Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / media / dvb / frontends / dib3000mb.c
index 37eaa74..ae589ad 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Frontend driver for mobile DVB-T demodulator DiBcom 3000-MB
+ * Frontend driver for mobile DVB-T demodulator DiBcom 3000M-B
  * DiBcom (http://www.dibcom.fr/)
  *
- * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
  *
  * based on GPL code from DibCom, which has
  *
 
 #include <linux/config.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
-#include "dvb_frontend.h"
 #include "dib3000-common.h"
 #include "dib3000mb_priv.h"
 #include "dib3000.h"
 
 /* Version information */
 #define DRIVER_VERSION "0.1"
-#define DRIVER_DESC "DiBcom 3000-MB DVB-T demodulator driver"
+#define DRIVER_DESC "DiBcom 3000M-B DVB-T demodulator"
 #define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
 
 #ifdef CONFIG_DVB_DIBCOM_DEBUG
 static int debug;
-module_param(debug, int, 0x644);
+module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able)).");
 #endif
 #define deb_info(args...) dprintk(0x01,args)
@@ -53,36 +53,32 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe,
                                  struct dvb_frontend_parameters *fep);
 
 static int dib3000mb_set_frontend(struct dvb_frontend* fe,
-               struct dvb_frontend_parameters *fep, int tuner)
+                                 struct dvb_frontend_parameters *fep, int tuner)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
        struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
        fe_code_rate_t fe_cr = FEC_NONE;
-       int search_state,seq;
+       int search_state, seq;
 
-       if (tuner) {
-               wr(DIB3000MB_REG_TUNER,
-                               DIB3000_TUNER_WRITE_ENABLE(state->config.pll_addr));
+       if (tuner && state->config.pll_set) {
                state->config.pll_set(fe, fep);
-               wr(DIB3000MB_REG_TUNER,
-                               DIB3000_TUNER_WRITE_DISABLE(state->config.pll_addr));
 
                deb_setf("bandwidth: ");
                switch (ofdm->bandwidth) {
                        case BANDWIDTH_8_MHZ:
                                deb_setf("8 MHz\n");
-                               wr_foreach(dib3000mb_reg_timing_freq,dib3000mb_timing_freq[2]);
-                               wr_foreach(dib3000mb_reg_bandwidth,dib3000mb_bandwidth_8mhz);
+                               wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]);
+                               wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz);
                                break;
                        case BANDWIDTH_7_MHZ:
                                deb_setf("7 MHz\n");
-                               wr_foreach(dib3000mb_reg_timing_freq,dib3000mb_timing_freq[1]);
-                               wr_foreach(dib3000mb_reg_bandwidth,dib3000mb_bandwidth_7mhz);
+                               wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[1]);
+                               wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_7mhz);
                                break;
                        case BANDWIDTH_6_MHZ:
                                deb_setf("6 MHz\n");
-                               wr_foreach(dib3000mb_reg_timing_freq,dib3000mb_timing_freq[0]);
-                               wr_foreach(dib3000mb_reg_bandwidth,dib3000mb_bandwidth_6mhz);
+                               wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[0]);
+                               wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_6mhz);
                                break;
                        case BANDWIDTH_AUTO:
                                return -EOPNOTSUPP;
@@ -91,7 +87,7 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe,
                                return -EINVAL;
                }
        }
-       wr(DIB3000MB_REG_LOCK1_MASK,DIB3000MB_LOCK1_SEARCH_4);
+       wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
 
        deb_setf("transmission mode: ");
        switch (ofdm->transmission_mode) {
@@ -171,25 +167,25 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe,
                default:
                        return -EINVAL;
        }
-       deb_setf("hierachy: "); 
+       deb_setf("hierachy: ");
        switch (ofdm->hierarchy_information) {
                case HIERARCHY_NONE:
                        deb_setf("none ");
                        /* fall through */
                case HIERARCHY_1:
-                       deb_setf("alpha=1\n");  
+                       deb_setf("alpha=1\n");
                        wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_1);
                        break;
                case HIERARCHY_2:
-                       deb_setf("alpha=2\n");  
+                       deb_setf("alpha=2\n");
                        wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_2);
                        break;
                case HIERARCHY_4:
-                       deb_setf("alpha=4\n");  
+                       deb_setf("alpha=4\n");
                        wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_4);
                        break;
                case HIERARCHY_AUTO:
-                       deb_setf("alpha=auto\n");       
+                       deb_setf("alpha=auto\n");
                        break;
                default:
                        return -EINVAL;
@@ -244,39 +240,39 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe,
                [ofdm->guard_interval == GUARD_INTERVAL_AUTO]
                [fep->inversion == INVERSION_AUTO];
 
-       deb_setf("seq? %d\n",seq);
+       deb_setf("seq? %d\n", seq);
 
-       wr(DIB3000MB_REG_SEQ,seq);
+       wr(DIB3000MB_REG_SEQ, seq);
 
-       wr(DIB3000MB_REG_ISI,seq ? DIB3000MB_ISI_INHIBIT : DIB3000MB_ISI_ACTIVATE);
+       wr(DIB3000MB_REG_ISI, seq ? DIB3000MB_ISI_INHIBIT : DIB3000MB_ISI_ACTIVATE);
 
        if (ofdm->transmission_mode == TRANSMISSION_MODE_2K) {
                if (ofdm->guard_interval == GUARD_INTERVAL_1_8) {
-                       wr(DIB3000MB_REG_SYNC_IMPROVEMENT,DIB3000MB_SYNC_IMPROVE_2K_1_8);
+                       wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_2K_1_8);
                } else {
-                       wr(DIB3000MB_REG_SYNC_IMPROVEMENT,DIB3000MB_SYNC_IMPROVE_DEFAULT);
+                       wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_DEFAULT);
                }
 
-               wr(DIB3000MB_REG_UNK_121,DIB3000MB_UNK_121_2K);
+               wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_2K);
        } else {
-               wr(DIB3000MB_REG_UNK_121,DIB3000MB_UNK_121_DEFAULT);
+               wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_DEFAULT);
        }
 
-       wr(DIB3000MB_REG_MOBILE_ALGO,DIB3000MB_MOBILE_ALGO_OFF);
-       wr(DIB3000MB_REG_MOBILE_MODE_QAM,DIB3000MB_MOBILE_MODE_QAM_OFF);
-       wr(DIB3000MB_REG_MOBILE_MODE,DIB3000MB_MOBILE_MODE_OFF);
+       wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_OFF);
+       wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF);
+       wr(DIB3000MB_REG_MOBILE_MODE, DIB3000MB_MOBILE_MODE_OFF);
 
-       wr_foreach(dib3000mb_reg_agc_bandwidth,dib3000mb_agc_bandwidth_high);
+       wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_high);
 
-       wr(DIB3000MB_REG_ISI,DIB3000MB_ISI_ACTIVATE);
+       wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_ACTIVATE);
 
-       wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_AGC+DIB3000MB_RESTART_CTRL);
-       wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_OFF);
+       wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC + DIB3000MB_RESTART_CTRL);
+       wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
 
        /* wait for AGC lock */
        msleep(70);
 
-       wr_foreach(dib3000mb_reg_agc_bandwidth,dib3000mb_agc_bandwidth_low);
+       wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low);
 
        /* something has to be auto searched */
        if (ofdm->constellation == QAM_AUTO ||
@@ -285,12 +281,12 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe,
                fep->inversion == INVERSION_AUTO) {
                int as_count=0;
 
-               deb_setf("autosearch enabled.\n");      
+               deb_setf("autosearch enabled.\n");
 
-               wr(DIB3000MB_REG_ISI,DIB3000MB_ISI_INHIBIT);
+               wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT);
 
-               wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_AUTO_SEARCH);
-               wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_OFF);
+               wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AUTO_SEARCH);
+               wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
 
                while ((search_state =
                                dib3000_search_status(
@@ -298,7 +294,7 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe,
                                        rd(DIB3000MB_REG_LOCK2_VALUE))) < 0 && as_count++ < 100)
                        msleep(1);
 
-               deb_info("search_state after autosearch %d after %d checks\n",search_state,as_count);
+               deb_setf("search_state after autosearch %d after %d checks\n",search_state,as_count);
 
                if (search_state == 1) {
                        struct dvb_frontend_parameters feps;
@@ -309,8 +305,8 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe,
                }
 
        } else {
-               wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_CTRL);
-               wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_OFF);
+               wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_CTRL);
+               wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
        }
 
        return 0;
@@ -318,84 +314,80 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe,
 
 static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
 
-       wr(DIB3000MB_REG_POWER_CONTROL,DIB3000MB_POWER_UP);
+       deb_info("dib3000mb is getting up.\n");
+       wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_UP);
 
        wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC);
 
-       wr(DIB3000MB_REG_RESET_DEVICE,DIB3000MB_RESET_DEVICE);
-       wr(DIB3000MB_REG_RESET_DEVICE,DIB3000MB_RESET_DEVICE_RST);
+       wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE);
+       wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE_RST);
 
-       wr(DIB3000MB_REG_CLOCK,DIB3000MB_CLOCK_DEFAULT);
+       wr(DIB3000MB_REG_CLOCK, DIB3000MB_CLOCK_DEFAULT);
 
-       wr(DIB3000MB_REG_ELECT_OUT_MODE,DIB3000MB_ELECT_OUT_MODE_ON);
+       wr(DIB3000MB_REG_ELECT_OUT_MODE, DIB3000MB_ELECT_OUT_MODE_ON);
 
-       wr(DIB3000MB_REG_DDS_FREQ_MSB,DIB3000MB_DDS_FREQ_MSB);
-       wr(DIB3000MB_REG_DDS_FREQ_LSB,DIB3000MB_DDS_FREQ_LSB);
+       wr(DIB3000MB_REG_DDS_FREQ_MSB, DIB3000MB_DDS_FREQ_MSB);
+       wr(DIB3000MB_REG_DDS_FREQ_LSB, DIB3000MB_DDS_FREQ_LSB);
 
-       wr_foreach(dib3000mb_reg_timing_freq,dib3000mb_timing_freq[2]);
+       wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]);
 
        wr_foreach(dib3000mb_reg_impulse_noise,
                        dib3000mb_impulse_noise_values[DIB3000MB_IMPNOISE_OFF]);
 
-       wr_foreach(dib3000mb_reg_agc_gain,dib3000mb_default_agc_gain);
+       wr_foreach(dib3000mb_reg_agc_gain, dib3000mb_default_agc_gain);
 
-       wr(DIB3000MB_REG_PHASE_NOISE,DIB3000MB_PHASE_NOISE_DEFAULT);
+       wr(DIB3000MB_REG_PHASE_NOISE, DIB3000MB_PHASE_NOISE_DEFAULT);
 
        wr_foreach(dib3000mb_reg_phase_noise, dib3000mb_default_noise_phase);
 
-       wr_foreach(dib3000mb_reg_lock_duration,dib3000mb_default_lock_duration);
+       wr_foreach(dib3000mb_reg_lock_duration, dib3000mb_default_lock_duration);
 
-       wr_foreach(dib3000mb_reg_agc_bandwidth,dib3000mb_agc_bandwidth_low);
+       wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low);
 
-       wr(DIB3000MB_REG_LOCK0_MASK,DIB3000MB_LOCK0_DEFAULT);
-       wr(DIB3000MB_REG_LOCK1_MASK,DIB3000MB_LOCK1_SEARCH_4);
-       wr(DIB3000MB_REG_LOCK2_MASK,DIB3000MB_LOCK2_DEFAULT);
+       wr(DIB3000MB_REG_LOCK0_MASK, DIB3000MB_LOCK0_DEFAULT);
+       wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
+       wr(DIB3000MB_REG_LOCK2_MASK, DIB3000MB_LOCK2_DEFAULT);
        wr(DIB3000MB_REG_SEQ, dib3000_seq[1][1][1]);
 
-       wr_foreach(dib3000mb_reg_bandwidth,dib3000mb_bandwidth_8mhz);
-
-       wr(DIB3000MB_REG_UNK_68,DIB3000MB_UNK_68);
-       wr(DIB3000MB_REG_UNK_69,DIB3000MB_UNK_69);
-       wr(DIB3000MB_REG_UNK_71,DIB3000MB_UNK_71);
-       wr(DIB3000MB_REG_UNK_77,DIB3000MB_UNK_77);
-       wr(DIB3000MB_REG_UNK_78,DIB3000MB_UNK_78);
-       wr(DIB3000MB_REG_ISI,DIB3000MB_ISI_INHIBIT);
-       wr(DIB3000MB_REG_UNK_92,DIB3000MB_UNK_92);
-       wr(DIB3000MB_REG_UNK_96,DIB3000MB_UNK_96);
-       wr(DIB3000MB_REG_UNK_97,DIB3000MB_UNK_97);
-       wr(DIB3000MB_REG_UNK_106,DIB3000MB_UNK_106);
-       wr(DIB3000MB_REG_UNK_107,DIB3000MB_UNK_107);
-       wr(DIB3000MB_REG_UNK_108,DIB3000MB_UNK_108);
-       wr(DIB3000MB_REG_UNK_122,DIB3000MB_UNK_122);
-       wr(DIB3000MB_REG_MOBILE_MODE_QAM,DIB3000MB_MOBILE_MODE_QAM_OFF);
-       wr(DIB3000MB_REG_BERLEN,DIB3000MB_BERLEN_DEFAULT);
-
-       wr_foreach(dib3000mb_reg_filter_coeffs,dib3000mb_filter_coeffs);
-
-       wr(DIB3000MB_REG_MOBILE_ALGO,DIB3000MB_MOBILE_ALGO_ON);
-       wr(DIB3000MB_REG_MULTI_DEMOD_MSB,DIB3000MB_MULTI_DEMOD_MSB);
-       wr(DIB3000MB_REG_MULTI_DEMOD_LSB,DIB3000MB_MULTI_DEMOD_LSB);
-
-       wr(DIB3000MB_REG_OUTPUT_MODE,DIB3000MB_OUTPUT_MODE_SLAVE);
-
-       wr(DIB3000MB_REG_FIFO_142,DIB3000MB_FIFO_142);
-       wr(DIB3000MB_REG_MPEG2_OUT_MODE,DIB3000MB_MPEG2_OUT_MODE_188);
+       wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz);
+
+       wr(DIB3000MB_REG_UNK_68, DIB3000MB_UNK_68);
+       wr(DIB3000MB_REG_UNK_69, DIB3000MB_UNK_69);
+       wr(DIB3000MB_REG_UNK_71, DIB3000MB_UNK_71);
+       wr(DIB3000MB_REG_UNK_77, DIB3000MB_UNK_77);
+       wr(DIB3000MB_REG_UNK_78, DIB3000MB_UNK_78);
+       wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT);
+       wr(DIB3000MB_REG_UNK_92, DIB3000MB_UNK_92);
+       wr(DIB3000MB_REG_UNK_96, DIB3000MB_UNK_96);
+       wr(DIB3000MB_REG_UNK_97, DIB3000MB_UNK_97);
+       wr(DIB3000MB_REG_UNK_106, DIB3000MB_UNK_106);
+       wr(DIB3000MB_REG_UNK_107, DIB3000MB_UNK_107);
+       wr(DIB3000MB_REG_UNK_108, DIB3000MB_UNK_108);
+       wr(DIB3000MB_REG_UNK_122, DIB3000MB_UNK_122);
+       wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF);
+       wr(DIB3000MB_REG_BERLEN, DIB3000MB_BERLEN_DEFAULT);
+
+       wr_foreach(dib3000mb_reg_filter_coeffs, dib3000mb_filter_coeffs);
+
+       wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_ON);
+       wr(DIB3000MB_REG_MULTI_DEMOD_MSB, DIB3000MB_MULTI_DEMOD_MSB);
+       wr(DIB3000MB_REG_MULTI_DEMOD_LSB, DIB3000MB_MULTI_DEMOD_LSB);
+
+       wr(DIB3000MB_REG_OUTPUT_MODE, DIB3000MB_OUTPUT_MODE_SLAVE);
+
+       wr(DIB3000MB_REG_FIFO_142, DIB3000MB_FIFO_142);
+       wr(DIB3000MB_REG_MPEG2_OUT_MODE, DIB3000MB_MPEG2_OUT_MODE_188);
        wr(DIB3000MB_REG_PID_PARSE, DIB3000MB_PID_PARSE_ACTIVATE);
-       wr(DIB3000MB_REG_FIFO,DIB3000MB_FIFO_INHIBIT);
-       wr(DIB3000MB_REG_FIFO_146,DIB3000MB_FIFO_146);
-       wr(DIB3000MB_REG_FIFO_147,DIB3000MB_FIFO_147);
+       wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);
+       wr(DIB3000MB_REG_FIFO_146, DIB3000MB_FIFO_146);
+       wr(DIB3000MB_REG_FIFO_147, DIB3000MB_FIFO_147);
 
-       wr(DIB3000MB_REG_DATA_IN_DIVERSITY,DIB3000MB_DATA_DIVERSITY_IN_OFF);
+       wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF);
 
-       if (state->config.pll_init) {
-               wr(DIB3000MB_REG_TUNER,
-                       DIB3000_TUNER_WRITE_ENABLE(state->config.pll_addr));
+       if (state->config.pll_init)
                state->config.pll_init(fe);
-               wr(DIB3000MB_REG_TUNER,
-                       DIB3000_TUNER_WRITE_DISABLE(state->config.pll_addr));
-       }
 
        return 0;
 }
@@ -403,7 +395,7 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode)
 static int dib3000mb_get_frontend(struct dvb_frontend* fe,
                                  struct dvb_frontend_parameters *fep)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
        struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
        fe_code_rate_t *cr;
        u16 tps_val;
@@ -414,6 +406,7 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe,
                return 0;
 
        dds_val = ((rd(DIB3000MB_REG_DDS_VALUE_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_VALUE_LSB);
+       deb_getf("DDS_VAL: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_VALUE_MSB), rd(DIB3000MB_REG_DDS_VALUE_LSB));
        if (dds_val < threshold)
                inv_test1 = 0;
        else if (dds_val == threshold)
@@ -422,6 +415,7 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe,
                inv_test1 = 2;
 
        dds_val = ((rd(DIB3000MB_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_FREQ_LSB);
+       deb_getf("DDS_FREQ: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_FREQ_MSB), rd(DIB3000MB_REG_DDS_FREQ_LSB));
        if (dds_val < threshold)
                inv_test2 = 0;
        else if (dds_val == threshold)
@@ -452,7 +446,7 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe,
                default:
                        err("Unexpected constellation returned by TPS (%d)", tps_val);
                        break;
-       }
+       }
        deb_getf("TPS: %d\n", tps_val);
 
        if (rd(DIB3000MB_REG_TPS_HRCH)) {
@@ -562,7 +556,7 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe,
 
 static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
 
        *stat = 0;
 
@@ -575,16 +569,9 @@ static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat)
        if (rd(DIB3000MB_REG_TS_SYNC_LOCK))
                *stat |= (FE_HAS_SYNC | FE_HAS_LOCK);
 
-       deb_info("actual status is %2x\n",*stat);
+       deb_getf("actual status is %2x\n",*stat);
 
-       deb_getf("tps %x %x %x %x %x\n",
-                       rd(DIB3000MB_REG_TPS_1),
-                       rd(DIB3000MB_REG_TPS_2),
-                       rd(DIB3000MB_REG_TPS_3),
-                       rd(DIB3000MB_REG_TPS_4),
-                       rd(DIB3000MB_REG_TPS_5));
-       
-       deb_info("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n",
+       deb_getf("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n",
                        rd(DIB3000MB_REG_TPS_LOCK),
                        rd(DIB3000MB_REG_TPS_QAM),
                        rd(DIB3000MB_REG_TPS_HRCH),
@@ -601,99 +588,50 @@ static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat)
 
 static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
 
-       *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB) );
+       *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB));
        return 0;
 }
-/*
- * Amaury:
- * signal strength is measured with dBm (power compared to mW)
- * the standard range is -90dBm(low power) to -10 dBm (strong power),
- * but the calibration is done for -100 dBm to 0dBm
- */
 
-#define DIB3000MB_AGC_REF_dBm          -14
-#define DIB3000MB_GAIN_SLOPE_dBm       100
-#define DIB3000MB_GAIN_DELTA_dBm       -2
+/* see dib3000-watch dvb-apps for exact calcuations of signal_strength and snr */
 static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
-
-/* TODO log10 
-       u16 sigpow = rd(DIB3000MB_REG_SIGNAL_POWER), 
-               n_agc_power = rd(DIB3000MB_REG_AGC_POWER),
-               rf_power = rd(DIB3000MB_REG_RF_POWER);
-       double rf_power_dBm, ad_power_dBm, minar_power_dBm;
-       
-       if (n_agc_power == 0 )
-               n_agc_power = 1 ;
-
-       ad_power_dBm    = 10 * log10 ( (float)n_agc_power / (float)(1<<16) );
-       minor_power_dBm = ad_power_dBm - DIB3000MB_AGC_REF_dBm;
-       rf_power_dBm = (-DIB3000MB_GAIN_SLOPE_dBm * (float)rf_power / (float)(1<<16) + 
-                       DIB3000MB_GAIN_DELTA_dBm) + minor_power_dBm;
-       // relative rf_power 
-       *strength = (u16) ((rf_power_dBm + 100) / 100 * 0xffff);
-*/
+       struct dib3000_state* state = fe->demodulator_priv;
+
        *strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170;
        return 0;
 }
 
-/*
- * Amaury: 
- * snr is the signal quality measured in dB.
- * snr = 10*log10(signal power / noise power)
- * the best quality is near 35dB (cable transmission & good modulator)
- * the minimum without errors depend of transmission parameters
- * some indicative values are given in en300744 Annex A
- * ex : 16QAM 2/3 (Gaussian)  = 11.1 dB
- *
- * If SNR is above 20dB, BER should be always 0.
- * choose 0dB as the minimum
- */
 static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
        short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER);
        int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) |
                rd(DIB3000MB_REG_NOISE_POWER_LSB);
-/*
-       float snr_dBm=0;
-
-       if (sigpow > 0 && icipow > 0)
-               snr_dBm = 10.0 * log10( (float) (sigpow<<8) / (float)icipow )  ;
-       else if (sigpow > 0)
-               snr_dBm = 35;
-       
-       *snr = (u16) ((snr_dBm / 35) * 0xffff);
-*/
        *snr = (sigpow << 8) / ((icipow > 0) ? icipow : 1);
        return 0;
 }
 
 static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
 
-       *unc = rd(DIB3000MB_REG_UNC);
+       *unc = rd(DIB3000MB_REG_PACKET_ERROR_RATE);
        return 0;
 }
 
 static int dib3000mb_sleep(struct dvb_frontend* fe)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
-
-       wr(DIB3000MB_REG_POWER_CONTROL,DIB3000MB_POWER_DOWN);
+       struct dib3000_state* state = fe->demodulator_priv;
+       deb_info("dib3000mb is going to bed.\n");
+       wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_DOWN);
        return 0;
 }
 
 static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
 {
        tune->min_delay_ms = 800;
-       tune->step_size = 166667;
-       tune->max_drift = 166667*2;
-                                       
        return 0;
 }
 
@@ -709,29 +647,22 @@ static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_
 
 static void dib3000mb_release(struct dvb_frontend* fe)
 {
-       struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state *state = fe->demodulator_priv;
        kfree(state);
 }
 
 /* pid filter and transfer stuff */
-static int dib3000mb_pid_control(struct dvb_frontend *fe,int pid,int onoff)
+static int dib3000mb_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
 {
        struct dib3000_state *state = fe->demodulator_priv;
-       int index = dib3000_get_pid_index(state->pid_list, DIB3000MB_NUM_PIDS, pid, &state->pid_list_lock,onoff);
        pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);
-
-       if (index >= 0) {
-               wr(index+DIB3000MB_REG_FIRST_PID,pid);
-       } else {
-               err("no more pids for filtering.");
-               return -ENOMEM;
-       }
+       wr(index+DIB3000MB_REG_FIRST_PID,pid);
        return 0;
 }
 
 static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff)
 {
-       struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state *state = fe->demodulator_priv;
 
        deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
        if (onoff) {
@@ -740,24 +671,36 @@ static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff)
                wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);
        }
        return 0;
-       }
+}
 
 static int dib3000mb_pid_parse(struct dvb_frontend *fe, int onoff)
 {
-       //struct dib3000_state *state = fe->demodulator_priv;
-       /* switch it off and on */
+       struct dib3000_state *state = fe->demodulator_priv;
+       deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
+       wr(DIB3000MB_REG_PID_PARSE,onoff);
        return 0;
+}
+
+static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr)
+{
+       struct dib3000_state *state = fe->demodulator_priv;
+       if (onoff) {
+               wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
+       } else {
+               wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));
        }
+       return 0;
+}
 
 static struct dvb_frontend_ops dib3000mb_ops;
 
 struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
-                                     struct i2c_adapter* i2c, struct dib3000_xfer_ops *xfer_ops)
+                                     struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
 {
        struct dib3000_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct dib3000_state*) kmalloc(sizeof(struct dib3000_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct dib3000_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
@@ -773,9 +716,6 @@ struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
        if (rd(DIB3000_REG_DEVICE_ID) != DIB3000MB_DEVICE_ID)
                goto error;
 
-       if (dib3000_init_pid_list(state,DIB3000MB_NUM_PIDS))
-               goto error;
-
        /* create dvb_frontend */
        state->frontend.ops = &state->ops;
        state->frontend.demodulator_priv = state;
@@ -784,22 +724,22 @@ struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
        xfer_ops->pid_parse = dib3000mb_pid_parse;
        xfer_ops->fifo_ctrl = dib3000mb_fifo_control;
        xfer_ops->pid_ctrl = dib3000mb_pid_control;
+       xfer_ops->tuner_pass_ctrl = dib3000mb_tuner_pass_ctrl;
 
        return &state->frontend;
 
 error:
-       if (state)
        kfree(state);
        return NULL;
-       }
+}
 
 static struct dvb_frontend_ops dib3000mb_ops = {
 
        .info = {
-               .name                   = "DiBcom 3000-MB DVB-T",
-               .type                   = FE_OFDM,
-               .frequency_min          = 44250000,
-               .frequency_max          = 867250000,
+               .name                   = "DiBcom 3000M-B DVB-T",
+               .type                   = FE_OFDM,
+               .frequency_min          = 44250000,
+               .frequency_max          = 867250000,
                .frequency_stepsize     = 62500,
                .caps = FE_CAN_INVERSION_AUTO |
                                FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
@@ -807,6 +747,7 @@ static struct dvb_frontend_ops dib3000mb_ops = {
                                FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
                                FE_CAN_TRANSMISSION_MODE_AUTO |
                                FE_CAN_GUARD_INTERVAL_AUTO |
+                               FE_CAN_RECOVER |
                                FE_CAN_HIERARCHY_AUTO,
        },