From 8514611438e9e324a9faeac69393c62ef76a5832 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 24 Jul 2013 02:04:12 -0300 Subject: [PATCH] [media] e4000: implement DC offset correction I did some tests against modulator (television signal generator) and this seems to improve sensitivity a little bit on channel I used. Used device was able to receive transmission just as weak signal as with Windows XP. Thanks to Jacek for donating his non-working device. I cannot ask he to test anymore... Reported-by: Jacek Konieczny Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/e4000.c | 56 ++++++++++++++++++++++++++++++------ 1 file 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) -- 2.39.5