}
/*============================================================================*/
-static int
-ctrl_get_qam_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality);
+static int ctrl_get_qam_sig_quality(struct drx_demod_instance *demod);
+
static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel)
{
+ struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+ struct drxj_data *ext_attr = demod->my_ext_attr;
int rc;
u32 iqm_fs_rate_ofs = 0;
u32 iqm_fs_rate_lo = 0;
u16 fsm_state = 0;
int i = 0;
int ofsofs = 0;
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
-
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
/* Silence the controlling of lc, equ, and the acquisition state machine */
rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
struct drx_channel *channel,
s32 tuner_freq_offset, enum drx_lock_status *lock_status)
{
- struct drx_sig_quality sig_quality;
- struct drxj_data *ext_attr = NULL;
+ struct drxj_data *ext_attr = demod->my_ext_attr;
+ struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+ struct drx39xxj_state *state = dev_addr->user_data;
+ struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
int rc;
u32 lck_state = NO_LOCK;
u32 start_time = 0;
u16 data = 0;
/* external attributes for storing aquired channel constellation */
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
*lock_status = DRX_NOT_LOCKED;
start_time = jiffies_to_msecs(jiffies);
lck_state = NO_LOCK;
switch (lck_state) {
case NO_LOCK:
if (*lock_status == DRXJ_DEMOD_LOCK) {
- rc = ctrl_get_qam_sig_quality(demod, &sig_quality);
+ rc = ctrl_get_qam_sig_quality(demod);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
- if (sig_quality.MER > 208) {
+ if (p->cnr.stat[0].svalue > 20800) {
lck_state = DEMOD_LOCKED;
/* some delay to see if fec_lock possible TODO find the right value */
timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, waiting longer */
if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
((jiffies_to_msecs(jiffies) - d_locked_time) >
DRXJ_QAM_FEC_LOCK_WAITTIME)) {
- rc = ctrl_get_qam_sig_quality(demod, &sig_quality);
+ rc = ctrl_get_qam_sig_quality(demod);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
- if (sig_quality.MER > 208) {
+ if (p->cnr.stat[0].svalue > 20800) {
rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
struct drx_channel *channel,
s32 tuner_freq_offset, enum drx_lock_status *lock_status)
{
- struct drx_sig_quality sig_quality;
- struct drxj_data *ext_attr = NULL;
+ struct drxj_data *ext_attr = demod->my_ext_attr;
+ struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+ struct drx39xxj_state *state = dev_addr->user_data;
+ struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
int rc;
u32 lck_state = NO_LOCK;
u32 start_time = 0;
u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
/* external attributes for storing aquired channel constellation */
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
*lock_status = DRX_NOT_LOCKED;
start_time = jiffies_to_msecs(jiffies);
lck_state = NO_LOCK;
switch (lck_state) {
case NO_LOCK:
if (*lock_status == DRXJ_DEMOD_LOCK) {
- rc = ctrl_get_qam_sig_quality(demod, &sig_quality);
+ rc = ctrl_get_qam_sig_quality(demod);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
- if (sig_quality.MER > 268) {
+ if (p->cnr.stat[0].svalue > 26800) {
lck_state = DEMOD_LOCKED;
timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, wait longer */
d_locked_time = jiffies_to_msecs(jiffies);
* Pre-condition: Device must be started and in lock.
*/
static int
-ctrl_get_qam_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
+ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
{
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
- int rc;
- enum drx_modulation constellation = DRX_CONSTELLATION_UNKNOWN;
+ struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+ struct drxj_data *ext_attr = demod->my_ext_attr;
+ struct drx39xxj_state *state = dev_addr->user_data;
+ struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
struct drxjrs_errors measuredrs_errors = { 0, 0, 0, 0, 0 };
+ enum drx_modulation constellation = ext_attr->constellation;
+ int rc;
u32 pre_bit_err_rs = 0; /* pre RedSolomon Bit Error Rate */
u32 post_bit_err_rs = 0; /* post RedSolomon Bit Error Rate */
u16 qam_vd_period = 0; /* Viterbi Measurement period */
u32 vd_bit_cnt = 0; /* ViterbiDecoder Bit Count */
- /* get device basic information */
- dev_addr = demod->my_i2c_dev_addr;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
- constellation = ext_attr->constellation;
-
/* read the physical registers */
/* Get the RS error data */
rc = get_qamrs_err_count(dev_addr, &measuredrs_errors);
qam_post_rs_ber = e / m;
/* fill signal quality data structure */
- sig_quality->MER = ((u16) qam_sl_mer);
+ p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+ p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+ p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+ p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+ p->block_error.stat[0].scale = FE_SCALE_COUNTER;
+ p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+
+ p->cnr.stat[0].svalue = ((u16) qam_sl_mer) * 100;
if (ext_attr->standard == DRX_STANDARD_ITU_B)
- sig_quality->pre_viterbi_ber = qam_vd_ser;
+ p->pre_bit_error.stat[0].uvalue += qam_vd_ser;
else
- sig_quality->pre_viterbi_ber = qam_pre_rs_ber;
- sig_quality->post_viterbi_ber = qam_pre_rs_ber;
- sig_quality->post_reed_solomon_ber = qam_post_rs_ber;
- sig_quality->scale_factor_ber = ((u32) 1000000);
+ p->pre_bit_error.stat[0].uvalue += qam_pre_rs_ber;
+
+ p->post_bit_error.stat[0].uvalue = qam_post_rs_ber;
+
+ p->pre_bit_count.stat[0].uvalue += 1000000;
+ p->post_bit_count.stat[0].uvalue += 1000000;
+
+ p->block_error.stat[0].uvalue += pkt_errs;
+
#ifdef DRXJ_SIGNAL_ACCUM_ERR
rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
-#else
- sig_quality->packet_error = ((u16) pkt_errs);
#endif
return 0;
rw_error:
+ p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
return -EIO;
}
===== SigQuality() ==========================================================
===========================================================================*/
-static u16
-mer2indicator(u16 mer, u16 min_mer, u16 threshold_mer, u16 max_mer)
-{
- u16 indicator = 0;
-
- if (mer < min_mer) {
- indicator = 0;
- } else if (mer < threshold_mer) {
- if ((threshold_mer - min_mer) != 0)
- indicator = 25 * (mer - min_mer) / (threshold_mer - min_mer);
- } else if (mer < max_mer) {
- if ((max_mer - threshold_mer) != 0)
- indicator = 25 + 75 * (mer - threshold_mer) / (max_mer - threshold_mer);
- else
- indicator = 25;
- } else {
- indicator = 100;
- }
-
- return indicator;
-}
-
/**
* \fn int ctrl_sig_quality()
* \brief Retreive signal quality form device.
*/
static int
-ctrl_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
+ctrl_sig_quality(struct drx_demod_instance *demod,
+ enum drx_lock_status lock_status)
{
- struct i2c_device_addr *dev_addr = NULL;
- struct drxj_data *ext_attr = NULL;
+ struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+ struct drxj_data *ext_attr = demod->my_ext_attr;
+ struct drx39xxj_state *state = dev_addr->user_data;
+ struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
+ enum drx_standard standard = ext_attr->standard;
int rc;
- enum drx_standard standard = DRX_STANDARD_UNKNOWN;
- enum drx_lock_status lock_status = DRX_NOT_LOCKED;
- u16 min_mer = 0;
- u16 max_mer = 0;
- u16 threshold_mer = 0;
-
- /* Check arguments */
- if ((sig_quality == NULL) || (demod == NULL))
- return -EINVAL;
+ u32 ber;
+ u16 pkt, mer, strength;
- ext_attr = (struct drxj_data *) demod->my_ext_attr;
- standard = ext_attr->standard;
-
- /* get basic information */
- dev_addr = demod->my_i2c_dev_addr;
- rc = ctrl_lock_status(demod, &lock_status);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
+ rc = get_sig_strength(demod, &strength);
+ if (rc < 0) {
+ pr_err("error getting signal strength %d\n", rc);
+ p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ } else {
+ p->strength.stat[0].scale = FE_SCALE_RELATIVE;
+ p->strength.stat[0].uvalue = 65535UL * strength/ 100;
}
+
switch (standard) {
case DRX_STANDARD_8VSB:
#ifdef DRXJ_SIGNAL_ACCUM_ERR
- rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
- if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
- }
-#else
- rc = get_vsb_post_rs_pck_err(dev_addr, &sig_quality->packet_error);
+ rc = get_acc_pkt_err(demod, &pkt);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
#endif
if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
- sig_quality->post_viterbi_ber = 500000;
- sig_quality->MER = 20;
- sig_quality->pre_viterbi_ber = 0;
+ p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
} else {
+ rc = get_vsb_post_rs_pck_err(dev_addr, &pkt);
+ if (rc != 0) {
+ pr_err("error %d getting UCB\n", rc);
+ p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ } else {
+ p->block_error.stat[0].scale = FE_SCALE_COUNTER;
+ p->block_error.stat[0].uvalue += pkt;
+ }
+
/* PostViterbi is compute in steps of 10^(-6) */
- rc = get_vs_bpre_viterbi_ber(dev_addr, &sig_quality->pre_viterbi_ber);
+ rc = get_vs_bpre_viterbi_ber(dev_addr, &ber);
if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
+ pr_err("error %d getting pre-ber\n", rc);
+ p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ } else {
+ p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+ p->pre_bit_error.stat[0].uvalue += ber;
+ p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+ p->pre_bit_count.stat[0].uvalue += 1000000;
}
- rc = get_vs_bpost_viterbi_ber(dev_addr, &sig_quality->post_viterbi_ber);
+
+ rc = get_vs_bpost_viterbi_ber(dev_addr, &ber);
if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
+ pr_err("error %d getting post-ber\n", rc);
+ p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ } else {
+ p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+ p->post_bit_error.stat[0].uvalue += ber;
+ p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+ p->post_bit_count.stat[0].uvalue += 1000000;
}
- rc = get_vsbmer(dev_addr, &sig_quality->MER);
+ rc = get_vsbmer(dev_addr, &mer);
if (rc != 0) {
- pr_err("error %d\n", rc);
- goto rw_error;
+ pr_err("error %d getting MER\n", rc);
+ p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ } else {
+ p->cnr.stat[0].svalue = mer * 100;
+ p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
}
}
- min_mer = 20;
- max_mer = 360;
- threshold_mer = 145;
- sig_quality->post_reed_solomon_ber = 0;
- sig_quality->scale_factor_ber = 1000000;
- sig_quality->indicator =
- mer2indicator(sig_quality->MER, min_mer, threshold_mer,
- max_mer);
break;
#ifndef DRXJ_VSB_ONLY
case DRX_STANDARD_ITU_A:
case DRX_STANDARD_ITU_B:
case DRX_STANDARD_ITU_C:
- rc = ctrl_get_qam_sig_quality(demod, sig_quality);
+ rc = ctrl_get_qam_sig_quality(demod);
if (rc != 0) {
pr_err("error %d\n", rc);
goto rw_error;
}
- if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
- switch (ext_attr->constellation) {
- case DRX_CONSTELLATION_QAM256:
- sig_quality->MER = 210;
- break;
- case DRX_CONSTELLATION_QAM128:
- sig_quality->MER = 180;
- break;
- case DRX_CONSTELLATION_QAM64:
- sig_quality->MER = 150;
- break;
- case DRX_CONSTELLATION_QAM32:
- sig_quality->MER = 120;
- break;
- case DRX_CONSTELLATION_QAM16:
- sig_quality->MER = 90;
- break;
- default:
- sig_quality->MER = 0;
- return -EIO;
- }
- }
-
- switch (ext_attr->constellation) {
- case DRX_CONSTELLATION_QAM256:
- min_mer = 210;
- threshold_mer = 270;
- max_mer = 380;
- break;
- case DRX_CONSTELLATION_QAM64:
- min_mer = 150;
- threshold_mer = 210;
- max_mer = 380;
- break;
- case DRX_CONSTELLATION_QAM128:
- case DRX_CONSTELLATION_QAM32:
- case DRX_CONSTELLATION_QAM16:
- break;
- default:
- return -EIO;
- }
- sig_quality->indicator =
- mer2indicator(sig_quality->MER, min_mer, threshold_mer,
- max_mer);
break;
#endif
default:
default:
pr_err("Lock state unknown %d\n", lock_status);
}
+ ctrl_sig_quality(demod, lock_status);
return 0;
}
static int drx39xxj_read_ber(struct dvb_frontend *fe, u32 *ber)
{
- struct drx39xxj_state *state = fe->demodulator_priv;
- struct drx_demod_instance *demod = state->demod;
- int result;
- struct drx_sig_quality sig_quality;
+ struct dtv_frontend_properties *p = &fe->dtv_property_cache;
- result = ctrl_sig_quality(demod, &sig_quality);
- if (result != 0) {
- pr_err("drx39xxj: could not get ber!\n");
+ if (p->pre_bit_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
*ber = 0;
return 0;
}
- *ber = sig_quality.post_reed_solomon_ber;
+ *ber = p->pre_bit_error.stat[0].uvalue;
return 0;
}
static int drx39xxj_read_signal_strength(struct dvb_frontend *fe,
u16 *strength)
{
- struct drx39xxj_state *state = fe->demodulator_priv;
- struct drx_demod_instance *demod = state->demod;
- int result;
- struct drx_sig_quality sig_quality;
+ struct dtv_frontend_properties *p = &fe->dtv_property_cache;
- result = ctrl_sig_quality(demod, &sig_quality);
- if (result != 0) {
- pr_err("drx39xxj: could not get signal strength!\n");
+ if (p->strength.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
*strength = 0;
return 0;
}
- /* 1-100% scaled to 0-65535 */
- *strength = (sig_quality.indicator * 65535 / 100);
+ *strength = p->strength.stat[0].uvalue;
return 0;
}
static int drx39xxj_read_snr(struct dvb_frontend *fe, u16 *snr)
{
- struct drx39xxj_state *state = fe->demodulator_priv;
- struct drx_demod_instance *demod = state->demod;
- int result;
- struct drx_sig_quality sig_quality;
+ struct dtv_frontend_properties *p = &fe->dtv_property_cache;
- result = ctrl_sig_quality(demod, &sig_quality);
- if (result != 0) {
- pr_err("drx39xxj: could not read snr!\n");
+ if (p->cnr.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
*snr = 0;
return 0;
}
- *snr = sig_quality.MER;
+ *snr = p->cnr.stat[0].svalue / 10;
return 0;
}
-static int drx39xxj_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+static int drx39xxj_read_ucblocks(struct dvb_frontend *fe, u32 *ucb)
{
- struct drx39xxj_state *state = fe->demodulator_priv;
- struct drx_demod_instance *demod = state->demod;
- int result;
- struct drx_sig_quality sig_quality;
+ struct dtv_frontend_properties *p = &fe->dtv_property_cache;
- result = ctrl_sig_quality(demod, &sig_quality);
- if (result != 0) {
- pr_err("drx39xxj: could not get uc blocks!\n");
- *ucblocks = 0;
+ if (p->block_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
+ *ucb = 0;
return 0;
}
- *ucblocks = sig_quality.packet_error;
+ *ucb = p->block_error.stat[0].uvalue;
return 0;
}
pr_err("Failed to disable LNA!\n");
return 0;
}
-#ifdef DJH_DEBUG
- for (i = 0; i < 2000; i++) {
- fe_status_t status;
- drx39xxj_read_status(fe, &status);
- pr_debug("i=%d status=%d\n", i, status);
- msleep(100);
- i += 100;
- }
-#endif
+
+ /* After set_frontend, except for strength, stats aren't available */
+ p->strength.stat[0].scale = FE_SCALE_RELATIVE;
return 0;
}