public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] Add support for Software mode on AD7606's iio backend driver
@ 2024-11-21 10:18 Guillaume Stols
  2024-11-21 10:18 ` [PATCH 1/9] iio: adc: ad7606: Fix hardcoded offset in the ADC channels Guillaume Stols
                   ` (9 more replies)
  0 siblings, 10 replies; 23+ messages in thread
From: Guillaume Stols @ 2024-11-21 10:18 UTC (permalink / raw)
  To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Nuno Sa,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Jonathan Cameron, linux-iio, linux-kernel, Michael Hennerich,
	devicetree, dlechner, jstephan, aardelean, adureghello,
	Guillaume Stols

This series adds the support for software mode when the ADC is used in
iio_backend mode.
The bus access is based on Angelo's ad3552 implementation, that is we
have a particular compatible for the backend (here axi-adc) version
supporting the ad7606's register writing, and the ad7606 is defined as a
child node of the backend in the devicetree.
Small changes are added to make the code a bit more straightforward to
understand, and more compact.

Signed-off-by: Guillaume Stols <gstols@baylibre.com>
---
Guillaume Stols (9):
      iio: adc: ad7606: Fix hardcoded offset in the ADC channels
      dt-bindings: iio: dac: adi-axi-adc: Add ad7606 variant
      iio:adc: ad7606: Move the software mode configuration
      iio: adc: ad7606: Move software functions into common file
      iio: adc: adi-axi-adc: Add platform children support
      iio: adc: adi-axi-adc: Add support for AD7606 register writing
      iio: adc: ad7606: change r/w_register signature
      iio: adc: ad7606: Simplify channel macros
      iio: adc: ad7606: Add support for writing registers when using backend

 .../devicetree/bindings/iio/adc/adi,axi-adc.yaml   |   7 +
 drivers/iio/adc/ad7606.c                           | 202 +++++++++++++++++----
 drivers/iio/adc/ad7606.h                           | 113 ++++++++----
 drivers/iio/adc/ad7606_bi.h                        |  16 ++
 drivers/iio/adc/ad7606_par.c                       |  58 +++++-
 drivers/iio/adc/ad7606_spi.c                       | 141 +-------------
 drivers/iio/adc/adi-axi-adc.c                      | 178 +++++++++++++++++-
 7 files changed, 500 insertions(+), 215 deletions(-)
---
base-commit: 33d38f912d5ca05501c9bbfe14e0150da9ca85b6
change-id: 20241009-ad7606_add_iio_backend_software_mode-567d9c392243

Best regards,
--
Guillaume Stols <gstols@baylibre.com>


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

* [PATCH 1/9] iio: adc: ad7606: Fix hardcoded offset in the ADC channels
  2024-11-21 10:18 [PATCH 0/9] Add support for Software mode on AD7606's iio backend driver Guillaume Stols
@ 2024-11-21 10:18 ` Guillaume Stols
  2024-11-26 18:15   ` Jonathan Cameron
  2024-11-21 10:18 ` [PATCH 2/9] dt-bindings: iio: dac: adi-axi-adc: Add ad7606 variant Guillaume Stols
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Guillaume Stols @ 2024-11-21 10:18 UTC (permalink / raw)
  To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Nuno Sa,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Jonathan Cameron, linux-iio, linux-kernel, Michael Hennerich,
	devicetree, dlechner, jstephan, aardelean, adureghello,
	Guillaume Stols

When introducing num_adc_channels, I overlooked some new functions
created in a meanwhile that had also the hardcoded offset. This commit
adds the new logic to these functions.

Fixes: 7a671afeb592 ("iio: adc: ad7606: Introduce num_adc_channels")
Signed-off-by: Guillaume Stols <gstols@baylibre.com>
---
 drivers/iio/adc/ad7606.c | 48 ++++++++++++++++++++++++++++--------------------
 drivers/iio/adc/ad7606.h |  2 +-
 2 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c
index 8b2046baaa3e..893b93b86aa7 100644
--- a/drivers/iio/adc/ad7606.c
+++ b/drivers/iio/adc/ad7606.c
@@ -175,17 +175,17 @@ static const struct iio_chan_spec ad7616_channels[] = {
 	AD7606_CHANNEL(15, 16),
 };
 
-static int ad7606c_18bit_chan_scale_setup(struct ad7606_state *st,
+static int ad7606c_18bit_chan_scale_setup(struct iio_dev *indio_dev,
 					  struct iio_chan_spec *chan, int ch);
-static int ad7606c_16bit_chan_scale_setup(struct ad7606_state *st,
+static int ad7606c_16bit_chan_scale_setup(struct iio_dev *indio_dev,
 					  struct iio_chan_spec *chan, int ch);
-static int ad7606_16bit_chan_scale_setup(struct ad7606_state *st,
+static int ad7606_16bit_chan_scale_setup(struct iio_dev *indio_dev,
 					 struct iio_chan_spec *chan, int ch);
-static int ad7607_chan_scale_setup(struct ad7606_state *st,
+static int ad7607_chan_scale_setup(struct iio_dev *indio_dev,
 				   struct iio_chan_spec *chan, int ch);
-static int ad7608_chan_scale_setup(struct ad7606_state *st,
+static int ad7608_chan_scale_setup(struct iio_dev *indio_dev,
 				   struct iio_chan_spec *chan, int ch);
-static int ad7609_chan_scale_setup(struct ad7606_state *st,
+static int ad7609_chan_scale_setup(struct iio_dev *indio_dev,
 				   struct iio_chan_spec *chan, int ch);
 
 const struct ad7606_chip_info ad7605_4_info = {
@@ -323,9 +323,10 @@ int ad7606_reset(struct ad7606_state *st)
 }
 EXPORT_SYMBOL_NS_GPL(ad7606_reset, IIO_AD7606);
 
-static int ad7606_16bit_chan_scale_setup(struct ad7606_state *st,
+static int ad7606_16bit_chan_scale_setup(struct iio_dev *indio_dev,
 					 struct iio_chan_spec *chan, int ch)
 {
+	struct ad7606_state *st = iio_priv(indio_dev);
 	struct ad7606_chan_scale *cs = &st->chan_scales[ch];
 
 	if (!st->sw_mode_en) {
@@ -345,10 +346,12 @@ static int ad7606_16bit_chan_scale_setup(struct ad7606_state *st,
 	return 0;
 }
 
-static int ad7606_get_chan_config(struct ad7606_state *st, int ch,
+static int ad7606_get_chan_config(struct iio_dev *indio_dev, int ch,
 				  bool *bipolar, bool *differential)
 {
-	unsigned int num_channels = st->chip_info->num_channels - 1;
+	struct ad7606_state *st = iio_priv(indio_dev);
+	unsigned int num_channels = st->chip_info->num_adc_channels;
+	unsigned int offset = indio_dev->num_channels - st->chip_info->num_adc_channels;
 	struct device *dev = st->dev;
 	int ret;
 
@@ -364,7 +367,7 @@ static int ad7606_get_chan_config(struct ad7606_state *st, int ch,
 			continue;
 
 		/* channel number (here) is from 1 to num_channels */
-		if (reg == 0 || reg > num_channels) {
+		if (reg < offset  || reg > num_channels) {
 			dev_warn(dev,
 				 "Invalid channel number (ignoring): %d\n", reg);
 			continue;
@@ -399,9 +402,10 @@ static int ad7606_get_chan_config(struct ad7606_state *st, int ch,
 	return 0;
 }
 
-static int ad7606c_18bit_chan_scale_setup(struct ad7606_state *st,
+static int ad7606c_18bit_chan_scale_setup(struct iio_dev *indio_dev,
 					  struct iio_chan_spec *chan, int ch)
 {
+	struct ad7606_state *st = iio_priv(indio_dev);
 	struct ad7606_chan_scale *cs = &st->chan_scales[ch];
 	bool bipolar, differential;
 	int ret;
@@ -413,7 +417,7 @@ static int ad7606c_18bit_chan_scale_setup(struct ad7606_state *st,
 		return 0;
 	}
 
-	ret = ad7606_get_chan_config(st, ch, &bipolar, &differential);
+	ret = ad7606_get_chan_config(indio_dev, ch, &bipolar, &differential);
 	if (ret)
 		return ret;
 
@@ -455,9 +459,10 @@ static int ad7606c_18bit_chan_scale_setup(struct ad7606_state *st,
 	return 0;
 }
 
-static int ad7606c_16bit_chan_scale_setup(struct ad7606_state *st,
+static int ad7606c_16bit_chan_scale_setup(struct iio_dev *indio_dev,
 					  struct iio_chan_spec *chan, int ch)
 {
+	struct ad7606_state *st = iio_priv(indio_dev);
 	struct ad7606_chan_scale *cs = &st->chan_scales[ch];
 	bool bipolar, differential;
 	int ret;
@@ -469,7 +474,7 @@ static int ad7606c_16bit_chan_scale_setup(struct ad7606_state *st,
 		return 0;
 	}
 
-	ret = ad7606_get_chan_config(st, ch, &bipolar, &differential);
+	ret = ad7606_get_chan_config(indio_dev, ch, &bipolar, &differential);
 	if (ret)
 		return ret;
 
@@ -512,9 +517,10 @@ static int ad7606c_16bit_chan_scale_setup(struct ad7606_state *st,
 	return 0;
 }
 
-static int ad7607_chan_scale_setup(struct ad7606_state *st,
+static int ad7607_chan_scale_setup(struct iio_dev *indio_dev,
 				   struct iio_chan_spec *chan, int ch)
 {
+	struct ad7606_state *st = iio_priv(indio_dev);
 	struct ad7606_chan_scale *cs = &st->chan_scales[ch];
 
 	cs->range = 0;
@@ -523,9 +529,10 @@ static int ad7607_chan_scale_setup(struct ad7606_state *st,
 	return 0;
 }
 
-static int ad7608_chan_scale_setup(struct ad7606_state *st,
+static int ad7608_chan_scale_setup(struct iio_dev *indio_dev,
 				   struct iio_chan_spec *chan, int ch)
 {
+	struct ad7606_state *st = iio_priv(indio_dev);
 	struct ad7606_chan_scale *cs = &st->chan_scales[ch];
 
 	cs->range = 0;
@@ -534,9 +541,10 @@ static int ad7608_chan_scale_setup(struct ad7606_state *st,
 	return 0;
 }
 
-static int ad7609_chan_scale_setup(struct ad7606_state *st,
+static int ad7609_chan_scale_setup(struct iio_dev *indio_dev,
 				   struct iio_chan_spec *chan, int ch)
 {
+	struct ad7606_state *st = iio_priv(indio_dev);
 	struct ad7606_chan_scale *cs = &st->chan_scales[ch];
 
 	cs->range = 0;
@@ -1146,8 +1154,8 @@ static int ad7606_sw_mode_setup(struct iio_dev *indio_dev)
 
 static int ad7606_chan_scales_setup(struct iio_dev *indio_dev)
 {
-	unsigned int num_channels = indio_dev->num_channels - 1;
 	struct ad7606_state *st = iio_priv(indio_dev);
+	unsigned int offset = indio_dev->num_channels - st->chip_info->num_adc_channels;
 	struct iio_chan_spec *chans;
 	size_t size;
 	int ch, ret;
@@ -1161,8 +1169,8 @@ static int ad7606_chan_scales_setup(struct iio_dev *indio_dev)
 	memcpy(chans, indio_dev->channels, size);
 	indio_dev->channels = chans;
 
-	for (ch = 0; ch < num_channels; ch++) {
-		ret = st->chip_info->scale_setup_cb(st, &chans[ch + 1], ch);
+	for (ch = 0; ch < st->chip_info->num_adc_channels; ch++) {
+		ret = st->chip_info->scale_setup_cb(indio_dev, &chans[ch + offset], ch);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h
index 998814a92b82..8778ffe515b3 100644
--- a/drivers/iio/adc/ad7606.h
+++ b/drivers/iio/adc/ad7606.h
@@ -69,7 +69,7 @@
 
 struct ad7606_state;
 
-typedef int (*ad7606_scale_setup_cb_t)(struct ad7606_state *st,
+typedef int (*ad7606_scale_setup_cb_t)(struct iio_dev *indio_dev,
 				       struct iio_chan_spec *chan, int ch);
 
 /**

-- 
2.34.1


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

* [PATCH 2/9] dt-bindings: iio: dac: adi-axi-adc: Add ad7606 variant
  2024-11-21 10:18 [PATCH 0/9] Add support for Software mode on AD7606's iio backend driver Guillaume Stols
  2024-11-21 10:18 ` [PATCH 1/9] iio: adc: ad7606: Fix hardcoded offset in the ADC channels Guillaume Stols
@ 2024-11-21 10:18 ` Guillaume Stols
  2024-11-21 16:57   ` David Lechner
  2024-11-21 10:18 ` [PATCH 3/9] iio:adc: ad7606: Move the software mode configuration Guillaume Stols
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Guillaume Stols @ 2024-11-21 10:18 UTC (permalink / raw)
  To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Nuno Sa,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Jonathan Cameron, linux-iio, linux-kernel, Michael Hennerich,
	devicetree, dlechner, jstephan, aardelean, adureghello,
	Guillaume Stols

A new compatible is added to reflect the specialized version of the HDL
that is not covered by the IIO backend paradigm: We use the parallel
interface to write the ADC's registers, and accessing this interface
requires to use ADI_AXI_REG_CONFIG_RD,ADI_AXI_REG_CONFIG_WR and
ADI_AXI_REG_CONFIG_CTRL in a custom fashion.

Signed-off-by: Guillaume Stols <gstols@baylibre.com>
---
 Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
index e1f450b80db2..43bc0440c678 100644
--- a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
@@ -17,13 +17,20 @@ description: |
   interface for the actual ADC, while this IP core will interface
   to the data-lines of the ADC and handle the streaming of data into
   memory via DMA.
+  In some cases, the AXI ADC interface is used to perform specialized
+  operation to a particular ADC, e.g access the physical bus through
+  some special register to write ADC registers.
+  In this case, a different compatible is used, and the driver behaves
+  slightly differently according to the special needs.
 
   https://wiki.analog.com/resources/fpga/docs/axi_adc_ip
+  http://analogdevicesinc.github.io/hdl/library/axi_ad7606x/index.html
 
 properties:
   compatible:
     enum:
       - adi,axi-adc-10.0.a
+      - adi,axi-ad7606x
 
   reg:
     maxItems: 1

-- 
2.34.1


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

* [PATCH 3/9] iio:adc: ad7606: Move the software mode configuration
  2024-11-21 10:18 [PATCH 0/9] Add support for Software mode on AD7606's iio backend driver Guillaume Stols
  2024-11-21 10:18 ` [PATCH 1/9] iio: adc: ad7606: Fix hardcoded offset in the ADC channels Guillaume Stols
  2024-11-21 10:18 ` [PATCH 2/9] dt-bindings: iio: dac: adi-axi-adc: Add ad7606 variant Guillaume Stols
@ 2024-11-21 10:18 ` Guillaume Stols
  2024-11-26 18:21   ` Jonathan Cameron
  2024-11-21 10:18 ` [PATCH 4/9] iio: adc: ad7606: Move software functions into common file Guillaume Stols
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Guillaume Stols @ 2024-11-21 10:18 UTC (permalink / raw)
  To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Nuno Sa,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Jonathan Cameron, linux-iio, linux-kernel, Michael Hennerich,
	devicetree, dlechner, jstephan, aardelean, adureghello,
	Guillaume Stols

This is a preparation for the intoduction of the sofware functions in
the iio backend version of the driver.
The software mode configuration must be executed once the channels are
configured, and the number of channels is known. This is not the case
before iio-backend's configuration is called, and iio backend version of
the driver does not have a timestamp channel.
Also the sw_mode_config callback is configured during the
iio-backend configuration.
For clarity purpose, I moved the entire block instead of just the
concerned function calls.

Signed-off-by: Guillaume Stols <gstols@baylibre.com>
---
 drivers/iio/adc/ad7606.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c
index 893b93b86aa7..828603ed18f6 100644
--- a/drivers/iio/adc/ad7606.c
+++ b/drivers/iio/adc/ad7606.c
@@ -1246,17 +1246,6 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
 			return -ERESTARTSYS;
 	}
 
-	st->write_scale = ad7606_write_scale_hw;
-	st->write_os = ad7606_write_os_hw;
-
-	ret = ad7606_sw_mode_setup(indio_dev);
-	if (ret)
-		return ret;
-
-	ret = ad7606_chan_scales_setup(indio_dev);
-	if (ret)
-		return ret;
-
 	/* If convst pin is not defined, setup PWM. */
 	if (!st->gpio_convst) {
 		st->cnvst_pwm = devm_pwm_get(dev, NULL);
@@ -1334,6 +1323,20 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
 			return ret;
 	}
 
+	st->write_scale = ad7606_write_scale_hw;
+	st->write_os = ad7606_write_os_hw;
+
+	st->sw_mode_en = st->chip_info->sw_setup_cb &&
+			 device_property_present(st->dev, "adi,sw-mode");
+	if (st->sw_mode_en) {
+		indio_dev->info = &ad7606_info_sw_mode;
+		st->chip_info->sw_setup_cb(indio_dev);
+	}
+
+	ret = ad7606_chan_scales_setup(indio_dev);
+	if (ret)
+		return ret;
+
 	return devm_iio_device_register(dev, indio_dev);
 }
 EXPORT_SYMBOL_NS_GPL(ad7606_probe, IIO_AD7606);

-- 
2.34.1


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

* [PATCH 4/9] iio: adc: ad7606: Move software functions into common file
  2024-11-21 10:18 [PATCH 0/9] Add support for Software mode on AD7606's iio backend driver Guillaume Stols
                   ` (2 preceding siblings ...)
  2024-11-21 10:18 ` [PATCH 3/9] iio:adc: ad7606: Move the software mode configuration Guillaume Stols
