public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
@ 2026-03-05 11:37 Antoniu Miclaus
  2026-03-05 11:37 ` [PATCH v5 1/4] iio: backend: use __free(fwnode_handle) for automatic cleanup Antoniu Miclaus
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Antoniu Miclaus @ 2026-03-05 11:37 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,
	linux-iio, devicetree, linux-kernel

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:
  - Use __free(fwnode_handle) for automatic cleanup in iio backend
  - Refactored devm_iio_backend_get_by_index() 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

Changes in v5:
  - Drop the SPI patches (already applied)
  - Split the __free(fwnode_handle) cleanup into a separate patch (patch 1)
  - Fix "Get's" -> "Gets" typo in devm_iio_backend_get_by_index()
    kernel-doc (patch 2)
  - Declare loop variables in for-loop initializers (patch 4)
  - Drop redundant num_channels > 1 guard around ancillary device
    setup loop (patch 4)

Antoniu Miclaus (4):
  iio: backend: use __free(fwnode_handle) for automatic cleanup
  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          |  53 +++-
 drivers/iio/adc/ad4080.c                      | 230 ++++++++++++++----
 drivers/iio/industrialio-backend.c            |  62 +++--
 include/linux/iio/backend.h                   |   2 +
 4 files changed, 278 insertions(+), 69 deletions(-)

-- 
2.43.0


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

* [PATCH v5 1/4] iio: backend: use __free(fwnode_handle) for automatic cleanup
  2026-03-05 11:37 [PATCH v5 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
@ 2026-03-05 11:37 ` Antoniu Miclaus
  2026-03-05 11:37 ` [PATCH v5 2/4] iio: backend: add devm_iio_backend_get_by_index() Antoniu Miclaus
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 14+ messages in thread
From: Antoniu Miclaus @ 2026-03-05 11:37 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,
	linux-iio, devicetree, linux-kernel

Convert __devm_iio_backend_fwnode_get() to use the __free(fwnode_handle)
cleanup attribute for the fwnode_back variable, removing the need for
manual fwnode_handle_put() calls. Move the declaration closer to its
first use, narrowing its scope.

No functional change.

Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
---
 drivers/iio/industrialio-backend.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-backend.c
index 447b694d6d5f..58f7e1426095 100644
--- a/drivers/iio/industrialio-backend.c
+++ b/drivers/iio/industrialio-backend.c
@@ -952,7 +952,6 @@ EXPORT_SYMBOL_NS_GPL(iio_backend_data_transfer_addr, "IIO_BACKEND");
 static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, const char *name,
 							 struct fwnode_handle *fwnode)
 {
-	struct fwnode_handle *fwnode_back;
 	struct iio_backend *back;
 	unsigned int index;
 	int ret;
@@ -967,7 +966,8 @@ static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, con
 		index = 0;
 	}
 
-	fwnode_back = fwnode_find_reference(fwnode, "io-backends", index);
+	struct fwnode_handle *fwnode_back __free(fwnode_handle) =
+		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");
@@ -977,7 +977,6 @@ static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, con
 		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);
@@ -988,7 +987,6 @@ static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, con
 		return back;
 	}
 
-	fwnode_handle_put(fwnode_back);
 	return ERR_PTR(-EPROBE_DEFER);
 }
 
-- 
2.43.0


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

* [PATCH v5 2/4] iio: backend: add devm_iio_backend_get_by_index()
  2026-03-05 11:37 [PATCH v5 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
  2026-03-05 11:37 ` [PATCH v5 1/4] iio: backend: use __free(fwnode_handle) for automatic cleanup Antoniu Miclaus
@ 2026-03-05 11:37 ` Antoniu Miclaus
  2026-03-07 11:55   ` Jonathan Cameron
  2026-03-07 18:17   ` David Lechner
  2026-03-05 11:37 ` [PATCH v5 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support Antoniu Miclaus
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 14+ messages in thread
From: Antoniu Miclaus @ 2026-03-05 11:37 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,
	linux-iio, devicetree, linux-kernel

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.

Extract __devm_iio_backend_fwnode_get_by_index() from the existing
__devm_iio_backend_fwnode_get(), taking the index directly as a
parameter. The new public API devm_iio_backend_get_by_index() uses
the index to find the backend reference in the io-backends property,
avoiding the need for io-backend-names.

Reviewed-by: Nuno Sá <nuno.sa@analog.com>
Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
---
Changes in v5:
  - Split __free(fwnode_handle) cleanup into a separate patch
  - Fix "Get's" -> "Gets" typo in kernel-doc

 drivers/iio/industrialio-backend.c | 60 +++++++++++++++++++++---------
 include/linux/iio/backend.h        |  2 +
 2 files changed, 45 insertions(+), 17 deletions(-)

diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-backend.c
index 58f7e1426095..ab56e964bce4 100644
--- a/drivers/iio/industrialio-backend.c
+++ b/drivers/iio/industrialio-backend.c
@@ -949,25 +949,16 @@ int iio_backend_data_transfer_addr(struct iio_backend *back, u32 address)
 }
 EXPORT_SYMBOL_NS_GPL(iio_backend_data_transfer_addr, "IIO_BACKEND");
 
-static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, const char *name,
-							 struct fwnode_handle *fwnode)
+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 __free(fwnode_handle) =
+		fwnode_find_reference(fwnode, "io-backends", index);
 	struct iio_backend *back;
-	unsigned int index;
 	int ret;
 
-	if (name) {
-		ret = device_property_match_string(dev, "io-backend-names",
-						   name);
-		if (ret < 0)
-			return ERR_PTR(ret);
-		index = ret;
-	} else {
-		index = 0;
-	}
-
-	struct fwnode_handle *fwnode_back __free(fwnode_handle) =
-		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");
@@ -981,8 +972,7 @@ static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, con
 		if (ret)
 			return ERR_PTR(ret);
 
-		if (name)
-			back->idx = index;
+		back->idx = index;
 
 		return back;
 	}
@@ -990,6 +980,24 @@ static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, con
 	return ERR_PTR(-EPROBE_DEFER);
 }
 
