All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/10] xc5000: add support to return RF strength
@ 2016-06-29 22:43 Mauro Carvalho Chehab
  2016-06-29 22:43 ` [PATCH 02/10] au8522: use the RF strentgh provided by the tuner Mauro Carvalho Chehab
                   ` (8 more replies)
  0 siblings, 9 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2016-06-29 22:43 UTC (permalink / raw)
  To: Linux Media Mailing List; +Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab

The xc5000 tuner is able to return the gain used to adjust the
signal level. With that, it can return an estimation of the
signal strength. So, add support for it.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/tuners/xc5000.c | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index e6e5e90d8d95..91ad392eb60c 100644
--- a/drivers/media/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -569,6 +569,26 @@ static int xc_get_totalgain(struct xc5000_priv *priv, u16 *totalgain)
 	return xc5000_readreg(priv, XREG_TOTALGAIN, totalgain);
 }
 
+static int xc5000_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
+{
+	struct xc5000_priv *priv = fe->tuner_priv;
+	int ret;
+	u16 gain = 0;
+
+	*strength = 0;
+
+	ret = xc_get_totalgain(priv, &gain);
+	if (ret < 0)
+		return ret;
+
+	*strength = 65535 - gain;
+
+	dprintk(1, "Signal strength = 0x%04x (gain = 0x%04x)\n",
+		*strength, gain);
+
+	return 0;
+}
+
 static u16 wait_for_lock(struct xc5000_priv *priv)
 {
 	u16 lock_state = 0;
@@ -706,9 +726,10 @@ static void xc_debug_dump(struct xc5000_priv *priv)
 	xc_get_analogsnr(priv,  &snr);
 	dprintk(1, "*** Unweighted analog SNR = %d dB\n", snr & 0x3f);
 
+	// With au0828, signal strength is given by (aprox) = 30-gain dBm
 	xc_get_totalgain(priv,  &totalgain);
-	dprintk(1, "*** Total gain = %d.%d dB\n", totalgain / 256,
-		(totalgain % 256) * 100 / 256);
+	dprintk(1, "*** Total gain = %d.%d dB (0x%04x)\n", totalgain / 256,
+		(totalgain % 256) * 100 / 256, totalgain);
 
 	if (priv->pll_register_no) {
 		xc5000_readreg(priv, priv->pll_register_no, &regval);
@@ -1390,7 +1411,8 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = {
 	.get_frequency	   = xc5000_get_frequency,
 	.get_if_frequency  = xc5000_get_if_frequency,
 	.get_bandwidth	   = xc5000_get_bandwidth,
-	.get_status	   = xc5000_get_status
+	.get_status	   = xc5000_get_status,
+	.get_rf_strength   = xc5000_get_rf_strength
 };
 
 struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 02/10] au8522: use the RF strentgh provided by the tuner
  2016-06-29 22:43 [PATCH 01/10] xc5000: add support to return RF strength Mauro Carvalho Chehab
@ 2016-06-29 22:43 ` Mauro Carvalho Chehab
  2016-06-29 22:43 ` [PATCH 03/10] au8522: add support for dvbv5 statistics API Mauro Carvalho Chehab
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2016-06-29 22:43 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, David S. Miller,
	Daniel Vetter, Michael Ira Krufky, Laurent Pinchart

The usage of SNR to estimate the signal strength is a poor man's
approach. The best is to use the RF strength as measured by the
tuner. So, use it, if available.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/dvb-frontends/au8522_dig.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c
index e676b9461a59..ee14fd48c414 100644
--- a/drivers/media/dvb-frontends/au8522_dig.c
+++ b/drivers/media/dvb-frontends/au8522_dig.c
@@ -767,16 +767,30 @@ static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
 static int au8522_read_signal_strength(struct dvb_frontend *fe,
 				       u16 *signal_strength)
 {
-	/* borrowed from lgdt330x.c
+	u16 snr;
+	u32 tmp;
+	int ret;
+
+	/* If the tuner has RF strength, use it */
+	if (fe->ops.tuner_ops.get_rf_strength) {
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 1);
+		ret = fe->ops.tuner_ops.get_rf_strength(fe, signal_strength);
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+		return ret;
+	}
+
+	/*
+	 * If it doen't, estimate from SNR
+	 * (borrowed from lgdt330x.c)
 	 *
 	 * Calculate strength from SNR up to 35dB
 	 * Even though the SNR can go higher than 35dB,
 	 * there is some comfort factor in having a range of
 	 * strong signals that can show at 100%
 	 */
-	u16 snr;
-	u32 tmp;
-	int ret = au8522_read_snr(fe, &snr);
+	ret = au8522_read_snr(fe, &snr);
 
 	*signal_strength = 0;
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 03/10] au8522: add support for dvbv5 statistics API
  2016-06-29 22:43 [PATCH 01/10] xc5000: add support to return RF strength Mauro Carvalho Chehab
  2016-06-29 22:43 ` [PATCH 02/10] au8522: use the RF strentgh provided by the tuner Mauro Carvalho Chehab
@ 2016-06-29 22:43 ` Mauro Carvalho Chehab
  2016-06-29 22:43 ` [PATCH 04/10] au8522: reorder functions to avoid a forward declaration Mauro Carvalho Chehab
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2016-06-29 22:43 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, David S. Miller,
	Michael Ira Krufky, Daniel Vetter, Laurent Pinchart, Shuah Khan,
	Rafael Lourenço de Lima Chehab

It is possible to provide both SNR and signal strength in
dB. Let's convert it to use the DVBv5 API and start showing
the SNR in dB.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/dvb-frontends/au8522_dig.c  | 142 ++++++++++++++++++++++--------
 drivers/media/dvb-frontends/au8522_priv.h |   5 ++
 2 files changed, 108 insertions(+), 39 deletions(-)

diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c
index ee14fd48c414..8a0764f605b0 100644
--- a/drivers/media/dvb-frontends/au8522_dig.c
+++ b/drivers/media/dvb-frontends/au8522_dig.c
@@ -641,9 +641,17 @@ static int au8522_set_frontend(struct dvb_frontend *fe)
 
 	state->current_frequency = c->frequency;
 
+	/* Reset DVBv5 stats */
+	c->strength.stat[0].scale = FE_SCALE_RELATIVE;
+	c->strength.stat[0].uvalue = 0;
+	c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
 	return 0;
 }
 
+static void au8522_get_stats(struct dvb_frontend *fe, enum fe_status status);
+
 static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status)
 {
 	struct au8522_state *state = fe->demodulator_priv;
@@ -699,6 +707,8 @@ static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status)
 
 	dprintk("%s() status 0x%08x\n", __func__, *status);
 
+	au8522_get_stats(fe, *status);
+
 	return 0;
 }
 
@@ -764,70 +774,108 @@ static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
 	return ret;
 }
 
-static int au8522_read_signal_strength(struct dvb_frontend *fe,
-				       u16 *signal_strength)
+static void au8522_get_stats(struct dvb_frontend *fe, enum fe_status status)
 {
-	u16 snr;
-	u32 tmp;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	struct au8522_state *state = fe->demodulator_priv;
 	int ret;
 
-	/* If the tuner has RF strength, use it */
+	/* Get S/N ratio */
+	if (status & FE_HAS_LOCK) {
+		ret = au8522_read_snr(fe, &state->snr);
+		if (ret < 0) {
+			state->snr = 0;
+			c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+		} else {
+			c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+			c->cnr.stat[0].svalue = state->snr * 100;
+		}
+	} else {
+		state->snr = 0;
+		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	}
+
+	/* Get (or estimate) RF strength */
 	if (fe->ops.tuner_ops.get_rf_strength) {
+		/* If the tuner has RF strength, use it */
+
 		if (fe->ops.i2c_gate_ctrl)
 			fe->ops.i2c_gate_ctrl(fe, 1);
-		ret = fe->ops.tuner_ops.get_rf_strength(fe, signal_strength);
+		ret = fe->ops.tuner_ops.get_rf_strength(fe, &state->strength);
 		if (fe->ops.i2c_gate_ctrl)
 			fe->ops.i2c_gate_ctrl(fe, 0);
-		return ret;
-	}
-
-	/*
-	 * If it doen't, estimate from SNR
-	 * (borrowed from lgdt330x.c)
-	 *
-	 * Calculate strength from SNR up to 35dB
-	 * Even though the SNR can go higher than 35dB,
-	 * there is some comfort factor in having a range of
-	 * strong signals that can show at 100%
-	 */
-	ret = au8522_read_snr(fe, &snr);
-
-	*signal_strength = 0;
-
-	if (0 == ret) {
-		/* The following calculation method was chosen
+		if (ret < 0)
+			state->strength = 0;
+	} else {
+		u32 tmp;
+		/*
+		 * If it doen't, estimate from SNR
+		 * (borrowed from lgdt330x.c)
+		 *
+		 * Calculate strength from SNR up to 35dB
+		 * Even though the SNR can go higher than 35dB,
+		 * there is some comfort factor in having a range of
+		 * strong signals that can show at 100%
+		 *
+		 * The following calculation method was chosen
 		 * purely for the sake of code re-use from the
-		 * other demod drivers that use this method */
+		 * other demod drivers that use this method
+		 */
 
 		/* Convert from SNR in dB * 10 to 8.24 fixed-point */
-		tmp = (snr * ((1 << 24) / 10));
+		tmp = (state->snr * ((1 << 24) / 10));
 
 		/* Convert from 8.24 fixed-point to
-		 * scale the range 0 - 35*2^24 into 0 - 65535*/
+		* scale the range 0 - 35*2^24 into 0 - 65535*/
 		if (tmp >= 8960 * 0x10000)
-			*signal_strength = 0xffff;
+			state->strength = 0xffff;
 		else
-			*signal_strength = tmp / 8960;
+			state->strength = tmp / 8960;
 	}
+	c->strength.stat[0].scale = FE_SCALE_RELATIVE;
+	c->strength.stat[0].uvalue = state->strength;
 
-	return ret;
-}
-
-static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-	struct au8522_state *state = fe->demodulator_priv;
+	/* Read UCB blocks */
+	if (!(status & FE_HAS_LOCK)) {
+		c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+		return;
+	}
 
 	if (state->current_modulation == VSB_8)
-		*ucblocks = au8522_readreg(state, 0x4087);
+		state->ucblocks = au8522_readreg(state, 0x4087);
 	else
-		*ucblocks = au8522_readreg(state, 0x4543);
+		state->ucblocks = au8522_readreg(state, 0x4543);
+
+	c->block_error.stat[0].scale = FE_SCALE_COUNTER;
+	c->block_error.stat[0].uvalue = state->ucblocks;
+}
+static int au8522_read_signal_strength(struct dvb_frontend *fe,
+				       u16 *signal_strength)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+
+	*signal_strength = state->strength;
+
+	return 0;
+}
+
+static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+
+	*ucblocks = state->ucblocks;
 
 	return 0;
 }
 
 static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber)
 {
-	return au8522_read_ucblocks(fe, ber);
+	struct au8522_state *state = fe->demodulator_priv;
+
+	/* FIXME: This is so wrong! */
+	*ber = state->ucblocks;
+
+	return 0;
 }
 
 static int au8522_get_frontend(struct dvb_frontend *fe,
@@ -908,6 +956,22 @@ error:
 }
 EXPORT_SYMBOL(au8522_attach);
 
+static int au8522_dvb_init(struct dvb_frontend *fe)
+{
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+	/* Initialize DVBv5 statistics */
+	c->strength.stat[0].scale = FE_SCALE_RELATIVE;
+	c->strength.stat[0].uvalue = 0;
+	c->strength.len = 1;
+	c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	c->cnr.len = 1;
+	c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	c->block_error.len = 1;
+
+	return au8522_init(fe);
+}
+
 static struct dvb_frontend_ops au8522_ops = {
 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
 	.info = {
@@ -918,7 +982,7 @@ static struct dvb_frontend_ops au8522_ops = {
 		.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
 	},
 
-	.init                 = au8522_init,
+	.init                 = au8522_dvb_init,
 	.sleep                = au8522_sleep,
 	.i2c_gate_ctrl        = au8522_i2c_gate_ctrl,
 	.set_frontend         = au8522_set_frontend,
diff --git a/drivers/media/dvb-frontends/au8522_priv.h b/drivers/media/dvb-frontends/au8522_priv.h
index f5a9438f6ce5..7b4f74997128 100644
--- a/drivers/media/dvb-frontends/au8522_priv.h
+++ b/drivers/media/dvb-frontends/au8522_priv.h
@@ -70,6 +70,11 @@ struct au8522_state {
 	u32 rev;
 	struct v4l2_ctrl_handler hdl;
 
+	/* Statistics */
+	u16 strength;
+	u16 snr;
+	u32 ucblocks;
+
 #ifdef CONFIG_MEDIA_CONTROLLER
 	struct media_pad pads[DEMOD_NUM_PADS];
 #endif
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 04/10] au8522: reorder functions to avoid a forward declaration
  2016-06-29 22:43 [PATCH 01/10] xc5000: add support to return RF strength Mauro Carvalho Chehab
  2016-06-29 22:43 ` [PATCH 02/10] au8522: use the RF strentgh provided by the tuner Mauro Carvalho Chehab
  2016-06-29 22:43 ` [PATCH 03/10] au8522: add support for dvbv5 statistics API Mauro Carvalho Chehab
@ 2016-06-29 22:43 ` Mauro Carvalho Chehab
  2016-06-29 22:43 ` [PATCH 05/10] au8522: remove au8522_read_ber() ops Mauro Carvalho Chehab
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2016-06-29 22:43 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, David S. Miller,
	Michael Ira Krufky, Laurent Pinchart, Jiri Kosina

Move au8522_read_status() to be after au8522_get_stats(), in
order to avoid the need of a forward declaration.

No functional changes.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/dvb-frontends/au8522_dig.c | 122 +++++++++++++++----------------
 1 file changed, 60 insertions(+), 62 deletions(-)

diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c
index 8a0764f605b0..aebee53903cc 100644
--- a/drivers/media/dvb-frontends/au8522_dig.c
+++ b/drivers/media/dvb-frontends/au8522_dig.c
@@ -650,68 +650,6 @@ static int au8522_set_frontend(struct dvb_frontend *fe)
 	return 0;
 }
 
-static void au8522_get_stats(struct dvb_frontend *fe, enum fe_status status);
-
-static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status)
-{
-	struct au8522_state *state = fe->demodulator_priv;
-	u8 reg;
-	u32 tuner_status = 0;
-
-	*status = 0;
-
-	if (state->current_modulation == VSB_8) {
-		dprintk("%s() Checking VSB_8\n", __func__);
-		reg = au8522_readreg(state, 0x4088);
-		if ((reg & 0x03) == 0x03)
-			*status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
-	} else {
-		dprintk("%s() Checking QAM\n", __func__);
-		reg = au8522_readreg(state, 0x4541);
-		if (reg & 0x80)
-			*status |= FE_HAS_VITERBI;
-		if (reg & 0x20)
-			*status |= FE_HAS_LOCK | FE_HAS_SYNC;
-	}
-
-	switch (state->config.status_mode) {
-	case AU8522_DEMODLOCKING:
-		dprintk("%s() DEMODLOCKING\n", __func__);
-		if (*status & FE_HAS_VITERBI)
-			*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
-		break;
-	case AU8522_TUNERLOCKING:
-		/* Get the tuner status */
-		dprintk("%s() TUNERLOCKING\n", __func__);
-		if (fe->ops.tuner_ops.get_status) {
-			if (fe->ops.i2c_gate_ctrl)
-				fe->ops.i2c_gate_ctrl(fe, 1);
-
-			fe->ops.tuner_ops.get_status(fe, &tuner_status);
-
-			if (fe->ops.i2c_gate_ctrl)
-				fe->ops.i2c_gate_ctrl(fe, 0);
-		}
-		if (tuner_status)
-			*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
-		break;
-	}
-	state->fe_status = *status;
-
-	if (*status & FE_HAS_LOCK)
-		/* turn on LED, if it isn't on already */
-		au8522_led_ctrl(state, -1);
-	else
-		/* turn off LED */
-		au8522_led_ctrl(state, 0);
-
-	dprintk("%s() status 0x%08x\n", __func__, *status);
-
-	au8522_get_stats(fe, *status);
-
-	return 0;
-}
-
 static int au8522_led_status(struct au8522_state *state, const u16 *snr)
 {
 	struct au8522_led_config *led_config = state->config.led_cfg;
@@ -859,6 +797,66 @@ static int au8522_read_signal_strength(struct dvb_frontend *fe,
 	return 0;
 }
 
+static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+	u8 reg;
+	u32 tuner_status = 0;
+
+	*status = 0;
+
+	if (state->current_modulation == VSB_8) {
+		dprintk("%s() Checking VSB_8\n", __func__);
+		reg = au8522_readreg(state, 0x4088);
+		if ((reg & 0x03) == 0x03)
+			*status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
+	} else {
+		dprintk("%s() Checking QAM\n", __func__);
+		reg = au8522_readreg(state, 0x4541);
+		if (reg & 0x80)
+			*status |= FE_HAS_VITERBI;
+		if (reg & 0x20)
+			*status |= FE_HAS_LOCK | FE_HAS_SYNC;
+	}
+
+	switch (state->config.status_mode) {
+	case AU8522_DEMODLOCKING:
+		dprintk("%s() DEMODLOCKING\n", __func__);
+		if (*status & FE_HAS_VITERBI)
+			*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+		break;
+	case AU8522_TUNERLOCKING:
+		/* Get the tuner status */
+		dprintk("%s() TUNERLOCKING\n", __func__);
+		if (fe->ops.tuner_ops.get_status) {
+			if (fe->ops.i2c_gate_ctrl)
+				fe->ops.i2c_gate_ctrl(fe, 1);
+
+			fe->ops.tuner_ops.get_status(fe, &tuner_status);
+
+			if (fe->ops.i2c_gate_ctrl)
+				fe->ops.i2c_gate_ctrl(fe, 0);
+		}
+		if (tuner_status)
+			*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+		break;
+	}
+	state->fe_status = *status;
+
+	if (*status & FE_HAS_LOCK)
+		/* turn on LED, if it isn't on already */
+		au8522_led_ctrl(state, -1);
+	else
+		/* turn off LED */
+		au8522_led_ctrl(state, 0);
+
+	dprintk("%s() status 0x%08x\n", __func__, *status);
+
+	au8522_get_stats(fe, *status);
+
+	return 0;
+}
+
 static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 {
 	struct au8522_state *state = fe->demodulator_priv;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 05/10] au8522: remove au8522_read_ber() ops
  2016-06-29 22:43 [PATCH 01/10] xc5000: add support to return RF strength Mauro Carvalho Chehab
                   ` (2 preceding siblings ...)
  2016-06-29 22:43 ` [PATCH 04/10] au8522: reorder functions to avoid a forward declaration Mauro Carvalho Chehab
@ 2016-06-29 22:43 ` Mauro Carvalho Chehab
  2016-06-29 22:43 ` [PATCH 06/10] au8522: show signal strength in dBm, for devices with xc5000 Mauro Carvalho Chehab
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2016-06-29 22:43 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, Michael Ira Krufky,
	David S. Miller, Daniel Vetter, Jiri Kosina, Laurent Pinchart

There's no code on au8522 to get the bit error rate.
Remove the fake function that were returning the number of
uncorrected error blocks as if they were ber.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/dvb-frontends/au8522_dig.c | 30 ++++++++++--------------------
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c
index aebee53903cc..22d837494cc7 100644
--- a/drivers/media/dvb-frontends/au8522_dig.c
+++ b/drivers/media/dvb-frontends/au8522_dig.c
@@ -787,15 +787,6 @@ static void au8522_get_stats(struct dvb_frontend *fe, enum fe_status status)
 	c->block_error.stat[0].scale = FE_SCALE_COUNTER;
 	c->block_error.stat[0].uvalue = state->ucblocks;
 }
-static int au8522_read_signal_strength(struct dvb_frontend *fe,
-				       u16 *signal_strength)
-{
-	struct au8522_state *state = fe->demodulator_priv;
-
-	*signal_strength = state->strength;
-
-	return 0;
-}
 
 static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status)
 {
@@ -857,6 +848,16 @@ static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status)
 	return 0;
 }
 
+static int au8522_read_signal_strength(struct dvb_frontend *fe,
+				       u16 *signal_strength)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+
+	*signal_strength = state->strength;
+
+	return 0;
+}
+
 static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 {
 	struct au8522_state *state = fe->demodulator_priv;
@@ -866,16 +867,6 @@ static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 	return 0;
 }
 
-static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-	struct au8522_state *state = fe->demodulator_priv;
-
-	/* FIXME: This is so wrong! */
-	*ber = state->ucblocks;
-
-	return 0;
-}
-
 static int au8522_get_frontend(struct dvb_frontend *fe,
 			       struct dtv_frontend_properties *c)
 {
@@ -987,7 +978,6 @@ static struct dvb_frontend_ops au8522_ops = {
 	.get_frontend         = au8522_get_frontend,
 	.get_tune_settings    = au8522_get_tune_settings,
 	.read_status          = au8522_read_status,
-	.read_ber             = au8522_read_ber,
 	.read_signal_strength = au8522_read_signal_strength,
 	.read_snr             = au8522_read_snr,
 	.read_ucblocks        = au8522_read_ucblocks,
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 06/10] au8522: show signal strength in dBm, for devices with xc5000
  2016-06-29 22:43 [PATCH 01/10] xc5000: add support to return RF strength Mauro Carvalho Chehab
                   ` (3 preceding siblings ...)
  2016-06-29 22:43 ` [PATCH 05/10] au8522: remove au8522_read_ber() ops Mauro Carvalho Chehab
@ 2016-06-29 22:43 ` Mauro Carvalho Chehab
  2016-06-29 22:43 ` [PATCH 07/10] lgdt3306a: Expose SNR via dvbv5 stats Mauro Carvalho Chehab
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2016-06-29 22:43 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, Michael Ira Krufky,
	David S. Miller, Daniel Vetter, Jiri Kosina, Laurent Pinchart

Devices with xc5000 provide the signal strength value in dBm.
So, provide it with the proper scale to userspace.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/dvb-frontends/au8522_dig.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c
index 22d837494cc7..518040228064 100644
--- a/drivers/media/dvb-frontends/au8522_dig.c
+++ b/drivers/media/dvb-frontends/au8522_dig.c
@@ -744,6 +744,15 @@ static void au8522_get_stats(struct dvb_frontend *fe, enum fe_status status)
 			fe->ops.i2c_gate_ctrl(fe, 0);
 		if (ret < 0)
 			state->strength = 0;
+
+		/*
+		 * FIXME: As this frontend is used only with au0828, and,
+		 * currently, the tuner is eiter xc5000 or tda18271, and
+		 * only the first implements get_rf_strength(), we'll assume
+		 * that the strength will be returned in dB.
+		 */
+		c->strength.stat[0].svalue = 35000 - 1000 * (65535 - state->strength) / 256;
+		c->strength.stat[0].scale = FE_SCALE_DECIBEL;
 	} else {
 		u32 tmp;
 		/*
@@ -769,9 +778,9 @@ static void au8522_get_stats(struct dvb_frontend *fe, enum fe_status status)
 			state->strength = 0xffff;
 		else
 			state->strength = tmp / 8960;
+		c->strength.stat[0].uvalue = state->strength;
+		c->strength.stat[0].scale = FE_SCALE_RELATIVE;
 	}
-	c->strength.stat[0].scale = FE_SCALE_RELATIVE;
-	c->strength.stat[0].uvalue = state->strength;
 
 	/* Read UCB blocks */
 	if (!(status & FE_HAS_LOCK)) {
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 07/10] lgdt3306a: Expose SNR via dvbv5 stats
  2016-06-29 22:43 [PATCH 01/10] xc5000: add support to return RF strength Mauro Carvalho Chehab
                   ` (4 preceding siblings ...)
  2016-06-29 22:43 ` [PATCH 06/10] au8522: show signal strength in dBm, for devices with xc5000 Mauro Carvalho Chehab
@ 2016-06-29 22:43 ` Mauro Carvalho Chehab
  2016-06-29 22:43 ` [PATCH 08/10] dvb_frontend: create a new ops to help returning signals in dB Mauro Carvalho Chehab
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2016-06-29 22:43 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, Michael Ira Krufky

Add support for dvbv5 stats to expose the S/N ratio in
decibels.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/dvb-frontends/lgdt3306a.c | 36 +++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c
index 179c26e5eb4e..6b686c3a44ce 100644
--- a/drivers/media/dvb-frontends/lgdt3306a.c
+++ b/drivers/media/dvb-frontends/lgdt3306a.c
@@ -811,6 +811,7 @@ static int lgdt3306a_fe_sleep(struct dvb_frontend *fe)
 static int lgdt3306a_init(struct dvb_frontend *fe)
 {
 	struct lgdt3306a_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 	u8 val;
 	int ret;
 
@@ -962,6 +963,13 @@ static int lgdt3306a_init(struct dvb_frontend *fe)
 	ret = lgdt3306a_sleep(state);
 	lg_chkerr(ret);
 
+	/* Initialize DVBv5 statistics */
+	p->strength.stat[0].scale = FE_SCALE_RELATIVE;
+	p->strength.stat[0].uvalue = 0;
+	p->strength.len = 1;
+	p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	p->cnr.len = 1;
+
 fail:
 	return ret;
 }
@@ -1032,6 +1040,11 @@ static int lgdt3306a_set_parameters(struct dvb_frontend *fe)
 	if (lg_chkerr(ret))
 		goto fail;
 
+	/* Reset DVBv5 stats */
+	p->strength.stat[0].scale = FE_SCALE_RELATIVE;
+	p->strength.stat[0].uvalue = 0;
+	p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
 #ifdef DBG_DUMP
 	lgdt3306a_DumpAllRegs(state);
 #endif
@@ -1497,6 +1510,8 @@ static u32 lgdt3306a_calculate_snr_x100(struct lgdt3306a_state *state)
 	snr_x100 = log10_x1000((pwr * 10000) / mse) - 3000;
 	dbg_info("mse=%u, pwr=%u, snr_x100=%d\n", mse, pwr, snr_x100);
 
+	state->snr = snr_x100;
+
 	return snr_x100;
 }
 
@@ -1558,6 +1573,18 @@ lgdt3306a_qam_lock_poll(struct lgdt3306a_state *state)
 	return LG3306_UNLOCK;
 }
 
+static void lgdt3306a_get_stats(struct dvb_frontend *fe, enum fe_status status)
+{
+	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+	struct lgdt3306a_state *state = fe->demodulator_priv;
+
+	if (!(status & FE_HAS_LOCK))
+		return;
+
+	p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+	p->cnr.stat[0].svalue = state->snr * 10;
+}
+
 static int lgdt3306a_read_status(struct dvb_frontend *fe,
 				 enum fe_status *status)
 {
@@ -1599,9 +1626,16 @@ static int lgdt3306a_read_status(struct dvb_frontend *fe,
 			}
 			break;
 		default:
+			state->snr = 0;
 			ret = -EINVAL;
 		}
+	} else {
+		state->snr = 0;
 	}
+
+
+	lgdt3306a_get_stats(fe, *status);
+
 	return ret;
 }
 
@@ -1610,8 +1644,6 @@ static int lgdt3306a_read_snr(struct dvb_frontend *fe, u16 *snr)
 {
 	struct lgdt3306a_state *state = fe->demodulator_priv;
 
-	state->snr = lgdt3306a_calculate_snr_x100(state);
-	/* report SNR in dB * 10 */
 	*snr = state->snr/10;
 
 	return 0;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 08/10] dvb_frontend: create a new ops to help returning signals in dB
  2016-06-29 22:43 [PATCH 01/10] xc5000: add support to return RF strength Mauro Carvalho Chehab
                   ` (5 preceding siblings ...)
  2016-06-29 22:43 ` [PATCH 07/10] lgdt3306a: Expose SNR via dvbv5 stats Mauro Carvalho Chehab
@ 2016-06-29 22:43 ` Mauro Carvalho Chehab
  2016-06-30 13:48   ` Steven Toth
  2016-06-29 22:43 ` [PATCH 09/10] au8522/xc5000: use the new get_rf_attenuation() ops Mauro Carvalho Chehab
  2016-06-29 22:43 ` [PATCH 10/10] lgdt3306a: better handle RF fake strength Mauro Carvalho Chehab
  8 siblings, 1 reply; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2016-06-29 22:43 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, Jonathan Corbet,
	Michael Ira Krufky

add a new ops that will allow tuners to better report the
dB level of its AGC logic to the demod drivers. As the maximum
gain may vary from tuner to tuner, we'll be reversing the
logic here: instead of reporting the gain, let's report the
attenuation. This way, converting from it to the legacy DVBv3
way is trivial. It is also easy to adjust the level of
the received signal to dBm, as it is just a matter of adding
an offset at the demod and/or at the bridge driver.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/dvb-core/dvb_frontend.h | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index 9592573a0b41..e8a4d341f420 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -227,8 +227,17 @@ enum dvbfe_search {
  * 			should return 0.
  * @get_status:		returns the frontend lock status
  * @get_rf_strength:	returns the RF signal strengh. Used mostly to support
- *			analog TV and radio. Digital TV should report, instead,
- *			via DVBv5 API (@dvb_frontend.dtv_property_cache;).
+ *			analog TV and radio. This is deprecated, in favor of
+ *			@get_rf_attenuation.
+ * @get_rf_attenuation:	returns the RF signal attenuation, relative to the
+ *			maximum supported gain, in 1/1000 dB steps. Please
+ *			notice that 0 means that the tuner is using its maximum
+ *			gain. So, a value of 10000, for example, means a 10dB
+ *			attenuation. This is ops is meant to be used by
+ *			demodulator drivers to estimate the maximum signal
+ *			strength. For that, it will add an offset, in order to
+ *			expose the signal strength to userspace via dvbv5
+ *			stats, in dBm.
  * @get_afc:		Used only by analog TV core. Reports the frequency
  *			drift due to AFC.
  * @calc_regs:		callback function used to pass register data settings
@@ -264,6 +273,7 @@ struct dvb_tuner_ops {
 #define TUNER_STATUS_STEREO 2
 	int (*get_status)(struct dvb_frontend *fe, u32 *status);
 	int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength);
+	s32 (*get_rf_attenuation)(struct dvb_frontend *fe);
 	int (*get_afc)(struct dvb_frontend *fe, s32 *afc);
 
 	/*
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 09/10] au8522/xc5000: use the new get_rf_attenuation() ops
  2016-06-29 22:43 [PATCH 01/10] xc5000: add support to return RF strength Mauro Carvalho Chehab
                   ` (6 preceding siblings ...)
  2016-06-29 22:43 ` [PATCH 08/10] dvb_frontend: create a new ops to help returning signals in dB Mauro Carvalho Chehab
@ 2016-06-29 22:43 ` Mauro Carvalho Chehab
  2016-06-29 22:43 ` [PATCH 10/10] lgdt3306a: better handle RF fake strength Mauro Carvalho Chehab
  8 siblings, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2016-06-29 22:43 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, Daniel Vetter,
	Michael Ira Krufky, Laurent Pinchart, David S. Miller

Switch to the new get_rf_attenuation(), in order to remove
some hacks at au8522.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/dvb-frontends/au8522_dig.c | 26 +++++++++++---------
 drivers/media/tuners/xc5000.c            | 42 ++++++++++++++------------------
 2 files changed, 32 insertions(+), 36 deletions(-)

diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c
index 518040228064..46887cc2225b 100644
--- a/drivers/media/dvb-frontends/au8522_dig.c
+++ b/drivers/media/dvb-frontends/au8522_dig.c
@@ -734,27 +734,29 @@ static void au8522_get_stats(struct dvb_frontend *fe, enum fe_status status)
 	}
 
 	/* Get (or estimate) RF strength */
-	if (fe->ops.tuner_ops.get_rf_strength) {
+	if (fe->ops.tuner_ops.get_rf_attenuation) {
+		s32 strength;
+
 		/* If the tuner has RF strength, use it */
-
 		if (fe->ops.i2c_gate_ctrl)
 			fe->ops.i2c_gate_ctrl(fe, 1);
-		ret = fe->ops.tuner_ops.get_rf_strength(fe, &state->strength);
+		strength = fe->ops.tuner_ops.get_rf_attenuation(fe);
 		if (fe->ops.i2c_gate_ctrl)
 			fe->ops.i2c_gate_ctrl(fe, 0);
-		if (ret < 0)
-			state->strength = 0;
 
-		/*
-		 * FIXME: As this frontend is used only with au0828, and,
-		 * currently, the tuner is eiter xc5000 or tda18271, and
-		 * only the first implements get_rf_strength(), we'll assume
-		 * that the strength will be returned in dB.
-		 */
-		c->strength.stat[0].svalue = 35000 - 1000 * (65535 - state->strength) / 256;
 		c->strength.stat[0].scale = FE_SCALE_DECIBEL;
+		c->strength.stat[0].svalue = 35000 - strength;
+
+		dprintk("Signal strength = %d.%02d dBm\n",
+	                strength / 1000, (strength % 1000) / 10);
+
+
+		/* For DVBv3 legacy support, adjust scale */
+		strength = 65535 - strength;
+		state->strength = (strength < 0) ? 0 : strength;
 	} else {
 		u32 tmp;
+
 		/*
 		 * If it doen't, estimate from SNR
 		 * (borrowed from lgdt330x.c)
diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index 91ad392eb60c..1eb57150b1f6 100644
--- a/drivers/media/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -569,24 +569,18 @@ static int xc_get_totalgain(struct xc5000_priv *priv, u16 *totalgain)
 	return xc5000_readreg(priv, XREG_TOTALGAIN, totalgain);
 }
 
-static int xc5000_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
+static s32 xc5000_get_rf_attenuation(struct dvb_frontend *fe)
 {
 	struct xc5000_priv *priv = fe->tuner_priv;
 	int ret;
-	u16 gain = 0;
-
-	*strength = 0;
+	u16 gain = 65535;
 
 	ret = xc_get_totalgain(priv, &gain);
 	if (ret < 0)
-		return ret;
+		return 256000;
 
-	*strength = 65535 - gain;
-
-	dprintk(1, "Signal strength = 0x%04x (gain = 0x%04x)\n",
-		*strength, gain);
-
-	return 0;
+	/* In theory, it will range from 256 dB to 0 dB */
+	return (1000 * gain) / 256;
 }
 
 static u16 wait_for_lock(struct xc5000_priv *priv)
@@ -1399,20 +1393,20 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = {
 		.frequency_step =      50000,
 	},
 
-	.release	   = xc5000_release,
-	.init		   = xc5000_init,
-	.sleep		   = xc5000_sleep,
-	.suspend	   = xc5000_suspend,
-	.resume		   = xc5000_resume,
+	.release	    = xc5000_release,
+	.init		    = xc5000_init,
+	.sleep		    = xc5000_sleep,
+	.suspend	    = xc5000_suspend,
+	.resume		    = xc5000_resume,
 
-	.set_config	   = xc5000_set_config,
-	.set_params	   = xc5000_set_digital_params,
-	.set_analog_params = xc5000_set_analog_params,
-	.get_frequency	   = xc5000_get_frequency,
-	.get_if_frequency  = xc5000_get_if_frequency,
-	.get_bandwidth	   = xc5000_get_bandwidth,
-	.get_status	   = xc5000_get_status,
-	.get_rf_strength   = xc5000_get_rf_strength
+	.set_config	    = xc5000_set_config,
+	.set_params	    = xc5000_set_digital_params,
+	.set_analog_params  = xc5000_set_analog_params,
+	.get_frequency	    = xc5000_get_frequency,
+	.get_if_frequency   = xc5000_get_if_frequency,
+	.get_bandwidth	    = xc5000_get_bandwidth,
+	.get_status	    = xc5000_get_status,
+	.get_rf_attenuation = xc5000_get_rf_attenuation,
 };
 
 struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 10/10] lgdt3306a: better handle RF fake strength
  2016-06-29 22:43 [PATCH 01/10] xc5000: add support to return RF strength Mauro Carvalho Chehab
                   ` (7 preceding siblings ...)
  2016-06-29 22:43 ` [PATCH 09/10] au8522/xc5000: use the new get_rf_attenuation() ops Mauro Carvalho Chehab
@ 2016-06-29 22:43 ` Mauro Carvalho Chehab
  8 siblings, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2016-06-29 22:43 UTC (permalink / raw)
  To: Linux Media Mailing List
  Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, Michael Ira Krufky

