Skip to contentSkip to conversation

Do some improvements/fixups on mb86a20s, cx231xx and em28xx

PATCH In review Mauro Carvalho Chehab 1 participant 13 messages Mar 3, 2013 – Mar 4, 2013

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover Do some improvements/fixups on mb86a20s, cx231xx and em28xx

While working to add support for a new device, I discovered a series of issues with mb86a20s and one with em28xx.

While here, I also changed cx231xx to improve its signal detection, by using a different IF frequency and increasing the IF signal level from the tuner by 12dB.

Mauro Carvalho Chehab (11):
[media] mb86a20s: don't pollute dmesg with debug messages [media] mb86a20s: adjust IF based on what's set on the tuner [media] mb86a20s: provide CNR stats before FE_HAS_SYNC [media] mb86a20s: Fix signal strength calculus
[media] mb86a20s: don't allow updating signal strength too fast [media] mb86a20s: change AGC tuning parameters
[media] mb86a20s: Always reset the frontend with set_frontend [media] mb86a20s: Don't reset strength with the other stats [media] mb86a20s: cleanup the status at set_frontend() [media] cx231xx: Improve signal reception for PV SBTVD [media] em28xx-dvb: Don't put device in suspend mode at feed stop

 drivers/media/dvb-core/dmxdev.c         |   3 +-
 drivers/media/dvb-frontends/mb86a20s.c  | 200 +++++++++++++++++++++-----------
 drivers/media/usb/cx231xx/cx231xx-dvb.c |   4 +-
 drivers/media/usb/em28xx/em28xx-dvb.c   |   2 -
 4 files changed, 136 insertions(+), 73 deletions(-)
Signature · 1 line
1.8.1.4
#1 lore raw

PATCH 1/11 mb86a20s: don't pollute dmesg with debug messages

There are a few debug tests that are shown with dev_err() or dev_info(). Replace them by dev_dbg().

---
 drivers/media/dvb-frontends/mb86a20s.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/media/dvb-frontends/mb86a20s.c +3 -3
