summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2013-01-24 18:51:23 +0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-01-24 20:27:16 +0400
commit313cf4efa40ef739199bd68a76f89f8a5224a541 (patch)
treeb345159d7a230b2bb9109c8cb718a3f4d262b5d7
parentad0abbf118519c14fee5256395f9c104e8023e9b (diff)
downloadlinux-313cf4efa40ef739199bd68a76f89f8a5224a541.tar.xz
[media] mb86a20s: fix the PER reset logic
The logic that resets the device is wrong. It should be resetting just the layer that got read. Also, stop is needed before updating the counters. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/dvb-frontends/mb86a20s.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c
index 305ebc08cf43..7d4e9119632d 100644
--- a/drivers/media/dvb-frontends/mb86a20s.c
+++ b/drivers/media/dvb-frontends/mb86a20s.c
@@ -934,7 +934,7 @@ static int mb86a20s_get_blk_error(struct dvb_frontend *fe,
u32 *error, u32 *count)
{
struct mb86a20s_state *state = fe->demodulator_priv;
- int rc;
+ int rc, val;
u32 collect_rate;
dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
@@ -1007,7 +1007,6 @@ static int mb86a20s_get_blk_error(struct dvb_frontend *fe,
goto reset_measurement;
collect_rate = state->estimated_rate[layer] / 204 / 8;
-
if (collect_rate < 32)
collect_rate = 32;
if (collect_rate > 65535)
@@ -1017,6 +1016,16 @@ static int mb86a20s_get_blk_error(struct dvb_frontend *fe,
dev_dbg(&state->i2c->dev,
"%s: updating PER counter on layer %c to %d.\n",
__func__, 'A' + layer, collect_rate);
+
+ /* Stop PER measurement */
+ rc = mb86a20s_writereg(state, 0x50, 0xb0);
+ if (rc < 0)
+ return rc;
+ rc = mb86a20s_writereg(state, 0x51, 0x00);
+ if (rc < 0)
+ return rc;
+
+ /* Update this layer's counter */
rc = mb86a20s_writereg(state, 0x50, 0xb2 + layer * 2);
if (rc < 0)
return rc;
@@ -1029,6 +1038,25 @@ static int mb86a20s_get_blk_error(struct dvb_frontend *fe,
rc = mb86a20s_writereg(state, 0x51, collect_rate & 0xff);
if (rc < 0)
return rc;
+
+ /* start PER measurement */
+ rc = mb86a20s_writereg(state, 0x50, 0xb0);
+ if (rc < 0)
+ return rc;
+ rc = mb86a20s_writereg(state, 0x51, 0x07);
+ if (rc < 0)
+ return rc;
+
+ /* Reset all counters to collect new data */
+ rc = mb86a20s_writereg(state, 0x50, 0xb1);
+ if (rc < 0)
+ return rc;
+ rc = mb86a20s_writereg(state, 0x51, 0x07);
+ if (rc < 0)
+ return rc;
+ rc = mb86a20s_writereg(state, 0x51, 0x00);
+
+ return rc;
}
reset_measurement:
@@ -1036,14 +1064,16 @@ reset_measurement:
rc = mb86a20s_writereg(state, 0x50, 0xb1);
if (rc < 0)
return rc;
- rc = mb86a20s_writereg(state, 0x51, (1 << layer));
+ rc = mb86a20s_readreg(state, 0x51);
if (rc < 0)
return rc;
- rc = mb86a20s_writereg(state, 0x51, 0x00);
+ val = rc;
+ rc = mb86a20s_writereg(state, 0x51, val | (1 << layer));
if (rc < 0)
return rc;
+ rc = mb86a20s_writereg(state, 0x51, val & ~(1 << layer));
- return 0;
+ return rc;
}
struct linear_segments {