@@ -181,6 +181,7 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
* Zero length reads always succeed, even if no device is connected
*/
+retry:
/* Write to i2c device */
ret = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len);
if (ret != len) {
@@ -200,11 +201,8 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
ret = dev->em28xx_read_reg(dev, 0x05);
if (ret == 0) /* success */
return len;
- if (ret == 0x10) {
- em28xx_warn("I2C transfer timeout on writing to addr 0x%02x",
- addr);
- return -ENODEV;
- }
+ if (ret == 0x10)
+ goto retry;
if (ret < 0) {
em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n",
ret);
@@ -218,6 +216,11 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
*/
}
+ if (ret == 0x10) {
+ em28xx_warn("I2C transfer timeout on writing to addr 0x%02x",
+ addr);
+ return -ENODEV;
+ }
em28xx_warn("write to i2c device at 0x%x timed out\n", addr);
return -EIO;
}
@@ -228,6 +231,7 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
*/
static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len)
{
+ unsigned long timeout = jiffies + msecs_to_jiffies(EM2800_I2C_XFER_TIMEOUT);
int ret;
if (len < 1 || len > 64)
@@ -237,30 +241,35 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len)
* Zero length reads always succeed, even if no device is connected
*/
- /* Read data from i2c device */
- ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len);
- if (ret < 0) {
- em28xx_warn("reading from i2c device at 0x%x failed (error=%i)\n",
- addr, ret);
- return ret;
- }
- /*
- * NOTE: some devices with two i2c busses have the bad habit to return 0
- * bytes if we are on bus B AND there was no write attempt to the
- * specified slave address before AND no device is present at the
- * requested slave address.
- * Anyway, the next check will fail with -ENODEV in this case, so avoid
- * spamming the system log on device probing and do nothing here.
- */
-
- /* Check success of the i2c operation */
- ret = dev->em28xx_read_reg(dev, 0x05);
- if (ret == 0) /* success */
- return len;
- if (ret < 0) {
- em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n",
- ret);
- return ret;
+ while (time_is_after_jiffies(timeout)) {
+ /* Read data from i2c device */
+ ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len);
+ if (ret < 0) {
+ em28xx_warn("reading from i2c device at 0x%x failed (error=%i)\n",
+ addr, ret);
+ return ret;
+ }
+ /*
+ * NOTE: some devices with two i2c busses have the bad habit to return 0
+ * bytes if we are on bus B AND there was no write attempt to the
+ * specified slave address before AND no device is present at the
+ * requested slave address.
+ * Anyway, the next check will fail with -ENODEV in this case, so avoid
+ * spamming the system log on device probing and do nothing here.
+ */
+
+ /* Check success of the i2c operation */
+ ret = dev->em28xx_read_reg(dev, 0x05);
+ if (ret == 0) /* success */
+ return len;
+ if (ret < 0) {
+ em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n",
+ ret);
+ return ret;
+ }
+ if (ret != 0x10)
+ break;
+ msleep(5);
}
if (ret == 0x10) {
em28xx_warn("I2C transfer timeout on read from addr 0x%02x", addr);