summaryrefslogtreecommitdiffstats
path: root/drivers/media/tuners/e4000.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/tuners/e4000.c')
-rw-r--r--drivers/media/tuners/e4000.c56
1 files changed, 48 insertions, 8 deletions
diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c
index 1b33ed368abe..a3a9c87a472b 100644
--- a/drivers/media/tuners/e4000.c
+++ b/drivers/media/tuners/e4000.c
@@ -140,14 +140,12 @@ static int e4000_init(struct dvb_frontend *fe)
if (ret < 0)
goto err;
- /*
- * TODO: Implement DC offset control correctly.
- * DC offsets has quite much effect for received signal quality in case
- * of direct conversion tuners (Zero-IF). Surely we will now lose few
- * decimals or even decibels from SNR...
- */
/* DC offset control */
- ret = e4000_wr_reg(priv, 0x2d, 0x0c);
+ ret = e4000_wr_reg(priv, 0x2d, 0x1f);
+ if (ret < 0)
+ goto err;
+
+ ret = e4000_wr_regs(priv, 0x70, "\x01\x01", 2);
if (ret < 0)
goto err;
@@ -204,7 +202,7 @@ static int e4000_set_params(struct dvb_frontend *fe)
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret, i, sigma_delta;
unsigned int f_VCO;
- u8 buf[5];
+ u8 buf[5], i_data[4], q_data[4];
dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d frequency=%d " \
"bandwidth_hz=%d\n", __func__,
@@ -292,6 +290,48 @@ static int e4000_set_params(struct dvb_frontend *fe)
if (ret < 0)
goto err;
+ /* DC offset */
+ for (i = 0; i < 4; i++) {
+ if (i == 0)
+ ret = e4000_wr_regs(priv, 0x15, "\x00\x7e\x24", 3);
+ else if (i == 1)
+ ret = e4000_wr_regs(priv, 0x15, "\x00\x7f", 2);
+ else if (i == 2)
+ ret = e4000_wr_regs(priv, 0x15, "\x01", 1);
+ else
+ ret = e4000_wr_regs(priv, 0x16, "\x7e", 1);
+
+ if (ret < 0)
+ goto err;
+
+ ret = e4000_wr_reg(priv, 0x29, 0x01);
+ if (ret < 0)
+ goto err;
+
+ ret = e4000_rd_regs(priv, 0x2a, buf, 3);
+ if (ret < 0)
+ goto err;
+
+ i_data[i] = (((buf[2] >> 0) & 0x3) << 6) | (buf[0] & 0x3f);
+ q_data[i] = (((buf[2] >> 4) & 0x3) << 6) | (buf[1] & 0x3f);
+ }
+
+ buf[0] = q_data[0];
+ buf[1] = q_data[1];
+ buf[2] = q_data[3];
+ buf[3] = q_data[2];
+ ret = e4000_wr_regs(priv, 0x50, buf, 4);
+ if (ret < 0)
+ goto err;
+
+ buf[0] = i_data[0];
+ buf[1] = i_data[1];
+ buf[2] = i_data[3];
+ buf[3] = i_data[2];
+ ret = e4000_wr_regs(priv, 0x60, buf, 4);
+ if (ret < 0)
+ goto err;
+
/* gain control auto */
ret = e4000_wr_reg(priv, 0x1a, 0x17);
if (ret < 0)