diff options
author | Devin Heitmueller <dheitmueller@linuxtv.org> | 2009-03-11 02:00:41 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:43:25 -0400 |
commit | 32c000ad93fe8c447342632024ddef1ca516a0e9 (patch) | |
tree | d9dde8a58a416645b5a3bed779051d5c41e50944 /drivers/media/video/au0828 | |
parent | 8b2f079523450fa2d65cbb3f8453820bf1e17533 (diff) |
V4L/DVB (11067): au0828: workaround a bug in the au0828 i2c handling
There is an issue related to the i2c clock for addressing the xc5000. The
au0828 chip does not support clock stretching, which the xc5000 makes use of.
This results in cases where we silently get back garbage in i2c read
operations. To work around this issue until we slow down the i2c clock when
talking with that specific device.
This was not an issue before we had analog support because we never needed to
enumerate the i2c bus, and digital tuning never actually needed to perform
read operations against the xc5000.
Thanks to Michael Krufky <mkrufky@linuxtv.org> and Steven Toth
<stoth@linuxtv.org> for providing sample hardware, engineering level support,
and testing.
Signed-off-by: Devin Heitmueller <dheitmueller@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/au0828')
-rw-r--r-- | drivers/media/video/au0828/au0828-i2c.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/video/au0828/au0828-i2c.c index d618fbaade1b..ee3e3040d54c 100644 --- a/drivers/media/video/au0828/au0828-i2c.c +++ b/drivers/media/video/au0828/au0828-i2c.c | |||
@@ -140,7 +140,16 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, | |||
140 | dprintk(4, "%s()\n", __func__); | 140 | dprintk(4, "%s()\n", __func__); |
141 | 141 | ||
142 | au0828_write(dev, REG_2FF, 0x01); | 142 | au0828_write(dev, REG_2FF, 0x01); |
143 | au0828_write(dev, REG_202, 0x07); | 143 | |
144 | /* FIXME: There is a problem with i2c communications with xc5000 that | ||
145 | requires us to slow down the i2c clock until we have a better | ||
146 | strategy (such as using the secondary i2c bus to do firmware | ||
147 | loading */ | ||
148 | if ((msg->addr << 1) == 0xc2) { | ||
149 | au0828_write(dev, REG_202, 0x40); | ||
150 | } else { | ||
151 | au0828_write(dev, REG_202, 0x07); | ||
152 | } | ||
144 | 153 | ||
145 | /* Hardware needs 8 bit addresses */ | 154 | /* Hardware needs 8 bit addresses */ |
146 | au0828_write(dev, REG_203, msg->addr << 1); | 155 | au0828_write(dev, REG_203, msg->addr << 1); |
@@ -191,7 +200,16 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, | |||
191 | dprintk(4, "%s()\n", __func__); | 200 | dprintk(4, "%s()\n", __func__); |
192 | 201 | ||
193 | au0828_write(dev, REG_2FF, 0x01); | 202 | au0828_write(dev, REG_2FF, 0x01); |
194 | au0828_write(dev, REG_202, 0x07); | 203 | |
204 | /* FIXME: There is a problem with i2c communications with xc5000 that | ||
205 | requires us to slow down the i2c clock until we have a better | ||
206 | strategy (such as using the secondary i2c bus to do firmware | ||
207 | loading */ | ||
208 | if ((msg->addr << 1) == 0xc2) { | ||
209 | au0828_write(dev, REG_202, 0x40); | ||
210 | } else { | ||
211 | au0828_write(dev, REG_202, 0x07); | ||
212 | } | ||
195 | 213 | ||
196 | /* Hardware needs 8 bit addresses */ | 214 | /* Hardware needs 8 bit addresses */ |
197 | au0828_write(dev, REG_203, msg->addr << 1); | 215 | au0828_write(dev, REG_203, msg->addr << 1); |