[RFC PATCH v3 3/5] iio: buffer: Extend DMAengine buffer interfaces to take extra sysfs attributes

From: Marcelo Schmitt

Date: Tue Jun 16 2026 - 22:04:20 EST


Some devices using DMAengine buffers are connected to extra hardware that
allows setting how fast data is transferred to/from the buffer. However,
those extra pieces of harwdware are external to the sensor chip such that
supporting the transfer speed as a sensor property is a bit of an
inaccuracy. Expand IIO DMAengine buffer interfaces to take arguments for
extra sysfs attributes, enabling the transfer speed to be configured
through the buffer interface.

Signed-off-by: Marcelo Schmitt <marcelo.schmitt@xxxxxxxxxx>
---
New patch.

Now that I've come to this buffer "solution", I have pretty much convinced
myself it would be better to instead have some sort of IIO trigger to control
the signal source connected to SPI offloading trigger module.

drivers/iio/adc/ad4000.c | 3 ++-
drivers/iio/adc/ad4030.c | 3 ++-
drivers/iio/adc/ad4691.c | 3 ++-
drivers/iio/adc/ad4695.c | 2 +-
drivers/iio/adc/ad7380.c | 2 +-
drivers/iio/adc/ad7606_spi.c | 2 +-
drivers/iio/adc/ad7768-1.c | 3 ++-
drivers/iio/adc/ad7944.c | 2 +-
drivers/iio/adc/ad_sigma_delta.c | 2 +-
.../buffer/industrialio-buffer-dmaengine.c | 19 ++++++++++++-------
drivers/iio/dac/ad5791.c | 2 +-
drivers/iio/dac/ad8460.c | 2 +-
drivers/iio/dac/adi-axi-dac.c | 2 +-
include/linux/iio/buffer-dmaengine.h | 16 ++++++++++------
14 files changed, 38 insertions(+), 25 deletions(-)

diff --git a/drivers/iio/adc/ad4000.c b/drivers/iio/adc/ad4000.c
index fd3d79fca785..b79b627310af 100644
--- a/drivers/iio/adc/ad4000.c
+++ b/drivers/iio/adc/ad4000.c
@@ -871,7 +871,8 @@ static int ad4000_spi_offload_setup(struct iio_dev *indio_dev,
"Failed to get offload RX DMA\n");

ret = devm_iio_dmaengine_buffer_setup_with_handle(dev, indio_dev, rx_dma,
- IIO_BUFFER_DIRECTION_IN);
+ IIO_BUFFER_DIRECTION_IN,
+ NULL);
if (ret)
return dev_err_probe(dev, ret, "Failed to setup DMA buffer\n");

diff --git a/drivers/iio/adc/ad4030.c b/drivers/iio/adc/ad4030.c
index 9c5f19321e3b..713fe95176c0 100644
--- a/drivers/iio/adc/ad4030.c
+++ b/drivers/iio/adc/ad4030.c
@@ -1400,7 +1400,8 @@ static int ad4030_spi_offload_setup(struct iio_dev *indio_dev,
"failed to get offload RX DMA\n");

return devm_iio_dmaengine_buffer_setup_with_handle(dev, indio_dev, rx_dma,
- IIO_BUFFER_DIRECTION_IN);
+ IIO_BUFFER_DIRECTION_IN,
+ NULL);
}

