From de3ef6fcdbca1721d77e99d7ee7ce0e2486e6ee7 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Fri, 2 Aug 2024 21:21:04 +0100 Subject: [PATCH] drivers: i2c: add an option to skip auto-sending stop on last message The I2C transfer API has been recently changed to always automatically set a STOP on the last message, which was well documented but implemented only by few drivers. Unfortunately, while documented, this is a change in the current behavior and it turns out that some applications depended on it for some complex operations. Add a flag to temporarily restore the old behavior, buying time to fix the application code depending on this. Signed-off-by: Fabio Baltieri --- drivers/i2c/Kconfig | 14 ++++++++++++++ include/zephyr/drivers/i2c.h | 8 ++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 9c90a500ba9d61..ab423e5f167388 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -54,6 +54,20 @@ config I2C_CALLBACK help API and implementations of i2c_transfer_cb. +config I2C_ALLOW_NO_STOP_TRANSACTIONS + bool "Allows I2C transfers with no STOP on the last transaction [DEPRECATED]" + depends on !I2C_NRFX_TWI + depends on !I2C_NRFX_TWIM + depends on !I2C_STM32 + depends on !I2C_GD32 + depends on !I2C_ESP32 + depends on !I2C_DW + select DEPRECATED + help + Allow I2C transactions with no STOP on the last message. This is + unsupported and can leave the bus in an unexpected state. The option + will be removed in Zephyr 4.1. + config I2C_RTIO bool "I2C RTIO API" select EXPERIMENTAL diff --git a/include/zephyr/drivers/i2c.h b/include/zephyr/drivers/i2c.h index 1455820ca8895e..5f1c3fbe8ae4d3 100644 --- a/include/zephyr/drivers/i2c.h +++ b/include/zephyr/drivers/i2c.h @@ -801,7 +801,9 @@ static inline int z_impl_i2c_transfer(const struct device *dev, return 0; } - msgs[num_msgs - 1].flags |= I2C_MSG_STOP; + if (!IS_ENABLED(CONFIG_I2C_ALLOW_NO_STOP_TRANSACTIONS)) { + msgs[num_msgs - 1].flags |= I2C_MSG_STOP; + } int res = api->transfer(dev, msgs, num_msgs, addr); @@ -857,7 +859,9 @@ static inline int i2c_transfer_cb(const struct device *dev, return 0; } - msgs[num_msgs - 1].flags |= I2C_MSG_STOP; + if (!IS_ENABLED(CONFIG_I2C_ALLOW_NO_STOP_TRANSACTIONS)) { + msgs[num_msgs - 1].flags |= I2C_MSG_STOP; + } return api->transfer_cb(dev, msgs, num_msgs, addr, cb, userdata); }