fsl_i2c: Wait for STOP condition to propagate
After issuing a STOP one must wait until the STOP has completed
on the bus before doing something new to the controller.
Also add an extra read of SR as the manual mentions doing that
is a good idea.
Remove surplus write of CR just before a write, isn't required and
could potentially disturb the I2C bus.
Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c
index 47bbf79..56f9680 100644
--- a/drivers/i2c/fsl_i2c.c
+++ b/drivers/i2c/fsl_i2c.c
@@ -223,7 +223,7 @@
#endif
}
-static __inline__ int
+static int
i2c_wait4bus(void)
{
unsigned long long timeval = get_ticks();
@@ -248,6 +248,8 @@
csr = readb(&i2c_dev[i2c_bus_num]->sr);
if (!(csr & I2C_SR_MIF))
continue;
+ /* Read again to allow register to stabilise */
+ csr = readb(&i2c_dev[i2c_bus_num]->sr);
writeb(0x0, &i2c_dev[i2c_bus_num]->sr);
@@ -293,9 +295,6 @@
{
int i;
- writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX,
- &i2c_dev[i2c_bus_num]->cr);
-
for (i = 0; i < length; i++) {
writeb(data[i], &i2c_dev[i2c_bus_num]->dr);
@@ -351,6 +350,9 @@
&& i2c_write_addr(dev, I2C_READ_BIT, 1) != 0)
i = __i2c_read(data, length);
+ if (length && i2c_wait4bus()) /* Wait until STOP */
+ debug("i2c_read: wait4bus timed out\n");
+
writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
if (i == length)
@@ -372,6 +374,8 @@
}
writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
+ if (i2c_wait4bus()) /* Wait until STOP */
+ debug("i2c_write: wait4bus timed out\n");
if (i == length)
return 0;