summaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
authorAngelo Dureghello <angelo@kernel-space.org>2023-04-05 00:59:26 +0200
committerHeiko Schocher <hs@denx.de>2023-04-11 06:51:56 +0200
commitb6afa7cf62d7d3c618454009707a458a15a22942 (patch)
tree355118744f5a73c4b8d5df19998eeb0e2aa13e97 /drivers/i2c
parent987e20e5931df5b8e30f4ab363fe6c6adf94704f (diff)
downloadu-boot-b6afa7cf62d7d3c618454009707a458a15a22942.tar.gz
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>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/fsl_i2c.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c
index d312f35f04..d9d8ee81d2 100644
--- a/drivers/i2c/fsl_i2c.c
+++ b/drivers/i2c/fsl_i2c.c
@@ -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);
}