Skip to contentSkip to conversation

iio: adc: Add support for LTC2378 and similar ADCs

PATCH Superseded Marcelo Schmitt 4 participants 12 messages Jul 23 – Jul 26

Subsystems (4)

v8 of 10 Superseded Latest is v10 →

lore
Share & tools
lore

Marcelo Schmitt

author maintainer
#0 lore raw

v8 cover iio: adc: Add support for LTC2378 and similar ADCs

This patch series adds support for LTC2378 and similar low noise, low power, high speed, successive approximation register (SAR) ADCs. These ADCs are similar among each other, varying mainly on the amount of precision bits, maximum sample rate, and input configuration (either fully differential or pseudo-differential).

Patch 1 adds device tree documentation for LTC2378.

Patch 2 enables single-shot sample read with a GPIO connected to the LTC2378 CNV pin.

Patch 3 enables high-speed data captures with SPI offloading.
The setup is similar to AD4030, with a specialized PWM generator being used both for SPI offload triggering and conversion start signaling.

Patch 4 enables running buffered data captures without SPI offloading.

Patch 5 recommends using voltageY-voltageZ ABI for differential parts.

Even though these parts are somewhat similar to AD4000, the wiring configuration for LTC parts is different as well as the available HDL for high speed sample rate mode. Because of that, I propose creating a new device driver for supporting LTC2378-like devices.

Specifications can be found at:
https://www.analog.com/media/en/technical-documentation/data-sheets/233818fa.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/236416fa.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/236418f.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/236716fa.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/236718f.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/236816f.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/236818f.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/236918fa.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/237016fa.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/237616fa.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/237618fa.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/237620fb.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/237716fa.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/237718fa.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/237720fb.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/237816fa.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/237818fa.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/237820fb.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/237918fb.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/238016fb.pdf

Previous submissions:
v7: https://lore.kernel.org/linux-iio/[email protected]/
v6: https://lore.kernel.org/linux-iio/[email protected]/
v5: https://lore.kernel.org/linux-iio/[email protected]/
v4: https://lore.kernel.org/linux-iio/[email protected]/
v3: https://lore.kernel.org/linux-iio/[email protected]/
v2: https://lore.kernel.org/linux-iio/[email protected]/
v1: https://lore.kernel.org/linux-iio/[email protected]/

Change log v7 -> v8:
[DT]
No changes in device tree doc.
[IIO]
- Updated channel macros to make up indexed IIO channels.
- Encourage differential voltage ABI usage [NEW PATCH].
- Simplified if/else to consecutive if statements on ltc2378_refin_setup().
- Picked up review tags.

With best regards,
Marcelo

Marcelo Schmitt (5):
dt-bindings: iio: adc: Add ltc2378
iio: adc: ltc2378: Add support for LTC2378-20 and similar ADCs
iio: adc: ltc2378: Enable high-speed data capture
iio: adc: ltc2378: Enable triggered buffer data capture
iio: ABI: Encourage differential voltage ABI usage

 Documentation/ABI/testing/sysfs-bus-iio       |   9 +-
 .../bindings/iio/adc/adi,ltc2378.yaml         | 170 ++++
 MAINTAINERS                                   |   8 +
 drivers/iio/adc/Kconfig                       |  19 +
 drivers/iio/adc/Makefile                      |   1 +
 drivers/iio/adc/ltc2378.c                     | 851 ++++++++++++++++++
 6 files changed, 1054 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/adi,ltc2378.yaml
 create mode 100644 drivers/iio/adc/ltc2378.c

base-commit: aa58ecc73466d0cb8c418de98e2225490bf600e3

Signature · 1 line
2.53.0
author maintainer
#1 lore raw

PATCH v8 1/5 dt-bindings: iio: adc: Add ltc2378

Document how to describe LTC2378-20 and similar ADCs in device tree.

---
No changes in device tree doc since v6.

 .../bindings/iio/adc/adi,ltc2378.yaml         | 170 ++++++++++++++++++
 MAINTAINERS                                   |   7 +
 2 files changed, 177 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/adi,ltc2378.yaml
