All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC v4 10/10] docs: iio: add documentation for ad9910 driver
  2026-05-08 17:00 [PATCH RFC v4 00/10] AD9910 Direct Digital Synthesizer Rodrigo Alencar
@ 2026-05-08 17:00   ` Rodrigo Alencar via B4 Relay
  0 siblings, 0 replies; 11+ messages in thread
From: Rodrigo Alencar @ 2026-05-08 17:00 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-kernel, linux-doc, linux-hardening
  Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
	David Lechner, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Jonathan Corbet, Shuah Khan,
	Kees Cook, Gustavo A. R. Silva, Rodrigo Alencar

Add documentation for the AD9910 DDS IIO driver, which describes channels,
DDS modes, attributes and ABI usage examples.

Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
---
 Documentation/iio/ad9910.rst | 607 +++++++++++++++++++++++++++++++++++++++++++
 Documentation/iio/index.rst  |   1 +
 MAINTAINERS                  |   1 +
 3 files changed, 609 insertions(+)

diff --git a/Documentation/iio/ad9910.rst b/Documentation/iio/ad9910.rst
new file mode 100644
index 000000000000..7c5dad054d5f
--- /dev/null
+++ b/Documentation/iio/ad9910.rst
@@ -0,0 +1,607 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+=============
+AD9910 driver
+=============
+
+Direct Digital Synthesizer (DDS) driver for the Analog Devices Inc. AD9910.
+The module name is ``ad9910``.
+
+* `AD9910 <https://www.analog.com/en/products/ad9910.html>`_
+
+The AD9910 is a 1 GSPS DDS with a 14-bit DAC, controlled over SPI. The driver
+exposes the device through the IIO ``altvoltage`` channel type and supports
+five DDS operating modes: single tone, parallel port modulation, digital ramp
+generation (DRG), RAM playback and output shift keying (OSK). The device has
+8 hardware profiles, each capable of storing independent single tone and RAM
+playback parameters.
+
+
+Channel hierarchy
+=================
+
+The driver exposes the following IIO output channels, each identified by a
+unique channel number and a human-readable label:
+
+* ``out_altvoltage100``: ``phy``: Physical output: system clock and profile control
+
+  * ``out_altvoltage101``: ``profile[0]``: Single tone control for profile 0:
+    frequency, phase, amplitude
+
+  * ``out_altvoltage102``: ``profile[1]``: Single tone control for profile 1:
+    frequency, phase, amplitude
+
+  * ``out_altvoltage103``: ``profile[2]``: Single tone control for profile 2:
+    frequency, phase, amplitude
+
+  * ``out_altvoltage104``: ``profile[3]``: Single tone control for profile 3:
+    frequency, phase, amplitude
+
+  * ``out_altvoltage105``: ``profile[4]``: Single tone control for profile 4:
+    frequency, phase, amplitude
+
+  * ``out_altvoltage106``: ``profile[5]``: Single tone control for profile 5:
+    frequency, phase, amplitude
+
+  * ``out_altvoltage107``: ``profile[6]``: Single tone control for profile 6:
+    frequency, phase, amplitude
+
+  * ``out_altvoltage108``: ``profile[7]``: Single tone control for profile 7:
+    frequency, phase, amplitude
+
+  * ``out_altvoltage110``: ``parallel_port``: Parallel port modulation channel
+
+  * ``out_altvoltage120``: ``digital_ramp_generator``: DRG control: enable
+
+    * ``out_altvoltage121``: ``digital_ramp_up``: DRG ramp-up parameters:
+      dwell enable, limits, rate of change, ramp rate
+    * ``out_altvoltage122``: ``digital_ramp_down``: DRG ramp-down parameters:
+      dwell enable, limits, rate of change, ramp rate
+
+  * ``out_altvoltage130``: ``ram_control``: RAM playback: enable, frequency,
+    phase and sampling frequency for active profile. Other configurations are
+    provided through a firmware upload interface.
+
+  * ``out_altvoltage150``: ``output_shift_keying``: OSK: enable, amplitude
+    scale, ramp rate, rate of change control
+
+The ``phy`` channel is the root of the hierarchy. Changing its
+``sampling_frequency`` reconfigures the system clock (SYSCLK) which affects all
+other channels.
+
+Most of the mode-specific channels (single-tone, DRG, RAM, OSK) have an
+``enable`` attribute that turns the mode on/off.
+
+DDS modes
+=========
+
+The AD9910 supports multiple modes of operation that can be configured
+independently or in combination. Such modes and their corresponding IIO channels
+are described in this section. Each DDS core parameter (frequency, phase and
+amplitude) value can come from different sources, but only one is active at a
+time. This activation depends on a priority list, which is based on the enable
+and destination configurations for such modes. The following tables are
+extracted from the AD9910 datasheet and summarizes the control parameters for
+each mode and their priority when multiple sources are enabled simultaneously:
+
+.. flat-table:: DDS Frequency Control
+   :header-rows: 1
+
+   * - Priority
+     - Data Source
+     - Conditions
+
+   * - Highest Priority
+     - RAM
+     - RAM enabled and data destination is frequency
+
+   * -
+     - DRG
+     - DRG enabled and data destination is frequency
+
+   * -
+     - Parallel data and FTW (frequency_offset)
+     - Parallel data port enabled and data destination is frequency
+
+   * -
+     - FTW register (frequency)
+     - RAM enabled and data destination is not frequency
+
+   * - Lowest Priority
+     - FTW (frequency) in single tone channel for the active profile
+     - All other cases
+
+.. flat-table:: DDS Phase Control
+   :header-rows: 1
+
+   * - Priority
+     - Data Source
+     - Conditions
+
+   * - Highest Priority
+     - RAM
+     - RAM enabled and data destination is phase or polar
+
+   * -
+     - DRG
+     - DRG enabled and data destination is phase
+
+   * -
+     - Parallel data port
+     - Parallel data port enabled and data destination is phase
+
+   * -
+     - Parallel data port and POW register LSBs (phase_offset)
+     - Parallel data port enabled and data destination is polar
+
+   * -
+     - POW register (phase)
+     - RAM enabled and destination is not phase nor polar
+
+   * - Lowest Priority
+     - POW (phase) in single tone channel for the active profile
+     - All other cases
+
+.. flat-table:: DDS Amplitude Control
+   :header-rows: 1
+
+   * - Priority
+     - Data Source
+     - Conditions
+
+   * - Highest Priority
+     - ASF register and OSK generator
+     - OSK enabled
+
+   * -
+     - RAM
+     - RAM enabled and data destination is amplitude or polar
+
+   * -
+     - DRG
+     - DRG enabled and data destination is amplitude
+
+   * -
+     - Parallel data port
+     - Parallel data port enabled and data destination is amplitude
+
+   * -
+     - Parallel data port and ASF register LSBs (scale_offset)
+     - Parallel data port enabled and data destination is polar
+
+   * - Lowest Priority
+     - ASF (scale) in single tone channel for the active profile
+     - (Amplitude scale is already enabled by default)
+
+While debugging or testing, the debug attributes ``frequency_source``,
+``phase_source`` and ``amplitude_source`` can be used to read the label of
+the channel that is actively controlling the correspondent DDS parameter,
+which reflects the priority list described above.
+
+Single Tone mode
+----------------
+
+Single tone is the baseline operating mode. The ``profile[Y]`` channels
+provides enable, frequency, phase and amplitude control:
+
+.. flat-table::
+   :header-rows: 1
+
+   * - Attribute
+     - Unit
+     - Description
+
+   * - ``en``
+     - boolean (0 or 1)
+     - Enable/disable profile Y. Only one profile can be active at a
+       time. Then enabling a profile disables the current active profile.
+       Disabling an active profile brings the device to a powered down state.
+
+   * - ``frequency``
+     - Hz
+     - Output frequency. Range :math:`[0, f_{SYSCLK}/2)`. Stored in the
+       profile's frequency tuning word (FTW).
+
+   * - ``phase``
+     - rad
+     - Phase offset. Range :math:`[0, 2\pi)`. Stored in the profile's phase
+       offset word (POW).
+
+   * - ``scale``
+     - fractional
+     - Amplitude scale factor. Range :math:`[0, 1]`. Stored in the profile's
+       amplitude scale factor (ASF).
+
+Profile switching is allowed while RAM mode is enabled. In that case single tone
+parameters are stored in a shadow register and are not written to hardware until
+RAM mode is disabled.
+
+Usage examples
+^^^^^^^^^^^^^^
+
+Configure a 100 MHz tone in profile to 2 and set it as the active profile:
+
+.. code-block:: bash
+
+  echo 100000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage103_frequency
+  echo 0.5 > /sys/bus/iio/devices/iio:device0/out_altvoltage103_scale
+  echo 0 > /sys/bus/iio/devices/iio:device0/out_altvoltage103_phase
+
+  # Activate profile 2
+  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage103_en
+
+Read back the current single tone frequency:
+
+.. code-block:: bash
+
+  cat /sys/bus/iio/devices/iio:device0/out_altvoltage103_frequency
+
+Parallel Port mode
+------------------
+
+The parallel port allows real-time modulation of DDS parameters through a
+16-bit external data bus.
+
+.. flat-table::
+   :header-rows: 1
+
+   * - Attribute
+     - Unit
+     - Description
+
+   * - ``frequency_scale``
+     - power-of-2
+     - FM gain multiplier applied to 16-bit parallel input. Range :math:`[1, 32768]`,
+       must be a power of 2.
+
+   * - ``frequency_offset``
+     - Hz
+     - Base FTW to which scaled parallel data is added. Range :math:`[0, f_{SYSCLK}/2)`.
+
+   * - ``phase_offset``
+     - rad
+     - Base phase for polar modulation. Lower 8 bits of POW register.
+       Range :math:`[0, 2\pi/256)`.
+
+   * - ``scale_offset``
+     - fractional
+     - Base amplitude for polar modulation. Lower 6 bits of ASF register.
+       Range :math:`[0, 1/256)`.
+
+Usage examples
+^^^^^^^^^^^^^^
+
+Set parallel port frequency modulation with a scale of 16 and a 50 MHz
+offset:
+
+.. code-block:: bash
+
+  echo 16 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_scale
+  echo 50000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_offset
+
+Digital ramp generator (DRG)
+----------------------------
+
+The DRG produces linear frequency, phase or amplitude sweeps using dedicated
+hardware. It is controlled through three channels: a parent control channel
+(``digital_ramp_generator``) and two child ramp channels
+(``digital_ramp_up``, ``digital_ramp_down``). DRG destination is set when
+ramp attributes are written, i.e. writing to ``frequency`` or ``frequency_roc``
+sets the destination to frequency.
+
+Control channel attributes
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. flat-table::
+   :header-rows: 1
+
+   * - Attribute
+     - Unit
+     - Description
+
+   * - ``en``
+     - boolean
+     - Enable/disable the DRG.
+
+Ramp channel attributes
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``digital_ramp_up`` and ``digital_ramp_down`` channels share the same
+attribute set but configure ascending and descending ramp parameters
+independently:
+
+.. flat-table::
+   :header-rows: 1
+
+   * - Attribute
+     - Unit
+     - Description
+
+   * - ``dwell_en``
+     - boolean
+     - Enable dwell at the ramp limit. When disabled, the ramp auto-transitions
+       at this limit without waiting for the DRCTL pin. Disabling both creates a
+       bidirectional continuous ramp (Triangular pattern). Other configurations
+       create a single-shot ramp at the transition of the DRCTL pin: ramp-up
+       only, ramp-down only or bidirectional with dwell at the limits.
+
+   * - ``frequency``
+     - Hz
+     - Frequency ramp limit. Range: :math:`[0, f_{SYSCLK}/2)`. Writing a value
+       sets the ramp destination to frequency. Reading back returns the
+       currently active frequency limit or -EBUSY if other destination is
+       active (phase or amplitude).
+
+   * - ``phase``
+     - rad
+     - Phase ramp limit. Range: :math:`[0, 2\pi)`. Writing a value sets the
+       ramp destination to phase. Reading back returns the currently active
+       phase limit or -EBUSY if other destination is active (frequency or
+       amplitude).
+
+   * - ``scale``
+     - fractional
+     - Amplitude scale ramp limit. Range: :math:`[0, 1)`. Writing a value sets
+       the ramp destination to amplitude. Reading back returns the currently
+       active scale limit or -EBUSY if other destination is active (frequency
+       or phase).
+
+   * - ``sampling_frequency``
+     - Hz
+     - Ramp clock rate. It is controlled by an integer divider so the requested
+       value will adjust to nearest supported value.
+
+   * - ``frequency_roc``
+     - Hz/s
+     - Frequency rate of change. Sets the per-tick frequency increment/decrement
+       based on the current ramp clock rate.
+
+   * - ``phase_roc``
+     - rad/s
+     - Phase rate of change. Sets the per-tick phase increment/decrement based
+       on the current ramp clock rate.
+
+   * - ``scale_roc``
+     - 1/s
+     - Amplitude scale rate of change. Sets the per-tick amplitude scale
+       increment/decrement based on the current ramp clock rate.
+
+Usage examples
+^^^^^^^^^^^^^^
+
+Configure a frequency sweep from 40 MHz to 60 MHz with a rate of change of
+25 GHz/s:
+
+.. code-block:: bash
+
+  # Disable dwell on both limits for a bidirectional continuous ramp
+  echo 0 > /sys/bus/iio/devices/iio:device0/out_altvoltage121_dwell_en
+  echo 0 > /sys/bus/iio/devices/iio:device0/out_altvoltage122_dwell_en
+
+  # Set ramp limits
+  echo 60000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage121_frequency
+  echo 40000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage122_frequency
+
+  # Set ramp rate
+  echo 25000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage121_sampling_frequency
+  echo 25000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage122_sampling_frequency
+
+  # Set frequency rate of change (Hz/s)
+  echo 25000000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage121_frequency_roc
+  echo 25000000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage122_frequency_roc
+
+  # Enable the DRG
+  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage120_en
+
+RAM mode
+--------
+
+The AD9910 contains a 1024 x 32-bit RAM that can be loaded with waveform data
+and played back to modulate frequency, phase, amplitude, or polar (phase +
+amplitude) parameters.
+
+RAM control channel attributes
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. flat-table::
+   :header-rows: 1
+
+   * - Attribute
+     - Unit
+     - Description
+
+   * - ``en``
+     - boolean
+     - Enable/disable RAM playback. Toggling swaps profile registers between
+       single tone and RAM configurations across all 8 profiles.
+
+   * - ``frequency``
+     - Hz
+     - Frequency tuning word used as the single tone frequency when
+       RAM destination is not ``frequency``. Range: :math:`[0, f_{SYSCLK}/2)`.
+
+   * - ``phase``
+     - rad
+     - Phase offset word used as the single tone phase when RAM destination
+       is not ``phase``. Range: :math:`[0, 2\pi)`.
+
+   * - ``sampling_frequency``
+     - Hz
+     - RAM playback step rate of the active profile, which controls how fast the
+       address counter advances. It is controlled by an integer divider so the
+       requested value will adjust to nearest supported value.
+
+Loading RAM data
+^^^^^^^^^^^^^^^^
+
+RAM data is loaded through the firmware upload framework. The driver registers
+a firmware upload sysfs entry named ``iio_deviceX:ram``. The FW data follows
+a simple binary format:
+
+- 80-byte header:
+
+  - 4-byte big-endian magic word: 0x00AD9910;
+  - 4-byte big-endian CFR1 value: configuration for the CFR1 register. Only
+    bits relevant to RAM mode (data destination and internal profile control)
+    are considered. Other bits are ignored and have no effect:
+
+    - Bits [30:29]: RAM data destination:
+
+      - 00: frequency;
+      - 01: phase;
+      - 10: amplitude;
+      - 11: polar;
+
+    - Bits [20:17]: Internal profile control (see Table 14 of the datasheet);
+
+  - 8 sets of 8-byte big-endian profile data for profiles 0-7. Each set contains:
+
+    - Bits [55:40]: Address step rate value;
+    - Bits [39:30]: End address for the profile;
+    - Bits [23:14]: Start address for the profile;
+    - Bit [5]: no-dwell high for ramp-up mode;
+    - Bit [3]: zero-crossing for direct-switch mode;
+    - Bits [2:0]: operating mode:
+
+      - 000: direct switch;
+      - 001: ramp-up;
+      - 010: bidirectional;
+      - 011: bidirectional continuous;
+      - 100: ramp-up continuous;
+
+  - 4-byte big-endian reserved word: set to 0;
+  - 4-byte big-endian word count: number of 32-bit words to be loaded (0-1024);
+
+- Followed by the specified number of 32-bit big-endian data words.
+
+Usage examples
+^^^^^^^^^^^^^^
+
+Configure RAM mode with firmware data and enable it:
+
+.. code-block:: bash
+
+  # Load RAM data via firmware upload
+  echo 1 > /sys/class/firmware/iio\:device0\:ram/loading
+  cat ad9910-ram.bin > /sys/class/firmware/iio\:device0\:ram/data
+  echo 0 > /sys/class/firmware/iio\:device0\:ram/loading
+
+  # Enable RAM mode
+  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage130_en
+
+Output Shift Keying (OSK)
+-------------------------
+
+OSK controls the output amplitude envelope, allowing the output to be ramped
+on/off rather than switched abruptly.
+
+.. flat-table::
+   :header-rows: 1
+
+   * - Attribute
+     - Unit
+     - Description
+
+   * - ``en``
+     - boolean (0 or 1)
+     - Enable/disable OSK.
+
+   * - ``scale``
+     - fractional
+     - Target amplitude for the OSK ramp. 14-bit ASF field. Range: :math:`[0, 1)`.
+
+   * - ``sampling_frequency``
+     - Hz
+     - OSK ramp rate. It is controlled by an integer divider so the requested
+       value will adjust to nearest supported value.
+
+   * - ``scale_roc``
+     - 1/s
+     - Amplitude scale rate of change. Writing a non-zero value enables
+       automatic OSK and selects the closest hardware step size. Writing ``0``
+       disables automatic ramping (manual control of the ASK register using
+       ``scale``). Writing the maximum available value enables pin-controlled
+       immediate transition with no ramping.
+
+   * - ``scale_roc_available``
+     - 1/s
+     - Lists the available ``scale_roc`` values based on the current
+       ``sampling_frequency``. The first value is always ``0`` (disabled) and
+       the last value corresponds to pin-controlled immediate mode.
+
+Usage examples
+^^^^^^^^^^^^^^
+
+Enable OSK with automatic ramping:
+
+.. code-block:: bash
+
+  # Set ramp rate
+  echo 1000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_sampling_frequency
+
+  # Check available rate of change values
+  cat /sys/bus/iio/devices/iio:device0/out_altvoltage150_scale_roc_available
+
+  # Enable automatic OSK with a rate of change
+  echo 61.035000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_scale_roc
+
+  # Enable OSK
+  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_en
+
+Enable pin-controlled immediate OSK:
+
+.. code-block:: bash
+
+  # Read the last (highest) available value for pin-controlled mode
+  cat /sys/bus/iio/devices/iio:device0/out_altvoltage150_scale_roc_available
+
+  # Enable OSK in manual mode (no rate of change)
+  echo 0 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_scale_roc
+  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_en
+
+  # Set target amplitude to full scale
+  echo 1.0 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_scale
+
+Physical channel
+================
+
+The ``phy`` channel provides device-level control:
+
+.. flat-table::
+   :header-rows: 1
+
+   * - Attribute
+     - Unit
+     - Description
+
+   * - ``sampling_frequency``
+     - Hz
+     - System clock (SYSCLK) frequency. With PLL enabled, configures the PLL
+       multiplier (range 420-1000 MHz). Without PLL, ref clock can only be
+       divided by 2.
+
+   * - ``powerdown``
+     - boolean (0 or 1)
+     - Software power-down. Writing 1 powers down the digital core, DAC,
+       reference clock input and auxiliary DAC simultaneously.
+
+Usage examples
+--------------
+
+Set the system clock to 1 GHz:
+
+.. code-block:: bash
+
+  echo 1000000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage100_sampling_frequency
+
+Read current system clock frequency:
+
+.. code-block:: bash
+
+  cat /sys/bus/iio/devices/iio:device0/out_altvoltage100_sampling_frequency
+
+Power down the device:
+
+.. code-block:: bash
+
+  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage100_powerdown
diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst
index 007e0a1fcc5a..1ada7b460066 100644
--- a/Documentation/iio/index.rst
+++ b/Documentation/iio/index.rst
@@ -30,6 +30,7 @@ Industrial I/O Kernel Drivers
    ad7606
    ad7625
    ad7944
+   ad9910
    ade9000
    adis16475
    adis16480
diff --git a/MAINTAINERS b/MAINTAINERS
index b52c0aae96b7..57bff3d169d5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1645,6 +1645,7 @@ S:	Supported
 W:	https://ez.analog.com/linux-software-drivers
 F:	Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9910
 F:	Documentation/devicetree/bindings/iio/frequency/adi,ad9910.yaml
+F:	Documentation/iio/ad9910.rst
 F:	drivers/iio/frequency/ad9910.c
 
 ANALOG DEVICES INC MAX22007 DRIVER

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH RFC v4 10/10] docs: iio: add documentation for ad9910 driver
@ 2026-05-08 17:00   ` Rodrigo Alencar via B4 Relay
  0 siblings, 0 replies; 11+ messages in thread
From: Rodrigo Alencar via B4 Relay @ 2026-05-08 17:00 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-kernel, linux-doc, linux-hardening
  Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
	David Lechner, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Jonathan Corbet, Shuah Khan,
	Kees Cook, Gustavo A. R. Silva, Rodrigo Alencar

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

Add documentation for the AD9910 DDS IIO driver, which describes channels,
DDS modes, attributes and ABI usage examples.

Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
---
 Documentation/iio/ad9910.rst | 607 +++++++++++++++++++++++++++++++++++++++++++
 Documentation/iio/index.rst  |   1 +
 MAINTAINERS                  |   1 +
 3 files changed, 609 insertions(+)

diff --git a/Documentation/iio/ad9910.rst b/Documentation/iio/ad9910.rst
new file mode 100644
index 000000000000..7c5dad054d5f
--- /dev/null
+++ b/Documentation/iio/ad9910.rst
@@ -0,0 +1,607 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+=============
+AD9910 driver
+=============
+
+Direct Digital Synthesizer (DDS) driver for the Analog Devices Inc. AD9910.
+The module name is ``ad9910``.
+
+* `AD9910 <https://www.analog.com/en/products/ad9910.html>`_
+
+The AD9910 is a 1 GSPS DDS with a 14-bit DAC, controlled over SPI. The driver
+exposes the device through the IIO ``altvoltage`` channel type and supports
+five DDS operating modes: single tone, parallel port modulation, digital ramp
+generation (DRG), RAM playback and output shift keying (OSK). The device has
+8 hardware profiles, each capable of storing independent single tone and RAM
+playback parameters.
+
+
+Channel hierarchy
+=================
+
+The driver exposes the following IIO output channels, each identified by a
+unique channel number and a human-readable label:
+
+* ``out_altvoltage100``: ``phy``: Physical output: system clock and profile control
+
+  * ``out_altvoltage101``: ``profile[0]``: Single tone control for profile 0:
+    frequency, phase, amplitude
+
+  * ``out_altvoltage102``: ``profile[1]``: Single tone control for profile 1:
+    frequency, phase, amplitude
+
+  * ``out_altvoltage103``: ``profile[2]``: Single tone control for profile 2:
+    frequency, phase, amplitude
+
+  * ``out_altvoltage104``: ``profile[3]``: Single tone control for profile 3:
+    frequency, phase, amplitude
+
+  * ``out_altvoltage105``: ``profile[4]``: Single tone control for profile 4:
+    frequency, phase, amplitude
+
+  * ``out_altvoltage106``: ``profile[5]``: Single tone control for profile 5:
+    frequency, phase, amplitude
+
+  * ``out_altvoltage107``: ``profile[6]``: Single tone control for profile 6:
+    frequency, phase, amplitude
+
+  * ``out_altvoltage108``: ``profile[7]``: Single tone control for profile 7:
+    frequency, phase, amplitude
+
+  * ``out_altvoltage110``: ``parallel_port``: Parallel port modulation channel
+
+  * ``out_altvoltage120``: ``digital_ramp_generator``: DRG control: enable
+
+    * ``out_altvoltage121``: ``digital_ramp_up``: DRG ramp-up parameters:
+      dwell enable, limits, rate of change, ramp rate
+    * ``out_altvoltage122``: ``digital_ramp_down``: DRG ramp-down parameters:
+      dwell enable, limits, rate of change, ramp rate
+
+  * ``out_altvoltage130``: ``ram_control``: RAM playback: enable, frequency,
+    phase and sampling frequency for active profile. Other configurations are
+    provided through a firmware upload interface.
+
+  * ``out_altvoltage150``: ``output_shift_keying``: OSK: enable, amplitude
+    scale, ramp rate, rate of change control
+
+The ``phy`` channel is the root of the hierarchy. Changing its
+``sampling_frequency`` reconfigures the system clock (SYSCLK) which affects all
+other channels.
+
+Most of the mode-specific channels (single-tone, DRG, RAM, OSK) have an
+``enable`` attribute that turns the mode on/off.
+
+DDS modes
+=========
+
+The AD9910 supports multiple modes of operation that can be configured
+independently or in combination. Such modes and their corresponding IIO channels
+are described in this section. Each DDS core parameter (frequency, phase and
+amplitude) value can come from different sources, but only one is active at a
+time. This activation depends on a priority list, which is based on the enable
+and destination configurations for such modes. The following tables are
+extracted from the AD9910 datasheet and summarizes the control parameters for
+each mode and their priority when multiple sources are enabled simultaneously:
+
+.. flat-table:: DDS Frequency Control
+   :header-rows: 1
+
+   * - Priority
+     - Data Source
+     - Conditions
+
+   * - Highest Priority
+     - RAM
+     - RAM enabled and data destination is frequency
+
+   * -
+     - DRG
+     - DRG enabled and data destination is frequency
+
+   * -
+     - Parallel data and FTW (frequency_offset)
+     - Parallel data port enabled and data destination is frequency
+
+   * -
+     - FTW register (frequency)
+     - RAM enabled and data destination is not frequency
+
+   * - Lowest Priority
+     - FTW (frequency) in single tone channel for the active profile
+     - All other cases
+
+.. flat-table:: DDS Phase Control
+   :header-rows: 1
+
+   * - Priority
+     - Data Source
+     - Conditions
+
+   * - Highest Priority
+     - RAM
+     - RAM enabled and data destination is phase or polar
+
+   * -
+     - DRG
+     - DRG enabled and data destination is phase
+
+   * -
+     - Parallel data port
+     - Parallel data port enabled and data destination is phase
+
+   * -
+     - Parallel data port and POW register LSBs (phase_offset)
+     - Parallel data port enabled and data destination is polar
+
+   * -
+     - POW register (phase)
+     - RAM enabled and destination is not phase nor polar
+
+   * - Lowest Priority
+     - POW (phase) in single tone channel for the active profile
+     - All other cases
+
+.. flat-table:: DDS Amplitude Control
+   :header-rows: 1
+
+   * - Priority
+     - Data Source
+     - Conditions
+
+   * - Highest Priority
+     - ASF register and OSK generator
+     - OSK enabled
+
+   * -
+     - RAM
+     - RAM enabled and data destination is amplitude or polar
+
+   * -
+     - DRG
+     - DRG enabled and data destination is amplitude
+
+   * -
+     - Parallel data port
+     - Parallel data port enabled and data destination is amplitude
+
+   * -
+     - Parallel data port and ASF register LSBs (scale_offset)
+     - Parallel data port enabled and data destination is polar
+
+   * - Lowest Priority
+     - ASF (scale) in single tone channel for the active profile
+     - (Amplitude scale is already enabled by default)
+
+While debugging or testing, the debug attributes ``frequency_source``,
+``phase_source`` and ``amplitude_source`` can be used to read the label of
+the channel that is actively controlling the correspondent DDS parameter,
+which reflects the priority list described above.
+
+Single Tone mode
+----------------
+
+Single tone is the baseline operating mode. The ``profile[Y]`` channels
+provides enable, frequency, phase and amplitude control:
+
+.. flat-table::
+   :header-rows: 1
+
+   * - Attribute
+     - Unit
+     - Description
+
+   * - ``en``
+     - boolean (0 or 1)
+     - Enable/disable profile Y. Only one profile can be active at a
+       time. Then enabling a profile disables the current active profile.
+       Disabling an active profile brings the device to a powered down state.
+
+   * - ``frequency``
+     - Hz
+     - Output frequency. Range :math:`[0, f_{SYSCLK}/2)`. Stored in the
+       profile's frequency tuning word (FTW).
+
+   * - ``phase``
+     - rad
+     - Phase offset. Range :math:`[0, 2\pi)`. Stored in the profile's phase
+       offset word (POW).
+
+   * - ``scale``
+     - fractional
+     - Amplitude scale factor. Range :math:`[0, 1]`. Stored in the profile's
+       amplitude scale factor (ASF).
+
+Profile switching is allowed while RAM mode is enabled. In that case single tone
+parameters are stored in a shadow register and are not written to hardware until
+RAM mode is disabled.
+
+Usage examples
+^^^^^^^^^^^^^^
+
+Configure a 100 MHz tone in profile to 2 and set it as the active profile:
+
+.. code-block:: bash
+
+  echo 100000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage103_frequency
+  echo 0.5 > /sys/bus/iio/devices/iio:device0/out_altvoltage103_scale
+  echo 0 > /sys/bus/iio/devices/iio:device0/out_altvoltage103_phase
+
+  # Activate profile 2
+  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage103_en
+
+Read back the current single tone frequency:
+
+.. code-block:: bash
+
+  cat /sys/bus/iio/devices/iio:device0/out_altvoltage103_frequency
+
+Parallel Port mode
+------------------
+
+The parallel port allows real-time modulation of DDS parameters through a
+16-bit external data bus.
+
+.. flat-table::
+   :header-rows: 1
+
+   * - Attribute
+     - Unit
+     - Description
+
+   * - ``frequency_scale``
+     - power-of-2
+     - FM gain multiplier applied to 16-bit parallel input. Range :math:`[1, 32768]`,
+       must be a power of 2.
+
+   * - ``frequency_offset``
+     - Hz
+     - Base FTW to which scaled parallel data is added. Range :math:`[0, f_{SYSCLK}/2)`.
+
+   * - ``phase_offset``
+     - rad
+     - Base phase for polar modulation. Lower 8 bits of POW register.
+       Range :math:`[0, 2\pi/256)`.
+
+   * - ``scale_offset``
+     - fractional
+     - Base amplitude for polar modulation. Lower 6 bits of ASF register.
+       Range :math:`[0, 1/256)`.
+
+Usage examples
+^^^^^^^^^^^^^^
+
+Set parallel port frequency modulation with a scale of 16 and a 50 MHz
+offset:
+
+.. code-block:: bash
+
+  echo 16 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_scale
+  echo 50000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_offset
+
+Digital ramp generator (DRG)
+----------------------------
+
+The DRG produces linear frequency, phase or amplitude sweeps using dedicated
+hardware. It is controlled through three channels: a parent control channel
+(``digital_ramp_generator``) and two child ramp channels
+(``digital_ramp_up``, ``digital_ramp_down``). DRG destination is set when
+ramp attributes are written, i.e. writing to ``frequency`` or ``frequency_roc``
+sets the destination to frequency.
+
+Control channel attributes
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. flat-table::
+   :header-rows: 1
+
+   * - Attribute
+     - Unit
+     - Description
+
+   * - ``en``
+     - boolean
+     - Enable/disable the DRG.
+
+Ramp channel attributes
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``digital_ramp_up`` and ``digital_ramp_down`` channels share the same
+attribute set but configure ascending and descending ramp parameters
+independently:
+
+.. flat-table::
+   :header-rows: 1
+
+   * - Attribute
+     - Unit
+     - Description
+
+   * - ``dwell_en``
+     - boolean
+     - Enable dwell at the ramp limit. When disabled, the ramp auto-transitions
+       at this limit without waiting for the DRCTL pin. Disabling both creates a
+       bidirectional continuous ramp (Triangular pattern). Other configurations
+       create a single-shot ramp at the transition of the DRCTL pin: ramp-up
+       only, ramp-down only or bidirectional with dwell at the limits.
+
+   * - ``frequency``
+     - Hz
+     - Frequency ramp limit. Range: :math:`[0, f_{SYSCLK}/2)`. Writing a value
+       sets the ramp destination to frequency. Reading back returns the
+       currently active frequency limit or -EBUSY if other destination is
+       active (phase or amplitude).
+
+   * - ``phase``
+     - rad
+     - Phase ramp limit. Range: :math:`[0, 2\pi)`. Writing a value sets the
+       ramp destination to phase. Reading back returns the currently active
+       phase limit or -EBUSY if other destination is active (frequency or
+       amplitude).
+
+   * - ``scale``
+     - fractional
+     - Amplitude scale ramp limit. Range: :math:`[0, 1)`. Writing a value sets
+       the ramp destination to amplitude. Reading back returns the currently
+       active scale limit or -EBUSY if other destination is active (frequency
+       or phase).
+
+   * - ``sampling_frequency``
+     - Hz
+     - Ramp clock rate. It is controlled by an integer divider so the requested
+       value will adjust to nearest supported value.
+
+   * - ``frequency_roc``
+     - Hz/s
+     - Frequency rate of change. Sets the per-tick frequency increment/decrement
+       based on the current ramp clock rate.
+
+   * - ``phase_roc``
+     - rad/s
+     - Phase rate of change. Sets the per-tick phase increment/decrement based
+       on the current ramp clock rate.
+
+   * - ``scale_roc``
+     - 1/s
+     - Amplitude scale rate of change. Sets the per-tick amplitude scale
+       increment/decrement based on the current ramp clock rate.
+
+Usage examples
+^^^^^^^^^^^^^^
+
+Configure a frequency sweep from 40 MHz to 60 MHz with a rate of change of
+25 GHz/s:
+
+.. code-block:: bash
+
+  # Disable dwell on both limits for a bidirectional continuous ramp
+  echo 0 > /sys/bus/iio/devices/iio:device0/out_altvoltage121_dwell_en
+  echo 0 > /sys/bus/iio/devices/iio:device0/out_altvoltage122_dwell_en
+
+  # Set ramp limits
+  echo 60000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage121_frequency
+  echo 40000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage122_frequency
+
+  # Set ramp rate
+  echo 25000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage121_sampling_frequency
+  echo 25000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage122_sampling_frequency
+
+  # Set frequency rate of change (Hz/s)
+  echo 25000000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage121_frequency_roc
+  echo 25000000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage122_frequency_roc
+
+  # Enable the DRG
+  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage120_en
+
+RAM mode
+--------
+
+The AD9910 contains a 1024 x 32-bit RAM that can be loaded with waveform data
+and played back to modulate frequency, phase, amplitude, or polar (phase +
+amplitude) parameters.
+
+RAM control channel attributes
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. flat-table::
+   :header-rows: 1
+
+   * - Attribute
+     - Unit
+     - Description
+
+   * - ``en``
+     - boolean
+     - Enable/disable RAM playback. Toggling swaps profile registers between
+       single tone and RAM configurations across all 8 profiles.
+
+   * - ``frequency``
+     - Hz
+     - Frequency tuning word used as the single tone frequency when
+       RAM destination is not ``frequency``. Range: :math:`[0, f_{SYSCLK}/2)`.
+
+   * - ``phase``
+     - rad
+     - Phase offset word used as the single tone phase when RAM destination
+       is not ``phase``. Range: :math:`[0, 2\pi)`.
+
+   * - ``sampling_frequency``
+     - Hz
+     - RAM playback step rate of the active profile, which controls how fast the
+       address counter advances. It is controlled by an integer divider so the
+       requested value will adjust to nearest supported value.
+
+Loading RAM data
+^^^^^^^^^^^^^^^^
+
+RAM data is loaded through the firmware upload framework. The driver registers
+a firmware upload sysfs entry named ``iio_deviceX:ram``. The FW data follows
+a simple binary format:
+
+- 80-byte header:
+
+  - 4-byte big-endian magic word: 0x00AD9910;
+  - 4-byte big-endian CFR1 value: configuration for the CFR1 register. Only
+    bits relevant to RAM mode (data destination and internal profile control)
+    are considered. Other bits are ignored and have no effect:
+
+    - Bits [30:29]: RAM data destination:
+
+      - 00: frequency;
+      - 01: phase;
+      - 10: amplitude;
+      - 11: polar;
+
+    - Bits [20:17]: Internal profile control (see Table 14 of the datasheet);
+
+  - 8 sets of 8-byte big-endian profile data for profiles 0-7. Each set contains:
+
+    - Bits [55:40]: Address step rate value;
+    - Bits [39:30]: End address for the profile;
+    - Bits [23:14]: Start address for the profile;
+    - Bit [5]: no-dwell high for ramp-up mode;
+    - Bit [3]: zero-crossing for direct-switch mode;
+    - Bits [2:0]: operating mode:
+
+      - 000: direct switch;
+      - 001: ramp-up;
+      - 010: bidirectional;
+      - 011: bidirectional continuous;
+      - 100: ramp-up continuous;
+
+  - 4-byte big-endian reserved word: set to 0;
+  - 4-byte big-endian word count: number of 32-bit words to be loaded (0-1024);
+
+- Followed by the specified number of 32-bit big-endian data words.
+
+Usage examples
+^^^^^^^^^^^^^^
+
+Configure RAM mode with firmware data and enable it:
+
+.. code-block:: bash
+
+  # Load RAM data via firmware upload
+  echo 1 > /sys/class/firmware/iio\:device0\:ram/loading
+  cat ad9910-ram.bin > /sys/class/firmware/iio\:device0\:ram/data
+  echo 0 > /sys/class/firmware/iio\:device0\:ram/loading
+
+  # Enable RAM mode
+  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage130_en
+
+Output Shift Keying (OSK)
+-------------------------
+
+OSK controls the output amplitude envelope, allowing the output to be ramped
+on/off rather than switched abruptly.
+
+.. flat-table::
+   :header-rows: 1
+
+   * - Attribute
+     - Unit
+     - Description
+
+   * - ``en``
+     - boolean (0 or 1)
+     - Enable/disable OSK.
+
+   * - ``scale``
+     - fractional
+     - Target amplitude for the OSK ramp. 14-bit ASF field. Range: :math:`[0, 1)`.
+
+   * - ``sampling_frequency``
+     - Hz
+     - OSK ramp rate. It is controlled by an integer divider so the requested
+       value will adjust to nearest supported value.
+
+   * - ``scale_roc``
+     - 1/s
+     - Amplitude scale rate of change. Writing a non-zero value enables
+       automatic OSK and selects the closest hardware step size. Writing ``0``
+       disables automatic ramping (manual control of the ASK register using
+       ``scale``). Writing the maximum available value enables pin-controlled
+       immediate transition with no ramping.
+
+   * - ``scale_roc_available``
+     - 1/s
+     - Lists the available ``scale_roc`` values based on the current
+       ``sampling_frequency``. The first value is always ``0`` (disabled) and
+       the last value corresponds to pin-controlled immediate mode.
+
+Usage examples
+^^^^^^^^^^^^^^
+
+Enable OSK with automatic ramping:
+
+.. code-block:: bash
+
+  # Set ramp rate
+  echo 1000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_sampling_frequency
+
+  # Check available rate of change values
+  cat /sys/bus/iio/devices/iio:device0/out_altvoltage150_scale_roc_available
+
+  # Enable automatic OSK with a rate of change
+  echo 61.035000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_scale_roc
+
+  # Enable OSK
+  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_en
+
+Enable pin-controlled immediate OSK:
+
+.. code-block:: bash
+
+  # Read the last (highest) available value for pin-controlled mode
+  cat /sys/bus/iio/devices/iio:device0/out_altvoltage150_scale_roc_available
+
+  # Enable OSK in manual mode (no rate of change)
+  echo 0 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_scale_roc
+  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_en
+
+  # Set target amplitude to full scale
+  echo 1.0 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_scale
+
+Physical channel
+================
+
+The ``phy`` channel provides device-level control:
+
+.. flat-table::
+   :header-rows: 1
+
+   * - Attribute
+     - Unit
+     - Description
+
+   * - ``sampling_frequency``
+     - Hz
+     - System clock (SYSCLK) frequency. With PLL enabled, configures the PLL
+       multiplier (range 420-1000 MHz). Without PLL, ref clock can only be
+       divided by 2.
+
+   * - ``powerdown``
+     - boolean (0 or 1)
+     - Software power-down. Writing 1 powers down the digital core, DAC,
+       reference clock input and auxiliary DAC simultaneously.
+
+Usage examples
+--------------
+
+Set the system clock to 1 GHz:
+
+.. code-block:: bash
+
+  echo 1000000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage100_sampling_frequency
+
+Read current system clock frequency:
+
+.. code-block:: bash
+
+  cat /sys/bus/iio/devices/iio:device0/out_altvoltage100_sampling_frequency
+
+Power down the device:
+
+.. code-block:: bash
+
+  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage100_powerdown
diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst
index 007e0a1fcc5a..1ada7b460066 100644
--- a/Documentation/iio/index.rst
+++ b/Documentation/iio/index.rst
@@ -30,6 +30,7 @@ Industrial I/O Kernel Drivers
    ad7606
    ad7625
    ad7944
+   ad9910
    ade9000
    adis16475
    adis16480
diff --git a/MAINTAINERS b/MAINTAINERS
index b52c0aae96b7..57bff3d169d5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1645,6 +1645,7 @@ S:	Supported
 W:	https://ez.analog.com/linux-software-drivers
 F:	Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9910
 F:	Documentation/devicetree/bindings/iio/frequency/adi,ad9910.yaml
+F:	Documentation/iio/ad9910.rst
 F:	drivers/iio/frequency/ad9910.c
 
 ANALOG DEVICES INC MAX22007 DRIVER

-- 
2.43.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC v4 10/10] docs: iio: add documentation for ad9910 driver
  2026-05-08 17:00   ` Rodrigo Alencar via B4 Relay
  (?)
@ 2026-05-09  1:21   ` sashiko-bot
  -1 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-05-09  1:21 UTC (permalink / raw)
  To: Rodrigo Alencar via B4 Relay; +Cc: devicetree, krzk+dt, conor+dt, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The parallel port channel ID used in the usage example does not match the documented channel hierarchy.
--

commit 734cfe5a204649de75b2933d43b7a6c5df484c59
Author: Rodrigo Alencar <rodrigo.alencar@analog.com>

docs: iio: add documentation for ad9910 driver

This commit adds documentation for the AD9910 DDS IIO driver. It describes
the channels, DDS operating modes, attributes, and provides ABI usage
examples.

> diff --git a/Documentation/iio/ad9910.rst b/Documentation/iio/ad9910.rst
> new file mode 100644
> index 0000000000000..7c5dad054d5fa
> --- /dev/null
> +++ b/Documentation/iio/ad9910.rst
[ ... ]
> +  * ``out_altvoltage108``: ``profile[7]``: Single tone control for profile 7:
> +    frequency, phase, amplitude
> +
> +  * ``out_altvoltage110``: ``parallel_port``: Parallel port modulation channel
> +
> +  * ``out_altvoltage120``: ``digital_ramp_generator``: DRG control: enable
[ ... ]
> +Usage examples
> +^^^^^^^^^^^^^^
> +
> +Set parallel port frequency modulation with a scale of 16 and a 50 MHz
> +offset:
> +
> +.. code-block:: bash
> +
> +  echo 16 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_scale
> +  echo 50000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_offset

This isn't a bug, but the parallel port channel ID used in the usage example
does not match the earlier documented channel hierarchy. The example uses
out_altvoltage113, while the hierarchy section documents the parallel port
channel as out_altvoltage110.

Could the example be updated to use out_altvoltage110 to keep the
documentation consistent?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260508-ad9910-iio-driver-v4-0-d26bfd20ee3d@analog.com?part=10

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC v4 10/10] docs: iio: add documentation for ad9910 driver
  2026-05-08 17:00   ` Rodrigo Alencar via B4 Relay
  (?)
  (?)
@ 2026-05-09 23:42   ` David Lechner
  2026-05-10  9:30     ` Rodrigo Alencar
  -1 siblings, 1 reply; 11+ messages in thread
From: David Lechner @ 2026-05-09 23:42 UTC (permalink / raw)
  To: rodrigo.alencar, linux-iio, devicetree, linux-kernel, linux-doc,
	linux-hardening
  Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
	Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Jonathan Corbet, Shuah Khan, Kees Cook,
	Gustavo A. R. Silva

On 5/8/26 12:00 PM, Rodrigo Alencar via B4 Relay wrote:
> From: Rodrigo Alencar <rodrigo.alencar@analog.com>
> 
> Add documentation for the AD9910 DDS IIO driver, which describes channels,
> DDS modes, attributes and ABI usage examples.
> 
> Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
> ---
>  Documentation/iio/ad9910.rst | 607 +++++++++++++++++++++++++++++++++++++++++++
>  Documentation/iio/index.rst  |   1 +
>  MAINTAINERS                  |   1 +
>  3 files changed, 609 insertions(+)
> 
> diff --git a/Documentation/iio/ad9910.rst b/Documentation/iio/ad9910.rst
> new file mode 100644
> index 000000000000..7c5dad054d5f
> --- /dev/null
> +++ b/Documentation/iio/ad9910.rst
> @@ -0,0 +1,607 @@
> +.. SPDX-License-Identifier: GPL-2.0-only
> +
> +=============
> +AD9910 driver
> +=============
> +
> +Direct Digital Synthesizer (DDS) driver for the Analog Devices Inc. AD9910.
> +The module name is ``ad9910``.
> +
> +* `AD9910 <https://www.analog.com/en/products/ad9910.html>`_
> +
> +The AD9910 is a 1 GSPS DDS with a 14-bit DAC, controlled over SPI. The driver
> +exposes the device through the IIO ``altvoltage`` channel type and supports
> +five DDS operating modes: single tone, parallel port modulation, digital ramp
> +generation (DRG), RAM playback and output shift keying (OSK). The device has
> +8 hardware profiles, each capable of storing independent single tone and RAM
> +playback parameters.
> +
> +
> +Channel hierarchy
> +=================
> +
> +The driver exposes the following IIO output channels, each identified by a
> +unique channel number and a human-readable label:
> +

Can we format this as a table with a header to make it clear what each item is?
I'm guessing that the second `` is the label?

And perhaps provide a link to the sections below that describe the common attributes
of each channel type?

> +* ``out_altvoltage100``: ``phy``: Physical output: system clock and profile control

Any attributes on this one?

> +
> +  * ``out_altvoltage101``: ``profile[0]``: Single tone control for profile 0:

Why not just ``profile0``?

Also, why not ``out_altvoltage110`` so that the last digit matches the profile
index? It looks like we are skipping by 10s later anyway.

> +    frequency, phase, amplitude
> +
> +  * ``out_altvoltage102``: ``profile[1]``: Single tone control for profile 1:
> +    frequency, phase, amplitude
> +
> +  * ``out_altvoltage103``: ``profile[2]``: Single tone control for profile 2:
> +    frequency, phase, amplitude
> +
> +  * ``out_altvoltage104``: ``profile[3]``: Single tone control for profile 3:
> +    frequency, phase, amplitude
> +
> +  * ``out_altvoltage105``: ``profile[4]``: Single tone control for profile 4:
> +    frequency, phase, amplitude
> +
> +  * ``out_altvoltage106``: ``profile[5]``: Single tone control for profile 5:
> +    frequency, phase, amplitude
> +
> +  * ``out_altvoltage107``: ``profile[6]``: Single tone control for profile 6:
> +    frequency, phase, amplitude
> +
> +  * ``out_altvoltage108``: ``profile[7]``: Single tone control for profile 7:
> +    frequency, phase, amplitude
> +
> +  * ``out_altvoltage110``: ``parallel_port``: Parallel port modulation channel

I guess no attributes on this one yet since implementation is deferred?

> +
> +  * ``out_altvoltage120``: ``digital_ramp_generator``: DRG control: enable
> +
> +    * ``out_altvoltage121``: ``digital_ramp_up``: DRG ramp-up parameters:
> +      dwell enable, limits, rate of change, ramp rate
> +    * ``out_altvoltage122``: ``digital_ramp_down``: DRG ramp-down parameters:
> +      dwell enable, limits, rate of change, ramp rate

Oh, I guess these are just the general "control knob" name, not the actual
sysfs attribute name.

> +
> +  * ``out_altvoltage130``: ``ram_control``: RAM playback: enable, frequency,
> +    phase and sampling frequency for active profile. Other configurations are
> +    provided through a firmware upload interface.
> +
> +  * ``out_altvoltage150``: ``output_shift_keying``: OSK: enable, amplitude
> +    scale, ramp rate, rate of change control
> +
> +The ``phy`` channel is the root of the hierarchy. Changing its
> +``sampling_frequency`` reconfigures the system clock (SYSCLK) which affects all
> +other channels.
> +
> +Most of the mode-specific channels (single-tone, DRG, RAM, OSK) have an
> +``enable`` attribute that turns the mode on/off.
> +
> +DDS modes
> +=========
> +
> +The AD9910 supports multiple modes of operation that can be configured
> +independently or in combination. Such modes and their corresponding IIO channels
> +are described in this section. Each DDS core parameter (frequency, phase and
> +amplitude) value can come from different sources, but only one is active at a
> +time. This activation depends on a priority list, which is based on the enable
> +and destination configurations for such modes. The following tables are
> +extracted from the AD9910 datasheet and summarizes the control parameters for
> +each mode and their priority when multiple sources are enabled simultaneously:
> +
> +.. flat-table:: DDS Frequency Control
> +   :header-rows: 1
> +
> +   * - Priority
> +     - Data Source
> +     - Conditions
> +
> +   * - Highest Priority
> +     - RAM
> +     - RAM enabled and data destination is frequency
> +
> +   * -
> +     - DRG
> +     - DRG enabled and data destination is frequency
> +
> +   * -
> +     - Parallel data and FTW (frequency_offset)
> +     - Parallel data port enabled and data destination is frequency
> +
> +   * -
> +     - FTW register (frequency)
> +     - RAM enabled and data destination is not frequency
> +
> +   * - Lowest Priority
> +     - FTW (frequency) in single tone channel for the active profile
> +     - All other cases
> +
> +.. flat-table:: DDS Phase Control
> +   :header-rows: 1
> +
> +   * - Priority
> +     - Data Source
> +     - Conditions
> +
> +   * - Highest Priority
> +     - RAM
> +     - RAM enabled and data destination is phase or polar
> +
> +   * -
> +     - DRG
> +     - DRG enabled and data destination is phase
> +
> +   * -
> +     - Parallel data port
> +     - Parallel data port enabled and data destination is phase
> +
> +   * -
> +     - Parallel data port and POW register LSBs (phase_offset)
> +     - Parallel data port enabled and data destination is polar
> +
> +   * -
> +     - POW register (phase)
> +     - RAM enabled and destination is not phase nor polar
> +
> +   * - Lowest Priority
> +     - POW (phase) in single tone channel for the active profile
> +     - All other cases
> +
> +.. flat-table:: DDS Amplitude Control
> +   :header-rows: 1
> +
> +   * - Priority
> +     - Data Source
> +     - Conditions
> +
> +   * - Highest Priority
> +     - ASF register and OSK generator
> +     - OSK enabled
> +
> +   * -
> +     - RAM
> +     - RAM enabled and data destination is amplitude or polar
> +
> +   * -
> +     - DRG
> +     - DRG enabled and data destination is amplitude
> +
> +   * -
> +     - Parallel data port
> +     - Parallel data port enabled and data destination is amplitude
> +
> +   * -
> +     - Parallel data port and ASF register LSBs (scale_offset)
> +     - Parallel data port enabled and data destination is polar
> +
> +   * - Lowest Priority
> +     - ASF (scale) in single tone channel for the active profile
> +     - (Amplitude scale is already enabled by default)
> +
> +While debugging or testing, the debug attributes ``frequency_source``,
> +``phase_source`` and ``amplitude_source`` can be used to read the label of
> +the channel that is actively controlling the correspondent DDS parameter,
> +which reflects the priority list described above.
> +
> +Single Tone mode
> +----------------
> +
> +Single tone is the baseline operating mode. The ``profile[Y]`` channels
> +provides enable, frequency, phase and amplitude control:
> +
> +.. flat-table::
> +   :header-rows: 1
> +
> +   * - Attribute
> +     - Unit
> +     - Description
> +
> +   * - ``en``
> +     - boolean (0 or 1)
> +     - Enable/disable profile Y. Only one profile can be active at a
> +       time. Then enabling a profile disables the current active profile.
> +       Disabling an active profile brings the device to a powered down state.
> +
> +   * - ``frequency``
> +     - Hz
> +     - Output frequency. Range :math:`[0, f_{SYSCLK}/2)`. Stored in the
> +       profile's frequency tuning word (FTW).
> +
> +   * - ``phase``
> +     - rad
> +     - Phase offset. Range :math:`[0, 2\pi)`. Stored in the profile's phase
> +       offset word (POW).
> +
> +   * - ``scale``
> +     - fractional
> +     - Amplitude scale factor. Range :math:`[0, 1]`. Stored in the profile's
> +       amplitude scale factor (ASF).
> +
> +Profile switching is allowed while RAM mode is enabled. In that case single tone
> +parameters are stored in a shadow register and are not written to hardware until
> +RAM mode is disabled.
> +
> +Usage examples
> +^^^^^^^^^^^^^^
> +
> +Configure a 100 MHz tone in profile to 2 and set it as the active profile:
> +
> +.. code-block:: bash
> +
> +  echo 100000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage103_frequency
> +  echo 0.5 > /sys/bus/iio/devices/iio:device0/out_altvoltage103_scale
> +  echo 0 > /sys/bus/iio/devices/iio:device0/out_altvoltage103_phase
> +
> +  # Activate profile 2
> +  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage103_en
> +
> +Read back the current single tone frequency:
> +
> +.. code-block:: bash
> +
> +  cat /sys/bus/iio/devices/iio:device0/out_altvoltage103_frequency
> +
> +Parallel Port mode
> +------------------
> +
> +The parallel port allows real-time modulation of DDS parameters through a
> +16-bit external data bus.
> +
> +.. flat-table::
> +   :header-rows: 1
> +
> +   * - Attribute
> +     - Unit
> +     - Description
> +
> +   * - ``frequency_scale``
> +     - power-of-2
> +     - FM gain multiplier applied to 16-bit parallel input. Range :math:`[1, 32768]`,

General comment for the whole doc. Can you spell out the acronyms the
first time they are used for us noobs.

> +       must be a power of 2.
> +
> +   * - ``frequency_offset``
> +     - Hz
> +     - Base FTW to which scaled parallel data is added. Range :math:`[0, f_{SYSCLK}/2)`.
> +
> +   * - ``phase_offset``
> +     - rad
> +     - Base phase for polar modulation. Lower 8 bits of POW register.
> +       Range :math:`[0, 2\pi/256)`.
> +
> +   * - ``scale_offset``
> +     - fractional
> +     - Base amplitude for polar modulation. Lower 6 bits of ASF register.
> +       Range :math:`[0, 1/256)`.
> +

I guess there was some discussion on these attributes. I see some of these in the
ad9832 driver in staging, but I'm guessing they are new ABI. It isn't clear to
me from the documentation here what they actually do though. I guess they are
just basic transformations on the input signal?

And a practical note, they should be "frequencyscale". I don't like that it is
harder to read, but it is easier for a machine to parse.

> +Usage examples
> +^^^^^^^^^^^^^^
> +
> +Set parallel port frequency modulation with a scale of 16 and a 50 MHz
> +offset:
> +
> +.. code-block:: bash
> +
> +  echo 16 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_scale
> +  echo 50000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_offset
> +
> +Digital ramp generator (DRG)
> +----------------------------
> +
> +The DRG produces linear frequency, phase or amplitude sweeps using dedicated
> +hardware. It is controlled through three channels: a parent control channel
> +(``digital_ramp_generator``) and two child ramp channels
> +(``digital_ramp_up``, ``digital_ramp_down``). DRG destination is set when
> +ramp attributes are written, i.e. writing to ``frequency`` or ``frequency_roc``
> +sets the destination to frequency.

Would it be better to say that the destination is set when the the
value is non-zero? Otherwise, how would one change the destination
once set?

> +
> +Control channel attributes
> +^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +.. flat-table::
> +   :header-rows: 1
> +
> +   * - Attribute
> +     - Unit
> +     - Description
> +
> +   * - ``en``
> +     - boolean
> +     - Enable/disable the DRG.
> +
> +Ramp channel attributes
> +^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +The ``digital_ramp_up`` and ``digital_ramp_down`` channels share the same
> +attribute set but configure ascending and descending ramp parameters
> +independently:
> +
> +.. flat-table::
> +   :header-rows: 1
> +
> +   * - Attribute
> +     - Unit
> +     - Description
> +
> +   * - ``dwell_en``
> +     - boolean
> +     - Enable dwell at the ramp limit. When disabled, the ramp auto-transitions
> +       at this limit without waiting for the DRCTL pin. Disabling both creates a
> +       bidirectional continuous ramp (Triangular pattern). Other configurations
> +       create a single-shot ramp at the transition of the DRCTL pin: ramp-up
> +       only, ramp-down only or bidirectional with dwell at the limits.
> +
> +   * - ``frequency``
> +     - Hz
> +     - Frequency ramp limit. Range: :math:`[0, f_{SYSCLK}/2)`. Writing a value
> +       sets the ramp destination to frequency. Reading back returns the
> +       currently active frequency limit or -EBUSY if other destination is
> +       active (phase or amplitude).
> +
> +   * - ``phase``
> +     - rad
> +     - Phase ramp limit. Range: :math:`[0, 2\pi)`. Writing a value sets the
> +       ramp destination to phase. Reading back returns the currently active
> +       phase limit or -EBUSY if other destination is active (frequency or
> +       amplitude).
> +
> +   * - ``scale``
> +     - fractional
> +     - Amplitude scale ramp limit. Range: :math:`[0, 1)`. Writing a value sets
> +       the ramp destination to amplitude. Reading back returns the currently
> +       active scale limit or -EBUSY if other destination is active (frequency
> +       or phase).
> +
> +   * - ``sampling_frequency``
> +     - Hz
> +     - Ramp clock rate. It is controlled by an integer divider so the requested
> +       value will adjust to nearest supported value.
> +
> +   * - ``frequency_roc``
> +     - Hz/s
> +     - Frequency rate of change. Sets the per-tick frequency increment/decrement
> +       based on the current ramp clock rate.
> +
> +   * - ``phase_roc``
> +     - rad/s
> +     - Phase rate of change. Sets the per-tick phase increment/decrement based
> +       on the current ramp clock rate.
> +
> +   * - ``scale_roc``
> +     - 1/s
> +     - Amplitude scale rate of change. Sets the per-tick amplitude scale
> +       increment/decrement based on the current ramp clock rate.
> +
> +Usage examples
> +^^^^^^^^^^^^^^
> +
> +Configure a frequency sweep from 40 MHz to 60 MHz with a rate of change of
> +25 GHz/s:
> +
> +.. code-block:: bash
> +
> +  # Disable dwell on both limits for a bidirectional continuous ramp
> +  echo 0 > /sys/bus/iio/devices/iio:device0/out_altvoltage121_dwell_en
> +  echo 0 > /sys/bus/iio/devices/iio:device0/out_altvoltage122_dwell_en
> +
> +  # Set ramp limits
> +  echo 60000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage121_frequency
> +  echo 40000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage122_frequency
> +
> +  # Set ramp rate
> +  echo 25000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage121_sampling_frequency
> +  echo 25000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage122_sampling_frequency
> +
> +  # Set frequency rate of change (Hz/s)
> +  echo 25000000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage121_frequency_roc
> +  echo 25000000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage122_frequency_roc
> +
> +  # Enable the DRG
> +  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage120_en
> +
> +RAM mode
> +--------
> +
> +The AD9910 contains a 1024 x 32-bit RAM that can be loaded with waveform data
> +and played back to modulate frequency, phase, amplitude, or polar (phase +
> +amplitude) parameters.
> +
> +RAM control channel attributes
> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +.. flat-table::
> +   :header-rows: 1
> +
> +   * - Attribute
> +     - Unit
> +     - Description
> +
> +   * - ``en``
> +     - boolean
> +     - Enable/disable RAM playback. Toggling swaps profile registers between
> +       single tone and RAM configurations across all 8 profiles.
> +
> +   * - ``frequency``
> +     - Hz
> +     - Frequency tuning word used as the single tone frequency when
> +       RAM destination is not ``frequency``. Range: :math:`[0, f_{SYSCLK}/2)`.
> +
> +   * - ``phase``
> +     - rad
> +     - Phase offset word used as the single tone phase when RAM destination
> +       is not ``phase``. Range: :math:`[0, 2\pi)`.
> +
> +   * - ``sampling_frequency``
> +     - Hz
> +     - RAM playback step rate of the active profile, which controls how fast the
> +       address counter advances. It is controlled by an integer divider so the
> +       requested value will adjust to nearest supported value.
> +
> +Loading RAM data
> +^^^^^^^^^^^^^^^^
> +
> +RAM data is loaded through the firmware upload framework. The driver registers
> +a firmware upload sysfs entry named ``iio_deviceX:ram``. The FW data follows
> +a simple binary format:
> +
> +- 80-byte header:
> +
> +  - 4-byte big-endian magic word: 0x00AD9910;
> +  - 4-byte big-endian CFR1 value: configuration for the CFR1 register. Only
> +    bits relevant to RAM mode (data destination and internal profile control)
> +    are considered. Other bits are ignored and have no effect:
> +
> +    - Bits [30:29]: RAM data destination:
> +
> +      - 00: frequency;
> +      - 01: phase;
> +      - 10: amplitude;
> +      - 11: polar;
> +
> +    - Bits [20:17]: Internal profile control (see Table 14 of the datasheet);
> +
> +  - 8 sets of 8-byte big-endian profile data for profiles 0-7. Each set contains:
> +
> +    - Bits [55:40]: Address step rate value;
> +    - Bits [39:30]: End address for the profile;
> +    - Bits [23:14]: Start address for the profile;
> +    - Bit [5]: no-dwell high for ramp-up mode;
> +    - Bit [3]: zero-crossing for direct-switch mode;
> +    - Bits [2:0]: operating mode:
> +
> +      - 000: direct switch;
> +      - 001: ramp-up;
> +      - 010: bidirectional;
> +      - 011: bidirectional continuous;
> +      - 100: ramp-up continuous;
> +
> +  - 4-byte big-endian reserved word: set to 0;

Will it be enough? :-)

Another option could be to include a file format version field.

> +  - 4-byte big-endian word count: number of 32-bit words to be loaded (0-1024);
> +
> +- Followed by the specified number of 32-bit big-endian data words.
> +
> +Usage examples
> +^^^^^^^^^^^^^^
> +
> +Configure RAM mode with firmware data and enable it:
> +
> +.. code-block:: bash
> +
> +  # Load RAM data via firmware upload
> +  echo 1 > /sys/class/firmware/iio\:device0\:ram/loading
> +  cat ad9910-ram.bin > /sys/class/firmware/iio\:device0\:ram/data
> +  echo 0 > /sys/class/firmware/iio\:device0\:ram/loading
> +
> +  # Enable RAM mode
> +  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage130_en
> +
> +Output Shift Keying (OSK)
> +-------------------------
> +
> +OSK controls the output amplitude envelope, allowing the output to be ramped
> +on/off rather than switched abruptly.
> +
> +.. flat-table::
> +   :header-rows: 1
> +
> +   * - Attribute
> +     - Unit
> +     - Description
> +
> +   * - ``en``
> +     - boolean (0 or 1)
> +     - Enable/disable OSK.
> +
> +   * - ``scale``
> +     - fractional
> +     - Target amplitude for the OSK ramp. 14-bit ASF field. Range: :math:`[0, 1)`.
> +
> +   * - ``sampling_frequency``
> +     - Hz
> +     - OSK ramp rate. It is controlled by an integer divider so the requested
> +       value will adjust to nearest supported value.
> +

Would be more logical to to keep scale attributes together.

> +   * - ``scale_roc``
> +     - 1/s
> +     - Amplitude scale rate of change. Writing a non-zero value enables
> +       automatic OSK and selects the closest hardware step size. Writing ``0``
> +       disables automatic ramping (manual control of the ASK register using
> +       ``scale``). Writing the maximum available value enables pin-controlled
> +       immediate transition with no ramping.
> +
> +   * - ``scale_roc_available``
> +     - 1/s
> +     - Lists the available ``scale_roc`` values based on the current
> +       ``sampling_frequency``. The first value is always ``0`` (disabled) and
> +       the last value corresponds to pin-controlled immediate mode.
> +
> +Usage examples
> +^^^^^^^^^^^^^^
> +
> +Enable OSK with automatic ramping:
> +
> +.. code-block:: bash
> +
> +  # Set ramp rate
> +  echo 1000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_sampling_frequency
> +
> +  # Check available rate of change values
> +  cat /sys/bus/iio/devices/iio:device0/out_altvoltage150_scale_roc_available
> +
> +  # Enable automatic OSK with a rate of change
> +  echo 61.035000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_scale_roc
> +
> +  # Enable OSK
> +  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_en
> +
> +Enable pin-controlled immediate OSK:
> +
> +.. code-block:: bash
> +
> +  # Read the last (highest) available value for pin-controlled mode
> +  cat /sys/bus/iio/devices/iio:device0/out_altvoltage150_scale_roc_available
> +
> +  # Enable OSK in manual mode (no rate of change)
> +  echo 0 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_scale_roc
> +  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_en
> +
> +  # Set target amplitude to full scale
> +  echo 1.0 > /sys/bus/iio/devices/iio:device0/out_altvoltage150_scale
> +
> +Physical channel
> +================
> +
> +The ``phy`` channel provides device-level control:
> +
> +.. flat-table::
> +   :header-rows: 1
> +
> +   * - Attribute
> +     - Unit
> +     - Description
> +
> +   * - ``sampling_frequency``
> +     - Hz
> +     - System clock (SYSCLK) frequency. With PLL enabled, configures the PLL
> +       multiplier (range 420-1000 MHz). Without PLL, ref clock can only be
> +       divided by 2.

What controls the PLL?

> +
> +   * - ``powerdown``
> +     - boolean (0 or 1)
> +     - Software power-down. Writing 1 powers down the digital core, DAC,
> +       reference clock input and auxiliary DAC simultaneously.
> +
> +Usage examples
> +--------------
> +
> +Set the system clock to 1 GHz:
> +
> +.. code-block:: bash
> +
> +  echo 1000000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage100_sampling_frequency
> +
> +Read current system clock frequency:
> +
> +.. code-block:: bash
> +
> +  cat /sys/bus/iio/devices/iio:device0/out_altvoltage100_sampling_frequency
> +
> +Power down the device:
> +
> +.. code-block:: bash
> +
> +  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage100_powerdown
> diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst
> index 007e0a1fcc5a..1ada7b460066 100644
> --- a/Documentation/iio/index.rst
> +++ b/Documentation/iio/index.rst
> @@ -30,6 +30,7 @@ Industrial I/O Kernel Drivers
>     ad7606
>     ad7625
>     ad7944
> +   ad9910
>     ade9000
>     adis16475
>     adis16480
> diff --git a/MAINTAINERS b/MAINTAINERS
> index b52c0aae96b7..57bff3d169d5 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1645,6 +1645,7 @@ S:	Supported
>  W:	https://ez.analog.com/linux-software-drivers
>  F:	Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9910
>  F:	Documentation/devicetree/bindings/iio/frequency/adi,ad9910.yaml
> +F:	Documentation/iio/ad9910.rst
>  F:	drivers/iio/frequency/ad9910.c
>  
>  ANALOG DEVICES INC MAX22007 DRIVER
> 

I like the direction this is going. Looks sensible to me.

