summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGao Pan <pandy.gao@nxp.com>2018-07-08 11:46:41 +0800
committerHeiko Schocher <hs@denx.de>2018-07-12 11:09:07 +0200
commita32effd2838a62a5d1dcc01f613508f1d90b5667 (patch)
tree538216d800839f69e7eb44f6241a4ed9df5de412
parent9b2ebcc06048cf49c2f8a8d152177ed1a8363878 (diff)
imx: lpi2c: fix clock issue when NACK detected
For LPI2C IP, NACK is detected by the rising edge of the ninth clock. In current uboot driver, once NACK is detected, it will reset and then disable LPI2C master. As a result, we can never see the falling edge of the ninth clock. Signed-off-by: Gao Pan <pandy.gao@nxp.com> Signed-off-by: Peng Fan <peng.fan@nxp.com> Reviewed-by: Heiko Schocher <hs@denx.de>
-rw-r--r--drivers/i2c/imx_lpi2c.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/i2c/imx_lpi2c.c b/drivers/i2c/imx_lpi2c.c
index a6e41c5c918..d2e11b411ba 100644
--- a/drivers/i2c/imx_lpi2c.c
+++ b/drivers/i2c/imx_lpi2c.c
@@ -15,6 +15,7 @@
#include <i2c.h>
#define LPI2C_FIFO_SIZE 4
+#define LPI2C_NACK_TOUT_MS 1
#define LPI2C_TIMEOUT_MS 100
/* Weak linked function for overridden by some SoC power function */
@@ -184,6 +185,7 @@ static int bus_i2c_stop(struct imx_lpi2c_reg *regs)
{
lpi2c_status_t result;
u32 status;
+ ulong start_time;
result = bus_i2c_wait_for_tx_ready(regs);
if (result) {
@@ -194,7 +196,8 @@ static int bus_i2c_stop(struct imx_lpi2c_reg *regs)
/* send stop command */
writel(LPI2C_MTDR_CMD(0x2), &regs->mtdr);
- while (result == LPI2C_SUCESS) {
+ start_time = get_timer(0);
+ while (1) {
status = readl(&regs->msr);
result = imx_lpci2c_check_clear_error(regs);
/* stop detect flag */
@@ -204,6 +207,11 @@ static int bus_i2c_stop(struct imx_lpi2c_reg *regs)
writel(status, &regs->msr);
break;
}
+
+ if (get_timer(start_time) > LPI2C_NACK_TOUT_MS) {
+ debug("stop timeout\n");
+ return -ETIMEDOUT;
+ }
}
return result;
@@ -363,10 +371,8 @@ static int imx_lpi2c_probe_chip(struct udevice *bus, u32 chip,
}
result = bus_i2c_stop(regs);
- if (result) {
+ if (result)
bus_i2c_init(bus, 100000);
- return -result;
- }
return result;
}