Skip to content

IIO Buffered Acquisition and DMA Integration

Overview

The Linux Industrial I/O (IIO) subsystem provides a common framework for data-conversion and sensor devices such as ADCs, DACs, accelerometers, gyroscopes, and other measurement devices.

For buffered input devices, the acquisition path must solve two different problems:

  • Move samples efficiently from hardware into memory.
  • Describe those samples using the logical layout expected by IIO and userspace.

DMA can solve the first problem, but it does not define the meaning or layout of the transferred samples.

A useful separation is:

Hardware
Hardware Sample Layout
DMA Transport
IIO Buffer Management
Logical IIO Scan Layout
Userspace

Understanding this boundary is especially important when the hardware produces a fixed sample format while the IIO scan configuration allows userspace to enable only selected channels.


Architecture

IIO buffered acquisition can use different producer architectures depending on the device and driver.

IIO triggered and DMA-backed buffered acquisition architecture

A triggered acquisition path commonly involves the CPU constructing or pushing each scan:

Trigger
Poll Function
Read Device
Build Scan
IIO Buffer
Userspace

A DMA-backed acquisition path instead moves larger amounts of data with less per-sample CPU involvement:

Hardware Sample Stream
DMA Engine
DMA Buffer Block
IIO Buffer Management
Userspace

The two paths share the same higher-level requirement: the data exposed through the IIO buffer must match the configured scan representation.


IIO Device and Channels

An IIO device represents a physical or logical data-acquisition device.

A multi-channel ADC may expose channels such as:

IIO Device
├── CH0
├── CH1
├── CH2
└── CH3

Each channel has metadata that describes how the corresponding data is represented.

For buffered acquisition, important properties include:

Property Meaning
Channel Identifies the logical or physical channel
scan_index Determines the element's position in the scan model
Real data width Number of meaningful data bits
Storage width Number of bits occupied by the buffered representation

The channel number and scan_index are separate concepts.

A simple device may use:

CH0 → scan_index 0
CH1 → scan_index 1
CH2 → scan_index 2
CH3 → scan_index 3

but drivers should not assume that the channel number always determines the scan-mask bit position.


Scan Elements

A buffered IIO sample is represented as a scan containing the enabled scan elements.

For a four-channel ADC:

CH0 | CH1 | CH2 | CH3

If each channel occupies 16 bits of storage, one full scan occupies:

2 + 2 + 2 + 2
= 8 bytes

The storage width is not necessarily the same as the ADC resolution.

For example:

ADC resolution = 12 bits
Storage width  = 16 bits

The sample contains 12 meaningful bits but still occupies 2 bytes in the scan representation.

Therefore the buffered layout is based on the storage representation rather than simply dividing the ADC resolution by eight.


Active Scan Mask

The active scan mask describes which scan elements participate in the current buffered configuration.

For a device whose scan indices are 0 through 3:

bit 0 → CH0
bit 1 → CH1
bit 2 → CH2
bit 3 → CH3

A full scan may use:

active_scan_mask = 0xF
                 = 1111b

CH0 CH1 CH2 CH3

A sparse scan may use:

active_scan_mask = 0xD
                 = 1101b

CH0 CH2 CH3

The active scan mask therefore describes the logical scan configuration.

It does not necessarily reconfigure the physical data format produced by the hardware.


Logical Scan Size

The logical size of one configured scan is commonly referred to as scan_bytes.

For the simplified four-channel example with 16-bit storage:

mask = 0xF

CH0 CH1 CH2 CH3
 2   2   2   2 bytes

logical scan size = 8 bytes

For:

mask = 0xD

CH0 CH2 CH3
 2   2   2 bytes

logical scan size = 6 bytes

This simple sum is sufficient for the conceptual model used here.

Real IIO scan layouts may also need to account for additional scan elements, timestamp storage, alignment, and padding.


Hardware Layout vs Logical IIO Layout

One of the most important design issues appears when the hardware frame format is fixed.

Consider an ADC that always produces:

CH0 CH1 CH2 CH3

Disabling CH1 in the IIO scan configuration does not necessarily cause the hardware interface to emit:

CH0 CH2 CH3

The hardware may continue to produce a fixed frame, for example:

CH0 0x0000 CH2 CH3

DMA transfers the hardware-visible bytes.

Therefore:

DMA Hardware Scan
CH0 CH1 CH2 CH3

may need to become:

Logical IIO Scan
CH0 CH2 CH3

