summaryrefslogtreecommitdiff
path: root/drivers/media/dvb-frontends/mb86a20s.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2013-01-24 18:48:44 +0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-01-24 20:26:55 +0400
commitad0abbf118519c14fee5256395f9c104e8023e9b (patch)
tree3b8165a66484c6d75210a9b8646da643202448ce /drivers/media/dvb-frontends/mb86a20s.c
parent593ae89a3f2ea69b0cffb8d8ca63549c6c02ec19 (diff)
downloadlinux-ad0abbf118519c14fee5256395f9c104e8023e9b.tar.xz
[media] mb86a20s: some fixes at preBER 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. While there, rename it, as we'll soon introduce a postBER logic there. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb-frontends/mb86a20s.c')
-rw-r--r--drivers/media/dvb-frontends/mb86a20s.c51
1 files changed, 39 insertions, 12 deletions
diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c
index c5c2c49ea99a..305ebc08cf43 100644
--- a/drivers/media/dvb-frontends/mb86a20s.c
+++ b/drivers/media/dvb-frontends/mb86a20s.c
@@ -785,12 +785,12 @@ ok:
return rc;
}
-static int mb86a20s_get_ber_before_vterbi(struct dvb_frontend *fe,
- unsigned layer,
- u32 *error, u32 *count)
+static int mb86a20s_get_pre_ber(struct dvb_frontend *fe,
+ unsigned layer,
+ u32 *error, u32 *count)
{
struct mb86a20s_state *state = fe->demodulator_priv;
- int rc;
+ int rc, val;
dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
@@ -805,7 +805,7 @@ static int mb86a20s_get_ber_before_vterbi(struct dvb_frontend *fe,
/* Check if data is available for that layer */
if (!(rc & (1 << layer))) {
dev_dbg(&state->i2c->dev,
- "%s: BER for layer %c is not available yet.\n",
+ "%s: preBER for layer %c is not available yet.\n",
__func__, 'A' + layer);
return -EBUSY;
}
@@ -866,8 +866,13 @@ static int mb86a20s_get_ber_before_vterbi(struct dvb_frontend *fe,
if (state->estimated_rate[layer]
&& state->estimated_rate[layer] != *count) {
dev_dbg(&state->i2c->dev,
- "%s: updating layer %c counter to %d.\n",
+ "%s: updating layer %c preBER counter to %d.\n",
__func__, 'A' + layer, state->estimated_rate[layer]);
+
+ /* Turn off BER before Viterbi */
+ rc = mb86a20s_writereg(state, 0x52, 0x00);
+
+ /* Update counter for this layer */
rc = mb86a20s_writereg(state, 0x50, 0xa7 + layer * 3);
if (rc < 0)
return rc;
@@ -889,16 +894,39 @@ static int mb86a20s_get_ber_before_vterbi(struct dvb_frontend *fe,
state->estimated_rate[layer]);
if (rc < 0)
return rc;
+
+ /* Turn on BER before Viterbi */
+ rc = mb86a20s_writereg(state, 0x52, 0x01);
+
+ /* Reset all preBER counters */
+ rc = mb86a20s_writereg(state, 0x53, 0x00);
+ if (rc < 0)
+ return rc;
+ rc = mb86a20s_writereg(state, 0x53, 0x07);
+ } else {
+ /* Reset counter to collect new data */
+ rc = mb86a20s_readreg(state, 0x53);
+ if (rc < 0)
+ return rc;
+ val = rc;
+ rc = mb86a20s_writereg(state, 0x53, val & ~(1 << layer));
+ if (rc < 0)
+ return rc;
+ rc = mb86a20s_writereg(state, 0x53, val | (1 << layer));
}
/* Reset counter to collect new data */
- rc = mb86a20s_writereg(state, 0x53, 0x07 & ~(1 << layer));
+ rc = mb86a20s_readreg(state, 0x5f);
if (rc < 0)
return rc;
- rc = mb86a20s_writereg(state, 0x53, 0x07);
+ val = rc;
+ rc = mb86a20s_writereg(state, 0x5f, val & ~(1 << layer));
+ if (rc < 0)
+ return rc;
+ rc = mb86a20s_writereg(state, 0x5f, val);
- return 0;
+ return rc;
}
static int mb86a20s_get_blk_error(struct dvb_frontend *fe,
@@ -1401,9 +1429,8 @@ static int mb86a20s_get_stats(struct dvb_frontend *fe)
/* Read per-layer BER */
/* Handle BER before vterbi */
- rc = mb86a20s_get_ber_before_vterbi(fe, i,
- &bit_error,
- &bit_count);
+ rc = mb86a20s_get_pre_ber(fe, i,
+ &bit_error, &bit_count);
if (rc >= 0) {
c->pre_bit_error.stat[1 + i].scale = FE_SCALE_COUNTER;
c->pre_bit_error.stat[1 + i].uvalue += bit_error;