From fbad3555624a738a632ddb1b968e98a20e743941 Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Wed, 20 Oct 2010 06:07:47 -0700 Subject: ARMV7: OMAP: I2C driver: Restructure i2c_probe function This patch removes the "magic number" delays and instead monitors state changes in the status register bits. Signed-off-by: Steve Sakoman Tested-by: Heiko Schocher --- drivers/i2c/omap24xx_i2c.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c index 35201c3..a72d1a1 100644 --- a/drivers/i2c/omap24xx_i2c.c +++ b/drivers/i2c/omap24xx_i2c.c @@ -310,6 +310,7 @@ static void flush_fifo(void) int i2c_probe (uchar chip) { + u16 status; int res = 1; /* default = fail */ if (chip == readw (&i2c_base->oa)) { @@ -325,19 +326,37 @@ int i2c_probe (uchar chip) writew (chip, &i2c_base->sa); /* stop bit needed here */ writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, &i2c_base->con); - /* enough delay for the NACK bit set */ - udelay (50000); - if (!(readw (&i2c_base->stat) & I2C_STAT_NACK)) { - res = 0; /* success case */ - flush_fifo(); - writew(0xFFFF, &i2c_base->stat); - } else { - writew(0xFFFF, &i2c_base->stat); /* failue, clear sources*/ - writew (readw (&i2c_base->con) | I2C_CON_STP, &i2c_base->con); /* finish up xfer */ - udelay(20000); - wait_for_bb (); + while (1) { + status = wait_for_pin(); + if (status == 0) { + res = 1; + goto probe_exit; + } + if (status & I2C_STAT_NACK) { + res = 1; + writew(0xff, &i2c_base->stat); + writew (readw (&i2c_base->con) | I2C_CON_STP, &i2c_base->con); + wait_for_bb (); + break; + } + if (status & I2C_STAT_ARDY) { + writew(I2C_STAT_ARDY, &i2c_base->stat); + break; + } + if (status & I2C_STAT_RRDY) { + res = 0; +#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \ + defined(CONFIG_OMAP44XX) + readb(&i2c_base->data); +#else + readw(&i2c_base->data); +#endif + writew(I2C_STAT_RRDY, &i2c_base->stat); + } } + +probe_exit: flush_fifo(); writew (0, &i2c_base->cnt); /* don't allow any more data in...we don't want it.*/ writew(0xFFFF, &i2c_base->stat); -- cgit v1.1