Documentation/devicetree/bindings/iio/adc/adi,ltc2378.yaml new file +170 -0
new file mode 100644
index 000000000000..33de1dc4c256
@@ -0,0 +1,170 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/adi,ltc2378.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices LTC2378 and similar Analog to Digital Converters
+
+maintainers:
+  - Marcelo Schmitt <[email protected]>
+
+description: |
+  Analog Devices LTC2378 series of ADCs.
+  Specifications can be found at:
+    https://www.analog.com/media/en/technical-documentation/data-sheets/233818fa.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/236416fa.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/236418f.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/236716fa.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/236718f.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/236816f.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/236818f.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/236918fa.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/237016fa.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/237616fa.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/237618fa.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/237620fb.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/237716fa.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/237718fa.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/237720fb.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/237816fa.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/237818fa.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/237820fb.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/237918fb.pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/238016fb.pdf
+
+$ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      # Single compatible string match.
+      - enum:
+          - adi,ltc2338-18
+          - adi,ltc2364-16
+          - adi,ltc2364-18
+          - adi,ltc2376-16
+          - adi,ltc2376-18
+          - adi,ltc2376-20
+
+      # Low sample rate fallback for 16-bit unipolar sensors.
+      - items:
+          - enum:
+              - adi,ltc2370-16 # 2 MSPS
+              - adi,ltc2368-16 # 1 MSPS
+              - adi,ltc2367-16 # 500 kSPS
+          - const: adi,ltc2364-16 # fallback (250 kSPS)
+
+      # Low sample rate fallback for 18-bit unipolar sensors.
+      - items:
+          - enum:
+              - adi,ltc2369-18 # 1.6 MSPS
+              - adi,ltc2368-18 # 1 MSPS
+              - adi,ltc2367-18 # 500 kSPS
+          - const: adi,ltc2364-18 # fallback (250 kSPS)
+
+      # Low sample rate fallback for 16-bit bipolar sensors.
+      - items:
+          - enum:
+              - adi,ltc2380-16 # 2 MSPS
+              - adi,ltc2378-16 # 1 MSPS
+              - adi,ltc2377-16 # 500 kSPS
+          - const: adi,ltc2376-16 # fallback (250 kSPS)
+
+      # Low sample rate fallback for 18-bit bipolar sensors.
+      - items:
+          - enum:
+              - adi,ltc2379-18 # 1.6 MSPS
+              - adi,ltc2378-18 # 1 MSPS
+              - adi,ltc2377-18 # 500 kSPS
+          - const: adi,ltc2376-18 # fallback (250 kSPS)
+
+      # Low sample rate fallback for 20-bit bipolar sensors.
+      - items:
+          - enum:
+              - adi,ltc2378-20 # 1 MSPS
+              - adi,ltc2377-20 # 500 kSPS
+          - const: adi,ltc2376-20 # fallback (250 kSPS)
+
+  reg:
+    maxItems: 1
+
+  spi-max-frequency:
+    maximum: 100000000
+
+  vdd-supply:
+    description: A 2.5V supply that powers the chip (VDD).
+
+  ovdd-supply:
+    description:
+      A 1.71V to 5.25V supply that sets the logic level for digital interface.
+
+  ref-supply:
+    description:
+      Voltage reference input that determines the scale of ADC conversions.
+
+  refin-supply:
+    description:
+      Alternative voltage reference input.
+
+  cnv-gpios:
+    description:
+      When provided, this property indicates the GPIO that is connected to the
+      CNV pin.
+    maxItems: 1
+
+  pwms:
+    description: PWM signal connected to the CNV pin.
+    maxItems: 1
+
+  interrupts:
+    description:
+      Interrupt for signaling the completion of conversion results. The active
+      low signal provided on the BUSY pin asserts when ADC conversions finish.
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - vdd-supply
+  - ovdd-supply
+
+allOf:
+  # Except for LTC2338, all designs require a voltage reference input
+  - if:
+      properties:
+        compatible:
+          not:
+            contains:
+              enum:
+                - adi,ltc2338-18
+    then:
+      required:
+        - ref-supply
+      properties:
+        refin-supply: false
+    else:
+      properties:
+        ref-supply: false
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        adc@0 {
+            compatible = "adi,ltc2378-20", "adi,ltc2376-20";
+            reg = <0>;
+            spi-max-frequency = <71000000>;
+            vdd-supply = <&supply_2_5V>;
+            ovdd-supply = <&supply_3_3V>;
+            ref-supply = <&supply_5V>;
+            cnv-gpios = <&gpio0 88 GPIO_ACTIVE_HIGH>;
+            interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
+            interrupt-parent = <&gpio>;
+        };
+    };
MAINTAINERS +7 -0
index 2b1ec46c5919..f0ae26699c99 100644
@@ -15343,6 +15343,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/iio/dac/lltc,ltc1660.yaml
 F:	drivers/iio/dac/ltc1660.c
 
