From: Rodrigo Alencar <[email protected]>

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

Signed-off-by: Rodrigo Alencar <[email protected]>
---
 Documentation/iio/ad9910.rst | 666 +++++++++++++++++++++++++++++++++++++++++++
 Documentation/iio/index.rst  |   1 +
 MAINTAINERS                  |   1 +
 3 files changed, 668 insertions(+)

diff --git a/Documentation/iio/ad9910.rst b/Documentation/iio/ad9910.rst
new file mode 100644
index 000000000000..dbcf8f8a1dda
--- /dev/null
+++ b/Documentation/iio/ad9910.rst
@@ -0,0 +1,666 @@
+.. 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. 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 have an ``enable`` attribute that turns the mode on/off.
+
+.. flat-table::
+   :header-rows: 1
+
+   * - Channel
+     - Label
+     - Parent
+     - Description
+
+   * - ``out_altvoltage100``
+     - ``phy``
+     -
+     - Physical output: system clock and profile control.
+       See `Physical channel`_.
+
+   * - ``out_altvoltage110`` ... ``out_altvoltage117``
+     - ``profile0`` ... ``profile7``
+     - ``phy``
+     - Single tone control: frequency, phase, amplitude.
+       See `Single Tone mode`_.
+
+   * - ``out_altvoltage120``
+     - ``parallel_port``
+     - ``phy``
+     - Parallel port modulation channel.
+       See `Parallel Port mode`_.
+
+   * - ``out_altvoltage130``
+     - ``digital_ramp_generator``
+     - ``phy``
+     - Digital ramp generator (DRG) control: enable.
+       See `Digital ramp generator (DRG)`_.
+
+   * - ``out_altvoltage131``
+     - ``digital_ramp_up``
+     - ``digital_ramp_generator``
+     - DRG ramp-up parameters: dwell enable, limits, rate of change, ramp rate.
+
+   * - ``out_altvoltage132``
+     - ``digital_ramp_down``
+     - ``digital_ramp_generator``
+     - DRG ramp-down parameters: dwell enable, limits, rate of change, ramp 
rate.
+
+   * - ``out_altvoltage140``
+     - ``ram_control``
+     - ``phy``
+     - RAM playback: enable, frequency, phase and sampling frequency for active
+       profile. See `RAM mode`_.
+
+   * - ``out_altvoltage150``
+     - ``output_shift_keying``
+     - ``phy``
+     - Output shift keying (OSK): enable, amplitude scale, ramp rate,
+       rate of change control. See `Output Shift Keying (OSK)`_.
+
+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 Frequency Tuning Word, 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 Phase Offset Word, 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
+     - Amplitude Scale Factor, 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 ``profileY`` channels
+provide 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_altvoltage112_frequency
+  echo 0.5 > /sys/bus/iio/devices/iio:device0/out_altvoltage112_scale
+  echo 0 > /sys/bus/iio/devices/iio:device0/out_altvoltage112_phase
+
+  # Activate profile 2
+  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage112_en
+
+Read back the current single tone frequency:
+
+.. code-block:: bash
+
+  cat /sys/bus/iio/devices/iio:device0/out_altvoltage112_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
+     - Frequency modulation (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_altvoltage120_frequency_scale
+  echo 50000000 > 
/sys/bus/iio/devices/iio:device0/out_altvoltage120_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``).
+
+The DRG can target only one destination at a time (frequency, phase or
+amplitude). Destination selection follows a "last write wins" policy: writing
+any value (including zero) to a destination-specific attribute (e.g.
+``frequency``, ``frequency_roc``, ``phase``, ``phase_roc``, ``scale`` or
+``scale_roc``) switches the DRG destination accordingly. Reading an attribute
+whose destination is not currently active returns ``-EBUSY``.
+
+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_altvoltage131_dwell_en
+  echo 0 > /sys/bus/iio/devices/iio:device0/out_altvoltage132_dwell_en
+
+  # Set ramp limits
+  echo 60000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage131_frequency
+  echo 40000000 > /sys/bus/iio/devices/iio:device0/out_altvoltage132_frequency
+
+  # Set ramp rate
+  echo 25000000 > 
/sys/bus/iio/devices/iio:device0/out_altvoltage131_sampling_frequency
+  echo 25000000 > 
/sys/bus/iio/devices/iio:device0/out_altvoltage132_sampling_frequency
+
+  # Set frequency rate of change (Hz/s)
+  echo 25000000000 > 
/sys/bus/iio/devices/iio:device0/out_altvoltage131_frequency_roc
+  echo 25000000000 > 
/sys/bus/iio/devices/iio:device0/out_altvoltage132_frequency_roc
+
+  # Enable the DRG
+  echo 1 > /sys/bus/iio/devices/iio:device0/out_altvoltage130_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 firmware data
+follows a binary format (version 1) with an 80-byte header followed by data
+words. All fields are big-endian.
+
+.. flat-table:: RAM firmware header (80 bytes)
+   :header-rows: 1
+
+   * - Offset
+     - Size
+     - Field
+     - Description
+
+   * - 0
+     - 4
+     - ``magic``
+     - Magic number: ``0x00AD9910``
+
+   * - 4
+     - 2
+     - ``version``
+     - Format version: ``0x0001``
+
+   * - 6
+     - 2
+     - ``wcount``
+     - Number of 32-bit RAM data words (0--1024)
+
+   * - 8
+     - 4
+     - ``crc``
+     - CRC32 checksum over ``cfr1``, ``profiles`` and ``words``
+
+   * - 12
+     - 4
+     - ``cfr1``
+     - CFR1 register value. Only RAM-relevant bits are used:
+       bits [30:29] set data destination (00: frequency, 01: phase,
+       10: amplitude, 11: polar); bits [20:17] set internal profile
+       control (see datasheet Table 14)
+
+   * - 16
+     - 64
+     - ``profiles[0..7]``
+     - 8 sets of 8-byte RAM profile configurations (see below)
+
+   * - 80
+     - 4 x wcount
+     - ``words[]``
+     - RAM data words in reverse order
+
+Each 8-byte profile entry contains:
+
+.. flat-table:: RAM profile entry (8 bytes)
+   :header-rows: 1
+
+   * - Bits
+     - Field
+     - Description
+
+   * - [55:40]
+     - Address step rate
+     - Controls playback speed for this profile
+
+   * - [39:30]
+     - End address
+     - Last RAM address for this profile
+
+   * - [23:14]
+     - Start address
+     - First RAM address for this profile
+
+   * - [5]
+     - No-dwell high
+     - No-dwell at high limit (ramp-up mode)
+
+   * - [3]
+     - Zero-crossing
+     - Zero-crossing enable (direct-switch mode)
+
+   * - [2:0]
+     - Operating mode
+     - 000: direct switch, 001: ramp-up, 010: bidirectional,
+       011: bidirectional continuous, 100: ramp-up continuous
+
+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_altvoltage140_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)`.
+
+   * - ``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 ASF 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.
+
+   * - ``sampling_frequency``
+     - Hz
+     - OSK ramp rate. It is controlled by an integer divider so the requested
+       value will adjust to nearest supported value.
+
+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. When the internal PLL is enabled
+       (via the ``adi,pll-enable`` devicetree property), configures the PLL
+       multiplier (range 420--1000 MHz). Without PLL, the reference 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 c39affe4157a..363b7af827c3 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



Reply via email to