diff options
Diffstat (limited to 'drivers/i2c/omap24xx_i2c.c')
| -rw-r--r-- | drivers/i2c/omap24xx_i2c.c | 31 | 
1 files changed, 21 insertions, 10 deletions
| diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c index 3256133dc..7c98f150d 100644 --- a/drivers/i2c/omap24xx_i2c.c +++ b/drivers/i2c/omap24xx_i2c.c @@ -27,6 +27,8 @@  #include "omap24xx_i2c.h" +#define I2C_TIMEOUT	10 +  static void wait_for_bb (void);  static u16 wait_for_pin (void);  static void flush_fifo(void); @@ -41,6 +43,7 @@ void i2c_init (int speed, int slaveadd)  	int psc, fsscll, fssclh;  	int hsscll = 0, hssclh = 0;  	u32 scll, sclh; +	int timeout = I2C_TIMEOUT;  	/* Only handle standard, fast and high speeds */  	if ((speed != OMAP_I2C_STANDARD) && @@ -102,15 +105,24 @@ void i2c_init (int speed, int slaveadd)  		sclh = (unsigned int)fssclh;  	} -	writew(0x2, &i2c_base->sysc); /* for ES2 after soft reset */ -	udelay(1000); -	writew(0x0, &i2c_base->sysc); /* will probably self clear but */ -  	if (readw (&i2c_base->con) & I2C_CON_EN) {  		writew (0, &i2c_base->con);  		udelay (50000);  	} +	writew(0x2, &i2c_base->sysc); /* for ES2 after soft reset */ +	udelay(1000); + +	writew(I2C_CON_EN, &i2c_base->con); +	while (!(readw(&i2c_base->syss) & I2C_SYSS_RDONE) && timeout--) { +		if (timeout <= 0) { +			printf("ERROR: Timeout in soft-reset\n"); +			return; +		} +		udelay(1000); +	} + +	writew(0, &i2c_base->con);  	writew(psc, &i2c_base->psc);  	writew(scll, &i2c_base->scll);  	writew(sclh, &i2c_base->sclh); @@ -159,15 +171,14 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)  	}  	if (!i2c_error) { -		/* free bus, otherwise we can't use a combined transction */ -		writew (0, &i2c_base->con); -		while (readw (&i2c_base->stat) || (readw (&i2c_base->con) & I2C_CON_MST)) { +		writew (I2C_CON_EN, &i2c_base->con); +		while (readw(&i2c_base->stat) & +			(I2C_STAT_XRDY | I2C_STAT_ARDY)) {  			udelay (10000);  			/* Have to clear pending interrupt to clear I2C_STAT */  			writew (0xFFFF, &i2c_base->stat);  		} -		wait_for_bb ();  		/* set slave address */  		writew (devaddr, &i2c_base->sa);  		/* read one byte from slave */ @@ -191,8 +202,8 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)  		if (!i2c_error) {  			writew (I2C_CON_EN, &i2c_base->con); -			while (readw (&i2c_base->stat) -			       || (readw (&i2c_base->con) & I2C_CON_MST)) { +			while (readw (&i2c_base->stat) & +				(I2C_STAT_RRDY | I2C_STAT_ARDY)) {  				udelay (10000);  				writew (0xFFFF, &i2c_base->stat);  			} |