Skip to content

Commit efdc383

Browse files
NXP-CarlosSongWolfram Sang
authored andcommitted
i2c: imx-lpi2c: fix SMBus block read NACK after byte count
The LPI2C controller sends a NACK at the end of a receive command unless another receive command is already queued in MTDR. During SMBus block reads, this causes the controller to NACK immediately after receiving the block length byte, aborting the transfer before the data bytes are read. Fix this by queueing a second receive command as soon as the block length byte is received, keeping MTDR non-empty and ensuring continuous ACKs. The initial receive command reads the block length, and the subsequent command reads the remaining data bytes according to the reported length. Fixes: a55fa9d ("i2c: imx-lpi2c: add low power i2c bus driver") Signed-off-by: Carlos Song <carlos.song@nxp.com> Cc: <stable@vger.kernel.org> # v4.10+ Reviewed-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Andi Shyti <andi.shyti@kernel.org> Link: https://lore.kernel.org/r/20260123105459.3448822-1-carlos.song@nxp.com Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
1 parent 8ed5a41 commit efdc383

1 file changed

Lines changed: 83 additions & 24 deletions

File tree

drivers/i2c/busses/i2c-imx-lpi2c.c

Lines changed: 83 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Copyright 2016 Freescale Semiconductor, Inc.
66
*/
77

8+
#include <linux/bitfield.h>
89
#include <linux/clk.h>
910
#include <linux/completion.h>
1011
#include <linux/delay.h>
@@ -90,6 +91,7 @@
9091
#define MRDR_RXEMPTY BIT(14)
9192
#define MDER_TDDE BIT(0)
9293
#define MDER_RDDE BIT(1)
94+
#define MSR_RDF_ASSERTED(x) FIELD_GET(MSR_RDF, (x))
9395

