summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb/frontends/dib3000mc.c
diff options
context:
space:
mode:
authorPatrick Boettcher <devnull@localhost>2004-11-23 20:16:39 +0000
committerPatrick Boettcher <devnull@localhost>2004-11-23 20:16:39 +0000
commitee339a263583741edee12aa5c5ef05f132ff5ed6 (patch)
treeb9c817b2d45adfaac3057162e4952c640489af84 /linux/drivers/media/dvb/frontends/dib3000mc.c
parent32b5a869607ea6d1f30bc165dddec51a611b6632 (diff)
downloadmediapointer-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.c327
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;