[PATCH v3 3/4] i2c: omap24xx_i2c: support CONFIG for repeated start in DM_I2C xfer

Aniket Limaye a-limaye at ti.com
Tue Apr 22 12:19:51 CEST 2025


Repeated Start Condition (Sr) can be used to transfer multiple i2c msgs
without sending a Stop condition (P). So far, the driver default was to
always send a Stop condition after every i2c msg.

Add support for a config option (CONFIG_SYS_I2C_OMAP24XX_REPEATED_START)
to disable sending the Stop condition by default. If this config is
enabled, Stop condition will be sent only if explicitly requested in the
msg flags OR if it is the last msg in the transfer.

Consequently, handle the Repeated Start condition (Sr) in the next msg
by not calling the wait_for_bb() check since it will simply timeout in
the absence of a stop condition (BB will be 1 until Stop is programmed)

Signed-off-by: Aniket Limaye <a-limaye at ti.com>
---

v2:
- fixup code formatting and comment blocks
- CONFIG_I2C_REPEATED_START -> CONFIG_SYS_I2C_OMAP24XX_REPEATED_START
- Link to v1: https://lore.kernel.org/u-boot/20250304220546.866602-3-a-limaye@ti.com/

---
 drivers/i2c/omap24xx_i2c.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index 4afdba02211..a6361d3d17d 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -1066,18 +1066,28 @@ static int omap_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
 	u16 i2c_con_reg = 0;
 
 	debug("%s: %d messages\n", __func__, nmsgs);
-	for (; nmsgs > 0; nmsgs--, msg++) {
-		/* Wait until bus not busy */
-		if (wait_for_bb(priv->regs, priv->ip_rev, priv->waitdelay))
-			return -EREMOTEIO;
+	for (int i = 0; i < nmsgs; i++, msg++) {
+		/*
+		 * If previous msg sent a Stop or if this is the first msg
+		 * Wait until bus not busy
+		 */
+		if ((i2c_con_reg & I2C_CON_STP) || (i == 0))
+			if (wait_for_bb(priv->regs, priv->ip_rev, priv->waitdelay))
+				return -EREMOTEIO;
 
-		/* Set Controller mode with Start and Stop bit */
-		i2c_con_reg = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP;
+		/* Set Controller mode with Start bit */
+		i2c_con_reg = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT;
 		/* Set Transmitter/Receiver mode if it is a write/read msg */
 		if (msg->flags & I2C_M_RD)
 			i2c_con_reg &= ~I2C_CON_TRX;
 		else
 			i2c_con_reg |= I2C_CON_TRX;
+		/* Send Stop condition (P) by default */
+		if (!IS_ENABLED(CONFIG_SYS_I2C_OMAP24XX_REPEATED_START))
+			i2c_con_reg |= I2C_CON_STP;
+		/* Send Stop if explicitly requested or if this is the last msg */
+		if ((msg->flags & I2C_M_STOP) || (i == nmsgs - 1))
+			i2c_con_reg |= I2C_CON_STP;
 
 		debug("%s: chip=0x%x, len=0x%x, i2c_con_reg=0x%x\n",
 		      __func__, msg->addr, msg->len, i2c_con_reg);
-- 
2.49.0



More information about the U-Boot mailing list