diff options
author | Michael Hunold <devnull@localhost> | 2003-03-19 07:45:29 +0000 |
---|---|---|
committer | Michael Hunold <devnull@localhost> | 2003-03-19 07:45:29 +0000 |
commit | c46bb51b9727222c179fba7ffb0b0d7df7eb28a1 (patch) | |
tree | c17ce49639a7eab37d1c7cb9a1e0291809b77e14 /linux/drivers/media/common/saa7146_i2c.c | |
parent | ffa323cf87fe8eddbdcaeb4f8ee1ed6a57700e68 (diff) | |
download | mediapointer-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.c | 35 |
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; } |