* [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 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-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 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
* 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
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