[12/15] si2165: add DVBv5 BER statistics
Commit Message
Add support for BER statistics.
Configure a measurement period of 30000 packets.
Signed-off-by: Matthias Schwarzott <zzam@gentoo.org>
---
drivers/media/dvb-frontends/si2165.c | 57 +++++++++++++++++++++++++++++--
drivers/media/dvb-frontends/si2165_priv.h | 11 ++++++
2 files changed, 66 insertions(+), 2 deletions(-)
@@ -594,8 +594,9 @@ static int si2165_init(struct dvb_frontend *fe)
if (ret < 0)
goto error;
- /* ber_pkt */
- ret = si2165_writereg16(state, REG_BER_PKT, 0x7530);
+ /* ber_pkt - default 65535 */
+ ret = si2165_writereg16(state, REG_BER_PKT,
+ STATISTICS_PERIOD_PKT_COUNT);
if (ret < 0)
goto error;
@@ -642,6 +643,10 @@ static int si2165_init(struct dvb_frontend *fe)
c = &state->fe.dtv_property_cache;
c->cnr.len = 1;
c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_error.len = 1;
+ c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_count.len = 1;
+ c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
return 0;
error:
@@ -738,6 +743,54 @@ static int si2165_read_status(struct dvb_frontend *fe, enum fe_status *status)
} else
c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ /* BER */
+ if (*status & FE_HAS_VITERBI) {
+ if (c->post_bit_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
+ /* start new sampling period to get rid of old data*/
+ ret = si2165_writereg8(state, REG_BER_RST, 0x01);
+ if (ret < 0)
+ return ret;
+
+ /* set scale to enter read code on next call */
+ c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_error.stat[0].uvalue = 0;
+ c->post_bit_count.stat[0].uvalue = 0;
+
+ } else {
+ ret = si2165_readreg8(state, REG_BER_AVAIL, &u8tmp);
+ if (ret < 0)
+ return ret;
+
+ if (u8tmp & 1) {
+ u32 biterrcnt;
+
+ ret = si2165_readreg24(state, REG_BER_BIT,
+ &biterrcnt);
+ if (ret < 0)
+ return ret;
+
+ c->post_bit_error.stat[0].uvalue +=
+ biterrcnt;
+ c->post_bit_count.stat[0].uvalue +=
+ STATISTICS_PERIOD_BIT_COUNT;
+
+ /* start new sampling period */
+ ret = si2165_writereg8(state,
+ REG_BER_RST, 0x01);
+ if (ret < 0)
+ return ret;
+
+ dev_dbg(&state->client->dev,
+ "post_bit_error=%u post_bit_count=%u\n",
+ biterrcnt, STATISTICS_PERIOD_BIT_COUNT);
+ }
+ }
+ } else {
+ c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ }
+
return 0;
}
@@ -38,6 +38,9 @@ struct si2165_config {
bool inversion;
};
+#define STATISTICS_PERIOD_PKT_COUNT 30000u
+#define STATISTICS_PERIOD_BIT_COUNT (STATISTICS_PERIOD_PKT_COUNT * 204 * 8)
+
#define REG_CHIP_MODE 0x0000
#define REG_CHIP_REVCODE 0x0023
#define REV_CHIP_TYPE 0x0118
@@ -95,8 +98,16 @@ struct si2165_config {
#define REG_GP_REG0_MSB 0x0387
#define REG_CRC 0x037a
#define REG_CHECK_SIGNAL 0x03a8
+#define REG_CBER_RST 0x0424
+#define REG_CBER_BIT 0x0428
+#define REG_CBER_ERR 0x0430
+#define REG_CBER_AVAIL 0x0434
#define REG_PS_LOCK 0x0440
+#define REG_UNCOR_CNT 0x0468
+#define REG_BER_RST 0x046c
#define REG_BER_PKT 0x0470
+#define REG_BER_BIT 0x0478
+#define REG_BER_AVAIL 0x047c
#define REG_FEC_LOCK 0x04e0
#define REG_TS_DATA_MODE 0x04e4
#define REG_TS_CLK_MODE 0x04e5