{"id":2219549,"url":"http://patchwork.ozlabs.org/api/1.0/covers/2219549/?format=json","project":{"id":42,"url":"http://patchwork.ozlabs.org/api/1.0/projects/42/?format=json","name":"Linux GPIO development","link_name":"linux-gpio","list_id":"linux-gpio.vger.kernel.org","list_email":"linux-gpio@vger.kernel.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20260403-ad4692-multichannel-sar-adc-driver-v6-0-fa2a01a57c4e@analog.com>","date":"2026-04-03T11:03:01","name":"[v6,0/4] iio: adc: ad4691: add driver for AD4691 multichannel SAR ADC family","submitter":{"id":92791,"url":"http://patchwork.ozlabs.org/api/1.0/people/92791/?format=json","name":"Radu Sabau via B4 Relay","email":"devnull+radu.sabau.analog.com@kernel.org"},"series":[{"id":498617,"url":"http://patchwork.ozlabs.org/api/1.0/series/498617/?format=json","date":"2026-04-03T11:03:02","name":"iio: adc: ad4691: add driver for AD4691 multichannel SAR ADC family","version":6,"mbox":"http://patchwork.ozlabs.org/series/498617/mbox/"}],"headers":{"Return-Path":"\n <linux-gpio+bounces-34633-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-gpio@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=DGRY/D5+;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=linux-gpio+bounces-34633-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=\"DGRY/D5+\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=10.30.226.201"],"Received":["from tor.lore.kernel.org (tor.lore.kernel.org\n [IPv6:2600:3c04:e001:36c::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fnG6Y44jsz1yCt\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 03 Apr 2026 22:03:17 +1100 (AEDT)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id D3ABD3021992\n\tfor <incoming@patchwork.ozlabs.org>; Fri,  3 Apr 2026 11:03:10 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 538B93AEF46;\n\tFri,  3 Apr 2026 11:03:08 +0000 (UTC)","from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org\n [10.30.226.201])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id F2A9137CD3A;\n\tFri,  3 Apr 2026 11:03:07 +0000 (UTC)","by smtp.kernel.org (Postfix) with ESMTPS id 878A7C4CEF7;\n\tFri,  3 Apr 2026 11:03:07 +0000 (UTC)","from aws-us-west-2-korg-lkml-1.web.codeaurora.org\n (localhost.localdomain [127.0.0.1])\n\tby smtp.lore.kernel.org (Postfix) with ESMTP id 701E5E7E370;\n\tFri,  3 Apr 2026 11:03:07 +0000 (UTC)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1775214188; cv=none;\n b=NKbbKlnyecNOHH1p2xJqeVtY019iddX2/alakY3xnsRw2L7AZD8dsY92qrdKmzV4oPSSV8/pCmkD9iRT7wZN0iLZ2ebY6dp48YqxJ9v1/qVVBhiiM+3fJAUKfAbLH8ZM5LjH7Mgk+PJbM1IJJC4lAvckG8j2Wq5QoPtyzkvw7rQ=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1775214188; c=relaxed/simple;\n\tbh=e8UCeVlyE7LiPTUQG7GWYv5hsUN5zhmvmrFc6kisRRg=;\n\th=From:Subject:Date:Message-Id:MIME-Version:Content-Type:To:Cc;\n b=iMViMwPVJwo7G2N9K52PXEPpJraeEwrZBkOFaeAeh+/ue2yllUb02efrc06BKT5yYBNQRygBm3TdPWmNNee7r8SuOh0lMdhWXO4zpncYjYjhIjj6jRaGIDgZQj5PqOrJDU7mbIPygmZrpP85bIhOvItyBKO0bRS+O7fFfc6iFDk=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=DGRY/D5+; arc=none smtp.client-ip=10.30.226.201","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;\n\ts=k20201202; t=1775214187;\n\tbh=e8UCeVlyE7LiPTUQG7GWYv5hsUN5zhmvmrFc6kisRRg=;\n\th=From:Subject:Date:To:Cc:Reply-To:From;\n\tb=DGRY/D5+l/D1FvlBzaQpn4+1oDbTXs8ArT6B9TaEmhaXx5+ikP0KYOy2GqsP/LAiz\n\t TZCpRD9sempIlhAHMcOHHhTqaHTw6C66R5KSxcGzP7qsmV70DcWxPKFboUaEBo+aja\n\t 9md+Kx7tFaFhbDbzObC0YS5MKz394uBlgmGAoWocZNewAGGEivGuM9Tpk5tvo2XpzE\n\t t7fIMk0alcJIey9PbKtVHvwLQ2QHQXevEg4K7M4NSDPM+XKbe3a6i/8YxI3mKPY6M3\n\t YP308kQL/YKESxEIux0Xnd+f4Rn19eHftVWEvUrXvTFlGlr1HotZkhKPDbYVDe3bQY\n\t SCyvu8mbg/jzw==","From":"Radu Sabau via B4 Relay <devnull+radu.sabau.analog.com@kernel.org>","Subject":"[PATCH v6 0/4] iio: adc: ad4691: add driver for AD4691\n multichannel SAR ADC family","Date":"Fri, 03 Apr 2026 14:03:01 +0300","Message-Id":"\n <20260403-ad4692-multichannel-sar-adc-driver-v6-0-fa2a01a57c4e@analog.com>","Precedence":"bulk","X-Mailing-List":"linux-gpio@vger.kernel.org","List-Id":"<linux-gpio.vger.kernel.org>","List-Subscribe":"<mailto:linux-gpio+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-gpio+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"8bit","X-B4-Tracking":"v=1; b=H4sIAGaez2kC/43OTWrDMBAF4KsErauiGUmW3FXvUbLQzyQROHaQU\n pESfPfKgYKLN2ZW7zF8M09WKCcq7OPwZJlqKmkaW+jeDixc3HgmnmLLDAV2QgrkLqquR379Hu5\n p2Rhp4MXl1gcec6qUubGkolIRlUfWoFumU3q8jnwdW76kcp/yz+tmhaX94/UevgIXXMoOsXc2h\n mA+3eiG6fwepitb/IorE8QuE5sZe++tI68JtqZcm3KXKZvpVQQVLTiwsDHVysR9f6pmCo0BhG5\n j3MbUa9PsMnUzAU7G9pGU8fafOc/zL3WTeSwlAgAA","X-Change-ID":"20260302-ad4692-multichannel-sar-adc-driver-78e4d44d24b2","To":"Lars-Peter Clausen <lars@metafoo.de>,\n  Michael Hennerich <Michael.Hennerich@analog.com>,\n  Jonathan Cameron <jic23@kernel.org>, David Lechner <dlechner@baylibre.com>,\n\t=?utf-8?q?Nuno_S=C3=A1?= <nuno.sa@analog.com>,\n  Andy Shevchenko <andy@kernel.org>, Rob Herring <robh@kernel.org>,\n  Krzysztof Kozlowski <krzk+dt@kernel.org>,\n  Conor Dooley <conor+dt@kernel.org>,\n =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= <ukleinek@kernel.org>,\n  Liam Girdwood <lgirdwood@gmail.com>, Mark Brown <broonie@kernel.org>,\n  Linus Walleij <linusw@kernel.org>, Bartosz Golaszewski <brgl@kernel.org>,\n  Philipp Zabel <p.zabel@pengutronix.de>, Jonathan Corbet <corbet@lwn.net>,\n  Shuah Khan <skhan@linuxfoundation.org>","Cc":"linux-iio@vger.kernel.org, devicetree@vger.kernel.org,\n linux-kernel@vger.kernel.org, linux-pwm@vger.kernel.org,\n linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,\n Radu Sabau <radu.sabau@analog.com>","X-Mailer":"b4 0.14.3","X-Developer-Signature":"v=1; a=ed25519-sha256; t=1775214183; l=11808;\n i=radu.sabau@analog.com; s=20260220; h=from:subject:message-id;\n bh=e8UCeVlyE7LiPTUQG7GWYv5hsUN5zhmvmrFc6kisRRg=;\n b=yDO84jXBRZUJFy3+VsC/jXtXAxgYjxFTUkc/0fmsLyob66sCxcan3Vgo2RH28Nzl2QStFh4Ft\n Bjzb1TMMcGTBJU1QHwkikxWlkid10T7aajbTtb+afeO3CUAaLrVyYn7","X-Developer-Key":"i=radu.sabau@analog.com; a=ed25519;\n pk=lDPQHgn9jTdt0vo58Na9lLxLaE2mb330if71Cn+EvFU=","X-Endpoint-Received":"by B4 Relay for radu.sabau@analog.com/20260220 with\n auth_id=642","X-Original-From":"Radu Sabau <radu.sabau@analog.com>","Reply-To":"radu.sabau@analog.com"},"content":"This series adds support for the Analog Devices AD4691 family of\nhigh-speed, low-power multichannel successive approximation register\n(SAR) ADCs with an SPI-compatible serial interface.\n\nThe family includes:\n  - AD4691: 16-channel, 500 kSPS\n  - AD4692: 16-channel, 1 MSPS\n  - AD4693: 8-channel, 500 kSPS\n  - AD4694: 8-channel, 1 MSPS\n\nThe devices support two operating modes, auto-detected from the device\ntree:\n  - CNV Burst Mode: external PWM drives CNV independently of SPI;\n                    DATA_READY on a GP pin signals end of conversion\n  - Manual Mode: CNV tied to SPI CS; each SPI transfer reads\n                 the previous conversion result and starts the\n                 next (pipelined N+1 scheme)\n\nA new driver is warranted rather than extending ad4695: the AD4691\ndata path uses an accumulator-register model — results are read from\nAVG_IN registers, with ACC_MASK, ADC_SETUP, DEVICE_SETUP, and\nGPIO_MODE registers controlling the sequencer — none of which exist\nin AD4695. CNV Burst Mode (PWM drives CNV independently of SPI) and\nManual Mode (pipelined N+1 transfers) also have no equivalent in\nAD4695's command-embedded single-cycle protocol.\n\nThe series is structured as follows:\n  1/4 - DT bindings (YAML schema) and MAINTAINERS entry\n  2/4 - Initial driver: register map via custom regmap callbacks,\n        IIO read_raw/write_raw, both operating modes, single-channel\n        reads via internal oscillator (Autonomous Mode)\n  3/4 - Triggered buffer support: IRQ-driven (DATA_READY on a GP pin\n        selected via interrupt-names) for CNV Burst Mode; external IIO\n        trigger for Manual Mode to handle the pipelined N+1 SPI protocol\n  4/4 - SPI Engine offload support: DMA-backed high-throughput\n        capture path using the SPI offload subsystem\n\nDatasheets:\n  https://www.analog.com/en/products/ad4691.html\n  https://www.analog.com/en/products/ad4692.html\n  https://www.analog.com/en/products/ad4693.html\n  https://www.analog.com/en/products/ad4694.html\n\nSigned-off-by: Radu Sabau <radu.sabau@analog.com>\n---\nChanges in v6:\n- Replace device.h with dev_printk.h + device/devres.h; add array_size.h\n- Rename osc_freqs[] → osc_freqs_Hz[] with explicit [0xN] index designators\n- Move loop variable into for() declaration in set_sampling_freq\n- Convert multi-line block comment to single-line in single_shot_read\n- Replace (u16)~ cast with ~BIT() & GENMASK(15, 0) for ACC_MASK_REG write;\n  GENMASK(15, 0) is still needed, otherwise maximum value condition line\n  in reg_write() would fail.\n- Extract osc_idx/period_us temporaries in single_shot_read; add comment\n- Use devm_regulator_bulk_get_enable() for avdd + vio supplies\n- Reformat reset_gpio_probe() comment; remove (GPIOD_OUT_HIGH) detail\n- Extract REF_CTRL value into temporary before regmap_update_bits\n- Use regmap_assign_bits for OSC_FREQ_REG in config\n- Remove ad4691_free_scan_bufs NULL assignments; they are not checked.\n- Replace indio_dev->masklength with iio_get_masklength() throughout\n- Fix spi_optimize_message error path to use goto err in preenable\n- Add iio_buffer_enabled() guard in sampling_frequency_store and\n  set_oversampling_ratio\n- Move ad4691_gpio_setup call from ad4691_config into\n  setup_triggered_buffer after IRQ lookup; remove duplicate\n  fwnode_irq_get_byname loop\n- Replace oversampling ratio search loop with is_power_of_2 + ilog2\n- Link to v5: https://lore.kernel.org/r/20260327-ad4692-multichannel-sar-adc-driver-v5-0-11f789de47b8@analog.com\n\nChanges in v5:\n- Reorder datasheets numerically\n- Fix interrupt-names: use enum with minItems/maxItems\n- Remove if/then block requiring interrupts — driver detail, not hardware constraint\n- Remove redundant .shift = 0 from channel macro\n- Write max_rate comparison as 1 * HZ_PER_MHZ\n- Invert set_sampling_freq loop to use continue\n- Fix fsleep() line break; remove blank line in read_raw\n- Reorder supply init: vio immediately after avdd\n- Move comment rewrites and OSC_FREQ_REG condition into the base driver patch\n- Add bit-15 READ comment in reg_read\n- Rewrite ldo-in handling with cleaner if/else-if pattern\n- Drop redundant refbuf_en = false; invert if (!rst) in reset\n- Drop reset_control_assert() — GPIO already asserted at probe\n- Use regmap_update_bits/assign_bits in config\n- Remove tab-column alignment of state struct members\n- Declare osc_freqs[] as const int, eliminating explicit casts\n- Drop obvious AUTONOMOUS mode comment\n- Rename ACC_COUNT_LIMIT → ACC_DEPTH_IN to match datasheet\n- Use bitmap_weight()/bitmap_read() for active_scan_mask access;\n  add #include <linux/bitmap.h>\n- Fix channel macro line-continuation tab alignment\n- Use IIO_CHAN_SOFT_TIMESTAMP(8) for 8-channel variants\n- Use aligned_s64 ts in scan struct\n- Add comment explaining start-index removal in set_sampling_freq\n- Remove trailing comma after NULL in buffer_attrs[]\n- Add IRQF_NO_AUTOEN rationale comment\n- Remove unreachable manual_mode guards in sampling_frequency_show/store\n- Remove st->trig; use indio_dev->trig directly\n- Move max_speed_hz param to the offload patch where it is used\n- Use DIV_ROUND_UP for CNV period; use compound pwm_state initializer\n- Move offload fields into a separately allocated sub-struct\n- Build TX words via u8* byte-fill; fixes sparse __be32 warnings\n- Add three scan types (NORMAL/OFFLOAD_CNV/OFFLOAD_MANUAL) with\n  get_current_scan_type; triggered buffer path uses storagebits=16\n- Fix IIO_CHAN_INFO_SCALE: use iio_get_current_scan_type() for realbits\n- Add MODULE_IMPORT_NS(\"IIO_DMAENGINE_BUFFER\")\n- Add Documentation/iio/ad4691.rst\n- Link to v4: https://lore.kernel.org/r/20260320-ad4692-multichannel-sar-adc-driver-v4-0-052c1050507a@analog.com\n\nChanges in v4:\n- dt-bindings: add avdd-supply (required) and ldo-in-supply (optional);\n  rename vref-supply → ref-supply, vrefin-supply → refin-supply;\n  corrected reset-gpios polarity (active-high → active-low); remove\n  clocks and pwm-names; extend interrupts to up to 4 GP pins with\n  interrupt-names \"gp0\"..\"gp3\"; reduce #trigger-source-cells to\n  const: 1 (GP pin number); add gpio-controller / #gpio-cells = <2>;\n  drop adi,ad4691.h header; update binding examples\n- driver: rename CNV Clock Mode → CNV Burst Mode throughout\n- driver: add avdd-supply (required) and ldo-in-supply; track ref vs.\n  refin supply for REFBUF_EN; set LDO_EN in DEVICE_SETUP when ldo-in\n  is present; add software reset fallback via SPI_CONFIG_A register\n- driver: merge ACC_MASK1_REG / ACC_MASK2_REG into ACC_MASK_REG with\n  a single ADDR_DESCENDING 16-bit SPI write\n- driver: remove clocks usage; set PWM rate directly without ref clock\n- driver: rename chip info structs (ad4691_chip_info etc.); rename\n  *chip → *info in state struct; replace adc_mode enum with manual_mode\n  bool; replace ktime sampling_period with u32 cnv_period_ns\n- driver: move IIO_CHAN_INFO_SAMP_FREQ to info_mask_separate with an\n  available list for the internal oscillator frequency\n- driver: use regcache MAPLE instead of RBTREE\n- triggered buffer: derive DATA_READY GP pin from interrupt-names in\n  firmware (\"gp0\"..\"gp3\") instead of assuming GP0\n- triggered buffer: use regmap_update_bits for DEVICE_SETUP mode toggle\n  to avoid clobbering LDO_EN when toggling MANUAL_MODE bit\n- triggered buffer: split buffer setup ops into separate Manual and\n  CNV Burst variants (mirrors offload path structure)\n- SPI offload: promote channel storagebits from 16 to 32 to match DMA\n  word size; introduce ad4691_manual_channels[] with shift=16 (data in\n  upper 16 bits of the 32-bit word); update triggered-buffer paths to\n  the same layout for consistency\n- SPI offload: derive GP pin from trigger-source args[0] instead of\n  hardcoding GP0; split offload buffer setup ops per mode\n- replace put_unaligned_be32() + FIELD_PREP() with cpu_to_be32() and\n  plain bit-shift ops for SPI offload message construction\n- multiple reviewer-requested code style and correctness fixes\n  (Andy Shevchenko, Nuno Sá, Uwe Kleine-König, David Lechner)\n- Link to v3: https://lore.kernel.org/r/20260313-ad4692-multichannel-sar-adc-driver-v3-0-b4d14d81a181@analog.com\n\nChanges in v3:\n- Replace GPIO reset handling with reset controller framework\n- Replace two regmap_write() calls for ACC_MASK1/ACC_MASK2 with regmap_bulk_write()\n- Move conv_us declaration closer to its first use\n- Derive spi_device/dev from regmap instead of storing st->spi\n- ad4691_trigger_handler(): use guard(mutex)() and iio_for_each_active_channel()\n- ad4691_setup_triggered_buffer(): return -ENOMEM/-ENOENT directly instead of\n  wrapping in dev_err_probe(); fix fwnode_irq_get() check (irq <= 0 → irq < 0)\n- Add GENMASK defines for SPI offload 32-bit message layout; replace manual\n  bit-shifts with put_unaligned_be32() + FIELD_PREP()\n- Use DIV_ROUND_CLOSEST_ULL() instead of div64_u64()\n- ad4691_set_sampling_freq(): fix indentation; drop unnecessary else after return\n- ad4691_probe(): use PTR_ERR_OR_ZERO() for devm_spi_offload_get()\n- Link to v2: https://lore.kernel.org/r/20260310-ad4692-multichannel-sar-adc-driver-v2-0-d9bb8aeb5e17@analog.com\n\nChanges in v2:\n- Drop adi,spi-mode DT property; operating mode now auto-detected\n  from pwms presence (CNV Clock Mode if present, Manual Mode if not)\n- Reduce from 5 operating modes to 2 (CNV Clock Mode, Manual Mode);\n  Autonomous, SPI Burst and CNV Burst modes removed as user-selectable\n  modes; Autonomous Mode is now the internal idle/single-shot state\n- Single-shot read_raw always uses internal oscillator (Autonomous\n  Mode), independent of the configured buffer mode\n- Replace bulk regulator API with devm_regulator_get_enable() and\n  devm_regulator_get_enable_read_voltage()\n- Use guard(mutex) and IIO_DEV_ACQUIRE_DIRECT_MODE scoped helpers\n- Replace enum + indexed chip_info array with named chip_info structs\n- Remove product_id field and hardware ID check from probe\n- Factor IIO_CHAN_INFO_RAW body into ad4691_single_shot_read() helper\n- Use fwnode_irq_get(dev_fwnode(dev), 0); drop interrupt-names from\n  DT binding\n- Use devm_clk_get_enabled(dev, NULL); drop clock-names from DT\n  binding\n- Use spi_write_then_read() for DMA-safe register writes\n- Use put_unaligned_be16() for SPI header construction\n- fsleep() instead of usleep_range() in single-shot path\n- storagebits 24->32 for manual-mode channels (uniform DMA layout)\n- Collect full scan into vals[16], single iio_push_to_buffers_with_ts()\n- Use pf->timestamp instead of iio_get_time_ns() in trigger handler\n- Remove IRQF_TRIGGER_FALLING (comes from firmware/DT)\n- Fix offload xfer array size ([17]: N channels + 1 state reset)\n- Drop third DT binding example per reviewer request\n- Link to v1: https://lore.kernel.org/r/20260305-ad4692-multichannel-sar-adc-driver-v1-0-336229a8dcc7@analog.com\n\n---\nRadu Sabau (4):\n      dt-bindings: iio: adc: add AD4691 family\n      iio: adc: ad4691: add initial driver for AD4691 family\n      iio: adc: ad4691: add triggered buffer support\n      iio: adc: ad4691: add SPI offload support\n\n .../devicetree/bindings/iio/adc/adi,ad4691.yaml    |  162 ++\n Documentation/iio/ad4691.rst                       |  259 +++\n Documentation/iio/index.rst                        |    1 +\n MAINTAINERS                                        |    9 +\n drivers/iio/adc/Kconfig                            |   14 +\n drivers/iio/adc/Makefile                           |    1 +\n drivers/iio/adc/ad4691.c                           | 1685 ++++++++++++++++++++\n 7 files changed, 2131 insertions(+)\n---\nbase-commit: 11439c4635edd669ae435eec308f4ab8a0804808\nchange-id: 20260302-ad4692-multichannel-sar-adc-driver-78e4d44d24b2\n\nBest regards,"}