Hi Stefan, On Fri, Mar 18, 2016 at 3:54 PM, Stefan Roese <s...@denx.de> wrote: > dw_i2c_enable() is used to dis-/en-able the I2C controller. It makes > sense to add such a function, as the controller is dis-/en-abled > multiple times in the code. Additionally, this function now checks, > if the controller is really dis-/en-abled. This code is copied > from the Linux I2C driver version. > > Signed-off-by: Stefan Roese <s...@denx.de> > Cc: Simon Glass <s...@chromium.org> > Cc: Bin Meng <bmeng...@gmail.com> > Cc: Marek Vasut <ma...@denx.de> > Cc: Heiko Schocher <h...@denx.de> > --- > drivers/i2c/designware_i2c.c | 46 > +++++++++++++++++++++++++------------------- > 1 file changed, 26 insertions(+), 20 deletions(-) > > diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c > index e768cde..c8ea520 100644 > --- a/drivers/i2c/designware_i2c.c > +++ b/drivers/i2c/designware_i2c.c > @@ -34,6 +34,26 @@ static struct i2c_regs *i2c_get_base(struct i2c_adapter > *adap) > return NULL; > } > > +static void dw_i2c_enable(struct i2c_regs *i2c_base, bool enable) > +{ > + int timeout = 100; > + > + do { > + writel(enable, &i2c_base->ic_enable); > + if ((readl(&i2c_base->ic_enable_status) & 1) == enable) > + return; > + > + /* > + * Wait 10 times the signaling period of the highest I2C > + * transfer supported by the driver (for 400KHz this is > + * 25us) as described in the DesignWare I2C databook. > + */ > + udelay(25); > + } while (timeout--); > + > + printf("timeout in %sabling I2C adapter\n", enable ? "en" : "dis"); > +} > + > /* > * set_speed - Set the i2c speed mode (standard, high, fast) > * @i2c_spd: required i2c speed mode > @@ -45,12 +65,9 @@ static void set_speed(struct i2c_adapter *adap, int > i2c_spd) > struct i2c_regs *i2c_base = i2c_get_base(adap); > unsigned int cntl; > unsigned int hcnt, lcnt; > - unsigned int enbl; > > /* to set speed cltr must be disabled */ > - enbl = readl(&i2c_base->ic_enable); > - enbl &= ~IC_ENABLE_0B; > - writel(enbl, &i2c_base->ic_enable); > + dw_i2c_enable(i2c_base, 0);
nits: change 0 to false since the parameter type is bool? > > cntl = (readl(&i2c_base->ic_con) & (~IC_CON_SPD_MSK)); > > @@ -84,8 +101,7 @@ static void set_speed(struct i2c_adapter *adap, int > i2c_spd) > writel(cntl, &i2c_base->ic_con); > > /* Enable back i2c now speed set */ > - enbl |= IC_ENABLE_0B; > - writel(enbl, &i2c_base->ic_enable); > + dw_i2c_enable(i2c_base, 1); ditto, 1-> true? > } > > /* > @@ -123,12 +139,9 @@ static void dw_i2c_init(struct i2c_adapter *adap, int > speed, > int slaveaddr) > { > struct i2c_regs *i2c_base = i2c_get_base(adap); > - unsigned int enbl; > > /* Disable i2c */ > - enbl = readl(&i2c_base->ic_enable); > - enbl &= ~IC_ENABLE_0B; > - writel(enbl, &i2c_base->ic_enable); > + dw_i2c_enable(i2c_base, 0); ditto > > writel((IC_CON_SD | IC_CON_SPD_FS | IC_CON_MM), &i2c_base->ic_con); > writel(IC_RX_TL, &i2c_base->ic_rx_tl); > @@ -138,9 +151,7 @@ static void dw_i2c_init(struct i2c_adapter *adap, int > speed, > writel(slaveaddr, &i2c_base->ic_sar); > > /* Enable i2c */ > - enbl = readl(&i2c_base->ic_enable); > - enbl |= IC_ENABLE_0B; > - writel(enbl, &i2c_base->ic_enable); > + dw_i2c_enable(i2c_base, 1); ditto > } > > /* > @@ -152,19 +163,14 @@ static void dw_i2c_init(struct i2c_adapter *adap, int > speed, > static void i2c_setaddress(struct i2c_adapter *adap, unsigned int i2c_addr) > { > struct i2c_regs *i2c_base = i2c_get_base(adap); > - unsigned int enbl; > > /* Disable i2c */ > - enbl = readl(&i2c_base->ic_enable); > - enbl &= ~IC_ENABLE_0B; > - writel(enbl, &i2c_base->ic_enable); > + dw_i2c_enable(i2c_base, 0); > > writel(i2c_addr, &i2c_base->ic_tar); > > /* Enable i2c */ > - enbl = readl(&i2c_base->ic_enable); > - enbl |= IC_ENABLE_0B; > - writel(enbl, &i2c_base->ic_enable); > + dw_i2c_enable(i2c_base, 1); > } > Regards, Bin _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot