Devicetree
 help / color / mirror / Atom feed
* [PATCH v6 0/2] iio: adc: Add support for Texas Instruments ADS112C04
@ 2026-08-20  7:51 Kyle Hsieh
  2026-08-20  7:51 ` [PATCH v6 1/2] dt-bindings: iio: adc: ti,ads112c04: Add binding for ADS112C04 Kyle Hsieh
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Kyle Hsieh @ 2026-08-20  7:51 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Liam Girdwood,
	Mark Brown, Philipp Zabel
  Cc: linux-iio, devicetree, linux-kernel, Kyle Hsieh, Conor Dooley

This patch series introduces support for the Texas Instruments ADS112C04
Analog-to-Digital Converters.

The ADS112C04 (16-bit) is precision, low-power, delta-sigma ADCs with
an I2C interface. They feature a flexible input multiplexer supporting
single-ended and differential measurements, a programmable gain amplifier,
and an internal voltage reference.

Note: While this chip shares similarities with the ADS112C14 (currently 
being upstreamed by David Lechner), the register maps and feature sets 
are sufficiently different to warrant a separate driver. However, the
DT bindings and channel parsing logic have been aligned with the
ADS112C14 conventions.

This initial submission provides a minimal feature set (single-shot 
conversions and basic DRDY interrupt) covering current use cases.

Signed-off-by: Kyle Hsieh <kylehsieh1995@gmail.com>
---
Changes in v6:
- dt-bindings: iio: adc: ti,ads112c04:
  - Dropped the redundant 'items' wrapper from
    excitation-current-nanoamp and burn-out-current-nanoamp.
  - Moved reference-sources' default to the property level.
  - Kept David's Reviewed-by and Conor's Acked-by: the changes are schema
    syntax only, with no change to the accepted values or semantics.
    Happy to drop the tags if either would prefer to re-review.

- iio: adc: ti-ads112c04:
  - Split the read_poll_timeout() arguments logically and dropped the
    redundant outer parentheses.
  - Added ADS112C04_RESOLUTION_BITS and used it for both the
    sign_extend32() bit index and the scale exponent.
  - Added the missing <linux/array_size.h> include.
  - Used local variables for the single-channel/diff-channels property
    names so the error messages stay in sync.
  - Added a comment for the post-reset delay.
- Link to v5: https://lore.kernel.org/r/20260813-ti-ads112c04-driver-v5-0-79dff9e249cd@gmail.com

Changes in v5:
- Addressed several suggestions from v1-v4 that I had missed in earlier
  revisions. Apologies for the churn this caused; I went back through
  all four threads as David asked.

- dt-bindings: iio: adc: ti,ads112c04:
  - No changes. Picked up David's Reviewed-by and Conor's Acked-by.

- iio: adc: ti-ads112c04:
  - Made the reference voltage per-channel, following the ADS112C14
    driver: reference-sources is parsed with
    fwnode_property_match_property_string() and stored per channel, and
    the CONFIG1 VREF field is now updated together with the MUX before
    each conversion. avdd is read with
    devm_regulator_get_enable_read_voltage() when a channel uses it.
  - Organised the register field macros indented under their register,
    and shortened CONFIG to CONF in the field names.
  - Spelled out all CONFIG0/CONFIG1 fields explicitly with FIELD_PREP()
    when initialising, rather than relying on implicit zeros.
  - Moved the internal reference macro to the top of the file with the
    other defines and renamed it to ADS112C04_INT_REF_mV.
  - Dropped disable_irq_nosync(); the handler only calls complete(),
    which is safe in a normal IRQ handler, so a threaded IRQ isn't
    needed. The bare `0` flags argument is now packed with the
    other arguments.
  - Fixed word-read byte ordering by using
    i2c_smbus_read_word_swapped().
  - Dropped the has_refp state member; it is passed as a function
    argument instead.
  - Added a REVISIT comment on spec->type for when
    ti,refp-refn-resistor-ohms is implemented.
  - Reduced the power-on reset delay from 50ms to 500us, per the
    datasheet.
  - Replaced the diff-channels if-else chain with a 4x4 lookup table
    indexed by [AINP][AINN].
  - Used wait_for_completion_timeout() directly in the if condition,
    swapped err/ret in ads112c04_wait_for_data(), made the channel
    index unsigned int with the assignment split out, stopped reusing
    pair[0] for single-channel, and used ARRAY_SIZE(pair).
  - Added ADS112C04_MAX_CHANNELS and used it in the bounds check.
  - Split reference-sources parsing into a helper to keep the call
    within the line length limit.
  - Updated the commit message to describe per-channel reference
    selection; refn-supply remains unsupported.
  - Switched the hardware reset to the reset controller framework
    (devm_reset_control_get_optional_exclusive()), which works with the
    existing reset-gpios property via the reset-gpio driver. The binding
    is unchanged.
- Link to v4: https://lore.kernel.org/r/20260811-ti-ads112c04-driver-v4-0-ae704ac17241@gmail.com

Changes in v4:
- dt-bindings: iio: adc: ti,ads112c04:
  - Fixed excitation-current-nanoamp to use single-entry list syntax
    (items: - enum: [...]) instead of combining maxItems: 1 with a
    mapping-style items, which failed dt_binding_check.
  - Widened excitation-channels to maximum: 5 to account for IDAC1/
    IDAC2 also being routable to REFP0/REFN0, and documented the
    mapping, per David Lechner.
  - Reduced excitation-current-nanoamp to a single entry, since the
    two IDAC outputs share one current setting, per David Lechner.
  - Changed burn-out-current-nanoamp to use `const: 10000`, per David
    Lechner.
  - Renamed reference-sources' internal enum value to "internal"
    (dropped voltage suffix, since there is only one internal
    reference), per David Lechner.

- iio: adc: ti-ads112c04:
  - Fixed word-read byte ordering by switching to
    i2c_smbus_read_word_swapped(), addressing a big-endian data
    corruption issue flagged by Sashiko AI review.
  - Masked the DRDY interrupt in the hardirq handler
    (disable_irq_nosync()) and re-enabled it once the conversion data
    is read, to avoid an interrupt storm on level-triggered DRDY
    configurations, without hardcoding the trigger type.
  - Reworked reference-sources handling in parse_channels(): it is now
    validated against the actually-selected refp-supply instead of
    being unconditionally rejected, per David Lechner.
  - Simplified regulator handling in probe() using
    devm_regulator_get_enable_read_voltage(), dropping the now-unused
    vref_reg field, per David Lechner.
  - Corrected the commit message to no longer claim refn-supply
    support, since it remains explicitly unsupported in probe().
- Added a MAINTAINERS entry for the new binding and driver.
- Link to v3: https://lore.kernel.org/r/20260805-ti-ads112c04-driver-v3-0-49f436829e01@gmail.com

Changes in v3:
- dt-bindings: iio: adc: ti,ads112c04:
  - Resolved dt_binding_check errors by removing redundant $ref for
    standard unit suffixes and fixing YAML array syntax.
  - Added full hardware capability descriptions (excitation-channels,
    excitation-current-nanoamp, burn-out-current-nanoamp,
    reference-sources) as suggested by David Lechner.
  - Restricted the reg maximum to 11 and updated the regex to
    ^channel@[0-9a-b]$ to accurately reflect the 12 possible MUX
    combinations.

- iio: adc: ti-ads112c04:
  - Transitioned all I2C read/write wrappers to use SMBus APIs
    (i2c_smbus_read_byte_data, i2c_smbus_read_word_data, etc.) to
    gracefully handle I2C errors, NACKs, and Repeated Starts, addressing
    feedback from Joshua Crofts and Jonathan Cameron.
  - Added forward compatibility checks in probe() and parse_channels()
    using dev_err_probe() to return -EOPNOTSUPP for unimplemented DT
    properties.
  - Reverted devm_request_irq() flags to 0 to let the driver inherit the
    trigger type strictly from the DT, per Jonathan Cameron's advice.
  - Reduced the data wait timeout to 100ms, reflecting the chip's slowest
    data rate of 20 SPS.
  - Fixed #include alphabetical sorting, grouped <linux/iio/*> headers,
    and added missing headers.
  - Fixed variable declaration ordering (reverse xmas tree) and updated
    variable naming to vref_mV (SI unit exception).
  - Optimized GPIO reset logic using GPIOD_OUT_HIGH.
- Link to v2: https://lore.kernel.org/r/20260731-ti-ads112c04-driver-v2-0-aab0168c3c01@gmail.com

Changes in v2:
- Replaced `vref-supply` with `refp-supply` and `refn-supply` to accurately reflect hardware.
- Refactored the driver to dynamically parse channel configurations and routing from DT child nodes.
- Modernized the driver using kernel macros.
- Handled endianness elegantly.
- Added hardware reset fallback logic.
- Inherited IRQ trigger type from device tree instead of hardcoding.
- Fixed a bug where the MUX software cache could desync from hardware if the I2C write failed.
- Added strict return value checking for all I2C writes during probe.
- Updated the `i2c_device_id` array to use C99 named initializers.
- Link to v1: https://lore.kernel.org/r/20260728-ti-ads112c04-driver-v1-0-475efe4e2b78@gmail.com

---
Kyle Hsieh (2):
      dt-bindings: iio: adc: ti,ads112c04: Add binding for ADS112C04
      iio: adc: ti-ads112c04: Add support for TI ADS112C04

 .../devicetree/bindings/iio/adc/ti,ads112c04.yaml  | 146 ++++++
 MAINTAINERS                                        |   7 +
 drivers/iio/adc/Kconfig                            |  10 +
 drivers/iio/adc/Makefile                           |   1 +
 drivers/iio/adc/ti-ads112c04.c                     | 527 +++++++++++++++++++++
 5 files changed, 691 insertions(+)
---
base-commit: 350d1fb9204b13c5f95e511e98b8bcb47574d425
change-id: 20260724-ti-ads112c04-driver-be7e89047834

Best regards,
-- 
Kyle Hsieh <kylehsieh1995@gmail.com>


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

* [PATCH v6 1/2] dt-bindings: iio: adc: ti,ads112c04: Add binding for ADS112C04
  2026-08-20  7:51 [PATCH v6 0/2] iio: adc: Add support for Texas Instruments ADS112C04 Kyle Hsieh
@ 2026-08-20  7:51 ` Kyle Hsieh
  2026-08-20  7:58   ` sashiko-bot
  2026-08-20  7:51 ` [PATCH v6 2/2] iio: adc: ti-ads112c04: Add support for TI ADS112C04 Kyle Hsieh
  2026-08-21  1:25 ` [PATCH v6 0/2] iio: adc: Add support for Texas Instruments ADS112C04 Jonathan Cameron
  2 siblings, 1 reply; 8+ messages in thread
From: Kyle Hsieh @ 2026-08-20  7:51 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Liam Girdwood,
	Mark Brown, Philipp Zabel
  Cc: linux-iio, devicetree, linux-kernel, Kyle Hsieh, Conor Dooley

Add device tree binding documentation for Texas Instruments ADS112C04
I2C Analog-to-Digital Converters.

These devices provide 4-channel, 16-bit delta-sigma ADCs with an I2C
interface, programmable gain amplifier (PGA), and data-ready (DRDY)
interrupt output.

The binding uses child nodes to dynamically define the connected
single-ended or differential channels.

Excitation current, burn-out current, and reference source properties
are also included to fully describe the chip's hardware capabilities,
aligned with the ti,ads112c14 binding conventions.

Reviewed-by: David Lechner <dlechner@baylibre.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Kyle Hsieh <kylehsieh1995@gmail.com>
---
 .../devicetree/bindings/iio/adc/ti,ads112c04.yaml  | 146 +++++++++++++++++++++
 MAINTAINERS                                        |   6 +
 2 files changed, 152 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/adc/ti,ads112c04.yaml b/Documentation/devicetree/bindings/iio/adc/ti,ads112c04.yaml
new file mode 100644
index 000000000000..81b3511139f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/ti,ads112c04.yaml
@@ -0,0 +1,146 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/ti,ads112c04.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments ADS112C04 ADC
+
+maintainers:
+  - Kyle Hsieh <kylehsieh1995@gmail.com>
+
+description:
+  The ADS112C04 (16-bit) are precision analog-to-digital converters (ADCs)
+  with an I2C interface. They feature a flexible input multiplexer, a
+  low-noise programmable gain amplifier (PGA), two programmable excitation
+  current sources, a voltage reference, and a precision temperature sensor.
+
+properties:
+  compatible:
+    enum:
+      - ti,ads112c04
+
+  reg:
+    maxItems: 1
+    description: I2C address of the device.
+
+  interrupts:
+    maxItems: 1
+    description: Data ready (DRDY) interrupt output.
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 0
+
+  reset-gpios:
+    maxItems: 1
+    description: GPIO connected to the RESET pin. Active low.
+
+  avdd-supply: true
+  dvdd-supply: true
+
+  refp-supply: true
+  refn-supply: true
+
+  ti,refp-refn-resistor-ohms:
+    description: Resistance of the external resistor between REFP and REFN.
+
+patternProperties:
+  "^channel@[0-9a-b]$":
+    $ref: adc.yaml
+    unevaluatedProperties: false
+    properties:
+      reg:
+        items:
+          - maximum: 11
+
+      single-channel:
+        maximum: 3
+
+      diff-channels:
+        items:
+          maximum: 3
+
+      excitation-channels:
+        maxItems: 2
+        items:
+          maximum: 5
+        description:
+          Additionally to AIN0-AIN3, IDAC1/IDAC2 can also be routed to
+          REFP0 (4) and REFN0 (5).
+
+      excitation-current-nanoamp:
+        enum: [10000, 50000, 100000, 250000, 500000, 1000000, 1500000]
+
+      burn-out-current-nanoamp:
+        const: 10000
+
+      reference-sources:
+        items:
+          - enum: [internal, external, avdd]
+        default: [ internal ]
+
+    dependencies:
+      excitation-channels: [ excitation-current-nanoamp ]
+      excitation-current-nanoamp: [ excitation-channels ]
+
+    oneOf:
+      - required: [ single-channel ]
+      - required: [ diff-channels ]
+
+required:
+  - compatible
+  - reg
+  - avdd-supply
+  - dvdd-supply
+
+dependencies:
+  refn-supply: [ refp-supply ]
+
+oneOf:
+  - required:
+      - refp-supply
+  - required:
+      - ti,refp-refn-resistor-ohms
+  - properties:
+      refp-supply: false
+      refn-supply: false
+      ti,refp-refn-resistor-ohms: false
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/gpio/gpio.h>
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        adc@40 {
+            compatible = "ti,ads112c04";
+            reg = <0x40>;
+            interrupt-parent = <&gpio>;
+            interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
+
+            reset-gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+            avdd-supply = <&vdd_3v3_reg>;
+            dvdd-supply = <&vdd_3v3_reg>;
+            refp-supply = <&vref_reg>;
+
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            channel@0 {
+                reg = <0>;
+                diff-channels = <0>, <1>;
+            };
+
+            channel@1 {
+                reg = <1>;
+                single-channel = <2>;
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 04fa5322d9f7..417d74b6d6cc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26987,6 +26987,12 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/iio/adc/ti,ads1119.yaml
 F:	drivers/iio/adc/ti-ads1119.c
 
+TI ADS112C04 ADC DRIVER
+M:	Kyle Hsieh <kylehsieh1995@gmail.com>
+L:	linux-iio@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/iio/adc/ti,ads112c04.yaml
+
 TI ADS112C14 ADC DRIVER
 M:	David Lechner <dlechner@baylibre.com>
 L:	linux-iio@vger.kernel.org

-- 
2.34.1


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

* [PATCH v6 2/2] iio: adc: ti-ads112c04: Add support for TI ADS112C04
  2026-08-20  7:51 [PATCH v6 0/2] iio: adc: Add support for Texas Instruments ADS112C04 Kyle Hsieh
  2026-08-20  7:51 ` [PATCH v6 1/2] dt-bindings: iio: adc: ti,ads112c04: Add binding for ADS112C04 Kyle Hsieh