@ 2024-11-21 10:18 ` Guillaume Stols
  2024-11-26 18:29   ` Jonathan Cameron
  2024-11-21 10:18 ` [PATCH 5/9] iio: adc: adi-axi-adc: Add platform children support Guillaume Stols
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Guillaume Stols @ 2024-11-21 10:18 UTC (permalink / raw)
  To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Nuno Sa,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Jonathan Cameron, linux-iio, linux-kernel, Michael Hennerich,
	devicetree, dlechner, jstephan, aardelean, adureghello,
	Guillaume Stols

Since the register are always the same, whatever bus is used, moving the
software functions into the main file avoids the code to be duplicated
in both SPI and parallel version of the driver.

Signed-off-by: Guillaume Stols <gstols@baylibre.com>
---
 drivers/iio/adc/ad7606.c     | 128 ++++++++++++++++++++++++++++++++++++++++--
 drivers/iio/adc/ad7606.h     |  37 ++++++++++--
 drivers/iio/adc/ad7606_spi.c | 131 +------------------------------------------
 3 files changed, 156 insertions(+), 140 deletions(-)

diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c
index 828603ed18f6..df0e49bc4bdb 100644
--- a/drivers/iio/adc/ad7606.c
+++ b/drivers/iio/adc/ad7606.c
@@ -85,6 +85,10 @@ static const unsigned int ad7606_oversampling_avail[7] = {
 	1, 2, 4, 8, 16, 32, 64,
 };
 
+static const unsigned int ad7606B_oversampling_avail[9] = {
+	1, 2, 4, 8, 16, 32, 64, 128, 256
+};
+
 static const unsigned int ad7616_oversampling_avail[8] = {
 	1, 2, 4, 8, 16, 32, 64, 128,
 };
@@ -187,6 +191,8 @@ static int ad7608_chan_scale_setup(struct iio_dev *indio_dev,
 				   struct iio_chan_spec *chan, int ch);
 static int ad7609_chan_scale_setup(struct iio_dev *indio_dev,
 				   struct iio_chan_spec *chan, int ch);
+static int ad7616_sw_mode_setup(struct iio_dev *indio_dev);
+static int ad7606B_sw_mode_setup(struct iio_dev *indio_dev);
 
 const struct ad7606_chip_info ad7605_4_info = {
 	.channels = ad7605_channels,
@@ -239,6 +245,7 @@ const struct ad7606_chip_info ad7606b_info = {
 	.oversampling_avail = ad7606_oversampling_avail,
 	.oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail),
 	.scale_setup_cb = ad7606_16bit_chan_scale_setup,
+	.sw_setup_cb = ad7606B_sw_mode_setup,
 };
 EXPORT_SYMBOL_NS_GPL(ad7606b_info, IIO_AD7606);
 
@@ -250,6 +257,7 @@ const struct ad7606_chip_info ad7606c_16_info = {
 	.oversampling_avail = ad7606_oversampling_avail,
 	.oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail),
 	.scale_setup_cb = ad7606c_16bit_chan_scale_setup,
+	.sw_setup_cb = ad7606B_sw_mode_setup,
 };
 EXPORT_SYMBOL_NS_GPL(ad7606c_16_info, IIO_AD7606);
 
@@ -294,6 +302,7 @@ const struct ad7606_chip_info ad7606c_18_info = {
 	.oversampling_avail = ad7606_oversampling_avail,
 	.oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail),
 	.scale_setup_cb = ad7606c_18bit_chan_scale_setup,
+	.sw_setup_cb = ad7606B_sw_mode_setup,
 };
 EXPORT_SYMBOL_NS_GPL(ad7606c_18_info, IIO_AD7606);
 
@@ -307,6 +316,7 @@ const struct ad7606_chip_info ad7616_info = {
 	.oversampling_num = ARRAY_SIZE(ad7616_oversampling_avail),
 	.os_req_reset = true,
 	.scale_setup_cb = ad7606_16bit_chan_scale_setup,
+	.sw_setup_cb = ad7616_sw_mode_setup,
 };
 EXPORT_SYMBOL_NS_GPL(ad7616_info, IIO_AD7606);
 
@@ -1138,16 +1148,122 @@ static const struct iio_trigger_ops ad7606_trigger_ops = {
 	.validate_device = iio_trigger_validate_own_device,
 };
 
-static int ad7606_sw_mode_setup(struct iio_dev *indio_dev)
+static int ad7606_write_mask(struct ad7606_state *st,
+			     unsigned int addr,
+			     unsigned long mask,
+			     unsigned int val)
+{
+	int readval;
+
+	readval = st->bops->reg_read(st, addr);
+	if (readval < 0)
+		return readval;
+
+	readval &= ~mask;
+	readval |= val;
+
+	return st->bops->reg_write(st, addr, readval);
+}
+
+static int ad7616_write_scale_sw(struct iio_dev *indio_dev, int ch, int val)
 {
 	struct ad7606_state *st = iio_priv(indio_dev);
+	unsigned int ch_addr, mode, ch_index;
 
-	st->sw_mode_en = st->bops->sw_mode_config &&
-			 device_property_present(st->dev, "adi,sw-mode");
-	if (!st->sw_mode_en)
-		return 0;
+	/*
+	 * Ad7616 has 16 channels divided in group A and group B.
+	 * The range of channels from A are stored in registers with address 4
+	 * while channels from B are stored in register with address 6.
+	 * The last bit from channels determines if it is from group A or B
+	 * because the order of channels in iio is 0A, 0B, 1A, 1B...
+	 */
+	ch_index = ch >> 1;
+
+	ch_addr = AD7616_RANGE_CH_ADDR(ch_index);
+
+	if ((ch & 0x1) == 0) /* channel A */
+		ch_addr += AD7616_RANGE_CH_A_ADDR_OFF;
+	else	/* channel B */
+		ch_addr += AD7616_RANGE_CH_B_ADDR_OFF;
+
+	/* 0b01 for 2.5v, 0b10 for 5v and 0b11 for 10v */
+	mode = AD7616_RANGE_CH_MODE(ch_index, ((val + 1) & 0b11));
+
+	return ad7606_write_mask(st, ch_addr, AD7616_RANGE_CH_MSK(ch_index),
+				     mode);
+}
+
+static int ad7616_write_os_sw(struct iio_dev *indio_dev, int val)
+{
+	struct ad7606_state *st = iio_priv(indio_dev);
+
+	return ad7606_write_mask(st, AD7616_CONFIGURATION_REGISTER,
+				     AD7616_OS_MASK, val << 2);
+}
+
+static int ad7606_write_scale_sw(struct iio_dev *indio_dev, int ch, int val)
+{
+	struct ad7606_state *st = iio_priv(indio_dev);
+
+	return ad7606_write_mask(st,
+				     AD7606_RANGE_CH_ADDR(ch),
+				     AD7606_RANGE_CH_MSK(ch),
+				     AD7606_RANGE_CH_MODE(ch, val));
+}
+
+static int ad7606_write_os_sw(struct iio_dev *indio_dev, int val)
+{
+	struct ad7606_state *st = iio_priv(indio_dev);
+
+	return st->bops->reg_write(st, AD7606_OS_MODE, val);
+}
+
+static int ad7616_sw_mode_setup(struct iio_dev *indio_dev)
+{
+	struct ad7606_state *st = iio_priv(indio_dev);
+	int ret;
+
+	/*
+	 * Scale can be configured individually for each channel
+	 * in software mode.
+	 */
+
+	st->write_scale = ad7616_write_scale_sw;
+	st->write_os = &ad7616_write_os_sw;
+
+	ret = st->bops->sw_mode_config(indio_dev);
+	if (ret)
+		return ret;
+
+	/* Activate Burst mode and SEQEN MODE */
+	return ad7606_write_mask(st,
+			      AD7616_CONFIGURATION_REGISTER,
+			      AD7616_BURST_MODE | AD7616_SEQEN_MODE,
+			      AD7616_BURST_MODE | AD7616_SEQEN_MODE);
+}
+
+static int ad7606B_sw_mode_setup(struct iio_dev *indio_dev)
+{
+	struct ad7606_state *st = iio_priv(indio_dev);
+	DECLARE_BITMAP(os, 3);
+
+	bitmap_fill(os, 3);
+	/*
+	 * Software mode is enabled when all three oversampling
+	 * pins are set to high. If oversampling gpios are defined
+	 * in the device tree, then they need to be set to high,
+	 * otherwise, they must be hardwired to VDD
+	 */
+	if (st->gpio_os) {
+		gpiod_set_array_value(st->gpio_os->ndescs,
+				      st->gpio_os->desc, st->gpio_os->info, os);
+	}
+	/* OS of 128 and 256 are available only in software mode */
+	st->oversampling_avail = ad7606B_oversampling_avail;
+	st->num_os_ratios = ARRAY_SIZE(ad7606B_oversampling_avail);
 
-	indio_dev->info = &ad7606_info_sw_mode;
+	st->write_scale = ad7606_write_scale_sw;
+	st->write_os = &ad7606_write_os_sw;
 
 	return st->bops->sw_mode_config(indio_dev);
 }
diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h
index 8778ffe515b3..7a044b499cfe 100644
--- a/drivers/iio/adc/ad7606.h
+++ b/drivers/iio/adc/ad7606.h
@@ -10,6 +10,36 @@
 
 #define AD760X_MAX_CHANNELS	16
 
+#define AD7616_CONFIGURATION_REGISTER	0x02
+#define AD7616_OS_MASK			GENMASK(4, 2)
+#define AD7616_BURST_MODE		BIT(6)
+#define AD7616_SEQEN_MODE		BIT(5)
+#define AD7616_RANGE_CH_A_ADDR_OFF	0x04
+#define AD7616_RANGE_CH_B_ADDR_OFF	0x06
+/*
+ * Range of channels from a group are stored in 2 registers.
+ * 0, 1, 2, 3 in a register followed by 4, 5, 6, 7 in second register.
+ * For channels from second group(8-15) the order is the same, only with
+ * an offset of 2 for register address.
+ */
+#define AD7616_RANGE_CH_ADDR(ch)	((ch) >> 2)
+/* The range of the channel is stored in 2 bits */
+#define AD7616_RANGE_CH_MSK(ch)		(0b11 << (((ch) & 0b11) * 2))
+#define AD7616_RANGE_CH_MODE(ch, mode)	((mode) << ((((ch) & 0b11)) * 2))
+
+#define AD7606_CONFIGURATION_REGISTER	0x02
+#define AD7606_SINGLE_DOUT		0x00
+
+/*
+ * Range for AD7606B channels are stored in registers starting with address 0x3.
+ * Each register stores range for 2 channels(4 bits per channel).
+ */
+#define AD7606_RANGE_CH_MSK(ch)		(GENMASK(3, 0) << (4 * ((ch) & 0x1)))
+#define AD7606_RANGE_CH_MODE(ch, mode)	\
+	((GENMASK(3, 0) & (mode)) << (4 * ((ch) & 0x1)))
+#define AD7606_RANGE_CH_ADDR(ch)	(0x03 + ((ch) >> 1))
+#define AD7606_OS_MODE			0x08
+
 #define AD760X_CHANNEL(num, mask_sep, mask_type, mask_all, bits) {	\
 		.type = IIO_VOLTAGE,				\
 		.indexed = 1,					\
@@ -71,6 +101,7 @@ struct ad7606_state;
 
 typedef int (*ad7606_scale_setup_cb_t)(struct iio_dev *indio_dev,
 				       struct iio_chan_spec *chan, int ch);
+typedef int (*ad7606_sw_setup_cb_t)(struct iio_dev *indio_dev);
 
 /**
  * struct ad7606_chip_info - chip specific information
@@ -80,6 +111,7 @@ typedef int (*ad7606_scale_setup_cb_t)(struct iio_dev *indio_dev,
  * @num_channels:	number of channels
  * @num_adc_channels	the number of channels the ADC actually inputs.
  * @scale_setup_cb:	callback to setup the scales for each channel
+ * @sw_setup_cb:	callback to setup the software mode if available.
  * @oversampling_avail	pointer to the array which stores the available
  *			oversampling ratios.
  * @oversampling_num	number of elements stored in oversampling_avail array
@@ -94,6 +126,7 @@ struct ad7606_chip_info {
 	unsigned int			num_adc_channels;
 	unsigned int			num_channels;
 	ad7606_scale_setup_cb_t		scale_setup_cb;
+	ad7606_sw_setup_cb_t		sw_setup_cb;
 	const unsigned int		*oversampling_avail;
 	unsigned int			oversampling_num;
 	bool				os_req_reset;
@@ -206,10 +239,6 @@ struct ad7606_bus_ops {
 	int (*reg_write)(struct ad7606_state *st,
 				unsigned int addr,
 				unsigned int val);
-	int (*write_mask)(struct ad7606_state *st,
-				 unsigned int addr,
-				 unsigned long mask,
-				 unsigned int val);
 	int (*update_scan_mode)(struct iio_dev *indio_dev, const unsigned long *scan_mask);
 	u16 (*rd_wr_cmd)(int addr, char isWriteOp);
 };
diff --git a/drivers/iio/adc/ad7606_spi.c b/drivers/iio/adc/ad7606_spi.c
index 0662300cde8d..640e36092662 100644
--- a/drivers/iio/adc/ad7606_spi.c
+++ b/drivers/iio/adc/ad7606_spi.c
@@ -15,36 +15,6 @@
 
 #define MAX_SPI_FREQ_HZ		23500000	/* VDRIVE above 4.75 V */
 
-#define AD7616_CONFIGURATION_REGISTER	0x02
-#define AD7616_OS_MASK			GENMASK(4, 2)
-#define AD7616_BURST_MODE		BIT(6)
-#define AD7616_SEQEN_MODE		BIT(5)
-#define AD7616_RANGE_CH_A_ADDR_OFF	0x04
-#define AD7616_RANGE_CH_B_ADDR_OFF	0x06
-/*
- * Range of channels from a group are stored in 2 registers.
- * 0, 1, 2, 3 in a register followed by 4, 5, 6, 7 in second register.
- * For channels from second group(8-15) the order is the same, only with
- * an offset of 2 for register address.
- */
-#define AD7616_RANGE_CH_ADDR(ch)	((ch) >> 2)
-/* The range of the channel is stored in 2 bits */
-#define AD7616_RANGE_CH_MSK(ch)		(0b11 << (((ch) & 0b11) * 2))
-#define AD7616_RANGE_CH_MODE(ch, mode)	((mode) << ((((ch) & 0b11)) * 2))
-
-#define AD7606_CONFIGURATION_REGISTER	0x02
-#define AD7606_SINGLE_DOUT		0x00
-
-/*
- * Range for AD7606B channels are stored in registers starting with address 0x3.
- * Each register stores range for 2 channels(4 bits per channel).
- */
-#define AD7606_RANGE_CH_MSK(ch)		(GENMASK(3, 0) << (4 * ((ch) & 0x1)))
-#define AD7606_RANGE_CH_MODE(ch, mode)	\
-	((GENMASK(3, 0) & mode) << (4 * ((ch) & 0x1)))
-#define AD7606_RANGE_CH_ADDR(ch)	(0x03 + ((ch) >> 1))
-#define AD7606_OS_MODE			0x08
-
 static const struct iio_chan_spec ad7616_sw_channels[] = {
 	IIO_CHAN_SOFT_TIMESTAMP(16),
 	AD7616_CHANNEL(0),
@@ -194,76 +164,6 @@ static int ad7606_spi_reg_write(struct ad7606_state *st,
 	return spi_write(spi, &st->d16[0], sizeof(st->d16[0]));
 }
 
-static int ad7606_spi_write_mask(struct ad7606_state *st,
-				 unsigned int addr,
-				 unsigned long mask,
-				 unsigned int val)
-{
-	int readval;
-
-	readval = st->bops->reg_read(st, addr);
-	if (readval < 0)
-		return readval;
-
-	readval &= ~mask;
-	readval |= val;
-
-	return st->bops->reg_write(st, addr, readval);
-}
-
-static int ad7616_write_scale_sw(struct iio_dev *indio_dev, int ch, int val)
-{
-	struct ad7606_state *st = iio_priv(indio_dev);
-	unsigned int ch_addr, mode, ch_index;
-
-
-	/*
-	 * Ad7616 has 16 channels divided in group A and group B.
-	 * The range of channels from A are stored in registers with address 4
-	 * while channels from B are stored in register with address 6.
-	 * The last bit from channels determines if it is from group A or B
-	 * because the order of channels in iio is 0A, 0B, 1A, 1B...
-	 */
-	ch_index = ch >> 1;
-
-	ch_addr = AD7616_RANGE_CH_ADDR(ch_index);
-
-	if ((ch & 0x1) == 0) /* channel A */
-		ch_addr += AD7616_RANGE_CH_A_ADDR_OFF;
-	else	/* channel B */
-		ch_addr += AD7616_RANGE_CH_B_ADDR_OFF;
-
-	/* 0b01 for 2.5v, 0b10 for 5v and 0b11 for 10v */
-	mode = AD7616_RANGE_CH_MODE(ch_index, ((val + 1) & 0b11));
-	return st->bops->write_mask(st, ch_addr, AD7616_RANGE_CH_MSK(ch_index),
-				     mode);
-}
-
-static int ad7616_write_os_sw(struct iio_dev *indio_dev, int val)
-{
-	struct ad7606_state *st = iio_priv(indio_dev);
-
-	return st->bops->write_mask(st, AD7616_CONFIGURATION_REGISTER,
-				     AD7616_OS_MASK, val << 2);
-}
-
-static int ad7606_write_scale_sw(struct iio_dev *indio_dev, int ch, int val)
-{
-	struct ad7606_state *st = iio_priv(indio_dev);
-
-	return ad7606_spi_write_mask(st,
-				     AD7606_RANGE_CH_ADDR(ch),
-				     AD7606_RANGE_CH_MSK(ch),
-				     AD7606_RANGE_CH_MODE(ch, val));
-}
-
-static int ad7606_write_os_sw(struct iio_dev *indio_dev, int val)
-{
-	struct ad7606_state *st = iio_priv(indio_dev);
-
-	return ad7606_spi_reg_write(st, AD7606_OS_MODE, val);
-}
-
 static int ad7616_sw_mode_config(struct iio_dev *indio_dev)
 {
 	struct ad7606_state *st = iio_priv(indio_dev);
@@ -274,38 +174,12 @@ static int ad7616_sw_mode_config(struct iio_dev *indio_dev)
 	 */
 	indio_dev->channels = ad7616_sw_channels;
 
-	st->write_scale = ad7616_write_scale_sw;
-	st->write_os = &ad7616_write_os_sw;
-
-	/* Activate Burst mode and SEQEN MODE */
-	return st->bops->write_mask(st,
-			      AD7616_CONFIGURATION_REGISTER,
-			      AD7616_BURST_MODE | AD7616_SEQEN_MODE,
-			      AD7616_BURST_MODE | AD7616_SEQEN_MODE);
+	return 0;
 }
 
 static int ad7606B_sw_mode_config(struct iio_dev *indio_dev)
 {
 	struct ad7606_state *st = iio_priv(indio_dev);
-	DECLARE_BITMAP(os, 3);
-
-	bitmap_fill(os, 3);
-	/*
-	 * Software mode is enabled when all three oversampling
-	 * pins are set to high. If oversampling gpios are defined
-	 * in the device tree, then they need to be set to high,
-	 * otherwise, they must be hardwired to VDD
-	 */
-	if (st->gpio_os) {
-		gpiod_set_array_value(st->gpio_os->ndescs,
-				      st->gpio_os->desc, st->gpio_os->info, os);
-	}
-	/* OS of 128 and 256 are available only in software mode */
-	st->oversampling_avail = ad7606B_oversampling_avail;
-	st->num_os_ratios = ARRAY_SIZE(ad7606B_oversampling_avail);
-
-	st->write_scale = ad7606_write_scale_sw;
-	st->write_os = &ad7606_write_os_sw;
 
 	/* Configure device spi to output on a single channel */
 	st->bops->reg_write(st,
@@ -350,7 +224,6 @@ static const struct ad7606_bus_ops ad7616_spi_bops = {
 	.read_block = ad7606_spi_read_block,
 	.reg_read = ad7606_spi_reg_read,
 	.reg_write = ad7606_spi_reg_write,
-	.write_mask = ad7606_spi_write_mask,
 	.rd_wr_cmd = ad7616_spi_rd_wr_cmd,
 	.sw_mode_config = ad7616_sw_mode_config,
 };
@@ -359,7 +232,6 @@ static const struct ad7606_bus_ops ad7606b_spi_bops = {
 	.read_block = ad7606_spi_read_block,
 	.reg_read = ad7606_spi_reg_read,
 	.reg_write = ad7606_spi_reg_write,
-	.write_mask = ad7606_spi_write_mask,
 	.rd_wr_cmd = ad7606B_spi_rd_wr_cmd,
 	.sw_mode_config = ad7606B_sw_mode_config,
 };
@@ -368,7 +240,6 @@ static const struct ad7606_bus_ops ad7606c_18_spi_bops = {
 	.read_block = ad7606_spi_read_block18to32,
 	.reg_read = ad7606_spi_reg_read,
 	.reg_write = ad7606_spi_reg_write,
-	.write_mask = ad7606_spi_write_mask,
 	.rd_wr_cmd = ad7606B_spi_rd_wr_cmd,
 	.sw_mode_config = ad7606c_18_sw_mode_config,
 };

-- 
2.34.1


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

* [PATCH 5/9] iio: adc: adi-axi-adc: Add platform children support
  2024-11-21 10:18 [PATCH 0/9] Add support for Software mode on AD7606's iio backend driver Guillaume Stols
                   ` (3 preceding siblings ...)
  2024-11-21 10:18 ` [PATCH 4/9] iio: adc: ad7606: Move software functions into common file Guillaume Stols
@ 2024-11-21 10:18 ` Guillaume Stols
  2024-11-26 18:41   ` Jonathan Cameron
  2024-11-21 10:18 ` [PATCH 6/9] iio: adc: adi-axi-adc: Add support for AD7606 register writing Guillaume Stols
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Guillaume Stols @ 2024-11-21 10:18 UTC (permalink / raw)
  To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Nuno Sa,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Jonathan Cameron, linux-iio, linux-kernel, Michael Hennerich,
	devicetree, dlechner, jstephan, aardelean, adureghello,
	Guillaume Stols

This is a preparation for the next commit adding support for register
read and write functions on AD7606.
Since sometimes a bus will be used, it has been agreed during ad3552's
driver implementation that the device's driver bus is the backend, whose
device node will be a child node.
To provide the special callbacks for setting the register, axi-adc needs
to pass them to the child device's driver through platform data.

Signed-off-by: Guillaume Stols <gstols@baylibre.com>
---
 drivers/iio/adc/adi-axi-adc.c | 79 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 74 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c
index 5c8c87eb36d1..704ebd6ea83e 100644
--- a/drivers/iio/adc/adi-axi-adc.c
+++ b/drivers/iio/adc/adi-axi-adc.c
@@ -80,7 +80,18 @@
 	 ADI_AXI_REG_CHAN_CTRL_FMT_EN |		\
 	 ADI_AXI_REG_CHAN_CTRL_ENABLE)
 
