summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoakim Tjernlund <Joakim.Tjernlund@transmode.se>2009-09-17 11:07:15 +0200
committerHeiko Schocher <hs@denx.de>2009-09-28 07:35:52 +0200
commit21f4cbb77299788e2b06c9b0f48cf20a5ab00d4a (patch)
treee7668f7ea1f9b9872801f93967c5f4b81aaad8d7
parent984f10baac8ef6032df52f135943d6b0bc96f724 (diff)
downloadu-boot-imx-21f4cbb77299788e2b06c9b0f48cf20a5ab00d4a.zip
u-boot-imx-21f4cbb77299788e2b06c9b0f48cf20a5ab00d4a.tar.gz
u-boot-imx-21f4cbb77299788e2b06c9b0f48cf20a5ab00d4a.tar.bz2
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>
-rw-r--r--drivers/i2c/fsl_i2c.c12
1 files changed, 8 insertions, 4 deletions
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 @@ i2c_init(int speed, int slaveadd)
#endif
}
-static __inline__ int
+static int
i2c_wait4bus(void)
{
unsigned long long timeval = get_ticks();
@@ -248,6 +248,8 @@ i2c_wait(int write)
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 @@ __i2c_write(u8 *data, int length)
{
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_read(u8 dev, uint addr, int alen, u8 *data, int length)
&& 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 @@ i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
}
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;