* [PATCH 3/3] [media] cxd2841er: Reading SNR for DVB-C added
@ 2016-07-15 20:21 Abylay Ospan
2016-07-15 20:35 ` Abylay Ospan
0 siblings, 1 reply; 2+ messages in thread
From: Abylay Ospan @ 2016-07-15 20:21 UTC (permalink / raw)
To: Mauro Carvalho Chehab, linux-media; +Cc: Abylay Ospan
now driver returns correct values for DVB-C:
SNR (in dB)
Signed-off-by: Abylay Ospan <aospan@netup.ru>
---
drivers/media/dvb-frontends/cxd2841er.c | 89 ++++++++++++++++++++++++++++++---
1 file changed, 81 insertions(+), 8 deletions(-)
diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c
index 623b04f3..99baccf 100644
--- a/drivers/media/dvb-frontends/cxd2841er.c
+++ b/drivers/media/dvb-frontends/cxd2841er.c
@@ -1570,7 +1570,8 @@ static int cxd2841er_read_ber_t(struct cxd2841er_priv *priv,
return 0;
}
-static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv, u8 delsys)
+static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv,
+ u8 delsys, u32 *snr)
{
u8 data[3];
u32 res = 0, value;
@@ -1628,9 +1629,71 @@ static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv, u8 delsys)
} else {
dev_dbg(&priv->i2c->dev,
"%s(): no data available\n", __func__);
+ return -EINVAL;
}
done:
- return res;
+ *snr = res;
+ return 0;
+}
+
+uint32_t sony_log(uint32_t x)
+{
+ return (((10000>>8)*(intlog2(x)>>16) + LOG2_E_100X/2)/LOG2_E_100X);
+}
+
+static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr)
+{
+ u32 reg;
+ u8 data[2];
+ enum sony_dvbc_constellation_t qam = SONY_DVBC_CONSTELLATION_16QAM;
+
+ *snr = 0;
+ if (priv->state != STATE_ACTIVE_TC) {
+ dev_dbg(&priv->i2c->dev,
+ "%s(): invalid state %d\n",
+ __func__, priv->state);
+ return -EINVAL;
+ }
+
+ /*
+ * Freeze registers: ensure multiple separate register reads
+ * are from the same snapshot
+ */
+ cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x01);
+
+ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
+ cxd2841er_read_regs(priv, I2C_SLVT, 0x19, data, 1);
+ qam = (enum sony_dvbc_constellation_t) (data[0] & 0x07);
+ cxd2841er_read_regs(priv, I2C_SLVT, 0x4C, data, 2);
+
+ reg = ((u32)(data[0]&0x1f) << 8) | (u32)data[1];
+ if (reg == 0) {
+ dev_dbg(&priv->i2c->dev,
+ "%s(): reg value out of range\n", __func__);
+ return 0;
+ }
+
+ switch (qam) {
+ case SONY_DVBC_CONSTELLATION_16QAM:
+ case SONY_DVBC_CONSTELLATION_64QAM:
+ case SONY_DVBC_CONSTELLATION_256QAM:
+ /* SNR(dB) = -9.50 * ln(IREG_SNR_ESTIMATE / (24320)) */
+ if (reg < 126)
+ reg = 126;
+ *snr = -95 * (int32_t)sony_log(reg) + 95941;
+ break;
+ case SONY_DVBC_CONSTELLATION_32QAM:
+ case SONY_DVBC_CONSTELLATION_128QAM:
+ /* SNR(dB) = -8.75 * ln(IREG_SNR_ESTIMATE / (20800)) */
+ if (reg < 69)
+ reg = 69;
+ *snr = -88 * (int32_t)sony_log(reg) + 86999;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
}
static int cxd2841er_read_snr_t(struct cxd2841er_priv *priv, u32 *snr)
@@ -1871,23 +1934,29 @@ static void cxd2841er_read_signal_strength(struct dvb_frontend *fe)
static void cxd2841er_read_snr(struct dvb_frontend *fe)
{
u32 tmp = 0;
+ int ret = 0;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct cxd2841er_priv *priv = fe->demodulator_priv;
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
switch (p->delivery_system) {
+ case SYS_DVBC_ANNEX_A:
+ case SYS_DVBC_ANNEX_B:
+ case SYS_DVBC_ANNEX_C:
+ ret = cxd2841er_read_snr_c(priv, &tmp);
+ break;
case SYS_DVBT:
- cxd2841er_read_snr_t(priv, &tmp);
+ ret = cxd2841er_read_snr_t(priv, &tmp);
break;
case SYS_DVBT2:
- cxd2841er_read_snr_t2(priv, &tmp);
+ ret = cxd2841er_read_snr_t2(priv, &tmp);
break;
case SYS_ISDBT:
- cxd2841er_read_snr_i(priv, &tmp);
+ ret = cxd2841er_read_snr_i(priv, &tmp);
break;
case SYS_DVBS:
case SYS_DVBS2:
- tmp = cxd2841er_dvbs_read_snr(priv, p->delivery_system);
+ ret = cxd2841er_dvbs_read_snr(priv, p->delivery_system, &tmp);
break;
default:
dev_dbg(&priv->i2c->dev, "%s(): unknown delivery system %d\n",
@@ -1896,8 +1965,12 @@ static void cxd2841er_read_snr(struct dvb_frontend *fe)
return;
}
- p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
- p->cnr.stat[0].svalue = tmp;
+ if (!ret) {
+ p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+ p->cnr.stat[0].svalue = tmp;
+ } else {
+ p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ }
}
static void cxd2841er_read_ucblocks(struct dvb_frontend *fe)
--
2.7.4
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH 3/3] [media] cxd2841er: Reading SNR for DVB-C added
2016-07-15 20:21 [PATCH 3/3] [media] cxd2841er: Reading SNR for DVB-C added Abylay Ospan
@ 2016-07-15 20:35 ` Abylay Ospan
0 siblings, 0 replies; 2+ messages in thread
From: Abylay Ospan @ 2016-07-15 20:35 UTC (permalink / raw)
To: Mauro Carvalho Chehab, linux-media; +Cc: Abylay Ospan
Hi Mauro,
This is patches for cxd2841er for reading UCB, SNR and BER for DVB-C.
Please, apply this patches.
But first need to apply all of your previous patches (i'v picked it
from your emails):
commit f38faf6f4ff49b549c4b7d4ff7ae93945ed7255c
Author: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Date: Fri Jul 1 15:41:38 2016 -0300
cxd2841er: fix signal strength scale for ISDB-T
commit 731999916c317e4ec018d302e8a990b2379cb3a7
Author: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Date: Fri Jul 1 11:03:16 2016 -0300
cxd2841er: adjust the dB scale for DVB-C
commit a994179e7cca5f5fb4dbc1e26489cc644be99cef
Author: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Date: Fri Jul 1 11:03:14 2016 -0300
cxd2841er: provide signal strength for DVB-C
commit aed60dc2282486104009b6d3eb996a475a834fec
Author: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Date: Fri Jul 1 11:03:15 2016 -0300
cxd2841er: fix BER report via DVBv5 stats API
I have made repository with all required patches here:
https://github.com/aospan/media_tree
(it's based on git://linuxtv.org/media_tree.git)
Please pull all of this patches.
thanks !
2016-07-15 16:21 GMT-04:00 Abylay Ospan <aospan@netup.ru>:
> now driver returns correct values for DVB-C:
> SNR (in dB)
>
> Signed-off-by: Abylay Ospan <aospan@netup.ru>
> ---
> drivers/media/dvb-frontends/cxd2841er.c | 89 ++++++++++++++++++++++++++++++---
> 1 file changed, 81 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c
> index 623b04f3..99baccf 100644
> --- a/drivers/media/dvb-frontends/cxd2841er.c
> +++ b/drivers/media/dvb-frontends/cxd2841er.c
> @@ -1570,7 +1570,8 @@ static int cxd2841er_read_ber_t(struct cxd2841er_priv *priv,
> return 0;
> }
>
> -static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv, u8 delsys)
> +static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv,
> + u8 delsys, u32 *snr)
> {
> u8 data[3];
> u32 res = 0, value;
> @@ -1628,9 +1629,71 @@ static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv, u8 delsys)
> } else {
> dev_dbg(&priv->i2c->dev,
> "%s(): no data available\n", __func__);
> + return -EINVAL;
> }
> done:
> - return res;
> + *snr = res;
> + return 0;
> +}
> +
> +uint32_t sony_log(uint32_t x)
> +{
> + return (((10000>>8)*(intlog2(x)>>16) + LOG2_E_100X/2)/LOG2_E_100X);
> +}
> +
> +static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr)
> +{
> + u32 reg;
> + u8 data[2];
> + enum sony_dvbc_constellation_t qam = SONY_DVBC_CONSTELLATION_16QAM;
> +
> + *snr = 0;
> + if (priv->state != STATE_ACTIVE_TC) {
> + dev_dbg(&priv->i2c->dev,
> + "%s(): invalid state %d\n",
> + __func__, priv->state);
> + return -EINVAL;
> + }
> +
> + /*
> + * Freeze registers: ensure multiple separate register reads
> + * are from the same snapshot
> + */
> + cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x01);
> +
> + cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
> + cxd2841er_read_regs(priv, I2C_SLVT, 0x19, data, 1);
> + qam = (enum sony_dvbc_constellation_t) (data[0] & 0x07);
> + cxd2841er_read_regs(priv, I2C_SLVT, 0x4C, data, 2);
> +
> + reg = ((u32)(data[0]&0x1f) << 8) | (u32)data[1];
> + if (reg == 0) {
> + dev_dbg(&priv->i2c->dev,
> + "%s(): reg value out of range\n", __func__);
> + return 0;
> + }
> +
> + switch (qam) {
> + case SONY_DVBC_CONSTELLATION_16QAM:
> + case SONY_DVBC_CONSTELLATION_64QAM:
> + case SONY_DVBC_CONSTELLATION_256QAM:
> + /* SNR(dB) = -9.50 * ln(IREG_SNR_ESTIMATE / (24320)) */
> + if (reg < 126)
> + reg = 126;
> + *snr = -95 * (int32_t)sony_log(reg) + 95941;
> + break;
> + case SONY_DVBC_CONSTELLATION_32QAM:
> + case SONY_DVBC_CONSTELLATION_128QAM:
> + /* SNR(dB) = -8.75 * ln(IREG_SNR_ESTIMATE / (20800)) */
> + if (reg < 69)
> + reg = 69;
> + *snr = -88 * (int32_t)sony_log(reg) + 86999;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + return 0;
> }
>
> static int cxd2841er_read_snr_t(struct cxd2841er_priv *priv, u32 *snr)
> @@ -1871,23 +1934,29 @@ static void cxd2841er_read_signal_strength(struct dvb_frontend *fe)
> static void cxd2841er_read_snr(struct dvb_frontend *fe)
> {
> u32 tmp = 0;
> + int ret = 0;
> struct dtv_frontend_properties *p = &fe->dtv_property_cache;
> struct cxd2841er_priv *priv = fe->demodulator_priv;
>
> dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
> switch (p->delivery_system) {
> + case SYS_DVBC_ANNEX_A:
> + case SYS_DVBC_ANNEX_B:
> + case SYS_DVBC_ANNEX_C:
> + ret = cxd2841er_read_snr_c(priv, &tmp);
> + break;
> case SYS_DVBT:
> - cxd2841er_read_snr_t(priv, &tmp);
> + ret = cxd2841er_read_snr_t(priv, &tmp);
> break;
> case SYS_DVBT2:
> - cxd2841er_read_snr_t2(priv, &tmp);
> + ret = cxd2841er_read_snr_t2(priv, &tmp);
> break;
> case SYS_ISDBT:
> - cxd2841er_read_snr_i(priv, &tmp);
> + ret = cxd2841er_read_snr_i(priv, &tmp);
> break;
> case SYS_DVBS:
> case SYS_DVBS2:
> - tmp = cxd2841er_dvbs_read_snr(priv, p->delivery_system);
> + ret = cxd2841er_dvbs_read_snr(priv, p->delivery_system, &tmp);
> break;
> default:
> dev_dbg(&priv->i2c->dev, "%s(): unknown delivery system %d\n",
> @@ -1896,8 +1965,12 @@ static void cxd2841er_read_snr(struct dvb_frontend *fe)
> return;
> }
>
> - p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
> - p->cnr.stat[0].svalue = tmp;
> + if (!ret) {
> + p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
> + p->cnr.stat[0].svalue = tmp;
> + } else {
> + p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
> + }
> }
>
> static void cxd2841er_read_ucblocks(struct dvb_frontend *fe)
> --
> 2.7.4
>
--
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-07-15 20:35 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-15 20:21 [PATCH 3/3] [media] cxd2841er: Reading SNR for DVB-C added Abylay Ospan
2016-07-15 20:35 ` Abylay Ospan
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.