+LTC2378 IIO ADC DRIVER
+M:	Marcelo Schmitt <[email protected]>
+L:	[email protected]
+S:	Supported
+W:	https://ez.analog.com/linux-software-drivers
+F:	Documentation/devicetree/bindings/iio/adc/adi,ltc2378.yaml
+
 LTC2664 IIO DAC DRIVER
 M:	Michael Hennerich <[email protected]>
 M:	Kim Seer Paller <[email protected]>
Signature · 1 line
2.53.0
author maintainer
#2 lore raw

PATCH v8 2/5 iio: adc: ltc2378: Add support for LTC2378-20 and similar ADCs

In reply to Marcelo Schmitt

Support for LTC2378-20 and similar analog-to-digital converters.

---
Change log v7 -> v8:
- Updated channel macros to make up indexed IIO channels.
- Simplified if/else to consecutive if statements on ltc2378_refin_setup().

 MAINTAINERS               |   1 +
 drivers/iio/adc/Kconfig   |  12 ++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/ltc2378.c | 421 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 435 insertions(+)
 create mode 100644 drivers/iio/adc/ltc2378.c
MAINTAINERS +1 -0
index f0ae26699c99..25821b771692 100644
@@ -15349,6 +15349,7 @@ L:	[email protected]
 S:	Supported
 W:	https://ez.analog.com/linux-software-drivers
 F:	Documentation/devicetree/bindings/iio/adc/adi,ltc2378.yaml
+F:	drivers/iio/adc/ltc2378.c
 
 LTC2664 IIO DAC DRIVER
 M:	Michael Hennerich <[email protected]>
drivers/iio/adc/Kconfig +12 -0
index d1b198cb8a80..220c6739a8f2 100644
@@ -943,6 +943,18 @@ config LTC2309
 	  This driver can also be built as a module. If so, the module will
 	  be called ltc2309.
 
+config LTC2378
+	tristate "Analog Devices LTC2378 ADC driver"
+	depends on SPI
+	depends on REGULATOR || COMPILE_TEST
+	depends on GPIOLIB
+	help
+	  Say yes here to build support for Analog Devices LTC2378-20 and
+	  similar analog to digital converters.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called ltc2378.
+
 config LTC2471
 	tristate "Linear Technology LTC2471 and LTC2473 ADC driver"
 	depends on I2C
drivers/iio/adc/Makefile +1 -0
index 0f90b75577ff..6058a8be6ccd 100644
@@ -81,6 +81,7 @@ obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o
 obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o
 obj-$(CONFIG_LTC2309) += ltc2309.o
+obj-$(CONFIG_LTC2378) += ltc2378.o
 obj-$(CONFIG_LTC2471) += ltc2471.o
 obj-$(CONFIG_LTC2485) += ltc2485.o
 obj-$(CONFIG_LTC2496) += ltc2496.o ltc2497-core.o
drivers/iio/adc/ltc2378.c new file +421 -0

421 lines not on this page · raw message

Signature · 1 line
2.53.0
#3 lore raw

Re: [PATCH v8 2/5] iio: adc: ltc2378: Add support for LTC2378-20 and similar ADCs

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] The IIO scale factor exported for the LTC2338-18 is incorrect due to an unaccounted internal…

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The IIO scale factor exported for the LTC2338-18 is incorrect due to an unaccounted internal resistor divider (missing 2.5x multiplier). --

--- Patch [2]: [PATCH v8 2/5] iio: adc: ltc2378: Add support for LTC2378-20 and similar ADCs --- commit 79bd7cc98e49057401d7fb8d26685b9092c4787e
Author: Marcelo Schmitt <[email protected]>

iio: adc: ltc2378: Add support for LTC2378-20 and similar ADCs

Support for LTC2378-20 and similar analog-to-digital converters.

Quoted 5 lines
drivers/iio/adc/ltc2378.c new file +0 -0
new file mode 100644
index 0000000000000..107388f870626

