--- v4l-dvb/linux/drivers/media/dvb/frontends/dib3000mc.c 2006-06-30 19:59:10.000000000 +0400 +++ mp-bc1/linux/drivers/media/dvb/frontends/dib3000mc.c 2006-07-23 11:38:01.000000000 +0400 @@ -49,8 +49,10 @@ MODULE_PARM_DESC(debug, "set debugging l #define deb_getf(args...) dprintk(0x08,args) #define deb_stat(args...) dprintk(0x10,args) -static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode, - fe_transmit_mode_t transmission_mode, fe_bandwidth_t bandwidth) +static int dib3000mc_set_impulse_noise_compat(struct dib3000_state * state, + int mode, + fe_transmit_mode_t transmission_mode, + fe_bandwidth_t bandwidth) { switch (transmission_mode) { case TRANSMISSION_MODE_2K: @@ -95,7 +97,55 @@ static int dib3000mc_set_impulse_noise(s return 0; } -static int dib3000mc_set_timing(struct dib3000_state *state, int upd_offset, +static int dib3000mc_set_impulse_noise(struct dib3000_state * state, + int mode, + enum dvbfe_transmission_mode transmission_mode, + enum dvbfe_bandwidth bandwidth) +{ + switch (transmission_mode) { + case DVBFE_TRANSMISSION_MODE_2K: + wr_foreach(dib3000mc_reg_fft, dib3000mc_fft_modes[0]); + break; + case DVBFE_TRANSMISSION_MODE_8K: + wr_foreach(dib3000mc_reg_fft, dib3000mc_fft_modes[1]); + break; + default: + break; + } + + switch (bandwidth) { +/* case BANDWIDTH_5_MHZ: + wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[0]); + break; */ + case DVBFE_BANDWIDTH_6_MHZ: + wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[1]); + break; + case DVBFE_BANDWIDTH_7_MHZ: + wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[2]); + break; + case DVBFE_BANDWIDTH_8_MHZ: + wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[3]); + break; + default: + break; + } + + switch (mode) { + case 0: /* no impulse */ /* fall through */ + wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[0]); + break; + case 1: /* new algo */ + wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[1]); + set_or(DIB3000MC_REG_IMP_NOISE_55,DIB3000MC_IMP_NEW_ALGO(0)); /* gives 1<<10 */ + break; + default: /* old algo */ + wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[3]); + break; + } + return 0; +} + +static int dib3000mc_set_timing_compat(struct dib3000_state *state, int upd_offset, fe_transmit_mode_t fft, fe_bandwidth_t bw) { u16 timf_msb,timf_lsb; @@ -149,7 +199,69 @@ static int dib3000mc_set_timing(struct d return 0; } -static int dib3000mc_init_auto_scan(struct dib3000_state *state, fe_bandwidth_t bw, int boost) +static int dib3000mc_set_timing(struct dib3000_state *state, int upd_offset, + fe_transmit_mode_t fft, enum dvbfe_bandwidth bw) +{ + u16 timf_msb,timf_lsb; + s32 tim_offset,tim_sgn; + u64 comp1,comp2,comp=0; + + switch (bw) { + case DVBFE_BANDWIDTH_8_MHZ: + comp = DIB3000MC_CLOCK_REF * 8; + break; + case DVBFE_BANDWIDTH_7_MHZ: + comp = DIB3000MC_CLOCK_REF * 7; + break; + case DVBFE_BANDWIDTH_6_MHZ: + comp = DIB3000MC_CLOCK_REF * 6; + break; + default: + err("unknown bandwidth (%d)", bw); + break; + } + timf_msb = (comp >> 16) & 0xff; + timf_lsb = (comp & 0xffff); + + // Update the timing offset ; + if (upd_offset > 0) { + if (!state->timing_offset_comp_done) { + msleep(200); + state->timing_offset_comp_done = 1; + } + tim_offset = rd(DIB3000MC_REG_TIMING_OFFS_MSB); + if ((tim_offset & 0x2000) == 0x2000) + tim_offset |= 0xC000; + if (fft == DVBFE_TRANSMISSION_MODE_2K) + tim_offset <<= 2; + state->timing_offset += tim_offset; + } + + tim_offset = state->timing_offset; + if (tim_offset < 0) { + tim_sgn = 1; + tim_offset = -tim_offset; + } else + tim_sgn = 0; + + comp1 = (u32)tim_offset * (u32)timf_lsb ; + comp2 = (u32)tim_offset * (u32)timf_msb ; + comp = ((comp1 >> 16) + comp2) >> 7; + + if (tim_sgn == 0) + comp = (u32)(timf_msb << 16) + (u32) timf_lsb + comp; + else + comp = (u32)(timf_msb << 16) + (u32) timf_lsb - comp ; + + timf_msb = (comp >> 16) & 0xff; + timf_lsb = comp & 0xffff; + + wr(DIB3000MC_REG_TIMING_FREQ_MSB,timf_msb); + wr(DIB3000MC_REG_TIMING_FREQ_LSB,timf_lsb); + return 0; +} + +static int dib3000mc_init_auto_scan_compat(struct dib3000_state *state, fe_bandwidth_t bw, int boost) { if (boost) { wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_ON); @@ -185,7 +297,43 @@ static int dib3000mc_init_auto_scan(stru return 0; } -static int dib3000mc_set_adp_cfg(struct dib3000_state *state, fe_modulation_t con) +static int dib3000mc_init_auto_scan(struct dib3000_state *state, enum dvbfe_bandwidth bw, int boost) +{ + if (boost) { + wr(DIB3000MC_REG_SCAN_BOOST, DIB3000MC_SCAN_BOOST_ON); + } else { + wr(DIB3000MC_REG_SCAN_BOOST, DIB3000MC_SCAN_BOOST_OFF); + } + switch (bw) { + case DVBFE_BANDWIDTH_8_MHZ: + wr_foreach(dib3000mc_reg_bandwidth, dib3000mc_bandwidth_8mhz); + break; + case DVBFE_BANDWIDTH_7_MHZ: + wr_foreach(dib3000mc_reg_bandwidth, dib3000mc_bandwidth_7mhz); + break; + case DVBFE_BANDWIDTH_6_MHZ: + wr_foreach(dib3000mc_reg_bandwidth, dib3000mc_bandwidth_6mhz); + break; +/* case BANDWIDTH_5_MHZ: + wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_5mhz); + break;*/ + case BANDWIDTH_AUTO: + return -EOPNOTSUPP; + default: + err("unknown bandwidth value (%d).",bw); + return -EINVAL; +} + if (boost) { + u32 timeout = (rd(DIB3000MC_REG_BW_TIMOUT_MSB) << 16) + + rd(DIB3000MC_REG_BW_TIMOUT_LSB); + timeout *= 85; timeout >>= 7; + wr(DIB3000MC_REG_BW_TIMOUT_MSB,(timeout >> 16) & 0xffff); + wr(DIB3000MC_REG_BW_TIMOUT_LSB,timeout & 0xffff); + } + return 0; +} + +static int dib3000mc_set_adp_cfg_compat(struct dib3000_state *state, fe_modulation_t con) { switch (con) { case QAM_64: @@ -206,7 +354,29 @@ static int dib3000mc_set_adp_cfg(struct return 0; } -static int dib3000mc_set_general_cfg(struct dib3000_state *state, struct dvb_frontend_parameters *fep, int *auto_val) +static int dib3000mc_set_adp_cfg(struct dib3000_state *state, + enum dvbfe_modulation con) +{ + switch (con) { + case DVBFE_MOD_QAM64: + wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[2]); + break; + case DVBFE_MOD_QAM16: + wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[1]); + break; + case DVBFE_MOD_QPSK: + wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[0]); + break; + case DVBFE_MOD_QAMAUTO: + break; + default: + warn("unkown constellation."); + break; + } + return 0; +} + +static int dib3000mc_set_general_cfg_compat(struct dib3000_state *state, struct dvb_frontend_parameters *fep, int *auto_val) { struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; fe_code_rate_t fe_cr = FEC_NONE; @@ -293,6 +463,145 @@ static int dib3000mc_set_general_cfg(str return 0; } +static int dib3000mc_set_general_cfg(struct dib3000_state *state, + struct dvbfe_params *fep, + int *auto_val) +{ + struct dvbt_params *dvbt = &fep->delsys.dvbt; + enum dvbfe_fec fe_cr = DVBFE_FEC_NONE; + u8 fft = 0, guard = 0, qam = 0, alpha = 0, sel_hp = 0, cr = 0, hrch = 0; + int seq; + + switch (dvbt->transmission_mode) { + case DVBFE_TRANSMISSION_MODE_2K: + fft = DIB3000_TRANSMISSION_MODE_2K; + break; + case DVBFE_TRANSMISSION_MODE_8K: + fft = DIB3000_TRANSMISSION_MODE_8K; + break; + case DVBFE_TRANSMISSION_MODE_AUTO: + break; + default: + return -EINVAL; + } + switch (dvbt->guard_interval) { + case DVBFE_GUARD_INTERVAL_1_32: + guard = DIB3000_GUARD_TIME_1_32; + break; + case DVBFE_GUARD_INTERVAL_1_16: + guard = DIB3000_GUARD_TIME_1_16; + break; + case DVBFE_GUARD_INTERVAL_1_8: + guard = DIB3000_GUARD_TIME_1_8; + break; + case DVBFE_GUARD_INTERVAL_1_4: + guard = DIB3000_GUARD_TIME_1_4; + break; + case DVBFE_GUARD_INTERVAL_AUTO: + break; + default: + return -EINVAL; + } + switch (dvbt->constellation) { + case DVBFE_MOD_QPSK: + qam = DIB3000_CONSTELLATION_QPSK; + break; + case DVBFE_MOD_QAM16: + qam = DIB3000_CONSTELLATION_16QAM; + break; + case DVBFE_MOD_QAM64: + qam = DIB3000_CONSTELLATION_64QAM; + break; + case DVBFE_MOD_QAMAUTO: + break; + default: + return -EINVAL; + } + switch (dvbt->hierarchy) { + case DVBFE_HIERARCHY_OFF: /* fall through */ + break; + case DVBFE_HIERARCHY_ON: + switch (dvbt->alpha) { + case DVBFE_ALPHA_1: + alpha = DIB3000_ALPHA_1; + break; + case DVBFE_ALPHA_2: + alpha = DIB3000_ALPHA_2; + break; + case DVBFE_ALPHA_4: + alpha = DIB3000_ALPHA_4; + break; + } + break; + case DVBFE_HIERARCHY_AUTO: + break; + default: + return -EINVAL; + } + if (dvbt->hierarchy == DVBFE_HIERARCHY_OFF) { + hrch = DIB3000_HRCH_OFF; + sel_hp = DIB3000_SELECT_HP; + fe_cr = dvbt->code_rate_HP; + } else if (dvbt->hierarchy != DVBFE_HIERARCHY_AUTO) { + hrch = DIB3000_HRCH_ON; + sel_hp = DIB3000_SELECT_LP; + fe_cr = dvbt->code_rate_LP; + } + switch (fe_cr) { + case DVBFE_FEC_1_2: + cr = DIB3000_FEC_1_2; + break; + case DVBFE_FEC_2_3: + cr = DIB3000_FEC_2_3; + break; + case DVBFE_FEC_3_4: + cr = DIB3000_FEC_3_4; + break; + case DVBFE_FEC_5_6: + cr = DIB3000_FEC_5_6; + break; + case DVBFE_FEC_7_8: + cr = DIB3000_FEC_7_8; + break; + case DVBFE_FEC_NONE: + break; + case DVBFE_FEC_AUTO: + break; + default: + return -EINVAL; + } + + wr(DIB3000MC_REG_DEMOD_PARM, DIB3000MC_DEMOD_PARM(alpha, qam, guard, fft)); + wr(DIB3000MC_REG_HRCH_PARM,DIB3000MC_HRCH_PARM(sel_hp, cr, hrch)); + + switch (fep->inversion) { + case INVERSION_OFF: + wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF); + break; + case INVERSION_AUTO: /* fall through */ + case INVERSION_ON: + wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_ON); + break; + default: + return -EINVAL; + } + + seq = dib3000_seq + [dvbt->transmission_mode == DVBFE_TRANSMISSION_MODE_AUTO] + [dvbt->guard_interval == DVBFE_GUARD_INTERVAL_AUTO] + [fep->inversion == INVERSION_AUTO]; + + deb_setf("seq? %d\n", seq); + wr(DIB3000MC_REG_SEQ_TPS, DIB3000MC_SEQ_TPS(seq,1)); + *auto_val = dvbt->constellation == DVBFE_MOD_QAMAUTO || + dvbt->hierarchy == DVBFE_HIERARCHY_AUTO || + dvbt->guard_interval == DVBFE_GUARD_INTERVAL_AUTO || + dvbt->transmission_mode == DVBFE_TRANSMISSION_MODE_AUTO || + fe_cr == DVBFE_FEC_AUTO || + fep->inversion == INVERSION_AUTO; + return 0; +} + static int dib3000mc_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) { @@ -454,6 +763,170 @@ static int dib3000mc_get_frontend(struct return 0; } +static int dib3000mc_get_params(struct dvb_frontend *fe, + struct dvbfe_params *fep) +{ + struct dib3000_state *state = fe->demodulator_priv; + struct dvbt_params *dvbt = &fep->delsys.dvbt; + enum dvbfe_fec *cr; + u16 tps_val,cr_val; + int inv_test1,inv_test2; + u32 dds_val, threshold = 0x1000000; + + if (!(rd(DIB3000MC_REG_LOCK_507) & DIB3000MC_LOCK_507)) + return 0; + + dds_val = (rd(DIB3000MC_REG_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_DDS_FREQ_LSB); + deb_getf("DDS_FREQ: %6x\n",dds_val); + if (dds_val < threshold) + inv_test1 = 0; + else if (dds_val == threshold) + inv_test1 = 1; + else + inv_test1 = 2; + + dds_val = (rd(DIB3000MC_REG_SET_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_SET_DDS_FREQ_LSB); + deb_getf("DDS_SET_FREQ: %6x\n",dds_val); + if (dds_val < threshold) + inv_test2 = 0; + else if (dds_val == threshold) + inv_test2 = 1; + else + inv_test2 = 2; + + fep->inversion = + ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) || + ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ? + INVERSION_ON : INVERSION_OFF; + + deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion); + + fep->frequency = state->last_tuned_freq; + fep->delsys.dvbt.bandwidth= state->last_tuned_bw; + + tps_val = rd(DIB3000MC_REG_TUNING_PARM); + + switch (DIB3000MC_TP_QAM(tps_val)) { + case DIB3000_CONSTELLATION_QPSK: + deb_getf("QPSK "); + dvbt->constellation = DVBFE_MOD_QPSK; + break; + case DIB3000_CONSTELLATION_16QAM: + deb_getf("QAM16 "); + dvbt->constellation = DVBFE_MOD_QAM16; + break; + case DIB3000_CONSTELLATION_64QAM: + deb_getf("QAM64 "); + dvbt->constellation = DVBFE_MOD_QAM64; + break; + default: + err("Unexpected constellation returned by TPS (%d)", tps_val); + break; + } + + if (DIB3000MC_TP_HRCH(tps_val)) { + deb_getf("HRCH ON "); + cr = &dvbt->code_rate_LP; + dvbt->code_rate_HP = DVBFE_FEC_NONE; + switch (DIB3000MC_TP_ALPHA(tps_val)) { + case DIB3000_ALPHA_0: + deb_getf("HIERARCHY_NONE "); + dvbt->hierarchy = DVBFE_HIERARCHY_OFF; + break; + case DIB3000_ALPHA_1: + deb_getf("HIERARCHY_1 "); + dvbt->hierarchy = DVBFE_HIERARCHY_ON; + dvbt->alpha = DVBFE_ALPHA_1; + break; + case DIB3000_ALPHA_2: + deb_getf("HIERARCHY_2 "); + dvbt->hierarchy = DVBFE_HIERARCHY_ON; + dvbt->alpha = DVBFE_ALPHA_2; + break; + case DIB3000_ALPHA_4: + deb_getf("HIERARCHY_4 "); + dvbt->hierarchy = DVBFE_HIERARCHY_ON; + dvbt->alpha = DVBFE_ALPHA_4; + break; + default: + err("Unexpected ALPHA value returned by TPS (%d)", tps_val); + break; + } + cr_val = DIB3000MC_TP_FEC_CR_LP(tps_val); + } else { + deb_getf("HRCH OFF "); + cr = &dvbt->code_rate_HP; + dvbt->code_rate_LP = DVBFE_FEC_NONE; + dvbt->hierarchy = DVBFE_HIERARCHY_OFF; + cr_val = DIB3000MC_TP_FEC_CR_HP(tps_val); + } + + switch (cr_val) { + case DIB3000_FEC_1_2: + deb_getf("FEC_1_2 "); + *cr = DVBFE_FEC_1_2; + break; + case DIB3000_FEC_2_3: + deb_getf("FEC_2_3 "); + *cr = DVBFE_FEC_2_3; + break; + case DIB3000_FEC_3_4: + deb_getf("FEC_3_4 "); + *cr = DVBFE_FEC_3_4; + break; + case DIB3000_FEC_5_6: + deb_getf("FEC_5_6 "); + *cr = DVBFE_FEC_4_5; + break; + case DIB3000_FEC_7_8: + deb_getf("FEC_7_8 "); + *cr = DVBFE_FEC_7_8; + break; + default: + err("Unexpected FEC returned by TPS (%d)", tps_val); + break; + } + + switch (DIB3000MC_TP_GUARD(tps_val)) { + case DIB3000_GUARD_TIME_1_32: + deb_getf("GUARD_INTERVAL_1_32 "); + dvbt->guard_interval = DVBFE_GUARD_INTERVAL_1_32; + break; + case DIB3000_GUARD_TIME_1_16: + deb_getf("GUARD_INTERVAL_1_16 "); + dvbt->guard_interval = DVBFE_GUARD_INTERVAL_1_16; + break; + case DIB3000_GUARD_TIME_1_8: + deb_getf("GUARD_INTERVAL_1_8 "); + dvbt->guard_interval = DVBFE_GUARD_INTERVAL_1_8; + break; + case DIB3000_GUARD_TIME_1_4: + deb_getf("GUARD_INTERVAL_1_4 "); + dvbt->guard_interval = DVBFE_GUARD_INTERVAL_1_4; + break; + default: + err("Unexpected Guard Time returned by TPS (%d)", tps_val); + break; + } + + switch (DIB3000MC_TP_FFT(tps_val)) { + case DIB3000_TRANSMISSION_MODE_2K: + deb_getf("TRANSMISSION_MODE_2K "); + dvbt->transmission_mode = DVBFE_TRANSMISSION_MODE_2K; + break; + case DIB3000_TRANSMISSION_MODE_8K: + deb_getf("TRANSMISSION_MODE_8K "); + dvbt->transmission_mode = DVBFE_TRANSMISSION_MODE_8K; + break; + default: + err("unexpected transmission mode return by TPS (%d)", tps_val); + break; + } + deb_getf("\n"); + + return 0; +} + static int dib3000mc_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep, int tuner) { @@ -462,14 +935,15 @@ static int dib3000mc_set_frontend(struct int search_state,auto_val; u16 val; - if (tuner && fe->ops.tuner_ops.set_params) { /* initial call from dvb */ - fe->ops.tuner_ops.set_params(fe, fep); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + if (tuner && fe->ops.tuner_ops.set_params_compat) { /* initial call from dvb */ + fe->ops.tuner_ops.set_params_compat(fe, fep); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); state->last_tuned_freq = fep->frequency; // if (!scanboost) { - dib3000mc_set_timing(state,0,ofdm->transmission_mode,ofdm->bandwidth); - dib3000mc_init_auto_scan(state, ofdm->bandwidth, 0); + dib3000mc_set_timing_compat(state,0,ofdm->transmission_mode,ofdm->bandwidth); + dib3000mc_init_auto_scan_compat(state, ofdm->bandwidth, 0); state->last_tuned_bw = ofdm->bandwidth; wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth); @@ -491,7 +965,7 @@ static int dib3000mc_set_frontend(struct wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[3]); } auto_val = 0; - dib3000mc_set_general_cfg(state,fep,&auto_val); + dib3000mc_set_general_cfg_compat(state, fep, &auto_val); dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth); val = rd(DIB3000MC_REG_DEMOD_PARM); @@ -536,11 +1010,11 @@ static int dib3000mc_set_frontend(struct // dib3000mc_set_timing(state,1,ofdm->transmission_mode,ofdm->bandwidth); auto_val = 0; - dib3000mc_set_general_cfg(state,fep,&auto_val); + dib3000mc_set_general_cfg_compat(state, fep, &auto_val); if (auto_val) deb_info("auto_val is true, even though an auto search was already performed.\n"); - dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth); + dib3000mc_set_impulse_noise_compat(state, 0, ofdm->constellation, ofdm->bandwidth); val = rd(DIB3000MC_REG_DEMOD_PARM); wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON); @@ -549,13 +1023,116 @@ static int dib3000mc_set_frontend(struct msleep(30); wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE); - dib3000mc_set_adp_cfg(state,ofdm->constellation); + dib3000mc_set_adp_cfg_compat(state, ofdm->constellation); wr_foreach(dib3000mc_reg_offset, dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]); } return 0; } +static int dib3000mc_set_param(struct dvb_frontend *fe, + struct dvbfe_params *fep, int tuner) +{ + struct dib3000_state *state = fe->demodulator_priv; + struct dvbt_params *dvbt = &fep->delsys.dvbt; + int search_state,auto_val; + u16 val; + + if (tuner && fe->ops.tuner_ops.set_params) { /* initial call from dvb */ + fe->ops.tuner_ops.set_params(fe, fep); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + state->last_tuned_freq = fep->frequency; + // if (!scanboost) { + dib3000mc_set_timing(state, 0, dvbt->transmission_mode, dvbt->bandwidth); + dib3000mc_init_auto_scan(state, dvbt->bandwidth, 0); + state->last_tuned_bw = dvbt->bandwidth; + + wr_foreach(dib3000mc_reg_agc_bandwidth, dib3000mc_agc_bandwidth); + wr(DIB3000MC_REG_RESTART, DIB3000MC_RESTART_AGC); + wr(DIB3000MC_REG_RESTART, DIB3000MC_RESTART_OFF); + + /* Default cfg isi offset adp */ + wr_foreach(dib3000mc_reg_offset, dib3000mc_offset[0]); + + wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT | DIB3000MC_ISI_INHIBIT); + dib3000mc_set_adp_cfg(state, dvbt->constellation); + wr(DIB3000MC_REG_UNK_133, DIB3000MC_UNK_133); + + wr_foreach(dib3000mc_reg_bandwidth_general, dib3000mc_bandwidth_general); + /* power smoothing */ + if (dvbt->bandwidth != DVBFE_BANDWIDTH_8_MHZ) { + wr_foreach(dib3000mc_reg_bw, dib3000mc_bw[0]); + } else { + wr_foreach(dib3000mc_reg_bw, dib3000mc_bw[3]); + } + auto_val = 0; + dib3000mc_set_general_cfg(state, fep, &auto_val); + dib3000mc_set_impulse_noise(state, 0, dvbt->constellation, dvbt->bandwidth); + + val = rd(DIB3000MC_REG_DEMOD_PARM); + wr(DIB3000MC_REG_DEMOD_PARM,val|DIB3000MC_DEMOD_RST_DEMOD_ON); + wr(DIB3000MC_REG_DEMOD_PARM,val); + // } + msleep(70); + + /* something has to be auto searched */ + if (auto_val) { + int as_count=0; + + deb_setf("autosearch enabled.\n"); + + val = rd(DIB3000MC_REG_DEMOD_PARM); + wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON); + wr(DIB3000MC_REG_DEMOD_PARM,val); + + while ((search_state = dib3000_search_status( + rd(DIB3000MC_REG_AS_IRQ),1)) < 0 && as_count++ < 100) + msleep(10); + + deb_info("search_state after autosearch %d after %d checks\n", search_state, as_count); + + if (search_state == 1) { + struct dvbfe_params feps; + if (dib3000mc_get_params(fe, &feps) == 0) { + deb_setf("reading tuning data from frontend succeeded.\n"); + return dib3000mc_set_param(fe, &feps, 0); + } + } + } else { + dib3000mc_set_impulse_noise(state, 0, dvbt->transmission_mode, dvbt->bandwidth); + wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE); + dib3000mc_set_adp_cfg(state, dvbt->constellation); + + /* set_offset_cfg */ + wr_foreach(dib3000mc_reg_offset, + dib3000mc_offset[(dvbt->transmission_mode == TRANSMISSION_MODE_8K)+1]); + } + } else { /* second call, after autosearch (fka: set_WithKnownParams) */ +// dib3000mc_set_timing(state,1,ofdm->transmission_mode,ofdm->bandwidth); + + auto_val = 0; + dib3000mc_set_general_cfg(state, fep, &auto_val); + if (auto_val) + deb_info("auto_val is true, even though an auto search was already performed.\n"); + + dib3000mc_set_impulse_noise(state, 0, dvbt->constellation, dvbt->bandwidth); + + val = rd(DIB3000MC_REG_DEMOD_PARM); + wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON); + wr(DIB3000MC_REG_DEMOD_PARM,val); + + msleep(30); + + wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE); + dib3000mc_set_adp_cfg(state, dvbt->constellation); + wr_foreach(dib3000mc_reg_offset, + dib3000mc_offset[(dvbt->transmission_mode == TRANSMISSION_MODE_8K)+1]); + } + return 0; +} + static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode) { struct dib3000_state *state = fe->demodulator_priv; @@ -740,6 +1317,12 @@ static int dib3000mc_set_frontend_and_tu return dib3000mc_set_frontend(fe, fep, 1); } +static int dib3000mc_set_params(struct dvb_frontend *fe, + struct dvbfe_params *fep) +{ + return dib3000mc_set_param(fe, fep, 1); +} + static void dib3000mc_release(struct dvb_frontend* fe) { struct dib3000_state *state = fe->demodulator_priv; @@ -875,6 +1458,36 @@ error: } EXPORT_SYMBOL(dib3000mc_attach); +static struct dvbfe_info dvbt_info = { + .name = "DiBcom 3000P/M-C DVB-T", + .delivery = DVBFE_DELSYS_DVBT, + .delsys = { + .dvbt.modulation = DVBFE_MOD_OFDM, + .dvbt.stream_priority = DVBFE_STREAM_PRIORITY_HP | + DVBFE_STREAM_PRIORITY_LP, + }, + + .frequency_min = 44250000, + .frequency_max = 867250000, + .frequency_step = 62500, +}; + +static int dib3000mc_get_info(struct dvb_frontend *fe, + struct dvbfe_info *fe_info) +{ + memcpy(fe_info, &dvbt_info, sizeof (dvbt_info)); + + return 0; +} + +static int dib3000mc_get_delsys(struct dvb_frontend *fe, + enum dvbfe_delsys *fe_delsys) +{ + *fe_delsys = DVBFE_DELSYS_DVBT; + + return 0; +} + static struct dvb_frontend_ops dib3000mc_ops = { .info = { @@ -907,6 +1520,11 @@ static struct dvb_frontend_ops dib3000mc .read_signal_strength = dib3000mc_read_signal_strength, .read_snr = dib3000mc_read_snr, .read_ucblocks = dib3000mc_read_unc_blocks, + + .set_params = dib3000mc_set_params, + .get_params = dib3000mc_get_params, + .get_info = dib3000mc_get_info, + .get_delsys = dib3000mc_get_delsys, }; MODULE_AUTHOR(DRIVER_AUTHOR);
_______________________________________________ linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb