summaryrefslogtreecommitdiff
path: root/drivers/media/dvb-frontends/cxd2841er.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>2016-05-04 18:25:38 -0300
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2016-06-07 12:13:50 -0300
commit76344a3fc54d04aaf71763a1428245c9e1d9a4ac (patch)
tree88ec37406ebdfd5fc8a3a50cb0b5714190e20221 /drivers/media/dvb-frontends/cxd2841er.c
parent4da093ce4e8bd36223763c900f623ce36a0d51c3 (diff)
[media] ISDB-T retune and offset fix and DVB-C bw fix
now when new tuning parameters specified demod should retune. Also ISDB-T frequency offset calculation added (cxd2841er_get_carrier_offset_i). While here, fix re-tune for DVB-C Annex A, using the desired bandwidth, instead of using 8MHz. Signed-off-by: Abylay Ospan <aospan@netup.ru> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/dvb-frontends/cxd2841er.c')
-rw-r--r--drivers/media/dvb-frontends/cxd2841er.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c
index 609187d52d7a..45bc43886738 100644
--- a/drivers/media/dvb-frontends/cxd2841er.c
+++ b/drivers/media/dvb-frontends/cxd2841er.c
@@ -433,6 +433,15 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
u32 bandwidth);
+static int cxd2841er_sleep_tc_to_active_i(struct cxd2841er_priv *priv,
+ u32 bandwidth);
+
+static int cxd2841er_active_i_to_sleep_tc(struct cxd2841er_priv *priv);
+
+static int cxd2841er_sleep_tc_to_shutdown(struct cxd2841er_priv *priv);
+
+static int cxd2841er_shutdown_to_sleep_tc(struct cxd2841er_priv *priv);
+
static int cxd2841er_retune_active(struct cxd2841er_priv *priv,
struct dtv_frontend_properties *p)
{
@@ -460,7 +469,13 @@ static int cxd2841er_retune_active(struct cxd2841er_priv *priv,
priv, p->bandwidth_hz);
case SYS_DVBC_ANNEX_A:
return cxd2841er_sleep_tc_to_active_c_band(
- priv, 8000000);
+ priv, p->bandwidth_hz);
+ case SYS_ISDBT:
+ cxd2841er_active_i_to_sleep_tc(priv);
+ cxd2841er_sleep_tc_to_shutdown(priv);
+ cxd2841er_shutdown_to_sleep_tc(priv);
+ return cxd2841er_sleep_tc_to_active_i(
+ priv, p->bandwidth_hz);
}
}
dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n",
@@ -1095,6 +1110,50 @@ static int cxd2841er_get_carrier_offset_s_s2(struct cxd2841er_priv *priv,
return 0;
}
+static int cxd2841er_get_carrier_offset_i(struct cxd2841er_priv *priv,
+ u32 bandwidth, int *offset)
+{
+ u8 data[4];
+
+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
+ if (priv->state != STATE_ACTIVE_TC) {
+ dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
+ __func__, priv->state);
+ return -EINVAL;
+ }
+ if (priv->system != SYS_ISDBT) {
+ dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n",
+ __func__, priv->system);
+ return -EINVAL;
+ }
+ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
+ cxd2841er_read_regs(priv, I2C_SLVT, 0x4c, data, sizeof(data));
+ *offset = -1 * sign_extend32(
+ ((u32)(data[0] & 0x1F) << 24) | ((u32)data[1] << 16) |
+ ((u32)data[2] << 8) | (u32)data[3], 29);
+
+ switch (bandwidth) {
+ case 6000000:
+ *offset = -1 * ((*offset) * 8/264);
+ break;
+ case 7000000:
+ *offset = -1 * ((*offset) * 8/231);
+ break;
+ case 8000000:
+ *offset = -1 * ((*offset) * 8/198);
+ break;
+ default:
+ dev_dbg(&priv->i2c->dev, "%s(): invalid bandwidth %d\n",
+ __func__, bandwidth);
+ return -EINVAL;
+ }
+
+ dev_dbg(&priv->i2c->dev, "%s(): bandwidth %d offset %d\n",
+ __func__, bandwidth, *offset);
+
+ return 0;
+}
+
static int cxd2841er_get_carrier_offset_t(struct cxd2841er_priv *priv,
u32 bandwidth, int *offset)
{
@@ -2941,6 +3000,11 @@ static int cxd2841er_tune_tc(struct dvb_frontend *fe,
cxd2841er_read_status_tc(fe, status);
if (*status & FE_HAS_LOCK) {
switch (priv->system) {
+ case SYS_ISDBT:
+ ret = cxd2841er_get_carrier_offset_i(
+ priv, p->bandwidth_hz,
+ &carrier_offset);
+ break;
case SYS_DVBT:
ret = cxd2841er_get_carrier_offset_t(
priv, p->bandwidth_hz,