|
@@ -27,6 +27,8 @@
|
|
|
|
|
|
#include "omap24xx_i2c.h"
|
|
#include "omap24xx_i2c.h"
|
|
|
|
|
|
|
|
+#define I2C_TIMEOUT 10
|
|
|
|
+
|
|
static void wait_for_bb (void);
|
|
static void wait_for_bb (void);
|
|
static u16 wait_for_pin (void);
|
|
static u16 wait_for_pin (void);
|
|
static void flush_fifo(void);
|
|
static void flush_fifo(void);
|
|
@@ -41,6 +43,7 @@ void i2c_init (int speed, int slaveadd)
|
|
int psc, fsscll, fssclh;
|
|
int psc, fsscll, fssclh;
|
|
int hsscll = 0, hssclh = 0;
|
|
int hsscll = 0, hssclh = 0;
|
|
u32 scll, sclh;
|
|
u32 scll, sclh;
|
|
|
|
+ int timeout = I2C_TIMEOUT;
|
|
|
|
|
|
/* Only handle standard, fast and high speeds */
|
|
/* Only handle standard, fast and high speeds */
|
|
if ((speed != OMAP_I2C_STANDARD) &&
|
|
if ((speed != OMAP_I2C_STANDARD) &&
|
|
@@ -102,15 +105,24 @@ void i2c_init (int speed, int slaveadd)
|
|
sclh = (unsigned int)fssclh;
|
|
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) {
|
|
if (readw (&i2c_base->con) & I2C_CON_EN) {
|
|
writew (0, &i2c_base->con);
|
|
writew (0, &i2c_base->con);
|
|
udelay (50000);
|
|
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(psc, &i2c_base->psc);
|
|
writew(scll, &i2c_base->scll);
|
|
writew(scll, &i2c_base->scll);
|
|
writew(sclh, &i2c_base->sclh);
|
|
writew(sclh, &i2c_base->sclh);
|
|
@@ -159,15 +171,14 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
|
|
}
|
|
}
|
|
|
|
|
|
if (!i2c_error) {
|
|
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);
|
|
udelay (10000);
|
|
/* Have to clear pending interrupt to clear I2C_STAT */
|
|
/* Have to clear pending interrupt to clear I2C_STAT */
|
|
writew (0xFFFF, &i2c_base->stat);
|
|
writew (0xFFFF, &i2c_base->stat);
|
|
}
|
|
}
|
|
|
|
|
|
- wait_for_bb ();
|
|
|
|
/* set slave address */
|
|
/* set slave address */
|
|
writew (devaddr, &i2c_base->sa);
|
|
writew (devaddr, &i2c_base->sa);
|
|
/* read one byte from slave */
|
|
/* read one byte from slave */
|
|
@@ -191,8 +202,8 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
|
|
|
|
|
|
if (!i2c_error) {
|
|
if (!i2c_error) {
|
|
writew (I2C_CON_EN, &i2c_base->con);
|
|
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);
|
|
udelay (10000);
|
|
writew (0xFFFF, &i2c_base->stat);
|
|
writew (0xFFFF, &i2c_base->stat);
|
|
}
|
|
}
|