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/i2c | |
| parent | d480c4677315f15f155b64a14aa679adf27704c5 (diff) | |
| download | olio-uboot-2014.01-fbad3555624a738a632ddb1b968e98a20e743941.tar.xz olio-uboot-2014.01-fbad3555624a738a632ddb1b968e98a20e743941.zip | |
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/i2c')
| -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 35201c381..a72d1a125 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); |