public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] iio: temperature: ltc2983: Add support for ADT7604
@ 2026-04-27 13:25 Liviu Stan
  2026-04-27 13:25 ` [PATCH 1/2] dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983 Liviu Stan
  2026-04-27 13:25 ` [PATCH 2/2] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
  0 siblings, 2 replies; 6+ messages in thread
From: Liviu Stan @ 2026-04-27 13:25 UTC (permalink / raw)
  To: Nuno Sá, Lars-Peter Clausen, Michael Hennerich,
	Jonathan Cameron, David Lechner, Andy Shevchenko, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
	linux-kernel
  Cc: Liviu Stan

This series adds support for the ADT7604 multi-sensor temperature
measurement and leak detection system to the existing ltc2983 driver.

The ADT7604 shares the same die as the LTC2984, reusing its register
map and SPI interface. It repurposes the custom RTD sensor type (18)
as a copper trace resistance sensor and the custom thermistor type (27)
as a leak detector, removing thermocouple, diode and direct ADC support.

Patch 1 updates the device tree bindings: adds adi,adt7604 compatible,
copper-trace@ and leak-detector@ sensor node types with their respective
properties, and an ADT7604 example.

Patch 2 updates the driver: adds adt7604_chip_info with a has_copper_trace
capability flag, the resistance result register bank (0x0060-0x00AF),
hardcoded sensor configuration for both new sensor types, sub-ohm copper
trace support, unsupported sensor type rejection at probe, and IIO_RESISTANCE
channels with appropriate scales (1/1,024,000 for copper trace, 1/1024 for
leak detector).

Tested on EVAL-ADT7604-AZ connected to Raspberry Pi 5 via SPI.

Liviu Stan (2):
  dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983
  iio: temperature: ltc2983: Add support for ADT7604

 .../bindings/iio/temperature/adi,ltc2983.yaml | 170 ++++++++-
 drivers/iio/temperature/ltc2983.c             | 347 +++++++++++++-----
 2 files changed, 418 insertions(+), 99 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/2] dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983
  2026-04-27 13:25 [PATCH 0/2] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
@ 2026-04-27 13:25 ` Liviu Stan
  2026-04-27 19:34   ` Conor Dooley
  2026-04-27 13:25 ` [PATCH 2/2] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
  1 sibling, 1 reply; 6+ messages in thread
From: Liviu Stan @ 2026-04-27 13:25 UTC (permalink / raw)
  To: Lars-Peter Clausen, Michael Hennerich, Nuno Sá,
	Jonathan Cameron, David Lechner, Andy Shevchenko, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
	linux-kernel
  Cc: Liviu Stan

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 standard (> 1 ohm, optional adi,custom-rtd
  table). Primary output is resistance in mOhm.

- leak-detector@: maps to the custom thermistor sensor type (27).
  Takes an optional adi,custom-leak-detector lookup table encoding
  resistance (uOhm) against coverage data (P + 273.15 in uK).
  Primary output is resistance in Ohm; when a table is provided,
  IIO_TEMP reports coverage percentage (raw / 1024).

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.

Signed-off-by: Liviu Stan <liviu.stan@analog.com>
---
 .../bindings/iio/temperature/adi,ltc2983.yaml | 170 +++++++++++++++++-
 1 file changed, 167 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..e777b37d588d 100644
--- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
+++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
@@ -4,14 +4,14 @@
 $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, LTC2986, LTM2985, ADT7604 Multi-sensor Temperature system
 
 maintainers:
   - Nuno Sá <nuno.sa@analog.com>
 
 description: |
-  Analog Devices LTC2983, LTC2984, LTC2986, LTM2985 Multi-Sensor Digital
-  Temperature Measurement Systems
+  Analog Devices LTC2983, LTC2984, LTC2986, LTM2985, ADT7604 Multi-Sensor
+  Digital Temperature Measurement Systems
 
   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 +43,7 @@ properties:
   compatible:
     oneOf:
       - enum:
+          - adi,adt7604
           - adi,ltc2983
           - adi,ltc2986
           - adi,ltm2985
@@ -436,6 +437,96 @@ patternProperties:
     required:
       - adi,custom-temp
 
+  '^copper-trace@':
+    $ref: '#/$defs/sensor-node'
+    unevaluatedProperties: false
+    description: |
+      Copper trace resistance sensor (ADT7604 only). Uses the custom RTD
+      sensor type (18). Two variants exist: sub-ohm (< 1 ohm, no custom
+      table allowed) and standard (> 1 ohm, optional 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: 18
+
+      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,custom-rtd:
+        description:
+          Optional resistance-to-temperature table for copper trace sensors
+          with resistance > 1 ohm. See Page 62 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-rtd: false
+
+  '^leak-detector@':
+    $ref: '#/$defs/sensor-node'
+    unevaluatedProperties: false
+    description: |
+      Leak detector sensor (ADT7604 only). Uses the custom thermistor sensor
+      type (27). Outputs resistance in ohms and, when a custom table is
+      provided, a coverage percentage via IIO_TEMP (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: 27
+
+      adi,rsense-handle:
+        description: Associated sense resistor sensor.
+        $ref: /schemas/types.yaml#/definitions/phandle
+
+      adi,custom-leak-detector:
+        description: |
+          Lookup table mapping resistance to coverage data. Entries must be
+          in ascending resistance order. The coverage data field encodes the
+          coverage percentage P as (P + 273.15) expressed in uK, i.e.
+          (P * 1000000 + 273150000).
+        $ref: /schemas/types.yaml#/definitions/uint64-matrix
+        minItems: 3
+        maxItems: 64
+        items:
+          items:
+            - description: Resistance point in uOhms.
+            - description: Coverage data point (P + 273150000) in uK.
+
+    required:
+      - adi,rsense-handle
+
   '^rsense@':
     $ref: '#/$defs/sensor-node'
     unevaluatedProperties: false
@@ -477,6 +568,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 +663,61 @@ 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 = <18>;
+                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 = <27>;
+                adi,rsense-handle = <&r_sense>;
+                adi,custom-leak-detector =
+                    /bits/ 64 <          0 373150000>,
+                    /bits/ 64 <  202020000 372150000>,
+                    /bits/ 64 < 1000000000 293150000>;
+            };
+
+            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] 6+ messages in thread

* [PATCH 2/2] iio: temperature: ltc2983: Add support for ADT7604
  2026-04-27 13:25 [PATCH 0/2] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
  2026-04-27 13:25 ` [PATCH 1/2] dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983 Liviu Stan
@ 2026-04-27 13:25 ` Liviu Stan
  2026-04-27 18:23   ` Andy Shevchenko
  2026-04-28 11:14   ` Nuno Sá
  1 sibling, 2 replies; 6+ messages in thread
From: Liviu Stan @ 2026-04-27 13:25 UTC (permalink / raw)
  To: Lars-Peter Clausen, Michael Hennerich, Nuno Sá,
	Jonathan Cameron, David Lechner, Andy Shevchenko, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
	linux-kernel
  Cc: Liviu Stan

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.

Custom RTD (type 18) becomes the copper trace sensor. Sensor
configuration bits 21:18 are hardcoded to 0b1001 per the
datasheet. Two variants are supported via the new
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) accept an optional
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 (20+4 bit resistance field) instead of
64, and is specified via the new adi,custom-leak-detector DT
property.

Both sensor types expose an IIO_RESISTANCE channel reading from
the resistance result register bank (0x060-0x00AF), added to
the regmap readable ranges. Scales are 1/1,024,000 for copper
trace (result in mOhm) and 1/1024 for leak detector (result
in Ohm).

A has_copper_trace capability flag is introduced in
ltc2983_chip_info to identify the ADT7604, following the
existing has_temp and has_eeprom pattern.

Tested on EVAL-ADT7604-AZ connected to Raspberry Pi 5 via SPI.

Signed-off-by: Liviu Stan <liviu.stan@analog.com>
---
 drivers/iio/temperature/ltc2983.c | 347 +++++++++++++++++++++---------
 1 file changed, 251 insertions(+), 96 deletions(-)

diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
index 38e6f8dfd3b8..1966f6fb0305 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_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_RES_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)
@@ -214,6 +216,7 @@ struct ltc2983_chip_info {
 	unsigned int max_channels_nr;
 	bool has_temp;
 	bool has_eeprom;
+	bool has_copper_trace;
 };
 
 struct ltc2983_data {
@@ -272,6 +275,7 @@ struct ltc2983_rtd {
 	u32 r_sense_chan;
 	u32 excitation_current;
 	u32 rtd_curve;
+	bool sub_ohm;
 };
 
 struct ltc2983_thermistor {
@@ -575,6 +579,10 @@ static int ltc2983_rtd_assign_chan(struct ltc2983_data *st,
 		if (ret)
 			return ret;
 	}
+
+	if (rtd->sub_ohm)
+		chan_val &= ~GENMASK(17, 0);
+
 	return __ltc2983_chan_assign_common(st, sensor, chan_val);
 }
 
@@ -758,83 +766,113 @@ 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) {
-		switch (n_wires) {
-		case 2:
-			rtd->sensor_config = LTC2983_RTD_N_WIRES(0);
-			break;
-		case 3:
-			rtd->sensor_config = LTC2983_RTD_N_WIRES(1);
-			break;
-		case 4:
-			rtd->sensor_config = LTC2983_RTD_N_WIRES(2);
-			break;
-		case 5:
-			/* 4 wires, Kelvin Rsense */
-			rtd->sensor_config = LTC2983_RTD_N_WIRES(3);
-			break;
-		default:
+	/* ADT7604 requires hardcoding sensor configuration bits to 0b1001 */
+	if (st->info->has_copper_trace &&
+	    sensor->type == LTC2983_SENSOR_RTD_CUSTOM) {
+		rtd->sensor_config = 0x9;
+		if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
 			return dev_err_ptr_probe(dev, -EINVAL,
-						 "Invalid number of wires:%u\n",
-						 n_wires);
+						 "Invalid chann:%d for copper trace\n",
+						 sensor->chan);
+	} else {
+		ret = fwnode_property_read_u32(child, "adi,number-of-wires", &n_wires);
+		if (!ret) {
+			switch (n_wires) {
+			case 2:
+				rtd->sensor_config = LTC2983_RTD_N_WIRES(0);
+				break;
+			case 3:
+				rtd->sensor_config = LTC2983_RTD_N_WIRES(1);
+				break;
+			case 4:
+				rtd->sensor_config = LTC2983_RTD_N_WIRES(2);
+				break;
+			case 5:
+				/* 4 wires, Kelvin Rsense */
+				rtd->sensor_config = LTC2983_RTD_N_WIRES(3);
+				break;
+			default:
+				return dev_err_ptr_probe(dev, -EINVAL,
+							 "Invalid number of wires:%u\n",
+							 n_wires);
+			}
 		}
-	}
 
-	if (fwnode_property_read_bool(child, "adi,rsense-share")) {
-		/* Current rotation is only available with rsense sharing */
-		if (fwnode_property_read_bool(child, "adi,current-rotate")) {
-			if (n_wires == 2 || n_wires == 3)
+		if (fwnode_property_read_bool(child, "adi,rsense-share")) {
+			/* Current rotation is only available with rsense sharing */
+			if (fwnode_property_read_bool(child, "adi,current-rotate")) {
+				if (n_wires == 2 || n_wires == 3)
+					return dev_err_ptr_probe(dev, -EINVAL,
+								 "Rotation not allowed for 2/3 Wire RTDs\n");
+
+				rtd->sensor_config |= LTC2983_RTD_C_ROTATE(1);
+			} else {
+				rtd->sensor_config |= LTC2983_RTD_R_SHARE(1);
+			}
+		}
+		/*
+		 * 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.
+		 * For 4wire RTDs with kelvin rsense, the rsense channel cannot be
+		 * <=1 since chanel - 1 and channel - 2 are used.
+		 */
+		if (rtd->sensor_config & LTC2983_RTD_4_WIRE_MASK) {
+			/* 4-wire */
+			u8 min = LTC2983_DIFFERENTIAL_CHAN_MIN,
+				max = st->info->max_channels_nr;
+
+			if (rtd->sensor_config & LTC2983_RTD_ROTATION_MASK)
+				max = st->info->max_channels_nr - 1;
+
+			if ((rtd->sensor_config & LTC2983_RTD_KELVIN_R_SENSE_MASK)
+			     == LTC2983_RTD_KELVIN_R_SENSE_MASK &&
+			    rtd->r_sense_chan <= min)
+				/* kelvin rsense*/
 				return dev_err_ptr_probe(dev, -EINVAL,
-							 "Rotation not allowed for 2/3 Wire RTDs\n");
+							 "Invalid rsense chann:%d to use in kelvin rsense\n",
+							 rtd->r_sense_chan);
 
-			rtd->sensor_config |= LTC2983_RTD_C_ROTATE(1);
+			if (sensor->chan < min || sensor->chan > max)
+				return dev_err_ptr_probe(dev, -EINVAL,
+							 "Invalid chann:%d for the rtd config\n",
+							 sensor->chan);
 		} else {
-			rtd->sensor_config |= LTC2983_RTD_R_SHARE(1);
+			/* same as differential case */
+			if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
+				return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
+							 "Invalid chann:%d for RTD\n",
+							 sensor->chan);
 		}
 	}
-	/*
-	 * 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.
-	 * For 4wire RTDs with kelvin rsense, the rsense channel cannot be
-	 * <=1 since channel - 1 and channel - 2 are used.
-	 */
-	if (rtd->sensor_config & LTC2983_RTD_4_WIRE_MASK) {
-		/* 4-wire */
-		u8 min = LTC2983_DIFFERENTIAL_CHAN_MIN,
-			max = st->info->max_channels_nr;
-
-		if (rtd->sensor_config & LTC2983_RTD_ROTATION_MASK)
-			max = st->info->max_channels_nr - 1;
-
-		if (((rtd->sensor_config & LTC2983_RTD_KELVIN_R_SENSE_MASK)
-		     == LTC2983_RTD_KELVIN_R_SENSE_MASK) &&
-		    (rtd->r_sense_chan <=  min))
-			/* kelvin rsense*/
-			return dev_err_ptr_probe(dev, -EINVAL,
-						 "Invalid rsense chann:%d to use in 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",
-						 sensor->chan);
-	} else {
-		/* same as differential case */
-		if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
-			return dev_err_ptr_probe(&st->spi->dev, -EINVAL,
-						 "Invalid chann:%d for RTD\n",
-						 sensor->chan);
-	}
 
 	/* check custom sensor */
 	if (sensor->type == LTC2983_SENSOR_RTD_CUSTOM) {
-		rtd->custom = __ltc2983_custom_sensor_new(st, child,
-							  "adi,custom-rtd",
-							  false, 2048, false);
-		if (IS_ERR(rtd->custom))
-			return ERR_CAST(rtd->custom);
+		if (st->info->has_copper_trace) {
+			if (fwnode_property_present(child, "adi,custom-rtd")) {
+				rtd->custom = __ltc2983_custom_sensor_new(st, child,
+									  "adi,custom-rtd",
+									  false, 2048,
+									  false);
+				if (IS_ERR(rtd->custom))
+					return ERR_CAST(rtd->custom);
+			}
+		} else {
+			rtd->custom = __ltc2983_custom_sensor_new(st, child,
+								  "adi,custom-rtd",
+								  false, 2048, false);
+			if (IS_ERR(rtd->custom))
+				return ERR_CAST(rtd->custom);
+		}
+	}
+
+	if (st->info->has_copper_trace &&
+	    sensor->type == LTC2983_SENSOR_RTD_CUSTOM) {
+		rtd->sub_ohm = fwnode_property_read_bool(child,
+							 "adi,copper-trace-sub-ohm");
+		if (rtd->sub_ohm && rtd->custom)
+			return dev_err_ptr_probe(dev, -EINVAL,
+						 "sub-ohm copper trace cannot have a custom table\n");
 	}
 
 	/* set common parameters */
@@ -908,17 +946,27 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
 		return dev_err_ptr_probe(dev, ret,
 					 "rsense channel must be configured...\n");
 
-	if (fwnode_property_read_bool(child, "adi,single-ended")) {
-		thermistor->sensor_config = LTC2983_THERMISTOR_SGL(1);
-	} else if (fwnode_property_read_bool(child, "adi,rsense-share")) {
-		/* rotation is only possible if sharing rsense */
-		if (fwnode_property_read_bool(child, "adi,current-rotate"))
-			thermistor->sensor_config =
-						LTC2983_THERMISTOR_C_ROTATE(1);
-		else
-			thermistor->sensor_config =
-						LTC2983_THERMISTOR_R_SHARE(1);
+	if (st->info->has_copper_trace &&
+	    sensor->type == LTC2983_SENSOR_THERMISTOR_CUSTOM) {
+		thermistor->sensor_config = LTC2983_THERMISTOR_C_ROTATE(1);
+		if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
+			return dev_err_ptr_probe(dev, -EINVAL,
+						 "Invalid chann:%d for leak detector\n",
+						 sensor->chan);
+	} else {
+		if (fwnode_property_read_bool(child, "adi,single-ended")) {
+			thermistor->sensor_config = LTC2983_THERMISTOR_SGL(1);
+		} else if (fwnode_property_read_bool(child, "adi,rsense-share")) {
+			/* rotation is only possible if sharing rsense */
+			if (fwnode_property_read_bool(child, "adi,current-rotate"))
+				thermistor->sensor_config =
+							LTC2983_THERMISTOR_C_ROTATE(1);
+			else
+				thermistor->sensor_config =
+							LTC2983_THERMISTOR_R_SHARE(1);
+		}
 	}
+
 	/* validate channel index */
 	if (!(thermistor->sensor_config & LTC2983_THERMISTOR_DIFF_MASK) &&
 	    sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
@@ -928,23 +976,36 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
 
 	/* check custom sensor */
 	if (sensor->type >= LTC2983_SENSOR_THERMISTOR_STEINHART) {
-		bool steinhart = false;
-		const char *propname;
-
-		if (sensor->type == LTC2983_SENSOR_THERMISTOR_STEINHART) {
-			steinhart = true;
-			propname = "adi,custom-steinhart";
+		if (st->info->has_copper_trace &&
+		    sensor->type == LTC2983_SENSOR_THERMISTOR_CUSTOM) {
+			if (fwnode_property_present(child, "adi,custom-leak-detector")) {
+				thermistor->custom =
+					__ltc2983_custom_sensor_new(st, child,
+								    "adi,custom-leak-detector",
+								    false, 16, false);
+				if (IS_ERR(thermistor->custom))
+					return ERR_CAST(thermistor->custom);
+			}
 		} else {
-			propname = "adi,custom-thermistor";
+			bool steinhart = false;
+			const char *propname;
+
+			if (sensor->type == LTC2983_SENSOR_THERMISTOR_STEINHART) {
+				steinhart = true;
+				propname = "adi,custom-steinhart";
+			} else {
+				propname = "adi,custom-thermistor";
+			}
+
+			thermistor->custom = __ltc2983_custom_sensor_new(st, child,
+									 propname,
+									 steinhart,
+									 64, false);
+			if (IS_ERR(thermistor->custom))
+				return ERR_CAST(thermistor->custom);
 		}
-
-		thermistor->custom = __ltc2983_custom_sensor_new(st, child,
-								 propname,
-								 steinhart,
-								 64, false);
-		if (IS_ERR(thermistor->custom))
-			return ERR_CAST(thermistor->custom);
 	}
+
 	/* set common parameters */
 	thermistor->sensor.fault_handler = ltc2983_common_fault_handler;
 	thermistor->sensor.assign_chan = ltc2983_thermistor_assign_chan;
@@ -1167,7 +1228,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)
 {
 	u32 start_conversion = 0;
 	int ret;
@@ -1197,13 +1259,23 @@ 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_CHAN_RES_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(&st->spi->dev, "Invalid conversion detected\n");
 		return -EIO;
@@ -1214,6 +1286,7 @@ static int ltc2983_chan_read(struct ltc2983_data *st,
 		return ret;
 
 	*val = sign_extend32((*val) & LTC2983_DATA_MASK, LTC2983_DATA_SIGN_BIT);
+
 	return 0;
 }
 
@@ -1234,7 +1307,12 @@ 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);
+		if (chan->type == IIO_RESISTANCE)
+			ret = ltc2983_chan_read(st, st->sensors[chan->address],
+						ADT7604_RES_RES_START_REG, val);
+		else
+			ret = ltc2983_chan_read(st, st->sensors[chan->address],
+						LTC2983_TEMP_RES_START_REG, val);
 		mutex_unlock(&st->lock);
 		return ret ?: IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
@@ -1251,6 +1329,18 @@ static int ltc2983_read_raw(struct iio_dev *indio_dev,
 			/* 2^21 */
 			*val2 = 2097152;
 			return IIO_VAL_FRACTIONAL;
+		case IIO_RESISTANCE:
+			/* value in ohm */
+			*val = 1;
+			/*
+			 * Copper trace result is in milliohm with 10 fractional
+			 * bits: divide by 2^10 * 1000 = 1024000.
+			 * Leak detector result is in ohm with 10 fractional
+			 * bits: divide by 2^10 = 1024.
+			 */
+			*val2 = (st->sensors[chan->address]->type == LTC2983_SENSOR_RTD_CUSTOM) ?
+				1024000 : 1024;
+			return IIO_VAL_FRACTIONAL;
 		default:
 			return -EINVAL;
 		}
@@ -1292,6 +1382,17 @@ static irqreturn_t ltc2983_irq_handler(int irq, void *data)
 	__chan; \
 })
 
+#define LTC2983_RESISTANCE_CHAN(index, __address) ({ \
+	struct iio_chan_spec __chan = { \
+		.type = IIO_RESISTANCE, \
+		.indexed = 1, \
+		.channel = index, \
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \
+		.address = __address, \
+	}; \
+	__chan; \
+})
+
 static int ltc2983_parse_fw(struct ltc2983_data *st)
 {
 	struct device *dev = &st->spi->dev;
@@ -1339,6 +1440,16 @@ 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 (st->info->has_copper_trace) {
+			if ((sensor.type >= LTC2983_SENSOR_THERMOCOUPLE &&
+			     sensor.type <= LTC2983_SENSOR_THERMOCOUPLE_CUSTOM) ||
+			     sensor.type == LTC2983_SENSOR_DIODE ||
+			     sensor.type == LTC2983_SENSOR_DIRECT_ADC)
+				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, chann %u",
 			sensor.type, sensor.chan);
 
@@ -1380,6 +1491,15 @@ static int ltc2983_parse_fw(struct ltc2983_data *st)
 		st->sensors[chan]->chan = sensor.chan;
 		st->sensors[chan]->type = sensor.type;
 
+		if (st->info->has_copper_trace) {
+			if (st->sensors[chan]->type == LTC2983_SENSOR_THERMISTOR_CUSTOM &&
+			    to_thermistor(st->sensors[chan])->custom)
+				st->iio_channels++;
+			else if (st->sensors[chan]->type == LTC2983_SENSOR_RTD_CUSTOM &&
+				 to_rtd(st->sensors[chan])->custom)
+				st->iio_channels++;
+		}
+
 		channel_avail_mask |= BIT(sensor.chan);
 		chan++;
 	}
@@ -1426,7 +1546,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;
+	u32 iio_chan_t = 0, iio_chan_v = 0, iio_chan_r = 0, chan, iio_idx = 0, status;
 	int ret;
 
 	/* make sure the device is up: start bit (7) is 0 and done bit (6) is 1 */
@@ -1473,6 +1593,26 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
 		    !assign_iio)
 			continue;
 
+		/*
+		 * Copper trace and leak detector sensors without a custom table
+		 * produce only a resistance result; the chip does not populate
+		 * the temperature result register. Emit only an IIO_RESISTANCE
+		 * channel in this case.
+		 */
+		if (st->info->has_copper_trace) {
+			bool resistance_only =
+				(st->sensors[chan]->type == LTC2983_SENSOR_RTD_CUSTOM &&
+				 !to_rtd(st->sensors[chan])->custom) ||
+				(st->sensors[chan]->type == LTC2983_SENSOR_THERMISTOR_CUSTOM &&
+				 !to_thermistor(st->sensors[chan])->custom);
+
+			if (resistance_only) {
+				st->iio_chan[iio_idx++] =
+					LTC2983_RESISTANCE_CHAN(iio_chan_r++, chan);
+				continue;
+			}
+		}
+
 		/* assign iio channel */
 		if (st->sensors[chan]->type != LTC2983_SENSOR_DIRECT_ADC) {
 			chan_type = IIO_TEMP;
@@ -1488,6 +1628,11 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
 		 */
 		st->iio_chan[iio_idx++] = LTC2983_CHAN(chan_type, (*iio_chan)++,
 						       chan);
+
+		if (st->info->has_copper_trace &&
+		    (st->sensors[chan]->type == LTC2983_SENSOR_RTD_CUSTOM ||
+		     st->sensors[chan]->type == LTC2983_SENSOR_THERMISTOR_CUSTOM))
+			st->iio_chan[iio_idx++] = LTC2983_RESISTANCE_CHAN(iio_chan_r++, chan);
 	}
 
 	return 0;
@@ -1496,6 +1641,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),
@@ -1659,11 +1805,19 @@ static const struct ltc2983_chip_info ltm2985_chip_info_data = {
 	.has_eeprom = true,
 };
 
+static const struct ltc2983_chip_info adt7604_chip_info_data = {
+	.name = "adt7604",
+	.max_channels_nr = 20,
+	.has_eeprom = true,
+	.has_copper_trace = true,
+};
+
 static const struct spi_device_id ltc2983_id_table[] = {
 	{ "ltc2983", (kernel_ulong_t)&ltc2983_chip_info_data },
 	{ "ltc2984", (kernel_ulong_t)&ltc2984_chip_info_data },
 	{ "ltc2986", (kernel_ulong_t)&ltc2986_chip_info_data },
 	{ "ltm2985", (kernel_ulong_t)&ltm2985_chip_info_data },
+	{ "adt7604", (kernel_ulong_t)&adt7604_chip_info_data },
 	{ }
 };
 MODULE_DEVICE_TABLE(spi, ltc2983_id_table);
@@ -1673,6 +1827,7 @@ static const struct of_device_id ltc2983_of_match[] = {
 	{ .compatible = "adi,ltc2984", .data = &ltc2984_chip_info_data },
 	{ .compatible = "adi,ltc2986", .data = &ltc2986_chip_info_data },
 	{ .compatible = "adi,ltm2985", .data = &ltm2985_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] 6+ messages in thread

* Re: [PATCH 2/2] iio: temperature: ltc2983: Add support for ADT7604
  2026-04-27 13:25 ` [PATCH 2/2] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
@ 2026-04-27 18:23   ` Andy Shevchenko
  2026-04-28 11:14   ` Nuno Sá
  1 sibling, 0 replies; 6+ messages in thread
From: Andy Shevchenko @ 2026-04-27 18:23 UTC (permalink / raw)
  To: Liviu Stan
  Cc: Lars-Peter Clausen, Michael Hennerich, Nuno Sá,
	Jonathan Cameron, David Lechner, Andy Shevchenko, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
	linux-kernel

On Mon, Apr 27, 2026 at 04:25:08PM +0300, Liviu Stan 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.
> 
> Custom RTD (type 18) becomes the copper trace sensor. Sensor
> configuration bits 21:18 are hardcoded to 0b1001 per the
> datasheet. Two variants are supported via the new
> 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) accept an optional
> 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 (20+4 bit resistance field) instead of
> 64, and is specified via the new adi,custom-leak-detector DT
> property.
> 
> Both sensor types expose an IIO_RESISTANCE channel reading from
> the resistance result register bank (0x060-0x00AF), added to
> the regmap readable ranges. Scales are 1/1,024,000 for copper
> trace (result in mOhm) and 1/1024 for leak detector (result
> in Ohm).
> 
> A has_copper_trace capability flag is introduced in
> ltc2983_chip_info to identify the ADT7604, following the
> existing has_temp and has_eeprom pattern.
> 
> Tested on EVAL-ADT7604-AZ connected to Raspberry Pi 5 via SPI.

...

>  #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_RES_ADDR(chan, base) \
> +			((((chan) - 1) * 4) + (base))

For the sake of consistency I would see (base) also to be in the _START_ADDR()
macro.

...

> +	bool sub_ohm;

What does this mean? Perhaps rename to is_in_milliohms or something like that?

...

> +		ret = fwnode_property_read_u32(child, "adi,number-of-wires", &n_wires);
> +		if (!ret) {

Yeah, this is in the original code. Consider at some point to make it rather
returning meaningful error codes, id est

		if (fwnode_property_present(child, "adi,number-of-wires")) {
			ret = fwnode_property_read_u32(child, "adi,number-of-wires", &n_wires);
			if (ret)
				return ret; // or with message that we can't get property value

> +			switch (n_wires) {
> +			case 2:
> +				rtd->sensor_config = LTC2983_RTD_N_WIRES(0);
> +				break;
> +			case 3:
> +				rtd->sensor_config = LTC2983_RTD_N_WIRES(1);
> +				break;
> +			case 4:
> +				rtd->sensor_config = LTC2983_RTD_N_WIRES(2);
> +				break;
> +			case 5:
> +				/* 4 wires, Kelvin Rsense */
> +				rtd->sensor_config = LTC2983_RTD_N_WIRES(3);
> +				break;
> +			default:
> +				return dev_err_ptr_probe(dev, -EINVAL,
> +							 "Invalid number of wires:%u\n",
> +							 n_wires);
> +			}
>  		}

...

> +			if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
> +				return dev_err_ptr_probe(&st->spi->dev, -EINVAL,

Don't you have 'dev' variable to use? If not, maybe makes sense to introduce.

> +							 "Invalid chann:%d for RTD\n",

chann? Perhaps just "chan"?

> +							 sensor->chan);
>  		}

