diff options
author | Conor Dooley <conor.dooley@microchip.com> | 2022-10-26 08:49:18 +0100 |
---|---|---|
committer | Heiko Schocher <hs@denx.de> | 2022-11-14 07:20:10 +0100 |
commit | 95b22bd6dcf198340b0c40a906a463064c215b0c (patch) | |
tree | 069dc353e0ca1878499e1333101cb09bdc3237d7 /drivers | |
parent | 0cbeed4f6648e0e4966475e3544280a69ecb59d3 (diff) | |
download | u-boot-95b22bd6dcf198340b0c40a906a463064c215b0c.zip u-boot-95b22bd6dcf198340b0c40a906a463064c215b0c.tar.gz u-boot-95b22bd6dcf198340b0c40a906a463064c215b0c.tar.bz2 |
i2c: microchip: fix ack sending logic
"Master receive mode" was not correctly sending ACKs/NACKs in the
interrupt handler. Bring the handling of M_SLAR_ACK, M_RX_DATA_ACKED &
M_RX_DATA_NACKED in line with the Linux driver.
Fixes: 0dc0d1e094 ("i2c: Add Microchip PolarFire SoC I2C driver")
Reported-by: Shravan Chippa <shravan.chippa@microchip.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Padmarao Begari <padmarao.begari@microchip.com>
Reviewed-by: Heiko Schocher <hs@denx.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/i2c-microchip.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/i2c/i2c-microchip.c b/drivers/i2c/i2c-microchip.c index 12f65d0..3a27459 100644 --- a/drivers/i2c/i2c-microchip.c +++ b/drivers/i2c/i2c-microchip.c @@ -2,8 +2,9 @@ /* * Microchip I2C controller driver * - * Copyright (C) 2021 Microchip Technology Inc. + * Copyright (C) 2021-2022 Microchip Technology Inc. * Padmarao Begari <padmarao.begari@microchip.com> + * Conor Dooley <conor.dooley@microchip.com> */ #include <common.h> #include <clk.h> @@ -265,10 +266,18 @@ static int mpfs_i2c_service_handler(struct mpfs_i2c_bus *bus) } break; case STATUS_M_SLAR_ACK: - ctrl = readl(bus->base + MPFS_I2C_CTRL); - ctrl |= CTRL_AA; - writel(ctrl, bus->base + MPFS_I2C_CTRL); - if (bus->msg_len == 0) { + if (bus->msg_len > 1u) { + ctrl = readl(bus->base + MPFS_I2C_CTRL); + ctrl |= CTRL_AA; + writel(ctrl, bus->base + MPFS_I2C_CTRL); + } else if (bus->msg_len == 1u) { + ctrl = readl(bus->base + MPFS_I2C_CTRL); + ctrl &= ~CTRL_AA; + writel(ctrl, bus->base + MPFS_I2C_CTRL); + } else { + ctrl = readl(bus->base + MPFS_I2C_CTRL); + ctrl |= CTRL_AA; + writel(ctrl, bus->base + MPFS_I2C_CTRL); /* On the last byte to be transmitted, send STOP */ mpfs_i2c_stop(bus); finish = true; @@ -276,6 +285,9 @@ static int mpfs_i2c_service_handler(struct mpfs_i2c_bus *bus) break; case STATUS_M_RX_DATA_ACKED: mpfs_i2c_empty_rx(bus); + break; + case STATUS_M_RX_DATA_NACKED: + mpfs_i2c_empty_rx(bus); if (bus->msg_len == 0) { /* On the last byte to be transmitted, send STOP */ mpfs_i2c_stop(bus); @@ -283,7 +295,6 @@ static int mpfs_i2c_service_handler(struct mpfs_i2c_bus *bus) } break; case STATUS_M_TX_DATA_NACK: - case STATUS_M_RX_DATA_NACKED: case STATUS_M_SLAR_NACK: case STATUS_M_SLAW_NACK: bus->msg_err = -ENXIO; |