[U-Boot] [PATCH V2] arm: omap: i2c: don't zero cnt in i2c_write

Nikita Kiryanov nikita at compulab.co.il
Thu Nov 28 17:04:42 CET 2013


Writing zero into I2Ci.I2C_CNT register causes random I2C failures in OMAP3
based devices. This seems to be related to the following advisory which
apears in multiple erratas for OMAP3 SoCs (OMAP35xx, DM37xx), as well as
OMAP4430 TRM:

Advisory:
I2C Module Does Not Allow 0-Byte Data Requests
Details:
When configured as the master, the I2C module does not allow 0-byte data
transfers. Note: Programming I2Ci.I2C_CNT[15:0]: DCOUNT = 0 will cause
undefined behavior.
Workaround(s):
No workaround. Do not use 0-byte data requests.

The writes in question are unnecessary from a functional point of view.
Most of them are done after I/O has finished, and the only one that preceds
I/O (in i2c_probe()) is also unnecessary because a stop bit is sent before
actual data transmission takes place.

Therefore, remove all writes that zero the cnt register.

Cc: Heiko Schocher <hs at denx.de>
Cc: Thomas Petazzoni <thomas.petazzoni at free-electrons.com>
Cc: Tom Rini <trini at ti.com>
Cc: Lubomir Popov <lpopov at mm-sol.com>
Cc: Enric Balletbo Serra <eballetbo at gmail.com>
Signed-off-by: Nikita Kiryanov <nikita at compulab.co.il>
---
Changes in V2:	
	Removed all instances of writew(0, &i2c_base->cnt) instead of just the
	one in i2c_write (following a test of V1 by Thomas Petazzoni).

 drivers/i2c/omap24xx_i2c.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index 3d38c03..c784004 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -158,7 +158,6 @@ static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
 	udelay(1000);
 	flush_fifo(adap);
 	writew(0xFFFF, &i2c_base->stat);
-	writew(0, &i2c_base->cnt);
 }
 
 static void flush_fifo(struct i2c_adapter *adap)
@@ -198,8 +197,6 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
 		return res;
 
 	/* No data transfer, slave addr only */
-	writew(0, &i2c_base->cnt);
-	/* Set slave address */
 	writew(chip, &i2c_base->sa);
 	/* Stop bit needed here */
 	writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
@@ -234,7 +231,6 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
 pr_exit:
 	flush_fifo(adap);
 	writew(0xFFFF, &i2c_base->stat);
-	writew(0, &i2c_base->cnt);
 	return res;
 }
 
@@ -372,7 +368,6 @@ static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
 rd_exit:
 	flush_fifo(adap);
 	writew(0xFFFF, &i2c_base->stat);
-	writew(0, &i2c_base->cnt);
 	return i2c_error;
 }
 
@@ -473,7 +468,6 @@ static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
 wr_exit:
 	flush_fifo(adap);
 	writew(0xFFFF, &i2c_base->stat);
-	writew(0, &i2c_base->cnt);
 	return i2c_error;
 }
 
-- 
1.8.1.2



More information about the U-Boot mailing list