--- v4l-dvb/linux/drivers/media/dvb/frontends/dib3000mb.c 2006-06-30 19:59:10.000000000 +0400 +++ mp-bc1/linux/drivers/media/dvb/frontends/dib3000mb.c 2006-07-23 11:37:54.000000000 +0400 @@ -51,6 +51,8 @@ MODULE_PARM_DESC(debug, "set debugging l static int dib3000mb_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep); +static int dib3000mb_get_params(struct dvb_frontend *fe, + struct dvbfe_params *fep); static int dib3000mb_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep, int tuner) @@ -60,9 +62,10 @@ static int dib3000mb_set_frontend(struct fe_code_rate_t fe_cr = FEC_NONE; int search_state, seq; - if (tuner && fe->ops.tuner_ops.set_params) { - 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) { + fe->ops.tuner_ops.set_params_compat(fe, fep); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); deb_setf("bandwidth: "); switch (ofdm->bandwidth) { @@ -313,6 +316,272 @@ static int dib3000mb_set_frontend(struct return 0; } +static int dib3000mb_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; + enum dvbfe_fec fe_cr = DVBFE_FEC_NONE; + int search_state, seq; + + if (tuner && fe->ops.tuner_ops.set_params) { + fe->ops.tuner_ops.set_params(fe, fep); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + deb_setf("bandwidth: "); + switch (dvbt->bandwidth) { + case DVBFE_BANDWIDTH_8_MHZ: + deb_setf("8 MHz\n"); + wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]); + wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz); + break; + case DVBFE_BANDWIDTH_7_MHZ: + deb_setf("7 MHz\n"); + wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[1]); + wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_7mhz); + break; + case DVBFE_BANDWIDTH_6_MHZ: + deb_setf("6 MHz\n"); + wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[0]); + wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_6mhz); + break; + case DVBFE_BANDWIDTH_AUTO: + return -EOPNOTSUPP; + default: + err("unkown bandwidth value."); + return -EINVAL; + } + } + wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4); + + deb_setf("transmission mode: "); + switch (dvbt->transmission_mode) { + case DVBFE_TRANSMISSION_MODE_2K: + deb_setf("2k\n"); + wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_2K); + break; + case DVBFE_TRANSMISSION_MODE_8K: + deb_setf("8k\n"); + wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_8K); + break; + case DVBFE_TRANSMISSION_MODE_AUTO: + deb_setf("auto\n"); + break; + default: + return -EINVAL; + } + + deb_setf("guard: "); + switch (dvbt->guard_interval) { + case DVBFE_GUARD_INTERVAL_1_32: + deb_setf("1_32\n"); + wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_32); + break; + case DVBFE_GUARD_INTERVAL_1_16: + deb_setf("1_16\n"); + wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_16); + break; + case DVBFE_GUARD_INTERVAL_1_8: + deb_setf("1_8\n"); + wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_8); + break; + case DVBFE_GUARD_INTERVAL_1_4: + deb_setf("1_4\n"); + wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_4); + break; + case DVBFE_GUARD_INTERVAL_AUTO: + deb_setf("auto\n"); + break; + default: + return -EINVAL; + } + + deb_setf("inversion: "); + switch (fep->inversion) { + case INVERSION_OFF: + deb_setf("off\n"); + wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_OFF); + break; + case INVERSION_AUTO: + deb_setf("auto "); + break; + case INVERSION_ON: + deb_setf("on\n"); + wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_ON); + break; + default: + return -EINVAL; + } + + deb_setf("constellation: "); + switch (dvbt->constellation) { + case DVBFE_MOD_QPSK: + deb_setf("qpsk\n"); + wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_QPSK); + break; + case DVBFE_MOD_QAM16: + deb_setf("qam16\n"); + wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_16QAM); + break; + case DVBFE_MOD_QAM64: + deb_setf("qam64\n"); + wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_64QAM); + break; + case DVBFE_MOD_QAMAUTO: + break; + default: + return -EINVAL; + } + deb_setf("hierachy: "); + switch (dvbt->hierarchy) { + case DVBFE_HIERARCHY_OFF: + deb_setf("none "); + /* fall through */ + break; + case DVBFE_HIERARCHY_ON: + switch (dvbt->alpha) { + case DVBFE_ALPHA_1: + deb_setf("alpha=1\n"); + wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_1); + break; + case DVBFE_ALPHA_2: + deb_setf("alpha=2\n"); + wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_2); + break; + case DVBFE_ALPHA_4: + deb_setf("alpha=4\n"); + wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_4); + break; + } + break; + case DVBFE_HIERARCHY_AUTO: + deb_setf("alpha=auto\n"); + break; + default: + return -EINVAL; + } + + deb_setf("hierarchy: "); + if (dvbt->hierarchy == DVBFE_HIERARCHY_OFF) { + deb_setf("none\n"); + wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_OFF); + wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_HP); + fe_cr = dvbt->code_rate_HP; + } else if (dvbt->hierarchy != DVBFE_HIERARCHY_AUTO) { + deb_setf("on\n"); + wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_ON); + wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_LP); + fe_cr = dvbt->code_rate_LP; + } + deb_setf("fec: "); + switch (fe_cr) { + case DVBFE_FEC_1_2: + deb_setf("1_2\n"); + wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_1_2); + break; + case DVBFE_FEC_2_3: + deb_setf("2_3\n"); + wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_2_3); + break; + case DVBFE_FEC_3_4: + deb_setf("3_4\n"); + wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_3_4); + break; + case DVBFE_FEC_5_6: + deb_setf("5_6\n"); + wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_5_6); + break; + case DVBFE_FEC_7_8: + deb_setf("7_8\n"); + wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_7_8); + break; + case DVBFE_FEC_NONE: + deb_setf("none "); + break; + case DVBFE_FEC_AUTO: + deb_setf("auto\n"); + 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(DIB3000MB_REG_SEQ, seq); + + wr(DIB3000MB_REG_ISI, seq ? DIB3000MB_ISI_INHIBIT : DIB3000MB_ISI_ACTIVATE); + + if (dvbt->transmission_mode == DVBFE_TRANSMISSION_MODE_2K) { + if (dvbt->guard_interval == DVBFE_GUARD_INTERVAL_1_8) { + wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_2K_1_8); + } else { + wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_DEFAULT); + } + + wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_2K); + } else { + wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_DEFAULT); + } + + wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_OFF); + wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF); + wr(DIB3000MB_REG_MOBILE_MODE, DIB3000MB_MOBILE_MODE_OFF); + + wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_high); + + wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_ACTIVATE); + + wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC + DIB3000MB_RESTART_CTRL); + wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF); + + /* wait for AGC lock */ + msleep(70); + + wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low); + + /* something has to be auto searched */ + if (dvbt->constellation == DVBFE_MOD_QAMAUTO || + dvbt->hierarchy == DVBFE_HIERARCHY_AUTO || + fe_cr == DVBFE_FEC_AUTO || + fep->inversion == INVERSION_AUTO) { + int as_count=0; + + deb_setf("autosearch enabled.\n"); + + wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT); + + wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AUTO_SEARCH); + wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF); + + while ((search_state = + dib3000_search_status( + rd(DIB3000MB_REG_AS_IRQ_PENDING), + rd(DIB3000MB_REG_LOCK2_VALUE))) < 0 && as_count++ < 100) + msleep(1); + + deb_setf("search_state after autosearch %d after %d checks\n",search_state,as_count); + + if (search_state == 1) { + struct dvbfe_params feps; + if (dib3000mb_get_params(fe, &feps) == 0) { + deb_setf("reading tuning data from frontend succeeded.\n"); + return dib3000mb_set_param(fe, &feps, 0); + } + } + + } else { + wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_CTRL); + wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF); + } + + return 0; +} static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) { struct dib3000_state* state = fe->demodulator_priv; @@ -552,6 +821,173 @@ static int dib3000mb_get_frontend(struct return 0; } +static int dib3000mb_get_params(struct dvb_frontend *fe, + struct dvbfe_params *fep) +{ + struct dib3000_state *state = fe->demodulator_priv; + struct dvbt_params *dvbt = &fep->delsys.dvbt; +// fe_code_rate_t *cr; + enum dvbfe_fec *cr; + + u16 tps_val; + int inv_test1,inv_test2; + u32 dds_val, threshold = 0x800000; + + if (!rd(DIB3000MB_REG_TPS_LOCK)) + return 0; + + dds_val = ((rd(DIB3000MB_REG_DDS_VALUE_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_VALUE_LSB); + deb_getf("DDS_VAL: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_VALUE_MSB), rd(DIB3000MB_REG_DDS_VALUE_LSB)); + if (dds_val < threshold) + inv_test1 = 0; + else if (dds_val == threshold) + inv_test1 = 1; + else + inv_test1 = 2; + + dds_val = ((rd(DIB3000MB_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_FREQ_LSB); + deb_getf("DDS_FREQ: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_FREQ_MSB), rd(DIB3000MB_REG_DDS_FREQ_LSB)); + 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); + + switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) { + 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; + } + deb_getf("TPS: %d\n", tps_val); + + if (rd(DIB3000MB_REG_TPS_HRCH)) { + deb_getf("HRCH ON\n"); + cr = &dvbt->code_rate_LP; + dvbt->code_rate_HP = DVBFE_FEC_NONE; + switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) { + 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; + } + deb_getf("TPS: %d\n", tps_val); + + tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_LP); + } else { + deb_getf("HRCH OFF\n"); + cr = &dvbt->code_rate_HP; + dvbt->code_rate_LP = DVBFE_FEC_NONE; + dvbt->hierarchy = DVBFE_HIERARCHY_OFF; + + tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_HP); + } + + switch (tps_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; + } + deb_getf("TPS: %d\n",tps_val); + + switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) { + 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; + } + deb_getf("TPS: %d\n", tps_val); + + switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) { + 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("TPS: %d\n", tps_val); + + return 0; +} + static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat) { struct dib3000_state* state = fe->demodulator_priv; @@ -643,6 +1079,12 @@ static int dib3000mb_set_frontend_and_tu return dib3000mb_set_frontend(fe, fep, 1); } +static int dib3000mb_set_params(struct dvb_frontend *fe, + struct dvbfe_params *fep) +{ + return dib3000mb_set_param(fe, fep, 1); +} + static void dib3000mb_release(struct dvb_frontend* fe) { struct dib3000_state *state = fe->demodulator_priv; @@ -730,6 +1172,41 @@ error: return NULL; } +static struct dvbfe_info dvbt_info = { + .name = "DiBcom 3000M-B 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 dib3000mb_get_info(struct dvb_frontend *fe, + struct dvbfe_info *fe_info) +{ + memcpy(fe_info, &dvbt_info, sizeof (dvbt_info)); + + return 0; +} + +static int dib3000mb_get_delsys(struct dvb_frontend *fe, + enum dvbfe_delsys *fe_delsys) +{ + *fe_delsys = DVBFE_DELSYS_DVBT; + + return 0; +} + +static enum dvbfe_algo dib3000mb_get_algo(struct dvb_frontend *fe) +{ + return DVBFE_ALGO_RECOVERY; +} + static struct dvb_frontend_ops dib3000mb_ops = { .info = { @@ -762,6 +1239,12 @@ static struct dvb_frontend_ops dib3000mb .read_signal_strength = dib3000mb_read_signal_strength, .read_snr = dib3000mb_read_snr, .read_ucblocks = dib3000mb_read_unc_blocks, + + .set_params = dib3000mb_set_params, + .get_params = dib3000mb_get_params, + .get_info = dib3000mb_get_info, + .get_delsys = dib3000mb_get_delsys, + .get_frontend_algo = dib3000mb_get_algo, }; MODULE_AUTHOR(DRIVER_AUTHOR);
_______________________________________________ linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb