
drivers_i2c_fsl_i2c.patch - need to set I2C to be idle according to the MCF5282 user's manual
If I2SR[IBB] is set when the I2C bus module is enabled, execute the following code sequence before proceeding with normal initialization code. This issues a STOP command to the slave device, placing it in idle state as if it were just power-cycled on.
I2CR = 0x0 I2CR = 0xA dummy read of I2DR I2SR = 0x0 I2CR = 0x0
Signed-off-by: David Wu davidwu@arcturusnetworks.com Signed-off-by: Michael Durrant mdurrant@arcturusnetworks.com --- drivers/i2c/fsl_i2c.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c index 2241990..bce750c 100644 --- a/drivers/i2c/fsl_i2c.c +++ b/drivers/i2c/fsl_i2c.c @@ -251,12 +251,25 @@ i2c_init(int speed, int slaveadd) #endif }
+static __inline__ int i2c_set_idle(void) +{ + writeb(0, &i2c_dev[i2c_bus_num]->cr); + writeb(I2C_CR_MEN | I2C_CR_MSTA, &i2c_dev[i2c_bus_num]->cr); + readb(&i2c_dev[i2c_bus_num]->dr); + writeb(0, &i2c_dev[i2c_bus_num]->sr); + writeb(0, &i2c_dev[i2c_bus_num]->cr); + writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr); +} + static int i2c_wait4bus(void) { unsigned long long timeval = get_ticks(); const unsigned long long timeout = usec2ticks(CONFIG_I2C_MBB_TIMEOUT);
+ if (readb(&i2c_dev[i2c_bus_num]->sr) & I2C_SR_MBB) + i2c_set_idle(); + while (readb(&i2c_dev[i2c_bus_num]->sr) & I2C_SR_MBB) { if ((get_ticks() - timeval) > timeout) return -1; -- 1.4.3.4