I didn't have time to read the code, so just going off of the docs for now.



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC v4 10/10] docs: iio: add documentation for ad9910 driver
  2026-05-09 23:42   ` David Lechner
@ 2026-05-10  9:30     ` Rodrigo Alencar
  2026-05-11 14:46       ` David Lechner
  0 siblings, 1 reply; 11+ messages in thread
From: Rodrigo Alencar @ 2026-05-10  9:30 UTC (permalink / raw)
  To: David Lechner, rodrigo.alencar, linux-iio, devicetree,
	linux-kernel, linux-doc, linux-hardening
  Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
	Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Jonathan Corbet, Shuah Khan, Kees Cook,
	Gustavo A. R. Silva

On 26/05/09 06:42PM, David Lechner wrote:
> On 5/8/26 12:00 PM, Rodrigo Alencar via B4 Relay wrote:
> > From: Rodrigo Alencar <rodrigo.alencar@analog.com>
> > 
> > Add documentation for the AD9910 DDS IIO driver, which describes channels,
> > DDS modes, attributes and ABI usage examples.

...

> > +Channel hierarchy
> > +=================
> > +
> > +The driver exposes the following IIO output channels, each identified by a
> > +unique channel number and a human-readable label:
> > +
> 
> Can we format this as a table with a header to make it clear what each item is?
> I'm guessing that the second `` is the label?
> 
> And perhaps provide a link to the sections below that describe the common attributes
> of each channel type?

Yes, that is a label. A table is better indeed.
 
> > +* ``out_altvoltage100``: ``phy``: Physical output: system clock and profile control
> 
> Any attributes on this one?
> 
> > +
> > +  * ``out_altvoltage101``: ``profile[0]``: Single tone control for profile 0:
> 
> Why not just ``profile0``?
> 
> Also, why not ``out_altvoltage110`` so that the last digit matches the profile
> index? It looks like we are skipping by 10s later anyway.

Yeah, that can be done. I thought of out_altvoltage110 being a channel to hold common
things between profiles, but it ended up empty so I left the spot as a placeholder.

> > +    frequency, phase, amplitude
> > +
> > +  * ``out_altvoltage102``: ``profile[1]``: Single tone control for profile 1:
> > +    frequency, phase, amplitude
> > +
> > +  * ``out_altvoltage103``: ``profile[2]``: Single tone control for profile 2:
> > +    frequency, phase, amplitude
> > +
> > +  * ``out_altvoltage104``: ``profile[3]``: Single tone control for profile 3:
> > +    frequency, phase, amplitude
> > +
> > +  * ``out_altvoltage105``: ``profile[4]``: Single tone control for profile 4:
> > +    frequency, phase, amplitude
> > +
> > +  * ``out_altvoltage106``: ``profile[5]``: Single tone control for profile 5:
> > +    frequency, phase, amplitude
> > +
> > +  * ``out_altvoltage107``: ``profile[6]``: Single tone control for profile 6:
> > +    frequency, phase, amplitude
> > +
> > +  * ``out_altvoltage108``: ``profile[7]``: Single tone control for profile 7:
> > +    frequency, phase, amplitude
> > +
> > +  * ``out_altvoltage110``: ``parallel_port``: Parallel port modulation channel
> 
> I guess no attributes on this one yet since implementation is deferred?

Only basic knobs will be exposed, proper implementation will come with a later backend
support.

> > +
> > +  * ``out_altvoltage120``: ``digital_ramp_generator``: DRG control: enable
> > +
> > +    * ``out_altvoltage121``: ``digital_ramp_up``: DRG ramp-up parameters:
> > +      dwell enable, limits, rate of change, ramp rate
> > +    * ``out_altvoltage122``: ``digital_ramp_down``: DRG ramp-down parameters:
> > +      dwell enable, limits, rate of change, ramp rate
> 
> Oh, I guess these are just the general "control knob" name, not the actual
> sysfs attribute name.

Correct, just a description.

> 
> > +
> > +  * ``out_altvoltage130``: ``ram_control``: RAM playback: enable, frequency,
> > +    phase and sampling frequency for active profile. Other configurations are
> > +    provided through a firmware upload interface.
> > +
> > +  * ``out_altvoltage150``: ``output_shift_keying``: OSK: enable, amplitude
> > +    scale, ramp rate, rate of change control
> > +
> > +The ``phy`` channel is the root of the hierarchy. Changing its
> > +``sampling_frequency`` reconfigures the system clock (SYSCLK) which affects all
> > +other channels.
> > +
> > +Most of the mode-specific channels (single-tone, DRG, RAM, OSK) have an
> > +``enable`` attribute that turns the mode on/off.
> > +

...

> > +Parallel Port mode
> > +------------------
> > +
> > +The parallel port allows real-time modulation of DDS parameters through a
> > +16-bit external data bus.
> > +
> > +.. flat-table::
> > +   :header-rows: 1
> > +
> > +   * - Attribute
> > +     - Unit
> > +     - Description
> > +
> > +   * - ``frequency_scale``
> > +     - power-of-2
> > +     - FM gain multiplier applied to 16-bit parallel input. Range :math:`[1, 32768]`,
> 
> General comment for the whole doc. Can you spell out the acronyms the
> first time they are used for us noobs.
> 
> > +       must be a power of 2.
> > +
> > +   * - ``frequency_offset``
> > +     - Hz
> > +     - Base FTW to which scaled parallel data is added. Range :math:`[0, f_{SYSCLK}/2)`.
> > +
> > +   * - ``phase_offset``
> > +     - rad
> > +     - Base phase for polar modulation. Lower 8 bits of POW register.
> > +       Range :math:`[0, 2\pi/256)`.
> > +
> > +   * - ``scale_offset``
> > +     - fractional
> > +     - Base amplitude for polar modulation. Lower 6 bits of ASF register.
> > +       Range :math:`[0, 1/256)`.
> > +
> 
> I guess there was some discussion on these attributes. I see some of these in the
> ad9832 driver in staging, but I'm guessing they are new ABI. It isn't clear to
> me from the documentation here what they actually do though. I guess they are
> just basic transformations on the input signal?

Not sure how the ABI is not clear:

	For a channel that allows amplitude control through buffers, this
	represents the value for a base amplitude scale. The actual output
	amplitude scale is a result with the sum of this value.

So yes, it is a basic transformation.

> 
> And a practical note, they should be "frequencyscale". I don't like that it is
> harder to read, but it is easier for a machine to parse.

Parsers like the ones in libiio is not having problems with that.

> > +Usage examples
> > +^^^^^^^^^^^^^^
> > +
> > +Set parallel port frequency modulation with a scale of 16 and a 50 MHz
> > +offset:
> > +
> > +.. code-block:: bash
> > +
> > +  echo 16 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_scale
> > +  echo 50000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_offset
> > +
> > +Digital ramp generator (DRG)
> > +----------------------------
> > +
> > +The DRG produces linear frequency, phase or amplitude sweeps using dedicated
> > +hardware. It is controlled through three channels: a parent control channel
> > +(``digital_ramp_generator``) and two child ramp channels
> > +(``digital_ramp_up``, ``digital_ramp_down``). DRG destination is set when
> > +ramp attributes are written, i.e. writing to ``frequency`` or ``frequency_roc``
> > +sets the destination to frequency.
> 
> Would it be better to say that the destination is set when the the
> value is non-zero? Otherwise, how would one change the destination
> once set?

Destination is only one, so you just need to write phase or phase_roc, if you want
to target phase then. Does that not sound intuitive?

Zero is a valid value to be written.

> 
> > +
> > +Control channel attributes
> > +^^^^^^^^^^^^^^^^^^^^^^^^^^
> > +
> > +.. flat-table::
> > +   :header-rows: 1
> > +
> > +   * - Attribute
> > +     - Unit
> > +     - Description
> > +
> > +   * - ``en``
> > +     - boolean
> > +     - Enable/disable the DRG.
> > +
> > +Ramp channel attributes
> > +^^^^^^^^^^^^^^^^^^^^^^^^
> > +
> > +The ``digital_ramp_up`` and ``digital_ramp_down`` channels share the same
> > +attribute set but configure ascending and descending ramp parameters
> > +independently:
> > +
> > +.. flat-table::
> > +   :header-rows: 1
> > +
> > +   * - Attribute
> > +     - Unit
> > +     - Description
> > +
> > +   * - ``dwell_en``
> > +     - boolean
> > +     - Enable dwell at the ramp limit. When disabled, the ramp auto-transitions
> > +       at this limit without waiting for the DRCTL pin. Disabling both creates a
> > +       bidirectional continuous ramp (Triangular pattern). Other configurations
> > +       create a single-shot ramp at the transition of the DRCTL pin: ramp-up
> > +       only, ramp-down only or bidirectional with dwell at the limits.
> > +
> > +   * - ``frequency``
> > +     - Hz
> > +     - Frequency ramp limit. Range: :math:`[0, f_{SYSCLK}/2)`. Writing a value
> > +       sets the ramp destination to frequency. Reading back returns the
> > +       currently active frequency limit or -EBUSY if other destination is
> > +       active (phase or amplitude).
> > +
> > +   * - ``phase``
> > +     - rad
> > +     - Phase ramp limit. Range: :math:`[0, 2\pi)`. Writing a value sets the
> > +       ramp destination to phase. Reading back returns the currently active
> > +       phase limit or -EBUSY if other destination is active (frequency or
> > +       amplitude).
> > +
> > +   * - ``scale``
> > +     - fractional
> > +     - Amplitude scale ramp limit. Range: :math:`[0, 1)`. Writing a value sets
> > +       the ramp destination to amplitude. Reading back returns the currently
> > +       active scale limit or -EBUSY if other destination is active (frequency
> > +       or phase).
> > +
> > +   * - ``sampling_frequency``
> > +     - Hz
> > +     - Ramp clock rate. It is controlled by an integer divider so the requested
> > +       value will adjust to nearest supported value.
> > +
> > +   * - ``frequency_roc``
> > +     - Hz/s
> > +     - Frequency rate of change. Sets the per-tick frequency increment/decrement
> > +       based on the current ramp clock rate.
> > +
> > +   * - ``phase_roc``
> > +     - rad/s
> > +     - Phase rate of change. Sets the per-tick phase increment/decrement based
> > +       on the current ramp clock rate.
> > +
> > +   * - ``scale_roc``
> > +     - 1/s
> > +     - Amplitude scale rate of change. Sets the per-tick amplitude scale
> > +       increment/decrement based on the current ramp clock rate.
> > +
> > +Usage examples
> > +^^^^^^^^^^^^^^
> > +
> > +Configure a frequency sweep from 40 MHz to 60 MHz with a rate of change of
> > +25 GHz/s:
> > +
> > +.. code-block:: bash
> > +
> > +  # Disable dwell on both limits for a bidirectional continuous ramp
> > +  echo 0 > /sys/bus/iio/devices/iio:device0/out_altvoltage121_dwell_en
> > +  echo 0 > /sys/bus/iio/devices/iio:device0/out_altvoltage122_dwell_en
> > +
> > +  # Set ramp limits
> > +  echo 60000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage121_frequency
> > +  echo 40000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage122_frequency
> > +
> > +  # Set ramp rate
> > +  echo 25000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage121_sampling_frequency
> > +  echo 25000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage122_sampling_frequency
> > +
> > +  # Set frequency rate of change (Hz/s)
> > +  echo 25000000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage121_frequency_roc
> > +  echo 25000000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage122_frequency_roc
> > +
> > +  # Enable the DRG
> > +  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage120_en
> > +
> > +RAM mode
> > +--------
> > +
> > +The AD9910 contains a 1024 x 32-bit RAM that can be loaded with waveform data
> > +and played back to modulate frequency, phase, amplitude, or polar (phase +
> > +amplitude) parameters.
> > +
> > +RAM control channel attributes
> > +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > +
> > +.. flat-table::
> > +   :header-rows: 1
> > +
> > +   * - Attribute
> > +     - Unit
> > +     - Description
> > +
> > +   * - ``en``
> > +     - boolean
> > +     - Enable/disable RAM playback. Toggling swaps profile registers between
> > +       single tone and RAM configurations across all 8 profiles.
> > +
> > +   * - ``frequency``
> > +     - Hz
> > +     - Frequency tuning word used as the single tone frequency when
> > +       RAM destination is not ``frequency``. Range: :math:`[0, f_{SYSCLK}/2)`.
> > +
> > +   * - ``phase``
> > +     - rad
> > +     - Phase offset word used as the single tone phase when RAM destination
> > +       is not ``phase``. Range: :math:`[0, 2\pi)`.
> > +
> > +   * - ``sampling_frequency``
> > +     - Hz
> > +     - RAM playback step rate of the active profile, which controls how fast the
> > +       address counter advances. It is controlled by an integer divider so the
> > +       requested value will adjust to nearest supported value.
> > +
> > +Loading RAM data
> > +^^^^^^^^^^^^^^^^
> > +
> > +RAM data is loaded through the firmware upload framework. The driver registers
> > +a firmware upload sysfs entry named ``iio_deviceX:ram``. The FW data follows
> > +a simple binary format:
> > +
> > +- 80-byte header:
> > +
> > +  - 4-byte big-endian magic word: 0x00AD9910;
> > +  - 4-byte big-endian CFR1 value: configuration for the CFR1 register. Only
> > +    bits relevant to RAM mode (data destination and internal profile control)
> > +    are considered. Other bits are ignored and have no effect:
> > +
> > +    - Bits [30:29]: RAM data destination:
> > +
> > +      - 00: frequency;
> > +      - 01: phase;
> > +      - 10: amplitude;
> > +      - 11: polar;
> > +
> > +    - Bits [20:17]: Internal profile control (see Table 14 of the datasheet);
> > +
> > +  - 8 sets of 8-byte big-endian profile data for profiles 0-7. Each set contains:
> > +
> > +    - Bits [55:40]: Address step rate value;
> > +    - Bits [39:30]: End address for the profile;
> > +    - Bits [23:14]: Start address for the profile;
> > +    - Bit [5]: no-dwell high for ramp-up mode;
> > +    - Bit [3]: zero-crossing for direct-switch mode;
> > +    - Bits [2:0]: operating mode:
> > +
> > +      - 000: direct switch;
> > +      - 001: ramp-up;
> > +      - 010: bidirectional;
> > +      - 011: bidirectional continuous;
> > +      - 100: ramp-up continuous;
> > +
> > +  - 4-byte big-endian reserved word: set to 0;
> 
> Will it be enough? :-)
> 
> Another option could be to include a file format version field.

Yeah, maybe a CRC and a version as you pointed out. In terms of RAM functionality,
that would be all. Maybe a table for this one too...

> > +  - 4-byte big-endian word count: number of 32-bit words to be loaded (0-1024);
> > +
> > +- Followed by the specified number of 32-bit big-endian data words.
> > +
> > +Usage examples
> > +^^^^^^^^^^^^^^
> > +
> > +Configure RAM mode with firmware data and enable it:
> > +
> > +.. code-block:: bash
> > +
> > +  # Load RAM data via firmware upload
> > +  echo 1 > /sys/class/firmware/iio\:device0\:ram/loading
> > +  cat ad9910-ram.bin > /sys/class/firmware/iio\:device0\:ram/data
> > +  echo 0 > /sys/class/firmware/iio\:device0\:ram/loading
> > +
> > +  # Enable RAM mode
> > +  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage130_en
> > +

...

> > +Physical channel
> > +================
> > +
> > +The ``phy`` channel provides device-level control:
> > +
> > +.. flat-table::
> > +   :header-rows: 1
> > +
> > +   * - Attribute
> > +     - Unit
> > +     - Description
> > +
> > +   * - ``sampling_frequency``
> > +     - Hz
> > +     - System clock (SYSCLK) frequency. With PLL enabled, configures the PLL
> > +       multiplier (range 420-1000 MHz). Without PLL, ref clock can only be
> > +       divided by 2.
> 
> What controls the PLL?

It gets enabled in the device-tree. One would want that when feeding a lower clock rate
source as a reference clock. It would also need a loop-filter connected to the device.

This property can be used to configure the desired sysclk frequency, the PLL divider/multiplier
and VCO configs will be derived from that. 

> > +
> > +   * - ``powerdown``
> > +     - boolean (0 or 1)
> > +     - Software power-down. Writing 1 powers down the digital core, DAC,
> > +       reference clock input and auxiliary DAC simultaneously.
> > +

...

> 
> I like the direction this is going. Looks sensible to me.
> 
> I didn't have time to read the code, so just going off of the docs for now.

Thanks for the review. The code would need some cleanup after the ABI is mature.
Also, sashiko is pointing out a lot of issues already.. so those I suppose I can
handle on my own for now. 

-- 
Kind regards,

Rodrigo Alencar

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC v4 10/10] docs: iio: add documentation for ad9910 driver
@ 2026-05-10 12:01 kernel test robot
  0 siblings, 0 replies; 11+ messages in thread
From: kernel test robot @ 2026-05-10 12:01 UTC (permalink / raw)
  To: oe-kbuild; +Cc: lkp

:::::: 
:::::: Manual check reason: "dtcheck: binding changes may go via different trees"
:::::: 

BCC: lkp@intel.com
CC: oe-kbuild-all@lists.linux.dev
In-Reply-To: <20260508-ad9910-iio-driver-v4-10-d26bfd20ee3d@analog.com>
References: <20260508-ad9910-iio-driver-v4-10-d26bfd20ee3d@analog.com>
TO: Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org>

Hi Rodrigo,

[This is a private test report for your RFC patch.]
kernel test robot noticed the following build warnings:

[auto build test WARNING on 9e62a5d329f8f0f07c4d5f80a691e3f16dcb957c]

url:    https://github.com/intel-lab-lkp/linux/commits/Rodrigo-Alencar-via-B4-Relay/dt-bindings-iio-frequency-add-ad9910/20260510-101220
base:   9e62a5d329f8f0f07c4d5f80a691e3f16dcb957c
patch link:    https://lore.kernel.org/r/20260508-ad9910-iio-driver-v4-10-d26bfd20ee3d%40analog.com
patch subject: [PATCH RFC v4 10/10] docs: iio: add documentation for ad9910 driver
:::::: branch date: 10 hours ago
:::::: commit date: 10 hours ago
config: csky-randconfig-2052-20260510 (https://download.01.org/0day-ci/archive/20260510/202605101422.M9fU9TGG-lkp@intel.com/config)
compiler: csky-linux-gcc (GCC) 15.1.0
dtschema: 2026.5.dev4+g4ccc1997d
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260510/202605101422.M9fU9TGG-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/r/202605101422.M9fU9TGG-lkp@intel.com/

dtcheck warnings: (new ones prefixed by >>)
>> Documentation/devicetree/bindings/iio/frequency/adi,ad9910.yaml:148:28: [warning] too few spaces after comma (commas)

vim +148 Documentation/devicetree/bindings/iio/frequency/adi,ad9910.yaml

6c18b7a7132552 Rodrigo Alencar 2026-05-08    8  
6c18b7a7132552 Rodrigo Alencar 2026-05-08    9  maintainers:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   10    - Rodrigo Alencar <rodrigo.alencar@analog.com>
6c18b7a7132552 Rodrigo Alencar 2026-05-08   11  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   12  description:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   13    The AD9910 is a 1 GSPS direct digital synthesizer (DDS) with an integrated
6c18b7a7132552 Rodrigo Alencar 2026-05-08   14    14-bit DAC. It features single tone mode with 8 configurable profiles,
6c18b7a7132552 Rodrigo Alencar 2026-05-08   15    a digital ramp generator, RAM control, OSK, and a parallel data port for
6c18b7a7132552 Rodrigo Alencar 2026-05-08   16    high-speed streaming.
6c18b7a7132552 Rodrigo Alencar 2026-05-08   17  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   18    https://www.analog.com/en/products/ad9910.html
6c18b7a7132552 Rodrigo Alencar 2026-05-08   19  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   20  properties:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   21    compatible:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   22      const: adi,ad9910
6c18b7a7132552 Rodrigo Alencar 2026-05-08   23  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   24    reg:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   25      maxItems: 1
6c18b7a7132552 Rodrigo Alencar 2026-05-08   26  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   27    spi-max-frequency:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   28      maximum: 70000000
6c18b7a7132552 Rodrigo Alencar 2026-05-08   29  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   30    clocks:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   31      minItems: 1
6c18b7a7132552 Rodrigo Alencar 2026-05-08   32      items:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   33        - description: Reference clock (REF_CLK).
6c18b7a7132552 Rodrigo Alencar 2026-05-08   34        - description: Optional synchronization clock (SYNC_IN).
6c18b7a7132552 Rodrigo Alencar 2026-05-08   35  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   36    clock-names:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   37      oneOf:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   38        - items:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   39            - const: ref_clk
6c18b7a7132552 Rodrigo Alencar 2026-05-08   40        - items:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   41            - const: ref_clk
6c18b7a7132552 Rodrigo Alencar 2026-05-08   42            - const: sync_in
6c18b7a7132552 Rodrigo Alencar 2026-05-08   43  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   44    '#clock-cells':
6c18b7a7132552 Rodrigo Alencar 2026-05-08   45      const: 1
6c18b7a7132552 Rodrigo Alencar 2026-05-08   46  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   47    clock-output-names:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   48      minItems: 1
6c18b7a7132552 Rodrigo Alencar 2026-05-08   49      maxItems: 3
6c18b7a7132552 Rodrigo Alencar 2026-05-08   50      items:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   51        enum: [ sync_clk, pdclk, sync_out ]
6c18b7a7132552 Rodrigo Alencar 2026-05-08   52  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   53    interrupts:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   54      minItems: 1
6c18b7a7132552 Rodrigo Alencar 2026-05-08   55      items:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   56        - description:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   57            Signal that indicates that Digital Ramp Generator has reached a limit.
6c18b7a7132552 Rodrigo Alencar 2026-05-08   58        - description:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   59            Signal that indicates the end of a RAM Sweep.
6c18b7a7132552 Rodrigo Alencar 2026-05-08   60  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   61    interrupt-names:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   62      minItems: 1
6c18b7a7132552 Rodrigo Alencar 2026-05-08   63      maxItems: 2
6c18b7a7132552 Rodrigo Alencar 2026-05-08   64      items:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   65        enum: [ drover, ram_swp_ovr ]
6c18b7a7132552 Rodrigo Alencar 2026-05-08   66  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   67    dvdd-io33-supply:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   68      description: 3.3V Digital I/O supply.
6c18b7a7132552 Rodrigo Alencar 2026-05-08   69  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   70    avdd33-supply:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   71      description: 3.3V Analog DAC supply.
6c18b7a7132552 Rodrigo Alencar 2026-05-08   72  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   73    dvdd18-supply:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   74      description: 1.8V Digital Core supply.
6c18b7a7132552 Rodrigo Alencar 2026-05-08   75  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   76    avdd18-supply:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   77      description: 1.8V Analog Core supply.
6c18b7a7132552 Rodrigo Alencar 2026-05-08   78  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   79    reset-gpios:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   80      description:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   81        GPIOs controlling the Main Device reset.
6c18b7a7132552 Rodrigo Alencar 2026-05-08   82  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   83    io-reset-gpios:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   84      maxItems: 1
6c18b7a7132552 Rodrigo Alencar 2026-05-08   85      description:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   86        GPIO controlling the I/O_RESET pin.
6c18b7a7132552 Rodrigo Alencar 2026-05-08   87  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   88    powerdown-gpios:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   89      maxItems: 1
6c18b7a7132552 Rodrigo Alencar 2026-05-08   90      description:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   91        GPIO controlling the EXT_PWR_DWN pin.
6c18b7a7132552 Rodrigo Alencar 2026-05-08   92  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   93    update-gpios:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   94      maxItems: 1
6c18b7a7132552 Rodrigo Alencar 2026-05-08   95      description:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   96        GPIO controlling the I/O_UPDATE pin.
6c18b7a7132552 Rodrigo Alencar 2026-05-08   97  
6c18b7a7132552 Rodrigo Alencar 2026-05-08   98    profile-gpios:
6c18b7a7132552 Rodrigo Alencar 2026-05-08   99      minItems: 3
6c18b7a7132552 Rodrigo Alencar 2026-05-08  100      maxItems: 3
6c18b7a7132552 Rodrigo Alencar 2026-05-08  101      description:
6c18b7a7132552 Rodrigo Alencar 2026-05-08  102        GPIOs controlling the PROFILE[2:0] pins for profile selection.
6c18b7a7132552 Rodrigo Alencar 2026-05-08  103  
6c18b7a7132552 Rodrigo Alencar 2026-05-08  104    sync-err-gpios:
6c18b7a7132552 Rodrigo Alencar 2026-05-08  105      maxItems: 1
6c18b7a7132552 Rodrigo Alencar 2026-05-08  106      description:
6c18b7a7132552 Rodrigo Alencar 2026-05-08  107        GPIO used to read SYNC_SMP_ERR pin status.
6c18b7a7132552 Rodrigo Alencar 2026-05-08  108  
6c18b7a7132552 Rodrigo Alencar 2026-05-08  109    lock-detect-gpios:
6c18b7a7132552 Rodrigo Alencar 2026-05-08  110      maxItems: 1
6c18b7a7132552 Rodrigo Alencar 2026-05-08  111      description:
6c18b7a7132552 Rodrigo Alencar 2026-05-08  112        GPIO used to read PLL_LOCK pin status.
6c18b7a7132552 Rodrigo Alencar 2026-05-08  113  
6c18b7a7132552 Rodrigo Alencar 2026-05-08  114    adi,pll-enable:
6c18b7a7132552 Rodrigo Alencar 2026-05-08  115      type: boolean
6c18b7a7132552 Rodrigo Alencar 2026-05-08  116      description:
6c18b7a7132552 Rodrigo Alencar 2026-05-08  117        Indicates that a loop filter is connected and the internal PLL is enabled.
6c18b7a7132552 Rodrigo Alencar 2026-05-08  118        Often used when the reference clock is provided by a crystal or by a
6c18b7a7132552 Rodrigo Alencar 2026-05-08  119        single-ended on-board oscillator.
6c18b7a7132552 Rodrigo Alencar 2026-05-08  120  
6c18b7a7132552 Rodrigo Alencar 2026-05-08  121    adi,charge-pump-current-microamp:
6c18b7a7132552 Rodrigo Alencar 2026-05-08  122      minimum: 212
6c18b7a7132552 Rodrigo Alencar 2026-05-08  123      maximum: 387
6c18b7a7132552 Rodrigo Alencar 2026-05-08  124      default: 212
6c18b7a7132552 Rodrigo Alencar 2026-05-08  125      description:
6c18b7a7132552 Rodrigo Alencar 2026-05-08  126        PLL charge pump current in microamps. Only applicable when the internal
6c18b7a7132552 Rodrigo Alencar 2026-05-08  127        PLL is enabled. The value is rounded to the nearest supported step. This
6c18b7a7132552 Rodrigo Alencar 2026-05-08  128        value depends mostly on the loop filter design.
6c18b7a7132552 Rodrigo Alencar 2026-05-08  129  
6c18b7a7132552 Rodrigo Alencar 2026-05-08  130    adi,refclk-out-drive-strength:
6c18b7a7132552 Rodrigo Alencar 2026-05-08  131      $ref: /schemas/types.yaml#/definitions/string
6c18b7a7132552 Rodrigo Alencar 2026-05-08  132      enum: [ disabled, low, medium, high ]
6c18b7a7132552 Rodrigo Alencar 2026-05-08  133      default: disabled
6c18b7a7132552 Rodrigo Alencar 2026-05-08  134      description:
6c18b7a7132552 Rodrigo Alencar 2026-05-08  135        Reference clock output (DRV0) drive strength. Only applicable when
6c18b7a7132552 Rodrigo Alencar 2026-05-08  136        the internal PLL is enabled.
6c18b7a7132552 Rodrigo Alencar 2026-05-08  137  
6c18b7a7132552 Rodrigo Alencar 2026-05-08  138    adi,dac-output-current-microamp:
6c18b7a7132552 Rodrigo Alencar 2026-05-08  139      minimum: 8640
6c18b7a7132552 Rodrigo Alencar 2026-05-08  140      maximum: 31590
6c18b7a7132552 Rodrigo Alencar 2026-05-08  141      default: 20070
6c18b7a7132552 Rodrigo Alencar 2026-05-08  142      description:
6c18b7a7132552 Rodrigo Alencar 2026-05-08  143        DAC full-scale output current in microamps.
6c18b7a7132552 Rodrigo Alencar 2026-05-08  144  
6c18b7a7132552 Rodrigo Alencar 2026-05-08  145  dependencies:
6c18b7a7132552 Rodrigo Alencar 2026-05-08  146    adi,charge-pump-current-microamp: [ 'adi,pll-enable' ]
6c18b7a7132552 Rodrigo Alencar 2026-05-08  147    adi,refclk-out-drive-strength: [ 'adi,pll-enable' ]
6c18b7a7132552 Rodrigo Alencar 2026-05-08 @148    lock-detect-gpios: [ adi,pll-enable ]
6c18b7a7132552 Rodrigo Alencar 2026-05-08  149    interrupts: [ interrupt-names ]
6c18b7a7132552 Rodrigo Alencar 2026-05-08  150    clocks: [ clock-names ]
6c18b7a7132552 Rodrigo Alencar 2026-05-08  151    '#clock-cells': [ clock-output-names ]
6c18b7a7132552 Rodrigo Alencar 2026-05-08  152  
6c18b7a7132552 Rodrigo Alencar 2026-05-08  153  required:
6c18b7a7132552 Rodrigo Alencar 2026-05-08  154    - compatible
6c18b7a7132552 Rodrigo Alencar 2026-05-08  155    - reg
6c18b7a7132552 Rodrigo Alencar 2026-05-08  156    - clocks
6c18b7a7132552 Rodrigo Alencar 2026-05-08  157    - dvdd-io33-supply
6c18b7a7132552 Rodrigo Alencar 2026-05-08  158    - avdd33-supply
6c18b7a7132552 Rodrigo Alencar 2026-05-08  159    - dvdd18-supply
6c18b7a7132552 Rodrigo Alencar 2026-05-08  160    - avdd18-supply
6c18b7a7132552 Rodrigo Alencar 2026-05-08  161  
6c18b7a7132552 Rodrigo Alencar 2026-05-08  162  allOf:
6c18b7a7132552 Rodrigo Alencar 2026-05-08  163    - $ref: /schemas/spi/spi-peripheral-props.yaml#
6c18b7a7132552 Rodrigo Alencar 2026-05-08  164  

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC v4 10/10] docs: iio: add documentation for ad9910 driver
  2026-05-10  9:30     ` Rodrigo Alencar
