diff options
Diffstat (limited to 'drivers/i2c/algos')
-rw-r--r-- | drivers/i2c/algos/i2c-algo-bit.c | 2 | ||||
-rw-r--r-- | drivers/i2c/algos/i2c-algo-pca.c | 13 |
2 files changed, 13 insertions, 2 deletions
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index d420cc5f563..e25e13980af 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -104,7 +104,7 @@ static int sclhi(struct i2c_algo_bit_data *adap) * chips may hold it low ("clock stretching") while they * are processing data internally. */ - if (time_after_eq(jiffies, start + adap->timeout)) + if (time_after(jiffies, start + adap->timeout)) return -ETIMEDOUT; cond_resched(); } diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index f68e5f8e23e..78d42aae008 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -190,7 +190,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, int completed = 1; unsigned long timeout = jiffies + i2c_adap->timeout; - while (pca_status(adap) != 0xf8) { + while ((state = pca_status(adap)) != 0xf8) { if (time_before(jiffies, timeout)) { msleep(10); } else { @@ -287,10 +287,21 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, case 0x30: /* Data byte in I2CDAT has been transmitted; NOT ACK has been received */ DEB2("NOT ACK received after data byte\n"); + pca_stop(adap); goto out; case 0x38: /* Arbitration lost during SLA+W, SLA+R or data bytes */ DEB2("Arbitration lost\n"); + /* + * The PCA9564 data sheet (2006-09-01) says "A + * START condition will be transmitted when the + * bus becomes free (STOP or SCL and SDA high)" + * when the STA bit is set (p. 11). + * + * In case this won't work, try pca_reset() + * instead. + */ + pca_start(adap); goto out; case 0x58: /* Data byte has been received; NOT ACK has been returned */ |