9496
#define SCR_SEN BIT(0)
9597
#define SCR_RST BIT(1)
@@ -482,7 +484,7 @@ static bool lpi2c_imx_write_txfifo(struct lpi2c_imx_struct *lpi2c_imx, bool atom
482484

483485
static bool lpi2c_imx_read_rxfifo(struct lpi2c_imx_struct *lpi2c_imx, bool atomic)
484486
{
485-
unsigned int blocklen, remaining;
487+
unsigned int remaining;
486488
unsigned int temp, data;
487489

488490
do {
@@ -493,15 +495,6 @@ static bool lpi2c_imx_read_rxfifo(struct lpi2c_imx_struct *lpi2c_imx, bool atomi
493495
lpi2c_imx->rx_buf[lpi2c_imx->delivered++] = data & 0xff;
494496
} while (1);
495497

496-
/*
497-
* First byte is the length of remaining packet in the SMBus block
498-
* data read. Add it to msgs->len.
499-
*/
500-
if (lpi2c_imx->block_data) {
501-
blocklen = lpi2c_imx->rx_buf[0];
502-
lpi2c_imx->msglen += blocklen;
503-
}
504-
505498
remaining = lpi2c_imx->msglen - lpi2c_imx->delivered;
506499

507500
if (!remaining) {
@@ -514,12 +507,7 @@ static bool lpi2c_imx_read_rxfifo(struct lpi2c_imx_struct *lpi2c_imx, bool atomi
514507
lpi2c_imx_set_rx_watermark(lpi2c_imx);
515508

516509
/* multiple receive commands */
517-
if (lpi2c_imx->block_data) {
518-
lpi2c_imx->block_data = 0;
519-
temp = remaining;
520-
temp |= (RECV_DATA << 8);
521-
writel(temp, lpi2c_imx->base + LPI2C_MTDR);
522-
} else if (!(lpi2c_imx->delivered & 0xff)) {
510+
if (!(lpi2c_imx->delivered & 0xff)) {
523511
temp = (remaining > CHUNK_DATA ? CHUNK_DATA : remaining) - 1;
524512
temp |= (RECV_DATA << 8);
525513
writel(temp, lpi2c_imx->base + LPI2C_MTDR);
@@ -557,18 +545,77 @@ static int lpi2c_imx_write_atomic(struct lpi2c_imx_struct *lpi2c_imx,
557545
return err;
558546
}
559547

560-
static void lpi2c_imx_read_init(struct lpi2c_imx_struct *lpi2c_imx,
561-
struct i2c_msg *msgs)
548+
static unsigned int lpi2c_SMBus_block_read_length_byte(struct lpi2c_imx_struct *lpi2c_imx)
562549
{
563-
unsigned int temp;
550+
unsigned int data;
551+
552+
data = readl(lpi2c_imx->base + LPI2C_MRDR);
553+
lpi2c_imx->rx_buf[lpi2c_imx->delivered++] = data & 0xff;
554+
555+
return data;
556+
}
557+
558+
static int lpi2c_imx_read_init(struct lpi2c_imx_struct *lpi2c_imx,
559+
struct i2c_msg *msgs)
560+
{
561+
unsigned int temp, val, block_len;
562+
int ret;
564563

565564
lpi2c_imx->rx_buf = msgs->buf;
566565
lpi2c_imx->block_data = msgs->flags & I2C_M_RECV_LEN;
567566

568567
lpi2c_imx_set_rx_watermark(lpi2c_imx);
569-
temp = msgs->len > CHUNK_DATA ? CHUNK_DATA - 1 : msgs->len - 1;
570-
temp |= (RECV_DATA << 8);
571-
writel(temp, lpi2c_imx->base + LPI2C_MTDR);
568+
569+
if (!lpi2c_imx->block_data) {
570+
temp = msgs->len > CHUNK_DATA ? CHUNK_DATA - 1 : msgs->len - 1;
571+
temp |= (RECV_DATA << 8);
572+
writel(temp, lpi2c_imx->base + LPI2C_MTDR);
573+
} else {
574+
/*
575+
* The LPI2C controller automatically sends a NACK after the last byte of a
576+
* receive command, unless the next command in MTDR is also a receive command.
577+
* If MTDR is empty when a receive completes, a NACK is sent by default.
578+
*
579+
* To comply with the SMBus block read spec, we start with a 2-byte read:
580+
* The first byte in RXFIFO is the block length. Once this byte arrives, the
581+
* controller immediately updates MTDR with the next read command, ensuring
582+
* continuous ACK instead of NACK.
583+
*
584+
* The second byte is the first block data byte. Therefore, the subsequent
585+
* read command should request (block_len - 1) bytes, since one data byte
586+
* has already been read.
587+
*/
588+
589+
writel((RECV_DATA << 8) | 0x01, lpi2c_imx->base + LPI2C_MTDR);
590+
591+
ret = readl_poll_timeout(lpi2c_imx->base + LPI2C_MSR, val,
592+
MSR_RDF_ASSERTED(val), 1, 1000);
593+
if (ret) {
594+
dev_err(&lpi2c_imx->adapter.dev, "SMBus read count failed %d\n", ret);
595+
return ret;
596+
}
597+
598+
/* Read block length byte and confirm this SMBus transfer meets protocol */
599+
block_len = lpi2c_SMBus_block_read_length_byte(lpi2c_imx);
600+
if (block_len == 0 || block_len > I2C_SMBUS_BLOCK_MAX) {
601+
dev_err(&lpi2c_imx->adapter.dev, "Invalid SMBus block read length\n");
602+
return -EPROTO;
603+
}
604+
605+
/*
606+
* When block_len shows more bytes need to be read, update second read command to
607+
* keep MTDR non-empty and ensuring continuous ACKs. Only update command register
608+
* here. All block bytes will be read out at IRQ handler or lpi2c_imx_read_atomic()
609+
* function.
610+
*/
611+
if (block_len > 1)
612+
writel((RECV_DATA << 8) | (block_len - 2), lpi2c_imx->base + LPI2C_MTDR);
613+
614+
lpi2c_imx->msglen += block_len;
615+
msgs->len += block_len;
616+
}
617+
618+
return 0;
572619
}
573620

574621
static bool lpi2c_imx_read_chunk_atomic(struct lpi2c_imx_struct *lpi2c_imx)
@@ -613,6 +660,10 @@ static bool is_use_dma(struct lpi2c_imx_struct *lpi2c_imx, struct i2c_msg *msg)
613660
if (!lpi2c_imx->can_use_dma)
614661
return false;
615662

663+
/* DMA is not suitable for SMBus block read */
664+
if (msg->flags & I2C_M_RECV_LEN)
665+
return false;
666+
616667
/*
617668
* When the length of data is less than I2C_DMA_THRESHOLD,
618669
* cpu mode is used directly to avoid low performance.
@@ -623,10 +674,14 @@ static bool is_use_dma(struct lpi2c_imx_struct *lpi2c_imx, struct i2c_msg *msg)
623674
static int lpi2c_imx_pio_xfer(struct lpi2c_imx_struct *lpi2c_imx,
624675
struct i2c_msg *msg)
625676
{
677+
int ret;
678+
626679
reinit_completion(&lpi2c_imx->complete);
627680

628681
if (msg->flags & I2C_M_RD) {
629-
lpi2c_imx_read_init(lpi2c_imx, msg);
682+
ret = lpi2c_imx_read_init(lpi2c_imx, msg);
683+
if (ret)
684+
return ret;
630685
lpi2c_imx_intctrl(lpi2c_imx, MIER_RDIE | MIER_NDIE);
631686
} else {
632687
lpi2c_imx_write(lpi2c_imx, msg);
@@ -638,8 +693,12 @@ static int lpi2c_imx_pio_xfer(struct lpi2c_imx_struct *lpi2c_imx,
638693
static int lpi2c_imx_pio_xfer_atomic(struct lpi2c_imx_struct *lpi2c_imx,
639694
struct i2c_msg *msg)
640695
{
696+
int ret;
697+
641698
if (msg->flags & I2C_M_RD) {
642-
lpi2c_imx_read_init(lpi2c_imx, msg);
699+
ret = lpi2c_imx_read_init(lpi2c_imx, msg);
700+
if (ret)
701+
return ret;
643702
return lpi2c_imx_read_atomic(lpi2c_imx, msg);
644703
}
645704

0 commit comments

Comments
 (0)