* [PATCH v3 1/8] iio: temperature: ltc2983: Fix macro parenthesization and rename
2026-05-21 16:42 [PATCH v3 0/8] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
@ 2026-05-21 16:42 ` Liviu Stan
2026-05-22 9:11 ` Joshua Crofts
2026-05-21 16:42 ` [PATCH v3 2/8] iio: temperature: ltc2983: Use local device pointer consistently Liviu Stan
` (6 subsequent siblings)
7 siblings, 1 reply; 30+ messages in thread
From: Liviu Stan @ 2026-05-21 16:42 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Francesco Lavra, Liviu Stan, linux-iio,
linux-kernel, linux, devicetree
Wrap the 'chan' parameter in LTC2983_CHAN_START_ADDR() and
LTC2983_CHAN_RES_ADDR() with parentheses to prevent potential
macro argument expansion issues. Also rename LTC2983_CHAN_START_ADDR
to LTC2983_CHAN_ASSIGN_ADDR and LTC2983_CHAN_RES_ADDR to
LTC2983_RESULT_ADDR, to better reflect the datasheet names and avoid
them being confused as related.
Signed-off-by: Liviu Stan <liviu.stan@analog.com>
---
Changes in v3:
- Dropped the Fixes: tag
- Removed the "base" parameter from ADT7604_RES_RES_ADDR(); the resistance
result memory region is (currently) ADT7604-specific so the macro's
modification belongs in the driver patch
drivers/iio/temperature/ltc2983.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
index 38e6f8dfd3b8..67a09934c5bd 100644
--- a/drivers/iio/temperature/ltc2983.c
+++ b/drivers/iio/temperature/ltc2983.c
@@ -56,10 +56,10 @@
#define LTC2983_EEPROM_WRITE_TIME_MS 2600
#define LTC2983_EEPROM_READ_TIME_MS 20
-#define LTC2983_CHAN_START_ADDR(chan) \
- (((chan - 1) * 4) + LTC2983_CHAN_ASSIGN_START_REG)
-#define LTC2983_CHAN_RES_ADDR(chan) \
- (((chan - 1) * 4) + LTC2983_TEMP_RES_START_REG)
+#define LTC2983_CHAN_ASSIGN_ADDR(chan) \
+ ((((chan) - 1) * 4) + LTC2983_CHAN_ASSIGN_START_REG)
+#define LTC2983_RESULT_ADDR(chan) \
+ ((((chan) - 1) * 4) + LTC2983_TEMP_RES_START_REG)
#define LTC2983_THERMOCOUPLE_DIFF_MASK BIT(3)
#define LTC2983_THERMOCOUPLE_SGL(x) \
FIELD_PREP(LTC2983_THERMOCOUPLE_DIFF_MASK, x)
@@ -351,7 +351,7 @@ static int __ltc2983_chan_assign_common(struct ltc2983_data *st,
const struct ltc2983_sensor *sensor,
u32 chan_val)
{
- u32 reg = LTC2983_CHAN_START_ADDR(sensor->chan);
+ u32 reg = LTC2983_CHAN_ASSIGN_ADDR(sensor->chan);
chan_val |= LTC2983_CHAN_TYPE(sensor->type);
dev_dbg(&st->spi->dev, "Assign reg:0x%04X, val:0x%08X\n", reg,
@@ -1197,7 +1197,7 @@ static int ltc2983_chan_read(struct ltc2983_data *st,
}
/* read the converted data */
- ret = regmap_bulk_read(st->regmap, LTC2983_CHAN_RES_ADDR(sensor->chan),
+ ret = regmap_bulk_read(st->regmap, LTC2983_RESULT_ADDR(sensor->chan),
&st->temp, sizeof(st->temp));
if (ret)
return ret;
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread* Re: [PATCH v3 1/8] iio: temperature: ltc2983: Fix macro parenthesization and rename
2026-05-21 16:42 ` [PATCH v3 1/8] iio: temperature: ltc2983: Fix macro parenthesization and rename Liviu Stan
@ 2026-05-22 9:11 ` Joshua Crofts
2026-05-22 12:56 ` Jonathan Cameron
0 siblings, 1 reply; 30+ messages in thread
From: Joshua Crofts @ 2026-05-22 9:11 UTC (permalink / raw)
To: Liviu Stan
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Francesco Lavra, linux-iio, linux-kernel, linux,
devicetree
On Thu, 21 May 2026 at 19:19, Liviu Stan <liviu.stan@analog.com> wrote:
>
> Wrap the 'chan' parameter in LTC2983_CHAN_START_ADDR() and
> LTC2983_CHAN_RES_ADDR() with parentheses to prevent potential
> macro argument expansion issues. Also rename LTC2983_CHAN_START_ADDR
> to LTC2983_CHAN_ASSIGN_ADDR and LTC2983_CHAN_RES_ADDR to
> LTC2983_RESULT_ADDR, to better reflect the datasheet names and avoid
> them being confused as related.
>
> Signed-off-by: Liviu Stan <liviu.stan@analog.com>
> ---
Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
--
Kind regards
CJD
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH v3 1/8] iio: temperature: ltc2983: Fix macro parenthesization and rename
2026-05-22 9:11 ` Joshua Crofts
@ 2026-05-22 12:56 ` Jonathan Cameron
0 siblings, 0 replies; 30+ messages in thread
From: Jonathan Cameron @ 2026-05-22 12:56 UTC (permalink / raw)
To: Joshua Crofts
Cc: Liviu Stan, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Francesco Lavra, linux-iio, linux-kernel, linux,
devicetree
On Fri, 22 May 2026 11:11:59 +0200
Joshua Crofts <joshua.crofts1@gmail.com> wrote:
> On Thu, 21 May 2026 at 19:19, Liviu Stan <liviu.stan@analog.com> wrote:
> >
> > Wrap the 'chan' parameter in LTC2983_CHAN_START_ADDR() and
> > LTC2983_CHAN_RES_ADDR() with parentheses to prevent potential
> > macro argument expansion issues. Also rename LTC2983_CHAN_START_ADDR
> > to LTC2983_CHAN_ASSIGN_ADDR and LTC2983_CHAN_RES_ADDR to
> > LTC2983_RESULT_ADDR, to better reflect the datasheet names and avoid
> > them being confused as related.
> >
> > Signed-off-by: Liviu Stan <liviu.stan@analog.com>
> > ---
>
> Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
>
I had a quick datasheet dive. The naming in there is rather
messy and to me seems inconsistent but these two names are indeed
used at least sometimes. Along with conversion result start address
(which indexed by conversion channel)
(table 8).
So whilst I don't have a strong preference in favour of this rename
I guess it's fine.
Jonathan
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v3 2/8] iio: temperature: ltc2983: Use local device pointer consistently
2026-05-21 16:42 [PATCH v3 0/8] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
2026-05-21 16:42 ` [PATCH v3 1/8] iio: temperature: ltc2983: Fix macro parenthesization and rename Liviu Stan
@ 2026-05-21 16:42 ` Liviu Stan
2026-05-22 7:37 ` Joshua Crofts
` (2 more replies)
2026-05-21 16:42 ` [PATCH v3 3/8] iio: temperature: ltc2983: Fix inconsistent channel wording in messages Liviu Stan
` (5 subsequent siblings)
7 siblings, 3 replies; 30+ messages in thread
From: Liviu Stan @ 2026-05-21 16:42 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Francesco Lavra, Liviu Stan, linux-iio,
linux-kernel, linux, devicetree
Some functions define a local 'dev' pointer but still use bare
'&st->spi->dev' in some code paths, and some don't have it at all.
Replace bare references with the local pointer for consistency.
Signed-off-by: Liviu Stan <liviu.stan@analog.com>
---
Changes in v3:
- Dropped the Fixes: tag
- Fixed one remaining dev_dbg() call in __ltc2983_chan_assign_common()
that was still using the raw device pointer instead of the dev local
variable introduced by this patch
drivers/iio/temperature/ltc2983.c | 83 +++++++++++++++++--------------
1 file changed, 47 insertions(+), 36 deletions(-)
diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
index 67a09934c5bd..d9dcf3e86696 100644
--- a/drivers/iio/temperature/ltc2983.c
+++ b/drivers/iio/temperature/ltc2983.c
@@ -351,10 +351,11 @@ static int __ltc2983_chan_assign_common(struct ltc2983_data *st,
const struct ltc2983_sensor *sensor,
u32 chan_val)
{
+ struct device *dev = &st->spi->dev;
u32 reg = LTC2983_CHAN_ASSIGN_ADDR(sensor->chan);
chan_val |= LTC2983_CHAN_TYPE(sensor->type);
- dev_dbg(&st->spi->dev, "Assign reg:0x%04X, val:0x%08X\n", reg,
+ dev_dbg(dev, "Assign reg:0x%04X, val:0x%08X\n", reg,
chan_val);
st->chan_val = cpu_to_be32(chan_val);
return regmap_bulk_write(st->regmap, reg, &st->chan_val,
@@ -656,11 +657,12 @@ static struct ltc2983_sensor *
ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data *st,
const struct ltc2983_sensor *sensor)
{
+ struct device *dev = &st->spi->dev;
struct ltc2983_thermocouple *thermo;
u32 oc_current;
int ret;
- thermo = devm_kzalloc(&st->spi->dev, sizeof(*thermo), GFP_KERNEL);
+ thermo = devm_kzalloc(dev, sizeof(*thermo), GFP_KERNEL);
if (!thermo)
return ERR_PTR(-ENOMEM);
@@ -687,7 +689,7 @@ ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data
LTC2983_THERMOCOUPLE_OC_CURR(3);
break;
default:
- return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
+ return dev_err_ptr_probe(dev, -EINVAL,
"Invalid open circuit current:%u\n",
oc_current);
}
@@ -697,7 +699,7 @@ ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data
/* validate channel index */
if (!(thermo->sensor_config & LTC2983_THERMOCOUPLE_DIFF_MASK) &&
sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
- return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
+ return dev_err_ptr_probe(dev, -EINVAL,
"Invalid chann:%d for differential thermocouple\n",
sensor->chan);
@@ -712,7 +714,7 @@ ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data
* This would be caught later but we can just return
* the error right away.
*/
- return dev_err_ptr_probe(&st->spi->dev, ret,
+ return dev_err_ptr_probe(dev, ret,
"Property reg must be given\n");
}
@@ -823,7 +825,7 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
} else {
/* same as differential case */
if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
- return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
+ return dev_err_ptr_probe(dev, -EINVAL,
"Invalid chann:%d for RTD\n",
sensor->chan);
}
@@ -873,7 +875,7 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
rtd->excitation_current = 0x08;
break;
default:
- return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
+ return dev_err_ptr_probe(dev, -EINVAL,
"Invalid value for excitation current(%u)\n",
excitation_current);
}
@@ -922,7 +924,7 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
/* validate channel index */
if (!(thermistor->sensor_config & LTC2983_THERMISTOR_DIFF_MASK) &&
sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
- return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
+ return dev_err_ptr_probe(dev, -EINVAL,
"Invalid chann:%d for differential thermistor\n",
sensor->chan);
@@ -964,7 +966,7 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
case 0:
/* auto range */
if (sensor->type >= LTC2983_SENSOR_THERMISTOR_STEINHART)
- return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
+ return dev_err_ptr_probe(dev, -EINVAL,
"Auto Range not allowed for custom sensors\n");
thermistor->excitation_current = 0x0c;
@@ -1003,7 +1005,7 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
thermistor->excitation_current = 0x0b;
break;
default:
- return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
+ return dev_err_ptr_probe(dev, -EINVAL,
"Invalid value for excitation current(%u)\n",
excitation_current);
}
@@ -1016,11 +1018,12 @@ static struct ltc2983_sensor *
ltc2983_diode_new(const struct fwnode_handle *child, const struct ltc2983_data *st,
const struct ltc2983_sensor *sensor)
{
+ struct device *dev = &st->spi->dev;
struct ltc2983_diode *diode;
u32 temp = 0, excitation_current = 0;
int ret;
- diode = devm_kzalloc(&st->spi->dev, sizeof(*diode), GFP_KERNEL);
+ diode = devm_kzalloc(dev, sizeof(*diode), GFP_KERNEL);
if (!diode)
return ERR_PTR(-ENOMEM);
@@ -1036,7 +1039,7 @@ ltc2983_diode_new(const struct fwnode_handle *child, const struct ltc2983_data *
/* validate channel index */
if (!(diode->sensor_config & LTC2983_DIODE_DIFF_MASK) &&
sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
- return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
+ return dev_err_ptr_probe(dev, -EINVAL,
"Invalid chann:%d for differential thermistor\n",
sensor->chan);
@@ -1061,7 +1064,7 @@ ltc2983_diode_new(const struct fwnode_handle *child, const struct ltc2983_data *
diode->excitation_current = 0x03;
break;
default:
- return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
+ return dev_err_ptr_probe(dev, -EINVAL,
"Invalid value for excitation current(%u)\n",
excitation_current);
}
@@ -1079,23 +1082,24 @@ static struct ltc2983_sensor *ltc2983_r_sense_new(struct fwnode_handle *child,
struct ltc2983_data *st,
const struct ltc2983_sensor *sensor)
{
+ struct device *dev = &st->spi->dev;
struct ltc2983_rsense *rsense;
int ret;
u32 temp;
- rsense = devm_kzalloc(&st->spi->dev, sizeof(*rsense), GFP_KERNEL);
+ rsense = devm_kzalloc(dev, sizeof(*rsense), GFP_KERNEL);
if (!rsense)
return ERR_PTR(-ENOMEM);
/* validate channel index */
if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
- return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
+ return dev_err_ptr_probe(dev, -EINVAL,
"Invalid chann:%d for r_sense\n",
sensor->chan);
ret = fwnode_property_read_u32(child, "adi,rsense-val-milli-ohms", &temp);
if (ret)
- return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
+ return dev_err_ptr_probe(dev, -EINVAL,
"Property adi,rsense-val-milli-ohms missing\n");
/*
* Times 1000 because we have milli-ohms and __convert_to_raw
@@ -1115,9 +1119,10 @@ static struct ltc2983_sensor *ltc2983_adc_new(struct fwnode_handle *child,
struct ltc2983_data *st,
const struct ltc2983_sensor *sensor)
{
+ struct device *dev = &st->spi->dev;
struct ltc2983_adc *adc;
- adc = devm_kzalloc(&st->spi->dev, sizeof(*adc), GFP_KERNEL);
+ adc = devm_kzalloc(dev, sizeof(*adc), GFP_KERNEL);
if (!adc)
return ERR_PTR(-ENOMEM);
@@ -1125,7 +1130,7 @@ static struct ltc2983_sensor *ltc2983_adc_new(struct fwnode_handle *child,
adc->single_ended = true;
if (!adc->single_ended && sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
- return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
+ return dev_err_ptr_probe(dev, -EINVAL,
"Invalid chan:%d for differential adc\n",
sensor->chan);
@@ -1140,9 +1145,10 @@ static struct ltc2983_sensor *ltc2983_temp_new(struct fwnode_handle *child,
struct ltc2983_data *st,
const struct ltc2983_sensor *sensor)
{
+ struct device *dev = &st->spi->dev;
struct ltc2983_temp *temp;
- temp = devm_kzalloc(&st->spi->dev, sizeof(*temp), GFP_KERNEL);
+ temp = devm_kzalloc(dev, sizeof(*temp), GFP_KERNEL);
if (!temp)
return ERR_PTR(-ENOMEM);
@@ -1150,7 +1156,7 @@ static struct ltc2983_sensor *ltc2983_temp_new(struct fwnode_handle *child,
temp->single_ended = true;
if (!temp->single_ended && sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
- return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
+ return dev_err_ptr_probe(dev, -EINVAL,
"Invalid chan:%d for differential temp\n",
sensor->chan);
@@ -1169,13 +1175,14 @@ static struct ltc2983_sensor *ltc2983_temp_new(struct fwnode_handle *child,
static int ltc2983_chan_read(struct ltc2983_data *st,
const struct ltc2983_sensor *sensor, int *val)
{
+ struct device *dev = &st->spi->dev;
u32 start_conversion = 0;
int ret;
unsigned long time;
start_conversion = LTC2983_STATUS_START(true);
start_conversion |= LTC2983_STATUS_CHAN_SEL(sensor->chan);
- dev_dbg(&st->spi->dev, "Start conversion on chan:%d, status:%02X\n",
+ dev_dbg(dev, "Start conversion on chan:%d, status:%02X\n",
sensor->chan, start_conversion);
/* start conversion */
ret = regmap_write(st->regmap, LTC2983_STATUS_REG, start_conversion);
@@ -1192,7 +1199,7 @@ static int ltc2983_chan_read(struct ltc2983_data *st,
time = wait_for_completion_timeout(&st->completion,
msecs_to_jiffies(300));
if (!time) {
- dev_warn(&st->spi->dev, "Conversion timed out\n");
+ dev_warn(dev, "Conversion timed out\n");
return -ETIMEDOUT;
}
@@ -1205,7 +1212,7 @@ static int ltc2983_chan_read(struct ltc2983_data *st,
*val = __be32_to_cpu(st->temp);
if (!(LTC2983_RES_VALID_MASK & *val)) {
- dev_err(&st->spi->dev, "Invalid conversion detected\n");
+ dev_err(dev, "Invalid conversion detected\n");
return -EIO;
}
@@ -1222,11 +1229,12 @@ static int ltc2983_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask)
{
struct ltc2983_data *st = iio_priv(indio_dev);
+ struct device *dev = &st->spi->dev;
int ret;
/* sanity check */
if (chan->address >= st->num_channels) {
- dev_err(&st->spi->dev, "Invalid chan address:%ld",
+ dev_err(dev, "Invalid chan address:%ld",
chan->address);
return -EINVAL;
}
@@ -1303,7 +1311,7 @@ static int ltc2983_parse_fw(struct ltc2983_data *st)
st->num_channels = device_get_child_node_count(dev);
if (!st->num_channels)
- return dev_err_probe(&st->spi->dev, -EINVAL,
+ return dev_err_probe(dev, -EINVAL,
"At least one channel must be given!\n");
st->sensors = devm_kcalloc(dev, st->num_channels, sizeof(*st->sensors),
@@ -1391,6 +1399,7 @@ static int ltc2983_eeprom_cmd(struct ltc2983_data *st, unsigned int cmd,
unsigned int wait_time, unsigned int status_reg,
unsigned long status_fail_mask)
{
+ struct device *dev = &st->spi->dev;
unsigned long time;
unsigned int val;
int ret;
@@ -1410,7 +1419,7 @@ static int ltc2983_eeprom_cmd(struct ltc2983_data *st, unsigned int cmd,
time = wait_for_completion_timeout(&st->completion,
msecs_to_jiffies(wait_time));
if (!time)
- return dev_err_probe(&st->spi->dev, -ETIMEDOUT,
+ return dev_err_probe(dev, -ETIMEDOUT,
"EEPROM command timed out\n");
ret = regmap_read(st->regmap, status_reg, &val);
@@ -1418,7 +1427,7 @@ static int ltc2983_eeprom_cmd(struct ltc2983_data *st, unsigned int cmd,
return ret;
if (val & status_fail_mask)
- return dev_err_probe(&st->spi->dev, -EINVAL,
+ return dev_err_probe(dev, -EINVAL,
"EEPROM command failed: 0x%02X\n", val);
return 0;
@@ -1427,6 +1436,7 @@ static int ltc2983_eeprom_cmd(struct ltc2983_data *st, unsigned int cmd,
static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
{
u32 iio_chan_t = 0, iio_chan_v = 0, chan, iio_idx = 0, status;
+ struct device *dev = &st->spi->dev;
int ret;
/* make sure the device is up: start bit (7) is 0 and done bit (6) is 1 */
@@ -1434,7 +1444,7 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
LTC2983_STATUS_UP(status) == 1, 25000,
25000 * 10);
if (ret)
- return dev_err_probe(&st->spi->dev, ret,
+ return dev_err_probe(dev, ret,
"Device startup timed out\n");
ret = regmap_update_bits(st->regmap, LTC2983_GLOBAL_CONFIG_REG,
@@ -1535,12 +1545,13 @@ static const struct iio_info ltc2983_iio_info = {
static int ltc2983_probe(struct spi_device *spi)
{
+ struct device *dev = &spi->dev;
struct ltc2983_data *st;
struct iio_dev *indio_dev;
struct gpio_desc *gpio;
int ret;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
@@ -1552,7 +1563,7 @@ static int ltc2983_probe(struct spi_device *spi)
st->regmap = devm_regmap_init_spi(spi, <c2983_regmap_config);
if (IS_ERR(st->regmap))
- return dev_err_probe(&spi->dev, PTR_ERR(st->regmap),
+ return dev_err_probe(dev, PTR_ERR(st->regmap),
"Failed to initialize regmap\n");
mutex_init(&st->lock);
@@ -1565,11 +1576,11 @@ static int ltc2983_probe(struct spi_device *spi)
if (ret)
return ret;
- ret = devm_regulator_get_enable(&spi->dev, "vdd");
+ ret = devm_regulator_get_enable(dev, "vdd");
if (ret)
return ret;
- gpio = devm_gpiod_get_optional(&st->spi->dev, "reset", GPIOD_OUT_HIGH);
+ gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(gpio))
return PTR_ERR(gpio);
@@ -1579,7 +1590,7 @@ static int ltc2983_probe(struct spi_device *spi)
gpiod_set_value_cansleep(gpio, 0);
}
- st->iio_chan = devm_kzalloc(&spi->dev,
+ st->iio_chan = devm_kzalloc(dev,
st->iio_channels * sizeof(*st->iio_chan),
GFP_KERNEL);
if (!st->iio_chan)
@@ -1589,10 +1600,10 @@ static int ltc2983_probe(struct spi_device *spi)
if (ret)
return ret;
- ret = devm_request_irq(&spi->dev, spi->irq, ltc2983_irq_handler,
+ ret = devm_request_irq(dev, spi->irq, ltc2983_irq_handler,
IRQF_TRIGGER_RISING, st->info->name, st);
if (ret)
- return dev_err_probe(&spi->dev, ret,
+ return dev_err_probe(dev, ret,
"failed to request an irq\n");
if (st->info->has_eeprom) {
@@ -1610,7 +1621,7 @@ static int ltc2983_probe(struct spi_device *spi)
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = <c2983_iio_info;
- return devm_iio_device_register(&spi->dev, indio_dev);
+ return devm_iio_device_register(dev, indio_dev);
}
static int ltc2983_resume(struct device *dev)
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread* Re: [PATCH v3 2/8] iio: temperature: ltc2983: Use local device pointer consistently
2026-05-21 16:42 ` [PATCH v3 2/8] iio: temperature: ltc2983: Use local device pointer consistently Liviu Stan
@ 2026-05-22 7:37 ` Joshua Crofts
2026-05-22 13:02 ` Jonathan Cameron
2026-06-02 23:19 ` Andy Shevchenko
2 siblings, 0 replies; 30+ messages in thread
From: Joshua Crofts @ 2026-05-22 7:37 UTC (permalink / raw)
To: Liviu Stan
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Francesco Lavra, linux-iio, linux-kernel, linux,
devicetree
On Thu, 21 May 2026 at 20:17, Liviu Stan <liviu.stan@analog.com> wrote:
>
> Some functions define a local 'dev' pointer but still use bare
> '&st->spi->dev' in some code paths, and some don't have it at all.
> Replace bare references with the local pointer for consistency.
>
> Signed-off-by: Liviu Stan <liviu.stan@analog.com>
> ---
> Changes in v3:
> - Dropped the Fixes: tag
> - Fixed one remaining dev_dbg() call in __ltc2983_chan_assign_common()
> that was still using the raw device pointer instead of the dev local
> variable introduced by this patch
>
> drivers/iio/temperature/ltc2983.c | 83 +++++++++++++++++--------------
> 1 file changed, 47 insertions(+), 36 deletions(-)
LGTM
Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
--
Kind regards
CJD
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH v3 2/8] iio: temperature: ltc2983: Use local device pointer consistently
2026-05-21 16:42 ` [PATCH v3 2/8] iio: temperature: ltc2983: Use local device pointer consistently Liviu Stan
2026-05-22 7:37 ` Joshua Crofts
@ 2026-05-22 13:02 ` Jonathan Cameron
2026-05-22 13:56 ` Stan, Liviu
2026-06-02 23:19 ` Andy Shevchenko
2 siblings, 1 reply; 30+ messages in thread
From: Jonathan Cameron @ 2026-05-22 13:02 UTC (permalink / raw)
To: Liviu Stan
Cc: David Lechner, Nuno Sá, Andy Shevchenko, Michael Hennerich,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Antoniu Miclaus,
Francesco Lavra, linux-iio, linux-kernel, linux, devicetree
On Thu, 21 May 2026 19:42:55 +0300
Liviu Stan <liviu.stan@analog.com> wrote:
> Some functions define a local 'dev' pointer but still use bare
> '&st->spi->dev' in some code paths, and some don't have it at all.
> Replace bare references with the local pointer for consistency.
>
> Signed-off-by: Liviu Stan <liviu.stan@analog.com>
Hi Liviu,
When doing this sort of change, one of the advantages is often that code lines
get shorter. So look at the lines touched and see if the wrapping remains
appropriate.
At least some of the cases I point out below already fitted on one line
under 80 chars but none the less they are now even shorter so that needs
tidying up. Note that a few other cases are just over 80 chars.
Take a look at those and decide if readability is improved much by just
going a few characters over. That line length isn't the hard rule it
used to be!
> ---
> Changes in v3:
> - Dropped the Fixes: tag
> - Fixed one remaining dev_dbg() call in __ltc2983_chan_assign_common()
> that was still using the raw device pointer instead of the dev local
> variable introduced by this patch
>
> drivers/iio/temperature/ltc2983.c | 83 +++++++++++++++++--------------
> 1 file changed, 47 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
> index 67a09934c5bd..d9dcf3e86696 100644
> --- a/drivers/iio/temperature/ltc2983.c
> +++ b/drivers/iio/temperature/ltc2983.c
> @@ -351,10 +351,11 @@ static int __ltc2983_chan_assign_common(struct ltc2983_data *st,
> const struct ltc2983_sensor *sensor,
> u32 chan_val)
> {
> + struct device *dev = &st->spi->dev;
> u32 reg = LTC2983_CHAN_ASSIGN_ADDR(sensor->chan);
>
> chan_val |= LTC2983_CHAN_TYPE(sensor->type);
> - dev_dbg(&st->spi->dev, "Assign reg:0x%04X, val:0x%08X\n", reg,
> + dev_dbg(dev, "Assign reg:0x%04X, val:0x%08X\n", reg,
> chan_val);
chan_val easily fits on the line above now. It actually did before
but given you are changing this lets tidy it up to;
dev_dbg(dev, "Assign reg:0x%04X, val:0x%08X\n", reg, chan_val);
> st->chan_val = cpu_to_be32(chan_val);
> return regmap_bulk_write(st->regmap, reg, &st->chan_val,
> @@ -1222,11 +1229,12 @@ static int ltc2983_read_raw(struct iio_dev *indio_dev,
> int *val, int *val2, long mask)
> {
> struct ltc2983_data *st = iio_priv(indio_dev);
> + struct device *dev = &st->spi->dev;
> int ret;
>
> /* sanity check */
> if (chan->address >= st->num_channels) {
> - dev_err(&st->spi->dev, "Invalid chan address:%ld",
> + dev_err(dev, "Invalid chan address:%ld",
> chan->address);
dev_err(dev, "Invalid chan address:%ld", chan->address);
> return -EINVAL;
> }
> @@ -1427,6 +1436,7 @@ static int ltc2983_eeprom_cmd(struct ltc2983_data *st, unsigned int cmd,
> static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
> {
> u32 iio_chan_t = 0, iio_chan_v = 0, chan, iio_idx = 0, status;
> + struct device *dev = &st->spi->dev;
> int ret;
>
> /* make sure the device is up: start bit (7) is 0 and done bit (6) is 1 */
> @@ -1434,7 +1444,7 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
> LTC2983_STATUS_UP(status) == 1, 25000,
> 25000 * 10);
> if (ret)
> - return dev_err_probe(&st->spi->dev, ret,
> + return dev_err_probe(dev, ret,
> "Device startup timed out\n");
return dev_err_probe(dev, ret, "Device startup timed out\n");
>
> ret = regmap_update_bits(st->regmap, LTC2983_GLOBAL_CONFIG_REG,
> @@ -1535,12 +1545,13 @@ static const struct iio_info ltc2983_iio_info = {
> @@ -1589,10 +1600,10 @@ static int ltc2983_probe(struct spi_device *spi)
> if (ret)
> return ret;
>
> - ret = devm_request_irq(&spi->dev, spi->irq, ltc2983_irq_handler,
> + ret = devm_request_irq(dev, spi->irq, ltc2983_irq_handler,
> IRQF_TRIGGER_RISING, st->info->name, st);
> if (ret)
> - return dev_err_probe(&spi->dev, ret,
> + return dev_err_probe(dev, ret,
> "failed to request an irq\n");
return dev_err_probe(dev, ret, "failed to request an irq\n");
Thanks,
Jonathan
>
^ permalink raw reply [flat|nested] 30+ messages in thread* RE: [PATCH v3 2/8] iio: temperature: ltc2983: Use local device pointer consistently
2026-05-22 13:02 ` Jonathan Cameron
@ 2026-05-22 13:56 ` Stan, Liviu
0 siblings, 0 replies; 30+ messages in thread
From: Stan, Liviu @ 2026-05-22 13:56 UTC (permalink / raw)
To: Jonathan Cameron
Cc: David Lechner, Sa, Nuno, Andy Shevchenko, Hennerich, Michael,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Miclaus, Antoniu,
Francesco Lavra, linux-iio@vger.kernel.org,
linux-kernel@vger.kernel.org, linux, devicetree@vger.kernel.org
On Fri, 22 May 2026 14:02:55 +0100 Jonathan Cameron <jic23@kernel.org> wrote:
> On Thu, 21 May 2026 19:42:55 +0300
> Liviu Stan <liviu.stan@analog.com> wrote:
>
> > Some functions define a local 'dev' pointer but still use bare
> > '&st->spi->dev' in some code paths, and some don't have it at all.
> > Replace bare references with the local pointer for consistency.
> >
> > Signed-off-by: Liviu Stan <liviu.stan@analog.com>
>
> Hi Liviu,
>
> When doing this sort of change, one of the advantages is often that code lines
> get shorter. So look at the lines touched and see if the wrapping remains
> appropriate.
>
> At least some of the cases I point out below already fitted on one line
> under 80 chars but none the less they are now even shorter so that needs
> tidying up. Note that a few other cases are just over 80 chars.
> Take a look at those and decide if readability is improved much by just
> going a few characters over. That line length isn't the hard rule it
> used to be!
>
Hi,
Understood, I'll tidy them up! Thanks!
Liviu
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH v3 2/8] iio: temperature: ltc2983: Use local device pointer consistently
2026-05-21 16:42 ` [PATCH v3 2/8] iio: temperature: ltc2983: Use local device pointer consistently Liviu Stan
2026-05-22 7:37 ` Joshua Crofts
2026-05-22 13:02 ` Jonathan Cameron
@ 2026-06-02 23:19 ` Andy Shevchenko
2 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2026-06-02 23:19 UTC (permalink / raw)
To: Liviu Stan
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Francesco Lavra, linux-iio, linux-kernel, linux,
devicetree
On Thu, May 21, 2026 at 07:42:55PM +0300, Liviu Stan wrote:
> Some functions define a local 'dev' pointer but still use bare
> '&st->spi->dev' in some code paths, and some don't have it at all.
> Replace bare references with the local pointer for consistency.
...
> - dev_dbg(&st->spi->dev, "Assign reg:0x%04X, val:0x%08X\n", reg,
> + dev_dbg(dev, "Assign reg:0x%04X, val:0x%08X\n", reg,
> chan_val);
Now it's perfectly a single line.
...
> if (chan->address >= st->num_channels) {
> - dev_err(&st->spi->dev, "Invalid chan address:%ld",
> + dev_err(dev, "Invalid chan address:%ld",
> chan->address);
Ditto.
> return -EINVAL;
> }
...
> if (ret)
> - return dev_err_probe(&st->spi->dev, ret,
> + return dev_err_probe(dev, ret,
> "Device startup timed out\n");
Ditto.
...
> - st->iio_chan = devm_kzalloc(&spi->dev,
> + st->iio_chan = devm_kzalloc(dev,
> st->iio_channels * sizeof(*st->iio_chan),
> GFP_KERNEL);
This should be first switched to devm_kcalloc().
...
> - ret = devm_request_irq(&spi->dev, spi->irq, ltc2983_irq_handler,
> + ret = devm_request_irq(dev, spi->irq, ltc2983_irq_handler,
> IRQF_TRIGGER_RISING, st->info->name, st);
> if (ret)
> - return dev_err_probe(&spi->dev, ret,
> + return dev_err_probe(dev, ret,
> "failed to request an irq\n");
Another patch should just drop this duplicate message.
...
So, this has to be split to three:
- dropping dup message
- moving to devm_kcalloc() and at the same time define local dev in the probe
(and only in the probe without changing anything else)
- this patch
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v3 3/8] iio: temperature: ltc2983: Fix inconsistent channel wording in messages
2026-05-21 16:42 [PATCH v3 0/8] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
2026-05-21 16:42 ` [PATCH v3 1/8] iio: temperature: ltc2983: Fix macro parenthesization and rename Liviu Stan
2026-05-21 16:42 ` [PATCH v3 2/8] iio: temperature: ltc2983: Use local device pointer consistently Liviu Stan
@ 2026-05-21 16:42 ` Liviu Stan
2026-05-22 7:07 ` Joshua Crofts
2026-06-02 23:21 ` Andy Shevchenko
2026-05-21 16:42 ` [PATCH v3 4/8] iio: temperature: ltc2983: Use fwnode_property_present() for optional properties Liviu Stan
` (4 subsequent siblings)
7 siblings, 2 replies; 30+ messages in thread
From: Liviu Stan @ 2026-05-21 16:42 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Liviu Stan, Francesco Lavra, linux-iio,
linux-kernel, linux, devicetree
Replace occurrences of the abbreviated 'chann' and 'chan' with
'channel' in error and debug messages throughout the driver.
Also changed the diode invalid channel error message from
"thermistor" to "diode".
Signed-off-by: Liviu Stan <liviu.stan@analog.com>
---
Changes in v3:
- Dropped both Fixes: tags
- Removed the "all" from "all occurrences" in the commit message
- Fixed some missed "chan" / "chann" occurrences
drivers/iio/temperature/ltc2983.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
index d9dcf3e86696..0b9e5f761bd8 100644
--- a/drivers/iio/temperature/ltc2983.c
+++ b/drivers/iio/temperature/ltc2983.c
@@ -700,7 +700,7 @@ ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data
if (!(thermo->sensor_config & LTC2983_THERMOCOUPLE_DIFF_MASK) &&
sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
return dev_err_ptr_probe(dev, -EINVAL,
- "Invalid chann:%d for differential thermocouple\n",
+ "Invalid channel %d for differential thermocouple\n",
sensor->chan);
struct fwnode_handle *ref __free(fwnode_handle) =
@@ -798,7 +798,7 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
/*
* rtd channel indexes are a bit more complicated to validate.
* For 4wire RTD with rotation, the channel selection cannot be
- * >=19 since the chann + 1 is used in this configuration.
+ * >=19 since the channel + 1 is used in this configuration.
* For 4wire RTDs with kelvin rsense, the rsense channel cannot be
* <=1 since channel - 1 and channel - 2 are used.
*/
@@ -815,18 +815,18 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
(rtd->r_sense_chan <= min))
/* kelvin rsense*/
return dev_err_ptr_probe(dev, -EINVAL,
- "Invalid rsense chann:%d to use in kelvin rsense\n",
+ "Invalid channel %d for kelvin rsense\n",
rtd->r_sense_chan);
if (sensor->chan < min || sensor->chan > max)
return dev_err_ptr_probe(dev, -EINVAL,
- "Invalid chann:%d for the rtd config\n",
+ "Invalid channel %d for RTD config\n",
sensor->chan);
} else {
/* same as differential case */
if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
return dev_err_ptr_probe(dev, -EINVAL,
- "Invalid chann:%d for RTD\n",
+ "Invalid channel %d for RTD\n",
sensor->chan);
}
@@ -925,7 +925,7 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
if (!(thermistor->sensor_config & LTC2983_THERMISTOR_DIFF_MASK) &&
sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
return dev_err_ptr_probe(dev, -EINVAL,
- "Invalid chann:%d for differential thermistor\n",
+ "Invalid channel %d for differential thermistor\n",
sensor->chan);
/* check custom sensor */
@@ -1040,7 +1040,7 @@ ltc2983_diode_new(const struct fwnode_handle *child, const struct ltc2983_data *
if (!(diode->sensor_config & LTC2983_DIODE_DIFF_MASK) &&
sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
return dev_err_ptr_probe(dev, -EINVAL,
- "Invalid chann:%d for differential thermistor\n",
+ "Invalid channel %d for differential diode\n",
sensor->chan);
/* set common parameters */
@@ -1094,7 +1094,7 @@ static struct ltc2983_sensor *ltc2983_r_sense_new(struct fwnode_handle *child,
/* validate channel index */
if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
return dev_err_ptr_probe(dev, -EINVAL,
- "Invalid chann:%d for r_sense\n",
+ "Invalid channel %d for r_sense\n",
sensor->chan);
ret = fwnode_property_read_u32(child, "adi,rsense-val-milli-ohms", &temp);
@@ -1131,7 +1131,7 @@ static struct ltc2983_sensor *ltc2983_adc_new(struct fwnode_handle *child,
if (!adc->single_ended && sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
return dev_err_ptr_probe(dev, -EINVAL,
- "Invalid chan:%d for differential adc\n",
+ "Invalid channel %d for differential ADC\n",
sensor->chan);
/* set common parameters */
@@ -1157,7 +1157,7 @@ static struct ltc2983_sensor *ltc2983_temp_new(struct fwnode_handle *child,
if (!temp->single_ended && sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
return dev_err_ptr_probe(dev, -EINVAL,
- "Invalid chan:%d for differential temp\n",
+ "Invalid channel %d for differential temp\n",
sensor->chan);
temp->custom = __ltc2983_custom_sensor_new(st, child, "adi,custom-temp",
@@ -1182,7 +1182,7 @@ static int ltc2983_chan_read(struct ltc2983_data *st,
start_conversion = LTC2983_STATUS_START(true);
start_conversion |= LTC2983_STATUS_CHAN_SEL(sensor->chan);
- dev_dbg(dev, "Start conversion on chan:%d, status:%02X\n",
+ dev_dbg(dev, "Start conversion on channel:%d, status:%02X\n",
sensor->chan, start_conversion);
/* start conversion */
ret = regmap_write(st->regmap, LTC2983_STATUS_REG, start_conversion);
@@ -1234,7 +1234,7 @@ static int ltc2983_read_raw(struct iio_dev *indio_dev,
/* sanity check */
if (chan->address >= st->num_channels) {
- dev_err(dev, "Invalid chan address:%ld",
+ dev_err(dev, "Invalid channel address: %ld\n",
chan->address);
return -EINVAL;
}
@@ -1332,14 +1332,14 @@ static int ltc2983_parse_fw(struct ltc2983_data *st)
if (sensor.chan < LTC2983_MIN_CHANNELS_NR ||
sensor.chan > st->info->max_channels_nr)
return dev_err_probe(dev, -EINVAL,
- "chan:%d must be from %u to %u\n",
+ "channel:%d must be from %u to %u\n",
sensor.chan,
LTC2983_MIN_CHANNELS_NR,
st->info->max_channels_nr);
if (channel_avail_mask & BIT(sensor.chan))
return dev_err_probe(dev, -EINVAL,
- "chan:%d already in use\n",
+ "channel:%d already in use\n",
sensor.chan);
ret = fwnode_property_read_u32(child, "adi,sensor-type", &sensor.type);
@@ -1347,7 +1347,7 @@ static int ltc2983_parse_fw(struct ltc2983_data *st)
return dev_err_probe(dev, ret,
"adi,sensor-type property must given for child nodes\n");
- dev_dbg(dev, "Create new sensor, type %u, chann %u",
+ dev_dbg(dev, "Create new sensor, type %u, channel %u",
sensor.type, sensor.chan);
if (sensor.type >= LTC2983_SENSOR_THERMOCOUPLE &&
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread* Re: [PATCH v3 3/8] iio: temperature: ltc2983: Fix inconsistent channel wording in messages
2026-05-21 16:42 ` [PATCH v3 3/8] iio: temperature: ltc2983: Fix inconsistent channel wording in messages Liviu Stan
@ 2026-05-22 7:07 ` Joshua Crofts
2026-06-02 23:21 ` Andy Shevchenko
1 sibling, 0 replies; 30+ messages in thread
From: Joshua Crofts @ 2026-05-22 7:07 UTC (permalink / raw)
To: Liviu Stan
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Francesco Lavra, linux-iio, linux-kernel, linux,
devicetree
On Thu, 21 May 2026 at 20:16, Liviu Stan <liviu.stan@analog.com> wrote:
>
> Replace occurrences of the abbreviated 'chann' and 'chan' with
> 'channel' in error and debug messages throughout the driver.
> Also changed the diode invalid channel error message from
> "thermistor" to "diode".
>
> Signed-off-by: Liviu Stan <liviu.stan@analog.com>
> ---
> Changes in v3:
> - Dropped both Fixes: tags
> - Removed the "all" from "all occurrences" in the commit message
> - Fixed some missed "chan" / "chann" occurrences
>
> drivers/iio/temperature/ltc2983.c | 30 +++++++++++++++---------------
> 1 file changed, 15 insertions(+), 15 deletions(-)
Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
--
Kind regards
CJD
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH v3 3/8] iio: temperature: ltc2983: Fix inconsistent channel wording in messages
2026-05-21 16:42 ` [PATCH v3 3/8] iio: temperature: ltc2983: Fix inconsistent channel wording in messages Liviu Stan
2026-05-22 7:07 ` Joshua Crofts
@ 2026-06-02 23:21 ` Andy Shevchenko
1 sibling, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2026-06-02 23:21 UTC (permalink / raw)
To: Liviu Stan
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Francesco Lavra, linux-iio, linux-kernel, linux,
devicetree
On Thu, May 21, 2026 at 07:42:56PM +0300, Liviu Stan wrote:
> Replace occurrences of the abbreviated 'chann' and 'chan' with
> 'channel' in error and debug messages throughout the driver.
> Also changed the diode invalid channel error message from
> "thermistor" to "diode".
...
> - dev_dbg(dev, "Start conversion on chan:%d, status:%02X\n",
> + dev_dbg(dev, "Start conversion on channel:%d, status:%02X\n",
Here and below inconsistently used : with channel. Be consistent with the above.
> sensor->chan, start_conversion);
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v3 4/8] iio: temperature: ltc2983: Use fwnode_property_present() for optional properties
2026-05-21 16:42 [PATCH v3 0/8] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
` (2 preceding siblings ...)
2026-05-21 16:42 ` [PATCH v3 3/8] iio: temperature: ltc2983: Fix inconsistent channel wording in messages Liviu Stan
@ 2026-05-21 16:42 ` Liviu Stan
2026-06-02 23:23 ` Andy Shevchenko
2026-05-21 16:42 ` [PATCH v3 5/8] iio: temperature: ltc2983: Fix n_wires default bypassing rotation check Liviu Stan
` (3 subsequent siblings)
7 siblings, 1 reply; 30+ messages in thread
From: Liviu Stan @ 2026-05-21 16:42 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Francesco Lavra, Liviu Stan, linux-iio,
linux-kernel, linux, devicetree
Checking fwnode_property_read_u32() return value with if (!ret)
silently swallows meaningful error codes when a property is present
but malformed. Use fwnode_property_present() first so that absence
uses the default while a present but unreadable property returns
a proper error.
Signed-off-by: Liviu Stan <liviu.stan@analog.com>
---
Changes in v3:
- Dropped the Fixes: tag
- Fixed other occurrences brought up by sashiko
drivers/iio/temperature/ltc2983.c | 84 +++++++++++++++++++++----------
1 file changed, 58 insertions(+), 26 deletions(-)
diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
index 0b9e5f761bd8..10f423fbe9cc 100644
--- a/drivers/iio/temperature/ltc2983.c
+++ b/drivers/iio/temperature/ltc2983.c
@@ -669,8 +669,14 @@ ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data
if (fwnode_property_read_bool(child, "adi,single-ended"))
thermo->sensor_config = LTC2983_THERMOCOUPLE_SGL(1);
- ret = fwnode_property_read_u32(child, "adi,sensor-oc-current-microamp", &oc_current);
- if (!ret) {
+ if (fwnode_property_present(child, "adi,sensor-oc-current-microamp")) {
+ ret = fwnode_property_read_u32(child,
+ "adi,sensor-oc-current-microamp",
+ &oc_current);
+ if (ret)
+ return dev_err_ptr_probe(dev, ret,
+ "Failed to read adi,sensor-oc-current-microamp\n");
+
switch (oc_current) {
case 10:
thermo->sensor_config |=
@@ -760,8 +766,12 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
return dev_err_ptr_probe(dev, ret,
"Property reg must be given\n");
- ret = fwnode_property_read_u32(child, "adi,number-of-wires", &n_wires);
- if (!ret) {
+ if (fwnode_property_present(child, "adi,number-of-wires")) {
+ ret = fwnode_property_read_u32(child, "adi,number-of-wires", &n_wires);
+ if (ret)
+ return dev_err_ptr_probe(dev, ret,
+ "Failed to read adi,number-of-wires\n");
+
switch (n_wires) {
case 2:
rtd->sensor_config = LTC2983_RTD_N_WIRES(0);
@@ -843,12 +853,13 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
rtd->sensor.fault_handler = ltc2983_common_fault_handler;
rtd->sensor.assign_chan = ltc2983_rtd_assign_chan;
- ret = fwnode_property_read_u32(child, "adi,excitation-current-microamp",
- &excitation_current);
- if (ret) {
- /* default to 5uA */
- rtd->excitation_current = 1;
- } else {
+ if (fwnode_property_present(child, "adi,excitation-current-microamp")) {
+ ret = fwnode_property_read_u32(child, "adi,excitation-current-microamp",
+ &excitation_current);
+ if (ret)
+ return dev_err_ptr_probe(dev, ret,
+ "Failed to read adi,excitation-current-microamp\n");
+
switch (excitation_current) {
case 5:
rtd->excitation_current = 0x01;
@@ -879,9 +890,17 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
"Invalid value for excitation current(%u)\n",
excitation_current);
}
+ } else {
+ /* default to 5uA */
+ rtd->excitation_current = 1;
}
- fwnode_property_read_u32(child, "adi,rtd-curve", &rtd->rtd_curve);
+ if (fwnode_property_present(child, "adi,rtd-curve")) {
+ ret = fwnode_property_read_u32(child, "adi,rtd-curve", &rtd->rtd_curve);
+ if (ret)
+ return dev_err_ptr_probe(dev, ret,
+ "Failed to read adi,rtd-curve\n");
+ }
return &rtd->sensor;
}
@@ -951,17 +970,13 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
thermistor->sensor.fault_handler = ltc2983_common_fault_handler;
thermistor->sensor.assign_chan = ltc2983_thermistor_assign_chan;
- ret = fwnode_property_read_u32(child, "adi,excitation-current-nanoamp",
- &excitation_current);
- if (ret) {
- /* Auto range is not allowed for custom sensors */
- if (sensor->type >= LTC2983_SENSOR_THERMISTOR_STEINHART)
- /* default to 1uA */
- thermistor->excitation_current = 0x03;
- else
- /* default to auto-range */
- thermistor->excitation_current = 0x0c;
- } else {
+ if (fwnode_property_present(child, "adi,excitation-current-nanoamp")) {
+ ret = fwnode_property_read_u32(child, "adi,excitation-current-nanoamp",
+ &excitation_current);
+ if (ret)
+ return dev_err_ptr_probe(dev, ret,
+ "Failed to read adi,excitation-current-nanoamp\n");
+
switch (excitation_current) {
case 0:
/* auto range */
@@ -1009,6 +1024,14 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
"Invalid value for excitation current(%u)\n",
excitation_current);
}
+ } else {
+ /* Auto range is not allowed for custom sensors */
+ if (sensor->type >= LTC2983_SENSOR_THERMISTOR_STEINHART)
+ /* default to 1uA */
+ thermistor->excitation_current = 0x03;
+ else
+ /* default to auto-range */
+ thermistor->excitation_current = 0x0c;
}
return &thermistor->sensor;
@@ -1047,9 +1070,13 @@ ltc2983_diode_new(const struct fwnode_handle *child, const struct ltc2983_data *
diode->sensor.fault_handler = ltc2983_common_fault_handler;
diode->sensor.assign_chan = ltc2983_diode_assign_chan;
- ret = fwnode_property_read_u32(child, "adi,excitation-current-microamp",
- &excitation_current);
- if (!ret) {
+ if (fwnode_property_present(child, "adi,excitation-current-microamp")) {
+ ret = fwnode_property_read_u32(child, "adi,excitation-current-microamp",
+ &excitation_current);
+ if (ret)
+ return dev_err_ptr_probe(dev, ret,
+ "Failed to read adi,excitation-current-microamp\n");
+
switch (excitation_current) {
case 10:
diode->excitation_current = 0x00;
@@ -1070,7 +1097,12 @@ ltc2983_diode_new(const struct fwnode_handle *child, const struct ltc2983_data *
}
}
- fwnode_property_read_u32(child, "adi,ideal-factor-value", &temp);
+ if (fwnode_property_present(child, "adi,ideal-factor-value")) {
+ ret = fwnode_property_read_u32(child, "adi,ideal-factor-value", &temp);
+ if (ret)
+ return dev_err_ptr_probe(dev, ret,
+ "Failed to read adi,ideal-factor-value\n");
+ }
/* 2^20 resolution */
diode->ideal_factor_value = __convert_to_raw(temp, 1048576);
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread* Re: [PATCH v3 4/8] iio: temperature: ltc2983: Use fwnode_property_present() for optional properties
2026-05-21 16:42 ` [PATCH v3 4/8] iio: temperature: ltc2983: Use fwnode_property_present() for optional properties Liviu Stan
@ 2026-06-02 23:23 ` Andy Shevchenko
0 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2026-06-02 23:23 UTC (permalink / raw)
To: Liviu Stan
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Francesco Lavra, linux-iio, linux-kernel, linux,
devicetree
On Thu, May 21, 2026 at 07:42:57PM +0300, Liviu Stan wrote:
> Checking fwnode_property_read_u32() return value with if (!ret)
> silently swallows meaningful error codes when a property is present
> but malformed. Use fwnode_property_present() first so that absence
> uses the default while a present but unreadable property returns
> a proper error.
...
const char *propname;
propname = ...;
> + if (fwnode_property_present(child, "adi,sensor-oc-current-microamp")) {
> + ret = fwnode_property_read_u32(child,
> + "adi,sensor-oc-current-microamp",
> + &oc_current);
if (fwnode_property_present(child, propname)) {
ret = fwnode_property_read_u32(child, propname, &oc_current);
> + if (ret)
> + return dev_err_ptr_probe(dev, ret,
> + "Failed to read adi,sensor-oc-current-microamp\n");
return dev_err_ptr_probe(dev, ret,
"Failed to read %s\n", propname);
In the same way below may be amended.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v3 5/8] iio: temperature: ltc2983: Fix n_wires default bypassing rotation check
2026-05-21 16:42 [PATCH v3 0/8] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
` (3 preceding siblings ...)
2026-05-21 16:42 ` [PATCH v3 4/8] iio: temperature: ltc2983: Use fwnode_property_present() for optional properties Liviu Stan
@ 2026-05-21 16:42 ` Liviu Stan
2026-05-22 13:06 ` Jonathan Cameron
2026-05-21 16:42 ` [PATCH v3 6/8] iio: core: Add IIO_COVERAGE channel type Liviu Stan
` (2 subsequent siblings)
7 siblings, 1 reply; 30+ messages in thread
From: Liviu Stan @ 2026-05-21 16:42 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Francesco Lavra, Liviu Stan, linux-iio,
linux-kernel, linux, devicetree
When adi,number-of-wires is absent, n_wires is left at 0. The binding
documents a default of 2 wires, matching the hardware default. However
the current-rotate validation checks n_wires == 2 || n_wires == 3, so
with n_wires = 0 the guard is bypassed and adi,current-rotate is accepted
for a 2-wire RTD.
Initialize n_wires = 2 to match the binding default and ensure the
rotation check fires correctly when the property is absent.
Fixes: f110f3188e56 ("iio: temperature: Add support for LTC2983")
Signed-off-by: Liviu Stan <liviu.stan@analog.com>
---
Changes in v3:
- New patch
drivers/iio/temperature/ltc2983.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
index 10f423fbe9cc..326f843f4271 100644
--- a/drivers/iio/temperature/ltc2983.c
+++ b/drivers/iio/temperature/ltc2983.c
@@ -749,7 +749,7 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
struct ltc2983_rtd *rtd;
int ret = 0;
struct device *dev = &st->spi->dev;
- u32 excitation_current = 0, n_wires = 0;
+ u32 excitation_current = 0, n_wires = 2;
rtd = devm_kzalloc(dev, sizeof(*rtd), GFP_KERNEL);
if (!rtd)
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread* Re: [PATCH v3 5/8] iio: temperature: ltc2983: Fix n_wires default bypassing rotation check
2026-05-21 16:42 ` [PATCH v3 5/8] iio: temperature: ltc2983: Fix n_wires default bypassing rotation check Liviu Stan
@ 2026-05-22 13:06 ` Jonathan Cameron
0 siblings, 0 replies; 30+ messages in thread
From: Jonathan Cameron @ 2026-05-22 13:06 UTC (permalink / raw)
To: Liviu Stan
Cc: David Lechner, Nuno Sá, Andy Shevchenko, Michael Hennerich,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Antoniu Miclaus,
Francesco Lavra, linux-iio, linux-kernel, linux, devicetree
On Thu, 21 May 2026 19:42:58 +0300
Liviu Stan <liviu.stan@analog.com> wrote:
> When adi,number-of-wires is absent, n_wires is left at 0. The binding
> documents a default of 2 wires, matching the hardware default. However
> the current-rotate validation checks n_wires == 2 || n_wires == 3, so
> with n_wires = 0 the guard is bypassed and adi,current-rotate is accepted
> for a 2-wire RTD.
>
> Initialize n_wires = 2 to match the binding default and ensure the
> rotation check fires correctly when the property is absent.
>
> Fixes: f110f3188e56 ("iio: temperature: Add support for LTC2983")
> Signed-off-by: Liviu Stan <liviu.stan@analog.com>
This should be the first patch in the series so it is obvious that it
is easily backported without the rest + I might pick up via the fixes-togreg
tree.
Jonathan
> ---
> Changes in v3:
> - New patch
>
> drivers/iio/temperature/ltc2983.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
> index 10f423fbe9cc..326f843f4271 100644
> --- a/drivers/iio/temperature/ltc2983.c
> +++ b/drivers/iio/temperature/ltc2983.c
> @@ -749,7 +749,7 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
> struct ltc2983_rtd *rtd;
> int ret = 0;
> struct device *dev = &st->spi->dev;
> - u32 excitation_current = 0, n_wires = 0;
> + u32 excitation_current = 0, n_wires = 2;
>
> rtd = devm_kzalloc(dev, sizeof(*rtd), GFP_KERNEL);
> if (!rtd)
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v3 6/8] iio: core: Add IIO_COVERAGE channel type
2026-05-21 16:42 [PATCH v3 0/8] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
` (4 preceding siblings ...)
2026-05-21 16:42 ` [PATCH v3 5/8] iio: temperature: ltc2983: Fix n_wires default bypassing rotation check Liviu Stan
@ 2026-05-21 16:42 ` Liviu Stan
2026-05-21 18:10 ` sashiko-bot
2026-05-22 9:57 ` Stan, Liviu
2026-05-21 16:43 ` [PATCH v3 7/8] dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983 Liviu Stan
2026-05-21 16:43 ` [PATCH v3 8/8] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
7 siblings, 2 replies; 30+ messages in thread
From: Liviu Stan @ 2026-05-21 16:42 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Francesco Lavra, Liviu Stan, linux-iio,
linux-kernel, linux, devicetree
Add a new channel type for sensors that report fractional coverage as
a percentage. The sysfs attribute is in_coverageX_raw; after applying
in_coverageX_scale the value is in percent. The first user is the
ADT7604 leak detector, where the value represents the portion of the
sensing element that is wetted.
Signed-off-by: Liviu Stan <liviu.stan@analog.com>
---
Changes in v3:
- Renamed the sysfs attribute from in_coveragepercentX_raw to
in_coverageX_raw
- Added a _scale ABI documentation entry
- Corrected KernelVersion in the ABI documentation from 6.15 to 7.2
- Added IIO_COVERAGE to the event_is_known() switch in
tools/iio/iio_event_monitor.c
Documentation/ABI/testing/sysfs-bus-iio | 17 +++++++++++++++++
drivers/iio/industrialio-core.c | 1 +
include/uapi/linux/iio/types.h | 1 +
tools/iio/iio_event_monitor.c | 2 ++
4 files changed, 21 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 925a33fd309a..ca20ad5860dc 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -1980,6 +1980,23 @@ Description:
Raw (unscaled no offset etc.) resistance reading.
Units after application of scale and offset are ohms.
+What: /sys/bus/iio/devices/iio:deviceX/in_coverageX_raw
+KernelVersion: 7.2
+Contact: linux-iio@vger.kernel.org
+Description:
+ Raw (unscaled no offset etc.) coverage reading. Used for sensors
+ that report fractional coverage as a percentage, such as leak
+ detectors where the value represents what portion of the sensing
+ element is wetted. Units after application of scale and offset are
+ percent.
+
+What: /sys/bus/iio/devices/iio:deviceX/in_coverageX_scale
+KernelVersion: 7.2
+Contact: linux-iio@vger.kernel.org
+Description:
+ Scale to be applied to in_coverageX_raw to obtain coverage
+ in percent.
+
What: /sys/bus/iio/devices/iio:deviceX/heater_enable
KernelVersion: 4.1.0
Contact: linux-iio@vger.kernel.org
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index bd6f4f9f4533..ffe0dc49c4b9 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -98,6 +98,7 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_CHROMATICITY] = "chromaticity",
[IIO_ATTENTION] = "attention",
[IIO_ALTCURRENT] = "altcurrent",
+ [IIO_COVERAGE] = "coverage",
};
static const char * const iio_modifier_names[] = {
diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
index d7c2bb223651..c9295c707041 100644
--- a/include/uapi/linux/iio/types.h
+++ b/include/uapi/linux/iio/types.h
@@ -53,6 +53,7 @@ enum iio_chan_type {
IIO_CHROMATICITY,
IIO_ATTENTION,
IIO_ALTCURRENT,
+ IIO_COVERAGE,
};
enum iio_modifier {
diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c
index df6c43d7738d..bc3ef4c77c2b 100644
--- a/tools/iio/iio_event_monitor.c
+++ b/tools/iio/iio_event_monitor.c
@@ -65,6 +65,7 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_CHROMATICITY] = "chromaticity",
[IIO_ATTENTION] = "attention",
[IIO_ALTCURRENT] = "altcurrent",
+ [IIO_COVERAGE] = "coverage",
};
static const char * const iio_ev_type_text[] = {
@@ -194,6 +195,7 @@ static bool event_is_known(struct iio_event_data *event)
case IIO_CHROMATICITY:
case IIO_ATTENTION:
case IIO_ALTCURRENT:
+ case IIO_COVERAGE:
break;
default:
return false;
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread* Re: [PATCH v3 6/8] iio: core: Add IIO_COVERAGE channel type
2026-05-21 16:42 ` [PATCH v3 6/8] iio: core: Add IIO_COVERAGE channel type Liviu Stan
@ 2026-05-21 18:10 ` sashiko-bot
2026-05-22 9:57 ` Stan, Liviu
1 sibling, 0 replies; 30+ messages in thread
From: sashiko-bot @ 2026-05-21 18:10 UTC (permalink / raw)
To: Liviu Stan; +Cc: robh, devicetree, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The sysfs ABI documentation for IIO_COVERAGE incorrectly uses 'X' instead of 'Y' as the channel index wildcard.
--
commit 6217a0a065fdaa7ef3fffa525f2928d59a323a05
Author: Liviu Stan <liviu.stan@analog.com>
iio: core: Add IIO_COVERAGE channel type
This commit introduces a new channel type for sensors that report fractional
coverage as a percentage. It updates the core IIO structures and provides
the necessary sysfs ABI documentation for the new attributes.
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index 4fc9f6bd42812..90fb8ef26de0e 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -1959,6 +1959,23 @@ Description:
> Raw (unscaled no offset etc.) resistance reading.
> Units after application of scale and offset are ohms.
>
> +What: /sys/bus/iio/devices/iio:deviceX/in_coverageX_raw
[Severity: Low]
Should this use Y for the channel index wildcard instead of X? The IIO sysfs
ABI documentation typically uses X strictly for the device index and Y for the
channel index, which would make this in_coverageY_raw.
> +KernelVersion: 7.2
> +Contact: linux-iio@vger.kernel.org
> +Description:
> + Raw (unscaled no offset etc.) coverage reading. Used for sensors
> + that report fractional coverage as a percentage, such as leak
> + detectors where the value represents what portion of the sensing
> + element is wetted. Units after application of scale and offset are
> + percent.
> +
> +What: /sys/bus/iio/devices/iio:deviceX/in_coverageX_scale
[Severity: Low]
Does this attribute have the same naming consistency issue? Following the
standard convention, this would be in_coverageY_scale.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260521164323.770626-1-liviu.stan@analog.com?part=6
^ permalink raw reply [flat|nested] 30+ messages in thread
* RE: [PATCH v3 6/8] iio: core: Add IIO_COVERAGE channel type
2026-05-21 16:42 ` [PATCH v3 6/8] iio: core: Add IIO_COVERAGE channel type Liviu Stan
2026-05-21 18:10 ` sashiko-bot
@ 2026-05-22 9:57 ` Stan, Liviu
1 sibling, 0 replies; 30+ messages in thread
From: Stan, Liviu @ 2026-05-22 9:57 UTC (permalink / raw)
To: Stan, Liviu, Jonathan Cameron, David Lechner, Sa, Nuno,
Andy Shevchenko, Hennerich, Michael, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Miclaus, Antoniu,
Francesco Lavra, linux-iio@vger.kernel.org,
linux-kernel@vger.kernel.org, linux, devicetree@vger.kernel.org
Hello everyone, I'll reply to sashiko's review here:
On Thu, 21 May 2026 18:10:28 +0000 sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Low] The sysfs ABI documentation for IIO_COVERAGE incorrectly uses 'X' instead of 'Y' as the channel index wildcard.
> --
>
> commit 6217a0a065fdaa7ef3fffa525f2928d59a323a05
> Author: Liviu Stan <liviu.stan@analog.com>
> iio: core: Add IIO_COVERAGE channel type
>
> This commit introduces a new channel type for sensors that report fractional
> coverage as a percentage. It updates the core IIO structures and provides
> the necessary sysfs ABI documentation for the new attributes.
>
> > diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> > index 4fc9f6bd42812..90fb8ef26de0e 100644
> > --- a/Documentation/ABI/testing/sysfs-bus-iio
> > +++ b/Documentation/ABI/testing/sysfs-bus-iio
> > @@ -1959,6 +1959,23 @@ Description:
> > Raw (unscaled no offset etc.) resistance reading.
> > Units after application of scale and offset are ohms.
> >
> > +What: /sys/bus/iio/devices/iio:deviceX/in_coverageX_raw
>
> [Severity: Low]
> Should this use Y for the channel index wildcard instead of X? The IIO sysfs
> ABI documentation typically uses X strictly for the device index and Y for the
> channel index, which would make this in_coverageY_raw.
>
> > +KernelVersion: 7.2
> > +Contact: linux-iio@vger.kernel.org
> > +Description:
> > + Raw (unscaled no offset etc.) coverage reading. Used for sensors
> > + that report fractional coverage as a percentage, such as leak
> > + detectors where the value represents what portion of the sensing
> > + element is wetted. Units after application of scale and offset are
> > + percent.
> > +
> > +What: /sys/bus/iio/devices/iio:deviceX/in_coverageX_scale
>
> [Severity: Low]
> Does this attribute have the same naming consistency issue? Following the
> standard convention, this would be in_coverageY_scale.
>
> --
> Sashiko AI review * https://sashiko.dev/#/patchset/20260521164323.770626-1-liviu.stan@analog.com?part=6
>
I see now that other attributes have Y as the channel index wildcard.
Will change
Thanks,
Liviu
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v3 7/8] dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983
2026-05-21 16:42 [PATCH v3 0/8] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
` (5 preceding siblings ...)
2026-05-21 16:42 ` [PATCH v3 6/8] iio: core: Add IIO_COVERAGE channel type Liviu Stan
@ 2026-05-21 16:43 ` Liviu Stan
2026-05-21 18:23 ` sashiko-bot
2026-05-21 16:43 ` [PATCH v3 8/8] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
7 siblings, 1 reply; 30+ messages in thread
From: Liviu Stan @ 2026-05-21 16:43 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Liviu Stan, Francesco Lavra, linux-iio,
linux-kernel, linux, devicetree
The ADT7604 shares the same die as the LTC2984. It repurposes the
custom RTD sensor type (18) as a copper trace resistance sensor
and the custom thermistor type (27) as a leak detector, and
removes thermocouple, diode and direct ADC sensor types.
Add adi,adt7604 to the compatible list and introduce two new
sensor node types specific to this device:
- copper-trace@: maps to the custom RTD sensor type (18). Two
variants: sub-ohm (< 1 ohm, adi,copper-trace-sub-ohm boolean,
no custom table and excitation current) and standard (> 1 ohm,
required adi,custom-copper-trace table, optional excitation current
defaulting to the datasheet recommended value). Primary output
is resistance in ohms. For > 1 ohm copper traces with a custom table,
the chip also outputs temperature in millidegrees Celsius.
- leak-detector@: maps to the custom thermistor sensor type (27).
Takes a required adi,custom-leak-detector lookup table encoding
resistance (uOhm) against coverage data (%). Two outputs:
resistance in ohms and coverage in percent.
Separate node types are used rather than extending the existing
rtd@ and thermistor@ nodes because adi,custom-rtd is required
for sensor type 18, and several properties (adi,number-of-wires,
adi,rtd-curve, adi,rsense-share, adi,single-ended,
adi,current-rotate) have no meaning for the new sensor types, since
the configuration is hardcoded, and would need to be explicitly
forbidden or ignored in the driver.
allOf conditions are added to restrict thermocouple, diode, direct
ADC and active temperature nodes to non-ADT7604 devices, and to
restrict copper-trace and leak-detector nodes to the ADT7604
(some parts only).
Signed-off-by: Liviu Stan <liviu.stan@analog.com>
---
Changes in v3:
- Changed the custom leak detector table encoding, users now specify
plain coverage percentage values (0-100) in the device tree and the
driver applies the +273.15 C offset internally before writing the
hardware table
- Changed custom-rtd to custom-copper-trace to better represent the
copper trace custom table, and made it required for > 1 ohm variants
- Made custom-leak-detector required for leak detector sensors
- Updated commit message to reflect the changes
- Updated leak detector node description
- Updated adi,custom-leak-detector description
- Modified the example leak detector custom table to match the datasheet
.../bindings/iio/temperature/adi,ltc2983.yaml | 207 +++++++++++++++++-
1 file changed, 204 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
index a22725f7619b..14cfa28809ed 100644
--- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
+++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
@@ -4,14 +4,18 @@
$id: http://devicetree.org/schemas/iio/temperature/adi,ltc2983.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: Analog Devices LTC2983, LTC2986, LTM2985 Multi-sensor Temperature system
+title: Analog Devices LTC2983 and similar Multi-sensor Temperature systems
maintainers:
- Nuno Sá <nuno.sa@analog.com>
description: |
- Analog Devices LTC2983, LTC2984, LTC2986, LTM2985 Multi-Sensor Digital
- Temperature Measurement Systems
+ Analog Devices Multi-Sensor Digital Temperature Measurement Systems:
+ - ADT7604
+ - LTC2983
+ - LTC2984
+ - LTC2986
+ - LTM2985
https://www.analog.com/media/en/technical-documentation/data-sheets/2983fc.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/2984fb.pdf
@@ -43,6 +47,7 @@ properties:
compatible:
oneOf:
- enum:
+ - adi,adt7604
- adi,ltc2983
- adi,ltc2986
- adi,ltm2985
@@ -436,6 +441,121 @@ patternProperties:
required:
- adi,custom-temp
+ '^copper-trace@':
+ $ref: '#/$defs/sensor-node'
+ unevaluatedProperties: false
+ description: |
+ Copper trace resistance sensor (some parts only). Two variants exist:
+ sub-ohm (< 1 ohm, no custom table allowed) and standard (> 1 ohm,
+ required custom table).
+
+ properties:
+ reg:
+ minimum: 2
+ maximum: 20
+
+ adi,sensor-type:
+ description: Sensor type for copper trace sensors.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ const: 32
+
+ adi,rsense-handle:
+ description: Associated sense resistor sensor.
+ $ref: /schemas/types.yaml#/definitions/phandle
+
+ adi,copper-trace-sub-ohm:
+ description:
+ Select the sub-ohm (< 1 ohm) copper trace variant. Custom table
+ and excitation current are not allowed in this mode.
+ type: boolean
+
+ adi,excitation-current-microamp:
+ description:
+ Excitation current applied to the copper trace. Not used in
+ sub-ohm mode. The datasheet recommends 1mA for copper trace
+ sensors due to their typically small resistance.
+ enum: [5, 10, 25, 50, 100, 250, 500, 1000]
+ default: 1000
+
+ adi,custom-copper-trace:
+ description:
+ Resistance-to-temperature table for copper trace sensors with
+ resistance > 1 ohm. Required when adi,copper-trace-sub-ohm is not
+ set. See Page 36 of the datasheet.
+ $ref: /schemas/types.yaml#/definitions/uint64-matrix
+ minItems: 3
+ maxItems: 64
+ items:
+ items:
+ - description: Resistance point in uOhms.
+ - description: Temperature point in uK.
+
+ required:
+ - adi,rsense-handle
+
+ allOf:
+ - if:
+ required:
+ - adi,copper-trace-sub-ohm
+ then:
+ properties:
+ adi,custom-copper-trace: false
+ adi,excitation-current-microamp: false
+ - if:
+ not:
+ required:
+ - adi,copper-trace-sub-ohm
+ then:
+ required:
+ - adi,custom-copper-trace
+
+ '^leak-detector@':
+ $ref: '#/$defs/sensor-node'
+ unevaluatedProperties: false
+ description: |
+ Leak detector sensor (some parts only). Outputs resistance in ohms and
+ a coverage percentage via IIO_COVERAGE (raw/1024 = coverage %).
+
+ properties:
+ reg:
+ minimum: 2
+ maximum: 20
+
+ adi,sensor-type:
+ description: Sensor type for leak detector sensors.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ const: 33
+
+ adi,rsense-handle:
+ description: Associated sense resistor sensor.
+ $ref: /schemas/types.yaml#/definitions/phandle
+
+ adi,excitation-current-nanoamp:
+ description:
+ Excitation current applied to the leak detector. The correct value
+ depends on the electrical characteristics of the liquid being sensed.
+ For example, 10000 (10µA) is recommended for PG25 (see datasheet
+ Table 39).
+ enum: [250, 500, 1000, 5000, 10000, 25000, 50000, 100000, 250000,
+ 500000, 1000000]
+
+ adi,custom-leak-detector:
+ description: |
+ Lookup table mapping resistance to coverage percentage. Entries must
+ be in ascending resistance order.
+ $ref: /schemas/types.yaml#/definitions/uint64-matrix
+ minItems: 3
+ maxItems: 64
+ items:
+ items:
+ - description: Resistance point in uOhms.
+ - description: Coverage data percentage (0 to 100).
+
+ required:
+ - adi,rsense-handle
+ - adi,excitation-current-nanoamp
+ - adi,custom-leak-detector
+
'^rsense@':
$ref: '#/$defs/sensor-node'
unevaluatedProperties: false
@@ -477,6 +597,22 @@ allOf:
patternProperties:
'^temp@': false
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: adi,adt7604
+ then:
+ patternProperties:
+ '^thermocouple@': false
+ '^diode@': false
+ '^adc@': false
+ '^temp@': false
+ else:
+ patternProperties:
+ '^copper-trace@': false
+ '^leak-detector@': false
+
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
@@ -556,4 +692,69 @@ examples:
};
};
};
+
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ temperature-sensor@0 {
+ compatible = "adi,adt7604";
+ reg = <0>;
+ interrupt-parent = <&gpio>;
+ interrupts = <25 IRQ_TYPE_EDGE_RISING>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ vdd-supply = <&supply>;
+
+ trace_rsense: rsense@2 {
+ reg = <2>;
+ adi,sensor-type = <29>;
+ adi,rsense-val-milli-ohms = <100000>; // 100 ohm
+ };
+
+ copper-trace@4 {
+ reg = <4>;
+ adi,sensor-type = <32>;
+ adi,rsense-handle = <&trace_rsense>;
+ adi,copper-trace-sub-ohm;
+ };
+
+ r_sense: rsense@12 {
+ reg = <12>;
+ adi,sensor-type = <29>;
+ adi,rsense-val-milli-ohms = <1000000>; // 1 kohm
+ };
+
+ leak-detector@14 {
+ reg = <14>;
+ adi,sensor-type = <33>;
+ adi,rsense-handle = <&r_sense>;
+ adi,excitation-current-nanoamp = <10000>;
+ adi,custom-leak-detector =
+ /bits/ 64 < 0 100>,
+ /bits/ 64 < 202020000 99>,
+ /bits/ 64 < 285710000 70>,
+ /bits/ 64 < 333330000 60>,
+ /bits/ 64 < 400000000 50>,
+ /bits/ 64 < 500000000 40>,
+ /bits/ 64 < 666670000 30>,
+ /bits/ 64 < 1000000000 20>,
+ /bits/ 64 < 2000000000 10>,
+ /bits/ 64 <1000000000000 0>;
+ };
+
+ rtd@18 {
+ reg = <18>;
+ adi,sensor-type = <12>; // PT100
+ adi,rsense-handle = <&r_sense>;
+ adi,number-of-wires = <2>;
+ adi,rsense-share;
+ adi,excitation-current-microamp = <500>;
+ adi,rtd-curve = <0>;
+ };
+ };
+ };
...
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread* Re: [PATCH v3 7/8] dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983
2026-05-21 16:43 ` [PATCH v3 7/8] dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983 Liviu Stan
@ 2026-05-21 18:23 ` sashiko-bot
2026-05-22 11:42 ` Liviu Stan
0 siblings, 1 reply; 30+ messages in thread
From: sashiko-bot @ 2026-05-21 18:23 UTC (permalink / raw)
To: Liviu Stan; +Cc: devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Low] The new compatible string 'adi,adt7604' is omitted from the existing conditional block that disables '^temp@' nodes, violating subsystem guidelines.
- [Low] The schema allows invalid 'adi,sensor-type' values in '^rtd@' and '^thermistor@' nodes for the ADT7604.
--
commit fbbcd3bcbfbb106e48a6545868dd2b27a56b39b5
Author: Liviu Stan <liviu.stan@analog.com>
dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983
This commit adds support for the ADT7604 to the LTC2983 binding schema. It
introduces the adi,adt7604 compatible string and adds two new sensor node
types: copper-trace@ and leak-detector@. It also adds conditional checks to
restrict unsupported nodes for the ADT7604 device.
> diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
> index a22725f7619b7..14cfa28809edd 100644
> --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
> +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
[ ... ]
> @@ -477,6 +597,22 @@ allOf:
> patternProperties:
> '^temp@': false
>
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: adi,adt7604
> + then:
> + patternProperties:
> + '^thermocouple@': false
> + '^diode@': false
> + '^adc@': false
> + '^temp@': false
[Severity: Low]
Since ADT7604 shares the ^temp@: false constraint with the existing devices,
should adi,adt7604 be added to the existing compatible enum block instead of
duplicating the ^temp@ restriction in this new conditional?
[Severity: Low]
The commit message mentions that ADT7604 repurposes the custom RTD sensor type
(18) and custom thermistor type (27).
However, the schema doesn't restrict adi,sensor-type = <18> inside ^rtd@ nodes
or adi,sensor-type = <27> inside ^thermistor@ nodes for the adi,adt7604
compatible.
Should these restrictions be added to this block to prevent invalid device
tree configurations from passing validation?
> + else:
> + patternProperties:
> + '^copper-trace@': false
> + '^leak-detector@': false
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260521164323.770626-1-liviu.stan@analog.com?part=7
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH v3 7/8] dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983
2026-05-21 18:23 ` sashiko-bot
@ 2026-05-22 11:42 ` Liviu Stan
2026-05-22 13:17 ` Jonathan Cameron
0 siblings, 1 reply; 30+ messages in thread
From: Liviu Stan @ 2026-05-22 11:42 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Liviu Stan, Francesco Lavra, linux-iio,
linux-kernel, linux, devicetree
On Thu, 21 May 2026 18:23:07 +0000 sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [Low] The new compatible string 'adi,adt7604' is omitted from the existing conditional block that disables '^temp@' nodes, violating subsystem guidelines.
> - [Low] The schema allows invalid 'adi,sensor-type' values in '^rtd@' and '^thermistor@' nodes for the ADT7604.
> --
>
> commit fbbcd3bcbfbb106e48a6545868dd2b27a56b39b5
> Author: Liviu Stan <liviu.stan@analog.com>
>
> dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983
>
> This commit adds support for the ADT7604 to the LTC2983 binding schema. It
> introduces the adi,adt7604 compatible string and adds two new sensor node
> types: copper-trace@ and leak-detector@. It also adds conditional checks to
> restrict unsupported nodes for the ADT7604 device.
>
> > diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
> > index a22725f7619b7..14cfa28809edd 100644
> > --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
> > +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
> [ ... ]
> > @@ -477,6 +597,22 @@ allOf:
> > patternProperties:
> > '^temp@': false
> >
> > + - if:
> > + properties:
> > + compatible:
> > + contains:
> > + const: adi,adt7604
> > + then:
> > + patternProperties:
> > + '^thermocouple@': false
> > + '^diode@': false
> > + '^adc@': false
> > + '^temp@': false
>
> [Severity: Low]
> Since ADT7604 shares the ^temp@: false constraint with the existing devices,
> should adi,adt7604 be added to the existing compatible enum block instead of
> duplicating the ^temp@ restriction in this new conditional?
I think keeping all ADT7604 related constraints in one block is more readable.
For the block above it's different because ltc2984 and ltc2983 share the same
constraints.
>
> [Severity: Low]
> The commit message mentions that ADT7604 repurposes the custom RTD sensor type
> (18) and custom thermistor type (27).
>
> However, the schema doesn't restrict adi,sensor-type = <18> inside ^rtd@ nodes
> or adi,sensor-type = <27> inside ^thermistor@ nodes for the adi,adt7604
> compatible.
>
> Should these restrictions be added to this block to prevent invalid device
> tree configurations from passing validation?
>
This makes sense, we could restrict sensor type 18 and 27 for the ADT7604, even
though the driver's supported_sensors bitmask already rejects them.
I could add something like:
- if:
properties:
compatible:
contains:
const: adi,adt7604
then:
patternProperties:
'^thermocouple@': false
'^diode@': false
'^adc@': false
'^temp@': false
'^rtd@':
properties:
adi,sensor-type:
not:
const: 18
'^thermistor@':
properties:
adi,sensor-type:
not:
const: 27
What do you think?
Thanks,
Liviu
^ permalink raw reply [flat|nested] 30+ messages in thread* Re: [PATCH v3 7/8] dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983
2026-05-22 11:42 ` Liviu Stan
@ 2026-05-22 13:17 ` Jonathan Cameron
0 siblings, 0 replies; 30+ messages in thread
From: Jonathan Cameron @ 2026-05-22 13:17 UTC (permalink / raw)
To: Liviu Stan
Cc: David Lechner, Nuno Sá, Andy Shevchenko, Michael Hennerich,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Antoniu Miclaus,
Francesco Lavra, linux-iio, linux-kernel, linux, devicetree
On Fri, 22 May 2026 14:42:53 +0300
Liviu Stan <liviu.stan@analog.com> wrote:
> On Thu, 21 May 2026 18:23:07 +0000 sashiko-bot@kernel.org wrote:
>
> > Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> > - [Low] The new compatible string 'adi,adt7604' is omitted from the existing conditional block that disables '^temp@' nodes, violating subsystem guidelines.
> > - [Low] The schema allows invalid 'adi,sensor-type' values in '^rtd@' and '^thermistor@' nodes for the ADT7604.
> > --
> >
> > commit fbbcd3bcbfbb106e48a6545868dd2b27a56b39b5
> > Author: Liviu Stan <liviu.stan@analog.com>
> >
> > dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983
> >
> > This commit adds support for the ADT7604 to the LTC2983 binding schema. It
> > introduces the adi,adt7604 compatible string and adds two new sensor node
> > types: copper-trace@ and leak-detector@. It also adds conditional checks to
> > restrict unsupported nodes for the ADT7604 device.
> >
> > > diff --git a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
> > > index a22725f7619b7..14cfa28809edd 100644
> > > --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
> > > +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
> > [ ... ]
> > > @@ -477,6 +597,22 @@ allOf:
> > > patternProperties:
> > > '^temp@': false
> > >
> > > + - if:
> > > + properties:
> > > + compatible:
> > > + contains:
> > > + const: adi,adt7604
> > > + then:
> > > + patternProperties:
> > > + '^thermocouple@': false
> > > + '^diode@': false
> > > + '^adc@': false
> > > + '^temp@': false
> >
> > [Severity: Low]
> > Since ADT7604 shares the ^temp@: false constraint with the existing devices,
> > should adi,adt7604 be added to the existing compatible enum block instead of
> > duplicating the ^temp@ restriction in this new conditional?
>
> I think keeping all ADT7604 related constraints in one block is more readable.
> For the block above it's different because ltc2984 and ltc2983 share the same
> constraints.
Agreed
>
> >
> > [Severity: Low]
> > The commit message mentions that ADT7604 repurposes the custom RTD sensor type
> > (18) and custom thermistor type (27).
> >
> > However, the schema doesn't restrict adi,sensor-type = <18> inside ^rtd@ nodes
> > or adi,sensor-type = <27> inside ^thermistor@ nodes for the adi,adt7604
> > compatible.
> >
> > Should these restrictions be added to this block to prevent invalid device
> > tree configurations from passing validation?
> >
>
> This makes sense, we could restrict sensor type 18 and 27 for the ADT7604, even
> though the driver's supported_sensors bitmask already rejects them.
>
> I could add something like:
>
> - if:
> properties:
> compatible:
> contains:
> const: adi,adt7604
> then:
> patternProperties:
> '^thermocouple@': false
> '^diode@': false
> '^adc@': false
> '^temp@': false
> '^rtd@':
> properties:
> adi,sensor-type:
> not:
> const: 18
> '^thermistor@':
> properties:
> adi,sensor-type:
> not:
> const: 27
>
> What do you think?
>
Seems like a nice to have.
> Thanks,
> Liviu
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v3 8/8] iio: temperature: ltc2983: Add support for ADT7604
2026-05-21 16:42 [PATCH v3 0/8] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
` (6 preceding siblings ...)
2026-05-21 16:43 ` [PATCH v3 7/8] dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983 Liviu Stan
@ 2026-05-21 16:43 ` Liviu Stan
2026-05-21 19:18 ` sashiko-bot
2026-05-22 13:34 ` Jonathan Cameron
7 siblings, 2 replies; 30+ messages in thread
From: Liviu Stan @ 2026-05-21 16:43 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Francesco Lavra, Liviu Stan, linux-iio,
linux-kernel, linux, devicetree
The ADT7604 shares the same die as the LTC2984. It repurposes the
custom RTD sensor type (18) as a copper trace resistance sensor
and the custom thermistor type (27) as a leak detector, and
removes thermocouple, diode and direct ADC sensor types.
Two new software sensor type values are introduced
(LTC2983_SENSOR_COPPER_TRACE = 32, LTC2983_SENSOR_LEAK_DETECTOR = 33)
that map to the hardware register values 18 and 27 respectively.
Dedicated structs (ltc2983_copper_trace, ltc2983_leak_detector) and
parser functions are added rather than extending the existing RTD and
thermistor paths, as the hardware configuration bits are fully
hardcoded and several RTD/thermistor properties would need to be
explicitly forbidden or ignored.
Custom RTD (type 18) becomes the copper trace sensor. Sensor
configuration bits are hardcoded to 0b1001 per the datasheet.
Two variants are supported via the adi,copper-trace-sub-ohm DT
property: sub-ohm traces (< 1 ohm) have bits 17:0 cleared with no
excitation current or custom table; standard traces (> 1 ohm) have
a required resistance-to-temperature table.
Custom thermistor (type 27) becomes the leak detector. Sensor
configuration bits are hardcoded to 0b001. The custom table uses
a resolution of 16 instead of 64, and is specified via the
required adi,custom-leak-detector DT property.
Both sensor types expose an IIO_RESISTANCE channel reading from
the resistance result register bank (0x0060-0x00AF). Added a
"base" parameter to the LTC2983_RESULT_ADDR macro and a "base_reg"
parameter to the ltc2983_chan_read function so we can read from
both result register banks. The resistance register encodes the
measured resistance with 10 fractional bits, so dividing by 1024
gives ohms. Since the sense resistor is specified in ohms, the
output is in ohms for both sensor types and a single 1/1024
scale applies to both. For > 1 ohm copper traces and for leak
detectors, a secondary channel also appears: IIO_TEMP
(millidegrees Celsius) for copper trace and IIO_COVERAGE (percent)
for leak detector.
The ltc2983_chip_info struct is extended with a u64 supported_sensors
bitmask using BIT_ULL() to safely represent the new sensor type bits
32 and 33 on 32-bit builds. A LTC2983_SENSOR_NUM sentinel is added
to the enum so that the bounds check uses >= LTC2983_SENSOR_NUM
rather than hardcoding the last sensor type.
Tested on EVAL-ADT7604-AZ connected to Raspberry Pi 5 via SPI.
Signed-off-by: Liviu Stan <liviu.stan@analog.com>
---
Changes in v3:
- Relocated the "base" parameter addition from patch 1 to this one since
the resistance result memory region is (currently) ADT7604-specific
- Updated the commit message to mention the base and base_reg parameters
added to the result-bank read helpers
- Stacked the IIO_RESISTANCE and IIO_COVERAGE case labels in
ltc2983_read_raw()
- Added LTC2983_SENSOR_NUM sentinel at the end of the sensor-type enum
- Changed the sensor-type bounds check from > LTC2983_SENSOR_LEAK_DETECTOR
to >= LTC2983_SENSOR_NUM
- Reordered the ltm2985_chip_info_data struct initializer so has_eeprom
doesn't look like it was added to the ltm2985 in the diff
- Changed the custom leak detector table encoding, users now specify
plain coverage percentage values (0-100) in the device tree and the
driver applies the +273.15 C offset internally before writing the
hardware table
- Changed custom-rtd to custom-copper-trace to better represent the
copper trace custom table, and made it required for > 1 ohm variants
- Made custom-leak-detector required for leak detector sensors, _new
and _assign_chan functions were updated for both sensor types
- Updated commit message to reflect the changes
- Removed "..." from "rsense channel must be configured" error message
from ltc2983_leak_detector_new()
- Removed blank line before hw_type declaration in
__ltc2983_chan_assign_common
drivers/iio/temperature/ltc2983.c | 413 ++++++++++++++++++++++++++++--
1 file changed, 394 insertions(+), 19 deletions(-)
diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
index 326f843f4271..e2ffeee026ee 100644
--- a/drivers/iio/temperature/ltc2983.c
+++ b/drivers/iio/temperature/ltc2983.c
@@ -28,6 +28,8 @@
#define LTC2983_STATUS_REG 0x0000
#define LTC2983_TEMP_RES_START_REG 0x0010
#define LTC2983_TEMP_RES_END_REG 0x005F
+#define ADT7604_RES_RES_START_REG 0x0060
+#define ADT7604_RES_RES_END_REG 0x00AF
#define LTC2983_EEPROM_KEY_REG 0x00B0
#define LTC2983_EEPROM_READ_STATUS_REG 0x00D0
#define LTC2983_GLOBAL_CONFIG_REG 0x00F0
@@ -58,8 +60,8 @@
#define LTC2983_CHAN_ASSIGN_ADDR(chan) \
((((chan) - 1) * 4) + LTC2983_CHAN_ASSIGN_START_REG)
-#define LTC2983_RESULT_ADDR(chan) \
- ((((chan) - 1) * 4) + LTC2983_TEMP_RES_START_REG)
+#define LTC2983_RESULT_ADDR(chan, base) \
+ ((((chan) - 1) * 4) + (base))
#define LTC2983_THERMOCOUPLE_DIFF_MASK BIT(3)
#define LTC2983_THERMOCOUPLE_SGL(x) \
FIELD_PREP(LTC2983_THERMOCOUPLE_DIFF_MASK, x)
@@ -186,17 +188,44 @@ enum {
LTC2983_SENSOR_SENSE_RESISTOR = 29,
LTC2983_SENSOR_DIRECT_ADC = 30,
LTC2983_SENSOR_ACTIVE_TEMP = 31,
+ /* Sensor types for some parts only; map to RTD_CUSTOM/THERMISTOR_CUSTOM in HW */
+ LTC2983_SENSOR_COPPER_TRACE = 32,
+ LTC2983_SENSOR_LEAK_DETECTOR = 33,
+ LTC2983_SENSOR_NUM,
};
+/* Bitmask of sensor types supported by LTC2983/LTC2984 and derivatives */
+#define LTC2983_COMMON_SENSORS \
+ (GENMASK_ULL(LTC2983_SENSOR_THERMOCOUPLE_CUSTOM, LTC2983_SENSOR_THERMOCOUPLE) | \
+ GENMASK_ULL(LTC2983_SENSOR_RTD_CUSTOM, LTC2983_SENSOR_RTD) | \
+ GENMASK_ULL(LTC2983_SENSOR_THERMISTOR_CUSTOM, LTC2983_SENSOR_THERMISTOR) | \
+ BIT_ULL(LTC2983_SENSOR_DIODE) | \
+ BIT_ULL(LTC2983_SENSOR_SENSE_RESISTOR) | \
+ BIT_ULL(LTC2983_SENSOR_DIRECT_ADC))
+
+/* Bitmask of sensor types supported by ADT7604 */
+#define ADT7604_SENSORS \
+ (GENMASK_ULL(LTC2983_SENSOR_RTD_CUSTOM - 1, LTC2983_SENSOR_RTD) | \
+ GENMASK_ULL(LTC2983_SENSOR_THERMISTOR_CUSTOM - 1, LTC2983_SENSOR_THERMISTOR) | \
+ BIT_ULL(LTC2983_SENSOR_SENSE_RESISTOR) | \
+ BIT_ULL(LTC2983_SENSOR_COPPER_TRACE) | \
+ BIT_ULL(LTC2983_SENSOR_LEAK_DETECTOR))
+
#define to_thermocouple(_sensor) \
container_of(_sensor, struct ltc2983_thermocouple, sensor)
#define to_rtd(_sensor) \
container_of(_sensor, struct ltc2983_rtd, sensor)
+#define to_copper_trace(_sensor) \
+ container_of(_sensor, struct ltc2983_copper_trace, sensor)
+
#define to_thermistor(_sensor) \
container_of(_sensor, struct ltc2983_thermistor, sensor)
+#define to_leak_detector(_sensor) \
+ container_of(_sensor, struct ltc2983_leak_detector, sensor)
+
#define to_diode(_sensor) \
container_of(_sensor, struct ltc2983_diode, sensor)
@@ -212,7 +241,7 @@ enum {
struct ltc2983_chip_info {
const char *name;
unsigned int max_channels_nr;
- bool has_temp;
+ u64 supported_sensors;
bool has_eeprom;
};
@@ -247,6 +276,8 @@ struct ltc2983_sensor {
u32 chan;
/* sensor type */
u32 type;
+ /* number of IIO channels this sensor produces */
+ u8 n_iio_chan;
};
struct ltc2983_custom_sensor {
@@ -274,6 +305,25 @@ struct ltc2983_rtd {
u32 rtd_curve;
};
+struct ltc2983_copper_trace {
+ struct ltc2983_sensor sensor;
+ struct ltc2983_custom_sensor *custom;
+ u32 r_sense_chan;
+ u32 excitation_current;
+ /* selects the <1Ω variant: bits 17:0 of the channel word are zeroed,
+ * disabling excitation current and custom table fields (ADT7604
+ * datasheet Table 26)
+ */
+ bool is_sub_ohm;
+};
+
+struct ltc2983_leak_detector {
+ struct ltc2983_sensor sensor;
+ struct ltc2983_custom_sensor *custom;
+ u32 r_sense_chan;
+ u32 excitation_current;
+};
+
struct ltc2983_thermistor {
struct ltc2983_sensor sensor;
struct ltc2983_custom_sensor *custom;
@@ -353,8 +403,14 @@ static int __ltc2983_chan_assign_common(struct ltc2983_data *st,
{
struct device *dev = &st->spi->dev;
u32 reg = LTC2983_CHAN_ASSIGN_ADDR(sensor->chan);
+ u32 hw_type = sensor->type;
- chan_val |= LTC2983_CHAN_TYPE(sensor->type);
+ if (hw_type == LTC2983_SENSOR_COPPER_TRACE)
+ hw_type = LTC2983_SENSOR_RTD_CUSTOM;
+ else if (hw_type == LTC2983_SENSOR_LEAK_DETECTOR)
+ hw_type = LTC2983_SENSOR_THERMISTOR_CUSTOM;
+
+ chan_val |= LTC2983_CHAN_TYPE(hw_type);
dev_dbg(dev, "Assign reg:0x%04X, val:0x%08X\n", reg,
chan_val);
st->chan_val = cpu_to_be32(chan_val);
@@ -486,6 +542,14 @@ __ltc2983_custom_sensor_new(struct ltc2983_data *st, const struct fwnode_handle
for (index = 0; index < n_entries; index++) {
u64 temp = ((u64 *)new_custom->table)[index];
+ /*
+ * Users specify plain coverage percentage (0-100). Convert
+ * to µK so __convert_to_raw() produces the correct hardware
+ * encoding: P + 273.15 K.
+ */
+ if ((index % 2) != 0 && !strcmp(propname, "adi,custom-leak-detector"))
+ temp = temp * 1000000 + 273150000;
+
if ((index % 2) != 0)
temp = __convert_to_raw(temp, 1024);
else if (has_signed && (s64)temp < 0)
@@ -579,6 +643,31 @@ static int ltc2983_rtd_assign_chan(struct ltc2983_data *st,
return __ltc2983_chan_assign_common(st, sensor, chan_val);
}
+static int ltc2983_copper_trace_assign_chan(struct ltc2983_data *st,
+ const struct ltc2983_sensor *sensor)
+{
+ struct ltc2983_copper_trace *ct = to_copper_trace(sensor);
+ u32 chan_val;
+
+ chan_val = LTC2983_CHAN_ASSIGN(ct->r_sense_chan);
+ /* Sensor config bits 21:18 must be 0b1001 (ADT7604 datasheet Table 26) */
+ chan_val |= LTC2983_RTD_CFG(0x9);
+
+ if (ct->is_sub_ohm) {
+ chan_val &= ~GENMASK(17, 0);
+ } else {
+ int ret;
+
+ chan_val |= LTC2983_RTD_EXC_CURRENT(ct->excitation_current);
+ ret = __ltc2983_chan_custom_sensor_assign(st, ct->custom,
+ &chan_val);
+ if (ret)
+ return ret;
+ }
+
+ return __ltc2983_chan_assign_common(st, sensor, chan_val);
+}
+
static int ltc2983_thermistor_assign_chan(struct ltc2983_data *st,
const struct ltc2983_sensor *sensor)
{
@@ -602,6 +691,25 @@ static int ltc2983_thermistor_assign_chan(struct ltc2983_data *st,
return __ltc2983_chan_assign_common(st, sensor, chan_val);
}
+static int ltc2983_leak_detector_assign_chan(struct ltc2983_data *st,
+ const struct ltc2983_sensor *sensor)
+{
+ struct ltc2983_leak_detector *ld = to_leak_detector(sensor);
+ u32 chan_val;
+ int ret;
+
+ chan_val = LTC2983_CHAN_ASSIGN(ld->r_sense_chan);
+ /* bits 21:19 must be 0b001 (ADT7604 datasheet Table 38) */
+ chan_val |= LTC2983_THERMISTOR_CFG(1);
+ chan_val |= LTC2983_THERMISTOR_EXC_CURRENT(ld->excitation_current);
+
+ ret = __ltc2983_chan_custom_sensor_assign(st, ld->custom, &chan_val);
+ if (ret)
+ return ret;
+
+ return __ltc2983_chan_assign_common(st, sensor, chan_val);
+}
+
static int ltc2983_diode_assign_chan(struct ltc2983_data *st,
const struct ltc2983_sensor *sensor)
{
@@ -1037,6 +1145,195 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
return &thermistor->sensor;
}
+static struct ltc2983_sensor *
+ltc2983_copper_trace_new(const struct fwnode_handle *child, struct ltc2983_data *st,
+ const struct ltc2983_sensor *sensor)
+{
+ struct device *dev = &st->spi->dev;
+ struct ltc2983_copper_trace *ct;
+ int ret;
+
+ if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
+ return dev_err_ptr_probe(dev, -EINVAL,
+ "Invalid channel %d for copper trace\n",
+ sensor->chan);
+
+ ct = devm_kzalloc(dev, sizeof(*ct), GFP_KERNEL);
+ if (!ct)
+ return ERR_PTR(-ENOMEM);
+
+ struct fwnode_handle *ref __free(fwnode_handle) =
+ fwnode_find_reference(child, "adi,rsense-handle", 0);
+ if (IS_ERR(ref))
+ return dev_err_cast_probe(dev, ref,
+ "Property adi,rsense-handle missing or invalid\n");
+
+ ret = fwnode_property_read_u32(ref, "reg", &ct->r_sense_chan);
+ if (ret)
+ return dev_err_ptr_probe(dev, ret, "Property reg must be given\n");
+
+ ct->is_sub_ohm = fwnode_property_read_bool(child, "adi,copper-trace-sub-ohm");
+
+ if (ct->is_sub_ohm && fwnode_property_present(child, "adi,custom-copper-trace"))
+ return dev_err_ptr_probe(dev, -EINVAL,
+ "sub-ohm copper trace cannot have a custom table\n");
+
+ if (!ct->is_sub_ohm) {
+ u32 excitation_current = 0;
+
+ if (!fwnode_property_present(child, "adi,custom-copper-trace"))
+ return dev_err_ptr_probe(dev, -EINVAL,
+ "adi,custom-copper-trace is required for >1 ohm copper trace\n");
+
+ ct->custom = __ltc2983_custom_sensor_new(st, child, "adi,custom-copper-trace",
+ false, 2048, false);
+ if (IS_ERR(ct->custom))
+ return ERR_CAST(ct->custom);
+
+ if (fwnode_property_present(child, "adi,excitation-current-microamp")) {
+ ret = fwnode_property_read_u32(child, "adi,excitation-current-microamp",
+ &excitation_current);
+ if (ret)
+ return dev_err_ptr_probe(dev, ret,
+ "Failed to read adi,excitation-current-microamp\n");
+
+ switch (excitation_current) {
+ case 5:
+ ct->excitation_current = 0x01;
+ break;
+ case 10:
+ ct->excitation_current = 0x02;
+ break;
+ case 25:
+ ct->excitation_current = 0x03;
+ break;
+ case 50:
+ ct->excitation_current = 0x04;
+ break;
+ case 100:
+ ct->excitation_current = 0x05;
+ break;
+ case 250:
+ ct->excitation_current = 0x06;
+ break;
+ case 500:
+ ct->excitation_current = 0x07;
+ break;
+ case 1000:
+ ct->excitation_current = 0x08;
+ break;
+ default:
+ return dev_err_ptr_probe(dev, -EINVAL,
+ "Invalid value for excitation current(%u)\n",
+ excitation_current);
+ }
+ } else {
+ /* default to 1mA per datasheet recommendation for copper trace */
+ ct->excitation_current = 0x08;
+ }
+ }
+
+ ct->sensor.fault_handler = ltc2983_common_fault_handler;
+ ct->sensor.assign_chan = ltc2983_copper_trace_assign_chan;
+ if (ct->is_sub_ohm)
+ ct->sensor.n_iio_chan = 1;
+ else
+ ct->sensor.n_iio_chan = 2;
+
+ return &ct->sensor;
+}
+
+static struct ltc2983_sensor *
+ltc2983_leak_detector_new(const struct fwnode_handle *child, struct ltc2983_data *st,
+ const struct ltc2983_sensor *sensor)
+{
+ struct device *dev = &st->spi->dev;
+ struct ltc2983_leak_detector *ld;
+ int ret;
+ u32 excitation_current = 0;
+
+ if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
+ return dev_err_ptr_probe(dev, -EINVAL,
+ "Invalid channel %d for leak detector\n",
+ sensor->chan);
+
+ ld = devm_kzalloc(dev, sizeof(*ld), GFP_KERNEL);
+ if (!ld)
+ return ERR_PTR(-ENOMEM);
+
+ struct fwnode_handle *ref __free(fwnode_handle) =
+ fwnode_find_reference(child, "adi,rsense-handle", 0);
+ if (IS_ERR(ref))
+ return dev_err_cast_probe(dev, ref,
+ "Property adi,rsense-handle missing or invalid\n");
+
+ ret = fwnode_property_read_u32(ref, "reg", &ld->r_sense_chan);
+ if (ret)
+ return dev_err_ptr_probe(dev, ret,
+ "rsense channel must be configured\n");
+
+ if (!fwnode_property_present(child, "adi,custom-leak-detector"))
+ return dev_err_ptr_probe(dev, -EINVAL,
+ "adi,custom-leak-detector is required for leak detectors\n");
+
+ ld->custom = __ltc2983_custom_sensor_new(st, child, "adi,custom-leak-detector",
+ false, 16, false);
+ if (IS_ERR(ld->custom))
+ return ERR_CAST(ld->custom);
+
+ ret = fwnode_property_read_u32(child, "adi,excitation-current-nanoamp",
+ &excitation_current);
+ if (ret)
+ return dev_err_ptr_probe(dev, ret,
+ "adi,excitation-current-nanoamp is required for leak detectors\n");
+
+ switch (excitation_current) {
+ case 250:
+ ld->excitation_current = 0x01;
+ break;
+ case 500:
+ ld->excitation_current = 0x02;
+ break;
+ case 1000:
+ ld->excitation_current = 0x03;
+ break;
+ case 5000:
+ ld->excitation_current = 0x04;
+ break;
+ case 10000:
+ ld->excitation_current = 0x05;
+ break;
+ case 25000:
+ ld->excitation_current = 0x06;
+ break;
+ case 50000:
+ ld->excitation_current = 0x07;
+ break;
+ case 100000:
+ ld->excitation_current = 0x08;
+ break;
+ case 250000:
+ ld->excitation_current = 0x09;
+ break;
+ case 500000:
+ ld->excitation_current = 0x0a;
+ break;
+ case 1000000:
+ ld->excitation_current = 0x0b;
+ break;
+ default:
+ return dev_err_ptr_probe(dev, -EINVAL,
+ "Invalid value for excitation current(%u)\n",
+ excitation_current);
+ }
+
+ ld->sensor.fault_handler = ltc2983_common_fault_handler;
+ ld->sensor.assign_chan = ltc2983_leak_detector_assign_chan;
+ ld->sensor.n_iio_chan = 2;
+
+ return &ld->sensor;
+}
+
static struct ltc2983_sensor *
ltc2983_diode_new(const struct fwnode_handle *child, const struct ltc2983_data *st,
const struct ltc2983_sensor *sensor)
@@ -1205,7 +1502,8 @@ static struct ltc2983_sensor *ltc2983_temp_new(struct fwnode_handle *child,
}
static int ltc2983_chan_read(struct ltc2983_data *st,
- const struct ltc2983_sensor *sensor, int *val)
+ const struct ltc2983_sensor *sensor,
+ u32 base_reg, int *val)
{
struct device *dev = &st->spi->dev;
u32 start_conversion = 0;
@@ -1236,13 +1534,23 @@ static int ltc2983_chan_read(struct ltc2983_data *st,
}
/* read the converted data */
- ret = regmap_bulk_read(st->regmap, LTC2983_RESULT_ADDR(sensor->chan),
+ ret = regmap_bulk_read(st->regmap, LTC2983_RESULT_ADDR(sensor->chan, base_reg),
&st->temp, sizeof(st->temp));
if (ret)
return ret;
*val = __be32_to_cpu(st->temp);
+ if (base_reg == ADT7604_RES_RES_START_REG) {
+ /*
+ * Resistance result register gives a plain unsigned value,
+ * D31 is always 0, no valid bit, no fault bits. Read bits[30:0]
+ * directly — the temperature result format does not apply here.
+ */
+ *val &= GENMASK(30, 0);
+ return 0;
+ }
+
if (!(LTC2983_RES_VALID_MASK & *val)) {
dev_err(dev, "Invalid conversion detected\n");
return -EIO;
@@ -1274,7 +1582,16 @@ static int ltc2983_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
mutex_lock(&st->lock);
- ret = ltc2983_chan_read(st, st->sensors[chan->address], val);
+ switch (chan->type) {
+ case IIO_RESISTANCE:
+ ret = ltc2983_chan_read(st, st->sensors[chan->address],
+ ADT7604_RES_RES_START_REG, val);
+ break;
+ default:
+ ret = ltc2983_chan_read(st, st->sensors[chan->address],
+ LTC2983_TEMP_RES_START_REG, val);
+ break;
+ }
mutex_unlock(&st->lock);
return ret ?: IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
@@ -1291,6 +1608,13 @@ static int ltc2983_read_raw(struct iio_dev *indio_dev,
/* 2^21 */
*val2 = 2097152;
return IIO_VAL_FRACTIONAL;
+ case IIO_RESISTANCE:
+ case IIO_COVERAGE:
+ /* value in ohm/percent */
+ *val = 1;
+ /* 2^10 */
+ *val2 = 1024;
+ return IIO_VAL_FRACTIONAL;
default:
return -EINVAL;
}
@@ -1351,7 +1675,7 @@ static int ltc2983_parse_fw(struct ltc2983_data *st)
if (!st->sensors)
return -ENOMEM;
- st->iio_channels = st->num_channels;
+ st->iio_channels = 0;
device_for_each_child_node_scoped(dev, child) {
struct ltc2983_sensor sensor;
@@ -1379,6 +1703,12 @@ static int ltc2983_parse_fw(struct ltc2983_data *st)
return dev_err_probe(dev, ret,
"adi,sensor-type property must given for child nodes\n");
+ if (sensor.type >= LTC2983_SENSOR_NUM ||
+ !(st->info->supported_sensors & BIT_ULL(sensor.type)))
+ return dev_err_probe(dev, -EINVAL,
+ "sensor type %d not supported on %s\n",
+ sensor.type, st->info->name);
+
dev_dbg(dev, "Create new sensor, type %u, channel %u",
sensor.type, sensor.chan);
@@ -1399,13 +1729,14 @@ static int ltc2983_parse_fw(struct ltc2983_data *st)
} else if (sensor.type == LTC2983_SENSOR_SENSE_RESISTOR) {
st->sensors[chan] = ltc2983_r_sense_new(child, st,
&sensor);
- /* don't add rsense to iio */
- st->iio_channels--;
} else if (sensor.type == LTC2983_SENSOR_DIRECT_ADC) {
st->sensors[chan] = ltc2983_adc_new(child, st, &sensor);
- } else if (st->info->has_temp &&
- sensor.type == LTC2983_SENSOR_ACTIVE_TEMP) {
+ } else if (sensor.type == LTC2983_SENSOR_ACTIVE_TEMP) {
st->sensors[chan] = ltc2983_temp_new(child, st, &sensor);
+ } else if (sensor.type == LTC2983_SENSOR_COPPER_TRACE) {
+ st->sensors[chan] = ltc2983_copper_trace_new(child, st, &sensor);
+ } else if (sensor.type == LTC2983_SENSOR_LEAK_DETECTOR) {
+ st->sensors[chan] = ltc2983_leak_detector_new(child, st, &sensor);
} else {
return dev_err_probe(dev, -EINVAL,
"Unknown sensor type %d\n",
@@ -1420,6 +1751,16 @@ static int ltc2983_parse_fw(struct ltc2983_data *st)
st->sensors[chan]->chan = sensor.chan;
st->sensors[chan]->type = sensor.type;
+ /*
+ * Dedicated functions set n_iio_chan themselves; for all other
+ * sensor types rsense produces 0 channels, everything else 1.
+ */
+ if (!st->sensors[chan]->n_iio_chan) {
+ if (sensor.type != LTC2983_SENSOR_SENSE_RESISTOR)
+ st->sensors[chan]->n_iio_chan = 1;
+ }
+ st->iio_channels += st->sensors[chan]->n_iio_chan;
+
channel_avail_mask |= BIT(sensor.chan);
chan++;
}
@@ -1467,8 +1808,9 @@ static int ltc2983_eeprom_cmd(struct ltc2983_data *st, unsigned int cmd,
static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
{
- u32 iio_chan_t = 0, iio_chan_v = 0, chan, iio_idx = 0, status;
struct device *dev = &st->spi->dev;
+ u32 iio_chan_t = 0, iio_chan_v = 0, iio_chan_r = 0, iio_chan_c = 0;
+ u32 chan, iio_idx = 0, status;
int ret;
/* make sure the device is up: start bit (7) is 0 and done bit (6) is 1 */
@@ -1516,12 +1858,33 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
continue;
/* assign iio channel */
- if (st->sensors[chan]->type != LTC2983_SENSOR_DIRECT_ADC) {
- chan_type = IIO_TEMP;
- iio_chan = &iio_chan_t;
- } else {
+ switch (st->sensors[chan]->type) {
+ case LTC2983_SENSOR_COPPER_TRACE:
+ if (st->sensors[chan]->n_iio_chan == 1) {
+ /* sub-ohm copper traces produce only a resistance result */
+ st->iio_chan[iio_idx++] =
+ LTC2983_CHAN(IIO_RESISTANCE, iio_chan_r++, chan);
+ } else {
+ st->iio_chan[iio_idx++] =
+ LTC2983_CHAN(IIO_TEMP, iio_chan_t++, chan);
+ st->iio_chan[iio_idx++] =
+ LTC2983_CHAN(IIO_RESISTANCE, iio_chan_r++, chan);
+ }
+ continue;
+ case LTC2983_SENSOR_LEAK_DETECTOR:
+ st->iio_chan[iio_idx++] =
+ LTC2983_CHAN(IIO_COVERAGE, iio_chan_c++, chan);
+ st->iio_chan[iio_idx++] =
+ LTC2983_CHAN(IIO_RESISTANCE, iio_chan_r++, chan);
+ continue;
+ case LTC2983_SENSOR_DIRECT_ADC:
chan_type = IIO_VOLTAGE;
iio_chan = &iio_chan_v;
+ break;
+ default:
+ chan_type = IIO_TEMP;
+ iio_chan = &iio_chan_t;
+ break;
}
/*
@@ -1538,6 +1901,7 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
static const struct regmap_range ltc2983_reg_ranges[] = {
regmap_reg_range(LTC2983_STATUS_REG, LTC2983_STATUS_REG),
regmap_reg_range(LTC2983_TEMP_RES_START_REG, LTC2983_TEMP_RES_END_REG),
+ regmap_reg_range(ADT7604_RES_RES_START_REG, ADT7604_RES_RES_END_REG),
regmap_reg_range(LTC2983_EEPROM_KEY_REG, LTC2983_EEPROM_KEY_REG),
regmap_reg_range(LTC2983_EEPROM_READ_STATUS_REG,
LTC2983_EEPROM_READ_STATUS_REG),
@@ -1680,26 +2044,35 @@ static DEFINE_SIMPLE_DEV_PM_OPS(ltc2983_pm_ops, ltc2983_suspend,
static const struct ltc2983_chip_info ltc2983_chip_info_data = {
.name = "ltc2983",
.max_channels_nr = 20,
+ .supported_sensors = LTC2983_COMMON_SENSORS,
};
static const struct ltc2983_chip_info ltc2984_chip_info_data = {
.name = "ltc2984",
.max_channels_nr = 20,
.has_eeprom = true,
+ .supported_sensors = LTC2983_COMMON_SENSORS,
};
static const struct ltc2983_chip_info ltc2986_chip_info_data = {
.name = "ltc2986",
.max_channels_nr = 10,
- .has_temp = true,
.has_eeprom = true,
+ .supported_sensors = LTC2983_COMMON_SENSORS | BIT_ULL(LTC2983_SENSOR_ACTIVE_TEMP),
};
static const struct ltc2983_chip_info ltm2985_chip_info_data = {
.name = "ltm2985",
.max_channels_nr = 10,
- .has_temp = true,
.has_eeprom = true,
+ .supported_sensors = LTC2983_COMMON_SENSORS | BIT_ULL(LTC2983_SENSOR_ACTIVE_TEMP),
+};
+
+static const struct ltc2983_chip_info adt7604_chip_info_data = {
+ .name = "adt7604",
+ .max_channels_nr = 20,
+ .has_eeprom = true,
+ .supported_sensors = ADT7604_SENSORS,
};
static const struct spi_device_id ltc2983_id_table[] = {
@@ -1707,6 +2080,7 @@ static const struct spi_device_id ltc2983_id_table[] = {
{ "ltc2984", (kernel_ulong_t)<c2984_chip_info_data },
{ "ltc2986", (kernel_ulong_t)<c2986_chip_info_data },
{ "ltm2985", (kernel_ulong_t)<m2985_chip_info_data },
+ { "adt7604", (kernel_ulong_t)&adt7604_chip_info_data },
{ }
};
MODULE_DEVICE_TABLE(spi, ltc2983_id_table);
@@ -1716,6 +2090,7 @@ static const struct of_device_id ltc2983_of_match[] = {
{ .compatible = "adi,ltc2984", .data = <c2984_chip_info_data },
{ .compatible = "adi,ltc2986", .data = <c2986_chip_info_data },
{ .compatible = "adi,ltm2985", .data = <m2985_chip_info_data },
+ { .compatible = "adi,adt7604", .data = &adt7604_chip_info_data },
{ }
};
MODULE_DEVICE_TABLE(of, ltc2983_of_match);
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread* Re: [PATCH v3 8/8] iio: temperature: ltc2983: Add support for ADT7604
2026-05-21 16:43 ` [PATCH v3 8/8] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
@ 2026-05-21 19:18 ` sashiko-bot
2026-05-22 13:23 ` Liviu Stan
2026-05-22 13:34 ` Jonathan Cameron
1 sibling, 1 reply; 30+ messages in thread
From: sashiko-bot @ 2026-05-21 19:18 UTC (permalink / raw)
To: Liviu Stan; +Cc: devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [High] Reading the IIO_RESISTANCE channel bypasses hardware fault detection, causing hardware errors (like broken sensor traces) to be silently reported as valid data.
Pre-existing issues:
- [High] reinit_completion() is called after initiating the hardware conversion, creating a race condition that can cause spurious read timeouts.
--
commit d382a4cbefd41723ab5ddd91fd399d716c8faaec
Author: Liviu Stan <liviu.stan@analog.com>
Subject: iio: temperature: ltc2983: Add support for ADT7604
This commit adds support for the ADT7604 temperature sensor by repurposing
custom RTD and thermistor types as copper trace resistance and leak detector
sensors. It introduces two new software sensor types and exposes a new
IIO_RESISTANCE channel reading from a separate result register bank. The
ltc2983_chip_info struct is also extended to use a 64-bit supported_sensors
bitmask for the new types.
> diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
> index 326f843f42713..e2ffeee026eef 100644
> --- a/drivers/iio/temperature/ltc2983.c
> +++ b/drivers/iio/temperature/ltc2983.c
[ ... ]
> @@ -1205,7 +1502,8 @@ static struct ltc2983_sensor *ltc2983_temp_new(struct fwnode_handle *child,
> }
>
> static int ltc2983_chan_read(struct ltc2983_data *st,
> - const struct ltc2983_sensor *sensor, int *val)
> + const struct ltc2983_sensor *sensor,
> + u32 base_reg, int *val)
> {
> struct device *dev = &st->spi->dev;
> u32 start_conversion = 0;
[Severity: High]
This is a pre-existing issue, but can this function experience spurious
read timeouts due to a race condition with the completion?
Looking at the rest of this function:
ret = regmap_write(st->regmap, LTC2983_STATUS_REG, start_conversion);
if (ret)
return ret;
reinit_completion(&st->completion);
If the hardware conversion finishes very quickly after regmap_write(),
could the interrupt fire and call complete() before the CPU executes
reinit_completion()? This would overwrite the completion event, causing the
subsequent wait_for_completion_timeout() to spuriously time out.
Would it be safer to call reinit_completion() before initiating the hardware
action?
[ ... ]
> @@ -1236,13 +1534,23 @@ static int ltc2983_chan_read(struct ltc2983_data *st,
> }
>
> /* read the converted data */
> - ret = regmap_bulk_read(st->regmap, LTC2983_RESULT_ADDR(sensor->chan),
> + ret = regmap_bulk_read(st->regmap, LTC2983_RESULT_ADDR(sensor->chan, base_reg),
> &st->temp, sizeof(st->temp));
> if (ret)
> return ret;
>
> *val = __be32_to_cpu(st->temp);
>
> + if (base_reg == ADT7604_RES_RES_START_REG) {
> + /*
> + * Resistance result register gives a plain unsigned value,
> + * D31 is always 0, no valid bit, no fault bits. Read bits[30:0]
> + * directly — the temperature result format does not apply here.
> + */
> + *val &= GENMASK(30, 0);
> + return 0;
[Severity: High]
Will returning early here bypass hardware fault detection for resistance
channels?
As the comment notes, the resistance result register does not contain fault
bits. However, hardware fault indicators (like Hard Fault, Soft Fault, or
Over Range) are stored in the primary Temperature Result register.
By returning before reading the Temperature Result register and calling
sensor->fault_handler(), does this code silently ignore sensor faults? This
might be problematic for sub-ohm copper traces, which only expose the
IIO_RESISTANCE channel, leaving users with no mechanism to detect a broken
trace.
> + }
> +
> if (!(LTC2983_RES_VALID_MASK & *val)) {
> dev_err(dev, "Invalid conversion detected\n");
> return -EIO;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260521164323.770626-1-liviu.stan@analog.com?part=8
^ permalink raw reply [flat|nested] 30+ messages in thread* Re: [PATCH v3 8/8] iio: temperature: ltc2983: Add support for ADT7604
2026-05-21 19:18 ` sashiko-bot
@ 2026-05-22 13:23 ` Liviu Stan
2026-05-22 14:09 ` David Lechner
0 siblings, 1 reply; 30+ messages in thread
From: Liviu Stan @ 2026-05-22 13:23 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Francesco Lavra, Liviu Stan, linux-iio,
linux-kernel, linux, devicetree
On Thu, 21 May 2026 19:18:28 +0000 sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
>
> New issues:
> - [High] Reading the IIO_RESISTANCE channel bypasses hardware fault detection, causing hardware errors (like broken sensor traces) to be silently reported as valid data.
>
> Pre-existing issues:
> - [High] reinit_completion() is called after initiating the hardware conversion, creating a race condition that can cause spurious read timeouts.
> --
>
> commit d382a4cbefd41723ab5ddd91fd399d716c8faaec
> Author: Liviu Stan <liviu.stan@analog.com>
> Subject: iio: temperature: ltc2983: Add support for ADT7604
>
> This commit adds support for the ADT7604 temperature sensor by repurposing
> custom RTD and thermistor types as copper trace resistance and leak detector
> sensors. It introduces two new software sensor types and exposes a new
> IIO_RESISTANCE channel reading from a separate result register bank. The
> ltc2983_chip_info struct is also extended to use a 64-bit supported_sensors
> bitmask for the new types.
>
> > diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
> > index 326f843f42713..e2ffeee026eef 100644
> > --- a/drivers/iio/temperature/ltc2983.c
> > +++ b/drivers/iio/temperature/ltc2983.c
>
> [ ... ]
>
> > @@ -1205,7 +1502,8 @@ static struct ltc2983_sensor *ltc2983_temp_new(struct fwnode_handle *child,
> > }
> >
> > static int ltc2983_chan_read(struct ltc2983_data *st,
> > - const struct ltc2983_sensor *sensor, int *val)
> > + const struct ltc2983_sensor *sensor,
> > + u32 base_reg, int *val)
> > {
> > struct device *dev = &st->spi->dev;
> > u32 start_conversion = 0;
>
> [Severity: High]
> This is a pre-existing issue, but can this function experience spurious
> read timeouts due to a race condition with the completion?
>
> Looking at the rest of this function:
>
> ret = regmap_write(st->regmap, LTC2983_STATUS_REG, start_conversion);
> if (ret)
> return ret;
>
> reinit_completion(&st->completion);
>
> If the hardware conversion finishes very quickly after regmap_write(),
> could the interrupt fire and call complete() before the CPU executes
> reinit_completion()? This would overwrite the completion event, causing the
> subsequent wait_for_completion_timeout() to spuriously time out.
>
> Would it be safer to call reinit_completion() before initiating the hardware
> action?
This is theoretically valid but in practice, the conversion requires at minimum
two 82ms cycles (167ms), so there is no realistic window for the interrupt to
race with reinit_completion(). What do you guys think?
>
> [ ... ]
>
> > @@ -1236,13 +1534,23 @@ static int ltc2983_chan_read(struct ltc2983_data *st,
> > }
> >
> > /* read the converted data */
> > - ret = regmap_bulk_read(st->regmap, LTC2983_RESULT_ADDR(sensor->chan),
> > + ret = regmap_bulk_read(st->regmap, LTC2983_RESULT_ADDR(sensor->chan, base_reg),
> > &st->temp, sizeof(st->temp));
> > if (ret)
> > return ret;
> >
> > *val = __be32_to_cpu(st->temp);
> >
> > + if (base_reg = ADT7604_RES_RES_START_REG) {
> > + /*
> > + * Resistance result register gives a plain unsigned value,
> > + * D31 is always 0, no valid bit, no fault bits. Read bits[30:0]
> > + * directly — the temperature result format does not apply here.
> > + */
> > + *val &= GENMASK(30, 0);
> > + return 0;
>
> [Severity: High]
> Will returning early here bypass hardware fault detection for resistance
> channels?
>
> As the comment notes, the resistance result register does not contain fault
> bits. However, hardware fault indicators (like Hard Fault, Soft Fault, or
> Over Range) are stored in the primary Temperature Result register.
>
> By returning before reading the Temperature Result register and calling
> sensor->fault_handler(), does this code silently ignore sensor faults? This
> might be problematic for sub-ohm copper traces, which only expose the
> IIO_RESISTANCE channel, leaving users with no mechanism to detect a broken
> trace.
>
First, I don't understand why Sashiko wrote "base_reg =
ADT7604_RES_RES_START_REG", the patch has a "==" there. Second, the temperature
result register stores fault indicator bits for temperature reads, not resistance.
Thanks,
Liviu
^ permalink raw reply [flat|nested] 30+ messages in thread* Re: [PATCH v3 8/8] iio: temperature: ltc2983: Add support for ADT7604
2026-05-22 13:23 ` Liviu Stan
@ 2026-05-22 14:09 ` David Lechner
0 siblings, 0 replies; 30+ messages in thread
From: David Lechner @ 2026-05-22 14:09 UTC (permalink / raw)
To: Liviu Stan, Jonathan Cameron, Nuno Sá, Andy Shevchenko,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Antoniu Miclaus, Francesco Lavra, linux-iio, linux-kernel, linux,
devicetree
On 5/22/26 8:23 AM, Liviu Stan wrote:
> On Thu, 21 May 2026 19:18:28 +0000 sashiko-bot@kernel.org wrote:
>
>> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
>>
>> New issues:
>> - [High] Reading the IIO_RESISTANCE channel bypasses hardware fault detection, causing hardware errors (like broken sensor traces) to be silently reported as valid data.
>>
>> Pre-existing issues:
>> - [High] reinit_completion() is called after initiating the hardware conversion, creating a race condition that can cause spurious read timeouts.
>> --
>>
>> commit d382a4cbefd41723ab5ddd91fd399d716c8faaec
>> Author: Liviu Stan <liviu.stan@analog.com>
>> Subject: iio: temperature: ltc2983: Add support for ADT7604
>>
>> This commit adds support for the ADT7604 temperature sensor by repurposing
>> custom RTD and thermistor types as copper trace resistance and leak detector
>> sensors. It introduces two new software sensor types and exposes a new
>> IIO_RESISTANCE channel reading from a separate result register bank. The
>> ltc2983_chip_info struct is also extended to use a 64-bit supported_sensors
>> bitmask for the new types.
>>
>>> diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
>>> index 326f843f42713..e2ffeee026eef 100644
>>> --- a/drivers/iio/temperature/ltc2983.c
>>> +++ b/drivers/iio/temperature/ltc2983.c
>>
>> [ ... ]
>>
>>> @@ -1205,7 +1502,8 @@ static struct ltc2983_sensor *ltc2983_temp_new(struct fwnode_handle *child,
>>> }
>>>
>>> static int ltc2983_chan_read(struct ltc2983_data *st,
>>> - const struct ltc2983_sensor *sensor, int *val)
>>> + const struct ltc2983_sensor *sensor,
>>> + u32 base_reg, int *val)
>>> {
>>> struct device *dev = &st->spi->dev;
>>> u32 start_conversion = 0;
>>
>> [Severity: High]
>> This is a pre-existing issue, but can this function experience spurious
>> read timeouts due to a race condition with the completion?
>>
>> Looking at the rest of this function:
>>
>> ret = regmap_write(st->regmap, LTC2983_STATUS_REG, start_conversion);
>> if (ret)
>> return ret;
>>
>> reinit_completion(&st->completion);
>>
>> If the hardware conversion finishes very quickly after regmap_write(),
>> could the interrupt fire and call complete() before the CPU executes
>> reinit_completion()? This would overwrite the completion event, causing the
>> subsequent wait_for_completion_timeout() to spuriously time out.
>>
>> Would it be safer to call reinit_completion() before initiating the hardware
>> action?
>
> This is theoretically valid but in practice, the conversion requires at minimum
> two 82ms cycles (167ms), so there is no realistic window for the interrupt to
> race with reinit_completion(). What do you guys think?
I would still move it before the write so that it looks correct
and others can copy/paste the logic on other devices.
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH v3 8/8] iio: temperature: ltc2983: Add support for ADT7604
2026-05-21 16:43 ` [PATCH v3 8/8] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
2026-05-21 19:18 ` sashiko-bot
@ 2026-05-22 13:34 ` Jonathan Cameron
2026-05-22 14:24 ` Stan, Liviu
1 sibling, 1 reply; 30+ messages in thread
From: Jonathan Cameron @ 2026-05-22 13:34 UTC (permalink / raw)
To: Liviu Stan
Cc: David Lechner, Nuno Sá, Andy Shevchenko, Michael Hennerich,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Antoniu Miclaus,
Francesco Lavra, linux-iio, linux-kernel, linux, devicetree
On Thu, 21 May 2026 19:43:01 +0300
Liviu Stan <liviu.stan@analog.com> wrote:
> The ADT7604 shares the same die as the LTC2984. It repurposes the
> custom RTD sensor type (18) as a copper trace resistance sensor
> and the custom thermistor type (27) as a leak detector, and
> removes thermocouple, diode and direct ADC sensor types.
>
> Two new software sensor type values are introduced
> (LTC2983_SENSOR_COPPER_TRACE = 32, LTC2983_SENSOR_LEAK_DETECTOR = 33)
> that map to the hardware register values 18 and 27 respectively.
> Dedicated structs (ltc2983_copper_trace, ltc2983_leak_detector) and
> parser functions are added rather than extending the existing RTD and
> thermistor paths, as the hardware configuration bits are fully
> hardcoded and several RTD/thermistor properties would need to be
> explicitly forbidden or ignored.
>
> Custom RTD (type 18) becomes the copper trace sensor. Sensor
> configuration bits are hardcoded to 0b1001 per the datasheet.
> Two variants are supported via the adi,copper-trace-sub-ohm DT
> property: sub-ohm traces (< 1 ohm) have bits 17:0 cleared with no
> excitation current or custom table; standard traces (> 1 ohm) have
> a required resistance-to-temperature table.
>
> Custom thermistor (type 27) becomes the leak detector. Sensor
> configuration bits are hardcoded to 0b001. The custom table uses
> a resolution of 16 instead of 64, and is specified via the
> required adi,custom-leak-detector DT property.
>
> Both sensor types expose an IIO_RESISTANCE channel reading from
> the resistance result register bank (0x0060-0x00AF). Added a
> "base" parameter to the LTC2983_RESULT_ADDR macro and a "base_reg"
> parameter to the ltc2983_chan_read function so we can read from
> both result register banks. The resistance register encodes the
> measured resistance with 10 fractional bits, so dividing by 1024
> gives ohms. Since the sense resistor is specified in ohms, the
> output is in ohms for both sensor types and a single 1/1024
> scale applies to both. For > 1 ohm copper traces and for leak
> detectors, a secondary channel also appears: IIO_TEMP
> (millidegrees Celsius) for copper trace and IIO_COVERAGE (percent)
> for leak detector.
>
> The ltc2983_chip_info struct is extended with a u64 supported_sensors
> bitmask using BIT_ULL() to safely represent the new sensor type bits
> 32 and 33 on 32-bit builds. A LTC2983_SENSOR_NUM sentinel is added
> to the enum so that the bounds check uses >= LTC2983_SENSOR_NUM
> rather than hardcoding the last sensor type.
>
> Tested on EVAL-ADT7604-AZ connected to Raspberry Pi 5 via SPI.
>
> Signed-off-by: Liviu Stan <liviu.stan@analog.com>
The sashiko comment about the completion race looks real to me.
Can you take a look at that. Might be some odd reason why we can't
reinit_completion() before triggering the capture but that would
be very unusual.
Otherwise just two really small things I missed in earlier reviews.
If everything else was ready to go I'd have tweaked these whilst
applying but seems you'll be doing a v4 so over to you!
Jonathan
> drivers/iio/temperature/ltc2983.c | 413 ++++++++++++++++++++++++++++--
> 1 file changed, 394 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
> index 326f843f4271..e2ffeee026ee 100644
> --- a/drivers/iio/temperature/ltc2983.c
> +++ b/drivers/iio/temperature/ltc2983.c
> @@ -186,17 +188,44 @@ enum {
> LTC2983_SENSOR_SENSE_RESISTOR = 29,
> LTC2983_SENSOR_DIRECT_ADC = 30,
> LTC2983_SENSOR_ACTIVE_TEMP = 31,
> + /* Sensor types for some parts only; map to RTD_CUSTOM/THERMISTOR_CUSTOM in HW */
> + LTC2983_SENSOR_COPPER_TRACE = 32,
> + LTC2983_SENSOR_LEAK_DETECTOR = 33,
> + LTC2983_SENSOR_NUM,
That's a terminating entry so no trailing comma. It always has to be last.
> };
> static const struct spi_device_id ltc2983_id_table[] = {
> @@ -1707,6 +2080,7 @@ static const struct spi_device_id ltc2983_id_table[] = {
> { "ltc2984", (kernel_ulong_t)<c2984_chip_info_data },
> { "ltc2986", (kernel_ulong_t)<c2986_chip_info_data },
> { "ltm2985", (kernel_ulong_t)<m2985_chip_info_data },
> + { "adt7604", (kernel_ulong_t)&adt7604_chip_info_data },
As below.
> { }
> };
> MODULE_DEVICE_TABLE(spi, ltc2983_id_table);
> @@ -1716,6 +2090,7 @@ static const struct of_device_id ltc2983_of_match[] = {
> { .compatible = "adi,ltc2984", .data = <c2984_chip_info_data },
> { .compatible = "adi,ltc2986", .data = <c2986_chip_info_data },
> { .compatible = "adi,ltm2985", .data = <m2985_chip_info_data },
> + { .compatible = "adi,adt7604", .data = &adt7604_chip_info_data },
Oops I missed this before. Alphabetical order.
Jonathan
> { }
^ permalink raw reply [flat|nested] 30+ messages in thread* RE: [PATCH v3 8/8] iio: temperature: ltc2983: Add support for ADT7604
2026-05-22 13:34 ` Jonathan Cameron
@ 2026-05-22 14:24 ` Stan, Liviu
2026-05-22 17:31 ` Jonathan Cameron
0 siblings, 1 reply; 30+ messages in thread
From: Stan, Liviu @ 2026-05-22 14:24 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner
Cc: David Lechner, Sa, Nuno, Andy Shevchenko, Hennerich, Michael,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Miclaus, Antoniu,
Francesco Lavra, linux-iio@vger.kernel.org,
linux-kernel@vger.kernel.org, linux, devicetree@vger.kernel.org
On Fri, 22 May 2026 14:34:44 +0100 Jonathan Cameron <jic23@kernel.org> wrote:
> On Thu, 21 May 2026 19:43:01 +0300
> Liviu Stan <liviu.stan@analog.com> wrote:
>
...
>
> The sashiko comment about the completion race looks real to me.
> Can you take a look at that. Might be some odd reason why we can't
> reinit_completion() before triggering the capture but that would
> be very unusual.
>
I don't see any reason why we couldn't put it before the regmap_write,
it has also already been done in ltc2983_eeprom_cmd(). So, I will change
it in v4.
> Otherwise just two really small things I missed in earlier reviews.
> If everything else was ready to go I'd have tweaked these whilst
> applying but seems you'll be doing a v4 so over to you!
Understood, will change them in v4!:) Thanks!
On Fri, 22 May 2026 09:09:33 -0500 David Lechner <dlechner@baylibre.com> wrote:
> On 5/22/26 8:23 AM, Liviu Stan wrote:
> > On Thu, 21 May 2026 19:18:28 +0000 sashiko-bot@kernel.org wrote:
> >
> >> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
...
> >> [Severity: High]
> >> This is a pre-existing issue, but can this function experience spurious
> >> read timeouts due to a race condition with the completion?
> >>
> >> Looking at the rest of this function:
> >>
> >> ret = regmap_write(st->regmap, LTC2983_STATUS_REG, start_conversion);
> >> if (ret)
> >> return ret;
> >>
> >> reinit_completion(&st->completion);
> >>
> >> If the hardware conversion finishes very quickly after regmap_write(),
> >> could the interrupt fire and call complete() before the CPU executes
> >> reinit_completion()? This would overwrite the completion event, causing the
> >> subsequent wait_for_completion_timeout() to spuriously time out.
> >>
> >> Would it be safer to call reinit_completion() before initiating the hardware
> >> action?
> >
> > This is theoretically valid but in practice, the conversion requires at minimum
> > two 82ms cycles (167ms), so there is no realistic window for the interrupt to
> > race with reinit_completion(). What do you guys think?
>
> I would still move it before the write so that it looks correct
> and others can copy/paste the logic on other devices.
That makes sense. Thanks!
Would this be considered a fix?
Liviu
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH v3 8/8] iio: temperature: ltc2983: Add support for ADT7604
2026-05-22 14:24 ` Stan, Liviu
@ 2026-05-22 17:31 ` Jonathan Cameron
0 siblings, 0 replies; 30+ messages in thread
From: Jonathan Cameron @ 2026-05-22 17:31 UTC (permalink / raw)
To: Stan, Liviu
Cc: David Lechner, Sa, Nuno, Andy Shevchenko, Hennerich, Michael,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Miclaus, Antoniu,
Francesco Lavra, linux-iio@vger.kernel.org,
linux-kernel@vger.kernel.org, linux, devicetree@vger.kernel.org
On Fri, 22 May 2026 14:24:27 +0000
"Stan, Liviu" <Liviu.Stan@analog.com> wrote:
> On Fri, 22 May 2026 14:34:44 +0100 Jonathan Cameron <jic23@kernel.org> wrote:
>
> > On Thu, 21 May 2026 19:43:01 +0300
> > Liviu Stan <liviu.stan@analog.com> wrote:
> >
> ...
> >
> > The sashiko comment about the completion race looks real to me.
> > Can you take a look at that. Might be some odd reason why we can't
> > reinit_completion() before triggering the capture but that would
> > be very unusual.
> >
>
> I don't see any reason why we couldn't put it before the regmap_write,
> it has also already been done in ltc2983_eeprom_cmd(). So, I will change
> it in v4.
>
> > Otherwise just two really small things I missed in earlier reviews.
> > If everything else was ready to go I'd have tweaked these whilst
> > applying but seems you'll be doing a v4 so over to you!
>
> Understood, will change them in v4!:) Thanks!
>
> On Fri, 22 May 2026 09:09:33 -0500 David Lechner <dlechner@baylibre.com> wrote:
>
> > On 5/22/26 8:23 AM, Liviu Stan wrote:
> > > On Thu, 21 May 2026 19:18:28 +0000 sashiko-bot@kernel.org wrote:
> > >
> > >> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> ...
> > >> [Severity: High]
> > >> This is a pre-existing issue, but can this function experience spurious
> > >> read timeouts due to a race condition with the completion?
> > >>
> > >> Looking at the rest of this function:
> > >>
> > >> ret = regmap_write(st->regmap, LTC2983_STATUS_REG, start_conversion);
> > >> if (ret)
> > >> return ret;
> > >>
> > >> reinit_completion(&st->completion);
> > >>
> > >> If the hardware conversion finishes very quickly after regmap_write(),
> > >> could the interrupt fire and call complete() before the CPU executes
> > >> reinit_completion()? This would overwrite the completion event, causing the
> > >> subsequent wait_for_completion_timeout() to spuriously time out.
> > >>
> > >> Would it be safer to call reinit_completion() before initiating the hardware
> > >> action?
> > >
> > > This is theoretically valid but in practice, the conversion requires at minimum
> > > two 82ms cycles (167ms), so there is no realistic window for the interrupt to
> > > race with reinit_completion(). What do you guys think?
> >
> > I would still move it before the write so that it looks correct
> > and others can copy/paste the logic on other devices.
>
> That makes sense. Thanks!
>
> Would this be considered a fix?
Yes, though not an urgent one given no particular reports of it being hit.
Just put it at the start of the series and I'll apply it with the rest.
Can get backported after next merge window.
Thanks,
Jonathan
>
> Liviu
^ permalink raw reply [flat|nested] 30+ messages in thread