mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-24 20:54:24 +08:00
mpc83xx: Fix empty i2c reads/writes in fsl_i2c.c
Fix empty i2c reads/writes, i2c_write(0x50, 0x00, 0, NULL, 0) which is used to se if an slave will ACK after receiving its address. Correct i2c probing to use this method as the old method could upset a slave as it wrote a data byte to it. Add a small delay in i2c_init() to let the controller shutdown any ongoing I2C activity. Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
This commit is contained in:
parent
7a78f148d6
commit
f6f5f709e5
@ -58,6 +58,7 @@ i2c_init(int speed, int slaveadd)
|
|||||||
dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET);
|
dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET);
|
||||||
|
|
||||||
writeb(0, &dev->cr); /* stop I2C controller */
|
writeb(0, &dev->cr); /* stop I2C controller */
|
||||||
|
udelay(5); /* let it shutdown in peace */
|
||||||
writeb(0x3F, &dev->fdr); /* set bus speed */
|
writeb(0x3F, &dev->fdr); /* set bus speed */
|
||||||
writeb(0x3F, &dev->dfsrr); /* set default filter */
|
writeb(0x3F, &dev->dfsrr); /* set default filter */
|
||||||
writeb(slaveadd << 1, &dev->adr); /* write slave address */
|
writeb(slaveadd << 1, &dev->adr); /* write slave address */
|
||||||
@ -191,15 +192,17 @@ __i2c_read(u8 *data, int length)
|
|||||||
int
|
int
|
||||||
i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
|
i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = -1; /* signal error */
|
||||||
u8 *a = (u8*)&addr;
|
u8 *a = (u8*)&addr;
|
||||||
|
|
||||||
if (i2c_wait4bus() >= 0
|
if (i2c_wait4bus() >= 0
|
||||||
&& i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0
|
&& i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0
|
||||||
&& __i2c_write(&a[4 - alen], alen) == alen
|
&& __i2c_write(&a[4 - alen], alen) == alen)
|
||||||
&& i2c_write_addr(dev, I2C_READ_BIT, 1) != 0) {
|
i = 0; /* No error so far */
|
||||||
|
|
||||||
|
if (length
|
||||||
|
&& i2c_write_addr(dev, I2C_READ_BIT, 1) != 0)
|
||||||
i = __i2c_read(data, length);
|
i = __i2c_read(data, length);
|
||||||
}
|
|
||||||
|
|
||||||
writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
|
writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
|
||||||
|
|
||||||
@ -212,7 +215,7 @@ i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
|
|||||||
int
|
int
|
||||||
i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
|
i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = -1; /* signal error */
|
||||||
u8 *a = (u8*)&addr;
|
u8 *a = (u8*)&addr;
|
||||||
|
|
||||||
if (i2c_wait4bus() >= 0
|
if (i2c_wait4bus() >= 0
|
||||||
@ -232,16 +235,14 @@ i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
|
|||||||
int
|
int
|
||||||
i2c_probe(uchar chip)
|
i2c_probe(uchar chip)
|
||||||
{
|
{
|
||||||
int tmp;
|
/* For unknow reason the controller will ACK when
|
||||||
|
* probing for a slave with the same address, so skip
|
||||||
/*
|
* it.
|
||||||
* Try to read the first location of the chip. The underlying
|
|
||||||
* driver doesn't appear to support sending just the chip address
|
|
||||||
* and looking for an <ACK> back.
|
|
||||||
*/
|
*/
|
||||||
udelay(10000);
|
if (chip == (readb(&i2c_dev[i2c_bus_num]->adr) >> 1))
|
||||||
|
return -1;
|
||||||
|
|
||||||
return i2c_read(chip, 0, 1, (uchar *)&tmp, 1);
|
return i2c_read(chip, 0, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uchar
|
uchar
|
||||||
|
Loading…
Reference in New Issue
Block a user