before the compact logical representation is exposed to the consumer.

Hardware DMA scan layout and logical IIO scan conversion

This gives the central distinction:

hardware scan layout
logical IIO scan layout

Scan Repacking

When the hardware and logical layouts differ, software may need to repack the scan.

For example:

Hardware:

CH0     CH1     CH2     CH3
0x1000  0x2000  0x3000  0x4000

with:

active_scan_mask = 0xD

becomes:

Logical IIO:

CH0     CH2     CH3
0x1000  0x3000  0x4000

A simple repacking algorithm maintains two independent offsets:

Offset Advances When
Hardware offset Every hardware element
Logical offset Only an enabled element is copied

Conceptually:

Hardware
+-----+-----+-----+-----+
| CH0 | CH1 | CH2 | CH3 |
+-----+-----+-----+-----+
   |           |     |
   +-----+-----+-----+
         |
         | selected elements
         v

Logical
+-----+-----+-----+
| CH0 | CH2 | CH3 |
+-----+-----+-----+

The operation changes the representation of the data and therefore normally requires CPU work and memory copying.


Block-Level Conversion

DMA transfers frequently contain multiple hardware scans rather than one scan at a time.

Suppose one hardware scan occupies 8 bytes and a DMA block contains four scans:

4 × 8 bytes
= 32 bytes

If the logical scan contains only CH0, CH2, and CH3:

logical scan size = 6 bytes

repacking four scans produces:

4 × 6 bytes
= 24 bytes

Therefore:

DMA Hardware Block
32 bytes
Scan Repacking
Logical IIO Block
24 bytes

The number of hardware scans must remain well defined.

For a fixed-width hardware scan:

block size % hardware scan size == 0

ensures that the block contains only complete scans.


DMA-Compatible Layout

Repacking is not always required.

If the active logical scan contains every element in exactly the same representation and ordering as the hardware stream:

Hardware:
CH0 CH1 CH2 CH3

Logical:
CH0 CH1 CH2 CH3

the layouts are compatible.

Conceptually:

Fixed Hardware Layout
Active Scan Configuration
   ┌────┴─────┐
   │          │
 compatible  incompatible
   │          │
   ▼          ▼
Direct      Repack
layout      or reject

This creates an important driver design choice.

A driver may:

  • Support software repacking for incompatible scan configurations.
  • Restrict DMA-backed acquisition to layouts that match the hardware stream.
  • Use different acquisition paths depending on the selected scan configuration.

The appropriate policy depends on the hardware and performance requirements.


Direct DMA Does Not Automatically Mean Zero Copy

Layout compatibility is a prerequisite for an efficient direct DMA path, but it does not by itself guarantee zero-copy delivery to userspace.

Several layers may still participate in buffer management:

Hardware
DMA Mapping
DMA Buffer
IIO Buffer Framework
Userspace Interface

Whether additional copies occur depends on the actual IIO buffer implementation and driver architecture.

Therefore:

DMA-compatible layout
guaranteed zero copy

The useful conclusion is narrower:

A matching hardware and logical layout avoids the need for channel-removal repacking.


Triggered Buffer Acquisition

Triggered buffers are useful when acquisition is naturally associated with a trigger event.

A conceptual path is:

Trigger Event
Poll Function
Read Sample Data
Construct Scan
Push Scan to Buffer

Because the CPU participates in constructing each scan, software can naturally perform operations such as:

  • Reading individual registers
  • Selecting channel values
  • Reordering data
  • Adding a software timestamp
  • Pushing the completed scan into the IIO buffer

This path is flexible but introduces CPU work for each acquisition event.


DMA-Backed Acquisition

DMA-backed acquisition is useful when hardware can produce a continuous or block-oriented stream.

Conceptually:

Peripheral / ADC
DMA Controller
DMA Buffer Block
Completion
IIO Buffer Management
Consumer

The CPU does not need to move each individual sample from the peripheral.

However, the data arriving in memory follows the hardware representation.

This is why DMA-backed acquisition makes hardware-to-IIO layout compatibility especially important.


IIO DMA Buffer Layers

The IIO DMA buffer architecture separates generic buffer-block management from the DMA Engine backend.

Conceptually:

IIO Buffer Core
IIO DMA Buffer Queue
DMAengine Backend
DMA Engine
DMA Controller Driver
Hardware

The responsibilities are different:

Layer Responsibility
IIO Buffer Provides buffered data semantics to the subsystem
IIO DMA Buffer Queue Manages buffer blocks and their lifecycle
DMAengine Backend Converts buffer work into DMA transactions
DMA Engine Provides the generic DMA transaction API
DMA Controller Driver Programs the actual DMA hardware

An IIO buffer block and a DMA descriptor are therefore not the same object.

IIO Block
    → buffer-management unit

DMA Descriptor
    → DMA transaction representation

The DMA backend connects these two lifecycles.


DMA Submission and Completion

A DMA-backed block follows the familiar DMA Engine transaction lifecycle.

Conceptually:

IIO Buffer Block
Prepare DMA Transaction
dmaengine_submit()
dma_async_issue_pending()
DMA Transfer
Completion Callback
IIO Block Completion

Completion may also use DMA residue information to determine how many bytes were actually transferred.

Conceptually:

completed bytes
    =
requested bytes - residue

This is useful when a block completes with fewer valid bytes than its total capacity.


Buffer Ownership

A DMA-backed streaming buffer can remain mapped while individual blocks repeatedly change ownership.

A useful conceptual lifecycle is:

Available
DMA In Flight
Completed
Consumer
Reusable
DMA In Flight

This means two different lifetimes must remain separate:

DMA mapping lifetime
block ownership lifetime

A buffer can remain DMA-mapped while a particular block is temporarily owned by the CPU or userspace-facing buffer framework.

This is the same ownership principle used by continuous DMA ring-buffer designs.


Completion and Consumer Wakeup

DMA completion alone does not finish the buffered acquisition path.

The completed block must become visible to the buffer consumer.

Conceptually:

DMA Completion
Update Block State
Mark Data Available
Wake Waiters
read() / poll()
Userspace

The exact implementation belongs to the IIO buffer framework and depends on the buffer backend, but the architectural boundary is important:

DMA completion transfers ownership back toward the software buffer path; it does not directly represent a userspace read.


Timestamp Semantics

Timestamp handling must be considered separately from DMA completion.

For a single triggered scan, the trigger or acquisition event may provide a useful timestamp reference.

FIFO and DMA block acquisition are different.

Suppose a device samples periodically:

Sample 0
Sample 1
Sample 2
Sample 3
      FIFO
one SPI DMA read

The DMA completion time describes when the transfer completed.

It does not mean all four samples were acquired at that exact time.

Therefore:

DMA completion timestamp
per-sample acquisition timestamp

A driver that needs accurate per-sample timestamps may reconstruct them using:

  • Known sample intervals
  • FIFO sample rate
  • Hardware counters
  • Hardware timestamps
  • Trigger timing
  • Interrupt timing

The correct timestamp model depends on the device.


Design Considerations

Prefer Hardware-Compatible Layouts When Possible

If the hardware can be configured to emit exactly the enabled channels, direct DMA integration becomes easier.

If the hardware format is fixed, the driver must decide whether sparse scans justify software repacking.

Keep Transport and Representation Separate

DMA configuration answers questions such as:

Where does the data move?
How large is the transfer?
When is it complete?

IIO scan configuration answers:

Which elements are logically enabled?
How are they ordered?
How much storage does one scan occupy?

Mixing these responsibilities makes buffer design harder to reason about.

Treat Buffer Capacity and Valid Data Size Separately

A destination block may have more capacity than the amount of logical data produced.

For example:

buffer capacity = 32 bytes
valid logical data = 24 bytes

These values should not be treated as interchangeable.

Reject Incomplete Hardware Scans

When converting fixed-size scans, an input block ending in a partial scan should not silently expose that trailing data as a complete sample.

Do Not Infer Scan Bits From Channel Count

The active scan-mask bit position is defined by scan_index.

A device with three channels does not necessarily imply that valid scan bits are simply bits 0 through 2.


Summary

IIO buffered acquisition adds data semantics and buffer management above the raw DMA transport layer.

The central relationship is:

Hardware Layout
DMA Transport
IIO Buffer Management
Logical Scan Layout
Userspace

An active scan mask determines which scan elements belong to the logical buffered representation, while the hardware may continue to generate a fixed physical frame.

When:

hardware layout
        =
logical scan layout

a direct DMA-compatible path is possible without channel-removal repacking.

When:

hardware layout
logical scan layout

the driver must either transform the data or reject that configuration from the direct DMA path.

This distinction is fundamental when integrating high-throughput ADCs and sensors with IIO DMA-backed buffering.