Commit 4aa4fd86 authored by Antti Palosaari's avatar Antti Palosaari Committed by Mauro Carvalho Chehab

[media] cxd2820r: wrap legacy DVBv3 statistics via DVBv5 statistics

Return DVBv5 statistics via legacy DVBv3 API.
Signed-off-by: default avatarAntti Palosaari <crope@iki.fi>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 90d5d2e3
......@@ -149,114 +149,6 @@ int cxd2820r_get_frontend_c(struct dvb_frontend *fe,
return ret;
}
int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
u8 buf[3], start_ber = 0;
*ber = 0;
if (priv->ber_running) {
ret = cxd2820r_rd_regs(priv, 0x10076, buf, sizeof(buf));
if (ret)
goto error;
if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) {
*ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0];
start_ber = 1;
}
} else {
priv->ber_running = true;
start_ber = 1;
}
if (start_ber) {
/* (re)start BER */
ret = cxd2820r_wr_reg(priv, 0x10079, 0x01);
if (ret)
goto error;
}
return ret;
error:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe,
u16 *strength)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
u8 buf[2];
u16 tmp;
ret = cxd2820r_rd_regs(priv, 0x10049, buf, sizeof(buf));
if (ret)
goto error;
tmp = (buf[0] & 0x03) << 8 | buf[1];
tmp = (~tmp & 0x03ff);
if (tmp == 512)
/* ~no signal */
tmp = 0;
else if (tmp > 350)
tmp = 350;
/* scale value to 0x0000-0xffff */
*strength = tmp * 0xffff / (350-0);
return ret;
error:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
u8 tmp;
unsigned int A, B;
/* report SNR in dB * 10 */
ret = cxd2820r_rd_reg(priv, 0x10019, &tmp);
if (ret)
goto error;
if (((tmp >> 0) & 0x03) % 2) {
A = 875;
B = 650;
} else {
A = 950;
B = 760;
}
ret = cxd2820r_rd_reg(priv, 0x1004d, &tmp);
if (ret)
goto error;
#define CXD2820R_LOG2_E_24 24204406 /* log2(e) << 24 */
if (tmp)
*snr = A * (intlog2(B / tmp) >> 5) / (CXD2820R_LOG2_E_24 >> 5)
/ 10;
else
*snr = 0;
return ret;
error:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks)
{
*ucblocks = 0;
/* no way to read ? */
return 0;
}
int cxd2820r_read_status_c(struct dvb_frontend *fe, enum fe_status *status)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
......
......@@ -345,101 +345,58 @@ static int cxd2820r_get_frontend(struct dvb_frontend *fe,
static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__,
fe->dtv_property_cache.delivery_system);
switch (fe->dtv_property_cache.delivery_system) {
case SYS_DVBT:
ret = cxd2820r_read_ber_t(fe, ber);
break;
case SYS_DVBT2:
ret = cxd2820r_read_ber_t2(fe, ber);
break;
case SYS_DVBC_ANNEX_A:
ret = cxd2820r_read_ber_c(fe, ber);
break;
default:
ret = -EINVAL;
break;
}
return ret;
*ber = (priv->post_bit_error - priv->post_bit_error_prev_dvbv3);
priv->post_bit_error_prev_dvbv3 = priv->post_bit_error;
return 0;
}
static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__,
fe->dtv_property_cache.delivery_system);
switch (fe->dtv_property_cache.delivery_system) {
case SYS_DVBT:
ret = cxd2820r_read_signal_strength_t(fe, strength);
break;
case SYS_DVBT2:
ret = cxd2820r_read_signal_strength_t2(fe, strength);
break;
case SYS_DVBC_ANNEX_A:
ret = cxd2820r_read_signal_strength_c(fe, strength);
break;
default:
ret = -EINVAL;
break;
}
return ret;
if (c->strength.stat[0].scale == FE_SCALE_RELATIVE)
*strength = c->strength.stat[0].uvalue;
else
*strength = 0;
return 0;
}
static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__,
fe->dtv_property_cache.delivery_system);
switch (fe->dtv_property_cache.delivery_system) {
case SYS_DVBT:
ret = cxd2820r_read_snr_t(fe, snr);
break;
case SYS_DVBT2:
ret = cxd2820r_read_snr_t2(fe, snr);
break;
case SYS_DVBC_ANNEX_A:
ret = cxd2820r_read_snr_c(fe, snr);
break;
default:
ret = -EINVAL;
break;
}
return ret;
if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL)
*snr = div_s64(c->cnr.stat[0].svalue, 100);
else
*snr = 0;
return 0;
}
static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__,
fe->dtv_property_cache.delivery_system);
switch (fe->dtv_property_cache.delivery_system) {
case SYS_DVBT:
ret = cxd2820r_read_ucblocks_t(fe, ucblocks);
break;
case SYS_DVBT2:
ret = cxd2820r_read_ucblocks_t2(fe, ucblocks);
break;
case SYS_DVBC_ANNEX_A:
ret = cxd2820r_read_ucblocks_c(fe, ucblocks);
break;
default:
ret = -EINVAL;
break;
}
return ret;
*ucblocks = 0;
return 0;
}
static int cxd2820r_init(struct dvb_frontend *fe)
......
......@@ -41,6 +41,7 @@ struct cxd2820r_priv {
struct i2c_adapter *i2c;
struct dvb_frontend fe;
struct cxd2820r_config cfg;
u64 post_bit_error_prev_dvbv3;
u64 post_bit_error;
bool ber_running;
......@@ -87,14 +88,6 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe);
int cxd2820r_read_status_c(struct dvb_frontend *fe, enum fe_status *status);
int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber);
int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe, u16 *strength);
int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr);
int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks);
int cxd2820r_init_c(struct dvb_frontend *fe);
int cxd2820r_sleep_c(struct dvb_frontend *fe);
......@@ -111,14 +104,6 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe);
int cxd2820r_read_status_t(struct dvb_frontend *fe, enum fe_status *status);
int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber);
int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe, u16 *strength);
int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr);
int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks);
int cxd2820r_init_t(struct dvb_frontend *fe);
int cxd2820r_sleep_t(struct dvb_frontend *fe);
......@@ -135,14 +120,6 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe);
int cxd2820r_read_status_t2(struct dvb_frontend *fe, enum fe_status *status);
int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber);
int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe, u16 *strength);
int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr);
int cxd2820r_read_ucblocks_t2(struct dvb_frontend *fe, u32 *ucblocks);
int cxd2820r_init_t2(struct dvb_frontend *fe);
int cxd2820r_sleep_t2(struct dvb_frontend *fe);
......
......@@ -254,100 +254,6 @@ int cxd2820r_get_frontend_t(struct dvb_frontend *fe,
return ret;
}
int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
u8 buf[3], start_ber = 0;
*ber = 0;
if (priv->ber_running) {
ret = cxd2820r_rd_regs(priv, 0x00076, buf, sizeof(buf));
if (ret)
goto error;
if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) {
*ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0];
start_ber = 1;
}
} else {
priv->ber_running = true;
start_ber = 1;
}
if (start_ber) {
/* (re)start BER */
ret = cxd2820r_wr_reg(priv, 0x00079, 0x01);
if (ret)
goto error;
}
return ret;
error:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe,
u16 *strength)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
u8 buf[2];
u16 tmp;
ret = cxd2820r_rd_regs(priv, 0x00026, buf, sizeof(buf));
if (ret)
goto error;
tmp = (buf[0] & 0x0f) << 8 | buf[1];
tmp = ~tmp & 0x0fff;
/* scale value to 0x0000-0xffff from 0x0000-0x0fff */
*strength = tmp * 0xffff / 0x0fff;
return ret;
error:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
u8 buf[2];
u16 tmp;
/* report SNR in dB * 10 */
ret = cxd2820r_rd_regs(priv, 0x00028, buf, sizeof(buf));
if (ret)
goto error;
tmp = (buf[0] & 0x1f) << 8 | buf[1];
#define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */
if (tmp)
*snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24)
/ 100);
else
*snr = 0;
dev_dbg(&priv->i2c->dev, "%s: dBx10=%d val=%04x\n", __func__, *snr,
tmp);
return ret;
error:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks)
{
*ucblocks = 0;
/* no way to read ? */
return 0;
}
int cxd2820r_read_status_t(struct dvb_frontend *fe, enum fe_status *status)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
......
......@@ -387,93 +387,6 @@ int cxd2820r_read_status_t2(struct dvb_frontend *fe, enum fe_status *status)
return ret;
}
int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
u8 buf[4];
unsigned int errbits;
*ber = 0;
/* FIXME: correct calculation */
ret = cxd2820r_rd_regs(priv, 0x02039, buf, sizeof(buf));
if (ret)
goto error;
if ((buf[0] >> 4) & 0x01) {
errbits = (buf[0] & 0x0f) << 24 | buf[1] << 16 |
buf[2] << 8 | buf[3];
if (errbits)
*ber = errbits * 64 / 16588800;
}
return ret;
error:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe,
u16 *strength)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
u8 buf[2];
u16 tmp;
ret = cxd2820r_rd_regs(priv, 0x02026, buf, sizeof(buf));
if (ret)
goto error;
tmp = (buf[0] & 0x0f) << 8 | buf[1];
tmp = ~tmp & 0x0fff;
/* scale value to 0x0000-0xffff from 0x0000-0x0fff */
*strength = tmp * 0xffff / 0x0fff;
return ret;
error:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
u8 buf[2];
u16 tmp;
/* report SNR in dB * 10 */
ret = cxd2820r_rd_regs(priv, 0x02028, buf, sizeof(buf));
if (ret)
goto error;
tmp = (buf[0] & 0x0f) << 8 | buf[1];
#define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */
if (tmp)
*snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24)
/ 100);
else
*snr = 0;
dev_dbg(&priv->i2c->dev, "%s: dBx10=%d val=%04x\n", __func__, *snr,
tmp);
return ret;
error:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
int cxd2820r_read_ucblocks_t2(struct dvb_frontend *fe, u32 *ucblocks)
{
*ucblocks = 0;
/* no way to read ? */
return 0;
}
int cxd2820r_sleep_t2(struct dvb_frontend *fe)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment