Devicetree
 help / color / mirror / Atom feed
From: me@herrie.org
To: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: Herman van Hazendonk <github.com@herrie.org>,
	jic23@kernel.org, linusw@kernel.org, denis.ciocca@st.com,
	robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
	dlechner@baylibre.com, nuno.sa@analog.com, andy@kernel.org,
	sanjayembeddedse@gmail.com, maudspierings@gocontroll.com,
	linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 3/3] iio: magnetometer: st_magn: honour st,fullscale-mg DT property
Date: Mon, 15 Jun 2026 14:40:03 +0200	[thread overview]
Message-ID: <75adda02cb8faf9d99953ad4fdcbf961@herrie.org> (raw)
In-Reply-To: <aiMMzSf8-C9fTlWW@ashevche-desk.local>

On 2026-06-05 19:52, Andy Shevchenko wrote:
> On Fri, Jun 05, 2026 at 12:08:43PM +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-mg 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 driver
>> tolerates an unknown / unsupported value by falling back to the chip
>> default and warning, so the property is purely additive -- existing
>> in-tree DTSes are unaffected.
>> 
>> Per-sensor mg ranges are listed in st_magn_sensors_settings[]. For
>> LSM303DLH the valid values are 1300, 1900, 2500, 4000, 4700, 5600
>> and 8100; for LSM303DLHC they are 1300, 1900, 2500, 4000, 4700, 5600,
>> 8100 (same code path); for LIS3MDL they are 4000, 8000, 12000, 16000;
>> and so on. Sensors with a fixed full-scale (fs.addr == 0) simply
>> ignore the property.
>> 
>> 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.
> 
> ...
> 
>> +	{
> 
> Oh, no. Use
> 
> 	const char *propname;
> 	...
> 	propname = "st,fullscale-mg";
> 	if (device_property_present(..., propname)) {
> 		struct st_sensor_fullscale *fs = &mdata->sensor_settings->fs;
> 		u32 fs_mg;
> 
> 		ret = device_property_read_u32(parent, propname, &fs_mg);
> 		if (ret)
> 			return ret;
> 
> 		...
> 	}
> 
> instead.

Hi Andy,

Done in v2: propname lifted to a local, presence check first, 
device_property_read_u32()
failure now return errs rather than silently skipping, and the dev_warn 
format string uses
%s, propname so the name is in exactly one place.
> 
>> +		u32 fs_mg;
> 
>> +		if (!device_property_read_u32(parent, "st,fullscale-mg",
>> +					      &fs_mg)) {
>> +			struct st_sensor_fullscale *fs =
>> +				&mdata->sensor_settings->fs;
>> +			int i;
>> +
>> +			for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
>> +				if (!fs->fs_avl[i].num)
>> +					break;
> 
> This is strange. What's the point to go via the whole table? Does it 
> have gaps?
> 
>> +				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,
>> +					 "st,fullscale-mg=%u not supported, using %u\n",
> 
> Also use %s and propname.
> 
>> +					 fs_mg, mdata->current_fullscale->num);
>> +		}
>> +	}
It's not gaps: fs_avl[] is a fixed-size array of 
ST_SENSORS_FULLSCALE_AVL_MAX (currently 8)
entries, but different magnetometers fill in different prefix lengths up 
to that cap.
LSM303DLH uses 7 entries; LSM303DLHC uses 7; LIS3MDL only uses 4.

The if (!fs->fs_avl[i].num) break; is the existing sentinel convention 
used elsewhere in this
file (see st_sensors_set_fullscale_by_gain() / st_sensors_match_fs()) so 
the loop terminates at
the first zero .num. I kept the same convention so future sensors with 
shorter ranges just work;
happy to switch to a ARRAY_SIZE() + is_terminator() helper if you'd 
prefer, but that would be a
wider cleanup than this patch warrants.

Thanks,
Herman

      reply	other threads:[~2026-06-15 12:47 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-05 10:08 [PATCH 0/3] iio: lsm303dlh-magn: endianness + boot-time fullscale selection Herman van Hazendonk
2026-06-05 10:08 ` [PATCH 1/3] iio: common: st_sensors: honour channel endianness in read_axis_data Herman van Hazendonk
2026-06-05 17:47   ` Andy Shevchenko
2026-06-15 12:41     ` me
2026-06-14 18:39   ` Jonathan Cameron
2026-06-15 11:12     ` me
2026-06-05 10:08 ` [PATCH 2/3] dt-bindings: iio: st,st-sensors: add st,fullscale-mg Herman van Hazendonk
2026-06-05 16:07   ` Conor Dooley
2026-06-07 22:54   ` Linus Walleij
2026-06-14 18:44   ` Jonathan Cameron
2026-06-15 11:16     ` me
2026-06-21 12:41       ` Jonathan Cameron
2026-06-05 10:08 ` [PATCH 3/3] iio: magnetometer: st_magn: honour st,fullscale-mg DT property Herman van Hazendonk
2026-06-05 17:52   ` Andy Shevchenko
2026-06-15 12:40     ` me [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=75adda02cb8faf9d99953ad4fdcbf961@herrie.org \
    --to=me@herrie.org \
    --cc=andriy.shevchenko@intel.com \
    --cc=andy@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=denis.ciocca@st.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dlechner@baylibre.com \
    --cc=github.com@herrie.org \
    --cc=jic23@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=linusw@kernel.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maudspierings@gocontroll.com \
    --cc=nuno.sa@analog.com \
    --cc=robh@kernel.org \
    --cc=sanjayembeddedse@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox