From 95b22bd6dcf198340b0c40a906a463064c215b0c Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Wed, 26 Oct 2022 08:49:18 +0100 Subject: 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 Signed-off-by: Conor Dooley Reviewed-by: Padmarao Begari Reviewed-by: Heiko Schocher --- drivers/i2c/i2c-microchip.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/i2c-microchip.c b/drivers/i2c/i2c-microchip.c index 12f65d0af75..3a274593868 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 + * Conor Dooley */ #include #include @@ -265,16 +266,27 @@ 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; } 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 */ @@ -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; -- cgit v1.2.3 From 6d133b31580a90e24fe95292a3e55aabe0fcc2da Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Wed, 26 Oct 2022 08:49:19 +0100 Subject: i2c: microchip: fix erroneous late ack send A late ack is currently being sent at the end of a transfer due to incorrect logic in mchp_corei2c_empty_rx(). Currently the Assert Ack bit is being written to the controller's control reg after the last byte has been received, causing it to sent another byte with the ack. Instead, the AA flag should be written to the control register when the penultimate byte is read so it is sent out for the last byte. Reported-by: Andreas Buerkler Fixes: 0dc0d1e094 ("i2c: Add Microchip PolarFire SoC I2C driver") Signed-off-by: Conor Dooley Reviewed-by: Padmarao Begari Reviewed-by: Heiko Schocher Removed Tag by hs: Fixes: 0190d48488 ("i2c: microchip: fix ack sending logic") --- drivers/i2c/i2c-microchip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/i2c-microchip.c b/drivers/i2c/i2c-microchip.c index 3a274593868..d82b80f5355 100644 --- a/drivers/i2c/i2c-microchip.c +++ b/drivers/i2c/i2c-microchip.c @@ -224,7 +224,7 @@ static void mpfs_i2c_empty_rx(struct mpfs_i2c_bus *bus) bus->msg_len--; } - if (bus->msg_len == 0) { + if (bus->msg_len <= 1) { ctrl = readl(bus->base + MPFS_I2C_CTRL); ctrl &= ~CTRL_AA; writel(ctrl, bus->base + MPFS_I2C_CTRL); -- cgit v1.2.3 From b0c485fd384b2706717d4c19fa9837c1d785e9e8 Mon Sep 17 00:00:00 2001 From: Sergei Antonov Date: Thu, 20 Oct 2022 17:28:14 +0300 Subject: i2c: i2c-gpio: add newline Add newline at the end of the printed string. Signed-off-by: Sergei Antonov Reviewed-by: Simon Glass Reviewed-by: Heiko Schocher --- drivers/i2c/i2c-gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/i2c-gpio.c b/drivers/i2c/i2c-gpio.c index 1aedad5c8ed..4ed9e9e7cdd 100644 --- a/drivers/i2c/i2c-gpio.c +++ b/drivers/i2c/i2c-gpio.c @@ -362,7 +362,7 @@ static int i2c_gpio_of_to_plat(struct udevice *dev) return 0; error: - pr_err("Can't get %s gpios! Error: %d", dev->name, ret); + pr_err("Can't get %s gpios! Error: %d\n", dev->name, ret); return ret; } -- cgit v1.2.3