Commit 4a86bc10 authored by Abylay Ospan's avatar Abylay Ospan Committed by Mauro Carvalho Chehab

[media] cxd2841er: freeze/unfreeze registers when reading stats

ensure multiple separate register reads are from the same snapshot
Signed-off-by: default avatarAbylay Ospan <aospan@netup.ru>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 2ceeca04
...@@ -1570,6 +1570,25 @@ static int cxd2841er_read_ber_t(struct cxd2841er_priv *priv, ...@@ -1570,6 +1570,25 @@ static int cxd2841er_read_ber_t(struct cxd2841er_priv *priv,
return 0; return 0;
} }
static int cxd2841er_freeze_regs(struct cxd2841er_priv *priv)
{
/*
* Freeze registers: ensure multiple separate register reads
* are from the same snapshot
*/
cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x01);
return 0;
}
static int cxd2841er_unfreeze_regs(struct cxd2841er_priv *priv)
{
/*
* un-freeze registers
*/
cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x00);
return 0;
}
static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv, static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv,
u8 delsys, u32 *snr) u8 delsys, u32 *snr)
{ {
...@@ -1578,6 +1597,7 @@ static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv, ...@@ -1578,6 +1597,7 @@ static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv,
int min_index, max_index, index; int min_index, max_index, index;
static const struct cxd2841er_cnr_data *cn_data; static const struct cxd2841er_cnr_data *cn_data;
cxd2841er_freeze_regs(priv);
/* Set SLV-T Bank : 0xA1 */ /* Set SLV-T Bank : 0xA1 */
cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa1); cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa1);
/* /*
...@@ -1629,9 +1649,11 @@ static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv, ...@@ -1629,9 +1649,11 @@ static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv,
} else { } else {
dev_dbg(&priv->i2c->dev, dev_dbg(&priv->i2c->dev,
"%s(): no data available\n", __func__); "%s(): no data available\n", __func__);
cxd2841er_unfreeze_regs(priv);
return -EINVAL; return -EINVAL;
} }
done: done:
cxd2841er_unfreeze_regs(priv);
*snr = res; *snr = res;
return 0; return 0;
} }
...@@ -1655,12 +1677,7 @@ static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr) ...@@ -1655,12 +1677,7 @@ static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr)
return -EINVAL; return -EINVAL;
} }
/* cxd2841er_freeze_regs(priv);
* 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_write_reg(priv, I2C_SLVT, 0x00, 0x40);
cxd2841er_read_regs(priv, I2C_SLVT, 0x19, data, 1); cxd2841er_read_regs(priv, I2C_SLVT, 0x19, data, 1);
qam = (enum sony_dvbc_constellation_t) (data[0] & 0x07); qam = (enum sony_dvbc_constellation_t) (data[0] & 0x07);
...@@ -1670,6 +1687,7 @@ static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr) ...@@ -1670,6 +1687,7 @@ static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr)
if (reg == 0) { if (reg == 0) {
dev_dbg(&priv->i2c->dev, dev_dbg(&priv->i2c->dev,
"%s(): reg value out of range\n", __func__); "%s(): reg value out of range\n", __func__);
cxd2841er_unfreeze_regs(priv);
return 0; return 0;
} }
...@@ -1690,9 +1708,11 @@ static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr) ...@@ -1690,9 +1708,11 @@ static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr)
*snr = -88 * (int32_t)sony_log(reg) + 86999; *snr = -88 * (int32_t)sony_log(reg) + 86999;
break; break;
default: default:
cxd2841er_unfreeze_regs(priv);
return -EINVAL; return -EINVAL;
} }
cxd2841er_unfreeze_regs(priv);
return 0; return 0;
} }
...@@ -1707,17 +1727,21 @@ static int cxd2841er_read_snr_t(struct cxd2841er_priv *priv, u32 *snr) ...@@ -1707,17 +1727,21 @@ static int cxd2841er_read_snr_t(struct cxd2841er_priv *priv, u32 *snr)
"%s(): invalid state %d\n", __func__, priv->state); "%s(): invalid state %d\n", __func__, priv->state);
return -EINVAL; return -EINVAL;
} }
cxd2841er_freeze_regs(priv);
cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
reg = ((u32)data[0] << 8) | (u32)data[1]; reg = ((u32)data[0] << 8) | (u32)data[1];
if (reg == 0) { if (reg == 0) {
dev_dbg(&priv->i2c->dev, dev_dbg(&priv->i2c->dev,
"%s(): reg value out of range\n", __func__); "%s(): reg value out of range\n", __func__);
cxd2841er_unfreeze_regs(priv);
return 0; return 0;
} }
if (reg > 4996) if (reg > 4996)
reg = 4996; reg = 4996;
*snr = 10000 * ((intlog10(reg) - intlog10(5350 - reg)) >> 24) + 28500; *snr = 10000 * ((intlog10(reg) - intlog10(5350 - reg)) >> 24) + 28500;
cxd2841er_unfreeze_regs(priv);
return 0; return 0;
} }
...@@ -1732,18 +1756,22 @@ static int cxd2841er_read_snr_t2(struct cxd2841er_priv *priv, u32 *snr) ...@@ -1732,18 +1756,22 @@ static int cxd2841er_read_snr_t2(struct cxd2841er_priv *priv, u32 *snr)
"%s(): invalid state %d\n", __func__, priv->state); "%s(): invalid state %d\n", __func__, priv->state);
return -EINVAL; return -EINVAL;
} }
cxd2841er_freeze_regs(priv);
cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20); cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
reg = ((u32)data[0] << 8) | (u32)data[1]; reg = ((u32)data[0] << 8) | (u32)data[1];
if (reg == 0) { if (reg == 0) {
dev_dbg(&priv->i2c->dev, dev_dbg(&priv->i2c->dev,
"%s(): reg value out of range\n", __func__); "%s(): reg value out of range\n", __func__);
cxd2841er_unfreeze_regs(priv);
return 0; return 0;
} }
if (reg > 10876) if (reg > 10876)
reg = 10876; reg = 10876;
*snr = 10000 * ((intlog10(reg) - *snr = 10000 * ((intlog10(reg) -
intlog10(12600 - reg)) >> 24) + 32000; intlog10(12600 - reg)) >> 24) + 32000;
cxd2841er_unfreeze_regs(priv);
return 0; return 0;
} }
...@@ -1760,21 +1788,20 @@ static int cxd2841er_read_snr_i(struct cxd2841er_priv *priv, u32 *snr) ...@@ -1760,21 +1788,20 @@ static int cxd2841er_read_snr_i(struct cxd2841er_priv *priv, u32 *snr)
return -EINVAL; return -EINVAL;
} }
/* Freeze all registers */ cxd2841er_freeze_regs(priv);
cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x01);
cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60); cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
reg = ((u32)data[0] << 8) | (u32)data[1]; reg = ((u32)data[0] << 8) | (u32)data[1];
if (reg == 0) { if (reg == 0) {
dev_dbg(&priv->i2c->dev, dev_dbg(&priv->i2c->dev,
"%s(): reg value out of range\n", __func__); "%s(): reg value out of range\n", __func__);
cxd2841er_unfreeze_regs(priv);
return 0; return 0;
} }
if (reg > 4996) if (reg > 4996)
reg = 4996; reg = 4996;
*snr = 100 * intlog10(reg) - 9031; *snr = 100 * intlog10(reg) - 9031;
cxd2841er_unfreeze_regs(priv);
return 0; return 0;
} }
...@@ -1977,7 +2004,7 @@ static void cxd2841er_read_ucblocks(struct dvb_frontend *fe) ...@@ -1977,7 +2004,7 @@ static void cxd2841er_read_ucblocks(struct dvb_frontend *fe)
{ {
struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct cxd2841er_priv *priv = fe->demodulator_priv; struct cxd2841er_priv *priv = fe->demodulator_priv;
u32 ucblocks; u32 ucblocks = 0;
dev_dbg(&priv->i2c->dev, "%s()\n", __func__); dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
switch (p->delivery_system) { switch (p->delivery_system) {
...@@ -1999,7 +2026,7 @@ static void cxd2841er_read_ucblocks(struct dvb_frontend *fe) ...@@ -1999,7 +2026,7 @@ static void cxd2841er_read_ucblocks(struct dvb_frontend *fe)
p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
return; return;
} }
dev_dbg(&priv->i2c->dev, "%s()\n", __func__); dev_dbg(&priv->i2c->dev, "%s() ucblocks=%u\n", __func__, ucblocks);
p->block_error.stat[0].scale = FE_SCALE_COUNTER; p->block_error.stat[0].scale = FE_SCALE_COUNTER;
p->block_error.stat[0].uvalue = ucblocks; p->block_error.stat[0].uvalue = ucblocks;
...@@ -3076,6 +3103,7 @@ static int cxd2841er_sleep_tc_to_active_c(struct cxd2841er_priv *priv, ...@@ -3076,6 +3103,7 @@ static int cxd2841er_sleep_tc_to_active_c(struct cxd2841er_priv *priv,
/* Enable demod clock */ /* Enable demod clock */
cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01); cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01);
/* Disable RF level monitor */ /* Disable RF level monitor */
cxd2841er_write_reg(priv, I2C_SLVT, 0x59, 0x00);
cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00);
/* Enable ADC clock */ /* Enable ADC clock */
cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
......
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