Huang Changming-R66093 <r66...@freescale.com> wrote on 2011/10/27 09:51:49: > > > > Thanks and Best Regards > Jerry Huang > > > > -----Original Message----- > > From: u-boot-boun...@lists.denx.de [mailto:u-boot-boun...@lists.denx.de] > > On Behalf Of Huang Changming-R66093 > > Sent: Thursday, October 27, 2011 3:40 PM > > To: Joakim Tjernlund > > Cc: u-boot@lists.denx.de > > Subject: Re: [U-Boot] [PATCH 2/2] Powerpc/i2c: Force i2c to become bus > > master out of reset > > > > > > > > Thanks and Best Regards > > Jerry Huang > > > > > > > -----Original Message----- > > > From: Joakim Tjernlund [mailto:joakim.tjernl...@transmode.se] > > > Sent: Thursday, October 27, 2011 3:26 PM > > > To: Huang Changming-R66093 > > > Cc: u-boot@lists.denx.de > > > Subject: Re: [U-Boot] [PATCH 2/2] Powerpc/i2c: Force i2c to become > > bus > > > master out of reset > > > > > > > From: <chang-ming.hu...@freescale.com> > > > > > > > > From: Jerry Huang <chang-ming.hu...@freescale.com> > > > > > > > > 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 <chang-ming.hu...@freescale.com> > > > > --- > > > > 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) { > > > > > > You need to the sequence unconditionally, the slave can be stuck > > > without driving SCL. > > > > > > > + 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); > > > > + } > > > > > > The above sequence is different than the kernel version, why? > > > > I don't know the kernel version, but I write the u-boot code according > > to the Reference Manual of PowerPC, e.g p1022: > > 11.5.6 Generation of SCL When SDA Low > > 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: > > 1. Disable the I2C module and set the master bit by setting I2CCR to > > 0x20 > > 2. Enable the I2C module by setting I2CCR to 0xA0 > > 3. Read the I2CDR > > 4. Return the I2C module to slave mode by setting I2CCR to 0x80 > > > Compare with kernel version, the difference is one line: > Uboot: readb(&dev->dr); > Kernel has no any operation. > But, I check the comment of kernel, because the 9th clock pulse isn't > generated, > the sequence of function mpc_i2c_fixup is needed to generate 9th clock pulse.
Not so, there is more than that if you look closer. The description in the kernel is a bit misleading(or so I think). I prefer the kernel version for 2 reasons: 1) It has been there for quite some time so if there were something wrong with, it should have been noticed by now. 2) I have a vauge memory of checking it again the mpc8321 manual and I was happy with it. Jocke _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot