From nobody Mon Feb 9 08:49:24 2026 Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8E18023237F for ; Mon, 10 Mar 2025 17:41:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741628475; cv=none; b=TMPDX6ECiyb5G8trbdeanrI34rGD0TaizW1JqqY8A/Z/0My4mhJkZoqSRQtQYwRY/i27tmGa8dFaxkCi4e0zC9eFW2dFVTHPJgfcRxb3+owZbX1ma4JqKnvk0WJfwlAIfKBlXw4lYZIf+K8U8ooJ/W4tuEwpqkSUAjIszuZXnjo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741628475; c=relaxed/simple; bh=/mxbPBPHIikhAFRN8rcn/47DsU2LMelbsUgTvqHEeHc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LK2B3HA+OyD41G/IlNXfb//EUX9KXZuXcO9ul0O7PK9HswKoWMb4joC6cg8Rj+CrDD8f37hYDyIAXSULKFMxelv8FPAd/N8XgMTQ5qXBYECAlCmga9wYHGyIeTAWzFTXWDdblGUNAsDJLgo34INK3jzICruSAAcns3saHUGnbFM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=ky2SD+Xd; arc=none smtp.client-ip=209.85.128.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="ky2SD+Xd" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-43cf3192f3bso13957965e9.1 for ; Mon, 10 Mar 2025 10:41:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1741628471; x=1742233271; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=FWTl/Il2R/pyB5A61m5+Ru5Ym+TwIMgmhhjaKwbDWLg=; b=ky2SD+XdR4A9H8mMMugrTpTQzQhjVLPe1iyebdzSaHPsrep43ujt2nTGnuUju8CtFa lNZmakSjwgtoycyXQtDNyCZX8rJXNPUDKxjWuebHnzG6zJLYPT78g9qd8Y6iiXwVAPRQ hXUaD2VrisV8aFH1POMy5tEPCRyPpLQ9VQTflLkMnoCHib6tHHRX+FLA+l0FlAqXdgRt j1KhxvmykHygPuKDGbJMleV5nnkOCbBD73trp1PJu5+VIaJ1KAj2Jexrs/R9fZ2D6qP9 DeWKsgo8ELmofDkMF269j5e+G8M3cS/nRTjOSLiC4MNqkTEHVxQbt2o5Q1u6WxEtZ6Yj x7mA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741628471; x=1742233271; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=FWTl/Il2R/pyB5A61m5+Ru5Ym+TwIMgmhhjaKwbDWLg=; b=hAwoJD+XY5VCjwxPBe00y+At3ka1oRKhXJsF2pVSxfwWI+YSMpZCx6BsSWDT6AHBgw STz71xJtm/Q3g/0yGPbWn4/v1x3AnO3oMVCCCphZOI2Vz2BUIHxUPu4ji9b1WlmRT3ql GxSO1Z2V3y8ityc//p9WUAu5DeB6CeGVRNMMfNDmlPJK48ro4OxNBFJKRoohi86KijgX Toq+bo/a9TAgLR0UvR0pxF4JPkYKLK1UgaFwvHV041+WLnZ+oFhMcxunkDuiaiW10pNY fQUD4z7+p6Z5o5VA9zYKRyVEiYqIIkb4tsbJvLh8lTI6iPvEkfeH6zFACZeCxSdMvCCL 6z4Q== X-Forwarded-Encrypted: i=1; AJvYcCW1qyqgxjz7663VgbpqORHgBuXaCGXdNAPbuLi9n076sLVQ3jhXcDoGLjzCLbYGNyoFPKReYEz8iqfF2KU=@vger.kernel.org X-Gm-Message-State: AOJu0YxwlBBOFq9Gj4vXZbMZFZI7DHXcLeYWJgZOKOK5sysLcyIf630L EIGali6uRQUquW0llv4viRMZGHd1Avt01a+MHMhqyzKESw/FVDMeJvqlq4hC8NA= X-Gm-Gg: ASbGncte0noN4v6ezgGiXD7pxg9BGg8YkqE3xu4tVmgCxWQyByFQJ6i9UHZbNmNx2VB 0gfYK3ZivqN7L8D4/Y068gOd2N8U1AjOnQwv2VeKLgl5LjgxT0n6xfF8ln6yTk3/M7u4fVJlrWf AYVLo9r1I3HcuZ89n5WtnU6uEIJkWbtAqCH+g3WGYPjbfFdBypHh6WazWHi5KT84bjuD6+d/JmO RZzmUUpOq0YPGDb9EHnNvw3vxPWKgnEH2kxy84MyP21codFKPMrj5MB3XyVRsKL1wkVLcxW8c+v w8in26k4YB7M/NCq4PEi3Dq48tEM6u3nF1AB+AI9Ds21PsPE8+RAT26oiPRUOAVGqHdBQ9FFDs3 C+GtVfuJXhY6gKqcexNM= X-Google-Smtp-Source: AGHT+IEU1RH4EHxS7tu91RJngpnPZ7CzTfcAu7+QdvKqdupJct4Dq/I2NslEyt7fmSqzpFtKX7meHQ== X-Received: by 2002:a5d:47c1:0:b0:391:2bcc:11f2 with SMTP id ffacd0b85a97d-39132d2ac45mr8833354f8f.1.1741628470605; Mon, 10 Mar 2025 10:41:10 -0700 (PDT) Received: from [127.0.1.1] (host-82-56-170-15.retail.telecomitalia.it. [82.56.170.15]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3912bfba8a9sm15597038f8f.9.2025.03.10.10.41.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Mar 2025 10:41:10 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Mon, 10 Mar 2025 18:39:52 +0100 Subject: [PATCH v4 1/2] iio: ad7380: add support for SPI offload Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250310-wip-bl-spi-offload-ad7380-v4-1-b184b37b7c72@baylibre.com> References: <20250310-wip-bl-spi-offload-ad7380-v4-0-b184b37b7c72@baylibre.com> In-Reply-To: <20250310-wip-bl-spi-offload-ad7380-v4-0-b184b37b7c72@baylibre.com> To: Jonathan Cameron , Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , David Lechner , Jonathan Corbet Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, Angelo Dureghello X-Mailer: b4 0.14.2 From: Angelo Dureghello Add support for SPI offload to the ad7380 driver. SPI offload allows sampling data at the max sample rate (2MSPS with one SDO line). This is developed and tested against the ADI example FPGA design for this family of ADCs [1]. [1]: http://analogdevicesinc.github.io/hdl/projects/ad738x_fmc/index.html Signed-off-by: Angelo Dureghello --- drivers/iio/adc/Kconfig | 2 + drivers/iio/adc/ad7380.c | 511 +++++++++++++++++++++++++++++++++++++++++++= ---- 2 files changed, 477 insertions(+), 36 deletions(-) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index b7ae6e0ae0df0f9ecc6023ed4b1b0ebfcd643e7e..6529df1a498c2c3b32b3640b5c3= a90d8fff33788 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -228,7 +228,9 @@ config AD7298 config AD7380 tristate "Analog Devices AD7380 ADC driver" depends on SPI_MASTER + select SPI_OFFLOAD select IIO_BUFFER + select IIO_BUFFER_DMAENGINE select IIO_TRIGGER select IIO_TRIGGERED_BUFFER help diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c index 407930f1f5dd107154a6c34c6afd4429ebb69826..4fcb49fdf56639784098f0147a9= faef8dcb6b0f6 100644 --- a/drivers/iio/adc/ad7380.c +++ b/drivers/iio/adc/ad7380.c @@ -16,6 +16,9 @@ * adaq4370-4 : https://www.analog.com/media/en/technical-documentation/da= ta-sheets/adaq4370-4.pdf * adaq4380-4 : https://www.analog.com/media/en/technical-documentation/da= ta-sheets/adaq4380-4.pdf * adaq4381-4 : https://www.analog.com/media/en/technical-documentation/da= ta-sheets/adaq4381-4.pdf + * + * HDL ad738x_fmc: https://analogdevicesinc.github.io/hdl/projects/ad738x_= fmc/index.html + * */ =20 #include @@ -30,11 +33,13 @@ #include #include #include +#include #include #include #include =20 #include +#include #include #include #include @@ -93,6 +98,12 @@ #define AD7380_NUM_SDO_LINES 1 #define AD7380_DEFAULT_GAIN_MILLI 1000 =20 +/* + * Using SPI offload, storagebits is always 32, so can't be used to comput= e struct + * spi_transfer.len. Using realbits instead. + */ +#define AD7380_SPI_BYTES(scan_type) ((scan_type)->realbits > 16 ? 4 : 2) + struct ad7380_timing_specs { const unsigned int t_csh_ns; /* CS minimum high time */ }; @@ -100,6 +111,7 @@ struct ad7380_timing_specs { struct ad7380_chip_info { const char *name; const struct iio_chan_spec *channels; + const struct iio_chan_spec *offload_channels; unsigned int num_channels; unsigned int num_simult_channels; bool has_hardware_gain; @@ -112,6 +124,7 @@ struct ad7380_chip_info { unsigned int num_vcm_supplies; const unsigned long *available_scan_masks; const struct ad7380_timing_specs *timing_specs; + u32 max_conversion_rate_hz; }; =20 static const struct iio_event_spec ad7380_events[] =3D { @@ -217,6 +230,91 @@ static const struct iio_scan_type ad7380_scan_type_16_= u[] =3D { }, }; =20 +/* + * Defining here scan types for offload mode, since with current available= HDL + * only a value of 32 for storagebits is supported. + */ + +/* Extended scan types for 12-bit unsigned chips, offload support. */ +static const struct iio_scan_type ad7380_scan_type_12_u_offload[] =3D { + [AD7380_SCAN_TYPE_NORMAL] =3D { + .sign =3D 'u', + .realbits =3D 12, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, + [AD7380_SCAN_TYPE_RESOLUTION_BOOST] =3D { + .sign =3D 'u', + .realbits =3D 14, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, +}; + +/* Extended scan types for 14-bit signed chips, offload support. */ +static const struct iio_scan_type ad7380_scan_type_14_s_offload[] =3D { + [AD7380_SCAN_TYPE_NORMAL] =3D { + .sign =3D 's', + .realbits =3D 14, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, + [AD7380_SCAN_TYPE_RESOLUTION_BOOST] =3D { + .sign =3D 's', + .realbits =3D 16, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, +}; + +/* Extended scan types for 14-bit unsigned chips, offload support. */ +static const struct iio_scan_type ad7380_scan_type_14_u_offload[] =3D { + [AD7380_SCAN_TYPE_NORMAL] =3D { + .sign =3D 'u', + .realbits =3D 14, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, + [AD7380_SCAN_TYPE_RESOLUTION_BOOST] =3D { + .sign =3D 'u', + .realbits =3D 16, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, +}; + +/* Extended scan types for 16-bit signed_chips, offload support. */ +static const struct iio_scan_type ad7380_scan_type_16_s_offload[] =3D { + [AD7380_SCAN_TYPE_NORMAL] =3D { + .sign =3D 's', + .realbits =3D 16, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, + [AD7380_SCAN_TYPE_RESOLUTION_BOOST] =3D { + .sign =3D 's', + .realbits =3D 18, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, +}; + +/* Extended scan types for 16-bit unsigned chips, offload support. */ +static const struct iio_scan_type ad7380_scan_type_16_u_offload[] =3D { + [AD7380_SCAN_TYPE_NORMAL] =3D { + .sign =3D 'u', + .realbits =3D 16, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, + [AD7380_SCAN_TYPE_RESOLUTION_BOOST] =3D { + .sign =3D 'u', + .realbits =3D 18, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, +}; + #define _AD7380_CHANNEL(index, bits, diff, sign, gain) { \ .type =3D IIO_VOLTAGE, \ .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | \ @@ -238,48 +336,123 @@ static const struct iio_scan_type ad7380_scan_type_1= 6_u[] =3D { .num_event_specs =3D ARRAY_SIZE(ad7380_events), \ } =20 +#define _AD7380_OFFLOAD_CHANNEL(index, bits, diff, sign, gain) { \ + .type =3D IIO_VOLTAGE, \ + .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | = \ + ((gain) ? BIT(IIO_CHAN_INFO_SCALE) : 0) | \ + ((diff) ? 0 : BIT(IIO_CHAN_INFO_OFFSET)), \ + .info_mask_shared_by_type =3D ((gain) ? 0 : BIT(IIO_CHAN_INFO_SCALE)) | = \ + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_type_available =3D \ + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .indexed =3D 1, = \ + .differential =3D (diff), = \ + .channel =3D (diff) ? (2 * (index)) : (index), = \ + .channel2 =3D (diff) ? (2 * (index) + 1) : 0, = \ + .scan_index =3D (index), = \ + .has_ext_scan_type =3D 1, = \ + .ext_scan_type =3D ad7380_scan_type_##bits##_##sign##_offload, = \ + .num_ext_scan_type =3D = \ + ARRAY_SIZE(ad7380_scan_type_##bits##_##sign##_offload), \ + .event_spec =3D ad7380_events, = \ + .num_event_specs =3D ARRAY_SIZE(ad7380_events), = \ +} + +/* + * Notes on the offload channels: + * - There is no soft timestamp since everything is done in hardware. + * - There is a sampling frequency attribute added. This controls the SPI + * offload trigger. + * - The storagebits value depends on the SPI offload provider. Currently = there + * is only one supported provider, namely the ADI PULSAR ADC HDL project, + * which always uses 32-bit words for data values, even for <=3D 16-bit = ADCs. + * So the value is just hardcoded to 32 for now. + */ + #define AD7380_CHANNEL(index, bits, diff, sign) \ _AD7380_CHANNEL(index, bits, diff, sign, false) =20 #define ADAQ4380_CHANNEL(index, bits, diff, sign) \ _AD7380_CHANNEL(index, bits, diff, sign, true) =20 -#define DEFINE_AD7380_2_CHANNEL(name, bits, diff, sign) \ +#define DEFINE_AD7380_2_CHANNEL(name, bits, diff, sign) \ +static const struct iio_chan_spec name[] =3D { \ + AD7380_CHANNEL(0, bits, diff, sign), \ + AD7380_CHANNEL(1, bits, diff, sign), \ + IIO_CHAN_SOFT_TIMESTAMP(2), \ +} + +#define DEFINE_AD7380_4_CHANNEL(name, bits, diff, sign) \ +static const struct iio_chan_spec name[] =3D { \ + AD7380_CHANNEL(0, bits, diff, sign), \ + AD7380_CHANNEL(1, bits, diff, sign), \ + AD7380_CHANNEL(2, bits, diff, sign), \ + AD7380_CHANNEL(3, bits, diff, sign), \ + IIO_CHAN_SOFT_TIMESTAMP(4), \ +} + +#define DEFINE_ADAQ4380_4_CHANNEL(name, bits, diff, sign) \ +static const struct iio_chan_spec name[] =3D { \ + ADAQ4380_CHANNEL(0, bits, diff, sign), \ + ADAQ4380_CHANNEL(1, bits, diff, sign), \ + ADAQ4380_CHANNEL(2, bits, diff, sign), \ + ADAQ4380_CHANNEL(3, bits, diff, sign), \ + IIO_CHAN_SOFT_TIMESTAMP(4), \ +} + +#define DEFINE_AD7380_8_CHANNEL(name, bits, diff, sign) \ +static const struct iio_chan_spec name[] =3D { \ + AD7380_CHANNEL(0, bits, diff, sign), \ + AD7380_CHANNEL(1, bits, diff, sign), \ + AD7380_CHANNEL(2, bits, diff, sign), \ + AD7380_CHANNEL(3, bits, diff, sign), \ + AD7380_CHANNEL(4, bits, diff, sign), \ + AD7380_CHANNEL(5, bits, diff, sign), \ + AD7380_CHANNEL(6, bits, diff, sign), \ + AD7380_CHANNEL(7, bits, diff, sign), \ + IIO_CHAN_SOFT_TIMESTAMP(8), \ +} + +#define AD7380_OFFLOAD_CHANNEL(index, bits, diff, sign) \ +_AD7380_OFFLOAD_CHANNEL(index, bits, diff, sign, false) + +#define ADAQ4380_OFFLOAD_CHANNEL(index, bits, diff, sign) \ +_AD7380_OFFLOAD_CHANNEL(index, bits, diff, sign, true) + +#define DEFINE_AD7380_2_OFFLOAD_CHANNEL(name, bits, diff, sign) \ static const struct iio_chan_spec name[] =3D { \ - AD7380_CHANNEL(0, bits, diff, sign), \ - AD7380_CHANNEL(1, bits, diff, sign), \ - IIO_CHAN_SOFT_TIMESTAMP(2), \ + AD7380_OFFLOAD_CHANNEL(0, bits, diff, sign), \ + AD7380_OFFLOAD_CHANNEL(1, bits, diff, sign), \ } =20 -#define DEFINE_AD7380_4_CHANNEL(name, bits, diff, sign) \ +#define DEFINE_AD7380_4_OFFLOAD_CHANNEL(name, bits, diff, sign) \ static const struct iio_chan_spec name[] =3D { \ - AD7380_CHANNEL(0, bits, diff, sign), \ - AD7380_CHANNEL(1, bits, diff, sign), \ - AD7380_CHANNEL(2, bits, diff, sign), \ - AD7380_CHANNEL(3, bits, diff, sign), \ - IIO_CHAN_SOFT_TIMESTAMP(4), \ + AD7380_OFFLOAD_CHANNEL(0, bits, diff, sign), \ + AD7380_OFFLOAD_CHANNEL(1, bits, diff, sign), \ + AD7380_OFFLOAD_CHANNEL(2, bits, diff, sign), \ + AD7380_OFFLOAD_CHANNEL(3, bits, diff, sign), \ } =20 -#define DEFINE_ADAQ4380_4_CHANNEL(name, bits, diff, sign) \ -static const struct iio_chan_spec name[] =3D { \ - ADAQ4380_CHANNEL(0, bits, diff, sign), \ - ADAQ4380_CHANNEL(1, bits, diff, sign), \ - ADAQ4380_CHANNEL(2, bits, diff, sign), \ - ADAQ4380_CHANNEL(3, bits, diff, sign), \ - IIO_CHAN_SOFT_TIMESTAMP(4), \ +#define DEFINE_ADAQ4380_4_OFFLOAD_CHANNEL(name, bits, diff, sign) \ +static const struct iio_chan_spec name[] =3D { \ + AD7380_OFFLOAD_CHANNEL(0, bits, diff, sign), \ + AD7380_OFFLOAD_CHANNEL(1, bits, diff, sign), \ + AD7380_OFFLOAD_CHANNEL(2, bits, diff, sign), \ + AD7380_OFFLOAD_CHANNEL(3, bits, diff, sign), \ } =20 -#define DEFINE_AD7380_8_CHANNEL(name, bits, diff, sign) \ +#define DEFINE_AD7380_8_OFFLOAD_CHANNEL(name, bits, diff, sign) \ static const struct iio_chan_spec name[] =3D { \ - AD7380_CHANNEL(0, bits, diff, sign), \ - AD7380_CHANNEL(1, bits, diff, sign), \ - AD7380_CHANNEL(2, bits, diff, sign), \ - AD7380_CHANNEL(3, bits, diff, sign), \ - AD7380_CHANNEL(4, bits, diff, sign), \ - AD7380_CHANNEL(5, bits, diff, sign), \ - AD7380_CHANNEL(6, bits, diff, sign), \ - AD7380_CHANNEL(7, bits, diff, sign), \ - IIO_CHAN_SOFT_TIMESTAMP(8), \ + AD7380_OFFLOAD_CHANNEL(0, bits, diff, sign), \ + AD7380_OFFLOAD_CHANNEL(1, bits, diff, sign), \ + AD7380_OFFLOAD_CHANNEL(2, bits, diff, sign), \ + AD7380_OFFLOAD_CHANNEL(3, bits, diff, sign), \ + AD7380_OFFLOAD_CHANNEL(4, bits, diff, sign), \ + AD7380_OFFLOAD_CHANNEL(5, bits, diff, sign), \ + AD7380_OFFLOAD_CHANNEL(6, bits, diff, sign), \ + AD7380_OFFLOAD_CHANNEL(7, bits, diff, sign), \ } =20 /* fully differential */ @@ -303,6 +476,28 @@ DEFINE_AD7380_8_CHANNEL(ad7386_4_channels, 16, 0, u); DEFINE_AD7380_8_CHANNEL(ad7387_4_channels, 14, 0, u); DEFINE_AD7380_8_CHANNEL(ad7388_4_channels, 12, 0, u); =20 +/* offload channels */ +DEFINE_AD7380_2_OFFLOAD_CHANNEL(ad7380_offload_channels, 16, 1, s); +DEFINE_AD7380_2_OFFLOAD_CHANNEL(ad7381_offload_channels, 14, 1, s); +DEFINE_AD7380_4_OFFLOAD_CHANNEL(ad7380_4_offload_channels, 16, 1, s); +DEFINE_AD7380_4_OFFLOAD_CHANNEL(ad7381_4_offload_channels, 14, 1, s); +DEFINE_ADAQ4380_4_OFFLOAD_CHANNEL(adaq4380_4_offload_channels, 16, 1, s); +DEFINE_ADAQ4380_4_OFFLOAD_CHANNEL(adaq4381_4_offload_channels, 14, 1, s); + +/* pseudo differential */ +DEFINE_AD7380_2_OFFLOAD_CHANNEL(ad7383_offload_channels, 16, 0, s); +DEFINE_AD7380_2_OFFLOAD_CHANNEL(ad7384_offload_channels, 14, 0, s); +DEFINE_AD7380_4_OFFLOAD_CHANNEL(ad7383_4_offload_channels, 16, 0, s); +DEFINE_AD7380_4_OFFLOAD_CHANNEL(ad7384_4_offload_channels, 14, 0, s); + +/* Single ended */ +DEFINE_AD7380_4_OFFLOAD_CHANNEL(ad7386_offload_channels, 16, 0, u); +DEFINE_AD7380_4_OFFLOAD_CHANNEL(ad7387_offload_channels, 14, 0, u); +DEFINE_AD7380_4_OFFLOAD_CHANNEL(ad7388_offload_channels, 12, 0, u); +DEFINE_AD7380_8_OFFLOAD_CHANNEL(ad7386_4_offload_channels, 16, 0, u); +DEFINE_AD7380_8_OFFLOAD_CHANNEL(ad7387_4_offload_channels, 14, 0, u); +DEFINE_AD7380_8_OFFLOAD_CHANNEL(ad7388_4_offload_channels, 12, 0, u); + static const char * const ad7380_supplies[] =3D { "vcc", "vlogic", }; @@ -409,28 +604,33 @@ static const int ad7380_gains[] =3D { static const struct ad7380_chip_info ad7380_chip_info =3D { .name =3D "ad7380", .channels =3D ad7380_channels, + .offload_channels =3D ad7380_offload_channels, .num_channels =3D ARRAY_SIZE(ad7380_channels), .num_simult_channels =3D 2, .supplies =3D ad7380_supplies, .num_supplies =3D ARRAY_SIZE(ad7380_supplies), .available_scan_masks =3D ad7380_2_channel_scan_masks, .timing_specs =3D &ad7380_timing, + .max_conversion_rate_hz =3D 4 * MEGA, }; =20 static const struct ad7380_chip_info ad7381_chip_info =3D { .name =3D "ad7381", .channels =3D ad7381_channels, + .offload_channels =3D ad7381_offload_channels, .num_channels =3D ARRAY_SIZE(ad7381_channels), .num_simult_channels =3D 2, .supplies =3D ad7380_supplies, .num_supplies =3D ARRAY_SIZE(ad7380_supplies), .available_scan_masks =3D ad7380_2_channel_scan_masks, .timing_specs =3D &ad7380_timing, + .max_conversion_rate_hz =3D 4 * MEGA, }; =20 static const struct ad7380_chip_info ad7383_chip_info =3D { .name =3D "ad7383", .channels =3D ad7383_channels, + .offload_channels =3D ad7383_offload_channels, .num_channels =3D ARRAY_SIZE(ad7383_channels), .num_simult_channels =3D 2, .supplies =3D ad7380_supplies, @@ -439,11 +639,13 @@ static const struct ad7380_chip_info ad7383_chip_info= =3D { .num_vcm_supplies =3D ARRAY_SIZE(ad7380_2_channel_vcm_supplies), .available_scan_masks =3D ad7380_2_channel_scan_masks, .timing_specs =3D &ad7380_timing, + .max_conversion_rate_hz =3D 4 * MEGA, }; =20 static const struct ad7380_chip_info ad7384_chip_info =3D { .name =3D "ad7384", .channels =3D ad7384_channels, + .offload_channels =3D ad7384_offload_channels, .num_channels =3D ARRAY_SIZE(ad7384_channels), .num_simult_channels =3D 2, .supplies =3D ad7380_supplies, @@ -452,11 +654,13 @@ static const struct ad7380_chip_info ad7384_chip_info= =3D { .num_vcm_supplies =3D ARRAY_SIZE(ad7380_2_channel_vcm_supplies), .available_scan_masks =3D ad7380_2_channel_scan_masks, .timing_specs =3D &ad7380_timing, + .max_conversion_rate_hz =3D 4 * MEGA, }; =20 static const struct ad7380_chip_info ad7386_chip_info =3D { .name =3D "ad7386", .channels =3D ad7386_channels, + .offload_channels =3D ad7386_offload_channels, .num_channels =3D ARRAY_SIZE(ad7386_channels), .num_simult_channels =3D 2, .supplies =3D ad7380_supplies, @@ -464,11 +668,13 @@ static const struct ad7380_chip_info ad7386_chip_info= =3D { .has_mux =3D true, .available_scan_masks =3D ad7380_2x2_channel_scan_masks, .timing_specs =3D &ad7380_timing, + .max_conversion_rate_hz =3D 4 * MEGA, }; =20 static const struct ad7380_chip_info ad7387_chip_info =3D { .name =3D "ad7387", .channels =3D ad7387_channels, + .offload_channels =3D ad7387_offload_channels, .num_channels =3D ARRAY_SIZE(ad7387_channels), .num_simult_channels =3D 2, .supplies =3D ad7380_supplies, @@ -476,11 +682,13 @@ static const struct ad7380_chip_info ad7387_chip_info= =3D { .has_mux =3D true, .available_scan_masks =3D ad7380_2x2_channel_scan_masks, .timing_specs =3D &ad7380_timing, + .max_conversion_rate_hz =3D 4 * MEGA, }; =20 static const struct ad7380_chip_info ad7388_chip_info =3D { .name =3D "ad7388", .channels =3D ad7388_channels, + .offload_channels =3D ad7388_offload_channels, .num_channels =3D ARRAY_SIZE(ad7388_channels), .num_simult_channels =3D 2, .supplies =3D ad7380_supplies, @@ -488,11 +696,13 @@ static const struct ad7380_chip_info ad7388_chip_info= =3D { .has_mux =3D true, .available_scan_masks =3D ad7380_2x2_channel_scan_masks, .timing_specs =3D &ad7380_timing, + .max_conversion_rate_hz =3D 4 * MEGA, }; =20 static const struct ad7380_chip_info ad7380_4_chip_info =3D { .name =3D "ad7380-4", .channels =3D ad7380_4_channels, + .offload_channels =3D ad7380_4_offload_channels, .num_channels =3D ARRAY_SIZE(ad7380_4_channels), .num_simult_channels =3D 4, .supplies =3D ad7380_supplies, @@ -500,22 +710,26 @@ static const struct ad7380_chip_info ad7380_4_chip_in= fo =3D { .external_ref_only =3D true, .available_scan_masks =3D ad7380_4_channel_scan_masks, .timing_specs =3D &ad7380_4_timing, + .max_conversion_rate_hz =3D 4 * MEGA, }; =20 static const struct ad7380_chip_info ad7381_4_chip_info =3D { .name =3D "ad7381-4", .channels =3D ad7381_4_channels, + .offload_channels =3D ad7381_4_offload_channels, .num_channels =3D ARRAY_SIZE(ad7381_4_channels), .num_simult_channels =3D 4, .supplies =3D ad7380_supplies, .num_supplies =3D ARRAY_SIZE(ad7380_supplies), .available_scan_masks =3D ad7380_4_channel_scan_masks, .timing_specs =3D &ad7380_4_timing, + .max_conversion_rate_hz =3D 4 * MEGA, }; =20 static const struct ad7380_chip_info ad7383_4_chip_info =3D { .name =3D "ad7383-4", .channels =3D ad7383_4_channels, + .offload_channels =3D ad7383_4_offload_channels, .num_channels =3D ARRAY_SIZE(ad7383_4_channels), .num_simult_channels =3D 4, .supplies =3D ad7380_supplies, @@ -524,11 +738,13 @@ static const struct ad7380_chip_info ad7383_4_chip_in= fo =3D { .num_vcm_supplies =3D ARRAY_SIZE(ad7380_4_channel_vcm_supplies), .available_scan_masks =3D ad7380_4_channel_scan_masks, .timing_specs =3D &ad7380_4_timing, + .max_conversion_rate_hz =3D 4 * MEGA, }; =20 static const struct ad7380_chip_info ad7384_4_chip_info =3D { .name =3D "ad7384-4", .channels =3D ad7384_4_channels, + .offload_channels =3D ad7384_4_offload_channels, .num_channels =3D ARRAY_SIZE(ad7384_4_channels), .num_simult_channels =3D 4, .supplies =3D ad7380_supplies, @@ -537,11 +753,13 @@ static const struct ad7380_chip_info ad7384_4_chip_in= fo =3D { .num_vcm_supplies =3D ARRAY_SIZE(ad7380_4_channel_vcm_supplies), .available_scan_masks =3D ad7380_4_channel_scan_masks, .timing_specs =3D &ad7380_4_timing, + .max_conversion_rate_hz =3D 4 * MEGA, }; =20 static const struct ad7380_chip_info ad7386_4_chip_info =3D { .name =3D "ad7386-4", .channels =3D ad7386_4_channels, + .offload_channels =3D ad7386_4_offload_channels, .num_channels =3D ARRAY_SIZE(ad7386_4_channels), .num_simult_channels =3D 4, .supplies =3D ad7380_supplies, @@ -549,11 +767,13 @@ static const struct ad7380_chip_info ad7386_4_chip_in= fo =3D { .has_mux =3D true, .available_scan_masks =3D ad7380_2x4_channel_scan_masks, .timing_specs =3D &ad7380_4_timing, + .max_conversion_rate_hz =3D 4 * MEGA, }; =20 static const struct ad7380_chip_info ad7387_4_chip_info =3D { .name =3D "ad7387-4", .channels =3D ad7387_4_channels, + .offload_channels =3D ad7387_4_offload_channels, .num_channels =3D ARRAY_SIZE(ad7387_4_channels), .num_simult_channels =3D 4, .supplies =3D ad7380_supplies, @@ -561,11 +781,13 @@ static const struct ad7380_chip_info ad7387_4_chip_in= fo =3D { .has_mux =3D true, .available_scan_masks =3D ad7380_2x4_channel_scan_masks, .timing_specs =3D &ad7380_4_timing, + .max_conversion_rate_hz =3D 4 * MEGA, }; =20 static const struct ad7380_chip_info ad7388_4_chip_info =3D { .name =3D "ad7388-4", .channels =3D ad7388_4_channels, + .offload_channels =3D ad7388_4_offload_channels, .num_channels =3D ARRAY_SIZE(ad7388_4_channels), .num_simult_channels =3D 4, .supplies =3D ad7380_supplies, @@ -573,11 +795,13 @@ static const struct ad7380_chip_info ad7388_4_chip_in= fo =3D { .has_mux =3D true, .available_scan_masks =3D ad7380_2x4_channel_scan_masks, .timing_specs =3D &ad7380_4_timing, + .max_conversion_rate_hz =3D 4 * MEGA, }; =20 static const struct ad7380_chip_info adaq4370_4_chip_info =3D { .name =3D "adaq4370-4", .channels =3D adaq4380_4_channels, + .offload_channels =3D adaq4380_4_offload_channels, .num_channels =3D ARRAY_SIZE(adaq4380_4_channels), .num_simult_channels =3D 4, .supplies =3D adaq4380_supplies, @@ -586,11 +810,13 @@ static const struct ad7380_chip_info adaq4370_4_chip_= info =3D { .has_hardware_gain =3D true, .available_scan_masks =3D ad7380_4_channel_scan_masks, .timing_specs =3D &ad7380_4_timing, + .max_conversion_rate_hz =3D 2 * MEGA, }; =20 static const struct ad7380_chip_info adaq4380_4_chip_info =3D { .name =3D "adaq4380-4", .channels =3D adaq4380_4_channels, + .offload_channels =3D adaq4380_4_offload_channels, .num_channels =3D ARRAY_SIZE(adaq4380_4_channels), .num_simult_channels =3D 4, .supplies =3D adaq4380_supplies, @@ -599,11 +825,13 @@ static const struct ad7380_chip_info adaq4380_4_chip_= info =3D { .has_hardware_gain =3D true, .available_scan_masks =3D ad7380_4_channel_scan_masks, .timing_specs =3D &ad7380_4_timing, + .max_conversion_rate_hz =3D 4 * MEGA, }; =20 static const struct ad7380_chip_info adaq4381_4_chip_info =3D { .name =3D "adaq4381-4", .channels =3D adaq4381_4_channels, + .offload_channels =3D adaq4381_4_offload_channels, .num_channels =3D ARRAY_SIZE(adaq4381_4_channels), .num_simult_channels =3D 4, .supplies =3D adaq4380_supplies, @@ -614,6 +842,11 @@ static const struct ad7380_chip_info adaq4381_4_chip_i= nfo =3D { .timing_specs =3D &ad7380_4_timing, }; =20 +static const struct spi_offload_config ad7380_offload_config =3D { + .capability_flags =3D SPI_OFFLOAD_CAP_TRIGGER | + SPI_OFFLOAD_CAP_RX_STREAM_DMA, +}; + struct ad7380_state { const struct ad7380_chip_info *chip_info; struct spi_device *spi; @@ -629,6 +862,13 @@ struct ad7380_state { struct spi_message normal_msg; struct spi_transfer seq_xfer[4]; struct spi_message seq_msg; + struct spi_transfer offload_xfer; + struct spi_message offload_msg; + struct spi_offload *offload; + struct spi_offload_trigger *offload_trigger; + unsigned long offload_trigger_hz; + + int sample_freq_range[3]; /* * DMA (thus cache coherency maintenance) requires the transfer buffers * to live in their own cache lines. @@ -848,7 +1088,7 @@ static int ad7380_update_xfers(struct ad7380_state *st, xfer[2].bits_per_word =3D xfer[3].bits_per_word =3D scan_type->realbits; xfer[2].len =3D xfer[3].len =3D - BITS_TO_BYTES(scan_type->storagebits) * + AD7380_SPI_BYTES(scan_type) * st->chip_info->num_simult_channels; xfer[3].rx_buf =3D xfer[2].rx_buf + xfer[2].len; /* Additional delay required here when oversampling is enabled */ @@ -861,13 +1101,139 @@ static int ad7380_update_xfers(struct ad7380_state = *st, xfer[0].delay.value =3D t_convert; xfer[0].delay.unit =3D SPI_DELAY_UNIT_NSECS; xfer[1].bits_per_word =3D scan_type->realbits; - xfer[1].len =3D BITS_TO_BYTES(scan_type->storagebits) * + xfer[1].len =3D AD7380_SPI_BYTES(scan_type) * st->chip_info->num_simult_channels; } =20 return 0; } =20 +static int ad7380_set_sample_freq(struct ad7380_state *st, int val) +{ + struct spi_offload_trigger_config config =3D { + .type =3D SPI_OFFLOAD_TRIGGER_PERIODIC, + .periodic =3D { + .frequency_hz =3D val, + }, + }; + int ret; + + ret =3D spi_offload_trigger_validate(st->offload_trigger, &config); + if (ret) + return ret; + + st->offload_trigger_hz =3D config.periodic.frequency_hz; + + return 0; +} + +static int ad7380_init_offload_msg(struct ad7380_state *st, + struct iio_dev *indio_dev) +{ + struct spi_transfer *xfer =3D &st->offload_xfer; + struct device *dev =3D &st->spi->dev; + const struct iio_scan_type *scan_type; + int oversampling_ratio; + int ret; + + scan_type =3D iio_get_current_scan_type(indio_dev, + &indio_dev->channels[0]); + if (IS_ERR(scan_type)) + return PTR_ERR(scan_type); + + if (st->chip_info->has_mux) { + int index; + + ret =3D iio_active_scan_mask_index(indio_dev); + if (ret < 0) + return ret; + + index =3D ret; + if (index =3D=3D AD7380_SCAN_MASK_SEQ) { + ret =3D regmap_set_bits(st->regmap, AD7380_REG_ADDR_CONFIG1, + AD7380_CONFIG1_SEQ); + if (ret) + return ret; + + st->seq =3D true; + } else { + ret =3D ad7380_set_ch(st, index); + if (ret) + return ret; + } + } + + ret =3D ad7380_get_osr(st, &oversampling_ratio); + if (ret) + return ret; + + xfer->bits_per_word =3D scan_type->realbits; + xfer->offload_flags =3D SPI_OFFLOAD_XFER_RX_STREAM; + xfer->len =3D AD7380_SPI_BYTES(scan_type) * st->chip_info->num_simult_cha= nnels; + + spi_message_init_with_transfers(&st->offload_msg, xfer, 1); + st->offload_msg.offload =3D st->offload; + + ret =3D spi_optimize_message(st->spi, &st->offload_msg); + if (ret) { + dev_err(dev, "failed to prepare offload msg, err: %d\n", + ret); + return ret; + } + + return 0; +} + +static int ad7380_offload_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad7380_state *st =3D iio_priv(indio_dev); + struct spi_offload_trigger_config config =3D { + .type =3D SPI_OFFLOAD_TRIGGER_PERIODIC, + .periodic =3D { + .frequency_hz =3D st->offload_trigger_hz, + }, + }; + int ret; + + ret =3D ad7380_init_offload_msg(st, indio_dev); + if (ret) + return ret; + + ret =3D spi_offload_trigger_enable(st->offload, st->offload_trigger, &con= fig); + if (ret) + spi_unoptimize_message(&st->offload_msg); + + return ret; +} + +static int ad7380_offload_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad7380_state *st =3D iio_priv(indio_dev); + int ret; + + if (st->seq) { + ret =3D regmap_update_bits(st->regmap, + AD7380_REG_ADDR_CONFIG1, + AD7380_CONFIG1_SEQ, + FIELD_PREP(AD7380_CONFIG1_SEQ, 0)); + if (ret) + return ret; + + st->seq =3D false; + } + + spi_offload_trigger_disable(st->offload, st->offload_trigger); + + spi_unoptimize_message(&st->offload_msg); + + return 0; +} + +static const struct iio_buffer_setup_ops ad7380_offload_buffer_setup_ops = =3D { + .postenable =3D ad7380_offload_buffer_postenable, + .predisable =3D ad7380_offload_buffer_predisable, +}; + static int ad7380_triggered_buffer_preenable(struct iio_dev *indio_dev) { struct ad7380_state *st =3D iio_priv(indio_dev); @@ -998,7 +1364,7 @@ static int ad7380_read_direct(struct ad7380_state *st,= unsigned int scan_index, if (ret < 0) return ret; =20 - if (scan_type->storagebits > 16) { + if (scan_type->realbits > 16) { if (scan_type->sign =3D=3D 's') *val =3D sign_extend32(*(u32 *)(st->scan_data + 4 * index), scan_type->realbits - 1); @@ -1079,6 +1445,9 @@ static int ad7380_read_raw(struct iio_dev *indio_dev, if (ret) return ret; =20 + return IIO_VAL_INT; + case IIO_CHAN_INFO_SAMP_FREQ: + *val =3D st->offload_trigger_hz; return IIO_VAL_INT; default: return -EINVAL; @@ -1090,6 +1459,8 @@ static int ad7380_read_avail(struct iio_dev *indio_de= v, const int **vals, int *type, int *length, long mask) { + struct ad7380_state *st =3D iio_priv(indio_dev); + switch (mask) { case IIO_CHAN_INFO_OVERSAMPLING_RATIO: *vals =3D ad7380_oversampling_ratios; @@ -1097,6 +1468,10 @@ static int ad7380_read_avail(struct iio_dev *indio_d= ev, *type =3D IIO_VAL_INT; =20 return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SAMP_FREQ: + *vals =3D st->sample_freq_range; + *type =3D IIO_VAL_INT; + return IIO_AVAIL_RANGE; default: return -EINVAL; } @@ -1166,6 +1541,10 @@ static int ad7380_write_raw(struct iio_dev *indio_de= v, int ret; =20 switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + if (val < 1) + return -EINVAL; + return ad7380_set_sample_freq(st, val); case IIO_CHAN_INFO_OVERSAMPLING_RATIO: if (!iio_device_claim_direct(indio_dev)) return -EBUSY; @@ -1395,6 +1774,53 @@ static int ad7380_init(struct ad7380_state *st, bool= external_ref_en) AD7380_NUM_SDO_LINES)); } =20 +static int ad7380_probe_spi_offload(struct iio_dev *indio_dev, + struct ad7380_state *st) +{ + struct spi_device *spi =3D st->spi; + struct device *dev =3D &spi->dev; + struct dma_chan *rx_dma; + int sample_rate, ret; + + indio_dev->setup_ops =3D &ad7380_offload_buffer_setup_ops; + indio_dev->channels =3D st->chip_info->offload_channels; + /* Just removing the timestamp channel. */ + indio_dev->num_channels--; + + st->offload_trigger =3D devm_spi_offload_trigger_get(dev, st->offload, + SPI_OFFLOAD_TRIGGER_PERIODIC); + if (IS_ERR(st->offload_trigger)) + return dev_err_probe(dev, PTR_ERR(st->offload_trigger), + "failed to get offload trigger\n"); + + sample_rate =3D st->chip_info->max_conversion_rate_hz * + AD7380_NUM_SDO_LINES / st->chip_info->num_simult_channels; + + st->sample_freq_range[0] =3D 1; /* min */ + st->sample_freq_range[1] =3D 1; /* step */ + st->sample_freq_range[2] =3D sample_rate; /* max */ + + /* + * Starting with a quite low frequency, to allow oversampling x32, + * user is then reponsible to adjust the frequency for the specific case. + */ + ret =3D ad7380_set_sample_freq(st, sample_rate / 32); + if (ret) + return ret; + + rx_dma =3D 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 =3D devm_iio_dmaengine_buffer_setup_with_handle(dev, indio_dev, + rx_dma, IIO_BUFFER_DIRECTION_IN); + if (ret) + return dev_err_probe(dev, ret, "cannot setup dma buffer\n"); + + return 0; +} + static int ad7380_probe(struct spi_device *spi) { struct device *dev =3D &spi->dev; @@ -1566,12 +1992,24 @@ static int ad7380_probe(struct spi_device *spi) indio_dev->modes =3D INDIO_DIRECT_MODE; indio_dev->available_scan_masks =3D st->chip_info->available_scan_masks; =20 - ret =3D devm_iio_triggered_buffer_setup(dev, indio_dev, - iio_pollfunc_store_time, - ad7380_trigger_handler, - &ad7380_buffer_setup_ops); - if (ret) - return ret; + st->offload =3D devm_spi_offload_get(dev, spi, &ad7380_offload_config); + ret =3D PTR_ERR_OR_ZERO(st->offload); + if (ret && ret !=3D -ENODEV) + return dev_err_probe(dev, ret, "failed to get offload\n"); + + /* If no SPI offload, fall back to low speed usage. */ + if (ret =3D=3D -ENODEV) { + ret =3D devm_iio_triggered_buffer_setup(dev, indio_dev, + iio_pollfunc_store_time, + ad7380_trigger_handler, + &ad7380_buffer_setup_ops); + if (ret) + return ret; + } else { + ret =3D ad7380_probe_spi_offload(indio_dev, st); + if (ret) + return ret; + } =20 ret =3D ad7380_init(st, external_ref_en); if (ret) @@ -1636,3 +2074,4 @@ module_spi_driver(ad7380_driver); MODULE_AUTHOR("Stefan Popa "); MODULE_DESCRIPTION("Analog Devices AD738x ADC driver"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("IIO_DMAENGINE_BUFFER"); --=20 2.48.1 From nobody Mon Feb 9 08:49:24 2026 Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 863C822172E for ; Mon, 10 Mar 2025 17:41:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741628475; cv=none; b=oih3BokfONCqjFkStBwfhXhb2KCCQylxuUWfU297phyYvUs0yVZlObyv8mKtqq1G67vKVyp16epw8NhgUkrAq8e4U4BhpBHIdQE3auMuYLRH1F3mHU4zL5OrLUp/OKIS9Y9OJUcuDiTX8NWwVytD9LGk7fLVFaYW26k1cjJ3opE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741628475; c=relaxed/simple; bh=vap/8qEfDYJND2AdXVA7z71mlnRugvEHBnTI0XUnheM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BzN1QR/4lsfgIx3hwq7qEcIm0/NQ+GvKI+QZ3c8K36+UDzFEj9hbSS2RoEPHE7dXFQAU8+h4NYfIVu48TcnZksnEm6OL5U5QT5bVNEBuicOIyP/isdw75vZ30co+52qcwOit6LWQZL+AM2aNVbi2khsVPS4f/yBxKjNsi5q2WY8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=KpmEM4VC; arc=none smtp.client-ip=209.85.128.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="KpmEM4VC" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-43bb6b0b898so38572365e9.1 for ; Mon, 10 Mar 2025 10:41:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1741628472; x=1742233272; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=HgWPLY44UYfs7OSbFs+4rgP587/bNJC0XV4YHVYL62k=; b=KpmEM4VCpQxR5yAEKq+3oWWvTUofGix+mTld+3nmxJU/Oh8m214gB29pN9TrR6kkVU RrE3PkbvEuhY4lyeEzjEI8nvzocypDdWn2YS5Xrzy30FjrWcrQi7xTG6fP+oRi/iQWRQ WmAEb34+PFXbiypd6pLQLeHVYztSIv4Ytp9EbSySwjq2XL6YeneNg2wkRrwk9QXiU30a R0GtnUadDcv1oVlF5mb3fNUrxKdX5NLbfmvLZqcXQ2T6Jm/4CbYbOfNgLIc7aDjDPgD1 SIaC19V1CgjEBM3IaKMMtD8EadqKE5Q9jh14FsE1MtBR4Jt8GP+bKp/DGKQ88ww5BItn Gbgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741628472; x=1742233272; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=HgWPLY44UYfs7OSbFs+4rgP587/bNJC0XV4YHVYL62k=; b=kWLvi8hmf5WukNRLgzePM6rrxtjo9+1kMqvJsGlyXJZAt9r6KRnNKrJ+5gbsjYIHq9 6IlBq8fVZNjsAgnuAeiLSZvCEz8rfxp3aU+BI3ecXAQPoT5zCd+VqIdrUZg4Gr6PpAvR u0YGfQi3y1sXLcukhZ4/WIiZjuvUI+o5iBHhVxsljSus8IcA2obBiS/BRxXBaRA/1Rwg FoPUzDKouAFEgnEzsBgmyxsrahU5y3cR+LuzqjiZA+VhbmFKaQEyP87mEifYh6BXUv3y HExoeVkixL63Zs/l9RUbUKDMwomCjqgeB+cTGsQISn835i57E9or/xDO3pM0B59Q9VDR Jr3Q== X-Forwarded-Encrypted: i=1; AJvYcCWLued0aG9Bpzh9Guvi/O2mXDw0w3Hood4HbcZvn32cFUYCeFKbfr5SpBAUqoVC+f4urwlKJJAg0PWvaxQ=@vger.kernel.org X-Gm-Message-State: AOJu0YyUw0r396g7oULAisOqedDn1OBjubE1QKOE0hepYlzZ+sAoy2vf rxaLGWJrhqYpbTLm/PH3MEBkUx7KStvLOkluJOXAY1oVTytqzWPlpRoCSgNEzhk= X-Gm-Gg: ASbGnctRnCWiVCJzWbMdhbmjF2F+zaEEAL61BS6ekUPEtZh8plTKF4EQPM0+j0DXT0k WXixIAuftY58Lh82T8x6hV9qvG+Xd0GbTbg3QNfkQKhLMHwNYFQZ8wgGW1ihHJpqK7AMpQAPOCc x5NKGNmFzkFuh0vXCgyqWxGhbCK3/pwDDq8HYE/x26XkS0FnfNqXyK7N5/iuHZ6wYUhEwUZhoHV Hi6KOwYIiaPRBgFnCzRB2PliD4d1ZGVIQ50hBaFQ3lOsccgpg2/N3tXRiKxo7OEEtStZONqr0V7 WVoo64Mty09Dm3UWPEqo95ujMXjbTQVQTh7ZNfFvpypguPuFAoKRD1aeY2WLnqmC9iMytF7nlTD eGRAoyGnL08lJXYHQh4M= X-Google-Smtp-Source: AGHT+IF2E0/FEPYOs2Ol5yXnd/QF0za9bgmKGmRzY5a5rBVIupAH5/HrBOSGOMwS07vxF3l2bXd4bA== X-Received: by 2002:a5d:5f94:0:b0:38f:4d20:4a17 with SMTP id ffacd0b85a97d-392641bcf76mr754572f8f.13.1741628471882; Mon, 10 Mar 2025 10:41:11 -0700 (PDT) Received: from [127.0.1.1] (host-82-56-170-15.retail.telecomitalia.it. [82.56.170.15]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3912bfba8a9sm15597038f8f.9.2025.03.10.10.41.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Mar 2025 10:41:11 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Mon, 10 Mar 2025 18:39:53 +0100 Subject: [PATCH v4 2/2] doc: iio: ad7380: describe offload support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250310-wip-bl-spi-offload-ad7380-v4-2-b184b37b7c72@baylibre.com> References: <20250310-wip-bl-spi-offload-ad7380-v4-0-b184b37b7c72@baylibre.com> In-Reply-To: <20250310-wip-bl-spi-offload-ad7380-v4-0-b184b37b7c72@baylibre.com> To: Jonathan Cameron , Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , David Lechner , Jonathan Corbet Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, Angelo Dureghello X-Mailer: b4 0.14.2 From: Angelo Dureghello Add a section to the ad7380 documentation describing how to use the driver with SPI offloading. Signed-off-by: Angelo Dureghello --- Documentation/iio/ad7380.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Documentation/iio/ad7380.rst b/Documentation/iio/ad7380.rst index 35232a0e3ad730c19b5201b74280bdb6deaa9667..24a92a1c4371db6b59ef47edf06= cee860641ebbf 100644 --- a/Documentation/iio/ad7380.rst +++ b/Documentation/iio/ad7380.rst @@ -178,6 +178,24 @@ Unimplemented features - Power down mode - CRC indication =20 +SPI offload support +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +To be able to achieve the maximum sample rate, the driver can be used with= the +`AXI SPI Engine`_ to provide SPI offload support. + +.. _AXI SPI Engine: http://analogdevicesinc.github.io/hdl/projects/pulsar_= adc/index.html + +When SPI offload is being used, some attributes will be different. + +* ``trigger`` directory is removed. +* ``in_voltage0_sampling_frequency`` attribute is added for setting the sa= mple + rate. +* ``in_voltage0_sampling_frequency_available`` attribute is added for quer= ying + the max sample rate. +* ``timestamp`` channel is removed. +* Buffer data format may be different compared to when offload is not used, + e.g. the ``in_voltage0_type`` attribute. =20 Device buffers =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --=20 2.48.1