.../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(+)
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
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).
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
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.
© 2016 - 2026 Red Hat, Inc.