@ 2026-05-11 14:46       ` David Lechner
  2026-05-11 15:02         ` Rodrigo Alencar
  0 siblings, 1 reply; 11+ messages in thread
From: David Lechner @ 2026-05-11 14:46 UTC (permalink / raw)
  To: Rodrigo Alencar, rodrigo.alencar, linux-iio, devicetree,
	linux-kernel, linux-doc, linux-hardening
  Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
	Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Jonathan Corbet, Shuah Khan, Kees Cook,
	Gustavo A. R. Silva

On 5/10/26 4:30 AM, Rodrigo Alencar wrote:
> On 26/05/09 06:42PM, David Lechner wrote:
>> On 5/8/26 12:00 PM, Rodrigo Alencar via B4 Relay wrote:
>>> From: Rodrigo Alencar <rodrigo.alencar@analog.com>
>>>
>>> Add documentation for the AD9910 DDS IIO driver, which describes channels,
>>> DDS modes, attributes and ABI usage examples.
> 
> ...
> 
>>> +       must be a power of 2.
>>> +
>>> +   * - ``frequency_offset``
>>> +     - Hz
>>> +     - Base FTW to which scaled parallel data is added. Range :math:`[0, f_{SYSCLK}/2)`.
>>> +
>>> +   * - ``phase_offset``
>>> +     - rad
>>> +     - Base phase for polar modulation. Lower 8 bits of POW register.
>>> +       Range :math:`[0, 2\pi/256)`.
>>> +
>>> +   * - ``scale_offset``
>>> +     - fractional
>>> +     - Base amplitude for polar modulation. Lower 6 bits of ASF register.
>>> +       Range :math:`[0, 1/256)`.
>>> +
>>
>> I guess there was some discussion on these attributes. I see some of these in the
>> ad9832 driver in staging, but I'm guessing they are new ABI. It isn't clear to
>> me from the documentation here what they actually do though. I guess they are
>> just basic transformations on the input signal?
> 
> Not sure how the ABI is not clear:
> 
> 	For a channel that allows amplitude control through buffers, this
> 	represents the value for a base amplitude scale. The actual output
> 	amplitude scale is a result with the sum of this value.
> 
> So yes, it is a basic transformation.

I didn't have time to read the ABI docs yet. For scale_offset though,
how is that different from the existing offset attribute?

> 
>>
>> And a practical note, they should be "frequencyscale". I don't like that it is
>> harder to read, but it is easier for a machine to parse.
> 
> Parsers like the ones in libiio is not having problems with that.
> 
>>> +Usage examples
>>> +^^^^^^^^^^^^^^
>>> +
>>> +Set parallel port frequency modulation with a scale of 16 and a 50 MHz
>>> +offset:
>>> +
>>> +.. code-block:: bash
>>> +
>>> +  echo 16 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_scale
>>> +  echo 50000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_offset
>>> +
>>> +Digital ramp generator (DRG)
>>> +----------------------------
>>> +
>>> +The DRG produces linear frequency, phase or amplitude sweeps using dedicated
>>> +hardware. It is controlled through three channels: a parent control channel
>>> +(``digital_ramp_generator``) and two child ramp channels
>>> +(``digital_ramp_up``, ``digital_ramp_down``). DRG destination is set when
>>> +ramp attributes are written, i.e. writing to ``frequency`` or ``frequency_roc``
>>> +sets the destination to frequency.
>>
>> Would it be better to say that the destination is set when the the
>> value is non-zero? Otherwise, how would one change the destination
>> once set?
> 
> Destination is only one, so you just need to write phase or phase_roc, if you want
> to target phase then. Does that not sound intuitive?

I was thinking about if you needed to change the configuration.
If you set it to phase, then want to change it to frequency, how
could you do that if 0 is a valid value for phase?

Also how could you know which is selected by reading back the
values if 0 is a valid value?

> 
> Zero is a valid value to be written.
> 
>>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC v4 10/10] docs: iio: add documentation for ad9910 driver
  2026-05-11 14:46       ` David Lechner
@ 2026-05-11 15:02         ` Rodrigo Alencar
  2026-05-11 15:23           ` David Lechner
  0 siblings, 1 reply; 11+ messages in thread
From: Rodrigo Alencar @ 2026-05-11 15:02 UTC (permalink / raw)
  To: David Lechner, Rodrigo Alencar, rodrigo.alencar, linux-iio,
	devicetree, linux-kernel, linux-doc, linux-hardening
  Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
	Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Jonathan Corbet, Shuah Khan, Kees Cook,
	Gustavo A. R. Silva

On 26/05/11 09:46AM, David Lechner wrote:
> On 5/10/26 4:30 AM, Rodrigo Alencar wrote:
> > On 26/05/09 06:42PM, David Lechner wrote:
> >> On 5/8/26 12:00 PM, Rodrigo Alencar via B4 Relay wrote:
> >>> From: Rodrigo Alencar <rodrigo.alencar@analog.com>
> >>>
> >>> Add documentation for the AD9910 DDS IIO driver, which describes channels,
> >>> DDS modes, attributes and ABI usage examples.
> > 
> > ...
> > 
> >>> +       must be a power of 2.
> >>> +
> >>> +   * - ``frequency_offset``
> >>> +     - Hz
> >>> +     - Base FTW to which scaled parallel data is added. Range :math:`[0, f_{SYSCLK}/2)`.
> >>> +
> >>> +   * - ``phase_offset``
> >>> +     - rad
> >>> +     - Base phase for polar modulation. Lower 8 bits of POW register.
> >>> +       Range :math:`[0, 2\pi/256)`.
> >>> +
> >>> +   * - ``scale_offset``
> >>> +     - fractional
> >>> +     - Base amplitude for polar modulation. Lower 6 bits of ASF register.
> >>> +       Range :math:`[0, 1/256)`.
> >>> +
> >>
> >> I guess there was some discussion on these attributes. I see some of these in the
> >> ad9832 driver in staging, but I'm guessing they are new ABI. It isn't clear to
> >> me from the documentation here what they actually do though. I guess they are
> >> just basic transformations on the input signal?
> > 
> > Not sure how the ABI is not clear:
> > 
> > 	For a channel that allows amplitude control through buffers, this
> > 	represents the value for a base amplitude scale. The actual output
> > 	amplitude scale is a result with the sum of this value.
> > 
> > So yes, it is a basic transformation.
> 
> I didn't have time to read the ABI docs yet. For scale_offset though,
> how is that different from the existing offset attribute?

I suppose that existing offset ABI is applied to (raw * scale), mostly for
voltage channels, here the scale_offset is an offset to the scale itself.
 
> > 
> >>
> >> And a practical note, they should be "frequencyscale". I don't like that it is
> >> harder to read, but it is easier for a machine to parse.
> > 
> > Parsers like the ones in libiio is not having problems with that.
> > 
> >>> +Usage examples
> >>> +^^^^^^^^^^^^^^
> >>> +
> >>> +Set parallel port frequency modulation with a scale of 16 and a 50 MHz
> >>> +offset:
> >>> +
> >>> +.. code-block:: bash
> >>> +
> >>> +  echo 16 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_scale
> >>> +  echo 50000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_offset
> >>> +
> >>> +Digital ramp generator (DRG)
> >>> +----------------------------
> >>> +
> >>> +The DRG produces linear frequency, phase or amplitude sweeps using dedicated
> >>> +hardware. It is controlled through three channels: a parent control channel
> >>> +(``digital_ramp_generator``) and two child ramp channels
> >>> +(``digital_ramp_up``, ``digital_ramp_down``). DRG destination is set when
> >>> +ramp attributes are written, i.e. writing to ``frequency`` or ``frequency_roc``
> >>> +sets the destination to frequency.
> >>
> >> Would it be better to say that the destination is set when the the
> >> value is non-zero? Otherwise, how would one change the destination
> >> once set?
> > 
> > Destination is only one, so you just need to write phase or phase_roc, if you want
> > to target phase then. Does that not sound intuitive?
> 
> I was thinking about if you needed to change the configuration.
> If you set it to phase, then want to change it to frequency, how
> could you do that if 0 is a valid value for phase?
> 
> Also how could you know which is selected by reading back the
> values if 0 is a valid value?

This is where Jonathan raised some concerns, so it is a good oportunity for you
to provide your inputs! Right now, I am returning -EBUSY on read of an attribute
where its destination is not selected. As pointed out, the destination selection
is happening when writting to the attribute. In the previous patch, Jonathan
suggested frequency_active, phase_active and scale_active to track mode priority,
and It could be leveraged here for DRG destination selection. I havent gone for
that because I was not willing to add that to all the channels given that it is
mostly used for debugging, so I added frequency_source, phase_source and
amplitude_source to debugfs instead.

Destination selection for RAM mode is firmware based at this point.
Destination selection for Parallel mode is still not clear... could use
those *_active attributes or separate channels.

> > 
> > Zero is a valid value to be written.
> > 
> >>

-- 
Kind regards,

Rodrigo Alencar

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC v4 10/10] docs: iio: add documentation for ad9910 driver
  2026-05-11 15:02         ` Rodrigo Alencar
@ 2026-05-11 15:23           ` David Lechner
  2026-05-11 16:01             ` Rodrigo Alencar
  0 siblings, 1 reply; 11+ messages in thread
From: David Lechner @ 2026-05-11 15:23 UTC (permalink / raw)
  To: Rodrigo Alencar, rodrigo.alencar, linux-iio, devicetree,
	linux-kernel, linux-doc, linux-hardening
  Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
	Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Jonathan Corbet, Shuah Khan, Kees Cook,
	Gustavo A. R. Silva

On 5/11/26 10:02 AM, Rodrigo Alencar wrote:
> On 26/05/11 09:46AM, David Lechner wrote:
>> On 5/10/26 4:30 AM, Rodrigo Alencar wrote:
>>> On 26/05/09 06:42PM, David Lechner wrote:
>>>> On 5/8/26 12:00 PM, Rodrigo Alencar via B4 Relay wrote:
>>>>> From: Rodrigo Alencar <rodrigo.alencar@analog.com>
>>>>>
>>>>> Add documentation for the AD9910 DDS IIO driver, which describes channels,
>>>>> DDS modes, attributes and ABI usage examples.
>>>
>>> ...
>>>
>>>>> +       must be a power of 2.
>>>>> +
>>>>> +   * - ``frequency_offset``
>>>>> +     - Hz
>>>>> +     - Base FTW to which scaled parallel data is added. Range :math:`[0, f_{SYSCLK}/2)`.
>>>>> +
>>>>> +   * - ``phase_offset``
>>>>> +     - rad
>>>>> +     - Base phase for polar modulation. Lower 8 bits of POW register.
>>>>> +       Range :math:`[0, 2\pi/256)`.
>>>>> +
>>>>> +   * - ``scale_offset``
>>>>> +     - fractional
>>>>> +     - Base amplitude for polar modulation. Lower 6 bits of ASF register.
>>>>> +       Range :math:`[0, 1/256)`.
>>>>> +
>>>>
>>>> I guess there was some discussion on these attributes. I see some of these in the
>>>> ad9832 driver in staging, but I'm guessing they are new ABI. It isn't clear to
>>>> me from the documentation here what they actually do though. I guess they are
>>>> just basic transformations on the input signal?
>>>
>>> Not sure how the ABI is not clear:
>>>
>>> 	For a channel that allows amplitude control through buffers, this
>>> 	represents the value for a base amplitude scale. The actual output
>>> 	amplitude scale is a result with the sum of this value.
>>>
>>> So yes, it is a basic transformation.
>>
>> I didn't have time to read the ABI docs yet. For scale_offset though,
>> how is that different from the existing offset attribute?
> 
> I suppose that existing offset ABI is applied to (raw * scale), mostly for
> voltage channels, here the scale_offset is an offset to the scale itself.


Ah, so a very general case would be (raw * (scale + scale_offset)) + offset

when the scale can change as a function of time and comes from an external
source.

>  
>>>
>>>>
>>>> And a practical note, they should be "frequencyscale". I don't like that it is
>>>> harder to read, but it is easier for a machine to parse.
>>>
>>> Parsers like the ones in libiio is not having problems with that.
>>>
>>>>> +Usage examples
>>>>> +^^^^^^^^^^^^^^
>>>>> +
>>>>> +Set parallel port frequency modulation with a scale of 16 and a 50 MHz
>>>>> +offset:
>>>>> +
>>>>> +.. code-block:: bash
>>>>> +
>>>>> +  echo 16 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_scale
>>>>> +  echo 50000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_offset
>>>>> +
>>>>> +Digital ramp generator (DRG)
>>>>> +----------------------------
>>>>> +
>>>>> +The DRG produces linear frequency, phase or amplitude sweeps using dedicated
>>>>> +hardware. It is controlled through three channels: a parent control channel
>>>>> +(``digital_ramp_generator``) and two child ramp channels
>>>>> +(``digital_ramp_up``, ``digital_ramp_down``). DRG destination is set when
>>>>> +ramp attributes are written, i.e. writing to ``frequency`` or ``frequency_roc``
>>>>> +sets the destination to frequency.
>>>>
>>>> Would it be better to say that the destination is set when the the
>>>> value is non-zero? Otherwise, how would one change the destination
>>>> once set?
>>>
>>> Destination is only one, so you just need to write phase or phase_roc, if you want
>>> to target phase then. Does that not sound intuitive?
>>
>> I was thinking about if you needed to change the configuration.
>> If you set it to phase, then want to change it to frequency, how
>> could you do that if 0 is a valid value for phase?
>>
>> Also how could you know which is selected by reading back the
>> values if 0 is a valid value?
> 
> This is where Jonathan raised some concerns, so it is a good oportunity for you
> to provide your inputs! Right now, I am returning -EBUSY on read of an attribute
> where its destination is not selected. As pointed out, the destination selection
> is happening when writting to the attribute. In the previous patch, Jonathan
> suggested frequency_active, phase_active and scale_active to track mode priority,
> and It could be leveraged here for DRG destination selection. I havent gone for
> that because I was not willing to add that to all the channels given that it is
> mostly used for debugging, so I added frequency_source, phase_source and
> amplitude_source to debugfs instead.

The "last write wins" with the others changing to EBUSY makes more sense to
me now. If the docs said that, I missed it. Otherwise, that would be a helpful
thing to add to the docs here.

> 
> Destination selection for RAM mode is firmware based at this point.

Seems reasonable.

> Destination selection for Parallel mode is still not clear... could use
> those *_active attributes or separate channels.

Since there are _offset attributes proposed for parallel input already,
could we just make it the same where you have to write one of those
attributes?

> 
>>>
>>> Zero is a valid value to be written.
>>>
>>>>
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC v4 10/10] docs: iio: add documentation for ad9910 driver
  2026-05-11 15:23           ` David Lechner
@ 2026-05-11 16:01             ` Rodrigo Alencar
  2026-05-15 15:47               ` Rodrigo Alencar
  0 siblings, 1 reply; 11+ messages in thread
From: Rodrigo Alencar @ 2026-05-11 16:01 UTC (permalink / raw)
  To: David Lechner, Rodrigo Alencar, rodrigo.alencar, linux-iio,
	devicetree, linux-kernel, linux-doc, linux-hardening
  Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
	Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Jonathan Corbet, Shuah Khan, Kees Cook,
	Gustavo A. R. Silva

On 26/05/11 10:23AM, David Lechner wrote:
> On 5/11/26 10:02 AM, Rodrigo Alencar wrote:
> > On 26/05/11 09:46AM, David Lechner wrote:
> >> On 5/10/26 4:30 AM, Rodrigo Alencar wrote:
> >>> On 26/05/09 06:42PM, David Lechner wrote:
> >>>> On 5/8/26 12:00 PM, Rodrigo Alencar via B4 Relay wrote:
> >>>>> From: Rodrigo Alencar <rodrigo.alencar@analog.com>
> >>>>>
> >>>>> Add documentation for the AD9910 DDS IIO driver, which describes channels,
> >>>>> DDS modes, attributes and ABI usage examples.

...

> >>>> And a practical note, they should be "frequencyscale". I don't like that it is
> >>>> harder to read, but it is easier for a machine to parse.
> >>>
> >>> Parsers like the ones in libiio is not having problems with that.
> >>>
> >>>>> +Usage examples
> >>>>> +^^^^^^^^^^^^^^
> >>>>> +
> >>>>> +Set parallel port frequency modulation with a scale of 16 and a 50 MHz
> >>>>> +offset:
> >>>>> +
> >>>>> +.. code-block:: bash
> >>>>> +
> >>>>> +  echo 16 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_scale
> >>>>> +  echo 50000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage113_frequency_offset
> >>>>> +
> >>>>> +Digital ramp generator (DRG)
> >>>>> +----------------------------
> >>>>> +
> >>>>> +The DRG produces linear frequency, phase or amplitude sweeps using dedicated
> >>>>> +hardware. It is controlled through three channels: a parent control channel
> >>>>> +(``digital_ramp_generator``) and two child ramp channels
> >>>>> +(``digital_ramp_up``, ``digital_ramp_down``). DRG destination is set when
> >>>>> +ramp attributes are written, i.e. writing to ``frequency`` or ``frequency_roc``
> >>>>> +sets the destination to frequency.
> >>>>
> >>>> Would it be better to say that the destination is set when the the
> >>>> value is non-zero? Otherwise, how would one change the destination
> >>>> once set?
> >>>
> >>> Destination is only one, so you just need to write phase or phase_roc, if you want
> >>> to target phase then. Does that not sound intuitive?
> >>
> >> I was thinking about if you needed to change the configuration.
> >> If you set it to phase, then want to change it to frequency, how
> >> could you do that if 0 is a valid value for phase?
> >>
> >> Also how could you know which is selected by reading back the
> >> values if 0 is a valid value?
> > 
> > This is where Jonathan raised some concerns, so it is a good oportunity for you
> > to provide your inputs! Right now, I am returning -EBUSY on read of an attribute
> > where its destination is not selected. As pointed out, the destination selection
> > is happening when writting to the attribute. In the previous patch, Jonathan
> > suggested frequency_active, phase_active and scale_active to track mode priority,
> > and It could be leveraged here for DRG destination selection. I havent gone for
> > that because I was not willing to add that to all the channels given that it is
> > mostly used for debugging, so I added frequency_source, phase_source and
> > amplitude_source to debugfs instead.
> 
> The "last write wins" with the others changing to EBUSY makes more sense to
> me now. If the docs said that, I missed it. Otherwise, that would be a helpful
> thing to add to the docs here.
> 
> > 
> > Destination selection for RAM mode is firmware based at this point.
> 
> Seems reasonable.
> 
> > Destination selection for Parallel mode is still not clear... could use
> > those *_active attributes or separate channels.
> 
> Since there are _offset attributes proposed for parallel input already,
> could we just make it the same where you have to write one of those
> attributes?

Different from the DRG, both RAM and Parallel mode has this extra polar
destination, which targets both amplitude and phase at the same time.

For parallel mode I have the attributes:
- frequency_scale: applied when destination is frequency
- frequency_offset: applied when destination is frequency
- scale_offset: applied when destination is polar
- phase_offset: applied when destination is polar

In parallel mode, there aren't knobs like those for amplitude and phase
destinations. With the *_active thing or similar, polar can be both
phase_active and scale_active enabled at the same time. However, this
would not behave the same way Jonathan suggested, i.e. to be used for
mode priority indication... it would be used for destination configuration
instead.

> 
> > 
> >>>
> >>> Zero is a valid value to be written.
> >>>
> >>>>
> > 
> 

-- 
Kind regards,

Rodrigo Alencar

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC v4 10/10] docs: iio: add documentation for ad9910 driver
  2026-05-11 16:01             ` Rodrigo Alencar
@ 2026-05-15 15:47               ` Rodrigo Alencar
  0 siblings, 0 replies; 11+ messages in thread
From: Rodrigo Alencar @ 2026-05-15 15:47 UTC (permalink / raw)
  To: Rodrigo Alencar, David Lechner, rodrigo.alencar, linux-iio,
	devicetree, linux-kernel, linux-doc, linux-hardening
  Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
	Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel, Jonathan Corbet, Shuah Khan, Kees Cook,
	Gustavo A. R. Silva

On 26/05/11 05:01PM, Rodrigo Alencar wrote:
> On 26/05/11 10:23AM, David Lechner wrote:
> > On 5/11/26 10:02 AM, Rodrigo Alencar wrote:
> > > On 26/05/11 09:46AM, David Lechner wrote:
> > >> On 5/10/26 4:30 AM, Rodrigo Alencar wrote:
> > >>> On 26/05/09 06:42PM, David Lechner wrote:
> > >>>> On 5/8/26 12:00 PM, Rodrigo Alencar via B4 Relay wrote:
> > >>>>> From: Rodrigo Alencar <rodrigo.alencar@analog.com>
> > >>>>>
> > >>>>> Add documentation for the AD9910 DDS IIO driver, which describes channels,
> > >>>>> DDS modes, attributes and ABI usage examples.

...

> > >>>>> +Digital ramp generator (DRG)
> > >>>>> +----------------------------
> > >>>>> +
> > >>>>> +The DRG produces linear frequency, phase or amplitude sweeps using dedicated
> > >>>>> +hardware. It is controlled through three channels: a parent control channel
> > >>>>> +(``digital_ramp_generator``) and two child ramp channels
> > >>>>> +(``digital_ramp_up``, ``digital_ramp_down``). DRG destination is set when
> > >>>>> +ramp attributes are written, i.e. writing to ``frequency`` or ``frequency_roc``
> > >>>>> +sets the destination to frequency.
> > >>>>
> > >>>> Would it be better to say that the destination is set when the the
> > >>>> value is non-zero? Otherwise, how would one change the destination
> > >>>> once set?
> > >>>
> > >>> Destination is only one, so you just need to write phase or phase_roc, if you want
> > >>> to target phase then. Does that not sound intuitive?
> > >>
> > >> I was thinking about if you needed to change the configuration.
> > >> If you set it to phase, then want to change it to frequency, how
> > >> could you do that if 0 is a valid value for phase?
> > >>
> > >> Also how could you know which is selected by reading back the
> > >> values if 0 is a valid value?
> > > 
> > > This is where Jonathan raised some concerns, so it is a good oportunity for you
> > > to provide your inputs! Right now, I am returning -EBUSY on read of an attribute
> > > where its destination is not selected. As pointed out, the destination selection
> > > is happening when writting to the attribute. In the previous patch, Jonathan
> > > suggested frequency_active, phase_active and scale_active to track mode priority,
> > > and It could be leveraged here for DRG destination selection. I havent gone for
> > > that because I was not willing to add that to all the channels given that it is
> > > mostly used for debugging, so I added frequency_source, phase_source and
> > > amplitude_source to debugfs instead.
> > 
> > The "last write wins" with the others changing to EBUSY makes more sense to
> > me now. If the docs said that, I missed it. Otherwise, that would be a helpful
> > thing to add to the docs here.
> > 
> > > 
> > > Destination selection for RAM mode is firmware based at this point.
> > 
> > Seems reasonable.
> > 
> > > Destination selection for Parallel mode is still not clear... could use
> > > those *_active attributes or separate channels.
> > 
> > Since there are _offset attributes proposed for parallel input already,
> > could we just make it the same where you have to write one of those
> > attributes?
> 
> Different from the DRG, both RAM and Parallel mode has this extra polar
> destination, which targets both amplitude and phase at the same time.
> 
> For parallel mode I have the attributes:
> - frequency_scale: applied when destination is frequency
> - frequency_offset: applied when destination is frequency
> - scale_offset: applied when destination is polar
> - phase_offset: applied when destination is polar
> 
> In parallel mode, there aren't knobs like those for amplitude and phase
> destinations. With the *_active thing or similar, polar can be both
> phase_active and scale_active enabled at the same time. However, this
> would not behave the same way Jonathan suggested, i.e. to be used for
> mode priority indication... it would be used for destination configuration
> instead.

I was thinking, and it might be good to define this now because of the
fact I might need to create other 3 channels for the parallel mode (Maybe
that is fine and we can create them later if needed).

One thing to note is that in parallel mode, although the format pins (F0, F1)
that defines the parallel destination are synchronized with PDCLK (parallel port
clock), we cannot really send multiple formats in a single session, so we
cannot interleave destinations. Then, if having separate channels we would need
to contraint that (only one destination works at a time) with the available
scan masks.

Now, also related to the IIO backend support but for the DRG channel...
Anticipating new ABI for the IIO backend, currently I have the following to
expose ramp control from the FPGA IP:
- toggle_en: To allow the backend to control DRCTL pin, toggling it in response
	     to DROVER, according to the configured dwell modes.
- ramp_delay: the delay between ramp sweeps in seconds
- burst_count: amount of ramps in a burst of ramps
- burst_delay: delay between bursts in seconds (valid when burst_count > 0)

Would also be good if I can get a comment on those! Maybe toggle_en can be
removed as the other ones only make sense when there is dwell and when this
toggle is enabled. So toggle enabled can be set by default whenever we are
not in bidirectional continuous, i.e., we are dwelling at either max or min
limits (or both).

Just to summarize the motivation for those attributes... the idea to create
those ramp patterns is to allow a receiver that performs stretch processing
to assemble a "radar data cube" of data, where FFT applied to each dimension
gives different insights on the detected object: range, velocity and direction.
Each ramp would give a row, a burst gives a matrix, and with multiple antennas
one gets a 3D block of data.

...

-- 
Kind regards,

Rodrigo Alencar

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-05-15 15:47 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-10 12:01 [PATCH RFC v4 10/10] docs: iio: add documentation for ad9910 driver kernel test robot
  -- strict thread matches above, loose matches on Subject: below --
2026-05-08 17:00 [PATCH RFC v4 00/10] AD9910 Direct Digital Synthesizer Rodrigo Alencar
2026-05-08 17:00 ` [PATCH RFC v4 10/10] docs: iio: add documentation for ad9910 driver Rodrigo Alencar
2026-05-08 17:00   ` 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-11 14:46       ` David Lechner
2026-05-11 15:02         ` Rodrigo Alencar
2026-05-11 15:23           ` David Lechner
2026-05-11 16:01             ` Rodrigo Alencar
2026-05-15 15:47               ` Rodrigo Alencar

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.