static int ad4030_setup_pga(struct device *dev, struct iio_dev *indio_dev,
diff --git a/drivers/iio/adc/ad4691.c b/drivers/iio/adc/ad4691.c
index 548678adc2a4..9845fe9c4725 100644
--- a/drivers/iio/adc/ad4691.c
+++ b/drivers/iio/adc/ad4691.c
@@ -1980,7 +1980,8 @@ static int ad4691_setup_offload(struct iio_dev *indio_dev,
indio_dev->setup_ops = &ad4691_cnv_burst_offload_buffer_setup_ops;

ret = devm_iio_dmaengine_buffer_setup_with_handle(dev, indio_dev, rx_dma,
- IIO_BUFFER_DIRECTION_IN);
+ IIO_BUFFER_DIRECTION_IN,
+ NULL);
if (ret)
return ret;

diff --git a/drivers/iio/adc/ad4695.c b/drivers/iio/adc/ad4695.c
index 53642de7330d..78faeade19f5 100644
--- a/drivers/iio/adc/ad4695.c
+++ b/drivers/iio/adc/ad4695.c
@@ -1779,7 +1779,7 @@ static int ad4695_probe_spi_offload(struct iio_dev *indio_dev,
}

return devm_iio_dmaengine_buffer_setup_with_handle(dev, indio_dev,
- rx_dma, IIO_BUFFER_DIRECTION_IN);
+ rx_dma, IIO_BUFFER_DIRECTION_IN, NULL);
}

static const struct spi_offload_config ad4695_spi_offload_config = {
diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c
index 9f77990a03f9..415b8e1be920 100644
--- a/drivers/iio/adc/ad7380.c
+++ b/drivers/iio/adc/ad7380.c
@@ -1874,7 +1874,7 @@ static int ad7380_probe_spi_offload(struct iio_dev *indio_dev,
"failed to get offload RX DMA\n");

ret = devm_iio_dmaengine_buffer_setup_with_handle(dev, indio_dev,
- rx_dma, IIO_BUFFER_DIRECTION_IN);
+ rx_dma, IIO_BUFFER_DIRECTION_IN, NULL);
if (ret)
return dev_err_probe(dev, ret, "cannot setup dma buffer\n");

diff --git a/drivers/iio/adc/ad7606_spi.c b/drivers/iio/adc/ad7606_spi.c
index 7e17ccbcedd0..760b54bfe208 100644
--- a/drivers/iio/adc/ad7606_spi.c
+++ b/drivers/iio/adc/ad7606_spi.c
@@ -317,7 +317,7 @@ static int ad7606_spi_offload_probe(struct device *dev,
"failed to get offload RX DMA\n");

ret = devm_iio_dmaengine_buffer_setup_with_handle(dev, indio_dev,
- rx_dma, IIO_BUFFER_DIRECTION_IN);
+ rx_dma, IIO_BUFFER_DIRECTION_IN, NULL);
if (ret)
return dev_err_probe(dev, ret,
"failed to setup offload RX DMA\n");
diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
index 598936e47fd2..a13ac31281d8 100644
--- a/drivers/iio/adc/ad7768-1.c
+++ b/drivers/iio/adc/ad7768-1.c
@@ -1792,7 +1792,8 @@ static int ad7768_spi_offload_probe(struct iio_dev *indio_dev,
return dev_err_probe(dev, PTR_ERR(rx_dma), "failed to get offload RX DMA\n");

ret = devm_iio_dmaengine_buffer_setup_with_handle(dev, indio_dev, rx_dma,
- IIO_BUFFER_DIRECTION_IN);
+ IIO_BUFFER_DIRECTION_IN,
+ NULL);
if (ret)
return dev_err_probe(dev, ret, "failed to setup offload RX DMA\n");

diff --git a/drivers/iio/adc/ad7944.c b/drivers/iio/adc/ad7944.c
index 7722cf9e8214..63852a6c2acc 100644
--- a/drivers/iio/adc/ad7944.c
+++ b/drivers/iio/adc/ad7944.c
@@ -843,7 +843,7 @@ static int ad7944_probe(struct spi_device *spi)
*/

ret = devm_iio_dmaengine_buffer_setup_with_handle(dev,
- indio_dev, rx_dma, IIO_BUFFER_DIRECTION_IN);
+ indio_dev, rx_dma, IIO_BUFFER_DIRECTION_IN, NULL);
if (ret)
return ret;

diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
index a955556f9ec8..4b88e1c72c87 100644
--- a/drivers/iio/adc/ad_sigma_delta.c
+++ b/drivers/iio/adc/ad_sigma_delta.c
@@ -820,7 +820,7 @@ int devm_ad_sd_setup_buffer_and_trigger(struct device *dev, struct iio_dev *indi
"Failed to get RX DMA channel\n");