+struct axi_adc_info {
+	unsigned int version;
+	const struct iio_backend_info *backend_info;
+	bool bus_controller;
+	const void *pdata;
+	unsigned int pdata_sz;
+};
+
 struct adi_axi_adc_state {
+	/* Target ADC platform device */
+	struct platform_device *adc_pdev;
+	const struct axi_adc_info *info;
 	struct regmap *regmap;
 	struct device *dev;
 	/* lock to protect multiple accesses to the device registers */
@@ -325,6 +336,40 @@ static const struct regmap_config axi_adc_regmap_config = {
 	.reg_stride = 4,
 };
 
+static void axi_adc_child_remove(void *data)
+{
+	struct adi_axi_adc_state *st = data;
+
+	platform_device_unregister(st->adc_pdev);
+}
+
+static int axi_adc_create_platform_device(struct adi_axi_adc_state *st,
+					  struct fwnode_handle *child)
+{
+	struct platform_device_info pi = {
+		.parent = st->dev,
+		.name = fwnode_get_name(child),
+		.id = PLATFORM_DEVID_AUTO,
+		.fwnode = child,
+		.data = st->info->pdata,
+		.size_data = st->info->pdata_sz,
+	};
+	struct platform_device *pdev;
+	int ret;
+
+	pdev = platform_device_register_full(&pi);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	st->adc_pdev = pdev;
+
+	ret = devm_add_action_or_reset(st->dev, axi_adc_child_remove, st);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static const struct iio_backend_ops adi_axi_adc_ops = {
 	.enable = axi_adc_enable,
 	.disable = axi_adc_disable,
@@ -370,7 +415,9 @@ static int adi_axi_adc_probe(struct platform_device *pdev)
 		return dev_err_probe(&pdev->dev, PTR_ERR(st->regmap),
 				     "failed to init register map\n");
 
-	expected_ver = device_get_match_data(&pdev->dev);
+	st->info = device_get_match_data(&pdev->dev);
+
+	expected_ver = &st->info->version;
 	if (!expected_ver)
 		return -ENODEV;
 
@@ -408,6 +455,25 @@ static int adi_axi_adc_probe(struct platform_device *pdev)
 		return dev_err_probe(&pdev->dev, ret,
 				     "failed to register iio backend\n");
 
+	if (st->info->bus_controller) {
+		device_for_each_child_node_scoped(&pdev->dev, child) {
+			int val;
+
+			/* Processing only reg 0 node */
+			ret = fwnode_property_read_u32(child, "reg", &val);
+			if (ret || val != 0)
+				continue;
+			ret = fwnode_property_read_u32(child, "io-backends",
+						       &val);
+			if (ret)
+				continue;
+
+			ret = axi_adc_create_platform_device(st, child);
+			if (ret)
+				continue;
+		}
+	}
+
 	dev_info(&pdev->dev, "AXI ADC IP core (%d.%.2d.%c) probed\n",
 		 ADI_AXI_PCORE_VER_MAJOR(ver),
 		 ADI_AXI_PCORE_VER_MINOR(ver),
@@ -416,12 +482,15 @@ static int adi_axi_adc_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static unsigned int adi_axi_adc_10_0_a_info = ADI_AXI_PCORE_VER(10, 0, 'a');
+static const struct axi_adc_info adc_generic = {
+	.version = ADI_AXI_PCORE_VER(10, 0, 'a'),
+	.backend_info = &adi_axi_adc_generic,
+};
+
 
-/* Match table for of_platform binding */
 static const struct of_device_id adi_axi_adc_of_match[] = {
-	{ .compatible = "adi,axi-adc-10.0.a", .data = &adi_axi_adc_10_0_a_info },
-	{ /* end of list */ }
+	{ .compatible = "adi,axi-adc-10.0.a", .data = &adc_generic },
+	{  }
 };
 MODULE_DEVICE_TABLE(of, adi_axi_adc_of_match);
 

-- 
2.34.1


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

* [PATCH 6/9] iio: adc: adi-axi-adc: Add support for AD7606 register writing
  2024-11-21 10:18 [PATCH 0/9] Add support for Software mode on AD7606's iio backend driver Guillaume Stols
                   ` (4 preceding siblings ...)
  2024-11-21 10:18 ` [PATCH 5/9] iio: adc: adi-axi-adc: Add platform children support Guillaume Stols
@ 2024-11-21 10:18 ` Guillaume Stols
  2024-11-26 18:43   ` Jonathan Cameron
  2024-11-21 10:18 ` [PATCH 7/9] iio: adc: ad7606: change r/w_register signature Guillaume Stols
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Guillaume Stols @ 2024-11-21 10:18 UTC (permalink / raw)
  To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Nuno Sa,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Jonathan Cameron, linux-iio, linux-kernel, Michael Hennerich,
	devicetree, dlechner, jstephan, aardelean, adureghello,
	Guillaume Stols

Since we must access the bus parallel bus using a custom procedure,
let's add a specialized compatible, and define specialized callbacks for
writing the registers using the parallel interface.

Signed-off-by: Guillaume Stols <gstols@baylibre.com>
---
 drivers/iio/adc/ad7606_bi.h   | 16 +++++++
 drivers/iio/adc/adi-axi-adc.c | 99 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 115 insertions(+)

diff --git a/drivers/iio/adc/ad7606_bi.h b/drivers/iio/adc/ad7606_bi.h
new file mode 100644
index 000000000000..9ade23ec61dd
--- /dev/null
+++ b/drivers/iio/adc/ad7606_bi.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2010-2024 Analog Devices Inc.
+ * Copyright (c) 2024 Baylibre, SAS
+ */
+#ifndef __LINUX_PLATFORM_DATA_AD7606_H__
+#define __LINUX_PLATFORM_DATA_AD7606_H__
+
+#include <linux/iio/backend.h>
+
+struct ad7606_platform_data {
+	int (*bus_reg_read)(struct iio_backend *back, u32 reg, u32 *val);
+	int (*bus_reg_write)(struct iio_backend *back, u32 reg, u32 val);
+};
+
+#endif /* __LINUX_PLATFORM_DATA_AD7606_H__ */
diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c
index 704ebd6ea83e..d3cc7c25f163 100644
--- a/drivers/iio/adc/adi-axi-adc.c
+++ b/drivers/iio/adc/adi-axi-adc.c
@@ -27,6 +27,7 @@
 #include <linux/iio/buffer.h>
 #include <linux/iio/iio.h>
 
+#include "ad7606_bi.h"
 /*
  * Register definitions:
  *   https://wiki.analog.com/resources/fpga/docs/axi_adc_ip#register_map
@@ -73,6 +74,12 @@
 #define ADI_AXI_ADC_REG_DELAY(l)		(0x0800 + (l) * 0x4)
 #define   AXI_ADC_DELAY_CTRL_MASK		GENMASK(4, 0)
 
+#define ADI_AXI_REG_CONFIG_WR			0x0080
+#define ADI_AXI_REG_CONFIG_RD			0x0084
+#define ADI_AXI_REG_CONFIG_CTRL			0x008c
+#define   ADI_AXI_REG_CONFIG_CTRL_READ		0x03
+#define   ADI_AXI_REG_CONFIG_CTRL_WRITE		0x01
+
 #define ADI_AXI_ADC_MAX_IO_NUM_LANES		15
 
 #define ADI_AXI_REG_CHAN_CTRL_DEFAULTS		\
@@ -80,6 +87,11 @@
 	 ADI_AXI_REG_CHAN_CTRL_FMT_EN |		\
 	 ADI_AXI_REG_CHAN_CTRL_ENABLE)
 
+/* AD7606's specific */
+#define AD7606_REG_READ_BIT			0x8000
+#define AD7606_REG_ADDRESS_MASK			0xff00
+#define AD7606_REG_VALUE_MASK			0x00ff
+
 struct axi_adc_info {
 	unsigned int version;
 	const struct iio_backend_info *backend_info;
@@ -313,6 +325,80 @@ static struct iio_buffer *axi_adc_request_buffer(struct iio_backend *back,
 	return iio_dmaengine_buffer_setup(st->dev, indio_dev, dma_name);
 }
 
+static int axi_adc_raw_write(struct iio_backend *back, void *buf, unsigned int len)
+{
+	struct adi_axi_adc_state *st = iio_backend_get_priv(back);
+	u32 data;
+	u32 *bdata = buf;
+
+	data = *bdata;
+	regmap_write(st->regmap, ADI_AXI_REG_CONFIG_WR, data);
+	regmap_write(st->regmap, ADI_AXI_REG_CONFIG_CTRL,
+		     ADI_AXI_REG_CONFIG_CTRL_WRITE);
+	usleep_range(50, 100);
+	regmap_write(st->regmap, ADI_AXI_REG_CONFIG_CTRL, 0x00);
+	usleep_range(50, 100);
+
+	return 0;
+}
+
+static int axi_adc_raw_read(struct iio_backend *back, void *buf, unsigned int len)
+{
+	struct adi_axi_adc_state *st = iio_backend_get_priv(back);
+	u32 *bdata = buf;
+
+	regmap_write(st->regmap, ADI_AXI_REG_CONFIG_CTRL,
+		     ADI_AXI_REG_CONFIG_CTRL_READ);
+	usleep_range(50, 100);
+	regmap_read(st->regmap, ADI_AXI_REG_CONFIG_RD, bdata);
+	regmap_write(st->regmap, ADI_AXI_REG_CONFIG_CTRL, 0x00);
+	usleep_range(50, 100);
+
+	return 0;
+}
+
+static int ad7606_bi_reg_read(struct iio_backend *back, u32 reg, u32 *val)
+{
+	struct adi_axi_adc_state *st = iio_backend_get_priv(back);
+	u32 buf;
+
+	guard(mutex)(&st->lock);
+
+	/*
+	 * The address is written on the highest weight byte, and the MSB set at 1
+	 * indicates a read operation.
+	 */
+	buf = FIELD_PREP(AD7606_REG_ADDRESS_MASK, reg) | AD7606_REG_READ_BIT;
+	axi_adc_raw_write(back, &buf, 4);
+	axi_adc_raw_read(back, val, 4);
+
+	/* Write 0x0 on the bus to get back to ADC mode */
+	buf = 0;
+	axi_adc_raw_write(back, &buf, 4);
+	return 0;
+}
+
+static int ad7606_bi_reg_write(struct iio_backend *back, u32 reg, u32 val)
+{
+	struct adi_axi_adc_state *st = iio_backend_get_priv(back);
+	u32 buf;
+
+	guard(mutex)(&st->lock);
+
+	/* Read any register to switch to register mode */
+	buf = 0xaf00;
+	axi_adc_raw_write(back, &buf, 4);
+
+	buf = FIELD_PREP(AD7606_REG_ADDRESS_MASK, reg) | FIELD_PREP(AD7606_REG_VALUE_MASK, val);
+	axi_adc_raw_write(back, &buf, 4);
+
+	/* Write 0x0 on the bus to get back to ADC mode */
+	buf = 0;
+	axi_adc_raw_write(back, &buf, 4);
+
+	return 0;
+}
+
 static void axi_adc_free_buffer(struct iio_backend *back,
 				struct iio_buffer *buffer)
 {
@@ -487,9 +573,22 @@ static const struct axi_adc_info adc_generic = {
 	.backend_info = &adi_axi_adc_generic,
 };
 
+static const struct ad7606_platform_data ad7606_pdata = {
+		.bus_reg_read = ad7606_bi_reg_read,
+		.bus_reg_write = ad7606_bi_reg_write,
+};
+
+static const struct axi_adc_info adc_ad7606 = {
+	.version = ADI_AXI_PCORE_VER(10, 0, 'a'),
+	.backend_info = &adi_axi_adc_generic,
+	.bus_controller = true,
+	.pdata = &ad7606_pdata,
+	.pdata_sz = sizeof(ad7606_pdata),
+};
 
 static const struct of_device_id adi_axi_adc_of_match[] = {
 	{ .compatible = "adi,axi-adc-10.0.a", .data = &adc_generic },
+	{ .compatible = "adi,axi-ad7606x", .data = &adc_ad7606 },
 	{  }
 };
 MODULE_DEVICE_TABLE(of, adi_axi_adc_of_match);

-- 
2.34.1


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

* [PATCH 7/9] iio: adc: ad7606: change r/w_register signature
  2024-11-21 10:18 [PATCH 0/9] Add support for Software mode on AD7606's iio backend driver Guillaume Stols
                   ` (5 preceding siblings ...)
  2024-11-21 10:18 ` [PATCH 6/9] iio: adc: adi-axi-adc: Add support for AD7606 register writing Guillaume Stols
@ 2024-11-21 10:18 ` Guillaume Stols
  2024-11-21 10:18 ` [PATCH 8/9] iio: adc: ad7606: Simplify channel macros Guillaume Stols
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 23+ messages in thread
From: Guillaume Stols @ 2024-11-21 10:18 UTC (permalink / raw)
  To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Nuno Sa,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Jonathan Cameron, linux-iio, linux-kernel, Michael Hennerich,
	devicetree, dlechner, jstephan, aardelean, adureghello,
	Guillaume Stols

The register read/write with IIO backend will require to claim the
direct mode, and doing so requires passing the corresponding iio_dev
structure.
So we need to modify the function signature to pass the iio_dev
structure.

Signed-off-by: Guillaume Stols <gstols@baylibre.com>
---
 drivers/iio/adc/ad7606.c     | 25 +++++++++++--------------
 drivers/iio/adc/ad7606.h     |  8 ++++----
 drivers/iio/adc/ad7606_spi.c | 10 +++++-----
 3 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c
index df0e49bc4bdb..ef1c79587edb 100644
--- a/drivers/iio/adc/ad7606.c
+++ b/drivers/iio/adc/ad7606.c
@@ -574,13 +574,13 @@ static int ad7606_reg_access(struct iio_dev *indio_dev,
 	guard(mutex)(&st->lock);
 
 	if (readval) {
-		ret = st->bops->reg_read(st, reg);
+		ret = st->bops->reg_read(indio_dev, reg);
 		if (ret < 0)
 			return ret;
 		*readval = ret;
 		return 0;
 	} else {
-		return st->bops->reg_write(st, reg, writeval);
+		return st->bops->reg_write(indio_dev, reg, writeval);
 	}
 }
 
@@ -1148,26 +1148,26 @@ static const struct iio_trigger_ops ad7606_trigger_ops = {
 	.validate_device = iio_trigger_validate_own_device,
 };
 
-static int ad7606_write_mask(struct ad7606_state *st,
+static int ad7606_write_mask(struct iio_dev *indio_dev,
 			     unsigned int addr,
 			     unsigned long mask,
 			     unsigned int val)
 {
+	struct ad7606_state *st = iio_priv(indio_dev);
 	int readval;
 
-	readval = st->bops->reg_read(st, addr);
+	readval = st->bops->reg_read(indio_dev, addr);
 	if (readval < 0)
 		return readval;
 
 	readval &= ~mask;
 	readval |= val;
 
-	return st->bops->reg_write(st, addr, readval);
+	return st->bops->reg_write(indio_dev, addr, readval);
 }
 
 static int ad7616_write_scale_sw(struct iio_dev *indio_dev, int ch, int val)
 {
-	struct ad7606_state *st = iio_priv(indio_dev);
 	unsigned int ch_addr, mode, ch_index;
 
 	/*
@@ -1189,23 +1189,20 @@ static int ad7616_write_scale_sw(struct iio_dev *indio_dev, int ch, int val)
 	/* 0b01 for 2.5v, 0b10 for 5v and 0b11 for 10v */
 	mode = AD7616_RANGE_CH_MODE(ch_index, ((val + 1) & 0b11));
 
-	return ad7606_write_mask(st, ch_addr, AD7616_RANGE_CH_MSK(ch_index),
+	return ad7606_write_mask(indio_dev, ch_addr, AD7616_RANGE_CH_MSK(ch_index),
 				     mode);
 }
 
 static int ad7616_write_os_sw(struct iio_dev *indio_dev, int val)
 {
-	struct ad7606_state *st = iio_priv(indio_dev);
 
-	return ad7606_write_mask(st, AD7616_CONFIGURATION_REGISTER,
+	return ad7606_write_mask(indio_dev, AD7616_CONFIGURATION_REGISTER,
 				     AD7616_OS_MASK, val << 2);
 }
 
 static int ad7606_write_scale_sw(struct iio_dev *indio_dev, int ch, int val)
 {
-	struct ad7606_state *st = iio_priv(indio_dev);
-
-	return ad7606_write_mask(st,
+	return ad7606_write_mask(indio_dev,
 				     AD7606_RANGE_CH_ADDR(ch),
 				     AD7606_RANGE_CH_MSK(ch),
 				     AD7606_RANGE_CH_MODE(ch, val));
@@ -1215,7 +1212,7 @@ static int ad7606_write_os_sw(struct iio_dev *indio_dev, int val)
 {
 	struct ad7606_state *st = iio_priv(indio_dev);
 
-	return st->bops->reg_write(st, AD7606_OS_MODE, val);
+	return st->bops->reg_write(indio_dev, AD7606_OS_MODE, val);
 }
 
 static int ad7616_sw_mode_setup(struct iio_dev *indio_dev)
@@ -1236,7 +1233,7 @@ static int ad7616_sw_mode_setup(struct iio_dev *indio_dev)
 		return ret;
 
 	/* Activate Burst mode and SEQEN MODE */
-	return ad7606_write_mask(st,
+	return ad7606_write_mask(indio_dev,
 			      AD7616_CONFIGURATION_REGISTER,
 			      AD7616_BURST_MODE | AD7616_SEQEN_MODE,
 			      AD7616_BURST_MODE | AD7616_SEQEN_MODE);
diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h
index 7a044b499cfe..eca7ea99e24d 100644
--- a/drivers/iio/adc/ad7606.h
+++ b/drivers/iio/adc/ad7606.h
@@ -235,10 +235,10 @@ struct ad7606_bus_ops {
 	int (*iio_backend_config)(struct device *dev, struct iio_dev *indio_dev);
 	int (*read_block)(struct device *dev, int num, void *data);
 	int (*sw_mode_config)(struct iio_dev *indio_dev);
-	int (*reg_read)(struct ad7606_state *st, unsigned int addr);
-	int (*reg_write)(struct ad7606_state *st,
-				unsigned int addr,
-				unsigned int val);
+	int (*reg_read)(struct iio_dev *indio_dev, unsigned int addr);
+	int (*reg_write)(struct iio_dev *indio_dev,
+			 unsigned int addr,
+			 unsigned int val);
 	int (*update_scan_mode)(struct iio_dev *indio_dev, const unsigned long *scan_mask);
 	u16 (*rd_wr_cmd)(int addr, char isWriteOp);
 };
diff --git a/drivers/iio/adc/ad7606_spi.c b/drivers/iio/adc/ad7606_spi.c
index 640e36092662..376b8a72e8d4 100644
--- a/drivers/iio/adc/ad7606_spi.c
+++ b/drivers/iio/adc/ad7606_spi.c
@@ -128,8 +128,9 @@ static int ad7606_spi_read_block18to32(struct device *dev,
 	return spi_sync_transfer(spi, &xfer, 1);
 }
 
-static int ad7606_spi_reg_read(struct ad7606_state *st, unsigned int addr)
+static int ad7606_spi_reg_read(struct iio_dev *indio_dev, unsigned int addr)
 {
+	struct ad7606_state *st = iio_priv(indio_dev);
 	struct spi_device *spi = to_spi_device(st->dev);
 	struct spi_transfer t[] = {
 		{
@@ -152,10 +153,11 @@ static int ad7606_spi_reg_read(struct ad7606_state *st, unsigned int addr)
 	return be16_to_cpu(st->d16[1]);
 }
 
-static int ad7606_spi_reg_write(struct ad7606_state *st,
+static int ad7606_spi_reg_write(struct iio_dev *indio_dev,
 				unsigned int addr,
 				unsigned int val)
 {
+	struct ad7606_state *st = iio_priv(indio_dev);
 	struct spi_device *spi = to_spi_device(st->dev);
 
 	st->d16[0] = cpu_to_be16((st->bops->rd_wr_cmd(addr, 1) << 8) |
@@ -166,8 +168,6 @@ static int ad7606_spi_reg_write(struct ad7606_state *st,
 
 static int ad7616_sw_mode_config(struct iio_dev *indio_dev)
 {
-	struct ad7606_state *st = iio_priv(indio_dev);
-
 	/*
 	 * Scale can be configured individually for each channel
 	 * in software mode.
@@ -182,7 +182,7 @@ static int ad7606B_sw_mode_config(struct iio_dev *indio_dev)
 	struct ad7606_state *st = iio_priv(indio_dev);
 
 	/* Configure device spi to output on a single channel */
-	st->bops->reg_write(st,
+	st->bops->reg_write(indio_dev,
 			    AD7606_CONFIGURATION_REGISTER,
 			    AD7606_SINGLE_DOUT);
 

-- 
2.34.1


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

* [PATCH 8/9] iio: adc: ad7606: Simplify channel macros
  2024-11-21 10:18 [PATCH 0/9] Add support for Software mode on AD7606's iio backend driver Guillaume Stols
                   ` (6 preceding siblings ...)
  2024-11-21 10:18 ` [PATCH 7/9] iio: adc: ad7606: change r/w_register signature Guillaume Stols
@ 2024-11-21 10:18 ` Guillaume Stols
  2024-11-26 18:46   ` Jonathan Cameron
  2024-11-21 10:18 ` [PATCH 9/9] iio: adc: ad7606: Add support for writing registers when using backend Guillaume Stols
  2024-11-26 18:00 ` [PATCH 0/9] Add support for Software mode on AD7606's iio backend driver Jonathan Cameron
  9 siblings, 1 reply; 23+ messages in thread
From: Guillaume Stols @ 2024-11-21 10:18 UTC (permalink / raw)
  To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Nuno Sa,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Jonathan Cameron, linux-iio, linux-kernel, Michael Hennerich,
	devicetree, dlechner, jstephan, aardelean, adureghello,
	Guillaume Stols

This is a preparation to add the new channels for software mode and
hardware mode in iio backend mod more easily.

Signed-off-by: Guillaume Stols <gstols@baylibre.com>
---
 drivers/iio/adc/ad7606.h | 51 ++++++++++++++++++++++++------------------------
 1 file changed, 25 insertions(+), 26 deletions(-)

diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h
index eca7ea99e24d..74896d9f1929 100644
--- a/drivers/iio/adc/ad7606.h
+++ b/drivers/iio/adc/ad7606.h
@@ -40,37 +40,19 @@
 #define AD7606_RANGE_CH_ADDR(ch)	(0x03 + ((ch) >> 1))
 #define AD7606_OS_MODE			0x08
 
-#define AD760X_CHANNEL(num, mask_sep, mask_type, mask_all, bits) {	\
+#define AD760X_CHANNEL(num, mask_sep, mask_type, mask_all,	\
+		mask_sep_avail, mask_all_avail, bits) {		\
 		.type = IIO_VOLTAGE,				\
 		.indexed = 1,					\
 		.channel = num,					\
 		.address = num,					\
 		.info_mask_separate = mask_sep,			\
+		.info_mask_separate_available =			\
+			mask_sep_avail,				\
 		.info_mask_shared_by_type = mask_type,		\
 		.info_mask_shared_by_all = mask_all,		\
-		.scan_index = num,				\
-		.scan_type = {					\
-			.sign = 's',				\
-			.realbits = (bits),			\
-			.storagebits = (bits) > 16 ? 32 : 16,	\
-			.endianness = IIO_CPU,			\
-		},						\
-}
-
-#define AD7606_SW_CHANNEL(num, bits) {				\
-		.type = IIO_VOLTAGE,				\
-		.indexed = 1,					\
-		.channel = num,					\
-		.address = num,					\
-		.info_mask_separate =				\
-			BIT(IIO_CHAN_INFO_RAW) |		\
-			BIT(IIO_CHAN_INFO_SCALE),		\
-		.info_mask_separate_available =			\
-			BIT(IIO_CHAN_INFO_SCALE),		\
-		.info_mask_shared_by_all =			\
-			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
 		.info_mask_shared_by_all_available =		\
-			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
+			mask_all_avail,				\
 		.scan_index = num,				\
 		.scan_type = {					\
 			.sign = 's',				\
@@ -82,12 +64,28 @@
 
 #define AD7605_CHANNEL(num)				\
 	AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW),	\
-		BIT(IIO_CHAN_INFO_SCALE), 0, 16)
+		BIT(IIO_CHAN_INFO_SCALE), 0, 0, 0, 16)
 
 #define AD7606_CHANNEL(num, bits)			\
 	AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW),	\
 		BIT(IIO_CHAN_INFO_SCALE),		\
-		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), bits)
+		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
+		0, 0, bits)
+
+#define AD7606_SW_CHANNEL(num, bits)			\
+	AD760X_CHANNEL(num,				\
+		/* mask separate */			\
+		BIT(IIO_CHAN_INFO_RAW) |		\
+		BIT(IIO_CHAN_INFO_SCALE),		\
+		/* mask type */				\
+		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
+		/* mask all */				\
+		0,					\
+		/* mask separate available */		\
+		BIT(IIO_CHAN_INFO_SCALE),		\
+		/* mask all available */		\
+		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
+		bits)
 
 #define AD7616_CHANNEL(num)	AD7606_SW_CHANNEL(num, 16)
 
@@ -95,7 +93,8 @@
 	AD760X_CHANNEL(num, 0,				\
 		BIT(IIO_CHAN_INFO_SCALE),		\
 		BIT(IIO_CHAN_INFO_SAMP_FREQ) |		\
-		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), 16)
+		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),  \
+		0, 0, 16)
 
 struct ad7606_state;
 

-- 
2.34.1


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

* [PATCH 9/9] iio: adc: ad7606: Add support for writing registers when using backend
  2024-11-21 10:18 [PATCH 0/9] Add support for Software mode on AD7606's iio backend driver Guillaume Stols
                   ` (7 preceding siblings ...)
  2024-11-21 10:18 ` [PATCH 8/9] iio: adc: ad7606: Simplify channel macros Guillaume Stols
@ 2024-11-21 10:18 ` Guillaume Stols
  2024-11-26 18:48   ` Jonathan Cameron
  2024-11-26 18:00 ` [PATCH 0/9] Add support for Software mode on AD7606's iio backend driver Jonathan Cameron
  9 siblings, 1 reply; 23+ messages in thread
From: Guillaume Stols @ 2024-11-21 10:18 UTC (permalink / raw)
  To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Nuno Sa,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Jonathan Cameron, linux-iio, linux-kernel, Michael Hennerich,
	devicetree, dlechner, jstephan, aardelean, adureghello,
	Guillaume Stols

Adds the logic for effectively enabling the software mode for the
iio-backend, i.e enabling the software mode channel configuration and
implementing the register writing functions.

Signed-off-by: Guillaume Stols <gstols@baylibre.com>
---
 drivers/iio/adc/ad7606.h     | 15 ++++++++++++
 drivers/iio/adc/ad7606_par.c | 58 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h
index 74896d9f1929..a54dc110839f 100644
--- a/drivers/iio/adc/ad7606.h
+++ b/drivers/iio/adc/ad7606.h
@@ -96,6 +96,21 @@
 		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),  \
 		0, 0, 16)
 
+#define AD7606_BI_SW_CHANNEL(num)			\
+	AD760X_CHANNEL(num,				\
+		/* mask separate */			\
+		BIT(IIO_CHAN_INFO_SCALE),		\
+		/* mask type */				\
+		0,					\
+		/* mask all */				\
+		BIT(IIO_CHAN_INFO_SAMP_FREQ) |		\
+		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
+		/* mask separate available */		\
+		BIT(IIO_CHAN_INFO_SCALE),		\
+		/* mask all available */		\
+		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
+		16)
+
 struct ad7606_state;
 
 typedef int (*ad7606_scale_setup_cb_t)(struct iio_dev *indio_dev,
diff --git a/drivers/iio/adc/ad7606_par.c b/drivers/iio/adc/ad7606_par.c
index a25182a3daa7..0c1177f436f3 100644
--- a/drivers/iio/adc/ad7606_par.c
+++ b/drivers/iio/adc/ad7606_par.c
@@ -13,12 +13,14 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/property.h>
+#include <linux/pwm.h>
 #include <linux/types.h>
 
 #include <linux/iio/backend.h>
 #include <linux/iio/iio.h>
 
 #include "ad7606.h"
+#include "ad7606_bi.h"
 
 static const struct iio_chan_spec ad7606b_bi_channels[] = {
 	AD7606_BI_CHANNEL(0),
@@ -31,6 +33,17 @@ static const struct iio_chan_spec ad7606b_bi_channels[] = {
 	AD7606_BI_CHANNEL(7),
 };
 
+static const struct iio_chan_spec ad7606b_bi_sw_channels[] = {
+	AD7606_BI_SW_CHANNEL(0),
+	AD7606_BI_SW_CHANNEL(1),
+	AD7606_BI_SW_CHANNEL(2),
+	AD7606_BI_SW_CHANNEL(3),
+	AD7606_BI_SW_CHANNEL(4),
+	AD7606_BI_SW_CHANNEL(5),
+	AD7606_BI_SW_CHANNEL(6),
+	AD7606_BI_SW_CHANNEL(7),
+};
+
 static int ad7606_bi_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask)
 {
 	struct ad7606_state *st = iio_priv(indio_dev);
@@ -70,7 +83,7 @@ static int ad7606_bi_setup_iio_backend(struct device *dev, struct iio_dev *indio
 	if (ret)
 		return ret;
 
-	ret = devm_iio_backend_enable(dev, st->back);
+	ret = devm_iio_backend_enable(st->dev, st->back);
 	if (ret)
 		return ret;
 
@@ -86,9 +99,52 @@ static int ad7606_bi_setup_iio_backend(struct device *dev, struct iio_dev *indio
 	return 0;
 }
 
+static int ad7606_bi_reg_read(struct iio_dev *indio_dev, unsigned int addr)
+{
+	struct ad7606_state *st = iio_priv(indio_dev);
+	int val, ret;
+	struct ad7606_platform_data *pdata =  st->dev->platform_data;
+
+	iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {
+		ret = pdata->bus_reg_read(st->back,
+					addr,
+					&val);
+	}
+	if (ret < 0)
+		return ret;
+
+	return val;
+}
+
+static int ad7606_bi_reg_write(struct iio_dev *indio_dev,
+			       unsigned int addr,
+			       unsigned int val)
+{
+	struct ad7606_state *st = iio_priv(indio_dev);
+	struct ad7606_platform_data *pdata =  st->dev->platform_data;
+	int ret;
+
+	iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {
+	ret = pdata->bus_reg_write(st->back,
+					addr,
+					val);
+	}
+	return ret;
+}
+
+static int ad7606_bi_sw_mode_config(struct iio_dev *indio_dev)
+{
+	indio_dev->channels = ad7606b_bi_sw_channels;
+
+	return 0;
+}
+
 static const struct ad7606_bus_ops ad7606_bi_bops = {
 	.iio_backend_config = ad7606_bi_setup_iio_backend,
 	.update_scan_mode = ad7606_bi_update_scan_mode,
+	.reg_read = ad7606_bi_reg_read,
+	.reg_write = ad7606_bi_reg_write,
+	.sw_mode_config = ad7606_bi_sw_mode_config,
 };
 
 static int ad7606_par16_read_block(struct device *dev,

-- 
2.34.1


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

* Re: [PATCH 2/9] dt-bindings: iio: dac: adi-axi-adc: Add ad7606 variant
  2024-11-21 10:18 ` [PATCH 2/9] dt-bindings: iio: dac: adi-axi-adc: Add ad7606 variant Guillaume Stols
@ 2024-11-21 16:57   ` David Lechner
  2024-11-21 19:53     ` Conor Dooley
  0 siblings, 1 reply; 23+ messages in thread
From: David Lechner @ 2024-11-21 16:57 UTC (permalink / raw)
  To: Guillaume Stols, Lars-Peter Clausen, Michael Hennerich,
	Jonathan Cameron, Nuno Sa, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley
  Cc: Jonathan Cameron, linux-iio, linux-kernel, devicetree, jstephan,
	aardelean, adureghello

On 11/21/24 4:18 AM, Guillaume Stols wrote:
> A new compatible is added to reflect the specialized version of the HDL
> that is not covered by the IIO backend paradigm: We use the parallel

It still is being used as an IIO backend, so I would leave out the
phrase "that is not covered by the IIO backend paradigm".

> interface to write the ADC's registers, and accessing this interface
> requires to use ADI_AXI_REG_CONFIG_RD,ADI_AXI_REG_CONFIG_WR and
> ADI_AXI_REG_CONFIG_CTRL in a custom fashion.
> 
> Signed-off-by: Guillaume Stols <gstols@baylibre.com>
> ---
>  Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
> index e1f450b80db2..43bc0440c678 100644
> --- a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
> +++ b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
> @@ -17,13 +17,20 @@ description: |
>    interface for the actual ADC, while this IP core will interface
>    to the data-lines of the ADC and handle the streaming of data into
>    memory via DMA.
> +  In some cases, the AXI ADC interface is used to perform specialized
> +  operation to a particular ADC, e.g access the physical bus through
> +  some special register to write ADC registers.
> +  In this case, a different compatible is used, and the driver behaves

Quick, delete the word "driver" before Krzysztof sees it. :-p

Joking aside, the devicetree only describes how things are wired up,
it doesn't care how the driver uses the information. So we avoid
mentioning anything about drivers in the bindings.

> +  slightly differently according to the special needs.
>  
>    https://wiki.analog.com/resources/fpga/docs/axi_adc_ip
> +  http://analogdevicesinc.github.io/hdl/library/axi_ad7606x/index.html
>  
>  properties:
>    compatible:
>      enum:
>        - adi,axi-adc-10.0.a
> +      - adi,axi-ad7606x
>  
>    reg:
>      maxItems: 1
> 

Since this new compatible also provides a bus in addition to the io-backend,
I think we need some additional bindings to describe the child nodes for the
ADC devices attached to the bus.

I don't think there are any generic parallel-controller bindings like there
are for SPI controllers, so we can't $ref: /schemas/spi/spi-controller.yaml#
like we did for the similar case of adi,axi-ad3552r recently.

But maybe something like this:

properties:
  ...

  "#address-cells":
    const: 1

  "#size-cells":
    const: 0

patternProperties:
  "^adc@[0-9a-f]+$":
    type: object
    additionalProperties: true

    properties:
      reg:
        maxItems: 1

    required:
      - compatible
      - reg

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

* Re: [PATCH 2/9] dt-bindings: iio: dac: adi-axi-adc: Add ad7606 variant
  2024-11-21 16:57   ` David Lechner
@ 2024-11-21 19:53     ` Conor Dooley
  2024-11-26 17:59       ` Jonathan Cameron
  0 siblings, 1 reply; 23+ messages in thread
From: Conor Dooley @ 2024-11-21 19:53 UTC (permalink / raw)
  To: David Lechner
  Cc: Guillaume Stols, Lars-Peter Clausen, Michael Hennerich,
	Jonathan Cameron, Nuno Sa, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Jonathan Cameron, linux-iio, linux-kernel,
	devicetree, jstephan, aardelean, adureghello

[-- Attachment #1: Type: text/plain, Size: 1801 bytes --]

On Thu, Nov 21, 2024 at 10:57:44AM -0600, David Lechner wrote:
> On 11/21/24 4:18 AM, Guillaume Stols wrote:
> > A new compatible is added to reflect the specialized version of the HDL
> > that is not covered by the IIO backend paradigm: We use the parallel
> 
> It still is being used as an IIO backend, so I would leave out the
> phrase "that is not covered by the IIO backend paradigm".
> 
> > interface to write the ADC's registers, and accessing this interface
> > requires to use ADI_AXI_REG_CONFIG_RD,ADI_AXI_REG_CONFIG_WR and
> > ADI_AXI_REG_CONFIG_CTRL in a custom fashion.
> > 
> > Signed-off-by: Guillaume Stols <gstols@baylibre.com>
> > ---
> >  Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml | 7 +++++++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
> > index e1f450b80db2..43bc0440c678 100644
> > --- a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
> > +++ b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
> > @@ -17,13 +17,20 @@ description: |
> >    interface for the actual ADC, while this IP core will interface
> >    to the data-lines of the ADC and handle the streaming of data into
> >    memory via DMA.
> > +  In some cases, the AXI ADC interface is used to perform specialized
> > +  operation to a particular ADC, e.g access the physical bus through
> > +  some special register to write ADC registers.
> > +  In this case, a different compatible is used, and the driver behaves
> 
> Quick, delete the word "driver" before Krzysztof sees it. :-p

And also perhaps worth mentioning under the --- line that the x in the
compatible is not a wildcard, for similar reasons ;)

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 2/9] dt-bindings: iio: dac: adi-axi-adc: Add ad7606 variant
  2024-11-21 19:53     ` Conor Dooley
@ 2024-11-26 17:59       ` Jonathan Cameron
  2024-11-26 18:12         ` Conor Dooley
  0 siblings, 1 reply; 23+ messages in thread
From: Jonathan Cameron @ 2024-11-26 17:59 UTC (permalink / raw)
  To: Conor Dooley
  Cc: David Lechner, Guillaume Stols, Lars-Peter Clausen,
	Michael Hennerich, Nuno Sa, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Jonathan Cameron, linux-iio, linux-kernel,
	devicetree, jstephan, aardelean, adureghello

On Thu, 21 Nov 2024 19:53:53 +0000
Conor Dooley <conor@kernel.org> wrote:

> On Thu, Nov 21, 2024 at 10:57:44AM -0600, David Lechner wrote:
> > On 11/21/24 4:18 AM, Guillaume Stols wrote:  
> > > A new compatible is added to reflect the specialized version of the HDL
> > > that is not covered by the IIO backend paradigm: We use the parallel  
> > 
> > It still is being used as an IIO backend, so I would leave out the
> > phrase "that is not covered by the IIO backend paradigm".
> >   
> > > interface to write the ADC's registers, and accessing this interface
> > > requires to use ADI_AXI_REG_CONFIG_RD,ADI_AXI_REG_CONFIG_WR and
> > > ADI_AXI_REG_CONFIG_CTRL in a custom fashion.
> > > 
> > > Signed-off-by: Guillaume Stols <gstols@baylibre.com>
> > > ---
> > >  Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml | 7 +++++++
> > >  1 file changed, 7 insertions(+)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
> > > index e1f450b80db2..43bc0440c678 100644
> > > --- a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
> > > +++ b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
> > > @@ -17,13 +17,20 @@ description: |
> > >    interface for the actual ADC, while this IP core will interface
> > >    to the data-lines of the ADC and handle the streaming of data into
> > >    memory via DMA.
> > > +  In some cases, the AXI ADC interface is used to perform specialized
> > > +  operation to a particular ADC, e.g access the physical bus through
> > > +  some special register to write ADC registers.
> > > +  In this case, a different compatible is used, and the driver behaves  
> > 
> > Quick, delete the word "driver" before Krzysztof sees it. :-p  
> 
> And also perhaps worth mentioning under the --- line that the x in the
> compatible is not a wildcard, for similar reasons ;)
Well it is, just one that is used for the IP naming to cover all
the different ADCs it works with.

"The AXI AD7606x IP core can be used to interface the AD7606B, AD7606C-16,
AD7606C-18, AD7605-4, AD7606, AD7606-6, AD7606-4, AD7607, AD7608 and AD7609 devices using an FPGA."

Given that's what ADI calls the IP though we are stuck with it - however
'wrong' they may be :)

But agreed, something to call out to keep me away from the x as well!

Jonathan


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

* Re: [PATCH 0/9] Add support for Software mode on AD7606's iio backend driver
  2024-11-21 10:18 [PATCH 0/9] Add support for Software mode on AD7606's iio backend driver Guillaume Stols
                   ` (8 preceding siblings ...)
  2024-11-21 10:18 ` [PATCH 9/9] iio: adc: ad7606: Add support for writing registers when using backend Guillaume Stols
@ 2024-11-26 18:00 ` Jonathan Cameron
  9 siblings, 0 replies; 23+ messages in thread
From: Jonathan Cameron @ 2024-11-26 18:00 UTC (permalink / raw)
  To: Guillaume Stols
  Cc: Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron, linux-iio,
	linux-kernel, devicetree, dlechner, jstephan, aardelean,
	adureghello

On Thu, 21 Nov 2024 10:18:22 +0000
Guillaume Stols <gstols@baylibre.com> wrote:

> This series adds the support for software mode when the ADC is used in
> iio_backend mode.

I'm not sure form this description what "software mode" means.

Perhaps some more info on that for v2?

> The bus access is based on Angelo's ad3552 implementation, that is we
> have a particular compatible for the backend (here axi-adc) version
> supporting the ad7606's register writing, and the ad7606 is defined as a
> child node of the backend in the devicetree.
> Small changes are added to make the code a bit more straightforward to
> understand, and more compact.
> 
> Signed-off-by: Guillaume Stols <gstols@baylibre.com>
> ---
> Guillaume Stols (9):
>       iio: adc: ad7606: Fix hardcoded offset in the ADC channels
>       dt-bindings: iio: dac: adi-axi-adc: Add ad7606 variant
>       iio:adc: ad7606: Move the software mode configuration
>       iio: adc: ad7606: Move software functions into common file
>       iio: adc: adi-axi-adc: Add platform children support
>       iio: adc: adi-axi-adc: Add support for AD7606 register writing
>       iio: adc: ad7606: change r/w_register signature
>       iio: adc: ad7606: Simplify channel macros
>       iio: adc: ad7606: Add support for writing registers when using backend
> 
>  .../devicetree/bindings/iio/adc/adi,axi-adc.yaml   |   7 +
>  drivers/iio/adc/ad7606.c                           | 202 +++++++++++++++++----
>  drivers/iio/adc/ad7606.h                           | 113 ++++++++----
>  drivers/iio/adc/ad7606_bi.h                        |  16 ++
>  drivers/iio/adc/ad7606_par.c                       |  58 +++++-
>  drivers/iio/adc/ad7606_spi.c                       | 141 +-------------
>  drivers/iio/adc/adi-axi-adc.c                      | 178 +++++++++++++++++-
>  7 files changed, 500 insertions(+), 215 deletions(-)
> ---
> base-commit: 33d38f912d5ca05501c9bbfe14e0150da9ca85b6
> change-id: 20241009-ad7606_add_iio_backend_software_mode-567d9c392243
> 
> Best regards,
> --
> Guillaume Stols <gstols@baylibre.com>
> 
> 


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

* Re: [PATCH 2/9] dt-bindings: iio: dac: adi-axi-adc: Add ad7606 variant
  2024-11-26 17:59       ` Jonathan Cameron
@ 2024-11-26 18:12         ` Conor Dooley
  0 siblings, 0 replies; 23+ messages in thread
From: Conor Dooley @ 2024-11-26 18:12 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: David Lechner, Guillaume Stols, Lars-Peter Clausen,
	Michael Hennerich, Nuno Sa, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Jonathan Cameron, linux-iio, linux-kernel,
	devicetree, jstephan, aardelean, adureghello

[-- Attachment #1: Type: text/plain, Size: 2829 bytes --]

On Tue, Nov 26, 2024 at 05:59:31PM +0000, Jonathan Cameron wrote:
> On Thu, 21 Nov 2024 19:53:53 +0000
> Conor Dooley <conor@kernel.org> wrote:
> 
> > On Thu, Nov 21, 2024 at 10:57:44AM -0600, David Lechner wrote:
> > > On 11/21/24 4:18 AM, Guillaume Stols wrote:  
> > > > A new compatible is added to reflect the specialized version of the HDL
> > > > that is not covered by the IIO backend paradigm: We use the parallel  
> > > 
> > > It still is being used as an IIO backend, so I would leave out the
> > > phrase "that is not covered by the IIO backend paradigm".
> > >   
> > > > interface to write the ADC's registers, and accessing this interface
> > > > requires to use ADI_AXI_REG_CONFIG_RD,ADI_AXI_REG_CONFIG_WR and
> > > > ADI_AXI_REG_CONFIG_CTRL in a custom fashion.
> > > > 
> > > > Signed-off-by: Guillaume Stols <gstols@baylibre.com>
> > > > ---
> > > >  Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml | 7 +++++++
> > > >  1 file changed, 7 insertions(+)
> > > > 
> > > > diff --git a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
> > > > index e1f450b80db2..43bc0440c678 100644
> > > > --- a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
> > > > +++ b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
> > > > @@ -17,13 +17,20 @@ description: |
> > > >    interface for the actual ADC, while this IP core will interface
> > > >    to the data-lines of the ADC and handle the streaming of data into
> > > >    memory via DMA.
> > > > +  In some cases, the AXI ADC interface is used to perform specialized
> > > > +  operation to a particular ADC, e.g access the physical bus through
> > > > +  some special register to write ADC registers.
> > > > +  In this case, a different compatible is used, and the driver behaves  
> > > 
> > > Quick, delete the word "driver" before Krzysztof sees it. :-p  
> > 
> > And also perhaps worth mentioning under the --- line that the x in the
> > compatible is not a wildcard, for similar reasons ;)
> 
> Well it is, just one that is used for the IP naming to cover all
> the different ADCs it works with.

In "our" terms, when talking about bindings, is not a wildcard.
As you say below, the x refers to a specific IP that works with several
different ADCs, rather than attempting to use a single compatible for
multiple different IPs.

> "The AXI AD7606x IP core can be used to interface the AD7606B, AD7606C-16,
> AD7606C-18, AD7605-4, AD7606, AD7606-6, AD7606-4, AD7607, AD7608 and AD7609 devices using an FPGA."
> 
> Given that's what ADI calls the IP though we are stuck with it - however
> 'wrong' they may be :)
> 
> But agreed, something to call out to keep me away from the x as well!
> 
> Jonathan
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 1/9] iio: adc: ad7606: Fix hardcoded offset in the ADC channels
  2024-11-21 10:18 ` [PATCH 1/9] iio: adc: ad7606: Fix hardcoded offset in the ADC channels Guillaume Stols
@ 2024-11-26 18:15   ` Jonathan Cameron
  0 siblings, 0 replies; 23+ messages in thread
From: Jonathan Cameron @ 2024-11-26 18:15 UTC (permalink / raw)
  To: Guillaume Stols
  Cc: Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron, linux-iio,
	linux-kernel, devicetree, dlechner, jstephan, aardelean,
	adureghello

On Thu, 21 Nov 2024 10:18:23 +0000
Guillaume Stols <gstols@baylibre.com> wrote:

> When introducing num_adc_channels, I overlooked some new functions
> created in a meanwhile that had also the hardcoded offset. This commit
> adds the new logic to these functions.
> 
> Fixes: 7a671afeb592 ("iio: adc: ad7606: Introduce num_adc_channels")
> Signed-off-by: Guillaume Stols <gstols@baylibre.com>
Hi Guillaume,

Trivial thing inline.

I can't pick this up quite yet as need to wait to rebase my fixes on rc1 sometime
next week.

Jonathan

> ---
>  drivers/iio/adc/ad7606.c | 48 ++++++++++++++++++++++++++++--------------------
>  drivers/iio/adc/ad7606.h |  2 +-
>  2 files changed, 29 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c
> index 8b2046baaa3e..893b93b86aa7 100644
> --- a/drivers/iio/adc/ad7606.c
> +++ b/drivers/iio/adc/ad7606.c
> @@ -175,17 +175,17 @@ static const struct iio_chan_spec ad7616_channels[] = {
> -static int ad7606_16bit_chan_scale_setup(struct ad7606_state *st,
> +static int ad7606_16bit_chan_scale_setup(struct iio_dev *indio_dev,
>  					 struct iio_chan_spec *chan, int ch)
>  {
> +	struct ad7606_state *st = iio_priv(indio_dev);
>  	struct ad7606_chan_scale *cs = &st->chan_scales[ch];
>  
>  	if (!st->sw_mode_en) {
> @@ -345,10 +346,12 @@ static int ad7606_16bit_chan_scale_setup(struct ad7606_state *st,
>  	return 0;
>  }
>  
> -static int ad7606_get_chan_config(struct ad7606_state *st, int ch,
> +static int ad7606_get_chan_config(struct iio_dev *indio_dev, int ch,
>  				  bool *bipolar, bool *differential)
>  {
> -	unsigned int num_channels = st->chip_info->num_channels - 1;
> +	struct ad7606_state *st = iio_priv(indio_dev);
> +	unsigned int num_channels = st->chip_info->num_adc_channels;
> +	unsigned int offset = indio_dev->num_channels - st->chip_info->num_adc_channels;
>  	struct device *dev = st->dev;
>  	int ret;
>  
> @@ -364,7 +367,7 @@ static int ad7606_get_chan_config(struct ad7606_state *st, int ch,
>  			continue;
>  
>  		/* channel number (here) is from 1 to num_channels */
> -		if (reg == 0 || reg > num_channels) {
> +		if (reg < offset  || reg > num_channels) {

Unwanted bonus space before ||

>  			dev_warn(dev,
>  				 "Invalid channel number (ignoring): %d\n", reg);
>  			continue;
> @@ -399,9 +402,10 @@ static int ad7606_get_chan_config(struct ad7606_state *st, int ch,
>  	return 0;
>  }

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

* Re: [PATCH 3/9] iio:adc: ad7606: Move the software mode configuration
  2024-11-21 10:18 ` [PATCH 3/9] iio:adc: ad7606: Move the software mode configuration Guillaume Stols
@ 2024-11-26 18:21   ` Jonathan Cameron
  0 siblings, 0 replies; 23+ messages in thread
From: Jonathan Cameron @ 2024-11-26 18:21 UTC (permalink / raw)
  To: Guillaume Stols
  Cc: Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron, linux-iio,
	linux-kernel, devicetree, dlechner, jstephan, aardelean,
	adureghello

On Thu, 21 Nov 2024 10:18:25 +0000
Guillaume Stols <gstols@baylibre.com> wrote:

> This is a preparation for the intoduction of the sofware functions in
> the iio backend version of the driver.
> The software mode configuration must be executed once the channels are
> configured, and the number of channels is known. This is not the case
> before iio-backend's configuration is called, and iio backend version of
> the driver does not have a timestamp channel.
> Also the sw_mode_config callback is configured during the
> iio-backend configuration.
> For clarity purpose, I moved the entire block instead of just the
> concerned function calls.
> 
> Signed-off-by: Guillaume Stols <gstols@baylibre.com>
> ---
>  drivers/iio/adc/ad7606.c | 25 ++++++++++++++-----------
>  1 file changed, 14 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c
> index 893b93b86aa7..828603ed18f6 100644
> --- a/drivers/iio/adc/ad7606.c
> +++ b/drivers/iio/adc/ad7606.c
> @@ -1246,17 +1246,6 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
>  			return -ERESTARTSYS;
>  	}
>  
> -	st->write_scale = ad7606_write_scale_hw;
> -	st->write_os = ad7606_write_os_hw;
> -
> -	ret = ad7606_sw_mode_setup(indio_dev);
Isn't this the only call to this function?

> -	if (ret)
> -		return ret;
> -
> -	ret = ad7606_chan_scales_setup(indio_dev);
> -	if (ret)
> -		return ret;
> -
>  	/* If convst pin is not defined, setup PWM. */
>  	if (!st->gpio_convst) {
>  		st->cnvst_pwm = devm_pwm_get(dev, NULL);
> @@ -1334,6 +1323,20 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
>  			return ret;
>  	}
>  
> +	st->write_scale = ad7606_write_scale_hw;
> +	st->write_os = ad7606_write_os_hw;
> +
> +	st->sw_mode_en = st->chip_info->sw_setup_cb &&
> +			 device_property_present(st->dev, "adi,sw-mode");
> +	if (st->sw_mode_en) {
> +		indio_dev->info = &ad7606_info_sw_mode;
> +		st->chip_info->sw_setup_cb(indio_dev);

Where did this callback come from?

Looks like this and the next patch need tidying up so each does
one distinct thing.

> +	}
> +
> +	ret = ad7606_chan_scales_setup(indio_dev);
> +	if (ret)
> +		return ret;
> +
>  	return devm_iio_device_register(dev, indio_dev);
>  }
>  EXPORT_SYMBOL_NS_GPL(ad7606_probe, IIO_AD7606);
> 


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

* Re: [PATCH 4/9] iio: adc: ad7606: Move software functions into common file
  2024-11-21 10:18 ` [PATCH 4/9] iio: adc: ad7606: Move software functions into common file Guillaume Stols
@ 2024-11-26 18:29   ` Jonathan Cameron
  0 siblings, 0 replies; 23+ messages in thread
From: Jonathan Cameron @ 2024-11-26 18:29 UTC (permalink / raw)
  To: Guillaume Stols
  Cc: Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron, linux-iio,
	linux-kernel, devicetree, dlechner, jstephan, aardelean,
	adureghello

On Thu, 21 Nov 2024 10:18:26 +0000
Guillaume Stols <gstols@baylibre.com> wrote:

> Since the register are always the same, whatever bus is used, moving the
> software functions into the main file avoids the code to be duplicated
> in both SPI and parallel version of the driver.
> 
> Signed-off-by: Guillaume Stols <gstols@baylibre.com>
> ---
>  drivers/iio/adc/ad7606.c     | 128 ++++++++++++++++++++++++++++++++++++++++--
>  drivers/iio/adc/ad7606.h     |  37 ++++++++++--
>  drivers/iio/adc/ad7606_spi.c | 131 +------------------------------------------
>  3 files changed, 156 insertions(+), 140 deletions(-)
> 
> diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c
> index 828603ed18f6..df0e49bc4bdb 100644
> --- a/drivers/iio/adc/ad7606.c
> +++ b/drivers/iio/adc/ad7606.c
> @@ -85,6 +85,10 @@ static const unsigned int ad7606_oversampling_avail[7] = {
>  	1, 2, 4, 8, 16, 32, 64,
>  };
>  
> +static const unsigned int ad7606B_oversampling_avail[9] = {

Same in original code, but why capital B?

I think you didn't remove this as intended from ad7606_spi.c
so we have a duplicate.


> +	1, 2, 4, 8, 16, 32, 64, 128, 256
> +};
> +
>  static const unsigned int ad7616_oversampling_avail[8] = {
>  	1, 2, 4, 8, 16, 32, 64, 128,
>  };
> @@ -187,6 +191,8 @@ static int ad7608_chan_scale_setup(struct iio_dev *indio_dev,
>  				   struct iio_chan_spec *chan, int ch);
>  static int ad7609_chan_scale_setup(struct iio_dev *indio_dev,
>  				   struct iio_chan_spec *chan, int ch);
> +static int ad7616_sw_mode_setup(struct iio_dev *indio_dev);
> +static int ad7606B_sw_mode_setup(struct iio_dev *indio_dev);
Similar question. Why capital B?  We make ad lowercase, so I'd think it makes
sense for the B as well.



> +
> +static int ad7616_write_os_sw(struct iio_dev *indio_dev, int val)
> +{
> +	struct ad7606_state *st = iio_priv(indio_dev);
> +
> +	return ad7606_write_mask(st, AD7616_CONFIGURATION_REGISTER,
> +				     AD7616_OS_MASK, val << 2);
> +}
> +
> +static int ad7606_write_scale_sw(struct iio_dev *indio_dev, int ch, int val)
> +{
> +	struct ad7606_state *st = iio_priv(indio_dev);
> +
> +	return ad7606_write_mask(st,
> +				     AD7606_RANGE_CH_ADDR(ch),
> +				     AD7606_RANGE_CH_MSK(ch),
> +				     AD7606_RANGE_CH_MODE(ch, val));

Odd alignment.

> +}


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

* Re: [PATCH 5/9] iio: adc: adi-axi-adc: Add platform children support
  2024-11-21 10:18 ` [PATCH 5/9] iio: adc: adi-axi-adc: Add platform children support Guillaume Stols
@ 2024-11-26 18:41   ` Jonathan Cameron
  0 siblings, 0 replies; 23+ messages in thread
From: Jonathan Cameron @ 2024-11-26 18:41 UTC (permalink / raw)
  To: Guillaume Stols
  Cc: Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron, linux-iio,
	linux-kernel, devicetree, dlechner, jstephan, aardelean,
	adureghello

>  
> -/* Match table for of_platform binding */

No longer true? 

>  static const struct of_device_id adi_axi_adc_of_match[] = {
> -	{ .compatible = "adi,axi-adc-10.0.a", .data = &adi_axi_adc_10_0_a_info },
> -	{ /* end of list */ }
Leave this terminator as it was.  

It's not important to have, but no need to add churn here given the comment does no harm.

> +	{ .compatible = "adi,axi-adc-10.0.a", .data = &adc_generic },
> +	{  }
>  };
>  MODULE_DEVICE_TABLE(of, adi_axi_adc_of_match);
>  
> 


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

* Re: [PATCH 6/9] iio: adc: adi-axi-adc: Add support for AD7606 register writing
  2024-11-21 10:18 ` [PATCH 6/9] iio: adc: adi-axi-adc: Add support for AD7606 register writing Guillaume Stols
@ 2024-11-26 18:43   ` Jonathan Cameron
  0 siblings, 0 replies; 23+ messages in thread
From: Jonathan Cameron @ 2024-11-26 18:43 UTC (permalink / raw)
  To: Guillaume Stols
  Cc: Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron, linux-iio,
	linux-kernel, devicetree, dlechner, jstephan, aardelean,
	adureghello

On Thu, 21 Nov 2024 10:18:28 +0000
Guillaume Stols <gstols@baylibre.com> wrote:

> Since we must access the bus parallel bus using a custom procedure,
> let's add a specialized compatible, and define specialized callbacks for
> writing the registers using the parallel interface.
> 
> Signed-off-by: Guillaume Stols <gstols@baylibre.com>
Trivial comments inline.

Thanks,

J
> +
> +static int ad7606_bi_reg_write(struct iio_backend *back, u32 reg, u32 val)
> +{
> +	struct adi_axi_adc_state *st = iio_backend_get_priv(back);
> +	u32 buf;
> +
> +	guard(mutex)(&st->lock);
> +
> +	/* Read any register to switch to register mode */
> +	buf = 0xaf00;
> +	axi_adc_raw_write(back, &buf, 4);

sizeof(buf) for these.


>  static void axi_adc_free_buffer(struct iio_backend *back,
>  				struct iio_buffer *buffer)
>  {
> @@ -487,9 +573,22 @@ static const struct axi_adc_info adc_generic = {
>  	.backend_info = &adi_axi_adc_generic,
>  };
>  
> +static const struct ad7606_platform_data ad7606_pdata = {
> +		.bus_reg_read = ad7606_bi_reg_read,
> +		.bus_reg_write = ad7606_bi_reg_write,

One less tab on indent.

> +};

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

* Re: [PATCH 8/9] iio: adc: ad7606: Simplify channel macros
  2024-11-21 10:18 ` [PATCH 8/9] iio: adc: ad7606: Simplify channel macros Guillaume Stols
@ 2024-11-26 18:46   ` Jonathan Cameron
  0 siblings, 0 replies; 23+ messages in thread
From: Jonathan Cameron @ 2024-11-26 18:46 UTC (permalink / raw)
  To: Guillaume Stols
  Cc: Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron, linux-iio,
	linux-kernel, devicetree, dlechner, jstephan, aardelean,
	adureghello

On Thu, 21 Nov 2024 10:18:30 +0000
Guillaume Stols <gstols@baylibre.com> wrote:

> This is a preparation to add the new channels for software mode and
> hardware mode in iio backend mod more easily.

I'm not sure this 'simplifies' anything!  Maybe change title.

> 
> Signed-off-by: Guillaume Stols <gstols@baylibre.com>
> ---
>  drivers/iio/adc/ad7606.h | 51 ++++++++++++++++++++++++------------------------
>  1 file changed, 25 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h
> index eca7ea99e24d..74896d9f1929 100644
> --- a/drivers/iio/adc/ad7606.h
> +++ b/drivers/iio/adc/ad7606.h
> @@ -40,37 +40,19 @@
>  #define AD7606_RANGE_CH_ADDR(ch)	(0x03 + ((ch) >> 1))
>  #define AD7606_OS_MODE			0x08
>  
> -#define AD760X_CHANNEL(num, mask_sep, mask_type, mask_all, bits) {	\
> +#define AD760X_CHANNEL(num, mask_sep, mask_type, mask_all,	\
> +		mask_sep_avail, mask_all_avail, bits) {		\
>  		.type = IIO_VOLTAGE,				\
>  		.indexed = 1,					\
>  		.channel = num,					\
>  		.address = num,					\
>  		.info_mask_separate = mask_sep,			\
> +		.info_mask_separate_available =			\
> +			mask_sep_avail,				\
>  		.info_mask_shared_by_type = mask_type,		\
>  		.info_mask_shared_by_all = mask_all,		\
> -		.scan_index = num,				\
> -		.scan_type = {					\
> -			.sign = 's',				\
> -			.realbits = (bits),			\
> -			.storagebits = (bits) > 16 ? 32 : 16,	\
> -			.endianness = IIO_CPU,			\
> -		},						\
> -}
> -
> -#define AD7606_SW_CHANNEL(num, bits) {				\
> -		.type = IIO_VOLTAGE,				\
> -		.indexed = 1,					\
> -		.channel = num,					\
> -		.address = num,					\
> -		.info_mask_separate =				\
> -			BIT(IIO_CHAN_INFO_RAW) |		\
> -			BIT(IIO_CHAN_INFO_SCALE),		\
> -		.info_mask_separate_available =			\
> -			BIT(IIO_CHAN_INFO_SCALE),		\
> -		.info_mask_shared_by_all =			\
> -			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
>  		.info_mask_shared_by_all_available =		\
> -			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
> +			mask_all_avail,				\
>  		.scan_index = num,				\
>  		.scan_type = {					\
>  			.sign = 's',				\
> @@ -82,12 +64,28 @@
>  
>  #define AD7605_CHANNEL(num)				\
>  	AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW),	\
> -		BIT(IIO_CHAN_INFO_SCALE), 0, 16)
> +		BIT(IIO_CHAN_INFO_SCALE), 0, 0, 0, 16)
>  
>  #define AD7606_CHANNEL(num, bits)			\
>  	AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW),	\
>  		BIT(IIO_CHAN_INFO_SCALE),		\
> -		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), bits)
> +		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
> +		0, 0, bits)
> +
> +#define AD7606_SW_CHANNEL(num, bits)			\
> +	AD760X_CHANNEL(num,				\
> +		/* mask separate */			\
> +		BIT(IIO_CHAN_INFO_RAW) |		\
> +		BIT(IIO_CHAN_INFO_SCALE),		\

Maybe use some longer lines to avoid so much wrapping.

> +		/* mask type */				\
> +		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
> +		/* mask all */				\
> +		0,					\
> +		/* mask separate available */		\
> +		BIT(IIO_CHAN_INFO_SCALE),		\
> +		/* mask all available */		\
> +		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
> +		bits)
>  
>  #define AD7616_CHANNEL(num)	AD7606_SW_CHANNEL(num, 16)
>  
> @@ -95,7 +93,8 @@
>  	AD760X_CHANNEL(num, 0,				\
>  		BIT(IIO_CHAN_INFO_SCALE),		\
>  		BIT(IIO_CHAN_INFO_SAMP_FREQ) |		\
> -		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), 16)
> +		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),  \
> +		0, 0, 16)
>  
>  struct ad7606_state;
>  
> 


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

* Re: [PATCH 9/9] iio: adc: ad7606: Add support for writing registers when using backend
  2024-11-21 10:18 ` [PATCH 9/9] iio: adc: ad7606: Add support for writing registers when using backend Guillaume Stols
@ 2024-11-26 18:48   ` Jonathan Cameron
  2024-11-26 19:13     ` David Lechner
  0 siblings, 1 reply; 23+ messages in thread
From: Jonathan Cameron @ 2024-11-26 18:48 UTC (permalink / raw)
  To: Guillaume Stols
  Cc: Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron, linux-iio,
	linux-kernel, devicetree, dlechner, jstephan, aardelean,
	adureghello

On Thu, 21 Nov 2024 10:18:31 +0000
Guillaume Stols <gstols@baylibre.com> wrote:

> Adds the logic for effectively enabling the software mode for the
> iio-backend, i.e enabling the software mode channel configuration and
> implementing the register writing functions.
> 
> Signed-off-by: Guillaume Stols <gstols@baylibre.com>

A few comments inline, but basically looks fine to me.

Thanks,

Jonathan

> diff --git a/drivers/iio/adc/ad7606_par.c b/drivers/iio/adc/ad7606_par.c
> index a25182a3daa7..0c1177f436f3 100644
> --- a/drivers/iio/adc/ad7606_par.c
> +++ b/drivers/iio/adc/ad7606_par.c

>  static int ad7606_bi_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask)
>  {
>  	struct ad7606_state *st = iio_priv(indio_dev);
> @@ -70,7 +83,7 @@ static int ad7606_bi_setup_iio_backend(struct device *dev, struct iio_dev *indio
>  	if (ret)
>  		return ret;
>  
> -	ret = devm_iio_backend_enable(dev, st->back);
> +	ret = devm_iio_backend_enable(st->dev, st->back);

Is that a different dev? That's not obvious...

>  	if (ret)
>  		return ret;
>  
> @@ -86,9 +99,52 @@ static int ad7606_bi_setup_iio_backend(struct device *dev, struct iio_dev *indio
>  	return 0;
>  }
>  
> +static int ad7606_bi_reg_read(struct iio_dev *indio_dev, unsigned int addr)
> +{
> +	struct ad7606_state *st = iio_priv(indio_dev);
> +	int val, ret;
> +	struct ad7606_platform_data *pdata =  st->dev->platform_data;
> +
> +	iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {
> +		ret = pdata->bus_reg_read(st->back,
> +					addr,
> +					&val);

As below.

> +	}
> +	if (ret < 0)
> +		return ret;
> +
> +	return val;
> +}
> +
> +static int ad7606_bi_reg_write(struct iio_dev *indio_dev,
> +			       unsigned int addr,
> +			       unsigned int val)
> +{
> +	struct ad7606_state *st = iio_priv(indio_dev);
> +	struct ad7606_platform_data *pdata =  st->dev->platform_data;
> +	int ret;
> +
> +	iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {

Given David's if_not_cond_guard() should land shortly I'd prefer
to use that going forwards for cases like this.

> +	ret = pdata->bus_reg_write(st->back,
> +					addr,
> +					val);
Put parameters all on one line.
+ return here (which needs the new if_not_cond_guard() to avoid
confusing the compiler).

> +	}
> +	return ret;
> +}

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

* Re: [PATCH 9/9] iio: adc: ad7606: Add support for writing registers when using backend
  2024-11-26 18:48   ` Jonathan Cameron
@ 2024-11-26 19:13     ` David Lechner
  0 siblings, 0 replies; 23+ messages in thread
From: David Lechner @ 2024-11-26 19:13 UTC (permalink / raw)
  To: Jonathan Cameron, Guillaume Stols
  Cc: Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron, linux-iio,
	linux-kernel, devicetree, jstephan, aardelean, adureghello

On 11/26/24 12:48 PM, Jonathan Cameron wrote:
> On Thu, 21 Nov 2024 10:18:31 +0000
> Guillaume Stols <gstols@baylibre.com> wrote:
> 
>> Adds the logic for effectively enabling the software mode for the
>> iio-backend, i.e enabling the software mode channel configuration and
>> implementing the register writing functions.
>>
>> Signed-off-by: Guillaume Stols <gstols@baylibre.com>
> 
> A few comments inline, but basically looks fine to me.
> 
> Thanks,
> 
> Jonathan
> 
>> diff --git a/drivers/iio/adc/ad7606_par.c b/drivers/iio/adc/ad7606_par.c
>> index a25182a3daa7..0c1177f436f3 100644
>> --- a/drivers/iio/adc/ad7606_par.c
>> +++ b/drivers/iio/adc/ad7606_par.c
> 
>>  static int ad7606_bi_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask)
>>  {
>>  	struct ad7606_state *st = iio_priv(indio_dev);
>> @@ -70,7 +83,7 @@ static int ad7606_bi_setup_iio_backend(struct device *dev, struct iio_dev *indio
>>  	if (ret)
>>  		return ret;
>>  
>> -	ret = devm_iio_backend_enable(dev, st->back);
>> +	ret = devm_iio_backend_enable(st->dev, st->back);
> 
> Is that a different dev? That's not obvious...
> 
>>  	if (ret)
>>  		return ret;
>>  
>> @@ -86,9 +99,52 @@ static int ad7606_bi_setup_iio_backend(struct device *dev, struct iio_dev *indio
>>  	return 0;
>>  }
>>  
>> +static int ad7606_bi_reg_read(struct iio_dev *indio_dev, unsigned int addr)
>> +{
>> +	struct ad7606_state *st = iio_priv(indio_dev);
>> +	int val, ret;
>> +	struct ad7606_platform_data *pdata =  st->dev->platform_data;
>> +
>> +	iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {
>> +		ret = pdata->bus_reg_read(st->back,
>> +					addr,
>> +					&val);
> 
> As below.
> 
>> +	}
>> +	if (ret < 0)
>> +		return ret;
>> +
>> +	return val;
>> +}
>> +
>> +static int ad7606_bi_reg_write(struct iio_dev *indio_dev,
>> +			       unsigned int addr,
>> +			       unsigned int val)
>> +{
>> +	struct ad7606_state *st = iio_priv(indio_dev);
>> +	struct ad7606_platform_data *pdata =  st->dev->platform_data;
>> +	int ret;
>> +
>> +	iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {
> 
> Given David's if_not_cond_guard() should land shortly I'd prefer
> to use that going forwards for cases like this.

Well, Torvalds wasn't happy with the patch and suggested we should
give up on trying to do conditional guards altogether in cleanup.h.

[1]: https://lore.kernel.org/all/CAHk-=whn07tnDosPfn+UcAtWHBcLg=KqA16SHVv0GV4t8P1fHw@mail.gmail.com/

So I'm tempted to just revert the if_not_cond_guard() patch rather
than trying to fix it.

> 
>> +	ret = pdata->bus_reg_write(st->back,
>> +					addr,
>> +					val);
> Put parameters all on one line.
> + return here (which needs the new if_not_cond_guard() to avoid
> confusing the compiler).
> 
>> +	}
>> +	return ret;
>> +}


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

end of thread, other threads:[~2024-11-26 19:13 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-21 10:18 [PATCH 0/9] Add support for Software mode on AD7606's iio backend driver Guillaume Stols
2024-11-21 10:18 ` [PATCH 1/9] iio: adc: ad7606: Fix hardcoded offset in the ADC channels Guillaume Stols
2024-11-26 18:15   ` Jonathan Cameron
2024-11-21 10:18 ` [PATCH 2/9] dt-bindings: iio: dac: adi-axi-adc: Add ad7606 variant Guillaume Stols
2024-11-21 16:57   ` David Lechner
2024-11-21 19:53     ` Conor Dooley
2024-11-26 17:59       ` Jonathan Cameron
2024-11-26 18:12         ` Conor Dooley
2024-11-21 10:18 ` [PATCH 3/9] iio:adc: ad7606: Move the software mode configuration Guillaume Stols
2024-11-26 18:21   ` Jonathan Cameron
2024-11-21 10:18 ` [PATCH 4/9] iio: adc: ad7606: Move software functions into common file Guillaume Stols
2024-11-26 18:29   ` Jonathan Cameron
2024-11-21 10:18 ` [PATCH 5/9] iio: adc: adi-axi-adc: Add platform children support Guillaume Stols
2024-11-26 18:41   ` Jonathan Cameron
2024-11-21 10:18 ` [PATCH 6/9] iio: adc: adi-axi-adc: Add support for AD7606 register writing Guillaume Stols
2024-11-26 18:43   ` Jonathan Cameron
2024-11-21 10:18 ` [PATCH 7/9] iio: adc: ad7606: change r/w_register signature Guillaume Stols
2024-11-21 10:18 ` [PATCH 8/9] iio: adc: ad7606: Simplify channel macros Guillaume Stols
2024-11-26 18:46   ` Jonathan Cameron
2024-11-21 10:18 ` [PATCH 9/9] iio: adc: ad7606: Add support for writing registers when using backend Guillaume Stols
2024-11-26 18:48   ` Jonathan Cameron
2024-11-26 19:13     ` David Lechner
2024-11-26 18:00 ` [PATCH 0/9] Add support for Software mode on AD7606's iio backend driver Jonathan Cameron

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