@ 2026-08-20  7:51 ` Kyle Hsieh
  2026-08-20  7:58   ` sashiko-bot
  2026-08-21 10:59   ` Andy Shevchenko
  2026-08-21  1:25 ` [PATCH v6 0/2] iio: adc: Add support for Texas Instruments ADS112C04 Jonathan Cameron
  2 siblings, 2 replies; 8+ messages in thread
From: Kyle Hsieh @ 2026-08-20  7:51 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Liam Girdwood,
	Mark Brown, Philipp Zabel
  Cc: linux-iio, devicetree, linux-kernel, Kyle Hsieh

Add IIO driver support for the Texas Instruments ADS112C04 (16-bit)
delta-sigma ADCs.

The driver implements:
- Single-shot conversions using the IIO raw read interface.
- Dynamic parsing of single-ended and differential channels from
  device tree child nodes.
- Hardware interrupt support via the DRDY pin, falling back to
  software polling if no IRQ is provided.
- Per-channel reference source selection (internal 2.048V, external
  REFP/REFN, or AVDD) via the reference-sources device tree property.
  refn-supply is not yet supported.
- Hardware reset via the reset controller framework, falling back to
  the RESET command when no reset controller is present.

Signed-off-by: Kyle Hsieh <kylehsieh1995@gmail.com>
---
 MAINTAINERS                    |   1 +
 drivers/iio/adc/Kconfig        |  10 +
 drivers/iio/adc/Makefile       |   1 +
 drivers/iio/adc/ti-ads112c04.c | 527 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 539 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 417d74b6d6cc..f51fbda9d4b9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26992,6 +26992,7 @@ M:	Kyle Hsieh <kylehsieh1995@gmail.com>
 L:	linux-iio@vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/iio/adc/ti,ads112c04.yaml
+F:	drivers/iio/adc/ti-ads112c04.c
 
 TI ADS112C14 ADC DRIVER
 M:	David Lechner <dlechner@baylibre.com>
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 990e7b3e7212..037fc7df8415 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -1817,6 +1817,16 @@ config TI_ADS1119
          This driver can also be built as a module. If so, the module will be
          called ti-ads1119.
 
+config TI_ADS112C04
+	tristate "Texas Instruments ADS112C04 ADC"
+	depends on I2C
+	help
+	  If you say yes here you get support for Texas Instruments
+	  ADS112C04 (16-bit) I2C analog to digital converters.
+
+	  This driver can also be built as a module. If so, the module will be
+	  called ti-ads112c04.
+
 config TI_ADS112C14
 	tristate "Texas Instruments ADS112C14/ADS122C14"
 	depends on I2C
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index dcec0abb03b7..d8acf2831fd2 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -155,6 +155,7 @@ obj-$(CONFIG_TI_ADS1015) += ti-ads1015.o
 obj-$(CONFIG_TI_ADS1018) += ti-ads1018.o
 obj-$(CONFIG_TI_ADS1100) += ti-ads1100.o
 obj-$(CONFIG_TI_ADS1119) += ti-ads1119.o
+obj-$(CONFIG_TI_ADS112C04) += ti-ads112c04.o
 obj-$(CONFIG_TI_ADS112C14) += ti-ads112c14.o
 obj-$(CONFIG_TI_ADS124S08) += ti-ads124s08.o
 obj-$(CONFIG_TI_ADS1298) += ti-ads1298.o
diff --git a/drivers/iio/adc/ti-ads112c04.c b/drivers/iio/adc/ti-ads112c04.c
new file mode 100644
index 000000000000..ebd141afe55b
--- /dev/null
+++ b/drivers/iio/adc/ti-ads112c04.c
@@ -0,0 +1,527 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Texas Instruments ADS112C04 16-bit I2C ADC driver
+ *
+ * Copyright (c) 2026 Kyle Hsieh <kylehsieh1995@gmail.com>
+ *
+ * Datasheet: https://www.ti.com/lit/ds/symlink/ads112c04.pdf
+ * Based on TI Reference Code and standard Linux IIO framework.
+ */
+
+#include <linux/array_size.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <linux/types.h>
+#include <linux/units.h>
+
+#include <linux/iio/iio.h>
+
+#define ADS112C04_CMD_RESET		0x06
+#define ADS112C04_CMD_START_SYNC	0x08
+#define ADS112C04_CMD_RDATA		0x10
+#define ADS112C04_CMD_RREG(reg)		(0x20 | ((reg) << 2))
+#define ADS112C04_CMD_WREG(reg)		(0x40 | ((reg) << 2))
+
+#define ADS112C04_REG_CONFIG0			0x00
+#define   ADS112C04_CONF0_MUX			  GENMASK(7, 4)
+#define     ADS112C04_CONF0_MUX_AIN0_AIN1	    0
+#define     ADS112C04_CONF0_MUX_AIN_SINGLE_BASE	    8
+#define   ADS112C04_CONF0_GAIN			  GENMASK(3, 1)
+#define     ADS112C04_CONF0_GAIN_X1		    0
+#define   ADS112C04_CONF0_PGA_BYPASS		  BIT(0)
+
+#define ADS112C04_REG_CONFIG1			0x01
+#define   ADS112C04_CONF1_DR			  GENMASK(7, 5)
+#define     ADS112C04_CONF1_DR_20SPS		    0
+#define   ADS112C04_CONF1_MODE			  BIT(4)
+#define     ADS112C04_CONF1_MODE_NORMAL		    0
+#define   ADS112C04_CONF1_CM			  BIT(3)
+#define     ADS112C04_CONF1_CM_SINGLE_SHOT	    0
+#define   ADS112C04_CONF1_VREF			  GENMASK(2, 1)
+#define     ADS112C04_CONF1_VREF_INTERNAL	    0
+#define     ADS112C04_CONF1_VREF_EXTERNAL	    1
+#define     ADS112C04_CONF1_VREF_AVDD		    2
+#define   ADS112C04_CONF1_TS			  BIT(0)
+#define     ADS112C04_CONF1_TS_DISABLED		    0
+
+#define ADS112C04_REG_CONFIG2			0x02
+#define   ADS112C04_CONF2_DRDY			  BIT(7)
+
+#define ADS112C04_INT_REF_mV			2048
+
+#define ADS112C04_MAX_CHANNELS		12
+
+#define ADS112C04_RESOLUTION_BITS	16
+
+enum {
+	ADS112C04_VREF_SOURCE_INTERNAL,
+	ADS112C04_VREF_SOURCE_EXTERNAL,
+	ADS112C04_VREF_SOURCE_AVDD,
+};
+
+static const char * const ads112c04_vref_names[] = {
+	[ADS112C04_VREF_SOURCE_INTERNAL] = "internal",
+	[ADS112C04_VREF_SOURCE_EXTERNAL] = "external",
+	[ADS112C04_VREF_SOURCE_AVDD]     = "avdd",
+};
+
+static const u8 ads112c04_vref_reg_val[] = {
+	[ADS112C04_VREF_SOURCE_INTERNAL] = ADS112C04_CONF1_VREF_INTERNAL,
+	[ADS112C04_VREF_SOURCE_EXTERNAL] = ADS112C04_CONF1_VREF_EXTERNAL,
+	[ADS112C04_VREF_SOURCE_AVDD]     = ADS112C04_CONF1_VREF_AVDD,
+};
+
+/* Indexed by [AINP][AINN], -1 means the combination is not available. */
+static const s8 ads112c04_diff_mux[4][4] = {
+	{ -1,  0,  1,  2 },
+	{  3, -1,  4,  5 },
+	{ -1, -1, -1,  6 },
+	{ -1, -1,  7, -1 },
+};
+
+struct ads112c04_state {
+	struct i2c_client *client;
+	/* Protects concurrent ADC reads and device configuration */
+	struct mutex lock;
+	struct completion completion;
+	u32 avdd_mV;
+	u32 ext_ref_mV;
+	u8 *vref_source;	/* one entry per channel, indexed by scan order */
+	u8 config0;
+	u8 config1;
+};
+
+static int ads112c04_write_cmd(struct i2c_client *client, u8 cmd)
+{
+	return i2c_smbus_write_byte(client, cmd);
+}
+
+static int ads112c04_read_reg(struct i2c_client *client, u8 reg, u8 *val)
+{
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(client, ADS112C04_CMD_RREG(reg));
+	if (ret < 0)
+		return ret;
+
+	*val = ret;
+
+	return 0;
+}
+
+static int ads112c04_write_reg(struct i2c_client *client, u8 reg, u8 val)
+{
+	return i2c_smbus_write_byte_data(client, ADS112C04_CMD_WREG(reg), val);
+}
+
+static int ads112c04_wait_for_data(struct ads112c04_state *st)
+{
+	int ret, err;
+	u8 val;
+
+	if (st->client->irq > 0) {
+		/* Timeout is 100ms (slowest data rate is 20 SPS) */
+		if (!wait_for_completion_timeout(&st->completion, msecs_to_jiffies(100)))
+			return -ETIMEDOUT;
+
+		return 0;
+	}
+
+	ret = read_poll_timeout(ads112c04_read_reg, err,
+				err < 0 || (val & ADS112C04_CONF2_DRDY),
+				1 * USEC_PER_MSEC, 100 * USEC_PER_MSEC, false,
+				st->client, ADS112C04_REG_CONFIG2, &val);
+	if (err < 0)
+		return err;
+
+	return ret;
+}
+
+static int ads112c04_read_data(struct ads112c04_state *st, int *val)
+{
+	int ret;
+
+	ret = i2c_smbus_read_word_swapped(st->client, ADS112C04_CMD_RDATA);
+	if (ret < 0)
+		return ret;
+
+	*val = sign_extend32(ret, ADS112C04_RESOLUTION_BITS - 1);
+
+	return 0;
+}
+
+static int ads112c04_get_adc_result(struct iio_dev *indio_dev,
+				    struct iio_chan_spec const *chan,
+				    int *val)
+{
+	struct ads112c04_state *st = iio_priv(indio_dev);
+	unsigned int idx = chan - indio_dev->channels;
+	u8 new_config0, new_config1;
+	int ret;
+
+	new_config0 = st->config0;
+	FIELD_MODIFY(ADS112C04_CONF0_MUX, &new_config0, chan->address);
+
+	if (st->config0 != new_config0) {
+		ret = ads112c04_write_reg(st->client, ADS112C04_REG_CONFIG0,
+					  new_config0);
+		if (ret < 0)
+			return ret;
+
+		st->config0 = new_config0;
+	}
+
+	new_config1 = st->config1;
+	FIELD_MODIFY(ADS112C04_CONF1_VREF, &new_config1,
+		     ads112c04_vref_reg_val[st->vref_source[idx]]);
+
+	if (st->config1 != new_config1) {
+		ret = ads112c04_write_reg(st->client, ADS112C04_REG_CONFIG1,
+					  new_config1);
+		if (ret < 0)
+			return ret;
+
+		st->config1 = new_config1;
+	}
+
+	reinit_completion(&st->completion);
+
+	ret = ads112c04_write_cmd(st->client, ADS112C04_CMD_START_SYNC);
+	if (ret < 0)
+		return ret;
+
+	ret = ads112c04_wait_for_data(st);
+	if (ret < 0)
+		return ret;
+
+	return ads112c04_read_data(st, val);
+}
+
+static int ads112c04_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2, long mask)
+{
+	struct ads112c04_state *st = iio_priv(indio_dev);
+	unsigned int idx = chan - indio_dev->channels;
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		mutex_lock(&st->lock);
+		ret = ads112c04_get_adc_result(indio_dev, chan, val);
+		mutex_unlock(&st->lock);
+
+		if (ret < 0)
+			return ret;
+		return IIO_VAL_INT;
+
+	case IIO_CHAN_INFO_SCALE:
+		switch (st->vref_source[idx]) {
+		case ADS112C04_VREF_SOURCE_EXTERNAL:
+			*val = st->ext_ref_mV;
+			break;
+		case ADS112C04_VREF_SOURCE_AVDD:
+			*val = st->avdd_mV;
+			break;
+		default:
+			*val = ADS112C04_INT_REF_mV;
+			break;
+		}
+		*val2 = ADS112C04_RESOLUTION_BITS - 1;
+		return IIO_VAL_FRACTIONAL_LOG2;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static irqreturn_t ads112c04_irq_handler(int irq, void *private)
+{
+	struct iio_dev *indio_dev = private;
+	struct ads112c04_state *st = iio_priv(indio_dev);
+
+	complete(&st->completion);
+
+	return IRQ_HANDLED;
+}
+
+static const struct iio_info ads112c04_info = {
+	.read_raw = ads112c04_read_raw,
+};
+
+static int ads112c04_parse_vref_source(struct fwnode_handle *child)
+{
+	if (!fwnode_property_present(child, "reference-sources"))
+		return ADS112C04_VREF_SOURCE_INTERNAL;
+
+	return fwnode_property_match_property_string(child, "reference-sources",
+						    ads112c04_vref_names,
+						    ARRAY_SIZE(ads112c04_vref_names));
+}
+
+static int ads112c04_parse_channels(struct iio_dev *indio_dev,
+				    bool *need_avdd_ref, bool *need_ext_ref)
+{
+	struct device *dev = indio_dev->dev.parent;
+	struct ads112c04_state *st = iio_priv(indio_dev);
+	struct iio_chan_spec *channels;
+	u32 num_channels, pair[2], channel;
+	unsigned int i;
+	int ret;
+
+	num_channels = device_get_named_child_node_count(dev, "channel");
+	if (!num_channels)
+		return dev_err_probe(dev, -EINVAL, "no channel subnodes found\n");
+
+	if (num_channels > ADS112C04_MAX_CHANNELS)
+		return dev_err_probe(dev, -EINVAL,
+				     "num of channel nodes exceeds %d\n",
+				     ADS112C04_MAX_CHANNELS);
+
+	channels = devm_kcalloc(dev, num_channels, sizeof(*channels), GFP_KERNEL);
+	if (!channels)
+		return -ENOMEM;
+
+	st->vref_source = devm_kcalloc(dev, num_channels,
+				       sizeof(*st->vref_source), GFP_KERNEL);
+	if (!st->vref_source)
+		return -ENOMEM;
+
+	i = 0;
+	device_for_each_named_child_node_scoped(dev, child, "channel") {
+		const char *sp = "single-channel", *dp = "diff-channels";
+		struct iio_chan_spec *spec = &channels[i];
+
+		if (fwnode_property_present(child, "excitation-channels"))
+			return dev_err_probe(dev, -EOPNOTSUPP,
+					     "excitation-channels is not supported yet\n");
+
+		st->vref_source[i] = ADS112C04_VREF_SOURCE_INTERNAL;
+
+		if (fwnode_property_present(child, "reference-sources")) {
+			ret = ads112c04_parse_vref_source(child);
+			if (ret < 0)
+				return dev_err_probe(dev, ret,
+						     "invalid reference-sources value\n");
+
+			st->vref_source[i] = ret;
+		}
+
+		if (st->vref_source[i] == ADS112C04_VREF_SOURCE_EXTERNAL)
+			*need_ext_ref = true;
+		if (st->vref_source[i] == ADS112C04_VREF_SOURCE_AVDD)
+			*need_avdd_ref = true;
+
+		/*
+		 * REVISIT: when ti,refp-refn-resistor-ohms is implemented, a
+		 * channel using an external resistor reference is effectively
+		 * a resistance measurement and should use IIO_RESISTANCE.
+		 */
+		spec->type = IIO_VOLTAGE;
+		spec->indexed = 1;
+		spec->info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE);
+
+		if (fwnode_property_present(child, sp)) {
+			ret = fwnode_property_read_u32(child, sp, &channel);
+			if (ret)
+				return dev_err_probe(dev, ret, "failed to read %s property\n", sp);
+
+			if (channel > 3)
+				return dev_err_probe(dev, -EINVAL, "%s must be 0-3\n", sp);
+
+			spec->channel = channel;
+			spec->address = ADS112C04_CONF0_MUX_AIN_SINGLE_BASE + channel;
+		} else if (fwnode_property_present(child, dp)) {
+			ret = fwnode_property_read_u32_array(child, dp, pair, ARRAY_SIZE(pair));
+			if (ret)
+				return dev_err_probe(dev, ret, "failed to read %s property\n", dp);
+
+			if (pair[0] > 3 || pair[1] > 3)
+				return dev_err_probe(dev, -EINVAL, "%s must be 0-3\n", dp);
+
+			spec->channel = pair[0];
+			spec->channel2 = pair[1];
+			spec->differential = 1;
+
+			if (ads112c04_diff_mux[pair[0]][pair[1]] < 0)
+				return dev_err_probe(dev, -EINVAL, "invalid %s combination\n", dp);
+
+			spec->address = ads112c04_diff_mux[pair[0]][pair[1]];
+		} else {
+			return dev_err_probe(dev, -EINVAL,
+					     "channel node must have %s or %s\n", sp, dp);
+		}
+
+		i++;
+	}
+
+	indio_dev->channels = channels;
+	indio_dev->num_channels = i;
+
+	return 0;
+}
+
+static int ads112c04_probe(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+	struct iio_dev *indio_dev;
+	struct ads112c04_state *st;
+	struct reset_control *reset;
+	bool need_avdd_ref = false, need_ext_ref = false;
+	int ret;
+
+	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	st = iio_priv(indio_dev);
+	st->client = client;
+
+	ret = devm_mutex_init(dev, &st->lock);
+	if (ret)
+		return ret;
+
+	init_completion(&st->completion);
+
+	indio_dev->name = "ads112c04";
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->info = &ads112c04_info;
+
+	/* Forward compatibility checks for unimplemented DT properties */
+	if (device_property_present(dev, "refn-supply") ||
+	    device_property_present(dev, "ti,refp-refn-resistor-ohms"))
+		return dev_err_probe(dev, -EOPNOTSUPP,
+				     "refn-supply and external resistors are not supported yet\n");
+
+	ret = ads112c04_parse_channels(indio_dev, &need_avdd_ref, &need_ext_ref);
+	if (ret)
+		return ret;
+
+	if (need_avdd_ref) {
+		ret = devm_regulator_get_enable_read_voltage(dev, "avdd");
+		if (ret < 0)
+			return dev_err_probe(dev, ret, "failed to get avdd voltage\n");
+
+		st->avdd_mV = ret / (MICRO / MILLI);
+	} else {
+		ret = devm_regulator_get_enable(dev, "avdd");
+		if (ret)
+			return dev_err_probe(dev, ret, "failed to get avdd regulator\n");
+	}
+
+	ret = devm_regulator_get_enable(dev, "dvdd");
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to get dvdd regulator\n");
+
+	if (device_property_present(dev, "refp-supply")) {
+		ret = devm_regulator_get_enable_read_voltage(dev, "refp");
+		if (ret < 0)
+			return dev_err_probe(dev, ret, "failed to get refp voltage\n");
+
+		st->ext_ref_mV = ret / (MICRO / MILLI);
+	}
+
+	if (need_ext_ref && !st->ext_ref_mV)
+		return dev_err_probe(dev, -EINVAL,
+				     "external reference measurements require refp-supply\n");
+
+	/* Datasheet: POR releases ~500us after supplies are stable */
+	fsleep(500);
+
+	reset = devm_reset_control_get_optional_exclusive(dev, NULL);
+	if (IS_ERR(reset))
+		return dev_err_probe(dev, PTR_ERR(reset), "failed to get reset\n");
+
+	if (reset) {
+		ret = reset_control_reset(reset);
+		if (ret)
+			return dev_err_probe(dev, ret, "failed to reset device\n");
+	} else {
+		ret = ads112c04_write_cmd(client, ADS112C04_CMD_RESET);
+		if (ret < 0)
+			return ret;
+	}
+
+	/*
+	 * Datasheet: td(RSSTA), the delay from the RESET rising edge to the
+	 * first I2C START, is 100ns minimum.
+	 */
+	fsleep(1 * USEC_PER_MSEC);
+
+	/*
+	 * Initialize CONFIG0 with all fields explicit: gain of 1 with the PGA
+	 * bypassed, which allows full-scale single-ended measurements. The MUX
+	 * field is updated per channel before each conversion.
+	 */
+	st->config0 = FIELD_PREP(ADS112C04_CONF0_MUX,
+				 ADS112C04_CONF0_MUX_AIN0_AIN1) |
+		      FIELD_PREP(ADS112C04_CONF0_GAIN,
+				 ADS112C04_CONF0_GAIN_X1) |
+		      ADS112C04_CONF0_PGA_BYPASS;
+
+	ret = ads112c04_write_reg(client, ADS112C04_REG_CONFIG0, st->config0);
+	if (ret)
+		return ret;
+
+	st->config1 = FIELD_PREP(ADS112C04_CONF1_DR,
+				 ADS112C04_CONF1_DR_20SPS) |
+		      FIELD_PREP(ADS112C04_CONF1_MODE,
+				 ADS112C04_CONF1_MODE_NORMAL) |
+		      FIELD_PREP(ADS112C04_CONF1_CM,
+				 ADS112C04_CONF1_CM_SINGLE_SHOT) |
+		      FIELD_PREP(ADS112C04_CONF1_VREF,
+				 ADS112C04_CONF1_VREF_INTERNAL) |
+		      FIELD_PREP(ADS112C04_CONF1_TS,
+				 ADS112C04_CONF1_TS_DISABLED);
+
+	ret = ads112c04_write_reg(client, ADS112C04_REG_CONFIG1, st->config1);
+	if (ret)
+		return ret;
+
+	if (client->irq > 0) {
+		ret = devm_request_irq(dev, client->irq, ads112c04_irq_handler, 0,
+				       indio_dev->name, indio_dev);
+		if (ret)
+			return ret;
+	}
+
+	return devm_iio_device_register(dev, indio_dev);
+}
+
+static const struct i2c_device_id ads112c04_id[] = {
+	{ .name = "ads112c04" },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ads112c04_id);
+
+static const struct of_device_id ads112c04_of_match[] = {
+	{ .compatible = "ti,ads112c04" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ads112c04_of_match);
+
+static struct i2c_driver ads112c04_driver = {
+	.driver = {
+		.name = "ads112c04",
+		.of_match_table = ads112c04_of_match,
+	},
+	.probe = ads112c04_probe,
+	.id_table = ads112c04_id,
+};
+module_i2c_driver(ads112c04_driver);
+
+MODULE_AUTHOR("Kyle Hsieh <kylehsieh1995@gmail.com>");
+MODULE_DESCRIPTION("Texas Instruments ADS112C04 ADC driver");
+MODULE_LICENSE("GPL");

-- 
2.34.1


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

* Re: [PATCH v6 2/2] iio: adc: ti-ads112c04: Add support for TI ADS112C04
  2026-08-20  7:51 ` [PATCH v6 2/2] iio: adc: ti-ads112c04: Add support for TI ADS112C04 Kyle Hsieh
@ 2026-08-20  7:58   ` sashiko-bot
  2026-08-21 10:59   ` Andy Shevchenko
  1 sibling, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-08-20  7:58 UTC (permalink / raw)
  To: Kyle Hsieh; +Cc: conor+dt, devicetree, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Interrupt storm (hard lockup) if DRDY is configured as level-triggered.
--

--- Patch [2]: [PATCH v6 2/2] iio: adc: ti-ads112c04: Add support for TI ADS112C04 ---
commit 88f1a4a634251e87a5f5b33f385ea979bcaa7f17
Author: Kyle Hsieh <kylehsieh1995@gmail.com>

iio: adc: ti-ads112c04: Add support for TI ADS112C04

Add IIO driver support for the Texas Instruments ADS112C04 (16-bit)
delta-sigma ADCs. The driver implements single-shot conversions, dynamic
parsing of channels, hardware interrupts via the DRDY pin, and per-channel
reference source selection.

> diff --git a/drivers/iio/adc/ti-ads112c04.c b/drivers/iio/adc/ti-ads112c04.c
> new file mode 100644
> --- /dev/null
> +++ b/drivers/iio/adc/ti-ads112c04.c
[ ... ]
> +static irqreturn_t ads112c04_irq_handler(int irq, void *private)
> +{
> +	struct iio_dev *indio_dev = private;
> +	struct ads112c04_state *st = iio_priv(indio_dev);
> +
> +	complete(&st->completion);
> +
> +	return IRQ_HANDLED;
> +}
[ ... ]
> +static int ads112c04_probe(struct i2c_client *client)
> +{
[ ... ]
> +	if (client->irq > 0) {
> +		ret = devm_request_irq(dev, client->irq, ads112c04_irq_handler, 0,
> +				       indio_dev->name, indio_dev);

[Severity: High]
Since the hardware DRDY pin stays low until data is read, could an interrupt
storm occur here if the device tree configures the interrupt as
level-triggered?

By passing 0 for the irqflags, the driver accepts the device tree's default
trigger type. If it is set to a level trigger, ads112c04_irq_handler() will
fire, call complete(), and return IRQ_HANDLED without doing any I2C reads to
clear the device-side interrupt.

Because the interrupt source isn't cleared, the interrupt controller will
immediately re-trigger the hardirq. Won't this create an infinite loop that
starves the process context, preventing ads112c04_read_data() from ever
executing to clear the condition?

Should this request enforce an edge trigger, or use a threaded interrupt
handler with IRQF_ONESHOT so the interrupt is masked until the data is read?

> +		if (ret)
> +			return ret;
> +	}
> +
> +	return devm_iio_device_register(dev, indio_dev);
> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260820-ti-ads112c04-driver-v6-0-0e8f0aacce9b@gmail.com?part=2

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

* Re: [PATCH v6 1/2] dt-bindings: iio: adc: ti,ads112c04: Add binding for ADS112C04
  2026-08-20  7:51 ` [PATCH v6 1/2] dt-bindings: iio: adc: ti,ads112c04: Add binding for ADS112C04 Kyle Hsieh
@ 2026-08-20  7:58   ` sashiko-bot
  0 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-08-20  7:58 UTC (permalink / raw)
  To: Kyle Hsieh; +Cc: devicetree, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The `excitation-current-nanoamp` property incorrectly uses a scalar `enum` constraint instead of an `items` list, preventing the valid use of multiple excitation channels in the device tree.
--

--- Patch [1]: [PATCH v6 1/2] dt-bindings: iio: adc: ti,ads112c04: Add binding for ADS112C04 ---
commit ad41025959acbdcfe32933f6e12d580d2924bc04
Author: Kyle Hsieh <kylehsieh1995@gmail.com>

dt-bindings: iio: adc: ti,ads112c04: Add binding for ADS112C04

This commit adds device tree binding documentation for Texas Instruments
ADS112C04 I2C Analog-to-Digital Converters. It outlines the hardware
capabilities including the flexible input multiplexer, programmable gain
amplifier, and programmable excitation current sources.

> diff --git a/Documentation/devicetree/bindings/iio/adc/ti,ads112c04.yaml b/Documentation/devicetree/bindings/iio/adc/ti,ads112c04.yaml
> new file mode 100644
> index 0000000000000..81b3511139f3c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/adc/ti,ads112c04.yaml

[ ... ]

> +      excitation-channels:
> +        maxItems: 2
> +        items:
> +          maximum: 5
> +        description:
> +          Additionally to AIN0-AIN3, IDAC1/IDAC2 can also be routed to
> +          REFP0 (4) and REFN0 (5).
> +
> +      excitation-current-nanoamp:
> +        enum: [10000, 50000, 100000, 250000, 500000, 1000000, 1500000]

[Severity: Low]
Does this restrict the property to a single scalar value? 

Since excitation-channels allows up to two items, wouldn't
excitation-current-nanoamp also need to allow an array (for example, by
using maxItems: 2 and placing the enum inside an items constraint) so that
configurations defining two excitation currents can pass schema validation?

> +
> +      burn-out-current-nanoamp:
> +        const: 10000

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260820-ti-ads112c04-driver-v6-0-0e8f0aacce9b@gmail.com?part=1

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

* Re: [PATCH v6 0/2] iio: adc: Add support for Texas Instruments ADS112C04
  2026-08-20  7:51 [PATCH v6 0/2] iio: adc: Add support for Texas Instruments ADS112C04 Kyle Hsieh
  2026-08-20  7:51 ` [PATCH v6 1/2] dt-bindings: iio: adc: ti,ads112c04: Add binding for ADS112C04 Kyle Hsieh
  2026-08-20  7:51 ` [PATCH v6 2/2] iio: adc: ti-ads112c04: Add support for TI ADS112C04 Kyle Hsieh
@ 2026-08-21  1:25 ` Jonathan Cameron
  2026-08-21  3:37   ` Kyle Hsieh
  2 siblings, 1 reply; 8+ messages in thread
From: Jonathan Cameron @ 2026-08-21  1:25 UTC (permalink / raw)
  To: Kyle Hsieh
  Cc: David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Liam Girdwood, Mark Brown,
	Philipp Zabel, linux-iio, devicetree, linux-kernel, Conor Dooley

On Thu, 20 Aug 2026 15:51:50 +0800
Kyle Hsieh <kylehsieh1995@gmail.com> wrote:

> This patch series introduces support for the Texas Instruments ADS112C04
> Analog-to-Digital Converters.
> 
> The ADS112C04 (16-bit) is precision, low-power, delta-sigma ADCs with
> an I2C interface. They feature a flexible input multiplexer supporting
> single-ended and differential measurements, a programmable gain amplifier,
> and an internal voltage reference.
> 
> Note: While this chip shares similarities with the ADS112C14 (currently 
> being upstreamed by David Lechner), the register maps and feature sets 
> are sufficiently different to warrant a separate driver. However, the
> DT bindings and channel parsing logic have been aligned with the
> ADS112C14 conventions.
> 
> This initial submission provides a minimal feature set (single-shot 
> conversions and basic DRDY interrupt) covering current use cases.
> 
> Signed-off-by: Kyle Hsieh <kylehsieh1995@gmail.com>

Sashiko had some feedback on the interrupt - if you are respinning for
other reasons it might be good to add a comment in the dt-binding about
it being an edge interrupt. From a quick look at the datasheet a level
interrupt would not make much sense.

https://sashiko.dev/#/patchset/20260820-ti-ads112c04-driver-v6-0-0e8f0aacce9b%40gmail.com

Other than that, looks good to me.  You've had a lot of review from
others though so I'll leave it on list for a little while in case
any one wants to take a final look and perhaps give tags.

Thanks,

Jonathan

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

* Re: [PATCH v6 0/2] iio: adc: Add support for Texas Instruments ADS112C04
  2026-08-21  1:25 ` [PATCH v6 0/2] iio: adc: Add support for Texas Instruments ADS112C04 Jonathan Cameron
@ 2026-08-21  3:37   ` Kyle Hsieh
  0 siblings, 0 replies; 8+ messages in thread
From: Kyle Hsieh @ 2026-08-21  3:37 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Liam Girdwood, Mark Brown,
	Philipp Zabel, linux-iio, devicetree, linux-kernel, Conor Dooley

On Fri, Aug 21, 2026 at 9:25 AM Jonathan Cameron <jic23@kernel.org> wrote:
>
> On Thu, 20 Aug 2026 15:51:50 +0800
> Kyle Hsieh <kylehsieh1995@gmail.com> wrote:
>
> > This patch series introduces support for the Texas Instruments ADS112C04
> > Analog-to-Digital Converters.
> >
> > The ADS112C04 (16-bit) is precision, low-power, delta-sigma ADCs with
> > an I2C interface. They feature a flexible input multiplexer supporting
> > single-ended and differential measurements, a programmable gain amplifier,
> > and an internal voltage reference.
> >
> > Note: While this chip shares similarities with the ADS112C14 (currently
> > being upstreamed by David Lechner), the register maps and feature sets
> > are sufficiently different to warrant a separate driver. However, the
> > DT bindings and channel parsing logic have been aligned with the
> > ADS112C14 conventions.
> >
> > This initial submission provides a minimal feature set (single-shot
> > conversions and basic DRDY interrupt) covering current use cases.
> >
> > Signed-off-by: Kyle Hsieh <kylehsieh1995@gmail.com>
>
> Sashiko had some feedback on the interrupt - if you are respinning for
> other reasons it might be good to add a comment in the dt-binding about
> it being an edge interrupt. From a quick look at the datasheet a level
> interrupt would not make much sense.
>
Makes sense. Since DRDY is a pulse, an edge trigger is indeed the right
choice. I'll add the note to the binding if I respin, or send it as a
follow-up patch.

Thanks for the review.

Kyle Hsieh

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

* Re: [PATCH v6 2/2] iio: adc: ti-ads112c04: Add support for TI ADS112C04
  2026-08-20  7:51 ` [PATCH v6 2/2] iio: adc: ti-ads112c04: Add support for TI ADS112C04 Kyle Hsieh
  2026-08-20  7:58   ` sashiko-bot
@ 2026-08-21 10:59   ` Andy Shevchenko
  1 sibling, 0 replies; 8+ messages in thread
From: Andy Shevchenko @ 2026-08-21 10:59 UTC (permalink / raw)
  To: Kyle Hsieh
  Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Liam Girdwood,
	Mark Brown, Philipp Zabel, linux-iio, devicetree, linux-kernel

On Thu, Aug 20, 2026 at 03:51:52PM +0800, Kyle Hsieh wrote:
> Add IIO driver support for the Texas Instruments ADS112C04 (16-bit)
> delta-sigma ADCs.
> 
> The driver implements:
> - Single-shot conversions using the IIO raw read interface.
> - Dynamic parsing of single-ended and differential channels from
>   device tree child nodes.
> - Hardware interrupt support via the DRDY pin, falling back to
>   software polling if no IRQ is provided.
> - Per-channel reference source selection (internal 2.048V, external
>   REFP/REFN, or AVDD) via the reference-sources device tree property.
>   refn-supply is not yet supported.
> - Hardware reset via the reset controller framework, falling back to
>   the RESET command when no reset controller is present.

LGTM now,
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>

...

> +	/*
> +	 * Datasheet: td(RSSTA), the delay from the RESET rising edge to the
> +	 * first I2C START, is 100ns minimum.

This is order of magnitude delay. Do you mean 100 µs? (Actually would be good to
use Greek letter in the units, looks much cleaner in the comments.)

> +	 */
> +	fsleep(1 * USEC_PER_MSEC);

Otherwise this should be simply 1 (no multiplier).

-- 
With Best Regards,
Andy Shevchenko



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

end of thread, other threads:[~2026-08-21 10:59 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-20  7:51 [PATCH v6 0/2] iio: adc: Add support for Texas Instruments ADS112C04 Kyle Hsieh
2026-08-20  7:51 ` [PATCH v6 1/2] dt-bindings: iio: adc: ti,ads112c04: Add binding for ADS112C04 Kyle Hsieh
2026-08-20  7:58   ` sashiko-bot
2026-08-20  7:51 ` [PATCH v6 2/2] iio: adc: ti-ads112c04: Add support for TI ADS112C04 Kyle Hsieh
2026-08-20  7:58   ` sashiko-bot
2026-08-21 10:59   ` Andy Shevchenko
2026-08-21  1:25 ` [PATCH v6 0/2] iio: adc: Add support for Texas Instruments ADS112C04 Jonathan Cameron
2026-08-21  3:37   ` Kyle Hsieh

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