From: Stanley Chu <[email protected]> Add deblock callback to perform I2C bus recovery through the reset command. The recovery always resets the controller status, even if the bus is not stuck.
Signed-off-by: Stanley Chu <[email protected]> Signed-off-by: Jim Liu <[email protected]> --- drivers/i2c/npcm_i2c.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/npcm_i2c.c b/drivers/i2c/npcm_i2c.c index cc1847893f6..acde0b03c68 100644 --- a/drivers/i2c/npcm_i2c.c +++ b/drivers/i2c/npcm_i2c.c @@ -215,7 +215,7 @@ static void npcm_i2c_reset(struct npcm_i2c_bus *bus) { struct npcm_i2c_regs *reg = bus->reg; - debug("%s: module %d\n", __func__, bus->num); + printf("%s: module %d\n", __func__, bus->num); /* disable & enable SMB moudle */ clrbits_8(®->ctl2, SMBCTL2_ENABLE); setbits_8(®->ctl2, SMBCTL2_ENABLE); @@ -250,7 +250,7 @@ static void npcm_i2c_recovery(struct npcm_i2c_bus *bus, u32 addr) val = readb(®->ctl3); /* Skip recovery, bus not stucked */ if ((val & SMBCTL3_SCL_LVL) && (val & SMBCTL3_SDA_LVL)) - return; + goto reset; printf("Performing I2C bus %d recovery...\n", bus->num); /* SCL/SDA are not releaed, perform recovery */ @@ -281,6 +281,7 @@ static void npcm_i2c_recovery(struct npcm_i2c_bus *bus, u32 addr) } else { printf("Fail to recover I2C bus %d\n", bus->num); } +reset: npcm_i2c_reset(bus); } @@ -513,7 +514,7 @@ static int npcm_i2c_xfer(struct udevice *dev, if (bus->started) npcm_i2c_send_stop(bus, true); - if (err) + if (err && err != I2C_ERR_NACK) npcm_i2c_recovery(bus, msg->addr); return ret; @@ -560,6 +561,13 @@ static int npcm_i2c_set_bus_speed(struct udevice *dev, return npcm_i2c_init_clk(bus, speed); } +static int npcm_i2c_deblock(struct udevice *dev) +{ + npcm_i2c_recovery(dev_get_priv(dev), 0); + + return 0; +} + static int npcm_i2c_probe(struct udevice *dev) { struct npcm_i2c_bus *bus = dev_get_priv(dev); @@ -626,6 +634,7 @@ static int npcm_i2c_probe(struct udevice *dev) static const struct dm_i2c_ops nuvoton_i2c_ops = { .xfer = npcm_i2c_xfer, .set_bus_speed = npcm_i2c_set_bus_speed, + .deblock = npcm_i2c_deblock, }; static const struct udevice_id nuvoton_i2c_of_match[] = { -- 2.34.1