...

> +		if (st->info->has_copper_trace) {
> +			if (fwnode_property_present(child, "adi,custom-rtd")) {
> +				rtd->custom = __ltc2983_custom_sensor_new(st, child,
> +									  "adi,custom-rtd",
> +									  false, 2048,
> +									  false);
> +				if (IS_ERR(rtd->custom))
> +					return ERR_CAST(rtd->custom);
> +			}
> +		} else {
> +			rtd->custom = __ltc2983_custom_sensor_new(st, child,
> +								  "adi,custom-rtd",
> +								  false, 2048, false);
> +			if (IS_ERR(rtd->custom))
> +				return ERR_CAST(rtd->custom);
> +		}

Seeing so many indentation noise, I think this patch starves for some
preparatory ones that make helper(s) out of the existing rather long functions
and then in a new code it will much easier to follow what gets changed and how.

...

Due to above I stopped here, because patch seems unreviewable to me. If others
are motivated more than me ans see this change nice in terms of readability,
I won't object. Personally I think it must be refactored (a lot!) before actually
adding a support of a new HW.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983
  2026-04-27 13:25 ` [PATCH 1/2] dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983 Liviu Stan
@ 2026-04-27 19:34   ` Conor Dooley
  0 siblings, 0 replies; 6+ messages in thread
From: Conor Dooley @ 2026-04-27 19:34 UTC (permalink / raw)
  To: Liviu Stan
  Cc: Lars-Peter Clausen, Michael Hennerich, Nuno Sá,
	Jonathan Cameron, David Lechner, Andy Shevchenko, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 9180 bytes --]

On Mon, Apr 27, 2026 at 04:25:07PM +0300, Liviu Stan 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.

I have to wonder if this is the right approach, if it's the same device
just with a different label and advertised purpose.

> 
> 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 standard (> 1 ohm, optional adi,custom-rtd
>   table). Primary output is resistance in mOhm.
> 
> - leak-detector@: maps to the custom thermistor sensor type (27).
>   Takes an optional adi,custom-leak-detector lookup table encoding
>   resistance (uOhm) against coverage data (P + 273.15 in uK).
>   Primary output is resistance in Ohm; when a table is provided,
>   IIO_TEMP reports coverage percentage (raw / 1024).
> 
> 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.
> 
> Signed-off-by: Liviu Stan <liviu.stan@analog.com>
> ---
>  .../bindings/iio/temperature/adi,ltc2983.yaml | 170 +++++++++++++++++-
>  1 file changed, 167 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..e777b37d588d 100644
> --- a/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
> +++ b/Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
> @@ -4,14 +4,14 @@
>  $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, LTC2986, LTM2985, ADT7604 Multi-sensor Temperature system
>  
>  maintainers:
>    - Nuno Sá <nuno.sa@analog.com>
>  
>  description: |
> -  Analog Devices LTC2983, LTC2984, LTC2986, LTM2985 Multi-Sensor Digital
> -  Temperature Measurement Systems
> +  Analog Devices LTC2983, LTC2984, LTC2986, LTM2985, ADT7604 Multi-Sensor
> +  Digital Temperature Measurement Systems
>  
>    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 +43,7 @@ properties:
>    compatible:
>      oneOf:
>        - enum:
> +          - adi,adt7604
>            - adi,ltc2983
>            - adi,ltc2986
>            - adi,ltm2985
> @@ -436,6 +437,96 @@ patternProperties:
>      required:
>        - adi,custom-temp
>  
> +  '^copper-trace@':

Pedantry perhaps, but isn't this an "ohmmeter"?

> +    $ref: '#/$defs/sensor-node'
> +    unevaluatedProperties: false
> +    description: |
> +      Copper trace resistance sensor (ADT7604 only). Uses the custom RTD
> +      sensor type (18). Two variants exist: sub-ohm (< 1 ohm, no custom
> +      table allowed) and standard (> 1 ohm, optional 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: 18
> +
> +      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,custom-rtd:
> +        description:
> +          Optional resistance-to-temperature table for copper trace sensors
> +          with resistance > 1 ohm. See Page 62 of the datasheet.

I want to look into this property, where is 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-rtd: false
> +
> +  '^leak-detector@':
> +    $ref: '#/$defs/sensor-node'
> +    unevaluatedProperties: false
> +    description: |
> +      Leak detector sensor (ADT7604 only). Uses the custom thermistor sensor
> +      type (27). Outputs resistance in ohms and, when a custom table is
> +      provided, a coverage percentage via IIO_TEMP (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: 27
> +
> +      adi,rsense-handle:
> +        description: Associated sense resistor sensor.
> +        $ref: /schemas/types.yaml#/definitions/phandle
> +
> +      adi,custom-leak-detector:
> +        description: |
> +          Lookup table mapping resistance to coverage data. Entries must be
> +          in ascending resistance order. The coverage data field encodes the
> +          coverage percentage P as (P + 273.15) expressed in uK, i.e.
> +          (P * 1000000 + 273150000).
> +        $ref: /schemas/types.yaml#/definitions/uint64-matrix
> +        minItems: 3
> +        maxItems: 64
> +        items:
> +          items:
> +            - description: Resistance point in uOhms.
> +            - description: Coverage data point (P + 273150000) in uK.
> +
> +    required:
> +      - adi,rsense-handle
> +
>    '^rsense@':
>      $ref: '#/$defs/sensor-node'
>      unevaluatedProperties: false
> @@ -477,6 +568,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 +663,61 @@ 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 = <18>;
> +                adi,rsense-handle = <&trace_rsense>;

Are these ever linked in a different way?

> +                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 = <27>;
> +                adi,rsense-handle = <&r_sense>;

Ditto here and in the rtd node. Are these fixed linkages or actually
dynamic?

Cheers,
Conor.

> +                adi,custom-leak-detector =
> +                    /bits/ 64 <          0 373150000>,
> +                    /bits/ 64 <  202020000 372150000>,
> +                    /bits/ 64 < 1000000000 293150000>;
> +            };
> +
> +            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
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/2] iio: temperature: ltc2983: Add support for ADT7604
  2026-04-27 13:25 ` [PATCH 2/2] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
  2026-04-27 18:23   ` Andy Shevchenko
