Skip to content

Day34 - Linux IIO I2C Driver (Multi-Channel Direct Mode)

Overview

This day implements a Linux IIO driver over I2C for a custom STM32-based fake sensor.

The sensor provides:

  • 3 ADC channels (ADC0, ADC1, ADC2)
  • Register-based interface over I2C
  • Periodic sample update (time-driven, not request-driven)

The IIO driver exposes these channels via sysfs using direct mode.


System Architecture

STM32 (fake sensor)
 ├── sensor_reg (register model)
 ├── sensor_task (periodic update)
 └── i2c_slave (transport)

        ↓ I2C

Linux
 ├── i2c driver
 ├── IIO framework
 └── sysfs interface

IIO Device Interface

After driver probe:

/sys/bus/iio/devices/iio:deviceX/
 ├── name
 ├── in_voltage0_raw
 ├── in_voltage1_raw
 ├── in_voltage2_raw
 ├── in_voltage_scale

Channel Mapping

Channel Register sysfs
ADC0 0x10 / 0x11 in_voltage0_raw
ADC1 0x12 / 0x13 in_voltage1_raw
ADC2 0x14 / 0x15 in_voltage2_raw

Key Implementation

1. Channel Specification

.type = IIO_VOLTAGE
.indexed = 1
.channel = X

Result:

in_voltageX_raw

2. Shared Scale

.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE)

Result:

in_voltage_scale

3. read_raw() Mapping

sysfs read
IIO core
read_raw()
I2C register read
STM32 sensor

4. Raw Value Conversion

STM32 returns:

16-bit register (little endian)
12-bit valid data

Driver:

*val = raw & 0x0FFF;

Sensor Behavior (STM32 Side)

Sample Update Rule

sample_id++
adc0 = 100 + sample_id
adc1 = 200 + sample_id
adc2 = 300 + sample_id

Key Properties

  • Deterministic pattern (easy debug)
  • Time-driven (via main loop)
  • Independent from I2C access

Data Flow

Full Path

STM32 main loop
sensor_task_process()
update sample registers
Linux read
I2C transaction
read_raw()
sysfs output

Comparison with Previous Work

vs hwmon

hwmon IIO
Manual sysfs Auto-generated sysfs
Single value Multi-channel
show() read_raw()

vs Character Driver

Char Driver IIO
read/write read_raw
protocol-based measurement-based
user-defined format framework-defined

vs TTY

TTY IIO
byte stream structured samples
IRQ RX trigger-based (future)
flip buffer IIO buffer (future)

Key Takeaways

  1. IIO channel metadata defines sysfs ABI
  2. Multi-channel support is native in IIO
  3. read_raw() bridges sysfs and hardware
  4. Direct mode behaves like multi-channel single-shot sensor
  5. Sensor should be time-driven, not request-driven

Limitations (Current Stage)

  • No buffer support
  • No trigger
  • No timestamp
  • No interrupt (DRDY not used yet)

Next Step (Day35)

  • Add DRDY GPIO (data-ready interrupt)
  • Introduce IRQ handling in driver
  • Prepare for IIO trigger/buffer model