[PATCH 3/4] i2c-imx: fix low bitrate problem
Marc Kleine-Budde
mkl at pengutronix.de
Wed Dec 9 09:42:33 EST 2009
loop in i2c_imx_acked() in low bit rates it takes some time until the
ACK comes in.
Also add a delay before polling for bus not busy in i2c_imx_read.
Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
drivers/i2c/i2c-imx.c | 20 +++++++++++++++++---
1 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/drivers/i2c/i2c-imx.c b/drivers/i2c/i2c-imx.c
index 14d5260..c2a38ee 100644
--- a/drivers/i2c/i2c-imx.c
+++ b/drivers/i2c/i2c-imx.c
@@ -205,10 +205,18 @@ static int i2c_imx_wait_iif(struct i2c_adapter *adapter)
static int i2c_imx_acked(struct i2c_adapter *adapter)
{
unsigned long base = adapter->dev->map_base;
+ uint64_t start;
- if (readb(base + IMX_I2C_I2SR) & I2SR_RXAK) {
- dev_notice(adapter->dev, "<%s> No ACK\n", __func__);
- return -EIO;
+ start = get_time_ns();
+ while (1) {
+ unsigned int reg = readb(base + IMX_I2C_I2SR);
+ if (!(reg & I2SR_RXAK))
+ break;
+
+ if (is_timeout(start, MSECOND)) {
+ dev_err(adapter->dev, "<%s> No ACK\n", __func__);
+ return -EIO;
+ }
}
return 0;
@@ -398,6 +406,12 @@ static int i2c_imx_read(struct i2c_adapter *adapter, struct i2c_msg *msgs)
temp = readb(base + IMX_I2C_I2CR);
temp &= ~(I2CR_MSTA | I2CR_MTX);
writeb(temp, base + IMX_I2C_I2CR);
+
+ /*
+ * adding this delay helps on low bitrates
+ */
+ udelay(i2c_imx->disable_delay);
+
i2c_imx_bus_busy(adapter, 0);
i2c_imx->stopped = 1;
} else if (i == (msgs->len - 2)) {
--
1.6.5.4
More information about the u-boot-v2
mailing list