
This helps in a multiple bus master environment which is why I also added a wait for bus idle.
Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- drivers/i2c/mxc_i2c.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-)
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c index 2ef7b92..e433312 100644 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@ -190,22 +190,16 @@ static int tx_byte(struct mxc_i2c_regs *i2c_regs, u8 byte) }
/* - * Stop the controller + * Stop I2C transaction */ void i2c_imx_stop(void) { struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; - unsigned int temp = 0; + unsigned int temp = readb(&i2c_regs->i2cr);
- /* Stop I2C transaction */ - temp = readb(&i2c_regs->i2cr); temp &= ~(I2CR_MSTA | I2CR_MTX); writeb(temp, &i2c_regs->i2cr); - wait_for_sr_state(i2c_regs, ST_BUS_IDLE); - - /* Disable I2C controller */ - writeb(0, &i2c_regs->i2cr); }
/* @@ -219,11 +213,15 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs, int ret;
/* Enable I2C controller */ + if (!(readb(&i2c_regs->i2cr) & I2CR_IEN)) { + writeb(I2CR_IEN, &i2c_regs->i2cr); + /* Wait for controller to be stable */ + udelay(50); + } writeb(0, &i2c_regs->i2sr); - writeb(I2CR_IEN, &i2c_regs->i2cr); - - /* Wait for controller to be stable */ - udelay(50); + ret = wait_for_sr_state(i2c_regs, ST_BUS_IDLE); + if (ret < 0) + goto exit;
/* Start I2C transaction */ temp = readb(&i2c_regs->i2cr); @@ -250,6 +248,8 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs, return 0; exit: i2c_imx_stop(); + /* Disable I2C controller */ + writeb(0, &i2c_regs->i2cr); return ret; }
@@ -294,10 +294,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) * controller from generating another clock cycle */ if (i == (len - 1)) { - temp = readb(&i2c_regs->i2cr); - temp &= ~(I2CR_MSTA | I2CR_MTX); - writeb(temp, &i2c_regs->i2cr); - wait_for_sr_state(i2c_regs, ST_BUS_IDLE); + i2c_imx_stop(i2c_regs); } else if (i == (len - 2)) { temp = readb(&i2c_regs->i2cr); temp |= I2CR_TX_NO_AK;