mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-02-17 22:49:02 +00:00
i2c: fsl_i2c: fix m68k transferts
This driver is actually used for powerpc and m68k/ColdFire. On ColdFire SoC's, interrupt flag get not set if IIEN flag (mbcr bit6, interrupt enabled) is not set appropriately before each transfert. As a result, the transfert hangs forever waiting for IIEN. This patch set IIEN before each transfert, while considering this fix as not harming powerpc arch. Signed-off-by: Angelo Dureghello <angelo@kernel-space.org>
This commit is contained in:
parent
987e20e593
commit
b6afa7cf62
2 changed files with 19 additions and 7 deletions
|
@ -57,4 +57,14 @@ typedef struct fsl_i2c_base {
|
|||
#define I2C_DR_RES ~(I2C_DR)
|
||||
} fsl_i2c_t;
|
||||
|
||||
#if CONFIG_IS_ENABLED(DM_I2C)
|
||||
struct fsl_i2c_dev {
|
||||
struct fsl_i2c_base __iomem *base; /* register base */
|
||||
u32 i2c_clk;
|
||||
u32 index;
|
||||
u8 slaveadd;
|
||||
uint speed;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_I2C_H_ */
|
||||
|
|
|
@ -278,7 +278,8 @@ static void __i2c_init(const struct fsl_i2c_base *base, int speed, int
|
|||
set_i2c_bus_speed(base, i2c_clk, speed);
|
||||
writeb(slaveadd << 1, &base->adr);/* write slave address */
|
||||
writeb(0x0, &base->sr); /* clear status register */
|
||||
writeb(I2C_CR_MEN, &base->cr); /* start I2C controller */
|
||||
/* start I2C controller */
|
||||
writeb(I2C_CR_MEN | I2C_CR_MIEN, &base->cr);
|
||||
|
||||
timeval = get_ticks();
|
||||
while (readb(&base->sr) & I2C_SR_MBB) {
|
||||
|
@ -346,7 +347,7 @@ static int i2c_wait(const struct fsl_i2c_base *base, int write)
|
|||
static int i2c_write_addr(const struct fsl_i2c_base *base, u8 dev,
|
||||
u8 dir, int rsta)
|
||||
{
|
||||
writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX
|
||||
writeb(I2C_CR_MEN | I2C_CR_MIEN | I2C_CR_MSTA | I2C_CR_MTX
|
||||
| (rsta ? I2C_CR_RSTA : 0),
|
||||
&base->cr);
|
||||
|
||||
|
@ -378,7 +379,8 @@ static int __i2c_read_data(const struct fsl_i2c_base *base, u8 *data,
|
|||
{
|
||||
int i;
|
||||
|
||||
writeb(I2C_CR_MEN | I2C_CR_MSTA | ((length == 1) ? I2C_CR_TXAK : 0),
|
||||
writeb(I2C_CR_MEN | I2C_CR_MIEN |
|
||||
I2C_CR_MSTA | ((length == 1) ? I2C_CR_TXAK : 0),
|
||||
&base->cr);
|
||||
|
||||
/* dummy read */
|
||||
|
@ -390,13 +392,13 @@ static int __i2c_read_data(const struct fsl_i2c_base *base, u8 *data,
|
|||
|
||||
/* Generate ack on last next to last byte */
|
||||
if (i == length - 2)
|
||||
writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_TXAK,
|
||||
&base->cr);
|
||||
writeb(I2C_CR_MEN | I2C_CR_MIEN | I2C_CR_MSTA |
|
||||
I2C_CR_TXAK, &base->cr);
|
||||
|
||||
/* Do not generate stop on last byte */
|
||||
if (i == length - 1)
|
||||
writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX,
|
||||
&base->cr);
|
||||
writeb(I2C_CR_MEN | I2C_CR_MIEN | I2C_CR_MSTA |
|
||||
I2C_CR_MTX, &base->cr);
|
||||
|
||||
data[i] = readb(&base->dr);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue