aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <m.chehab@samsung.com>2014-03-09 16:46:01 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-03-11 06:37:19 -0400
commit03fdfbfd3b5944bfd210541a83c9b222e2c20920 (patch)
treedf45fa3ddf9a01da1a1bc13537a14997bc801858
parent80e5ed14e12d4452538c0492a560ab9a0294a850 (diff)
[media] drx-j: Prepare to use DVBv5 stats
Convert the stats internally to use DVBv5. For now, it will keep showing everything via DVBv3 API only, as the .len value were not initialized. That allows testing if the new stats code didn't break anything. A latter patch will add the final bits for the DVBv5 stats to fully work. Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/dvb-frontends/drx39xyj/drx_driver.h24
-rw-r--r--drivers/media/dvb-frontends/drx39xyj/drxj.c321
2 files changed, 125 insertions, 220 deletions
diff --git a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h
index e54eb35b52d9..9076bf21cc8a 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h
+++ b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h
@@ -1033,30 +1033,6 @@ struct drx_channel {
1033 1033
1034/*========================================*/ 1034/*========================================*/
1035 1035
1036/**
1037* \struct struct drx_sig_quality * Signal quality metrics.
1038*
1039* Used by DRX_CTRL_SIG_QUALITY.
1040*/
1041struct drx_sig_quality {
1042 u16 MER; /**< in steps of 0.1 dB */
1043 u32 pre_viterbi_ber;
1044 /**< in steps of 1/scale_factor_ber */
1045 u32 post_viterbi_ber;
1046 /**< in steps of 1/scale_factor_ber */
1047 u32 scale_factor_ber;
1048 /**< scale factor for BER */
1049 u16 packet_error;
1050 /**< number of packet errors */
1051 u32 post_reed_solomon_ber;
1052 /**< in steps of 1/scale_factor_ber */
1053 u32 pre_ldpc_ber;
1054 /**< in steps of 1/scale_factor_ber */
1055 u32 aver_iter;/**< in steps of 0.01 */
1056 u16 indicator;
1057 /**< indicative signal quality low=0..100=high */
1058};
1059
1060enum drx_cfg_sqi_speed { 1036enum drx_cfg_sqi_speed {
1061 DRX_SQI_SPEED_FAST = 0, 1037 DRX_SQI_SPEED_FAST = 0,
1062 DRX_SQI_SPEED_MEDIUM, 1038 DRX_SQI_SPEED_MEDIUM,
diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c
index ca807b1fc67c..6005e344f66c 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drxj.c
+++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c
@@ -8656,10 +8656,12 @@ rw_error:
8656} 8656}
8657 8657
8658/*============================================================================*/ 8658/*============================================================================*/
8659static int 8659static int ctrl_get_qam_sig_quality(struct drx_demod_instance *demod);
8660ctrl_get_qam_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality); 8660
8661static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel) 8661static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel)
8662{ 8662{
8663 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8664 struct drxj_data *ext_attr = demod->my_ext_attr;
8663 int rc; 8665 int rc;
8664 u32 iqm_fs_rate_ofs = 0; 8666 u32 iqm_fs_rate_ofs = 0;
8665 u32 iqm_fs_rate_lo = 0; 8667 u32 iqm_fs_rate_lo = 0;
@@ -8669,11 +8671,6 @@ static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *c
8669 u16 fsm_state = 0; 8671 u16 fsm_state = 0;
8670 int i = 0; 8672 int i = 0;
8671 int ofsofs = 0; 8673 int ofsofs = 0;
8672 struct i2c_device_addr *dev_addr = NULL;
8673 struct drxj_data *ext_attr = NULL;
8674
8675 dev_addr = demod->my_i2c_dev_addr;
8676 ext_attr = (struct drxj_data *) demod->my_ext_attr;
8677 8674
8678 /* Silence the controlling of lc, equ, and the acquisition state machine */ 8675 /* Silence the controlling of lc, equ, and the acquisition state machine */
8679 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0); 8676 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
@@ -8858,8 +8855,10 @@ qam64auto(struct drx_demod_instance *demod,
8858 struct drx_channel *channel, 8855 struct drx_channel *channel,
8859 s32 tuner_freq_offset, enum drx_lock_status *lock_status) 8856 s32 tuner_freq_offset, enum drx_lock_status *lock_status)
8860{ 8857{
8861 struct drx_sig_quality sig_quality; 8858 struct drxj_data *ext_attr = demod->my_ext_attr;
8862 struct drxj_data *ext_attr = NULL; 8859 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8860 struct drx39xxj_state *state = dev_addr->user_data;
8861 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
8863 int rc; 8862 int rc;
8864 u32 lck_state = NO_LOCK; 8863 u32 lck_state = NO_LOCK;
8865 u32 start_time = 0; 8864 u32 start_time = 0;
@@ -8868,7 +8867,6 @@ qam64auto(struct drx_demod_instance *demod,
8868 u16 data = 0; 8867 u16 data = 0;
8869 8868
8870 /* external attributes for storing aquired channel constellation */ 8869 /* external attributes for storing aquired channel constellation */
8871 ext_attr = (struct drxj_data *) demod->my_ext_attr;
8872 *lock_status = DRX_NOT_LOCKED; 8870 *lock_status = DRX_NOT_LOCKED;
8873 start_time = jiffies_to_msecs(jiffies); 8871 start_time = jiffies_to_msecs(jiffies);
8874 lck_state = NO_LOCK; 8872 lck_state = NO_LOCK;
@@ -8882,12 +8880,12 @@ qam64auto(struct drx_demod_instance *demod,
8882 switch (lck_state) { 8880 switch (lck_state) {
8883 case NO_LOCK: 8881 case NO_LOCK:
8884 if (*lock_status == DRXJ_DEMOD_LOCK) { 8882 if (*lock_status == DRXJ_DEMOD_LOCK) {
8885 rc = ctrl_get_qam_sig_quality(demod, &sig_quality); 8883 rc = ctrl_get_qam_sig_quality(demod);
8886 if (rc != 0) { 8884 if (rc != 0) {
8887 pr_err("error %d\n", rc); 8885 pr_err("error %d\n", rc);
8888 goto rw_error; 8886 goto rw_error;
8889 } 8887 }
8890 if (sig_quality.MER > 208) { 8888 if (p->cnr.stat[0].svalue > 20800) {
8891 lck_state = DEMOD_LOCKED; 8889 lck_state = DEMOD_LOCKED;
8892 /* some delay to see if fec_lock possible TODO find the right value */ 8890 /* some delay to see if fec_lock possible TODO find the right value */
8893 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, waiting longer */ 8891 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, waiting longer */
@@ -8951,12 +8949,12 @@ qam64auto(struct drx_demod_instance *demod,
8951 if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */ 8949 if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
8952 ((jiffies_to_msecs(jiffies) - d_locked_time) > 8950 ((jiffies_to_msecs(jiffies) - d_locked_time) >
8953 DRXJ_QAM_FEC_LOCK_WAITTIME)) { 8951 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
8954 rc = ctrl_get_qam_sig_quality(demod, &sig_quality); 8952 rc = ctrl_get_qam_sig_quality(demod);
8955 if (rc != 0) { 8953 if (rc != 0) {
8956 pr_err("error %d\n", rc); 8954 pr_err("error %d\n", rc);
8957 goto rw_error; 8955 goto rw_error;
8958 } 8956 }
8959 if (sig_quality.MER > 208) { 8957 if (p->cnr.stat[0].svalue > 20800) {
8960 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0); 8958 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
8961 if (rc != 0) { 8959 if (rc != 0) {
8962 pr_err("error %d\n", rc); 8960 pr_err("error %d\n", rc);
@@ -9005,8 +9003,10 @@ qam256auto(struct drx_demod_instance *demod,
9005 struct drx_channel *channel, 9003 struct drx_channel *channel,
9006 s32 tuner_freq_offset, enum drx_lock_status *lock_status) 9004 s32 tuner_freq_offset, enum drx_lock_status *lock_status)
9007{ 9005{
9008 struct drx_sig_quality sig_quality; 9006 struct drxj_data *ext_attr = demod->my_ext_attr;
9009 struct drxj_data *ext_attr = NULL; 9007 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9008 struct drx39xxj_state *state = dev_addr->user_data;
9009 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
9010 int rc; 9010 int rc;
9011 u32 lck_state = NO_LOCK; 9011 u32 lck_state = NO_LOCK;
9012 u32 start_time = 0; 9012 u32 start_time = 0;
@@ -9014,7 +9014,6 @@ qam256auto(struct drx_demod_instance *demod,
9014 u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; 9014 u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
9015 9015
9016 /* external attributes for storing aquired channel constellation */ 9016 /* external attributes for storing aquired channel constellation */
9017 ext_attr = (struct drxj_data *) demod->my_ext_attr;
9018 *lock_status = DRX_NOT_LOCKED; 9017 *lock_status = DRX_NOT_LOCKED;
9019 start_time = jiffies_to_msecs(jiffies); 9018 start_time = jiffies_to_msecs(jiffies);
9020 lck_state = NO_LOCK; 9019 lck_state = NO_LOCK;
@@ -9027,12 +9026,12 @@ qam256auto(struct drx_demod_instance *demod,
9027 switch (lck_state) { 9026 switch (lck_state) {
9028 case NO_LOCK: 9027 case NO_LOCK:
9029 if (*lock_status == DRXJ_DEMOD_LOCK) { 9028 if (*lock_status == DRXJ_DEMOD_LOCK) {
9030 rc = ctrl_get_qam_sig_quality(demod, &sig_quality); 9029 rc = ctrl_get_qam_sig_quality(demod);
9031 if (rc != 0) { 9030 if (rc != 0) {
9032 pr_err("error %d\n", rc); 9031 pr_err("error %d\n", rc);
9033 goto rw_error; 9032 goto rw_error;
9034 } 9033 }
9035 if (sig_quality.MER > 268) { 9034 if (p->cnr.stat[0].svalue > 26800) {
9036 lck_state = DEMOD_LOCKED; 9035 lck_state = DEMOD_LOCKED;
9037 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, wait longer */ 9036 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, wait longer */
9038 d_locked_time = jiffies_to_msecs(jiffies); 9037 d_locked_time = jiffies_to_msecs(jiffies);
@@ -9441,13 +9440,15 @@ static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
9441* Pre-condition: Device must be started and in lock. 9440* Pre-condition: Device must be started and in lock.
9442*/ 9441*/
9443static int 9442static int
9444ctrl_get_qam_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality) 9443ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
9445{ 9444{
9446 struct i2c_device_addr *dev_addr = NULL; 9445 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9447 struct drxj_data *ext_attr = NULL; 9446 struct drxj_data *ext_attr = demod->my_ext_attr;
9448 int rc; 9447 struct drx39xxj_state *state = dev_addr->user_data;
9449 enum drx_modulation constellation = DRX_CONSTELLATION_UNKNOWN; 9448 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
9450 struct drxjrs_errors measuredrs_errors = { 0, 0, 0, 0, 0 }; 9449 struct drxjrs_errors measuredrs_errors = { 0, 0, 0, 0, 0 };
9450 enum drx_modulation constellation = ext_attr->constellation;
9451 int rc;
9451 9452
9452 u32 pre_bit_err_rs = 0; /* pre RedSolomon Bit Error Rate */ 9453 u32 pre_bit_err_rs = 0; /* pre RedSolomon Bit Error Rate */
9453 u32 post_bit_err_rs = 0; /* post RedSolomon Bit Error Rate */ 9454 u32 post_bit_err_rs = 0; /* post RedSolomon Bit Error Rate */
@@ -9473,11 +9474,6 @@ ctrl_get_qam_sig_quality(struct drx_demod_instance *demod, struct drx_sig_qualit
9473 u16 qam_vd_period = 0; /* Viterbi Measurement period */ 9474 u16 qam_vd_period = 0; /* Viterbi Measurement period */
9474 u32 vd_bit_cnt = 0; /* ViterbiDecoder Bit Count */ 9475 u32 vd_bit_cnt = 0; /* ViterbiDecoder Bit Count */
9475 9476
9476 /* get device basic information */
9477 dev_addr = demod->my_i2c_dev_addr;
9478 ext_attr = (struct drxj_data *) demod->my_ext_attr;
9479 constellation = ext_attr->constellation;
9480
9481 /* read the physical registers */ 9477 /* read the physical registers */
9482 /* Get the RS error data */ 9478 /* Get the RS error data */
9483 rc = get_qamrs_err_count(dev_addr, &measuredrs_errors); 9479 rc = get_qamrs_err_count(dev_addr, &measuredrs_errors);
@@ -9605,26 +9601,43 @@ ctrl_get_qam_sig_quality(struct drx_demod_instance *demod, struct drx_sig_qualit
9605 qam_post_rs_ber = e / m; 9601 qam_post_rs_ber = e / m;
9606 9602
9607 /* fill signal quality data structure */ 9603 /* fill signal quality data structure */
9608 sig_quality->MER = ((u16) qam_sl_mer); 9604 p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
9605 p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
9606 p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
9607 p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
9608 p->block_error.stat[0].scale = FE_SCALE_COUNTER;
9609 p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
9610
9611 p->cnr.stat[0].svalue = ((u16) qam_sl_mer) * 100;
9609 if (ext_attr->standard == DRX_STANDARD_ITU_B) 9612 if (ext_attr->standard == DRX_STANDARD_ITU_B)
9610 sig_quality->pre_viterbi_ber = qam_vd_ser; 9613 p->pre_bit_error.stat[0].uvalue += qam_vd_ser;
9611 else 9614 else
9612 sig_quality->pre_viterbi_ber = qam_pre_rs_ber; 9615 p->pre_bit_error.stat[0].uvalue += qam_pre_rs_ber;
9613 sig_quality->post_viterbi_ber = qam_pre_rs_ber; 9616
9614 sig_quality->post_reed_solomon_ber = qam_post_rs_ber; 9617 p->post_bit_error.stat[0].uvalue = qam_post_rs_ber;
9615 sig_quality->scale_factor_ber = ((u32) 1000000); 9618
9619 p->pre_bit_count.stat[0].uvalue += 1000000;
9620 p->post_bit_count.stat[0].uvalue += 1000000;
9621
9622 p->block_error.stat[0].uvalue += pkt_errs;
9623
9616#ifdef DRXJ_SIGNAL_ACCUM_ERR 9624#ifdef DRXJ_SIGNAL_ACCUM_ERR
9617 rc = get_acc_pkt_err(demod, &sig_quality->packet_error); 9625 rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
9618 if (rc != 0) { 9626 if (rc != 0) {
9619 pr_err("error %d\n", rc); 9627 pr_err("error %d\n", rc);
9620 goto rw_error; 9628 goto rw_error;
9621 } 9629 }
9622#else
9623 sig_quality->packet_error = ((u16) pkt_errs);
9624#endif 9630#endif
9625 9631
9626 return 0; 9632 return 0;
9627rw_error: 9633rw_error:
9634 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9635 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9636 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9637 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9638 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9639 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9640
9628 return -EIO; 9641 return -EIO;
9629} 9642}
9630 9643
@@ -10627,28 +10640,6 @@ rw_error:
10627 ===== SigQuality() ========================================================== 10640 ===== SigQuality() ==========================================================
10628 ===========================================================================*/ 10641 ===========================================================================*/
10629 10642
10630static u16
10631mer2indicator(u16 mer, u16 min_mer, u16 threshold_mer, u16 max_mer)
10632{
10633 u16 indicator = 0;
10634
10635 if (mer < min_mer) {
10636 indicator = 0;
10637 } else if (mer < threshold_mer) {
10638 if ((threshold_mer - min_mer) != 0)
10639 indicator = 25 * (mer - min_mer) / (threshold_mer - min_mer);
10640 } else if (mer < max_mer) {
10641 if ((max_mer - threshold_mer) != 0)
10642 indicator = 25 + 75 * (mer - threshold_mer) / (max_mer - threshold_mer);
10643 else
10644 indicator = 25;
10645 } else {
10646 indicator = 100;
10647 }
10648
10649 return indicator;
10650}
10651
10652/** 10643/**
10653* \fn int ctrl_sig_quality() 10644* \fn int ctrl_sig_quality()
10654* \brief Retreive signal quality form device. 10645* \brief Retreive signal quality form device.
@@ -10661,130 +10652,94 @@ mer2indicator(u16 mer, u16 min_mer, u16 threshold_mer, u16 max_mer)
10661 10652
10662*/ 10653*/
10663static int 10654static int
10664ctrl_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality) 10655ctrl_sig_quality(struct drx_demod_instance *demod,
10656 enum drx_lock_status lock_status)
10665{ 10657{
10666 struct i2c_device_addr *dev_addr = NULL; 10658 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
10667 struct drxj_data *ext_attr = NULL; 10659 struct drxj_data *ext_attr = demod->my_ext_attr;
10660 struct drx39xxj_state *state = dev_addr->user_data;
10661 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
10662 enum drx_standard standard = ext_attr->standard;
10668 int rc; 10663 int rc;
10669 enum drx_standard standard = DRX_STANDARD_UNKNOWN; 10664 u32 ber;
10670 enum drx_lock_status lock_status = DRX_NOT_LOCKED; 10665 u16 pkt, mer, strength;
10671 u16 min_mer = 0;
10672 u16 max_mer = 0;
10673 u16 threshold_mer = 0;
10674
10675 /* Check arguments */
10676 if ((sig_quality == NULL) || (demod == NULL))
10677 return -EINVAL;
10678 10666
10679 ext_attr = (struct drxj_data *) demod->my_ext_attr; 10667 rc = get_sig_strength(demod, &strength);
10680 standard = ext_attr->standard; 10668 if (rc < 0) {
10681 10669 pr_err("error getting signal strength %d\n", rc);
10682 /* get basic information */ 10670 p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10683 dev_addr = demod->my_i2c_dev_addr; 10671 } else {
10684 rc = ctrl_lock_status(demod, &lock_status); 10672 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
10685 if (rc != 0) { 10673 p->strength.stat[0].uvalue = 65535UL * strength/ 100;
10686 pr_err("error %d\n", rc);
10687 goto rw_error;
10688 } 10674 }
10675
10689 switch (standard) { 10676 switch (standard) {
10690 case DRX_STANDARD_8VSB: 10677 case DRX_STANDARD_8VSB:
10691#ifdef DRXJ_SIGNAL_ACCUM_ERR 10678#ifdef DRXJ_SIGNAL_ACCUM_ERR
10692 rc = get_acc_pkt_err(demod, &sig_quality->packet_error); 10679 rc = get_acc_pkt_err(demod, &pkt);
10693 if (rc != 0) {
10694 pr_err("error %d\n", rc);
10695 goto rw_error;
10696 }
10697#else
10698 rc = get_vsb_post_rs_pck_err(dev_addr, &sig_quality->packet_error);
10699 if (rc != 0) { 10680 if (rc != 0) {
10700 pr_err("error %d\n", rc); 10681 pr_err("error %d\n", rc);
10701 goto rw_error; 10682 goto rw_error;
10702 } 10683 }
10703#endif 10684#endif
10704 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) { 10685 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
10705 sig_quality->post_viterbi_ber = 500000; 10686 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10706 sig_quality->MER = 20; 10687 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10707 sig_quality->pre_viterbi_ber = 0; 10688 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10689 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10690 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10691 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10708 } else { 10692 } else {
10693 rc = get_vsb_post_rs_pck_err(dev_addr, &pkt);
10694 if (rc != 0) {
10695 pr_err("error %d getting UCB\n", rc);
10696 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10697 } else {
10698 p->block_error.stat[0].scale = FE_SCALE_COUNTER;
10699 p->block_error.stat[0].uvalue += pkt;
10700 }
10701
10709 /* PostViterbi is compute in steps of 10^(-6) */ 10702 /* PostViterbi is compute in steps of 10^(-6) */
10710 rc = get_vs_bpre_viterbi_ber(dev_addr, &sig_quality->pre_viterbi_ber); 10703 rc = get_vs_bpre_viterbi_ber(dev_addr, &ber);
10711 if (rc != 0) { 10704 if (rc != 0) {
10712 pr_err("error %d\n", rc); 10705 pr_err("error %d getting pre-ber\n", rc);
10713 goto rw_error; 10706 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10707 } else {
10708 p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
10709 p->pre_bit_error.stat[0].uvalue += ber;
10710 p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
10711 p->pre_bit_count.stat[0].uvalue += 1000000;
10714 } 10712 }
10715 rc = get_vs_bpost_viterbi_ber(dev_addr, &sig_quality->post_viterbi_ber); 10713
10714 rc = get_vs_bpost_viterbi_ber(dev_addr, &ber);
10716 if (rc != 0) { 10715 if (rc != 0) {
10717 pr_err("error %d\n", rc); 10716 pr_err("error %d getting post-ber\n", rc);
10718 goto rw_error; 10717 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10718 } else {
10719 p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
10720 p->post_bit_error.stat[0].uvalue += ber;
10721 p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
10722 p->post_bit_count.stat[0].uvalue += 1000000;
10719 } 10723 }
10720 rc = get_vsbmer(dev_addr, &sig_quality->MER); 10724 rc = get_vsbmer(dev_addr, &mer);
10721 if (rc != 0) { 10725 if (rc != 0) {
10722 pr_err("error %d\n", rc); 10726 pr_err("error %d getting MER\n", rc);
10723 goto rw_error; 10727 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10728 } else {
10729 p->cnr.stat[0].svalue = mer * 100;
10730 p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
10724 } 10731 }
10725 } 10732 }
10726 min_mer = 20;
10727 max_mer = 360;
10728 threshold_mer = 145;
10729 sig_quality->post_reed_solomon_ber = 0;
10730 sig_quality->scale_factor_ber = 1000000;
10731 sig_quality->indicator =
10732 mer2indicator(sig_quality->MER, min_mer, threshold_mer,
10733 max_mer);
10734 break; 10733 break;
10735#ifndef DRXJ_VSB_ONLY 10734#ifndef DRXJ_VSB_ONLY
10736 case DRX_STANDARD_ITU_A: 10735 case DRX_STANDARD_ITU_A:
10737 case DRX_STANDARD_ITU_B: 10736 case DRX_STANDARD_ITU_B:
10738 case DRX_STANDARD_ITU_C: 10737 case DRX_STANDARD_ITU_C:
10739 rc = ctrl_get_qam_sig_quality(demod, sig_quality); 10738 rc = ctrl_get_qam_sig_quality(demod);
10740 if (rc != 0) { 10739 if (rc != 0) {
10741 pr_err("error %d\n", rc); 10740 pr_err("error %d\n", rc);
10742 goto rw_error; 10741 goto rw_error;
10743 } 10742 }
10744 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
10745 switch (ext_attr->constellation) {
10746 case DRX_CONSTELLATION_QAM256:
10747 sig_quality->MER = 210;
10748 break;
10749 case DRX_CONSTELLATION_QAM128:
10750 sig_quality->MER = 180;
10751 break;
10752 case DRX_CONSTELLATION_QAM64:
10753 sig_quality->MER = 150;
10754 break;
10755 case DRX_CONSTELLATION_QAM32:
10756 sig_quality->MER = 120;
10757 break;
10758 case DRX_CONSTELLATION_QAM16:
10759 sig_quality->MER = 90;
10760 break;
10761 default:
10762 sig_quality->MER = 0;
10763 return -EIO;
10764 }
10765 }
10766
10767 switch (ext_attr->constellation) {
10768 case DRX_CONSTELLATION_QAM256:
10769 min_mer = 210;
10770 threshold_mer = 270;
10771 max_mer = 380;
10772 break;
10773 case DRX_CONSTELLATION_QAM64:
10774 min_mer = 150;
10775 threshold_mer = 210;
10776 max_mer = 380;
10777 break;
10778 case DRX_CONSTELLATION_QAM128:
10779 case DRX_CONSTELLATION_QAM32:
10780 case DRX_CONSTELLATION_QAM16:
10781 break;
10782 default:
10783 return -EIO;
10784 }
10785 sig_quality->indicator =
10786 mer2indicator(sig_quality->MER, min_mer, threshold_mer,
10787 max_mer);
10788 break; 10743 break;
10789#endif 10744#endif
10790 default: 10745 default:
@@ -11997,81 +11952,61 @@ static int drx39xxj_read_status(struct dvb_frontend *fe, fe_status_t *status)
11997 default: 11952 default:
11998 pr_err("Lock state unknown %d\n", lock_status); 11953 pr_err("Lock state unknown %d\n", lock_status);
11999 } 11954 }
11955 ctrl_sig_quality(demod, lock_status);
12000 11956
12001 return 0; 11957 return 0;
12002} 11958}
12003 11959
12004static int drx39xxj_read_ber(struct dvb_frontend *fe, u32 *ber) 11960static int drx39xxj_read_ber(struct dvb_frontend *fe, u32 *ber)
12005{ 11961{
12006 struct drx39xxj_state *state = fe->demodulator_priv; 11962 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12007 struct drx_demod_instance *demod = state->demod;
12008 int result;
12009 struct drx_sig_quality sig_quality;
12010 11963
12011 result = ctrl_sig_quality(demod, &sig_quality); 11964 if (p->pre_bit_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12012 if (result != 0) {
12013 pr_err("drx39xxj: could not get ber!\n");
12014 *ber = 0; 11965 *ber = 0;
12015 return 0; 11966 return 0;
12016 } 11967 }
12017 11968
12018 *ber = sig_quality.post_reed_solomon_ber; 11969 *ber = p->pre_bit_error.stat[0].uvalue;
12019 return 0; 11970 return 0;
12020} 11971}
12021 11972
12022static int drx39xxj_read_signal_strength(struct dvb_frontend *fe, 11973static int drx39xxj_read_signal_strength(struct dvb_frontend *fe,
12023 u16 *strength) 11974 u16 *strength)
12024{ 11975{
12025 struct drx39xxj_state *state = fe->demodulator_priv; 11976 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12026 struct drx_demod_instance *demod = state->demod;
12027 int result;
12028 struct drx_sig_quality sig_quality;
12029 11977
12030 result = ctrl_sig_quality(demod, &sig_quality); 11978 if (p->strength.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12031 if (result != 0) {
12032 pr_err("drx39xxj: could not get signal strength!\n");
12033 *strength = 0; 11979 *strength = 0;
12034 return 0; 11980 return 0;
12035 } 11981 }
12036 11982
12037 /* 1-100% scaled to 0-65535 */ 11983 *strength = p->strength.stat[0].uvalue;
12038 *strength = (sig_quality.indicator * 65535 / 100);
12039 return 0; 11984 return 0;
12040} 11985}
12041 11986
12042static int drx39xxj_read_snr(struct dvb_frontend *fe, u16 *snr) 11987static int drx39xxj_read_snr(struct dvb_frontend *fe, u16 *snr)
12043{ 11988{
12044 struct drx39xxj_state *state = fe->demodulator_priv; 11989 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12045 struct drx_demod_instance *demod = state->demod;
12046 int result;
12047 struct drx_sig_quality sig_quality;
12048 11990
12049 result = ctrl_sig_quality(demod, &sig_quality); 11991 if (p->cnr.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12050 if (result != 0) {
12051 pr_err("drx39xxj: could not read snr!\n");
12052 *snr = 0; 11992 *snr = 0;
12053 return 0; 11993 return 0;
12054 } 11994 }
12055 11995
12056 *snr = sig_quality.MER; 11996 *snr = p->cnr.stat[0].svalue / 10;
12057 return 0; 11997 return 0;
12058} 11998}
12059 11999
12060static int drx39xxj_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 12000static int drx39xxj_read_ucblocks(struct dvb_frontend *fe, u32 *ucb)
12061{ 12001{
12062 struct drx39xxj_state *state = fe->demodulator_priv; 12002 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12063 struct drx_demod_instance *demod = state->demod;
12064 int result;
12065 struct drx_sig_quality sig_quality;
12066 12003
12067 result = ctrl_sig_quality(demod, &sig_quality); 12004 if (p->block_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12068 if (result != 0) { 12005 *ucb = 0;
12069 pr_err("drx39xxj: could not get uc blocks!\n");
12070 *ucblocks = 0;
12071 return 0; 12006 return 0;
12072 } 12007 }
12073 12008
12074 *ucblocks = sig_quality.packet_error; 12009 *ucb = p->block_error.stat[0].uvalue;
12075 return 0; 12010 return 0;
12076} 12011}
12077 12012
@@ -12178,15 +12113,9 @@ static int drx39xxj_set_frontend(struct dvb_frontend *fe)
12178 pr_err("Failed to disable LNA!\n"); 12113 pr_err("Failed to disable LNA!\n");
12179 return 0; 12114 return 0;
12180 } 12115 }
12181#ifdef DJH_DEBUG 12116
12182 for (i = 0; i < 2000; i++) { 12117 /* After set_frontend, except for strength, stats aren't available */
12183 fe_status_t status; 12118 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
12184 drx39xxj_read_status(fe, &status);
12185 pr_debug("i=%d status=%d\n", i, status);
12186 msleep(100);
12187 i += 100;
12188 }
12189#endif
12190 12119
12191 return 0; 12120 return 0;
12192} 12121}