ret = devm_iio_dmaengine_buffer_setup_with_handle(dev, indio_dev,
- rx_dma, IIO_BUFFER_DIRECTION_IN);
+ rx_dma, IIO_BUFFER_DIRECTION_IN, NULL);
if (ret)
return dev_err_probe(dev, ret, "Cannot setup DMA buffer\n");

diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c
index 98acce909854..343dbb6d1446 100644
--- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c
+++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c
@@ -289,7 +289,8 @@ EXPORT_SYMBOL_NS_GPL(iio_dmaengine_buffer_teardown, "IIO_DMAENGINE_BUFFER");
static struct iio_buffer
*__iio_dmaengine_buffer_setup_ext(struct iio_dev *indio_dev,
struct dma_chan *chan,
- enum iio_buffer_direction dir)
+ enum iio_buffer_direction dir,
+ const struct iio_dev_attr **buffer_attrs)
{
struct iio_buffer *buffer;
int ret;
@@ -301,6 +302,7 @@ static struct iio_buffer
indio_dev->modes |= INDIO_BUFFER_HARDWARE;

buffer->direction = dir;
+ buffer->attrs = buffer_attrs;

ret = iio_device_attach_buffer(indio_dev, buffer);
if (ret) {
@@ -329,7 +331,8 @@ static struct iio_buffer
struct iio_buffer *iio_dmaengine_buffer_setup_ext(struct device *dev,
struct iio_dev *indio_dev,
const char *channel,
- enum iio_buffer_direction dir)
+ enum iio_buffer_direction dir,
+ const struct iio_dev_attr **buffer_attrs)
{
struct dma_chan *chan;
struct iio_buffer *buffer;
@@ -338,7 +341,7 @@ struct iio_buffer *iio_dmaengine_buffer_setup_ext(struct device *dev,
if (IS_ERR(chan))
return ERR_CAST(chan);

- buffer = __iio_dmaengine_buffer_setup_ext(indio_dev, chan, dir);
+ buffer = __iio_dmaengine_buffer_setup_ext(indio_dev, chan, dir, buffer_attrs);
if (IS_ERR(buffer))
dma_release_channel(chan);

@@ -366,11 +369,12 @@ static void devm_iio_dmaengine_buffer_teardown(void *buffer)
int devm_iio_dmaengine_buffer_setup_ext(struct device *dev,
struct iio_dev *indio_dev,
const char *channel,
- enum iio_buffer_direction dir)
+ enum iio_buffer_direction dir,
+ const struct iio_dev_attr **buffer_attrs)
{
struct iio_buffer *buffer;

- buffer = iio_dmaengine_buffer_setup_ext(dev, indio_dev, channel, dir);
+ buffer = iio_dmaengine_buffer_setup_ext(dev, indio_dev, channel, dir, buffer_attrs);
if (IS_ERR(buffer))
return PTR_ERR(buffer);

@@ -403,11 +407,12 @@ static void devm_iio_dmaengine_buffer_free(void *buffer)
int devm_iio_dmaengine_buffer_setup_with_handle(struct device *dev,
struct iio_dev *indio_dev,
struct dma_chan *chan,
- enum iio_buffer_direction dir)
+ enum iio_buffer_direction dir,
+ const struct iio_dev_attr **buffer_attrs)
{
struct iio_buffer *buffer;

- buffer = __iio_dmaengine_buffer_setup_ext(indio_dev, chan, dir);
+ buffer = __iio_dmaengine_buffer_setup_ext(indio_dev, chan, dir, buffer_attrs);
if (IS_ERR(buffer))
return PTR_ERR(buffer);

diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c
index ae7297f08398..024607adb915 100644
--- a/drivers/iio/dac/ad5791.c
+++ b/drivers/iio/dac/ad5791.c
@@ -448,7 +448,7 @@ static int ad5791_offload_setup(struct iio_dev *indio_dev)
"failed to get offload TX DMA\n");

ret = devm_iio_dmaengine_buffer_setup_with_handle(&spi->dev,
- indio_dev, tx_dma, IIO_BUFFER_DIRECTION_OUT);
+ indio_dev, tx_dma, IIO_BUFFER_DIRECTION_OUT, NULL);
if (ret)
return ret;

diff --git a/drivers/iio/dac/ad8460.c b/drivers/iio/dac/ad8460.c
index 6e45686902dd..3c5fd71d5add 100644
--- a/drivers/iio/dac/ad8460.c
+++ b/drivers/iio/dac/ad8460.c
@@ -921,7 +921,7 @@ static int ad8460_probe(struct spi_device *spi)
indio_dev->setup_ops = &ad8460_buffer_setup_ops;

ret = devm_iio_dmaengine_buffer_setup_ext(dev, indio_dev, "tx",
- IIO_BUFFER_DIRECTION_OUT);
+ IIO_BUFFER_DIRECTION_OUT, NULL);
if (ret)
return dev_err_probe(dev, ret,
"Failed to get DMA buffer\n");
diff --git a/drivers/iio/dac/adi-axi-dac.c b/drivers/iio/dac/adi-axi-dac.c
index 451fad34e7ee..23028a92ceba 100644
--- a/drivers/iio/dac/adi-axi-dac.c
+++ b/drivers/iio/dac/adi-axi-dac.c
@@ -162,7 +162,7 @@ static struct iio_buffer *axi_dac_request_buffer(struct iio_backend *back,
dma_name = "tx";

return iio_dmaengine_buffer_setup_ext(st->dev, indio_dev, dma_name,
- IIO_BUFFER_DIRECTION_OUT);
+ IIO_BUFFER_DIRECTION_OUT, NULL);
}

