Devicetree
 help / color / mirror / Atom feed
From: Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org>
To: linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
	 linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org,
	 linux-hardening@vger.kernel.org
Cc: Lars-Peter Clausen <lars@metafoo.de>,
	 Michael Hennerich <Michael.Hennerich@analog.com>,
	 Jonathan Cameron <jic23@kernel.org>,
	David Lechner <dlechner@baylibre.com>,
	 Andy Shevchenko <andy@kernel.org>, Rob Herring <robh@kernel.org>,
	 Krzysztof Kozlowski <krzk+dt@kernel.org>,
	 Conor Dooley <conor+dt@kernel.org>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	 Jonathan Corbet <corbet@lwn.net>,
	Shuah Khan <skhan@linuxfoundation.org>,
	 Kees Cook <kees@kernel.org>,
	"Gustavo A. R. Silva" <gustavoars@kernel.org>,
	 Rodrigo Alencar <rodrigo.alencar@analog.com>
Subject: [PATCH RFC v4 08/10] iio: frequency: ad9910: show channel priority in debugfs
Date: Fri, 08 May 2026 18:00:24 +0100	[thread overview]
Message-ID: <20260508-ad9910-iio-driver-v4-8-d26bfd20ee3d@analog.com> (raw)
In-Reply-To: <20260508-ad9910-iio-driver-v4-0-d26bfd20ee3d@analog.com>

From: Rodrigo Alencar <rodrigo.alencar@analog.com>

Expose frequency_source, phase_source and amplitude_source attributes in
debugfs. Those indicate from which channel the specific DDS parameter is
being sourced by returning the its label. The implementation follows the
priority table found in the datasheet.

Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
---
 drivers/iio/frequency/ad9910.c | 171 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 171 insertions(+)

diff --git a/drivers/iio/frequency/ad9910.c b/drivers/iio/frequency/ad9910.c
index 1fdbaba356d7..d8fe88259f22 100644
--- a/drivers/iio/frequency/ad9910.c
+++ b/drivers/iio/frequency/ad9910.c
@@ -2082,6 +2082,170 @@ static int ad9910_setup(struct device *dev, struct ad9910_state *st,
 	return ad9910_io_update(st);
 }
 
