[PATCH 13/15] iio: adc: ad4030: Enable dual data rate

Marcelo Schmitt posted 15 patches 1 month ago
There is a newer version of this series
[PATCH 13/15] iio: adc: ad4030: Enable dual data rate
Posted by Marcelo Schmitt 1 month ago
Set AD4030 series device to do two data bit transitions per clock cycle per
active lane when specified by firmware. The dual data rate (DDR) feature is
available only for host clock mode and echo clock mode.

Co-developed-by: Sergiu Cuciurean <sergiu.cuciurean@analog.com>
Signed-off-by: Sergiu Cuciurean <sergiu.cuciurean@analog.com>
Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
---
 drivers/iio/adc/ad4030.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/iio/adc/ad4030.c b/drivers/iio/adc/ad4030.c
index a5931056936a..37ba00097efe 100644
--- a/drivers/iio/adc/ad4030.c
+++ b/drivers/iio/adc/ad4030.c
@@ -74,6 +74,7 @@
 	(AD4030_REG_GAIN_X0_MSB + (AD4030_REG_GAIN_BYTES_NB * (ch)))
 #define AD4030_REG_MODES			0x20
 #define     AD4030_REG_MODES_MASK_OUT_DATA_MODE	GENMASK(2, 0)
+#define     AD4030_REG_MODES_MASK_DDR_MODE	BIT(3)
 #define     AD4030_REG_MODES_MASK_CLOCK_MODE	GENMASK(5, 4)
 #define     AD4030_REG_MODES_MASK_LANE_MODE	GENMASK(7, 6)
 #define AD4030_REG_OSCILATOR			0x21
@@ -175,6 +176,7 @@ struct ad4030_state {
 	enum ad4030_out_mode mode;
 	enum ad4030_lane_mode lane_mode;
 	enum ad4030_clock_mode clock_mode;
+	bool ddr;
 	/* offload sampling spi message */
 	struct spi_transfer offload_xfer;
 	struct spi_message offload_msg;
@@ -1218,6 +1220,9 @@ static void ad4030_prepare_offload_msg(struct ad4030_state *st)
 	else
 		offload_bpw  = data_width / (1 << st->lane_mode);
 
+	if (st->ddr)
+		offload_bpw  /= 2;
+
 	st->offload_xfer.speed_hz = AD4030_SPI_MAX_REG_XFER_SPEED;
 	st->offload_xfer.bits_per_word = offload_bpw;
 	st->offload_xfer.len = roundup_pow_of_two(BITS_TO_BYTES(offload_bpw));
@@ -1271,6 +1276,12 @@ static int ad4030_config(struct ad4030_state *st)
 	reg_modes |= FIELD_PREP(AD4030_REG_MODES_MASK_CLOCK_MODE,
 				ret >= 0 ? ret : AD4030_SPI_CLOCK_MODE);
 
+	/* DDR is only valid for echo clock and host clock modes */
+	if (ret == AD4030_ECHO_CLOCK_MODE || ret == AD4030_CLOCK_HOST_MODE) {
+		st->ddr = device_property_read_bool(dev, "adi,dual-data-rate");
+		reg_modes |= FIELD_PREP(AD4030_REG_MODES_MASK_DDR_MODE, st->ddr);
+	}
+
 	ret = regmap_write(st->regmap, AD4030_REG_MODES, reg_modes);
 	if (ret)
 		return ret;
-- 
2.39.2
Re: [PATCH 13/15] iio: adc: ad4030: Enable dual data rate
Posted by David Lechner 1 month ago
On 8/29/25 7:45 PM, Marcelo Schmitt wrote:
> Set AD4030 series device to do two data bit transitions per clock cycle per
> active lane when specified by firmware. The dual data rate (DDR) feature is
> available only for host clock mode and echo clock mode.
> 
> Co-developed-by: Sergiu Cuciurean <sergiu.cuciurean@analog.com>
> Signed-off-by: Sergiu Cuciurean <sergiu.cuciurean@analog.com>
> Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
> ---
>  drivers/iio/adc/ad4030.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/drivers/iio/adc/ad4030.c b/drivers/iio/adc/ad4030.c
> index a5931056936a..37ba00097efe 100644
> --- a/drivers/iio/adc/ad4030.c
> +++ b/drivers/iio/adc/ad4030.c
> @@ -74,6 +74,7 @@
>  	(AD4030_REG_GAIN_X0_MSB + (AD4030_REG_GAIN_BYTES_NB * (ch)))
>  #define AD4030_REG_MODES			0x20
>  #define     AD4030_REG_MODES_MASK_OUT_DATA_MODE	GENMASK(2, 0)
> +#define     AD4030_REG_MODES_MASK_DDR_MODE	BIT(3)
>  #define     AD4030_REG_MODES_MASK_CLOCK_MODE	GENMASK(5, 4)
>  #define     AD4030_REG_MODES_MASK_LANE_MODE	GENMASK(7, 6)
>  #define AD4030_REG_OSCILATOR			0x21
> @@ -175,6 +176,7 @@ struct ad4030_state {
>  	enum ad4030_out_mode mode;
>  	enum ad4030_lane_mode lane_mode;
>  	enum ad4030_clock_mode clock_mode;
> +	bool ddr;
>  	/* offload sampling spi message */
>  	struct spi_transfer offload_xfer;
>  	struct spi_message offload_msg;
> @@ -1218,6 +1220,9 @@ static void ad4030_prepare_offload_msg(struct ad4030_state *st)
>  	else
>  		offload_bpw  = data_width / (1 << st->lane_mode);
>  
> +	if (st->ddr)
> +		offload_bpw  /= 2;
> +

There is already an existing dtr_mode flag in struct spi_transfer. We should
be using that instead of providing an inaccurate bits per word value.

>  	st->offload_xfer.speed_hz = AD4030_SPI_MAX_REG_XFER_SPEED;
>  	st->offload_xfer.bits_per_word = offload_bpw;
>  	st->offload_xfer.len = roundup_pow_of_two(BITS_TO_BYTES(offload_bpw));
> @@ -1271,6 +1276,12 @@ static int ad4030_config(struct ad4030_state *st)
>  	reg_modes |= FIELD_PREP(AD4030_REG_MODES_MASK_CLOCK_MODE,
>  				ret >= 0 ? ret : AD4030_SPI_CLOCK_MODE);
>  
> +	/* DDR is only valid for echo clock and host clock modes */
> +	if (ret == AD4030_ECHO_CLOCK_MODE || ret == AD4030_CLOCK_HOST_MODE) {
> +		st->ddr = device_property_read_bool(dev, "adi,dual-data-rate");

As mentioned in the dt-bindings patch review, we can already get this info
from the spi controller via dtr_caps. 

> +		reg_modes |= FIELD_PREP(AD4030_REG_MODES_MASK_DDR_MODE, st->ddr);
> +	}
> +
>  	ret = regmap_write(st->regmap, AD4030_REG_MODES, reg_modes);
>  	if (ret)
>  		return ret;

We will need a separate patch to add support for dtr_caps and dtr_mode to the
axi-spi-engine driver. And likely some HDL work for that as well. So I would
suggest splitting this out into a separate series.
Re: [PATCH 13/15] iio: adc: ad4030: Enable dual data rate
Posted by Andy Shevchenko 1 month ago
On Sat, Aug 30, 2025 at 3:45 AM Marcelo Schmitt
<marcelo.schmitt@analog.com> wrote:
>
> Set AD4030 series device to do two data bit transitions per clock cycle per
> active lane when specified by firmware. The dual data rate (DDR) feature is
> available only for host clock mode and echo clock mode.

...

>  struct ad4030_state {

>         enum ad4030_out_mode mode;
>         enum ad4030_lane_mode lane_mode;
>         enum ad4030_clock_mode clock_mode;
> +       bool ddr;

I believe you run `pahole` each time you modify the data type like this.

>         /* offload sampling spi message */
>         struct spi_transfer offload_xfer;
>         struct spi_message offload_msg;

...

>         else
>                 offload_bpw  = data_width / (1 << st->lane_mode);

With the previous comment WRT right shift...

> +       if (st->ddr)
> +               offload_bpw  /= 2;

...this also can use right shift, but I understand that 2 is more
explicit to show the point of DDR (as "double").

...

> +       /* DDR is only valid for echo clock and host clock modes */
> +       if (ret == AD4030_ECHO_CLOCK_MODE || ret == AD4030_CLOCK_HOST_MODE) {
> +               st->ddr = device_property_read_bool(dev, "adi,dual-data-rate");
> +               reg_modes |= FIELD_PREP(AD4030_REG_MODES_MASK_DDR_MODE, st->ddr);

FIELD_MODIFY()?

> +       }

-- 
With Best Regards,
Andy Shevchenko