Out-of-tree Linux IIO driver for CEVA BNO086 over I2C.
This project was developed almost entirely with AI assistance, primarily Claude Opus 4.7. Organizations or projects that forbid AI-generated code should treat this repository as out of policy.
The driver streams 11 SH-2 reports through one IIO device backed by a software
buffer. Reports are described by the table-driven bno086_reports[] registry
in bno086_core.c; decoder, channel array, scan cache, and
stream enable/disable hooks are all dispatched from that table.
Supported reports (one row per SH-2 report id):
| Report | SH-2 id | Channels | Scale (Q-point) |
|---|---|---|---|
| Game Rotation Vector | SH2_GAME_ROTATION_VECTOR |
in_rot0_quaternion_* |
Q14 |
| Rotation Vector | SH2_ROTATION_VECTOR |
in_rot1_quaternion_* |
Q14 |
| Geomagnetic RV | SH2_GEOMAGNETIC_ROTATION_VECTOR |
in_rot2_quaternion_* |
Q12 |
| Accelerometer (cal) | SH2_ACCELEROMETER |
in_accel_{x,y,z}_* |
Q8 |
| Linear Acceleration | SH2_LINEAR_ACCELERATION |
in_accel1_{x,y,z}_* (idx 1) |
Q8 |
| Raw Accelerometer | SH2_RAW_ACCELEROMETER |
in_accel2_{x,y,z}_* (idx 2, u16 LSB) |
1 (raw LSB) |
| Gyroscope (cal) | SH2_GYROSCOPE_CALIBRATED |
in_anglvel_{x,y,z}_* |
Q9 |
| Raw Gyroscope | SH2_RAW_GYROSCOPE |
in_anglvel1_{x,y,z}_* (u16 LSB) |
1 |
| Magnetometer (cal) | SH2_MAGNETIC_FIELD_CALIBRATED |
in_magn_{x,y,z}_* |
Q4 |
| Raw Magnetometer | SH2_RAW_MAGNETOMETER |
in_magn1_{x,y,z}_* (u16 LSB) |
1 |
| Gravity | SH2_GRAVITY |
in_gravity_{x,y,z}_* |
Q8 |
Notes:
- The three quaternion reports (GRV/RV/GeoRV) use symmetric indexed sysfs
names
in_rot{0,1,2}_quaternion_*. - Each report can be enabled independently through
scan_elements/in_*_en. The buffer push path repacks the per-report scan cache intoactive_scan_maskorder before callingiio_push_to_buffers_with_timestamp(). - Per-report sample interval (
in_*_sampling_frequency) is stored per report slot inbno086_data.report_interval_us[].
Use these docs for implementation and maintenance work:
- Architecture: docs/ARCHITECTURE.md
- SH-2/SHTP protocol details: docs/SH2_PROTOCOL.md
- IIO channel and buffer behavior: docs/IIO_INTEGRATION.md
- Agent handoff guide: AGENTS.md
Compatible string(s):
ceva,bno086ceva,bno085
Properties:
- required:
compatible,reg - optional:
interruptsorinterrupt-gpios(active-low level),reset-gpios(active-low),idle_poll_ms
idle_poll_ms (optional):
- Unit: milliseconds
- Default:
20 - Valid range:
1..1000(values outside this range are clamped) - Meaning: minimum poll interval in no-IRQ mode
- No active reports behavior: polling interval uses
idle_poll_msdirectly - Active reports behavior: polling interval is
max(idle_poll_ms, derived_report_interval_ms)
I2C addresses:
0x4a(SA0 low)0x4b(SA0 high)
If no IRQ is supplied, the driver uses polling fallback automatically.
Inside bno086:
make
sudo make modules_install
sudo depmod -a
sudo modprobe bno086The driver exposes a write-only device-level sysfs attribute that maps to
the SH-2 SET_REORIENTATION tare command:
/sys/bus/iio/devices/iio:deviceN/reorientation_quaternion
It accepts four space-separated Q14 signed integers (x y z w), each in
the range [-32768, 32767]. This is the SH-2 wire format byte-for-byte:
no rounding policy lives in the kernel, and no floating-point math runs in
kernel space (the driver is built -mno-sse / BNO086_NO_FPU).
Userspace performs the conversion from a unit quaternion to Q14:
q14 = clamp(round(q * 16384), -32768, 32767)
Examples:
# Identity (clears any active tare):
echo "0 0 0 16384" > /sys/bus/iio/devices/iio:deviceN/reorientation_quaternion
# 180 deg rotation about Z (i.e. "yaw flip"):
echo "0 0 16384 0" > /sys/bus/iio/devices/iio:deviceN/reorientation_quaternionThe tare is volatile; nothing is persisted to the chip's flash. There is no companion read-back attribute - the chip does not surface the active tare in a polled register; cache the last value written if you need it.
Errors:
-EINVALon malformed input or any component outside[-32768, 32767].-EAGAINif the SH-2 stack has not yet finished bring-up.-EIOif the SH-2 command fails (seedmesgfor the underlying code).