aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <m.chehab@samsung.com>2014-03-10 07:08:53 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-03-11 06:37:20 -0400
commit6983257813dcc052cb46639f28ac77f46ec7350f (patch)
tree80f10abde7eb4b521f98dd1346438e4253e25700
parent03fdfbfd3b5944bfd210541a83c9b222e2c20920 (diff)
[media] drx-j: properly handle bit counts on stats
Instead of just assuming that the min resolution is 1E-6, pass both bit error and bit counts for userspace to calculate BER. The same applies for PER, for 8VSB. It is not clear how to get the packet count for QAM. So, for now, don't expose PER for QAM. Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/dvb-frontends/drx39xyj/drxj.c89
1 files changed, 50 insertions, 39 deletions
diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c
index 6005e344f66c..9958277dd943 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drxj.c
+++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c
@@ -6199,7 +6199,8 @@ rw_error:
6199* \brief Get the values of packet error in 8VSB mode 6199* \brief Get the values of packet error in 8VSB mode
6200* \return Error code 6200* \return Error code
6201*/ 6201*/
6202static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *pck_errs) 6202static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr,
6203 u16 *pck_errs, u16 *pck_count)
6203{ 6204{
6204 int rc; 6205 int rc;
6205 u16 data = 0; 6206 u16 data = 0;
@@ -6224,9 +6225,8 @@ static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *pck_er
6224 pr_err("error: period and/or prescale is zero!\n"); 6225 pr_err("error: period and/or prescale is zero!\n");
6225 return -EIO; 6226 return -EIO;
6226 } 6227 }
6227 *pck_errs = 6228 *pck_errs = packet_errors_mant * (1 << packet_errors_exp);
6228 (u16) frac_times1e6(packet_errors_mant * (1 << packet_errors_exp), 6229 *pck_count = period * prescale * 77;
6229 (period * prescale * 77));
6230 6230
6231 return 0; 6231 return 0;
6232rw_error: 6232rw_error:
@@ -6238,7 +6238,8 @@ rw_error:
6238* \brief Get the values of ber in VSB mode 6238* \brief Get the values of ber in VSB mode
6239* \return Error code 6239* \return Error code
6240*/ 6240*/
6241static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber) 6241static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr,
6242 u32 *ber, u32 *cnt)
6242{ 6243{
6243 int rc; 6244 int rc;
6244 u16 data = 0; 6245 u16 data = 0;
@@ -6259,19 +6260,17 @@ static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
6259 bit_errors_exp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M) 6260 bit_errors_exp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)
6260 >> FEC_RS_NR_BIT_ERRORS_EXP__B; 6261 >> FEC_RS_NR_BIT_ERRORS_EXP__B;
6261 6262
6263 *cnt = period * prescale * 207 * ((bit_errors_exp > 2) ? 1 : 8);
6264
6262 if (((bit_errors_mant << bit_errors_exp) >> 3) > 68700) 6265 if (((bit_errors_mant << bit_errors_exp) >> 3) > 68700)
6263 *ber = 26570; 6266 *ber = (*cnt) * 26570;
6264 else { 6267 else {
6265 if (period * prescale == 0) { 6268 if (period * prescale == 0) {
6266 pr_err("error: period and/or prescale is zero!\n"); 6269 pr_err("error: period and/or prescale is zero!\n");
6267 return -EIO; 6270 return -EIO;
6268 } 6271 }
6269 *ber = 6272 *ber = bit_errors_mant << ((bit_errors_exp > 2) ?
6270 frac_times1e6(bit_errors_mant << 6273 (bit_errors_exp - 3) : bit_errors_exp);
6271 ((bit_errors_exp >
6272 2) ? (bit_errors_exp - 3) : bit_errors_exp),
6273 period * prescale * 207 *
6274 ((bit_errors_exp > 2) ? 1 : 8));
6275 } 6274 }
6276 6275
6277 return 0; 6276 return 0;
@@ -6284,7 +6283,8 @@ rw_error:
6284* \brief Get the values of ber in VSB mode 6283* \brief Get the values of ber in VSB mode
6285* \return Error code 6284* \return Error code
6286*/ 6285*/
6287static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber) 6286static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr,
6287 u32 *ber, u32 *cnt)
6288{ 6288{
6289 u16 data = 0; 6289 u16 data = 0;
6290 int rc; 6290 int rc;
@@ -6292,15 +6292,12 @@ static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
6292 rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_NR_SYM_ERRS__A, &data, 0); 6292 rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_NR_SYM_ERRS__A, &data, 0);
6293 if (rc != 0) { 6293 if (rc != 0) {
6294 pr_err("error %d\n", rc); 6294 pr_err("error %d\n", rc);
6295 goto rw_error; 6295 return -EIO;
6296 } 6296 }
6297 *ber = 6297 *ber = data;
6298 frac_times1e6(data, 6298 *cnt = VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT;
6299 VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT);
6300 6299
6301 return 0; 6300 return 0;
6302rw_error:
6303 return -EIO;
6304} 6301}
6305 6302
6306/** 6303/**
@@ -9289,7 +9286,8 @@ rw_error:
9289* 9286*
9290*/ 9287*/
9291static int 9288static int
9292get_qamrs_err_count(struct i2c_device_addr *dev_addr, struct drxjrs_errors *rs_errors) 9289get_qamrs_err_count(struct i2c_device_addr *dev_addr,
9290 struct drxjrs_errors *rs_errors)
9293{ 9291{
9294 int rc; 9292 int rc;
9295 u16 nr_bit_errors = 0, 9293 u16 nr_bit_errors = 0,
@@ -9474,6 +9472,8 @@ ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
9474 u16 qam_vd_period = 0; /* Viterbi Measurement period */ 9472 u16 qam_vd_period = 0; /* Viterbi Measurement period */
9475 u32 vd_bit_cnt = 0; /* ViterbiDecoder Bit Count */ 9473 u32 vd_bit_cnt = 0; /* ViterbiDecoder Bit Count */
9476 9474
9475 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9476
9477 /* read the physical registers */ 9477 /* read the physical registers */
9478 /* Get the RS error data */ 9478 /* Get the RS error data */
9479 rc = get_qamrs_err_count(dev_addr, &measuredrs_errors); 9479 rc = get_qamrs_err_count(dev_addr, &measuredrs_errors);
@@ -9554,9 +9554,9 @@ ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
9554 QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B; 9554 QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;
9555 9555
9556 if ((m << e) >> 3 > 549752) 9556 if ((m << e) >> 3 > 549752)
9557 qam_vd_ser = 500000; 9557 qam_vd_ser = 500000 * vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
9558 else 9558 else
9559 qam_vd_ser = frac_times1e6(m << ((e > 2) ? (e - 3) : e), vd_bit_cnt * ((e > 2) ? 1 : 8) / 8); 9559 qam_vd_ser = m << ((e > 2) ? (e - 3) : e);
9560 9560
9561 /* --------------------------------------- */ 9561 /* --------------------------------------- */
9562 /* pre and post RedSolomon BER Calculation */ 9562 /* pre and post RedSolomon BER Calculation */
@@ -9578,9 +9578,9 @@ ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
9578 9578
9579 /*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */ 9579 /*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */
9580 if (m > (rs_bit_cnt >> (e + 1)) || (rs_bit_cnt >> e) == 0) 9580 if (m > (rs_bit_cnt >> (e + 1)) || (rs_bit_cnt >> e) == 0)
9581 qam_pre_rs_ber = 500000; 9581 qam_pre_rs_ber = 500000 * rs_bit_cnt >> e;
9582 else 9582 else
9583 qam_pre_rs_ber = frac_times1e6(m, rs_bit_cnt >> e); 9583 qam_pre_rs_ber = m;
9584 9584
9585 /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) / */ 9585 /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) / */
9586 /* (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A) */ 9586 /* (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A) */
@@ -9609,16 +9609,16 @@ ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
9609 p->cnr.stat[0].scale = FE_SCALE_DECIBEL; 9609 p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
9610 9610
9611 p->cnr.stat[0].svalue = ((u16) qam_sl_mer) * 100; 9611 p->cnr.stat[0].svalue = ((u16) qam_sl_mer) * 100;
9612 if (ext_attr->standard == DRX_STANDARD_ITU_B) 9612 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9613 p->pre_bit_error.stat[0].uvalue += qam_vd_ser; 9613 p->pre_bit_error.stat[0].uvalue += qam_vd_ser;
9614 else 9614 p->pre_bit_count.stat[0].uvalue += vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
9615 } else {
9615 p->pre_bit_error.stat[0].uvalue += qam_pre_rs_ber; 9616 p->pre_bit_error.stat[0].uvalue += qam_pre_rs_ber;
9617 p->pre_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
9618 }
9616 9619
9617 p->post_bit_error.stat[0].uvalue = qam_post_rs_ber; 9620 p->post_bit_error.stat[0].uvalue = qam_post_rs_ber;
9618 9621
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; 9622 p->block_error.stat[0].uvalue += pkt_errs;
9623 9623
9624#ifdef DRXJ_SIGNAL_ACCUM_ERR 9624#ifdef DRXJ_SIGNAL_ACCUM_ERR
@@ -10661,8 +10661,8 @@ ctrl_sig_quality(struct drx_demod_instance *demod,
10661 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache; 10661 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
10662 enum drx_standard standard = ext_attr->standard; 10662 enum drx_standard standard = ext_attr->standard;
10663 int rc; 10663 int rc;
10664 u32 ber; 10664 u32 ber, cnt;
10665 u16 pkt, mer, strength; 10665 u16 err, pkt, mer, strength;
10666 10666
10667 rc = get_sig_strength(demod, &strength); 10667 rc = get_sig_strength(demod, &strength);
10668 if (rc < 0) { 10668 if (rc < 0) {
@@ -10684,23 +10684,26 @@ ctrl_sig_quality(struct drx_demod_instance *demod,
10684#endif 10684#endif
10685 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) { 10685 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
10686 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 10686 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10687 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10688 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 10687 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10688 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10689 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 10689 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10690 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10690 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 10691 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10691 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 10692 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10692 } else { 10693 } else {
10693 rc = get_vsb_post_rs_pck_err(dev_addr, &pkt); 10694 rc = get_vsb_post_rs_pck_err(dev_addr, &err, &pkt);
10694 if (rc != 0) { 10695 if (rc != 0) {
10695 pr_err("error %d getting UCB\n", rc); 10696 pr_err("error %d getting UCB\n", rc);
10696 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 10697 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10697 } else { 10698 } else {
10698 p->block_error.stat[0].scale = FE_SCALE_COUNTER; 10699 p->block_error.stat[0].scale = FE_SCALE_COUNTER;
10699 p->block_error.stat[0].uvalue += pkt; 10700 p->block_error.stat[0].uvalue += err;
10701 p->block_count.stat[0].scale = FE_SCALE_COUNTER;
10702 p->block_count.stat[0].uvalue += pkt;
10700 } 10703 }
10701 10704
10702 /* PostViterbi is compute in steps of 10^(-6) */ 10705 /* PostViterbi is compute in steps of 10^(-6) */
10703 rc = get_vs_bpre_viterbi_ber(dev_addr, &ber); 10706 rc = get_vs_bpre_viterbi_ber(dev_addr, &ber, &cnt);
10704 if (rc != 0) { 10707 if (rc != 0) {
10705 pr_err("error %d getting pre-ber\n", rc); 10708 pr_err("error %d getting pre-ber\n", rc);
10706 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 10709 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
@@ -10708,10 +10711,10 @@ ctrl_sig_quality(struct drx_demod_instance *demod,
10708 p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER; 10711 p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
10709 p->pre_bit_error.stat[0].uvalue += ber; 10712 p->pre_bit_error.stat[0].uvalue += ber;
10710 p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER; 10713 p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
10711 p->pre_bit_count.stat[0].uvalue += 1000000; 10714 p->pre_bit_count.stat[0].uvalue += cnt;
10712 } 10715 }
10713 10716
10714 rc = get_vs_bpost_viterbi_ber(dev_addr, &ber); 10717 rc = get_vs_bpost_viterbi_ber(dev_addr, &ber, &cnt);
10715 if (rc != 0) { 10718 if (rc != 0) {
10716 pr_err("error %d getting post-ber\n", rc); 10719 pr_err("error %d getting post-ber\n", rc);
10717 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 10720 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
@@ -10719,7 +10722,7 @@ ctrl_sig_quality(struct drx_demod_instance *demod,
10719 p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 10722 p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
10720 p->post_bit_error.stat[0].uvalue += ber; 10723 p->post_bit_error.stat[0].uvalue += ber;
10721 p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 10724 p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
10722 p->post_bit_count.stat[0].uvalue += 1000000; 10725 p->post_bit_count.stat[0].uvalue += cnt;
10723 } 10726 }
10724 rc = get_vsbmer(dev_addr, &mer); 10727 rc = get_vsbmer(dev_addr, &mer);
10725 if (rc != 0) { 10728 if (rc != 0) {
@@ -11966,7 +11969,15 @@ static int drx39xxj_read_ber(struct dvb_frontend *fe, u32 *ber)
11966 return 0; 11969 return 0;
11967 } 11970 }
11968 11971
11969 *ber = p->pre_bit_error.stat[0].uvalue; 11972 if (!p->pre_bit_count.stat[0].uvalue) {
11973 if (!p->pre_bit_error.stat[0].uvalue)
11974 *ber = 0;
11975 else
11976 *ber = 1000000;
11977 } else {
11978 *ber = frac_times1e6(p->pre_bit_error.stat[0].uvalue,
11979 p->pre_bit_count.stat[0].uvalue);
11980 }
11970 return 0; 11981 return 0;
11971} 11982}
11972 11983