[U-Boot] [PATCH] i2c: designware_i2c: Restore enable state after set speed

Jun Chen ptchentw at gmail.com
Wed Jun 5 07:23:16 UTC 2019


Before calling __dw_i2c_set_bus_speed(),
the I2C could already be set as ether enable or disable,
we should restore the original setting instead of enable i2c anyway.

This patch fix a bug happened in init function:
    __dw_i2c_init(){
            /* Disable i2c */
            ...
            __dw_i2c_set_bus_speed(i2c_base, NULL, speed);
            writel(slaveaddr, &i2c_base->ic_sar);
            /* Enable i2c */
    }
In this case, enable i2c inside __dw_i2c_set_bus_speed() function
will cause ic_sar write fail.

Signed-off-by: Jun Chen <ptchentw at gmail.com>
---

 drivers/i2c/designware_i2c.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index 9ccc241..d11d47d 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -82,6 +82,7 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base,
 {
 	unsigned int cntl;
 	unsigned int hcnt, lcnt;
+	unsigned int ena;
 	int i2c_spd;
 
 	if (speed >= I2C_MAX_SPEED)
@@ -91,6 +92,9 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base,
 	else
 		i2c_spd = IC_SPEED_MODE_STANDARD;
 
+	/* Get enable setting for restore later */
+	ena = readl(&i2c_base->ic_enable) & IC_ENABLE_0B;
+
 	/* to set speed cltr must be disabled */
 	dw_i2c_enable(i2c_base, false);
 
@@ -146,8 +150,9 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base,
 	if (scl_sda_cfg)
 		writel(scl_sda_cfg->sda_hold, &i2c_base->ic_sda_hold);
 
-	/* Enable back i2c now speed set */
-	dw_i2c_enable(i2c_base, true);
+	/* Restore back i2c now speed set */
+	if (ena == IC_ENABLE_0B)
+		dw_i2c_enable(i2c_base, true);
 
 	return 0;
 }
-- 
1.9.1



More information about the U-Boot mailing list