summaryrefslogtreecommitdiff
path: root/linux/drivers/media/common/saa7146_i2c.c
diff options
context:
space:
mode:
authorMichael Hunold <devnull@localhost>2003-03-19 07:45:29 +0000
committerMichael Hunold <devnull@localhost>2003-03-19 07:45:29 +0000
commitc46bb51b9727222c179fba7ffb0b0d7df7eb28a1 (patch)
treec17ce49639a7eab37d1c7cb9a1e0291809b77e14 /linux/drivers/media/common/saa7146_i2c.c
parentffa323cf87fe8eddbdcaeb4f8ee1ed6a57700e68 (diff)
downloadmediapointer-dvb-s2-c46bb51b9727222c179fba7ffb0b0d7df7eb28a1.tar.gz
mediapointer-dvb-s2-c46bb51b9727222c179fba7ffb0b0d7df7eb28a1.tar.bz2
- optimize the i2c retry-address error problem by distinguishing between
analog tv cards and dvb cards. (see source comments for further informations)
Diffstat (limited to 'linux/drivers/media/common/saa7146_i2c.c')
-rw-r--r--linux/drivers/media/common/saa7146_i2c.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/linux/drivers/media/common/saa7146_i2c.c b/linux/drivers/media/common/saa7146_i2c.c
index 9a0092635..cade026d2 100644
--- a/linux/drivers/media/common/saa7146_i2c.c
+++ b/linux/drivers/media/common/saa7146_i2c.c
@@ -313,7 +313,23 @@ int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg msgs[], i
for(i = 0; i < count; i++) {
err = saa7146_i2c_writeout(dev, &buffer[i] );
if ( 0 != err) {
+ /* this one is unsatisfying: some i2c slaves on some
+ dvb cards don't acknowledge correctly, so the saa7146
+ thinks that an address error occured. in that case, the
+ transaction should be retrying, even if an address error
+ occured. analog saa7146 based cards extensively rely on
+ i2c address probing, however, and address errors indicate that a
+ device is really *not* there. retrying in that case
+ increases the time the device needs to probe greatly, so
+ it should be avoided. because of the fact, that only
+ analog based cards use irq based i2c transactions (for dvb
+ cards, this screwes up other interrupt sources), we bail out
+ completely for analog cards after an address error and trust
+ the saa7146 address error detection. */
if ( -EREMOTEIO == err ) {
+ if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) {
+ goto out;
+ }
address_err++;
}
DEB_I2C(("error while sending message(s). starting again.\n"));
@@ -330,15 +346,6 @@ int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg msgs[], i
} while (err != num && retries--);
- /* another bug in revision 0: the i2c-registers get uploaded randomly by other
- uploads, so we better clear them out before continueing */
- if( 0 == dev->revision ) {
- u32 zero = 0;
- if( 0 != saa7146_i2c_writeout(dev, &zero)) {
- INFO(("revision 0 error. this should never happen.\n"));
- }
- }
-
/* if every retry had an address error, exit right away */
if (address_err == retries) {
goto out;
@@ -354,6 +361,16 @@ int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg msgs[], i
/* return the number of delivered messages */
DEB_I2C(("transmission successful. (msg:%d).\n",err));
out:
+ /* another bug in revision 0: the i2c-registers get uploaded randomly by other
+ uploads, so we better clear them out before continueing */
+ if( 0 == dev->revision ) {
+ u32 zero = 0;
+ saa7146_i2c_reset(dev);
+ if( 0 != saa7146_i2c_writeout(dev, &zero)) {
+ INFO(("revision 0 error. this should never happen.\n"));
+ }
+ }
+
up(&dev->i2c_lock);
return err;
}