+static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, const char *name,
+							 struct fwnode_handle *fwnode)
+{
+	unsigned int index;
+	int ret;
+
+	if (name) {
+		ret = device_property_match_string(dev, "io-backend-names", name);
+		if (ret < 0)
+			return ERR_PTR(ret);
+		index = ret;
+	} else {
+		index = 0;
+	}
+
+	return __devm_iio_backend_fwnode_get_by_index(dev, fwnode, index);
+}
+
 /**
  * devm_iio_backend_get - Device managed backend device get
  * @dev: Consumer device for the backend
@@ -1006,6 +1014,24 @@ struct iio_backend *devm_iio_backend_get(struct device *dev, const char *name)
 }
 EXPORT_SYMBOL_NS_GPL(devm_iio_backend_get, "IIO_BACKEND");
 
+/**
+ * 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
+ *
+ * Gets 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] 14+ messages in thread

* [PATCH v5 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support
  2026-03-05 11:37 [PATCH v5 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
  2026-03-05 11:37 ` [PATCH v5 1/4] iio: backend: use __free(fwnode_handle) for automatic cleanup Antoniu Miclaus
  2026-03-05 11:37 ` [PATCH v5 2/4] iio: backend: add devm_iio_backend_get_by_index() Antoniu Miclaus
@ 2026-03-05 11:37 ` Antoniu Miclaus
  2026-03-07 18:19   ` David Lechner
  2026-03-12 14:53   ` Rob Herring (Arm)
  2026-03-05 11:37 ` [PATCH v5 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
  2026-03-14 11:36 ` [PATCH v5 0/4] " Jonathan Cameron
  4 siblings, 2 replies; 14+ messages in thread
From: Antoniu Miclaus @ 2026-03-05 11:37 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,
	linux-iio, devicetree, linux-kernel

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 v5:
  - No changes

 .../bindings/iio/adc/adi,ad4080.yaml          | 53 ++++++++++++++++++-
 1 file changed, 51 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..0cf86c6f9925 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,10 @@ properties:
   vrefin-supply: true
 
   io-backends:
-    maxItems: 1
+    minItems: 1
+    items:
+      - description: Backend for channel A (primary)
+      - description: Backend for channel B (secondary)
 
   adi,lvds-cnv-enable:
     description: Enable the LVDS signal type on the CNV pin. Default is CMOS.
@@ -78,6 +91,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 +130,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] 14+ messages in thread

* [PATCH v5 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
  2026-03-05 11:37 [PATCH v5 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
                   ` (2 preceding siblings ...)
  2026-03-05 11:37 ` [PATCH v5 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support Antoniu Miclaus
@ 2026-03-05 11:37 ` Antoniu Miclaus
  2026-03-07 11:58   ` Jonathan Cameron
                     ` (2 more replies)
  2026-03-14 11:36 ` [PATCH v5 0/4] " Jonathan Cameron
  4 siblings, 3 replies; 14+ messages in thread
From: Antoniu Miclaus @ 2026-03-05 11:37 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,
	linux-iio, devicetree, linux-kernel

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>
Reviewed-by: Nuno Sá <nuno.sa@analog.com>
Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
---
Changes in v5:
  - Declare loop variables in for-loop initializers
  - Drop redundant num_channels > 1 guard around ancillary device
    setup loop

 drivers/iio/adc/ad4080.c | 230 +++++++++++++++++++++++++++++++--------
 1 file changed, 182 insertions(+), 48 deletions(-)

diff --git a/drivers/iio/adc/ad4080.c b/drivers/iio/adc/ad4080.c
index 7cf3b6ed7940..2d5fdfded466 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,28 @@ 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);
+	int ret;
+
+	for (unsigned int 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 +438,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 +465,51 @@ 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),					\
+		.storagebits = (storage),				\
+	},								\
+}
+
+/*
+ * 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),					\
@@ -438,17 +517,22 @@ static struct iio_chan_spec_ext_info ad4080_ext_info[] = {
 	},								\
 }
 
-static const struct iio_chan_spec ad4080_channel = AD4080_CHANNEL_DEFINE(20, 32);
+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 +594,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 +630,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 +649,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 +658,38 @@ 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);
+	int ret;
+
+	for (unsigned int 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");
 
@@ -617,14 +724,30 @@ 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 devices for additional channels */
+	for (unsigned int ch = 1; ch < st->info->num_channels; ch++) {
+		st->spi[ch] = devm_spi_new_ancillary_device(spi,
+							    spi_get_chipselect(spi, ch));
+		if (IS_ERR(st->spi[ch]))
+			return dev_err_probe(dev, PTR_ERR(st->spi[ch]),
+					     "failed to register ancillary device\n");
+
+		st->regmap[ch] = devm_regmap_init_spi(st->spi[ch],
+						      &ad4080_regmap_config);
+		if (IS_ERR(st->regmap[ch]))
+			return PTR_ERR(st->regmap[ch]);
+	}
+
 	ret = devm_mutex_init(dev, &st->lock);
 	if (ret)
 		return ret;
@@ -632,7 +755,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 +768,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 (unsigned int 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 +802,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 +814,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] 14+ messages in thread

