[PATCH v3 0/9] iio: adc: Add TI ADS126X ADC family support

Kurt Borja posted 9 patches 1 month, 3 weeks ago
There is a newer version of this series
.../devicetree/bindings/iio/adc/ti,ads1262.yaml    |  379 ++++
MAINTAINERS                                        |    7 +
drivers/iio/adc/Kconfig                            |   14 +
drivers/iio/adc/Makefile                           |    1 +
drivers/iio/adc/ti-ads1262.c                       | 1890 ++++++++++++++++++++
5 files changed, 2291 insertions(+)
[PATCH v3 0/9] iio: adc: Add TI ADS126X ADC family support
Posted by Kurt Borja 1 month, 3 weeks ago
Hi all,

This series introduces support for TI ADS1262 and ADS1263 ADCs [1].
These devices are very similar (if not the same), except ADS1263
includes a secondary auxiliary ADC.

I plan to add these features to the main driver soon:

  - Filters
  - Calibration (manual and automatic)
  - GPIO controller capabilities
  - Channel hot-reloading in buffer mode
  - SPI offload support (38400 SPS turns out to be too high for some
    systems)
  - Conversion delay support
  - Full support for monitor channels
  - The ti-ads1263-adc2 driver for ADC2

The auxiliary ADC operates almost completely independent of the main
ADC. The only consideration that has to be taken for interoperability is
when reading conversion data in direct mode (Datasheet 9.4.7.1), which
happens only in buffer mode, when multiple channels are enabled.

When reading data in direct mode, all SPI activity is forbidden between
the data-ready signal and the data retrieval. To achieve this a second
mutex called xfer_lock was introduced to block SPI activity on the
device.

This is one of the biggest drivers I've developed, so I hope the code
and the comments are self-explanatory. If not, please let me know so I
can clarify them.

As always, thanks for your reviews and help. Submitting upstream is
always a great learning experience :)

[1] https://www.ti.com/lit/ds/symlink/ads1263.pdf

Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
v3:
  dt-bindings
  -----------

  - Add interrupt-names property to support the dout/drdy DRDY pin

  - Model vbias and refout as regulator providers under a "regulators"
    node

  - Removed ref{p,n}-supply in favor of refp[1-3]-supply and
    refn[1-3]-supply, to match physical reference source pins.

  - Add ti,refp[1-3]-refn[1-3]-resistor-ohms for boards where the
    external reference is obtained from a resistor instead of being
    driven by a supply

  - Support single-channel and common-mode-channel

  - Add common-mode-[N]-supply properties for pseudo-differential
    inputs whose negative pin is tied to something other than ground

  - Allow excitation-* arrays to have only one item

  - Drop the "no connection" value from excitation-channels and the 0
    value from excitation-current-nanoamp, both are expressed by
    omitting the property or shortening the array

  - Restrict diff-channels to 0-14: drop the "Float" entry.

  - Add ti,reference-reversal

  - Renamed ti,idac-chopping -> ti,idac-rotation to match datasheet

  - Add avss-supply (negative analog supply) because it can actually be
    below ground (min -2.5 V; max 0 V).

  ti-ads1262
  ----------

  - Split the v2 driver into several commits to aliviate review burden

  - Conversion delay postponed to a later series

  - Filter selection postponed to a later series

  - Clock now allows the full frequency range. Worst case timing
    requirements are now calculated taking the worst case clock rate.

  - RESET signal now prefers GPIO if available

  - Move xfer_lock outside regmap calls

  - Use match_string() instead of ads1262_find_string()

  - Add hardware reset to ads1262_dev_reset()

  - ads1262_wait_for_conversion() now propagates errors

  - Support external reference resistors. Channels referenced that way
    are exposed as IIO_RESISTANCE.

  - Drop HARDWAREGAIN in favor of per channel _scale_available with the
    new IIO_VAL_DECIMAL64_PICO

  - Now the probe fails if there is no 'drdy' IRQ (doesn't mean it's now
    required in devicetree though). Support for no IRQ can be added if
    needed.

  - Style changes suggested by Jonathan and David.

  IMPORTANT:

  - Rework regulator parsing: now per-channel voltage reference is
    allowed and users may configure a reference resistor instead of
    supply.

    Additionally, I added support for bipolar analog supplies
    (AVSS < 0V). This configuration is important because it allows true
    bipolar measurements, but comes with a lot of problems because
    reference can also have voltage levels below ground and most
    importantly the regulator subsystem doesn't support negative
    voltages. The approach taken to solve this issue was the same as the
    ad4170-4 driver.

    More info in commit message and code comments.

  - @David: I added support for the monitor channels, but I prefer to
    parse them from DT instead of making them static (similar to the
    ad4170-4 approach too :p).

  - @David: About filters... As I mentioned in the previous version, the
    data_rate configuration takes precedence over the filter selection.
    If an incompatible filter (given a data rate) is selected, the chip
    resorts to a sane compatible one when doing conversions (either
    SINC1 or plain SINC5).

    Now, I don't know how to expose this in userspace. Should I limit
    the sampling_frequency_available attribute (given a filter)? Or
    should it be the other way around, limit the filter_type_available
    attribute (given a data rate)?.

  ti-ads1263-adc2
  ---------------

  - Postponed to a separate series to aliviate review burden.

v2: https://patch.msgid.link/20260628-ads126x-v2-0-4b1b231325ba@gmail.com

v1: https://patch.msgid.link/20260612-ads126x-v1-0-894c788d03ed@gmail.com

---
Kurt Borja (9):
      dt-bindings: iio: adc: support the TI ADS126x ADC family
      iio: adc: add the ti-ads1262 driver
      iio: adc: ti-ads1262: support per-channel sampling frequency
      iio: adc: ti-ads1262: support per-channel reference and gain
      iio: adc: ti-ads1262: support input chopping
      iio: adc: ti-ads1262: support excitation currents
      iio: adc: ti-ads1262: support triggered buffer sampling
      iio: adc: ti-ads1262: support REFOUT and VBIAS regulators
      iio: adc: ti-ads1262: support common mode supplies

 .../devicetree/bindings/iio/adc/ti,ads1262.yaml    |  379 ++++
 MAINTAINERS                                        |    7 +
 drivers/iio/adc/Kconfig                            |   14 +
 drivers/iio/adc/Makefile                           |    1 +
 drivers/iio/adc/ti-ads1262.c                       | 1890 ++++++++++++++++++++
 5 files changed, 2291 insertions(+)
---
base-commit: 350d1fb9204b13c5f95e511e98b8bcb47574d425
change-id: 20251129-ads126x-fb6107505cae

-- 
Thanks, 
 ~ Kurt
Re: [PATCH v3 0/9] iio: adc: Add TI ADS126X ADC family support
Posted by David Lechner 1 month, 3 weeks ago
On 8/7/26 10:58 PM, Kurt Borja wrote:

...

>   - @David: I added support for the monitor channels, but I prefer to
>     parse them from DT instead of making them static (similar to the
>     ad4170-4 approach too :p).

Why? Unless there really is some property that depends on how the
system is wired up, it seems like this is just making unnecessary
work for users to be able to use the monitor channels. And if someone
decided later that they do in fact want to use the monitoring channel
and it wasn't in the devicetree, sometimes it can be very difficult
to actually change the devicetree.

The monitor inputs also have many restrictions compared to a
normal input that it would be really hard to describe correctly
in the bindings without allowing things that should not actually
be allowed. (can't have excitation current or burnout, temperature
channel requires internal reference, most should be single-channel,
etc.)

> 
>   - @David: About filters... As I mentioned in the previous version, the
>     data_rate configuration takes precedence over the filter selection.
>     If an incompatible filter (given a data rate) is selected, the chip
>     resorts to a sane compatible one when doing conversions (either
>     SINC1 or plain SINC5).
> 
>     Now, I don't know how to expose this in userspace. Should I limit
>     the sampling_frequency_available attribute (given a filter)? Or
>     should it be the other way around, limit the filter_type_available
>     attribute (given a data rate)?.
 I figured that the filter type selection would be more important than
the rate so when I implemented it for ADS112C14, I made it so that
one has to pick the filter first and everything else flows from that.
(I didn't expose sampling frequency until the same time as filter type.)

The thinking behind this is that if you do care about filtering, then
you are picking filter type and sampling rate to get certain notches
and/or frequency response of the filter rather than trying to get a
faster or slower sample rate.

And the driver also allows using an hrtimer trigger to do single-shot
samples for cases where one doesn't want to sample as fast as possible
in continuous mode. This would be more useful to someone who just cares
about sample rate and not about filtering.

Just posted the series yesterday:
https://lore.kernel.org/linux-iio/20260807-iio-adc-ti-ads112c14-filter-support-v1-0-4d3ba00caf18@baylibre.com/T/#t

ADS126X seems a little less complicated in this regard though
as the same sampling rates are available for all filters with
the exception of the FIR filter having a limited subset. So I
would go with the option to limit sampling rate based on filter
type, not the other way around. If a higher rate is selected
when changing to the FIR filter type, just have it go to the
max (20 SPS).
Re: [PATCH v3 0/9] iio: adc: Add TI ADS126X ADC family support
Posted by Kurt Borja 1 month, 3 weeks ago
On Sat Aug 8, 2026 at 1:37 PM -05, David Lechner wrote:
> On 8/7/26 10:58 PM, Kurt Borja wrote:
>
> ...
>
>>   - @David: I added support for the monitor channels, but I prefer to
>>     parse them from DT instead of making them static (similar to the
>>     ad4170-4 approach too :p).
>
> Why? Unless there really is some property that depends on how the
> system is wired up, it seems like this is just making unnecessary
> work for users to be able to use the monitor channels. And if someone
> decided later that they do in fact want to use the monitoring channel
> and it wasn't in the devicetree, sometimes it can be very difficult
> to actually change the devicetree.

The only thing I can think of is the reference source. The datasheet
says "Measure the supply monitor readings using either the internal or
an external reference".

I saw that the ti-ads112c14 also allows the monitors to be referenced
externally but you didn't implement support for it. In my case I think
it's okay to leave it unimplemented too and make the channels static.

>
> The monitor inputs also have many restrictions compared to a
> normal input that it would be really hard to describe correctly
> in the bindings without allowing things that should not actually
> be allowed. (can't have excitation current or burnout, temperature
> channel requires internal reference, most should be single-channel,
> etc.)

Good point.

>
>> 
>>   - @David: About filters... As I mentioned in the previous version, the
>>     data_rate configuration takes precedence over the filter selection.
>>     If an incompatible filter (given a data rate) is selected, the chip
>>     resorts to a sane compatible one when doing conversions (either
>>     SINC1 or plain SINC5).
>> 
>>     Now, I don't know how to expose this in userspace. Should I limit
>>     the sampling_frequency_available attribute (given a filter)? Or
>>     should it be the other way around, limit the filter_type_available
>>     attribute (given a data rate)?.
>  I figured that the filter type selection would be more important than
> the rate so when I implemented it for ADS112C14, I made it so that
> one has to pick the filter first and everything else flows from that.
> (I didn't expose sampling frequency until the same time as filter type.)
>
> The thinking behind this is that if you do care about filtering, then
> you are picking filter type and sampling rate to get certain notches
> and/or frequency response of the filter rather than trying to get a
> faster or slower sample rate.

I think this makes a lot of sense in your chip because there is no
plain "data rate" register. The data rate ends up being a consequence of
the modulator divider + OSR/filter settings.

>
> And the driver also allows using an hrtimer trigger to do single-shot
> samples for cases where one doesn't want to sample as fast as possible
> in continuous mode. This would be more useful to someone who just cares
> about sample rate and not about filtering.

Why did you go for this instead of just leaving the continuous mode
running and reading on each trigger?

>
> Just posted the series yesterday:
> https://lore.kernel.org/linux-iio/20260807-iio-adc-ti-ads112c14-filter-support-v1-0-4d3ba00caf18@baylibre.com/T/#t

Can you Cc me this series too? The settlingtime stuff is something I'll
implement too.

>
> ADS126X seems a little less complicated in this regard though
> as the same sampling rates are available for all filters with
> the exception of the FIR filter having a limited subset. So I
> would go with the option to limit sampling rate based on filter
> type, not the other way around. If a higher rate is selected
> when changing to the FIR filter type, just have it go to the
> max (20 SPS).

I'll go for this!

>

Thank you very much for your review and tags :)

-- 
Thanks,
 ~ Kurt
Re: [PATCH v3 0/9] iio: adc: Add TI ADS126X ADC family support
Posted by David Lechner 1 month, 2 weeks ago
On 8/9/26 3:29 AM, Kurt Borja wrote:
> On Sat Aug 8, 2026 at 1:37 PM -05, David Lechner wrote:
>> On 8/7/26 10:58 PM, Kurt Borja wrote:
>>

...

>>
>> And the driver also allows using an hrtimer trigger to do single-shot
>> samples for cases where one doesn't want to sample as fast as possible
>> in continuous mode. This would be more useful to someone who just cares
>> about sample rate and not about filtering.
> 
> Why did you go for this instead of just leaving the continuous mode
> running and reading on each trigger?

The hrtimer trigger allows more than one channel to be enabled, so we
have to do all of the channel setup for the next channel before we
can send the start command to trigger the next conversion. Doing it
this way eliminates the possibility of not being able to update all
of the settings in between the DRDY interrupts.

For cases where we only want to read one channel, then we can use
the DRDY trigger instead of an hrtimer trigger. Since we don't have
to change channel config in that case, if we miss a DRDY interrupt
because we took to long to start the I2C transfer, it isn't a big
deal, we just drop a sample.

> 
>>
>> Just posted the series yesterday:
>> https://lore.kernel.org/linux-iio/20260807-iio-adc-ti-ads112c14-filter-support-v1-0-4d3ba00caf18@baylibre.com/T/#t
> 
> Can you Cc me this series too? The settlingtime stuff is something I'll
> implement too.

Yes, I meant to. It was late on a Friday when I sent it and I didn't
the best job checking all of the details like that.