[media] mb86a20s: fix the PER reset logic
authorMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 24 Jan 2013 14:51:23 +0000 (11:51 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 24 Jan 2013 16:27:16 +0000 (14:27 -0200)
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>
drivers/media/dvb-frontends/mb86a20s.c

index 305ebc08cf4319a3b76899148195c2d758d22f6c..7d4e9119632dd1d76f2cfb0cebcb2fb857ba48c1 100644 (file)
@@ -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 {