include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / media / dvb / frontends / dib3000mc.c
index cbbe2c2..40a0998 100644 (file)
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
-//#include <linux/init.h>
-//#include <linux/delay.h>
-//#include <linux/string.h>
-//#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 
@@ -26,6 +23,10 @@ static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
 
+static int buggy_sfn_workaround;
+module_param(buggy_sfn_workaround, int, 0644);
+MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
+
 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0)
 
 struct dib3000mc_state {
@@ -42,6 +43,8 @@ struct dib3000mc_state {
        fe_bandwidth_t current_bandwidth;
 
        u16 dev_id;
+
+       u8 sfn_workaround_active :1;
 };
 
 static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
@@ -591,9 +594,16 @@ static int dib3000mc_tune(struct dvb_frontend *demod, struct dvb_frontend_parame
        dib3000mc_set_channel_cfg(state, ch, 0);
 
        // activates isi
-       dib3000mc_write_word(state, 29, 0x1073);
+       if (state->sfn_workaround_active) {
+               dprintk("SFN workaround is active\n");
+               dib3000mc_write_word(state, 29, 0x1273);
+               dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift
+       } else {
+               dib3000mc_write_word(state, 29, 0x1073);
+               dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift
+       }
 
-       dib3000mc_set_adp_cfg(state, (uint8_t)ch->u.ofdm.constellation);
+       dib3000mc_set_adp_cfg(state, (u8)ch->u.ofdm.constellation);
        if (ch->u.ofdm.transmission_mode == TRANSMISSION_MODE_8K) {
                dib3000mc_write_word(state, 26, 38528);
                dib3000mc_write_word(state, 33, 8);
@@ -675,10 +685,16 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
                                struct dvb_frontend_parameters *fep)
 {
        struct dib3000mc_state *state = fe->demodulator_priv;
+    int ret;
+
+       dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
 
        state->current_bandwidth = fep->u.ofdm.bandwidth;
        dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
 
+       /* maybe the parameter has been changed */
+       state->sfn_workaround_active = buggy_sfn_workaround;
+
        if (fe->ops.tuner_ops.set_params) {
                fe->ops.tuner_ops.set_params(fe, fep);
                msleep(100);
@@ -688,7 +704,7 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
                fep->u.ofdm.guard_interval    == GUARD_INTERVAL_AUTO ||
                fep->u.ofdm.constellation     == QAM_AUTO ||
                fep->u.ofdm.code_rate_HP      == FEC_AUTO) {
-               int i = 100, found;
+               int i = 1000, found;
 
                dib3000mc_autosearch_start(fe, fep);
                do {
@@ -703,10 +719,11 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
                dib3000mc_get_frontend(fe, fep);
        }
 
+    ret = dib3000mc_tune(fe, fep);
+
        /* make this a config parameter */
        dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
-
-       return dib3000mc_tune(fe, fep);
+    return ret;
 }
 
 static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)