[ ... ]

drivers/iio/adc/ltc2378.c line 90

Quoted 5 lines
drivers/iio/adc/ltc2378.c new file +5 -0
+static const struct ltc2378_chip_info ltc2338_18_chip_info = {
+	.name = "ltc2338-18",
+	.internal_ref_uV = 2048000,
+	.chan = LTC2378_DIFF_CHANNEL(18),
+};

[Severity: Medium]
Does this chip info need a field to indicate the scale multiplier?

The LTC2338-18 has an internal resistor divider which acts as a 2.5x multiplier, but this struct doesn't currently contain a way to specify it.

[ ... ]

Quoted 8 lines
drivers/iio/adc/ltc2378.c new file +8 -0
+static int ltc2378_read_raw(struct iio_dev *indio_dev,
+			    const struct iio_chan_spec *chan,
+			    int *val, int *val2, long mask)
+{
+	struct ltc2378_state *st = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {

[ ... ]

drivers/iio/adc/ltc2378.c line 254

Quoted 2 lines
drivers/iio/adc/ltc2378.c new file +2 -0
+	case IIO_CHAN_INFO_SCALE:
+		*val = st->ref_uV / MILLI;

[Severity: Medium]
Will this return an incorrect IIO scale factor for the LTC2338-18?

The scale is calculated purely based on the reference voltage here, which does not account for the LTC2338-18's internal divider (missing the 2.5x multiplier). This could lead to incorrect voltage calculations in userspace.

Quoted 12 lines
drivers/iio/adc/ltc2378.c new file +12 -0
+		/*
+		 * For all LTC2378-like devices, the amount of bits that express
+		 * voltage magnitude depend on the polarity / output code format:
+		 * - straight binary: All precision/resolution bits are used.
+		 * - 2's complement: One of the precision bits is used for sign.
+		 */
+		if (chan->scan_type.format == IIO_SCAN_FORMAT_SIGNED_INT)
+			*val2 = chan->scan_type.realbits - 1;
+		else
+			*val2 = chan->scan_type.realbits;
+
+		return IIO_VAL_FRACTIONAL_LOG2;
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
#4 lore raw

Re: [PATCH v8 2/5] iio: adc: ltc2378: Add support for LTC2378-20 and similar ADCs

Quoted 27 lines · On 07/23, [email protected] wrote:

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The IIO scale factor exported for the LTC2338-18 is incorrect due to an unaccounted internal resistor divider (missing 2.5x multiplier). --

--- Patch [2]: [PATCH v8 2/5] iio: adc: ltc2378: Add support for LTC2378-20 and similar ADCs --- commit 79bd7cc98e49057401d7fb8d26685b9092c4787e
Author: Marcelo Schmitt <[email protected]>

iio: adc: ltc2378: Add support for LTC2378-20 and similar ADCs

Support for LTC2378-20 and similar analog-to-digital converters.

Quoted 5 lines
drivers/iio/adc/ltc2378.c new file +0 -0
new file mode 100644
index 0000000000000..107388f870626

[ ... ]

drivers/iio/adc/ltc2378.c line 90

Quoted 5 lines
drivers/iio/adc/ltc2378.c new file +5 -0
+static const struct ltc2378_chip_info ltc2338_18_chip_info = {
+	.name = "ltc2338-18",
+	.internal_ref_uV = 2048000,
+	.chan = LTC2378_DIFF_CHANNEL(18),
+};

[Severity: Medium]
Does this chip info need a field to indicate the scale multiplier?

Quoted 2 lines

The LTC2338-18 has an internal resistor divider which acts as a 2.5x multiplier, but this struct doesn't currently contain a way to specify it.

I guess it makes sense. Might split support for this specific part into a separate patch to avoid it holding on the rest of the series in v9.

maintainer
#5 lore raw

Re: [PATCH v8 2/5] iio: adc: ltc2378: Add support for LTC2378-20 and similar ADCs

Quoted 28 lines · On Fri, 24 Jul 2026 11:40:11 -0300 Marcelo Schmitt…
Quoted 27 lines · On 07/23, [email protected] wrote:

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The IIO scale factor exported for the LTC2338-18 is incorrect due to an unaccounted internal resistor divider (missing 2.5x multiplier). --

--- Patch [2]: [PATCH v8 2/5] iio: adc: ltc2378: Add support for LTC2378-20 and similar ADCs --- commit 79bd7cc98e49057401d7fb8d26685b9092c4787e
Author: Marcelo Schmitt <[email protected]>

iio: adc: ltc2378: Add support for LTC2378-20 and similar ADCs

Support for LTC2378-20 and similar analog-to-digital converters.

Quoted 5 lines
drivers/iio/adc/ltc2378.c new file +0 -0
new file mode 100644
index 0000000000000..107388f870626

[ ... ]

drivers/iio/adc/ltc2378.c line 90

Quoted 5 lines
drivers/iio/adc/ltc2378.c new file +5 -0
+static const struct ltc2378_chip_info ltc2338_18_chip_info = {
+	.name = "ltc2338-18",
+	.internal_ref_uV = 2048000,
+	.chan = LTC2378_DIFF_CHANNEL(18),
+};  

[Severity: Medium]
Does this chip info need a field to indicate the scale multiplier?

Quoted 5 lines
Quoted 2 lines

The LTC2338-18 has an internal resistor divider which acts as a 2.5x multiplier, but this struct doesn't currently contain a way to specify it.

I guess it makes sense. Might split support for this specific part into a separate patch to avoid it holding on the rest of the series in v9.

Works for me.

J

Quoted 1 line
author maintainer
#6 lore raw

PATCH v8 3/5 iio: adc: ltc2378: Enable high-speed data capture

In reply to Marcelo Schmitt

Make use of SPI transfer offloading to speed up data capture, enabling data acquisition at faster sample rates (up to 2 MSPS).

---
Change log v7 -> v8:
- Updated channel macros to make up indexed IIO channels.

 drivers/iio/adc/Kconfig   |   6 +
 drivers/iio/adc/ltc2378.c | 407 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 410 insertions(+), 3 deletions(-)
drivers/iio/adc/Kconfig +6 -0
index 220c6739a8f2..96df8453b826 100644
@@ -948,6 +948,12 @@ config LTC2378
 	depends on SPI
 	depends on REGULATOR || COMPILE_TEST
 	depends on GPIOLIB
+	depends on PWM
+	select IIO_BUFFER
+	select IIO_BUFFER_DMA
+	select IIO_BUFFER_DMAENGINE
+	select SPI_OFFLOAD
+	select SPI_OFFLOAD_TRIGGER_PWM
 	help
 	  Say yes here to build support for Analog Devices LTC2378-20 and
 	  similar analog to digital converters.
drivers/iio/adc/ltc2378.c +404 -3

568 lines not on this page · raw message

Signature · 1 line
2.53.0
#7 lore raw

Re: [PATCH v8 3/5] iio: adc: ltc2378: Enable high-speed data capture

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: - [High] Division by zero vulnerabilities in ltc2378_update_conversion_rate due to unhandled hardware…

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Division by zero vulnerabilities in ltc2378_update_conversion_rate due to unhandled hardware rounding of period/frequency.
- [Low] Unlocked data race on st->cnv_Hz between read_raw and write_raw.
--

--- Patch [3]: [PATCH v8 3/5] iio: adc: ltc2378: Enable high-speed data capture --- commit cad96004cef5739b24db063923b36678ea8e3617
Author: Marcelo Schmitt <[email protected]>
Subject: iio: adc: ltc2378: Enable high-speed data capture

Make use of SPI transfer offloading to speed up data capture, enabling data acquisition at faster sample rates (up to 2 MSPS).

drivers/iio/adc/ltc2378.c static int ltc2378_read_raw(struct iio_dev *indio_dev, · line 388

Quoted 10 lines
drivers/iio/adc/ltc2378.c +2 -0
index 107388f870626..7baee02450d39 100644
@@ -264,7 +384,137 @@ static int ltc2378_read_raw(struct iio_dev *indio_dev,
 			*val2 = chan->scan_type.realbits;
 
 		return IIO_VAL_FRACTIONAL_LOG2;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*val = st->cnv_Hz;

[Severity: Low]
Does this lockless read of st->cnv_Hz race with concurrent updates?

While ltc2378_write_raw() acquires the IIO direct mode lock before calling ltc2378_update_conversion_rate() to update st->cnv_Hz, this read path appears to access it without synchronization or READ_ONCE()/WRITE_ONCE() macros.

Quoted 1 line
drivers/iio/adc/ltc2378.c +1 -0
+		return IIO_VAL_INT;

[ ... ]

Quoted 2 lines
drivers/iio/adc/ltc2378.c +2 -0
+static int ltc2378_update_conversion_rate(struct ltc2378_state *st, int freq_Hz)
+{

[ ... ]

drivers/iio/adc/ltc2378.c static int ltc2378_read_raw(struct iio_dev *indio_dev, · line 477

Quoted 10 lines
drivers/iio/adc/ltc2378.c +10 -0
+	/*
+	 * Configure SPI offload PWM trigger.
+	 * The trigger should fire after tBUSYLH + tCONV + tDSDOBUSYL.
+	 * Minimum time needed: TBUSYLH (13ns) + TCONV (part-specific) + TDSDOBUSYL (5ns)
+	 *
+	 * Use the same period as CNV PWM to avoid timing issues.
+	 * Convert back from period to frequency for the SPI offload API.
+	 */
+	offload_period_ns = cnv_wf.period_length_ns;
+	config.periodic.frequency_hz = div_u64(HZ_PER_GHZ, offload_period_ns);

[Severity: High]
Can this result in a division by zero if offload_period_ns is 0?

If pwm_round_waveform_might_sleep() rounds the requested period down to 0, offload_period_ns will be 0 and cause a kernel panic here.

Quoted 1 line
drivers/iio/adc/ltc2378.c +1 -0
+	min_read_offset = LTC2378_TBUSYLH_NS + st->info->tconv_ns + LTC2378_TDSDOBUSYL_NS;

[ ... ]

drivers/iio/adc/ltc2378.c static int ltc2378_read_raw(struct iio_dev *indio_dev, · line 494

Quoted 6 lines
drivers/iio/adc/ltc2378.c +6 -0
+	/* Check the minimum CNV to SCLK delay is met */
+	if (config.periodic.offset_ns < min_read_offset)
+		return -EDOM;
+
+	/* Check the PWM periods remain the same */
+	offload_period_ns = div64_u64(HZ_PER_GHZ, config.periodic.frequency_hz);

[Severity: High]
Does this code panic if config.periodic.frequency_hz evaluates to 0?

If a user writes a very low sampling frequency, the PWM driver might round the hardware period up to a value greater than HZ_PER_GHZ. If offload_period_ns > HZ_PER_GHZ, the earlier calculation for config.periodic.frequency_hz will evaluate to 0.

Additionally, if spi_offload_trigger_validate() mutates frequency_hz down to 0, it would also result in a division by zero here.

Quoted 2 lines
drivers/iio/adc/ltc2378.c +2 -0
+	if (cnv_wf.period_length_ns != offload_period_ns)
+		return -EDOM;
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=3
#8 lore raw

Re: [PATCH v8 3/5] iio: adc: ltc2378: Enable high-speed data capture

Quoted 20 lines · On 07/23, [email protected] wrote:

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Division by zero vulnerabilities in ltc2378_update_conversion_rate due to unhandled hardware rounding of period/frequency.
- [Low] Unlocked data race on st->cnv_Hz between read_raw and write_raw.
--

--- Patch [3]: [PATCH v8 3/5] iio: adc: ltc2378: Enable high-speed data capture --- commit cad96004cef5739b24db063923b36678ea8e3617
Author: Marcelo Schmitt <[email protected]>
Subject: iio: adc: ltc2378: Enable high-speed data capture

Make use of SPI transfer offloading to speed up data capture, enabling data acquisition at faster sample rates (up to 2 MSPS).

Quoted 7 lines
drivers/iio/adc/ltc2378.c +0 -0
index 107388f870626..7baee02450d39 100644
@@ -264,7 +384,137 @@ static int ltc2378_read_raw(struct iio_dev *indio_dev,
 			*val2 = chan->scan_type.realbits;
 
Quoted 7 lines

drivers/iio/adc/ltc2378.c static int ltc2378_read_raw(struct iio_dev *indio_dev, · line 388

Quoted 3 lines
drivers/iio/adc/ltc2378.c +2 -0
 		return IIO_VAL_FRACTIONAL_LOG2;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*val = st->cnv_Hz;

[Severity: Low]
Does this lockless read of st->cnv_Hz race with concurrent updates?

Not a big deal, IMHO.

Quoted 49 lines

While ltc2378_write_raw() acquires the IIO direct mode lock before calling ltc2378_update_conversion_rate() to update st->cnv_Hz, this read path appears to access it without synchronization or READ_ONCE()/WRITE_ONCE() macros.

Quoted 1 line
drivers/iio/adc/ltc2378.c +1 -0
+		return IIO_VAL_INT;

[ ... ]

Quoted 2 lines
drivers/iio/adc/ltc2378.c +2 -0
+static int ltc2378_update_conversion_rate(struct ltc2378_state *st, int freq_Hz)
+{

[ ... ]

drivers/iio/adc/ltc2378.c static int ltc2378_read_raw(struct iio_dev *indio_dev, · line 477

Quoted 10 lines
drivers/iio/adc/ltc2378.c +10 -0
+	/*
+	 * Configure SPI offload PWM trigger.
+	 * The trigger should fire after tBUSYLH + tCONV + tDSDOBUSYL.
+	 * Minimum time needed: TBUSYLH (13ns) + TCONV (part-specific) + TDSDOBUSYL (5ns)
+	 *
+	 * Use the same period as CNV PWM to avoid timing issues.
+	 * Convert back from period to frequency for the SPI offload API.
+	 */
+	offload_period_ns = cnv_wf.period_length_ns;
+	config.periodic.frequency_hz = div_u64(HZ_PER_GHZ, offload_period_ns);

[Severity: High]
Can this result in a division by zero if offload_period_ns is 0?

If pwm_round_waveform_might_sleep() rounds the requested period down to 0, offload_period_ns will be 0 and cause a kernel panic here.

Quoted 1 line
drivers/iio/adc/ltc2378.c +1 -0
+	min_read_offset = LTC2378_TBUSYLH_NS + st->info->tconv_ns + LTC2378_TDSDOBUSYL_NS;

[ ... ]

drivers/iio/adc/ltc2378.c static int ltc2378_read_raw(struct iio_dev *indio_dev, · line 494

Quoted 6 lines
drivers/iio/adc/ltc2378.c +6 -0
+	/* Check the minimum CNV to SCLK delay is met */
+	if (config.periodic.offset_ns < min_read_offset)
+		return -EDOM;
+
+	/* Check the PWM periods remain the same */
+	offload_period_ns = div64_u64(HZ_PER_GHZ, config.periodic.frequency_hz);

[Severity: High]
Does this code panic if config.periodic.frequency_hz evaluates to 0?

If a user writes a very low sampling frequency, the PWM driver might round the hardware period up to a value greater than HZ_PER_GHZ. If offload_period_ns > HZ_PER_GHZ, the earlier calculation for config.periodic.frequency_hz will evaluate to 0.

Quoted 6 lines

Additionally, if spi_offload_trigger_validate() mutates frequency_hz down to 0, it would also result in a division by zero here.

drivers/iio/adc/ltc2378.c static int ltc2378_read_raw(struct iio_dev *indio_dev, · line 496

Quoted 2 lines
drivers/iio/adc/ltc2378.c +2 -0
+	if (cnv_wf.period_length_ns != offload_period_ns)
+		return -EDOM;

Theory already refuted in previous version.
https://lore.kernel.org/linux-iio/alpZwoau3QVPtBsP@debian-BULLSEYE-live-builder-AMD64/

author maintainer
#9 lore raw

PATCH v8 4/5 iio: adc: ltc2378: Enable triggered buffer data capture

In reply to Marcelo Schmitt

Enable users to run triggered data captures with LTC2378 and similar ADCs.

---
No changes in v8.

 drivers/iio/adc/Kconfig   |  1 +
 drivers/iio/adc/ltc2378.c | 75 +++++++++++++++++++++++++++------------
 2 files changed, 53 insertions(+), 23 deletions(-)
drivers/iio/adc/Kconfig +1 -0
index 96df8453b826..6cf67f7a6eed 100644
@@ -952,6 +952,7 @@ config LTC2378
 	select IIO_BUFFER
 	select IIO_BUFFER_DMA
 	select IIO_BUFFER_DMAENGINE
+	select IIO_TRIGGERED_BUFFER
 	select SPI_OFFLOAD
 	select SPI_OFFLOAD_TRIGGER_PWM
 	help
drivers/iio/adc/ltc2378.c +52 -23

225 lines not on this page · raw message

Signature · 1 line
2.53.0
author maintainer
#10 lore raw

PATCH v8 5/5 iio: ABI: Encourage differential voltage ABI usage

In reply to Marcelo Schmitt

So far, parts that could only do differential voltage measurements were only required to have a consistent labeling of their channels by complying either to voltageY or to voltageY-voltageZ ABI. Over time, code maintainers came to the conclusion that the voltageY-voltageZ ABI is better suited for differential-only chips as it provides a simple indication to users that the channels measure the difference of two inputs.

Adjust the ABI documentation to recommend using the voltageY-voltageZ ABI for chips that do only differential voltage measurements.

---
New patch in v8.

The updated ABI doc might not have gotten very clear, so I'm completely fine with any modifications to this patch. Also, since the documentation update is minimal, doesn't add any new ABI, and might be picked up through Jonathan's tree, I'm not CCing the documentaion mailing list.

 Documentation/ABI/testing/sysfs-bus-iio | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
Documentation/ABI/testing/sysfs-bus-iio +5 -4
index 5cc2e82c4997..7446e07b9ab2 100644
@@ -162,10 +162,11 @@ Contact:	[email protected]
 Description:
 		Raw (unscaled) differential voltage measurement equivalent to
 		channel Y - channel Z where these channel numbers apply to the
-		physically equivalent inputs when non differential readings are
-		separately available. In differential only parts, then all that
-		is required is a consistent labeling.  Units after application
-		of scale and offset are millivolts.
+		physically equivalent inputs when non-differential readings are
+		separately available. Even though differential-only parts had
+		been merely required to have consistent channel labeling, this
+		ABI is preferred over the non-differential one for those chips.
+		Units after application of scale and offset are millivolts.
 
 What:		/sys/bus/iio/devices/iio:deviceX/in_altvoltageY_rms_raw
 KernelVersion:	6.18
Signature · 1 line
2.53.0
maintainer
#11 lore raw

Re: [PATCH v8 5/5] iio: ABI: Encourage differential voltage ABI usage

Quoted 10 lines · On Thu, 23 Jul 2026 16:53:35 -0300 Marcelo Schmitt…

So far, parts that could only do differential voltage measurements were only required to have a consistent labeling of their channels by complying either to voltageY or to voltageY-voltageZ ABI. Over time, code maintainers came to the conclusion that the voltageY-voltageZ ABI is better suited for differential-only chips as it provides a simple indication to users that the channels measure the difference of two inputs.

Adjust the ABI documentation to recommend using the voltageY-voltageZ ABI for chips that do only differential voltage measurements.

Quoted 9 lines

---
New patch in v8.

The updated ABI doc might not have gotten very clear, so I'm completely fine with any modifications to this patch. Also, since the documentation update is minimal, doesn't add any new ABI, and might be picked up through Jonathan's tree, I'm not CCing the documentaion mailing list.

Looks fine to me.

I looked through the rest of the series and other than the thing you've suggested doing of dropping the slightly more complex part for now, looks good to me. Feel free to send a v9 whenever you have it ready. This is near enough merge I don't mind going a bit quicker than normal.

Jonathan

Quoted 23 lines
 Documentation/ABI/testing/sysfs-bus-iio | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
Documentation/ABI/testing/sysfs-bus-iio +5 -4
index 5cc2e82c4997..7446e07b9ab2 100644
@@ -162,10 +162,11 @@ Contact:	[email protected]
 Description:
 		Raw (unscaled) differential voltage measurement equivalent to
 		channel Y - channel Z where these channel numbers apply to the
-		physically equivalent inputs when non differential readings are
-		separately available. In differential only parts, then all that
-		is required is a consistent labeling.  Units after application
-		of scale and offset are millivolts.
+		physically equivalent inputs when non-differential readings are
+		separately available. Even though differential-only parts had
+		been merely required to have consistent channel labeling, this
+		ABI is preferred over the non-differential one for those chips.
+		Units after application of scale and offset are millivolts.
 
 What:		/sys/bus/iio/devices/iio:deviceX/in_altvoltageY_rms_raw
 KernelVersion:	6.18