diff options
author | Steve Sakoman <steve@sakoman.com> | 2010-10-20 06:07:47 -0700 |
---|---|---|
committer | Heiko Schocher <hs@denx.de> | 2010-10-20 15:28:48 +0200 |
commit | fbad3555624a738a632ddb1b968e98a20e743941 (patch) | |
tree | 2114222b2e3ec711fd980187aba040939b0bc33f /drivers | |
parent | d480c4677315f15f155b64a14aa679adf27704c5 (diff) | |
download | u-boot-imx-fbad3555624a738a632ddb1b968e98a20e743941.zip u-boot-imx-fbad3555624a738a632ddb1b968e98a20e743941.tar.gz u-boot-imx-fbad3555624a738a632ddb1b968e98a20e743941.tar.bz2 |
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 <steve.sakoman@linaro.org>
Tested-by: Heiko Schocher <hs@denx.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/omap24xx_i2c.c | 41 |
1 files changed, 30 insertions, 11 deletions
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); |