Re: [PATCH 1/3] iio: common: st_sensors: honour channel endianness in read_axis_data
From: me
Date: Mon Jun 15 2026 - 07:13:01 EST
On 2026-06-14 20:39, Jonathan Cameron wrote:
On Fri, 5 Jun 2026 12:08:41 +0200Hi Jonathan,
Herman van Hazendonk <github.com@xxxxxxxxxx> wrote:
st_sensors_read_axis_data() unconditionally decoded multi-byteHi Herman,
results with get_unaligned_le16() / get_unaligned_le24() regardless
of the channel's declared scan_type.endianness.
For every ST sensor that has used this helper since it was introduced
this happened to be fine because the ST IMU/accel/gyro/pressure
families publish their data registers as little-endian and the
channel specs in those drivers declare IIO_LE accordingly.
The LSM303DLH magnetometer however publishes its X/Y/Z output as a
pair of big-endian bytes (the H register sits at the lower address,
0x03/0x05/0x07, and the L register immediately after), and its
channel specs in st_magn_core.c correctly declare IIO_BE -- but
read_axis_data() ignored that and decoded as little-endian, swapping
the high and low bytes of every magnetometer sample.
The bug is most visible on a stationary chip: in earth's field the
true X reading is small and the high byte sits at 0x00, so swapping
the bytes pins sysfs X at exactly the low byte's pattern (e.g. 0x00F0
= 240). Y and Z still appear "to vary" because their magnitudes are
larger and the noise in the low byte produces big swings in the
swapped high byte:
before (chip flat, sysfs in_magn_*_raw):
X=240 (stuck), Y= 12032..23296, Z=-16128..-9728
after (direct i2c-dev big-endian decode, same chip same orientation):
X≈-4096, Y≈210, Z≈80 (sensible values reflecting earth's
ambient field at low gauss range)
Fix read_axis_data() to dispatch on ch->scan_type.endianness and
call get_unaligned_be16() / get_unaligned_be24() when the channel
declares IIO_BE. Existing IIO_LE consumers (st_accel, st_gyro,
st_pressure, st_lsm6dsx and others) are unaffected because their
channel specs already declare IIO_LE and the LE path is unchanged.
Fixes tag please. We want to know how far to backport and provide
info to those trying to work out if the bug affects their kernel
trees.
Thanks
Jonathan
Signed-off-by: Herman van Hazendonk <github.com@xxxxxxxxxx>
I've been working with the HP TouchPad which uses the Qualcomm APQ8060 to bring this to mainline kernel, which was running a very ancient 2.6.35 kernel where I could compare things since it was working there without issues, hence I could compare them side by side, check values etc.
It seems this "bug" was introduced with 3.9:
Fixes: 23491b513bcd ("iio:common: Add STMicroelectronics common library")
That's the commit that introduced st_sensors_read_axis_data() with the unconditional get_unaligned_le16() decode.
I'll include that for the v2.
Thanks,
Herman