drivers/iio/adc/ltc2309.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
The LTC2305 requires a minimum 1.6μs delay between the I2C write
operation (channel selection) and the subsequent read operation to
allow the chip to process the command and prepare the result. While
not explicitly documented in the datasheet, this timing requirement
was identified by the hardware designer as necessary for reliable
operation.
This extends the existing LTC2305 support (commit 8625d418d24b
("iio: adc: ltc2309: add support for ltc2305")) with the missing
inter-transaction delay.
Add a read_delay_us field to chip_info to support chip-specific timing
requirements. Use fsleep() to implement the delay, with LTC2305 set to
2μs (1.6μs requirement rounded up). LTC2309 does not require additional
delay beyond inherent I2C bus timing.
Also optimize chip_info structure with __counted_by_ptr() annotation
and field reordering to minimize padding.
Signed-off-by: Carlos Jones Jr <carlosjr.jones@analog.com>
---
Note: During independent development of LTC2305 support, the hardware
designer clarified that while the I2C bus timing might inherently provide
the 1.6μs gap in many cases, it should be explicitly guaranteed in the
driver to ensure reliable operation across different I2C controller
implementations and bus speeds.
drivers/iio/adc/ltc2309.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/adc/ltc2309.c b/drivers/iio/adc/ltc2309.c
index 316256edf150..87b78d0353f1 100644
--- a/drivers/iio/adc/ltc2309.c
+++ b/drivers/iio/adc/ltc2309.c
@@ -9,7 +9,9 @@
*
* Copyright (c) 2023, Liam Beguin <liambeguin@gmail.com>
*/
+#include <linux/array_size.h>
#include <linux/bitfield.h>
+#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
#include <linux/kernel.h>
@@ -34,12 +36,14 @@
* @client: I2C reference
* @lock: Lock to serialize data access
* @vref_mv: Internal voltage reference
+ * @read_delay_us: Chip-specific read delay in microseconds
*/
struct ltc2309 {
struct device *dev;
struct i2c_client *client;
struct mutex lock; /* serialize data access */
int vref_mv;
+ unsigned int read_delay_us;
};
/* Order matches expected channel address, See datasheet Table 1. */
@@ -117,20 +121,22 @@ static const struct iio_chan_spec ltc2309_channels[] = {
struct ltc2309_chip_info {
const char *name;
- const struct iio_chan_spec *channels;
+ unsigned int read_delay_us;
int num_channels;
+ const struct iio_chan_spec *channels __counted_by_ptr(num_channels);
};
static const struct ltc2309_chip_info ltc2305_chip_info = {
.name = "ltc2305",
- .channels = ltc2305_channels,
+ .read_delay_us = 2,
.num_channels = ARRAY_SIZE(ltc2305_channels),
+ .channels = ltc2305_channels,
};
static const struct ltc2309_chip_info ltc2309_chip_info = {
.name = "ltc2309",
- .channels = ltc2309_channels,
.num_channels = ARRAY_SIZE(ltc2309_channels),
+ .channels = ltc2309_channels,
};
static int ltc2309_read_raw_channel(struct ltc2309 *ltc2309,
@@ -151,6 +157,9 @@ static int ltc2309_read_raw_channel(struct ltc2309 *ltc2309,
return ret;
}
+ if (ltc2309->read_delay_us)
+ fsleep(ltc2309->read_delay_us);
+
ret = i2c_master_recv(ltc2309->client, (char *)&buf, 2);
if (ret < 0) {
dev_err(ltc2309->dev, "i2c read failed: %pe\n", ERR_PTR(ret));
@@ -206,6 +215,7 @@ static int ltc2309_probe(struct i2c_client *client)
ltc2309->dev = &indio_dev->dev;
ltc2309->client = client;
+ ltc2309->read_delay_us = chip_info->read_delay_us;
indio_dev->name = chip_info->name;
indio_dev->modes = INDIO_DIRECT_MODE;
base-commit: 8625d418d24bc0ff463267b26b7cb2e7a612495f
--
2.43.0
On Fri, Mar 27, 2026 at 11:41:59AM +0800, Carlos Jones Jr wrote:
> The LTC2305 requires a minimum 1.6μs delay between the I2C write
> operation (channel selection) and the subsequent read operation to
> allow the chip to process the command and prepare the result. While
> not explicitly documented in the datasheet, this timing requirement
> was identified by the hardware designer as necessary for reliable
> operation.
>
> This extends the existing LTC2305 support (commit 8625d418d24b
> ("iio: adc: ltc2309: add support for ltc2305")) with the missing
> inter-transaction delay.
>
> Add a read_delay_us field to chip_info to support chip-specific timing
> requirements. Use fsleep() to implement the delay, with LTC2305 set to
> 2μs (1.6μs requirement rounded up). LTC2309 does not require additional
> delay beyond inherent I2C bus timing.
> Also optimize chip_info structure with __counted_by_ptr() annotation
> and field reordering to minimize padding.
This should be a separate patch.
Please, always split the change to logical pieces.
--
With Best Regards,
Andy Shevchenko
© 2016 - 2026 Red Hat, Inc.