summaryrefslogtreecommitdiff
path: root/linux/drivers/media/common/saa7146_i2c.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/common/saa7146_i2c.c')
-rw-r--r--linux/drivers/media/common/saa7146_i2c.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/linux/drivers/media/common/saa7146_i2c.c b/linux/drivers/media/common/saa7146_i2c.c
index 1b3455dac..8a8c86265 100644
--- a/linux/drivers/media/common/saa7146_i2c.c
+++ b/linux/drivers/media/common/saa7146_i2c.c
@@ -198,6 +198,7 @@ int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword)
{
int i = 0;
u32 status = 0, mc2 = 0;
+ const int timeout = SAA7146_I2C_TIMEOUT * HZ / 1000;
/* write out i2c-command */
if( 0 != use_i2c_irq ) {
@@ -206,13 +207,19 @@ if( 0 != use_i2c_irq ) {
saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
saa7146_write(dev, I2C_TRANSFER, *dword);
- IER_ENABLE(dev, MASK_16|MASK_17);
+ IER_ENABLE(dev, MASK_17);
saa7146_write(dev, MC2, (MASK_00 | MASK_16));
- wait_event_interruptible(dev->i2c_wq, (0 == dev->i2c_op) );
+ interruptible_sleep_on_timeout(&dev->i2c_wq, timeout);
if( 0 != dev->i2c_op ) {
- printk("saa7146: bogus i2c stuff happened.\n");
+ DEB_I2C(("error: i2c timeout\n"));
dev->i2c_op = 0;
+ status = saa7146_read(dev, I2C_STATUS);
+ if( 0 != (status & SAA7146_I2C_APERR) ) {
+ DEB_I2C(("timeout in address phase.\n"));
+ return -2;
+ }
+ return -1;
}
status = saa7146_read(dev, I2C_STATUS);
} else {