* [PATCH v2 0/4] iio: adc: ad7768-1: add SPI offload support and fixes
@ 2026-02-23 11:59 Jonathan Santos
2026-02-23 11:59 ` [PATCH v2 1/4] iio: adc: ad7768-1: fix one-shot mode data acquisition Jonathan Santos
` (4 more replies)
0 siblings, 5 replies; 10+ messages in thread
From: Jonathan Santos @ 2026-02-23 11:59 UTC (permalink / raw)
To: linux-iio, linux-kernel
Cc: Jonathan Santos, lars, Michael.Hennerich, jic23, dlechner,
nuno.sa, andy, jonath4nns
This series adds SPI offload support to the AD7768-1 driver and includes
fixes for one-shot mode operation and IRQ management discovered during
development and testing.
---
Changes in v2:
* Refactor "fix one-shot mode data acquisition" patch and keep it for backporting
to older kernel versions.
* Instead of restricting the one-shot mode for some filter types, remove
it completely and guarantee the device is always in continuous
conversion mode.
* Add "disable IRQ autoenable" patch to fix an old CPU usage issue and to avoid
unnecessary interrupts when buffering data in offload mode.
* Addressed other review comments and kernel test robot reports, see individual patches.
* Link to v1: https://lore.kernel.org/linux-iio/cover.1769889074.git.Jonathan.Santos@analog.com/T/#t/
Jonathan Santos (4):
iio: adc: ad7768-1: fix one-shot mode data acquisition
iio: adc: ad7768-1: remove switch to one-shot mode
iio: adc: ad7768-1: disable IRQ autoenable
iio: adc: ad7768-1: add support for SPI offload
drivers/iio/adc/Kconfig | 2 +
drivers/iio/adc/ad7768-1.c | 220 ++++++++++++++++++++++++++++++++++---
2 files changed, 206 insertions(+), 16 deletions(-)
base-commit: 0713b26190addfa3a774b386c8658952ef9f7faf
--
2.34.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 1/4] iio: adc: ad7768-1: fix one-shot mode data acquisition
2026-02-23 11:59 [PATCH v2 0/4] iio: adc: ad7768-1: add SPI offload support and fixes Jonathan Santos
@ 2026-02-23 11:59 ` Jonathan Santos
2026-02-23 11:59 ` [PATCH v2 2/4] iio: adc: ad7768-1: remove switch to one-shot mode Jonathan Santos
` (3 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Jonathan Santos @ 2026-02-23 11:59 UTC (permalink / raw)
To: linux-iio, linux-kernel
Cc: Jonathan Santos, lars, Michael.Hennerich, jic23, dlechner,
nuno.sa, andy, jonath4nns
According to the datasheet, one-shot mode requires a SYNC_IN pulse to
trigger a new sample conversion. In the current implementation, No sync
pulse was sent after switching to one-shot mode and reinit_completion()
was called before mode switching, creating a race condition where spurious
interrupts during mode change could trigger completion prematurely.
Fix by sending a sync pulse after configuring one-shot mode and
reinit_completion() to ensure it only waits for the actual conversion
completion.
Fixes: a5f8c7da3dbe ("iio: adc: Add AD7768-1 ADC basic support")
Signed-off-by: Jonathan Santos <Jonathan.Santos@analog.com>
---
Changes in v2:
* reinit_completion() is now called before sending the SYNC pulse,
to ensure that the completion is properly reset before waiting
for the conversion to complete.
* Patch kept for backporting, even though superseded by next patch.
---
drivers/iio/adc/ad7768-1.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
index fcd8aea7152e..4cb63ab4768a 100644
--- a/drivers/iio/adc/ad7768-1.c
+++ b/drivers/iio/adc/ad7768-1.c
@@ -463,12 +463,17 @@ static int ad7768_scan_direct(struct iio_dev *indio_dev)
struct ad7768_state *st = iio_priv(indio_dev);
int readval, ret;
- reinit_completion(&st->completion);
-
ret = ad7768_set_mode(st, AD7768_ONE_SHOT);
if (ret < 0)
return ret;
+ reinit_completion(&st->completion);
+
+ /* One-shot mode requires a SYNC pulse to generate a new sample */
+ ret = ad7768_send_sync_pulse(st);
+ if (ret)
+ return ret;
+
ret = wait_for_completion_timeout(&st->completion,
msecs_to_jiffies(1000));
if (!ret)
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 2/4] iio: adc: ad7768-1: remove switch to one-shot mode
2026-02-23 11:59 [PATCH v2 0/4] iio: adc: ad7768-1: add SPI offload support and fixes Jonathan Santos
2026-02-23 11:59 ` [PATCH v2 1/4] iio: adc: ad7768-1: fix one-shot mode data acquisition Jonathan Santos
@ 2026-02-23 11:59 ` Jonathan Santos
2026-02-23 11:59 ` [PATCH v2 3/4] iio: adc: ad7768-1: disable IRQ autoenable Jonathan Santos
` (2 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Jonathan Santos @ 2026-02-23 11:59 UTC (permalink / raw)
To: linux-iio, linux-kernel
Cc: Jonathan Santos, lars, Michael.Hennerich, jic23, dlechner,
nuno.sa, andy, jonath4nns
wideband low ripple FIR Filter is not available in one-shot mode. In
order to make direct reads work for all filter options, remove the
switch for one-shot mode and guarantee device is always in continuous
conversion mode.
Fixes: fb1d3b24ebf5 ("iio: adc: ad7768-1: add filter type and oversampling ratio attributes")
Signed-off-by: Jonathan Santos <Jonathan.Santos@analog.com>
---
* Instead of restricting the one-shot mode for some filter types, remove
it completely and guarantee the device is always in continuous
conversion mode.
---
drivers/iio/adc/ad7768-1.c | 21 ++++-----------------
1 file changed, 4 insertions(+), 17 deletions(-)
diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
index 4cb63ab4768a..a927ae288fbb 100644
--- a/drivers/iio/adc/ad7768-1.c
+++ b/drivers/iio/adc/ad7768-1.c
@@ -463,17 +463,8 @@ static int ad7768_scan_direct(struct iio_dev *indio_dev)
struct ad7768_state *st = iio_priv(indio_dev);
int readval, ret;
- ret = ad7768_set_mode(st, AD7768_ONE_SHOT);
- if (ret < 0)
- return ret;
-
reinit_completion(&st->completion);
- /* One-shot mode requires a SYNC pulse to generate a new sample */
- ret = ad7768_send_sync_pulse(st);
- if (ret)
- return ret;
-
ret = wait_for_completion_timeout(&st->completion,
msecs_to_jiffies(1000));
if (!ret)
@@ -492,14 +483,6 @@ static int ad7768_scan_direct(struct iio_dev *indio_dev)
if (st->oversampling_ratio == 8)
readval >>= 8;
- /*
- * Any SPI configuration of the AD7768-1 can only be
- * performed in continuous conversion mode.
- */
- ret = ad7768_set_mode(st, AD7768_CONTINUOUS);
- if (ret < 0)
- return ret;
-
return readval;
}
@@ -1248,6 +1231,10 @@ static int ad7768_setup(struct iio_dev *indio_dev)
return ret;
}
+ ret = ad7768_set_mode(st, AD7768_CONTINUOUS);
+ if (ret)
+ return ret;
+
/* For backwards compatibility, try the adi,sync-in-gpios property */
st->gpio_sync_in = devm_gpiod_get_optional(&st->spi->dev, "adi,sync-in",
GPIOD_OUT_LOW);
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 3/4] iio: adc: ad7768-1: disable IRQ autoenable
2026-02-23 11:59 [PATCH v2 0/4] iio: adc: ad7768-1: add SPI offload support and fixes Jonathan Santos
2026-02-23 11:59 ` [PATCH v2 1/4] iio: adc: ad7768-1: fix one-shot mode data acquisition Jonathan Santos
2026-02-23 11:59 ` [PATCH v2 2/4] iio: adc: ad7768-1: remove switch to one-shot mode Jonathan Santos
@ 2026-02-23 11:59 ` Jonathan Santos
2026-02-23 11:59 ` [PATCH v2 4/4] iio: adc: ad7768-1: add support for SPI offload Jonathan Santos
2026-02-28 17:19 ` [PATCH v2 0/4] iio: adc: ad7768-1: add SPI offload support and fixes David Lechner
4 siblings, 0 replies; 10+ messages in thread
From: Jonathan Santos @ 2026-02-23 11:59 UTC (permalink / raw)
To: linux-iio, linux-kernel
Cc: Jonathan Santos, lars, Michael.Hennerich, jic23, dlechner,
nuno.sa, andy, jonath4nns
The device continuously converts data while powered up, generating
interrupts in the background. Configure the IRQ to be enabled and
disabled manually as needed to avoid unnecessary CPU load.
Signed-off-by: Jonathan Santos <Jonathan.Santos@analog.com>
---
Changes in v2:
* New patch. It solves the excessive CPU load issue and addresses
David's suggestion of having the interrupt disabled when using
offload.
* This is a reproduction of and old patch sent last year. please refer
to the thread [1].
[1]: https://lore.kernel.org/linux-iio/20250718013307.153281-1-Jonathan.Santos@analog.com/T/#t/
---
drivers/iio/adc/ad7768-1.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
index a927ae288fbb..b77523393a18 100644
--- a/drivers/iio/adc/ad7768-1.c
+++ b/drivers/iio/adc/ad7768-1.c
@@ -464,9 +464,11 @@ static int ad7768_scan_direct(struct iio_dev *indio_dev)
int readval, ret;
reinit_completion(&st->completion);
+ enable_irq(st->spi->irq);
ret = wait_for_completion_timeout(&st->completion,
msecs_to_jiffies(1000));
+ disable_irq(st->spi->irq);
if (!ret)
return -ETIMEDOUT;
@@ -1339,8 +1341,22 @@ static const struct iio_buffer_setup_ops ad7768_buffer_ops = {
.predisable = &ad7768_buffer_predisable,
};
+static int ad7768_set_trigger_state(struct iio_trigger *trig, bool enable)
+{
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+ struct ad7768_state *st = iio_priv(indio_dev);
+
+ if (enable)
+ enable_irq(st->spi->irq);
+ else
+ disable_irq(st->spi->irq);
+
+ return 0;
+}
+
static const struct iio_trigger_ops ad7768_trigger_ops = {
.validate_device = iio_trigger_validate_own_device,
+ .set_trigger_state = ad7768_set_trigger_state,
};
static int ad7768_set_channel_label(struct iio_dev *indio_dev,
@@ -1704,7 +1720,7 @@ static int ad7768_probe(struct spi_device *spi)
return ret;
ret = devm_request_irq(&spi->dev, spi->irq, &ad7768_interrupt,
- IRQF_TRIGGER_RISING | IRQF_NO_THREAD,
+ IRQF_TRIGGER_RISING | IRQF_NO_THREAD | IRQF_NO_AUTOEN,
indio_dev->name, indio_dev);
if (ret)
return ret;
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 4/4] iio: adc: ad7768-1: add support for SPI offload
2026-02-23 11:59 [PATCH v2 0/4] iio: adc: ad7768-1: add SPI offload support and fixes Jonathan Santos
` (2 preceding siblings ...)
2026-02-23 11:59 ` [PATCH v2 3/4] iio: adc: ad7768-1: disable IRQ autoenable Jonathan Santos
@ 2026-02-23 11:59 ` Jonathan Santos
2026-02-23 13:46 ` Andy Shevchenko
2026-02-28 17:18 ` David Lechner
2026-02-28 17:19 ` [PATCH v2 0/4] iio: adc: ad7768-1: add SPI offload support and fixes David Lechner
4 siblings, 2 replies; 10+ messages in thread
From: Jonathan Santos @ 2026-02-23 11:59 UTC (permalink / raw)
To: linux-iio, linux-kernel
Cc: Jonathan Santos, lars, Michael.Hennerich, jic23, dlechner,
nuno.sa, andy, jonath4nns
The AD7768-1 family supports sampling rates up to 1 MSPS, which exceeds
the capabilities of conventional triggered buffer operations due to SPI
transaction overhead and interrupt latency.
Add SPI offload support to enable hardware-accelerated data acquisition
that bypasses software SPI transactions using continuous data streaming.
Signed-off-by: Jonathan Santos <Jonathan.Santos@analog.com>
---
Changes in v2:
* Removed offload_en element in ad7768_state.
* Refactored ad7768_offload_buffer_postenable() to undo continuous read
mode in case something fails afterwards.
* Allow 1 or 2 arguments in the offload trigger, instead of only 1.
* Fixed indentation issues suggested by the Andy.
* Import IIO_DMAENGINE_BUFFER namespace (Reported by kernel test robot).
* Fixed error pointer reported in https://lore.kernel.org/all/202602051234.5gArzLyZ-lkp@intel.com/
It was supposed to return ret instead of the rx_dma pointer.
---
drivers/iio/adc/Kconfig | 2 +
drivers/iio/adc/ad7768-1.c | 186 ++++++++++++++++++++++++++++++++++++-
2 files changed, 185 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 60038ae8dfc4..a1c3226c3631 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -413,8 +413,10 @@ config AD7768_1
select REGMAP_SPI
select RATIONAL
select IIO_BUFFER
+ select IIO_BUFFER_DMAENGINE
select IIO_TRIGGER
select IIO_TRIGGERED_BUFFER
+ select SPI_OFFLOAD
help
Say yes here to build support for Analog Devices AD7768-1 SPI
simultaneously sampling sigma-delta analog to digital converter (ADC).
diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
index b77523393a18..da8b0bbeaec9 100644
--- a/drivers/iio/adc/ad7768-1.c
+++ b/drivers/iio/adc/ad7768-1.c
@@ -25,12 +25,15 @@
#include <linux/regulator/consumer.h>
#include <linux/regulator/driver.h>
#include <linux/sysfs.h>
+#include <linux/spi/offload/consumer.h>
+#include <linux/spi/offload/provider.h>
#include <linux/spi/spi.h>
#include <linux/unaligned.h>
#include <linux/units.h>
#include <linux/util_macros.h>
#include <linux/iio/buffer.h>
+#include <linux/iio/buffer-dmaengine.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
@@ -161,6 +164,8 @@ enum ad7768_filter_regval {
enum ad7768_scan_type {
AD7768_SCAN_TYPE_NORMAL,
AD7768_SCAN_TYPE_HIGH_SPEED,
+ AD7768_SCAN_TYPE_OFFLOAD_NORMAL,
+ AD7768_SCAN_TYPE_OFFLOAD_HIGH_SPEED,
};
enum {
@@ -266,6 +271,18 @@ static const struct iio_scan_type ad7768_scan_type[] = {
.storagebits = 16,
.endianness = IIO_BE,
},
+ [AD7768_SCAN_TYPE_OFFLOAD_NORMAL] = {
+ .sign = 's',
+ .realbits = 24,
+ .storagebits = 32,
+ .endianness = IIO_CPU,
+ },
+ [AD7768_SCAN_TYPE_OFFLOAD_HIGH_SPEED] = {
+ .sign = 's',
+ .realbits = 16,
+ .storagebits = 32,
+ .endianness = IIO_CPU,
+ },
};
struct ad7768_chip_info {
@@ -283,6 +300,8 @@ struct ad7768_chip_info {
struct ad7768_state {
struct spi_device *spi;
+ struct spi_offload *offload;
+ struct spi_offload_trigger *offload_trigger;
struct regmap *regmap;
struct regmap *regmap24;
int vref_uv;
@@ -306,6 +325,8 @@ struct ad7768_state {
struct gpio_desc *gpio_reset;
const char *labels[AD7768_MAX_CHANNELS];
struct gpio_chip gpiochip;
+ struct spi_transfer offload_xfer;
+ struct spi_message offload_msg;
const struct ad7768_chip_info *chip;
bool en_spi_sync;
struct mutex pga_lock; /* protect device internal state (PGA) */
@@ -1119,6 +1140,10 @@ static int ad7768_get_current_scan_type(const struct iio_dev *indio_dev,
{
struct ad7768_state *st = iio_priv(indio_dev);
+ if (st->offload)
+ return st->oversampling_ratio == 8 ?
+ AD7768_SCAN_TYPE_OFFLOAD_HIGH_SPEED : AD7768_SCAN_TYPE_OFFLOAD_NORMAL;
+
return st->oversampling_ratio == 8 ?
AD7768_SCAN_TYPE_HIGH_SPEED : AD7768_SCAN_TYPE_NORMAL;
}
@@ -1341,6 +1366,78 @@ static const struct iio_buffer_setup_ops ad7768_buffer_ops = {
.predisable = &ad7768_buffer_predisable,
};
+static int ad7768_offload_buffer_postenable(struct iio_dev *indio_dev)
+{
+ struct ad7768_state *st = iio_priv(indio_dev);
+ struct spi_offload_trigger_config config = {
+ .type = SPI_OFFLOAD_TRIGGER_DATA_READY,
+ };
+ const struct iio_scan_type *scan_type;
+ unsigned int unused;
+ int ret;
+
+ scan_type = iio_get_current_scan_type(indio_dev, &indio_dev->channels[0]);
+ if (IS_ERR(scan_type))
+ return PTR_ERR(scan_type);
+
+ st->offload_xfer.len = spi_bpw_to_bytes(scan_type->realbits);
+ st->offload_xfer.bits_per_word = scan_type->realbits;
+ st->offload_xfer.offload_flags = SPI_OFFLOAD_XFER_RX_STREAM;
+
+ spi_message_init_with_transfers(&st->offload_msg, &st->offload_xfer, 1);
+ st->offload_msg.offload = st->offload;
+
+ ret = spi_optimize_message(st->spi, &st->offload_msg);
+ if (ret) {
+ dev_err(&st->spi->dev, "failed to prepare offload, err: %d\n", ret);
+ return ret;
+ }
+
+ /*
+ * Write a 1 to the LSB of the INTERFACE_FORMAT register to enter
+ * continuous read mode. Subsequent data reads do not require an
+ * initial 8-bit write to query the ADC_DATA register.
+ */
+ ret = regmap_write(st->regmap, AD7768_REG_INTERFACE_FORMAT, 0x01);
+ if (ret)
+ goto err_unoptimize_message;
+
+ ret = spi_offload_trigger_enable(st->offload, st->offload_trigger,
+ &config);
+ if (ret)
+ goto err_exit_continuous_read_mode;
+
+ return 0;
+
+err_exit_continuous_read_mode:
+ regmap_read(st->regmap24, AD7768_REG24_ADC_DATA, &unused);
+
+err_unoptimize_message:
+ spi_unoptimize_message(&st->offload_msg);
+
+ return ret;
+}
+
+static int ad7768_offload_buffer_predisable(struct iio_dev *indio_dev)
+{
+ struct ad7768_state *st = iio_priv(indio_dev);
+ unsigned int unused;
+
+ spi_offload_trigger_disable(st->offload, st->offload_trigger);
+ spi_unoptimize_message(&st->offload_msg);
+
+ /*
+ * To exit continuous read mode, perform a single read of the ADC_DATA
+ * reg (0x2C), which allows further configuration of the device.
+ */
+ return regmap_read(st->regmap24, AD7768_REG24_ADC_DATA, &unused);
+}
+
+static const struct iio_buffer_setup_ops ad7768_offload_buffer_ops = {
+ .postenable = ad7768_offload_buffer_postenable,
+ .predisable = ad7768_offload_buffer_predisable,
+};
+
static int ad7768_set_trigger_state(struct iio_trigger *trig, bool enable)
{
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
@@ -1589,6 +1686,36 @@ static int ad7768_parse_aaf_gain(struct device *dev, struct ad7768_state *st)
return 0;
}
+static bool ad7768_offload_trigger_match(struct spi_offload_trigger *trigger,
+ enum spi_offload_trigger_type type,
+ u64 *args, u32 nargs)
+{
+ if (type != SPI_OFFLOAD_TRIGGER_DATA_READY)
+ return false;
+
+ /* Requires 1 or 2 args to indicate the trigger output signal */
+ if (nargs == 0 || nargs > 2 || args[0] != AD7768_TRIGGER_SOURCE_DRDY)
+ return false;
+
+ return true;
+}
+
+static int ad7768_offload_trigger_request(struct spi_offload_trigger *trigger,
+ enum spi_offload_trigger_type type,
+ u64 *args, u32 nargs)
+{
+ /* Should already be validated by match, but just in case */
+ if (nargs == 0 || nargs > 2)
+ return -EINVAL;
+
+ return 0;
+}
+
+static const struct spi_offload_trigger_ops ad7768_offload_trigger_ops = {
+ .match = ad7768_offload_trigger_match,
+ .request = ad7768_offload_trigger_request,
+};
+
static const struct ad7768_chip_info ad7768_chip_info = {
.name = "ad7768-1",
.channel_spec = ad7768_channels,
@@ -1626,10 +1753,51 @@ static const struct ad7768_chip_info adaq7769_chip_info = {
.has_variable_aaf = true,
};
+static const struct spi_offload_config ad7768_spi_offload_config = {
+ .capability_flags = SPI_OFFLOAD_CAP_TRIGGER | SPI_OFFLOAD_CAP_RX_STREAM_DMA,
+};
+
+static int ad7768_spi_offload_probe(struct iio_dev *indio_dev,
+ struct ad7768_state *st)
+{
+ struct device *dev = &st->spi->dev;
+ struct spi_offload_trigger_info trigger_info = {
+ .fwnode = dev_fwnode(dev),
+ .ops = &ad7768_offload_trigger_ops,
+ .priv = st,
+ };
+ struct dma_chan *rx_dma;
+ int ret;
+
+ ret = devm_spi_offload_trigger_register(dev, &trigger_info);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register offload trigger\n");
+
+ st->offload_trigger = devm_spi_offload_trigger_get(dev, st->offload,
+ SPI_OFFLOAD_TRIGGER_DATA_READY);
+ if (IS_ERR(st->offload_trigger))
+ return dev_err_probe(dev, PTR_ERR(st->offload_trigger),
+ "failed to get offload trigger\n");
+
+ rx_dma = devm_spi_offload_rx_stream_request_dma_chan(dev, st->offload);
+ if (IS_ERR(rx_dma))
+ 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);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to setup offload RX DMA\n");
+
+ indio_dev->setup_ops = &ad7768_offload_buffer_ops;
+
+ return 0;
+}
+
static int ad7768_probe(struct spi_device *spi)
{
struct ad7768_state *st;
struct iio_dev *indio_dev;
+ struct device *dev = &spi->dev;
int ret;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
@@ -1725,9 +1893,20 @@ static int ad7768_probe(struct spi_device *spi)
if (ret)
return ret;
- ret = ad7768_triggered_buffer_alloc(indio_dev);
- if (ret)
- return ret;
+ st->offload = devm_spi_offload_get(dev, spi, &ad7768_spi_offload_config);
+ ret = PTR_ERR_OR_ZERO(st->offload);
+ if (ret == -ENODEV) {
+ /* If not using SPI offload, fall back to low speed usage */
+ ret = ad7768_triggered_buffer_alloc(indio_dev);
+ if (ret)
+ return ret;
+ } else if (ret) {
+ return dev_err_probe(dev, ret, "failed to get SPI offload\n");
+ } else {
+ ret = ad7768_spi_offload_probe(indio_dev, st);
+ if (ret)
+ return ret;
+ }
return devm_iio_device_register(&spi->dev, indio_dev);
}
@@ -1763,3 +1942,4 @@ module_spi_driver(ad7768_driver);
MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
MODULE_DESCRIPTION("Analog Devices AD7768-1 ADC driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_DMAENGINE_BUFFER");
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2 4/4] iio: adc: ad7768-1: add support for SPI offload
2026-02-23 11:59 ` [PATCH v2 4/4] iio: adc: ad7768-1: add support for SPI offload Jonathan Santos
@ 2026-02-23 13:46 ` Andy Shevchenko
2026-02-28 19:20 ` Jonathan Cameron
2026-02-28 17:18 ` David Lechner
1 sibling, 1 reply; 10+ messages in thread
From: Andy Shevchenko @ 2026-02-23 13:46 UTC (permalink / raw)
To: Jonathan Santos
Cc: linux-iio, linux-kernel, lars, Michael.Hennerich, jic23, dlechner,
nuno.sa, andy, jonath4nns
On Mon, Feb 23, 2026 at 08:59:53AM -0300, Jonathan Santos wrote:
> The AD7768-1 family supports sampling rates up to 1 MSPS, which exceeds
> the capabilities of conventional triggered buffer operations due to SPI
> transaction overhead and interrupt latency.
>
> Add SPI offload support to enable hardware-accelerated data acquisition
> that bypasses software SPI transactions using continuous data streaming.
...
> +static int ad7768_spi_offload_probe(struct iio_dev *indio_dev,
> + struct ad7768_state *st)
> +{
> + struct device *dev = &st->spi->dev;
> + struct spi_offload_trigger_info trigger_info = {
> + .fwnode = dev_fwnode(dev),
> + .ops = &ad7768_offload_trigger_ops,
> + .priv = st,
> + };
> + struct dma_chan *rx_dma;
> + int ret;
> +
> + ret = devm_spi_offload_trigger_register(dev, &trigger_info);
> + if (ret)
> + return dev_err_probe(dev, ret, "failed to register offload trigger\n");
Double space...
(do not resend just for addressing this)
> + st->offload_trigger = devm_spi_offload_trigger_get(dev, st->offload,
> + SPI_OFFLOAD_TRIGGER_DATA_READY);
> + if (IS_ERR(st->offload_trigger))
> + return dev_err_probe(dev, PTR_ERR(st->offload_trigger),
> + "failed to get offload trigger\n");
> +
> + rx_dma = devm_spi_offload_rx_stream_request_dma_chan(dev, st->offload);
> + if (IS_ERR(rx_dma))
> + 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);
> + if (ret)
> + return dev_err_probe(dev, ret, "failed to setup offload RX DMA\n");
> +
> + indio_dev->setup_ops = &ad7768_offload_buffer_ops;
> +
> + return 0;
> +}
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 4/4] iio: adc: ad7768-1: add support for SPI offload
2026-02-23 11:59 ` [PATCH v2 4/4] iio: adc: ad7768-1: add support for SPI offload Jonathan Santos
2026-02-23 13:46 ` Andy Shevchenko
@ 2026-02-28 17:18 ` David Lechner
2026-03-01 12:10 ` Jonathan Cameron
1 sibling, 1 reply; 10+ messages in thread
From: David Lechner @ 2026-02-28 17:18 UTC (permalink / raw)
To: Jonathan Santos, linux-iio, linux-kernel
Cc: lars, Michael.Hennerich, jic23, nuno.sa, andy, jonath4nns
On 2/23/26 5:59 AM, Jonathan Santos wrote:
> The AD7768-1 family supports sampling rates up to 1 MSPS, which exceeds
> the capabilities of conventional triggered buffer operations due to SPI
> transaction overhead and interrupt latency.
>
...
> +static int ad7768_offload_buffer_postenable(struct iio_dev *indio_dev)
> +{
> + struct ad7768_state *st = iio_priv(indio_dev);
> + struct spi_offload_trigger_config config = {
> + .type = SPI_OFFLOAD_TRIGGER_DATA_READY,
> + };
> + const struct iio_scan_type *scan_type;
> + unsigned int unused;
> + int ret;
> +
> + scan_type = iio_get_current_scan_type(indio_dev, &indio_dev->channels[0]);
> + if (IS_ERR(scan_type))
> + return PTR_ERR(scan_type);
> +
> + st->offload_xfer.len = spi_bpw_to_bytes(scan_type->realbits);
> + st->offload_xfer.bits_per_word = scan_type->realbits;
> + st->offload_xfer.offload_flags = SPI_OFFLOAD_XFER_RX_STREAM;
> +
> + spi_message_init_with_transfers(&st->offload_msg, &st->offload_xfer, 1);
> + st->offload_msg.offload = st->offload;
> +
> + ret = spi_optimize_message(st->spi, &st->offload_msg);
> + if (ret) {
> + dev_err(&st->spi->dev, "failed to prepare offload, err: %d\n", ret);
> + return ret;
> + }
> +
> + /*
> + * Write a 1 to the LSB of the INTERFACE_FORMAT register to enter
> + * continuous read mode. Subsequent data reads do not require an
> + * initial 8-bit write to query the ADC_DATA register.
> + */
> + ret = regmap_write(st->regmap, AD7768_REG_INTERFACE_FORMAT, 0x01);
> + if (ret)
> + goto err_unoptimize_message;
> +
> + ret = spi_offload_trigger_enable(st->offload, st->offload_trigger,
> + &config);
> + if (ret)
> + goto err_exit_continuous_read_mode;
> +
> + return 0;
> +
> +err_exit_continuous_read_mode:
I wouldn't mind a comment here explaining what this read does.
> + regmap_read(st->regmap24, AD7768_REG24_ADC_DATA, &unused);
> +
> +err_unoptimize_message:
> + spi_unoptimize_message(&st->offload_msg);
> +
> + return ret;
> +}
...
> +static bool ad7768_offload_trigger_match(struct spi_offload_trigger *trigger,
> + enum spi_offload_trigger_type type,
> + u64 *args, u32 nargs)
> +{
> + if (type != SPI_OFFLOAD_TRIGGER_DATA_READY)
> + return false;
> +
> + /* Requires 1 or 2 args to indicate the trigger output signal */
Would be more clear to say "up to 2 args are allowed, but only 1 is used".
> + if (nargs == 0 || nargs > 2 || args[0] != AD7768_TRIGGER_SOURCE_DRDY)
> + return false;
> +
> + return true;
> +}
> +
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 0/4] iio: adc: ad7768-1: add SPI offload support and fixes
2026-02-23 11:59 [PATCH v2 0/4] iio: adc: ad7768-1: add SPI offload support and fixes Jonathan Santos
` (3 preceding siblings ...)
2026-02-23 11:59 ` [PATCH v2 4/4] iio: adc: ad7768-1: add support for SPI offload Jonathan Santos
@ 2026-02-28 17:19 ` David Lechner
4 siblings, 0 replies; 10+ messages in thread
From: David Lechner @ 2026-02-28 17:19 UTC (permalink / raw)
To: Jonathan Santos, linux-iio, linux-kernel
Cc: lars, Michael.Hennerich, jic23, nuno.sa, andy, jonath4nns
On 2/23/26 5:59 AM, Jonathan Santos wrote:
> This series adds SPI offload support to the AD7768-1 driver and includes
> fixes for one-shot mode operation and IRQ management discovered during
> development and testing.
>
Reviewed-by: David Lechner <dlechner@baylibre.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 4/4] iio: adc: ad7768-1: add support for SPI offload
2026-02-23 13:46 ` Andy Shevchenko
@ 2026-02-28 19:20 ` Jonathan Cameron
0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2026-02-28 19:20 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Jonathan Santos, linux-iio, linux-kernel, lars, Michael.Hennerich,
dlechner, nuno.sa, andy, jonath4nns
On Mon, 23 Feb 2026 15:46:24 +0200
Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> On Mon, Feb 23, 2026 at 08:59:53AM -0300, Jonathan Santos wrote:
> > The AD7768-1 family supports sampling rates up to 1 MSPS, which exceeds
> > the capabilities of conventional triggered buffer operations due to SPI
> > transaction overhead and interrupt latency.
> >
> > Add SPI offload support to enable hardware-accelerated data acquisition
> > that bypasses software SPI transactions using continuous data streaming.
>
> ...
>
> > +static int ad7768_spi_offload_probe(struct iio_dev *indio_dev,
> > + struct ad7768_state *st)
> > +{
> > + struct device *dev = &st->spi->dev;
> > + struct spi_offload_trigger_info trigger_info = {
> > + .fwnode = dev_fwnode(dev),
> > + .ops = &ad7768_offload_trigger_ops,
> > + .priv = st,
> > + };
> > + struct dma_chan *rx_dma;
> > + int ret;
> > +
> > + ret = devm_spi_offload_trigger_register(dev, &trigger_info);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "failed to register offload trigger\n");
>
> Double space...
> (do not resend just for addressing this)
Tidied up.
Series applied to the togreg branch of iio.git and for now pushed out as testing
Thanks!
Jonathan
>
> > + st->offload_trigger = devm_spi_offload_trigger_get(dev, st->offload,
> > + SPI_OFFLOAD_TRIGGER_DATA_READY);
> > + if (IS_ERR(st->offload_trigger))
> > + return dev_err_probe(dev, PTR_ERR(st->offload_trigger),
> > + "failed to get offload trigger\n");
> > +
> > + rx_dma = devm_spi_offload_rx_stream_request_dma_chan(dev, st->offload);
> > + if (IS_ERR(rx_dma))
> > + 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);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "failed to setup offload RX DMA\n");
> > +
> > + indio_dev->setup_ops = &ad7768_offload_buffer_ops;
> > +
> > + return 0;
> > +}
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 4/4] iio: adc: ad7768-1: add support for SPI offload
2026-02-28 17:18 ` David Lechner
@ 2026-03-01 12:10 ` Jonathan Cameron
0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2026-03-01 12:10 UTC (permalink / raw)
To: David Lechner
Cc: Jonathan Santos, linux-iio, linux-kernel, lars, Michael.Hennerich,
nuno.sa, andy, jonath4nns
On Sat, 28 Feb 2026 11:18:22 -0600
David Lechner <dlechner@baylibre.com> wrote:
> On 2/23/26 5:59 AM, Jonathan Santos wrote:
> > The AD7768-1 family supports sampling rates up to 1 MSPS, which exceeds
> > the capabilities of conventional triggered buffer operations due to SPI
> > transaction overhead and interrupt latency.
> >
>
> ...
>
> > +static int ad7768_offload_buffer_postenable(struct iio_dev *indio_dev)
> > +{
> > + struct ad7768_state *st = iio_priv(indio_dev);
> > + struct spi_offload_trigger_config config = {
> > + .type = SPI_OFFLOAD_TRIGGER_DATA_READY,
> > + };
> > + const struct iio_scan_type *scan_type;
> > + unsigned int unused;
> > + int ret;
> > +
> > + scan_type = iio_get_current_scan_type(indio_dev, &indio_dev->channels[0]);
> > + if (IS_ERR(scan_type))
> > + return PTR_ERR(scan_type);
> > +
> > + st->offload_xfer.len = spi_bpw_to_bytes(scan_type->realbits);
> > + st->offload_xfer.bits_per_word = scan_type->realbits;
> > + st->offload_xfer.offload_flags = SPI_OFFLOAD_XFER_RX_STREAM;
> > +
> > + spi_message_init_with_transfers(&st->offload_msg, &st->offload_xfer, 1);
> > + st->offload_msg.offload = st->offload;
> > +
> > + ret = spi_optimize_message(st->spi, &st->offload_msg);
> > + if (ret) {
> > + dev_err(&st->spi->dev, "failed to prepare offload, err: %d\n", ret);
> > + return ret;
> > + }
> > +
> > + /*
> > + * Write a 1 to the LSB of the INTERFACE_FORMAT register to enter
> > + * continuous read mode. Subsequent data reads do not require an
> > + * initial 8-bit write to query the ADC_DATA register.
> > + */
> > + ret = regmap_write(st->regmap, AD7768_REG_INTERFACE_FORMAT, 0x01);
> > + if (ret)
> > + goto err_unoptimize_message;
> > +
> > + ret = spi_offload_trigger_enable(st->offload, st->offload_trigger,
> > + &config);
> > + if (ret)
> > + goto err_exit_continuous_read_mode;
> > +
> > + return 0;
> > +
> > +err_exit_continuous_read_mode:
>
> I wouldn't mind a comment here explaining what this read does.
Given I'm not sure, Jonathan, can we have such a comment as a follow up patch please.
>
> > + regmap_read(st->regmap24, AD7768_REG24_ADC_DATA, &unused);
> > +
> > +err_unoptimize_message:
> > + spi_unoptimize_message(&st->offload_msg);
> > +
> > + return ret;
> > +}
>
> ...
>
> > +static bool ad7768_offload_trigger_match(struct spi_offload_trigger *trigger,
> > + enum spi_offload_trigger_type type,
> > + u64 *args, u32 nargs)
> > +{
> > + if (type != SPI_OFFLOAD_TRIGGER_DATA_READY)
> > + return false;
> > +
> > + /* Requires 1 or 2 args to indicate the trigger output signal */
>
> Would be more clear to say "up to 2 args are allowed, but only 1 is used".
I tweaked this.
>
> > + if (nargs == 0 || nargs > 2 || args[0] != AD7768_TRIGGER_SOURCE_DRDY)
> > + return false;
> > +
> > + return true;
> > +}
> > +
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-03-01 12:10 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-23 11:59 [PATCH v2 0/4] iio: adc: ad7768-1: add SPI offload support and fixes Jonathan Santos
2026-02-23 11:59 ` [PATCH v2 1/4] iio: adc: ad7768-1: fix one-shot mode data acquisition Jonathan Santos
2026-02-23 11:59 ` [PATCH v2 2/4] iio: adc: ad7768-1: remove switch to one-shot mode Jonathan Santos
2026-02-23 11:59 ` [PATCH v2 3/4] iio: adc: ad7768-1: disable IRQ autoenable Jonathan Santos
2026-02-23 11:59 ` [PATCH v2 4/4] iio: adc: ad7768-1: add support for SPI offload Jonathan Santos
2026-02-23 13:46 ` Andy Shevchenko
2026-02-28 19:20 ` Jonathan Cameron
2026-02-28 17:18 ` David Lechner
2026-03-01 12:10 ` Jonathan Cameron
2026-02-28 17:19 ` [PATCH v2 0/4] iio: adc: ad7768-1: add SPI offload support and fixes David Lechner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox