
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 Kiskytroy.kisky@boundarydevices.com
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);
} printf("%s: give up i2c_regs=%p\n", __func__, i2c_regs); return ret;toggle_i2c(i2c_regs);
@@ -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