There's a logic at lgdt3306a with emulates the signal strength
via SNR measures. Such logic should be used for dvbv5 stats
as well, so change the code to provide a more coherent
data to userspace.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/dvb-frontends/lgdt3306a.c | 121 ++++++++++++++++++--------------
 1 file changed, 67 insertions(+), 54 deletions(-)

diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c
index 6b686c3a44ce..446dc264701a 100644
--- a/drivers/media/dvb-frontends/lgdt3306a.c
+++ b/drivers/media/dvb-frontends/lgdt3306a.c
@@ -65,6 +65,7 @@ struct lgdt3306a_state {
 	enum fe_modulation current_modulation;
 	u32 current_frequency;
 	u32 snr;
+	u16 strength;
 };
 
 /*
@@ -1573,10 +1574,74 @@ lgdt3306a_qam_lock_poll(struct lgdt3306a_state *state)
 	return LG3306_UNLOCK;
 }
 
+
+static u16 lgdt3306a_fake_strength(struct dvb_frontend *fe)
+{
+	struct lgdt3306a_state *state = fe->demodulator_priv;
+	u16 snr; /* snr_x10 */
+	int ret;
+	u32 ref_snr; /* snr*100 */
+	u32 str;
+
+	/*
+	 * Calculate some sort of "strength" from SNR
+	 */
+
+	switch (state->current_modulation) {
+	case VSB_8:
+		 ref_snr = 1600; /* 16dB */
+		 break;
+	case QAM_64:
+		 ref_snr = 2200; /* 22dB */
+		 break;
+	case QAM_256:
+		 ref_snr = 2800; /* 28dB */
+		 break;
+	default:
+		return 0;
+	}
+
+	ret = fe->ops.read_snr(fe, &snr);
+	if (lg_chkerr(ret))
+		return 0;
+
+	if (state->snr <= (ref_snr - 100))
+		str = 0;
+	else if (state->snr <= ref_snr)
+		str = (0xffff * 65) / 100; /* 65% */
+	else {
+		str = state->snr - ref_snr;
+		str /= 50;
+		str += 78; /* 78%-100% */
+		if (str > 100)
+			str = 100;
+		str = (0xffff * str) / 100;
+	}
+
+	return (u16)str;
+}
+
 static void lgdt3306a_get_stats(struct dvb_frontend *fe, enum fe_status status)
 {
 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 	struct lgdt3306a_state *state = fe->demodulator_priv;
+	int ret;
+
+	if (fe->ops.tuner_ops.get_rf_strength) {
+		state->strength = 0;
+
+		ret = fe->ops.tuner_ops.get_rf_strength(fe, &state->strength);
+		if (ret == 0)
+			dbg_info("strength=%d\n", state->strength);
+		else
+			dbg_info("fe->ops.tuner_ops.get_rf_strength() failed\n");
+
+	} else {
+		state->strength = lgdt3306a_fake_strength(fe);
+		p->cnr.stat[0].scale = FE_SCALE_RELATIVE;
+
+		dbg_info("strength=%d\n", state->strength);
+	}
 
 	if (!(status & FE_HAS_LOCK))
 		return;
@@ -1589,17 +1654,8 @@ static int lgdt3306a_read_status(struct dvb_frontend *fe,
 				 enum fe_status *status)
 {
 	struct lgdt3306a_state *state = fe->demodulator_priv;
-	u16 strength = 0;
 	int ret = 0;
 
-	if (fe->ops.tuner_ops.get_rf_strength) {
-		ret = fe->ops.tuner_ops.get_rf_strength(fe, &strength);
-		if (ret == 0)
-			dbg_info("strength=%d\n", strength);
-		else
-			dbg_info("fe->ops.tuner_ops.get_rf_strength() failed\n");
-	}
-
 	*status = 0;
 	if (lgdt3306a_neverlock_poll(state) == LG3306_NL_LOCK) {
 		*status |= FE_HAS_SIGNAL;
@@ -1633,13 +1689,11 @@ static int lgdt3306a_read_status(struct dvb_frontend *fe,
 		state->snr = 0;
 	}
 
-
 	lgdt3306a_get_stats(fe, *status);
 
 	return ret;
 }
 
-
 static int lgdt3306a_read_snr(struct dvb_frontend *fe, u16 *snr)
 {
 	struct lgdt3306a_state *state = fe->demodulator_priv;
@@ -1652,52 +1706,11 @@ static int lgdt3306a_read_snr(struct dvb_frontend *fe, u16 *snr)
 static int lgdt3306a_read_signal_strength(struct dvb_frontend *fe,
 					 u16 *strength)
 {
-	/*
-	 * Calculate some sort of "strength" from SNR
-	 */
 	struct lgdt3306a_state *state = fe->demodulator_priv;
-	u16 snr; /* snr_x10 */
-	int ret;
-	u32 ref_snr; /* snr*100 */
-	u32 str;
 
-	*strength = 0;
+	*strength = state->strength;
 
-	switch (state->current_modulation) {
-	case VSB_8:
-		 ref_snr = 1600; /* 16dB */
-		 break;
-	case QAM_64:
-		 ref_snr = 2200; /* 22dB */
-		 break;
-	case QAM_256:
-		 ref_snr = 2800; /* 28dB */
-		 break;
-	default:
-		return -EINVAL;
-	}
-
-	ret = fe->ops.read_snr(fe, &snr);
-	if (lg_chkerr(ret))
-		goto fail;
-
-	if (state->snr <= (ref_snr - 100))
-		str = 0;
-	else if (state->snr <= ref_snr)
-		str = (0xffff * 65) / 100; /* 65% */
-	else {
-		str = state->snr - ref_snr;
-		str /= 50;
-		str += 78; /* 78%-100% */
-		if (str > 100)
-			str = 100;
-		str = (0xffff * str) / 100;
-	}
-	*strength = (u16)str;
-	dbg_info("strength=%u\n", *strength);
-
-fail:
-	return ret;
+	return 0;
 }
 
 /* ------------------------------------------------------------------------ */
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 08/10] dvb_frontend: create a new ops to help returning signals in dB
  2016-06-29 22:43 ` [PATCH 08/10] dvb_frontend: create a new ops to help returning signals in dB Mauro Carvalho Chehab
@ 2016-06-30 13:48   ` Steven Toth
  2016-06-30 15:01     ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 12+ messages in thread
From: Steven Toth @ 2016-06-30 13:48 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Linux Media Mailing List, Mauro Carvalho Chehab, Jonathan Corbet,
	Michael Ira Krufky

> add a new ops that will allow tuners to better report the
> dB level of its AGC logic to the demod drivers. As the maximum
> gain may vary from tuner to tuner, we'll be reversing the
> logic here: instead of reporting the gain, let's report the
> attenuation. This way, converting from it to the legacy DVBv3
> way is trivial. It is also easy to adjust the level of
> the received signal to dBm, as it is just a matter of adding
> an offset at the demod and/or at the bridge driver.

Mauro,

Have you verified this work with a detailed spectrum analysis study?
If so then please share. For example, by measuring the I/F out of
various tuners in a mix of use cases, with and without the AGC being
driven by any downstream demodulator? Also, taking into consideration
any external LNA variance.

I'm concerned that a tuner AGC Gain is a meaningless measurement and
in practice demodulators don't actually care, and tuners don't
implement their gain reporting capabilities correctly at all.

This feels like a solution to a problem that doesn't exist.

-- 
Steven Toth - Kernel Labs
http://www.kernellabs.com
+1.646.355.8490

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 08/10] dvb_frontend: create a new ops to help returning signals in dB
  2016-06-30 13:48   ` Steven Toth
@ 2016-06-30 15:01     ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2016-06-30 15:01 UTC (permalink / raw)
  To: Steven Toth
  Cc: Linux Media Mailing List, Mauro Carvalho Chehab, Jonathan Corbet,
	Michael Ira Krufky

Hi Steven,

Em Thu, 30 Jun 2016 09:48:30 -0400
Steven Toth <stoth@kernellabs.com> escreveu:

> > add a new ops that will allow tuners to better report the
> > dB level of its AGC logic to the demod drivers. As the maximum
> > gain may vary from tuner to tuner, we'll be reversing the
> > logic here: instead of reporting the gain, let's report the
> > attenuation. This way, converting from it to the legacy DVBv3
> > way is trivial. It is also easy to adjust the level of
> > the received signal to dBm, as it is just a matter of adding
> > an offset at the demod and/or at the bridge driver.  
> 
> Mauro,
> 
> Have you verified this work with a detailed spectrum analysis study?
> If so then please share. For example, by measuring the I/F out of
> various tuners in a mix of use cases, with and without the AGC being
> driven by any downstream demodulator? Also, taking into consideration
> any external LNA variance.
> 
> I'm concerned that a tuner AGC Gain is a meaningless measurement and
> in practice demodulators don't actually care, and tuners don't
> implement their gain reporting capabilities correctly at all.
> 
> This feels like a solution to a problem that doesn't exist.

The role idea here is to provide a rough estimation about the signal
strength, and not to enter into the measurement instrument business.

I know that the actual tuner AGC gain is not precise[1]:
	- it may vary with the frequency;
	- it may vary with the component variance;
	- it may vary with modulation parameters;
	- it may vary with the temperature.

Yet, the signal strength is used on some software to detect "weak"
signals and skip such transponders. There is such code, for example
in Kaffeine since 2009:
	commit 73a5aae68ab46d761267043c9774289833b79dbc
	Author: Christoph Pfister <christophpfister@gmail.com>
	Date:   Sat Apr 25 13:41:28 2009 +0000

	    add autoscan support

+               if ((signal != 0) && (signal < 0x2000)) {
+                       // signal too weak
+                       carry = false;
+               }

The color on Kaffeine's gauge gradient bar also tries to express if
the signal level is OK or not, showing only red for weak signals,
and becoming green as the signal increases up to a certain level.

The strength is also one parameters to estimate the signal quality.
The libdvbv5 considers it, when reporting DTV_QUALITY parameter.

So, the hole idea here is *not* to provide a precise measure, but
to try to use about the same scale on the drivers, whenever
possible.

Regards,
Mauro

[1] I would give a 5-stars here for Siano: on the tests I did, the
signal strength reported by the siano devices is very precise.


Thanks,
Mauro

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2016-06-30 15:08 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-29 22:43 [PATCH 01/10] xc5000: add support to return RF strength Mauro Carvalho Chehab
2016-06-29 22:43 ` [PATCH 02/10] au8522: use the RF strentgh provided by the tuner Mauro Carvalho Chehab
2016-06-29 22:43 ` [PATCH 03/10] au8522: add support for dvbv5 statistics API Mauro Carvalho Chehab
2016-06-29 22:43 ` [PATCH 04/10] au8522: reorder functions to avoid a forward declaration Mauro Carvalho Chehab
2016-06-29 22:43 ` [PATCH 05/10] au8522: remove au8522_read_ber() ops Mauro Carvalho Chehab
2016-06-29 22:43 ` [PATCH 06/10] au8522: show signal strength in dBm, for devices with xc5000 Mauro Carvalho Chehab
2016-06-29 22:43 ` [PATCH 07/10] lgdt3306a: Expose SNR via dvbv5 stats Mauro Carvalho Chehab
2016-06-29 22:43 ` [PATCH 08/10] dvb_frontend: create a new ops to help returning signals in dB Mauro Carvalho Chehab
2016-06-30 13:48   ` Steven Toth
2016-06-30 15:01     ` Mauro Carvalho Chehab
2016-06-29 22:43 ` [PATCH 09/10] au8522/xc5000: use the new get_rf_attenuation() ops Mauro Carvalho Chehab
2016-06-29 22:43 ` [PATCH 10/10] lgdt3306a: better handle RF fake strength Mauro Carvalho Chehab

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.