From nobody Sat Oct 24 02:57:34 2026 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1792682350; b=XrZuHQ1l8W6YGdEq/UP8YGU+VR9fGEelAm2ZEv1bwp4y9lmscSEQbRsSeJkMs2C46mHB xWcEz+l0e+2BX7YFtqGv1gKX+P78twcSzPHZcH4vBnbQns6ar0B2zJX5pLZNgZr03n76X 1Bv24h0Nro6FyLDHziLAeIYIVpYeNn4JYLo9ycu07ea4JnmmwlRSIExgRu7+yUCyUNQLJ SvrphK7HayrUufYimleiHtjrgbW1ePYveFb2NCtLzIIarByClTOYxFbt5QwLDasLQXsT2 n3f/cgUv7ZBjfwQCDjEhi7b6PD286zTL45xOX3NroK00H4N1oldFH5k72azifmnnRzQ== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1792682350; h=Received:DKIM-Signature:Received:From:Date:Subject:MIME-Version: Content-Type:Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=fvStjk2P5Y/1Jdt3vgXWKnB8BBjsKIf7mXeprvth/xQ=; b=2B/4hqSQGkGxVc7sr+iPQCxomLW0iz6jCh8ejSd5fCNP5wkGzm6008ZQXa2RW+aZ//mY fCmEe7EPlolnkP5yc5QJzcOJ5RgKevKr+JN0itKXmcVi1mWeTi6HYzdDgd9t5q5tJ8yNI kLpvhOPCGnh9cLC7fOtD+Pw2pXltiwceK0aqq06fhZEgSedJNDIWrqApRgJOWpgpvENAF x0jMKVoKd+3Yf9jjjpsnLE5bmKT2uCv9Fm3BhHZBGQpIZmo0V+wXGKximiqnLrfrm50mC pni2Y5Ow0UgWessLDkv+lVgesnFtFeXmfnqR0ltBDeKtDfuik5qd/y4BUrC8gbhEhMA== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=bpN75crW; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AE715606CC43; Thu, 22 Oct 2026 15:19:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=bpN75crW Authentication-Results: smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 ARC-Seal: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; cv=none; t=1792682349; b=ifgZGx5BiqBeTWrnFqt60Jghy8Nmkx6IVCE06RKhauZjg3sjTQY//JbK3PkEK+FLNKdI aQldORaOpDWsbG0hCvdj+1bL8rU6kqB35Wu+MoGrQ6blELP0HUPlBr7zNts/TRp3xRWNp O+WfD0xwtHl8Qj1LKkkADl3pQohi/IYBT4Vjk1cb0pu5nwGuGATvrajibWyotOxFWUGUX M8bBG1ajlVepHSqQK6qw/vgk9vtUe2HbCdLbERsZFOcZHgy/41LC1BPZNJ9/BN/CbyfrL 8zKplgxz0zJNUm2H+TMXvmWMGiktMAk3TXDbKChHeZ3aIEWKbH/UI8nszzTEGM7y3XQ== ARC-Message-Signature: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; c=relaxed/relaxed; t=1792682349; h=DKIM-Signature:Received:From:Date:Subject:MIME-Version:Content-Type: Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=fvStjk2P5Y/1Jdt3vgXWKnB8BBjsKIf7mXeprvth/xQ=; b=ge8RgnS0yBXSczKI6iEjndzjeP3KjlIO1VfV8bL+scxcI7VGz/uVLH9oGEunsCBF35rl KDo7D9qnZB/AEym2bo2pbSZVY0EoAN6vMDCMhoVx0UjQCTOI62+8cCYiApg6i9k37Eei8 siVrITt1UQm1aQdutsM/FskMY5RJj9LuwMCSlvl7oyhQ0fTt/JHmqodOkD3GjuTfE+6Ar zDxV3uXZiSwbD9D7Tf/OT6s/7AYKJERCGewO10BHHOhOMqnRA7b3CuQd9UQNpmAt3KxLp QxUVWtKQ4n9pXpzGbhYdD/aees7n8SJK1PM+MWiK/thJtRKmn0CgoOD5KQXZs10efqA== ARC-Authentication-Results: i=1; smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 Received: from lkml.kernel.org (nexus.subspace.kernel.org [100.80.115.77]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.kernel.org (Postfix) with ESMTPS id E5F141F01828; Thu, 22 Oct 2026 15:19:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792682349; bh=fvStjk2P5Y/1Jdt3vgXWKnB8BBjsKIf7mXeprvth/xQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To; b=bpN75crWXyrGU6vEOJo0LqBTP6TdhqcZnzgM391FOlb4yY8nfvmSJpWOUZmeCGbnG +glc9v9xl9IEOc96rPOvAM1VkD3uwS7HvQBRFtgpnNWczuJ/CokH59mFv0Z7kb3HKC mRdUFztPbPAu8dSaJo1+z7mRUL5EkHGYnCQaa0wP2tDEHQZAKItxYlTAIIASZkhxQi ojvd5JXTGGVgGlmd08A8YJgqg2NAROodQ+lQ9tiJxnPL6QBqBxmeJ0mgWdTSZb6Sx/ cGuWA6G/k4JX0hxSCSDAOcc8xPZKxahWz6WjkqDn5jNnhUrMfYnm2FT7mBazAsDoy/ ocH3KxyjvaQ1Q== Received: from nexus.subspace.kernel.org (localhost [IPv6:::1]) by lkml.kernel.org (Postfix) with ESMTP id 6F94241E4E; Thu, 22 Oct 2026 15:19:08 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Thu, 22 Oct 2026 12:18:59 -0300 Subject: [PATCH v2 01/10] iio: frequency: ad9910: powerdown fix X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Message-Id: <20261022-ad9910-backend-support-v2-1-0ff7f0bff326@analog.com> References: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> In-Reply-To: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> To: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, linux@analog.com, devicetree@vger.kernel.org, linux-pwm@vger.kernel.org, linux-doc@vger.kernel.org, Jonathan Cameron Cc: Olivier Moysan , Jonathan Cameron , David Lechner , Andy Shevchenko , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Jonathan Corbet , Shuah Khan , Randy Dunlap , Rodrigo Alencar X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1792682347; l=2077; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=aJtPIXmw5LGBhO6Ijl0bIJNuEuTO3aFnvbkzsDyxwGs=; b=h3/LsJueV0GYhI7rqbtQOzAPYVcgKAo9BSKeRCo5KLWK8yJL0GnbnqX/uFiGyviY7amK/iPGg PYwPjp03N+PCCISoO1mXYvzrxcH4l1STar1V3ZEXXKWlpRZI8N8QOxb X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com Content-Transfer-Encoding: quoted-printable From: Rodrigo Alencar Enable the software powerdown on all the applicable CFR1 register bits at once with an IO update. It turns out that DIGITAL and REFCLK_INPUT powerdown do need an IO update when enabling the powerdown, but that is not the case when powering it up again. It is an asymmetric behavior, which was observed while profiling power consumption in the lab. Fixes: 22452fe6cd08 ("iio: frequency: ad9910: initial driver implementation= ") Reviewed-by: Nuno S=C3=A1 Signed-off-by: Rodrigo Alencar --- drivers/iio/frequency/ad9910.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/drivers/iio/frequency/ad9910.c b/drivers/iio/frequency/ad9910.c index 04a4e184b873..8bc24d0b7442 100644 --- a/drivers/iio/frequency/ad9910.c +++ b/drivers/iio/frequency/ad9910.c @@ -621,26 +621,16 @@ static int ad9910_sw_powerdown_set(struct ad9910_stat= e *st, bool enable) if (ad9910_sw_powerdown_get(st) =3D=3D enable) return 0; =20 - /* - * When powering down, the DAC and AUX_DAC (SW1) must be powered down - * first, as they require an I/O update to take effect. The opposite is - * true when powering up, the DAC and AUX_DAC must be powered up last, - * i.e., after the DIGITAL and REFCLK_INPUT (SW0) power up. - */ - if (enable) { - ret =3D ad9910_reg32_update(st, AD9910_REG_CFR1, - AD9910_CFR1_SW1_POWER_DOWN_MSK, - AD9910_CFR1_SW1_POWER_DOWN_MSK, - true); - if (ret) - return ret; - + if (enable) return ad9910_reg32_update(st, AD9910_REG_CFR1, - AD9910_CFR1_SW0_POWER_DOWN_MSK, - AD9910_CFR1_SW0_POWER_DOWN_MSK, - false); - } + AD9910_CFR1_SW_POWER_DOWN_MSK, + AD9910_CFR1_SW_POWER_DOWN_MSK, + true); =20 + /* + * When powering up, the DIGITAL and REFCLK_INPUT (SW0) must be powered + * up first, as they do not require an I/O update to take effect. + */ ret =3D ad9910_reg32_update(st, AD9910_REG_CFR1, AD9910_CFR1_SW0_POWER_DOWN_MSK, 0, false); if (ret) --=20 2.43.0 From nobody Sat Oct 24 02:57:34 2026 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1792682350; b=RJODuBTW/OOPoIoaOdCd/qfSQ2RexaDbCiu6uf5+Ygmg0DQSxWgS3ZTThQkPo2hN8C6R qdfnVWMKWc7shqNHYD0t1YkY0Lil0daUNk7vDz0yuQm6UIw4R4F+ywFHuYYV9rwlh+QEo hOVFytdMiKpFtBcnPDn/EQPpqP4E37ISpGaBnQbuSDuf9PiUWCgSDPLjM/hPPFTl4UgD8 fg55sz3m1phrtzbXU8anVMmjS2fbWzM4YoOCpcgZMMzBGlyidcrbiEpHtTCnYTzTtEcN6 cKdnEinOOMKAaTmeqQpRrT0AuPNlaXS77B99ZCdpKNOTwCJSg15Iqy4BzLwYgfhcHdQ== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1792682350; h=Received:DKIM-Signature:Received:From:Date:Subject:MIME-Version: Content-Type:Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=ZgsSRgLhdRJXX0D7l/a2ulYRdMo+CZDmbqVMPRhhICM=; b=caJKiVVnj68qwDJVlFBvxxlKetxyd4xE7Suj9ObtRU3Z3/QVWXcaItl5bVS9gVogqDoM p6qMQ/TVcOKVnvojKjNa07Y9sWrxxbV9jO9XAvqIalvJncqysNMTPOuRJhIfG4F5IlyRG H5oPKMSjsYFYXGZmDJARw3NEBEzAL14Ggh/s8cyQsVS+ZH0wAEPXeb2W/q2CE7ctWwWWq 25oYs/RBMpYBjSYXtvRmBVxcIs67kaVAKBgxFGS20K3ytYrqewP7b+jphNvjwVmQ+xLI0 ZKLeL4pWpgqrXNhLulJG82TE4ViTTohNmTgtO1op8P3Knh/MGF0iK/TsPp5MzcGEgCw== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b="SPbTJyJ/"; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 70A4A606BE53; Thu, 22 Oct 2026 15:19:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=SPbTJyJ/ Authentication-Results: smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 ARC-Seal: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; cv=none; t=1792682350; b=oPC/mkmqL8k6dIkjwPihWQV9mpKOt7kbD/PGPfkbsmWPcGs92ojZDTl9KgZofKw+Snsb g+c27fbKqFss1NX3eO5UiOggmqFj5TNjE5o33MSOJPNrLo5PPCNQ6/qChGa6Y8BRPxDE0 1iV9JkkYP698giNZJIDa8PJsinnYbLicCx5pWj/lVBdn5HajnXsND4ZZzHxIi3+UToBLD fu6hEEX2Gvb3bbwj9QqMBVQ7JnHZr8i5LwSyBFA5iJRBr+wQabYq3FqGV7eZyJqyn+IDR sMXi7BevvScyOxn1jCzAf4879IrKH0DarU5mGIzjhFlPbki4BooceENoaLl0dJ24EvQ== ARC-Message-Signature: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; c=relaxed/relaxed; t=1792682350; h=DKIM-Signature:Received:From:Date:Subject:MIME-Version:Content-Type: Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=ZgsSRgLhdRJXX0D7l/a2ulYRdMo+CZDmbqVMPRhhICM=; b=0RGDpY6S8NmYp5VJkwXRGfJPdYLP2DKQFCsmITiQAfs1cR9oypn51IxYUHDJe9GZSPdB rHSXKiEzBkxpu59y3lPc83z8z/oHwOloR8tmJ7iTjkT5V7WT7i/T9T9M9BoxVXLSrr76I vZ3u4LpNXpBpVIG51kUXy4uN4+y6/YPd6hUeXbYVEMvHzlTzpUaFdoE/lk2LdLpLckGtZ ZO8UHPoNzJFxyddegqcsX+/Po5DZtuVFUAZBhxA/vreEGHHBPY9X1Cmc8AHeb+kcEjSJc ChC/Iwt2IulmYwHYelZ+EtTzHq3pY7hG9LNkQg+lqO2g4zwLDPO7a3OAMsWA3k/M8XQ== ARC-Authentication-Results: i=1; smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 Received: from lkml.kernel.org (nexus.subspace.kernel.org [100.80.115.77]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.kernel.org (Postfix) with ESMTPS id EDAAF1F01829; Thu, 22 Oct 2026 15:19:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792682350; bh=ZgsSRgLhdRJXX0D7l/a2ulYRdMo+CZDmbqVMPRhhICM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To; b=SPbTJyJ/DSyInQsNKfFWtSuBgD41b2GlQb9P1KOcVynpHjyMVjwa3WzR34zmwgjO2 xJGLw6cg5HxcVzUFqHkBKH9QAfsXGCoXd2xkd3PGxRzMCXC8rjkgW2CN0diQ0ivMQu gnuRnj/ondEM3SSw2CmKTzXVhUzNKnhW18pA/DTnYI/uKmDX7kTXWIuliP+bR7CKki boSShZpNL3xbYyn0bIkPCYTN2cb08VlTqVhWggUlGDu+3fLXE2haRhdc+h3f/2Izjo 3jbCLKe+4QkLshII6r6/hLr5WjNq70jeJEyRO/O2UPIXb3V3QJNZRhnzpLCJlundvM b8pk9pIse/Kfg== Received: from nexus.subspace.kernel.org (localhost [IPv6:::1]) by lkml.kernel.org (Postfix) with ESMTP id 770D441E4D; Thu, 22 Oct 2026 15:19:08 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Thu, 22 Oct 2026 12:19:00 -0300 Subject: [PATCH v2 02/10] iio: backend: add devm_iio_backend_get_optional() X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Message-Id: <20261022-ad9910-backend-support-v2-2-0ff7f0bff326@analog.com> References: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> In-Reply-To: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> To: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, linux@analog.com, devicetree@vger.kernel.org, linux-pwm@vger.kernel.org, linux-doc@vger.kernel.org, Jonathan Cameron Cc: Olivier Moysan , Jonathan Cameron , David Lechner , Andy Shevchenko , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Jonathan Corbet , Shuah Khan , Randy Dunlap , Rodrigo Alencar X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1792682347; l=4433; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=DR+JgLsY7qzSw7iJ/0ySFgwEAMpmPHtv/6q9aBcxSno=; b=3crxF6HvT5YXyw7lQncL7kG6Ddm2Syj8/O1U35ssgsGrGerNwuxlVurVylA8hO61dD0jB5dih vVin55RAwaJCDMT2C+5/HMGDQ7QNjwZAXflztbrTsKBiQ0ei9DvZwhj X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com Content-Transfer-Encoding: quoted-printable From: Rodrigo Alencar Frontend devices might not need a backend driver to rely on. An IIO device that supports backends can behave differently when they are not available and that should be acceptable. Such parts may provide basic functionality solely using the control interface (SPI for instance), being able to have extended features when a backend is present. Add devm_iio_backend_get_optional(), which returns NULL when the backend is not described in firmware, i.e., when the io-backends property is not present or, for a named lookup, when the name is not listed in the io-backend-names property. Other errors, such as probe deferral, are still returned. To make that possible, a named lookup that does not match any entry of io-backend-names now fails with -ENOENT, the same error returned when the io-backends reference is missing. Also, the missing reference is no longer logged as an error, leaving that to the caller. Reviewed-by: Nuno S=C3=A1 Signed-off-by: Rodrigo Alencar --- drivers/iio/industrialio-backend.c | 38 ++++++++++++++++++++++++++++++++++= ++++ include/linux/iio/backend.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-= backend.c index fbf5c39d7655..d12d163f45ca 100644 --- a/drivers/iio/industrialio-backend.c +++ b/drivers/iio/industrialio-backend.c @@ -1006,6 +1006,9 @@ static struct iio_backend *__devm_iio_backend_fwnode_= get_by_index(struct device =20 struct fwnode_handle *fwnode_back __free(fwnode_handle) =3D fwnode_find_reference(fwnode, "io-backends", index); + /* not described in firmware, let the caller decide what to do */ + if (PTR_ERR(fwnode_back) =3D=3D -ENOENT) + return ERR_CAST(fwnode_back); if (IS_ERR(fwnode_back)) return dev_err_cast_probe(dev, fwnode_back, "Cannot get Firmware reference\n"); @@ -1034,7 +1037,17 @@ static struct iio_backend *__devm_iio_backend_fwnode= _get(struct device *dev, con int ret; =20 if (name) { + if (!device_property_present(dev, "io-backend-names")) + return ERR_PTR(-ENOENT); + ret =3D device_property_match_string(dev, "io-backend-names", name); + /* + * device_property_match_string() also returns -ENODATA when + * @name is not listed in the property, which means that this + * backend is not described in firmware. + */ + if (ret =3D=3D -ENODATA) + return ERR_PTR(-ENOENT); if (ret < 0) return ERR_PTR(ret); index =3D ret; @@ -1061,6 +1074,31 @@ struct iio_backend *devm_iio_backend_get(struct devi= ce *dev, const char *name) } EXPORT_SYMBOL_NS_GPL(devm_iio_backend_get, "IIO_BACKEND"); =20 +/** + * devm_iio_backend_get_optional - Optional device managed backend device = get + * @dev: Consumer device for the backend + * @name: Backend name + * + * Gets the backend associated with @dev. A backend not described in firmw= are, + * i.e., the io-backends property is not present or @name is not listed in + * the io-backend-names property, is not treated as an error. + * + * RETURNS: + * A backend pointer, NULL if the backend is not described in firmware, + * negative error pointer otherwise. + */ +struct iio_backend *devm_iio_backend_get_optional(struct device *dev, + const char *name) +{ + struct iio_backend *back =3D devm_iio_backend_get(dev, name); + + if (IS_ERR(back) && PTR_ERR(back) =3D=3D -ENOENT) + return NULL; + + return back; +} +EXPORT_SYMBOL_NS_GPL(devm_iio_backend_get_optional, "IIO_BACKEND"); + /** * devm_iio_backend_get_by_index - Device managed backend device get by in= dex * @dev: Consumer device for the backend diff --git a/include/linux/iio/backend.h b/include/linux/iio/backend.h index 9c16b695a602..93d5f2073cc3 100644 --- a/include/linux/iio/backend.h +++ b/include/linux/iio/backend.h @@ -267,6 +267,8 @@ int iio_backend_extend_chan_spec(struct iio_backend *ba= ck, bool iio_backend_has_caps(struct iio_backend *back, u32 caps); void *iio_backend_get_priv(const struct iio_backend *conv); struct iio_backend *devm_iio_backend_get(struct device *dev, const char *n= ame); +struct iio_backend *devm_iio_backend_get_optional(struct device *dev, + const char *name); struct iio_backend *devm_iio_backend_get_by_index(struct device *dev, unsi= gned int index); struct iio_backend *devm_iio_backend_fwnode_get(struct device *dev, const char *name, --=20 2.43.0 From nobody Sat Oct 24 02:57:34 2026 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1792682351; b=I3W1fTemq+9aCBsUtJXVvy1outmHpi7h69gSPiEQ44BLjJZLXyrmG1qifxGUV5T/WXLa zhi5c2G4d/4kLQF4gXMTxRkjCXVze+cFkJi75GM6Ho4rwAQFJkNVZM7yG2amcp960wn8y KAeQEpkWeUfcHoWe/bQlk4KY92lsETw5xWMI5vP4olZuBQ8vPLyxqRFxulf8N26OgYmao RpzkSy6JfEhU/i0wiWjVn7Z4zaG0G1ejs58iuv5lhJmwj2WScllKkNUkJo1DFlvMNtU8O 0oqDhhIA/SQ4ZXMsj7JyhZ3LfrOSeaf1ne3tyXQg1jyw2OByzn82gigmzyLQe0nc+jg== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1792682351; h=Received:DKIM-Signature:Received:From:Date:Subject:MIME-Version: Content-Type:Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=mgr3ZBUadswlY0m18RoK45iupDXQ8OR9+gCMQmzuBbo=; b=UvSG34QLNqsxgOoQ74y+xZQoVEoJ3tmgCrNWhYEz1P0D7qd3nNHdItnlqiH3Owc5dwOy ErGcrbNkV4Lz1TGqzbcqEm02i34FLyhcKTRKd/h+PzFWsdt2QsfTCph5EkagL13JrddkA 0oZAmROhncXIaCGu1FwEOwl07miR1tT1EpO0jx95ir0uD1tBSgDLQUDEWGRtRComdqJCz TUyoMglDngSiCdXnDqiGqevRIMgJbit+mnIAk6U418RMMn8iwssK2HoiG9Mg+jL/OMLAw 7uto8XFW3bbx8BQWgn9nZhXPEGz08M9auEto8WiuapbH2H+QR0v+pOm53J/DQvazsew== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=IEFt0zHa; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BCFB4606CC5A; Thu, 22 Oct 2026 15:19:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=IEFt0zHa Authentication-Results: smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 ARC-Seal: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; cv=none; t=1792682350; b=tAHIoPT4yQYa5WD5VzurJM3c2a31QKk+fxh3JrxlIInJiLQtWsjlQdZt96/Yp0dW9pDk WFKuSkwgXSYm8W9oTRWFH2JxtHqMA7lHDT4cVWla83CMD+blHQncKaRQMsnfPJf3lJe1F zH9nHN4t0PHUc0rGHm05n2oIEQmFOMBrpQSerFfvv8ka3MowseYumloDzttjO5XW5F0t8 sid21JgR+i7WZ0yuiMVGyZ8qq4530tPD01ZApgO1P3zbCl5eG6SHAzGBvYJG4YuRdAWPr MW5NEI0pTqt48pAmnctyThQZxLzkwQ0Ns1qOHXRhxc4d2O7Wxw2rDPetldxK6yBCmQA== ARC-Message-Signature: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; c=relaxed/relaxed; t=1792682350; h=DKIM-Signature:Received:From:Date:Subject:MIME-Version:Content-Type: Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=mgr3ZBUadswlY0m18RoK45iupDXQ8OR9+gCMQmzuBbo=; b=1e1a3N96K8qD2LQAMSXQhDigwpOGHakkxOg5ZdEsysbw24x4Flp5adNINH3HOkPqA9YC x5Qz/eoXIL+BJSAStpNrNnyDOuI4lDcJcLMQ62CFzV3nJUGgADFVvGm+ivFzttbhAgjID FncvtU8mEl31dWOXdVS/51ghT6XRHb9gmDgpExIqFNv24PP5tGjGlBxnlKp6/Gm7Po9Uk d1jJSjKEnoYyS2VXcnGiVSXt5pACwh7i2hss+aP8hfwFzooyh0M+x2SwAb15kaGOVTQKG T1yus0oWWGrfo86obBBlWiNCpeiX38V/TIGR0UcoamwUGaFC6iytYvWUR33IL3qq8hQ== ARC-Authentication-Results: i=1; smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 Received: from lkml.kernel.org (nexus.subspace.kernel.org [100.80.115.77]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.kernel.org (Postfix) with ESMTPS id 00A701F031E0; Thu, 22 Oct 2026 15:19:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792682350; bh=mgr3ZBUadswlY0m18RoK45iupDXQ8OR9+gCMQmzuBbo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To; b=IEFt0zHaSNUWl/E5sitxQcOI6HRlusm66q/3D22+EwobWGHwkBg3CW/PitV8DKqsz DRkBhKTQvllN4fwzSuMtreGs7LiCaEBeSdih5RS+SRcorjxrHuPqhRWTDRjnBwb3JX DBWyzZSfx9sZ49crCLGzKQY1HEPkSIB1YqhF1i6muC9S3mEOMsMwqv6DVBFy62g7PQ RQGMVpNV6//xtwN1vnd7lJVYlo6T5VnBaP8NCEEuotbk8KapnbueIwDwBjTLnJ9qqL dh+kxo5JxPw3iIxAq65xKDuba2+OCEltjeqGqiOVOjouYlckoh7mSIXtAx92H0DN7w +zNcjGd6tWa0A== Received: from nexus.subspace.kernel.org (localhost [IPv6:::1]) by lkml.kernel.org (Postfix) with ESMTP id 7E68441E52; Thu, 22 Oct 2026 15:19:08 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Thu, 22 Oct 2026 12:19:01 -0300 Subject: [PATCH v2 03/10] dt-bindings: iio: frequency: add adi,ad9910-axi-backend X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Message-Id: <20261022-ad9910-backend-support-v2-3-0ff7f0bff326@analog.com> References: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> In-Reply-To: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> To: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, linux@analog.com, devicetree@vger.kernel.org, linux-pwm@vger.kernel.org, linux-doc@vger.kernel.org, Jonathan Cameron Cc: Olivier Moysan , Jonathan Cameron , David Lechner , Andy Shevchenko , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Jonathan Corbet , Shuah Khan , Randy Dunlap , Rodrigo Alencar X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1792682347; l=3683; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=CY1SqfatwESZkmEigRY0fdqsP8jg+f3FT7aQydkMpu0=; b=oI+lu8LbTOa5A6uaf9OYIuX4y81mOUXtMN/wKCdcC1YNfsNQkrOSbWCPrVI6U8OWrnOPgJPKy 9F4hXqVq0vZAMv7vRARXh22XzTJpNGwoCWVbyO2/DO/H8ETPZ4TtVbZ X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com Content-Transfer-Encoding: quoted-printable From: Rodrigo Alencar Add bindings for the AD9910 AXI backend IP core. The FPGA IP core interfaces with the data and control pins of the AD9910 DDS, streaming data from memory via DMA into the 18-bit parallel data port (F[1:0] and D[15:0] pins), which is clocked by the PDCLK output of the device. It also drives the PROFILE[2:0] pins and the DRCTL pin, which controls the slope direction of the digital ramp generator (DRG). The DRCTL pin is driven by a PWM generator, so the IP core is described both as an IIO backend and as a PWM provider. Signed-off-by: Rodrigo Alencar Acked-by: Conor Dooley --- .../iio/frequency/adi,ad9910-axi-backend.yaml | 74 ++++++++++++++++++= ++++ MAINTAINERS | 1 + 2 files changed, 75 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/frequency/adi,ad9910-axi= -backend.yaml b/Documentation/devicetree/bindings/iio/frequency/adi,ad9910-= axi-backend.yaml new file mode 100644 index 000000000000..20c45fbaf945 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/frequency/adi,ad9910-axi-backen= d.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/frequency/adi,ad9910-axi-backend.ya= ml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD9910 AXI Backend IP core + +maintainers: + - Rodrigo Alencar + +description: + FPGA IP core that interfaces with the data and control pins of the AD9910 + Direct Digital Synthesizer. The SPI bus is used as the control interface + of the AD9910 device, while this IP core streams data from memory via DMA + into the 18-bit parallel data port (F[1:0] and D[15:0] pins), which is + clocked by the PDCLK output of the AD9910. The IP core also drives the + PROFILE[2:0] pins for profile selection and provides a PWM generator that + drives the DRCTL pin, controlling the digital ramp generator (DRG) slope + direction. + + https://developer.analog.com/docs/hdl/latest/library/axi_ad9910/index.ht= ml + +properties: + compatible: + const: adi,ad9910-axi-backend + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + description: AXI bus clock (s_axi_aclk). + + dmas: + maxItems: 1 + + dma-names: + items: + - const: tx + + '#io-backend-cells': + const: 0 + + '#pwm-cells': + const: 3 + description: + The first cell must be 0, as only the DRCTL PWM output is available. + The second cell is the PWM period in nanoseconds and the third cell + holds the PWM flags. + +required: + - compatible + - reg + - clocks + - dmas + - dma-names + - '#io-backend-cells' + - '#pwm-cells' + +additionalProperties: false + +examples: + - | + ad9910_backend: dds-backend@44a00000 { + compatible =3D "adi,ad9910-axi-backend"; + reg =3D <0x44a00000 0x10000>; + clocks =3D <&clkc 15>; + dmas =3D <&tx_dma 0>; + dma-names =3D "tx"; + #io-backend-cells =3D <0>; + #pwm-cells =3D <3>; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index 52024397dc78..351ec0bca477 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1731,6 +1731,7 @@ S: Supported W: https://ez.analog.com/linux-software-drivers F: Documentation/ABI/testing/debugfs-iio-ad9910 F: Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9910 +F: Documentation/devicetree/bindings/iio/frequency/adi,ad9910-axi-backend.= yaml F: Documentation/devicetree/bindings/iio/frequency/adi,ad9910.yaml F: Documentation/iio/ad9910.rst F: drivers/iio/frequency/ad9910.c --=20 2.43.0 From nobody Sat Oct 24 02:57:34 2026 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1792682350; b=qdbuQeFleJ4BzhPR86iEXabGgadXZlempxhzG57Dt4y3IM9HXFTw+Wq+wQ+oionOoTuQ 1z8q45Sst4rYBfx1XlR1ILXOUeQgX7RkEtT7M3d4xbZK69aH7uJ2cKIo8m0yKvgVwajk5 ZkDf1IxSHNsQQVlnDxnhLPgoSgheaD2uHP+To2hHIQoSROYhwkZUTJKAB2OCQYuDhtOnz IaUSgyOsrE2mMiJ7siiWlsExqvGuucpA+SSpKf4JgcNP2ktLqcUa71UNpnTAaOMXL9kFx oGQrYEame4GKMGhaVu+E8A4gj78bzJVtcREhsOHmIg7XtHuxHrmOc6jUskIM9SKw/oA== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1792682350; h=Received:DKIM-Signature:Received:From:Date:Subject:MIME-Version: Content-Type:Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=tspvrJnpoKFHb7HbQbrWvZ9PGJAK8DVOcpQAjMGTVTU=; b=CXa51UqCGVMfxQ9NQ1c8z1hxNwPQghLzQ0L5LRiF0tebrtIQsZwHmBRAEc9q9l8OLnCK tGB+z3HmUvh/FPMHkQ1ezxmxZMJFjh8196SP7Ck+4TbDTC1kpQYENfTPrjNcTfVTREyxX ZO6fmAoUhRqdbDyh3LGSK7tHpso7XjfgzXfWT4cMi2wpvpuufq+g83luaBFS8mfZsf/f7 BHzPQXIYICHbfcZ8nKPm5Vt2WYEqxwS6BeEVOueBZqkZaW6oePxWrOR3RIA2VxYr9cKPb TVuGQBh23TtSkW7PGn8J+AasQGdMyv8dGatyMPYDvhd3OZwYwRdRes1xA0NdadQCwyQ== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=V3v2BCtb; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3A83D606CC4A; Thu, 22 Oct 2026 15:19:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=V3v2BCtb Authentication-Results: smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 ARC-Seal: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; cv=none; t=1792682349; b=ETrOkxX2aNLnORgC8Z2maRzKAGR+bRXeCSJT5Irq/CMJ7zV/JTURGRGo7gkDpwj100yF JbmAitX6GXIHfohUowgX96L+doxX2oYM1lWsqwPKDtnLRNmp05synLF13N+/hqeB6+gGX buI4J/gx+h5s3bBpVjhNcho93g9LuZqhRP0TJhKZUYKl2Dd18um5TeJU0CmW2/l48Li7N 2fUAlVyb5IDzVtUHZNJsgXEPK+ekNCzrS99MgvIeIfTU5Hzgdy2UaYWX+3z7a2m0AoTjN kzqHtH7+5bWVRMW97dRQmbuV2TRg13hf2Bc9PZxMj/2sKVMIXqgB5jjx4cjWb5Sss1g== ARC-Message-Signature: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; c=relaxed/relaxed; t=1792682349; h=DKIM-Signature:Received:From:Date:Subject:MIME-Version:Content-Type: Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=tspvrJnpoKFHb7HbQbrWvZ9PGJAK8DVOcpQAjMGTVTU=; b=JVuDP36x1ms9ZgHzDnHts8b1y5nUxHdQsm0XuwSwDbxmX9C6EHkR/oHQFoIpQ6lA0xUN DgEy34pXY3ifTL/BJ4Y53kVlvdlVg0ezLjgZxB9TZwWUlRHdYeB3KQlUeA3a+w4oGsvmJ Wye1zm6vZF1pBOoUjrCWuO+hzkSD26NkFo+ox9WgMBqWyUYifROWIEjEljXyth0t7Gwu7 iZvpfqmxcJCtYX2mcPMGof1OxTe94y3O2qBM/VBeUS08wEAWxQ3A2aJBrdLpayPmO0Gt1 Dy1/UgMCzCd6ywsvdAZNT7n+4gcNtXzxqiE/ZurrG4MYdrLHE9n0Hu3uhUvxmm74kWw== ARC-Authentication-Results: i=1; smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 Received: from lkml.kernel.org (nexus.subspace.kernel.org [100.80.115.77]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.kernel.org (Postfix) with ESMTPS id 0844B1F031E1; Thu, 22 Oct 2026 15:19:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792682349; bh=tspvrJnpoKFHb7HbQbrWvZ9PGJAK8DVOcpQAjMGTVTU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To; b=V3v2BCtbez1PkCclnED6TCXlvF+z1wqCBzv2widFxVucJi4ayQ64/SWSt3jRcsBpw 03BZVIL+XxnLPFZFKyiTDAMK9pD531bId+cUqXPrBJUXFbrqaYAcLCxKsPAS18rEVf PrzekblA4rSN8NMuEtE0h1rOKQz/U7nwdn3AA/bBm/04DUYKppq/WXQd7nLKNXhztU Z9SuKb8G/1ERdrY/0Z0KrMOLCbxu5eLebCGAJt6FI2d9b4OXCVmjG2MI+VjDAuNY1I 2qV7YvbszegqRmlDKctufATa4/DOUm+zIpIkVzxJW8DXuuqpXHRZF3uHIL1atz5yfV 0L5oDQMy4BU1g== Received: from nexus.subspace.kernel.org (localhost [IPv6:::1]) by lkml.kernel.org (Postfix) with ESMTP id 85FBA41E56; Thu, 22 Oct 2026 15:19:08 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Thu, 22 Oct 2026 12:19:02 -0300 Subject: [PATCH v2 04/10] dt-bindings: iio: frequency: ad9910: add io-backends property X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Message-Id: <20261022-ad9910-backend-support-v2-4-0ff7f0bff326@analog.com> References: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> In-Reply-To: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> To: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, linux@analog.com, devicetree@vger.kernel.org, linux-pwm@vger.kernel.org, linux-doc@vger.kernel.org, Jonathan Cameron Cc: Olivier Moysan , Jonathan Cameron , David Lechner , Andy Shevchenko , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Jonathan Corbet , Shuah Khan , Randy Dunlap , Rodrigo Alencar , Conor Dooley X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1792682347; l=2580; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=j5dklZUTaCzTsmtRwls0MFDoIhZtjambNyK1FFjRxqs=; b=BsBOHVrPcRaqCnqD4VjmxeKnUFNL37ft9mauZkQYeiH7Dh5zw1B2NjNd5fVxFfd8mSvZZU9lZ rWk/dEVGvOqAluy7AvsMnkS+trqT9dnGz4d3NEEcB2AdsOo82aU+KoU X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com Content-Transfer-Encoding: quoted-printable From: Rodrigo Alencar The AD9910 parallel data port allows high-speed modulation of the DDS core parameters, which requires a data source such as an FPGA IP core connected to the F[1:0] and D[15:0] pins. Add the io-backends property, so that an IIO backend providing such interface can be referenced. The property is optional as the parallel port is. The device remains functional through the SPI control interface only, as other modes can be used to drive the DDS core. Acked-by: Conor Dooley Signed-off-by: Rodrigo Alencar --- .../bindings/iio/frequency/adi,ad9910.yaml | 38 ++++++++++++++++++= ++++ 1 file changed, 38 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/frequency/adi,ad9910.yam= l b/Documentation/devicetree/bindings/iio/frequency/adi,ad9910.yaml index 4eebbd388b27..02fd49db93ff 100644 --- a/Documentation/devicetree/bindings/iio/frequency/adi,ad9910.yaml +++ b/Documentation/devicetree/bindings/iio/frequency/adi,ad9910.yaml @@ -120,6 +120,13 @@ properties: items: - const: drctl =20 + io-backends: + maxItems: 1 + description: + IIO backend that interfaces with the parallel data port, enabling da= ta + streaming into the device. The backend may also drive the PROFILE[2:= 0] + and DRCTL pins, the latter being exposed as a PWM provider. + adi,pll-enable: type: boolean description: @@ -206,4 +213,35 @@ examples: adi,refclk-out-drive-strength =3D "disabled"; }; }; + - | + #include + spi { + #address-cells =3D <1>; + #size-cells =3D <0>; + dds@0 { + compatible =3D "adi,ad9910"; + reg =3D <0>; + spi-max-frequency =3D <1000000>; + + #clock-cells =3D <1>; + clock-output-names =3D "sync_clk", "pdclk", "sync_out"; + + clocks =3D <&ad9910_refclk>; + clock-names =3D "ref_clk"; + + dvdd-io33-supply =3D <&vdd_io33>; + avdd33-supply =3D <&vdd_a33>; + dvdd18-supply =3D <&vdd_d18>; + avdd18-supply =3D <&vdd_a18>; + + reset-gpios =3D <&gpio 0 GPIO_ACTIVE_HIGH>; + io-reset-gpios =3D <&gpio 1 GPIO_ACTIVE_HIGH>; + powerdown-gpios =3D <&gpio 2 GPIO_ACTIVE_HIGH>; + update-gpios =3D <&gpio 3 GPIO_ACTIVE_HIGH>; + + io-backends =3D <&ad9910_backend>; + pwms =3D <&ad9910_backend 0 1000000 0>; + pwm-names =3D "drctl"; + }; + }; ... --=20 2.43.0 From nobody Sat Oct 24 02:57:34 2026 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1792682351; b=FsO85DMZXueoLc/TA5gRiIrQE5is6SJ4iI7/sXs+p1bWvG6Q8TIjkPGOQ2E7h6qv+r5x ubquT/PKpV6AaYlTACT3fe/B2b2r4t48Lvi3eBsQ8Ff3WtwAmS5LNcnNdYSmpn7VTN/eD tKUaNwv7bSL4OOwCW6dPldHgTvjZpInRW268zjE8r2Yj5sRV6GYuDeSv5UlNijrLm79QB Bf1gOXuRIZkoZ65RZOanhB4yhBK+4DfyvP0w2DCdjXrHeKLFiAh2vJpQis6YWY4zD0wv2 k82gJ9YaNpym+qoIf1/0bjfYieEBfEUeoTHU9JychEQR4TCwLSZvubqH0aB9rxDwDbA== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1792682351; h=Received:DKIM-Signature:Received:From:Date:Subject:MIME-Version: Content-Type:Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=XeYeuHW2ROs8z63PamAF7/Z5t0LYjZHf+QlIp4GkasQ=; b=HOMEqCF3PnCqGixRg0RmWRactXrc+NyedfDWKRKkkfrvgxqJsZ464VVsRFolJsDy1sNa rG29hp82KGb6dU1yEvCxFSbUWEhXt4IFT7CaivR8Co/wK+GGYolGzCbv1QH6yHf2tEUtU lsPYro1UR7jP1dUrbonoMFJpmwbasGQ5uZgaf63BLbIx0cgdvG+ivp0VssjNJftj5MT7c AZn78bQC6fmchUoPqMgjdQBOHEtZXlSBcLzqB2DKOEGUaLXtcYOw5FydX3feBk+4uc2g7 6Wmosdw/jyM5QWP6x6LcamntzQcWhB6jLKtyClXgI0f68s/uZKyzft8WsoWFRURPOfw== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=NYBAX83e; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 748D9606CC73; Thu, 22 Oct 2026 15:19:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=NYBAX83e Authentication-Results: smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 ARC-Seal: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; cv=none; t=1792682351; b=c9IZJdnWhDKN95QBNZlzMW99BJ9EUWNlxFiAE6y5vLhzoDzvUwHvmKkYVDX9f6/h3dbw 2WpDHEfkmd0+o/A/rTkJ+m6YNlLVN2qxRxQlpq4gThKvI/pR8J/Jdisnh07O/ygl0OGwO b4GeC+SgYqlCywzpk334qQNfCwYlpP1tSyfUoiG2Wg+BVyQgrRrwRK9mSrfQ6czWhgp4i al1JvvVlfW5sf4jvPqnw+C1toTyULf7lUEEpswU3j9gMbgxKEZkljQCJ1rQzdy5zobBA5 Xj/fPM7fF0hMVIMqJEFLymKHhVCUa2xjOrrcaiiDuQJilVeSYcgAonZKp9LeL2qCxPA== ARC-Message-Signature: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; c=relaxed/relaxed; t=1792682351; h=DKIM-Signature:Received:From:Date:Subject:MIME-Version:Content-Type: Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=XeYeuHW2ROs8z63PamAF7/Z5t0LYjZHf+QlIp4GkasQ=; b=TUaC9JydlWI4Jl84IgKCZqvpAY/n8eekV6lz0IxMEOuYKv+tUuuLBmYotr4bSrHLZps7 OaOwoGyhkjC+alC+cOZL//jQgfZf70DjL6I52xgNDWYOnXSKSGMNt1LwiFqPOK8VEKjj7 999jm4adV3rB5neDf5goQDGqZ5YlKCPNe2T1qIS6QefGRlVxyJXMFm5NM8+xWWhWskv2V ynsuch+aKqzA3adnEyYIVIGX3TjMceDwpYXJ6KQPHfEKEkIioV60xN/52YNOEGD10AFgR K43RaO0wyF36RMkUHBn4l0zqqAb7VRK0XnCK3GsFEZiEDAyRBh4UcK6Fn2ins8qyNXw== ARC-Authentication-Results: i=1; smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 Received: from lkml.kernel.org (nexus.subspace.kernel.org [100.80.115.77]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.kernel.org (Postfix) with ESMTPS id C237F1F031E4; Thu, 22 Oct 2026 15:19:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792682351; bh=XeYeuHW2ROs8z63PamAF7/Z5t0LYjZHf+QlIp4GkasQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To; b=NYBAX83evJEstw7ApFOpVq2XvQqSyNdpZsWezR1phO3Z+tNHHDgkUO3tlAgwoYnG4 giPa4nVCImQcvb2c0pCJ7cqJyGNo8/MRa1Njc8oXmA9UfxMN+8xxzJ38pu8nTIs6B/ VF+GGcrM27y/aNrpxIJF6L96Tnw951t0qeCVWPJDwzDbDrqAWz7j3hRSRX2jjOrTLW 5hDO4w2r3JzhsRc0GybrRGdxSOGycGXQKodBv0FC3SIxXgljtjp4BWNyfNLMSnd+tw yU3Dy78yQ8Bpbl1LsuazSissQynuYF3BkAf4EqzmOmqvjcCPwdpN7sv8c3Utfauof9 jGWqlH2IBnthw== Received: from nexus.subspace.kernel.org (localhost [IPv6:::1]) by lkml.kernel.org (Postfix) with ESMTP id 8DA2641E5A; Thu, 22 Oct 2026 15:19:08 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Thu, 22 Oct 2026 12:19:03 -0300 Subject: [PATCH v2 05/10] iio: frequency: ad9910: move channel indexes into a shared header X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Message-Id: <20261022-ad9910-backend-support-v2-5-0ff7f0bff326@analog.com> References: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> In-Reply-To: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> To: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, linux@analog.com, devicetree@vger.kernel.org, linux-pwm@vger.kernel.org, linux-doc@vger.kernel.org, Jonathan Cameron Cc: Olivier Moysan , Jonathan Cameron , David Lechner , Andy Shevchenko , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Jonathan Corbet , Shuah Khan , Randy Dunlap , Rodrigo Alencar X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1792682347; l=4373; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=x6NMO+HwBMwaNr1Y6ukLdwzGO76H8amSFklxVgJRt5o=; b=RY7ZuoYgghx0fHm+9xcyD5cZQ7KOqVeFqS1v/fNRORDaW9GdAukFEEkBq5CXOA4U4RNz5nk4h Ck7OCTLSUhCDJFZsyNlCXKjsMWm9UCKsjZjNGhNVSPQp4qJowTmP56F X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com Content-Transfer-Encoding: quoted-printable From: Rodrigo Alencar The channel indexes are used as channel identifiers in IIO backend operations, such as enabling a parallel data port destination or selecting a profile. Move them, along with the data destination definitions, into a shared header, so that the frontend and backend drivers agree on those identifiers. No functional change. Reviewed-by: Nuno S=C3=A1 Signed-off-by: Rodrigo Alencar --- MAINTAINERS | 1 + drivers/iio/frequency/ad9910.c | 35 ++------------------------------- drivers/iio/frequency/ad9910.h | 44 ++++++++++++++++++++++++++++++++++++++= ++++ 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 351ec0bca477..64aa7b539ca3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1735,6 +1735,7 @@ F: Documentation/devicetree/bindings/iio/frequency/ad= i,ad9910-axi-backend.yaml F: Documentation/devicetree/bindings/iio/frequency/adi,ad9910.yaml F: Documentation/iio/ad9910.rst F: drivers/iio/frequency/ad9910.c +F: drivers/iio/frequency/ad9910.h =20 ANALOG DEVICES INC MAX22007 DRIVER M: Janani Sunil diff --git a/drivers/iio/frequency/ad9910.c b/drivers/iio/frequency/ad9910.c index 8bc24d0b7442..dc13986dff3d 100644 --- a/drivers/iio/frequency/ad9910.c +++ b/drivers/iio/frequency/ad9910.c @@ -33,6 +33,8 @@ #include #include =20 +#include "ad9910.h" + /* Register addresses */ #define AD9910_REG_CFR1 0x00 #define AD9910_REG_CFR2 0x01 @@ -194,11 +196,6 @@ #define AD9910_RAM_ENABLED(st) \ FIELD_GET(AD9910_CFR1_RAM_ENABLE_MSK, (st)->reg[AD9910_REG_CFR1].val32) =20 -#define AD9910_DEST_FREQUENCY 0 -#define AD9910_DEST_PHASE 1 -#define AD9910_DEST_AMPLITUDE 2 -#define AD9910_DEST_POLAR 3 - /* PLL constants */ #define AD9910_PLL_MIN_N 12 #define AD9910_PLL_MAX_N 127 @@ -302,34 +299,6 @@ struct ad9910_ram_fw { __be32 words[] __counted_by_be(wcount); } __packed; =20 -enum { - AD9910_CHAN_IDX_PHY, - AD9910_CHAN_IDX_PROFILE_0, - AD9910_CHAN_IDX_PROFILE_1, - AD9910_CHAN_IDX_PROFILE_2, - AD9910_CHAN_IDX_PROFILE_3, - AD9910_CHAN_IDX_PROFILE_4, - AD9910_CHAN_IDX_PROFILE_5, - AD9910_CHAN_IDX_PROFILE_6, - AD9910_CHAN_IDX_PROFILE_7, - AD9910_CHAN_IDX_PARALLEL_AMP, - AD9910_CHAN_IDX_PARALLEL_PHASE, - AD9910_CHAN_IDX_PARALLEL_FREQ, - AD9910_CHAN_IDX_PARALLEL_POLAR_AMP, - AD9910_CHAN_IDX_PARALLEL_POLAR_PHASE, - AD9910_CHAN_IDX_DRG_FREQ, - AD9910_CHAN_IDX_DRG_PHASE, - AD9910_CHAN_IDX_DRG_AMP, - AD9910_CHAN_IDX_DRG_FREQ_RAMP_UP, - AD9910_CHAN_IDX_DRG_FREQ_RAMP_DOWN, - AD9910_CHAN_IDX_DRG_PHASE_RAMP_UP, - AD9910_CHAN_IDX_DRG_PHASE_RAMP_DOWN, - AD9910_CHAN_IDX_DRG_AMP_RAMP_UP, - AD9910_CHAN_IDX_DRG_AMP_RAMP_DOWN, - AD9910_CHAN_IDX_RAM, - AD9910_CHAN_IDX_OSK, -}; - enum { AD9910_POWERDOWN, AD9910_DWELL_EN, diff --git a/drivers/iio/frequency/ad9910.h b/drivers/iio/frequency/ad9910.h new file mode 100644 index 000000000000..6452a8678ed9 --- /dev/null +++ b/drivers/iio/frequency/ad9910.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * AD9910 SPI DDS (Direct Digital Synthesizer) driver + * + * Copyright 2026 Analog Devices Inc. + */ + +#ifndef IIO_FREQUENCY_AD9910_H_ +#define IIO_FREQUENCY_AD9910_H_ + +#define AD9910_DEST_FREQUENCY 0 +#define AD9910_DEST_PHASE 1 +#define AD9910_DEST_AMPLITUDE 2 +#define AD9910_DEST_POLAR 3 + +enum ad9910_channel_idx { + AD9910_CHAN_IDX_PHY, + AD9910_CHAN_IDX_PROFILE_0, + AD9910_CHAN_IDX_PROFILE_1, + AD9910_CHAN_IDX_PROFILE_2, + AD9910_CHAN_IDX_PROFILE_3, + AD9910_CHAN_IDX_PROFILE_4, + AD9910_CHAN_IDX_PROFILE_5, + AD9910_CHAN_IDX_PROFILE_6, + AD9910_CHAN_IDX_PROFILE_7, + AD9910_CHAN_IDX_PARALLEL_AMP, + AD9910_CHAN_IDX_PARALLEL_PHASE, + AD9910_CHAN_IDX_PARALLEL_FREQ, + AD9910_CHAN_IDX_PARALLEL_POLAR_AMP, + AD9910_CHAN_IDX_PARALLEL_POLAR_PHASE, + AD9910_CHAN_IDX_DRG_FREQ, + AD9910_CHAN_IDX_DRG_PHASE, + AD9910_CHAN_IDX_DRG_AMP, + AD9910_CHAN_IDX_DRG_FREQ_RAMP_UP, + AD9910_CHAN_IDX_DRG_FREQ_RAMP_DOWN, + AD9910_CHAN_IDX_DRG_PHASE_RAMP_UP, + AD9910_CHAN_IDX_DRG_PHASE_RAMP_DOWN, + AD9910_CHAN_IDX_DRG_AMP_RAMP_UP, + AD9910_CHAN_IDX_DRG_AMP_RAMP_DOWN, + AD9910_CHAN_IDX_RAM, + AD9910_CHAN_IDX_OSK, +}; + +#endif /* IIO_FREQUENCY_AD9910_H_ */ --=20 2.43.0 From nobody Sat Oct 24 02:57:34 2026 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1792682353; b=rFivczNDKPP7lWvcjYop23XO9EEQ4XduDHIW/+G1YsXqbCqGy/58cSZ+AwxaP53RYmEX Jirpp4RJ88Xlrdwq4EP7fC39k/FWHB5FRF86kXGZHS682m+LxOLZ+Oa5elhSK4fHzuKo+ +Joz6ojWa3hLmzn6BmbdM+8WcYta9O+Z87RHFGhrO68I4uWE+k4WNSq1bTmW4+8JrBfpz N8z05TL8OrY7HSTdHoQ/H5M8pJgBlgRMRUx60/NYzFaMusKuTM0VWfw0F8sAP0i+/em3b rYoPrgzTYx2nImkEQu8gVbIE2gxXVEJXR3YlE157gmCeR5P4N8L2cD780EnIjBVI1Hg== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1792682353; h=Received:DKIM-Signature:Received:From:Date:Subject:MIME-Version: Content-Type:Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=oJsB/DytyL4k823jwaMeEOB0kGngjvgULQLUFB1RXrg=; b=VB2y5uzxn1xKF/ZE3egWGRlOQCuRHoAMbzEWVxYFuFfmxpi07w3SKlE0q2J95tbm/yLF Tz1hxR2mqD7XKfj/BP0LdS/PrVLhmt//1GV5larG6Fs4bu7vXTyEQwNET26N3G9yyYe+8 u3P7roBofhRC2732rYgRF+OwEDS74l2Gl3/RqsAv1zB0YgHatXFRBSnZiut0YddnWebdU 3Asxi5kmvXgHYJwTUg9O6yobCepyraty/S7xr3zMs+okbYmcDArBcNU/lijYQmhJSfdIM ILF+lyKSNGmlFs26qFteNNQI06IzjyDFIkXTnYjjbb7RT4gJBU3D79wRknAc1GQ0sTw== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=ZdiPlTmb; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 83A37606D4C9; Thu, 22 Oct 2026 15:19:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=ZdiPlTmb Authentication-Results: smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 ARC-Seal: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; cv=none; t=1792682352; b=oQWFHc3FQIE9/JB8SQKZwPO8ThxF33mgnCj/oazsKXycOzUqHDyIzpo97PF+L72AkEYF HGLQ06dckLH0BAzUfPBpINvDqwKKmgP9Yj72erDyC9gsnOfadV9jYK1oUJGITDkaErlAj vIung0m05y1DQ6c48RZbjW9nYXV+r4xwMSYXocPj4uSXUAiMDk0FAYG9OVtm4BrN6ZvIu NyFkdvMdwSxkgvgk0rDjE9Bc8p+UnzNQC1SBvDtmsmBVy4+VxsZOEM6MKztGpcTWJCn4H oZ1whzx2y6k5R+oXXWu1T2tNcloe7jqnBQfCValsApH2DYXYvZVT8WvbNhn73hpYYSw== ARC-Message-Signature: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; c=relaxed/relaxed; t=1792682352; h=DKIM-Signature:Received:From:Date:Subject:MIME-Version:Content-Type: Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=oJsB/DytyL4k823jwaMeEOB0kGngjvgULQLUFB1RXrg=; b=zJmLVL0tzm6Sp9wnw1x3SlyFv7EF+2IfVZWqjPFL6yMjWvOi3YpDJ6RvLJxxeGT8shlR sCodkPPnLu9LliRFd/eAD0hE9FxbP9NpQwnQHWb7qqdbnZK7eyS/2c7Jxx94FnR3DzcZM n5NAz4IkoCJxBU0d1l+B3UGCpNH7jVwmWzRBnFYV+81UX3p8wxCAUHDlKOSNhMaeRqR09 mNNykrF/n5ah54vjbOO0Y7jfKdfWYiu/uFZlCvVGo9ZGyNFbkhPhf1+IWoj9RzhCzbogI KdpYTpJdfxTZZM/Embi+BNI2hMOpIekBJz7v/XJGn9uCw9Mn/o6Wm9wNtD22YtxpQ0A== ARC-Authentication-Results: i=1; smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 Received: from lkml.kernel.org (nexus.subspace.kernel.org [100.80.115.77]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.kernel.org (Postfix) with ESMTPS id C2DDF1F031E6; Thu, 22 Oct 2026 15:19:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792682352; bh=oJsB/DytyL4k823jwaMeEOB0kGngjvgULQLUFB1RXrg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To; b=ZdiPlTmbXws2tGpJbGfKd1CPYZfaaOtZuRyTtpTiAkUnXfDYDL2NSyGnNhduAyzDU 0tQuYTVvMaXvtRdnMQWYM9kPoPcXmGzr5B7BLzDvA9tDn0QV4nyCg1uLIrJ/5pOFe8 NX2sj9lVOE6xYwRyf4wATXnz95nn8Qvuw12qKXUr9QE51d2YsEaTxGHUusLXbQBrP/ 80JOZLdACz5ufhS2TDvy1RkaLO8V2xWX3MnBf3eAJXSQB9joaKWsqPhgkK5eZaTnsA ldEPW1kh2AcCeaydLtkkCYQskoZjJuF2ovXYfmv3RdtfWP9N1ahtENnkuELmQ68fak JNoRyn+oJs7nA== Received: from nexus.subspace.kernel.org (localhost [IPv6:::1]) by lkml.kernel.org (Postfix) with ESMTP id 954AB41E5E; Thu, 22 Oct 2026 15:19:08 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Thu, 22 Oct 2026 12:19:04 -0300 Subject: [PATCH v2 06/10] iio: frequency: ad9910: add axi backend driver X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Message-Id: <20261022-ad9910-backend-support-v2-6-0ff7f0bff326@analog.com> References: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> In-Reply-To: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> To: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, linux@analog.com, devicetree@vger.kernel.org, linux-pwm@vger.kernel.org, linux-doc@vger.kernel.org, Jonathan Cameron Cc: Olivier Moysan , Jonathan Cameron , David Lechner , Andy Shevchenko , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Jonathan Corbet , Shuah Khan , Randy Dunlap , Rodrigo Alencar X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1792682347; l=18974; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=b81S0u53Z7GW/he410X9LoYNn4PYTbzojgL2N4oyueE=; b=Y4q2a7o/PLmoZTvqF1+J8xUMcY+1V7ssKZBZMzL3uGiARjLDnvF6XxDs4F7PUPBvLkIyqPbwa +KgAPENTPoWCJCBcCkB3QFO42RbJgCXG+6hDsnQ6TnjJIg3+B/4Ggi0 X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com Content-Transfer-Encoding: quoted-printable From: Rodrigo Alencar Add the driver for the AD9910 AXI backend IP core, which interfaces with the data and control pins of the AD9910 DDS. It registers as an IIO backend that provides: - a DMA output buffer that streams data into the parallel data port; - the parallel data destination (F[1:0] pins) and data rate, derived from the PDCLK frequency; - the PROFILE[2:0] pins control, through profile channel enables. It also registers a PWM chip with a single output driving the DRCTL pin, which the AD9910 driver uses to control the digital ramp generator direction. The PWM implements the waveform callbacks, with period, duty length and duty offset programmed in SYNC_CLK cycles. The duty offset is realized by a delay applied once, before DRCTL starts toggling. The waveform is reprogrammed when the SYNC_CLK rate changes, so that the PWM output keeps its timing. Signed-off-by: Rodrigo Alencar --- MAINTAINERS | 1 + drivers/iio/frequency/Kconfig | 17 + drivers/iio/frequency/Makefile | 1 + drivers/iio/frequency/ad9910-axi-backend.c | 525 +++++++++++++++++++++++++= ++++ 4 files changed, 544 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 64aa7b539ca3..abfbbf0b6b4e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1734,6 +1734,7 @@ F: Documentation/ABI/testing/sysfs-bus-iio-frequency-= ad9910 F: Documentation/devicetree/bindings/iio/frequency/adi,ad9910-axi-backend.= yaml F: Documentation/devicetree/bindings/iio/frequency/adi,ad9910.yaml F: Documentation/iio/ad9910.rst +F: drivers/iio/frequency/ad9910-axi-backend.c F: drivers/iio/frequency/ad9910.c F: drivers/iio/frequency/ad9910.h =20 diff --git a/drivers/iio/frequency/Kconfig b/drivers/iio/frequency/Kconfig index 994d199080eb..f7f5c3cce005 100644 --- a/drivers/iio/frequency/Kconfig +++ b/drivers/iio/frequency/Kconfig @@ -42,6 +42,23 @@ config AD9910 To compile this driver as a module, choose M here: the module will be called ad9910. =20 +config AD9910_AXI_BACKEND + tristate "Analog Devices AD9910 AXI Backend driver" + depends on AD9910 + depends on HAS_IOMEM && PWM + select IIO_BACKEND + select IIO_BUFFER + select IIO_BUFFER_DMAENGINE + select REGMAP_MMIO + help + Say yes here to build support for the AXI Backend Driver for the + Analog Devices AD9910 DDS. The IP core is used to drive digital ramp + control pins and interface with the parallel data port of the AD9910 + device. + + To compile this driver as a module, choose M here: the + module will be called ad9910-axi-backend. + endmenu =20 # diff --git a/drivers/iio/frequency/Makefile b/drivers/iio/frequency/Makefile index e3b1d36ed620..bfac9e205e81 100644 --- a/drivers/iio/frequency/Makefile +++ b/drivers/iio/frequency/Makefile @@ -6,6 +6,7 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_AD9523) +=3D ad9523.o obj-$(CONFIG_AD9910) +=3D ad9910.o +obj-$(CONFIG_AD9910_AXI_BACKEND) +=3D ad9910-axi-backend.o obj-$(CONFIG_ADF41513) +=3D adf41513.o obj-$(CONFIG_ADF4350) +=3D adf4350.o obj-$(CONFIG_ADF4371) +=3D adf4371.o diff --git a/drivers/iio/frequency/ad9910-axi-backend.c b/drivers/iio/frequ= ency/ad9910-axi-backend.c new file mode 100644 index 000000000000..f5374aeb2afe --- /dev/null +++ b/drivers/iio/frequency/ad9910-axi-backend.c @@ -0,0 +1,525 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * AD9910 AXI Backend driver + * + * Copyright 2026 Analog Devices Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "ad9910.h" + +/* Register addresses */ +#define AD9910_AXI_REG_RESET 0x040 +#define AD9910_AXI_REG_DRG 0x084 +#define AD9910_AXI_REG_PROFILE 0x088 +#define AD9910_AXI_REG_DRCTL_PERIOD 0x08C +#define AD9910_AXI_REG_DRCTL_WIDTH 0x090 +#define AD9910_AXI_REG_DRCTL_DELAY 0x094 +#define AD9910_AXI_REG_BURST_COUNT 0x098 +#define AD9910_AXI_REG_BURST_DELAY 0x09C +#define AD9910_AXI_REG_RAMP_CFG 0x0A0 + +#define AD9910_AXI_REG_UPDATE_CTRL 0x104 +#define AD9910_AXI_REG_PAR_RATE 0x108 +#define AD9910_AXI_REG_F_CFG 0x10C + +#define AD9910_AXI_REG_RESET_CORE_MSK BIT(0) + +#define AD9910_AXI_REG_DRG_DRCTL_MSK BIT(2) +#define AD9910_AXI_REG_DRG_TOGGLE_EN_MSK BIT(3) + +#define AD9910_AXI_REG_RAMP_CFG_ONE_SHOT_MSK GENMASK(1, 0) +#define AD9910_AXI_REG_BURST_COUNT_MSK GENMASK(19, 0) + +#define AD9910_AXI_REG_UPDATE_RATE_MSK BIT(0) +#define AD9910_AXI_REG_UPDATE_PAR_IF_EN_MSK BIT(1) +#define AD9910_AXI_REG_UPDATE_EXT_TRIG_MSK BIT(2) + +#define AD9910_AXI_REG_PROFILE_MSK GENMASK(2, 0) +#define AD9910_AXI_REG_IO_UPDATE_MSK BIT(0) +#define AD9910_AXI_REG_F_CFG_MSK GENMASK(1, 0) + +#define AD9910_AXI_PD_CLK_MAX_FREQ_HZ (250ULL * HZ_PER_MHZ) +#define AD9910_AXI_PAR_RATE_MAX U16_MAX +#define AD9910_AXI_ONE_SHOT_BURST 1 + +struct ad9910_axi_state { + struct device *dev; + struct regmap *regmap; + /* + * lock to protect multiple accesses to the device registers and global + * data/variables. + */ + struct mutex lock; + u64 pd_clk_freq_uhz; + /* last applied DRCTL waveform, kept when the SYNC_CLK rate changes */ + struct pwm_waveform drctl_wf; +}; + +/* DRCTL waveform in SYNC_CLK cycles, a zero period means disabled */ +struct ad9910_axi_drctl_wfhw { + u32 period; + u32 width; + u32 delay; +}; + +static u32 ad9910_axi_ns_to_cycles(struct ad9910_axi_state *st, u64 ns) +{ + return min(mul_u64_u64_div_u64(ns, st->pd_clk_freq_uhz, + 1ULL * NANO * MICROHZ_PER_HZ), U32_MAX); +} + +static u64 ad9910_axi_cycles_to_ns(struct ad9910_axi_state *st, u32 cycles) +{ + return mul_u64_u64_div_u64_roundup((u64)cycles * NANO, MICROHZ_PER_HZ, + st->pd_clk_freq_uhz); +} + +static int ad9910_axi_drctl_tohw(struct ad9910_axi_state *st, + const struct pwm_waveform *wf, + struct ad9910_axi_drctl_wfhw *wfhw) +{ + if (!wf->period_length_ns) { + *wfhw =3D (struct ad9910_axi_drctl_wfhw){ }; + return 0; + } + + wfhw->period =3D ad9910_axi_ns_to_cycles(st, wf->period_length_ns); + if (!wfhw->period) { + /* round up to the shortest period, with no duty and no delay */ + *wfhw =3D (struct ad9910_axi_drctl_wfhw){ .period =3D 1 }; + return 1; + } + + wfhw->width =3D min(ad9910_axi_ns_to_cycles(st, wf->duty_length_ns), + wfhw->period); + /* + * The delay is applied once, before DRCTL starts toggling, which + * results in the duty offset of the periodic waveform. A delay of a + * whole period is the same as no delay at all. + */ + wfhw->delay =3D ad9910_axi_ns_to_cycles(st, wf->duty_offset_ns); + if (wfhw->delay >=3D wfhw->period) + wfhw->delay =3D 0; + + return 0; +} + +static void ad9910_axi_drctl_fromhw(struct ad9910_axi_state *st, + const struct ad9910_axi_drctl_wfhw *wfhw, + struct pwm_waveform *wf) +{ + if (!wfhw->period) { + *wf =3D (struct pwm_waveform){ }; + return; + } + + wf->period_length_ns =3D ad9910_axi_cycles_to_ns(st, wfhw->period); + wf->duty_length_ns =3D ad9910_axi_cycles_to_ns(st, wfhw->width); + wf->duty_offset_ns =3D ad9910_axi_cycles_to_ns(st, wfhw->delay); +} + +static int ad9910_axi_drctl_write(struct ad9910_axi_state *st, + const struct ad9910_axi_drctl_wfhw *wfhw) +{ + int ret; + + /* + * DRCTL toggling restarts, applying the delay, when enabled or when + * its period or width changes. Changing the delay alone does not + * restart it, so disable toggling while updating the waveform. + */ + ret =3D regmap_clear_bits(st->regmap, AD9910_AXI_REG_DRG, + AD9910_AXI_REG_DRG_TOGGLE_EN_MSK); + if (ret || !wfhw->period) + return ret; + + ret =3D regmap_write(st->regmap, AD9910_AXI_REG_DRCTL_DELAY, wfhw->delay); + if (ret) + return ret; + + ret =3D regmap_write(st->regmap, AD9910_AXI_REG_DRCTL_WIDTH, wfhw->width); + if (ret) + return ret; + + ret =3D regmap_write(st->regmap, AD9910_AXI_REG_DRCTL_PERIOD, wfhw->perio= d); + if (ret) + return ret; + + /* + * Register values reach the SYNC_CLK domain in snapshots, taken every + * 64 AXI clock cycles. Make sure toggling being disabled is captured + * by one of them before enabling it again. + */ + fsleep(2); + + return regmap_set_bits(st->regmap, AD9910_AXI_REG_DRG, + AD9910_AXI_REG_DRG_TOGGLE_EN_MSK); +} + +static int ad9910_axi_chan_enable(struct iio_backend *back, unsigned int c= han) +{ + struct ad9910_axi_state *st =3D iio_backend_get_priv(back); + int ret; + + guard(mutex)(&st->lock); + + switch (chan) { + /* + * Profiles are mutually exclusive, as the PROFILE[2:0] pins always + * select one of them. Enabling a profile channel selects it, which + * implicitly disables the previously selected one, hence there is + * nothing to do when disabling a profile channel. + */ + case AD9910_CHAN_IDX_PROFILE_0 ... AD9910_CHAN_IDX_PROFILE_7: + chan -=3D AD9910_CHAN_IDX_PROFILE_0; + return regmap_update_bits(st->regmap, AD9910_AXI_REG_PROFILE, + AD9910_AXI_REG_PROFILE_MSK, + FIELD_PREP(AD9910_AXI_REG_PROFILE_MSK, chan)); + case AD9910_CHAN_IDX_PARALLEL_AMP ... AD9910_CHAN_IDX_PARALLEL_POLAR_PHAS= E: + /* + * F[1:0] destination follows the parallel channel order: + * amplitude, phase, frequency and polar. + */ + chan =3D min(chan - AD9910_CHAN_IDX_PARALLEL_AMP, + FIELD_MAX(AD9910_AXI_REG_F_CFG_MSK)); + ret =3D regmap_update_bits(st->regmap, AD9910_AXI_REG_F_CFG, + AD9910_AXI_REG_F_CFG_MSK, chan); + if (ret) + return ret; + + return regmap_set_bits(st->regmap, AD9910_AXI_REG_UPDATE_CTRL, + AD9910_AXI_REG_UPDATE_PAR_IF_EN_MSK); + default: + return -EINVAL; + } +} + +static int ad9910_axi_chan_disable(struct iio_backend *back, unsigned int = chan) +{ + struct ad9910_axi_state *st =3D iio_backend_get_priv(back); + + switch (chan) { + case AD9910_CHAN_IDX_PROFILE_0 ... AD9910_CHAN_IDX_PROFILE_7: + return 0; + case AD9910_CHAN_IDX_PARALLEL_AMP ... AD9910_CHAN_IDX_PARALLEL_POLAR_PHAS= E: + return regmap_clear_bits(st->regmap, AD9910_AXI_REG_UPDATE_CTRL, + AD9910_AXI_REG_UPDATE_PAR_IF_EN_MSK); + default: + return -EINVAL; + } +} + +static struct iio_buffer *ad9910_axi_request_buffer(struct iio_backend *ba= ck, + struct iio_dev *indio_dev) +{ + struct ad9910_axi_state *st =3D iio_backend_get_priv(back); + const char *dma_name; + + if (device_property_read_string(st->dev, "dma-names", &dma_name)) + dma_name =3D "tx"; + + return iio_dmaengine_buffer_setup_ext(st->dev, indio_dev, dma_name, + IIO_BUFFER_DIRECTION_OUT); +} + +static void ad9910_axi_free_buffer(struct iio_backend *back, + struct iio_buffer *buffer) +{ + iio_dmaengine_buffer_teardown(buffer); +} + +static int ad9910_axi_set_sample_rate(struct iio_backend *back, + unsigned int chan, u64 sample_rate) +{ + struct ad9910_axi_state *st =3D iio_backend_get_priv(back); + struct ad9910_axi_drctl_wfhw wfhw; + u64 div, pd_clk_freq_uhz; + int ret; + + guard(mutex)(&st->lock); + + switch (chan) { + case AD9910_CHAN_IDX_PHY: + if (!sample_rate || sample_rate > 4 * AD9910_AXI_PD_CLK_MAX_FREQ_HZ) + return -EINVAL; + + pd_clk_freq_uhz =3D sample_rate * MICROHZ_PER_HZ >> 2; + if (pd_clk_freq_uhz =3D=3D st->pd_clk_freq_uhz) + return 0; + + st->pd_clk_freq_uhz =3D pd_clk_freq_uhz; + if (!st->drctl_wf.period_length_ns) + return 0; + + /* + * DRCTL is clocked by SYNC_CLK, reprogram it so that the PWM + * output keeps the applied waveform. + */ + ad9910_axi_drctl_tohw(st, &st->drctl_wf, &wfhw); + return ad9910_axi_drctl_write(st, &wfhw); + case AD9910_CHAN_IDX_PARALLEL_AMP ... AD9910_CHAN_IDX_PARALLEL_POLAR_PHAS= E: + if (!sample_rate || sample_rate > AD9910_AXI_PD_CLK_MAX_FREQ_HZ) + return -EINVAL; + + sample_rate *=3D MICROHZ_PER_HZ; + div =3D DIV64_U64_ROUND_CLOSEST(st->pd_clk_freq_uhz, sample_rate); + div =3D clamp(div, 1U, AD9910_AXI_PAR_RATE_MAX); + ret =3D regmap_write(st->regmap, AD9910_AXI_REG_PAR_RATE, div - 1); + if (ret) + return ret; + + return regmap_set_bits(st->regmap, AD9910_AXI_REG_UPDATE_CTRL, + AD9910_AXI_REG_UPDATE_RATE_MSK); + default: + return -EINVAL; + } +} + +static int ad9910_axi_read_raw(struct iio_backend *back, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + struct ad9910_axi_state *st =3D iio_backend_get_priv(back); + u32 div; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + switch (chan->address) { + case AD9910_CHAN_IDX_PARALLEL_AMP ... AD9910_CHAN_IDX_PARALLEL_POLAR_PHA= SE: { + guard(mutex)(&st->lock); + + ret =3D regmap_read(st->regmap, AD9910_AXI_REG_PAR_RATE, + &div); + if (ret) + return ret; + + iio_val_s64_decompose(div64_u64(st->pd_clk_freq_uhz, + (u64)div + 1), + val, val2); + return IIO_VAL_DECIMAL64_MICRO; + } + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int ad9910_axi_reg_access(struct iio_backend *back, unsigned int re= g, + unsigned int writeval, unsigned int *readval) +{ + struct ad9910_axi_state *st =3D iio_backend_get_priv(back); + + if (readval) + return regmap_read(st->regmap, reg, readval); + + return regmap_write(st->regmap, reg, writeval); +} + +static const struct iio_backend_ops ad9910_axi_iio_back_ops =3D { + .chan_enable =3D ad9910_axi_chan_enable, + .chan_disable =3D ad9910_axi_chan_disable, + .request_buffer =3D ad9910_axi_request_buffer, + .free_buffer =3D ad9910_axi_free_buffer, + .set_sample_rate =3D ad9910_axi_set_sample_rate, + .read_raw =3D ad9910_axi_read_raw, + .debugfs_reg_access =3D iio_backend_debugfs_ptr(ad9910_axi_reg_access), +}; + +static const struct iio_backend_info ad9910_axi_back_info =3D { + .name =3D "ad9910-axi", + .ops =3D &ad9910_axi_iio_back_ops, +}; + +static const struct regmap_config ad9910_axi_regmap_config =3D { + .val_bits =3D 32, + .reg_bits =3D 32, + .reg_stride =3D 4, + .max_register =3D 0x0800, +}; + +static int ad9910_axi_pwm_round_waveform_tohw(struct pwm_chip *chip, + struct pwm_device *pwm, + const struct pwm_waveform *wf, + void *wfhw) +{ + struct ad9910_axi_state *st =3D pwmchip_get_drvdata(chip); + + guard(mutex)(&st->lock); + + return ad9910_axi_drctl_tohw(st, wf, wfhw); +} + +static int ad9910_axi_pwm_round_waveform_fromhw(struct pwm_chip *chip, + struct pwm_device *pwm, + const void *wfhw, + struct pwm_waveform *wf) +{ + struct ad9910_axi_state *st =3D pwmchip_get_drvdata(chip); + + guard(mutex)(&st->lock); + + ad9910_axi_drctl_fromhw(st, wfhw, wf); + + return 0; +} + +static int ad9910_axi_pwm_read_waveform(struct pwm_chip *chip, + struct pwm_device *pwm, void *_wfhw) +{ + struct ad9910_axi_state *st =3D pwmchip_get_drvdata(chip); + struct ad9910_axi_drctl_wfhw *wfhw =3D _wfhw; + u32 drg; + int ret; + + guard(mutex)(&st->lock); + + ret =3D regmap_read(st->regmap, AD9910_AXI_REG_DRG, &drg); + if (ret) + return ret; + + if (!FIELD_GET(AD9910_AXI_REG_DRG_TOGGLE_EN_MSK, drg)) { + *wfhw =3D (struct ad9910_axi_drctl_wfhw){ }; + return 0; + } + + ret =3D regmap_read(st->regmap, AD9910_AXI_REG_DRCTL_PERIOD, &wfhw->perio= d); + if (ret) + return ret; + + ret =3D regmap_read(st->regmap, AD9910_AXI_REG_DRCTL_WIDTH, &wfhw->width); + if (ret) + return ret; + + return regmap_read(st->regmap, AD9910_AXI_REG_DRCTL_DELAY, &wfhw->delay); +} + +static int ad9910_axi_pwm_write_waveform(struct pwm_chip *chip, + struct pwm_device *pwm, + const void *_wfhw) +{ + struct ad9910_axi_state *st =3D pwmchip_get_drvdata(chip); + const struct ad9910_axi_drctl_wfhw *wfhw =3D _wfhw; + int ret; + + guard(mutex)(&st->lock); + + ret =3D ad9910_axi_drctl_write(st, wfhw); + if (ret) + return ret; + + ad9910_axi_drctl_fromhw(st, wfhw, &st->drctl_wf); + + return 0; +} + +static const struct pwm_ops ad9910_axi_pwm_ops =3D { + .sizeof_wfhw =3D sizeof(struct ad9910_axi_drctl_wfhw), + .round_waveform_tohw =3D ad9910_axi_pwm_round_waveform_tohw, + .round_waveform_fromhw =3D ad9910_axi_pwm_round_waveform_fromhw, + .read_waveform =3D ad9910_axi_pwm_read_waveform, + .write_waveform =3D ad9910_axi_pwm_write_waveform, +}; + +static int ad9910_axi_setup(struct ad9910_axi_state *st) +{ + int ret; + + st->pd_clk_freq_uhz =3D AD9910_AXI_PD_CLK_MAX_FREQ_HZ * MICROHZ_PER_HZ; + + ret =3D regmap_set_bits(st->regmap, AD9910_AXI_REG_RESET, + AD9910_AXI_REG_RESET_CORE_MSK); + if (ret) + return ret; + + return regmap_clear_bits(st->regmap, AD9910_AXI_REG_RESET, + AD9910_AXI_REG_RESET_CORE_MSK); +} + +static int ad9910_axi_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct ad9910_axi_state *st; + struct pwm_chip *chip; + void __iomem *base; + struct clk *clk; + int ret; + + chip =3D devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*st)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + + st =3D pwmchip_get_drvdata(chip); + + base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + clk =3D devm_clk_get_enabled(dev, NULL); + if (IS_ERR(clk)) + return dev_err_probe(dev, PTR_ERR(clk), "failed to get clock\n"); + + st->dev =3D dev; + st->regmap =3D devm_regmap_init_mmio(dev, base, + &ad9910_axi_regmap_config); + if (IS_ERR(st->regmap)) + return dev_err_probe(dev, PTR_ERR(st->regmap), + "failed to init register map\n"); + + ret =3D devm_mutex_init(dev, &st->lock); + if (ret) + return ret; + + ret =3D ad9910_axi_setup(st); + if (ret) + return dev_err_probe(dev, ret, "failed to setup device\n"); + + chip->ops =3D &ad9910_axi_pwm_ops; + + ret =3D devm_pwmchip_add(dev, chip); + if (ret) + return dev_err_probe(dev, ret, "Could not register PWM chip\n"); + + return devm_iio_backend_register(dev, &ad9910_axi_back_info, st); +} + +static const struct of_device_id ad9910_axi_of_match[] =3D { + { .compatible =3D "adi,ad9910-axi-backend" }, + { } +}; +MODULE_DEVICE_TABLE(of, ad9910_axi_of_match); + +static struct platform_driver ad9910_axi_driver =3D { + .driver =3D { + .name =3D "ad9910-axi-backend", + .of_match_table =3D ad9910_axi_of_match, + }, + .probe =3D ad9910_axi_probe, +}; +module_platform_driver(ad9910_axi_driver); + +MODULE_AUTHOR("Rodrigo Alencar "); +MODULE_DESCRIPTION("Analog Devices AD9910 AXI Backend driver"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("IIO_DMAENGINE_BUFFER"); +MODULE_IMPORT_NS("IIO_BACKEND"); --=20 2.43.0 From nobody Sat Oct 24 02:57:34 2026 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1792682352; b=f55cP+9JaqjXShR99S6NHqaKDYg9yMo1w0AVEYeRzdB2aQOaUO2VJNWnY6RTJf0OUqCr E6bdaz+IeX+gCeS+uqwp5j2WAjnzEiQLrLpTPHXNZy2xqnkYOYROjkf9iKIKOlOE+bScj eEXQgPmZ769eTksoZZWvK/UjhE3WuGAv+XihccfeDLF7g90bgSA6YRvX8WGKoRIJ8VlVS TcVF918DKQd951pER059dSdHi6+fp38viZrFUmOBMim9HdZbGZrSmpxrF+ntfzVfd4pZC MXztYZDUnkB08gam19eMmxXKB6HBOGLgp5LL5BqeL0DcDccqsSPn9wB1bC5Ur36lTiA== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1792682352; h=Received:DKIM-Signature:Received:From:Date:Subject:MIME-Version: Content-Type:Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=ASU/1nucHGs7zXptz0kFRF1rgrqexVMgT37opJvwI9s=; b=4IVP/gyv48gGksPqoi2vwZy+MZNAOBmnDHsFIUmaDcgMtQXWkH56ut7wCLRlJhSCR+RQ 3j1SqDIfIppZ1CLXVY5LRSVyodMX9IZob+vneO+GCbVXtlMbgHABnB+HdQfTc2NGZwQQZ Z+9cOr1LumhoUaZe/WiCgaiOOM0R9GiX/ZN4i1tIoVtEfipxxG1pDY7eSgmxH21OGkPI8 l0Ig2fENATbbiIdpROBcnYC7qu7PdnZBj5XwlTRVh0C9MUTQt6ki+ROM6YJoXne+afGXl 0biTPjKrdQ5X8TuQaZcyhEq6zf0AEFYmd5tqnEFvWRqJZaSadrk5prP27B7IWy1xX1Q== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=Zg+18BBx; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5A427606CC47; Thu, 22 Oct 2026 15:19:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=Zg+18BBx Authentication-Results: smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 ARC-Seal: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; cv=none; t=1792682352; b=jz7LWfH/nj6cvubYcwvA7o1kknR2B4TKWckxQf1bbHNGYKkAqIapt4Qzix33LOHJl9MF HFprt++KCX3pVLHJwVtOzs8NlCeKaTkJZs3MLxCiSD9fJSScahwqp6Cg+zh1qITZra/E7 M3h36ww+jBPCD7t9EDwO8EBlO7bhaKKAQ3NGHpMVYnIpV9uKbUECadE1Z0yPcM8SjM6s6 Ge3PqpY6WMyioS2fzvM8pRPleMJvFBRre9y2QbD3Fyw3j1YAiiciyJFvWG0dCPFAxuwai bkkX+x8YQjUO7wqU4Kkdh2XNCItJ550dXOnuXJKoczOlsl/esAIK+pi2E2IeO1di3+Q== ARC-Message-Signature: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; c=relaxed/relaxed; t=1792682352; h=DKIM-Signature:Received:From:Date:Subject:MIME-Version:Content-Type: Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=ASU/1nucHGs7zXptz0kFRF1rgrqexVMgT37opJvwI9s=; b=LPQ0jkbn4inRONTqWLnEcXTZGOS7xncAcHmfHXYm7CYMe4AMDa/xK83jVkVjdjSAElrx iVk9V8azM1mph3taeLOf5D5ojtVeYg74tKwvdxx5Rv3UQe6kC//6vbhWTk9E2XCXxB489 AL7+P42/0uH2z+GsJpmSlrtQCnjz8YsoYTjr2TSc0iOXJaQGEvU/8P2LMjkp9ptrjS2O1 1TIrRtttEThKtQT54fmrumUySefVL/mAagzFkhtD2JELtKab5p5wNSP7Y2CujktXb6F3g 09vwUeUPqlxHHEb+NfsKe+HaYLRU8I2m/Q0qmY0HuEKaydwgD4EY89HtiQrqA9nVyOw== ARC-Authentication-Results: i=1; smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 Received: from lkml.kernel.org (nexus.subspace.kernel.org [100.80.115.77]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.kernel.org (Postfix) with ESMTPS id 24F1F1F01825; Thu, 22 Oct 2026 15:19:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792682352; bh=ASU/1nucHGs7zXptz0kFRF1rgrqexVMgT37opJvwI9s=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To; b=Zg+18BBxgzSbBVog2eR6aCPhCSD/oQRpTaxPEM5Ad+ER2lHIMs7+Q2XVpX8lJoaQs wwl2Fy9Sq9FSjnTm0ZFEOfskGg/3h/sDAuxL9Oj6Nah0PYP6Iu/9rI2GTGsiXGvnTI DwPcSFSDKejyoIs2Kl3yV3CKaj7atf/SgA0ey0Cqi0RV6e9quFPlbEKheToL6EP2hv N4/NPQutwd8jTcMuLZL+6RsYSjkeajQTYhkEE6SqmJwpbHev4fYyF7zyjIivs9MTD5 MQQ0XOvODI3bUVTtB9Zs63zVX0JRQFVtaP5PoRyT43ahQjv8zSPOs0lwlw4DPbRL8N eER2QZpuu4R0w== Received: from nexus.subspace.kernel.org (localhost [IPv6:::1]) by lkml.kernel.org (Postfix) with ESMTP id 9D1A441E62; Thu, 22 Oct 2026 15:19:08 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Thu, 22 Oct 2026 12:19:05 -0300 Subject: [PATCH v2 07/10] iio: frequency: ad9910: support drctl control X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Message-Id: <20261022-ad9910-backend-support-v2-7-0ff7f0bff326@analog.com> References: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> In-Reply-To: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> To: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, linux@analog.com, devicetree@vger.kernel.org, linux-pwm@vger.kernel.org, linux-doc@vger.kernel.org, Jonathan Cameron Cc: Olivier Moysan , Jonathan Cameron , David Lechner , Andy Shevchenko , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Jonathan Corbet , Shuah Khan , Randy Dunlap , Rodrigo Alencar X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1792682347; l=10005; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=+drkCiwvC0cJDxHxuoqYeJAU17jORfYYcdbKgVaZEK0=; b=iKhLZRnMO5bp4wslxyzRSmJ7lYIPKbq9saD0T6LmXPEJY833ylDQuemoj9z8rL7QpzP7GaSKD bS2xZ1T3tKeBql127j16ilCj++4S5gPYRCuZQv4DchvgLgT05eX/pDd X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com Content-Transfer-Encoding: quoted-printable From: Rodrigo Alencar The DRCTL pin controls the slope direction of the AD9910 digital ramp generator (DRG). When dwell is enabled at a ramp limit, the DRG holds that limit until the next DRCTL transition, so the sweep pattern is defined by the waveform applied to that pin, which can be generated by a PWM. Get the optional "drctl" PWM and expose the integration_time attribute in the DRG ramp up and ramp down channels, which sets the time interval assigned to each ramp direction while the sweep parameter is accumulating. The DRCTL waveform is described with the PWM waveform API, using the duty offset when DRCTL needs to start low. The PWM is disabled when the resulting period is zero. The waveform is rounded by the PWM provider before being applied, so that integration_time reports the intervals achieved by it. Writing to integration_time fails with -EOPNOTSUPP when no DRCTL PWM is available. As the waveform API has no stubs, the driver now depends on PWM. Signed-off-by: Rodrigo Alencar --- drivers/iio/frequency/Kconfig | 1 + drivers/iio/frequency/ad9910.c | 143 +++++++++++++++++++++++++++++++++++++= ++-- 2 files changed, 138 insertions(+), 6 deletions(-) diff --git a/drivers/iio/frequency/Kconfig b/drivers/iio/frequency/Kconfig index f7f5c3cce005..591476f23ace 100644 --- a/drivers/iio/frequency/Kconfig +++ b/drivers/iio/frequency/Kconfig @@ -29,6 +29,7 @@ config AD9910 tristate "Analog Devices AD9910 Direct Digital Synthesizer" depends on SPI depends on GPIOLIB + depends on PWM select CRC32 select FW_LOADER select FW_UPLOAD diff --git a/drivers/iio/frequency/ad9910.c b/drivers/iio/frequency/ad9910.c index dc13986dff3d..1de02017f78c 100644 --- a/drivers/iio/frequency/ad9910.c +++ b/drivers/iio/frequency/ad9910.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -324,12 +325,16 @@ union ad9910_reg { struct ad9910_state { struct spi_device *spi; struct clk *refclk; + struct pwm_device *drctl_pwm; struct fw_upload *ram_fwu; =20 struct gpio_desc *gpio_pwdown; struct gpio_desc *gpio_update; struct gpio_descs *gpio_profile; =20 + s64 ramp_up_time_ns; + s64 ramp_down_time_ns; + /* cached registers */ union ad9910_reg reg[AD9910_REG_NUM_CACHED]; =20 @@ -609,6 +614,58 @@ static int ad9910_sw_powerdown_set(struct ad9910_state= *st, bool enable) AD9910_CFR1_SW1_POWER_DOWN_MSK, 0, true); } =20 +static int ad9910_drctl_sync(struct ad9910_state *st) +{ + struct pwm_waveform wf =3D { }; + bool ndh, ndl; + int ret; + + if (!st->drctl_pwm) + return 0; + + ndh =3D FIELD_GET(AD9910_CFR2_DRG_NO_DWELL_HIGH_MSK, + st->reg[AD9910_REG_CFR2].val32); + ndl =3D FIELD_GET(AD9910_CFR2_DRG_NO_DWELL_LOW_MSK, + st->reg[AD9910_REG_CFR2].val32); + + if (!ndh && ndl) { + /* DRCTL low on the first half, so that it ramps down first */ + wf.period_length_ns =3D st->ramp_down_time_ns; + wf.duty_offset_ns =3D st->ramp_down_time_ns / 2; + wf.duty_length_ns =3D wf.period_length_ns - wf.duty_offset_ns; + } else if (ndh && !ndl) { + wf.period_length_ns =3D st->ramp_up_time_ns; + wf.duty_length_ns =3D st->ramp_up_time_ns / 2; + } else if (!ndh && !ndl) { + wf.period_length_ns =3D st->ramp_up_time_ns + st->ramp_down_time_ns; + wf.duty_length_ns =3D st->ramp_up_time_ns; + } else { + wf.period_length_ns =3D st->ramp_up_time_ns + st->ramp_down_time_ns; + } + + /* a zero period disables the PWM, nothing to round */ + if (wf.period_length_ns) { + ret =3D pwm_round_waveform_might_sleep(st->drctl_pwm, &wf); + if (ret < 0) + return ret; + } + + ret =3D pwm_set_waveform_might_sleep(st->drctl_pwm, &wf, false); + if (ret) + return ret; + + if (!ndh && ndl) { + st->ramp_down_time_ns =3D wf.period_length_ns; + } else if (ndh && !ndl) { + st->ramp_up_time_ns =3D wf.period_length_ns; + } else if (!ndh && !ndl) { + st->ramp_up_time_ns =3D wf.duty_length_ns; + st->ramp_down_time_ns =3D wf.period_length_ns - wf.duty_length_ns; + } + + return 0; +} + static ssize_t ad9910_ext_info_read(struct iio_dev *indio_dev, uintptr_t private, const struct iio_chan_spec *chan, @@ -675,6 +732,13 @@ static ssize_t ad9910_ext_info_write(struct iio_dev *i= ndio_dev, if (ret) return ret; } + + /* + * DRCTL waveform depends on the dwell configuration, but the + * previous integration time values may not suit the new + * waveform, which should not prevent dwell_en from changing. + */ + ad9910_drctl_sync(st); break; default: return -EINVAL; @@ -1054,7 +1118,8 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .channel =3D AD9910_CHANNEL_DRG_RAMP_UP, .address =3D AD9910_CHAN_IDX_DRG_FREQ_RAMP_UP, .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_SAMP_FREQ), + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_INT_TIME), .ext_info =3D ad9910_drg_ramp_ext_info, .parent =3D &ad9910_channels[AD9910_CHAN_IDX_DRG_FREQ], }, @@ -1065,7 +1130,8 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .channel =3D AD9910_CHANNEL_DRG_RAMP_DOWN, .address =3D AD9910_CHAN_IDX_DRG_FREQ_RAMP_DOWN, .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_SAMP_FREQ), + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_INT_TIME), .ext_info =3D ad9910_drg_ramp_ext_info, .parent =3D &ad9910_channels[AD9910_CHAN_IDX_DRG_FREQ], }, @@ -1076,7 +1142,8 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .channel =3D AD9910_CHANNEL_DRG_RAMP_UP, .address =3D AD9910_CHAN_IDX_DRG_PHASE_RAMP_UP, .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_SAMP_FREQ), + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_INT_TIME), .ext_info =3D ad9910_drg_ramp_ext_info, .parent =3D &ad9910_channels[AD9910_CHAN_IDX_DRG_PHASE], }, @@ -1087,7 +1154,8 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .channel =3D AD9910_CHANNEL_DRG_RAMP_DOWN, .address =3D AD9910_CHAN_IDX_DRG_PHASE_RAMP_DOWN, .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_SAMP_FREQ), + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_INT_TIME), .ext_info =3D ad9910_drg_ramp_ext_info, .parent =3D &ad9910_channels[AD9910_CHAN_IDX_DRG_PHASE], }, @@ -1098,7 +1166,8 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .channel =3D AD9910_CHANNEL_DRG_RAMP_UP, .address =3D AD9910_CHAN_IDX_DRG_AMP_RAMP_UP, .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_SAMP_FREQ), + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_INT_TIME), .ext_info =3D ad9910_drg_ramp_ext_info, .parent =3D &ad9910_channels[AD9910_CHAN_IDX_DRG_AMP], }, @@ -1109,7 +1178,8 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .channel =3D AD9910_CHANNEL_DRG_RAMP_DOWN, .address =3D AD9910_CHAN_IDX_DRG_AMP_RAMP_DOWN, .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_SAMP_FREQ), + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_INT_TIME), .ext_info =3D ad9910_drg_ramp_ext_info, .parent =3D &ad9910_channels[AD9910_CHAN_IDX_DRG_AMP], }, @@ -1337,6 +1407,17 @@ static int ad9910_read_raw(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_CHAN_INFO_INT_TIME: + switch (chan->channel) { + case AD9910_CHANNEL_DRG_RAMP_UP: + iio_val_s64_decompose(st->ramp_up_time_ns, val, val2); + return IIO_VAL_DECIMAL64_NANO; + case AD9910_CHANNEL_DRG_RAMP_DOWN: + iio_val_s64_decompose(st->ramp_down_time_ns, val, val2); + return IIO_VAL_DECIMAL64_NANO; + default: + return -EINVAL; + } default: return -EINVAL; } @@ -1637,6 +1718,34 @@ static int ad9910_write_raw(struct iio_dev *indio_de= v, return -EINVAL; } } + case IIO_CHAN_INFO_INT_TIME: { + s64 val64 =3D iio_val_s64_compose(val, val2); + s64 *time_ns, prev_ns; + + if (!st->drctl_pwm) + return -EOPNOTSUPP; + if (val64 < 0) + return -EINVAL; + + switch (chan->channel) { + case AD9910_CHANNEL_DRG_RAMP_UP: + time_ns =3D &st->ramp_up_time_ns; + break; + case AD9910_CHANNEL_DRG_RAMP_DOWN: + time_ns =3D &st->ramp_down_time_ns; + break; + default: + return -EINVAL; + } + + prev_ns =3D *time_ns; + *time_ns =3D val64; + ret =3D ad9910_drctl_sync(st); + if (ret) + *time_ns =3D prev_ns; + + return ret; + } default: return -EINVAL; } @@ -1671,6 +1780,8 @@ static int ad9910_write_raw_get_fmt(struct iio_dev *i= ndio_dev, return IIO_VAL_INT_PLUS_NANO; case IIO_CHAN_INFO_OFFSET: return IIO_VAL_DECIMAL64_MICRO; + case IIO_CHAN_INFO_INT_TIME: + return IIO_VAL_DECIMAL64_NANO; default: return -EINVAL; } @@ -1958,6 +2069,11 @@ static void ad9910_sw_powerdown_action(void *data) ad9910_sw_powerdown_set(data, true); } =20 +static void ad9910_drctl_disable_action(void *data) +{ + pwm_disable(data); +} + static void ad9910_hw_powerdown_action(void *data) { struct ad9910_state *st =3D data; @@ -2249,6 +2365,21 @@ static int ad9910_probe(struct spi_device *spi) =20 fsleep(AD9910_WAKEUP_DELAY_us); =20 + st->drctl_pwm =3D devm_pwm_get(dev, "drctl"); + if (IS_ERR(st->drctl_pwm)) { + ret =3D PTR_ERR(st->drctl_pwm); + if (ret !=3D -ENOENT && ret !=3D -ENODEV) + return dev_err_probe(dev, PTR_ERR(st->drctl_pwm), + "failed to get drctl pwm\n"); + st->drctl_pwm =3D NULL; + } else { + ret =3D devm_add_action_or_reset(dev, ad9910_drctl_disable_action, + st->drctl_pwm); + if (ret) + return dev_err_probe(dev, ret, + "failed to add drctl disable action\n"); + } + ret =3D ad9910_parse_fw(st); if (ret) return ret; --=20 2.43.0 From nobody Sat Oct 24 02:57:34 2026 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1792682353; b=xBqX3yk/H6YSa/z6JwACL439ojQsDcs7MarnSmfnZJs0VlgpyuoXIuorqnoIsvFPuPeP XWxK9Hj4JBJyaa0lmKd6fiQBxFsrVbtkpLiSVMIaYPx2tEYw5VQn8qOy7N7h9JAphSLj0 8D8qd1+bti8GflVcePoVy6S8XMDfRvZHQtPveNUnPbo0J3ytWcGK/P840HHuhNr4VT59n 3AvbUf4tus6QpIux22i9b8UMRyXeUTcbKYjHRyfhVhDrQVHMELZ1aILtHIkkSRsxuk+VQ 92HgKooqYi9DzA1kC8WT45LhHZ7qJ5qHmVsFJIrUHYCnYDxw+gm6Oq38va906Smq20A== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1792682353; h=Received:DKIM-Signature:Received:From:Date:Subject:MIME-Version: Content-Type:Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=r0X7kG0Zr9cHisTCNdoHjXXfiq9q907Y9QODkbFnhk4=; b=3eqbw7IXpoNipj1gUfIu21pRbVTdOZC4MkCRtiSvk9BFpqifriJ7VE8MsTbN2FBr9Sge lfdsDtKjQ9QtqTPehqxRQNts7t1L739PAQL9jn6rTgq+NsxPLGinGm5Sn6fvMR/+vxOV4 HplQf8sAJsqFi6NLYAdJmZNSb+MAFS8751ZefDE6uW7BwcQ8d76heWBUNZHtqeo9auaqA mZ9ImygduMVTUPw/dooFCbetCn+Fwty79PNV83+MyAS72I896tBszrzTNn9v6Lds+G6U5 tDrwYCfJbNtRR1DcjFqpumHtbTMXIqzf5ruSazKItn9leWZXjSWSB4VMFBM6bH0rCAQ== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=Uq3y2ABM; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 33FF7606D4DE; Thu, 22 Oct 2026 15:19:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=Uq3y2ABM Authentication-Results: smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 ARC-Seal: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; cv=none; t=1792682352; b=DCmZGsghYY2q86OFPVVRGH4Z6hRvyKwcRfMjZMl6EWxCW28DROd6wtAF5T1FCjXPsb5E CifIhz0ZyDNcS4FLD9TA1DBhqiCyB0oFNb6W+DO5dql7mhsP3aCB/f83ayRbVmz2E3mjr kCEDx9xQrJlql808m0w0TU+ivTUKMedGuDd/840QK5LliL0SLekSzpwesMH0vECOaBsqE KPGDz6+pwIoQILJUFsOPYYwmJ1aIMtvgGhfxJMzNh1MXKWmN8xwLVY49cYNRrwJlMCpLu 9usHSh3o2SGKHW1YLiLt/9YZe1ajR60jC0+pOI9/+ojRTv7zshYhIS1ES5k0C6B81bw== ARC-Message-Signature: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; c=relaxed/relaxed; t=1792682352; h=DKIM-Signature:Received:From:Date:Subject:MIME-Version:Content-Type: Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=r0X7kG0Zr9cHisTCNdoHjXXfiq9q907Y9QODkbFnhk4=; b=2mXrZ2tjUjUx5D5L/FmkC9a940jqAWDOLOw7JLEvzaqkQr27YC+VwjON1beNMYFA6PbS PLfZObznSVNaqCFANT0hdsjZN1cdBnAlJBvNdCtXkhdAgIOAt9CxGD0A+Q7uA9skDCxpR ozqjg2Ot7VnMfAKfuYOhGhHUhpwZu1UN2SNzzJ41B0/adTiUlMeYGlwTnQRm0Vjmiwplu G7mTzj11CaRaogE2KvX4cbXG+V00xeVPYVYAP80uAZk6OwmdjxfQ5qO1HXjEQUnBCEffC mIuePvhqtfq1oX9Pt1SVUAi/aHRabGnS7Xq4QlvxovnOO0S3TijPkTILaIIDngF6Myw== ARC-Authentication-Results: i=1; smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 Received: from lkml.kernel.org (nexus.subspace.kernel.org [100.80.115.77]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.kernel.org (Postfix) with ESMTPS id 294B81F031E3; Thu, 22 Oct 2026 15:19:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792682352; bh=r0X7kG0Zr9cHisTCNdoHjXXfiq9q907Y9QODkbFnhk4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To; b=Uq3y2ABM73lUwBzEooyZ7qwaAgyC2ZAI9LJvTOAxduiqqE5eYDcIxKqZ1XhYYiHao Lyt+30Q3ErIYSmDn7mx9fGKIF9s+HJlql/i8mPxruRw8791+hX8v/mc/1GhNrUMN8/ WNu/8poPqqcX0mR8jGgSwaNf/PPIBLUCIFZ7wv1UFd9Pcb1G4e5/oW8G9aMZ4iCwU3 NBfgsct73FP7XhsfX7uj1yPmC3/yo9JA0ct8eyQivGlrRyrW+SFT4UG8KsCsek0QUk ZK/M45pYE5K2QpMI+Mz3NfO4OcEC/xbc0kEk83xaQjZIvA5opwttxvfANzERIcdg1q 5JkN4qVhxF0qA== Received: from nexus.subspace.kernel.org (localhost [IPv6:::1]) by lkml.kernel.org (Postfix) with ESMTP id A474841E66; Thu, 22 Oct 2026 15:19:08 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Thu, 22 Oct 2026 12:19:06 -0300 Subject: [PATCH v2 08/10] iio: frequency: ad9910: support iio backend X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Message-Id: <20261022-ad9910-backend-support-v2-8-0ff7f0bff326@analog.com> References: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> In-Reply-To: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> To: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, linux@analog.com, devicetree@vger.kernel.org, linux-pwm@vger.kernel.org, linux-doc@vger.kernel.org, Jonathan Cameron Cc: Olivier Moysan , Jonathan Cameron , David Lechner , Andy Shevchenko , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Jonathan Corbet , Shuah Khan , Randy Dunlap , Rodrigo Alencar X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1792682347; l=18094; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=gAp+yrbQi8sNJ0EWZAA9UvE+r8wfxoOlqWorwLPpoNM=; b=m+p74mmmOgY/3DjpWUR/5mSYBarljp0htsUq0CgbkLF1qtglXtU+rZUAs/MJH1ovyRpTXbZvZ uzG0TkeVxoKCYQeJndT4wWT9mLZFp9rz1UnDJHsCN4aAgtRC9tOwWvw X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com Content-Transfer-Encoding: quoted-printable From: Rodrigo Alencar The AD9910 parallel data port allows modulation of the DDS core parameters at up to the PDCLK rate, which requires a high-speed data source. Add support for an optional IIO backend that provides such interface, with data streamed into the device through an output buffer. The parallel port channels get scan indexes and scan types according to the data destination: 14-bit amplitude, 16-bit phase, 16-bit frequency, or the 8-bit amplitude and phase pair for polar modulation. As only one destination can be active at a time, this is enforced by the available scan masks. On buffer enable, the destination is configured in the backend and the parallel data port is enabled. The sampling_frequency attribute of the parallel port channels controls the backend data rate. The backend is also notified about profile changes, as it may drive the PROFILE[2:0] pins, and the debugfs source attributes now consider the parallel data port when reporting which channel controls each DDS core parameter. Signed-off-by: Rodrigo Alencar --- drivers/iio/frequency/Kconfig | 1 + drivers/iio/frequency/ad9910.c | 222 +++++++++++++++++++++++++++++++++++++= ++-- 2 files changed, 217 insertions(+), 6 deletions(-) diff --git a/drivers/iio/frequency/Kconfig b/drivers/iio/frequency/Kconfig index 591476f23ace..b3ed2e39e2fb 100644 --- a/drivers/iio/frequency/Kconfig +++ b/drivers/iio/frequency/Kconfig @@ -33,6 +33,7 @@ config AD9910 select CRC32 select FW_LOADER select FW_UPLOAD + select IIO_BACKEND help Say yes here to build support for Analog Devices AD9910 1 GSPS, 14-Bit DDS with integrated DAC. diff --git a/drivers/iio/frequency/ad9910.c b/drivers/iio/frequency/ad9910.c index 1de02017f78c..549d27bd8d7f 100644 --- a/drivers/iio/frequency/ad9910.c +++ b/drivers/iio/frequency/ad9910.c @@ -31,6 +31,7 @@ #include #include =20 +#include #include #include =20 @@ -300,6 +301,15 @@ struct ad9910_ram_fw { __be32 words[] __counted_by_be(wcount); } __packed; =20 +enum { + AD9910_SCAN_IDX_AMP =3D 0, + AD9910_SCAN_IDX_PHASE, + AD9910_SCAN_IDX_FREQ, + /* polar phase goes first, as it is placed in the lower byte, D[7:0] */ + AD9910_SCAN_IDX_POLAR_PHASE, + AD9910_SCAN_IDX_POLAR_AMP, +}; + enum { AD9910_POWERDOWN, AD9910_DWELL_EN, @@ -331,6 +341,7 @@ struct ad9910_state { struct gpio_desc *gpio_pwdown; struct gpio_desc *gpio_update; struct gpio_descs *gpio_profile; + struct iio_backend *back; =20 s64 ramp_up_time_ns; s64 ramp_down_time_ns; @@ -350,6 +361,7 @@ struct ad9910_state { =20 struct ad9910_data data; u8 profile; + u8 scan_mask; =20 bool ram_fwu_cancel; char ram_fwu_name[20]; @@ -568,6 +580,16 @@ static int ad9910_set_sysclk_freq(struct ad9910_state = *st, u32 freq_hz, =20 st->data.sysclk_freq_hz =3D sysclk_freq_hz; =20 + /* + * SYSCLK is already updated in the device, so the driver state is not + * rolled back on a backend failure. The error is still returned, which + * lets userspace know that something went wrong. + */ + if (st->back) + return iio_backend_set_sampling_freq(st->back, + AD9910_CHAN_IDX_PHY, + sysclk_freq_hz); + return 0; } =20 @@ -579,6 +601,10 @@ static int ad9910_profile_set(struct ad9910_state *st,= u8 profile) values[0] =3D profile; gpiod_multi_set_value_cansleep(st->gpio_profile, values); =20 + if (st->back) + return iio_backend_chan_enable(st->back, + AD9910_CHAN_IDX_PROFILE_0 + profile); + return 0; } =20 @@ -1008,6 +1034,7 @@ static const struct iio_chan_spec_ext_info ad9910_osk= _ext_info[] =3D { .output =3D 1, \ .channel =3D AD9910_CHANNEL_PROFILE_ ## idx, \ .address =3D AD9910_CHAN_IDX_PROFILE_ ## idx, \ + .scan_index =3D -1, \ .info_mask_separate =3D BIT(IIO_CHAN_INFO_ENABLE) | \ BIT(IIO_CHAN_INFO_FREQUENCY) | \ BIT(IIO_CHAN_INFO_PHASE) | \ @@ -1022,6 +1049,7 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_PHY, .address =3D AD9910_CHAN_IDX_PHY, + .scan_index =3D -1, .info_mask_separate =3D BIT(IIO_CHAN_INFO_SAMP_FREQ), .info_mask_shared_by_type =3D BIT(IIO_CHAN_INFO_SCALE), .ext_info =3D ad9910_phy_ext_info, @@ -1040,6 +1068,14 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_PARALLEL, .address =3D AD9910_CHAN_IDX_PARALLEL_AMP, + .scan_index =3D AD9910_SCAN_IDX_AMP, + .scan_type =3D { + .sign =3D 'u', + .realbits =3D 14, + .storagebits =3D 16, + .shift =3D 2, + }, + .info_mask_separate =3D BIT(IIO_CHAN_INFO_SAMP_FREQ), .parent =3D &ad9910_channels[AD9910_CHAN_IDX_PHY], }, [AD9910_CHAN_IDX_PARALLEL_PHASE] =3D { @@ -1048,7 +1084,14 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_PARALLEL, .address =3D AD9910_CHAN_IDX_PARALLEL_PHASE, - .info_mask_separate =3D BIT(IIO_CHAN_INFO_SCALE), + .scan_index =3D AD9910_SCAN_IDX_PHASE, + .scan_type =3D { + .sign =3D 'u', + .realbits =3D 16, + .storagebits =3D 16, + }, + .info_mask_separate =3D BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_SCALE), .parent =3D &ad9910_channels[AD9910_CHAN_IDX_PHY], }, [AD9910_CHAN_IDX_PARALLEL_FREQ] =3D { @@ -1057,7 +1100,14 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_PARALLEL, .address =3D AD9910_CHAN_IDX_PARALLEL_FREQ, - .info_mask_separate =3D BIT(IIO_CHAN_INFO_OFFSET) | + .scan_index =3D AD9910_SCAN_IDX_FREQ, + .scan_type =3D { + .sign =3D 'u', + .realbits =3D 16, + .storagebits =3D 16, + }, + .info_mask_separate =3D BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE), .parent =3D &ad9910_channels[AD9910_CHAN_IDX_PHY], }, @@ -1067,7 +1117,14 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_PARALLEL_POLAR, .address =3D AD9910_CHAN_IDX_PARALLEL_POLAR_AMP, - .info_mask_separate =3D BIT(IIO_CHAN_INFO_OFFSET) | + .scan_index =3D AD9910_SCAN_IDX_POLAR_AMP, + .scan_type =3D { + .sign =3D 'u', + .realbits =3D 8, + .storagebits =3D 8, + }, + .info_mask_separate =3D BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE), .parent =3D &ad9910_channels[AD9910_CHAN_IDX_PHY], }, @@ -1077,7 +1134,14 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_PARALLEL_POLAR, .address =3D AD9910_CHAN_IDX_PARALLEL_POLAR_PHASE, - .info_mask_separate =3D BIT(IIO_CHAN_INFO_OFFSET) | + .scan_index =3D AD9910_SCAN_IDX_POLAR_PHASE, + .scan_type =3D { + .sign =3D 'u', + .realbits =3D 8, + .storagebits =3D 8, + }, + .info_mask_separate =3D BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE), .parent =3D &ad9910_channels[AD9910_CHAN_IDX_PHY], }, @@ -1087,6 +1151,7 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_DRG, .address =3D AD9910_CHAN_IDX_DRG_FREQ, + .scan_index =3D -1, .info_mask_separate =3D BIT(IIO_CHAN_INFO_ENABLE) | BIT(IIO_CHAN_INFO_SCALE), .parent =3D &ad9910_channels[AD9910_CHAN_IDX_PHY], @@ -1097,6 +1162,7 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_DRG, .address =3D AD9910_CHAN_IDX_DRG_PHASE, + .scan_index =3D -1, .info_mask_separate =3D BIT(IIO_CHAN_INFO_ENABLE) | BIT(IIO_CHAN_INFO_SCALE), .parent =3D &ad9910_channels[AD9910_CHAN_IDX_PHY], @@ -1107,6 +1173,7 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_DRG, .address =3D AD9910_CHAN_IDX_DRG_AMP, + .scan_index =3D -1, .info_mask_separate =3D BIT(IIO_CHAN_INFO_ENABLE) | BIT(IIO_CHAN_INFO_SCALE), .parent =3D &ad9910_channels[AD9910_CHAN_IDX_PHY], @@ -1117,6 +1184,7 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_DRG_RAMP_UP, .address =3D AD9910_CHAN_IDX_DRG_FREQ_RAMP_UP, + .scan_index =3D -1, .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_INT_TIME), @@ -1129,6 +1197,7 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_DRG_RAMP_DOWN, .address =3D AD9910_CHAN_IDX_DRG_FREQ_RAMP_DOWN, + .scan_index =3D -1, .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_INT_TIME), @@ -1141,6 +1210,7 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_DRG_RAMP_UP, .address =3D AD9910_CHAN_IDX_DRG_PHASE_RAMP_UP, + .scan_index =3D -1, .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_INT_TIME), @@ -1153,6 +1223,7 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_DRG_RAMP_DOWN, .address =3D AD9910_CHAN_IDX_DRG_PHASE_RAMP_DOWN, + .scan_index =3D -1, .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_INT_TIME), @@ -1165,6 +1236,7 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_DRG_RAMP_UP, .address =3D AD9910_CHAN_IDX_DRG_AMP_RAMP_UP, + .scan_index =3D -1, .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_INT_TIME), @@ -1177,6 +1249,7 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_DRG_RAMP_DOWN, .address =3D AD9910_CHAN_IDX_DRG_AMP_RAMP_DOWN, + .scan_index =3D -1, .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_INT_TIME), @@ -1189,6 +1262,7 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_RAM, .address =3D AD9910_CHAN_IDX_RAM, + .scan_index =3D -1, .info_mask_separate =3D BIT(IIO_CHAN_INFO_ENABLE) | BIT(IIO_CHAN_INFO_FREQUENCY) | BIT(IIO_CHAN_INFO_PHASE) | @@ -1201,6 +1275,7 @@ static const struct iio_chan_spec ad9910_channels[] = =3D { .output =3D 1, .channel =3D AD9910_CHANNEL_OSK, .address =3D AD9910_CHAN_IDX_OSK, + .scan_index =3D -1, .info_mask_separate =3D BIT(IIO_CHAN_INFO_ENABLE) | BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SAMP_FREQ), @@ -1314,6 +1389,12 @@ static int ad9910_read_raw(struct iio_dev *indio_dev, case AD9910_CHANNEL_PHY: *val =3D st->data.sysclk_freq_hz; return IIO_VAL_INT; + case AD9910_CHANNEL_PARALLEL: + case AD9910_CHANNEL_PARALLEL_POLAR: + if (!st->back) + return -EOPNOTSUPP; + + return iio_backend_read_raw(st->back, chan, val, val2, info); case AD9910_CHANNEL_DRG_RAMP_UP: tmp32 =3D FIELD_GET(AD9910_DRG_RATE_INC_MSK, st->reg[AD9910_REG_DRG_RATE].val32); @@ -1623,6 +1704,17 @@ static int ad9910_write_raw(struct iio_dev *indio_de= v, if (chan->channel =3D=3D AD9910_CHANNEL_PHY) return ad9910_set_sysclk_freq(st, val, true); =20 + if (chan->channel =3D=3D AD9910_CHANNEL_PARALLEL || + chan->channel =3D=3D AD9910_CHANNEL_PARALLEL_POLAR) { + if (!st->back) + return -EOPNOTSUPP; + if (val < 0) + return -EINVAL; + + return iio_backend_set_sampling_freq(st->back, + chan->address, val); + } + if (val < 0 || val2 < 0 || val > st->data.sysclk_freq_hz / 4) return -EINVAL; =20 @@ -1773,9 +1865,14 @@ static int ad9910_write_raw_get_fmt(struct iio_dev *= indio_dev, return -EINVAL; } case IIO_CHAN_INFO_SAMP_FREQ: - if (chan->channel =3D=3D AD9910_CHANNEL_PHY) + switch (chan->channel) { + case AD9910_CHANNEL_PHY: + case AD9910_CHANNEL_PARALLEL: + case AD9910_CHANNEL_PARALLEL_POLAR: return IIO_VAL_INT; - return IIO_VAL_INT_PLUS_MICRO; + default: + return IIO_VAL_INT_PLUS_MICRO; + } case IIO_CHAN_INFO_SCALE: return IIO_VAL_INT_PLUS_NANO; case IIO_CHAN_INFO_OFFSET: @@ -2169,6 +2266,12 @@ static inline const char *ad9910_frequency_source_ge= t(struct ad9910_state *st) st->reg[AD9910_REG_CFR2].val32)) return ad9910_channel_str[AD9910_CHAN_IDX_DRG_FREQ]; =20 + /* Parallel data port enabled and data destination is frequency */ + mode_en =3D FIELD_GET(AD9910_CFR2_PARALLEL_DATA_PORT_EN_MSK, + st->reg[AD9910_REG_CFR2].val32); + if (mode_en && (st->scan_mask & BIT(AD9910_SCAN_IDX_FREQ))) + return ad9910_channel_str[AD9910_CHAN_IDX_PARALLEL_FREQ]; + /* FTW: RAM enabled and data destination is phase, amplitude, or polar */ if (ram_en) return ad9910_channel_str[AD9910_CHAN_IDX_RAM]; @@ -2209,6 +2312,16 @@ static inline const char *ad9910_phase_source_get(st= ruct ad9910_state *st) st->reg[AD9910_REG_CFR2].val32)) return ad9910_channel_str[AD9910_CHAN_IDX_DRG_PHASE]; =20 + /* Parallel data port enabled and data destination is phase */ + mode_en =3D FIELD_GET(AD9910_CFR2_PARALLEL_DATA_PORT_EN_MSK, + st->reg[AD9910_REG_CFR2].val32); + if (mode_en) { + if (st->scan_mask & BIT(AD9910_SCAN_IDX_PHASE)) + return ad9910_channel_str[AD9910_CHAN_IDX_PARALLEL_PHASE]; + if (st->scan_mask & BIT(AD9910_SCAN_IDX_POLAR_PHASE)) + return ad9910_channel_str[AD9910_CHAN_IDX_PARALLEL_POLAR_PHASE]; + } + /* POW: RAM enabled and data destination is frequency or amplitude */ if (ram_en) return ad9910_channel_str[AD9910_CHAN_IDX_RAM]; @@ -2255,6 +2368,16 @@ static inline const char *ad9910_amplitude_source_ge= t(struct ad9910_state *st) st->reg[AD9910_REG_CFR2].val32)) return ad9910_channel_str[AD9910_CHAN_IDX_DRG_AMP]; =20 + /* Parallel data port enabled and data destination is amplitude */ + mode_en =3D FIELD_GET(AD9910_CFR2_PARALLEL_DATA_PORT_EN_MSK, + st->reg[AD9910_REG_CFR2].val32); + if (mode_en) { + if (st->scan_mask & BIT(AD9910_SCAN_IDX_AMP)) + return ad9910_channel_str[AD9910_CHAN_IDX_PARALLEL_AMP]; + if (st->scan_mask & BIT(AD9910_SCAN_IDX_POLAR_AMP)) + return ad9910_channel_str[AD9910_CHAN_IDX_PARALLEL_POLAR_AMP]; + } + /* only way to control amplitude at this point is through OSK */ if (ram_en) return ad9910_channel_str[AD9910_CHAN_IDX_OSK]; @@ -2283,6 +2406,78 @@ static inline void ad9910_debugfs_init(struct ad9910= _state *st, &ad9910_amplitude_source_fops); } =20 +static const u8 ad9910_scan_chan_idx[] =3D { + [AD9910_SCAN_IDX_AMP] =3D AD9910_CHAN_IDX_PARALLEL_AMP, + [AD9910_SCAN_IDX_PHASE] =3D AD9910_CHAN_IDX_PARALLEL_PHASE, + [AD9910_SCAN_IDX_FREQ] =3D AD9910_CHAN_IDX_PARALLEL_FREQ, + [AD9910_SCAN_IDX_POLAR_PHASE] =3D AD9910_CHAN_IDX_PARALLEL_POLAR_PHASE, + [AD9910_SCAN_IDX_POLAR_AMP] =3D AD9910_CHAN_IDX_PARALLEL_POLAR_AMP, +}; + +static u32 ad9910_buffer_chan_idx(struct iio_dev *indio_dev) +{ + unsigned int scan_idx =3D find_first_bit(indio_dev->active_scan_mask, + iio_get_masklength(indio_dev)); + + return ad9910_scan_chan_idx[scan_idx]; +} + +static int ad9910_buffer_preenable(struct iio_dev *indio_dev) +{ + struct ad9910_state *st =3D iio_priv(indio_dev); + int ret; + + guard(mutex)(&st->lock); + + st->scan_mask =3D *indio_dev->active_scan_mask; + ret =3D iio_backend_chan_enable(st->back, + ad9910_buffer_chan_idx(indio_dev)); + if (ret) + return ret; + + ret =3D ad9910_reg32_update(st, AD9910_REG_CFR2, + AD9910_CFR2_PARALLEL_DATA_PORT_EN_MSK, + AD9910_CFR2_PARALLEL_DATA_PORT_EN_MSK, + true); + if (ret) + iio_backend_chan_disable(st->back, + ad9910_buffer_chan_idx(indio_dev)); + + return ret; +} + +static int ad9910_buffer_postdisable(struct iio_dev *indio_dev) +{ + struct ad9910_state *st =3D iio_priv(indio_dev); + int ret, ret2; + + guard(mutex)(&st->lock); + + st->scan_mask =3D 0; + ret =3D ad9910_reg32_update(st, AD9910_REG_CFR2, + AD9910_CFR2_PARALLEL_DATA_PORT_EN_MSK, + 0, true); + + /* disable the backend channel regardless, return the first error */ + ret2 =3D iio_backend_chan_disable(st->back, + ad9910_buffer_chan_idx(indio_dev)); + + return ret ?: ret2; +} + +static const struct iio_buffer_setup_ops ad9910_buffer_setup_ops =3D { + .preenable =3D ad9910_buffer_preenable, + .postdisable =3D ad9910_buffer_postdisable, +}; + +static const unsigned long ad9910_available_scan_masks[] =3D { + BIT(AD9910_SCAN_IDX_AMP), + BIT(AD9910_SCAN_IDX_PHASE), + BIT(AD9910_SCAN_IDX_FREQ), + BIT(AD9910_SCAN_IDX_POLAR_AMP) | BIT(AD9910_SCAN_IDX_POLAR_PHASE), + 0 +}; + static int ad9910_probe(struct spi_device *spi) { static const char * const supplies[] =3D { @@ -2326,6 +2521,20 @@ static int ad9910_probe(struct spi_device *spi) return dev_err_probe(dev, PTR_ERR(dev_rst), "failed to get device reset control\n"); =20 + st->back =3D devm_iio_backend_get_optional(dev, NULL); + if (IS_ERR(st->back)) + return dev_err_probe(dev, PTR_ERR(st->back), + "failed to get iio backend\n"); + if (st->back) { + ret =3D devm_iio_backend_request_buffer(dev, st->back, indio_dev); + if (ret) + return dev_err_probe(dev, ret, + "failed to request iio backend buffer\n"); + + indio_dev->setup_ops =3D &ad9910_buffer_setup_ops; + indio_dev->available_scan_masks =3D ad9910_available_scan_masks; + } + /* * The IO RESET pin is not used in this driver, as we assume that all * SPI transfers are complete, but if it is wired up, we need to make @@ -2435,3 +2644,4 @@ module_spi_driver(ad9910_driver); MODULE_AUTHOR("Rodrigo Alencar "); MODULE_DESCRIPTION("Analog Devices AD9910 DDS driver"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("IIO_BACKEND"); --=20 2.43.0 From nobody Sat Oct 24 02:57:34 2026 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1792682353; b=vr/qgzHedxomh9v18WawsZ3gZArUouALlqNUD01V2LsYZKbb6X6KB7Tr2bgxTNyXzzVp SNetzHaxyKGZX45MNgLeRbK05wwav7V5kc3LafjKmmNu7f/KY+rCbslz10TLztlVZVoJb RfHcHAJfS/rpHt8K64W/c/+IDZzhrCdAFAVDMlhlKLwItk+FIwwjIoGXxAV/er9BFMrOh i7Uu35IFjwFkzwO9YIYHhAh81yId+8U6a8JugSmCOthVVYp8yNs+s4jG8d1ju5pYsDLBU FN0vF+Xf5RWZL2q8v7ZZL36CF12aVuOdOetwjNioPX/QPwB+dCXEJgXISBJM1yvQ++A== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1792682353; h=Received:DKIM-Signature:Received:From:Date:Subject:MIME-Version: Content-Type:Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=bKY/is6AhRtOF4CROF9s6PJ1wA3Cbs/0fe03oh4k6vM=; b=n/wfg7zM/CPL4C9VXzLhi8uq1LtzfmaHSoRJpYammvANtMEpt6MW7jnDYSv8uDltLDNO 3jZtUuwN1yRQZ2gmn1cjir3FxN4XEJ8SOZiRfbiXwgnOthlO901qIEd2+3jvL7yZ236CN j6v0VyCgm9oM6XZlNQ5/30cvcs4d6w6FQtvN1FWDsC2eXlFyI7rGBidtHvY9WIV65JVzp bEQMnpm5VjKWLjA84k6hYt+uerDPGUVrAExnfdsxs8LaS0uqdolyjig9rEczyCy01dwan DqKpJBdlejswV2Nn9PY7kpgSPpzAKVTA4T0EEDj+Inpu8CPvmpyxbAWBDQg+nvrB5zw== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=Oitr2jY7; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 22EEA606D4C0; Thu, 22 Oct 2026 15:19:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=Oitr2jY7 Authentication-Results: smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 ARC-Seal: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; cv=none; t=1792682351; b=10A2KMoVdjMW7uhQE3C9Qodv41aeJvUfKXuKV8KvuekX8TX6/jnklyPhgQXR5VyQzCLv RUzNFXn1ewqn2kRS04Za8kKWIc+DAeWnO28iCcfApGbNg5tgJU8R8Vx3jqZWkro/oV8Vz FGmVFnFgQnThEUCgDJkGCq1RegLgQTha2zfAGFQtkgiRBn3v+4C+atKtHmJvYJozOfn89 ZuNE+uAymJTbjWDl5c+kNwHFdciT4FMk5IqyHDHUTIy6MFxfZi+7iO8Aq78oJxf13W77d k4dVq2zljcshAcqX6GasMgceFLDtQP686ioxsyHhm6zE3B57Dxy+nbN+jEyL4mEl56g== ARC-Message-Signature: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; c=relaxed/relaxed; t=1792682351; h=DKIM-Signature:Received:From:Date:Subject:MIME-Version:Content-Type: Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=bKY/is6AhRtOF4CROF9s6PJ1wA3Cbs/0fe03oh4k6vM=; b=gkL2tlXJUkhLZPQQcwy0eO5YYt+Ris+fWC0lpz7WdI64Ix/qvLwsXId5CbTWf7Ggk7ky f9LCfHwwt4Z+xvxoX+fzyiqhFLmsEulUZxQZAhfT1Fy9p9TGODnFv7lwWCtwGwGzm/drc XP/XOZ2FmcBaoM9I5YAx6ojE1WFLslaoXI8uRQS3+SYQqg3hcuK3FivjKMr0MHt8l3Klt OaJd1RlTHeRC7euU4unK1146lPoFTcsjU1dEUVl0RLw/ZMw+C6K51I2cVcDSbR9KSTJa1 v9NFSUziTVzX8uhTzeZjOjl6VIEsdZ4O3QKB40PjxPOzQaf3wpmw3nK4kuXbCu/LabQ== ARC-Authentication-Results: i=1; smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 Received: from lkml.kernel.org (nexus.subspace.kernel.org [100.80.115.77]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.kernel.org (Postfix) with ESMTPS id 7A75D1F031E5; Thu, 22 Oct 2026 15:19:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792682351; bh=bKY/is6AhRtOF4CROF9s6PJ1wA3Cbs/0fe03oh4k6vM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To; b=Oitr2jY70WC+tS40+akIbGFn/CEBrRnklik5rH5DArCu4DaZz63UZyZUlRUDnrYRZ ov0GluiqtZr08GA2v2IKF0jp39qPxXXznbj0XhbnpiiaHbUVVzDPpZFR6Jw79Vm16Q 787nswks7jaJcVzpfNo9IKsucAQ4WNOK8ODimNQywtkzK5PHwR3T3pc4ISZcCHK2qJ AV7gEL9RvwuBVk8q6k/VMikQZ0TWd1KM44g1kw6ojRXzRZNI4OA4wyWr+dEPlYphBr HUJqToMdakjIDsWm722HtneAfGJb7ltG6zWUQ2Q1X0kophSFAKdH6+c1/+cICsa7Py qECNeyuKOokLg== Received: from nexus.subspace.kernel.org (localhost [IPv6:::1]) by lkml.kernel.org (Postfix) with ESMTP id AC71441E6A; Thu, 22 Oct 2026 15:19:08 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Thu, 22 Oct 2026 12:19:07 -0300 Subject: [PATCH v2 09/10] iio: ABI: add integration_time for output channels X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Message-Id: <20261022-ad9910-backend-support-v2-9-0ff7f0bff326@analog.com> References: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> In-Reply-To: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> To: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, linux@analog.com, devicetree@vger.kernel.org, linux-pwm@vger.kernel.org, linux-doc@vger.kernel.org, Jonathan Cameron Cc: Olivier Moysan , Jonathan Cameron , David Lechner , Andy Shevchenko , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Jonathan Corbet , Shuah Khan , Randy Dunlap , Rodrigo Alencar X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1792682347; l=2039; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=snDH6M+COm79T6hMU2A4F2/Mb35rg85wpRy/sNJ/PXk=; b=AX9Y8IIo8DZzVnP9+O0i+ZiT0a9n/HEiHL+Tk6p7GgXlTRKLNRGwrRJgk9Wpu8L6KQfiwh72E qPMePHApTPKCFEdMPziIWkyDReC6FbugqiMF2dqSq4Hoev63XQrOKwY X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com Content-Transfer-Encoding: quoted-printable From: Rodrigo Alencar Document the integration_time attribute for output channels, which is the time interval during which the output is generated by integrating a quantity, such as its rate of change. It is the output counterpart of the integration_time already defined for input channels. Add entries for the altcurrent, frequency and phase channel types, which are going to be used by the AD9910 DDS driver. Reviewed-by: Nuno S=C3=A1 Signed-off-by: Rodrigo Alencar --- Documentation/ABI/testing/sysfs-bus-iio | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/te= sting/sysfs-bus-iio index 2b6f57041763..b09254a57438 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -1744,6 +1744,23 @@ Description: seconds. If shared across all channels of a given type, _integration_time is used. =20 +What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_integration_time +What: /sys/bus/iio/devices/iio:deviceX/out_frequencyY_integration_time +What: /sys/bus/iio/devices/iio:deviceX/out_phaseY_integration_time +KernelVersion: 7.5 +Contact: linux-iio@vger.kernel.org +Description: + This attribute is used to get/set the integration time in + seconds of an output channel, i.e., the time interval during + which the output is generated by integrating (accumulating) a + quantity over time, such as the rate of change (roc) of the + channel. The output variation over this interval corresponds to + the integral of that quantity, which may be bounded by limits + configured through other channel attributes. The written value + may be adjusted to the nearest interval supported by the + hardware. If shared across all channels of a given type, + _integration_time is used. + What: /sys/.../iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_integration_time KernelVersion: 4.0 Contact: linux-iio@vger.kernel.org --=20 2.43.0 From nobody Sat Oct 24 02:57:34 2026 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1792682353; b=rdis2a1DI6X3zNeOwwFTAnkFnLhwTBS1V1kRel3RSph5KwFxv88HI+RYHD8Kr9WoXpFc 2JgE3dhOjoRxVKzwanLU1Ms8+XounvJ2mXthswNktOFaVaF3kmVdHq19P2UvYvhEVL8sJ 5NSbUmgzlfZ862gRJ1zCdn9AflvO5Bw++PB0JnyBEJjk9FSpzMWLYrxUcOBAo1kpVCwwP SCfFu1lAr1RW/Q6lRQC3Oi+SsdLKA5Dwk5h4wc9l+JWBowozeqEJI/8hYVZ6wwuCL7O28 6KBJYnXPr+GEszZ5dhkm9yaI0dzpUiF0f+PIrq4GHRZJ+N93cGh7JuXqezhs4YmH9sA== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1792682353; h=Received:DKIM-Signature:Received:From:Date:Subject:MIME-Version: Content-Type:Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=6+KUMNWETbOIm1etOJvqfpofFQZLeiAo3ByMDioY4WU=; b=rh+FJXMpFqIuKTYN9L7k7uThpwI5KnuPqvXqli5uDGXzqz+Y9OPWxKzLL1ZsOvxRx434 1VoZ5kpHyQM2XFWsSvCb9uEDpgjgiaLff4Bqj8BCVtjMItK4CiyWHtU3CuewPcq9PFOjX +auU30cXdsjMD3EFusatTmYStYqvz4O/lsH0pEnOD1YXJ6sBw/19B7ePmJpuHYoGrlmUu VQtxJerHKfZaRw3NeEi9tYKOeJBnG1u/smzxKu/GXSvrVMZAvkw+Uz3IZfvuXN5Stv5wC 7YMOU27ijqmmULQ6Bf8iNQzImv9dvnrQ5uICmdikZaIzgbRsMQ47NxaRgdPZoVKTMaw== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=UkMkVaMR; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A5003606CC49; Thu, 22 Oct 2026 15:19:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=UkMkVaMR Authentication-Results: smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 ARC-Seal: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; cv=none; t=1792682352; b=0qmLwQAqJg8htCiJh2prayla+QSJXGbrtEw+IKYzfBYIwsIW05tfGQ3sPF8Cz3idd01n MK3w/m34BoqzrOxi4iOohbJ0V/GP2r4XvBpseU1ddY+2GCvtKcUhFiRGW7Z9zs+IK8ZjH w3weykxdIRrcFM3MAe2DVvY/US8ihUY+0sw4s4/sJVmIapz5dUve6QM7xFeO+DLJmHcK+ BC92tR9JnpvkpELODYcjL1nbIuEj8dL6yzt8J0RgZ0YtD1zXgnZgR5Dkn5JZqmaC83Qzw N6uo5+b2RVLyVQRLAncgT9CXaj/FE1yJnc3Khh2yDCy5DySnBeM+gphbCwQf8pbtejA== ARC-Message-Signature: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; c=relaxed/relaxed; t=1792682352; h=DKIM-Signature:Received:From:Date:Subject:MIME-Version:Content-Type: Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=6+KUMNWETbOIm1etOJvqfpofFQZLeiAo3ByMDioY4WU=; b=z7xenscEQKLaVKcBAn3/hqFgBAe47ucOVQnxqt37PGShSJos7PfoESWqjH1656m++exr 8hgCMG5MxzUFCvX975C9NlB5hBCrGPVk9kgL5HEn3Cp11EipEA6IYQI2upThisiCj3z/H biNaGxWa2tanDjazNITsM5jeiOS6Q9D7OjMBXcKwMOVq+SaM3TvBR7ZdfRDBTKkGT7BDy EqoyF6nAD+bZT9oahBRtoBhYDsUI9bFqCl0ogTxHts9Om7jEAXf/WVLZGPRLEykrhfnA0 Qijd1mCqRHDKUbvzgdMWbPsaczmB0w0uYkqwp3kVrLNx/aucgB4X55BlwYm4kZt+MVQ== ARC-Authentication-Results: i=1; smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 Received: from lkml.kernel.org (nexus.subspace.kernel.org [100.80.115.77]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.kernel.org (Postfix) with ESMTPS id 825971F031ED; Thu, 22 Oct 2026 15:19:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792682352; bh=6+KUMNWETbOIm1etOJvqfpofFQZLeiAo3ByMDioY4WU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To; b=UkMkVaMRETkcUXeOOihD1HEZocJL8C0LNJOb0sRg3PkG1dZJgra5bb9aSThLT3eKq YyUWLu9XtFWCrgG23TYSkqr9tH/4Faqa/epS2HSFGWkhDHx9kxlVd7d2p2KGa0oOy5 Z3+ZVCCdega5k/Jgnnq0og6WAWu5oIb0NJRUy1MPCQzYv4sRiv5LQGjLV2/Ghiy8n9 OQN5HNfRUVQKAiwa4y5BVNJSsGyAtJ9EYu7NfR2pDzJz/BygHjvwp48q6FPRe8cbUD FSGmBZBvuBumDDOQXu6OpPWU8twjSuoFkp6oezH5pnr8NDeJfpmx8Gl3BWLWCSg+hK utIYjkHFHCSVQ== Received: from nexus.subspace.kernel.org (localhost [IPv6:::1]) by lkml.kernel.org (Postfix) with ESMTP id B761B41E6F; Thu, 22 Oct 2026 15:19:08 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Thu, 22 Oct 2026 12:19:08 -0300 Subject: [PATCH v2 10/10] docs: iio: ad9910: document DRCTL pin control X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Message-Id: <20261022-ad9910-backend-support-v2-10-0ff7f0bff326@analog.com> References: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> In-Reply-To: <20261022-ad9910-backend-support-v2-0-0ff7f0bff326@analog.com> To: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, linux@analog.com, devicetree@vger.kernel.org, linux-pwm@vger.kernel.org, linux-doc@vger.kernel.org, Jonathan Cameron Cc: Olivier Moysan , Jonathan Cameron , David Lechner , Andy Shevchenko , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Jonathan Corbet , Shuah Khan , Randy Dunlap , Rodrigo Alencar X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1792682347; l=6219; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=9AdEqIZ+bYqk9Lw6P7OuqM0LPTI0z5xHBJLcZX+ImKY=; b=uXb3PIln3CqI5BQMvSFeUzmQlLZ1I31Q5FdLc+gCuiqatzRl2MJl5j89dMPyZZ2mimGOwRjBy HED3yDG8d7YByxQfFGWKiPN+Wp+AtN+j4n5YOh7bgHJBjxBBepXlNJT X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com Content-Transfer-Encoding: quoted-printable From: Rodrigo Alencar Document the integration_time attribute of the digital ramp generator (DRG) rising and falling channels, and describe how the DRCTL pin waveform is generated from those values according to the dwell_en configuration. Add usage examples for triangular and sawtooth sweeps driven through the DRCTL pin. Signed-off-by: Rodrigo Alencar --- Documentation/iio/ad9910.rst | 90 ++++++++++++++++++++++++++++++++++++++++= +--- 1 file changed, 84 insertions(+), 6 deletions(-) diff --git a/Documentation/iio/ad9910.rst b/Documentation/iio/ad9910.rst index aab569f561db..bff55cca8c82 100644 --- a/Documentation/iio/ad9910.rst +++ b/Documentation/iio/ad9910.rst @@ -85,13 +85,13 @@ system clock (SYSCLK) which affects all other channels. - ``drg_rising_frequency`` - ``drg_frequency`` - DRG frequency rising-ramp parameters: limit code, dwell enable, - ramp clock, rate of change. + ramp clock, rate of change, integration time. =20 * - ``out_frequency132`` - ``drg_falling_frequency`` - ``drg_frequency`` - DRG frequency falling-ramp parameters: limit code, dwell enable, - ramp clock, rate of change. + ramp clock, rate of change, integration time. =20 * - ``out_phase130`` - ``drg_phase`` @@ -104,13 +104,13 @@ system clock (SYSCLK) which affects all other channel= s. - ``drg_rising_phase`` - ``drg_phase`` - DRG phase rising-ramp parameters: limit code, dwell enable, ramp cl= ock, - rate of change. + rate of change, integration time. =20 * - ``out_phase132`` - ``drg_falling_phase`` - ``drg_phase`` - DRG phase falling-ramp parameters: limit code, dwell enable, ramp c= lock, - rate of change. + rate of change, integration time. =20 * - ``out_altcurrent130`` - ``drg_amplitude`` @@ -123,13 +123,13 @@ system clock (SYSCLK) which affects all other channel= s. - ``drg_rising_amplitude`` - ``drg_amplitude`` - DRG amplitude rising-ramp parameters: limit code, dwell enable, - ramp clock, rate of change. + ramp clock, rate of change, integration time. =20 * - ``out_altcurrent132`` - ``drg_falling_amplitude`` - ``drg_amplitude`` - DRG amplitude falling-ramp parameters: limit code, dwell enable, - ramp clock, rate of change. + ramp clock, rate of change, integration time. =20 * - ``out_altcurrent140`` - ``ram`` @@ -493,6 +493,60 @@ Ramp channel attributes from the hardware step size and the current ramp clock. Writing requires ``sampling_frequency`` to be configured first. =20 + * - ``integration_time`` + - s + - Time interval assigned to the ramp direction, which is used to gene= rate + the DRCTL pin waveform. See `DRCTL pin control`_. Rising and falling + ramp channels of all destinations share the same underlying value f= or + their respective directions. The written value is adjusted to the + resolution supported by the PWM provider. + +DRCTL pin control +^^^^^^^^^^^^^^^^^ + +The DRCTL pin selects the DRG slope direction: a logic high drives the ramp +towards the upper limit and a logic low drives it towards the lower limit. +When a PWM is assigned to the DRCTL pin (via the ``pwms`` and ``pwm-names`` +devicetree properties), the driver generates the DRCTL waveform from the +``integration_time`` of the rising and falling ramp channels, according to= the +``dwell_en`` configuration: + +.. flat-table:: + :header-rows: 1 + + * - Rising ``dwell_en`` + - Falling ``dwell_en`` + - DRCTL waveform + + * - 1 + - 1 + - DRCTL is held high for the rising ``integration_time`` and then held + low for the falling ``integration_time``. The PWM period is the sum= of + both intervals. If a ramp reaches its limit before its interval + elapses, the output dwells at that limit. + + * - 0 + - 1 + - Sawtooth rising ramp: a new ramp starts at every DRCTL rising edge, + which happens periodically at the rising ``integration_time``. The + falling ``integration_time`` is not used. + + * - 1 + - 0 + - Sawtooth falling ramp: a new ramp starts at every DRCTL falling edg= e, + which happens periodically at the falling ``integration_time``. The + rising ``integration_time`` is not used. + + * - 0 + - 0 + - Bidirectional continuous ramp. DRCTL is not relevant and it is held + low. + +The DRCTL output is disabled when the resulting PWM period is zero, e.g., = when +the relevant ``integration_time`` attributes are set to ``0``. Without a P= WM +assigned to the DRCTL pin, writing to ``integration_time`` fails with +``-EOPNOTSUPP``. + Usage examples ^^^^^^^^^^^^^^ =20 @@ -525,6 +579,30 @@ Configure a frequency sweep from 40 MHz to 60 MHz with= a rate of change of # Enable the DRG with frequency as the destination echo 1 > /sys/bus/iio/devices/iio\:device0/out_frequency130_en =20 +With the same limits and rate of change, each ramp takes 0.8 ms to complet= e. +Configure a PWM-driven triangular sweep that dwells 0.2 ms at each limit: + +.. code-block:: bash + + # Enable dwell on both limits, so DRCTL controls the ramp direction + echo 1 > /sys/bus/iio/devices/iio\:device0/out_frequency131_dwell_en + echo 1 > /sys/bus/iio/devices/iio\:device0/out_frequency132_dwell_en + + # DRCTL high for 1 ms (rising ramp) and low for 1 ms (falling ramp) + echo 0.001 > /sys/bus/iio/devices/iio\:device0/out_frequency131_integrat= ion_time + echo 0.001 > /sys/bus/iio/devices/iio\:device0/out_frequency132_integrat= ion_time + +Configure a rising sawtooth sweep that restarts every 1 ms: + +.. code-block:: bash + + # No dwell at the upper limit: the ramp returns to the lower limit + echo 0 > /sys/bus/iio/devices/iio\:device0/out_frequency131_dwell_en + echo 1 > /sys/bus/iio/devices/iio\:device0/out_frequency132_dwell_en + + # A new rising ramp starts every 1 ms + echo 0.001 > /sys/bus/iio/devices/iio\:device0/out_frequency131_integrat= ion_time + RAM mode -------- =20 --=20 2.43.0