From patchwork Fri Nov 15 20:18:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 843780 Received: from mail-oo1-f49.google.com (mail-oo1-f49.google.com [209.85.161.49]) (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 005E61D5CF1 for ; Fri, 15 Nov 2024 20:18:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731701933; cv=none; b=LjGedzHjtU0fg3SuyRs84ObKpIfDQ08Q77Oe+ycaBCFTh/ysZN4lUxZld0YBlC5EQM7KQ51EatVTqsuLmTecgL+GUzflVJzLQRjZ3Hjvl+p+A54sO2FyBNS9BwMGvp+3vZAb9wRYC4H/WS89zZLIndmTqzZwv2CbvpyvH3FCydE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731701933; c=relaxed/simple; bh=TOgkx/m/6FrPpC7rnBHkuU0C5+5RkznAgqFoBKD3ESA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HmAVwtxK/iHYmFvOm04pgNyHmgVE1Kv1KXVJfJxi8l4o8KuikEUBIhQXsf06Sm1/vPCZ+JrwX6zUlems96fy+AfwJql107QMlbre+yTlHgcoWKbGQRtsJV8s4g3aWX+U/rfQkdKsgxGXoq23FH6C9D2nz2dJijkVBY/s+MyxTIw= 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=rtNuM5JR; arc=none smtp.client-ip=209.85.161.49 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="rtNuM5JR" Received: by mail-oo1-f49.google.com with SMTP id 006d021491bc7-5ee645cf74fso571913eaf.2 for ; Fri, 15 Nov 2024 12:18:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1731701930; x=1732306730; 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=A3CE0yheT4DVVry1IgtvS9L1hkM/iTvAih5hXhwRp+I=; b=rtNuM5JRgCZEpNamsauUYR59uY6Y0RXY6f4zloZYI2Mre+8Ks6LQQjz9bmQ1xp6r8c l8G6McpUKvu55X+HpzMDj5xITsF9KUGQRNRme9K0rAu/fpyf7m5oj1yI8z550br/uU1Z bWXTs+PvKWkQGnHyxMWe3ovyCcMeyqhVQ6LBTQUQsSIP3H7uTt80Z5/h2EWmWn2/mEIF uSRXniwKFumkJIBJ0uIMiJ/Tsvg+rNb+BlwRvKG3zTEztCLtKBA/QUaSy0SUEFuxYIjL PeAD9UDm7Oa8yP6g56FvDDjxI03g2YJe/r2uYxON39vJwspgxjNlWLjgf40A+9m+Sfh1 6KmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731701930; x=1732306730; 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=A3CE0yheT4DVVry1IgtvS9L1hkM/iTvAih5hXhwRp+I=; b=vba3vInTNcbCRyC41rXbyisENQTHIDtrMjy0O+KKZH01SK+D+SjTxV1Jrrmq2Eaydx MTtfU9ych5LZ62abgsjHoPFfFbf0n466hawODN7ZFN2sZWfXB9jK9OElY5uy8meBLv+O zXL6uLYRMtShyvpMVyTRMIURXrxbBgsIv4D9DI2ZnLbzzZ3H3uj8KzlqzmAlmYBa6WqL 7DoaFfhZkgGUHqn8fZr7W+ItclxWSdkC1hikqh25l0KlzfxMkMeyULWYPax6Esy1FDll GDjThFLii11aUwvUtXg47ZhdGdW7/Y9WEHbgw/ISA8HTNZLKMLd0it/Sk1q2chJzYf7e 3+4w== X-Forwarded-Encrypted: i=1; AJvYcCWrFfuipnynQajAexreMhlVtqb0ACfxMEyBmcA/piMmRNWahHHLqztOoBEdY+6XDPiit5Ctanket9Q=@vger.kernel.org X-Gm-Message-State: AOJu0YzNEHnSz328AwNAWtrCGIBuIdqzRrCM7j6S0KYjW42RFpk1SwZ1 +jr/f9TYcv3W9O1aRDI5+B/yYxIkzSCVtwHnRDN+ZgIvB+nvUAhu4511bEY78uU= X-Google-Smtp-Source: AGHT+IGYDEqISIJl9ctlQZb+4mYv7YJKqQHrlE6VL4Ec7aVtP9KKyc8lkY2pH9Td0Cs929GYSGBYnA== X-Received: by 2002:a05:6871:5292:b0:287:20ea:2db2 with SMTP id 586e51a60fabf-2962e0369a3mr4342642fac.25.1731701930037; Fri, 15 Nov 2024 12:18:50 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71a780ea62esm748978a34.5.2024.11.15.12.18.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Nov 2024 12:18:49 -0800 (PST) From: David Lechner Date: Fri, 15 Nov 2024 14:18:40 -0600 Subject: [PATCH v5 01/16] spi: add basic support for SPI offloading Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241115-dlech-mainline-spi-engine-offload-2-v5-1-bea815bd5ea5@baylibre.com> References: <20241115-dlech-mainline-spi-engine-offload-2-v5-0-bea815bd5ea5@baylibre.com> In-Reply-To: <20241115-dlech-mainline-spi-engine-offload-2-v5-0-bea815bd5ea5@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, David Lechner X-Mailer: b4 0.14.1 Add the basic infrastructure to support SPI offload providers and consumers. SPI offloading is a feature that allows the SPI controller to perform transfers without any CPU intervention. This is useful, e.g. for high-speed data acquisition. SPI controllers with offload support need to implement the get_offload and put_offload callbacks and can use the devm_spi_offload_alloc() to allocate offload instances. SPI peripheral drivers will call devm_spi_offload_get() to get a reference to the matching offload instance. This offload instance can then be attached to a SPI message to request offloading that message. It is expected that SPI controllers with offload support will check for the offload instance in the SPI message in the ctlr->optimize_message() callback and handle it accordingly. CONFIG_SPI_OFFLOAD is intended to be a select-only option. Both consumer and provider drivers should `select SPI_OFFLOAD` in their Kconfig to ensure that the SPI core is built with offload support. Signed-off-by: David Lechner --- v5 changes: * Don't include linux/property.h (moved to later patch). * Only allocate single offload instance instead of array. * Allocate *priv separately to avoid alignment issues. * Add put_offload() callback instead of assuming devm semantics. * Drop struct spi_offload::spi. It was only being used as a flag. * Don't get/put struct spi_offload::provider_dev. * Add MAINTAINERS entry for me as reviewer for anything related to SPI offload. v4 changes: * SPI offload functions moved to a separate file instead of spi.c (spi.c is already too long). * struct spi_offload and devm_spi_offload_get() are back, similar to but improved over v1. This avoids having to pass the function ID string to every function call and re-lookup the offload instance. * offload message prepare/unprepare functions are removed. Instead the existing optimize/unoptimize functions should be used. Setting spi_message::offload pointer is used as a flag to differentiate between an offloaded message and a regular message. v3 changes: * Minor changes to doc comments. * Changed to use phandle array for spi-offloads. * Changed id to string to make use of spi-offload-names. v2 changes: * This is a rework of "spi: add core support for controllers with offload capabilities" from v1. * The spi_offload_get() function that Nuno didn't like is gone. Instead, there is now a mapping callback that uses the new generic devicetree binding to request resources automatically when a SPI device is probed. * The spi_offload_enable/disable() functions for dealing with hardware triggers are deferred to a separate patch. * This leaves adding spi_offload_prepare/unprepare() which have been reworked to be a bit more robust. --- MAINTAINERS | 6 +++ drivers/spi/Kconfig | 3 ++ drivers/spi/Makefile | 1 + drivers/spi/spi-offload.c | 103 ++++++++++++++++++++++++++++++++++++++++ include/linux/spi/spi-offload.h | 60 +++++++++++++++++++++++ include/linux/spi/spi.h | 18 +++++++ 6 files changed, 191 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index bcc42036d635..75c8ca9a8584 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22019,6 +22019,12 @@ F: Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml F: drivers/mtd/spi-nor/ F: include/linux/mtd/spi-nor.h +SPI OFFLOAD +R: David Lechner +F: drivers/spi/spi-offload.c +F: include/linux/spi/spi-offload.h +K: spi_offload + SPI SUBSYSTEM M: Mark Brown L: linux-spi@vger.kernel.org diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index f51f9466e518..cdc483b0ec5c 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -55,6 +55,9 @@ config SPI_MEM This extension is meant to simplify interaction with SPI memories by providing a high-level interface to send memory-like commands. +config SPI_OFFLOAD + bool + comment "SPI Master Controller Drivers" config SPI_AIROHA_SNFI diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index aea5e54de195..39025ae5364d 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -10,6 +10,7 @@ ccflags-$(CONFIG_SPI_DEBUG) := -DDEBUG obj-$(CONFIG_SPI_MASTER) += spi.o obj-$(CONFIG_SPI_MEM) += spi-mem.o obj-$(CONFIG_SPI_MUX) += spi-mux.o +obj-$(CONFIG_SPI_OFFLOAD) += spi-offload.o obj-$(CONFIG_SPI_SPIDEV) += spidev.o obj-$(CONFIG_SPI_LOOPBACK_TEST) += spi-loopback-test.o diff --git a/drivers/spi/spi-offload.c b/drivers/spi/spi-offload.c new file mode 100644 index 000000000000..5ded7aecf9fc --- /dev/null +++ b/drivers/spi/spi-offload.c @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024 Analog Devices Inc. + * Copyright (C) 2024 BayLibre, SAS + */ + +#define DEFAULT_SYMBOL_NAMESPACE SPI_OFFLOAD + +#include +#include +#include +#include +#include +#include +#include + +struct spi_controller_and_offload { + struct spi_controller *controller; + struct spi_offload *offload; +}; + +/** + * devm_spi_offload_alloc() - Allocate offload instance + * @dev: Device for devm purposes and assigned to &struct spi_offload.provider_dev + * @priv_size: Size of private data to allocate + * + * Offload providers should use this to allocate offload instances. + * + * Return: Pointer to new offload instance or error on failure. + */ +struct spi_offload *devm_spi_offload_alloc(struct device *dev, + size_t priv_size) +{ + struct spi_offload *offload; + void *priv; + + offload = devm_kzalloc(dev, sizeof(*offload), GFP_KERNEL); + if (!offload) + return ERR_PTR(-ENOMEM); + + priv = devm_kzalloc(dev, priv_size, GFP_KERNEL); + if (!priv) + return ERR_PTR(-ENOMEM); + + offload->provider_dev = dev; + offload->priv = priv; + + return offload; +} +EXPORT_SYMBOL_GPL(devm_spi_offload_alloc); + +static void spi_offload_put(void *data) +{ + struct spi_controller_and_offload *resource = data; + + resource->controller->put_offload(resource->offload); + kfree(resource); +} + +/** + * devm_spi_offload_get() - Get an offload instance + * @dev: Device for devm purposes + * @spi: SPI device to use for the transfers + * @config: Offload configuration + * + * Peripheral drivers call this function to get an offload instance that meets + * the requirements specified in @config. If no suitable offload instance is + * available, -ENODEV is returned. + * + * Return: Offload instance or error on failure. + */ +struct spi_offload *devm_spi_offload_get(struct device *dev, + struct spi_device *spi, + const struct spi_offload_config *config) +{ + struct spi_controller_and_offload *resource; + int ret; + + if (!spi || !config) + return ERR_PTR(-EINVAL); + + if (!spi->controller->get_offload) + return ERR_PTR(-ENODEV); + + resource = kzalloc(sizeof(*resource), GFP_KERNEL); + if (!resource) + return ERR_PTR(-ENOMEM); + + resource->controller = spi->controller; + resource->offload = spi->controller->get_offload(spi, config); + ret = PTR_ERR_OR_ZERO(resource->offload); + if (ret) { + kfree(resource); + return ERR_PTR(ret); + } + + ret = devm_add_action_or_reset(dev, spi_offload_put, resource); + if (ret) + return ERR_PTR(ret); + + return resource->offload; +} +EXPORT_SYMBOL_GPL(devm_spi_offload_get); diff --git a/include/linux/spi/spi-offload.h b/include/linux/spi/spi-offload.h new file mode 100644 index 000000000000..81b115fc89bf --- /dev/null +++ b/include/linux/spi/spi-offload.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 Analog Devices Inc. + * Copyright (C) 2024 BayLibre, SAS + */ + +/* + * SPI Offloading support. + * + * Some SPI controllers support offloading of SPI transfers. Essentially, this + * is the ability for a SPI controller to perform SPI transfers with minimal + * or even no CPU intervention, e.g. via a specialized SPI controller with a + * hardware trigger or via a conventional SPI controller using a non-Linux MCU + * processor core to offload the work. + */ + +#ifndef __LINUX_SPI_OFFLOAD_H +#define __LINUX_SPI_OFFLOAD_H + +#include + +MODULE_IMPORT_NS(SPI_OFFLOAD); + +struct device; +struct spi_device; + +/* Offload can be triggered by external hardware event. */ +#define SPI_OFFLOAD_CAP_TRIGGER BIT(0) +/* Offload can record and then play back TX data when triggered. */ +#define SPI_OFFLOAD_CAP_TX_STATIC_DATA BIT(1) +/* Offload can get TX data from an external stream source. */ +#define SPI_OFFLOAD_CAP_TX_STREAM_DMA BIT(2) +/* Offload can send RX data to an external stream sink. */ +#define SPI_OFFLOAD_CAP_RX_STREAM_DMA BIT(3) + +/** + * struct spi_offload_config - offload configuration + * + * This is used to request an offload with specific configuration. + */ +struct spi_offload_config { + /** @capability_flags: required capabilities. See %SPI_OFFLOAD_CAP_* */ + u32 capability_flags; +}; + +/** + * struct spi_offload - offload instance + */ +struct spi_offload { + /** @provider_dev: for get/put reference counting */ + struct device *provider_dev; + /** @priv: provider driver private data */ + void *priv; +}; + +struct spi_offload *devm_spi_offload_alloc(struct device *dev, size_t priv_size); +struct spi_offload *devm_spi_offload_get(struct device *dev, struct spi_device *spi, + const struct spi_offload_config *config); + +#endif /* __LINUX_SPI_OFFLOAD_H */ diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 8497f4747e24..c2b24a0909ea 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -31,6 +31,9 @@ struct spi_transfer; struct spi_controller_mem_ops; struct spi_controller_mem_caps; struct spi_message; +struct spi_controller_offload_ops; +struct spi_offload; +struct spi_offload_config; /* * INTERFACES between SPI master-side drivers and SPI slave protocol handlers, @@ -496,6 +499,10 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch * @mem_ops: optimized/dedicated operations for interactions with SPI memory. * This field is optional and should only be implemented if the * controller has native support for memory like operations. + * @get_offload: callback for controllers with offload support to get matching + * offload instance. Implementations should return -ENODEV if no match is + * found. + * @put_offload: release the offload instance acquired by @get_offload. * @mem_caps: controller capabilities for the handling of memory operations. * @unprepare_message: undo any work done by prepare_message(). * @target_abort: abort the ongoing transfer request on an SPI target controller @@ -740,6 +747,10 @@ struct spi_controller { const struct spi_controller_mem_ops *mem_ops; const struct spi_controller_mem_caps *mem_caps; + struct spi_offload *(*get_offload)(struct spi_device *spi, + const struct spi_offload_config *config); + void (*put_offload)(struct spi_offload *offload); + /* GPIO chip select */ struct gpio_desc **cs_gpiods; bool use_gpio_descriptors; @@ -1108,6 +1119,7 @@ struct spi_transfer { * @state: for use by whichever driver currently owns the message * @opt_state: for use by whichever driver currently owns the message * @resources: for resource management when the SPI message is processed + * @offload: (optional) offload instance used by this message * * A @spi_message is used to execute an atomic sequence of data transfers, * each represented by a struct spi_transfer. The sequence is "atomic" @@ -1168,6 +1180,12 @@ struct spi_message { */ void *opt_state; + /* + * Optional offload instance used by this message. This must be set + * by the peripheral driver before calling spi_optimize_message(). + */ + struct spi_offload *offload; + /* List of spi_res resources when the SPI message is processed */ struct list_head resources; }; From patchwork Fri Nov 15 20:18:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 843779 Received: from mail-oa1-f47.google.com (mail-oa1-f47.google.com [209.85.160.47]) (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 BF9321E2846 for ; Fri, 15 Nov 2024 20:18:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731701935; cv=none; b=sxEyNWf4vcEi5zrxXyi0/KpQqinHgVWXPdHCgvN/dxrE5QGweOA7q5Y9FE4F5UAWiiSSwLViI9lMo2mkKQY625nPykSX8lbRouWujBtZaTXeSQMUddXNoQrRjcDa7zlZ+xu2GdZNJupDYXntIpI7N1rPQlFT/eqAq8h60/afknI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731701935; c=relaxed/simple; bh=/brcg85kbnd2G8W/XlwOERT7c14hy3w6WyG/qyK3teM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=P73hO2F2ZVfTGUE9zfCJUadsHd3XjtjXR0u/lqRKbXpx9cH86sz8Ly0aiBVWSqGrw/2vJIzBUWzJqHao8Qv1Bg5B8uMZr2TJwvP55srfRPhpXrnr6/DFBY/q1cGTrZAj5YR98PcV0Ud351sIS/NdYoII0sUTtsw9R/k0Z8gd1g4= 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=hleUTxoT; arc=none smtp.client-ip=209.85.160.47 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="hleUTxoT" Received: by mail-oa1-f47.google.com with SMTP id 586e51a60fabf-290ff24354dso13282fac.0 for ; Fri, 15 Nov 2024 12:18:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1731701933; x=1732306733; 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=mRU4AU2p10ANc+DkhnwT4CXPMLQZx70yMguYOCpfFSY=; b=hleUTxoT1VZU4cAgMHLKRXPdHPg2xv04kUBAv51NpVmEObB8PM0ApWZ4NZZ4kz1tX5 Wm67MnmAiJYgZVLkrcrrUkEiIM0XrfeRm0HYii9qRUYiNHWOzm7RfJcVx2ijoK4dEyNW 9DnLfERBZ56Lr20mMv0izH8om2eSTbU+W+e/Y9nWFSFAnhy6IVDcfl0v/Y6twqBBNjhJ aFdBu3U7d/jiollqz+W5nP9L89N1RcbJEvOqhgOBQELrU4gSaOu3h3Ves0C2wWW3b1P1 kVENjuDeG8dgjXcCfMKq+VOPLskrpX6yq4ZcWi9Lzpge6NltfGnLahseieiSrlYs3jSP 0urA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731701933; x=1732306733; 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=mRU4AU2p10ANc+DkhnwT4CXPMLQZx70yMguYOCpfFSY=; b=bzGnVyuW7BYGCZYjICFSxdLdEo3IDjgvS3pFnShRWf9V8vMq/Fi8RszECF9v6U0l6K ayhDiRUTEdRcpRYW7+LUHwnJcwR1wtRB6Cr4RMxXPtPaqRAAYk5IJpZsu6MLb6UMqwLQ czcHyg5MeNFuKl1HbDZryH4cjudHAzNVHagk9S0hHdDC/INsj3HQr2fIjClCxjSUmG/u vYFW1UrZfL2mimhFjiGQoNt1sBtFFwe+JOZ5+61LQ9o6GpCPXlPBlnf/2EB1qtbLzXur 4VcP9ptt1URSHXS5820Is+m9Hy0aDXEDwXlHwzWgmB9P6zEV3L4TPZga7XT4YyIAYgH7 RN/w== X-Forwarded-Encrypted: i=1; AJvYcCX7w+RqVep/9jnfxtbnApfr+2MVGHF1NMTFN6Du7lowjQAjqfZjOJoazjF2YzFbLaeMvLs7WarwgYc=@vger.kernel.org X-Gm-Message-State: AOJu0YyYjDiPQ/SF8UcK2Se1PvAW+/46u7RnObKKMbxyaH8RJKAdadm4 uhTcyyOcPUdzZ+eQE97clzcxRapWVxznHAvAmtnzw8xk34JxwwE1Pv7G196QnPU= X-Google-Smtp-Source: AGHT+IEq4dvxzsxFEL++1N4Levf1DEfOWHAxo1ifVYZbayZTOwOVP2E9GaVwjZAe8BvQjJvrahEhEQ== X-Received: by 2002:a05:6870:96a2:b0:287:0:9ecc with SMTP id 586e51a60fabf-2962dfe8e32mr4184189fac.33.1731701932849; Fri, 15 Nov 2024 12:18:52 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71a780ea62esm748978a34.5.2024.11.15.12.18.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Nov 2024 12:18:52 -0800 (PST) From: David Lechner Date: Fri, 15 Nov 2024 14:18:42 -0600 Subject: [PATCH v5 03/16] spi: dt-bindings: add trigger-source.yaml Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241115-dlech-mainline-spi-engine-offload-2-v5-3-bea815bd5ea5@baylibre.com> References: <20241115-dlech-mainline-spi-engine-offload-2-v5-0-bea815bd5ea5@baylibre.com> In-Reply-To: <20241115-dlech-mainline-spi-engine-offload-2-v5-0-bea815bd5ea5@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, David Lechner X-Mailer: b4 0.14.1 Add a new binding for SPI offload trigger sources. Signed-off-by: David Lechner --- v5 changes: * Add MAINTAINERS entry. v4 changes: new patch in v4. FWIW, this is essentially identical to the leds trigger-source binding. --- .../devicetree/bindings/spi/trigger-source.yaml | 28 ++++++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 29 insertions(+) diff --git a/Documentation/devicetree/bindings/spi/trigger-source.yaml b/Documentation/devicetree/bindings/spi/trigger-source.yaml new file mode 100644 index 000000000000..d64367726af2 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/trigger-source.yaml @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spi/trigger-source.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Trigger source providers for SPI offloads + +maintainers: + - David Lechner + +description: + Each trigger source provider should be represented by a device tree node. It + may be e.g. a SPI peripheral chip or a clock source. + +properties: + '#trigger-source-cells': + description: + Number of cells in a source trigger. Typically 0 for nodes of simple + trigger sources. For nodes with more than one output signal, the first + cell be used to specify which output signal to use. If the same signal is + available on more than one pin, the second cell can be used to specify + which pin to use. + enum: [ 0, 1, 2 ] + +additionalProperties: true + +... diff --git a/MAINTAINERS b/MAINTAINERS index 75c8ca9a8584..91a4a7eb6194 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22021,6 +22021,7 @@ F: include/linux/mtd/spi-nor.h SPI OFFLOAD R: David Lechner +F: Documentation/devicetree/bindings/spi/trigger-source.yaml F: drivers/spi/spi-offload.c F: include/linux/spi/spi-offload.h K: spi_offload From patchwork Fri Nov 15 20:18:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 843778 Received: from mail-oo1-f45.google.com (mail-oo1-f45.google.com [209.85.161.45]) (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 99FFF1E5733 for ; Fri, 15 Nov 2024 20:18:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731701941; cv=none; b=Qo8zzeg5EQg2+bi3QFjHlIu24Mh7e+7C+DcEvwdeQIMEpiOQknl6CcrJoYZfIY1Otr+WJgvoqsCTEUvlmhvOxF7qqn10G1u4/01gJqw4cwgCAUX7h1nwVz0zs+30EG/9sk3uVBw3Kb8rc66oVqN7+oxrCLkctwysRZ4aSVnxCYo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731701941; c=relaxed/simple; bh=EOrNOpVWi5EnXRP0UHniNwzvlTT9ETmHZWZMFC0dRL4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oaFajRRWlsjd1lTPJ7HPTfUH9lTqN30fqS1ok6MzVXwGMxEEa+lU2rAcsBC0y6cijyOB8ClnOoFtQ2FZ9bsl/S6zzkKmN9W5vHolx8zYzKEHSlwFntqSIQAeXoiZMnFpbtlGf7IMY9oer7RUmD3jAY2yGIY5bC5I0htr9/CkuNI= 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=k1rg/IUX; arc=none smtp.client-ip=209.85.161.45 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="k1rg/IUX" Received: by mail-oo1-f45.google.com with SMTP id 006d021491bc7-5ee645cf763so1181051eaf.2 for ; Fri, 15 Nov 2024 12:18:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1731701938; x=1732306738; 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=t7IS98DAXMrAPkmBeqmORVUNuKNfq4F6AMKjYOvJmjo=; b=k1rg/IUXPQIFLvPDLcEDyAKj8U007qJy/DfuA26fiGdk5FD0ZVt8Po4OtNm8udWu7E II1dY03Zu548P0r62f8RGgt8nzKZCA/ehTpcBRr1k6Ae66YUCv3PLRTV89Fuk6cdGNBN r9IDf7v5rOkh4Y95oPRdx8PfnGpMtZG/sCvNTAcLCUJxLxHxLltAu/5Az8Gq8QwxnXg0 MbHsc+O8Il3A0K2lZ99iSZnG9dSKv51Jxt+S61fM7CgjocGp94G3xU3VxUr1RJLyYm3I x8HXN1BJ5AMZYijdfB2xJxNtgxUvZAOXpSIukuUmqpAZZw7AeZX9Md1wx/zL0hKcqlhH FgoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731701938; x=1732306738; 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=t7IS98DAXMrAPkmBeqmORVUNuKNfq4F6AMKjYOvJmjo=; b=c4DoxvVkrN/LfED8zN3s/6OOYVNaedqcogDu1n5yvnmvLnJj86+HFwcY+06H8e/6jC ooou6ZtN6ir50iWTUTuxigz425jS4ySRqbNOPOYWLGXSF2Da+PJ80p8Sht0EjJYNe76N yV1koLg2QksgA82wFeusJNenchG6Ea5DATLnMwwU2L+tlfLhUsJpZtJlAGgDjmAzY8h1 YZ+s/kJpSbs0cKiJ7yKYAgjOR/EbQ9IRzi82UhAhFTSTDE3vMpK0YKBVeUgg4RY7gE1F VeKUr4m7hZmho8m+EX6knavKtvGeDNEG2yFCYThp1ONzVkDXgMx3sRXP7QxoIbnIPJwc Kq8g== X-Forwarded-Encrypted: i=1; AJvYcCVjSZ8/0+y+ioxKg8udQA4mBj15GENvbXU0lDvaQwAcJCXNnnPK3ecC8RCmwiSZQjIogWJPnsmdps4=@vger.kernel.org X-Gm-Message-State: AOJu0YyP1h8bXy0lHVHvC3T9joyCbr7qs1kl9/RMu+QIwCHOngEdjavw ShWS1HpIsVzR2KDfEcdw23vzJZdHWgSTQI/B0hZBuli3vhiDkzRzgerkd8gThRI= X-Google-Smtp-Source: AGHT+IFHeOlL2szpnhn4w4uUrf+kcWOlOBXXrP/zlahKkvyGqcUo6Oac5nm5vBqKn+mlHYLrAPqrcQ== X-Received: by 2002:a05:6820:4c88:b0:5eb:c6ba:783b with SMTP id 006d021491bc7-5eeab29d4a5mr3913047eaf.1.1731701937692; Fri, 15 Nov 2024 12:18:57 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71a780ea62esm748978a34.5.2024.11.15.12.18.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Nov 2024 12:18:57 -0800 (PST) From: David Lechner Date: Fri, 15 Nov 2024 14:18:44 -0600 Subject: [PATCH v5 05/16] spi: offload-trigger: add PWM trigger driver Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241115-dlech-mainline-spi-engine-offload-2-v5-5-bea815bd5ea5@baylibre.com> References: <20241115-dlech-mainline-spi-engine-offload-2-v5-0-bea815bd5ea5@baylibre.com> In-Reply-To: <20241115-dlech-mainline-spi-engine-offload-2-v5-0-bea815bd5ea5@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, David Lechner X-Mailer: b4 0.14.1 Add a new driver for a generic PWM trigger for SPI offloads. Signed-off-by: David Lechner --- v5 changes: * Updated to accommodate changes in other patches in this series. * Add MAINTAINERS entry. v4 changes: new patch in v4 --- MAINTAINERS | 1 + drivers/spi/Kconfig | 12 +++ drivers/spi/Makefile | 3 + drivers/spi/spi-offload-trigger-pwm.c | 162 ++++++++++++++++++++++++++++++++++ 4 files changed, 178 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index a43532a1edde..36a40aaa026a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22023,6 +22023,7 @@ SPI OFFLOAD R: David Lechner F: Documentation/devicetree/bindings/spi/trigger-pwm.yaml F: Documentation/devicetree/bindings/spi/trigger-source.yaml +F: drivers/spi/spi-offload-trigger-pwm.c F: drivers/spi/spi-offload.c F: include/linux/spi/spi-offload.h K: spi_offload diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index cdc483b0ec5c..867d4b55bef9 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -1308,4 +1308,16 @@ endif # SPI_SLAVE config SPI_DYNAMIC def_bool ACPI || OF_DYNAMIC || SPI_SLAVE +if SPI_OFFLOAD + +comment "SPI Offload triggers" + +config SPI_OFFLOAD_TRIGGER_PWM + tristate "SPI offload trigger using PWM" + depends on PWM + help + Generic SPI offload trigger implemented using PWM output. + +endif # SPI_OFFLOAD + endif # SPI diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 39025ae5364d..9396d32e1994 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -163,3 +163,6 @@ obj-$(CONFIG_SPI_AMD) += spi-amd.o # SPI slave protocol handlers obj-$(CONFIG_SPI_SLAVE_TIME) += spi-slave-time.o obj-$(CONFIG_SPI_SLAVE_SYSTEM_CONTROL) += spi-slave-system-control.o + +# SPI offload triggers +obj-$(CONFIG_SPI_OFFLOAD_TRIGGER_PWM) += spi-offload-trigger-pwm.o diff --git a/drivers/spi/spi-offload-trigger-pwm.c b/drivers/spi/spi-offload-trigger-pwm.c new file mode 100644 index 000000000000..7e1b4a80becc --- /dev/null +++ b/drivers/spi/spi-offload-trigger-pwm.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024 Analog Devices Inc. + * Copyright (C) 2024 BayLibre, SAS + * + * Generic PWM trigger for SPI offload. + */ + +#include +#include +#include +#include +#include + +struct spi_offload_trigger_pwm_state { + struct device *dev; + struct pwm_device *pwm; +}; + +static bool spi_offload_trigger_pwm_match(struct spi_offload_trigger *trigger, + enum spi_offload_trigger_type type, + u64 *args, u32 nargs) +{ + if (nargs) + return false; + + return type == SPI_OFFLOAD_TRIGGER_PERIODIC; +} + +static int spi_offload_trigger_pwm_validate(struct spi_offload_trigger *trigger, + struct spi_offload_trigger_config *config) +{ + struct spi_offload_trigger_pwm_state *st = spi_offload_trigger_get_priv(trigger); + struct spi_offload_trigger_periodic *periodic = &config->periodic; + struct pwm_waveform wf = { }; + int ret; + + if (config->type != SPI_OFFLOAD_TRIGGER_PERIODIC) + return -EINVAL; + + if (!periodic->frequency_hz) + return -EINVAL; + + wf.period_length_ns = DIV_ROUND_UP_ULL(NSEC_PER_SEC, periodic->frequency_hz); + /* REVISIT: 50% duty-cycle for now - may add config parameter later */ + wf.duty_length_ns = wf.period_length_ns / 2; + + ret = pwm_round_waveform_might_sleep(st->pwm, &wf); + if (ret < 0) + return ret; + + periodic->frequency_hz = DIV_ROUND_UP_ULL(NSEC_PER_SEC, wf.period_length_ns); + + return 0; +} + +static int spi_offload_trigger_pwm_enable(struct spi_offload_trigger *trigger, + struct spi_offload_trigger_config *config) +{ + struct spi_offload_trigger_pwm_state *st = spi_offload_trigger_get_priv(trigger); + struct spi_offload_trigger_periodic *periodic = &config->periodic; + struct pwm_waveform wf = { }; + + if (config->type != SPI_OFFLOAD_TRIGGER_PERIODIC) + return -EINVAL; + + if (!periodic->frequency_hz) + return -EINVAL; + + wf.period_length_ns = DIV_ROUND_UP_ULL(NSEC_PER_SEC, periodic->frequency_hz); + /* REVISIT: 50% duty-cycle for now - may add config parameter later */ + wf.duty_length_ns = wf.period_length_ns / 2; + + return pwm_set_waveform_might_sleep(st->pwm, &wf, false); +} + +static void spi_offload_trigger_pwm_disable(struct spi_offload_trigger *trigger) +{ + struct spi_offload_trigger_pwm_state *st = spi_offload_trigger_get_priv(trigger); + struct pwm_waveform wf; + int ret; + + ret = pwm_get_waveform_might_sleep(st->pwm, &wf); + if (ret < 0) { + dev_err(st->dev, "failed to get waveform: %d\n", ret); + return; + } + + wf.duty_length_ns = 0; + + ret = pwm_set_waveform_might_sleep(st->pwm, &wf, false); + if (ret < 0) + dev_err(st->dev, "failed to disable PWM: %d\n", ret); +} + +static const struct spi_offload_trigger_ops spi_offload_trigger_pwm_ops = { + .match = spi_offload_trigger_pwm_match, + .validate = spi_offload_trigger_pwm_validate, + .enable = spi_offload_trigger_pwm_enable, + .disable = spi_offload_trigger_pwm_disable, +}; + +static void spi_offload_trigger_pwm_release(void *data) +{ + pwm_disable(data); +} + +static int spi_offload_trigger_pwm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct spi_offload_trigger_info info = { + .fwnode = dev_fwnode(dev), + .ops = &spi_offload_trigger_pwm_ops, + }; + struct spi_offload_trigger_pwm_state *st; + struct pwm_state state; + int ret; + + st = devm_kzalloc(&pdev->dev, sizeof(*st), GFP_KERNEL); + if (!st) + return -ENOMEM; + + info.priv = st; + st->dev = dev; + + st->pwm = devm_pwm_get(&pdev->dev, NULL); + if (IS_ERR(st->pwm)) + return dev_err_probe(dev, PTR_ERR(st->pwm), "failed to get PWM\n"); + + /* init with duty_cycle = 0, output enabled to ensure trigger off */ + pwm_init_state(st->pwm, &state); + state.enabled = true; + + ret = pwm_apply_might_sleep(st->pwm, &state); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to apply PWM state\n"); + + ret = devm_add_action_or_reset(dev, spi_offload_trigger_pwm_release, st->pwm); + if (ret) + return ret; + + return devm_spi_offload_trigger_register(dev, &info); +} + +static const struct of_device_id spi_offload_trigger_pwm_of_match_table[] = { + { .compatible = "trigger-pwm" }, + { } +}; +MODULE_DEVICE_TABLE(of, spi_offload_trigger_pwm_of_match_table); + +static struct platform_driver spi_offload_trigger_pwm_driver = { + .driver = { + .name = "trigger-pwm", + .of_match_table = spi_offload_trigger_pwm_of_match_table, + }, + .probe = spi_offload_trigger_pwm_probe, +}; +module_platform_driver(spi_offload_trigger_pwm_driver); + +MODULE_AUTHOR("David Lechner "); +MODULE_DESCRIPTION("Generic PWM trigger"); +MODULE_LICENSE("GPL"); From patchwork Fri Nov 15 20:18:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 843777 Received: from mail-oo1-f51.google.com (mail-oo1-f51.google.com [209.85.161.51]) (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 6AD291E7671 for ; Fri, 15 Nov 2024 20:19:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731701942; cv=none; b=SXyNRUrLY+dHislxSVpFVfxXBIWF2cIHctooLcseHjC7pW+rlUOVjPPHBdtyNCggm3BryypenHsqB6TBz3nKLO0KL5vafBo6qt5xq6kIt//ckMmPEgFyqiQbtonsNWCgldaU+cGLfN7avnSkX/OkiAAkrOOteIrzKb6lTxe0DuQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731701942; c=relaxed/simple; bh=n3gvwTh1zq8LlUg6hocRmmA4Ouflzb8V3XorZLtL5w4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=V+PUziwN2jvl6fiVhNKnnXpkdrjW9ZKRSXLJnSpIBvMUiLTQbw+CFAWjOkmPpl1wkpkjACI7hRKUmXprlQyZb88oM5CS3rD5kXyRHGNnWDzK1lhWG8SZUgpKs1nPoVjoeYrDmFQTapehrjyF6eDAnjAttoCsA8hezS3aLgadDFQ= 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=EGIhGVzr; arc=none smtp.client-ip=209.85.161.51 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="EGIhGVzr" Received: by mail-oo1-f51.google.com with SMTP id 006d021491bc7-5ebc349204cso1155074eaf.3 for ; Fri, 15 Nov 2024 12:19:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1731701939; x=1732306739; 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=unmeYdeBn+D1ZmpuSEm58bDvDpLySt7nxP95EdRhLZ8=; b=EGIhGVzrPnCQqFzGqlEBlsPSFk2yk6HjE8FrCX7NpXMjF/X4qu3rwygcOVjNR+m2k9 SWU73rXaSRVJ4zC4imZuBukk/aLKZLsY5EjXmOHRbCEmacq6pDRBneVzmpAfXm/D6Do6 grgBZlAJuktmg/mBOhesZOEBvimhZpdxSHtrslhvAc4yP1DOALdtr/BXRu23gGAGPf2P wtLRO3pFcNpA+ct3K7V3G71KmMwPuC8spJpfRMSQF3PbM2RPZ7V/6EVQMlpPhD+0R/ot gvaNFfQx8L/1pltZ4QGGsBJ27yDC0sLzk3AoyFGFVuVCORCIuRNeccqC+lfVRcp1ac51 vJIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731701939; x=1732306739; 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=unmeYdeBn+D1ZmpuSEm58bDvDpLySt7nxP95EdRhLZ8=; b=qB0s6u3W+DdawI1FqFRaI9VI1u1ZVmYqGi5zMHva/0ScPWb8CJ8n4UHAU4PqU/MX7K 6Z3fYZKyQPVymWFzQMxJn7ATxP6auNnr9aYPe1xcRDMQwykb7Vl7E1Vw9MhiLba1tHZQ RHVOcLLSbfPSE1On6JRT4Jr/yP/C8wFP32Fjg0q8ZXQrZ1GeZGsbtUR3bLOTIt6u4f1r NEO4f8YViDz12jtIkLsTSoeK8v7eDAgFoKYGfr2ZNq1b4/ZXY108qt/CDl7f0zWFpWJW ATs5BRg5AV9NlEFjlQOGHRplx+toTl0+K7k2Uk1t+nwbLFBFUrNBI7ENWc1fA0PIGEFs G9Lg== X-Forwarded-Encrypted: i=1; AJvYcCVHisZxz/SfSv6spdQ5MjmOQQPeENUSiX7Ak+yLwVRzopXGb4XD/0j8OKV3TFw34sKjyQbT1EN6xrs=@vger.kernel.org X-Gm-Message-State: AOJu0YwMZKiOWhr7GtYycBQib+un8N+iYAupfLb/XYzcV+v097hO34bn FpW5iyawZHy0DhfFHd8kQjqeVhj2u32cuHy+qL9PXWHv92YhwoEIM6nOz2hva3Q= X-Google-Smtp-Source: AGHT+IHeF5FoHsWnd/xYfNXHiRj6XV96twgJUsRypMRtTcUzak6K6jO+tc0oO8DmmLcbRnoHfwfN1Q== X-Received: by 2002:a05:6820:983:b0:5eb:6a67:6255 with SMTP id 006d021491bc7-5eeab2c11ffmr3502045eaf.1.1731701939465; Fri, 15 Nov 2024 12:18:59 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71a780ea62esm748978a34.5.2024.11.15.12.18.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Nov 2024 12:18:59 -0800 (PST) From: David Lechner Date: Fri, 15 Nov 2024 14:18:46 -0600 Subject: [PATCH v5 07/16] spi: dt-bindings: axi-spi-engine: add SPI offload properties Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241115-dlech-mainline-spi-engine-offload-2-v5-7-bea815bd5ea5@baylibre.com> References: <20241115-dlech-mainline-spi-engine-offload-2-v5-0-bea815bd5ea5@baylibre.com> In-Reply-To: <20241115-dlech-mainline-spi-engine-offload-2-v5-0-bea815bd5ea5@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, David Lechner X-Mailer: b4 0.14.1 The AXI SPI Engine has support for hardware offloading capabilities. This includes a connection to a DMA controller for streaming RX data and a trigger input for starting execution of the SPI message programmed in the offload. Each SPI Engine may have up to 1 offload. The spec actually says that it could support up to 32, so we are using an index number in the dma-names (e.g. offload0-rx) to allow for this possibility in the future. Signed-off-by: David Lechner --- v5 changes: * Also document offload0-tx DMA names since the hardware can support that now. * Limit the number of offloads to 1 for now since it would require significant hardware changes to actually support more than that. v4 changes: * Dropped #spi-offload-cells property. * Changed subject line. v3 changes: * Added #spi-offload-cells property. * Added properties for triggers and RX data stream connected to DMA. v2 changes: * This is basically a new patch. It partially replaces "dt-bindings: iio: offload: add binding for PWM/DMA triggered buffer". * The controller no longer has an offloads object node and the spi-offloads property is now a standard SPI peripheral property. --- .../bindings/spi/adi,axi-spi-engine.yaml | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Documentation/devicetree/bindings/spi/adi,axi-spi-engine.yaml b/Documentation/devicetree/bindings/spi/adi,axi-spi-engine.yaml index d48faa42d025..d703b47eb498 100644 --- a/Documentation/devicetree/bindings/spi/adi,axi-spi-engine.yaml +++ b/Documentation/devicetree/bindings/spi/adi,axi-spi-engine.yaml @@ -41,6 +41,26 @@ properties: - const: s_axi_aclk - const: spi_clk + trigger-sources: + description: + An array of trigger source phandles for offload instances. The index in + the array corresponds to the offload instance number. + $ref: /schemas/types.yaml#/definitions/phandle-array + maxItems: 1 + + dmas: + description: + DMA channels connected to the input or output stream interface of an + offload instance. + minItems: 1 + maxItems: 2 + + dma-names: + items: + pattern: "^offload0-[tr]x$" + minItems: 1 + maxItems: 2 + required: - compatible - reg @@ -59,6 +79,10 @@ examples: clocks = <&clkc 15>, <&clkc 15>; clock-names = "s_axi_aclk", "spi_clk"; + trigger-sources = <&trigger_clock>; + dmas = <&dma 0>; + dma-names = "offload0-rx"; + #address-cells = <1>; #size-cells = <0>; From patchwork Fri Nov 15 20:18:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 843776 Received: from mail-ot1-f52.google.com (mail-ot1-f52.google.com [209.85.210.52]) (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 51E431EF951 for ; Fri, 15 Nov 2024 20:19:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731701945; cv=none; b=IIumdLHzPx2nwTS05zI7wSstjfXizLvKY9wbAQeNhPJlXGR5G9nxOV85ut+Ol2B/AWILs04bNpNCvC8xchvnfBdngHFsO0h5/8EpPdhQDvUPaQFZNw+2WpKBXyKndL9LpUR31hG/0Q6cNGb2mu9C/+hGsCde2Ah4dhfvhOHeiKg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731701945; c=relaxed/simple; bh=liN7b/KYzKtzeNSL+5oMImxJ6lcQk3gX9Kb2jv+h/ro=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SACDLo3QWwqh2JkC6tk6/egc53qbYPByF+gVpjw16hjZaJ42AxS1SUwL0mYn2L50tO4qkyrEBZu6vyqHgCXRl1EZpIejXbVgvwyFK4r9Mh26jqpLtW+RI6Prvu22MwkELlW1LqAPnXuETMJavomtE7dkbG2UuDg9mZjBAvvBsn0= 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=hVHA84Dw; arc=none smtp.client-ip=209.85.210.52 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="hVHA84Dw" Received: by mail-ot1-f52.google.com with SMTP id 46e09a7af769-7180e07185bso913894a34.3 for ; Fri, 15 Nov 2024 12:19:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1731701942; x=1732306742; 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=0V8K9STxeMmBsbxzTyK1zNzGuxIPVz8nmTjFT2BLRT4=; b=hVHA84DwKhpRjhy76VpaVoC8S++0uxCpadJArbTlAPX6/fh99tkkusWCsN/ZEYEZTp uO5Cb9HUcb02/nvSK/Ej4vIptodo1oUCBwdqEwIxDkmVHaEAnOI+Ccc+i8TyNkv7Vzdn YSXqyaQxtDb2up4x1syImbvUO1g6Jrigz2CmXS7kpSPrvIDmqXlXM+1e276cYqO2l3bM YlUlVyQ8UPkyjGEIprGgUBaOLA5VzCFHnm5mWn/izdOIE8dnf8FrBi47/hbqiEg3IODO PfIVWJrkwYbo0eOa6cWTJWDJeApf8L3lNSvCs1VFqxB0nsQbJsoPSixrnnIvCN0um5N1 ZHCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731701942; x=1732306742; 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=0V8K9STxeMmBsbxzTyK1zNzGuxIPVz8nmTjFT2BLRT4=; b=ZPmnWj+sORvGPGgO9MJ+u9Qx91vzG7xINImAYEXGaiYsQdXLosR31Y/gs0BfVhne2F yw/85vG8e6ACPo5QSdkBkK9yS9lxP7heGxzO9Bb7lyMoPuzkEgfYSVnVNsa/ufaz89U5 inIl5J/Z6FDEwoMghvHB1waFVhnppr6nfInvNXy8FZEiQ+njNwitIVQBcOcwXhBSmzig L/zsVPUHn5Mx2UyIfLT3hwstREmZjqqSwps2Hk/WAU4aCz0BQNrYfW63CMXGPSfTcsN8 E9/mlhxObAS6R9Bfhd9cLk7r5lWBTnGV7Yt/9Ppxwa3AverAYpvxc+7DbocKR3Cva/AS NfGA== X-Forwarded-Encrypted: i=1; AJvYcCXpbuUI3LDMnbxD8bJV16cxaGOS059zATb5fWr2cTqXDJ3PMo2CPuu4QYhpa7cCqLaO6Qs724kUvkg=@vger.kernel.org X-Gm-Message-State: AOJu0Yyi27+b+3MHist5HzXUaispI9d72ecp1a0FNXEBhCJCePHb+kTL mz27AX2/yCa7RnvutxE6RgOtChHfMl+6qYs9+0yAAuGKMC76jkzoViFIB1RPppk= X-Google-Smtp-Source: AGHT+IE09WFChQ+/hR2mVDvjYMehhUE2fePG8D9Jb1Cbzj66rlCOErUZI2AFvqUCBNYs2zx0h1rLDQ== X-Received: by 2002:a05:6830:6c0f:b0:71a:7603:d2d2 with SMTP id 46e09a7af769-71a7797c309mr4591306a34.18.1731701942374; Fri, 15 Nov 2024 12:19:02 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71a780ea62esm748978a34.5.2024.11.15.12.19.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Nov 2024 12:19:01 -0800 (PST) From: David Lechner Date: Fri, 15 Nov 2024 14:18:48 -0600 Subject: [PATCH v5 09/16] iio: buffer-dmaengine: document iio_dmaengine_buffer_setup_ext Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241115-dlech-mainline-spi-engine-offload-2-v5-9-bea815bd5ea5@baylibre.com> References: <20241115-dlech-mainline-spi-engine-offload-2-v5-0-bea815bd5ea5@baylibre.com> In-Reply-To: <20241115-dlech-mainline-spi-engine-offload-2-v5-0-bea815bd5ea5@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, David Lechner X-Mailer: b4 0.14.1 The iio_dmaengine_buffer_setup_ext() function is public and should be documented. Also, while touching this, fix the description of @dev in related functions. @dev does not strictly have to be the parent of the IIO device. It is only passed to dma_request_chan() so strictly speaking, it can be any device that is a valid DMA channel consumer. Signed-off-by: David Lechner --- v5 changes: none v4 changes: * This patch is new in v4. Jonathan, I think this patch stands on its own if you want to take it earlier than the rest of this series. --- drivers/iio/buffer/industrialio-buffer-dmaengine.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c index 19af1caf14cd..054af21dfa65 100644 --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -206,7 +206,7 @@ static const struct iio_dev_attr *iio_dmaengine_buffer_attrs[] = { /** * iio_dmaengine_buffer_alloc() - Allocate new buffer which uses DMAengine - * @dev: Parent device for the buffer + * @dev: DMA channel consumer device * @channel: DMA channel name, typically "rx". * * This allocates a new IIO buffer which internally uses the DMAengine framework @@ -288,6 +288,21 @@ void iio_dmaengine_buffer_free(struct iio_buffer *buffer) } EXPORT_SYMBOL_NS_GPL(iio_dmaengine_buffer_free, IIO_DMAENGINE_BUFFER); +/** + * iio_dmaengine_buffer_setup_ext() - Setup a DMA buffer for an IIO device + * @dev: DMA channel consumer device + * @indio_dev: IIO device to which to attach this buffer. + * @channel: DMA channel name, typically "rx". + * @dir: Direction of buffer (in or out) + * + * This allocates a new IIO buffer with devm_iio_dmaengine_buffer_alloc() + * and attaches it to an IIO device with iio_device_attach_buffer(). + * It also appends the INDIO_BUFFER_HARDWARE mode to the supported modes of the + * IIO device. + * + * Once done using the buffer iio_dmaengine_buffer_free() should be used to + * release it. + */ struct iio_buffer *iio_dmaengine_buffer_setup_ext(struct device *dev, struct iio_dev *indio_dev, const char *channel, @@ -321,7 +336,7 @@ static void __devm_iio_dmaengine_buffer_free(void *buffer) /** * devm_iio_dmaengine_buffer_setup_ext() - Setup a DMA buffer for an IIO device - * @dev: Parent device for the buffer + * @dev: Device for devm ownership and DMA channel consumer device * @indio_dev: IIO device to which to attach this buffer. * @channel: DMA channel name, typically "rx". * @dir: Direction of buffer (in or out) From patchwork Fri Nov 15 20:18:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 843775 Received: from mail-ot1-f46.google.com (mail-ot1-f46.google.com [209.85.210.46]) (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 362771F706F for ; Fri, 15 Nov 2024 20:19:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731701948; cv=none; b=gn7NOGjh9CZ3GgaLdEgYJyBGuwL7KyyiEcGeoNSwVKcbCiyb1IA5wCfB6HScygISIasvlQsbpra/ZYZ2yp8F8aTfAxl4SX1PYdGvdW6ILGeP8y8NSkUt42hLN59xedhWDsvJTXtJUltZWo8FGA9CrBVVDjMjrynFz05Gi1eUwoY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731701948; c=relaxed/simple; bh=nByoFKUVSmX22QOrB5tKOE6hy2vdogrk8IlWYmMb7iA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Tcyq0PUQMTYdSCnNY+Ezwk1f3Ut55cXcS9szT1WBWdrA8e9KLUcSYWfLEroIMEn6SBkMvCo+RugLUeigm7z8DzqBN5VTgA9S3n3e3ZLgwg1Ebzuqy4chaVDQb89+KEvp/Bn7Rk8o1T4PbK4tGOobjsodK9f9XFfAhC5dGOdFdmY= 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=sJ8yRa/U; arc=none smtp.client-ip=209.85.210.46 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="sJ8yRa/U" Received: by mail-ot1-f46.google.com with SMTP id 46e09a7af769-7181c0730ddso782375a34.2 for ; Fri, 15 Nov 2024 12:19:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1731701944; x=1732306744; 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=hQ9TBdpHxWzvzSyVZJpMzkKE9PvbJoCuWgBYWs06guk=; b=sJ8yRa/Utq4US7mqGjtp09jKg2wwKGJuVrHGEesX5c7N7HAPjhNBipsa+NlrX0nL8K wL/UOwxJgIG81dqzE+jo36b+szK8oGAuvBEtXkTUtGWyr6tiJfwbXAysivb81Hy8ut8l lc0W3Jz6fJsEgrko/e/H+JTKL/a9HFFvdxrv27SJqZicxZQ1VBVEi/IPcqz7xxsLtwlP ge3wSeHSbVaZK8AB+xSfZyR/Ox+xhj3i/hxisdhISUs05k6Xu3i7KW1S81qMaOfj1d1o 2bL6gICF0X0osl8nrPnUSC1E0mBul9Q2Y9fM4ged6EMHZ4ad1zZKI/3gp7pMwtm5z+cn FlCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731701944; x=1732306744; 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=hQ9TBdpHxWzvzSyVZJpMzkKE9PvbJoCuWgBYWs06guk=; b=dw6vH7ayUt01vCMvB2LJoeBsjCkVQ1TLmdaXm91mnZbkCvhi0W23yc2DssNk9vweEi fBtpfXom1y8gVaIntuP32GxosJ1Wvnhly+7/+Y38EKEjGz6hmetIKZeSVi69W/ZAGOLl TfLR1eEahauZu7I2MEfN7FfGOn8+ZwIjZeyfBgXO02CYB4ykVPS71Is46B809jANw4q4 dnaaxRnWf4JKbpgGkpKzFjaSInM2H8KSZnx1Pp5tmBZYqLRQQ7xhr1cN3ZyyOjy7WjdA zuZHi6/0m1uU4Qn2d0wQDyraRvgGk/zt7Ntx+LMnjM+3AL5iFfMd13SkvQbpeCpZ/sJe uyiw== X-Forwarded-Encrypted: i=1; AJvYcCXFlNhTQwXzuFrb5hhdnu1cBA77CSJyOPqEETJ55Iuy9TZgNiDiS6p04ZsrR2uimyW5GhtBvbqBCwM=@vger.kernel.org X-Gm-Message-State: AOJu0YysFbNpnchoqpNyENQoCQjgSkE7uSnZ9SYd/tJ7XzbCcoQUUSAH 2RtH9DPT6eVNQR1Vw9wg4sTdJZ0cUPQ456Bels2e8xptOBFsfdEOaGRHFwriWN0= X-Google-Smtp-Source: AGHT+IFpIObwug+gjtaFB8EYgLYodh+d7CpNa3uZrjGmbI+QPIYY+qYFAjZ6xzpN4D9Z/f4yyjISHA== X-Received: by 2002:a05:6830:64ca:b0:718:194d:8ab with SMTP id 46e09a7af769-71a77a55f3cmr4663542a34.27.1731701944380; Fri, 15 Nov 2024 12:19:04 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71a780ea62esm748978a34.5.2024.11.15.12.19.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Nov 2024 12:19:03 -0800 (PST) From: David Lechner Date: Fri, 15 Nov 2024 14:18:49 -0600 Subject: [PATCH v5 10/16] iio: buffer-dmaengine: add devm_iio_dmaengine_buffer_setup_ext2() Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241115-dlech-mainline-spi-engine-offload-2-v5-10-bea815bd5ea5@baylibre.com> References: <20241115-dlech-mainline-spi-engine-offload-2-v5-0-bea815bd5ea5@baylibre.com> In-Reply-To: <20241115-dlech-mainline-spi-engine-offload-2-v5-0-bea815bd5ea5@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, David Lechner X-Mailer: b4 0.14.1 Add a new devm_iio_dmaengine_buffer_setup_ext2() function to handle cases where the DMA channel is managed by the caller rather than being requested and released by the iio_dmaengine module. Signed-off-by: David Lechner --- v5 changes: none v4 changes: * This replaces "iio: buffer-dmaengine: generalize requesting DMA channel" --- drivers/iio/buffer/industrialio-buffer-dmaengine.c | 107 +++++++++++++++------ include/linux/iio/buffer-dmaengine.h | 5 + 2 files changed, 81 insertions(+), 31 deletions(-) diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c index 054af21dfa65..602cb2e147a6 100644 --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -33,6 +33,7 @@ struct dmaengine_buffer { struct iio_dma_buffer_queue queue; struct dma_chan *chan; + bool owns_chan; struct list_head active; size_t align; @@ -216,28 +217,23 @@ static const struct iio_dev_attr *iio_dmaengine_buffer_attrs[] = { * Once done using the buffer iio_dmaengine_buffer_free() should be used to * release it. */ -static struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev, - const char *channel) +static struct iio_buffer *iio_dmaengine_buffer_alloc(struct dma_chan *chan, + bool owns_chan) { struct dmaengine_buffer *dmaengine_buffer; unsigned int width, src_width, dest_width; struct dma_slave_caps caps; - struct dma_chan *chan; int ret; dmaengine_buffer = kzalloc(sizeof(*dmaengine_buffer), GFP_KERNEL); - if (!dmaengine_buffer) - return ERR_PTR(-ENOMEM); - - chan = dma_request_chan(dev, channel); - if (IS_ERR(chan)) { - ret = PTR_ERR(chan); - goto err_free; + if (!dmaengine_buffer) { + ret = -ENOMEM; + goto err_release; } ret = dma_get_slave_caps(chan, &caps); if (ret < 0) - goto err_release; + goto err_free; /* Needs to be aligned to the maximum of the minimums */ if (caps.src_addr_widths) @@ -252,6 +248,7 @@ static struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev, INIT_LIST_HEAD(&dmaengine_buffer->active); dmaengine_buffer->chan = chan; + dmaengine_buffer->owns_chan = owns_chan; dmaengine_buffer->align = width; dmaengine_buffer->max_size = dma_get_max_seg_size(chan->device->dev); @@ -263,10 +260,12 @@ static struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev, return &dmaengine_buffer->queue.buffer; -err_release: - dma_release_channel(chan); err_free: kfree(dmaengine_buffer); +err_release: + if (owns_chan) + dma_release_channel(chan); + return ERR_PTR(ret); } @@ -282,12 +281,38 @@ void iio_dmaengine_buffer_free(struct iio_buffer *buffer) iio_buffer_to_dmaengine_buffer(buffer); iio_dma_buffer_exit(&dmaengine_buffer->queue); - dma_release_channel(dmaengine_buffer->chan); - iio_buffer_put(buffer); + + if (dmaengine_buffer->owns_chan) + dma_release_channel(dmaengine_buffer->chan); } EXPORT_SYMBOL_NS_GPL(iio_dmaengine_buffer_free, IIO_DMAENGINE_BUFFER); +static struct iio_buffer +*__iio_dmaengine_buffer_setup_ext(struct iio_dev *indio_dev, + struct dma_chan *chan, bool owns_chan, + enum iio_buffer_direction dir) +{ + struct iio_buffer *buffer; + int ret; + + buffer = iio_dmaengine_buffer_alloc(chan, owns_chan); + if (IS_ERR(buffer)) + return ERR_CAST(buffer); + + indio_dev->modes |= INDIO_BUFFER_HARDWARE; + + buffer->direction = dir; + + ret = iio_device_attach_buffer(indio_dev, buffer); + if (ret) { + iio_dmaengine_buffer_free(buffer); + return ERR_PTR(ret); + } + + return buffer; +} + /** * iio_dmaengine_buffer_setup_ext() - Setup a DMA buffer for an IIO device * @dev: DMA channel consumer device @@ -308,24 +333,13 @@ struct iio_buffer *iio_dmaengine_buffer_setup_ext(struct device *dev, const char *channel, enum iio_buffer_direction dir) { - struct iio_buffer *buffer; - int ret; - - buffer = iio_dmaengine_buffer_alloc(dev, channel); - if (IS_ERR(buffer)) - return ERR_CAST(buffer); - - indio_dev->modes |= INDIO_BUFFER_HARDWARE; - - buffer->direction = dir; + struct dma_chan *chan; - ret = iio_device_attach_buffer(indio_dev, buffer); - if (ret) { - iio_dmaengine_buffer_free(buffer); - return ERR_PTR(ret); - } + chan = dma_request_chan(dev, channel); + if (IS_ERR(chan)) + return ERR_CAST(chan); - return buffer; + return __iio_dmaengine_buffer_setup_ext(indio_dev, chan, true, dir); } EXPORT_SYMBOL_NS_GPL(iio_dmaengine_buffer_setup_ext, IIO_DMAENGINE_BUFFER); @@ -362,6 +376,37 @@ int devm_iio_dmaengine_buffer_setup_ext(struct device *dev, } EXPORT_SYMBOL_NS_GPL(devm_iio_dmaengine_buffer_setup_ext, IIO_DMAENGINE_BUFFER); +/** + * devm_iio_dmaengine_buffer_setup_ext2() - Setup a DMA buffer for an IIO device + * @dev: Device for devm ownership + * @indio_dev: IIO device to which to attach this buffer. + * @chan: DMA channel + * @dir: Direction of buffer (in or out) + * + * This allocates a new IIO buffer with devm_iio_dmaengine_buffer_alloc() + * and attaches it to an IIO device with iio_device_attach_buffer(). + * It also appends the INDIO_BUFFER_HARDWARE mode to the supported modes of the + * IIO device. + * + * This is the same as devm_iio_dmaengine_buffer_setup_ext() except that the + * caller manages requesting and releasing the DMA channel. + */ +int devm_iio_dmaengine_buffer_setup_ext2(struct device *dev, + struct iio_dev *indio_dev, + struct dma_chan *chan, + enum iio_buffer_direction dir) +{ + struct iio_buffer *buffer; + + buffer = __iio_dmaengine_buffer_setup_ext(indio_dev, chan, false, dir); + if (IS_ERR(buffer)) + return PTR_ERR(buffer); + + return devm_add_action_or_reset(dev, __devm_iio_dmaengine_buffer_free, + buffer); +} +EXPORT_SYMBOL_NS_GPL(devm_iio_dmaengine_buffer_setup_ext2, IIO_DMAENGINE_BUFFER); + MODULE_AUTHOR("Lars-Peter Clausen "); MODULE_DESCRIPTION("DMA buffer for the IIO framework"); MODULE_LICENSE("GPL"); diff --git a/include/linux/iio/buffer-dmaengine.h b/include/linux/iio/buffer-dmaengine.h index 81d9a19aeb91..7bdb979b59f2 100644 --- a/include/linux/iio/buffer-dmaengine.h +++ b/include/linux/iio/buffer-dmaengine.h @@ -11,6 +11,7 @@ struct iio_dev; struct device; +struct dma_chan; void iio_dmaengine_buffer_free(struct iio_buffer *buffer); struct iio_buffer *iio_dmaengine_buffer_setup_ext(struct device *dev, @@ -26,6 +27,10 @@ int devm_iio_dmaengine_buffer_setup_ext(struct device *dev, struct iio_dev *indio_dev, const char *channel, enum iio_buffer_direction dir); +int devm_iio_dmaengine_buffer_setup_ext2(struct device *dev, + struct iio_dev *indio_dev, + struct dma_chan *chan, + enum iio_buffer_direction dir); #define devm_iio_dmaengine_buffer_setup(dev, indio_dev, channel) \ devm_iio_dmaengine_buffer_setup_ext(dev, indio_dev, channel, \ From patchwork Fri Nov 15 20:18:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 843774 Received: from mail-oa1-f45.google.com (mail-oa1-f45.google.com [209.85.160.45]) (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 6C3251F8934 for ; Fri, 15 Nov 2024 20:19:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731701951; cv=none; b=gzcEuOEmLyD9012U4yn/xZLOeVbX1vSrkG4mWGL6uic+fIBzZfL2J6v3tRq6Ch+oZoZxpAv3+oZc2eJgrjewfdBSBQ697DoVHZO9BTyHsnicY1mRxuyNVqv/i8rqvQHmrCu/BOfP/lR27Dv2BOIktilIoyCSdOAXzeMPfZg0tL0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731701951; c=relaxed/simple; bh=K0ELSxsB5ewnDfByel6azG1qzhpSdfFUlrceHRoZqqY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gkqqk5YB0wP2XxKvQPqz4WhIorKyJHn3Ve3KlDZmujUrl7IPpb6gk+K1cw0Y4NYuBd3m2Qc79WhyCNfC9K54z4yFI91lPAq5togLLX9KicLKO/XeItkTnmk9i0gn6GbBTvwx0zuN9ems8d7/o7ff4UFQLdKeO3FN1oRNotdXmeA= 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=iLOt5OkK; arc=none smtp.client-ip=209.85.160.45 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="iLOt5OkK" Received: by mail-oa1-f45.google.com with SMTP id 586e51a60fabf-28c7f207806so984296fac.3 for ; Fri, 15 Nov 2024 12:19:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1731701948; x=1732306748; 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=gHWSp9g71dav0wBB3RsBnAwDxMnAi0+sYhD4RSgE92s=; b=iLOt5OkKff+H5qnAg29jnxdMSADjMWv2Sf9Mj0EybfejW3UveERNNhVF1EfBKL/QqY /cWsP4VzVQq6+dc/jkUd/wrmWOD+riSMQ4COkYHemH4zcDe/fWa798zioVavY0Ed0TWa dQ6wx329dxa1F8jhbx7rIUPaZGyA4Cwps7+E/3CKkjRpKmcvgapykEieeMwjY08vAOPl u8l0HFef/L10UTUNRKfE/4hRlpd2S1HKumYvcVh1dPVdBfxvgU0+/SXJ08BiItKXr8LP 34CKDIcKbNdaHLLOnIz+Zgvk2ERupSs3ooqKJ1ucFJXCiNDvkXDYoiFOB/X4oRzDxqa4 iLqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731701948; x=1732306748; 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=gHWSp9g71dav0wBB3RsBnAwDxMnAi0+sYhD4RSgE92s=; b=rOHDQh0kG6jsL+JVphvrkK9ldjPwbFBhCx9UwUPNXHmcadyflbpzhWjv9Og9l+3Dhe +5+pLXn8OEhANjE3nzRdkkwAj17TXqaSW7paPOBEeu1SS4eu+2u11RnXQC8PTvY952NR ZjN+3zsXJ96w4MZ1vDOecrmbmgaPf2dELIZmSW8cSn6xPKzmS9MFapgX5vNJEOrrXmML BuZbpxN16oFF8HniskSqWvDz5bClt2y41o2IWsiKjDhGs4RsWhN2g0SzWqsXLeoKQyjR O0ROECTlbTw2zp7lIN1ulPyLTv4sH1LHHJJmYJ1xc1dJAuRXzGs0fsBeY7pnI2w0QOt5 jvnw== X-Forwarded-Encrypted: i=1; AJvYcCXLvpy2GWwhJ/1MrBfinhoQZbNyfVTrub8ZLjJqBPy+eURMAli6WhEY2ZMvnPfX5Y7i2B3TgR6gIoo=@vger.kernel.org X-Gm-Message-State: AOJu0YyziDUsUocMU0omj8MTImM5iK+fESpAAEFgVju+zWkO9QmrFArS g5Q7mD97zYpga5lW8mBiuD9BhVf/FZ9UNVWy15hSL0C1GW1kD+KBk9g7qb/sCTc= X-Google-Smtp-Source: AGHT+IGWBHYcdZrBR+Etr+tBdm3Lz7gnqd+0QTKy8x+5SgSS97gRVwEjKew7vBfdhv9QAdngjnHbCA== X-Received: by 2002:a05:6870:32d4:b0:27c:df1d:85c6 with SMTP id 586e51a60fabf-2962dd3a1c0mr3912680fac.8.1731701948269; Fri, 15 Nov 2024 12:19:08 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71a780ea62esm748978a34.5.2024.11.15.12.19.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Nov 2024 12:19:06 -0800 (PST) From: David Lechner Date: Fri, 15 Nov 2024 14:18:52 -0600 Subject: [PATCH v5 13/16] doc: iio: ad7944: describe offload support Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241115-dlech-mainline-spi-engine-offload-2-v5-13-bea815bd5ea5@baylibre.com> References: <20241115-dlech-mainline-spi-engine-offload-2-v5-0-bea815bd5ea5@baylibre.com> In-Reply-To: <20241115-dlech-mainline-spi-engine-offload-2-v5-0-bea815bd5ea5@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, David Lechner X-Mailer: b4 0.14.1 Add a section to the ad7944 documentation describing how to use the driver with SPI offloading. Signed-off-by: David Lechner --- v5 changes: new patch in v5 --- Documentation/iio/ad7944.rst | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/Documentation/iio/ad7944.rst b/Documentation/iio/ad7944.rst index 0d26e56aba88..e6dbe4d7f58c 100644 --- a/Documentation/iio/ad7944.rst +++ b/Documentation/iio/ad7944.rst @@ -46,6 +46,8 @@ CS mode, 3-wire, without busy indicator To select this mode in the device tree, set the ``adi,spi-mode`` property to ``"single"`` and omit the ``cnv-gpios`` property. +This is the only wiring configuration supported when using `SPI offload support`_. + CS mode, 4-wire, without busy indicator ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -106,7 +108,6 @@ Unimplemented features ---------------------- - ``BUSY`` indication -- ``TURBO`` mode Device attributes @@ -147,6 +148,27 @@ AD7986 is a fully-differential ADC and has the following attributes: In "chain" mode, additional chips will appear as additional voltage input channels, e.g. ``in_voltage2-voltage3_raw``. +SPI offload support +=================== + +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 sample + rate. +* ``in_voltage0_sampling_frequency_available`` attribute is added for querying + 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. + +If the ``turbo-gpios`` property is present in the device tree, the driver will +turn on TURBO during buffered reads and turn it off otherwise. Device buffers ============== From patchwork Fri Nov 15 20:18:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 843773 Received: from mail-oo1-f50.google.com (mail-oo1-f50.google.com [209.85.161.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 012081FAC38 for ; Fri, 15 Nov 2024 20:19:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731701955; cv=none; b=EBDVxTsneUS4dr3Kl7XAwlmC4HI5Nlp8Gxh3CX3oTDuiTn1VGil2ZrCRF95V4ZM850Q9lMcCtflNtlbDWo3pNYLA9cpbwuxbUKPE8DoGu2ZCK2II5iDku3s2EiMgZoz9jLrxN0fIBlI0Gn5jRePPf0dW9vz3KZraL7nda4sCRtk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731701955; c=relaxed/simple; bh=lAGm0BfqgiNcIcjLhq96l0xwQMzn10PfebZ1OkujxZY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=afxJNKmErv/1NofgQzEwe1/WazYzqAa84vvTcMyWyZHsp16QGhgE3Ux6NxLNogQnWpM+d+TMXNQEv7h0WN0fXRP9qE4AJzwu4ddpU/5ni1wOUtr8ghJ6v2NgAyk4E193bSUDi4hIvTI0HTRg9nysH+gCwobgATtEzTJ0Oko48/o= 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=y2PppCwh; arc=none smtp.client-ip=209.85.161.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="y2PppCwh" Received: by mail-oo1-f50.google.com with SMTP id 006d021491bc7-5ee55fa4b31so1226702eaf.0 for ; Fri, 15 Nov 2024 12:19:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1731701952; x=1732306752; 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=+8s25RYMi+zlyRDlUm0JExPlZPMjT1HBFf4tYIofzew=; b=y2PppCwhMF68/W9cV0d37bUh48J1V2i/bz+69x752BvQIPWXO7JJG80uPa3M/bWNAA cCEGFqOKBD3JmgBIUJ+AR3xsr846QjbJr71EYnmJeoudd1QtTHfss0eo05knaorC4bZD jeyvpaWI7tbQR5HdvAqEt1qwgGUhZUcOG8K3cXrXHXYwarq7KqFMMyoDKx4OV5SbK5ss pU5w7oncMjw2d8R9d/YFM+f57WgiZbyyPbVaaEZQgn+lJSXSmq0kI7Kh2Kn9VOAFag4G U9Vdmlw9OvyHLMh2TOfRNFZ+ZsjMI5jUVlC7A2rA+C1RAP4Hl3DCh/ghCENB5A6xmWIA T6qQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731701952; x=1732306752; 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=+8s25RYMi+zlyRDlUm0JExPlZPMjT1HBFf4tYIofzew=; b=ZlvBO7novfzGzQgs5dMvGsonEByKKAdyrDhWTctpMYgvyo2zwL69JjvwcBn2UIhK5S 3UcQY/IJmwE2HdCfMy0/J1/DPjp3O+zORHzux2jrCYwTg2cy3ct8Vhazz1x+vf0KsdoV jRXAQr9Ojc5KbEOLNWWCnkgcWW9aibUkCWgJvHOV2RrMiEVdqtBGUNEAykZWkK7PGnil O75EoqWaNl5NgD/OoTLTtNKCe2dEB5doObNRmR/ttTonz3hAY6U4S3c6PP7fO05iLZ1A A3zfzNH6YWKezjCjQQIY+Np6hoRXq6G0Fp7kLBRRr4F5JefhSSQpEAOkKY+rjeb8hOlQ YB/g== X-Forwarded-Encrypted: i=1; AJvYcCWPAo6N53QW7QEnZlGLHBjwMfaQLIlxwg3fYgWrGJQj/NhigYOq1POgu2c/X7leM4OlgDzPkHndhW0=@vger.kernel.org X-Gm-Message-State: AOJu0Yx0P5syQP3HLwoxtgs1rbutx/3ECDxC/6vJWEOJnbhn8ucxy/Y1 eLRvmi3Tu21yzTp5fNU7on/r5c4fQKiCNXoRBbWjsilGQd/TyHoPsD/i4uSYNHk= X-Google-Smtp-Source: AGHT+IF+lv4w+8HYxFzmk7lngOHQjR5NRVDb+KEp2Ni5zx2ZGPOp/A07V9v7MCv0sDwNk76D0Q1dow== X-Received: by 2002:a05:6820:2d0c:b0:5ed:feae:d5bd with SMTP id 006d021491bc7-5eeab410f02mr4409964eaf.3.1731701952105; Fri, 15 Nov 2024 12:19:12 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71a780ea62esm748978a34.5.2024.11.15.12.19.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Nov 2024 12:19:10 -0800 (PST) From: David Lechner Date: Fri, 15 Nov 2024 14:18:54 -0600 Subject: [PATCH v5 15/16] iio: adc: ad4695: Add support for SPI offload Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241115-dlech-mainline-spi-engine-offload-2-v5-15-bea815bd5ea5@baylibre.com> References: <20241115-dlech-mainline-spi-engine-offload-2-v5-0-bea815bd5ea5@baylibre.com> In-Reply-To: <20241115-dlech-mainline-spi-engine-offload-2-v5-0-bea815bd5ea5@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, David Lechner X-Mailer: b4 0.14.1 Add support for SPI offload to the ad4695 driver. SPI offload allows sampling data at the max sample rate (500kSPS or 1MSPS). This is developed and tested against the ADI example FPGA design for this family of ADCs [1]. [1]: http://analogdevicesinc.github.io/hdl/projects/ad469x_fmc/index.html Signed-off-by: David Lechner --- v5 changes: * Register SCLK speed handling has been split out into a separate series. * Add sampling_frequency_available attribute. * Limit max allowed sampling frequency based on chip info. * Expand explanations of offload enable/disable ordering requirements. * Finish TODO to use macros for phandle arg values. * Don't use dev_info() when falling back to non-offload operation. * Update to accommodate changes in other patches in this series. v4 changes: new patch in v4 --- drivers/iio/adc/Kconfig | 1 + drivers/iio/adc/ad4695.c | 438 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 422 insertions(+), 17 deletions(-) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 995b9cacbaa9..ec60b64c46e1 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -52,6 +52,7 @@ config AD4695 tristate "Analog Device AD4695 ADC Driver" depends on SPI select IIO_BUFFER + select IIO_BUFFER_DMAENGINE select IIO_TRIGGERED_BUFFER select REGMAP help diff --git a/drivers/iio/adc/ad4695.c b/drivers/iio/adc/ad4695.c index 10f61290e2c1..02880d1ef31b 100644 --- a/drivers/iio/adc/ad4695.c +++ b/drivers/iio/adc/ad4695.c @@ -19,14 +19,18 @@ #include #include #include +#include #include #include #include #include #include +#include #include +#include #include #include +#include #include #include @@ -66,6 +70,8 @@ #define AD4695_REG_STD_SEQ_CONFIG 0x0024 #define AD4695_REG_GPIO_CTRL 0x0026 #define AD4695_REG_GP_MODE 0x0027 +#define AD4695_REG_GP_MODE_BUSY_GP_SEL BIT(5) +#define AD4695_REG_GP_MODE_BUSY_GP_EN BIT(1) #define AD4695_REG_TEMP_CTRL 0x0029 #define AD4695_REG_TEMP_CTRL_TEMP_EN BIT(0) #define AD4695_REG_CONFIG_IN(n) (0x0030 | (n)) @@ -124,13 +130,22 @@ struct ad4695_channel_config { struct ad4695_state { struct spi_device *spi; + struct spi_offload *offload; + struct spi_offload_trigger *offload_trigger; struct regmap *regmap; struct regmap *regmap16; struct gpio_desc *reset_gpio; + /* currently PWM CNV only supported with SPI offload use */ + struct pwm_device *cnv_pwm; + /* protects against concurrent use of cnv_pwm */ + struct mutex cnv_pwm_lock; + /* offload also requires separate gpio to manually control CNV */ + struct gpio_desc *cnv_gpio; /* voltages channels plus temperature and timestamp */ struct iio_chan_spec iio_chan[AD4695_MAX_CHANNELS + 2]; struct ad4695_channel_config channels_cfg[AD4695_MAX_CHANNELS]; const struct ad4695_chip_info *chip_info; + int sample_freq_range[3]; /* Reference voltage. */ unsigned int vref_mv; /* Common mode input pin voltage. */ @@ -355,6 +370,13 @@ static const struct ad4695_chip_info ad4698_chip_info = { .num_voltage_inputs = 8, }; +static void ad4695_cnv_manual_trigger(struct ad4695_state *st) +{ + gpiod_set_value_cansleep(st->cnv_gpio, 1); + ndelay(10); + gpiod_set_value_cansleep(st->cnv_gpio, 0); +} + /** * ad4695_set_single_cycle_mode - Set the device in single cycle mode * @st: The AD4695 state @@ -460,6 +482,17 @@ static int ad4695_exit_conversion_mode(struct ad4695_state *st) */ st->cnv_cmd2 = AD4695_CMD_EXIT_CNV_MODE << 3; + if (st->cnv_gpio) { + ad4695_cnv_manual_trigger(st); + + /* + * In this case, CNV is not connected to CS, so we don't need + * the extra CS toggle to trigger the conversion and toggling + * CS would have no effect. + */ + return spi_sync_transfer(st->spi, &xfers[1], 1); + } + return spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers)); } @@ -687,6 +720,159 @@ static irqreturn_t ad4695_trigger_handler(int irq, void *p) return IRQ_HANDLED; } +static int ad4695_offload_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad4695_state *st = iio_priv(indio_dev); + struct spi_offload_trigger_config config = { + .type = SPI_OFFLOAD_TRIGGER_DATA_READY, + }; + struct spi_transfer *xfer = &st->buf_read_xfer[0]; + struct pwm_state state; + u8 temp_chan_bit = st->chip_info->num_voltage_inputs; + u8 num_slots = 0; + u8 temp_en = 0; + unsigned int bit; + int ret; + + iio_for_each_active_channel(indio_dev, bit) { + if (bit == temp_chan_bit) { + temp_en = 1; + continue; + } + + ret = regmap_write(st->regmap, AD4695_REG_AS_SLOT(num_slots), + FIELD_PREP(AD4695_REG_AS_SLOT_INX, bit)); + if (ret) + return ret; + + num_slots++; + } + + /* + * For non-offload, we could discard data to work around this + * restriction, but with offload, that is not possible. + */ + if (num_slots < 2) { + dev_err(&st->spi->dev, + "At least two voltage channels must be enabled.\n"); + return -EINVAL; + } + + ret = regmap_update_bits(st->regmap, AD4695_REG_TEMP_CTRL, + AD4695_REG_TEMP_CTRL_TEMP_EN, + FIELD_PREP(AD4695_REG_TEMP_CTRL_TEMP_EN, + temp_en)); + if (ret) + return ret; + + /* Each BUSY event means just one sample for one channel is ready. */ + memset(xfer, 0, sizeof(*xfer)); + xfer->offload_flags = SPI_OFFLOAD_XFER_RX_STREAM; + xfer->bits_per_word = 16; + xfer->len = 2; + + spi_message_init_with_transfers(&st->buf_read_msg, xfer, 1); + st->buf_read_msg.offload = st->offload; + + ret = spi_optimize_message(st->spi, &st->buf_read_msg); + if (ret) + return ret; + + /* + * NB: technically, this is part the SPI offload trigger enable, but it + * doesn't work to call it from the offload trigger enable callback + * because it requires accessing the SPI bus. Calling it from the + * trigger enable callback could cause a deadlock. + */ + ret = regmap_set_bits(st->regmap, AD4695_REG_GP_MODE, + AD4695_REG_GP_MODE_BUSY_GP_EN); + if (ret) + goto err_unoptimize_message; + + ret = spi_offload_trigger_enable(st->offload, st->offload_trigger, + &config); + if (ret) + goto err_disable_busy_output; + + ret = ad4695_enter_advanced_sequencer_mode(st, num_slots); + if (ret) + goto err_offload_trigger_disable; + + guard(mutex)(&st->cnv_pwm_lock); + pwm_get_state(st->cnv_pwm, &state); + /* + * PWM subsystem generally rounds down, so requesting 2x minimum high + * time ensures that we meet the minimum high time in any case. + */ + state.duty_cycle = AD4695_T_CNVH_NS * 2; + ret = pwm_apply_might_sleep(st->cnv_pwm, &state); + if (ret) + goto err_offload_exit_conversion_mode; + + return 0; + +err_offload_exit_conversion_mode: + /* + * We have to unwind in a different order to avoid triggering offload. + * ad4695_exit_conversion_mode() triggers a conversion, so it has to be + * done after spi_offload_trigger_disable(). + */ + spi_offload_trigger_disable(st->offload, st->offload_trigger); + ad4695_exit_conversion_mode(st); + goto err_disable_busy_output; + +err_offload_trigger_disable: + spi_offload_trigger_disable(st->offload, st->offload_trigger); + +err_disable_busy_output: + regmap_clear_bits(st->regmap, AD4695_REG_GP_MODE, + AD4695_REG_GP_MODE_BUSY_GP_EN); + +err_unoptimize_message: + spi_unoptimize_message(&st->buf_read_msg); + + return ret; +} + +static int ad4695_offload_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad4695_state *st = iio_priv(indio_dev); + struct pwm_state state; + int ret; + + scoped_guard(mutex, &st->cnv_pwm_lock) { + pwm_get_state(st->cnv_pwm, &state); + state.duty_cycle = 0; + ret = pwm_apply_might_sleep(st->cnv_pwm, &state); + if (ret) + return ret; + } + + spi_offload_trigger_disable(st->offload, st->offload_trigger); + + /* + * ad4695_exit_conversion_mode() triggers a conversion, so it has to be + * done after spi_offload_trigger_disable(). + */ + ret = ad4695_exit_conversion_mode(st); + if (ret) + return ret; + + ret = regmap_clear_bits(st->regmap, AD4695_REG_GP_MODE, + AD4695_REG_GP_MODE_BUSY_GP_EN); + if (ret) + return ret; + + spi_unoptimize_message(&st->buf_read_msg); + + return 0; +} + +static const struct iio_buffer_setup_ops ad4695_offload_buffer_setup_ops = { + .postenable = ad4695_offload_buffer_postenable, + .predisable = ad4695_offload_buffer_predisable, +}; + /** * ad4695_read_one_sample - Read a single sample using single-cycle mode * @st: The AD4695 state @@ -718,6 +904,13 @@ static int ad4695_read_one_sample(struct ad4695_state *st, unsigned int address) if (ret) return ret; + /* + * If CNV is connected to CS, the previous function will have triggered + * the conversion, otherwise, we do it manually. + */ + if (st->cnv_gpio) + ad4695_cnv_manual_trigger(st); + /* * Setting the first channel to the temperature channel isn't supported * in single-cycle mode, so we have to do an extra conversion to read @@ -729,6 +922,13 @@ static int ad4695_read_one_sample(struct ad4695_state *st, unsigned int address) ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers)); if (ret) return ret; + + /* + * If CNV is connected to CS, the previous function will have + * triggered the conversion, otherwise, we do it manually. + */ + if (st->cnv_gpio) + ad4695_cnv_manual_trigger(st); } /* Then read the result and exit conversion mode. */ @@ -842,11 +1042,34 @@ static int ad4695_read_raw(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_CHAN_INFO_SAMP_FREQ: { + struct pwm_state state; + + ret = pwm_get_state_hw(st->cnv_pwm, &state); + if (ret) + return ret; + + *val = DIV_ROUND_UP_ULL(NSEC_PER_SEC, state.period); + + return IIO_VAL_INT; + } default: return -EINVAL; } } +static int ad4695_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + return IIO_VAL_INT; + default: + return IIO_VAL_INT_PLUS_MICRO; + } +} + static int ad4695_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) @@ -900,6 +1123,17 @@ static int ad4695_write_raw(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_CHAN_INFO_SAMP_FREQ: { + struct pwm_state state; + + if (val <= 0 || val > st->chip_info->max_sample_rate) + return -EINVAL; + + guard(mutex)(&st->cnv_pwm_lock); + pwm_get_state(st->cnv_pwm, &state); + state.period = DIV_ROUND_UP_ULL(NSEC_PER_SEC, val); + return pwm_apply_might_sleep(st->cnv_pwm, &state); + } default: return -EINVAL; } @@ -923,6 +1157,7 @@ static int ad4695_read_avail(struct iio_dev *indio_dev, */ S16_MIN / 4, 0, 0, MICRO / 4, S16_MAX / 4, S16_MAX % 4 * MICRO / 4 }; + struct ad4695_state *st = iio_priv(indio_dev); switch (mask) { case IIO_CHAN_INFO_CALIBSCALE: @@ -943,6 +1178,10 @@ static int ad4695_read_avail(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_CHAN_INFO_SAMP_FREQ: + *vals = st->sample_freq_range; + *type = IIO_VAL_INT; + return IIO_AVAIL_RANGE; default: return -EINVAL; } @@ -978,6 +1217,7 @@ static int ad4695_debugfs_reg_access(struct iio_dev *indio_dev, static const struct iio_info ad4695_info = { .read_raw = &ad4695_read_raw, + .write_raw_get_fmt = &ad4695_write_raw_get_fmt, .write_raw = &ad4695_write_raw, .read_avail = &ad4695_read_avail, .debugfs_reg_access = &ad4695_debugfs_reg_access, @@ -1091,26 +1331,156 @@ static int ad4695_parse_channel_cfg(struct ad4695_state *st) return 0; } +static bool ad4695_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; + + // args[0] is the trigger event. + // args[1] is the GPIO pin number. + if (nargs != 2 || args[0] != AD4695_TRIGGER_EVENT_BUSY) + return false; + + return true; +} + +static int ad4695_offload_trigger_request(struct spi_offload_trigger *trigger, + enum spi_offload_trigger_type type, + u64 *args, u32 nargs) +{ + struct ad4695_state *st = spi_offload_trigger_get_priv(trigger); + + /* Should already be validated by match, but just in case. */ + if (nargs != 2) + return -EINVAL; + + /* DT tells us if BUSY event uses GP0 or GP3. */ + if (args[1] == AD4695_TRIGGER_PIN_GP3) + return regmap_set_bits(st->regmap, AD4695_REG_GP_MODE, + AD4695_REG_GP_MODE_BUSY_GP_SEL); + + return regmap_clear_bits(st->regmap, AD4695_REG_GPIO_CTRL, + AD4695_REG_GP_MODE_BUSY_GP_SEL); +} + +static int +ad4695_offload_trigger_validate(struct spi_offload_trigger *trigger, + struct spi_offload_trigger_config *config) +{ + if (config->type != SPI_OFFLOAD_TRIGGER_DATA_READY) + return -EINVAL; + + return 0; +} + +/* + * NB: There are no enable/disable callbacks here due to requiring a SPI + * message to enable or disable the BUSY output on the ADC. + */ +static const struct spi_offload_trigger_ops ad4695_offload_trigger_ops = { + .match = ad4695_offload_trigger_match, + .request = ad4695_offload_trigger_request, + .validate = ad4695_offload_trigger_validate, +}; + +static void ad4695_pwm_disable(void *pwm) +{ + pwm_disable(pwm); +} + +static int ad4695_probe_spi_offload(struct iio_dev *indio_dev, + struct ad4695_state *st) +{ + struct device *dev = &st->spi->dev; + struct spi_offload_trigger_info trigger_info = { + .fwnode = dev_fwnode(dev), + .ops = &ad4695_offload_trigger_ops, + .priv = st, + }; + struct pwm_state pwm_state; + struct dma_chan *rx_dma; + int ret, i; + + indio_dev->num_channels = st->chip_info->num_voltage_inputs + 1; + indio_dev->setup_ops = &ad4695_offload_buffer_setup_ops; + + if (!st->cnv_gpio) + return dev_err_probe(dev, -ENODEV, + "CNV GPIO is required for SPI offload\n"); + + 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"); + + ret = devm_mutex_init(dev, &st->cnv_pwm_lock); + if (ret) + return ret; + + st->cnv_pwm = devm_pwm_get(dev, NULL); + if (IS_ERR(st->cnv_pwm)) + return dev_err_probe(dev, PTR_ERR(st->cnv_pwm), + "failed to get CNV PWM\n"); + + pwm_init_state(st->cnv_pwm, &pwm_state); + + /* If firmware didn't provide default rate, use 10kHz (arbitrary). */ + if (pwm_state.period == 0) + pwm_state.period = 100 * MILLI; + + pwm_state.enabled = true; + + ret = pwm_apply_might_sleep(st->cnv_pwm, &pwm_state); + if (ret) + return dev_err_probe(dev, ret, "failed to apply CNV PWM\n"); + + ret = devm_add_action_or_reset(dev, ad4695_pwm_disable, st->cnv_pwm); + if (ret) + return ret; + + 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"); + + /* + * REVISIT: ideally, we would ask the RX DMA stream what the + * buffer layout is. Right now, the only supported offload is + * the ADI ad469x HDL project which always uses 32-bit word + * size for data values, regardless of the SPI bits per word. + */ + + for (i = 0; i < indio_dev->num_channels; i++) { + struct iio_chan_spec *chan = &st->iio_chan[i]; + + /* update storagebits to match offload capabilities */ + chan->scan_type.storagebits = 32; + /* add sample frequency for PWM CNV trigger */ + chan->info_mask_separate |= BIT(IIO_CHAN_INFO_SAMP_FREQ); + chan->info_mask_separate_available |= BIT(IIO_CHAN_INFO_SAMP_FREQ); + } + + return devm_iio_dmaengine_buffer_setup_ext2(dev, indio_dev, rx_dma, + IIO_BUFFER_DIRECTION_IN); +} + static int ad4695_probe(struct spi_device *spi) { struct device *dev = &spi->dev; struct ad4695_state *st; struct iio_dev *indio_dev; - struct gpio_desc *cnv_gpio; bool use_internal_ldo_supply; bool use_internal_ref_buffer; int ret; - cnv_gpio = devm_gpiod_get_optional(dev, "cnv", GPIOD_OUT_LOW); - if (IS_ERR(cnv_gpio)) - return dev_err_probe(dev, PTR_ERR(cnv_gpio), - "Failed to get CNV GPIO\n"); - - /* Driver currently requires CNV pin to be connected to SPI CS */ - if (cnv_gpio) - return dev_err_probe(dev, -ENODEV, - "CNV GPIO is not supported\n"); - indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); if (!indio_dev) return -ENOMEM; @@ -1122,6 +1492,10 @@ static int ad4695_probe(struct spi_device *spi) if (!st->chip_info) return -EINVAL; + st->sample_freq_range[0] = 1; /* min */ + st->sample_freq_range[1] = 1; /* step */ + st->sample_freq_range[2] = st->chip_info->max_sample_rate; /* max */ + st->regmap = devm_regmap_init(dev, &ad4695_regmap_bus, st, &ad4695_regmap_config); if (IS_ERR(st->regmap)) @@ -1134,6 +1508,11 @@ static int ad4695_probe(struct spi_device *spi) return dev_err_probe(dev, PTR_ERR(st->regmap16), "Failed to initialize regmap16\n"); + st->cnv_gpio = devm_gpiod_get_optional(dev, "cnv", GPIOD_OUT_LOW); + if (IS_ERR(st->cnv_gpio)) + return dev_err_probe(dev, PTR_ERR(st->cnv_gpio), + "Failed to get CNV GPIO\n"); + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(ad4695_power_supplies), ad4695_power_supplies); @@ -1260,12 +1639,36 @@ static int ad4695_probe(struct spi_device *spi) indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = st->iio_chan; - ret = devm_iio_triggered_buffer_setup(dev, indio_dev, - iio_pollfunc_store_time, - ad4695_trigger_handler, - &ad4695_buffer_setup_ops); - if (ret) - return ret; + static const struct spi_offload_config ad4695_offload_config = { + .capability_flags = SPI_OFFLOAD_CAP_TRIGGER + | SPI_OFFLOAD_CAP_RX_STREAM_DMA, + }; + + st->offload = devm_spi_offload_get(dev, spi, &ad4695_offload_config); + ret = PTR_ERR_OR_ZERO(st->offload); + if (ret && ret != -ENODEV) + return dev_err_probe(dev, ret, "failed to get SPI offload\n"); + + /* If no SPI offload, fall back to low speed usage. */ + if (ret == -ENODEV) { + /* Driver currently requires CNV pin to be connected to SPI CS */ + if (st->cnv_gpio) + return dev_err_probe(dev, -EINVAL, + "CNV GPIO is not supported\n"); + + indio_dev->num_channels = st->chip_info->num_voltage_inputs + 2; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, + iio_pollfunc_store_time, + ad4695_trigger_handler, + &ad4695_buffer_setup_ops); + if (ret) + return ret; + } else { + ret = ad4695_probe_spi_offload(indio_dev, st); + if (ret) + return ret; + } return devm_iio_device_register(dev, indio_dev); } @@ -1302,3 +1705,4 @@ MODULE_AUTHOR("Ramona Gradinariu "); MODULE_AUTHOR("David Lechner "); MODULE_DESCRIPTION("Analog Devices AD4695 ADC driver"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_DMAENGINE_BUFFER);