diff options
author | Patrick Boettcher <devnull@localhost> | 2004-11-23 20:16:39 +0000 |
---|---|---|
committer | Patrick Boettcher <devnull@localhost> | 2004-11-23 20:16:39 +0000 |
commit | ee339a263583741edee12aa5c5ef05f132ff5ed6 (patch) | |
tree | b9c817b2d45adfaac3057162e4952c640489af84 /linux/drivers/media/dvb/frontends/dib3000mc.c | |
parent | 32b5a869607ea6d1f30bc165dddec51a611b6632 (diff) | |
download | mediapointer-dvb-s2-ee339a263583741edee12aa5c5ef05f132ff5ed6.tar.gz mediapointer-dvb-s2-ee339a263583741edee12aa5c5ef05f132ff5ed6.tar.bz2 |
- revise debug options
- merged changes from DiBcom v2.1 drivers to dib3000mc
- added transfer control callbacks to dib3000mc
Diffstat (limited to 'linux/drivers/media/dvb/frontends/dib3000mc.c')
-rw-r--r-- | linux/drivers/media/dvb/frontends/dib3000mc.c | 327 |
1 files changed, 209 insertions, 118 deletions
diff --git a/linux/drivers/media/dvb/frontends/dib3000mc.c b/linux/drivers/media/dvb/frontends/dib3000mc.c index 2127bd66b..2a9de89aa 100644 --- a/linux/drivers/media/dvb/frontends/dib3000mc.c +++ b/linux/drivers/media/dvb/frontends/dib3000mc.c @@ -38,6 +38,17 @@ #define DRIVER_DESC "DiBcom 3000-MC DVB-T demodulator driver" #define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de" +#ifdef CONFIG_DVB_DIBCOM_DEBUG +static int debug; +module_param(debug, int, 0x644); +MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able))."); +#endif +#define deb_info(args...) dprintk(0x01,args) +#define deb_xfer(args...) dprintk(0x02,args) +#define deb_setf(args...) dprintk(0x04,args) +#define deb_getf(args...) dprintk(0x08,args) + + static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode, fe_transmit_mode_t transmission_mode, fe_bandwidth_t bandwidth) { @@ -75,7 +86,7 @@ static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode, break; case 1: /* new algo */ wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[1]); - set(DIB3000MC_REG_IMP_NOISE_55,DIB3000MC_IMP_NEW_ALGO(0)); /* gives 1<<10 */ + 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]); @@ -84,6 +95,96 @@ static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode, return 0; } +static int dib3000mc_set_timing(struct dib3000_state *state, int upd_offset, + fe_transmit_mode_t fft, fe_bandwidth_t bw) +{ + u16 timf_msb,timf_lsb; + s32 tim_offset,tim_sgn; + u64 comp1,comp2,comp=0; + + switch (bw) { + case BANDWIDTH_8_MHZ: comp = DIB3000MC_CLOCK_REF*8; break; + case BANDWIDTH_7_MHZ: comp = DIB3000MC_CLOCK_REF*7; break; + case 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 == 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(struct dib3000_state *state, fe_bandwidth_t 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 BANDWIDTH_8_MHZ: + wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz); + break; + case BANDWIDTH_7_MHZ: + wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_7mhz); + break; + case 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_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep); @@ -94,6 +195,7 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe, struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; fe_code_rate_t fe_cr = FEC_NONE; int search_state, seq; + u16 val; u8 fft=0, guard=0, qam=0, alpha=0, sel_hp=0, cr=0, hrch=0; if (tuner) { @@ -102,44 +204,28 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe, state->config->pll_set(fe, fep); wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(state->config->pll_addr)); + } - wr_foreach(dib3000mc_reg_offset,dib3000mc_offset[0]); - wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_AGC); - wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF); - - /* wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT); - wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[1]);*/ - wr(DIB3000MC_REG_UNK_133,DIB3000MC_UNK_133); + dib3000mc_set_timing(state,0,ofdm->transmission_mode,ofdm->bandwidth); + dib3000mc_init_auto_scan(state, ofdm->bandwidth, 0); + + wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_AGC); + wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF); - switch (ofdm->bandwidth) { - case BANDWIDTH_8_MHZ: - wr_foreach(dib3000mc_reg_timing_freq,dib3000mc_timing_freq[3]); - wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz); - wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[3]); - break; - case BANDWIDTH_7_MHZ: - wr_foreach(dib3000mc_reg_timing_freq,dib3000mc_timing_freq[2]); - wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_7mhz); - wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[2]); - break; - case BANDWIDTH_6_MHZ: - wr_foreach(dib3000mc_reg_timing_freq,dib3000mc_timing_freq[1]); - wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_6mhz); - wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[1]); - break; -/* case BANDWIDTH_5_MHZ: - wr_foreach(dib3000mc_reg_timing_freq,dib3000mc_timing_freq[0]); - wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_5mhz); - wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[0]); - break;*/ - case BANDWIDTH_AUTO: - return -EOPNOTSUPP; - default: - err("unkown bandwidth value."); - return -EINVAL; - } - } +/* Default cfg isi offset adp */ + wr_foreach(dib3000mc_reg_offset,dib3000mc_offset[0]); + + wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT | DIB3000MC_ISI_INHIBIT); + wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[1]); + wr(DIB3000MC_REG_UNK_133,DIB3000MC_UNK_133); + wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general); + if (ofdm->bandwidth == BANDWIDTH_8_MHZ) { + wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[3]); + } else { + wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[0]); + } + switch (ofdm->transmission_mode) { case TRANSMISSION_MODE_2K: fft = DIB3000_TRANSMISSION_MODE_2K; break; case TRANSMISSION_MODE_8K: fft = DIB3000_TRANSMISSION_MODE_8K; break; @@ -214,6 +300,10 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe, wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS(seq,1)); dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->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); @@ -222,18 +312,18 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe, /* something has to be auto searched */ if (ofdm->constellation == QAM_AUTO || ofdm->hierarchy_information == HIERARCHY_AUTO || + ofdm->guard_interval == GUARD_INTERVAL_AUTO || + ofdm->transmission_mode == TRANSMISSION_MODE_AUTO || fe_cr == FEC_AUTO || - fep->inversion == INVERSION_AUTO) { + fep->inversion == INVERSION_AUTO + ) { int as_count=0; - u16 tmp; deb_setf("autosearch enabled.\n"); - wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_INHIBIT); - - tmp = rd(DIB3000MC_REG_DEMOD_PARM); - wr(DIB3000MC_REG_DEMOD_PARM,tmp | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON); - wr(DIB3000MC_REG_DEMOD_PARM,tmp); + 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) @@ -243,6 +333,7 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe, if (search_state == 1) { struct dvb_frontend_parameters feps; + feps.u.ofdm.bandwidth = ofdm->bandwidth; /* bw is not auto searched */; if (dib3000mc_get_frontend(fe, &feps) == 0) { deb_setf("reading tuning data from frontend succeeded.\n"); return dib3000mc_set_frontend(fe, &feps, 0); @@ -253,25 +344,37 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe, wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[qam]); /* set_offset_cfg */ wr_foreach(dib3000mc_reg_offset, - dib3000mc_offset[(ofdm->transmission_mode = TRANSMISSION_MODE_8K)+1]); + dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]); - wr(DIB3000MC_REG_LOCK_MASK,DIB3000MC_ACTIVATE_LOCK_MASK); /* activates some locks if needed */ +// dib3000mc_set_timing(1,ofdm->transmission_mode,ofdm->bandwidth); + +// wr(DIB3000MC_REG_LOCK_MASK,DIB3000MC_ACTIVATE_LOCK_MASK); /* activates some locks if needed */ - set(DIB3000MC_REG_DEMOD_PARM,DIB3000MC_DEMOD_RST_AUTO_SRCH_ON); - set(DIB3000MC_REG_DEMOD_PARM,DIB3000MC_DEMOD_RST_AUTO_SRCH_OFF); +/* set_or(DIB3000MC_REG_DEMOD_PARM,DIB3000MC_DEMOD_RST_AUTO_SRCH_ON); + set_or(DIB3000MC_REG_DEMOD_PARM,DIB3000MC_DEMOD_RST_AUTO_SRCH_OFF); wr(DIB3000MC_REG_RESTART_VIT,DIB3000MC_RESTART_VIT_ON); - wr(DIB3000MC_REG_RESTART_VIT,DIB3000MC_RESTART_VIT_OFF); + wr(DIB3000MC_REG_RESTART_VIT,DIB3000MC_RESTART_VIT_OFF);*/ } return 0; } + + static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode) { struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; + state->timing_offset = 0; + state->timing_offset_comp_done = 0; + wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON); wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_PAR_CONT_CLK); - wr(DIB3000MC_REG_RST_I2C_ADDR,DIB3000MC_DEMOD_ADDR(state->config->demod_address)); + wr(DIB3000MC_REG_RST_I2C_ADDR, + DIB3000MC_DEMOD_ADDR(state->config->demod_address) | + DIB3000MC_DEMOD_ADDR_ON); + + wr(DIB3000MC_REG_RST_I2C_ADDR, + DIB3000MC_DEMOD_ADDR(state->config->demod_address)); wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_CONFIG); wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF); @@ -291,26 +394,31 @@ static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode) wr(DIB3000MC_REG_UNK_99,DIB3000MC_UNK_99); wr(DIB3000MC_REG_UNK_111,DIB3000MC_UNK_111_PH_N_MODE_0); /* phase noise algo off */ - wr_foreach(dib3000mc_reg_mobile_mode,dib3000mc_mobile_mode[1]); /* mobile mode - auto reception */ + /* mobile mode - portable reception */ + wr_foreach(dib3000mc_reg_mobile_mode,dib3000mc_mobile_mode[1]); /* TUNER_PANASONIC_ENV57H12D5: */ - wr_foreach(dib3000mc_reg_agc,dib3000mc_agc_tuner[1]); wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth); + wr_foreach(dib3000mc_reg_agc_bandwidth_general,dib3000mc_agc_bandwidth_general); + wr_foreach(dib3000mc_reg_agc,dib3000mc_agc_tuner[1]); - // 10 - wr(110,3277); + wr(DIB3000MC_REG_UNK_110,DIB3000MC_UNK_110); wr(26,0x6680); wr(DIB3000MC_REG_UNK_1,DIB3000MC_UNK_1); wr(DIB3000MC_REG_UNK_2,DIB3000MC_UNK_2); wr(DIB3000MC_REG_UNK_3,DIB3000MC_UNK_3); wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS_DEFAULT); + + wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general); wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz); + wr(DIB3000MC_REG_UNK_4,DIB3000MC_UNK_4); wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF); wr(DIB3000MC_REG_SET_DDS_FREQ_LSB,DIB3000MC_DDS_FREQ_LSB); - wr_foreach(dib3000mc_reg_timing_freq,dib3000mc_timing_freq[3]); + dib3000mc_set_timing(state,0,TRANSMISSION_MODE_2K,BANDWIDTH_8_MHZ); +// wr_foreach(dib3000mc_reg_timing_freq,dib3000mc_timing_freq[3]); wr(DIB3000MC_REG_UNK_120,DIB3000MC_UNK_120); wr(DIB3000MC_REG_UNK_134,DIB3000MC_UNK_134); @@ -319,7 +427,7 @@ static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode) dib3000mc_set_impulse_noise(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ); /* output mode control, just the MPEG2_SLAVE */ - set(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE); + set_or(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE); wr(DIB3000MC_REG_SMO_MODE,DIB3000MC_SMO_MODE_SLAVE); wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_SLAVE); wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_SLAVE); @@ -342,7 +450,8 @@ static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode) wr(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF); - set(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF); + set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF); + /* if (state->config->pll_init) { wr(DIB3000MC_REG_TUNER, @@ -362,13 +471,13 @@ static int dib3000mc_get_frontend(struct dvb_frontend* fe, fe_code_rate_t *cr; u16 tps_val,cr_val; int inv_test1,inv_test2; - u32 dds_val, threshold = 0x100000; + u32 dds_val, threshold = 0x1000000; - if (!(rd(DIB3000MC_REG_LOCK_507) && DIB3000MC_LOCK_507)) + if (!(rd(DIB3000MC_REG_LOCK_507) & DIB3000MC_LOCK_507)) return 0; dds_val = ((rd(DIB3000MC_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MC_REG_DDS_FREQ_LSB); - if (dds_val & threshold) + if (dds_val < threshold) inv_test1 = 0; else if (dds_val == threshold) inv_test1 = 1; @@ -376,7 +485,7 @@ static int dib3000mc_get_frontend(struct dvb_frontend* fe, inv_test1 = 2; dds_val = ((rd(DIB3000MC_REG_SET_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MC_REG_SET_DDS_FREQ_LSB); - if (dds_val & threshold) + if (dds_val < threshold) inv_test2 = 0; else if (dds_val == threshold) inv_test2 = 1; @@ -542,65 +651,37 @@ static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) *unc = rd(DIB3000MC_REG_PACKET_ERROR_COUNT); 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 - */ + +/* see dib3000mb.c for calculation comments */ static int dib3000mc_read_signal_strength(struct dvb_frontend* fe, u16 *strength) { struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; + u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB); + *strength = (((val >> 6) & 0xff) << 8) + (val & 0x3f); -/* TODO log10 - u16 sigpow = rd(DIB3000MC_REG_SIGNAL_POWER), - n_agc_power = rd(DIB3000MC_REG_AGC_POWER), - rf_power = rd(DIB3000MC_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 - DIB3000MC_AGC_REF_dBm; - rf_power_dBm = (-DIB3000MC_GAIN_SLOPE_dBm * (float)rf_power / (float)(1<<16) + - DIB3000MC_GAIN_DELTA_dBm) + minor_power_dBm; - // relative rf_power - *strength = (u16) ((rf_power_dBm + 100) / 100 * 0xffff); -*/ -// *strength = rd(DIB3000MC_REG_SIGNAL_POWER) * 0xffff / 0x170; + deb_info("signal: mantisse = %d, exponent = %d\n",(*strength >> 8) & 0xff, *strength & 0xff); 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 - */ +/* see dib3000mb.c for calculation comments */ static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr) { -// struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; -// short sigpow = rd(DIB3000MC_REG_SIGNAL_POWER); -// int icipow = ((rd(DIB3000MC_REG_NOISE_POWER_MSB) & 0xff) << 16) | -// rd(DIB3000MC_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); + struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; + + u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_MSB), + val2 = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB); + u16 sig,noise; + + sig = (((val >> 6) & 0xff) << 8) + (val & 0x3f); + noise = (((val >> 4) & 0xff) << 8) + ((val & 0xf) << 2) + ((val2 >> 14) & 0x3); + if (noise == 0) + *snr = 0xffff; + else + *snr = (u16) sig/noise; + + deb_info("signal: mantisse = %d, exponent = %d\n",(sig >> 8) & 0xff, sig & 0xff); + deb_info("noise: mantisse = %d, exponent = %d\n",(noise >> 8) & 0xff, noise & 0xff); + deb_info("snr: %d\n",*snr); return 0; } @@ -608,7 +689,10 @@ static int dib3000mc_sleep(struct dvb_frontend* fe) { struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; -// wr(DIB3000MC_REG_POWER_CONTROL, DIB3000MC_POWER_DOWN); + set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_PWR_DOWN); + wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_DOWN); + wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_POWER_DOWN); + wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_DOWN); return 0; } @@ -658,18 +742,25 @@ static int dib3000mc_fifo_control(struct dvb_frontend *fe, int onoff) { struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv; u16 tmp = rd(DIB3000MC_REG_SMO_MODE); - wr(DIB3000MC_REG_SMO_MODE,tmp & 0xe7); -/* if (onoff) { + deb_xfer("%s fifo",onoff ? "enabling" : "disabling"); + if (onoff) { + wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH); } else { - wr(DIB3000MC_REG_SMO_MODE,tmp | 0x8); - }*/ + wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH); + } return 0; } -static int dib3000mc_pid_filter(struct dvb_frontend *fe, int onoff) +static int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff) { struct dib3000_state *state = fe->demodulator_priv; - /* switch it off and on */ + u16 tmp = rd(DIB3000MC_REG_SMO_MODE); + deb_xfer("%s pid parsing",onoff ? "enabling" : "disabling"); + if (onoff) { + wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_PID_PARSE); + } else { + wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_NO_PID_PARSE); + } return 0; } @@ -717,7 +808,7 @@ struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config, state->frontend.demodulator_priv = state; /* set the xfer operations */ - xfer_ops->pid_filter = dib3000mc_pid_filter; + xfer_ops->pid_parse = dib3000mc_pid_parse; xfer_ops->fifo_ctrl = dib3000mc_fifo_control; xfer_ops->pid_ctrl = dib3000mc_pid_control; |