diff options
Diffstat (limited to 'drivers/media/dvb/frontends/dib7000p.c')
-rw-r--r-- | drivers/media/dvb/frontends/dib7000p.c | 456 |
1 files changed, 246 insertions, 210 deletions
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index ce8534ff142e..5ceadc285b3a 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c @@ -70,6 +70,8 @@ struct dib7000p_state { u8 i2c_write_buffer[4]; u8 i2c_read_buffer[2]; struct mutex i2c_buffer_lock; + + u8 input_mode_mpeg; }; enum dib7000p_power_mode { @@ -78,8 +80,11 @@ enum dib7000p_power_mode { DIB7000P_POWER_INTERFACE_ONLY, }; +/* dib7090 specific fonctions */ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode); static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff); +static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode); +static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode); static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) { @@ -276,17 +281,23 @@ static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_p dib7000p_write_word(state, 774, reg_774); dib7000p_write_word(state, 775, reg_775); dib7000p_write_word(state, 776, reg_776); - dib7000p_write_word(state, 899, reg_899); dib7000p_write_word(state, 1280, reg_1280); + if (state->version != SOC7090) + dib7000p_write_word(state, 899, reg_899); return 0; } static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no) { - u16 reg_908 = dib7000p_read_word(state, 908), reg_909 = dib7000p_read_word(state, 909); + u16 reg_908 = 0, reg_909 = 0; u16 reg; + if (state->version != SOC7090) { + reg_908 = dib7000p_read_word(state, 908); + reg_909 = dib7000p_read_word(state, 909); + } + switch (no) { case DIBX000_SLOW_ADC_ON: if (state->version == SOC7090) { @@ -342,8 +353,10 @@ static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_ad reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4; reg_908 |= (state->cfg.enable_current_mirror & 1) << 7; - dib7000p_write_word(state, 908, reg_908); - dib7000p_write_word(state, 909, reg_909); + if (state->version != SOC7090) { + dib7000p_write_word(state, 908, reg_908); + dib7000p_write_word(state, 909, reg_909); + } } static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw) @@ -398,6 +411,24 @@ int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value) } EXPORT_SYMBOL(dib7000p_set_wbd_ref); +int dib7000p_get_agc_values(struct dvb_frontend *fe, + u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd) +{ + struct dib7000p_state *state = fe->demodulator_priv; + + if (agc_global != NULL) + *agc_global = dib7000p_read_word(state, 394); + if (agc1 != NULL) + *agc1 = dib7000p_read_word(state, 392); + if (agc2 != NULL) + *agc2 = dib7000p_read_word(state, 393); + if (wbd != NULL) + *wbd = dib7000p_read_word(state, 397); + + return 0; +} +EXPORT_SYMBOL(dib7000p_get_agc_values); + static void dib7000p_reset_pll(struct dib7000p_state *state) { struct dibx000_bandwidth_config *bw = &state->cfg.bw[0]; @@ -519,7 +550,7 @@ static u16 dib7000p_defaults[] = { // auto search configuration 3, 2, 0x0004, - 0x1000, + (1<<3)|(1<<11)|(1<<12)|(1<<13), 0x0814, /* Equal Lock */ 12, 6, @@ -595,13 +626,6 @@ static u16 dib7000p_defaults[] = { 1, 235, 0x0062, - 2, 901, - 0x0006, - (3 << 10) | (1 << 6), - - 1, 905, - 0x2c8e, - 0, }; @@ -618,15 +642,18 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) dib7000p_write_word(state, 770, 0xffff); dib7000p_write_word(state, 771, 0xffff); dib7000p_write_word(state, 772, 0x001f); - dib7000p_write_word(state, 898, 0x0003); dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3))); dib7000p_write_word(state, 770, 0); dib7000p_write_word(state, 771, 0); dib7000p_write_word(state, 772, 0); - dib7000p_write_word(state, 898, 0); dib7000p_write_word(state, 1280, 0); + if (state->version != SOC7090) { + dib7000p_write_word(state, 898, 0x0003); + dib7000p_write_word(state, 898, 0); + } + /* default */ dib7000p_reset_pll(state); @@ -640,7 +667,7 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */ dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */ dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */ - dib7000p_write_word(state, 273, (1<<6) | 30); + dib7000p_write_word(state, 273, (0<<6) | 30); } if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0) dprintk("OUTPUT_MODE could not be reset."); @@ -655,7 +682,7 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) dib7000p_set_bandwidth(state, 8000); if (state->version == SOC7090) { - dib7000p_write_word(state, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */ + dib7000p_write_word(state, 36, 0x0755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */ } else { if (state->cfg.tuner_is_baseband) dib7000p_write_word(state, 36, 0x0755); @@ -664,6 +691,11 @@ static int dib7000p_demod_reset(struct dib7000p_state *state) } dib7000p_write_tab(state, dib7000p_defaults); + if (state->version != SOC7090) { + dib7000p_write_word(state, 901, 0x0006); + dib7000p_write_word(state, 902, (3 << 10) | (1 << 6)); + dib7000p_write_word(state, 905, 0x2c8e); + } dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); @@ -780,8 +812,9 @@ static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz) } } -static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) +static int dib7000p_agc_startup(struct dvb_frontend *demod) { + struct dtv_frontend_properties *ch = &demod->dtv_property_cache; struct dib7000p_state *state = demod->demodulator_priv; int ret = -1; u8 *agc_state = &state->agc_state; @@ -904,15 +937,16 @@ u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf) } EXPORT_SYMBOL(dib7000p_ctrl_timf); -static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq) +static void dib7000p_set_channel(struct dib7000p_state *state, + struct dtv_frontend_properties *ch, u8 seq) { u16 value, est[4]; - dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); + dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz)); /* nfft, guard, qam, alpha */ value = 0; - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_2K: value |= (0 << 7); break; @@ -924,7 +958,7 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte value |= (1 << 7); break; } - switch (ch->u.ofdm.guard_interval) { + switch (ch->guard_interval) { case GUARD_INTERVAL_1_32: value |= (0 << 5); break; @@ -939,7 +973,7 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte value |= (2 << 5); break; } - switch (ch->u.ofdm.constellation) { + switch (ch->modulation) { case QPSK: value |= (0 << 3); break; @@ -970,11 +1004,11 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte value = 0; if (1 != 0) value |= (1 << 6); - if (ch->u.ofdm.hierarchy_information == 1) + if (ch->hierarchy == 1) value |= (1 << 4); if (1 == 1) value |= 1; - switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) { + switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) { case FEC_2_3: value |= (2 << 1); break; @@ -1001,7 +1035,7 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte dib7000p_write_word(state, 33, 0x0005); /* P_dvsy_sync_wait */ - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_8K: value = 256; break; @@ -1013,7 +1047,7 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte value = 64; break; } - switch (ch->u.ofdm.guard_interval) { + switch (ch->guard_interval) { case GUARD_INTERVAL_1_16: value *= 2; break; @@ -1034,11 +1068,11 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay; /* deactive the possibility of diversity reception if extended interleaver */ - state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K; + state->div_force_off = !1 && ch->transmission_mode != TRANSMISSION_MODE_8K; dib7000p_set_diversity_in(&state->demod, state->div_state); /* channel estimation fine configuration */ - switch (ch->u.ofdm.constellation) { + switch (ch->modulation) { case QAM_64: est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */ est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */ @@ -1062,27 +1096,31 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte dib7000p_write_word(state, 187 + value, est[value]); } -static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) +static int dib7000p_autosearch_start(struct dvb_frontend *demod) { + struct dtv_frontend_properties *ch = &demod->dtv_property_cache; struct dib7000p_state *state = demod->demodulator_priv; - struct dvb_frontend_parameters schan; + struct dtv_frontend_properties schan; u32 value, factor; u32 internal = dib7000p_get_internal_freq(state); schan = *ch; - schan.u.ofdm.constellation = QAM_64; - schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - schan.u.ofdm.code_rate_HP = FEC_2_3; - schan.u.ofdm.code_rate_LP = FEC_3_4; - schan.u.ofdm.hierarchy_information = 0; + schan.modulation = QAM_64; + schan.guard_interval = GUARD_INTERVAL_1_32; + schan.transmission_mode = TRANSMISSION_MODE_8K; + schan.code_rate_HP = FEC_2_3; + schan.code_rate_LP = FEC_3_4; + schan.hierarchy = 0; dib7000p_set_channel(state, &schan, 7); - factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth); - if (factor >= 5000) - factor = 1; - else + factor = BANDWIDTH_TO_KHZ(ch->bandwidth_hz); + if (factor >= 5000) { + if (state->version == SOC7090) + factor = 2; + else + factor = 1; + } else factor = 6; value = 30 * internal * factor; @@ -1205,8 +1243,9 @@ static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 dib7000p_write_word(state, 143, 0); } -static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) +static int dib7000p_tune(struct dvb_frontend *demod) { + struct dtv_frontend_properties *ch = &demod->dtv_property_cache; struct dib7000p_state *state = demod->demodulator_priv; u16 tmp = 0; @@ -1239,7 +1278,7 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */ tmp = (6 << 8) | 0x80; - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_2K: tmp |= (2 << 12); break; @@ -1255,7 +1294,7 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */ tmp = (0 << 4); - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_2K: tmp |= 0x6; break; @@ -1271,7 +1310,7 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */ tmp = (0 << 4); - switch (ch->u.ofdm.transmission_mode) { + switch (ch->transmission_mode) { case TRANSMISSION_MODE_2K: tmp |= 0x6; break; @@ -1303,9 +1342,9 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet } if (state->cfg.spur_protect) - dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); + dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->bandwidth_hz)); - dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); + dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz)); return 0; } @@ -1323,7 +1362,7 @@ static int dib7000p_sleep(struct dvb_frontend *demod) { struct dib7000p_state *state = demod->demodulator_priv; if (state->version == SOC7090) - return dib7090_set_output_mode(demod, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); + return dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); } @@ -1345,93 +1384,94 @@ static int dib7000p_identify(struct dib7000p_state *st) return 0; } -static int dib7000p_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int dib7000p_get_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct dib7000p_state *state = fe->demodulator_priv; u16 tps = dib7000p_read_word(state, 463); fep->inversion = INVERSION_AUTO; - fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth); + fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth); switch ((tps >> 8) & 0x3) { case 0: - fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; + fep->transmission_mode = TRANSMISSION_MODE_2K; break; case 1: - fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; + fep->transmission_mode = TRANSMISSION_MODE_8K; break; - /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */ + /* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */ } switch (tps & 0x3) { case 0: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; + fep->guard_interval = GUARD_INTERVAL_1_32; break; case 1: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; + fep->guard_interval = GUARD_INTERVAL_1_16; break; case 2: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; + fep->guard_interval = GUARD_INTERVAL_1_8; break; case 3: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; + fep->guard_interval = GUARD_INTERVAL_1_4; break; } switch ((tps >> 14) & 0x3) { case 0: - fep->u.ofdm.constellation = QPSK; + fep->modulation = QPSK; break; case 1: - fep->u.ofdm.constellation = QAM_16; + fep->modulation = QAM_16; break; case 2: default: - fep->u.ofdm.constellation = QAM_64; + fep->modulation = QAM_64; break; } /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */ /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */ - fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; + fep->hierarchy = HIERARCHY_NONE; switch ((tps >> 5) & 0x7) { case 1: - fep->u.ofdm.code_rate_HP = FEC_1_2; + fep->code_rate_HP = FEC_1_2; break; case 2: - fep->u.ofdm.code_rate_HP = FEC_2_3; + fep->code_rate_HP = FEC_2_3; break; case 3: - fep->u.ofdm.code_rate_HP = FEC_3_4; + fep->code_rate_HP = FEC_3_4; break; case 5: - fep->u.ofdm.code_rate_HP = FEC_5_6; + fep->code_rate_HP = FEC_5_6; break; case 7: default: - fep->u.ofdm.code_rate_HP = FEC_7_8; + fep->code_rate_HP = FEC_7_8; break; } switch ((tps >> 2) & 0x7) { case 1: - fep->u.ofdm.code_rate_LP = FEC_1_2; + fep->code_rate_LP = FEC_1_2; break; case 2: - fep->u.ofdm.code_rate_LP = FEC_2_3; + fep->code_rate_LP = FEC_2_3; break; case 3: - fep->u.ofdm.code_rate_LP = FEC_3_4; + fep->code_rate_LP = FEC_3_4; break; case 5: - fep->u.ofdm.code_rate_LP = FEC_5_6; + fep->code_rate_LP = FEC_5_6; break; case 7: default: - fep->u.ofdm.code_rate_LP = FEC_7_8; + fep->code_rate_LP = FEC_7_8; break; } @@ -1440,36 +1480,36 @@ static int dib7000p_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_pa return 0; } -static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int dib7000p_set_frontend(struct dvb_frontend *fe) { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct dib7000p_state *state = fe->demodulator_priv; int time, ret; - if (state->version == SOC7090) { + if (state->version == SOC7090) dib7090_set_diversity_in(fe, 0); - dib7090_set_output_mode(fe, OUTMODE_HIGH_Z); - } else + else dib7000p_set_output_mode(state, OUTMODE_HIGH_Z); /* 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); + fe->ops.tuner_ops.set_params(fe); /* start up the AGC */ state->agc_state = 0; do { - time = dib7000p_agc_startup(fe, fep); + time = dib7000p_agc_startup(fe); if (time != -1) msleep(time); } while (time != -1); - if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || - fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) { + if (fep->transmission_mode == TRANSMISSION_MODE_AUTO || + fep->guard_interval == GUARD_INTERVAL_AUTO || fep->modulation == QAM_AUTO || fep->code_rate_HP == FEC_AUTO) { int i = 800, found; - dib7000p_autosearch_start(fe, fep); + dib7000p_autosearch_start(fe); do { msleep(1); found = dib7000p_autosearch_is_irq(fe); @@ -1479,15 +1519,19 @@ static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_pa if (found == 0 || found == 1) return 0; - dib7000p_get_frontend(fe, fep); + dib7000p_get_frontend(fe); } - ret = dib7000p_tune(fe, fep); + ret = dib7000p_tune(fe); /* make this a config parameter */ - if (state->version == SOC7090) + if (state->version == SOC7090) { dib7090_set_output_mode(fe, state->cfg.output_mode); - else + if (state->cfg.enMpegOutput == 0) { + dib7090_setDibTxMux(state, MPEG_ON_DIBTX); + dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS); + } + } else dib7000p_set_output_mode(state, state->cfg.output_mode); return ret; @@ -1831,7 +1875,8 @@ static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg m return num; } -int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num, u16 apb_address) +static int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, + struct i2c_msg msg[], int num, u16 apb_address) { struct dib7000p_state *state = i2c_get_adapdata(i2c_adap); u16 word; @@ -1933,10 +1978,10 @@ static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[] apb_address = 915; break; case 0x27: - apb_address = 916; + apb_address = 917; break; case 0x28: - apb_address = 917; + apb_address = 916; break; case 0x1d: i = ((dib7000p_read_word(state, 72) >> 12) & 0x3); @@ -2031,12 +2076,7 @@ static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize) { - u8 index_buf; - u16 rx_copy_buf[22]; - dprintk("Configure DibStream Tx"); - for (index_buf = 0; index_buf < 22; index_buf++) - rx_copy_buf[index_buf] = dib7000p_read_word(state, 1536+index_buf); dib7000p_write_word(state, 1615, 1); dib7000p_write_word(state, 1603, P_Kin); @@ -2048,9 +2088,6 @@ static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout dib7000p_write_word(state, 1612, syncSize); dib7000p_write_word(state, 1615, 0); - for (index_buf = 0; index_buf < 22; index_buf++) - dib7000p_write_word(state, 1536+index_buf, rx_copy_buf[index_buf]); - return 0; } @@ -2077,109 +2114,121 @@ static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout return 0; } -static int dib7090_enDivOnHostBus(struct dib7000p_state *state) -{ - u16 reg; - - dprintk("Enable Diversity on host bus"); - reg = (1 << 8) | (1 << 5); - dib7000p_write_word(state, 1288, reg); - - return dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0); -} - -static int dib7090_enAdcOnHostBus(struct dib7000p_state *state) -{ - u16 reg; - - dprintk("Enable ADC on host bus"); - reg = (1 << 7) | (1 << 5); - dib7000p_write_word(state, 1288, reg); - - return dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0); -} - -static int dib7090_enMpegOnHostBus(struct dib7000p_state *state) +static void dib7090_enMpegMux(struct dib7000p_state *state, int onoff) { - u16 reg; - - dprintk("Enable Mpeg on host bus"); - reg = (1 << 9) | (1 << 5); - dib7000p_write_word(state, 1288, reg); + u16 reg_1287 = dib7000p_read_word(state, 1287); - return dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0); -} + switch (onoff) { + case 1: + reg_1287 &= ~(1<<7); + break; + case 0: + reg_1287 |= (1<<7); + break; + } -static int dib7090_enMpegInput(struct dib7000p_state *state) -{ - dprintk("Enable Mpeg input"); - return dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */ + dib7000p_write_word(state, 1287, reg_1287); } -static int dib7090_enMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2) +static void dib7090_configMpegMux(struct dib7000p_state *state, + u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2) { - u16 reg = (1 << 7) | ((pulseWidth & 0x1f) << 2) | ((enSerialMode & 0x1) << 1) | (enSerialClkDiv2 & 0x1); - dprintk("Enable Mpeg mux"); - dib7000p_write_word(state, 1287, reg); - reg &= ~(1 << 7); - dib7000p_write_word(state, 1287, reg); + dib7090_enMpegMux(state, 0); - reg = (1 << 4); - dib7000p_write_word(state, 1288, reg); + /* If the input mode is MPEG do not divide the serial clock */ + if ((enSerialMode == 1) && (state->input_mode_mpeg == 1)) + enSerialClkDiv2 = 0; - return 0; + dib7000p_write_word(state, 1287, ((pulseWidth & 0x1f) << 2) + | ((enSerialMode & 0x1) << 1) + | (enSerialClkDiv2 & 0x1)); + + dib7090_enMpegMux(state, 1); } -static int dib7090_disableMpegMux(struct dib7000p_state *state) +static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode) { - u16 reg; - - dprintk("Disable Mpeg mux"); - dib7000p_write_word(state, 1288, 0); - - reg = dib7000p_read_word(state, 1287); - reg &= ~(1 << 7); - dib7000p_write_word(state, 1287, reg); + u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 7); - return 0; + switch (mode) { + case MPEG_ON_DIBTX: + dprintk("SET MPEG ON DIBSTREAM TX"); + dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0); + reg_1288 |= (1<<9); + break; + case DIV_ON_DIBTX: + dprintk("SET DIV_OUT ON DIBSTREAM TX"); + dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0); + reg_1288 |= (1<<8); + break; + case ADC_ON_DIBTX: + dprintk("SET ADC_OUT ON DIBSTREAM TX"); + dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0); + reg_1288 |= (1<<7); + break; + default: + break; + } + dib7000p_write_word(state, 1288, reg_1288); } -static int dib7090_set_input_mode(struct dvb_frontend *fe, int mode) +static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode) { - struct dib7000p_state *state = fe->demodulator_priv; + u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 4); switch (mode) { - case INPUT_MODE_DIVERSITY: - dprintk("Enable diversity INPUT"); - dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0); + case DEMOUT_ON_HOSTBUS: + dprintk("SET DEM OUT OLD INTERF ON HOST BUS"); + dib7090_enMpegMux(state, 0); + reg_1288 |= (1<<6); + break; + case DIBTX_ON_HOSTBUS: + dprintk("SET DIBSTREAM TX ON HOST BUS"); + dib7090_enMpegMux(state, 0); + reg_1288 |= (1<<5); break; - case INPUT_MODE_MPEG: - dprintk("Enable Mpeg INPUT"); - dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */ + case MPEG_ON_HOSTBUS: + dprintk("SET MPEG MUX ON HOST BUS"); + reg_1288 |= (1<<4); break; - case INPUT_MODE_OFF: default: - dprintk("Disable INPUT"); - dib7090_cfg_DibRx(state, 0, 0, 0, 0, 0, 0, 0); break; } - return 0; + dib7000p_write_word(state, 1288, reg_1288); } -static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff) +int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff) { + struct dib7000p_state *state = fe->demodulator_priv; + u16 reg_1287; + switch (onoff) { - case 0: /* only use the internal way - not the diversity input */ - dib7090_set_input_mode(fe, INPUT_MODE_MPEG); - break; - case 1: /* both ways */ - case 2: /* only the diversity input */ - dib7090_set_input_mode(fe, INPUT_MODE_DIVERSITY); - break; + case 0: /* only use the internal way - not the diversity input */ + dprintk("%s mode OFF : by default Enable Mpeg INPUT", __func__); + dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); + + /* Do not divide the serial clock of MPEG MUX */ + /* in SERIAL MODE in case input mode MPEG is used */ + reg_1287 = dib7000p_read_word(state, 1287); + /* enSerialClkDiv2 == 1 ? */ + if ((reg_1287 & 0x1) == 1) { + /* force enSerialClkDiv2 = 0 */ + reg_1287 &= ~0x1; + dib7000p_write_word(state, 1287, reg_1287); + } + state->input_mode_mpeg = 1; + break; + case 1: /* both ways */ + case 2: /* only the diversity input */ + dprintk("%s ON : Enable diversity INPUT", __func__); + dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0); + state->input_mode_mpeg = 0; + break; } + dib7000p_set_diversity_in(&state->demod, onoff); return 0; } @@ -2204,69 +2253,63 @@ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode) case OUTMODE_MPEG2_SERIAL: if (prefer_mpeg_mux_use) { - dprintk("Sip 7090P setting output mode TS_SERIAL using Mpeg Mux"); - dib7090_enMpegOnHostBus(state); - dib7090_enMpegInput(state); - if (state->cfg.enMpegOutput == 1) - dib7090_enMpegMux(state, 3, 1, 1); - - } else { /* Use Smooth block */ - dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc"); - dib7090_disableMpegMux(state); - dib7000p_write_word(state, 1288, (1 << 6)); - outreg |= (2 << 6) | (0 << 1); + dprintk("setting output mode TS_SERIAL using Mpeg Mux"); + dib7090_configMpegMux(state, 3, 1, 1); + dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS); + } else {/* Use Smooth block */ + dprintk("setting output mode TS_SERIAL using Smooth bloc"); + dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); + outreg |= (2<<6) | (0 << 1); } break; case OUTMODE_MPEG2_PAR_GATED_CLK: if (prefer_mpeg_mux_use) { - dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Mpeg Mux"); - dib7090_enMpegOnHostBus(state); - dib7090_enMpegInput(state); - if (state->cfg.enMpegOutput == 1) - dib7090_enMpegMux(state, 2, 0, 0); - } else { /* Use Smooth block */ - dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block"); - dib7090_disableMpegMux(state); - dib7000p_write_word(state, 1288, (1 << 6)); - outreg |= (0 << 6); + dprintk("setting output mode TS_PARALLEL_GATED using Mpeg Mux"); + dib7090_configMpegMux(state, 2, 0, 0); + dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS); + } else { /* Use Smooth block */ + dprintk("setting output mode TS_PARALLEL_GATED using Smooth block"); + dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); + outreg |= (0<<6); } break; case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */ - dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block"); - dib7090_disableMpegMux(state); - dib7000p_write_word(state, 1288, (1 << 6)); - outreg |= (1 << 6); + dprintk("setting output mode TS_PARALLEL_CONT using Smooth block"); + dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); + outreg |= (1<<6); break; case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */ - dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block"); - dib7090_disableMpegMux(state); - dib7000p_write_word(state, 1288, (1 << 6)); - outreg |= (5 << 6); + dprintk("setting output mode TS_FIFO using Smooth block"); + dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS); + outreg |= (5<<6); smo_mode |= (3 << 1); fifo_threshold = 512; break; case OUTMODE_DIVERSITY: - dprintk("Sip 7090P setting output mode MODE_DIVERSITY"); - dib7090_disableMpegMux(state); - dib7090_enDivOnHostBus(state); + dprintk("setting output mode MODE_DIVERSITY"); + dib7090_setDibTxMux(state, DIV_ON_DIBTX); + dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS); break; case OUTMODE_ANALOG_ADC: - dprintk("Sip 7090P setting output mode MODE_ANALOG_ADC"); - dib7090_enAdcOnHostBus(state); + dprintk("setting output mode MODE_ANALOG_ADC"); + dib7090_setDibTxMux(state, ADC_ON_DIBTX); + dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS); break; } + if (mode != OUTMODE_HIGH_Z) + outreg |= (1 << 10); if (state->cfg.output_mpeg2_in_188_bytes) smo_mode |= (1 << 5); ret |= dib7000p_write_word(state, 235, smo_mode); ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */ - ret |= dib7000p_write_word(state, 1286, outreg | (1 << 10)); /* allways set Dout active = 1 !!! */ + ret |= dib7000p_write_word(state, 1286, outreg); return ret; } @@ -2296,13 +2339,6 @@ int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff) } EXPORT_SYMBOL(dib7090_tuner_sleep); -int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart) -{ - dprintk("AGC restart callback: %d", restart); - return 0; -} -EXPORT_SYMBOL(dib7090_agc_restart); - int dib7090_get_adc_power(struct dvb_frontend *fe) { return dib7000p_get_adc_power(fe); @@ -2391,9 +2427,9 @@ error: EXPORT_SYMBOL(dib7000p_attach); static struct dvb_frontend_ops dib7000p_ops = { + .delsys = { SYS_DVBT }, .info = { .name = "DiBcom 7000PC", - .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, .frequency_stepsize = 62500, |