From 8f6956c7f9fa72c502bde47df4122bd32d0b86d5 Mon Sep 17 00:00:00 2001 From: Matt Doran Date: Tue, 31 Jul 2007 07:09:30 -0300 Subject: [PATCH] V4L/DVB (5960): Add module parameter to enable SFN workaround In some areas in the world the broadcasters are not using the same cellid for each transmitter in a SFN. The DiBcom has problems with that setup. The module parameter buggy_sfn_workaround makes it re-usable. Signed-off-by: Matt Doran Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dib3000mc.c | 22 +++++++++++++++++----- drivers/media/dvb/frontends/dib7000p.c | 21 +++++++++++++++++++-- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c index 38d2322..f0096de 100644 --- a/drivers/media/dvb/frontends/dib3000mc.c +++ b/drivers/media/dvb/frontends/dib3000mc.c @@ -13,10 +13,6 @@ #include #include -//#include -//#include -//#include -//#include #include "dvb_frontend.h" @@ -26,6 +22,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(debug, "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 +42,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,7 +593,14 @@ 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, (u8)ch->u.ofdm.constellation); if (ch->u.ofdm.transmission_mode == TRANSMISSION_MODE_8K) { @@ -679,6 +688,9 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe, 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); diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index 1175ab9..aa7dc45 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c @@ -18,6 +18,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(debug, "Enable work-around for buggy SFNs (default: 0)"); + #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0) struct dib7000p_state { @@ -44,6 +48,8 @@ struct dib7000p_state { u16 gpio_dir; u16 gpio_val; + + u8 sfn_workaround_active :1; }; enum dib7000p_power_mode { @@ -751,8 +757,8 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte /* offset loop parameters */ dib7000p_write_word(state, 26, 0x6680); // timf(6xxx) - dib7000p_write_word(state, 29, 0x1273); // isi inh1273 on1073 dib7000p_write_word(state, 32, 0x0003); // pha_off_max(xxx3) + dib7000p_write_word(state, 29, 0x1273); // isi dib7000p_write_word(state, 33, 0x0005); // sfreq(xxx5) /* P_dvsy_sync_wait */ @@ -959,7 +965,15 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet msleep(45); /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */ - dib7000p_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3)); + tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3); + if (state->sfn_workaround_active) { + dprintk( "SFN workaround is active"); + tmp |= (1 << 9); + dib7000p_write_word(state, 166, 0x4000); // P_pha3_force_pha_shift + } else { + dib7000p_write_word(state, 166, 0x0000); // P_pha3_force_pha_shift + } + dib7000p_write_word(state, 29, tmp); // never achieved a lock with that bandwidth so far - wait for osc-freq to update if (state->timf == 0) @@ -1119,6 +1133,9 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe, state->current_bandwidth = fep->u.ofdm.bandwidth; dib7000p_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); -- 2.7.4