diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-05 20:55:59 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-05 20:55:59 +0200 |
commit | 27c053aa8d18d1fa7b83041e36bad20bcdf55514 (patch) | |
tree | c59dce17a248dd8f4757eca3823032334c626dcd /drivers/media/tuners/e4000.c | |
parent | Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux (diff) | |
parent | [media] cx88: Fix regression: CX88_AUDIO_WM8775 can't be 0 (diff) | |
download | linux-27c053aa8d18d1fa7b83041e36bad20bcdf55514.tar.xz linux-27c053aa8d18d1fa7b83041e36bad20bcdf55514.zip |
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
"This series contains:
- Exynos s5p-mfc driver got support for VP8 encoder
- Some SoC drivers gained support for asynchronous registration
(needed for DT)
- The RC subsystem gained support for RC activity LED;
- New drivers added: a video decoder(adv7842), a video encoder
(adv7511), a new GSPCA driver (stk1135) and support for Renesas
R-Car (vsp1)
- the first SDR kernel driver: mirics msi3101. Due to some troubles
with the driver, and because the API is still under discussion, it
will be merged at staging for 3.12. Need to rework on it
- usual new boards additions, fixes, cleanups and driver
improvements"
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (242 commits)
[media] cx88: Fix regression: CX88_AUDIO_WM8775 can't be 0
[media] exynos4-is: Fix entity unregistration on error path
[media] exynos-gsc: Register v4l2 device
[media] exynos4-is: Fix fimc-lite bayer formats
[media] em28xx: fix assignment of the eeprom data
[media] hdpvr: fix iteration over uninitialized lists in hdpvr_probe()
[media] usbtv: Throw corrupted frames away
[media] usbtv: Fix deinterlacing
[media] v4l2: added missing mutex.h include to v4l2-ctrls.h
[media] DocBook: upgrade media_api DocBook version to 4.2
[media] ml86v7667: fix compile warning: 'ret' set but not used
[media] s5p-g2d: Fix registration failure
[media] media: coda: Fix DT driver data pointer for i.MX27
[media] s5p-mfc: Fix input/output format reporting
[media] v4l: vsp1: Fix mutex double lock at streamon time
[media] v4l: vsp1: Add support for RT clock
[media] v4l: vsp1: Initialize media device bus_info field
[media] davinci: vpif_capture: fix error return code in vpif_probe()
[media] davinci: vpif_display: fix error return code in vpif_probe()
[media] MAINTAINERS: add entries for adv7511 and adv7842
...
Diffstat (limited to 'drivers/media/tuners/e4000.c')
-rw-r--r-- | drivers/media/tuners/e4000.c | 82 |
1 files changed, 60 insertions, 22 deletions
diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c index 1b33ed368abe..ad9309da4a91 100644 --- a/drivers/media/tuners/e4000.c +++ b/drivers/media/tuners/e4000.c @@ -41,8 +41,9 @@ static int e4000_wr_regs(struct e4000_priv *priv, u8 reg, u8 *val, int len) if (ret == 1) { ret = 0; } else { - dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \ - "len=%d\n", KBUILD_MODNAME, ret, reg, len); + dev_warn(&priv->i2c->dev, + "%s: i2c wr failed=%d reg=%02x len=%d\n", + KBUILD_MODNAME, ret, reg, len); ret = -EREMOTEIO; } return ret; @@ -72,8 +73,9 @@ static int e4000_rd_regs(struct e4000_priv *priv, u8 reg, u8 *val, int len) memcpy(val, buf, len); ret = 0; } else { - dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \ - "len=%d\n", KBUILD_MODNAME, ret, reg, len); + dev_warn(&priv->i2c->dev, + "%s: i2c rd failed=%d reg=%02x len=%d\n", + KBUILD_MODNAME, ret, reg, len); ret = -EREMOTEIO; } @@ -140,14 +142,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; @@ -203,12 +203,13 @@ static int e4000_set_params(struct dvb_frontend *fe) struct e4000_priv *priv = fe->tuner_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i, sigma_delta; - unsigned int f_VCO; - u8 buf[5]; + unsigned int f_vco; + 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__, - c->delivery_system, c->frequency, c->bandwidth_hz); + dev_dbg(&priv->i2c->dev, + "%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n", + __func__, c->delivery_system, c->frequency, + c->bandwidth_hz); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); @@ -228,19 +229,19 @@ static int e4000_set_params(struct dvb_frontend *fe) goto err; /* - * Note: Currently f_VCO overflows when c->frequency is 1 073 741 824 Hz + * Note: Currently f_vco overflows when c->frequency is 1 073 741 824 Hz * or more. */ - f_VCO = c->frequency * e4000_pll_lut[i].mul; - sigma_delta = 0x10000UL * (f_VCO % priv->cfg->clock) / priv->cfg->clock; - buf[0] = f_VCO / priv->cfg->clock; + f_vco = c->frequency * e4000_pll_lut[i].mul; + sigma_delta = 0x10000UL * (f_vco % priv->cfg->clock) / priv->cfg->clock; + buf[0] = f_vco / priv->cfg->clock; buf[1] = (sigma_delta >> 0) & 0xff; buf[2] = (sigma_delta >> 8) & 0xff; buf[3] = 0x00; buf[4] = e4000_pll_lut[i].div; - dev_dbg(&priv->i2c->dev, "%s: f_VCO=%u pll div=%d sigma_delta=%04x\n", - __func__, f_VCO, buf[0], sigma_delta); + dev_dbg(&priv->i2c->dev, "%s: f_vco=%u pll div=%d sigma_delta=%04x\n", + __func__, f_vco, buf[0], sigma_delta); ret = e4000_wr_regs(priv, 0x09, buf, 5); if (ret < 0) @@ -292,6 +293,43 @@ 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); + } + + swap(q_data[2], q_data[3]); + swap(i_data[2], i_data[3]); + + ret = e4000_wr_regs(priv, 0x50, q_data, 4); + if (ret < 0) + goto err; + + ret = e4000_wr_regs(priv, 0x60, i_data, 4); + if (ret < 0) + goto err; + /* gain control auto */ ret = e4000_wr_reg(priv, 0x1a, 0x17); if (ret < 0) |