aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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}