From: Kurt Borja <kuurtb@gmail.com>
To: Kurt Borja <kuurtb@gmail.com>,
Jonathan Cameron <jic23@kernel.org>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
David Lechner <dlechner@baylibre.com>
Cc: "Nuno Sá" <nuno.sa@analog.com>,
"Andy Shevchenko" <andy@kernel.org>,
linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org,
"Jonathan Cameron" <jic23@kernel.org>
Subject: [PATCH v2 7/7] iio: adc: Add ti-ads1263-adc2 driver
Date: Sun, 28 Jun 2026 00:36:08 -0500 [thread overview]
Message-ID: <20260628-ads126x-v2-7-4b1b231325ba@gmail.com> (raw)
In-Reply-To: <20260628-ads126x-v2-0-4b1b231325ba@gmail.com>
The TI ADS1263 embeds a second 24-bit delta-sigma ADC (ADC2) with its
own input mux, reference, gain and sample-rate selection.
Model ADC2 as a separate IIO device on the auxiliary bus: the ti-ads1262
SPI driver instantiates the auxiliary device and exports a small set of
TI_ADS1262-namespaced helpers for the conversion and register accesses
that must go through the shared bus. ADC2 channels are derived from the
parent's configured channels.
Signed-off-by: Kurt Borja <kuurtb@gmail.com>
---
MAINTAINERS | 2 +
drivers/iio/adc/Kconfig | 14 ++
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/ti-ads1262.c | 168 ++++++++++++++++-
drivers/iio/adc/ti-ads1262.h | 39 ++++
drivers/iio/adc/ti-ads1263-adc2.c | 379 ++++++++++++++++++++++++++++++++++++++
6 files changed, 602 insertions(+), 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index d868b25f2c65bcd9..342c661f079bcf39 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26929,6 +26929,8 @@ L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/iio/adc/ti,ads1262.yaml
F: drivers/iio/adc/ti-ads1262.c
+F: drivers/iio/adc/ti-ads1262.h
+F: drivers/iio/adc/ti-ads1263-adc2.c
TI ADS7924 ADC DRIVER
M: Hugo Villeneuve <hvilleneuve@dimonoff.com>
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 6051092c20b96731..ab2e8e45f3b442d6 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -1817,6 +1817,7 @@ config TI_ADS1262
select REGMAP
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
+ select AUXILIARY_BUS
help
If you say yes here you get support for Texas Instruments ADS1262 and
ADS1263 ADC chips.
@@ -1824,6 +1825,19 @@ config TI_ADS1262
This driver can also be built as a module. If so, the module will be
called ti-ads1262.
+config TI_ADS1263_ADC2
+ tristate "Texas Instruments ADS1263 auxiliary ADC (ADC2) driver"
+ depends on TI_ADS1262
+ select AUXILIARY_BUS
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ If you say yes here you get support for Texas Instruments ADS1263
+ auxiliary ADC (ADC2).
+
+ This driver can also be built as a module. If so, the module will be
+ called ti-ads1263-adc2.
+
config TI_ADS1298
tristate "Texas Instruments ADS1298"
depends on SPI
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 4b1f89a2317a35f7..4215f56f525349a5 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -156,6 +156,7 @@ obj-$(CONFIG_TI_ADS1119) += ti-ads1119.o
obj-$(CONFIG_TI_ADS112C14) += ti-ads112c14.o
obj-$(CONFIG_TI_ADS124S08) += ti-ads124s08.o
obj-$(CONFIG_TI_ADS1262) += ti-ads1262.o
+obj-$(CONFIG_TI_ADS1263_ADC2) += ti-ads1263-adc2.o
obj-$(CONFIG_TI_ADS1298) += ti-ads1298.o
obj-$(CONFIG_TI_ADS131E08) += ti-ads131e08.o
obj-$(CONFIG_TI_ADS131M02) += ti-ads131m02.o
diff --git a/drivers/iio/adc/ti-ads1262.c b/drivers/iio/adc/ti-ads1262.c
index 53bc70e0c35a59da..e3acc2eb9042c40a 100644
--- a/drivers/iio/adc/ti-ads1262.c
+++ b/drivers/iio/adc/ti-ads1262.c
@@ -14,10 +14,10 @@
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/compiler_attributes.h>
-#include <linux/compiler_types.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/gpio/consumer.h>
+#include <linux/idr.h>
#include <linux/interrupt.h>
#include <linux/lockdep.h>
#include <linux/math.h>
@@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/mutex.h>
+#include <linux/of.h>
#include <linux/overflow.h>
#include <linux/property.h>
#include <linux/regmap.h>
@@ -42,6 +43,8 @@
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
+#include "ti-ads1262.h"
+
#define ADS1262_OPCODE_NOP 0x00
#define ADS1262_OPCODE_RESET 0x06
#define ADS1262_OPCODE_START1 0x08
@@ -144,6 +147,8 @@
#define ADS1262_MAX_CHANNEL_COUNT 16
#define ADS1262_XFER_BUFFER_SZ 11
+static DEFINE_IDA(ads1262_ida);
+
enum {
ADS1262_DELAY_NO_DELAY,
ADS1262_DELAY_8700_NS,
@@ -1039,6 +1044,161 @@ static irqreturn_t ads1262_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
+int ads1263_adc2_channel_get_scale(struct ads1263_adc2_ctx *ctx, u8 realbits,
+ u8 gain, u8 ref_source, int *val, int *val2)
+{
+ return ads1262_calculate_scale(ctx->chip, realbits, gain, ref_source, ref_source,
+ val, val2);
+}
+EXPORT_SYMBOL_NS_GPL(ads1263_adc2_channel_get_scale, "TI_ADS1262");
+
+int ads1263_adc2_channel_enable(struct ads1263_adc2_ctx *ctx,
+ const struct ads1263_adc2_channel *chan)
+{
+ struct ads1262 *st = ctx->chip;
+ u8 val;
+ int ret;
+
+ guard(mutex)(&ctx->chan_lock);
+
+ val = FIELD_PREP(ADS1262_ADC2CFG_GAIN2_MASK, chan->gain) |
+ FIELD_PREP(ADS1262_ADC2CFG_REF2_MASK, chan->reference) |
+ FIELD_PREP(ADS1262_ADC2CFG_DR2_MASK, chan->data_rate);
+ ret = regmap_update_bits(st->regmap, ADS1262_ADC2CFG_REG,
+ ADS1262_ADC2CFG_GAIN2_MASK |
+ ADS1262_ADC2CFG_REF2_MASK |
+ ADS1262_ADC2CFG_DR2_MASK, val);
+
+ val = FIELD_PREP(ADS1262_ADC2MUX_MUXP2_MASK, chan->input[0]) |
+ FIELD_PREP(ADS1262_ADC2MUX_MUXN2_MASK, chan->input[1]);
+ return regmap_update_bits(st->regmap, ADS1262_ADC2MUX_REG,
+ ADS1262_ADC2MUX_MUXP2_MASK |
+ ADS1262_ADC2MUX_MUXN2_MASK, val);
+}
+EXPORT_SYMBOL_NS_GPL(ads1263_adc2_channel_enable, "TI_ADS1262");
+
+int ads1263_adc2_start(struct ads1263_adc2_ctx *ctx)
+{
+ struct ads1262 *st = ctx->chip;
+
+ return ads1262_dev_cmd(st, ADS1262_OPCODE_START2);
+}
+EXPORT_SYMBOL_NS_GPL(ads1263_adc2_start, "TI_ADS1262");
+
+int ads1263_adc2_stop(struct ads1263_adc2_ctx *ctx)
+{
+ struct ads1262 *st = ctx->chip;
+
+ return ads1262_dev_cmd(st, ADS1262_OPCODE_STOP2);
+}
+EXPORT_SYMBOL_NS_GPL(ads1263_adc2_stop, "TI_ADS1262");
+
+int ads1263_adc2_read(struct ads1263_adc2_ctx *ctx, __be32 *val)
+{
+ struct ads1262 *st = ctx->chip;
+
+ return ads1262_dev_read_by_cmd(st, ADS1262_OPCODE_RDATA2, val);
+}
+EXPORT_SYMBOL_NS_GPL(ads1263_adc2_read, "TI_ADS1262");
+
+static void ads1262_aux_device_destroy(void *data)
+{
+ struct auxiliary_device *adev = data;
+
+ auxiliary_device_delete(adev);
+ auxiliary_device_uninit(adev);
+}
+
+static void ads1262_aux_device_release(struct device *dev)
+{
+ struct auxiliary_device *adev = to_auxiliary_dev(dev);
+ struct ads1263_adc2_ctx *ctx =
+ container_of(adev, struct ads1263_adc2_ctx, adev);
+ struct device_node *node = adev->dev.of_node;
+
+ of_node_put(node);
+ mutex_destroy(&ctx->chan_lock);
+ kfree(ctx->channels);
+ ida_free(&ads1262_ida, adev->id);
+ kfree(ctx);
+}
+
+static int ads1262_aux_device_setup(struct ads1262 *st)
+{
+ struct device *parent = &st->spi->dev;
+ struct ads1263_adc2_channel *chans;
+ struct ads1262_channel *chan_data;
+ struct auxiliary_device *adev;
+ struct ads1263_adc2_ctx *ctx;
+ struct device_link *link;
+ int id, ret;
+
+ ctx = kzalloc_obj(*ctx);
+ if (!ctx)
+ return -ENOMEM;
+
+ id = ida_alloc(&ads1262_ida, GFP_KERNEL);
+ if (id < 0) {
+ ret = id;
+ goto out_free_adc2;
+ }
+
+ chans = kcalloc(st->num_channels, sizeof(*chans), GFP_KERNEL);
+ if (!chans) {
+ ret = -ENOMEM;
+ goto out_free_id;
+ }
+
+ for (unsigned int i = 0; i < st->num_channels; i++) {
+ chan_data = &st->channels[i];
+ chans[i].input[0] = chan_data->input[0];
+ chans[i].input[1] = chan_data->input[1];
+ chans[i].reference = chan_data->reference[2];
+ }
+
+ ctx->chip = st;
+ ctx->num_channels = st->num_channels;
+ ctx->channels = chans;
+ mutex_init(&ctx->chan_lock);
+
+ adev = &ctx->adev;
+ adev->name = "ads1263_adc2";
+ adev->id = id;
+ adev->dev.release = ads1262_aux_device_release;
+ adev->dev.parent = parent;
+ device_set_of_node_from_dev(&adev->dev, parent);
+
+ ret = auxiliary_device_init(adev);
+ if (ret)
+ goto out_free_res;
+
+ link = device_link_add(&adev->dev, parent, DL_FLAG_AUTOPROBE_CONSUMER);
+ if (!link) {
+ auxiliary_device_uninit(adev);
+ return dev_err_probe(parent, -ENXIO,
+ "Failed to add link to auxiliary device\n");
+ }
+
+ ret = auxiliary_device_add(adev);
+ if (ret) {
+ auxiliary_device_uninit(adev);
+ return ret;
+ }
+
+ return devm_add_action_or_reset(parent, ads1262_aux_device_destroy, adev);
+
+out_free_res:
+ of_node_put(adev->dev.of_node);
+ mutex_destroy(&ctx->chan_lock);
+ kfree(chans);
+out_free_id:
+ ida_free(&ads1262_ida, id);
+out_free_adc2:
+ kfree(ctx);
+
+ return ret;
+}
+
static int ads1262_get_filter_type(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan)
{
@@ -1627,6 +1787,12 @@ static int ads1262_spi_probe(struct spi_device *spi)
return ret;
}
+ if (info->has_aux_adc) {
+ ret = ads1262_aux_device_setup(st);
+ if (ret)
+ return ret;
+ }
+
return devm_iio_device_register(dev, indio_dev);
}
diff --git a/drivers/iio/adc/ti-ads1262.h b/drivers/iio/adc/ti-ads1262.h
new file mode 100644
index 0000000000000000..7a94ffd1fa983f9f
--- /dev/null
+++ b/drivers/iio/adc/ti-ads1262.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Texas Instruments ADS1262 ADC driver
+ *
+ * Copyright (C) 2025 Kurt Borja <kuurtb@gmail.com>
+ */
+
+#ifndef _ADS1262_H_
+#define _ADS1262_H_
+
+#include <linux/auxiliary_bus.h>
+#include <linux/types.h>
+
+struct ads1263_adc2_channel {
+ u8 gain;
+ u8 reference;
+ u8 data_rate;
+ u8 input[2];
+};
+
+struct ads1263_adc2_ctx {
+ struct auxiliary_device adev;
+ struct ads1262 *chip;
+
+ /* Protects channel state */
+ struct mutex chan_lock;
+ struct ads1263_adc2_channel *channels;
+ unsigned int num_channels;
+};
+
+int ads1263_adc2_channel_get_scale(struct ads1263_adc2_ctx *ctx, u8 realbits,
+ u8 gain, u8 ref_source, int *val, int *val2);
+int ads1263_adc2_channel_enable(struct ads1263_adc2_ctx *ctx,
+ const struct ads1263_adc2_channel *chan);
+int ads1263_adc2_start(struct ads1263_adc2_ctx *ctx);
+int ads1263_adc2_stop(struct ads1263_adc2_ctx *ctx);
+int ads1263_adc2_read(struct ads1263_adc2_ctx *ctx, __be32 *val);
+
+#endif
diff --git a/drivers/iio/adc/ti-ads1263-adc2.c b/drivers/iio/adc/ti-ads1263-adc2.c
new file mode 100644
index 0000000000000000..385531d96de11269
--- /dev/null
+++ b/drivers/iio/adc/ti-ads1263-adc2.c
@@ -0,0 +1,379 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Texas Instruments ADS1263 auxiliary ADC (ADC2) driver
+ *
+ * Copyright (C) 2025 Kurt Borja <kuurtb@gmail.com>
+ */
+
+#include <linux/align.h>
+#include <linux/array_size.h>
+#include <linux/bitmap.h>
+#include <linux/bitops.h>
+#include <linux/cleanup.h>
+#include <linux/container_of.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dev_printk.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/unaligned.h>
+#include <linux/units.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#include "ti-ads1262.h"
+
+/* ADC2CFG REF2 constants */
+#define ADS1263_ADC2_REF2_INTER 0
+#define ADS1263_ADC2_REF2_COUNT 5
+
+struct ads1263_adc2 {
+ struct iio_dev *indio_dev;
+ struct ads1263_adc2_ctx *ctx;
+};
+
+static const int ads1263_adc2_gain_avail[] = {
+ 1, 2, 4, 8, 16, 32, 64, 128
+};
+
+static const int ads1263_adc2_data_rate_avail[] = {
+ 10, 100, 400, 800
+};
+
+static const unsigned long ads1263_adc2_latency_us[] = {
+ 121000, 31200, 8710, 4970
+};
+
+static int ads1263_adc2_channel_read(struct iio_dev *indio_dev,
+ struct ads1263_adc2_channel *chan_data,
+ __be32 *val)
+{
+ struct ads1263_adc2 *st = iio_priv(indio_dev);
+ struct ads1263_adc2_ctx *ctx = st->ctx;
+ int ret;
+
+ IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim);
+ if (IIO_DEV_ACQUIRE_FAILED(claim))
+ return -EBUSY;
+
+ ret = ads1263_adc2_channel_enable(ctx, chan_data);
+ if (ret)
+ return ret;
+
+ ret = ads1263_adc2_start(ctx);
+ if (ret)
+ return ret;
+
+ ret = ads1263_adc2_stop(ctx);
+ if (ret)
+ return ret;
+
+ fsleep(ads1263_adc2_latency_us[chan_data->data_rate]);
+
+ return ads1263_adc2_read(ctx, val);
+}
+
+static int ads1263_adc2_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct ads1263_adc2 *st = iio_priv(indio_dev);
+ struct ads1263_adc2_ctx *ctx = st->ctx;
+ struct ads1263_adc2_channel *chan_data = &ctx->channels[chan->scan_index];
+ u8 realbits = chan->scan_type.realbits;
+ __be32 raw;
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = ads1263_adc2_channel_read(indio_dev, chan_data, &raw);
+ if (ret)
+ return ret;
+
+ *val = sign_extend32(get_unaligned_be24(&raw), realbits - 1);
+
+ return IIO_VAL_INT;
+
+ case IIO_CHAN_INFO_SCALE: {
+ guard(mutex)(&ctx->chan_lock);
+
+ ret = ads1263_adc2_channel_get_scale(ctx, realbits, chan_data->gain,
+ chan_data->reference, val, val2);
+ if (ret)
+ return ret;
+
+ return IIO_VAL_INT_PLUS_NANO;
+ }
+
+ case IIO_CHAN_INFO_HARDWAREGAIN: {
+ guard(mutex)(&ctx->chan_lock);
+
+ *val = ads1263_adc2_gain_avail[chan_data->gain];
+
+ return IIO_VAL_INT;
+ }
+
+ case IIO_CHAN_INFO_SAMP_FREQ: {
+ guard(mutex)(&ctx->chan_lock);
+
+ *val = ads1263_adc2_data_rate_avail[chan_data->data_rate];
+
+ return IIO_VAL_INT;
+ }
+
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int ads1263_adc2_read_avail(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ const int **vals, int *type,
+ int *length, long mask)
+{
+ switch (mask) {
+ case IIO_CHAN_INFO_HARDWAREGAIN:
+ *type = IIO_VAL_INT;
+ *vals = ads1263_adc2_gain_avail;
+ *length = ARRAY_SIZE(ads1263_adc2_gain_avail);
+ return IIO_AVAIL_LIST;
+
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *type = IIO_VAL_INT;
+ *vals = ads1263_adc2_data_rate_avail;
+ *length = ARRAY_SIZE(ads1263_adc2_data_rate_avail);
+ return IIO_AVAIL_LIST;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int ads1263_adc2_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct ads1263_adc2 *st = iio_priv(indio_dev);
+ struct ads1263_adc2_ctx *ctx = st->ctx;
+ struct ads1263_adc2_channel *chan_data = &ctx->channels[chan->scan_index];
+ unsigned int i;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_HARDWAREGAIN: {
+ for (i = 0; i < ARRAY_SIZE(ads1263_adc2_gain_avail); i++) {
+ if (val == ads1263_adc2_gain_avail[i])
+ break;
+ }
+ if (i == ARRAY_SIZE(ads1263_adc2_gain_avail))
+ return -EINVAL;
+
+ guard(mutex)(&ctx->chan_lock);
+ chan_data->gain = i;
+
+ break;
+ }
+
+ case IIO_CHAN_INFO_SAMP_FREQ: {
+ for (i = 0; i < ARRAY_SIZE(ads1263_adc2_data_rate_avail); i++) {
+ if (val == ads1263_adc2_data_rate_avail[i])
+ break;
+ }
+ if (i == ARRAY_SIZE(ads1263_adc2_data_rate_avail))
+ return -EINVAL;
+
+ guard(mutex)(&ctx->chan_lock);
+ chan_data->data_rate = i;
+
+ break;
+ }
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int ads1263_adc2_write_raw_get_fmt(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ long mask)
+{
+ switch (mask) {
+ case IIO_CHAN_INFO_CONVDELAY:
+ return IIO_VAL_INT_PLUS_NANO;
+ default:
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
+}
+
+static const struct iio_info ads1263_adc2_iio_info = {
+ .read_raw = ads1263_adc2_read_raw,
+ .read_avail = ads1263_adc2_read_avail,
+ .write_raw = ads1263_adc2_write_raw,
+ .write_raw_get_fmt = ads1263_adc2_write_raw_get_fmt,
+};
+
+static int ads1263_adc2_buffer_preenable(struct iio_dev *indio_dev)
+{
+ struct ads1263_adc2 *st = iio_priv(indio_dev);
+ struct ads1263_adc2_ctx *ctx = st->ctx;
+ unsigned long i;
+ int ret;
+
+ i = find_first_bit(indio_dev->active_scan_mask,
+ iio_get_masklength(indio_dev));
+ ret = ads1263_adc2_channel_enable(ctx, &ctx->channels[i]);
+ if (ret)
+ return ret;
+
+ return ads1263_adc2_start(ctx);
+}
+
+static int ads1263_adc2_buffer_postdisable(struct iio_dev *indio_dev)
+{
+ struct ads1263_adc2 *st = iio_priv(indio_dev);
+ struct ads1263_adc2_ctx *ctx = st->ctx;
+
+ ads1263_adc2_stop(ctx);
+
+ return 0;
+}
+
+static const struct iio_buffer_setup_ops ads1263_adc2_buffer_ops = {
+ .preenable = ads1263_adc2_buffer_preenable,
+ .postdisable = ads1263_adc2_buffer_postdisable,
+ .validate_scan_mask = iio_validate_scan_mask_onehot,
+};
+
+static irqreturn_t ads1263_adc2_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct ads1263_adc2 *st = iio_priv(indio_dev);
+ struct ads1263_adc2_ctx *ctx = st->ctx;
+ struct {
+ __be32 conv;
+ aligned_s64 ts;
+ } scan = {};
+ int ret;
+
+ ret = ads1263_adc2_read(ctx, &scan.conv);
+ if (ret)
+ goto out_notify_done;
+
+ iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan),
+ pf->timestamp);
+
+out_notify_done:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static int ads1263_adc2_channels_setup(struct iio_dev *indio_dev)
+{
+ struct ads1263_adc2 *st = iio_priv(indio_dev);
+ struct device *dev = &st->ctx->adev.dev;
+ struct ads1263_adc2_ctx *ctx = st->ctx;
+ struct ads1263_adc2_channel *chan_data;
+ struct iio_chan_spec *chns;
+ unsigned int i;
+
+ /* Account for the timestamp channel */
+ chns = devm_kcalloc(dev, ctx->num_channels + 1, sizeof(*chns),
+ GFP_KERNEL);
+ if (!chns)
+ return -ENOMEM;
+
+ for (i = 0; i < ctx->num_channels; i++) {
+ guard(mutex)(&ctx->chan_lock);
+
+ chan_data = &ctx->channels[i];
+ chns[i] = (struct iio_chan_spec) {
+ .type = IIO_VOLTAGE,
+ .channel = chan_data->input[0],
+ .channel2 = chan_data->input[1],
+ .scan_index = i,
+ .scan_type = {
+ .format = IIO_SCAN_FORMAT_SIGNED_INT,
+ .realbits = 24,
+ .storagebits = 32,
+ .shift = 8,
+ .endianness = IIO_BE,
+ },
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_HARDWAREGAIN) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ),
+ .info_mask_shared_by_type_available =
+ BIT(IIO_CHAN_INFO_HARDWAREGAIN) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ),
+ .indexed = true,
+ .differential = true,
+ };
+ }
+
+ chns[i] = IIO_CHAN_SOFT_TIMESTAMP(i);
+
+ indio_dev->num_channels = ctx->num_channels + 1;
+ indio_dev->channels = chns;
+
+ return 0;
+}
+
+static int ads1263_adc2_probe(struct auxiliary_device *auxdev,
+ const struct auxiliary_device_id *id)
+{
+ struct ads1263_adc2_ctx *ctx =
+ container_of(auxdev, struct ads1263_adc2_ctx, adev);
+ struct device *dev = &auxdev->dev;
+ struct iio_dev *indio_dev;
+ struct ads1263_adc2 *st;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ st = iio_priv(indio_dev);
+ st->ctx = ctx;
+ st->indio_dev = indio_dev;
+
+ indio_dev->name = "ads1263_adc2";
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &ads1263_adc2_iio_info;
+ ret = ads1263_adc2_channels_setup(indio_dev);
+ if (ret)
+ return ret;
+
+ ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
+ iio_pollfunc_store_time,
+ ads1263_adc2_trigger_handler,
+ &ads1263_adc2_buffer_ops);
+ if (ret)
+ return ret;
+
+ return devm_iio_device_register(dev, indio_dev);
+}
+
+static const struct auxiliary_device_id ads1263_adc2_auxiliary_match[] = {
+ { .name = "ti_ads1262.ads1263_adc2" },
+ { }
+};
+MODULE_DEVICE_TABLE(auxiliary, ads1263_adc2_auxiliary_match);
+
+static struct auxiliary_driver ads1263_adc2_driver = {
+ .name = "ads1263_adc2",
+ .probe = ads1263_adc2_probe,
+ .id_table = ads1263_adc2_auxiliary_match,
+};
+module_auxiliary_driver(ads1263_adc2_driver);
+
+MODULE_IMPORT_NS("TI_ADS1262");
+MODULE_DESCRIPTION("Texas Instruments ADS1263 auxiliary ADC (ADC2) driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kurt Borja <kuurtb@gmail.com>");
--
2.54.0
next prev parent reply other threads:[~2026-06-28 5:36 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-28 5:36 [PATCH v2 0/7] iio: adc: Add TI ADS126X ADC family support Kurt Borja
2026-06-28 5:36 ` [PATCH v2 1/7] dt-bindings: iio: adc: Add TI ADS126x ADC family Kurt Borja
2026-06-28 15:45 ` David Lechner
2026-06-28 19:12 ` Kurt Borja
2026-06-29 14:21 ` David Lechner
2026-06-29 16:27 ` Kurt Borja
2026-06-29 16:43 ` David Lechner
2026-06-30 17:14 ` Kurt Borja
2026-06-30 18:38 ` David Lechner
2026-07-01 0:28 ` Jonathan Cameron
2026-06-28 5:36 ` [PATCH v2 2/7] iio: adc: Add ti-ads1262 driver Kurt Borja
2026-06-28 17:15 ` David Lechner
2026-06-28 20:00 ` Kurt Borja
2026-06-29 14:38 ` David Lechner
2026-06-30 0:32 ` Jonathan Cameron
2026-06-30 17:17 ` Kurt Borja
2026-06-30 0:28 ` Jonathan Cameron
2026-06-30 0:43 ` Jonathan Cameron
2026-06-28 5:36 ` [PATCH v2 3/7] iio: adc: ti-ads1262: Add channel filter support Kurt Borja
2026-06-28 5:36 ` [PATCH v2 4/7] iio: adc: ti-ads1262: Add excitation current support Kurt Borja
2026-06-30 0:47 ` Jonathan Cameron
2026-06-30 17:18 ` Kurt Borja
2026-06-28 5:36 ` [PATCH v2 5/7] iio: adc: ti-ads1262: Add conversion delay support Kurt Borja
2026-06-30 0:50 ` Jonathan Cameron
2026-06-30 17:23 ` Kurt Borja
2026-06-30 18:44 ` David Lechner
2026-07-01 0:20 ` Jonathan Cameron
2026-07-06 16:19 ` David Lechner
2026-07-06 17:23 ` Jonathan Cameron
2026-07-07 1:38 ` Kurt Borja
2026-07-07 2:06 ` Jonathan Cameron
2026-06-28 5:36 ` [PATCH v2 6/7] iio: adc: ti-ads1262: Add buffer and trigger support Kurt Borja
2026-06-30 0:54 ` Jonathan Cameron
2026-06-28 5:36 ` Kurt Borja [this message]
2026-06-28 17:22 ` [PATCH v2 7/7] iio: adc: Add ti-ads1263-adc2 driver David Lechner
2026-06-28 20:08 ` Kurt Borja
2026-06-29 16:38 ` David Lechner
2026-06-30 1:00 ` Jonathan Cameron
2026-06-30 17:57 ` Kurt Borja
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260628-ads126x-v2-7-4b1b231325ba@gmail.com \
--to=kuurtb@gmail.com \
--cc=andy@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dlechner@baylibre.com \
--cc=jic23@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nuno.sa@analog.com \
--cc=robh@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.