static void axi_dac_free_buffer(struct iio_backend *back,
diff --git a/include/linux/iio/buffer-dmaengine.h b/include/linux/iio/buffer-dmaengine.h
index 37f27545f69f..bb7a348db72d 100644
--- a/include/linux/iio/buffer-dmaengine.h
+++ b/include/linux/iio/buffer-dmaengine.h
@@ -10,6 +10,7 @@
#include <linux/iio/buffer.h>

struct iio_dev;
+struct iio_dev_attr;
struct device;
struct dma_chan;

@@ -17,23 +18,26 @@ void iio_dmaengine_buffer_teardown(struct iio_buffer *buffer);
struct iio_buffer *iio_dmaengine_buffer_setup_ext(struct device *dev,
struct iio_dev *indio_dev,
const char *channel,
- enum iio_buffer_direction dir);
+ enum iio_buffer_direction dir,
+ const struct iio_dev_attr **buffer_attrs);

#define iio_dmaengine_buffer_setup(dev, indio_dev, channel) \
- iio_dmaengine_buffer_setup_ext(dev, indio_dev, channel, \
- IIO_BUFFER_DIRECTION_IN)
+ iio_dmaengine_buffer_setup_ext(dev, indio_dev, channel, \
+ IIO_BUFFER_DIRECTION_IN, NULL)

int devm_iio_dmaengine_buffer_setup_ext(struct device *dev,
struct iio_dev *indio_dev,
const char *channel,
- enum iio_buffer_direction dir);
+ enum iio_buffer_direction dir,
+ const struct iio_dev_attr **buffer_attrs);
int devm_iio_dmaengine_buffer_setup_with_handle(struct device *dev,
struct iio_dev *indio_dev,
struct dma_chan *chan,
- enum iio_buffer_direction dir);
+ enum iio_buffer_direction dir,
+ const struct iio_dev_attr **buffer_attrs);

#define devm_iio_dmaengine_buffer_setup(dev, indio_dev, channel) \
devm_iio_dmaengine_buffer_setup_ext(dev, indio_dev, channel, \
- IIO_BUFFER_DIRECTION_IN)
+ IIO_BUFFER_DIRECTION_IN, NULL)

#endif
--
2.53.0