X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fdvb%2Ffrontends%2Fdib3000mb.c;h=ae589adb1c0a47b9960bb9e5a130f47dc1619fe7;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=37eaa7439224e02c5325dcd451d19c08d469bcfe;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c index 37eaa7439..ae589adb1 100644 --- a/drivers/media/dvb/frontends/dib3000mb.c +++ b/drivers/media/dvb/frontends/dib3000mb.c @@ -1,8 +1,8 @@ /* - * Frontend driver for mobile DVB-T demodulator DiBcom 3000-MB + * Frontend driver for mobile DVB-T demodulator DiBcom 3000M-B * DiBcom (http://www.dibcom.fr/) * - * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de) + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) * * based on GPL code from DibCom, which has * @@ -23,25 +23,25 @@ #include #include -#include #include #include #include #include +#include +#include -#include "dvb_frontend.h" #include "dib3000-common.h" #include "dib3000mb_priv.h" #include "dib3000.h" /* Version information */ #define DRIVER_VERSION "0.1" -#define DRIVER_DESC "DiBcom 3000-MB DVB-T demodulator driver" +#define DRIVER_DESC "DiBcom 3000M-B DVB-T demodulator" #define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de" #ifdef CONFIG_DVB_DIBCOM_DEBUG static int debug; -module_param(debug, int, 0x644); +module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able))."); #endif #define deb_info(args...) dprintk(0x01,args) @@ -53,36 +53,32 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep); static int dib3000mb_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep, int tuner) + struct dvb_frontend_parameters *fep, int tuner) { - struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; + struct dib3000_state* state = fe->demodulator_priv; struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; fe_code_rate_t fe_cr = FEC_NONE; - int search_state,seq; + int search_state, seq; - if (tuner) { - wr(DIB3000MB_REG_TUNER, - DIB3000_TUNER_WRITE_ENABLE(state->config.pll_addr)); + if (tuner && state->config.pll_set) { state->config.pll_set(fe, fep); - wr(DIB3000MB_REG_TUNER, - DIB3000_TUNER_WRITE_DISABLE(state->config.pll_addr)); deb_setf("bandwidth: "); switch (ofdm->bandwidth) { case 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); + wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]); + wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz); break; case 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); + wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[1]); + wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_7mhz); break; case 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); + wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[0]); + wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_6mhz); break; case BANDWIDTH_AUTO: return -EOPNOTSUPP; @@ -91,7 +87,7 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, return -EINVAL; } } - wr(DIB3000MB_REG_LOCK1_MASK,DIB3000MB_LOCK1_SEARCH_4); + wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4); deb_setf("transmission mode: "); switch (ofdm->transmission_mode) { @@ -171,25 +167,25 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, default: return -EINVAL; } - deb_setf("hierachy: "); + deb_setf("hierachy: "); switch (ofdm->hierarchy_information) { case HIERARCHY_NONE: deb_setf("none "); /* fall through */ case HIERARCHY_1: - deb_setf("alpha=1\n"); + deb_setf("alpha=1\n"); wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_1); break; case HIERARCHY_2: - deb_setf("alpha=2\n"); + deb_setf("alpha=2\n"); wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_2); break; case HIERARCHY_4: - deb_setf("alpha=4\n"); + deb_setf("alpha=4\n"); wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_4); break; case HIERARCHY_AUTO: - deb_setf("alpha=auto\n"); + deb_setf("alpha=auto\n"); break; default: return -EINVAL; @@ -244,39 +240,39 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, [ofdm->guard_interval == GUARD_INTERVAL_AUTO] [fep->inversion == INVERSION_AUTO]; - deb_setf("seq? %d\n",seq); + deb_setf("seq? %d\n", seq); - wr(DIB3000MB_REG_SEQ,seq); + wr(DIB3000MB_REG_SEQ, seq); - wr(DIB3000MB_REG_ISI,seq ? DIB3000MB_ISI_INHIBIT : DIB3000MB_ISI_ACTIVATE); + wr(DIB3000MB_REG_ISI, seq ? DIB3000MB_ISI_INHIBIT : DIB3000MB_ISI_ACTIVATE); if (ofdm->transmission_mode == TRANSMISSION_MODE_2K) { if (ofdm->guard_interval == GUARD_INTERVAL_1_8) { - wr(DIB3000MB_REG_SYNC_IMPROVEMENT,DIB3000MB_SYNC_IMPROVE_2K_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_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_DEFAULT); } - wr(DIB3000MB_REG_UNK_121,DIB3000MB_UNK_121_2K); + wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_2K); } else { - wr(DIB3000MB_REG_UNK_121,DIB3000MB_UNK_121_DEFAULT); + 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(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_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_high); - wr(DIB3000MB_REG_ISI,DIB3000MB_ISI_ACTIVATE); + wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_ACTIVATE); - wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_AGC+DIB3000MB_RESTART_CTRL); - wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_OFF); + 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); + wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low); /* something has to be auto searched */ if (ofdm->constellation == QAM_AUTO || @@ -285,12 +281,12 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, fep->inversion == INVERSION_AUTO) { int as_count=0; - deb_setf("autosearch enabled.\n"); + deb_setf("autosearch enabled.\n"); - wr(DIB3000MB_REG_ISI,DIB3000MB_ISI_INHIBIT); + wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT); - wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_AUTO_SEARCH); - wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_OFF); + wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AUTO_SEARCH); + wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF); while ((search_state = dib3000_search_status( @@ -298,7 +294,7 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, rd(DIB3000MB_REG_LOCK2_VALUE))) < 0 && as_count++ < 100) msleep(1); - deb_info("search_state after autosearch %d after %d checks\n",search_state,as_count); + deb_setf("search_state after autosearch %d after %d checks\n",search_state,as_count); if (search_state == 1) { struct dvb_frontend_parameters feps; @@ -309,8 +305,8 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, } } else { - wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_CTRL); - wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_OFF); + wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_CTRL); + wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF); } return 0; @@ -318,84 +314,80 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) { - struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; + struct dib3000_state* state = fe->demodulator_priv; - wr(DIB3000MB_REG_POWER_CONTROL,DIB3000MB_POWER_UP); + deb_info("dib3000mb is getting up.\n"); + wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_UP); wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC); - wr(DIB3000MB_REG_RESET_DEVICE,DIB3000MB_RESET_DEVICE); - wr(DIB3000MB_REG_RESET_DEVICE,DIB3000MB_RESET_DEVICE_RST); + wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE); + wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE_RST); - wr(DIB3000MB_REG_CLOCK,DIB3000MB_CLOCK_DEFAULT); + wr(DIB3000MB_REG_CLOCK, DIB3000MB_CLOCK_DEFAULT); - wr(DIB3000MB_REG_ELECT_OUT_MODE,DIB3000MB_ELECT_OUT_MODE_ON); + wr(DIB3000MB_REG_ELECT_OUT_MODE, DIB3000MB_ELECT_OUT_MODE_ON); - wr(DIB3000MB_REG_DDS_FREQ_MSB,DIB3000MB_DDS_FREQ_MSB); - wr(DIB3000MB_REG_DDS_FREQ_LSB,DIB3000MB_DDS_FREQ_LSB); + wr(DIB3000MB_REG_DDS_FREQ_MSB, DIB3000MB_DDS_FREQ_MSB); + wr(DIB3000MB_REG_DDS_FREQ_LSB, DIB3000MB_DDS_FREQ_LSB); - wr_foreach(dib3000mb_reg_timing_freq,dib3000mb_timing_freq[2]); + wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]); wr_foreach(dib3000mb_reg_impulse_noise, dib3000mb_impulse_noise_values[DIB3000MB_IMPNOISE_OFF]); - wr_foreach(dib3000mb_reg_agc_gain,dib3000mb_default_agc_gain); + wr_foreach(dib3000mb_reg_agc_gain, dib3000mb_default_agc_gain); - wr(DIB3000MB_REG_PHASE_NOISE,DIB3000MB_PHASE_NOISE_DEFAULT); + wr(DIB3000MB_REG_PHASE_NOISE, DIB3000MB_PHASE_NOISE_DEFAULT); wr_foreach(dib3000mb_reg_phase_noise, dib3000mb_default_noise_phase); - wr_foreach(dib3000mb_reg_lock_duration,dib3000mb_default_lock_duration); + wr_foreach(dib3000mb_reg_lock_duration, dib3000mb_default_lock_duration); - wr_foreach(dib3000mb_reg_agc_bandwidth,dib3000mb_agc_bandwidth_low); + wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low); - wr(DIB3000MB_REG_LOCK0_MASK,DIB3000MB_LOCK0_DEFAULT); - wr(DIB3000MB_REG_LOCK1_MASK,DIB3000MB_LOCK1_SEARCH_4); - wr(DIB3000MB_REG_LOCK2_MASK,DIB3000MB_LOCK2_DEFAULT); + wr(DIB3000MB_REG_LOCK0_MASK, DIB3000MB_LOCK0_DEFAULT); + wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4); + wr(DIB3000MB_REG_LOCK2_MASK, DIB3000MB_LOCK2_DEFAULT); wr(DIB3000MB_REG_SEQ, dib3000_seq[1][1][1]); - wr_foreach(dib3000mb_reg_bandwidth,dib3000mb_bandwidth_8mhz); - - wr(DIB3000MB_REG_UNK_68,DIB3000MB_UNK_68); - wr(DIB3000MB_REG_UNK_69,DIB3000MB_UNK_69); - wr(DIB3000MB_REG_UNK_71,DIB3000MB_UNK_71); - wr(DIB3000MB_REG_UNK_77,DIB3000MB_UNK_77); - wr(DIB3000MB_REG_UNK_78,DIB3000MB_UNK_78); - wr(DIB3000MB_REG_ISI,DIB3000MB_ISI_INHIBIT); - wr(DIB3000MB_REG_UNK_92,DIB3000MB_UNK_92); - wr(DIB3000MB_REG_UNK_96,DIB3000MB_UNK_96); - wr(DIB3000MB_REG_UNK_97,DIB3000MB_UNK_97); - wr(DIB3000MB_REG_UNK_106,DIB3000MB_UNK_106); - wr(DIB3000MB_REG_UNK_107,DIB3000MB_UNK_107); - wr(DIB3000MB_REG_UNK_108,DIB3000MB_UNK_108); - wr(DIB3000MB_REG_UNK_122,DIB3000MB_UNK_122); - wr(DIB3000MB_REG_MOBILE_MODE_QAM,DIB3000MB_MOBILE_MODE_QAM_OFF); - wr(DIB3000MB_REG_BERLEN,DIB3000MB_BERLEN_DEFAULT); - - wr_foreach(dib3000mb_reg_filter_coeffs,dib3000mb_filter_coeffs); - - wr(DIB3000MB_REG_MOBILE_ALGO,DIB3000MB_MOBILE_ALGO_ON); - wr(DIB3000MB_REG_MULTI_DEMOD_MSB,DIB3000MB_MULTI_DEMOD_MSB); - wr(DIB3000MB_REG_MULTI_DEMOD_LSB,DIB3000MB_MULTI_DEMOD_LSB); - - wr(DIB3000MB_REG_OUTPUT_MODE,DIB3000MB_OUTPUT_MODE_SLAVE); - - wr(DIB3000MB_REG_FIFO_142,DIB3000MB_FIFO_142); - wr(DIB3000MB_REG_MPEG2_OUT_MODE,DIB3000MB_MPEG2_OUT_MODE_188); + wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz); + + wr(DIB3000MB_REG_UNK_68, DIB3000MB_UNK_68); + wr(DIB3000MB_REG_UNK_69, DIB3000MB_UNK_69); + wr(DIB3000MB_REG_UNK_71, DIB3000MB_UNK_71); + wr(DIB3000MB_REG_UNK_77, DIB3000MB_UNK_77); + wr(DIB3000MB_REG_UNK_78, DIB3000MB_UNK_78); + wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT); + wr(DIB3000MB_REG_UNK_92, DIB3000MB_UNK_92); + wr(DIB3000MB_REG_UNK_96, DIB3000MB_UNK_96); + wr(DIB3000MB_REG_UNK_97, DIB3000MB_UNK_97); + wr(DIB3000MB_REG_UNK_106, DIB3000MB_UNK_106); + wr(DIB3000MB_REG_UNK_107, DIB3000MB_UNK_107); + wr(DIB3000MB_REG_UNK_108, DIB3000MB_UNK_108); + wr(DIB3000MB_REG_UNK_122, DIB3000MB_UNK_122); + wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF); + wr(DIB3000MB_REG_BERLEN, DIB3000MB_BERLEN_DEFAULT); + + wr_foreach(dib3000mb_reg_filter_coeffs, dib3000mb_filter_coeffs); + + wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_ON); + wr(DIB3000MB_REG_MULTI_DEMOD_MSB, DIB3000MB_MULTI_DEMOD_MSB); + wr(DIB3000MB_REG_MULTI_DEMOD_LSB, DIB3000MB_MULTI_DEMOD_LSB); + + wr(DIB3000MB_REG_OUTPUT_MODE, DIB3000MB_OUTPUT_MODE_SLAVE); + + wr(DIB3000MB_REG_FIFO_142, DIB3000MB_FIFO_142); + wr(DIB3000MB_REG_MPEG2_OUT_MODE, DIB3000MB_MPEG2_OUT_MODE_188); wr(DIB3000MB_REG_PID_PARSE, DIB3000MB_PID_PARSE_ACTIVATE); - wr(DIB3000MB_REG_FIFO,DIB3000MB_FIFO_INHIBIT); - wr(DIB3000MB_REG_FIFO_146,DIB3000MB_FIFO_146); - wr(DIB3000MB_REG_FIFO_147,DIB3000MB_FIFO_147); + wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT); + wr(DIB3000MB_REG_FIFO_146, DIB3000MB_FIFO_146); + wr(DIB3000MB_REG_FIFO_147, DIB3000MB_FIFO_147); - wr(DIB3000MB_REG_DATA_IN_DIVERSITY,DIB3000MB_DATA_DIVERSITY_IN_OFF); + wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF); - if (state->config.pll_init) { - wr(DIB3000MB_REG_TUNER, - DIB3000_TUNER_WRITE_ENABLE(state->config.pll_addr)); + if (state->config.pll_init) state->config.pll_init(fe); - wr(DIB3000MB_REG_TUNER, - DIB3000_TUNER_WRITE_DISABLE(state->config.pll_addr)); - } return 0; } @@ -403,7 +395,7 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) static int dib3000mb_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) { - struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; + struct dib3000_state* state = fe->demodulator_priv; struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; fe_code_rate_t *cr; u16 tps_val; @@ -414,6 +406,7 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, 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) @@ -422,6 +415,7 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, 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) @@ -452,7 +446,7 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, default: err("Unexpected constellation returned by TPS (%d)", tps_val); break; - } + } deb_getf("TPS: %d\n", tps_val); if (rd(DIB3000MB_REG_TPS_HRCH)) { @@ -562,7 +556,7 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat) { - struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; + struct dib3000_state* state = fe->demodulator_priv; *stat = 0; @@ -575,16 +569,9 @@ static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat) if (rd(DIB3000MB_REG_TS_SYNC_LOCK)) *stat |= (FE_HAS_SYNC | FE_HAS_LOCK); - deb_info("actual status is %2x\n",*stat); + deb_getf("actual status is %2x\n",*stat); - deb_getf("tps %x %x %x %x %x\n", - rd(DIB3000MB_REG_TPS_1), - rd(DIB3000MB_REG_TPS_2), - rd(DIB3000MB_REG_TPS_3), - rd(DIB3000MB_REG_TPS_4), - rd(DIB3000MB_REG_TPS_5)); - - deb_info("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n", + deb_getf("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n", rd(DIB3000MB_REG_TPS_LOCK), rd(DIB3000MB_REG_TPS_QAM), rd(DIB3000MB_REG_TPS_HRCH), @@ -601,99 +588,50 @@ static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat) static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber) { - struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; + struct dib3000_state* state = fe->demodulator_priv; - *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB) ); + *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB)); return 0; } -/* - * Amaury: - * signal strength is measured with dBm (power compared to mW) - * the standard range is -90dBm(low power) to -10 dBm (strong power), - * but the calibration is done for -100 dBm to 0dBm - */ -#define DIB3000MB_AGC_REF_dBm -14 -#define DIB3000MB_GAIN_SLOPE_dBm 100 -#define DIB3000MB_GAIN_DELTA_dBm -2 +/* see dib3000-watch dvb-apps for exact calcuations of signal_strength and snr */ static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength) { - struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; - -/* TODO log10 - u16 sigpow = rd(DIB3000MB_REG_SIGNAL_POWER), - n_agc_power = rd(DIB3000MB_REG_AGC_POWER), - rf_power = rd(DIB3000MB_REG_RF_POWER); - double rf_power_dBm, ad_power_dBm, minar_power_dBm; - - if (n_agc_power == 0 ) - n_agc_power = 1 ; - - ad_power_dBm = 10 * log10 ( (float)n_agc_power / (float)(1<<16) ); - minor_power_dBm = ad_power_dBm - DIB3000MB_AGC_REF_dBm; - rf_power_dBm = (-DIB3000MB_GAIN_SLOPE_dBm * (float)rf_power / (float)(1<<16) + - DIB3000MB_GAIN_DELTA_dBm) + minor_power_dBm; - // relative rf_power - *strength = (u16) ((rf_power_dBm + 100) / 100 * 0xffff); -*/ + struct dib3000_state* state = fe->demodulator_priv; + *strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170; return 0; } -/* - * Amaury: - * snr is the signal quality measured in dB. - * snr = 10*log10(signal power / noise power) - * the best quality is near 35dB (cable transmission & good modulator) - * the minimum without errors depend of transmission parameters - * some indicative values are given in en300744 Annex A - * ex : 16QAM 2/3 (Gaussian) = 11.1 dB - * - * If SNR is above 20dB, BER should be always 0. - * choose 0dB as the minimum - */ static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr) { - struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; + struct dib3000_state* state = fe->demodulator_priv; short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER); int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) | rd(DIB3000MB_REG_NOISE_POWER_LSB); -/* - float snr_dBm=0; - - if (sigpow > 0 && icipow > 0) - snr_dBm = 10.0 * log10( (float) (sigpow<<8) / (float)icipow ) ; - else if (sigpow > 0) - snr_dBm = 35; - - *snr = (u16) ((snr_dBm / 35) * 0xffff); -*/ *snr = (sigpow << 8) / ((icipow > 0) ? icipow : 1); return 0; } static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) { - struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; + struct dib3000_state* state = fe->demodulator_priv; - *unc = rd(DIB3000MB_REG_UNC); + *unc = rd(DIB3000MB_REG_PACKET_ERROR_RATE); return 0; } static int dib3000mb_sleep(struct dvb_frontend* fe) { - struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; - - wr(DIB3000MB_REG_POWER_CONTROL,DIB3000MB_POWER_DOWN); + struct dib3000_state* state = fe->demodulator_priv; + deb_info("dib3000mb is going to bed.\n"); + wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_DOWN); return 0; } static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) { tune->min_delay_ms = 800; - tune->step_size = 166667; - tune->max_drift = 166667*2; - return 0; } @@ -709,29 +647,22 @@ static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_ static void dib3000mb_release(struct dvb_frontend* fe) { - struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv; + struct dib3000_state *state = fe->demodulator_priv; kfree(state); } /* pid filter and transfer stuff */ -static int dib3000mb_pid_control(struct dvb_frontend *fe,int pid,int onoff) +static int dib3000mb_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff) { struct dib3000_state *state = fe->demodulator_priv; - int index = dib3000_get_pid_index(state->pid_list, DIB3000MB_NUM_PIDS, pid, &state->pid_list_lock,onoff); pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0); - - if (index >= 0) { - wr(index+DIB3000MB_REG_FIRST_PID,pid); - } else { - err("no more pids for filtering."); - return -ENOMEM; - } + wr(index+DIB3000MB_REG_FIRST_PID,pid); return 0; } static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff) { - struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv; + struct dib3000_state *state = fe->demodulator_priv; deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling"); if (onoff) { @@ -740,24 +671,36 @@ static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff) wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT); } return 0; - } +} static int dib3000mb_pid_parse(struct dvb_frontend *fe, int onoff) { - //struct dib3000_state *state = fe->demodulator_priv; - /* switch it off and on */ + struct dib3000_state *state = fe->demodulator_priv; + deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling"); + wr(DIB3000MB_REG_PID_PARSE,onoff); return 0; +} + +static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr) +{ + struct dib3000_state *state = fe->demodulator_priv; + if (onoff) { + wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr)); + } else { + wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr)); } + return 0; +} static struct dvb_frontend_ops dib3000mb_ops; struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, - struct i2c_adapter* i2c, struct dib3000_xfer_ops *xfer_ops) + struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops) { struct dib3000_state* state = NULL; /* allocate memory for the internal state */ - state = (struct dib3000_state*) kmalloc(sizeof(struct dib3000_state), GFP_KERNEL); + state = kzalloc(sizeof(struct dib3000_state), GFP_KERNEL); if (state == NULL) goto error; @@ -773,9 +716,6 @@ struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, if (rd(DIB3000_REG_DEVICE_ID) != DIB3000MB_DEVICE_ID) goto error; - if (dib3000_init_pid_list(state,DIB3000MB_NUM_PIDS)) - goto error; - /* create dvb_frontend */ state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; @@ -784,22 +724,22 @@ struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, xfer_ops->pid_parse = dib3000mb_pid_parse; xfer_ops->fifo_ctrl = dib3000mb_fifo_control; xfer_ops->pid_ctrl = dib3000mb_pid_control; + xfer_ops->tuner_pass_ctrl = dib3000mb_tuner_pass_ctrl; return &state->frontend; error: - if (state) kfree(state); return NULL; - } +} static struct dvb_frontend_ops dib3000mb_ops = { .info = { - .name = "DiBcom 3000-MB DVB-T", - .type = FE_OFDM, - .frequency_min = 44250000, - .frequency_max = 867250000, + .name = "DiBcom 3000M-B DVB-T", + .type = FE_OFDM, + .frequency_min = 44250000, + .frequency_max = 867250000, .frequency_stepsize = 62500, .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | @@ -807,6 +747,7 @@ static struct dvb_frontend_ops dib3000mb_ops = { FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO, },