* Re: [PATCH v5 2/4] iio: backend: add devm_iio_backend_get_by_index()
  2026-03-05 11:37 ` [PATCH v5 2/4] iio: backend: add devm_iio_backend_get_by_index() Antoniu Miclaus
@ 2026-03-07 11:55   ` Jonathan Cameron
  2026-03-07 18:17   ` David Lechner
  1 sibling, 0 replies; 14+ messages in thread
From: Jonathan Cameron @ 2026-03-07 11:55 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, linux-iio, devicetree, linux-kernel

On Thu, 5 Mar 2026 13:37:28 +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.
> 
> Extract __devm_iio_backend_fwnode_get_by_index() from the existing
> __devm_iio_backend_fwnode_get(), taking the index directly as a
> parameter. The new public API devm_iio_backend_get_by_index() uses
> the index to find the backend reference in the io-backends property,
> avoiding the need for io-backend-names.
> 
> Reviewed-by: Nuno Sá <nuno.sa@analog.com>
> Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>

One comment on unwanted code movement.  Putting the lines highlighted
back where they were will also make the break up into the previous patch
and this one more sensible wrt to the diff.

Thanks,

Jonathan

> ---
> Changes in v5:
>   - Split __free(fwnode_handle) cleanup into a separate patch
>   - Fix "Get's" -> "Gets" typo in kernel-doc
> 
>  drivers/iio/industrialio-backend.c | 60 +++++++++++++++++++++---------
>  include/linux/iio/backend.h        |  2 +
>  2 files changed, 45 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-backend.c
> index 58f7e1426095..ab56e964bce4 100644
> --- a/drivers/iio/industrialio-backend.c
> +++ b/drivers/iio/industrialio-backend.c
> @@ -949,25 +949,16 @@ int iio_backend_data_transfer_addr(struct iio_backend *back, u32 address)
>  }
>  EXPORT_SYMBOL_NS_GPL(iio_backend_data_transfer_addr, "IIO_BACKEND");
>  
> -static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, const char *name,
> -							 struct fwnode_handle *fwnode)
> +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 __free(fwnode_handle) =
> +		fwnode_find_reference(fwnode, "io-backends", index);

Keep this where it was. So just above the check on whether it succeeded.
Absolutely fine to have uses of __free() declared inline with the code.



>  	struct iio_backend *back;
> -	unsigned int index;
>  	int ret;
>  
> -	if (name) {
> -		ret = device_property_match_string(dev, "io-backend-names",
> -						   name);
> -		if (ret < 0)
> -			return ERR_PTR(ret);
> -		index = ret;
> -	} else {
> -		index = 0;
> -	}
> -
> -	struct fwnode_handle *fwnode_back __free(fwnode_handle) =
> -		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");
> @@ -981,8 +972,7 @@ static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, con
>  		if (ret)
>  			return ERR_PTR(ret);
>  
> -		if (name)
> -			back->idx = index;
> +		back->idx = index;
>  
>  		return back;


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

* Re: [PATCH v5 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
  2026-03-05 11:37 ` [PATCH v5 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
@ 2026-03-07 11:58   ` Jonathan Cameron
  2026-03-07 17:11   ` kernel test robot
  2026-03-08  0:19   ` kernel test robot
  2 siblings, 0 replies; 14+ messages in thread
From: Jonathan Cameron @ 2026-03-07 11:58 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, linux-iio, devicetree, linux-kernel

On Thu, 5 Mar 2026 13:37:30 +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.
> 
> Reviewed-by: David Lechner <dlechner@baylibre.com>
> Reviewed-by: Nuno Sá <nuno.sa@analog.com>
> Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
This LGTM.

If nothing else comes up in review, I can make the code movement I suggested
in patch 2 as a tweak whilst applying rather than needing a v6.

Jonathan

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

* Re: [PATCH v5 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
  2026-03-05 11:37 ` [PATCH v5 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
  2026-03-07 11:58   ` Jonathan Cameron
@ 2026-03-07 17:11   ` kernel test robot
  2026-03-07 18:14     ` David Lechner
  2026-03-08  0:19   ` kernel test robot
  2 siblings, 1 reply; 14+ messages in thread
From: kernel test robot @ 2026-03-07 17:11 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,
	linux-iio, devicetree, linux-kernel
  Cc: oe-kbuild-all

Hi Antoniu,

kernel test robot noticed the following build errors:

[auto build test ERROR on v7.0-rc2]
[also build test ERROR on linus/master]
[cannot apply to jic23-iio/togreg next-20260306]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Antoniu-Miclaus/iio-backend-use-__free-fwnode_handle-for-automatic-cleanup/20260305-194647
base:   v7.0-rc2
patch link:    https://lore.kernel.org/r/20260305113756.47243-5-antoniu.miclaus%40analog.com
patch subject: [PATCH v5 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20260308/202603080146.6a7IzS7i-lkp@intel.com/config)
compiler: sh4-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260308/202603080146.6a7IzS7i-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603080146.6a7IzS7i-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/iio/adc/ad4080.c: In function 'ad4080_probe':
>> drivers/iio/adc/ad4080.c:739:31: error: implicit declaration of function 'devm_spi_new_ancillary_device'; did you mean 'spi_new_ancillary_device'? [-Wimplicit-function-declaration]
     739 |                 st->spi[ch] = devm_spi_new_ancillary_device(spi,
         |                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         |                               spi_new_ancillary_device
>> drivers/iio/adc/ad4080.c:739:29: error: assignment to 'struct spi_device *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     739 |                 st->spi[ch] = devm_spi_new_ancillary_device(spi,
         |                             ^


vim +739 drivers/iio/adc/ad4080.c

   705	
   706	static int ad4080_probe(struct spi_device *spi)
   707	{
   708		struct iio_dev *indio_dev;
   709		struct device *dev = &spi->dev;
   710		struct ad4080_state *st;
   711		struct clk *clk;
   712		int ret;
   713	
   714		indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
   715		if (!indio_dev)
   716			return -ENOMEM;
   717	
   718		st = iio_priv(indio_dev);
   719	
   720		ret = devm_regulator_bulk_get_enable(dev,
   721						     ARRAY_SIZE(ad4080_power_supplies),
   722						     ad4080_power_supplies);
   723		if (ret)
   724			return dev_err_probe(dev, ret,
   725					     "failed to get and enable supplies\n");
   726	
   727		/* Setup primary SPI device (channel 0) */
   728		st->spi[0] = spi;
   729		st->regmap[0] = devm_regmap_init_spi(spi, &ad4080_regmap_config);
   730		if (IS_ERR(st->regmap[0]))
   731			return PTR_ERR(st->regmap[0]);
   732	
   733		st->info = spi_get_device_match_data(spi);
   734		if (!st->info)
   735			return -ENODEV;
   736	
   737		/* Setup ancillary SPI devices for additional channels */
   738		for (unsigned int ch = 1; ch < st->info->num_channels; ch++) {
 > 739			st->spi[ch] = devm_spi_new_ancillary_device(spi,
   740								    spi_get_chipselect(spi, ch));
   741			if (IS_ERR(st->spi[ch]))
   742				return dev_err_probe(dev, PTR_ERR(st->spi[ch]),
   743						     "failed to register ancillary device\n");
   744	
   745			st->regmap[ch] = devm_regmap_init_spi(st->spi[ch],
   746							      &ad4080_regmap_config);
   747			if (IS_ERR(st->regmap[ch]))
   748				return PTR_ERR(st->regmap[ch]);
   749		}
   750	
   751		ret = devm_mutex_init(dev, &st->lock);
   752		if (ret)
   753			return ret;
   754	
   755		indio_dev->name = st->info->name;
   756		indio_dev->channels = st->info->channels;
   757		indio_dev->num_channels = st->info->num_channels;
   758		indio_dev->info = st->info->num_channels > 1 ?
   759				  &ad4880_iio_info : &ad4080_iio_info;
   760	
   761		ret = ad4080_properties_parse(st);
   762		if (ret)
   763			return ret;
   764	
   765		clk = devm_clk_get_enabled(&spi->dev, "cnv");
   766		if (IS_ERR(clk))
   767			return PTR_ERR(clk);
   768	
   769		st->clk_rate = clk_get_rate(clk);
   770	
   771		/* Get backends for all channels */
   772		for (unsigned int ch = 0; ch < st->info->num_channels; ch++) {
   773			st->back[ch] = devm_iio_backend_get_by_index(dev, ch);
   774			if (IS_ERR(st->back[ch]))
   775				return PTR_ERR(st->back[ch]);
   776	
   777			ret = devm_iio_backend_enable(dev, st->back[ch]);
   778			if (ret)
   779				return ret;
   780		}
   781	
   782		/*
   783		 * Request buffer from the first backend only. For multi-channel
   784		 * devices (e.g., AD4880), all backends share a single IIO buffer
   785		 * as data from all ADC channels is interleaved into one stream.
   786		 */
   787		ret = devm_iio_backend_request_buffer(dev, st->back[0], indio_dev);
   788		if (ret)
   789			return ret;
   790	
   791		ret = ad4080_setup(indio_dev);
   792		if (ret)
   793			return ret;
   794	
   795		return devm_iio_device_register(&spi->dev, indio_dev);
   796	}
   797	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH v5 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
  2026-03-07 17:11   ` kernel test robot
@ 2026-03-07 18:14     ` David Lechner
  0 siblings, 0 replies; 14+ messages in thread
From: David Lechner @ 2026-03-07 18:14 UTC (permalink / raw)
  To: kernel test robot, Antoniu Miclaus, Lars-Peter Clausen,
	Michael Hennerich, Jonathan Cameron, Nuno Sá,
	Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Olivier Moysan, linux-iio, devicetree, linux-kernel
  Cc: oe-kbuild-all

On 3/7/26 11:11 AM, kernel test robot wrote:
> Hi Antoniu,
> 
> kernel test robot noticed the following build errors:
> 
> [auto build test ERROR on v7.0-rc2]
> [also build test ERROR on linus/master]
> [cannot apply to jic23-iio/togreg next-20260306]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Antoniu-Miclaus/iio-backend-use-__free-fwnode_handle-for-automatic-cleanup/20260305-194647
> base:   v7.0-rc2
> patch link:    https://lore.kernel.org/r/20260305113756.47243-5-antoniu.miclaus%40analog.com
> patch subject: [PATCH v5 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
> config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20260308/202603080146.6a7IzS7i-lkp@intel.com/config)
> compiler: sh4-linux-gcc (GCC) 15.2.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260308/202603080146.6a7IzS7i-lkp@intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202603080146.6a7IzS7i-lkp@intel.com/
> 
> All errors (new ones prefixed by >>):
> 
>    drivers/iio/adc/ad4080.c: In function 'ad4080_probe':
>>> drivers/iio/adc/ad4080.c:739:31: error: implicit declaration of function 'devm_spi_new_ancillary_device'; did you mean 'spi_new_ancillary_device'? [-Wimplicit-function-declaration]
>      739 |                 st->spi[ch] = devm_spi_new_ancillary_device(spi,
>          |                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>          |                               spi_new_ancillary_device
>>> drivers/iio/adc/ad4080.c:739:29: error: assignment to 'struct spi_device *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
>      739 |                 st->spi[ch] = devm_spi_new_ancillary_device(spi,
>          |                             ^
> 
> 
The cover letter of the series should call out the dependency on the
SPI patches that have already been picked up.

There is even a git format for this that the bots understand to avoid
messages like this.

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

* Re: [PATCH v5 2/4] iio: backend: add devm_iio_backend_get_by_index()
  2026-03-05 11:37 ` [PATCH v5 2/4] iio: backend: add devm_iio_backend_get_by_index() Antoniu Miclaus
  2026-03-07 11:55   ` Jonathan Cameron
@ 2026-03-07 18:17   ` David Lechner
  1 sibling, 0 replies; 14+ messages in thread
From: David Lechner @ 2026-03-07 18:17 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, linux-iio,
	devicetree, linux-kernel

On 3/5/26 5:37 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.
> 

Reviewed-by: David Lechner <dlechner@baylibre.com>


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

* Re: [PATCH v5 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support
  2026-03-05 11:37 ` [PATCH v5 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support Antoniu Miclaus
@ 2026-03-07 18:19   ` David Lechner
  2026-03-12 14:53   ` Rob Herring (Arm)
  1 sibling, 0 replies; 14+ messages in thread
From: David Lechner @ 2026-03-07 18:19 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, linux-iio,
	devicetree, linux-kernel

On 3/5/26 5:37 AM, Antoniu Miclaus wrote:
> Add support for the AD4880, a dual-channel 20-bit 40MSPS SAR ADC
> with integrated fully differential amplifiers (FDA).
> 
Reviewed-by: David Lechner <dlechner@baylibre.com>


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

* Re: [PATCH v5 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
  2026-03-05 11:37 ` [PATCH v5 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
  2026-03-07 11:58   ` Jonathan Cameron
  2026-03-07 17:11   ` kernel test robot
@ 2026-03-08  0:19   ` kernel test robot
  2 siblings, 0 replies; 14+ messages in thread
From: kernel test robot @ 2026-03-08  0:19 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,
	linux-iio, devicetree, linux-kernel
  Cc: llvm, oe-kbuild-all

Hi Antoniu,

kernel test robot noticed the following build errors:

[auto build test ERROR on v7.0-rc2]
[also build test ERROR on linus/master]
[cannot apply to jic23-iio/togreg next-20260306]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Antoniu-Miclaus/iio-backend-use-__free-fwnode_handle-for-automatic-cleanup/20260305-194647
base:   v7.0-rc2
patch link:    https://lore.kernel.org/r/20260305113756.47243-5-antoniu.miclaus%40analog.com
patch subject: [PATCH v5 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
config: riscv-allyesconfig (https://download.01.org/0day-ci/archive/20260308/202603080827.qjeW4PYt-lkp@intel.com/config)
compiler: clang version 16.0.6 (https://github.com/llvm/llvm-project 7cbf1a2591520c2491aa35339f227775f4d3adf6)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260308/202603080827.qjeW4PYt-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603080827.qjeW4PYt-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/iio/adc/ad4080.c:739:17: error: call to undeclared function 'devm_spi_new_ancillary_device'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
                   st->spi[ch] = devm_spi_new_ancillary_device(spi,
                                 ^
   drivers/iio/adc/ad4080.c:739:17: note: did you mean 'spi_new_ancillary_device'?
   include/linux/spi/spi.h:389:27: note: 'spi_new_ancillary_device' declared here
   extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 chip_select);
                             ^
>> drivers/iio/adc/ad4080.c:739:15: error: incompatible integer to pointer conversion assigning to 'struct spi_device *' from 'int' [-Wint-conversion]
                   st->spi[ch] = devm_spi_new_ancillary_device(spi,
                               ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2 errors generated.


vim +/devm_spi_new_ancillary_device +739 drivers/iio/adc/ad4080.c

   705	
   706	static int ad4080_probe(struct spi_device *spi)
   707	{
   708		struct iio_dev *indio_dev;
   709		struct device *dev = &spi->dev;
   710		struct ad4080_state *st;
   711		struct clk *clk;
   712		int ret;
   713	
   714		indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
   715		if (!indio_dev)
   716			return -ENOMEM;
   717	
   718		st = iio_priv(indio_dev);
   719	
   720		ret = devm_regulator_bulk_get_enable(dev,
   721						     ARRAY_SIZE(ad4080_power_supplies),
   722						     ad4080_power_supplies);
   723		if (ret)
   724			return dev_err_probe(dev, ret,
   725					     "failed to get and enable supplies\n");
   726	
   727		/* Setup primary SPI device (channel 0) */
   728		st->spi[0] = spi;
   729		st->regmap[0] = devm_regmap_init_spi(spi, &ad4080_regmap_config);
   730		if (IS_ERR(st->regmap[0]))
   731			return PTR_ERR(st->regmap[0]);
   732	
   733		st->info = spi_get_device_match_data(spi);
   734		if (!st->info)
   735			return -ENODEV;
   736	
   737		/* Setup ancillary SPI devices for additional channels */
   738		for (unsigned int ch = 1; ch < st->info->num_channels; ch++) {
 > 739			st->spi[ch] = devm_spi_new_ancillary_device(spi,
   740								    spi_get_chipselect(spi, ch));
   741			if (IS_ERR(st->spi[ch]))
   742				return dev_err_probe(dev, PTR_ERR(st->spi[ch]),
   743						     "failed to register ancillary device\n");
   744	
   745			st->regmap[ch] = devm_regmap_init_spi(st->spi[ch],
   746							      &ad4080_regmap_config);
   747			if (IS_ERR(st->regmap[ch]))
   748				return PTR_ERR(st->regmap[ch]);
   749		}
   750	
   751		ret = devm_mutex_init(dev, &st->lock);
   752		if (ret)
   753			return ret;
   754	
   755		indio_dev->name = st->info->name;
   756		indio_dev->channels = st->info->channels;
   757		indio_dev->num_channels = st->info->num_channels;
   758		indio_dev->info = st->info->num_channels > 1 ?
   759				  &ad4880_iio_info : &ad4080_iio_info;
   760	
   761		ret = ad4080_properties_parse(st);
   762		if (ret)
   763			return ret;
   764	
   765		clk = devm_clk_get_enabled(&spi->dev, "cnv");
   766		if (IS_ERR(clk))
   767			return PTR_ERR(clk);
   768	
   769		st->clk_rate = clk_get_rate(clk);
   770	
   771		/* Get backends for all channels */
   772		for (unsigned int ch = 0; ch < st->info->num_channels; ch++) {
   773			st->back[ch] = devm_iio_backend_get_by_index(dev, ch);
   774			if (IS_ERR(st->back[ch]))
   775				return PTR_ERR(st->back[ch]);
   776	
   777			ret = devm_iio_backend_enable(dev, st->back[ch]);
   778			if (ret)
   779				return ret;
   780		}
   781	
   782		/*
   783		 * Request buffer from the first backend only. For multi-channel
   784		 * devices (e.g., AD4880), all backends share a single IIO buffer
   785		 * as data from all ADC channels is interleaved into one stream.
   786		 */
   787		ret = devm_iio_backend_request_buffer(dev, st->back[0], indio_dev);
   788		if (ret)
   789			return ret;
   790	
   791		ret = ad4080_setup(indio_dev);
   792		if (ret)
   793			return ret;
   794	
   795		return devm_iio_device_register(&spi->dev, indio_dev);
   796	}
   797	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH v5 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support
  2026-03-05 11:37 ` [PATCH v5 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support Antoniu Miclaus
  2026-03-07 18:19   ` David Lechner
@ 2026-03-12 14:53   ` Rob Herring (Arm)
  1 sibling, 0 replies; 14+ messages in thread
From: Rob Herring (Arm) @ 2026-03-12 14:53 UTC (permalink / raw)
  To: Antoniu Miclaus
  Cc: linux-iio, Lars-Peter Clausen, Conor Dooley, Olivier Moysan,
	Nuno Sá, Andy Shevchenko, Jonathan Cameron, David Lechner,
	Michael Hennerich, devicetree, linux-kernel, Krzysztof Kozlowski


On Thu, 05 Mar 2026 13:37:29 +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
> - Two io-backends entries for the two data channels
> 
> Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
> ---
> Changes in v5:
>   - No changes
> 
>  .../bindings/iio/adc/adi,ad4080.yaml          | 53 ++++++++++++++++++-
>  1 file changed, 51 insertions(+), 2 deletions(-)
> 

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>


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

* Re: [PATCH v5 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC
  2026-03-05 11:37 [PATCH v5 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
                   ` (3 preceding siblings ...)
  2026-03-05 11:37 ` [PATCH v5 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
@ 2026-03-14 11:36 ` Jonathan Cameron
  4 siblings, 0 replies; 14+ messages in thread
From: Jonathan Cameron @ 2026-03-14 11:36 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, linux-iio, devicetree, linux-kernel

On Thu, 5 Mar 2026 13:37:26 +0200
Antoniu Miclaus <antoniu.miclaus@analog.com> 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.
> 
> This series includes:
>   - Use __free(fwnode_handle) for automatic cleanup in iio backend
>   - Refactored devm_iio_backend_get_by_index() 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

Series applied with that ordering tweak in the new backend function patch.
Note that this crossed with a new device being added to the driver
and so it took a fair bit of conflict resolution. Please check I didn't mess
it up. 

Applied and pushed out as testing (subject to exiting a tunnel under London ;)

Thanks,

Jonathan

> 
> Changes in v5:
>   - Drop the SPI patches (already applied)
>   - Split the __free(fwnode_handle) cleanup into a separate patch (patch 1)
>   - Fix "Get's" -> "Gets" typo in devm_iio_backend_get_by_index()
>     kernel-doc (patch 2)
>   - Declare loop variables in for-loop initializers (patch 4)
>   - Drop redundant num_channels > 1 guard around ancillary device
>     setup loop (patch 4)
> 
> Antoniu Miclaus (4):
>   iio: backend: use __free(fwnode_handle) for automatic cleanup
>   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          |  53 +++-
>  drivers/iio/adc/ad4080.c                      | 230 ++++++++++++++----
>  drivers/iio/industrialio-backend.c            |  62 +++--
>  include/linux/iio/backend.h                   |   2 +
>  4 files changed, 278 insertions(+), 69 deletions(-)
> 


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

end of thread, other threads:[~2026-03-14 11:37 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-05 11:37 [PATCH v5 0/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
2026-03-05 11:37 ` [PATCH v5 1/4] iio: backend: use __free(fwnode_handle) for automatic cleanup Antoniu Miclaus
2026-03-05 11:37 ` [PATCH v5 2/4] iio: backend: add devm_iio_backend_get_by_index() Antoniu Miclaus
2026-03-07 11:55   ` Jonathan Cameron
2026-03-07 18:17   ` David Lechner
2026-03-05 11:37 ` [PATCH v5 3/4] dt-bindings: iio: adc: ad4080: add AD4880 support Antoniu Miclaus
2026-03-07 18:19   ` David Lechner
2026-03-12 14:53   ` Rob Herring (Arm)
2026-03-05 11:37 ` [PATCH v5 4/4] iio: adc: ad4080: add support for AD4880 dual-channel ADC Antoniu Miclaus
2026-03-07 11:58   ` Jonathan Cameron
2026-03-07 17:11   ` kernel test robot
2026-03-07 18:14     ` David Lechner
2026-03-08  0:19   ` kernel test robot
2026-03-14 11:36 ` [PATCH v5 0/4] " Jonathan Cameron

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