i2c: designware_i2c: Restore enable state after set speed
authorJun Chen <ptchentw@gmail.com>
Wed, 5 Jun 2019 07:23:16 +0000 (15:23 +0800)
committerHeiko Schocher <hs@denx.de>
Tue, 9 Jul 2019 05:02:10 +0000 (07:02 +0200)
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@gmail.com>
drivers/i2c/designware_i2c.c

index 9ccc2411a62a521bbaad9cadcdf46273136d7801..d11d47d246e464c3bb513f224918ae1dceddc26c 100644 (file)
@@ -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;
 }