* [PATCH v2 1/3] iio: common: st_sensors: honour channel endianness in read_axis_data
2026-06-16 13:02 [PATCH v2 0/3] iio: lsm303dlh-magn: endianness + boot-time fullscale selection Herman van Hazendonk
@ 2026-06-16 13:02 ` Herman van Hazendonk
2026-06-17 10:02 ` Andy Shevchenko
2026-06-16 13:02 ` [PATCH v2 2/3] dt-bindings: iio: st,st-sensors: add st,fullscale-milligauss Herman van Hazendonk
2026-06-16 13:02 ` [PATCH v2 3/3] iio: magnetometer: st_magn: honour st,fullscale-milligauss DT property Herman van Hazendonk
2 siblings, 1 reply; 12+ messages in thread
From: Herman van Hazendonk @ 2026-06-16 13:02 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
Denis Ciocca, Lars-Peter Clausen, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Denis Ciocca, Linus Walleij
Cc: linux-iio, linux-kernel, llvm, devicetree, stable,
Herman van Hazendonk
st_sensors_read_axis_data() unconditionally decoded multi-byte
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 LSM303DLHC
and LSM303DLM share the same st_magn_16bit_channels (IIO_BE) and
were therefore byte-swapped by the same bug; users of those parts
will see different in_magn_*_raw values after this fix lands.
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 (LSM303DLH 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.
While restructuring the branches, replace the previously implicit
silent-success-with-uninitialised-*data fall-through for
byte_for_channel outside 1..3 with an explicit return -EINVAL. No
in-tree ST sensor publishes such a channel, but the new behaviour
is strictly safer than handing userspace garbage.
Fixes: 23491b513bcd ("iio:common: Add STMicroelectronics common library")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-7 sparse smatch clang-analyzer coccinelle checkpatch
Assisted-by: Sashiko:claude-opus-4-7
Signed-off-by: Herman van Hazendonk <github.com@herrie.org>
---
drivers/iio/common/st_sensors/st_sensors_core.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
index dbc5e16fbde4..76f91696f66a 100644
--- a/drivers/iio/common/st_sensors/st_sensors_core.c
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -498,6 +498,7 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
u8 *outdata;
struct st_sensor_data *sdata = iio_priv(indio_dev);
unsigned int byte_for_channel;
+ u32 tmp;
byte_for_channel = DIV_ROUND_UP(ch->scan_type.realbits +
ch->scan_type.shift, 8);
@@ -508,12 +509,22 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
if (err < 0)
return err;
- if (byte_for_channel == 1)
- *data = (s8)*outdata;
- else if (byte_for_channel == 2)
- *data = (s16)get_unaligned_le16(outdata);
- else if (byte_for_channel == 3)
- *data = (s32)sign_extend32(get_unaligned_le24(outdata), 23);
+ if (byte_for_channel == 1) {
+ tmp = *outdata;
+ } else if (byte_for_channel == 2) {
+ if (ch->scan_type.endianness == IIO_BE)
+ tmp = get_unaligned_be16(outdata);
+ else
+ tmp = get_unaligned_le16(outdata);
+ } else if (byte_for_channel == 3) {
+ if (ch->scan_type.endianness == IIO_BE)
+ tmp = get_unaligned_be24(outdata);
+ else
+ tmp = get_unaligned_le24(outdata);
+ } else {
+ return -EINVAL;
+ }
+ *data = sign_extend32(tmp, BYTES_TO_BITS(byte_for_channel) - 1);
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH v2 1/3] iio: common: st_sensors: honour channel endianness in read_axis_data
2026-06-16 13:02 ` [PATCH v2 1/3] iio: common: st_sensors: honour channel endianness in read_axis_data Herman van Hazendonk
@ 2026-06-17 10:02 ` Andy Shevchenko
2026-06-23 19:23 ` Jonathan Cameron
0 siblings, 1 reply; 12+ messages in thread
From: Andy Shevchenko @ 2026-06-17 10:02 UTC (permalink / raw)
To: Herman van Hazendonk
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
Denis Ciocca, Lars-Peter Clausen, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Denis Ciocca, Linus Walleij,
linux-iio, linux-kernel, llvm, devicetree, stable
On Tue, Jun 16, 2026 at 03:02:04PM +0200, Herman van Hazendonk wrote:
> st_sensors_read_axis_data() unconditionally decoded multi-byte
> 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 LSM303DLHC
> and LSM303DLM share the same st_magn_16bit_channels (IIO_BE) and
> were therefore byte-swapped by the same bug; users of those parts
> will see different in_magn_*_raw values after this fix lands.
>
> 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 (LSM303DLH 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.
>
> While restructuring the branches, replace the previously implicit
> silent-success-with-uninitialised-*data fall-through for
> byte_for_channel outside 1..3 with an explicit return -EINVAL. No
> in-tree ST sensor publishes such a channel, but the new behaviour
> is strictly safer than handing userspace garbage.
Sounds like inevitable change in ABI, but worth doing it.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] iio: common: st_sensors: honour channel endianness in read_axis_data
2026-06-17 10:02 ` Andy Shevchenko
@ 2026-06-23 19:23 ` Jonathan Cameron
0 siblings, 0 replies; 12+ messages in thread
From: Jonathan Cameron @ 2026-06-23 19:23 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Herman van Hazendonk, David Lechner, Nuno Sá,
Andy Shevchenko, Nathan Chancellor, Nick Desaulniers,
Bill Wendling, Justin Stitt, Denis Ciocca, Lars-Peter Clausen,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Denis Ciocca,
Linus Walleij, linux-iio, linux-kernel, llvm, devicetree, stable
On Wed, 17 Jun 2026 13:02:54 +0300
Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> On Tue, Jun 16, 2026 at 03:02:04PM +0200, Herman van Hazendonk wrote:
> > st_sensors_read_axis_data() unconditionally decoded multi-byte
> > 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 LSM303DLHC
> > and LSM303DLM share the same st_magn_16bit_channels (IIO_BE) and
> > were therefore byte-swapped by the same bug; users of those parts
> > will see different in_magn_*_raw values after this fix lands.
> >
> > 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 (LSM303DLH 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.
> >
> > While restructuring the branches, replace the previously implicit
> > silent-success-with-uninitialised-*data fall-through for
> > byte_for_channel outside 1..3 with an explicit return -EINVAL. No
> > in-tree ST sensor publishes such a channel, but the new behaviour
> > is strictly safer than handing userspace garbage.
>
> Sounds like inevitable change in ABI, but worth doing it.
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Applied to the fixes-togreg branch of iio.git. I'll wait until after
rc1 to send a pull request though (and rebase on rc1 in the meantime).
The other patches may have to wait, I haven't checked yet!
Jonathan
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 2/3] dt-bindings: iio: st,st-sensors: add st,fullscale-milligauss
2026-06-16 13:02 [PATCH v2 0/3] iio: lsm303dlh-magn: endianness + boot-time fullscale selection Herman van Hazendonk
2026-06-16 13:02 ` [PATCH v2 1/3] iio: common: st_sensors: honour channel endianness in read_axis_data Herman van Hazendonk
@ 2026-06-16 13:02 ` Herman van Hazendonk
2026-06-16 15:41 ` Conor Dooley
2026-06-23 19:26 ` Jonathan Cameron
2026-06-16 13:02 ` [PATCH v2 3/3] iio: magnetometer: st_magn: honour st,fullscale-milligauss DT property Herman van Hazendonk
2 siblings, 2 replies; 12+ messages in thread
From: Herman van Hazendonk @ 2026-06-16 13:02 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
Denis Ciocca, Lars-Peter Clausen, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Denis Ciocca, Linus Walleij
Cc: linux-iio, linux-kernel, llvm, devicetree, Herman van Hazendonk
Add an optional st,fullscale-milligauss property that selects the
initial magnetometer full-scale range at probe time, expressed in
milligauss.
The motivating case is the LSM303DLH magnetometer on the HP TouchPad
(apq8060 / tenderloin) where the kernel's chip-default +/-1.3 G range
saturates the X axis to the chip's 0xF000 overflow sentinel out of
probe, because the chip is mounted close to surrounding power planes
and picks up enough DC bias to exceed the smallest range.
The chip is not wedged by the saturation: a sysfs write of a wider
range to in_magn_x_scale recovers it on the next conversion, and a
UDEV rule on add of the IIO device is a viable steady-state
workaround. What the DT property buys is the probe-time window: the
in-tree consumers we use (sensorfw's iio-sensors-adaptor and the
geomagnetic / orientation services on top of it) start polling
in_magn_x_raw essentially as soon as the device node appears and
treat the 0xF000 sentinel as a legitimate sample. Until a UDEV rule
fires and commits the wider range, every read returns the stuck
sentinel, and on slow-boot paths the consumer may have already
cached a bogus calibration baseline by the time UDEV catches up.
st,fullscale-milligauss lets the device tree declare a wider
initial range up-front so the correct range is in effect before any
IIO consumer can open the device, and keeps the board-specific
magnetometer calibration alongside the rest of the hardware
description rather than splitting it between DTS and per-distro
UDEV rules.
The full property name is spelled out rather than abbreviated to
"-mg" because this same binding file already covers ST accelerometers
where the conventional shorthand "mg" reads as milli-g (acceleration);
the explicit "-milligauss" suffix makes the unit unambiguous if a
similar tunable is ever introduced for the accel/gyro/pressure
families.
The property is scoped to magnetometer compatibles via allOf/if-then
clauses, with per-family enum lists of the accepted milligauss
values (1300..8100 for LSM303DLH/DLHC/DLM, 4000..16000 for
LIS3MDL/LSM9DS1/LSM303C). LSM303AGR / LIS2MDL / IIS2MDC have a
single fixed full-scale (15000 mg) with no register to switch
ranges, so the property is rejected outright for them. DTSes that
misspell the value, place the property on an accelerometer /
gyroscope / pressure node, or set it on a fixed-FS magnetometer
fail dt_binding_check rather than emitting a runtime warning.
The property is purely additive: if absent, drivers fall back to
their existing chip default. No existing in-tree DTS is affected.
Assisted-by: Claude:claude-opus-4-7 dt_binding_check checkpatch
Assisted-by: Sashiko:claude-opus-4-7
Signed-off-by: Herman van Hazendonk <github.com@herrie.org>
---
.../devicetree/bindings/iio/st,st-sensors.yaml | 71 ++++++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/Documentation/devicetree/bindings/iio/st,st-sensors.yaml b/Documentation/devicetree/bindings/iio/st,st-sensors.yaml
index a1a958215cdb..f0805604c849 100644
--- a/Documentation/devicetree/bindings/iio/st,st-sensors.yaml
+++ b/Documentation/devicetree/bindings/iio/st,st-sensors.yaml
@@ -126,6 +126,13 @@ properties:
mount-matrix:
description: an optional 3x3 mounting rotation matrix.
+ st,fullscale-milligauss:
+ description:
+ Initial magnetometer full-scale at probe time, in milligauss.
+ Per-chip allowed values are enumerated in the allOf clauses
+ below.
+ $ref: /schemas/types.yaml#/definitions/uint32
+
allOf:
- if:
properties:
@@ -163,6 +170,70 @@ allOf:
maxItems: 1
st,drdy-int-pin: false
+ # Per-chip enum lists for st,fullscale-milligauss. Out-of-range
+ # values fail dt_binding_check instead of being demoted to a
+ # runtime warning by the driver.
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - st,lsm303dlh-magn
+ - st,lsm303dlhc-magn
+ - st,lsm303dlm-magn
+ then:
+ properties:
+ st,fullscale-milligauss:
+ enum: [1300, 1900, 2500, 4000, 4700, 5600, 8100]
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - st,lis3mdl-magn
+ - st,lsm303c-magn
+ - st,lsm9ds1-magn
+ then:
+ properties:
+ st,fullscale-milligauss:
+ enum: [4000, 8000, 12000, 16000]
+
+ # Single fixed full-scale, no register to switch: reject.
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - st,iis2mdc
+ - st,lis2mdl
+ - st,lsm303agr-magn
+ then:
+ properties:
+ st,fullscale-milligauss: false
+
+ # Reject st,fullscale-milligauss on non-magnetometer compatibles.
+ # Keep this enum in sync with the three magn clauses above when
+ # adding a new magnetometer compatible.
+ - if:
+ not:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - st,iis2mdc
+ - st,lis2mdl
+ - st,lis3mdl-magn
+ - st,lsm303agr-magn
+ - st,lsm303c-magn
+ - st,lsm303dlh-magn
+ - st,lsm303dlhc-magn
+ - st,lsm303dlm-magn
+ - st,lsm9ds1-magn
+ then:
+ properties:
+ st,fullscale-milligauss: false
+
required:
- compatible
- reg
--
2.43.0
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH v2 2/3] dt-bindings: iio: st,st-sensors: add st,fullscale-milligauss
2026-06-16 13:02 ` [PATCH v2 2/3] dt-bindings: iio: st,st-sensors: add st,fullscale-milligauss Herman van Hazendonk
@ 2026-06-16 15:41 ` Conor Dooley
2026-06-23 19:26 ` Jonathan Cameron
1 sibling, 0 replies; 12+ messages in thread
From: Conor Dooley @ 2026-06-16 15:41 UTC (permalink / raw)
To: Herman van Hazendonk
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
Denis Ciocca, Lars-Peter Clausen, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Denis Ciocca, Linus Walleij,
linux-iio, linux-kernel, llvm, devicetree
[-- Attachment #1: Type: text/plain, Size: 78 bytes --]
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/3] dt-bindings: iio: st,st-sensors: add st,fullscale-milligauss
2026-06-16 13:02 ` [PATCH v2 2/3] dt-bindings: iio: st,st-sensors: add st,fullscale-milligauss Herman van Hazendonk
2026-06-16 15:41 ` Conor Dooley
@ 2026-06-23 19:26 ` Jonathan Cameron
1 sibling, 0 replies; 12+ messages in thread
From: Jonathan Cameron @ 2026-06-23 19:26 UTC (permalink / raw)
To: Herman van Hazendonk
Cc: David Lechner, Nuno Sá, Andy Shevchenko, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt, Denis Ciocca,
Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Denis Ciocca, Linus Walleij, linux-iio,
linux-kernel, llvm, devicetree
On Tue, 16 Jun 2026 15:02:05 +0200
Herman van Hazendonk <github.com@herrie.org> wrote:
> Add an optional st,fullscale-milligauss property that selects the
> initial magnetometer full-scale range at probe time, expressed in
> milligauss.
>
> The motivating case is the LSM303DLH magnetometer on the HP TouchPad
> (apq8060 / tenderloin) where the kernel's chip-default +/-1.3 G range
> saturates the X axis to the chip's 0xF000 overflow sentinel out of
> probe, because the chip is mounted close to surrounding power planes
> and picks up enough DC bias to exceed the smallest range.
>
> The chip is not wedged by the saturation: a sysfs write of a wider
> range to in_magn_x_scale recovers it on the next conversion, and a
> UDEV rule on add of the IIO device is a viable steady-state
> workaround. What the DT property buys is the probe-time window: the
> in-tree consumers we use (sensorfw's iio-sensors-adaptor and the
> geomagnetic / orientation services on top of it) start polling
> in_magn_x_raw essentially as soon as the device node appears and
> treat the 0xF000 sentinel as a legitimate sample. Until a UDEV rule
> fires and commits the wider range, every read returns the stuck
> sentinel, and on slow-boot paths the consumer may have already
> cached a bogus calibration baseline by the time UDEV catches up.
>
> st,fullscale-milligauss lets the device tree declare a wider
> initial range up-front so the correct range is in effect before any
> IIO consumer can open the device, and keeps the board-specific
> magnetometer calibration alongside the rest of the hardware
> description rather than splitting it between DTS and per-distro
> UDEV rules.
>
> The full property name is spelled out rather than abbreviated to
> "-mg" because this same binding file already covers ST accelerometers
> where the conventional shorthand "mg" reads as milli-g (acceleration);
> the explicit "-milligauss" suffix makes the unit unambiguous if a
> similar tunable is ever introduced for the accel/gyro/pressure
> families.
>
> The property is scoped to magnetometer compatibles via allOf/if-then
> clauses, with per-family enum lists of the accepted milligauss
> values (1300..8100 for LSM303DLH/DLHC/DLM, 4000..16000 for
> LIS3MDL/LSM9DS1/LSM303C). LSM303AGR / LIS2MDL / IIS2MDC have a
> single fixed full-scale (15000 mg) with no register to switch
> ranges, so the property is rejected outright for them. DTSes that
> misspell the value, place the property on an accelerometer /
> gyroscope / pressure node, or set it on a fixed-FS magnetometer
> fail dt_binding_check rather than emitting a runtime warning.
>
> The property is purely additive: if absent, drivers fall back to
> their existing chip default. No existing in-tree DTS is affected.
>
> Assisted-by: Claude:claude-opus-4-7 dt_binding_check checkpatch
> Assisted-by: Sashiko:claude-opus-4-7
> Signed-off-by: Herman van Hazendonk <github.com@herrie.org>
> ---
> .../devicetree/bindings/iio/st,st-sensors.yaml | 71 ++++++++++++++++++++++
> 1 file changed, 71 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/iio/st,st-sensors.yaml b/Documentation/devicetree/bindings/iio/st,st-sensors.yaml
> index a1a958215cdb..f0805604c849 100644
> --- a/Documentation/devicetree/bindings/iio/st,st-sensors.yaml
> +++ b/Documentation/devicetree/bindings/iio/st,st-sensors.yaml
> @@ -126,6 +126,13 @@ properties:
> mount-matrix:
> description: an optional 3x3 mounting rotation matrix.
>
> + st,fullscale-milligauss:
> + description:
> + Initial magnetometer full-scale at probe time, in milligauss.
> + Per-chip allowed values are enumerated in the allOf clauses
> + below.
> + $ref: /schemas/types.yaml#/definitions/uint32
> +
> allOf:
> - if:
> properties:
> @@ -163,6 +170,70 @@ allOf:
> maxItems: 1
> st,drdy-int-pin: false
>
> + # Per-chip enum lists for st,fullscale-milligauss. Out-of-range
> + # values fail dt_binding_check instead of being demoted to a
> + # runtime warning by the driver.
> + - if:
> + properties:
> + compatible:
> + contains:
> + enum:
> + - st,lsm303dlh-magn
> + - st,lsm303dlhc-magn
> + - st,lsm303dlm-magn
> + then:
> + properties:
> + st,fullscale-milligauss:
> + enum: [1300, 1900, 2500, 4000, 4700, 5600, 8100]
Can we also add default: to these entries to document what happens
when nothing is provided?
Thanks,
Jonathan
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 3/3] iio: magnetometer: st_magn: honour st,fullscale-milligauss DT property
2026-06-16 13:02 [PATCH v2 0/3] iio: lsm303dlh-magn: endianness + boot-time fullscale selection Herman van Hazendonk
2026-06-16 13:02 ` [PATCH v2 1/3] iio: common: st_sensors: honour channel endianness in read_axis_data Herman van Hazendonk
2026-06-16 13:02 ` [PATCH v2 2/3] dt-bindings: iio: st,st-sensors: add st,fullscale-milligauss Herman van Hazendonk
@ 2026-06-16 13:02 ` Herman van Hazendonk
2026-06-17 10:05 ` Andy Shevchenko
2026-06-23 19:29 ` Jonathan Cameron
2 siblings, 2 replies; 12+ messages in thread
From: Herman van Hazendonk @ 2026-06-16 13:02 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
Denis Ciocca, Lars-Peter Clausen, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Denis Ciocca, Linus Walleij
Cc: linux-iio, linux-kernel, llvm, devicetree, Herman van Hazendonk
The ST magnetometer core's common probe hardcodes fs_avl[0] -- the
highest-sensitivity full-scale supported by the chip -- as the
starting range. For the LSM303DLH that is +/-1.3 G; for the
LSM303DLHC and LSM303DLM it is +/-2 G; for the LIS3MDL it is +/-4 G.
That is the right default for "minimal noise floor at a desk", but
it leaves no margin for boards that pick up appreciable DC bias from
nearby PCB structures. On the HP TouchPad (apq8060 / tenderloin) the
LSM303DLH magnetometer is mounted close enough to the surrounding
power planes that X reads back as the chip's 0xF000 overflow
sentinel (== -4096 raw, the value the chip publishes when the ADC
saturates) on every sample at the chip-default range, while Y and Z
fall well within the +/-1.3 G window.
Parse the st,fullscale-milligauss device-tree property (documented
separately in dt-bindings/iio/st,st-sensors.yaml) in the
magnetometer common probe to select the initial fs_avl entry by its
mg value. The DT binding pins the accepted value set per compatible
via allOf/if-then enum clauses, so a malformed mg value fails
dt_binding_check rather than reaching the driver. Sensors with a
fixed full-scale (fs.addr == 0: LSM303AGR, LIS2MDL, IIS2MDC) have no
register to switch and the property is rejected outright for them
in the binding; the parse block is additionally gated on fs.addr as
defence in depth against stale DTBs.
Per-sensor mg ranges are listed in st_magn_sensors_settings[]. For
LSM303DLH and LSM303DLHC/DLM the valid values are 1300, 1900, 2500,
4000, 4700, 5600 and 8100; for LIS3MDL, LSM9DS1-magn and LSM303C-magn
they are 4000, 8000, 12000, 16000.
Empirical scale sweep on the HP TouchPad confirmed that on this
board any fs_avl >= 1 produces non-saturated X readings:
scale (0.001 G/LSB) | X raw Y raw Z raw
--------------------+-------------------------------
1.100 | -4096 44 46 (X saturated)
0.855 | -547 37 37 (clean)
0.670 | -433 94 103 (clean)
0.450 | -266 44 71 (clean)
0.400 | -235 34 65 (clean)
0.330 | -196 27 56 (clean)
0.230 | -145 15 40 (clean)
2500 mg is the natural choice for tenderloin: comfortably outside
the saturation regime while keeping useful precision for compass
applications.
Assisted-by: Claude:claude-opus-4-7 sparse smatch clang-analyzer coccinelle checkpatch
Assisted-by: Sashiko:claude-opus-4-7
Signed-off-by: Herman van Hazendonk <github.com@herrie.org>
---
drivers/iio/magnetometer/st_magn_core.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c
index ef348d316c00..6f369e8dddea 100644
--- a/drivers/iio/magnetometer/st_magn_core.c
+++ b/drivers/iio/magnetometer/st_magn_core.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/property.h>
#include <linux/sysfs.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@@ -608,6 +609,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev)
struct st_sensor_data *mdata = iio_priv(indio_dev);
struct device *parent = indio_dev->dev.parent;
struct st_sensors_platform_data *pdata = dev_get_platdata(parent);
+ const char *propname;
int err;
indio_dev->modes = INDIO_DIRECT_MODE;
@@ -628,6 +630,36 @@ int st_magn_common_probe(struct iio_dev *indio_dev)
mdata->current_fullscale = &mdata->sensor_settings->fs.fs_avl[0];
mdata->odr = mdata->sensor_settings->odr.odr_avl[0].hz;
+ /*
+ * Skip fixed-FS chips (fs.addr == 0): no register to switch.
+ * The binding rejects the property on these compatibles too;
+ * the gate guards stale DTBs.
+ */
+ propname = "st,fullscale-milligauss";
+ if (mdata->sensor_settings->fs.addr &&
+ device_property_present(parent, propname)) {
+ struct st_sensor_fullscale *fs = &mdata->sensor_settings->fs;
+ u32 fs_mg;
+ int i;
+
+ err = device_property_read_u32(parent, propname, &fs_mg);
+ if (err)
+ return err;
+
+ for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
+ if (!fs->fs_avl[i].num)
+ break;
+ if (fs->fs_avl[i].num == fs_mg) {
+ mdata->current_fullscale = &fs->fs_avl[i];
+ break;
+ }
+ }
+ if (mdata->current_fullscale->num != fs_mg)
+ dev_warn(parent, "%s=%u not supported, using %u\n",
+ propname, fs_mg,
+ mdata->current_fullscale->num);
+ }
+
if (!pdata)
pdata = (struct st_sensors_platform_data *)&default_magn_pdata;
--
2.43.0
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH v2 3/3] iio: magnetometer: st_magn: honour st,fullscale-milligauss DT property
2026-06-16 13:02 ` [PATCH v2 3/3] iio: magnetometer: st_magn: honour st,fullscale-milligauss DT property Herman van Hazendonk
@ 2026-06-17 10:05 ` Andy Shevchenko
2026-06-23 19:29 ` Jonathan Cameron
1 sibling, 0 replies; 12+ messages in thread
From: Andy Shevchenko @ 2026-06-17 10:05 UTC (permalink / raw)
To: Herman van Hazendonk
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
Denis Ciocca, Lars-Peter Clausen, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Denis Ciocca, Linus Walleij,
linux-iio, linux-kernel, llvm, devicetree
On Tue, Jun 16, 2026 at 03:02:06PM +0200, Herman van Hazendonk wrote:
> The ST magnetometer core's common probe hardcodes fs_avl[0] -- the
> highest-sensitivity full-scale supported by the chip -- as the
> starting range. For the LSM303DLH that is +/-1.3 G; for the
> LSM303DLHC and LSM303DLM it is +/-2 G; for the LIS3MDL it is +/-4 G.
>
> That is the right default for "minimal noise floor at a desk", but
> it leaves no margin for boards that pick up appreciable DC bias from
> nearby PCB structures. On the HP TouchPad (apq8060 / tenderloin) the
> LSM303DLH magnetometer is mounted close enough to the surrounding
> power planes that X reads back as the chip's 0xF000 overflow
> sentinel (== -4096 raw, the value the chip publishes when the ADC
> saturates) on every sample at the chip-default range, while Y and Z
> fall well within the +/-1.3 G window.
>
> Parse the st,fullscale-milligauss device-tree property (documented
> separately in dt-bindings/iio/st,st-sensors.yaml) in the
> magnetometer common probe to select the initial fs_avl entry by its
> mg value. The DT binding pins the accepted value set per compatible
> via allOf/if-then enum clauses, so a malformed mg value fails
> dt_binding_check rather than reaching the driver. Sensors with a
> fixed full-scale (fs.addr == 0: LSM303AGR, LIS2MDL, IIS2MDC) have no
> register to switch and the property is rejected outright for them
> in the binding; the parse block is additionally gated on fs.addr as
> defence in depth against stale DTBs.
>
> Per-sensor mg ranges are listed in st_magn_sensors_settings[]. For
> LSM303DLH and LSM303DLHC/DLM the valid values are 1300, 1900, 2500,
> 4000, 4700, 5600 and 8100; for LIS3MDL, LSM9DS1-magn and LSM303C-magn
> they are 4000, 8000, 12000, 16000.
>
> Empirical scale sweep on the HP TouchPad confirmed that on this
> board any fs_avl >= 1 produces non-saturated X readings:
>
> scale (0.001 G/LSB) | X raw Y raw Z raw
> --------------------+-------------------------------
> 1.100 | -4096 44 46 (X saturated)
> 0.855 | -547 37 37 (clean)
> 0.670 | -433 94 103 (clean)
> 0.450 | -266 44 71 (clean)
> 0.400 | -235 34 65 (clean)
> 0.330 | -196 27 56 (clean)
> 0.230 | -145 15 40 (clean)
>
> 2500 mg is the natural choice for tenderloin: comfortably outside
> the saturation regime while keeping useful precision for compass
> applications.
Not sure if we need that big commit message, better to move to the point.
> + propname = "st,fullscale-milligauss";
> + if (mdata->sensor_settings->fs.addr &&
> + device_property_present(parent, propname)) {
> + struct st_sensor_fullscale *fs = &mdata->sensor_settings->fs;
> + u32 fs_mg;
> + int i;
Instead...
> + err = device_property_read_u32(parent, propname, &fs_mg);
> + if (err)
> + return err;
> + for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
for (unsigned int i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
> + if (!fs->fs_avl[i].num)
> + break;
> + if (fs->fs_avl[i].num == fs_mg) {
> + mdata->current_fullscale = &fs->fs_avl[i];
> + break;
> + }
> + }
> + if (mdata->current_fullscale->num != fs_mg)
> + dev_warn(parent, "%s=%u not supported, using %u\n",
> + propname, fs_mg,
> + mdata->current_fullscale->num);
> + }
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH v2 3/3] iio: magnetometer: st_magn: honour st,fullscale-milligauss DT property
2026-06-16 13:02 ` [PATCH v2 3/3] iio: magnetometer: st_magn: honour st,fullscale-milligauss DT property Herman van Hazendonk
2026-06-17 10:05 ` Andy Shevchenko
@ 2026-06-23 19:29 ` Jonathan Cameron
2026-06-23 19:49 ` Andy Shevchenko
1 sibling, 1 reply; 12+ messages in thread
From: Jonathan Cameron @ 2026-06-23 19:29 UTC (permalink / raw)
To: Herman van Hazendonk
Cc: David Lechner, Nuno Sá, Andy Shevchenko, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt, Denis Ciocca,
Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Denis Ciocca, Linus Walleij, linux-iio,
linux-kernel, llvm, devicetree
On Tue, 16 Jun 2026 15:02:06 +0200
Herman van Hazendonk <github.com@herrie.org> wrote:
> The ST magnetometer core's common probe hardcodes fs_avl[0] -- the
> highest-sensitivity full-scale supported by the chip -- as the
> starting range. For the LSM303DLH that is +/-1.3 G; for the
> LSM303DLHC and LSM303DLM it is +/-2 G; for the LIS3MDL it is +/-4 G.
>
> That is the right default for "minimal noise floor at a desk", but
> it leaves no margin for boards that pick up appreciable DC bias from
> nearby PCB structures. On the HP TouchPad (apq8060 / tenderloin) the
> LSM303DLH magnetometer is mounted close enough to the surrounding
> power planes that X reads back as the chip's 0xF000 overflow
> sentinel (== -4096 raw, the value the chip publishes when the ADC
> saturates) on every sample at the chip-default range, while Y and Z
> fall well within the +/-1.3 G window.
>
> Parse the st,fullscale-milligauss device-tree property (documented
> separately in dt-bindings/iio/st,st-sensors.yaml) in the
> magnetometer common probe to select the initial fs_avl entry by its
> mg value. The DT binding pins the accepted value set per compatible
> via allOf/if-then enum clauses, so a malformed mg value fails
> dt_binding_check rather than reaching the driver. Sensors with a
> fixed full-scale (fs.addr == 0: LSM303AGR, LIS2MDL, IIS2MDC) have no
> register to switch and the property is rejected outright for them
> in the binding; the parse block is additionally gated on fs.addr as
> defence in depth against stale DTBs.
>
> Per-sensor mg ranges are listed in st_magn_sensors_settings[]. For
> LSM303DLH and LSM303DLHC/DLM the valid values are 1300, 1900, 2500,
> 4000, 4700, 5600 and 8100; for LIS3MDL, LSM9DS1-magn and LSM303C-magn
> they are 4000, 8000, 12000, 16000.
>
> Empirical scale sweep on the HP TouchPad confirmed that on this
> board any fs_avl >= 1 produces non-saturated X readings:
>
> scale (0.001 G/LSB) | X raw Y raw Z raw
> --------------------+-------------------------------
> 1.100 | -4096 44 46 (X saturated)
> 0.855 | -547 37 37 (clean)
> 0.670 | -433 94 103 (clean)
> 0.450 | -266 44 71 (clean)
> 0.400 | -235 34 65 (clean)
> 0.330 | -196 27 56 (clean)
> 0.230 | -145 15 40 (clean)
>
> 2500 mg is the natural choice for tenderloin: comfortably outside
> the saturation regime while keeping useful precision for compass
> applications.
>
> Assisted-by: Claude:claude-opus-4-7 sparse smatch clang-analyzer coccinelle checkpatch
> Assisted-by: Sashiko:claude-opus-4-7
Hmm. First time I remember seeing Sashiko credited like this. Seems like pretty much
every patch series of any complexity would end up crediting sashiko.
Out of curiosity were you just looking at reports, or were you running it locally to
help with development?
One thing inline.
> Signed-off-by: Herman van Hazendonk <github.com@herrie.org>
> ---
> drivers/iio/magnetometer/st_magn_core.c | 32 ++++++++++++++++++++++++++++++++
> 1 file changed, 32 insertions(+)
>
> diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c
> index ef348d316c00..6f369e8dddea 100644
> --- a/drivers/iio/magnetometer/st_magn_core.c
> +++ b/drivers/iio/magnetometer/st_magn_core.c
> @@ -10,6 +10,7 @@
> #include <linux/kernel.h>
> #include <linux/module.h>
> #include <linux/mutex.h>
> +#include <linux/property.h>
> #include <linux/sysfs.h>
> #include <linux/iio/iio.h>
> #include <linux/iio/sysfs.h>
> @@ -608,6 +609,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev)
> struct st_sensor_data *mdata = iio_priv(indio_dev);
> struct device *parent = indio_dev->dev.parent;
> struct st_sensors_platform_data *pdata = dev_get_platdata(parent);
> + const char *propname;
> int err;
>
> indio_dev->modes = INDIO_DIRECT_MODE;
> @@ -628,6 +630,36 @@ int st_magn_common_probe(struct iio_dev *indio_dev)
> mdata->current_fullscale = &mdata->sensor_settings->fs.fs_avl[0];
> mdata->odr = mdata->sensor_settings->odr.odr_avl[0].hz;
>
> + /*
> + * Skip fixed-FS chips (fs.addr == 0): no register to switch.
> + * The binding rejects the property on these compatibles too;
> + * the gate guards stale DTBs.
Isn't it optional? If so they aren't necessarily stale, people
may have relied on the default - which I now notice isn't specified
in the dt-binding (just replied to that patch).
> + */
> + propname = "st,fullscale-milligauss";
> + if (mdata->sensor_settings->fs.addr &&
> + device_property_present(parent, propname)) {
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH v2 3/3] iio: magnetometer: st_magn: honour st,fullscale-milligauss DT property
2026-06-23 19:29 ` Jonathan Cameron
@ 2026-06-23 19:49 ` Andy Shevchenko
2026-06-24 4:18 ` me
0 siblings, 1 reply; 12+ messages in thread
From: Andy Shevchenko @ 2026-06-23 19:49 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Herman van Hazendonk, David Lechner, Nuno Sá,
Andy Shevchenko, Nathan Chancellor, Nick Desaulniers,
Bill Wendling, Justin Stitt, Denis Ciocca, Lars-Peter Clausen,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Denis Ciocca,
Linus Walleij, linux-iio, linux-kernel, llvm, devicetree
On Tue, Jun 23, 2026 at 08:29:16PM +0100, Jonathan Cameron wrote:
> On Tue, 16 Jun 2026 15:02:06 +0200
> Herman van Hazendonk <github.com@herrie.org> wrote:
>
> > The ST magnetometer core's common probe hardcodes fs_avl[0] -- the
> > highest-sensitivity full-scale supported by the chip -- as the
> > starting range. For the LSM303DLH that is +/-1.3 G; for the
> > LSM303DLHC and LSM303DLM it is +/-2 G; for the LIS3MDL it is +/-4 G.
> >
> > That is the right default for "minimal noise floor at a desk", but
> > it leaves no margin for boards that pick up appreciable DC bias from
> > nearby PCB structures. On the HP TouchPad (apq8060 / tenderloin) the
> > LSM303DLH magnetometer is mounted close enough to the surrounding
> > power planes that X reads back as the chip's 0xF000 overflow
> > sentinel (== -4096 raw, the value the chip publishes when the ADC
> > saturates) on every sample at the chip-default range, while Y and Z
> > fall well within the +/-1.3 G window.
> >
> > Parse the st,fullscale-milligauss device-tree property (documented
> > separately in dt-bindings/iio/st,st-sensors.yaml) in the
> > magnetometer common probe to select the initial fs_avl entry by its
> > mg value. The DT binding pins the accepted value set per compatible
> > via allOf/if-then enum clauses, so a malformed mg value fails
> > dt_binding_check rather than reaching the driver. Sensors with a
> > fixed full-scale (fs.addr == 0: LSM303AGR, LIS2MDL, IIS2MDC) have no
> > register to switch and the property is rejected outright for them
> > in the binding; the parse block is additionally gated on fs.addr as
> > defence in depth against stale DTBs.
> >
> > Per-sensor mg ranges are listed in st_magn_sensors_settings[]. For
> > LSM303DLH and LSM303DLHC/DLM the valid values are 1300, 1900, 2500,
> > 4000, 4700, 5600 and 8100; for LIS3MDL, LSM9DS1-magn and LSM303C-magn
> > they are 4000, 8000, 12000, 16000.
> >
> > Empirical scale sweep on the HP TouchPad confirmed that on this
> > board any fs_avl >= 1 produces non-saturated X readings:
> >
> > scale (0.001 G/LSB) | X raw Y raw Z raw
> > --------------------+-------------------------------
> > 1.100 | -4096 44 46 (X saturated)
> > 0.855 | -547 37 37 (clean)
> > 0.670 | -433 94 103 (clean)
> > 0.450 | -266 44 71 (clean)
> > 0.400 | -235 34 65 (clean)
> > 0.330 | -196 27 56 (clean)
> > 0.230 | -145 15 40 (clean)
> >
> > 2500 mg is the natural choice for tenderloin: comfortably outside
> > the saturation regime while keeping useful precision for compass
> > applications.
> >
> > Assisted-by: Claude:claude-opus-4-7 sparse smatch clang-analyzer coccinelle checkpatch
> > Assisted-by: Sashiko:claude-opus-4-7
> Hmm. First time I remember seeing Sashiko credited like this. Seems like pretty much
> every patch series of any complexity would end up crediting sashiko.
> Out of curiosity were you just looking at reports, or were you running it locally to
> help with development?
I believe it's the second one, because LKML version uses Gemini (as far as I
understand the case). At least that's why I haven't commented on this tag.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/3] iio: magnetometer: st_magn: honour st,fullscale-milligauss DT property
2026-06-23 19:49 ` Andy Shevchenko
@ 2026-06-24 4:18 ` me
0 siblings, 0 replies; 12+ messages in thread
From: me @ 2026-06-24 4:18 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Jonathan Cameron, Herman van Hazendonk, David Lechner,
Nuno Sá, Andy Shevchenko, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt, Denis Ciocca,
Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Denis Ciocca, Linus Walleij, linux-iio,
linux-kernel, llvm, devicetree
On 2026-06-23 21:49, Andy Shevchenko wrote:
> On Tue, Jun 23, 2026 at 08:29:16PM +0100, Jonathan Cameron wrote:
>> On Tue, 16 Jun 2026 15:02:06 +0200
>> Herman van Hazendonk <github.com@herrie.org> wrote:
>>
>> > The ST magnetometer core's common probe hardcodes fs_avl[0] -- the
>> > highest-sensitivity full-scale supported by the chip -- as the
>> > starting range. For the LSM303DLH that is +/-1.3 G; for the
>> > LSM303DLHC and LSM303DLM it is +/-2 G; for the LIS3MDL it is +/-4 G.
>> >
>> > That is the right default for "minimal noise floor at a desk", but
>> > it leaves no margin for boards that pick up appreciable DC bias from
>> > nearby PCB structures. On the HP TouchPad (apq8060 / tenderloin) the
>> > LSM303DLH magnetometer is mounted close enough to the surrounding
>> > power planes that X reads back as the chip's 0xF000 overflow
>> > sentinel (== -4096 raw, the value the chip publishes when the ADC
>> > saturates) on every sample at the chip-default range, while Y and Z
>> > fall well within the +/-1.3 G window.
>> >
>> > Parse the st,fullscale-milligauss device-tree property (documented
>> > separately in dt-bindings/iio/st,st-sensors.yaml) in the
>> > magnetometer common probe to select the initial fs_avl entry by its
>> > mg value. The DT binding pins the accepted value set per compatible
>> > via allOf/if-then enum clauses, so a malformed mg value fails
>> > dt_binding_check rather than reaching the driver. Sensors with a
>> > fixed full-scale (fs.addr == 0: LSM303AGR, LIS2MDL, IIS2MDC) have no
>> > register to switch and the property is rejected outright for them
>> > in the binding; the parse block is additionally gated on fs.addr as
>> > defence in depth against stale DTBs.
>> >
>> > Per-sensor mg ranges are listed in st_magn_sensors_settings[]. For
>> > LSM303DLH and LSM303DLHC/DLM the valid values are 1300, 1900, 2500,
>> > 4000, 4700, 5600 and 8100; for LIS3MDL, LSM9DS1-magn and LSM303C-magn
>> > they are 4000, 8000, 12000, 16000.
>> >
>> > Empirical scale sweep on the HP TouchPad confirmed that on this
>> > board any fs_avl >= 1 produces non-saturated X readings:
>> >
>> > scale (0.001 G/LSB) | X raw Y raw Z raw
>> > --------------------+-------------------------------
>> > 1.100 | -4096 44 46 (X saturated)
>> > 0.855 | -547 37 37 (clean)
>> > 0.670 | -433 94 103 (clean)
>> > 0.450 | -266 44 71 (clean)
>> > 0.400 | -235 34 65 (clean)
>> > 0.330 | -196 27 56 (clean)
>> > 0.230 | -145 15 40 (clean)
>> >
>> > 2500 mg is the natural choice for tenderloin: comfortably outside
>> > the saturation regime while keeping useful precision for compass
>> > applications.
>> >
>> > Assisted-by: Claude:claude-opus-4-7 sparse smatch clang-analyzer coccinelle checkpatch
>> > Assisted-by: Sashiko:claude-opus-4-7
>> Hmm. First time I remember seeing Sashiko credited like this. Seems
>> like pretty much
>> every patch series of any complexity would end up crediting sashiko.
>> Out of curiosity were you just looking at reports, or were you running
>> it locally to
>> help with development?
>
> I believe it's the second one, because LKML version uses Gemini (as far
> as I
> understand the case). At least that's why I haven't commented on this
> tag.
I have the whole toolchain running locally to avoid too many submissions
and
feedback from Sashiko with Gemini after submitting. For small drivers I
can run
Gemini locally as well, usually stick with Claude Opus 4.7 since that's
what I
have a subscription for. For very complicated and large drivers Claude
Opus
tends to time out even with 1 or 2 hour, so I fall back to Claude Haiku
4.5
(which catches quite a few things, but is not as thorough as Opus or
Gemini).
Seeing Sashiko tends to provide different feedback on different rounds,
I try
to only submit when Sashiko and all others are clean.
Hope this clarifies!
Herman
^ permalink raw reply [flat|nested] 12+ messages in thread