From patchwork Thu Oct 27 01:29:39 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [U-Boot, 2/2] Powerpc/i2c: Force i2c to become bus master out of reset Date: Wed, 26 Oct 2011 15:29:39 -0000 From: Jerry Huang X-Patchwork-Id: 122053 Message-Id: <1319678979-23491-2-git-send-email-Chang-Ming.Huang@freescale.com> To: Cc: Jerry Huang From: Jerry Huang It is sometimes necessary to force the I2C module to become the I2C bus master out of reset and drive SCL(even though SDA may already be driven, which indicates that the bus is busy). This can occur when a system reset does not cause all I2C devices to be reset. Thus, SDA can be driven low by another I2C device while this I2C module is coming out of reset and stays low indefinitely. The following procedure can be used to force this I2C module to generate SCL so that the device driving SDA can finish its transaction. Signed-off-by: Jerry Huang --- drivers/i2c/fsl_i2c.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c index 258be0a..007db70 100644 --- a/drivers/i2c/fsl_i2c.c +++ b/drivers/i2c/fsl_i2c.c @@ -252,6 +252,24 @@ i2c_init(int speed, int slaveadd) writeb(slaveadd << 1, &dev->adr);/* write slave address */ writeb(0x0, &dev->sr); /* clear status register */ writeb(I2C_CR_MEN, &dev->cr); /* start I2C controller */ + + /* Force I2C module to become bus master which can occure when + * a system reset does not cause all I2C devices to be reset */ + udelay(5); + if (readb(&dev->sr) & I2C_SR_MBB) { + writeb(I2C_CR_MSTA, &dev->cr); + udelay(5); + writeb(I2C_CR_MEN | I2C_CR_MSTA, &dev->cr); + udelay(5); + readb(&dev->dr); + udelay(5); + writeb(I2C_CR_MEN, &dev->cr); + udelay(5); + if (readb(&dev->sr) & I2C_SR_MBB) + debug("I2C%d: Drive SCL failed\n", i + 1); + else + debug("I2C%d: Drive SCL succeed\n", i + 1); + } } #ifdef CONFIG_SYS_I2C_BOARD_LATE_INIT