+static inline const char *ad9910_frequency_source_get(struct iio_dev *indio_dev)
+{
+	struct ad9910_state *st = iio_priv(indio_dev);
+	bool ram_en, mode_en;
+
+	guard(mutex)(&st->lock);
+
+	/* RAM enabled and data destination is frequency */
+	ram_en = AD9910_RAM_ENABLED(st);
+	if (ram_en && AD9910_DEST_FREQUENCY ==
+		      FIELD_GET(AD9910_CFR1_RAM_PLAYBACK_DEST_MSK,
+				st->reg[AD9910_REG_CFR1].val32))
+		return ad9910_channel_str[AD9910_CHAN_IDX_RAM];
+
+	/* DRG enabled and data destination is frequency */
+	mode_en = FIELD_GET(AD9910_CFR2_DRG_ENABLE_MSK,
+			    st->reg[AD9910_REG_CFR2].val32);
+	if (mode_en && AD9910_DEST_FREQUENCY ==
+		       FIELD_GET(AD9910_CFR2_DRG_DEST_MSK,
+				 st->reg[AD9910_REG_CFR2].val32))
+		return ad9910_channel_str[AD9910_CHAN_IDX_DRG];
+
+	/* Parallel data port enabled and data destination is frequency */
+	mode_en = FIELD_GET(AD9910_CFR2_PARALLEL_DATA_PORT_EN_MSK,
+			    st->reg[AD9910_REG_CFR1].val32);
+	if (mode_en) /* TODO: get destination from backend once it is supported */
+		return ad9910_channel_str[AD9910_CHAN_IDX_PARALLEL_PORT];
+
+	/* FTW: RAM enabled and data destination is phase, amplitude, or polar */
+	if (ram_en)
+		return ad9910_channel_str[AD9910_CHAN_IDX_RAM];
+
+	/* single tone profiles */
+	return ad9910_channel_str[AD9910_CHAN_IDX_PROFILE_0 + st->profile];
+}
+
+static int ad9910_frequency_source_show(struct file *file, char __user *userbuf,
+					size_t count, loff_t *ppos)
+{
+	struct iio_dev *indio_dev = file->private_data;
+	const char *src = ad9910_frequency_source_get(indio_dev);
+
+	return simple_read_from_buffer(userbuf, count, ppos, src, strlen(src));
+}
+
+static inline const char *ad9910_phase_source_get(struct iio_dev *indio_dev)
+{
+	struct ad9910_state *st = iio_priv(indio_dev);
+	bool ram_en, mode_en;
+	u32 destination;
+
+	guard(mutex)(&st->lock);
+
+	/* RAM enabled and data destination is phase or polar  */
+	ram_en = AD9910_RAM_ENABLED(st);
+	if (ram_en) {
+		destination = FIELD_GET(AD9910_CFR1_RAM_PLAYBACK_DEST_MSK,
+					st->reg[AD9910_REG_CFR1].val32);
+		if (destination == AD9910_DEST_PHASE ||
+		    destination == AD9910_DEST_POLAR)
+			return ad9910_channel_str[AD9910_CHAN_IDX_RAM];
+	}
+
+	/* DRG enabled and data destination is phase */
+	mode_en = FIELD_GET(AD9910_CFR2_DRG_ENABLE_MSK,
+			    st->reg[AD9910_REG_CFR2].val32);
+	if (mode_en && AD9910_DEST_PHASE ==
+		       FIELD_GET(AD9910_CFR2_DRG_DEST_MSK,
+				 st->reg[AD9910_REG_CFR2].val32))
+		return ad9910_channel_str[AD9910_CHAN_IDX_DRG];
+
+	/* Parallel data port enabled and data destination is phase */
+	mode_en = FIELD_GET(AD9910_CFR2_PARALLEL_DATA_PORT_EN_MSK,
+			    st->reg[AD9910_REG_CFR1].val32);
+	if (mode_en) /* TODO: get destination from backend once it is supported */
+		return ad9910_channel_str[AD9910_CHAN_IDX_PARALLEL_PORT];
+
+	/* POW: RAM enabled and data destination is frequency, amplitude, or polar */
+	if (ram_en)
+		return ad9910_channel_str[AD9910_CHAN_IDX_RAM];
+
+	/* single tone profiles */
+	return ad9910_channel_str[AD9910_CHAN_IDX_PROFILE_0 + st->profile];
+}
+
+static int ad9910_phase_source_show(struct file *file, char __user *userbuf,
+				    size_t count, loff_t *ppos)
+{
+	struct iio_dev *indio_dev = file->private_data;
+	const char *src = ad9910_phase_source_get(indio_dev);
+
+	return simple_read_from_buffer(userbuf, count, ppos, src, strlen(src));
+}
+
+static inline const char *ad9910_amplitude_source_get(struct iio_dev *indio_dev)
+{
+	struct ad9910_state *st = iio_priv(indio_dev);
+	bool ram_en, mode_en;
+	u32 destination;
+
+	guard(mutex)(&st->lock);
+
+	/* OSK enabled */
+	mode_en = FIELD_GET(AD9910_CFR1_OSK_ENABLE_MSK,
+			    st->reg[AD9910_REG_CFR2].val32);
+	if (mode_en)
+		return ad9910_channel_str[AD9910_CHAN_IDX_OSK];
+
+	/* RAM enabled and data destination is amplitude or polar */
+	ram_en = AD9910_RAM_ENABLED(st);
+	if (ram_en) {
+		destination = FIELD_GET(AD9910_CFR1_RAM_PLAYBACK_DEST_MSK,
+					st->reg[AD9910_REG_CFR1].val32);
+		if (destination == AD9910_DEST_AMPLITUDE ||
+		    destination == AD9910_DEST_POLAR)
+			return ad9910_channel_str[AD9910_CHAN_IDX_RAM];
+	}
+
+	/* DRG enabled and data destination is amplitude */
+	mode_en = FIELD_GET(AD9910_CFR2_DRG_ENABLE_MSK,
+			    st->reg[AD9910_REG_CFR2].val32);
+	if (mode_en && AD9910_DEST_AMPLITUDE ==
+		       FIELD_GET(AD9910_CFR2_DRG_DEST_MSK,
+				 st->reg[AD9910_REG_CFR2].val32))
+		return ad9910_channel_str[AD9910_CHAN_IDX_DRG];
+
+	/* Parallel data port enabled and data destination is phase */
+	mode_en = FIELD_GET(AD9910_CFR2_PARALLEL_DATA_PORT_EN_MSK,
+			    st->reg[AD9910_REG_CFR1].val32);
+	if (mode_en) /* TODO: get destination from backend once it is supported */
+		return ad9910_channel_str[AD9910_CHAN_IDX_PARALLEL_PORT];
+
+	/* only way to control amplitude at this point is through OSK */
+	if (ram_en)
+		return ad9910_channel_str[AD9910_CHAN_IDX_OSK];
+
+	/* single tone profiles */
+	return ad9910_channel_str[AD9910_CHAN_IDX_PROFILE_0 + st->profile];
+}
+
+static int ad9910_amplitude_source_show(struct file *file, char __user *userbuf,
+					size_t count, loff_t *ppos)
+{
+	struct iio_dev *indio_dev = file->private_data;
+	const char *src = ad9910_amplitude_source_get(indio_dev);
+
+	return simple_read_from_buffer(userbuf, count, ppos, src, strlen(src));
+}
+
+static const struct file_operations ad9910_frequency_source_fops = {
+	.owner = THIS_MODULE,
+	.read = ad9910_frequency_source_show,
+};
+
+static const struct file_operations ad9910_phase_source_fops = {
+	.owner = THIS_MODULE,
+	.read = ad9910_phase_source_show,
+};
+
+static const struct file_operations ad9910_amplitude_source_fops = {
+	.owner = THIS_MODULE,
+	.read = ad9910_amplitude_source_show,
+};
+
 static inline void ad9910_debugfs_init(struct ad9910_state *st,
 				       struct iio_dev *indio_dev)
 {
@@ -2097,6 +2261,13 @@ static inline void ad9910_debugfs_init(struct ad9910_state *st,
 
 	snprintf(buf, sizeof(buf), "/sys/class/firmware/%s/data", st->ram_fwu_name);
 	debugfs_create_symlink("ram_data", d, buf);
+
+	debugfs_create_file("frequency_source", 0400, d, indio_dev,
+			    &ad9910_frequency_source_fops);
+	debugfs_create_file("phase_source", 0400, d, indio_dev,
+			    &ad9910_phase_source_fops);
+	debugfs_create_file("amplitude_source", 0400, d, indio_dev,
+			    &ad9910_amplitude_source_fops);
 }
 
 static int ad9910_probe(struct spi_device *spi)

-- 
2.43.0



  parent reply	other threads:[~2026-05-08 17:00 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-08 17:00 [PATCH RFC v4 00/10] AD9910 Direct Digital Synthesizer Rodrigo Alencar via B4 Relay
2026-05-08 17:00 ` [PATCH RFC v4 01/10] dt-bindings: iio: frequency: add ad9910 Rodrigo Alencar via B4 Relay
2026-05-08 22:02   ` sashiko-bot
2026-05-08 17:00 ` [PATCH RFC v4 02/10] iio: core: support 64-bit register through debugfs Rodrigo Alencar via B4 Relay
2026-05-08 22:20   ` sashiko-bot
2026-05-10 10:07   ` Andy Shevchenko
2026-05-08 17:00 ` [PATCH RFC v4 03/10] iio: frequency: ad9910: initial driver implementation Rodrigo Alencar via B4 Relay
2026-05-08 22:51   ` sashiko-bot
2026-05-08 17:00 ` [PATCH RFC v4 04/10] iio: frequency: ad9910: add basic parallel port support Rodrigo Alencar via B4 Relay
2026-05-08 23:19   ` sashiko-bot
2026-05-08 17:00 ` [PATCH RFC v4 05/10] iio: frequency: ad9910: add digital ramp generator support Rodrigo Alencar via B4 Relay
2026-05-08 23:53   ` sashiko-bot
2026-05-08 17:00 ` [PATCH RFC v4 06/10] iio: frequency: ad9910: add RAM mode support Rodrigo Alencar via B4 Relay
2026-05-09  0:33   ` sashiko-bot
2026-05-08 17:00 ` [PATCH RFC v4 07/10] iio: frequency: ad9910: add output shift keying support Rodrigo Alencar via B4 Relay
2026-05-09  1:08   ` sashiko-bot
2026-05-08 17:00 ` Rodrigo Alencar via B4 Relay [this message]
2026-05-09  1:49   ` [PATCH RFC v4 08/10] iio: frequency: ad9910: show channel priority in debugfs sashiko-bot
2026-05-08 17:00 ` [PATCH RFC v4 09/10] Documentation: ABI: testing: add docs for ad9910 sysfs entries Rodrigo Alencar via B4 Relay
2026-05-09  1:24   ` sashiko-bot
2026-05-08 17:00 ` [PATCH RFC v4 10/10] docs: iio: add documentation for ad9910 driver Rodrigo Alencar via B4 Relay
2026-05-09  1:21   ` sashiko-bot
2026-05-09 23:42   ` David Lechner
2026-05-10  9:30     ` Rodrigo Alencar
2026-05-09 22:31 ` [PATCH RFC v4 00/10] AD9910 Direct Digital Synthesizer David Lechner
2026-05-10  8:50   ` Rodrigo Alencar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260508-ad9910-iio-driver-v4-8-d26bfd20ee3d@analog.com \
    --to=devnull+rodrigo.alencar.analog.com@kernel.org \
    --cc=Michael.Hennerich@analog.com \
    --cc=andy@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=corbet@lwn.net \
    --cc=devicetree@vger.kernel.org \
    --cc=dlechner@baylibre.com \
    --cc=gustavoars@kernel.org \
    --cc=jic23@kernel.org \
    --cc=kees@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=lars@metafoo.de \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=p.zabel@pengutronix.de \
    --cc=robh@kernel.org \
    --cc=rodrigo.alencar@analog.com \
    --cc=skhan@linuxfoundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox