public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/3] fsl_i2c: Wait for STOP condition to propagate
@ 2009-09-17  9:07 Joakim Tjernlund
  2009-09-17  9:07 ` [U-Boot] [PATCH 2/3] fsl_i2c: Add CONFIG_FSL_I2C_CUSTOM_{DFSR/FDR} Joakim Tjernlund
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Joakim Tjernlund @ 2009-09-17  9:07 UTC (permalink / raw)
  To: u-boot

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>
---
 drivers/i2c/fsl_i2c.c |   12 ++++++++----
 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;
-- 
1.6.4.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 1/3] fsl_i2c: Wait for STOP condition to propagate
@ 2009-09-16 11:31 Joakim Tjernlund
  0 siblings, 0 replies; 19+ messages in thread
From: Joakim Tjernlund @ 2009-09-16 11:31 UTC (permalink / raw)
  To: u-boot

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>
---
 drivers/i2c/fsl_i2c.c |   12 ++++++++----
 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;
-- 
1.6.4.2

^ permalink raw reply related	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2009-09-23 12:19 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-17  9:07 [U-Boot] [PATCH 1/3] fsl_i2c: Wait for STOP condition to propagate Joakim Tjernlund
2009-09-17  9:07 ` [U-Boot] [PATCH 2/3] fsl_i2c: Add CONFIG_FSL_I2C_CUSTOM_{DFSR/FDR} Joakim Tjernlund
2009-09-17  9:07   ` [U-Boot] [PATCH 3/3] fsl_i2c: Impl. AN2919, rev 5 to calculate FDR/DFSR Joakim Tjernlund
2009-09-17 12:04     ` Heiko Schocher
2009-09-21 10:53     ` Wolfgang Grandegger
2009-09-21 11:34       ` Joakim Tjernlund
2009-09-21 11:59         ` Wolfgang Grandegger
2009-09-21 12:30           ` Joakim Tjernlund
2009-09-17 12:03   ` [U-Boot] [PATCH 2/3] fsl_i2c: Add CONFIG_FSL_I2C_CUSTOM_{DFSR/FDR} Heiko Schocher
2009-09-17 14:38   ` Timur Tabi
2009-09-17 18:11     ` Joakim Tjernlund
2009-09-17 12:03 ` [U-Boot] [PATCH 1/3] fsl_i2c: Wait for STOP condition to propagate Heiko Schocher
2009-09-17 12:37   ` Joakim Tjernlund
2009-09-22 20:57 ` Wolfgang Denk
2009-09-23  7:58   ` Joakim Tjernlund
2009-09-23  9:02     ` Heiko Schocher
2009-09-23  9:14       ` Joakim Tjernlund
2009-09-23 12:19         ` Heiko Schocher
  -- strict thread matches above, loose matches on Subject: below --
2009-09-16 11:31 Joakim Tjernlund

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox