* [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
@ 2026-02-06 16:07 Antoniu Miclaus
2026-02-06 16:07 ` [PATCH v2 1/4] spi: allow ancillary devices to share parent's chip selects Antoniu Miclaus
` (5 more replies)
0 siblings, 6 replies; 35+ messages in thread
From: Antoniu Miclaus @ 2026-02-06 16:07 UTC (permalink / raw)
To: Antoniu Miclaus, Lars-Peter Clausen, Michael Hennerich,
Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Olivier Moysan,
Mark Brown, linux-iio, devicetree, linux-kernel, linux-spi
Add support for the AD4880, a dual-channel 20-bit 40MSPS SAR ADC from
the same family as AD4080.
The AD4880 has two independent ADC channels, each with its own SPI
configuration interface and LVDS data output. The driver uses
spi_new_ancillary_device() for the second channel's SPI and requires
two io-backend instances for the data interfaces.
This series includes:
- SPI core fix to allow ancillary devices to share parent's chip selects
- New devm_iio_backend_get_by_index() helper for multi-channel backend lookup
- DT bindings update for AD4880
- Driver support for AD4880
Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ad4880.pdf
Antoniu Miclaus (4):
spi: allow ancillary devices to share parent's chip selects
iio: backend: add devm_iio_backend_get_by_index()
dt-bindings: iio: adc: ad4080: add AD4880 support
iio: adc: ad4080: add support for AD4880 dual-channel ADC
.../bindings/iio/adc/adi,ad4080.yaml | 51 +++-
drivers/iio/adc/ad4080.c | 256 ++++++++++++++----
drivers/iio/industrialio-backend.c | 51 ++++
drivers/spi/spi.c | 29 +-
include/linux/iio/backend.h | 2 +
5 files changed, 330 insertions(+), 59 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 1/4] spi: allow ancillary devices to share parent's chip selects
2026-02-06 16:07 [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
@ 2026-02-06 16:07 ` Antoniu Miclaus
2026-02-07 18:09 ` David Lechner
2026-02-06 16:07 ` [PATCH v2 2/4] iio: backend: add devm_iio_backend_get_by_index() Antoniu Miclaus
` (4 subsequent siblings)
5 siblings, 1 reply; 35+ messages in thread
From: Antoniu Miclaus @ 2026-02-06 16:07 UTC (permalink / raw)
To: Antoniu Miclaus, Lars-Peter Clausen, Michael Hennerich,
Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Olivier Moysan,
Mark Brown, linux-iio, devicetree, linux-kernel, linux-spi
When registering an ancillary SPI device, the current code flags a chip
select conflict with the parent device. This happens because the
ancillary device intentionally uses one of the parent's chip selects,
but __spi_add_device() checks against all existing devices including
the parent.
Allow this by passing the parent device pointer to __spi_add_device()
and skipping the conflict check when the existing device is the parent.
Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
---
drivers/spi/spi.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index e25df9990f82..18ca3c7bad6b 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -641,12 +641,26 @@ static inline int spi_dev_check_cs(struct device *dev,
return 0;
}
+struct spi_dev_check_info {
+ struct spi_device *new_spi;
+ struct spi_device *parent; /* set for ancillary devices */
+};
+
static int spi_dev_check(struct device *dev, void *data)
{
struct spi_device *spi = to_spi_device(dev);
- struct spi_device *new_spi = data;
+ struct spi_dev_check_info *info = data;
+ struct spi_device *new_spi = info->new_spi;
int status, idx;
+ /*
+ * When registering an ancillary device, skip checking against the
+ * parent device since the ancillary is intentionally using one of
+ * the parent's chip selects.
+ */
+ if (info->parent && spi == info->parent)
+ return 0;
+
if (spi->controller == new_spi->controller) {
for (idx = 0; idx < spi->num_chipselect; idx++) {
status = spi_dev_check_cs(dev, spi, idx, new_spi, 0);
@@ -663,10 +677,11 @@ static void spi_cleanup(struct spi_device *spi)
spi->controller->cleanup(spi);
}
-static int __spi_add_device(struct spi_device *spi)
+static int __spi_add_device(struct spi_device *spi, struct spi_device *parent)
{
struct spi_controller *ctlr = spi->controller;
struct device *dev = ctlr->dev.parent;
+ struct spi_dev_check_info check_info;
int status, idx;
u8 cs;
@@ -710,7 +725,9 @@ static int __spi_add_device(struct spi_device *spi)
* chipselect **BEFORE** we call setup(), else we'll trash
* its configuration.
*/
- status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check);
+ check_info.new_spi = spi;
+ check_info.parent = parent;
+ status = bus_for_each_dev(&spi_bus_type, NULL, &check_info, spi_dev_check);
if (status)
return status;
@@ -772,7 +789,7 @@ int spi_add_device(struct spi_device *spi)
spi_dev_set_name(spi);
mutex_lock(&ctlr->add_lock);
- status = __spi_add_device(spi);
+ status = __spi_add_device(spi, NULL);
mutex_unlock(&ctlr->add_lock);
return status;
}
@@ -2580,8 +2597,8 @@ struct spi_device *spi_new_ancillary_device(struct spi_device *spi,
WARN_ON(!mutex_is_locked(&ctlr->add_lock));
- /* Register the new device */
- rc = __spi_add_device(ancillary);
+ /* Register the new device, passing the parent to skip CS conflict check */
+ rc = __spi_add_device(ancillary, spi);
if (rc) {
dev_err(&spi->dev, "failed to register ancillary device\n");
goto err_out;
--
2.43.0
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v2 2/4] iio: backend: add devm_iio_backend_get_by_index()
2026-02-06 16:07 [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
2026-02-06 16:07 ` [PATCH v2 1/4] spi: allow ancillary devices to share parent's chip selects Antoniu Miclaus
@ 2026-02-06 16:07 ` Antoniu Miclaus
2026-02-07 14:57 ` Jonathan Cameron
` (2 more replies)
2026-02-06 16:07 ` [PATCH v2 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support Antoniu Miclaus
` (3 subsequent siblings)
5 siblings, 3 replies; 35+ messages in thread
From: Antoniu Miclaus @ 2026-02-06 16:07 UTC (permalink / raw)
To: Antoniu Miclaus, Lars-Peter Clausen, Michael Hennerich,
Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Olivier Moysan,
Mark Brown, linux-iio, devicetree, linux-kernel, linux-spi
Add a new function to get an IIO backend by its index in the
io-backends device tree property. This is useful for multi-channel
devices that have multiple backends, where looking up by index is
more straightforward than using named backends.
The new function directly uses the index to find the backend reference
in the io-backends property, avoiding the need for io-backend-names.
Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
---
drivers/iio/industrialio-backend.c | 51 ++++++++++++++++++++++++++++++
include/linux/iio/backend.h | 2 ++
2 files changed, 53 insertions(+)
diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-backend.c
index 447b694d6d5f..3b692d48481e 100644
--- a/drivers/iio/industrialio-backend.c
+++ b/drivers/iio/industrialio-backend.c
@@ -1008,6 +1008,57 @@ struct iio_backend *devm_iio_backend_get(struct device *dev, const char *name)
}
EXPORT_SYMBOL_NS_GPL(devm_iio_backend_get, "IIO_BACKEND");
+static struct iio_backend *
+__devm_iio_backend_fwnode_get_by_index(struct device *dev,
+ struct fwnode_handle *fwnode,
+ unsigned int index)
+{
+ struct fwnode_handle *fwnode_back;
+ struct iio_backend *back;
+ int ret;
+
+ fwnode_back = fwnode_find_reference(fwnode, "io-backends", index);
+ if (IS_ERR(fwnode_back))
+ return dev_err_cast_probe(dev, fwnode_back,
+ "Cannot get Firmware reference\n");
+
+ guard(mutex)(&iio_back_lock);
+ list_for_each_entry(back, &iio_back_list, entry) {
+ if (!device_match_fwnode(back->dev, fwnode_back))
+ continue;
+
+ fwnode_handle_put(fwnode_back);
+ ret = __devm_iio_backend_get(dev, back);
+ if (ret)
+ return ERR_PTR(ret);
+
+ back->idx = index;
+
+ return back;
+ }
+
+ fwnode_handle_put(fwnode_back);
+ return ERR_PTR(-EPROBE_DEFER);
+}
+
+/**
+ * devm_iio_backend_get_by_index - Device managed backend device get by index
+ * @dev: Consumer device for the backend
+ * @index: Index of the backend in the io-backends property
+ *
+ * Get's the backend at @index associated with @dev.
+ *
+ * RETURNS:
+ * A backend pointer, negative error pointer otherwise.
+ */
+struct iio_backend *devm_iio_backend_get_by_index(struct device *dev,
+ unsigned int index)
+{
+ return __devm_iio_backend_fwnode_get_by_index(dev, dev_fwnode(dev),
+ index);
+}
+EXPORT_SYMBOL_NS_GPL(devm_iio_backend_get_by_index, "IIO_BACKEND");
+
/**
* devm_iio_backend_fwnode_get - Device managed backend firmware node get
* @dev: Consumer device for the backend
diff --git a/include/linux/iio/backend.h b/include/linux/iio/backend.h
index 7f815f3fed6a..8f18df0ca896 100644
--- a/include/linux/iio/backend.h
+++ b/include/linux/iio/backend.h
@@ -237,6 +237,8 @@ int iio_backend_extend_chan_spec(struct iio_backend *back,
struct iio_chan_spec *chan);
void *iio_backend_get_priv(const struct iio_backend *conv);
struct iio_backend *devm_iio_backend_get(struct device *dev, const char *name);
+struct iio_backend *devm_iio_backend_get_by_index(struct device *dev,
+ unsigned int index);
struct iio_backend *devm_iio_backend_fwnode_get(struct device *dev,
const char *name,
struct fwnode_handle *fwnode);
--
2.43.0
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v2 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support
2026-02-06 16:07 [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
2026-02-06 16:07 ` [PATCH v2 1/4] spi: allow ancillary devices to share parent's chip selects Antoniu Miclaus
2026-02-06 16:07 ` [PATCH v2 2/4] iio: backend: add devm_iio_backend_get_by_index() Antoniu Miclaus
@ 2026-02-06 16:07 ` Antoniu Miclaus
2026-02-07 10:41 ` Krzysztof Kozlowski
2026-02-06 16:07 ` [PATCH v2 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
` (2 subsequent siblings)
5 siblings, 1 reply; 35+ messages in thread
From: Antoniu Miclaus @ 2026-02-06 16:07 UTC (permalink / raw)
To: Lars-Peter Clausen, Michael Hennerich, Antoniu Miclaus,
Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Olivier Moysan,
Mark Brown, linux-iio, devicetree, linux-kernel, linux-spi
Add support for the AD4880, a dual-channel 20-bit 40MSPS SAR ADC
with integrated fully differential amplifiers (FDA).
The AD4880 has two independent ADC channels, each with its own SPI
configuration interface. This requires:
- Two entries in reg property for primary and secondary channel chip selects
- Two io-backends entries for the two data channels
Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
---
Changes in v2:
- Replace custom adi,aux-spi-cs property with standard reg property
containing two entries for multi-channel devices
- Add conditional schema validation for reg and io-backends based on
compatible string
- Update example to use reg = <0 1> instead of adi,aux-spi-cs
- Add AD4880 datasheet link
.../bindings/iio/adc/adi,ad4080.yaml | 51 ++++++++++++++++++-
1 file changed, 49 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml
index ccd6a0ac1539..7108a91bb0bf 100644
--- a/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml
@@ -18,7 +18,11 @@ description: |
service a wide variety of precision, wide bandwidth data acquisition
applications.
+ The AD4880 is a dual-channel variant with two independent ADC channels,
+ each with its own SPI configuration interface.
+
https://www.analog.com/media/en/technical-documentation/data-sheets/ad4080.pdf
+ https://www.analog.com/media/en/technical-documentation/data-sheets/ad4880.pdf
$ref: /schemas/spi/spi-peripheral-props.yaml#
@@ -31,9 +35,15 @@ properties:
- adi,ad4084
- adi,ad4086
- adi,ad4087
+ - adi,ad4880
reg:
- maxItems: 1
+ minItems: 1
+ maxItems: 2
+ description:
+ SPI chip select(s). For single-channel devices, one chip select.
+ For multi-channel devices like AD4880, two chip selects are required
+ as each channel has its own SPI configuration interface.
spi-max-frequency:
description: Configuration of the SPI bus.
@@ -57,7 +67,8 @@ properties:
vrefin-supply: true
io-backends:
- maxItems: 1
+ minItems: 1
+ maxItems: 2
adi,lvds-cnv-enable:
description: Enable the LVDS signal type on the CNV pin. Default is CMOS.
@@ -78,6 +89,25 @@ required:
- vdd33-supply
- vrefin-supply
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: adi,ad4880
+ then:
+ properties:
+ reg:
+ minItems: 2
+ io-backends:
+ minItems: 2
+ else:
+ properties:
+ reg:
+ maxItems: 1
+ io-backends:
+ maxItems: 1
+
additionalProperties: false
examples:
@@ -98,4 +128,21 @@ examples:
io-backends = <&iio_backend>;
};
};
+ - |
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ adc@0 {
+ compatible = "adi,ad4880";
+ reg = <0 1>;
+ spi-max-frequency = <10000000>;
+ vdd33-supply = <&vdd33>;
+ vddldo-supply = <&vddldo>;
+ vrefin-supply = <&vrefin>;
+ clocks = <&cnv>;
+ clock-names = "cnv";
+ io-backends = <&iio_backend_cha>, <&iio_backend_chb>;
+ };
+ };
...
--
2.43.0
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v2 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-06 16:07 [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
` (2 preceding siblings ...)
2026-02-06 16:07 ` [PATCH v2 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support Antoniu Miclaus
@ 2026-02-06 16:07 ` Antoniu Miclaus
2026-02-07 15:04 ` Jonathan Cameron
` (2 more replies)
2026-02-08 12:50 ` [PATCH v2 0/4] " Andy Shevchenko
2026-02-25 19:07 ` (subset) " Mark Brown
5 siblings, 3 replies; 35+ messages in thread
From: Antoniu Miclaus @ 2026-02-06 16:07 UTC (permalink / raw)
To: Antoniu Miclaus, Lars-Peter Clausen, Michael Hennerich,
Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Olivier Moysan,
Mark Brown, linux-iio, devicetree, linux-kernel, linux-spi
Add support for the AD4880, a dual-channel 20-bit 40MSPS SAR ADC with
integrated fully differential amplifiers (FDA).
The AD4880 has two independent ADC channels, each with its own SPI
configuration interface. The driver uses spi_new_ancillary_device() to
create an additional SPI device for the second channel, allowing both
channels to share the same SPI bus with different chip selects.
Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
---
Changes in v2:
- Use second reg entry instead of custom adi,aux-spi-cs property for
secondary channel chip select
- Use devm_iio_backend_get_by_index() instead of named backends for
multi-channel backend lookup
- Separate iio_info structures for single-channel (ad4080) and
multi-channel (ad4880) devices
- Keep filter_type as shared attribute for single-channel devices,
use per-channel only for AD4880
- Add separate AD4880_CHANNEL_DEFINE macro with per-channel attributes
drivers/iio/adc/ad4080.c | 256 +++++++++++++++++++++++++++++++--------
1 file changed, 205 insertions(+), 51 deletions(-)
diff --git a/drivers/iio/adc/ad4080.c b/drivers/iio/adc/ad4080.c
index 7cf3b6ed7940..2b26f8a4d548 100644
--- a/drivers/iio/adc/ad4080.c
+++ b/drivers/iio/adc/ad4080.c
@@ -16,6 +16,7 @@
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
@@ -131,6 +132,9 @@
#define AD4084_CHIP_ID 0x0054
#define AD4086_CHIP_ID 0x0056
#define AD4087_CHIP_ID 0x0057
+#define AD4880_CHIP_ID 0x0750
+
+#define AD4080_MAX_CHANNELS 2
#define AD4080_LVDS_CNV_CLK_CNT_MAX 7
@@ -176,8 +180,9 @@ struct ad4080_chip_info {
};
struct ad4080_state {
- struct regmap *regmap;
- struct iio_backend *back;
+ struct spi_device *spi[AD4080_MAX_CHANNELS];
+ struct regmap *regmap[AD4080_MAX_CHANNELS];
+ struct iio_backend *back[AD4080_MAX_CHANNELS];
const struct ad4080_chip_info *info;
/*
* Synchronize access to members the of driver state, and ensure
@@ -203,10 +208,11 @@ static int ad4080_reg_access(struct iio_dev *indio_dev, unsigned int reg,
{
struct ad4080_state *st = iio_priv(indio_dev);
+ /* Use channel 0 regmap for debugfs access */
if (readval)
- return regmap_read(st->regmap, reg, readval);
+ return regmap_read(st->regmap[0], reg, readval);
- return regmap_write(st->regmap, reg, writeval);
+ return regmap_write(st->regmap[0], reg, writeval);
}
static int ad4080_get_scale(struct ad4080_state *st, int *val, int *val2)
@@ -227,8 +233,9 @@ static unsigned int ad4080_get_dec_rate(struct iio_dev *dev,
struct ad4080_state *st = iio_priv(dev);
int ret;
unsigned int data;
+ unsigned int ch = chan->channel;
- ret = regmap_read(st->regmap, AD4080_REG_FILTER_CONFIG, &data);
+ ret = regmap_read(st->regmap[ch], AD4080_REG_FILTER_CONFIG, &data);
if (ret)
return ret;
@@ -240,13 +247,14 @@ static int ad4080_set_dec_rate(struct iio_dev *dev,
unsigned int mode)
{
struct ad4080_state *st = iio_priv(dev);
+ unsigned int ch = chan->channel;
guard(mutex)(&st->lock);
if ((st->filter_type >= SINC_5 && mode >= 512) || mode < 2)
return -EINVAL;
- return regmap_update_bits(st->regmap, AD4080_REG_FILTER_CONFIG,
+ return regmap_update_bits(st->regmap[ch], AD4080_REG_FILTER_CONFIG,
AD4080_FILTER_CONFIG_SINC_DEC_RATE_MSK,
FIELD_PREP(AD4080_FILTER_CONFIG_SINC_DEC_RATE_MSK,
(ilog2(mode) - 1)));
@@ -304,23 +312,23 @@ static int ad4080_write_raw(struct iio_dev *indio_dev,
}
}
-static int ad4080_lvds_sync_write(struct ad4080_state *st)
+static int ad4080_lvds_sync_write(struct ad4080_state *st, unsigned int ch)
{
- struct device *dev = regmap_get_device(st->regmap);
+ struct device *dev = regmap_get_device(st->regmap[ch]);
int ret;
- ret = regmap_set_bits(st->regmap, AD4080_REG_ADC_DATA_INTF_CONFIG_A,
+ ret = regmap_set_bits(st->regmap[ch], AD4080_REG_ADC_DATA_INTF_CONFIG_A,
AD4080_ADC_DATA_INTF_CONFIG_A_INTF_CHK_EN);
if (ret)
return ret;
- ret = iio_backend_interface_data_align(st->back, 10000);
+ ret = iio_backend_interface_data_align(st->back[ch], 10000);
if (ret)
return dev_err_probe(dev, ret,
"Data alignment process failed\n");
dev_dbg(dev, "Success: Pattern correct and Locked!\n");
- return regmap_clear_bits(st->regmap, AD4080_REG_ADC_DATA_INTF_CONFIG_A,
+ return regmap_clear_bits(st->regmap[ch], AD4080_REG_ADC_DATA_INTF_CONFIG_A,
AD4080_ADC_DATA_INTF_CONFIG_A_INTF_CHK_EN);
}
@@ -329,9 +337,10 @@ static int ad4080_get_filter_type(struct iio_dev *dev,
{
struct ad4080_state *st = iio_priv(dev);
unsigned int data;
+ unsigned int ch = chan->channel;
int ret;
- ret = regmap_read(st->regmap, AD4080_REG_FILTER_CONFIG, &data);
+ ret = regmap_read(st->regmap[ch], AD4080_REG_FILTER_CONFIG, &data);
if (ret)
return ret;
@@ -343,6 +352,7 @@ static int ad4080_set_filter_type(struct iio_dev *dev,
unsigned int mode)
{
struct ad4080_state *st = iio_priv(dev);
+ unsigned int ch = chan->channel;
int dec_rate;
int ret;
@@ -355,11 +365,11 @@ static int ad4080_set_filter_type(struct iio_dev *dev,
if (mode >= SINC_5 && dec_rate >= 512)
return -EINVAL;
- ret = iio_backend_filter_type_set(st->back, mode);
+ ret = iio_backend_filter_type_set(st->back[ch], mode);
if (ret)
return ret;
- ret = regmap_update_bits(st->regmap, AD4080_REG_FILTER_CONFIG,
+ ret = regmap_update_bits(st->regmap[ch], AD4080_REG_FILTER_CONFIG,
AD4080_FILTER_CONFIG_FILTER_SEL_MSK,
FIELD_PREP(AD4080_FILTER_CONFIG_FILTER_SEL_MSK,
mode));
@@ -399,6 +409,29 @@ static int ad4080_read_avail(struct iio_dev *indio_dev,
}
}
+static int ad4880_update_scan_mode(struct iio_dev *indio_dev,
+ const unsigned long *scan_mask)
+{
+ struct ad4080_state *st = iio_priv(indio_dev);
+ unsigned int ch;
+ int ret;
+
+ for (ch = 0; ch < st->info->num_channels; ch++) {
+ /*
+ * Each backend has a single channel (channel 0 from the
+ * backend's perspective), so always use channel index 0.
+ */
+ if (test_bit(ch, scan_mask))
+ ret = iio_backend_chan_enable(st->back[ch], 0);
+ else
+ ret = iio_backend_chan_disable(st->back[ch], 0);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
static const struct iio_info ad4080_iio_info = {
.debugfs_reg_access = ad4080_reg_access,
.read_raw = ad4080_read_raw,
@@ -406,6 +439,19 @@ static const struct iio_info ad4080_iio_info = {
.read_avail = ad4080_read_avail,
};
+/*
+ * AD4880 needs update_scan_mode to enable/disable individual backend channels.
+ * Single-channel devices don't need this as their backends may not implement
+ * chan_enable/chan_disable operations.
+ */
+static const struct iio_info ad4880_iio_info = {
+ .debugfs_reg_access = ad4080_reg_access,
+ .read_raw = ad4080_read_raw,
+ .write_raw = ad4080_write_raw,
+ .read_avail = ad4080_read_avail,
+ .update_scan_mode = ad4880_update_scan_mode,
+};
+
static const struct iio_enum ad4080_filter_type_enum = {
.items = ad4080_filter_type_iio_enum,
.num_items = ARRAY_SIZE(ad4080_filter_type_iio_enum),
@@ -420,17 +466,28 @@ static struct iio_chan_spec_ext_info ad4080_ext_info[] = {
{ }
};
-#define AD4080_CHANNEL_DEFINE(bits, storage) { \
+/*
+ * AD4880 needs per-channel filter configuration since each channel has
+ * its own independent ADC with separate SPI interface.
+ */
+static struct iio_chan_spec_ext_info ad4880_ext_info[] = {
+ IIO_ENUM("filter_type", IIO_SEPARATE, &ad4080_filter_type_enum),
+ IIO_ENUM_AVAILABLE("filter_type", IIO_SEPARATE,
+ &ad4080_filter_type_enum),
+ { }
+};
+
+#define AD4080_CHANNEL_DEFINE(bits, storage, idx) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
- .channel = 0, \
+ .channel = (idx), \
.info_mask_separate = BIT(IIO_CHAN_INFO_SCALE), \
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
.info_mask_shared_by_all_available = \
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
.ext_info = ad4080_ext_info, \
- .scan_index = 0, \
+ .scan_index = (idx), \
.scan_type = { \
.sign = 's', \
.realbits = (bits), \
@@ -438,17 +495,45 @@ static struct iio_chan_spec_ext_info ad4080_ext_info[] = {
}, \
}
-static const struct iio_chan_spec ad4080_channel = AD4080_CHANNEL_DEFINE(20, 32);
+/*
+ * AD4880 has per-channel attributes (filter_type, oversampling_ratio,
+ * sampling_frequency) since each channel has its own independent ADC
+ * with separate SPI configuration interface.
+ */
+#define AD4880_CHANNEL_DEFINE(bits, storage, idx) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = (idx), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
+ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
+ .info_mask_separate_available = \
+ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
+ .ext_info = ad4880_ext_info, \
+ .scan_index = (idx), \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = (bits), \
+ .storagebits = (storage), \
+ }, \
+}
+
+static const struct iio_chan_spec ad4080_channel = AD4080_CHANNEL_DEFINE(20, 32, 0);
-static const struct iio_chan_spec ad4081_channel = AD4080_CHANNEL_DEFINE(20, 32);
+static const struct iio_chan_spec ad4081_channel = AD4080_CHANNEL_DEFINE(20, 32, 0);
-static const struct iio_chan_spec ad4083_channel = AD4080_CHANNEL_DEFINE(16, 16);
+static const struct iio_chan_spec ad4083_channel = AD4080_CHANNEL_DEFINE(16, 16, 0);
-static const struct iio_chan_spec ad4084_channel = AD4080_CHANNEL_DEFINE(16, 16);
+static const struct iio_chan_spec ad4084_channel = AD4080_CHANNEL_DEFINE(16, 16, 0);
-static const struct iio_chan_spec ad4086_channel = AD4080_CHANNEL_DEFINE(14, 16);
+static const struct iio_chan_spec ad4086_channel = AD4080_CHANNEL_DEFINE(14, 16, 0);
-static const struct iio_chan_spec ad4087_channel = AD4080_CHANNEL_DEFINE(14, 16);
+static const struct iio_chan_spec ad4087_channel = AD4080_CHANNEL_DEFINE(14, 16, 0);
+
+static const struct iio_chan_spec ad4880_channels[] = {
+ AD4880_CHANNEL_DEFINE(20, 32, 0),
+ AD4880_CHANNEL_DEFINE(20, 32, 1),
+};
static const struct ad4080_chip_info ad4080_chip_info = {
.name = "ad4080",
@@ -510,25 +595,34 @@ static const struct ad4080_chip_info ad4087_chip_info = {
.lvds_cnv_clk_cnt_max = 1,
};
-static int ad4080_setup(struct iio_dev *indio_dev)
+static const struct ad4080_chip_info ad4880_chip_info = {
+ .name = "ad4880",
+ .product_id = AD4880_CHIP_ID,
+ .scale_table = ad4080_scale_table,
+ .num_scales = ARRAY_SIZE(ad4080_scale_table),
+ .num_channels = 2,
+ .channels = ad4880_channels,
+ .lvds_cnv_clk_cnt_max = AD4080_LVDS_CNV_CLK_CNT_MAX,
+};
+
+static int ad4080_setup_channel(struct ad4080_state *st, unsigned int ch)
{
- struct ad4080_state *st = iio_priv(indio_dev);
- struct device *dev = regmap_get_device(st->regmap);
+ struct device *dev = regmap_get_device(st->regmap[ch]);
__le16 id_le;
u16 id;
int ret;
- ret = regmap_write(st->regmap, AD4080_REG_INTERFACE_CONFIG_A,
+ ret = regmap_write(st->regmap[ch], AD4080_REG_INTERFACE_CONFIG_A,
AD4080_INTERFACE_CONFIG_A_SW_RESET);
if (ret)
return ret;
- ret = regmap_write(st->regmap, AD4080_REG_INTERFACE_CONFIG_A,
+ ret = regmap_write(st->regmap[ch], AD4080_REG_INTERFACE_CONFIG_A,
AD4080_INTERFACE_CONFIG_A_SDO_ENABLE);
if (ret)
return ret;
- ret = regmap_bulk_read(st->regmap, AD4080_REG_PRODUCT_ID_L, &id_le,
+ ret = regmap_bulk_read(st->regmap[ch], AD4080_REG_PRODUCT_ID_L, &id_le,
sizeof(id_le));
if (ret)
return ret;
@@ -537,18 +631,18 @@ static int ad4080_setup(struct iio_dev *indio_dev)
if (id != st->info->product_id)
dev_info(dev, "Unrecognized CHIP_ID 0x%X\n", id);
- ret = regmap_set_bits(st->regmap, AD4080_REG_GPIO_CONFIG_A,
+ ret = regmap_set_bits(st->regmap[ch], AD4080_REG_GPIO_CONFIG_A,
AD4080_GPIO_CONFIG_A_GPO_1_EN);
if (ret)
return ret;
- ret = regmap_write(st->regmap, AD4080_REG_GPIO_CONFIG_B,
+ ret = regmap_write(st->regmap[ch], AD4080_REG_GPIO_CONFIG_B,
FIELD_PREP(AD4080_GPIO_CONFIG_B_GPIO_1_SEL_MSK,
AD4080_GPIO_CONFIG_B_GPIO_FILTER_RES_RDY));
if (ret)
return ret;
- ret = iio_backend_num_lanes_set(st->back, st->num_lanes);
+ ret = iio_backend_num_lanes_set(st->back[ch], st->num_lanes);
if (ret)
return ret;
@@ -556,7 +650,7 @@ static int ad4080_setup(struct iio_dev *indio_dev)
return 0;
/* Set maximum LVDS Data Transfer Latency */
- ret = regmap_update_bits(st->regmap,
+ ret = regmap_update_bits(st->regmap[ch],
AD4080_REG_ADC_DATA_INTF_CONFIG_B,
AD4080_ADC_DATA_INTF_CONFIG_B_LVDS_CNV_CLK_CNT_MSK,
FIELD_PREP(AD4080_ADC_DATA_INTF_CONFIG_B_LVDS_CNV_CLK_CNT_MSK,
@@ -565,24 +659,39 @@ static int ad4080_setup(struct iio_dev *indio_dev)
return ret;
if (st->num_lanes > 1) {
- ret = regmap_set_bits(st->regmap, AD4080_REG_ADC_DATA_INTF_CONFIG_A,
+ ret = regmap_set_bits(st->regmap[ch], AD4080_REG_ADC_DATA_INTF_CONFIG_A,
AD4080_ADC_DATA_INTF_CONFIG_A_SPI_LVDS_LANES);
if (ret)
return ret;
}
- ret = regmap_set_bits(st->regmap,
+ ret = regmap_set_bits(st->regmap[ch],
AD4080_REG_ADC_DATA_INTF_CONFIG_B,
AD4080_ADC_DATA_INTF_CONFIG_B_LVDS_CNV_EN);
if (ret)
return ret;
- return ad4080_lvds_sync_write(st);
+ return ad4080_lvds_sync_write(st, ch);
+}
+
+static int ad4080_setup(struct iio_dev *indio_dev)
+{
+ struct ad4080_state *st = iio_priv(indio_dev);
+ unsigned int ch;
+ int ret;
+
+ for (ch = 0; ch < st->info->num_channels; ch++) {
+ ret = ad4080_setup_channel(st, ch);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
}
static int ad4080_properties_parse(struct ad4080_state *st)
{
- struct device *dev = regmap_get_device(st->regmap);
+ struct device *dev = regmap_get_device(st->regmap[0]);
st->lvds_cnv_en = device_property_read_bool(dev, "adi,lvds-cnv-enable");
@@ -596,12 +705,18 @@ static int ad4080_properties_parse(struct ad4080_state *st)
return 0;
}
+static void ad4080_unregister_ancillary(void *data)
+{
+ spi_unregister_device(data);
+}
+
static int ad4080_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
struct device *dev = &spi->dev;
struct ad4080_state *st;
struct clk *clk;
+ unsigned int ch;
int ret;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
@@ -610,6 +725,10 @@ static int ad4080_probe(struct spi_device *spi)
st = iio_priv(indio_dev);
+ st->info = spi_get_device_match_data(spi);
+ if (!st->info)
+ return -ENODEV;
+
ret = devm_regulator_bulk_get_enable(dev,
ARRAY_SIZE(ad4080_power_supplies),
ad4080_power_supplies);
@@ -617,13 +736,37 @@ static int ad4080_probe(struct spi_device *spi)
return dev_err_probe(dev, ret,
"failed to get and enable supplies\n");
- st->regmap = devm_regmap_init_spi(spi, &ad4080_regmap_config);
- if (IS_ERR(st->regmap))
- return PTR_ERR(st->regmap);
+ /* Setup primary SPI device (channel 0) */
+ st->spi[0] = spi;
+ st->regmap[0] = devm_regmap_init_spi(spi, &ad4080_regmap_config);
+ if (IS_ERR(st->regmap[0]))
+ return PTR_ERR(st->regmap[0]);
- st->info = spi_get_device_match_data(spi);
- if (!st->info)
- return -ENODEV;
+ /* Setup ancillary SPI device for additional channel (AD4880) */
+ if (st->info->num_channels > 1) {
+ u32 reg[2];
+
+ ret = device_property_read_u32_array(dev, "reg", reg,
+ ARRAY_SIZE(reg));
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "missing second reg entry for multi-channel device\n");
+
+ st->spi[1] = spi_new_ancillary_device(spi, reg[1]);
+ if (IS_ERR(st->spi[1]))
+ return dev_err_probe(dev, PTR_ERR(st->spi[1]),
+ "failed to register ancillary device\n");
+
+ ret = devm_add_action_or_reset(dev, ad4080_unregister_ancillary,
+ st->spi[1]);
+ if (ret)
+ return ret;
+
+ st->regmap[1] = devm_regmap_init_spi(st->spi[1],
+ &ad4080_regmap_config);
+ if (IS_ERR(st->regmap[1]))
+ return PTR_ERR(st->regmap[1]);
+ }
ret = devm_mutex_init(dev, &st->lock);
if (ret)
@@ -632,7 +775,8 @@ static int ad4080_probe(struct spi_device *spi)
indio_dev->name = st->info->name;
indio_dev->channels = st->info->channels;
indio_dev->num_channels = st->info->num_channels;
- indio_dev->info = &ad4080_iio_info;
+ indio_dev->info = st->info->num_channels > 1 ?
+ &ad4880_iio_info : &ad4080_iio_info;
ret = ad4080_properties_parse(st);
if (ret)
@@ -644,15 +788,23 @@ static int ad4080_probe(struct spi_device *spi)
st->clk_rate = clk_get_rate(clk);
- st->back = devm_iio_backend_get(dev, NULL);
- if (IS_ERR(st->back))
- return PTR_ERR(st->back);
+ /* Get backends for all channels */
+ for (ch = 0; ch < st->info->num_channels; ch++) {
+ st->back[ch] = devm_iio_backend_get_by_index(dev, ch);
+ if (IS_ERR(st->back[ch]))
+ return PTR_ERR(st->back[ch]);
- ret = devm_iio_backend_request_buffer(dev, st->back, indio_dev);
- if (ret)
- return ret;
+ ret = devm_iio_backend_enable(dev, st->back[ch]);
+ if (ret)
+ return ret;
+ }
- ret = devm_iio_backend_enable(dev, st->back);
+ /*
+ * Request buffer from the first backend only. For multi-channel
+ * devices (e.g., AD4880), all backends share a single IIO buffer
+ * as data from all ADC channels is interleaved into one stream.
+ */
+ ret = devm_iio_backend_request_buffer(dev, st->back[0], indio_dev);
if (ret)
return ret;
@@ -670,6 +822,7 @@ static const struct spi_device_id ad4080_id[] = {
{ "ad4084", (kernel_ulong_t)&ad4084_chip_info },
{ "ad4086", (kernel_ulong_t)&ad4086_chip_info },
{ "ad4087", (kernel_ulong_t)&ad4087_chip_info },
+ { "ad4880", (kernel_ulong_t)&ad4880_chip_info },
{ }
};
MODULE_DEVICE_TABLE(spi, ad4080_id);
@@ -681,6 +834,7 @@ static const struct of_device_id ad4080_of_match[] = {
{ .compatible = "adi,ad4084", &ad4084_chip_info },
{ .compatible = "adi,ad4086", &ad4086_chip_info },
{ .compatible = "adi,ad4087", &ad4087_chip_info },
+ { .compatible = "adi,ad4880", &ad4880_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, ad4080_of_match);
--
2.43.0
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support
2026-02-06 16:07 ` [PATCH v2 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support Antoniu Miclaus
@ 2026-02-07 10:41 ` Krzysztof Kozlowski
2026-02-08 9:16 ` Nuno Sá
0 siblings, 1 reply; 35+ messages in thread
From: Krzysztof Kozlowski @ 2026-02-07 10:41 UTC (permalink / raw)
To: Antoniu Miclaus
Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On Fri, Feb 06, 2026 at 06:07:15PM +0200, Antoniu Miclaus wrote:
> Add support for the AD4880, a dual-channel 20-bit 40MSPS SAR ADC
> with integrated fully differential amplifiers (FDA).
>
> The AD4880 has two independent ADC channels, each with its own SPI
> configuration interface. This requires:
> - Two entries in reg property for primary and secondary channel chip selects
Please wrap commit message according to Linux coding style / submission
process (neither too early nor over the limit):
https://elixir.bootlin.com/linux/v6.4-rc1/source/Documentation/process/submitting-patches.rst#L597
Please run scripts/checkpatch.pl on the patches and fix reported
warnings.
> - Two io-backends entries for the two data channels
>
> Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
> ---
> Changes in v2:
> - Replace custom adi,aux-spi-cs property with standard reg property
> containing two entries for multi-channel devices
> - Add conditional schema validation for reg and io-backends based on
> compatible string
> - Update example to use reg = <0 1> instead of adi,aux-spi-cs
> - Add AD4880 datasheet link
>
> .../bindings/iio/adc/adi,ad4080.yaml | 51 ++++++++++++++++++-
> 1 file changed, 49 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml
> index ccd6a0ac1539..7108a91bb0bf 100644
> --- a/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml
> +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml
> @@ -18,7 +18,11 @@ description: |
> service a wide variety of precision, wide bandwidth data acquisition
> applications.
>
> + The AD4880 is a dual-channel variant with two independent ADC channels,
> + each with its own SPI configuration interface.
> +
> https://www.analog.com/media/en/technical-documentation/data-sheets/ad4080.pdf
> + https://www.analog.com/media/en/technical-documentation/data-sheets/ad4880.pdf
>
> $ref: /schemas/spi/spi-peripheral-props.yaml#
>
> @@ -31,9 +35,15 @@ properties:
> - adi,ad4084
> - adi,ad4086
> - adi,ad4087
> + - adi,ad4880
>
> reg:
> - maxItems: 1
> + minItems: 1
> + maxItems: 2
> + description:
> + SPI chip select(s). For single-channel devices, one chip select.
> + For multi-channel devices like AD4880, two chip selects are required
> + as each channel has its own SPI configuration interface.
>
> spi-max-frequency:
> description: Configuration of the SPI bus.
> @@ -57,7 +67,8 @@ properties:
> vrefin-supply: true
>
> io-backends:
> - maxItems: 1
> + minItems: 1
> + maxItems: 2
Instead list the items with minItems, so the order is defined.
>
> adi,lvds-cnv-enable:
> description: Enable the LVDS signal type on the CNV pin. Default is CMOS.
> @@ -78,6 +89,25 @@ required:
> - vdd33-supply
> - vrefin-supply
>
> +allOf:
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: adi,ad4880
> + then:
> + properties:
> + reg:
> + minItems: 2
> + io-backends:
> + minItems: 2
> + else:
> + properties:
> + reg:
> + maxItems: 1
> + io-backends:
> + maxItems: 1
> +
> additionalProperties: false
>
> examples:
> @@ -98,4 +128,21 @@ examples:
> io-backends = <&iio_backend>;
> };
> };
> + - |
> + spi {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + adc@0 {
> + compatible = "adi,ad4880";
> + reg = <0 1>;
<0>, <1>, no? You want two separate chip selects, right? (size-cells is
0).
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 2/4] iio: backend: add devm_iio_backend_get_by_index()
2026-02-06 16:07 ` [PATCH v2 2/4] iio: backend: add devm_iio_backend_get_by_index() Antoniu Miclaus
@ 2026-02-07 14:57 ` Jonathan Cameron
2026-02-07 18:13 ` David Lechner
2026-02-08 9:24 ` Nuno Sá
2 siblings, 0 replies; 35+ messages in thread
From: Jonathan Cameron @ 2026-02-07 14:57 UTC (permalink / raw)
To: Antoniu Miclaus
Cc: Lars-Peter Clausen, Michael Hennerich, David Lechner,
Nuno Sá, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Olivier Moysan, Mark Brown, linux-iio, devicetree,
linux-kernel, linux-spi
On Fri, 6 Feb 2026 18:07:14 +0200
Antoniu Miclaus <antoniu.miclaus@analog.com> wrote:
> Add a new function to get an IIO backend by its index in the
> io-backends device tree property. This is useful for multi-channel
> devices that have multiple backends, where looking up by index is
> more straightforward than using named backends.
>
> The new function directly uses the index to find the backend reference
> in the io-backends property, avoiding the need for io-backend-names.
>
> Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
One thing inline.
> ---
> drivers/iio/industrialio-backend.c | 51 ++++++++++++++++++++++++++++++
> include/linux/iio/backend.h | 2 ++
> 2 files changed, 53 insertions(+)
>
> diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-backend.c
> index 447b694d6d5f..3b692d48481e 100644
> --- a/drivers/iio/industrialio-backend.c
> +++ b/drivers/iio/industrialio-backend.c
> @@ -1008,6 +1008,57 @@ struct iio_backend *devm_iio_backend_get(struct device *dev, const char *name)
> }
> EXPORT_SYMBOL_NS_GPL(devm_iio_backend_get, "IIO_BACKEND");
>
> +static struct iio_backend *
> +__devm_iio_backend_fwnode_get_by_index(struct device *dev,
> + struct fwnode_handle *fwnode,
> + unsigned int index)
> +{
> + struct fwnode_handle *fwnode_back;
> + struct iio_backend *back;
> + int ret;
> +
> + fwnode_back = fwnode_find_reference(fwnode, "io-backends", index);
Applies more generally in this file, but does holding the fwnode over the
__dev_iio_backed_get() below matter? If not
struct fwnode_handle *fwnode_back __free(fwnode_handle) =
fwnode_find_reference(fwnode, "io-backends", index);
and you can drop the various fwnode_handle_put() calls.
> + if (IS_ERR(fwnode_back))
> + return dev_err_cast_probe(dev, fwnode_back,
> + "Cannot get Firmware reference\n");
> +
> + guard(mutex)(&iio_back_lock);
> + list_for_each_entry(back, &iio_back_list, entry) {
> + if (!device_match_fwnode(back->dev, fwnode_back))
> + continue;
> +
> + fwnode_handle_put(fwnode_back);
> + ret = __devm_iio_backend_get(dev, back);
> + if (ret)
> + return ERR_PTR(ret);
> +
> + back->idx = index;
> +
> + return back;
> + }
> +
> + fwnode_handle_put(fwnode_back);
> + return ERR_PTR(-EPROBE_DEFER);
> +}
> +
> +/**
> + * devm_iio_backend_get_by_index - Device managed backend device get by index
> + * @dev: Consumer device for the backend
> + * @index: Index of the backend in the io-backends property
> + *
> + * Get's the backend at @index associated with @dev.
> + *
> + * RETURNS:
> + * A backend pointer, negative error pointer otherwise.
> + */
> +struct iio_backend *devm_iio_backend_get_by_index(struct device *dev,
> + unsigned int index)
> +{
> + return __devm_iio_backend_fwnode_get_by_index(dev, dev_fwnode(dev),
> + index);
> +}
> +EXPORT_SYMBOL_NS_GPL(devm_iio_backend_get_by_index, "IIO_BACKEND");
> +
> /**
> * devm_iio_backend_fwnode_get - Device managed backend firmware node get
> * @dev: Consumer device for the backend
> diff --git a/include/linux/iio/backend.h b/include/linux/iio/backend.h
> index 7f815f3fed6a..8f18df0ca896 100644
> --- a/include/linux/iio/backend.h
> +++ b/include/linux/iio/backend.h
> @@ -237,6 +237,8 @@ int iio_backend_extend_chan_spec(struct iio_backend *back,
> struct iio_chan_spec *chan);
> void *iio_backend_get_priv(const struct iio_backend *conv);
> struct iio_backend *devm_iio_backend_get(struct device *dev, const char *name);
> +struct iio_backend *devm_iio_backend_get_by_index(struct device *dev,
> + unsigned int index);
> struct iio_backend *devm_iio_backend_fwnode_get(struct device *dev,
> const char *name,
> struct fwnode_handle *fwnode);
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-06 16:07 ` [PATCH v2 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
@ 2026-02-07 15:04 ` Jonathan Cameron
2026-02-07 18:29 ` David Lechner
2026-02-08 9:26 ` Nuno Sá
2 siblings, 0 replies; 35+ messages in thread
From: Jonathan Cameron @ 2026-02-07 15:04 UTC (permalink / raw)
To: Antoniu Miclaus
Cc: Lars-Peter Clausen, Michael Hennerich, David Lechner,
Nuno Sá, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Olivier Moysan, Mark Brown, linux-iio, devicetree,
linux-kernel, linux-spi
On Fri, 6 Feb 2026 18:07:16 +0200
Antoniu Miclaus <antoniu.miclaus@analog.com> wrote:
> Add support for the AD4880, a dual-channel 20-bit 40MSPS SAR ADC with
> integrated fully differential amplifiers (FDA).
>
> The AD4880 has two independent ADC channels, each with its own SPI
> configuration interface. The driver uses spi_new_ancillary_device() to
> create an additional SPI device for the second channel, allowing both
> channels to share the same SPI bus with different chip selects.
>
> Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
Hi Antoniu
Just one minor comment from me.
Thanks,
Jonathan
> ---
> Changes in v2:
> - Use second reg entry instead of custom adi,aux-spi-cs property for
> secondary channel chip select
> - Use devm_iio_backend_get_by_index() instead of named backends for
> multi-channel backend lookup
> - Separate iio_info structures for single-channel (ad4080) and
> multi-channel (ad4880) devices
> - Keep filter_type as shared attribute for single-channel devices,
> use per-channel only for AD4880
> - Add separate AD4880_CHANNEL_DEFINE macro with per-channel attributes
>
> drivers/iio/adc/ad4080.c | 256 +++++++++++++++++++++++++++++++--------
> 1 file changed, 205 insertions(+), 51 deletions(-)
>
> diff --git a/drivers/iio/adc/ad4080.c b/drivers/iio/adc/ad4080.c
> index 7cf3b6ed7940..2b26f8a4d548 100644
> --- a/drivers/iio/adc/ad4080.c
> +++ b/drivers/iio/adc/ad4080.c
>
> @@ -617,13 +736,37 @@ static int ad4080_probe(struct spi_device *spi)
> return dev_err_probe(dev, ret,
> "failed to get and enable supplies\n");
>
> - st->regmap = devm_regmap_init_spi(spi, &ad4080_regmap_config);
> - if (IS_ERR(st->regmap))
> - return PTR_ERR(st->regmap);
> + /* Setup primary SPI device (channel 0) */
> + st->spi[0] = spi;
> + st->regmap[0] = devm_regmap_init_spi(spi, &ad4080_regmap_config);
> + if (IS_ERR(st->regmap[0]))
> + return PTR_ERR(st->regmap[0]);
>
> - st->info = spi_get_device_match_data(spi);
> - if (!st->info)
> - return -ENODEV;
> + /* Setup ancillary SPI device for additional channel (AD4880) */
> + if (st->info->num_channels > 1) {
I wonder if this would be clearer as a loop? When there is a 2 channel device
around, a 4 channels one often shows up later.
for (int i = 1; i < st->info->num_channels; i++) {
> + u32 reg[2];
> +
> + ret = device_property_read_u32_array(dev, "reg", reg,
> + ARRAY_SIZE(reg));
> + if (ret)
> + return dev_err_probe(dev, ret,
> + "missing second reg entry for multi-channel device\n");
> +
> + st->spi[1] = spi_new_ancillary_device(spi, reg[1]);
> + if (IS_ERR(st->spi[1]))
> + return dev_err_probe(dev, PTR_ERR(st->spi[1]),
> + "failed to register ancillary device\n");
> +
> + ret = devm_add_action_or_reset(dev, ad4080_unregister_ancillary,
> + st->spi[1]);
> + if (ret)
> + return ret;
> +
> + st->regmap[1] = devm_regmap_init_spi(st->spi[1],
> + &ad4080_regmap_config);
> + if (IS_ERR(st->regmap[1]))
> + return PTR_ERR(st->regmap[1]);
> + }
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 1/4] spi: allow ancillary devices to share parent's chip selects
2026-02-06 16:07 ` [PATCH v2 1/4] spi: allow ancillary devices to share parent's chip selects Antoniu Miclaus
@ 2026-02-07 18:09 ` David Lechner
0 siblings, 0 replies; 35+ messages in thread
From: David Lechner @ 2026-02-07 18:09 UTC (permalink / raw)
To: Antoniu Miclaus, Lars-Peter Clausen, Michael Hennerich,
Jonathan Cameron, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On 2/6/26 10:07 AM, Antoniu Miclaus wrote:
> When registering an ancillary SPI device, the current code flags a chip
> select conflict with the parent device. This happens because the
> ancillary device intentionally uses one of the parent's chip selects,
> but __spi_add_device() checks against all existing devices including
> the parent.
>
> Allow this by passing the parent device pointer to __spi_add_device()
> and skipping the conflict check when the existing device is the parent.
>
...
> static int spi_dev_check(struct device *dev, void *data)
> {
> struct spi_device *spi = to_spi_device(dev);
> - struct spi_device *new_spi = data;
> + struct spi_dev_check_info *info = data;
> + struct spi_device *new_spi = info->new_spi;
> int status, idx;
>
> + /*
> + * When registering an ancillary device, skip checking against the
> + * parent device since the ancillary is intentionally using one of
> + * the parent's chip selects.
> + */
> + if (info->parent && spi == info->parent)
spi should never be NULL (or we would get a segfault later), so
if `(spi == info->parent)` should be enough.
> + return 0;
> +
Reviewed-by: David Lechner <dlechner@baylibre.com>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 2/4] iio: backend: add devm_iio_backend_get_by_index()
2026-02-06 16:07 ` [PATCH v2 2/4] iio: backend: add devm_iio_backend_get_by_index() Antoniu Miclaus
2026-02-07 14:57 ` Jonathan Cameron
@ 2026-02-07 18:13 ` David Lechner
2026-02-08 9:24 ` Nuno Sá
2 siblings, 0 replies; 35+ messages in thread
From: David Lechner @ 2026-02-07 18:13 UTC (permalink / raw)
To: Antoniu Miclaus, Lars-Peter Clausen, Michael Hennerich,
Jonathan Cameron, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On 2/6/26 10:07 AM, Antoniu Miclaus wrote:
> Add a new function to get an IIO backend by its index in the
> io-backends device tree property. This is useful for multi-channel
> devices that have multiple backends, where looking up by index is
> more straightforward than using named backends.
>
> The new function directly uses the index to find the backend reference
> in the io-backends property, avoiding the need for io-backend-names.
>
> Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
> ---
> drivers/iio/industrialio-backend.c | 51 ++++++++++++++++++++++++++++++
> include/linux/iio/backend.h | 2 ++
> 2 files changed, 53 insertions(+)
>
> diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-backend.c
> index 447b694d6d5f..3b692d48481e 100644
> --- a/drivers/iio/industrialio-backend.c
> +++ b/drivers/iio/industrialio-backend.c
> @@ -1008,6 +1008,57 @@ struct iio_backend *devm_iio_backend_get(struct device *dev, const char *name)
> }
> EXPORT_SYMBOL_NS_GPL(devm_iio_backend_get, "IIO_BACKEND");
>
> +static struct iio_backend *
> +__devm_iio_backend_fwnode_get_by_index(struct device *dev,
> + struct fwnode_handle *fwnode,
> + unsigned int index)
> +{
> + struct fwnode_handle *fwnode_back;
> + struct iio_backend *back;
> + int ret;
> +
> + fwnode_back = fwnode_find_reference(fwnode, "io-backends", index);
> + if (IS_ERR(fwnode_back))
> + return dev_err_cast_probe(dev, fwnode_back,
> + "Cannot get Firmware reference\n");
> +
> + guard(mutex)(&iio_back_lock);
> + list_for_each_entry(back, &iio_back_list, entry) {
> + if (!device_match_fwnode(back->dev, fwnode_back))
> + continue;
> +
> + fwnode_handle_put(fwnode_back);
> + ret = __devm_iio_backend_get(dev, back);
> + if (ret)
> + return ERR_PTR(ret);
> +
> + back->idx = index;
> +
> + return back;
> + }
> +
> + fwnode_handle_put(fwnode_back);
> + return ERR_PTR(-EPROBE_DEFER);
> +}
This duplicates most of __devm_iio_backend_fwnode_get(), so we could modify
__devm_iio_backend_fwnode_get() to call this function too.
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-06 16:07 ` [PATCH v2 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
2026-02-07 15:04 ` Jonathan Cameron
@ 2026-02-07 18:29 ` David Lechner
2026-02-08 9:26 ` Nuno Sá
2 siblings, 0 replies; 35+ messages in thread
From: David Lechner @ 2026-02-07 18:29 UTC (permalink / raw)
To: Antoniu Miclaus, Lars-Peter Clausen, Michael Hennerich,
Jonathan Cameron, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On 2/6/26 10:07 AM, Antoniu Miclaus wrote:
> Add support for the AD4880, a dual-channel 20-bit 40MSPS SAR ADC with
> integrated fully differential amplifiers (FDA).
>
> The AD4880 has two independent ADC channels, each with its own SPI
> configuration interface. The driver uses spi_new_ancillary_device() to
> create an additional SPI device for the second channel, allowing both
> channels to share the same SPI bus with different chip selects.
>
Reviewed-by: David Lechner <dlechner@baylibre.com>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support
2026-02-07 10:41 ` Krzysztof Kozlowski
@ 2026-02-08 9:16 ` Nuno Sá
2026-02-08 9:20 ` Krzysztof Kozlowski
0 siblings, 1 reply; 35+ messages in thread
From: Nuno Sá @ 2026-02-08 9:16 UTC (permalink / raw)
To: Krzysztof Kozlowski, Antoniu Miclaus
Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On Sat, 2026-02-07 at 11:41 +0100, Krzysztof Kozlowski wrote:
> On Fri, Feb 06, 2026 at 06:07:15PM +0200, Antoniu Miclaus wrote:
> > Add support for the AD4880, a dual-channel 20-bit 40MSPS SAR ADC
> > with integrated fully differential amplifiers (FDA).
> >
> > The AD4880 has two independent ADC channels, each with its own SPI
> > configuration interface. This requires:
> > - Two entries in reg property for primary and secondary channel chip selects
>
> Please wrap commit message according to Linux coding style / submission
> process (neither too early nor over the limit):
> https://elixir.bootlin.com/linux/v6.4-rc1/source/Documentation/process/submitting-patches.rst#L597
>
> Please run scripts/checkpatch.pl on the patches and fix reported
> warnings.
>
> > - Two io-backends entries for the two data channels
> >
> > Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
> > ---
> > Changes in v2:
> > - Replace custom adi,aux-spi-cs property with standard reg property
> > containing two entries for multi-channel devices
> > - Add conditional schema validation for reg and io-backends based on
> > compatible string
> > - Update example to use reg = <0 1> instead of adi,aux-spi-cs
> > - Add AD4880 datasheet link
> >
> > .../bindings/iio/adc/adi,ad4080.yaml | 51 ++++++++++++++++++-
> > 1 file changed, 49 insertions(+), 2 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml
> > b/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml
> > index ccd6a0ac1539..7108a91bb0bf 100644
> > --- a/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml
> > +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml
> > @@ -18,7 +18,11 @@ description: |
> > service a wide variety of precision, wide bandwidth data acquisition
> > applications.
> >
> > + The AD4880 is a dual-channel variant with two independent ADC channels,
> > + each with its own SPI configuration interface.
> > +
> > https://www.analog.com/media/en/technical-documentation/data-sheets/ad4080.pdf
> > + https://www.analog.com/media/en/technical-documentation/data-sheets/ad4880.pdf
> >
> > $ref: /schemas/spi/spi-peripheral-props.yaml#
> >
> > @@ -31,9 +35,15 @@ properties:
> > - adi,ad4084
> > - adi,ad4086
> > - adi,ad4087
> > + - adi,ad4880
> >
> > reg:
> > - maxItems: 1
> > + minItems: 1
> > + maxItems: 2
> > + description:
> > + SPI chip select(s). For single-channel devices, one chip select.
> > + For multi-channel devices like AD4880, two chip selects are required
> > + as each channel has its own SPI configuration interface.
> >
> > spi-max-frequency:
> > description: Configuration of the SPI bus.
> > @@ -57,7 +67,8 @@ properties:
> > vrefin-supply: true
> >
> > io-backends:
> > - maxItems: 1
> > + minItems: 1
> > + maxItems: 2
>
> Instead list the items with minItems, so the order is defined.
>
Also looks like we now need 'io-backend-names'.
- Nuno Sá
> >
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support
2026-02-08 9:16 ` Nuno Sá
@ 2026-02-08 9:20 ` Krzysztof Kozlowski
2026-02-09 16:43 ` Nuno Sá
0 siblings, 1 reply; 35+ messages in thread
From: Krzysztof Kozlowski @ 2026-02-08 9:20 UTC (permalink / raw)
To: Nuno Sá, Antoniu Miclaus
Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On 08/02/2026 10:16, Nuno Sá wrote:
>>>
>>> io-backends:
>>> - maxItems: 1
>>> + minItems: 1
>>> + maxItems: 2
>>
>> Instead list the items with minItems, so the order is defined.
>>
>
> Also looks like we now need 'io-backend-names'.
No. Just define the order here.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 2/4] iio: backend: add devm_iio_backend_get_by_index()
2026-02-06 16:07 ` [PATCH v2 2/4] iio: backend: add devm_iio_backend_get_by_index() Antoniu Miclaus
2026-02-07 14:57 ` Jonathan Cameron
2026-02-07 18:13 ` David Lechner
@ 2026-02-08 9:24 ` Nuno Sá
2026-02-09 15:28 ` David Lechner
2 siblings, 1 reply; 35+ messages in thread
From: Nuno Sá @ 2026-02-08 9:24 UTC (permalink / raw)
To: Antoniu Miclaus, Lars-Peter Clausen, Michael Hennerich,
Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Olivier Moysan,
Mark Brown, linux-iio, devicetree, linux-kernel, linux-spi
On Fri, 2026-02-06 at 18:07 +0200, Antoniu Miclaus wrote:
> Add a new function to get an IIO backend by its index in the
> io-backends device tree property. This is useful for multi-channel
> devices that have multiple backends, where looking up by index is
> more straightforward than using named backends.
>
> The new function directly uses the index to find the backend reference
> in the io-backends property, avoiding the need for io-backend-names.
>
> Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
> ---
> drivers/iio/industrialio-backend.c | 51 ++++++++++++++++++++++++++++++
> include/linux/iio/backend.h | 2 ++
> 2 files changed, 53 insertions(+)
>
> diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-
> backend.c
> index 447b694d6d5f..3b692d48481e 100644
> --- a/drivers/iio/industrialio-backend.c
> +++ b/drivers/iio/industrialio-backend.c
> @@ -1008,6 +1008,57 @@ struct iio_backend *devm_iio_backend_get(struct device *dev,
> const char *name)
> }
> EXPORT_SYMBOL_NS_GPL(devm_iio_backend_get, "IIO_BACKEND");
>
> +static struct iio_backend *
> +__devm_iio_backend_fwnode_get_by_index(struct device *dev,
> + struct fwnode_handle *fwnode,
> + unsigned int index)
> +{
> + struct fwnode_handle *fwnode_back;
> + struct iio_backend *back;
> + int ret;
> +
> + fwnode_back = fwnode_find_reference(fwnode, "io-backends", index);
> + if (IS_ERR(fwnode_back))
> + return dev_err_cast_probe(dev, fwnode_back,
> + "Cannot get Firmware reference\n");
> +
> + guard(mutex)(&iio_back_lock);
> + list_for_each_entry(back, &iio_back_list, entry) {
> + if (!device_match_fwnode(back->dev, fwnode_back))
> + continue;
> +
> + fwnode_handle_put(fwnode_back);
> + ret = __devm_iio_backend_get(dev, back);
> + if (ret)
> + return ERR_PTR(ret);
> +
> + back->idx = index;
> +
> + return back;
> + }
> +
> + fwnode_handle_put(fwnode_back);
> + return ERR_PTR(-EPROBE_DEFER);
> +}
I believe we don't necessarily need this. Why can't we use io-backend-names? I get
that in here we just want something matching the number of channels we have so giving
names is probably does not add much added value. But still, I would prefer t have
more simplicity in the API and it should be fairly easy for the frontend to use the
names argument.
_ Nuno Sá
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-06 16:07 ` [PATCH v2 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
2026-02-07 15:04 ` Jonathan Cameron
2026-02-07 18:29 ` David Lechner
@ 2026-02-08 9:26 ` Nuno Sá
2 siblings, 0 replies; 35+ messages in thread
From: Nuno Sá @ 2026-02-08 9:26 UTC (permalink / raw)
To: Antoniu Miclaus, Lars-Peter Clausen, Michael Hennerich,
Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Olivier Moysan,
Mark Brown, linux-iio, devicetree, linux-kernel, linux-spi
On Fri, 2026-02-06 at 18:07 +0200, Antoniu Miclaus wrote:
> Add support for the AD4880, a dual-channel 20-bit 40MSPS SAR ADC with
> integrated fully differential amplifiers (FDA).
>
> The AD4880 has two independent ADC channels, each with its own SPI
> configuration interface. The driver uses spi_new_ancillary_device() to
> create an additional SPI device for the second channel, allowing both
> channels to share the same SPI bus with different chip selects.
>
> Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
> ---
...
>
> - ret = devm_iio_backend_enable(dev, st->back);
> + /*
> + * Request buffer from the first backend only. For multi-channel
> + * devices (e.g., AD4880), all backends share a single IIO buffer
> + * as data from all ADC channels is interleaved into one stream.
> + */
> + ret = devm_iio_backend_request_buffer(dev, st->back[0], indio_dev);
> if (ret)
> return ret;
Ahh that's a pitty. When I read the cover, I thought we would finally have a multi
buffer user so we could fix some issues with it :)
- Nuno Sá
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-06 16:07 [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
` (3 preceding siblings ...)
2026-02-06 16:07 ` [PATCH v2 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
@ 2026-02-08 12:50 ` Andy Shevchenko
2026-02-14 16:08 ` Jonathan Cameron
2026-02-25 19:07 ` (subset) " Mark Brown
5 siblings, 1 reply; 35+ messages in thread
From: Andy Shevchenko @ 2026-02-08 12:50 UTC (permalink / raw)
To: Antoniu Miclaus
Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On Fri, Feb 06, 2026 at 06:07:12PM +0200, Antoniu Miclaus wrote:
> Add support for the AD4880, a dual-channel 20-bit 40MSPS SAR ADC from
> the same family as AD4080.
>
> The AD4880 has two independent ADC channels, each with its own SPI
> configuration interface and LVDS data output. The driver uses
> spi_new_ancillary_device() for the second channel's SPI and requires
> two io-backend instances for the data interfaces.
I believe there is a better approach, what you need is rather a flag
to SPI core to tell that this is the device with shared CS.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 2/4] iio: backend: add devm_iio_backend_get_by_index()
2026-02-08 9:24 ` Nuno Sá
@ 2026-02-09 15:28 ` David Lechner
2026-02-09 16:47 ` Nuno Sá
0 siblings, 1 reply; 35+ messages in thread
From: David Lechner @ 2026-02-09 15:28 UTC (permalink / raw)
To: Nuno Sá, Antoniu Miclaus, Lars-Peter Clausen,
Michael Hennerich, Jonathan Cameron, Nuno Sá,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Olivier Moysan, Mark Brown, linux-iio, devicetree, linux-kernel,
linux-spi
On 2/8/26 3:24 AM, Nuno Sá wrote:
> On Fri, 2026-02-06 at 18:07 +0200, Antoniu Miclaus wrote:
>> Add a new function to get an IIO backend by its index in the
>> io-backends device tree property. This is useful for multi-channel
>> devices that have multiple backends, where looking up by index is
>> more straightforward than using named backends.
>>
>> The new function directly uses the index to find the backend reference
>> in the io-backends property, avoiding the need for io-backend-names.
>>
>> Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
>> ---
>> drivers/iio/industrialio-backend.c | 51 ++++++++++++++++++++++++++++++
>> include/linux/iio/backend.h | 2 ++
>> 2 files changed, 53 insertions(+)
>>
>> diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-
>> backend.c
>> index 447b694d6d5f..3b692d48481e 100644
>> --- a/drivers/iio/industrialio-backend.c
>> +++ b/drivers/iio/industrialio-backend.c
>> @@ -1008,6 +1008,57 @@ struct iio_backend *devm_iio_backend_get(struct device *dev,
>> const char *name)
>> }
>> EXPORT_SYMBOL_NS_GPL(devm_iio_backend_get, "IIO_BACKEND");
>>
>> +static struct iio_backend *
>> +__devm_iio_backend_fwnode_get_by_index(struct device *dev,
>> + struct fwnode_handle *fwnode,
>> + unsigned int index)
>> +{
>> + struct fwnode_handle *fwnode_back;
>> + struct iio_backend *back;
>> + int ret;
>> +
>> + fwnode_back = fwnode_find_reference(fwnode, "io-backends", index);
>> + if (IS_ERR(fwnode_back))
>> + return dev_err_cast_probe(dev, fwnode_back,
>> + "Cannot get Firmware reference\n");
>> +
>> + guard(mutex)(&iio_back_lock);
>> + list_for_each_entry(back, &iio_back_list, entry) {
>> + if (!device_match_fwnode(back->dev, fwnode_back))
>> + continue;
>> +
>> + fwnode_handle_put(fwnode_back);
>> + ret = __devm_iio_backend_get(dev, back);
>> + if (ret)
>> + return ERR_PTR(ret);
>> +
>> + back->idx = index;
>> +
>> + return back;
>> + }
>> +
>> + fwnode_handle_put(fwnode_back);
>> + return ERR_PTR(-EPROBE_DEFER);
>> +}
>
> I believe we don't necessarily need this. Why can't we use io-backend-names? I get
> that in here we just want something matching the number of channels we have so giving
> names is probably does not add much added value. But still, I would prefer t have
> more simplicity in the API and it should be fairly easy for the frontend to use the
> names argument.
>
> _ Nuno Sá
>
IMHO, using names in this case would just be annoying because we would have to
sprintf the string to add the index to the string. And also have to spend time
coming up with more complex DT bindings. Using the index seems much simpler.
If you really feel strongly about it though, maybe we could make a
devm_iio_backend_fwnode_get_fmt() function instead that handles the
sprintf() part so that we only have to write that once?
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support
2026-02-08 9:20 ` Krzysztof Kozlowski
@ 2026-02-09 16:43 ` Nuno Sá
2026-02-09 17:13 ` Krzysztof Kozlowski
0 siblings, 1 reply; 35+ messages in thread
From: Nuno Sá @ 2026-02-09 16:43 UTC (permalink / raw)
To: Krzysztof Kozlowski, Antoniu Miclaus
Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On Sun, 2026-02-08 at 10:20 +0100, Krzysztof Kozlowski wrote:
> On 08/02/2026 10:16, Nuno Sá wrote:
> > > >
> > > > io-backends:
> > > > - maxItems: 1
> > > > + minItems: 1
> > > > + maxItems: 2
> > >
> > > Instead list the items with minItems, so the order is defined.
> > >
> >
> > Also looks like we now need 'io-backend-names'.
>
> No. Just define the order here.
>
Things are still not really defined on the code side (I know bindings don't care about the driver
side) but io-backend-names is a standard property and we might actually end up using it so that
we know how to map the backend to a given channel. Unless what you're saying is that in here, -names
doesn't really makes sense given that we just want n io-backends for n adc channels and having
-names as "adc1", "adc2", "adcn" is arguably useless.
- Nuno Sá
> Best regards,
> Krzysztof
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 2/4] iio: backend: add devm_iio_backend_get_by_index()
2026-02-09 15:28 ` David Lechner
@ 2026-02-09 16:47 ` Nuno Sá
2026-02-09 17:48 ` Nuno Sá
2026-02-09 18:20 ` David Lechner
0 siblings, 2 replies; 35+ messages in thread
From: Nuno Sá @ 2026-02-09 16:47 UTC (permalink / raw)
To: David Lechner, Antoniu Miclaus, Lars-Peter Clausen,
Michael Hennerich, Jonathan Cameron, Nuno Sá,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Olivier Moysan, Mark Brown, linux-iio, devicetree, linux-kernel,
linux-spi
On Mon, 2026-02-09 at 09:28 -0600, David Lechner wrote:
> On 2/8/26 3:24 AM, Nuno Sá wrote:
> > On Fri, 2026-02-06 at 18:07 +0200, Antoniu Miclaus wrote:
> > > Add a new function to get an IIO backend by its index in the
> > > io-backends device tree property. This is useful for multi-channel
> > > devices that have multiple backends, where looking up by index is
> > > more straightforward than using named backends.
> > >
> > > The new function directly uses the index to find the backend reference
> > > in the io-backends property, avoiding the need for io-backend-names.
> > >
> > > Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
> > > ---
> > > drivers/iio/industrialio-backend.c | 51 ++++++++++++++++++++++++++++++
> > > include/linux/iio/backend.h | 2 ++
> > > 2 files changed, 53 insertions(+)
> > >
> > > diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-
> > > backend.c
> > > index 447b694d6d5f..3b692d48481e 100644
> > > --- a/drivers/iio/industrialio-backend.c
> > > +++ b/drivers/iio/industrialio-backend.c
> > > @@ -1008,6 +1008,57 @@ struct iio_backend *devm_iio_backend_get(struct device *dev,
> > > const char *name)
> > > }
> > > EXPORT_SYMBOL_NS_GPL(devm_iio_backend_get, "IIO_BACKEND");
> > >
> > > +static struct iio_backend *
> > > +__devm_iio_backend_fwnode_get_by_index(struct device *dev,
> > > + struct fwnode_handle *fwnode,
> > > + unsigned int index)
> > > +{
> > > + struct fwnode_handle *fwnode_back;
> > > + struct iio_backend *back;
> > > + int ret;
> > > +
> > > + fwnode_back = fwnode_find_reference(fwnode, "io-backends", index);
> > > + if (IS_ERR(fwnode_back))
> > > + return dev_err_cast_probe(dev, fwnode_back,
> > > + "Cannot get Firmware reference\n");
> > > +
> > > + guard(mutex)(&iio_back_lock);
> > > + list_for_each_entry(back, &iio_back_list, entry) {
> > > + if (!device_match_fwnode(back->dev, fwnode_back))
> > > + continue;
> > > +
> > > + fwnode_handle_put(fwnode_back);
> > > + ret = __devm_iio_backend_get(dev, back);
> > > + if (ret)
> > > + return ERR_PTR(ret);
> > > +
> > > + back->idx = index;
> > > +
> > > + return back;
> > > + }
> > > +
> > > + fwnode_handle_put(fwnode_back);
> > > + return ERR_PTR(-EPROBE_DEFER);
> > > +}
> >
> > I believe we don't necessarily need this. Why can't we use io-backend-names? I get
> > that in here we just want something matching the number of channels we have so giving
> > names is probably does not add much added value. But still, I would prefer t have
> > more simplicity in the API and it should be fairly easy for the frontend to use the
> > names argument.
> >
> > _ Nuno Sá
> >
>
> IMHO, using names in this case would just be annoying because we would have to
> sprintf the string to add the index to the string. And also have to spend time
> coming up with more complex DT bindings. Using the index seems much simpler.
>
> If you really feel strongly about it though, maybe we could make a
> devm_iio_backend_fwnode_get_fmt() function instead that handles the
> sprintf() part so that we only have to write that once?
>
uHu? Maybe I'm completely missing your point but what I had in mind was just something like:
// from the frontend:
static const char * const names[] = { "adc1", "adc2" }
for (c = 0; c < ARRAY_SIZE(names); c++) {
back = devm_iio_backend_get(dev, names[c]);
}
So yes, I agree we would have a bit more complex bindings and more complexity in the
frontend. But on the bright side, no need to change backend code at all. And the
-names property is already used like the above fairly often If I'm not mistaken.
But again, I can agree that for this usecase getting things by index makes sense. Given
that we just want n backends for n channels, the name does not add much.
- Nuno Sá
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support
2026-02-09 16:43 ` Nuno Sá
@ 2026-02-09 17:13 ` Krzysztof Kozlowski
2026-02-09 17:45 ` Nuno Sá
0 siblings, 1 reply; 35+ messages in thread
From: Krzysztof Kozlowski @ 2026-02-09 17:13 UTC (permalink / raw)
To: Nuno Sá, Antoniu Miclaus
Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On 09/02/2026 17:43, Nuno Sá wrote:
> On Sun, 2026-02-08 at 10:20 +0100, Krzysztof Kozlowski wrote:
>> On 08/02/2026 10:16, Nuno Sá wrote:
>>>>>
>>>>> io-backends:
>>>>> - maxItems: 1
>>>>> + minItems: 1
>>>>> + maxItems: 2
>>>>
>>>> Instead list the items with minItems, so the order is defined.
>>>>
>>>
>>> Also looks like we now need 'io-backend-names'.
>>
>> No. Just define the order here.
>>
>
> Things are still not really defined on the code side (I know bindings don't care about the driver
> side) but io-backend-names is a standard property and we might actually end up using it so that
And names do not change that at all. Actually they might make it worse,
because they allow drivers to fetch item by name which people think
means "order is flexible".
> we know how to map the backend to a given channel. Unless what you're saying is that in here, -names
> doesn't really makes sense given that we just want n io-backends for n adc channels and having
> -names as "adc1", "adc2", "adcn" is arguably useless.
Names like adcX indeed would not make much sense.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support
2026-02-09 17:13 ` Krzysztof Kozlowski
@ 2026-02-09 17:45 ` Nuno Sá
0 siblings, 0 replies; 35+ messages in thread
From: Nuno Sá @ 2026-02-09 17:45 UTC (permalink / raw)
To: Krzysztof Kozlowski, Antoniu Miclaus
Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On Mon, 2026-02-09 at 18:13 +0100, Krzysztof Kozlowski wrote:
> On 09/02/2026 17:43, Nuno Sá wrote:
> > On Sun, 2026-02-08 at 10:20 +0100, Krzysztof Kozlowski wrote:
> > > On 08/02/2026 10:16, Nuno Sá wrote:
> > > > > >
> > > > > > io-backends:
> > > > > > - maxItems: 1
> > > > > > + minItems: 1
> > > > > > + maxItems: 2
> > > > >
> > > > > Instead list the items with minItems, so the order is defined.
> > > > >
> > > >
> > > > Also looks like we now need 'io-backend-names'.
> > >
> > > No. Just define the order here.
> > >
> >
> > Things are still not really defined on the code side (I know bindings don't care about the
> > driver
> > side) but io-backend-names is a standard property and we might actually end up using it so that
>
> And names do not change that at all. Actually they might make it worse,
> because they allow drivers to fetch item by name which people think
> means "order is flexible".
Fair and makes sense.
- Nuno Sá
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 2/4] iio: backend: add devm_iio_backend_get_by_index()
2026-02-09 16:47 ` Nuno Sá
@ 2026-02-09 17:48 ` Nuno Sá
2026-02-09 18:20 ` David Lechner
1 sibling, 0 replies; 35+ messages in thread
From: Nuno Sá @ 2026-02-09 17:48 UTC (permalink / raw)
To: David Lechner, Antoniu Miclaus, Lars-Peter Clausen,
Michael Hennerich, Jonathan Cameron, Nuno Sá,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Olivier Moysan, Mark Brown, linux-iio, devicetree, linux-kernel,
linux-spi
On Mon, 2026-02-09 at 16:47 +0000, Nuno Sá wrote:
> On Mon, 2026-02-09 at 09:28 -0600, David Lechner wrote:
> > On 2/8/26 3:24 AM, Nuno Sá wrote:
> > > On Fri, 2026-02-06 at 18:07 +0200, Antoniu Miclaus wrote:
> > > > Add a new function to get an IIO backend by its index in the
> > > > io-backends device tree property. This is useful for multi-channel
> > > > devices that have multiple backends, where looking up by index is
> > > > more straightforward than using named backends.
> > > >
> > > > The new function directly uses the index to find the backend reference
> > > > in the io-backends property, avoiding the need for io-backend-names.
> > > >
> > > > Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
> > > > ---
> > > > drivers/iio/industrialio-backend.c | 51 ++++++++++++++++++++++++++++++
> > > > include/linux/iio/backend.h | 2 ++
> > > > 2 files changed, 53 insertions(+)
> > > >
> > > > diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-
> > > > backend.c
> > > > index 447b694d6d5f..3b692d48481e 100644
> > > > --- a/drivers/iio/industrialio-backend.c
> > > > +++ b/drivers/iio/industrialio-backend.c
> > > > @@ -1008,6 +1008,57 @@ struct iio_backend *devm_iio_backend_get(struct device *dev,
> > > > const char *name)
> > > > }
> > > > EXPORT_SYMBOL_NS_GPL(devm_iio_backend_get, "IIO_BACKEND");
> > > >
> > > > +static struct iio_backend *
> > > > +__devm_iio_backend_fwnode_get_by_index(struct device *dev,
> > > > + struct fwnode_handle *fwnode,
> > > > + unsigned int index)
> > > > +{
> > > > + struct fwnode_handle *fwnode_back;
> > > > + struct iio_backend *back;
> > > > + int ret;
> > > > +
> > > > + fwnode_back = fwnode_find_reference(fwnode, "", index);
> > > > + if (IS_ERR(fwnode_back))
> > > > + return dev_err_cast_probe(dev, fwnode_back,
> > > > + "Cannot get Firmware reference\n");
> > > > +
> > > > + guard(mutex)(&iio_back_lock);
> > > > + list_for_each_entry(back, &iio_back_list, entry) {
> > > > + if (!device_match_fwnode(back->dev, fwnode_back))
> > > > + continue;
> > > > +
> > > > + fwnode_handle_put(fwnode_back);
> > > > + ret = __devm_iio_backend_get(dev, back);
> > > > + if (ret)
> > > > + return ERR_PTR(ret);
> > > > +
> > > > + back->idx = index;
> > > > +
> > > > + return back;
> > > > + }
> > > > +
> > > > + fwnode_handle_put(fwnode_back);
> > > > + return ERR_PTR(-EPROBE_DEFER);
> > > > +}
> > >
> > > I believe we don't necessarily need this. Why can't we use io-backend-names? I get
> > > that in here we just want something matching the number of channels we have so giving
> > > names is probably does not add much added value. But still, I would prefer t have
> > > more simplicity in the API and it should be fairly easy for the frontend to use the
> > > names argument.
> > >
> > > _ Nuno Sá
> > >
> >
> > IMHO, using names in this case would just be annoying because we would have to
> > sprintf the string to add the index to the string. And also have to spend time
> > coming up with more complex DT bindings. Using the index seems much simpler.
> >
> > If you really feel strongly about it though, maybe we could make a
> > devm_iio_backend_fwnode_get_fmt() function instead that handles the
> > sprintf() part so that we only have to write that once?
> >
>
> uHu? Maybe I'm completely missing your point but what I had in mind was just something like:
>
>
> // from the frontend:
>
> static const char * const names[] = { "adc1", "adc2" }
>
> for (c = 0; c < ARRAY_SIZE(names); c++) {
> back = devm_iio_backend_get(dev, names[c]);
> }
>
> So yes, I agree we would have a bit more complex bindings and more complexity in the
> frontend. But on the bright side, no need to change backend code at all. And the
> -names property is already used like the above fairly often If I'm not mistaken.
>
> But again, I can agree that for this usecase getting things by index makes sense. Given
> that we just want n backends for n channels, the name does not add much.
>
Given Krzysztof's feedback, let's not do the above. So, Antoniu, disregard my comments about using
io-backend-name.
- Nuno Sá
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 2/4] iio: backend: add devm_iio_backend_get_by_index()
2026-02-09 16:47 ` Nuno Sá
2026-02-09 17:48 ` Nuno Sá
@ 2026-02-09 18:20 ` David Lechner
1 sibling, 0 replies; 35+ messages in thread
From: David Lechner @ 2026-02-09 18:20 UTC (permalink / raw)
To: Nuno Sá, Antoniu Miclaus, Lars-Peter Clausen,
Michael Hennerich, Jonathan Cameron, Nuno Sá,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Olivier Moysan, Mark Brown, linux-iio, devicetree, linux-kernel,
linux-spi
On 2/9/26 10:47 AM, Nuno Sá wrote:
...
> uHu? Maybe I'm completely missing your point but what I had in mind was just something like:
>
>
> // from the frontend:
>
> static const char * const names[] = { "adc1", "adc2" }
Yeah, that isn't so bad. (A "why didn't I think of that moment").
And I saw the other replies already, so a moot point anyway.
>
> for (c = 0; c < ARRAY_SIZE(names); c++) {
> back = devm_iio_backend_get(dev, names[c]);
> }
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-08 12:50 ` [PATCH v2 0/4] " Andy Shevchenko
@ 2026-02-14 16:08 ` Jonathan Cameron
2026-02-14 18:11 ` Andy Shevchenko
0 siblings, 1 reply; 35+ messages in thread
From: Jonathan Cameron @ 2026-02-14 16:08 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Antoniu Miclaus, Lars-Peter Clausen, Michael Hennerich,
David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On Sun, 8 Feb 2026 14:50:23 +0200
Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> On Fri, Feb 06, 2026 at 06:07:12PM +0200, Antoniu Miclaus wrote:
> > Add support for the AD4880, a dual-channel 20-bit 40MSPS SAR ADC from
> > the same family as AD4080.
> >
> > The AD4880 has two independent ADC channels, each with its own SPI
> > configuration interface and LVDS data output. The driver uses
> > spi_new_ancillary_device() for the second channel's SPI and requires
> > two io-backend instances for the data interfaces.
>
> I believe there is a better approach, what you need is rather a flag
> to SPI core to tell that this is the device with shared CS.
>
Antoniu, this comment from Andy needs addressing before we move
on. It seems fairly fundamental and I'm not seeing a reply to it on list.
I'm not entirely sure what Andy is suggesting will work but this
is perhaps a mismatch in really understanding what is going on here.
Andy, how would a flag work given they seem to be separately addressable
SPI buses. I think this isn't a shared SPI CS, but rather a device
with two entirely separate SPI buses. I think the only reason
we are bothering to implement it as a single device at all is the
shared backend.
There is an argument that maybe we should be looking at how
to do data muxing backends to support the more general case of two
separate chips feeding into a single buffer, but that's a complex
beast and I'm not sure if it is something we actually need.
Jonathan
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-14 16:08 ` Jonathan Cameron
@ 2026-02-14 18:11 ` Andy Shevchenko
2026-02-14 18:31 ` David Lechner
0 siblings, 1 reply; 35+ messages in thread
From: Andy Shevchenko @ 2026-02-14 18:11 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Antoniu Miclaus, Lars-Peter Clausen, Michael Hennerich,
David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On Sat, Feb 14, 2026 at 04:08:52PM +0000, Jonathan Cameron wrote:
> On Sun, 8 Feb 2026 14:50:23 +0200
> Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> > On Fri, Feb 06, 2026 at 06:07:12PM +0200, Antoniu Miclaus wrote:
...
> > I believe there is a better approach, what you need is rather a flag
> > to SPI core to tell that this is the device with shared CS.
>
> Antoniu, this comment from Andy needs addressing before we move
> on. It seems fairly fundamental and I'm not seeing a reply to it on list.
>
> I'm not entirely sure what Andy is suggesting will work but this
> is perhaps a mismatch in really understanding what is going on here.
> Andy, how would a flag work given they seem to be separately addressable
> SPI buses. I think this isn't a shared SPI CS, but rather a device
> with two entirely separate SPI buses. I think the only reason
> we are bothering to implement it as a single device at all is the
> shared backend.
My understanding that there are two devices that for whatever reason share
the same CS line. Yes, I probably misread the idea behind, but I meant
some flag for SPI device that tells SPI core that the CS it wants is shared
(maybe a high bit in the cs field or so), then CS core won't complain on
validation about using the same cs number which is "already in use".
> There is an argument that maybe we should be looking at how
> to do data muxing backends to support the more general case of two
> separate chips feeding into a single buffer, but that's a complex
> beast and I'm not sure if it is something we actually need.
Yeah, if possible I prefer to look at the (ASCII art) schematics
on how the HW looks like (connections with busses and CS lines).
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-14 18:11 ` Andy Shevchenko
@ 2026-02-14 18:31 ` David Lechner
2026-02-15 8:03 ` Andy Shevchenko
0 siblings, 1 reply; 35+ messages in thread
From: David Lechner @ 2026-02-14 18:31 UTC (permalink / raw)
To: Andy Shevchenko, Jonathan Cameron
Cc: Antoniu Miclaus, Lars-Peter Clausen, Michael Hennerich,
Nuno Sá, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Olivier Moysan, Mark Brown, linux-iio, devicetree,
linux-kernel, linux-spi
On 2/14/26 12:11 PM, Andy Shevchenko wrote:
> On Sat, Feb 14, 2026 at 04:08:52PM +0000, Jonathan Cameron wrote:
>> On Sun, 8 Feb 2026 14:50:23 +0200
>> Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
>>> On Fri, Feb 06, 2026 at 06:07:12PM +0200, Antoniu Miclaus wrote:
>
> ...
>
>>> I believe there is a better approach, what you need is rather a flag
>>> to SPI core to tell that this is the device with shared CS.
>>
>> Antoniu, this comment from Andy needs addressing before we move
>> on. It seems fairly fundamental and I'm not seeing a reply to it on list.
>>
>> I'm not entirely sure what Andy is suggesting will work but this
>> is perhaps a mismatch in really understanding what is going on here.
>> Andy, how would a flag work given they seem to be separately addressable
>> SPI buses. I think this isn't a shared SPI CS, but rather a device
>> with two entirely separate SPI buses. I think the only reason
>> we are bothering to implement it as a single device at all is the
>> shared backend.
>
> My understanding that there are two devices that for whatever reason share
It is the opposite. It is a _single_ device with _two_ CS lines.
adc@0 {
reg = <0>, <1>;
...
};
> the same CS line. Yes, I probably misread the idea behind, but I meant
> some flag for SPI device that tells SPI core that the CS it wants is shared
> (maybe a high bit in the cs field or so), then CS core won't complain on
> validation about using the same cs number which is "already in use".
There was one existing user in the kernel of spi_new_ancillary_device()
that looked like this, so it seemed the right way to approach it. However,
code was added later that caused the primary SPI device to "claim" both
CS lines for itself and probably broke the one existing user of
spi_new_ancillary_device() (hard to tell without hardware to test).
The idea here was to unbreak that so we could use spi_new_ancillary_device()
just as in the existing use case.
The patch for that could have been a bit more strict to only allow the
spi_new_ancillary_device() to take CS 1 and fail otherwise, but users
are going to notice if it isn't working right anyway, so I didn't ask
for more checking.
>
>> There is an argument that maybe we should be looking at how
>> to do data muxing backends to support the more general case of two
>> separate chips feeding into a single buffer, but that's a complex
>> beast and I'm not sure if it is something we actually need.
I think it would actually be quite similar to what is done in this
series.
>
> Yeah, if possible I prefer to look at the (ASCII art) schematics
> on how the HW looks like (connections with busses and CS lines).
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-14 18:31 ` David Lechner
@ 2026-02-15 8:03 ` Andy Shevchenko
2026-02-15 23:16 ` David Lechner
0 siblings, 1 reply; 35+ messages in thread
From: Andy Shevchenko @ 2026-02-15 8:03 UTC (permalink / raw)
To: David Lechner
Cc: Jonathan Cameron, Antoniu Miclaus, Lars-Peter Clausen,
Michael Hennerich, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On Sat, Feb 14, 2026 at 12:31:12PM -0600, David Lechner wrote:
> On 2/14/26 12:11 PM, Andy Shevchenko wrote:
> > On Sat, Feb 14, 2026 at 04:08:52PM +0000, Jonathan Cameron wrote:
> >> On Sun, 8 Feb 2026 14:50:23 +0200
> >> Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> >>> On Fri, Feb 06, 2026 at 06:07:12PM +0200, Antoniu Miclaus wrote:
...
> >>> I believe there is a better approach, what you need is rather a flag
> >>> to SPI core to tell that this is the device with shared CS.
> >>
> >> Antoniu, this comment from Andy needs addressing before we move
> >> on. It seems fairly fundamental and I'm not seeing a reply to it on list.
> >>
> >> I'm not entirely sure what Andy is suggesting will work but this
> >> is perhaps a mismatch in really understanding what is going on here.
> >> Andy, how would a flag work given they seem to be separately addressable
> >> SPI buses. I think this isn't a shared SPI CS, but rather a device
> >> with two entirely separate SPI buses. I think the only reason
> >> we are bothering to implement it as a single device at all is the
> >> shared backend.
> >
> > My understanding that there are two devices that for whatever reason share
>
> It is the opposite. It is a _single_ device with _two_ CS lines.
Don't we have already support for that? This changes the picture even more towards
NAKing this. See below why.
> adc@0 {
> reg = <0>, <1>;
> ...
> };
>
> > the same CS line. Yes, I probably misread the idea behind, but I meant
> > some flag for SPI device that tells SPI core that the CS it wants is shared
> > (maybe a high bit in the cs field or so), then CS core won't complain on
> > validation about using the same cs number which is "already in use".
>
> There was one existing user in the kernel of spi_new_ancillary_device()
> that looked like this, so it seemed the right way to approach it. However,
> code was added later that caused the primary SPI device to "claim" both
> CS lines for itself and probably broke the one existing user of
> spi_new_ancillary_device() (hard to tell without hardware to test).
>
> The idea here was to unbreak that so we could use spi_new_ancillary_device()
> just as in the existing use case.
>
> The patch for that could have been a bit more strict to only allow the
> spi_new_ancillary_device() to take CS 1 and fail otherwise, but users
> are going to notice if it isn't working right anyway, so I didn't ask
> for more checking.
> >> There is an argument that maybe we should be looking at how
> >> to do data muxing backends to support the more general case of two
> >> separate chips feeding into a single buffer, but that's a complex
> >> beast and I'm not sure if it is something we actually need.
>
> I think it would actually be quite similar to what is done in this
> series.
TBH, the change sounds to me like a hack. It doesn't cover other potential ways
of the multi-cs devices come into play. Given that SPI core supports multi-cs
I don't see a good justification for this patch.
What did I miss?
> > Yeah, if possible I prefer to look at the (ASCII art) schematics
> > on how the HW looks like (connections with busses and CS lines).
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-15 8:03 ` Andy Shevchenko
@ 2026-02-15 23:16 ` David Lechner
2026-02-16 7:14 ` Andy Shevchenko
0 siblings, 1 reply; 35+ messages in thread
From: David Lechner @ 2026-02-15 23:16 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Jonathan Cameron, Antoniu Miclaus, Lars-Peter Clausen,
Michael Hennerich, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On 2/15/26 2:03 AM, Andy Shevchenko wrote:
> On Sat, Feb 14, 2026 at 12:31:12PM -0600, David Lechner wrote:
>> On 2/14/26 12:11 PM, Andy Shevchenko wrote:
>>> On Sat, Feb 14, 2026 at 04:08:52PM +0000, Jonathan Cameron wrote:
>>>> On Sun, 8 Feb 2026 14:50:23 +0200
>>>> Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
>>>>> On Fri, Feb 06, 2026 at 06:07:12PM +0200, Antoniu Miclaus wrote:
>
> ...
>
>>>>> I believe there is a better approach, what you need is rather a flag
>>>>> to SPI core to tell that this is the device with shared CS.
>>>>
>>>> Antoniu, this comment from Andy needs addressing before we move
>>>> on. It seems fairly fundamental and I'm not seeing a reply to it on list.
>>>>
>>>> I'm not entirely sure what Andy is suggesting will work but this
>>>> is perhaps a mismatch in really understanding what is going on here.
>>>> Andy, how would a flag work given they seem to be separately addressable
>>>> SPI buses. I think this isn't a shared SPI CS, but rather a device
>>>> with two entirely separate SPI buses. I think the only reason
>>>> we are bothering to implement it as a single device at all is the
>>>> shared backend.
>>>
>>> My understanding that there are two devices that for whatever reason share
>>
>> It is the opposite. It is a _single_ device with _two_ CS lines.
>
> Don't we have already support for that? This changes the picture even more towards
> NAKing this. See below why.
Yes, spi_new_ancillary_device() was introduced exactly for this sort
of thing, which is why I think it makes sense to use it.
>
>> adc@0 {
>> reg = <0>, <1>;
>> ...
>> };
>>
>>> the same CS line. Yes, I probably misread the idea behind, but I meant
>>> some flag for SPI device that tells SPI core that the CS it wants is shared
>>> (maybe a high bit in the cs field or so), then CS core won't complain on
>>> validation about using the same cs number which is "already in use".
>>
>> There was one existing user in the kernel of spi_new_ancillary_device()
>> that looked like this, so it seemed the right way to approach it. However,
>> code was added later that caused the primary SPI device to "claim" both
>> CS lines for itself and probably broke the one existing user of
>> spi_new_ancillary_device() (hard to tell without hardware to test).
>>
>> The idea here was to unbreak that so we could use spi_new_ancillary_device()
>> just as in the existing use case.
>>
>> The patch for that could have been a bit more strict to only allow the
>> spi_new_ancillary_device() to take CS 1 and fail otherwise, but users
>> are going to notice if it isn't working right anyway, so I didn't ask
>> for more checking.
>
>>>> There is an argument that maybe we should be looking at how
>>>> to do data muxing backends to support the more general case of two
>>>> separate chips feeding into a single buffer, but that's a complex
>>>> beast and I'm not sure if it is something we actually need.
>>
>> I think it would actually be quite similar to what is done in this
>> series.
>
> TBH, the change sounds to me like a hack. It doesn't cover other potential ways
> of the multi-cs devices come into play. Given that SPI core supports multi-cs
> I don't see a good justification for this patch.
>
> What did I miss?
As far as I can tell, other than the one existing user of
spi_new_ancillary_device(), other SPI multi-CS stuff is only used
by SPI flash memory devices, not general SPI devices. There code
that is being modified here was introduced to support the SPI
flash memory devices, so that use case is already covered by
existing code.
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-15 23:16 ` David Lechner
@ 2026-02-16 7:14 ` Andy Shevchenko
2026-02-16 18:53 ` David Lechner
0 siblings, 1 reply; 35+ messages in thread
From: Andy Shevchenko @ 2026-02-16 7:14 UTC (permalink / raw)
To: David Lechner
Cc: Jonathan Cameron, Antoniu Miclaus, Lars-Peter Clausen,
Michael Hennerich, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On Sun, Feb 15, 2026 at 05:16:47PM -0600, David Lechner wrote:
> On 2/15/26 2:03 AM, Andy Shevchenko wrote:
> > On Sat, Feb 14, 2026 at 12:31:12PM -0600, David Lechner wrote:
> >> On 2/14/26 12:11 PM, Andy Shevchenko wrote:
> >>> On Sat, Feb 14, 2026 at 04:08:52PM +0000, Jonathan Cameron wrote:
> >>>> On Sun, 8 Feb 2026 14:50:23 +0200
> >>>> Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> >>>>> On Fri, Feb 06, 2026 at 06:07:12PM +0200, Antoniu Miclaus wrote:
...
> >>>>> I believe there is a better approach, what you need is rather a flag
> >>>>> to SPI core to tell that this is the device with shared CS.
> >>>>
> >>>> Antoniu, this comment from Andy needs addressing before we move
> >>>> on. It seems fairly fundamental and I'm not seeing a reply to it on list.
> >>>>
> >>>> I'm not entirely sure what Andy is suggesting will work but this
> >>>> is perhaps a mismatch in really understanding what is going on here.
> >>>> Andy, how would a flag work given they seem to be separately addressable
> >>>> SPI buses. I think this isn't a shared SPI CS, but rather a device
> >>>> with two entirely separate SPI buses. I think the only reason
> >>>> we are bothering to implement it as a single device at all is the
> >>>> shared backend.
> >>>
> >>> My understanding that there are two devices that for whatever reason share
> >>
> >> It is the opposite. It is a _single_ device with _two_ CS lines.
> >
> > Don't we have already support for that? This changes the picture even more towards
> > NAKing this. See below why.
>
> Yes, spi_new_ancillary_device() was introduced exactly for this sort
> of thing, which is why I think it makes sense to use it.
>
> >> adc@0 {
> >> reg = <0>, <1>;
> >> ...
> >> };
> >>
> >>> the same CS line. Yes, I probably misread the idea behind, but I meant
> >>> some flag for SPI device that tells SPI core that the CS it wants is shared
> >>> (maybe a high bit in the cs field or so), then CS core won't complain on
> >>> validation about using the same cs number which is "already in use".
> >>
> >> There was one existing user in the kernel of spi_new_ancillary_device()
> >> that looked like this, so it seemed the right way to approach it. However,
> >> code was added later that caused the primary SPI device to "claim" both
> >> CS lines for itself and probably broke the one existing user of
> >> spi_new_ancillary_device() (hard to tell without hardware to test).
> >>
> >> The idea here was to unbreak that so we could use spi_new_ancillary_device()
> >> just as in the existing use case.
> >>
> >> The patch for that could have been a bit more strict to only allow the
> >> spi_new_ancillary_device() to take CS 1 and fail otherwise, but users
> >> are going to notice if it isn't working right anyway, so I didn't ask
> >> for more checking.
> >
> >>>> There is an argument that maybe we should be looking at how
> >>>> to do data muxing backends to support the more general case of two
> >>>> separate chips feeding into a single buffer, but that's a complex
> >>>> beast and I'm not sure if it is something we actually need.
> >>
> >> I think it would actually be quite similar to what is done in this
> >> series.
> >
> > TBH, the change sounds to me like a hack. It doesn't cover other potential ways
> > of the multi-cs devices come into play. Given that SPI core supports multi-cs
> > I don't see a good justification for this patch.
> >
> > What did I miss?
>
> As far as I can tell, other than the one existing user of
> spi_new_ancillary_device(), other SPI multi-CS stuff is only used
> by SPI flash memory devices, not general SPI devices. There code
> that is being modified here was introduced to support the SPI
> flash memory devices, so that use case is already covered by
> existing code.
Right. And obvious question why can't we apply the same approach
to any SPI device? Like extending existing code to cover generic
cases.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-16 7:14 ` Andy Shevchenko
@ 2026-02-16 18:53 ` David Lechner
2026-02-17 8:28 ` Andy Shevchenko
0 siblings, 1 reply; 35+ messages in thread
From: David Lechner @ 2026-02-16 18:53 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Jonathan Cameron, Antoniu Miclaus, Lars-Peter Clausen,
Michael Hennerich, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On 2/16/26 1:14 AM, Andy Shevchenko wrote:
> On Sun, Feb 15, 2026 at 05:16:47PM -0600, David Lechner wrote:
>> On 2/15/26 2:03 AM, Andy Shevchenko wrote:
>>> On Sat, Feb 14, 2026 at 12:31:12PM -0600, David Lechner wrote:
>>>> On 2/14/26 12:11 PM, Andy Shevchenko wrote:
>>>>> On Sat, Feb 14, 2026 at 04:08:52PM +0000, Jonathan Cameron wrote:
>>>>>> On Sun, 8 Feb 2026 14:50:23 +0200
>>>>>> Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
>>>>>>> On Fri, Feb 06, 2026 at 06:07:12PM +0200, Antoniu Miclaus wrote:
>
> ...
>
>>>>>>> I believe there is a better approach, what you need is rather a flag
>>>>>>> to SPI core to tell that this is the device with shared CS.
>>>>>>
>>>>>> Antoniu, this comment from Andy needs addressing before we move
>>>>>> on. It seems fairly fundamental and I'm not seeing a reply to it on list.
>>>>>>
>>>>>> I'm not entirely sure what Andy is suggesting will work but this
>>>>>> is perhaps a mismatch in really understanding what is going on here.
>>>>>> Andy, how would a flag work given they seem to be separately addressable
>>>>>> SPI buses. I think this isn't a shared SPI CS, but rather a device
>>>>>> with two entirely separate SPI buses. I think the only reason
>>>>>> we are bothering to implement it as a single device at all is the
>>>>>> shared backend.
>>>>>
>>>>> My understanding that there are two devices that for whatever reason share
>>>>
>>>> It is the opposite. It is a _single_ device with _two_ CS lines.
>>>
>>> Don't we have already support for that? This changes the picture even more towards
>>> NAKing this. See below why.
>>
>> Yes, spi_new_ancillary_device() was introduced exactly for this sort
>> of thing, which is why I think it makes sense to use it.
>>
>>>> adc@0 {
>>>> reg = <0>, <1>;
>>>> ...
>>>> };
>>>>
>>>>> the same CS line. Yes, I probably misread the idea behind, but I meant
>>>>> some flag for SPI device that tells SPI core that the CS it wants is shared
>>>>> (maybe a high bit in the cs field or so), then CS core won't complain on
>>>>> validation about using the same cs number which is "already in use".
>>>>
>>>> There was one existing user in the kernel of spi_new_ancillary_device()
>>>> that looked like this, so it seemed the right way to approach it. However,
>>>> code was added later that caused the primary SPI device to "claim" both
>>>> CS lines for itself and probably broke the one existing user of
>>>> spi_new_ancillary_device() (hard to tell without hardware to test).
>>>>
>>>> The idea here was to unbreak that so we could use spi_new_ancillary_device()
>>>> just as in the existing use case.
>>>>
>>>> The patch for that could have been a bit more strict to only allow the
>>>> spi_new_ancillary_device() to take CS 1 and fail otherwise, but users
>>>> are going to notice if it isn't working right anyway, so I didn't ask
>>>> for more checking.
>>>
>>>>>> There is an argument that maybe we should be looking at how
>>>>>> to do data muxing backends to support the more general case of two
>>>>>> separate chips feeding into a single buffer, but that's a complex
>>>>>> beast and I'm not sure if it is something we actually need.
>>>>
>>>> I think it would actually be quite similar to what is done in this
>>>> series.
>>>
>>> TBH, the change sounds to me like a hack. It doesn't cover other potential ways
>>> of the multi-cs devices come into play. Given that SPI core supports multi-cs
>>> I don't see a good justification for this patch.
>>>
>>> What did I miss?
>>
>> As far as I can tell, other than the one existing user of
>> spi_new_ancillary_device(), other SPI multi-CS stuff is only used
>> by SPI flash memory devices, not general SPI devices. There code
>> that is being modified here was introduced to support the SPI
>> flash memory devices, so that use case is already covered by
>> existing code.
>
> Right. And obvious question why can't we apply the same approach
> to any SPI device? Like extending existing code to cover generic
> cases.
>
spi_new_ancillary_device() was already accepted in the kernel as the
solution for this sort of use case, so isn't it already the generic
approach?
I can see that it could possibly be nice if the SPI core saw that
there was more than one CS and called spi_new_ancillary_device()
automatically and somehow passed that along with the main SPI device
to the driver probe function. But since this is only the second user
of spi_new_ancillary_device(), I don't think we have enough data
points to be able to say if this is really what all peripheral drivers
would want.
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-16 18:53 ` David Lechner
@ 2026-02-17 8:28 ` Andy Shevchenko
2026-02-17 22:55 ` David Lechner
0 siblings, 1 reply; 35+ messages in thread
From: Andy Shevchenko @ 2026-02-17 8:28 UTC (permalink / raw)
To: David Lechner
Cc: Jonathan Cameron, Antoniu Miclaus, Lars-Peter Clausen,
Michael Hennerich, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On Mon, Feb 16, 2026 at 12:53:10PM -0600, David Lechner wrote:
> On 2/16/26 1:14 AM, Andy Shevchenko wrote:
> > On Sun, Feb 15, 2026 at 05:16:47PM -0600, David Lechner wrote:
> >> On 2/15/26 2:03 AM, Andy Shevchenko wrote:
> >>> On Sat, Feb 14, 2026 at 12:31:12PM -0600, David Lechner wrote:
> >>>> On 2/14/26 12:11 PM, Andy Shevchenko wrote:
> >>>>> On Sat, Feb 14, 2026 at 04:08:52PM +0000, Jonathan Cameron wrote:
> >>>>>> On Sun, 8 Feb 2026 14:50:23 +0200
> >>>>>> Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> >>>>>>> On Fri, Feb 06, 2026 at 06:07:12PM +0200, Antoniu Miclaus wrote:
...
> >>>>>>> I believe there is a better approach, what you need is rather a flag
> >>>>>>> to SPI core to tell that this is the device with shared CS.
> >>>>>>
> >>>>>> Antoniu, this comment from Andy needs addressing before we move
> >>>>>> on. It seems fairly fundamental and I'm not seeing a reply to it on list.
> >>>>>>
> >>>>>> I'm not entirely sure what Andy is suggesting will work but this
> >>>>>> is perhaps a mismatch in really understanding what is going on here.
> >>>>>> Andy, how would a flag work given they seem to be separately addressable
> >>>>>> SPI buses. I think this isn't a shared SPI CS, but rather a device
> >>>>>> with two entirely separate SPI buses. I think the only reason
> >>>>>> we are bothering to implement it as a single device at all is the
> >>>>>> shared backend.
> >>>>>
> >>>>> My understanding that there are two devices that for whatever reason share
> >>>>
> >>>> It is the opposite. It is a _single_ device with _two_ CS lines.
> >>>
> >>> Don't we have already support for that? This changes the picture even more towards
> >>> NAKing this. See below why.
> >>
> >> Yes, spi_new_ancillary_device() was introduced exactly for this sort
> >> of thing, which is why I think it makes sense to use it.
> >>
> >>>> adc@0 {
> >>>> reg = <0>, <1>;
> >>>> ...
> >>>> };
> >>>>
> >>>>> the same CS line. Yes, I probably misread the idea behind, but I meant
> >>>>> some flag for SPI device that tells SPI core that the CS it wants is shared
> >>>>> (maybe a high bit in the cs field or so), then CS core won't complain on
> >>>>> validation about using the same cs number which is "already in use".
> >>>>
> >>>> There was one existing user in the kernel of spi_new_ancillary_device()
> >>>> that looked like this, so it seemed the right way to approach it. However,
> >>>> code was added later that caused the primary SPI device to "claim" both
> >>>> CS lines for itself and probably broke the one existing user of
> >>>> spi_new_ancillary_device() (hard to tell without hardware to test).
> >>>>
> >>>> The idea here was to unbreak that so we could use spi_new_ancillary_device()
> >>>> just as in the existing use case.
> >>>>
> >>>> The patch for that could have been a bit more strict to only allow the
> >>>> spi_new_ancillary_device() to take CS 1 and fail otherwise, but users
> >>>> are going to notice if it isn't working right anyway, so I didn't ask
> >>>> for more checking.
> >>>
> >>>>>> There is an argument that maybe we should be looking at how
> >>>>>> to do data muxing backends to support the more general case of two
> >>>>>> separate chips feeding into a single buffer, but that's a complex
> >>>>>> beast and I'm not sure if it is something we actually need.
> >>>>
> >>>> I think it would actually be quite similar to what is done in this
> >>>> series.
> >>>
> >>> TBH, the change sounds to me like a hack. It doesn't cover other potential ways
> >>> of the multi-cs devices come into play. Given that SPI core supports multi-cs
> >>> I don't see a good justification for this patch.
> >>>
> >>> What did I miss?
> >>
> >> As far as I can tell, other than the one existing user of
> >> spi_new_ancillary_device(), other SPI multi-CS stuff is only used
> >> by SPI flash memory devices, not general SPI devices. There code
> >> that is being modified here was introduced to support the SPI
> >> flash memory devices, so that use case is already covered by
> >> existing code.
> >
> > Right. And obvious question why can't we apply the same approach
> > to any SPI device? Like extending existing code to cover generic
> > cases.
>
> spi_new_ancillary_device() was already accepted in the kernel as the
> solution for this sort of use case, so isn't it already the generic
> approach?
I don't think the single user functionality is considered generic.
> I can see that it could possibly be nice if the SPI core saw that
> there was more than one CS and called spi_new_ancillary_device()
> automatically and somehow passed that along with the main SPI device
> to the driver probe function. But since this is only the second user
> of spi_new_ancillary_device(), I don't think we have enough data
> points to be able to say if this is really what all peripheral drivers
> would want.
Also, if that one designed for the case, why is needed patching?
...
The mentioned approach predates the SPI memory chip support being
integrated into SPI core. I think we should consider to kill
spi_new_ancillary_device() in favour of using the same mechanism
as being used for SPI mem chips.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-17 8:28 ` Andy Shevchenko
@ 2026-02-17 22:55 ` David Lechner
2026-02-18 19:08 ` Jonathan Cameron
0 siblings, 1 reply; 35+ messages in thread
From: David Lechner @ 2026-02-17 22:55 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Jonathan Cameron, Antoniu Miclaus, Lars-Peter Clausen,
Michael Hennerich, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On 2/17/26 2:28 AM, Andy Shevchenko wrote:
> On Mon, Feb 16, 2026 at 12:53:10PM -0600, David Lechner wrote:
>> On 2/16/26 1:14 AM, Andy Shevchenko wrote:
>>> On Sun, Feb 15, 2026 at 05:16:47PM -0600, David Lechner wrote:
>>>> On 2/15/26 2:03 AM, Andy Shevchenko wrote:
>>>>> On Sat, Feb 14, 2026 at 12:31:12PM -0600, David Lechner wrote:
>>>>>> On 2/14/26 12:11 PM, Andy Shevchenko wrote:
>>>>>>> On Sat, Feb 14, 2026 at 04:08:52PM +0000, Jonathan Cameron wrote:
>>>>>>>> On Sun, 8 Feb 2026 14:50:23 +0200
>>>>>>>> Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
>>>>>>>>> On Fri, Feb 06, 2026 at 06:07:12PM +0200, Antoniu Miclaus wrote:
>
> ...
>
>>>>>>>>> I believe there is a better approach, what you need is rather a flag
>>>>>>>>> to SPI core to tell that this is the device with shared CS.
>>>>>>>>
>>>>>>>> Antoniu, this comment from Andy needs addressing before we move
>>>>>>>> on. It seems fairly fundamental and I'm not seeing a reply to it on list.
>>>>>>>>
>>>>>>>> I'm not entirely sure what Andy is suggesting will work but this
>>>>>>>> is perhaps a mismatch in really understanding what is going on here.
>>>>>>>> Andy, how would a flag work given they seem to be separately addressable
>>>>>>>> SPI buses. I think this isn't a shared SPI CS, but rather a device
>>>>>>>> with two entirely separate SPI buses. I think the only reason
>>>>>>>> we are bothering to implement it as a single device at all is the
>>>>>>>> shared backend.
>>>>>>>
>>>>>>> My understanding that there are two devices that for whatever reason share
>>>>>>
>>>>>> It is the opposite. It is a _single_ device with _two_ CS lines.
>>>>>
>>>>> Don't we have already support for that? This changes the picture even more towards
>>>>> NAKing this. See below why.
>>>>
>>>> Yes, spi_new_ancillary_device() was introduced exactly for this sort
>>>> of thing, which is why I think it makes sense to use it.
>>>>
>>>>>> adc@0 {
>>>>>> reg = <0>, <1>;
>>>>>> ...
>>>>>> };
>>>>>>
>>>>>>> the same CS line. Yes, I probably misread the idea behind, but I meant
>>>>>>> some flag for SPI device that tells SPI core that the CS it wants is shared
>>>>>>> (maybe a high bit in the cs field or so), then CS core won't complain on
>>>>>>> validation about using the same cs number which is "already in use".
>>>>>>
>>>>>> There was one existing user in the kernel of spi_new_ancillary_device()
>>>>>> that looked like this, so it seemed the right way to approach it. However,
>>>>>> code was added later that caused the primary SPI device to "claim" both
>>>>>> CS lines for itself and probably broke the one existing user of
>>>>>> spi_new_ancillary_device() (hard to tell without hardware to test).
>>>>>>
>>>>>> The idea here was to unbreak that so we could use spi_new_ancillary_device()
>>>>>> just as in the existing use case.
>>>>>>
>>>>>> The patch for that could have been a bit more strict to only allow the
>>>>>> spi_new_ancillary_device() to take CS 1 and fail otherwise, but users
>>>>>> are going to notice if it isn't working right anyway, so I didn't ask
>>>>>> for more checking.
>>>>>
>>>>>>>> There is an argument that maybe we should be looking at how
>>>>>>>> to do data muxing backends to support the more general case of two
>>>>>>>> separate chips feeding into a single buffer, but that's a complex
>>>>>>>> beast and I'm not sure if it is something we actually need.
>>>>>>
>>>>>> I think it would actually be quite similar to what is done in this
>>>>>> series.
>>>>>
>>>>> TBH, the change sounds to me like a hack. It doesn't cover other potential ways
>>>>> of the multi-cs devices come into play. Given that SPI core supports multi-cs
>>>>> I don't see a good justification for this patch.
>>>>>
>>>>> What did I miss?
>>>>
>>>> As far as I can tell, other than the one existing user of
>>>> spi_new_ancillary_device(), other SPI multi-CS stuff is only used
>>>> by SPI flash memory devices, not general SPI devices. There code
>>>> that is being modified here was introduced to support the SPI
>>>> flash memory devices, so that use case is already covered by
>>>> existing code.
>>>
>>> Right. And obvious question why can't we apply the same approach
>>> to any SPI device? Like extending existing code to cover generic
>>> cases.
>>
>> spi_new_ancillary_device() was already accepted in the kernel as the
>> solution for this sort of use case, so isn't it already the generic
>> approach?
>
> I don't think the single user functionality is considered generic.
>
>> I can see that it could possibly be nice if the SPI core saw that
>> there was more than one CS and called spi_new_ancillary_device()
>> automatically and somehow passed that along with the main SPI device
>> to the driver probe function. But since this is only the second user
>> of spi_new_ancillary_device(), I don't think we have enough data
>> points to be able to say if this is really what all peripheral drivers
>> would want.
>
> Also, if that one designed for the case, why is needed patching?
Because the multi-CS stuff for SPI flash memory was added later
and broke it. There is only one obscure user, so it is not entirely
surprising if no one noticed yet.
>
> ...
>
> The mentioned approach predates the SPI memory chip support being
> integrated into SPI core. I think we should consider to kill
> spi_new_ancillary_device() in favour of using the same mechanism
> as being used for SPI mem chips.
>
I'm not sure the SPI mem work ever actually got finished. In the code, see:
if ((of_property_present(nc, "parallel-memories")) &&
(!(ctlr->flags & SPI_CONTROLLER_MULTI_CS))) {
dev_err(&ctlr->dev, "SPI controller doesn't support multi CS\n");
return -EINVAL;
}
But there is no SPI controller that has that flag. So I'm not sure if
anyone is actually using this yet. And anyway I think the aim there was
to be able to assert two CS at the same time, which is not what we are
aiming to do here.
And the other potential user of multi-cs is stacked-memories, but this
is only mentioned in dt-bindings docs and nowhere else.
There doesn't seem to be any other code besides the validation that is
done when the SPI device is added that makes use of more than one CS line.
I would like to agree with you that there should be a better way, but I
still don't see an obvious way to do it if there is one (other than the
suggestion I already gave that probe should somehow give you two spi
devices instead of one).
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-17 22:55 ` David Lechner
@ 2026-02-18 19:08 ` Jonathan Cameron
2026-02-20 10:45 ` Andy Shevchenko
0 siblings, 1 reply; 35+ messages in thread
From: Jonathan Cameron @ 2026-02-18 19:08 UTC (permalink / raw)
To: David Lechner
Cc: Andy Shevchenko, Antoniu Miclaus, Lars-Peter Clausen,
Michael Hennerich, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On Tue, 17 Feb 2026 16:55:56 -0600
David Lechner <dlechner@baylibre.com> wrote:
> On 2/17/26 2:28 AM, Andy Shevchenko wrote:
> > On Mon, Feb 16, 2026 at 12:53:10PM -0600, David Lechner wrote:
> >> On 2/16/26 1:14 AM, Andy Shevchenko wrote:
> >>> On Sun, Feb 15, 2026 at 05:16:47PM -0600, David Lechner wrote:
> >>>> On 2/15/26 2:03 AM, Andy Shevchenko wrote:
> >>>>> On Sat, Feb 14, 2026 at 12:31:12PM -0600, David Lechner wrote:
> >>>>>> On 2/14/26 12:11 PM, Andy Shevchenko wrote:
> >>>>>>> On Sat, Feb 14, 2026 at 04:08:52PM +0000, Jonathan Cameron wrote:
> >>>>>>>> On Sun, 8 Feb 2026 14:50:23 +0200
> >>>>>>>> Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> >>>>>>>>> On Fri, Feb 06, 2026 at 06:07:12PM +0200, Antoniu Miclaus wrote:
> >
> > ...
> >
> >>>>>>>>> I believe there is a better approach, what you need is rather a flag
> >>>>>>>>> to SPI core to tell that this is the device with shared CS.
> >>>>>>>>
> >>>>>>>> Antoniu, this comment from Andy needs addressing before we move
> >>>>>>>> on. It seems fairly fundamental and I'm not seeing a reply to it on list.
> >>>>>>>>
> >>>>>>>> I'm not entirely sure what Andy is suggesting will work but this
> >>>>>>>> is perhaps a mismatch in really understanding what is going on here.
> >>>>>>>> Andy, how would a flag work given they seem to be separately addressable
> >>>>>>>> SPI buses. I think this isn't a shared SPI CS, but rather a device
> >>>>>>>> with two entirely separate SPI buses. I think the only reason
> >>>>>>>> we are bothering to implement it as a single device at all is the
> >>>>>>>> shared backend.
> >>>>>>>
> >>>>>>> My understanding that there are two devices that for whatever reason share
> >>>>>>
> >>>>>> It is the opposite. It is a _single_ device with _two_ CS lines.
> >>>>>
> >>>>> Don't we have already support for that? This changes the picture even more towards
> >>>>> NAKing this. See below why.
> >>>>
> >>>> Yes, spi_new_ancillary_device() was introduced exactly for this sort
> >>>> of thing, which is why I think it makes sense to use it.
> >>>>
> >>>>>> adc@0 {
> >>>>>> reg = <0>, <1>;
> >>>>>> ...
> >>>>>> };
> >>>>>>
> >>>>>>> the same CS line. Yes, I probably misread the idea behind, but I meant
> >>>>>>> some flag for SPI device that tells SPI core that the CS it wants is shared
> >>>>>>> (maybe a high bit in the cs field or so), then CS core won't complain on
> >>>>>>> validation about using the same cs number which is "already in use".
> >>>>>>
> >>>>>> There was one existing user in the kernel of spi_new_ancillary_device()
> >>>>>> that looked like this, so it seemed the right way to approach it. However,
> >>>>>> code was added later that caused the primary SPI device to "claim" both
> >>>>>> CS lines for itself and probably broke the one existing user of
> >>>>>> spi_new_ancillary_device() (hard to tell without hardware to test).
> >>>>>>
> >>>>>> The idea here was to unbreak that so we could use spi_new_ancillary_device()
> >>>>>> just as in the existing use case.
> >>>>>>
> >>>>>> The patch for that could have been a bit more strict to only allow the
> >>>>>> spi_new_ancillary_device() to take CS 1 and fail otherwise, but users
> >>>>>> are going to notice if it isn't working right anyway, so I didn't ask
> >>>>>> for more checking.
> >>>>>
> >>>>>>>> There is an argument that maybe we should be looking at how
> >>>>>>>> to do data muxing backends to support the more general case of two
> >>>>>>>> separate chips feeding into a single buffer, but that's a complex
> >>>>>>>> beast and I'm not sure if it is something we actually need.
> >>>>>>
> >>>>>> I think it would actually be quite similar to what is done in this
> >>>>>> series.
> >>>>>
> >>>>> TBH, the change sounds to me like a hack. It doesn't cover other potential ways
> >>>>> of the multi-cs devices come into play. Given that SPI core supports multi-cs
> >>>>> I don't see a good justification for this patch.
> >>>>>
> >>>>> What did I miss?
> >>>>
> >>>> As far as I can tell, other than the one existing user of
> >>>> spi_new_ancillary_device(), other SPI multi-CS stuff is only used
> >>>> by SPI flash memory devices, not general SPI devices. There code
> >>>> that is being modified here was introduced to support the SPI
> >>>> flash memory devices, so that use case is already covered by
> >>>> existing code.
> >>>
> >>> Right. And obvious question why can't we apply the same approach
> >>> to any SPI device? Like extending existing code to cover generic
> >>> cases.
> >>
> >> spi_new_ancillary_device() was already accepted in the kernel as the
> >> solution for this sort of use case, so isn't it already the generic
> >> approach?
> >
> > I don't think the single user functionality is considered generic.
> >
> >> I can see that it could possibly be nice if the SPI core saw that
> >> there was more than one CS and called spi_new_ancillary_device()
> >> automatically and somehow passed that along with the main SPI device
> >> to the driver probe function. But since this is only the second user
> >> of spi_new_ancillary_device(), I don't think we have enough data
> >> points to be able to say if this is really what all peripheral drivers
> >> would want.
> >
> > Also, if that one designed for the case, why is needed patching?
>
> Because the multi-CS stuff for SPI flash memory was added later
> and broke it. There is only one obscure user, so it is not entirely
> surprising if no one noticed yet.
>
> >
> > ...
> >
> > The mentioned approach predates the SPI memory chip support being
> > integrated into SPI core. I think we should consider to kill
> > spi_new_ancillary_device() in favour of using the same mechanism
> > as being used for SPI mem chips.
> >
>
> I'm not sure the SPI mem work ever actually got finished. In the code, see:
>
> if ((of_property_present(nc, "parallel-memories")) &&
> (!(ctlr->flags & SPI_CONTROLLER_MULTI_CS))) {
> dev_err(&ctlr->dev, "SPI controller doesn't support multi CS\n");
> return -EINVAL;
> }
>
> But there is no SPI controller that has that flag. So I'm not sure if
> anyone is actually using this yet. And anyway I think the aim there was
> to be able to assert two CS at the same time, which is not what we are
> aiming to do here.
>
> And the other potential user of multi-cs is stacked-memories, but this
> is only mentioned in dt-bindings docs and nowhere else.
>
> There doesn't seem to be any other code besides the validation that is
> done when the SPI device is added that makes use of more than one CS line.
>
> I would like to agree with you that there should be a better way, but I
> still don't see an obvious way to do it if there is one (other than the
> suggestion I already gave that probe should somehow give you two spi
> devices instead of one).
>
I wonder a bit if a single SPI device but with explicit control of which
CS index in the spi_messages or similar would work? The disadvantage is you'd
probably want a lot of helpers to have variants with a selection parameter.
Would end up smelling like paged registers, just with a chip select to pick
the page rather than a page register.
If this isn't common, may not be worth the effort.
Jonathan
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-18 19:08 ` Jonathan Cameron
@ 2026-02-20 10:45 ` Andy Shevchenko
0 siblings, 0 replies; 35+ messages in thread
From: Andy Shevchenko @ 2026-02-20 10:45 UTC (permalink / raw)
To: Jonathan Cameron
Cc: David Lechner, Antoniu Miclaus, Lars-Peter Clausen,
Michael Hennerich, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Mark Brown,
linux-iio, devicetree, linux-kernel, linux-spi
On Wed, Feb 18, 2026 at 07:08:34PM +0000, Jonathan Cameron wrote:
> On Tue, 17 Feb 2026 16:55:56 -0600
> David Lechner <dlechner@baylibre.com> wrote:
> > On 2/17/26 2:28 AM, Andy Shevchenko wrote:
> > > On Mon, Feb 16, 2026 at 12:53:10PM -0600, David Lechner wrote:
> > >> On 2/16/26 1:14 AM, Andy Shevchenko wrote:
> > >>> On Sun, Feb 15, 2026 at 05:16:47PM -0600, David Lechner wrote:
> > >>>> On 2/15/26 2:03 AM, Andy Shevchenko wrote:
> > >>>>> On Sat, Feb 14, 2026 at 12:31:12PM -0600, David Lechner wrote:
> > >>>>>> On 2/14/26 12:11 PM, Andy Shevchenko wrote:
> > >>>>>>> On Sat, Feb 14, 2026 at 04:08:52PM +0000, Jonathan Cameron wrote:
> > >>>>>>>> On Sun, 8 Feb 2026 14:50:23 +0200
> > >>>>>>>> Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> > >>>>>>>>> On Fri, Feb 06, 2026 at 06:07:12PM +0200, Antoniu Miclaus wrote:
...
> > >>>>>>>>> I believe there is a better approach, what you need is rather a flag
> > >>>>>>>>> to SPI core to tell that this is the device with shared CS.
> > >>>>>>>>
> > >>>>>>>> Antoniu, this comment from Andy needs addressing before we move
> > >>>>>>>> on. It seems fairly fundamental and I'm not seeing a reply to it on list.
> > >>>>>>>>
> > >>>>>>>> I'm not entirely sure what Andy is suggesting will work but this
> > >>>>>>>> is perhaps a mismatch in really understanding what is going on here.
> > >>>>>>>> Andy, how would a flag work given they seem to be separately addressable
> > >>>>>>>> SPI buses. I think this isn't a shared SPI CS, but rather a device
> > >>>>>>>> with two entirely separate SPI buses. I think the only reason
> > >>>>>>>> we are bothering to implement it as a single device at all is the
> > >>>>>>>> shared backend.
> > >>>>>>>
> > >>>>>>> My understanding that there are two devices that for whatever reason share
> > >>>>>>
> > >>>>>> It is the opposite. It is a _single_ device with _two_ CS lines.
> > >>>>>
> > >>>>> Don't we have already support for that? This changes the picture even more towards
> > >>>>> NAKing this. See below why.
> > >>>>
> > >>>> Yes, spi_new_ancillary_device() was introduced exactly for this sort
> > >>>> of thing, which is why I think it makes sense to use it.
> > >>>>
> > >>>>>> adc@0 {
> > >>>>>> reg = <0>, <1>;
> > >>>>>> ...
> > >>>>>> };
> > >>>>>>
> > >>>>>>> the same CS line. Yes, I probably misread the idea behind, but I meant
> > >>>>>>> some flag for SPI device that tells SPI core that the CS it wants is shared
> > >>>>>>> (maybe a high bit in the cs field or so), then CS core won't complain on
> > >>>>>>> validation about using the same cs number which is "already in use".
> > >>>>>>
> > >>>>>> There was one existing user in the kernel of spi_new_ancillary_device()
> > >>>>>> that looked like this, so it seemed the right way to approach it. However,
> > >>>>>> code was added later that caused the primary SPI device to "claim" both
> > >>>>>> CS lines for itself and probably broke the one existing user of
> > >>>>>> spi_new_ancillary_device() (hard to tell without hardware to test).
> > >>>>>>
> > >>>>>> The idea here was to unbreak that so we could use spi_new_ancillary_device()
> > >>>>>> just as in the existing use case.
> > >>>>>>
> > >>>>>> The patch for that could have been a bit more strict to only allow the
> > >>>>>> spi_new_ancillary_device() to take CS 1 and fail otherwise, but users
> > >>>>>> are going to notice if it isn't working right anyway, so I didn't ask
> > >>>>>> for more checking.
> > >>>>>
> > >>>>>>>> There is an argument that maybe we should be looking at how
> > >>>>>>>> to do data muxing backends to support the more general case of two
> > >>>>>>>> separate chips feeding into a single buffer, but that's a complex
> > >>>>>>>> beast and I'm not sure if it is something we actually need.
> > >>>>>>
> > >>>>>> I think it would actually be quite similar to what is done in this
> > >>>>>> series.
> > >>>>>
> > >>>>> TBH, the change sounds to me like a hack. It doesn't cover other potential ways
> > >>>>> of the multi-cs devices come into play. Given that SPI core supports multi-cs
> > >>>>> I don't see a good justification for this patch.
> > >>>>>
> > >>>>> What did I miss?
> > >>>>
> > >>>> As far as I can tell, other than the one existing user of
> > >>>> spi_new_ancillary_device(), other SPI multi-CS stuff is only used
> > >>>> by SPI flash memory devices, not general SPI devices. There code
> > >>>> that is being modified here was introduced to support the SPI
> > >>>> flash memory devices, so that use case is already covered by
> > >>>> existing code.
> > >>>
> > >>> Right. And obvious question why can't we apply the same approach
> > >>> to any SPI device? Like extending existing code to cover generic
> > >>> cases.
> > >>
> > >> spi_new_ancillary_device() was already accepted in the kernel as the
> > >> solution for this sort of use case, so isn't it already the generic
> > >> approach?
> > >
> > > I don't think the single user functionality is considered generic.
> > >
> > >> I can see that it could possibly be nice if the SPI core saw that
> > >> there was more than one CS and called spi_new_ancillary_device()
> > >> automatically and somehow passed that along with the main SPI device
> > >> to the driver probe function. But since this is only the second user
> > >> of spi_new_ancillary_device(), I don't think we have enough data
> > >> points to be able to say if this is really what all peripheral drivers
> > >> would want.
> > >
> > > Also, if that one designed for the case, why is needed patching?
> >
> > Because the multi-CS stuff for SPI flash memory was added later
> > and broke it. There is only one obscure user, so it is not entirely
> > surprising if no one noticed yet.
Sounds to me like fixing multi-CS for SPI (flash mem) to make sure it
works for that case as well is a good idea. Another approach can be to
reconsider both existing ones (pros & cons) and come up with the better
idea and replace them with that.
But fixing an one hack by another hack seems to me not the best strategy.
...
> > > The mentioned approach predates the SPI memory chip support being
> > > integrated into SPI core. I think we should consider to kill
> > > spi_new_ancillary_device() in favour of using the same mechanism
> > > as being used for SPI mem chips.
> >
> > I'm not sure the SPI mem work ever actually got finished. In the code, see:
> >
> > if ((of_property_present(nc, "parallel-memories")) &&
> > (!(ctlr->flags & SPI_CONTROLLER_MULTI_CS))) {
> > dev_err(&ctlr->dev, "SPI controller doesn't support multi CS\n");
> > return -EINVAL;
> > }
> >
> > But there is no SPI controller that has that flag. So I'm not sure if
> > anyone is actually using this yet. And anyway I think the aim there was
> > to be able to assert two CS at the same time, which is not what we are
> > aiming to do here.
Good catch!
Taking what I wrote in the above section, maybe it's the best to remove it
and we go to understand what to do with the spi_new_ancillary_device?
> > And the other potential user of multi-cs is stacked-memories, but this
> > is only mentioned in dt-bindings docs and nowhere else.
> >
> > There doesn't seem to be any other code besides the validation that is
> > done when the SPI device is added that makes use of more than one CS line.
> >
> > I would like to agree with you that there should be a better way, but I
> > still don't see an obvious way to do it if there is one (other than the
> > suggestion I already gave that probe should somehow give you two spi
> > devices instead of one).
>
> I wonder a bit if a single SPI device but with explicit control of which
> CS index in the spi_messages or similar would work? The disadvantage is you'd
> probably want a lot of helpers to have variants with a selection parameter.
>
> Would end up smelling like paged registers, just with a chip select to pick
> the page rather than a page register.
>
> If this isn't common, may not be worth the effort.
At least that's common for I²C EEPROMs.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: (subset) [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
2026-02-06 16:07 [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
` (4 preceding siblings ...)
2026-02-08 12:50 ` [PATCH v2 0/4] " Andy Shevchenko
@ 2026-02-25 19:07 ` Mark Brown
5 siblings, 0 replies; 35+ messages in thread
From: Mark Brown @ 2026-02-25 19:07 UTC (permalink / raw)
To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, linux-iio,
devicetree, linux-kernel, linux-spi, Antoniu Miclaus
On Fri, 06 Feb 2026 18:07:12 +0200, Antoniu Miclaus wrote:
> Add support for the AD4880, a dual-channel 20-bit 40MSPS SAR ADC from
> the same family as AD4080.
>
> The AD4880 has two independent ADC channels, each with its own SPI
> configuration interface and LVDS data output. The driver uses
> spi_new_ancillary_device() for the second channel's SPI and requires
> two io-backend instances for the data interfaces.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
Thanks!
[1/4] spi: allow ancillary devices to share parent's chip selects
commit: ffef4123043c5bb29e61052a41e577ae1ee6837a
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply [flat|nested] 35+ messages in thread
end of thread, other threads:[~2026-02-25 19:07 UTC | newest]
Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-06 16:07 [PATCH v2 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
2026-02-06 16:07 ` [PATCH v2 1/4] spi: allow ancillary devices to share parent's chip selects Antoniu Miclaus
2026-02-07 18:09 ` David Lechner
2026-02-06 16:07 ` [PATCH v2 2/4] iio: backend: add devm_iio_backend_get_by_index() Antoniu Miclaus
2026-02-07 14:57 ` Jonathan Cameron
2026-02-07 18:13 ` David Lechner
2026-02-08 9:24 ` Nuno Sá
2026-02-09 15:28 ` David Lechner
2026-02-09 16:47 ` Nuno Sá
2026-02-09 17:48 ` Nuno Sá
2026-02-09 18:20 ` David Lechner
2026-02-06 16:07 ` [PATCH v2 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support Antoniu Miclaus
2026-02-07 10:41 ` Krzysztof Kozlowski
2026-02-08 9:16 ` Nuno Sá
2026-02-08 9:20 ` Krzysztof Kozlowski
2026-02-09 16:43 ` Nuno Sá
2026-02-09 17:13 ` Krzysztof Kozlowski
2026-02-09 17:45 ` Nuno Sá
2026-02-06 16:07 ` [PATCH v2 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
2026-02-07 15:04 ` Jonathan Cameron
2026-02-07 18:29 ` David Lechner
2026-02-08 9:26 ` Nuno Sá
2026-02-08 12:50 ` [PATCH v2 0/4] " Andy Shevchenko
2026-02-14 16:08 ` Jonathan Cameron
2026-02-14 18:11 ` Andy Shevchenko
2026-02-14 18:31 ` David Lechner
2026-02-15 8:03 ` Andy Shevchenko
2026-02-15 23:16 ` David Lechner
2026-02-16 7:14 ` Andy Shevchenko
2026-02-16 18:53 ` David Lechner
2026-02-17 8:28 ` Andy Shevchenko
2026-02-17 22:55 ` David Lechner
2026-02-18 19:08 ` Jonathan Cameron
2026-02-20 10:45 ` Andy Shevchenko
2026-02-25 19:07 ` (subset) " Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox