aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2013-01-24 08:25:16 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-01-24 11:28:14 -0500
commitd9b6f08a7f756d2d5105f5aaf23c326f41a0683b (patch)
treebf38863daa8cbf1e3728ec5d34924f0a04dd3627
parent313cf4efa40ef739199bd68a76f89f8a5224a541 (diff)
[media] mb86a20s: add a logic for post-BER measurement
The logic here is similar to the preBER. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/dvb-frontends/mb86a20s.c220
1 files changed, 196 insertions, 24 deletions
diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c
index 7d4e9119632d..ed39ee13a5ad 100644
--- a/drivers/media/dvb-frontends/mb86a20s.c
+++ b/drivers/media/dvb-frontends/mb86a20s.c
@@ -104,13 +104,20 @@ static struct regdata mb86a20s_init[] = {
104 { 0x50, 0xae }, { 0x51, 0xff }, 104 { 0x50, 0xae }, { 0x51, 0xff },
105 { 0x50, 0xaf }, { 0x51, 0xff }, 105 { 0x50, 0xaf }, { 0x51, 0xff },
106 106
107 { 0x5e, 0x00 }, /* Turn off BER after Viterbi */ 107 /*
108 { 0x50, 0xdc }, { 0x51, 0x01 }, 108 * On this demod, post BER counts blocks. When the count reaches the
109 { 0x50, 0xdd }, { 0x51, 0xf4 }, 109 * value below, it collects the block error count. The block counters
110 { 0x50, 0xde }, { 0x51, 0x01 }, 110 * are initialized to 127 here. This warrants that all of them will be
111 { 0x50, 0xdf }, { 0x51, 0xf4 }, 111 * quickly calculated when device gets locked. As TMCC is parsed, the
112 { 0x50, 0xe0 }, { 0x51, 0x01 }, 112 * values will be adjusted later in the driver's code.
113 { 0x50, 0xe1 }, { 0x51, 0xf4 }, 113 */
114 { 0x5e, 0x07 }, /* Turn on BER after Viterbi */
115 { 0x50, 0xdc }, { 0x51, 0x00 },
116 { 0x50, 0xdd }, { 0x51, 0x7f },
117 { 0x50, 0xde }, { 0x51, 0x00 },
118 { 0x50, 0xdf }, { 0x51, 0x7f },
119 { 0x50, 0xe0 }, { 0x51, 0x00 },
120 { 0x50, 0xe1 }, { 0x51, 0x7f },
114 121
115 /* 122 /*
116 * On this demod, when the block count reaches the count below, 123 * On this demod, when the block count reaches the count below,
@@ -187,12 +194,13 @@ static struct regdata mb86a20s_reset_reception[] = {
187 { 0x08, 0x00 }, 194 { 0x08, 0x00 },
188}; 195};
189 196
190static struct regdata mb86a20s_vber_reset[] = { 197static struct regdata mb86a20s_per_ber_reset[] = {
191 { 0x53, 0x00 }, /* VBER Counter reset */ 198 { 0x53, 0x00 }, /* pre BER Counter reset */
192 { 0x53, 0x07 }, 199 { 0x53, 0x07 },
193};
194 200
195static struct regdata mb86a20s_per_reset[] = { 201 { 0x5f, 0x00 }, /* post BER Counter reset */
202 { 0x5f, 0x07 },
203
196 { 0x50, 0xb1 }, /* PER Counter reset */ 204 { 0x50, 0xb1 }, /* PER Counter reset */
197 { 0x51, 0x07 }, 205 { 0x51, 0x07 },
198 { 0x51, 0x00 }, 206 { 0x51, 0x00 },
@@ -731,6 +739,8 @@ static int mb86a20s_reset_counters(struct dvb_frontend *fe)
731 memset(&c->cnr, 0, sizeof(c->cnr)); 739 memset(&c->cnr, 0, sizeof(c->cnr));
732 memset(&c->pre_bit_error, 0, sizeof(c->pre_bit_error)); 740 memset(&c->pre_bit_error, 0, sizeof(c->pre_bit_error));
733 memset(&c->pre_bit_count, 0, sizeof(c->pre_bit_count)); 741 memset(&c->pre_bit_count, 0, sizeof(c->pre_bit_count));
742 memset(&c->post_bit_error, 0, sizeof(c->post_bit_error));
743 memset(&c->post_bit_count, 0, sizeof(c->post_bit_count));
734 memset(&c->block_error, 0, sizeof(c->block_error)); 744 memset(&c->block_error, 0, sizeof(c->block_error));
735 memset(&c->block_count, 0, sizeof(c->block_count)); 745 memset(&c->block_count, 0, sizeof(c->block_count));
736 746
@@ -739,13 +749,8 @@ static int mb86a20s_reset_counters(struct dvb_frontend *fe)
739 749
740 /* Clear status for most stats */ 750 /* Clear status for most stats */
741 751
742 /* BER counter reset */ 752 /* BER/PER counter reset */
743 rc = mb86a20s_writeregdata(state, mb86a20s_vber_reset); 753 rc = mb86a20s_writeregdata(state, mb86a20s_per_ber_reset);
744 if (rc < 0)
745 goto err;
746
747 /* MER, PER counter reset */
748 rc = mb86a20s_writeregdata(state, mb86a20s_per_reset);
749 if (rc < 0) 754 if (rc < 0)
750 goto err; 755 goto err;
751 756
@@ -915,7 +920,124 @@ static int mb86a20s_get_pre_ber(struct dvb_frontend *fe,
915 rc = mb86a20s_writereg(state, 0x53, val | (1 << layer)); 920 rc = mb86a20s_writereg(state, 0x53, val | (1 << layer));
916 } 921 }
917 922
923 return rc;
924}
925
926static int mb86a20s_get_post_ber(struct dvb_frontend *fe,
927 unsigned layer,
928 u32 *error, u32 *count)
929{
930 struct mb86a20s_state *state = fe->demodulator_priv;
931 u32 counter, collect_rate;
932 int rc, val;
933
934 dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
935
936 if (layer >= 3)
937 return -EINVAL;
938
939 /* Check if the BER measures are already available */
940 rc = mb86a20s_readreg(state, 0x60);
941 if (rc < 0)
942 return rc;
943
944 /* Check if data is available for that layer */
945 if (!(rc & (1 << layer))) {
946 dev_dbg(&state->i2c->dev,
947 "%s: post BER for layer %c is not available yet.\n",
948 __func__, 'A' + layer);
949 return -EBUSY;
950 }
918 951
952 /* Read Bit Error Count */
953 rc = mb86a20s_readreg(state, 0x64 + layer * 3);
954 if (rc < 0)
955 return rc;
956 *error = rc << 16;
957 rc = mb86a20s_readreg(state, 0x65 + layer * 3);
958 if (rc < 0)
959 return rc;
960 *error |= rc << 8;
961 rc = mb86a20s_readreg(state, 0x66 + layer * 3);
962 if (rc < 0)
963 return rc;
964 *error |= rc;
965
966 dev_dbg(&state->i2c->dev,
967 "%s: post bit error for layer %c: %d.\n",
968 __func__, 'A' + layer, *error);
969
970 /* Read Bit Count */
971 rc = mb86a20s_writereg(state, 0x50, 0xdc + layer * 2);
972 if (rc < 0)
973 return rc;
974 rc = mb86a20s_readreg(state, 0x51);
975 if (rc < 0)
976 return rc;
977 counter = rc << 8;
978 rc = mb86a20s_writereg(state, 0x50, 0xdd + layer * 2);
979 if (rc < 0)
980 return rc;
981 rc = mb86a20s_readreg(state, 0x51);
982 if (rc < 0)
983 return rc;
984 counter |= rc;
985 *count = counter * 204 * 8;
986
987 dev_dbg(&state->i2c->dev,
988 "%s: post bit count for layer %c: %d.\n",
989 __func__, 'A' + layer, *count);
990
991 /*
992 * As we get TMCC data from the frontend, we can better estimate the
993 * BER bit counters, in order to do the BER measure during a longer
994 * time. Use those data, if available, to update the bit count
995 * measure.
996 */
997
998 if (!state->estimated_rate[layer])
999 goto reset_measurement;
1000
1001 collect_rate = state->estimated_rate[layer] / 204 / 8;
1002 if (collect_rate < 32)
1003 collect_rate = 32;
1004 if (collect_rate > 65535)
1005 collect_rate = 65535;
1006 if (collect_rate != counter) {
1007 dev_dbg(&state->i2c->dev,
1008 "%s: updating postBER counter on layer %c to %d.\n",
1009 __func__, 'A' + layer, collect_rate);
1010
1011 /* Turn off BER after Viterbi */
1012 rc = mb86a20s_writereg(state, 0x5e, 0x00);
1013
1014 /* Update counter for this layer */
1015 rc = mb86a20s_writereg(state, 0x50, 0xdc + layer * 2);
1016 if (rc < 0)
1017 return rc;
1018 rc = mb86a20s_writereg(state, 0x51, collect_rate >> 8);
1019 if (rc < 0)
1020 return rc;
1021 rc = mb86a20s_writereg(state, 0x50, 0xdd + layer * 2);
1022 if (rc < 0)
1023 return rc;
1024 rc = mb86a20s_writereg(state, 0x51, collect_rate & 0xff);
1025 if (rc < 0)
1026 return rc;
1027
1028 /* Turn on BER after Viterbi */
1029 rc = mb86a20s_writereg(state, 0x5e, 0x07);
1030
1031 /* Reset all preBER counters */
1032 rc = mb86a20s_writereg(state, 0x5f, 0x00);
1033 if (rc < 0)
1034 return rc;
1035 rc = mb86a20s_writereg(state, 0x5f, 0x07);
1036
1037 return rc;
1038 }
1039
1040reset_measurement:
919 /* Reset counter to collect new data */ 1041 /* Reset counter to collect new data */
920 rc = mb86a20s_readreg(state, 0x5f); 1042 rc = mb86a20s_readreg(state, 0x5f);
921 if (rc < 0) 1043 if (rc < 0)
@@ -924,7 +1046,7 @@ static int mb86a20s_get_pre_ber(struct dvb_frontend *fe,
924 rc = mb86a20s_writereg(state, 0x5f, val & ~(1 << layer)); 1046 rc = mb86a20s_writereg(state, 0x5f, val & ~(1 << layer));
925 if (rc < 0) 1047 if (rc < 0)
926 return rc; 1048 return rc;
927 rc = mb86a20s_writereg(state, 0x5f, val); 1049 rc = mb86a20s_writereg(state, 0x5f, val | (1 << layer));
928 1050
929 return rc; 1051 return rc;
930} 1052}
@@ -1417,6 +1539,8 @@ static void mb86a20s_stats_not_ready(struct dvb_frontend *fe)
1417 c->cnr.len = 4; 1539 c->cnr.len = 4;
1418 c->pre_bit_error.len = 4; 1540 c->pre_bit_error.len = 4;
1419 c->pre_bit_count.len = 4; 1541 c->pre_bit_count.len = 4;
1542 c->post_bit_error.len = 4;
1543 c->post_bit_count.len = 4;
1420 c->block_error.len = 4; 1544 c->block_error.len = 4;
1421 c->block_count.len = 4; 1545 c->block_count.len = 4;
1422 1546
@@ -1429,6 +1553,8 @@ static void mb86a20s_stats_not_ready(struct dvb_frontend *fe)
1429 c->cnr.stat[i].scale = FE_SCALE_NOT_AVAILABLE; 1553 c->cnr.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
1430 c->pre_bit_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE; 1554 c->pre_bit_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
1431 c->pre_bit_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE; 1555 c->pre_bit_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
1556 c->post_bit_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
1557 c->post_bit_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
1432 c->block_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE; 1558 c->block_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
1433 c->block_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE; 1559 c->block_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
1434 } 1560 }
@@ -1441,9 +1567,11 @@ static int mb86a20s_get_stats(struct dvb_frontend *fe)
1441 int rc = 0, i; 1567 int rc = 0, i;
1442 u32 bit_error = 0, bit_count = 0; 1568 u32 bit_error = 0, bit_count = 0;
1443 u32 t_pre_bit_error = 0, t_pre_bit_count = 0; 1569 u32 t_pre_bit_error = 0, t_pre_bit_count = 0;
1570 u32 t_post_bit_error = 0, t_post_bit_count = 0;
1444 u32 block_error = 0, block_count = 0; 1571 u32 block_error = 0, block_count = 0;
1445 u32 t_block_error = 0, t_block_count = 0; 1572 u32 t_block_error = 0, t_block_count = 0;
1446 int active_layers = 0, ber_layers = 0, per_layers = 0; 1573 int active_layers = 0, pre_ber_layers = 0, post_ber_layers = 0;
1574 int per_layers = 0;
1447 1575
1448 dev_dbg(&state->i2c->dev, "%s called.\n", __func__); 1576 dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
1449 1577
@@ -1457,7 +1585,6 @@ static int mb86a20s_get_stats(struct dvb_frontend *fe)
1457 /* Layer is active and has rc segments */ 1585 /* Layer is active and has rc segments */
1458 active_layers++; 1586 active_layers++;
1459 1587
1460 /* Read per-layer BER */
1461 /* Handle BER before vterbi */ 1588 /* Handle BER before vterbi */
1462 rc = mb86a20s_get_pre_ber(fe, i, 1589 rc = mb86a20s_get_pre_ber(fe, i,
1463 &bit_error, &bit_count); 1590 &bit_error, &bit_count);
@@ -1479,7 +1606,30 @@ static int mb86a20s_get_stats(struct dvb_frontend *fe)
1479 } 1606 }
1480 1607
1481 if (c->block_error.stat[1 + i].scale != FE_SCALE_NOT_AVAILABLE) 1608 if (c->block_error.stat[1 + i].scale != FE_SCALE_NOT_AVAILABLE)
1482 ber_layers++; 1609 pre_ber_layers++;
1610
1611 /* Handle BER post vterbi */
1612 rc = mb86a20s_get_post_ber(fe, i,
1613 &bit_error, &bit_count);
1614 if (rc >= 0) {
1615 c->post_bit_error.stat[1 + i].scale = FE_SCALE_COUNTER;
1616 c->post_bit_error.stat[1 + i].uvalue += bit_error;
1617 c->post_bit_count.stat[1 + i].scale = FE_SCALE_COUNTER;
1618 c->post_bit_count.stat[1 + i].uvalue += bit_count;
1619 } else if (rc != -EBUSY) {
1620 /*
1621 * If an I/O error happened,
1622 * measures are now unavailable
1623 */
1624 c->post_bit_error.stat[1 + i].scale = FE_SCALE_NOT_AVAILABLE;
1625 c->post_bit_count.stat[1 + i].scale = FE_SCALE_NOT_AVAILABLE;
1626 dev_err(&state->i2c->dev,
1627 "%s: Can't get BER for layer %c (error %d).\n",
1628 __func__, 'A' + i, rc);
1629 }
1630
1631 if (c->block_error.stat[1 + i].scale != FE_SCALE_NOT_AVAILABLE)
1632 post_ber_layers++;
1483 1633
1484 /* Handle Block errors for PER/UCB reports */ 1634 /* Handle Block errors for PER/UCB reports */
1485 rc = mb86a20s_get_blk_error(fe, i, 1635 rc = mb86a20s_get_blk_error(fe, i,
@@ -1506,10 +1656,14 @@ static int mb86a20s_get_stats(struct dvb_frontend *fe)
1506 if (c->block_error.stat[1 + i].scale != FE_SCALE_NOT_AVAILABLE) 1656 if (c->block_error.stat[1 + i].scale != FE_SCALE_NOT_AVAILABLE)
1507 per_layers++; 1657 per_layers++;
1508 1658
1509 /* Update total BER */ 1659 /* Update total preBER */
1510 t_pre_bit_error += c->pre_bit_error.stat[1 + i].uvalue; 1660 t_pre_bit_error += c->pre_bit_error.stat[1 + i].uvalue;
1511 t_pre_bit_count += c->pre_bit_count.stat[1 + i].uvalue; 1661 t_pre_bit_count += c->pre_bit_count.stat[1 + i].uvalue;
1512 1662
1663 /* Update total postBER */
1664 t_post_bit_error += c->post_bit_error.stat[1 + i].uvalue;
1665 t_post_bit_count += c->post_bit_count.stat[1 + i].uvalue;
1666
1513 /* Update total PER */ 1667 /* Update total PER */
1514 t_block_error += c->block_error.stat[1 + i].uvalue; 1668 t_block_error += c->block_error.stat[1 + i].uvalue;
1515 t_block_count += c->block_count.stat[1 + i].uvalue; 1669 t_block_count += c->block_count.stat[1 + i].uvalue;
@@ -1520,7 +1674,7 @@ static int mb86a20s_get_stats(struct dvb_frontend *fe)
1520 * Start showing global count if at least one error count is 1674 * Start showing global count if at least one error count is
1521 * available. 1675 * available.
1522 */ 1676 */
1523 if (ber_layers) { 1677 if (pre_ber_layers) {
1524 /* 1678 /*
1525 * At least one per-layer BER measure was read. We can now 1679 * At least one per-layer BER measure was read. We can now
1526 * calculate the total BER 1680 * calculate the total BER
@@ -1534,6 +1688,24 @@ static int mb86a20s_get_stats(struct dvb_frontend *fe)
1534 c->pre_bit_count.stat[0].uvalue = t_pre_bit_count; 1688 c->pre_bit_count.stat[0].uvalue = t_pre_bit_count;
1535 } 1689 }
1536 1690
1691 /*
1692 * Start showing global count if at least one error count is
1693 * available.
1694 */
1695 if (post_ber_layers) {
1696 /*
1697 * At least one per-layer BER measure was read. We can now
1698 * calculate the total BER
1699 *
1700 * Total Bit Error/Count is calculated as the sum of the
1701 * bit errors on all active layers.
1702 */
1703 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
1704 c->post_bit_error.stat[0].uvalue = t_post_bit_error;
1705 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
1706 c->post_bit_count.stat[0].uvalue = t_post_bit_count;
1707 }
1708
1537 if (per_layers) { 1709 if (per_layers) {
1538 /* 1710 /*
1539 * At least one per-layer UCB measure was read. We can now 1711 * At least one per-layer UCB measure was read. We can now