index f19cd73..44bfb88 100644
@@ -1095,7 +1095,7 @@ static int mb86a20s_get_blk_error(struct dvb_frontend *fe,
 	if (rc < 0)
 		return rc;
 	*error |= rc;
-	dev_err(&state->i2c->dev, "%s: block error for layer %c: %d.\n",
+	dev_dbg(&state->i2c->dev, "%s: block error for layer %c: %d.\n",
 		__func__, 'A' + layer, *error);
 
 	/* Read Bit Count */
@@ -1386,7 +1386,7 @@ static int mb86a20s_get_main_CNR(struct dvb_frontend *fe)
 		return rc;
 
 	if (!(rc & 0x40)) {
-		dev_info(&state->i2c->dev, "%s: CNR is not available yet.\n",
+		dev_dbg(&state->i2c->dev, "%s: CNR is not available yet.\n",
 			 __func__);
 		return -EBUSY;
 	}
@@ -1441,7 +1441,7 @@ static int mb86a20s_get_blk_error_layer_CNR(struct dvb_frontend *fe)
 
 	/* Check if data is available */
 	if (!(rc & 0x01)) {
-		dev_info(&state->i2c->dev,
+		dev_dbg(&state->i2c->dev,
 			"%s: MER measures aren't available yet.\n", __func__);
 		return -EBUSY;
 	}
Signature · 1 line
1.8.1.4
#2 lore raw

PATCH 2/11 mb86a20s: adjust IF based on what's set on the tuner

In reply to Mauro Carvalho Chehab

Instead of hardcoding a fixed IF frequency of 3.3 MHz, use the IF frequency provided by the tuner driver.

---
 drivers/media/dvb-frontends/mb86a20s.c | 57 +++++++++++++++++++++++++++++++---
 1 file changed, 53 insertions(+), 4 deletions(-)
drivers/media/dvb-frontends/mb86a20s.c +53 -4
index 44bfb88..daeee81 100644
@@ -31,6 +31,8 @@ struct mb86a20s_state {
 
 	struct dvb_frontend frontend;
 
+	u32 if_freq;
+
 	u32 estimated_rate[3];
 
 	bool need_init;
@@ -47,7 +49,7 @@ struct regdata {
  * Initialization sequence: Use whatevere default values that PV SBTVD
  * does on its initialisation, obtained via USB snoop
  */
-static struct regdata mb86a20s_init[] = {
+static struct regdata mb86a20s_init1[] = {
 	{ 0x70, 0x0f },
 	{ 0x70, 0xff },
 	{ 0x08, 0x01 },
@@ -56,7 +58,9 @@ static struct regdata mb86a20s_init[] = {
 	{ 0x39, 0x01 },
 	{ 0x71, 0x00 },
 	{ 0x28, 0x2a }, { 0x29, 0x00 }, { 0x2a, 0xff }, { 0x2b, 0x80 },
-	{ 0x28, 0x20 }, { 0x29, 0x33 }, { 0x2a, 0xdf }, { 0x2b, 0xa9 },
+};
+
+static struct regdata mb86a20s_init2[] = {
 	{ 0x28, 0x22 }, { 0x29, 0x00 }, { 0x2a, 0x1f }, { 0x2b, 0xf0 },
 	{ 0x3b, 0x21 },
 	{ 0x3c, 0x3a },
@@ -1737,6 +1741,7 @@ static int mb86a20s_get_stats(struct dvb_frontend *fe)
 static int mb86a20s_initfe(struct dvb_frontend *fe)
 {
 	struct mb86a20s_state *state = fe->demodulator_priv;
+	u64 pll;
 	int rc;
 	u8  regD5 = 1;
 
@@ -1746,10 +1751,35 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
 		fe->ops.i2c_gate_ctrl(fe, 0);
 
 	/* Initialize the frontend */
-	rc = mb86a20s_writeregdata(state, mb86a20s_init);
+	rc = mb86a20s_writeregdata(state, mb86a20s_init1);
 	if (rc < 0)
 		goto err;
 
+	/* Adjust IF frequency to match tuner */
+	if (fe->ops.tuner_ops.get_if_frequency)
+		fe->ops.tuner_ops.get_if_frequency(fe, &state->if_freq);
+
+	if (!state->if_freq)
+		state->if_freq = 3300000;
+
+	/* pll = freq[Hz] * 2^24/10^6 / 16.285714286 */
+	pll = state->if_freq * 1677721600L;
+	do_div(pll, 1628571429L);
+	rc = mb86a20s_writereg(state, 0x28, 0x20);
+	if (rc < 0)
+		goto err;
+	rc = mb86a20s_writereg(state, 0x29, (pll >> 16) & 0xff);
+	if (rc < 0)
+		goto err;
+	rc = mb86a20s_writereg(state, 0x2a, (pll >> 8) & 0xff);
+	if (rc < 0)
+		goto err;
+	rc = mb86a20s_writereg(state, 0x2b, pll & 0xff);
+	if (rc < 0)
+		goto err;
+	dev_dbg(&state->i2c->dev, "%s: IF=%d, PLL=0x%06llx\n",
+		__func__, state->if_freq, (long long)pll);
+
 	if (!state->config->is_serial) {
 		regD5 &= ~1;
 
@@ -1761,6 +1791,11 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
 			goto err;
 	}
 
+	rc = mb86a20s_writeregdata(state, mb86a20s_init2);
+	if (rc < 0)
+		goto err;
+
+
 err:
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
@@ -1779,7 +1814,7 @@ err:
 static int mb86a20s_set_frontend(struct dvb_frontend *fe)
 {
 	struct mb86a20s_state *state = fe->demodulator_priv;
-	int rc;
+	int rc, if_freq;
 #if 0
 	/*
 	 * FIXME: Properly implement the set frontend properties
@@ -1796,6 +1831,18 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe)
 		fe->ops.i2c_gate_ctrl(fe, 1);
 	fe->ops.tuner_ops.set_params(fe);
 
+	if (fe->ops.tuner_ops.get_if_frequency) {
+		fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
+
+		/*
+		 * If the IF frequency changed, re-initialize the
+		 * frontend. This is needed by some drivers like tda18271,
+		 * that only sets the IF after receiving a set_params() call
+		 */
+		if (if_freq != state->if_freq)
+			state->need_init = true;
+	}
+
 	/*
 	 * Make it more reliable: if, for some reason, the initial
 	 * device initialization doesn't happen, initialize it when
@@ -1805,6 +1852,8 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe)
 	 * the agc callback logic is not called during DVB attach time,
 	 * causing mb86a20s to not be initialized with Kworld SBTVD.
 	 * So, this hack is needed, in order to make Kworld SBTVD to work.
+	 *
+	 * It is also needed to change the IF after the initial init.
 	 */
 	if (state->need_init)
 		mb86a20s_initfe(fe);
Signature · 1 line
1.8.1.4
#3 lore raw

PATCH 3/11 mb86a20s: provide CNR stats before FE_HAS_SYNC

In reply to Mauro Carvalho Chehab

State 9 means TS started to be output, and it should be associated with FE_HAS_SYNC.

The mb86a20scan get CNR statistics at state 7, when frame sync is obtained.

As CNR may help to adjust the antenna, provide it earlier.

A latter patch could eventually start outputing MER measures earlier, but that would require a bigger change, and probably won't be better than the current way, as the time between changing from state 8 to 9 is generally lower than the time to get the stats collected.

---
 drivers/media/dvb-frontends/mb86a20s.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)
drivers/media/dvb-frontends/mb86a20s.c +16 -8
index daeee81..e222e55 100644
@@ -312,7 +312,7 @@ static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status)
 	dev_dbg(&state->i2c->dev, "%s: Status = 0x%02x (state = %d)\n",
 		 __func__, *status, val);
 
-	return 0;
+	return val;
 }
 
 static int mb86a20s_read_signal_strength(struct dvb_frontend *fe)
@@ -1564,7 +1564,7 @@ static void mb86a20s_stats_not_ready(struct dvb_frontend *fe)
 	}
 }
 
-static int mb86a20s_get_stats(struct dvb_frontend *fe)
+static int mb86a20s_get_stats(struct dvb_frontend *fe, int status_nr)
 {
 	struct mb86a20s_state *state = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
@@ -1584,6 +1584,14 @@ static int mb86a20s_get_stats(struct dvb_frontend *fe)
 	/* Get per-layer stats */
 	mb86a20s_get_blk_error_layer_CNR(fe);
 
+	/*
+	 * At state 7, only CNR is available
+	 * For BER measures, state=9 is required
+	 * FIXME: we may get MER measures with state=8
+	 */
+	if (status_nr < 9)
+		return 0;
+
 	for (i = 0; i < 3; i++) {
 		if (c->isdbt_layer_enabled & (1 << i)) {
 			/* Layer is active and has rc segments */
@@ -1875,7 +1883,7 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe,
 {
 	struct mb86a20s_state *state = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-	int rc;
+	int rc, status_nr;
 
 	dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
 
@@ -1883,12 +1891,12 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe,
 		fe->ops.i2c_gate_ctrl(fe, 0);
 
 	/* Get lock */
-	rc = mb86a20s_read_status(fe, status);
-	if (!(*status & FE_HAS_LOCK)) {
+	status_nr = mb86a20s_read_status(fe, status);
+	if (status_nr < 7) {
 		mb86a20s_stats_not_ready(fe);
 		mb86a20s_reset_frontend_cache(fe);
 	}
-	if (rc < 0) {
+	if (state < 0) {
 		dev_err(&state->i2c->dev,
 			"%s: Can't read frontend lock status\n", __func__);
 		goto error;
@@ -1908,7 +1916,7 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe,
 	/* Fill signal strength */
 	c->strength.stat[0].uvalue = rc;
 
-	if (*status & FE_HAS_LOCK) {
+	if (status_nr >= 7) {
 		/* Get TMCC info*/
 		rc = mb86a20s_get_frontend(fe);
 		if (rc < 0) {
@@ -1919,7 +1927,7 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe,
 		}
 
 		/* Get statistics */
-		rc = mb86a20s_get_stats(fe);
+		rc = mb86a20s_get_stats(fe, status_nr);
 		if (rc < 0 && rc != -EBUSY) {
 			dev_err(&state->i2c->dev,
 				"%s: Can't get FE statistics.\n", __func__);
Signature · 1 line
1.8.1.4
#4 lore raw

Re: [PATCH 03/11] [media] mb86a20s: provide CNR stats before FE_HAS_SYNC

Em Sun, 3 Mar 2013 12:58:43 -0300
Mauro Carvalho Chehab <[email protected]> escreveu:

Quoted 68 lines

State 9 means TS started to be output, and it should be associated with FE_HAS_SYNC.

The mb86a20scan get CNR statistics at state 7, when frame sync is obtained.

As CNR may help to adjust the antenna, provide it earlier.

A latter patch could eventually start outputing MER measures earlier, but that would require a bigger change, and probably won't be better than the current way, as the time between changing from state 8 to 9 is generally lower than the time to get the stats collected.

---
 drivers/media/dvb-frontends/mb86a20s.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)
drivers/media/dvb-frontends/mb86a20s.c +11 -3
index daeee81..e222e55 100644
@@ -312,7 +312,7 @@ static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status)
 	dev_dbg(&state->i2c->dev, "%s: Status = 0x%02x (state = %d)\n",
 		 __func__, *status, val);
 
-	return 0;
+	return val;
 }
 
 static int mb86a20s_read_signal_strength(struct dvb_frontend *fe)
@@ -1564,7 +1564,7 @@ static void mb86a20s_stats_not_ready(struct dvb_frontend *fe)
 	}
 }
 
-static int mb86a20s_get_stats(struct dvb_frontend *fe)
+static int mb86a20s_get_stats(struct dvb_frontend *fe, int status_nr)
 {
 	struct mb86a20s_state *state = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
@@ -1584,6 +1584,14 @@ static int mb86a20s_get_stats(struct dvb_frontend *fe)
 	/* Get per-layer stats */
 	mb86a20s_get_blk_error_layer_CNR(fe);
 
+	/*
+	 * At state 7, only CNR is available
+	 * For BER measures, state=9 is required
+	 * FIXME: we may get MER measures with state=8
+	 */
+	if (status_nr < 9)
+		return 0;
+
 	for (i = 0; i < 3; i++) {
 		if (c->isdbt_layer_enabled & (1 << i)) {
 			/* Layer is active and has rc segments */
@@ -1875,7 +1883,7 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe,
 {
 	struct mb86a20s_state *state = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-	int rc;
+	int rc, status_nr;
 
 	dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
 
@@ -1883,12 +1891,12 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe,
 		fe->ops.i2c_gate_ctrl(fe, 0);
 

drivers/media/dvb-frontends/mb86a20s.c static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe, · line 1899

Quoted 10 lines
drivers/media/dvb-frontends/mb86a20s.c +3 -3
 	/* Get lock */
-	rc = mb86a20s_read_status(fe, status);
-	if (!(*status & FE_HAS_LOCK)) {
+	status_nr = mb86a20s_read_status(fe, status);
+	if (status_nr < 7) {
 		mb86a20s_stats_not_ready(fe);
 		mb86a20s_reset_frontend_cache(fe);
 	}
-	if (rc < 0) {
+	if (state < 0) {

This is obviously wrong ;)

Patch with fixup enclosed.

Cheers,
Mauro

-

[PATCH 03/11v2] [media] mb86a20s: provide CNR stats before FE_HAS_SYNC

State 9 means TS started to be output, and it should be associated with FE_HAS_SYNC.

The mb86a20scan get CNR statistics at state 7, when frame sync is obtained.

As CNR may help to adjust the antenna, provide it earlier.

A latter patch could eventually start outputing MER measures earlier, but that would require a bigger change, and probably won't be better than the current way, as the time between changing from state 8 to 9 is generally lower than the time to get the stats collected.

drivers/media/dvb-frontends/mb86a20s.c +16 -8
index daeee81..2720b82 100644
@@ -312,7 +312,7 @@ static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status)
 	dev_dbg(&state->i2c->dev, "%s: Status = 0x%02x (state = %d)\n",
 		 __func__, *status, val);
 
-	return 0;
+	return val;
 }
 
 static int mb86a20s_read_signal_strength(struct dvb_frontend *fe)
@@ -1564,7 +1564,7 @@ static void mb86a20s_stats_not_ready(struct dvb_frontend *fe)
 	}
 }
 
-static int mb86a20s_get_stats(struct dvb_frontend *fe)
+static int mb86a20s_get_stats(struct dvb_frontend *fe, int status_nr)
 {
 	struct mb86a20s_state *state = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
@@ -1584,6 +1584,14 @@ static int mb86a20s_get_stats(struct dvb_frontend *fe)
 	/* Get per-layer stats */
 	mb86a20s_get_blk_error_layer_CNR(fe);
 
+	/*
+	 * At state 7, only CNR is available
+	 * For BER measures, state=9 is required
+	 * FIXME: we may get MER measures with state=8
+	 */
+	if (status_nr < 9)
+		return 0;
+
 	for (i = 0; i < 3; i++) {
 		if (c->isdbt_layer_enabled & (1 << i)) {
 			/* Layer is active and has rc segments */
@@ -1875,7 +1883,7 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe,
 {
 	struct mb86a20s_state *state = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-	int rc;
+	int rc, status_nr;
 
 	dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
 
@@ -1883,12 +1891,12 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe,
 		fe->ops.i2c_gate_ctrl(fe, 0);
 
 	/* Get lock */
-	rc = mb86a20s_read_status(fe, status);
-	if (!(*status & FE_HAS_LOCK)) {
+	status_nr = mb86a20s_read_status(fe, status);
+	if (status_nr < 7) {
 		mb86a20s_stats_not_ready(fe);
 		mb86a20s_reset_frontend_cache(fe);
 	}
-	if (rc < 0) {
+	if (status_nr < 0) {
 		dev_err(&state->i2c->dev,
 			"%s: Can't read frontend lock status\n", __func__);
 		goto error;
@@ -1908,7 +1916,7 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe,
 	/* Fill signal strength */
 	c->strength.stat[0].uvalue = rc;
 
-	if (*status & FE_HAS_LOCK) {
+	if (status_nr >= 7) {
 		/* Get TMCC info*/
 		rc = mb86a20s_get_frontend(fe);
 		if (rc < 0) {
@@ -1919,7 +1927,7 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe,
 		}
 
 		/* Get statistics */
-		rc = mb86a20s_get_stats(fe);
+		rc = mb86a20s_get_stats(fe, status_nr);
 		if (rc < 0 && rc != -EBUSY) {
 			dev_err(&state->i2c->dev,
 				"%s: Can't get FE statistics.\n", __func__);
#5 lore raw

PATCH 4/11 mb86a20s: Fix signal strength calculus

In reply to Mauro Carvalho Chehab

A register typo made the calculation to not work. Fix it.

---
 drivers/media/dvb-frontends/mb86a20s.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/dvb-frontends/mb86a20s.c +1 -1
index e222e55..983fb3b 100644
@@ -335,7 +335,7 @@ static int mb86a20s_read_signal_strength(struct dvb_frontend *fe)
 		rc = mb86a20s_writereg(state, 0x04, 0x20);
 		if (rc < 0)
 			return rc;
-		rc = mb86a20s_writereg(state, 0x04, rf);
+		rc = mb86a20s_writereg(state, 0x05, rf);
 		if (rc < 0)
 			return rc;
 
Signature · 1 line
1.8.1.4
#6 lore raw

PATCH 5/11 mb86a20s: don't allow updating signal strength too fast

In reply to Mauro Carvalho Chehab

Getting signal strength requires some loop poking with I2C. Don't let it happen too fast.

---
 drivers/media/dvb-frontends/mb86a20s.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)
drivers/media/dvb-frontends/mb86a20s.c +17 -7
index 983fb3b..82fa2af 100644
@@ -34,6 +34,7 @@ struct mb86a20s_state {
 	u32 if_freq;
 
 	u32 estimated_rate[3];
+	unsigned long get_strength_time;
 
 	bool need_init;
 };
@@ -318,9 +319,17 @@ static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status)
 static int mb86a20s_read_signal_strength(struct dvb_frontend *fe)
 {
 	struct mb86a20s_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	int rc;
 	unsigned rf_max, rf_min, rf;
 
+	if (state->get_strength_time &&
+	   (!time_after(jiffies, state->get_strength_time)))
+		return c->strength.stat[0].uvalue;
+
+	/* Reset its value if an error happen */
+	c->strength.stat[0].uvalue = 0;
+
 	/* Does a binary search to get RF strength */
 	rf_max = 0xfff;
 	rf_min = 0;
@@ -350,15 +359,19 @@ static int mb86a20s_read_signal_strength(struct dvb_frontend *fe)
 			rf = (rf_max + rf_min) / 2;
 
 			/* Rescale it from 2^12 (4096) to 2^16 */
-			rf <<= (16 - 12);
+			rf = rf << (16 - 12);
+			if (rf)
+				rf |= (1 << 12) - 1;
+
 			dev_dbg(&state->i2c->dev,
 				"%s: signal strength = %d (%d < RF=%d < %d)\n",
 				__func__, rf, rf_min, rf >> 4, rf_max);
-			return rf;
+			c->strength.stat[0].uvalue = rf;
+			state->get_strength_time = jiffies +
+						   msecs_to_jiffies(1000);
+			return 0;
 		}
 	} while (1);
-
-	return 0;
 }
 
 static int mb86a20s_get_modulation(struct mb86a20s_state *state,
@@ -1882,7 +1895,6 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe,
 					  fe_status_t *status)
 {
 	struct mb86a20s_state *state = fe->demodulator_priv;
-	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	int rc, status_nr;
 
 	dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
@@ -1913,8 +1925,6 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe,
 		rc = 0;		/* Status is OK */
 		goto error;
 	}
-	/* Fill signal strength */
-	c->strength.stat[0].uvalue = rc;
 
 	if (status_nr >= 7) {
 		/* Get TMCC info*/
Signature · 1 line
1.8.1.4
#7 lore raw

PATCH 6/11 mb86a20s: change AGC tuning parameters

In reply to Mauro Carvalho Chehab

Use the AGC settings present on a newer device.

The initial settings were taken from one of the first devices with mb86a20s, and there are several reports that this is not working properly on some places.

So, instead of keeping using it, get the parameters taken from a newer device. Tests are welcomed.

Tested also with cx231xx PixelView SBTVD Hybrid with no regressions noticed so far.

---
 drivers/media/dvb-core/dmxdev.c        |  3 +-
 drivers/media/dvb-frontends/mb86a20s.c | 86 +++++++++++++++++-----------------
 2 files changed, 46 insertions(+), 43 deletions(-)
drivers/media/dvb-core/dmxdev.c +2 -1
index d81dbb2..8896993 100644
@@ -852,7 +852,8 @@ static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev,
 				 struct dmxdev_filter *dmxdevfilter,
 				 struct dmx_sct_filter_params *params)
 {
-	dprintk("function : %s\n", __func__);
+	dprintk("function : %s, PID=0x%04x, flags=%02x, timeout=%d\n",
+		__func__, params->pid, params->flags, params->timeout);
 
 	dvb_dmxdev_filter_stop(dmxdevfilter);
 
drivers/media/dvb-frontends/mb86a20s.c +44 -42

119 lines not on this page · raw message

Signature · 1 line
1.8.1.4
#8 lore raw

PATCH 7/11 mb86a20s: Always reset the frontend with set_frontend

In reply to Mauro Carvalho Chehab

Always init the frontend when set_frontend is called. The rationale
is: it was noticed that, on some devices, it fails to lock with a different channel. It seems that some other registers need to be restored to its initial state, when the channel changes.

As it is better to reset everything, even wasting a few more miliseconds than to loose channel lock, let's change the logic to always reset.

---
 drivers/media/dvb-frontends/mb86a20s.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)
drivers/media/dvb-frontends/mb86a20s.c +7 -12
index c552300..1589662 100644
@@ -1854,18 +1854,9 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe)
 		fe->ops.i2c_gate_ctrl(fe, 1);
 	fe->ops.tuner_ops.set_params(fe);
 
-	if (fe->ops.tuner_ops.get_if_frequency) {
+	if (fe->ops.tuner_ops.get_if_frequency)
 		fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
 
-		/*
-		 * If the IF frequency changed, re-initialize the
-		 * frontend. This is needed by some drivers like tda18271,
-		 * that only sets the IF after receiving a set_params() call
-		 */
-		if (if_freq != state->if_freq)
-			state->need_init = true;
-	}
-
 	/*
 	 * Make it more reliable: if, for some reason, the initial
 	 * device initialization doesn't happen, initialize it when
@@ -1877,9 +1868,13 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe)
 	 * So, this hack is needed, in order to make Kworld SBTVD to work.
 	 *
 	 * It is also needed to change the IF after the initial init.
+	 *
+	 * HACK: Always init the frontend when set_frontend is called:
+	 * it was noticed that, on some devices, it fails to lock on a
+	 * different channel. So, it is better to reset everything, even
+	 * wasting some time, than to loose channel lock.
 	 */
-	if (state->need_init)
-		mb86a20s_initfe(fe);
+	mb86a20s_initfe(fe);
 
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 0);
Signature · 1 line
1.8.1.4
#9 lore raw

PATCH 8/11 mb86a20s: Don't reset strength with the other stats

In reply to Mauro Carvalho Chehab

Signal strength is always available. There's no reason to reset it, as it has its own logic to reset it already.

---
 drivers/media/dvb-frontends/mb86a20s.c | 1 -
 1 file changed, 1 deletion(-)
drivers/media/dvb-frontends/mb86a20s.c +0 -1
index 1589662..7238947 100644
@@ -754,7 +754,6 @@ static int mb86a20s_reset_counters(struct dvb_frontend *fe)
 
 	/* Reset the counters, if the channel changed */
 	if (state->last_frequency != c->frequency) {
-		memset(&c->strength, 0, sizeof(c->strength));
 		memset(&c->cnr, 0, sizeof(c->cnr));
 		memset(&c->pre_bit_error, 0, sizeof(c->pre_bit_error));
 		memset(&c->pre_bit_count, 0, sizeof(c->pre_bit_count));
Signature · 1 line
1.8.1.4
#10 lore raw

PATCH 9/11 mb86a20s: cleanup the status at set_frontend()

In reply to Mauro Carvalho Chehab

As the device got re-initialized, the stats should vanish until the device gets lock again.

---
 drivers/media/dvb-frontends/mb86a20s.c | 1 +
 1 file changed, 1 insertion(+)
drivers/media/dvb-frontends/mb86a20s.c +1 -0
index 7238947..2d85131 100644
@@ -1880,6 +1880,7 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe)
 
 	rc = mb86a20s_writeregdata(state, mb86a20s_reset_reception);
 	mb86a20s_reset_counters(fe);
+	mb86a20s_stats_not_ready(fe);
 
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
Signature · 1 line
1.8.1.4
#11 lore raw

PATCH 10/11 cx231xx: Improve signal reception for PV SBTVD

In reply to Mauro Carvalho Chehab

Instead of using 3.3 MHz IF, use 4MHz. That's the standard value for the demod, and, while it can be adjusted, 3.3 MHz is out of the recommended range. So, let's stick with the default.
With regards to the IF voltage level, instead of using 0.5 V(p-p) for IF, use 2V, giving a 12dB gain.
The rationale is that, on PixelView SBTVD Hybrid, even 2V(p-p) would be in the nominal range for IF, as the maximum range on this particular device is 3V. A higher gain here should help to improve reception under weak signals.

---
 drivers/media/usb/cx231xx/cx231xx-dvb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/media/usb/cx231xx/cx231xx-dvb.c +2 -2
index 7c4e360..14e2610 100644
@@ -89,8 +89,8 @@ static struct tda18271_std_map cnxt_rde253s_tda18271_std_map = {
 };
 
 static struct tda18271_std_map mb86a20s_tda18271_config = {
-	.dvbt_6   = { .if_freq = 3300, .agc_mode = 3, .std = 4,
-		      .if_lvl = 7, .rfagc_top = 0x37, },
+	.dvbt_6   = { .if_freq = 4000, .agc_mode = 3, .std = 4,
+		      .if_lvl = 0, .rfagc_top = 0x37, },
 };
 
 static struct tda18271_config cnxt_rde253s_tunerconfig = {
Signature · 1 line
1.8.1.4
#12 lore raw

PATCH 11/11 em28xx-dvb: Don't put device in suspend mode at feed stop

In reply to Mauro Carvalho Chehab

Putting em28xx in suspend mode when a feed stops is just plain wrong. Every time a new PES filter is changed, the DVB demux code will stop the current feed, and then start a new one. If are there any code that switches off the frontend, via some GPIO setting, this would make the DVB fail. This condition was actually trigged with one device, during DVB scan, as, during scan, it is common that userspace apps to change the filter several times, in order to get all tables.
Also, this is not needed at all, since the em28xx code already hooks into ops.ts_bus_ctrl(). This warrants that em28xx can check there if DVB frontend is in usage or not. The code there already puts the device on suspend mode, if the DVB frontend is not used (closed).

---
 drivers/media/usb/em28xx/em28xx-dvb.c | 2 --
 1 file changed, 2 deletions(-)
drivers/media/usb/em28xx/em28xx-dvb.c +0 -2
index a81ec2e..7200dfe 100644
@@ -220,8 +220,6 @@ static int em28xx_stop_streaming(struct em28xx_dvb *dvb)
 
 	em28xx_stop_urbs(dev);
 
-	em28xx_set_mode(dev, EM28XX_SUSPEND);
-
 	return 0;
 }
 
Signature · 1 line
1.8.1.4