diff options
Diffstat (limited to 'drivers/media/dvb-frontends/dib8000.c')
-rw-r--r-- | drivers/media/dvb-frontends/dib8000.c | 732 |
1 files changed, 389 insertions, 343 deletions
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c index 1632d78a5479..61e31f2d2f71 100644 --- a/drivers/media/dvb-frontends/dib8000.c +++ b/drivers/media/dvb-frontends/dib8000.c @@ -115,7 +115,7 @@ struct dib8000_state { u16 found_guard; u8 subchannel; u8 symbol_duration; - u32 timeout; + unsigned long timeout; u8 longest_intlv_layer; u16 output_mode; @@ -588,8 +588,8 @@ static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_s break; case DIBX000_ADC_OFF: // leave the VBG voltage on - reg_907 |= (1 << 14) | (1 << 13) | (1 << 12); - reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2); + reg_907 = (1 << 13) | (1 << 12); + reg_908 = (1 << 6) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 1); break; case DIBX000_VBG_ENABLE: @@ -656,7 +656,7 @@ static int dib8000_sad_calib(struct dib8000_state *state) return 0; } -int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value) +static int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value) { struct dib8000_state *state = fe->demodulator_priv; if (value > 4095) @@ -664,7 +664,6 @@ int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value) state->wbd_ref = value; return dib8000_write_word(state, 106, value); } -EXPORT_SYMBOL(dib8000_set_wbd_ref); static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw) { @@ -739,7 +738,7 @@ static void dib8000_reset_pll(struct dib8000_state *state) dib8000_reset_pll_common(state, pll); } -int dib8000_update_pll(struct dvb_frontend *fe, +static int dib8000_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio) { struct dib8000_state *state = fe->demodulator_priv; @@ -815,8 +814,6 @@ int dib8000_update_pll(struct dvb_frontend *fe, return 0; } -EXPORT_SYMBOL(dib8000_update_pll); - static int dib8000_reset_gpio(struct dib8000_state *st) { @@ -849,13 +846,12 @@ static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val) return 0; } -int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val) +static int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val) { struct dib8000_state *state = fe->demodulator_priv; return dib8000_cfg_gpio(state, num, dir, val); } -EXPORT_SYMBOL(dib8000_set_gpio); static const u16 dib8000_defaults[] = { /* auto search configuration - lock0 by default waiting * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */ @@ -1054,6 +1050,7 @@ static int dib8000_reset(struct dvb_frontend *fe) dib8000_write_word(state, 770, 0xffff); dib8000_write_word(state, 771, 0xffff); dib8000_write_word(state, 772, 0xfffc); + dib8000_write_word(state, 898, 0x000c); /* restart sad */ if (state->revision == 0x8090) dib8000_write_word(state, 1280, 0x0045); else @@ -1228,20 +1225,19 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band) return 0; } -void dib8000_pwm_agc_reset(struct dvb_frontend *fe) +static void dib8000_pwm_agc_reset(struct dvb_frontend *fe) { struct dib8000_state *state = fe->demodulator_priv; dib8000_set_adc_state(state, DIBX000_ADC_ON); dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))); } -EXPORT_SYMBOL(dib8000_pwm_agc_reset); static int dib8000_agc_soft_split(struct dib8000_state *state) { u16 agc, split_offset; if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0) - return FE_CALLBACK_TIME_NEVER; + return 0; // n_agc_global agc = dib8000_read_word(state, 390); @@ -1881,14 +1877,13 @@ static struct i2c_algorithm dib8096p_tuner_xfer_algo = { .functionality = dib8096p_i2c_func, }; -struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe) +static struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe) { struct dib8000_state *st = fe->demodulator_priv; return &st->dib8096p_tuner_adap; } -EXPORT_SYMBOL(dib8096p_get_i2c_tuner); -int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff) +static int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff) { struct dib8000_state *state = fe->demodulator_priv; u16 en_cur_state; @@ -1912,14 +1907,13 @@ int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff) return 0; } -EXPORT_SYMBOL(dib8096p_tuner_sleep); static const s32 lut_1000ln_mant[] = { 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600 }; -s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) +static s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) { struct dib8000_state *state = fe->demodulator_priv; u32 ix = 0, tmp_val = 0, exp = 0, mant = 0; @@ -1937,9 +1931,8 @@ s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) } return val; } -EXPORT_SYMBOL(dib8000_get_adc_power); -int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ) +static int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ) { struct dib8000_state *state = fe->demodulator_priv; int val = 0; @@ -1957,7 +1950,6 @@ int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ) return val; } -EXPORT_SYMBOL(dib8090p_get_dc_power); static void dib8000_update_timf(struct dib8000_state *state) { @@ -1968,7 +1960,7 @@ static void dib8000_update_timf(struct dib8000_state *state) dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default); } -u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf) +static u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf) { struct dib8000_state *state = fe->demodulator_priv; @@ -1986,21 +1978,11 @@ u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf) return state->timf; } -EXPORT_SYMBOL(dib8000_ctrl_timf); static const u16 adc_target_16dB[11] = { - (1 << 13) - 825 - 117, - (1 << 13) - 837 - 117, - (1 << 13) - 811 - 117, - (1 << 13) - 766 - 117, - (1 << 13) - 737 - 117, - (1 << 13) - 693 - 117, - (1 << 13) - 648 - 117, - (1 << 13) - 619 - 117, - (1 << 13) - 575 - 117, - (1 << 13) - 531 - 117, - (1 << 13) - 501 - 117 + 7250, 7238, 7264, 7309, 7338, 7382, 7427, 7456, 7500, 7544, 7574 }; + static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 }; static u16 dib8000_set_layer(struct dib8000_state *state, u8 layer_index, u16 max_constellation) @@ -2043,9 +2025,8 @@ static u16 dib8000_set_layer(struct dib8000_state *state, u8 layer_index, u16 ma break; } - if ((c->layer[layer_index].interleaving > 0) && ((c->layer[layer_index].interleaving <= 3) || (c->layer[layer_index].interleaving == 4 && c->isdbt_sb_mode == 1))) - time_intlv = c->layer[layer_index].interleaving; - else + time_intlv = fls(c->layer[layer_index].interleaving); + if (time_intlv > 3 && !(time_intlv == 4 && c->isdbt_sb_mode == 1)) time_intlv = 0; dib8000_write_word(state, 2 + layer_index, (constellation << 10) | ((c->layer[layer_index].segment_count & 0xf) << 6) | (cr << 3) | time_intlv); @@ -2362,6 +2343,9 @@ static void dib8000_set_isdbt_common_channel(struct dib8000_state *state, u8 seq int init_prbs; struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache; + if (autosearching) + c->isdbt_partial_reception = 1; + /* P_mode */ dib8000_write_word(state, 10, (seq << 4)); @@ -2856,12 +2840,12 @@ static void dib8000_set_sync_wait(struct dib8000_state *state) dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | (sync_wait << 4)); } -static u32 dib8000_get_timeout(struct dib8000_state *state, u32 delay, enum timeout_mode mode) +static unsigned long dib8000_get_timeout(struct dib8000_state *state, u32 delay, enum timeout_mode mode) { if (mode == SYMBOL_DEPENDENT_ON) - return systime() + (delay * state->symbol_duration); - else - return systime() + delay; + delay *= state->symbol_duration; + + return jiffies + usecs_to_jiffies(delay * 100); } static s32 dib8000_get_status(struct dvb_frontend *fe) @@ -2870,21 +2854,19 @@ static s32 dib8000_get_status(struct dvb_frontend *fe) return state->status; } -enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe) +static enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe) { struct dib8000_state *state = fe->demodulator_priv; return state->tune_state; } -EXPORT_SYMBOL(dib8000_get_tune_state); -int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state) +static int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state) { struct dib8000_state *state = fe->demodulator_priv; state->tune_state = tune_state; return 0; } -EXPORT_SYMBOL(dib8000_set_tune_state); static int dib8000_tune_restart_from_demod(struct dvb_frontend *fe) { @@ -3015,8 +2997,8 @@ static int dib8000_tune(struct dvb_frontend *fe) u16 locks, deeper_interleaver = 0, i; int ret = 1; /* 1 symbol duration (in 100us unit) delay most of the time */ - u32 *timeout = &state->timeout; - u32 now = systime(); + unsigned long *timeout = &state->timeout; + unsigned long now = jiffies; #ifdef DIB8000_AGC_FREEZE u16 agc1, agc2; #endif @@ -3026,318 +3008,327 @@ static int dib8000_tune(struct dvb_frontend *fe) #if 0 if (*tune_state < CT_DEMOD_STOP) - dprintk("IN: context status = %d, TUNE_STATE %d autosearch step = %u systime = %u", state->channel_parameters_set, *tune_state, state->autosearch_state, now); + dprintk("IN: context status = %d, TUNE_STATE %d autosearch step = %u jiffies = %lu", + state->channel_parameters_set, *tune_state, state->autosearch_state, now); #endif switch (*tune_state) { case CT_DEMOD_START: /* 30 */ - dib8000_reset_stats(fe); + dib8000_reset_stats(fe); - if (state->revision == 0x8090) - dib8090p_init_sdram(state); - state->status = FE_STATUS_TUNE_PENDING; - state->channel_parameters_set = is_manual_mode(c); + if (state->revision == 0x8090) + dib8090p_init_sdram(state); + state->status = FE_STATUS_TUNE_PENDING; + state->channel_parameters_set = is_manual_mode(c); - dprintk("Tuning channel on %s search mode", - state->channel_parameters_set ? "manual" : "auto"); + dprintk("Tuning channel on %s search mode", + state->channel_parameters_set ? "manual" : "auto"); - dib8000_viterbi_state(state, 0); /* force chan dec in restart */ + dib8000_viterbi_state(state, 0); /* force chan dec in restart */ - /* Layer monitor */ - dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60); + /* Layer monitor */ + dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60); - dib8000_set_frequency_offset(state); - dib8000_set_bandwidth(fe, c->bandwidth_hz / 1000); + dib8000_set_frequency_offset(state); + dib8000_set_bandwidth(fe, c->bandwidth_hz / 1000); - if (state->channel_parameters_set == 0) { /* The channel struct is unknown, search it ! */ + if (state->channel_parameters_set == 0) { /* The channel struct is unknown, search it ! */ #ifdef DIB8000_AGC_FREEZE - if (state->revision != 0x8090) { - state->agc1_max = dib8000_read_word(state, 108); - state->agc1_min = dib8000_read_word(state, 109); - state->agc2_max = dib8000_read_word(state, 110); - state->agc2_min = dib8000_read_word(state, 111); - agc1 = dib8000_read_word(state, 388); - agc2 = dib8000_read_word(state, 389); - dib8000_write_word(state, 108, agc1); - dib8000_write_word(state, 109, agc1); - dib8000_write_word(state, 110, agc2); - dib8000_write_word(state, 111, agc2); - } -#endif - state->autosearch_state = AS_SEARCHING_FFT; - state->found_nfft = TRANSMISSION_MODE_AUTO; - state->found_guard = GUARD_INTERVAL_AUTO; - *tune_state = CT_DEMOD_SEARCH_NEXT; - } else { /* we already know the channel struct so TUNE only ! */ - state->autosearch_state = AS_DONE; - *tune_state = CT_DEMOD_STEP_3; + if (state->revision != 0x8090) { + state->agc1_max = dib8000_read_word(state, 108); + state->agc1_min = dib8000_read_word(state, 109); + state->agc2_max = dib8000_read_word(state, 110); + state->agc2_min = dib8000_read_word(state, 111); + agc1 = dib8000_read_word(state, 388); + agc2 = dib8000_read_word(state, 389); + dib8000_write_word(state, 108, agc1); + dib8000_write_word(state, 109, agc1); + dib8000_write_word(state, 110, agc2); + dib8000_write_word(state, 111, agc2); } - state->symbol_duration = dib8000_get_symbol_duration(state); - break; +#endif + state->autosearch_state = AS_SEARCHING_FFT; + state->found_nfft = TRANSMISSION_MODE_AUTO; + state->found_guard = GUARD_INTERVAL_AUTO; + *tune_state = CT_DEMOD_SEARCH_NEXT; + } else { /* we already know the channel struct so TUNE only ! */ + state->autosearch_state = AS_DONE; + *tune_state = CT_DEMOD_STEP_3; + } + state->symbol_duration = dib8000_get_symbol_duration(state); + break; case CT_DEMOD_SEARCH_NEXT: /* 51 */ - dib8000_autosearch_start(fe); - if (state->revision == 0x8090) - ret = 50; - else - ret = 15; - *tune_state = CT_DEMOD_STEP_1; - break; + dib8000_autosearch_start(fe); + if (state->revision == 0x8090) + ret = 50; + else + ret = 15; + *tune_state = CT_DEMOD_STEP_1; + break; case CT_DEMOD_STEP_1: /* 31 */ - switch (dib8000_autosearch_irq(fe)) { - case 1: /* fail */ - state->status = FE_STATUS_TUNE_FAILED; - state->autosearch_state = AS_DONE; - *tune_state = CT_DEMOD_STOP; /* else we are done here */ - break; - case 2: /* Succes */ - state->status = FE_STATUS_FFT_SUCCESS; /* signal to the upper layer, that there was a channel found and the parameters can be read */ - *tune_state = CT_DEMOD_STEP_3; - if (state->autosearch_state == AS_SEARCHING_GUARD) - *tune_state = CT_DEMOD_STEP_2; - else - state->autosearch_state = AS_DONE; - break; - case 3: /* Autosearch FFT max correlation endded */ - *tune_state = CT_DEMOD_STEP_2; - break; - } + switch (dib8000_autosearch_irq(fe)) { + case 1: /* fail */ + state->status = FE_STATUS_TUNE_FAILED; + state->autosearch_state = AS_DONE; + *tune_state = CT_DEMOD_STOP; /* else we are done here */ + break; + case 2: /* Succes */ + state->status = FE_STATUS_FFT_SUCCESS; /* signal to the upper layer, that there was a channel found and the parameters can be read */ + *tune_state = CT_DEMOD_STEP_3; + if (state->autosearch_state == AS_SEARCHING_GUARD) + *tune_state = CT_DEMOD_STEP_2; + else + state->autosearch_state = AS_DONE; break; + case 3: /* Autosearch FFT max correlation endded */ + *tune_state = CT_DEMOD_STEP_2; + break; + } + break; case CT_DEMOD_STEP_2: - switch (state->autosearch_state) { - case AS_SEARCHING_FFT: - /* searching for the correct FFT */ - if (state->revision == 0x8090) { - corm[2] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597)); - corm[1] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599)); - corm[0] = (dib8000_read_word(state, 600) << 16) | (dib8000_read_word(state, 601)); - } else { - corm[2] = (dib8000_read_word(state, 594) << 16) | (dib8000_read_word(state, 595)); - corm[1] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597)); - corm[0] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599)); - } - /* dprintk("corm fft: %u %u %u", corm[0], corm[1], corm[2]); */ + switch (state->autosearch_state) { + case AS_SEARCHING_FFT: + /* searching for the correct FFT */ + if (state->revision == 0x8090) { + corm[2] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597)); + corm[1] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599)); + corm[0] = (dib8000_read_word(state, 600) << 16) | (dib8000_read_word(state, 601)); + } else { + corm[2] = (dib8000_read_word(state, 594) << 16) | (dib8000_read_word(state, 595)); + corm[1] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597)); + corm[0] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599)); + } + /* dprintk("corm fft: %u %u %u", corm[0], corm[1], corm[2]); */ - max_value = 0; - for (find_index = 1 ; find_index < 3 ; find_index++) { - if (corm[max_value] < corm[find_index]) - max_value = find_index ; - } + max_value = 0; + for (find_index = 1 ; find_index < 3 ; find_index++) { + if (corm[max_value] < corm[find_index]) + max_value = find_index ; + } - switch (max_value) { - case 0: - state->found_nfft = TRANSMISSION_MODE_2K; - break; - case 1: - state->found_nfft = TRANSMISSION_MODE_4K; - break; - case 2: - default: - state->found_nfft = TRANSMISSION_MODE_8K; - break; - } - /* dprintk("Autosearch FFT has found Mode %d", max_value + 1); */ - - *tune_state = CT_DEMOD_SEARCH_NEXT; - state->autosearch_state = AS_SEARCHING_GUARD; - if (state->revision == 0x8090) - ret = 50; - else - ret = 10; - break; - case AS_SEARCHING_GUARD: - /* searching for the correct guard interval */ - if (state->revision == 0x8090) - state->found_guard = dib8000_read_word(state, 572) & 0x3; - else - state->found_guard = dib8000_read_word(state, 570) & 0x3; - /* dprintk("guard interval found=%i", state->found_guard); */ - - *tune_state = CT_DEMOD_STEP_3; - break; + switch (max_value) { + case 0: + state->found_nfft = TRANSMISSION_MODE_2K; + break; + case 1: + state->found_nfft = TRANSMISSION_MODE_4K; + break; + case 2: default: - /* the demod should never be in this state */ - state->status = FE_STATUS_TUNE_FAILED; - state->autosearch_state = AS_DONE; - *tune_state = CT_DEMOD_STOP; /* else we are done here */ - break; + state->found_nfft = TRANSMISSION_MODE_8K; + break; } + /* dprintk("Autosearch FFT has found Mode %d", max_value + 1); */ + + *tune_state = CT_DEMOD_SEARCH_NEXT; + state->autosearch_state = AS_SEARCHING_GUARD; + if (state->revision == 0x8090) + ret = 50; + else + ret = 10; break; + case AS_SEARCHING_GUARD: + /* searching for the correct guard interval */ + if (state->revision == 0x8090) + state->found_guard = dib8000_read_word(state, 572) & 0x3; + else + state->found_guard = dib8000_read_word(state, 570) & 0x3; + /* dprintk("guard interval found=%i", state->found_guard); */ - case CT_DEMOD_STEP_3: /* 33 */ - state->symbol_duration = dib8000_get_symbol_duration(state); - dib8000_set_isdbt_loop_params(state, LOOP_TUNE_1); - dib8000_set_isdbt_common_channel(state, 0, 0);/* setting the known channel parameters here */ - *tune_state = CT_DEMOD_STEP_4; + *tune_state = CT_DEMOD_STEP_3; break; + default: + /* the demod should never be in this state */ + state->status = FE_STATUS_TUNE_FAILED; + state->autosearch_state = AS_DONE; + *tune_state = CT_DEMOD_STOP; /* else we are done here */ + break; + } + break; + + case CT_DEMOD_STEP_3: /* 33 */ + dib8000_set_isdbt_loop_params(state, LOOP_TUNE_1); + dib8000_set_isdbt_common_channel(state, 0, 0);/* setting the known channel parameters here */ + *tune_state = CT_DEMOD_STEP_4; + break; case CT_DEMOD_STEP_4: /* (34) */ - dib8000_demod_restart(state); + dib8000_demod_restart(state); - dib8000_set_sync_wait(state); - dib8000_set_diversity_in(state->fe[0], state->diversity_onoff); + dib8000_set_sync_wait(state); + dib8000_set_diversity_in(state->fe[0], state->diversity_onoff); - locks = (dib8000_read_word(state, 180) >> 6) & 0x3f; /* P_coff_winlen ? */ - /* coff should lock over P_coff_winlen ofdm symbols : give 3 times this length to lock */ - *timeout = dib8000_get_timeout(state, 2 * locks, SYMBOL_DEPENDENT_ON); - *tune_state = CT_DEMOD_STEP_5; - break; + locks = (dib8000_read_word(state, 180) >> 6) & 0x3f; /* P_coff_winlen ? */ + /* coff should lock over P_coff_winlen ofdm symbols : give 3 times this length to lock */ + *timeout = dib8000_get_timeout(state, 2 * locks, SYMBOL_DEPENDENT_ON); + *tune_state = CT_DEMOD_STEP_5; + break; case CT_DEMOD_STEP_5: /* (35) */ - locks = dib8000_read_lock(fe); - if (locks & (0x3 << 11)) { /* coff-lock and off_cpil_lock achieved */ - dib8000_update_timf(state); /* we achieved a coff_cpil_lock - it's time to update the timf */ - if (!state->differential_constellation) { - /* 2 times lmod4_win_len + 10 symbols (pipe delay after coff + nb to compute a 1st correlation) */ - *timeout = dib8000_get_timeout(state, (20 * ((dib8000_read_word(state, 188)>>5)&0x1f)), SYMBOL_DEPENDENT_ON); - *tune_state = CT_DEMOD_STEP_7; - } else { - *tune_state = CT_DEMOD_STEP_8; - } - } else if (now > *timeout) { - *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */ + locks = dib8000_read_lock(fe); + if (locks & (0x3 << 11)) { /* coff-lock and off_cpil_lock achieved */ + dib8000_update_timf(state); /* we achieved a coff_cpil_lock - it's time to update the timf */ + if (!state->differential_constellation) { + /* 2 times lmod4_win_len + 10 symbols (pipe delay after coff + nb to compute a 1st correlation) */ + *timeout = dib8000_get_timeout(state, (20 * ((dib8000_read_word(state, 188)>>5)&0x1f)), SYMBOL_DEPENDENT_ON); + *tune_state = CT_DEMOD_STEP_7; + } else { + *tune_state = CT_DEMOD_STEP_8; } - break; + } else if (time_after(now, *timeout)) { + *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */ + } + break; case CT_DEMOD_STEP_6: /* (36) if there is an input (diversity) */ - if ((state->fe[1] != NULL) && (state->output_mode != OUTMODE_DIVERSITY)) { - /* if there is a diversity fe in input and this fe is has not already failled : wait here until this this fe has succedeed or failled */ - if (dib8000_get_status(state->fe[1]) <= FE_STATUS_STD_SUCCESS) /* Something is locked on the input fe */ - *tune_state = CT_DEMOD_STEP_8; /* go for mpeg */ - else if (dib8000_get_status(state->fe[1]) >= FE_STATUS_TUNE_TIME_TOO_SHORT) { /* fe in input failled also, break the current one */ - *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */ - dib8000_viterbi_state(state, 1); /* start viterbi chandec */ - dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2); - state->status = FE_STATUS_TUNE_FAILED; - } - } else { + if ((state->fe[1] != NULL) && (state->output_mode != OUTMODE_DIVERSITY)) { + /* if there is a diversity fe in input and this fe is has not already failled : wait here until this this fe has succedeed or failled */ + if (dib8000_get_status(state->fe[1]) <= FE_STATUS_STD_SUCCESS) /* Something is locked on the input fe */ + *tune_state = CT_DEMOD_STEP_8; /* go for mpeg */ + else if (dib8000_get_status(state->fe[1]) >= FE_STATUS_TUNE_TIME_TOO_SHORT) { /* fe in input failled also, break the current one */ + *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */ dib8000_viterbi_state(state, 1); /* start viterbi chandec */ dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2); - *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */ state->status = FE_STATUS_TUNE_FAILED; } - break; + } else { + dib8000_viterbi_state(state, 1); /* start viterbi chandec */ + dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2); + *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */ + state->status = FE_STATUS_TUNE_FAILED; + } + break; case CT_DEMOD_STEP_7: /* 37 */ - locks = dib8000_read_lock(fe); - if (locks & (1<<10)) { /* lmod4_lock */ - ret = 14; /* wait for 14 symbols */ - *tune_state = CT_DEMOD_STEP_8; - } else if (now > *timeout) - *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */ - break; + locks = dib8000_read_lock(fe); + if (locks & (1<<10)) { /* lmod4_lock */ + ret = 14; /* wait for 14 symbols */ + *tune_state = CT_DEMOD_STEP_8; + } else if (time_after(now, *timeout)) + *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */ + break; case CT_DEMOD_STEP_8: /* 38 */ - dib8000_viterbi_state(state, 1); /* start viterbi chandec */ - dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2); - - /* mpeg will never lock on this condition because init_prbs is not set : search for it !*/ - if (c->isdbt_sb_mode - && c->isdbt_sb_subchannel < 14 - && !state->differential_constellation) { - state->subchannel = 0; - *tune_state = CT_DEMOD_STEP_11; - } else { - *tune_state = CT_DEMOD_STEP_9; - state->status = FE_STATUS_LOCKED; - } - break; + dib8000_viterbi_state(state, 1); /* start viterbi chandec */ + dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2); + + /* mpeg will never lock on this condition because init_prbs is not set : search for it !*/ + if (c->isdbt_sb_mode + && c->isdbt_sb_subchannel < 14 + && !state->differential_constellation) { + state->subchannel = 0; + *tune_state = CT_DEMOD_STEP_11; + } else { + *tune_state = CT_DEMOD_STEP_9; + state->status = FE_STATUS_LOCKED; + } + break; case CT_DEMOD_STEP_9: /* 39 */ - if ((state->revision == 0x8090) || ((dib8000_read_word(state, 1291) >> 9) & 0x1)) { /* fe capable of deinterleaving : esram */ - /* defines timeout for mpeg lock depending on interleaver length of longest layer */ - for (i = 0; i < 3; i++) { - if (c->layer[i].interleaving >= deeper_interleaver) { - dprintk("layer%i: time interleaver = %d ", i, c->layer[i].interleaving); - if (c->layer[i].segment_count > 0) { /* valid layer */ - deeper_interleaver = c->layer[0].interleaving; - state->longest_intlv_layer = i; - } + if ((state->revision == 0x8090) || ((dib8000_read_word(state, 1291) >> 9) & 0x1)) { /* fe capable of deinterleaving : esram */ + /* defines timeout for mpeg lock depending on interleaver length of longest layer */ + for (i = 0; i < 3; i++) { + if (c->layer[i].interleaving >= deeper_interleaver) { + dprintk("layer%i: time interleaver = %d ", i, c->layer[i].interleaving); + if (c->layer[i].segment_count > 0) { /* valid layer */ + deeper_interleaver = c->layer[0].interleaving; + state->longest_intlv_layer = i; } } + } - if (deeper_interleaver == 0) - locks = 2; /* locks is the tmp local variable name */ - else if (deeper_interleaver == 3) - locks = 8; - else - locks = 2 * deeper_interleaver; + if (deeper_interleaver == 0) + locks = 2; /* locks is the tmp local variable name */ + else if (deeper_interleaver == 3) + locks = 8; + else + locks = 2 * deeper_interleaver; - if (state->diversity_onoff != 0) /* because of diversity sync */ - locks *= 2; + if (state->diversity_onoff != 0) /* because of diversity sync */ + locks *= 2; - *timeout = now + (2000 * locks); /* give the mpeg lock 800ms if sram is present */ - dprintk("Deeper interleaver mode = %d on layer %d : timeout mult factor = %d => will use timeout = %d", deeper_interleaver, state->longest_intlv_layer, locks, *timeout); + *timeout = now + msecs_to_jiffies(200 * locks); /* give the mpeg lock 800ms if sram is present */ + dprintk("Deeper interleaver mode = %d on layer %d : timeout mult factor = %d => will use timeout = %ld", + deeper_interleaver, state->longest_intlv_layer, locks, *timeout); - *tune_state = CT_DEMOD_STEP_10; - } else - *tune_state = CT_DEMOD_STOP; - break; + *tune_state = CT_DEMOD_STEP_10; + } else + *tune_state = CT_DEMOD_STOP; + break; case CT_DEMOD_STEP_10: /* 40 */ - locks = dib8000_read_lock(fe); - if (locks&(1<<(7-state->longest_intlv_layer))) { /* mpeg lock : check the longest one */ - dprintk("Mpeg locks [ L0 : %d | L1 : %d | L2 : %d ]", (locks>>7)&0x1, (locks>>6)&0x1, (locks>>5)&0x1); - if (c->isdbt_sb_mode - && c->isdbt_sb_subchannel < 14 - && !state->differential_constellation) - /* signal to the upper layer, that there was a channel found and the parameters can be read */ - state->status = FE_STATUS_DEMOD_SUCCESS; - else + locks = dib8000_read_lock(fe); + if (locks&(1<<(7-state->longest_intlv_layer))) { /* mpeg lock : check the longest one */ + dprintk("ISDB-T layer locks: Layer A %s, Layer B %s, Layer C %s", + c->layer[0].segment_count ? (locks >> 7) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled", + c->layer[1].segment_count ? (locks >> 6) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled", + c->layer[2].segment_count ? (locks >> 5) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled"); + if (c->isdbt_sb_mode + && c->isdbt_sb_subchannel < 14 + && !state->differential_constellation) + /* signal to the upper layer, that there was a channel found and the parameters can be read */ + state->status = FE_STATUS_DEMOD_SUCCESS; + else + state->status = FE_STATUS_DATA_LOCKED; + *tune_state = CT_DEMOD_STOP; + } else if (time_after(now, *timeout)) { + if (c->isdbt_sb_mode + && c->isdbt_sb_subchannel < 14 + && !state->differential_constellation) { /* continue to try init prbs autosearch */ + state->subchannel += 3; + *tune_state = CT_DEMOD_STEP_11; + } else { /* we are done mpeg of the longest interleaver xas not locking but let's try if an other layer has locked in the same time */ + if (locks & (0x7 << 5)) { + dprintk("Not all ISDB-T layers locked in %d ms: Layer A %s, Layer B %s, Layer C %s", + jiffies_to_msecs(now - *timeout), + c->layer[0].segment_count ? (locks >> 7) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled", + c->layer[1].segment_count ? (locks >> 6) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled", + c->layer[2].segment_count ? (locks >> 5) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled"); + state->status = FE_STATUS_DATA_LOCKED; + } else + state->status = FE_STATUS_TUNE_FAILED; *tune_state = CT_DEMOD_STOP; - } else if (now > *timeout) { - if (c->isdbt_sb_mode - && c->isdbt_sb_subchannel < 14 - && !state->differential_constellation) { /* continue to try init prbs autosearch */ - state->subchannel += 3; - *tune_state = CT_DEMOD_STEP_11; - } else { /* we are done mpeg of the longest interleaver xas not locking but let's try if an other layer has locked in the same time */ - if (locks & (0x7<<5)) { - dprintk("Mpeg locks [ L0 : %d | L1 : %d | L2 : %d ]", (locks>>7)&0x1, (locks>>6)&0x1, (locks>>5)&0x1); - state->status = FE_STATUS_DATA_LOCKED; - } else - state->status = FE_STATUS_TUNE_FAILED; - *tune_state = CT_DEMOD_STOP; - } } - break; + } + break; case CT_DEMOD_STEP_11: /* 41 : init prbs autosearch */ - if (state->subchannel <= 41) { - dib8000_set_subchannel_prbs(state, dib8000_get_init_prbs(state, state->subchannel)); - *tune_state = CT_DEMOD_STEP_9; - } else { - *tune_state = CT_DEMOD_STOP; - state->status = FE_STATUS_TUNE_FAILED; - } - break; + if (state->subchannel <= 41) { + dib8000_set_subchannel_prbs(state, dib8000_get_init_prbs(state, state->subchannel)); + *tune_state = CT_DEMOD_STEP_9; + } else { + *tune_state = CT_DEMOD_STOP; + state->status = FE_STATUS_TUNE_FAILED; + } + break; default: - break; + break; } /* tuning is finished - cleanup the demod */ switch (*tune_state) { case CT_DEMOD_STOP: /* (42) */ #ifdef DIB8000_AGC_FREEZE - if ((state->revision != 0x8090) && (state->agc1_max != 0)) { - dib8000_write_word(state, 108, state->agc1_max); - dib8000_write_word(state, 109, state->agc1_min); - dib8000_write_word(state, 110, state->agc2_max); - dib8000_write_word(state, 111, state->agc2_min); - state->agc1_max = 0; - state->agc1_min = 0; - state->agc2_max = 0; - state->agc2_min = 0; - } + if ((state->revision != 0x8090) && (state->agc1_max != 0)) { + dib8000_write_word(state, 108, state->agc1_max); + dib8000_write_word(state, 109, state->agc1_min); + dib8000_write_word(state, 110, state->agc2_max); + dib8000_write_word(state, 111, state->agc2_min); + state->agc1_max = 0; + state->agc1_min = 0; + state->agc2_max = 0; + state->agc2_min = 0; + } #endif - ret = FE_CALLBACK_TIME_NEVER; - break; + ret = 0; + break; default: - break; + break; } if ((ret > 0) && (*tune_state > CT_DEMOD_STEP_3)) @@ -3408,7 +3399,7 @@ static int dib8000_get_frontend(struct dvb_frontend *fe) if (!(stat & FE_HAS_SYNC)) return 0; - dprintk("TMCC lock"); + dprintk("dib8000_get_frontend: TMCC lock"); for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat); if (stat&FE_HAS_SYNC) { @@ -3444,91 +3435,117 @@ static int dib8000_get_frontend(struct dvb_frontend *fe) switch ((val & 0x30) >> 4) { case 1: fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K; + dprintk("dib8000_get_frontend: transmission mode 2K"); + break; + case 2: + fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_4K; + dprintk("dib8000_get_frontend: transmission mode 4K"); break; case 3: default: fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K; + dprintk("dib8000_get_frontend: transmission mode 8K"); break; } switch (val & 0x3) { case 0: fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32; - dprintk("dib8000_get_frontend GI = 1/32 "); + dprintk("dib8000_get_frontend: Guard Interval = 1/32 "); break; case 1: fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16; - dprintk("dib8000_get_frontend GI = 1/16 "); + dprintk("dib8000_get_frontend: Guard Interval = 1/16 "); break; case 2: - dprintk("dib8000_get_frontend GI = 1/8 "); + dprintk("dib8000_get_frontend: Guard Interval = 1/8 "); fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8; break; case 3: - dprintk("dib8000_get_frontend GI = 1/4 "); + dprintk("dib8000_get_frontend: Guard Interval = 1/4 "); fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4; break; } val = dib8000_read_word(state, 505); fe->dtv_property_cache.isdbt_partial_reception = val & 1; - dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception); + dprintk("dib8000_get_frontend: partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception); for (i = 0; i < 3; i++) { - val = dib8000_read_word(state, 493 + i); - fe->dtv_property_cache.layer[i].segment_count = val & 0x0F; - dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count); + int show; + + val = dib8000_read_word(state, 493 + i) & 0x0f; + fe->dtv_property_cache.layer[i].segment_count = val; + + if (val == 0 || val > 13) + show = 0; + else + show = 1; + + if (show) + dprintk("dib8000_get_frontend: Layer %d segments = %d ", + i, fe->dtv_property_cache.layer[i].segment_count); val = dib8000_read_word(state, 499 + i) & 0x3; /* Interleaving can be 0, 1, 2 or 4 */ if (val == 3) val = 4; fe->dtv_property_cache.layer[i].interleaving = val; - dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", - i, fe->dtv_property_cache.layer[i].interleaving); + if (show) + dprintk("dib8000_get_frontend: Layer %d time_intlv = %d ", + i, fe->dtv_property_cache.layer[i].interleaving); val = dib8000_read_word(state, 481 + i); switch (val & 0x7) { case 1: fe->dtv_property_cache.layer[i].fec = FEC_1_2; - dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i); + if (show) + dprintk("dib8000_get_frontend: Layer %d Code Rate = 1/2 ", i); break; case 2: fe->dtv_property_cache.layer[i].fec = FEC_2_3; - dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i); + if (show) + dprintk("dib8000_get_frontend: Layer %d Code Rate = 2/3 ", i); break; case 3: fe->dtv_property_cache.layer[i].fec = FEC_3_4; - dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i); + if (show) + dprintk("dib8000_get_frontend: Layer %d Code Rate = 3/4 ", i); break; case 5: fe->dtv_property_cache.layer[i].fec = FEC_5_6; - dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i); + if (show) + dprintk("dib8000_get_frontend: Layer %d Code Rate = 5/6 ", i); break; default: fe->dtv_property_cache.layer[i].fec = FEC_7_8; - dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i); + if (show) + dprintk("dib8000_get_frontend: Layer %d Code Rate = 7/8 ", i); break; } val = dib8000_read_word(state, 487 + i); switch (val & 0x3) { case 0: - dprintk("dib8000_get_frontend : Layer %d DQPSK ", i); fe->dtv_property_cache.layer[i].modulation = DQPSK; + if (show) + dprintk("dib8000_get_frontend: Layer %d DQPSK ", i); break; case 1: fe->dtv_property_cache.layer[i].modulation = QPSK; - dprintk("dib8000_get_frontend : Layer %d QPSK ", i); + if (show) + dprintk("dib8000_get_frontend: Layer %d QPSK ", i); break; case 2: fe->dtv_property_cache.layer[i].modulation = QAM_16; - dprintk("dib8000_get_frontend : Layer %d QAM16 ", i); + if (show) + dprintk("dib8000_get_frontend: Layer %d QAM16 ", i); break; case 3: default: - dprintk("dib8000_get_frontend : Layer %d QAM64 ", i); fe->dtv_property_cache.layer[i].modulation = QAM_64; + if (show) + dprintk("dib8000_get_frontend: Layer %d QAM64 ", i); break; } } @@ -3554,9 +3571,9 @@ static int dib8000_set_frontend(struct dvb_frontend *fe) { struct dib8000_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache; - int l, i, active, time, time_slave = FE_CALLBACK_TIME_NEVER; + int l, i, active, time, time_slave = 0; u8 exit_condition, index_frontend; - u32 delay, callback_time; + unsigned long delay, callback_time; if (c->frequency == 0) { dprintk("dib8000: must at least specify frequency "); @@ -3608,15 +3625,24 @@ static int dib8000_set_frontend(struct dvb_frontend *fe) time = dib8000_agc_startup(state->fe[0]); for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { time_slave = dib8000_agc_startup(state->fe[index_frontend]); - if (time == FE_CALLBACK_TIME_NEVER) + if (time == 0) time = time_slave; - else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time)) + else if ((time_slave != 0) && (time_slave > time)) time = time_slave; } - if (time != FE_CALLBACK_TIME_NEVER) - msleep(time / 10); - else + if (time == 0) break; + + /* + * Despite dib8000_agc_startup returns time at a 0.1 ms range, + * the actual sleep time depends on CONFIG_HZ. The worse case + * is when CONFIG_HZ=100. In such case, the minimum granularity + * is 10ms. On some real field tests, the tuner sometimes don't + * lock when this timer is lower than 10ms. So, enforce a 10ms + * granularity. + */ + time = 10 * (time + 99)/100; + usleep_range(time * 1000, (time + 1) * 1000); exit_condition = 1; for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) { @@ -3631,11 +3657,14 @@ static int dib8000_set_frontend(struct dvb_frontend *fe) active = 1; do { - callback_time = FE_CALLBACK_TIME_NEVER; + callback_time = 0; for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { delay = dib8000_tune(state->fe[index_frontend]); - if (delay != FE_CALLBACK_TIME_NEVER) - delay += systime(); + if (delay != 0) { + delay = jiffies + usecs_to_jiffies(100 * delay); + if (!callback_time || delay < callback_time) + callback_time = delay; + } /* we are in autosearch */ if (state->channel_parameters_set == 0) { /* searching */ @@ -3646,6 +3675,7 @@ static int dib8000_set_frontend(struct dvb_frontend *fe) for (l = 0; (l < MAX_NUMBER_OF_FRONTENDS) && (state->fe[l] != NULL); l++) { if (l != index_frontend) { /* and for all frontend except the successful one */ + dprintk("Restarting frontend %d\n", l); dib8000_tune_restart_from_demod(state->fe[l]); state->fe[l]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode; @@ -3664,8 +3694,6 @@ static int dib8000_set_frontend(struct dvb_frontend *fe) } } } - if (delay < callback_time) - callback_time = delay; } /* tuning is done when the master frontend is done (failed or success) */ if (dib8000_get_status(state->fe[0]) == FE_STATUS_TUNE_FAILED || @@ -3681,12 +3709,12 @@ static int dib8000_set_frontend(struct dvb_frontend *fe) dprintk("tuning done with status %d", dib8000_get_status(state->fe[0])); } - if ((active == 1) && (callback_time == FE_CALLBACK_TIME_NEVER)) { + if ((active == 1) && (callback_time == 0)) { dprintk("strange callback time something went wrong"); active = 0; } - while ((active == 1) && (systime() < callback_time)) + while ((active == 1) && (time_before(jiffies, callback_time))) msleep(100); } while (active); @@ -4201,7 +4229,7 @@ static int dib8000_get_stats(struct dvb_frontend *fe, fe_status_t stat) return 0; } -int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave) +static int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave) { struct dib8000_state *state = fe->demodulator_priv; u8 index_frontend = 1; @@ -4217,9 +4245,8 @@ int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_ dprintk("too many slave frontend"); return -ENOMEM; } -EXPORT_SYMBOL(dib8000_set_slave_frontend); -int dib8000_remove_slave_frontend(struct dvb_frontend *fe) +static int dib8000_remove_slave_frontend(struct dvb_frontend *fe) { struct dib8000_state *state = fe->demodulator_priv; u8 index_frontend = 1; @@ -4235,9 +4262,8 @@ int dib8000_remove_slave_frontend(struct dvb_frontend *fe) dprintk("no frontend to be removed"); return -ENODEV; } -EXPORT_SYMBOL(dib8000_remove_slave_frontend); -struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index) +static struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index) { struct dib8000_state *state = fe->demodulator_priv; @@ -4245,10 +4271,8 @@ struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int sla return NULL; return state->fe[slave_index]; } -EXPORT_SYMBOL(dib8000_get_slave_frontend); - -int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, +static int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr, u8 is_dib8096p) { int k = 0, ret = 0; @@ -4325,7 +4349,6 @@ error_memory_read: return ret; } -EXPORT_SYMBOL(dib8000_i2c_enumeration); static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune) { tune->min_delay_ms = 1000; @@ -4348,15 +4371,13 @@ static void dib8000_release(struct dvb_frontend *fe) kfree(st); } -struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating) +static struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating) { struct dib8000_state *st = fe->demodulator_priv; return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating); } -EXPORT_SYMBOL(dib8000_get_i2c_master); - -int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) +static int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) { struct dib8000_state *st = fe->demodulator_priv; u16 val = dib8000_read_word(st, 299) & 0xffef; @@ -4365,15 +4386,13 @@ int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) dprintk("pid filter enabled %d", onoff); return dib8000_write_word(st, 299, val); } -EXPORT_SYMBOL(dib8000_pid_filter_ctrl); -int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) +static int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) { struct dib8000_state *st = fe->demodulator_priv; dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0); } -EXPORT_SYMBOL(dib8000_pid_filter); static const struct dvb_frontend_ops dib8000_ops = { .delsys = { SYS_ISDBT }, @@ -4405,12 +4424,12 @@ static const struct dvb_frontend_ops dib8000_ops = { .read_ucblocks = dib8000_read_unc_blocks, }; -struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg) +static struct dvb_frontend *dib8000_init(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg) { struct dvb_frontend *fe; struct dib8000_state *state; - dprintk("dib8000_attach"); + dprintk("dib8000_init"); state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL); if (state == NULL) @@ -4467,6 +4486,33 @@ error: return NULL; } +void *dib8000_attach(struct dib8000_ops *ops) +{ + if (!ops) + return NULL; + + ops->pwm_agc_reset = dib8000_pwm_agc_reset; + ops->get_dc_power = dib8090p_get_dc_power; + ops->set_gpio = dib8000_set_gpio; + ops->get_slave_frontend = dib8000_get_slave_frontend; + ops->set_tune_state = dib8000_set_tune_state; + ops->pid_filter_ctrl = dib8000_pid_filter_ctrl; + ops->remove_slave_frontend = dib8000_remove_slave_frontend; + ops->get_adc_power = dib8000_get_adc_power; + ops->update_pll = dib8000_update_pll; + ops->tuner_sleep = dib8096p_tuner_sleep; + ops->get_tune_state = dib8000_get_tune_state; + ops->get_i2c_tuner = dib8096p_get_i2c_tuner; + ops->set_slave_frontend = dib8000_set_slave_frontend; + ops->pid_filter = dib8000_pid_filter; + ops->ctrl_timf = dib8000_ctrl_timf; + ops->init = dib8000_init; + ops->get_i2c_master = dib8000_get_i2c_master; + ops->i2c_enumeration = dib8000_i2c_enumeration; + ops->set_wbd_ref = dib8000_set_wbd_ref; + + return ops; +} EXPORT_SYMBOL(dib8000_attach); MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>"); |