@ 2026-04-28 11:14   ` Nuno Sá
  1 sibling, 0 replies; 6+ messages in thread
From: Nuno Sá @ 2026-04-28 11:14 UTC (permalink / raw)
  To: Liviu Stan
  Cc: Lars-Peter Clausen, Michael Hennerich, Nuno Sá,
	Jonathan Cameron, David Lechner, Andy Shevchenko, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
	linux-kernel

On Mon, Apr 27, 2026 at 04:25:08PM +0300, Liviu Stan 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.
> 
> Custom RTD (type 18) becomes the copper trace sensor. Sensor
> configuration bits 21:18 are hardcoded to 0b1001 per the
> datasheet. Two variants are supported via the new
> 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) accept an optional
> 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 (20+4 bit resistance field) instead of
> 64, and is specified via the new adi,custom-leak-detector DT
> property.
> 
> Both sensor types expose an IIO_RESISTANCE channel reading from
> the resistance result register bank (0x060-0x00AF), added to
> the regmap readable ranges. Scales are 1/1,024,000 for copper
> trace (result in mOhm) and 1/1024 for leak detector (result
> in Ohm).

But for userspace we report both in Ohm? That's the ABI AFAICT. In DT,
you also mention IIO_TEMP is used:

"IIO_TEMP reports coverage percentage"

Can you expand more on what the above means? Are we reporting milli
degrees celcius to userspace?

I could not find the datasheet so I guess it's not yet public?

> 
> A has_copper_trace capability flag is introduced in
> ltc2983_chip_info to identify the ADT7604, following the
> existing has_temp and has_eeprom pattern.
> 
> Tested on EVAL-ADT7604-AZ connected to Raspberry Pi 5 via SPI.
> 
> Signed-off-by: Liviu Stan <liviu.stan@analog.com>
> ---
>  drivers/iio/temperature/ltc2983.c | 347 +++++++++++++++++++++---------
>  1 file changed, 251 insertions(+), 96 deletions(-)
> 
> diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
> index 38e6f8dfd3b8..1966f6fb0305 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_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_RES_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)
> @@ -214,6 +216,7 @@ struct ltc2983_chip_info {
>  	unsigned int max_channels_nr;
>  	bool has_temp;
>  	bool has_eeprom;
> +	bool has_copper_trace;
>  };
>  
>  struct ltc2983_data {
> @@ -272,6 +275,7 @@ struct ltc2983_rtd {
>  	u32 r_sense_chan;
>  	u32 excitation_current;
>  	u32 rtd_curve;
> +	bool sub_ohm;
>  };
>  
>  struct ltc2983_thermistor {
> @@ -575,6 +579,10 @@ static int ltc2983_rtd_assign_chan(struct ltc2983_data *st,
>  		if (ret)
>  			return ret;
>  	}
> +
> +	if (rtd->sub_ohm)
> +		chan_val &= ~GENMASK(17, 0);
> +
>  	return __ltc2983_chan_assign_common(st, sensor, chan_val);
>  }

I'm not sure if we shouldn't just treat the new types as new sensors
instead of trying to push them in the existing one. I agree with Andy,
the patch does not look great with respect to if() else() and going to
deep in indentation.

>  
> @@ -758,83 +766,113 @@ 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) {
> -		switch (n_wires) {
> -		case 2:
> -			rtd->sensor_config = LTC2983_RTD_N_WIRES(0);
> -			break;
> -		case 3:
> -			rtd->sensor_config = LTC2983_RTD_N_WIRES(1);
> -			break;
> -		case 4:
> -			rtd->sensor_config = LTC2983_RTD_N_WIRES(2);
> -			break;
> -		case 5:
> -			/* 4 wires, Kelvin Rsense */
> -			rtd->sensor_config = LTC2983_RTD_N_WIRES(3);
> -			break;
> -		default:
> +	/* ADT7604 requires hardcoding sensor configuration bits to 0b1001 */
> +	if (st->info->has_copper_trace &&
> +	    sensor->type == LTC2983_SENSOR_RTD_CUSTOM) {
> +		rtd->sensor_config = 0x9;
> +		if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)

Like the above, we have the following kind of condition all over the
place. In DT we can just have a different type for these and map it to
real value when creating the sensor.

...

>  
>  	/* set common parameters */
> @@ -908,17 +946,27 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
>  		return dev_err_ptr_probe(dev, ret,
>  					 "rsense channel must be configured...\n");
>  
> -	if (fwnode_property_read_bool(child, "adi,single-ended")) {
> -		thermistor->sensor_config = LTC2983_THERMISTOR_SGL(1);
> -	} else if (fwnode_property_read_bool(child, "adi,rsense-share")) {
> -		/* rotation is only possible if sharing rsense */
> -		if (fwnode_property_read_bool(child, "adi,current-rotate"))
> -			thermistor->sensor_config =
> -						LTC2983_THERMISTOR_C_ROTATE(1);
> -		else
> -			thermistor->sensor_config =
> -						LTC2983_THERMISTOR_R_SHARE(1);
> +	if (st->info->has_copper_trace &&
> +	    sensor->type == LTC2983_SENSOR_THERMISTOR_CUSTOM) {
> +		thermistor->sensor_config = LTC2983_THERMISTOR_C_ROTATE(1);
> +		if (sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
> +			return dev_err_ptr_probe(dev, -EINVAL,
> +						 "Invalid chann:%d for leak detector\n",
> +						 sensor->chan);

Same story

> +	} else {
> +		if (fwnode_property_read_bool(child, "adi,single-ended")) {
> +			thermistor->sensor_config = LTC2983_THERMISTOR_SGL(1);
> +		} else if (fwnode_property_read_bool(child, "adi,rsense-share")) {
> +			/* rotation is only possible if sharing rsense */
> +			if (fwnode_property_read_bool(child, "adi,current-rotate"))
> +				thermistor->sensor_config =
> +							LTC2983_THERMISTOR_C_ROTATE(1);
> +			else
> +				thermistor->sensor_config =
> +							LTC2983_THERMISTOR_R_SHARE(1);
> +		}
>  	}
> +
>  	/* validate channel index */
>  	if (!(thermistor->sensor_config & LTC2983_THERMISTOR_DIFF_MASK) &&
>  	    sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN)
> @@ -928,23 +976,36 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
>  
>  	/* check custom sensor */
>  	if (sensor->type >= LTC2983_SENSOR_THERMISTOR_STEINHART) {
> -		bool steinhart = false;
> -		const char *propname;
> -
> -		if (sensor->type == LTC2983_SENSOR_THERMISTOR_STEINHART) {
> -			steinhart = true;
> -			propname = "adi,custom-steinhart";
> +		if (st->info->has_copper_trace &&
> +		    sensor->type == LTC2983_SENSOR_THERMISTOR_CUSTOM) {
> +			if (fwnode_property_present(child, "adi,custom-leak-detector")) {
> +				thermistor->custom =
> +					__ltc2983_custom_sensor_new(st, child,
> +								    "adi,custom-leak-detector",
> +								    false, 16, false);
> +				if (IS_ERR(thermistor->custom))
> +					return ERR_CAST(thermistor->custom);
> +			}
>  		} else {
> -			propname = "adi,custom-thermistor";
> +			bool steinhart = false;
> +			const char *propname;
> +
> +			if (sensor->type == LTC2983_SENSOR_THERMISTOR_STEINHART) {
> +				steinhart = true;
> +				propname = "adi,custom-steinhart";
> +			} else {
> +				propname = "adi,custom-thermistor";
> +			}
> +
> +			thermistor->custom = __ltc2983_custom_sensor_new(st, child,
> +									 propname,
> +									 steinhart,
> +									 64, false);
> +			if (IS_ERR(thermistor->custom))
> +				return ERR_CAST(thermistor->custom);
>  		}
> -
> -		thermistor->custom = __ltc2983_custom_sensor_new(st, child,
> -								 propname,
> -								 steinhart,
> -								 64, false);
> -		if (IS_ERR(thermistor->custom))
> -			return ERR_CAST(thermistor->custom);
>  	}
> +
>  	/* set common parameters */
>  	thermistor->sensor.fault_handler = ltc2983_common_fault_handler;
>  	thermistor->sensor.assign_chan = ltc2983_thermistor_assign_chan;
> @@ -1167,7 +1228,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)
>  {
>  	u32 start_conversion = 0;
>  	int ret;
> @@ -1197,13 +1259,23 @@ 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_CHAN_RES_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(&st->spi->dev, "Invalid conversion detected\n");
>  		return -EIO;
> @@ -1214,6 +1286,7 @@ static int ltc2983_chan_read(struct ltc2983_data *st,
>  		return ret;
>  
>  	*val = sign_extend32((*val) & LTC2983_DATA_MASK, LTC2983_DATA_SIGN_BIT);
> +
>  	return 0;
>  }
>  
> @@ -1234,7 +1307,12 @@ 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);
> +		if (chan->type == IIO_RESISTANCE)
> +			ret = ltc2983_chan_read(st, st->sensors[chan->address],
> +						ADT7604_RES_RES_START_REG, val);
> +		else
> +			ret = ltc2983_chan_read(st, st->sensors[chan->address],
> +						LTC2983_TEMP_RES_START_REG, val);

I think the preferred style is to also have switch() case for the above

>  		mutex_unlock(&st->lock);
>  		return ret ?: IIO_VAL_INT;
>  	case IIO_CHAN_INFO_SCALE:
> @@ -1251,6 +1329,18 @@ static int ltc2983_read_raw(struct iio_dev *indio_dev,
>  			/* 2^21 */
>  			*val2 = 2097152;
>  			return IIO_VAL_FRACTIONAL;
> +		case IIO_RESISTANCE:
> +			/* value in ohm */
> +			*val = 1;
> +			/*
> +			 * Copper trace result is in milliohm with 10 fractional
> +			 * bits: divide by 2^10 * 1000 = 1024000.
> +			 * Leak detector result is in ohm with 10 fractional
> +			 * bits: divide by 2^10 = 1024.
> +			 */
> +			*val2 = (st->sensors[chan->address]->type == LTC2983_SENSOR_RTD_CUSTOM) ?
> +				1024000 : 1024;
> +			return IIO_VAL_FRACTIONAL;

I would prefer a plain if() else

>  		default:
>  			return -EINVAL;
>  		}
> @@ -1292,6 +1382,17 @@ static irqreturn_t ltc2983_irq_handler(int irq, void *data)
>  	__chan; \
>  })
>  
> +#define LTC2983_RESISTANCE_CHAN(index, __address) ({ \
> +	struct iio_chan_spec __chan = { \
> +		.type = IIO_RESISTANCE, \
> +		.indexed = 1, \
> +		.channel = index, \
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \
> +		.address = __address, \
> +	}; \
> +	__chan; \
> +})
> +
>  static int ltc2983_parse_fw(struct ltc2983_data *st)
>  {
>  	struct device *dev = &st->spi->dev;
> @@ -1339,6 +1440,16 @@ 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 (st->info->has_copper_trace) {
> +			if ((sensor.type >= LTC2983_SENSOR_THERMOCOUPLE &&
> +			     sensor.type <= LTC2983_SENSOR_THERMOCOUPLE_CUSTOM) ||
> +			     sensor.type == LTC2983_SENSOR_DIODE ||
> +			     sensor.type == LTC2983_SENSOR_DIRECT_ADC)
> +				return dev_err_probe(dev, -EINVAL,
> +			 "sensor type %d not supported on %s\n",
> +			 sensor.type, st->info->name);
> +		}
> +

The above is also not great! Maybe see the possibility of having a
supported sensors mask that you fill in chip_info! Then we would just
test_bit() in here

>  		dev_dbg(dev, "Create new sensor, type %u, chann %u",
>  			sensor.type, sensor.chan);
>  
> @@ -1380,6 +1491,15 @@ static int ltc2983_parse_fw(struct ltc2983_data *st)
>  		st->sensors[chan]->chan = sensor.chan;
>  		st->sensors[chan]->type = sensor.type;
>  
> +		if (st->info->has_copper_trace) {
> +			if (st->sensors[chan]->type == LTC2983_SENSOR_THERMISTOR_CUSTOM &&
> +			    to_thermistor(st->sensors[chan])->custom)
> +				st->iio_channels++;
> +			else if (st->sensors[chan]->type == LTC2983_SENSOR_RTD_CUSTOM &&
> +				 to_rtd(st->sensors[chan])->custom)
> +				st->iio_channels++;
> +		}
> +

Having to go up to to_thermistor() and to_rtd() in a common path like
here also smells :). One possible solution would be to refactor things
so that:

`st->iio_channels = st->num_channels` is not necessarily true.

struct ltc2983_sensor could have a new n_iio_chan count given that now
we can (AFAIU) one sensor with more that one IIO channel. Then we could
count things in a generic way in here.

We might need to change more things that I'm missing now.

>  		channel_avail_mask |= BIT(sensor.chan);
>  		chan++;
>  	}
> @@ -1426,7 +1546,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;
> +	u32 iio_chan_t = 0, iio_chan_v = 0, iio_chan_r = 0, chan, iio_idx = 0, status;
>  	int ret;
>  
>  	/* make sure the device is up: start bit (7) is 0 and done bit (6) is 1 */
> @@ -1473,6 +1593,26 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
>  		    !assign_iio)
>  			continue;
>  
> +		/*
> +		 * Copper trace and leak detector sensors without a custom table
> +		 * produce only a resistance result; the chip does not populate
> +		 * the temperature result register. Emit only an IIO_RESISTANCE
> +		 * channel in this case.
> +		 */
> +		if (st->info->has_copper_trace) {
> +			bool resistance_only =
> +				(st->sensors[chan]->type == LTC2983_SENSOR_RTD_CUSTOM &&
> +				 !to_rtd(st->sensors[chan])->custom) ||
> +				(st->sensors[chan]->type == LTC2983_SENSOR_THERMISTOR_CUSTOM &&
> +				 !to_thermistor(st->sensors[chan])->custom);
> +
> +			if (resistance_only) {
> +				st->iio_chan[iio_idx++] =
> +					LTC2983_RESISTANCE_CHAN(iio_chan_r++, chan);
> +				continue;
> +			}
> +		}
> +

My above suggestion would also fit for the above I believe.

>  		/* assign iio channel */
>  		if (st->sensors[chan]->type != LTC2983_SENSOR_DIRECT_ADC) {
>  			chan_type = IIO_TEMP;
> @@ -1488,6 +1628,11 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
>  		 */
>  		st->iio_chan[iio_idx++] = LTC2983_CHAN(chan_type, (*iio_chan)++,
>  						       chan);
> +
> +		if (st->info->has_copper_trace &&
> +		    (st->sensors[chan]->type == LTC2983_SENSOR_RTD_CUSTOM ||
> +		     st->sensors[chan]->type == LTC2983_SENSOR_THERMISTOR_CUSTOM))
> +			st->iio_chan[iio_idx++] = LTC2983_RESISTANCE_CHAN(iio_chan_r++, chan);


I think the above can also be dropped and improved with what I
suggested.

- Nuno Sá


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-04-28 11:13 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-27 13:25 [PATCH 0/2] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
2026-04-27 13:25 ` [PATCH 1/2] dt-bindings: iio: temperature: Add ADT7604 support to adi,ltc2983 Liviu Stan
2026-04-27 19:34   ` Conor Dooley
2026-04-27 13:25 ` [PATCH 2/2] iio: temperature: ltc2983: Add support for ADT7604 Liviu Stan
2026-04-27 18:23   ` Andy Shevchenko
2026-04-28 11:14   ` Nuno Sá

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox