From mboxrd@z Thu Jan 1 00:00:00 1970 From: Heiko Schocher Date: Sun, 24 Jun 2012 10:51:55 +0200 Subject: [U-Boot] [PATCH 17/24] mxc_i2c: add bus recovery support In-Reply-To: <1340338339-11626-17-git-send-email-troy.kisky@boundarydevices.com> References: <1340338339-11626-1-git-send-email-troy.kisky@boundarydevices.com> <1340338339-11626-17-git-send-email-troy.kisky@boundarydevices.com> Message-ID: <4FE6D52B.2060505@denx.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hello Troy, On 22.06.2012 06:12, Troy Kisky wrote: > Toggling the scl line 9 clocks is the standard > way of returning a locked up bus to idle condition. > > Signed-off-by: Troy Kisky > --- > drivers/i2c/mxc_i2c.c | 26 ++++++++++++++++++++++++++ > 1 file changed, 26 insertions(+) > > diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c > index ec05798..339bb6f 100644 > --- a/drivers/i2c/mxc_i2c.c > +++ b/drivers/i2c/mxc_i2c.c > @@ -246,6 +246,8 @@ static int i2c_init_transfer_(struct mxc_i2c_regs *i2c_regs, > return 0; > } > > +static void toggle_i2c(void *i2c_regs); > + > static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs, > uchar chip, uint addr, int alen) > { > @@ -264,6 +266,7 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs, > if (ret != -ERESTART) > writeb(0,&i2c_regs->i2cr); /* Disable controller */ > udelay(100); > + toggle_i2c(i2c_regs); > } > printf("%s: give up i2c_regs=%p\n", __func__, i2c_regs); > return ret; > @@ -381,6 +384,29 @@ void *get_base(void) > #endif > } > > +static struct i2c_parms *i2c_get_parms(void *base) > +{ > + int i = 0; > + struct i2c_parms *p = g_parms; > + while (i< ARRAY_SIZE(g_parms)) { > + if (p->base == base) > + return p; > + p++; > + i++; > + } > + printf("Invalid I2C base: %p\n", base); > + return NULL; > +} > + > +static void toggle_i2c(void *base) > +{ > + struct i2c_parms *p = i2c_get_parms(base); > + if (!p) > + return; > + if (p->toggle_fn) > + p->toggle_fn(p->toggle_data); > +} > + > int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) > { > return bus_i2c_read(get_base(), chip, addr, alen, buf, len); Hmm.. why you cannot use the CONFIG_SYS_I2C_INIT_BOARD and i2c_init_board() for unblocking the i2c bus? And where is the function, which really toggles the SCL pin, as you described in the commit message? bye, Heiko -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany