[PATCH] Fix the unc for the frontends tda10021 and stv0297

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

the uncorrected block count is reset on a read request for the tda10021 and stv0297. This makes the UNC value of the femon plugin useless. The attached patch will fix this issue. It is simple for the stv0297. For the tda10021, the uncorrected block count must be read cyclical, because the resolution of the counter is very low. This can be done within tda10021_read_status. The read-status-function is called cyclical from the frontend-thread.

Some other frontends have the same problem (tda10023, ves1820, ves1x93, ...).

-Hartmut



signed-off-by: Hartmut Birr <e9hack@xxxxxxxxx>
- The uncorrected block counter shouldn't be reset on read. The tda10021 contains 
  an uncorrected block counter, which has only a resoltion of 7 bits and 
  which isn't able wrap to zero. The driver must manage the block counter by itself. 
diff -r 4c4fd6b8755c linux/drivers/media/dvb/frontends/tda10021.c
--- a/linux/drivers/media/dvb/frontends/tda10021.c	Fri May 02 07:51:27 2008 -0300
+++ b/linux/drivers/media/dvb/frontends/tda10021.c	Sat May 03 18:55:09 2008 +0200
@@ -41,6 +41,8 @@ struct tda10021_state {
 
 	u8 pwm;
 	u8 reg0;
+	u8 last_lock : 1;
+	u32 ucblocks;
 };
 
 
@@ -266,6 +268,10 @@ static int tda10021_set_parameters (stru
 
 	tda10021_setup_reg0 (state, reg0x00[qam], p->inversion);
 
+	/* reset uncorrected block counter */
+	state->last_lock = 0;
+	state->ucblocks = 0;
+
 	return 0;
 }
 
@@ -273,6 +279,7 @@ static int tda10021_read_status(struct d
 {
 	struct tda10021_state* state = fe->demodulator_priv;
 	int sync;
+	u32 ucblocks;
 
 	*status = 0;
 	//0x11[0] == EQALGO -> Equalizer algorithms state
@@ -291,6 +298,22 @@ static int tda10021_read_status(struct d
 	if (sync & 8)
 		*status |= FE_HAS_LOCK;
 
+	/* read uncorrected block counter */
+	ucblocks = tda10021_readreg(state, 0x13) & 0x7f;
+
+	/* reset uncorrected block counter */
+	_tda10021_writereg(state, 0x10, tda10021_inittab[0x10] & 0xdf);
+	_tda10021_writereg(state, 0x10, tda10021_inittab[0x10]);
+
+	if (sync & 8) {
+		if (state->last_lock)
+			/* update ucblocks */
+			state->ucblocks += ucblocks;
+		state->last_lock = 1;
+	} else {
+		state->last_lock = 0;
+	}
+
 	return 0;
 }
 
@@ -335,14 +358,10 @@ static int tda10021_read_ucblocks(struct
 static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 {
 	struct tda10021_state* state = fe->demodulator_priv;
-
-	*ucblocks = tda10021_readreg (state, 0x13) & 0x7f;
-	if (*ucblocks == 0x7f)
-		*ucblocks = 0xffffffff;
-
-	/* reset uncorrected block counter */
-	_tda10021_writereg (state, 0x10, tda10021_inittab[0x10] & 0xdf);
-	_tda10021_writereg (state, 0x10, tda10021_inittab[0x10]);
+	fe_status_t status;
+
+	tda10021_read_status(fe, &status);
+	*ucblocks = state->ucblocks;
 
 	return 0;
 }
signed-off-by: Hartmut Birr <e9hack@xxxxxxxxx>
- Don't reset the uncorrected block counter on a read request.
diff -r 4c4fd6b8755c linux/drivers/media/dvb/frontends/stv0297.c
--- a/linux/drivers/media/dvb/frontends/stv0297.c	Fri May 02 07:51:27 2008 -0300
+++ b/linux/drivers/media/dvb/frontends/stv0297.c	Sat May 03 15:43:48 2008 +0200
@@ -398,7 +398,6 @@ static int stv0297_read_ucblocks(struct 
 	*ucblocks = (stv0297_readreg(state, 0xD5) << 8)
 		| stv0297_readreg(state, 0xD4);
 
-	stv0297_writereg_mask(state, 0xDF, 0x03, 0x02); /* clear the counters */
 	stv0297_writereg_mask(state, 0xDF, 0x03, 0x01); /* re-enable the counters */
 
 	return 0;
_______________________________________________
linux-dvb mailing list
linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux