[PATCH v2 0/4] Add QST QMC5883P magnetometer driver

Hardik Phalet posted 4 patches 2 months ago
.../iio/magnetometer/qst,qmc5883p.yaml        |  48 +
.../devicetree/bindings/vendor-prefixes.yaml  |   2 +
MAINTAINERS                                   |   7 +
drivers/staging/iio/Kconfig                   |   1 +
drivers/staging/iio/Makefile                  |   1 +
drivers/staging/iio/magnetometer/Kconfig      |  20 +
drivers/staging/iio/magnetometer/Makefile     |   7 +
drivers/staging/iio/magnetometer/TODO         |   5 +
drivers/staging/iio/magnetometer/qmc5883p.c   | 830 ++++++++++++++++++
9 files changed, 921 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/magnetometer/qst,qmc5883p.yaml
create mode 100644 drivers/staging/iio/magnetometer/Kconfig
create mode 100644 drivers/staging/iio/magnetometer/Makefile
create mode 100644 drivers/staging/iio/magnetometer/TODO
create mode 100644 drivers/staging/iio/magnetometer/qmc5883p.c
[PATCH v2 0/4] Add QST QMC5883P magnetometer driver
Posted by Hardik Phalet 2 months ago
This series adds initial Linux support for the QST QMC5883P, a 3-axis
anisotropic magneto-resistive (AMR) magnetometer with a 16-bit ADC that
communicates over I2C. To my knowledge there is no existing upstream
driver for this device.

The driver supports:
  - Raw magnetic field readings on X, Y, and Z axes
  - Four selectable full-scale ranges (±2 G, ±8 G, ±12 G, ±30 G)
  - Configurable output data rate (10, 50, 100, 200 Hz)
  - Configurable oversampling ratio (1, 2, 4, 8)
  - Configurable downsampling ratio (1, 2, 4, 8) via a custom sysfs
    attribute
  - Runtime PM with a 2 s autosuspend delay
  - System suspend/resume via pm_runtime_force_suspend/resume

Regmap with an rbtree cache is used throughout. CTRL_1 and CTRL_2
bit fields are accessed via regmap_field to avoid read-modify-write
races. The STATUS register is marked precious so regmap never reads
it speculatively and clears the DRDY/OVFL bits unexpectedly.

The init sequence on probe is: soft reset → wait 1 ms → deassert
reset → configure SET/RESET control → apply default ODR/OSR/DSR/RNG
→ enter normal mode. This ordering was determined empirically on
hardware to produce reliable, non-zero axis readings.

The driver is placed under drivers/staging/iio/magnetometer/ with a
TODO file tracking the remaining work before it can graduate:
  - Triggered buffer support (iio_triggered_buffer_setup)
  - DRDY interrupt support
  - Self-test implementation

Patches:
  1/4 - dt-bindings: vendor-prefixes: Add 'qst' for QST Corporation
  2/4 - dt-bindings: iio: magnetometer: Add binding for QST QMC5883P
  3/4 - staging: iio: magnetometer: Add QST QMC5883P driver
  4/4 - MAINTAINERS: Add entry for QST QMC5883P magnetometer driver

Testing
-------
Tested on a Raspberry Pi 4B running a mainline kernel (aarch64) with a
GY-271 HM-246 board connected via I2C bus 1. The chip was confirmed to
enumerate at address 0x2C via i2cdetect.

The driver was cross-compiled from Fedora (x86_64) targeting aarch64
and loaded as a module (qmc5883p.ko) with the Device Tree overlay
pointing at i2c1:0x2c.

Verification steps performed:
  - Chip ID register (0x00) reads back 0x80 on probe, confirming the
    correct device is present
  - All three axes (in_magn_x_raw, in_magn_y_raw, in_magn_z_raw) return
    non-zero, stable values when the board is held still and change
    appropriately when the board is rotated
  - in_magn_x_scale (and Y, Z) returns the expected fractional value for
    the default ±8 G range (1/37500000)
  - in_magn_sampling_frequency / _available, in_magn_oversampling_ratio /
    _available, and downsampling_ratio / downsampling_ratio_available all
    read and write correctly; the chip responds without error to each
    valid setting
  - Runtime PM: after 2 s of inactivity the device enters suspend mode
    (MODE = 0x00 confirmed via i2cdump); the next sysfs read correctly
    resumes the device and returns valid data
  - System suspend/resume (echo mem > /sys/power/state) leaves the
    driver in a consistent state; readings remain valid after resume
  - dt_binding_check passes for patch 2/4
  - Kernel builds cleanly with W=1 and no new warnings

Changes in v2:
  - Use get_unaligned_le16() from <linux/unaligned.h> instead of manual
    byte-shifting for deserialising axis data (review feedback)
  - Fix pm_runtime_* calls in downsampling_ratio_store() to use
    data->dev (the i2c parent device) instead of dev (the iio device),
    avoiding PM refcount imbalances (review feedback)
  - Replace manual pm_runtime_disable() devm action with
    devm_pm_runtime_enable(), which avoids a kcfi-violating function
    pointer cast (review feedback)
  - Move chip suspend into a devm action (qmc5883p_suspend_action)
    registered before devm_iio_device_register() so that devres LIFO
    ordering guarantees the IIO interface is fully unregistered before
    the hardware is put to sleep, closing a race window on removal
    (review feedback)
  - Drop qmc5883p_remove() and the .remove hook entirely, as the above
    devm action subsumes it (review feedback)
  - Remove the empty qmc5883p_runtime_idle() stub; passing NULL in
    RUNTIME_PM_OPS already provides the correct default behaviour
  - Add regulator support: use devm_regulator_get_enable_optional() for
    the vdd-supply documented in the dt-binding, with a 50 ms post-enable
    delay per datasheet section 5.3 (PSUP ramp + POR time) (review
    feedback)
  - Reinitialise the chip in qmc5883p_system_resume() via
    qmc5883p_chip_init() followed by regcache_mark_dirty() +
    regcache_sync(), so that the driver recovers correctly if the
    regulator was physically cut during system suspend and POR reset all
    registers (review feedback)

v1: https://lore.kernel.org/all/20260409162308.2590385-1-hardik.phalet@pm.me/

Hardik Phalet (4):
  dt-bindings: vendor-prefixes: Add QST Corporation
  dt-bindings: iio: magnetometer: Add binding for QST QMC5883P
  staging: iio: magnetometer: Add QST QMC5883P driver
  MAINTAINERS: Add entry for QST QMC5883P magnetometer driver

 .../iio/magnetometer/qst,qmc5883p.yaml        |  48 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 MAINTAINERS                                   |   7 +
 drivers/staging/iio/Kconfig                   |   1 +
 drivers/staging/iio/Makefile                  |   1 +
 drivers/staging/iio/magnetometer/Kconfig      |  20 +
 drivers/staging/iio/magnetometer/Makefile     |   7 +
 drivers/staging/iio/magnetometer/TODO         |   5 +
 drivers/staging/iio/magnetometer/qmc5883p.c   | 830 ++++++++++++++++++
 9 files changed, 921 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/magnetometer/qst,qmc5883p.yaml
 create mode 100644 drivers/staging/iio/magnetometer/Kconfig
 create mode 100644 drivers/staging/iio/magnetometer/Makefile
 create mode 100644 drivers/staging/iio/magnetometer/TODO
 create mode 100644 drivers/staging/iio/magnetometer/qmc5883p.c

-- 
2.53.0
Re: [PATCH v2 0/4] Add QST QMC5883P magnetometer driver
Posted by David Lechner 2 months ago
On 4/9/26 4:07 PM, Hardik Phalet wrote:

For a series this be, please wait at least a week for more feedback
before submitting the next revision.

> This series adds initial Linux support for the QST QMC5883P, a 3-axis
> anisotropic magneto-resistive (AMR) magnetometer with a 16-bit ADC that
> communicates over I2C. To my knowledge there is no existing upstream
> driver for this device.
> 
> The driver supports:
>   - Raw magnetic field readings on X, Y, and Z axes
>   - Four selectable full-scale ranges (±2 G, ±8 G, ±12 G, ±30 G)
>   - Configurable output data rate (10, 50, 100, 200 Hz)
>   - Configurable oversampling ratio (1, 2, 4, 8)
>   - Configurable downsampling ratio (1, 2, 4, 8) via a custom sysfs

What is the difference between oversampling and downsampling? I think
we have used some filter attribute for downsampling/decimation in some
other drivers so maybe that could be a good fit?

>     attribute
>   - Runtime PM with a 2 s autosuspend delay
>   - System suspend/resume via pm_runtime_force_suspend/resume
> 
> Regmap with an rbtree cache is used throughout. CTRL_1 and CTRL_2
> bit fields are accessed via regmap_field to avoid read-modify-write
> races. The STATUS register is marked precious so regmap never reads
> it speculatively and clears the DRDY/OVFL bits unexpectedly.
> 
> The init sequence on probe is: soft reset → wait 1 ms → deassert
> reset → configure SET/RESET control → apply default ODR/OSR/DSR/RNG
> → enter normal mode. This ordering was determined empirically on
> hardware to produce reliable, non-zero axis readings.
> 
> The driver is placed under drivers/staging/iio/magnetometer/ with a
> TODO file tracking the remaining work before it can graduate:
>   - Triggered buffer support (iio_triggered_buffer_setup)
>   - DRDY interrupt support
>   - Self-test implementation

These are not reasons to have the driver in staging. It is fine
to have a driver that doesn't implement all functionality. We should
be able to add those features without breaking anything.

Re: [PATCH v2 0/4] Add QST QMC5883P magnetometer driver
Posted by Hardik Phalet 2 months ago
On Sat Apr 11, 2026 at 12:56 AM IST, David Lechner wrote:
> On 4/9/26 4:07 PM, Hardik Phalet wrote:
>
> For a series this be, please wait at least a week for more feedback
> before submitting the next revision.
>
Noted. 

>> This series adds initial Linux support for the QST QMC5883P, a 3-axis
>> anisotropic magneto-resistive (AMR) magnetometer with a 16-bit ADC that
>> communicates over I2C. To my knowledge there is no existing upstream
>> driver for this device.
>>
>> The driver supports:
>>   - Raw magnetic field readings on X, Y, and Z axes
>>   - Four selectable full-scale ranges (±2 G, ±8 G, ±12 G, ±30 G)
>>   - Configurable output data rate (10, 50, 100, 200 Hz)
>>   - Configurable oversampling ratio (1, 2, 4, 8)
>>   - Configurable downsampling ratio (1, 2, 4, 8) via a custom sysfs
>
> What is the difference between oversampling and downsampling? I think
> we have used some filter attribute for downsampling/decimation in some
> other drivers so maybe that could be a good fit?
>
I mentioned my problem with it in my reply to your review for the third
patch in the series. Meanwhile, I will also have a look at how other
drivers are handling it.

>>     attribute
>>   - Runtime PM with a 2 s autosuspend delay
>>   - System suspend/resume via pm_runtime_force_suspend/resume
>>
>> Regmap with an rbtree cache is used throughout. CTRL_1 and CTRL_2
>> bit fields are accessed via regmap_field to avoid read-modify-write
>> races. The STATUS register is marked precious so regmap never reads
>> it speculatively and clears the DRDY/OVFL bits unexpectedly.
>>
>> The init sequence on probe is: soft reset → wait 1 ms → deassert
>> reset → configure SET/RESET control → apply default ODR/OSR/DSR/RNG
>> → enter normal mode. This ordering was determined empirically on
>> hardware to produce reliable, non-zero axis readings.
>>
>> The driver is placed under drivers/staging/iio/magnetometer/ with a
>> TODO file tracking the remaining work before it can graduate:
>>   - Triggered buffer support (iio_triggered_buffer_setup)
>>   - DRDY interrupt support
>>   - Self-test implementation
>
> These are not reasons to have the driver in staging. It is fine
> to have a driver that doesn't implement all functionality. We should
> be able to add those features without breaking anything.
Noted.

Regards,
Hardik
Re: [PATCH v2 0/4] Add QST QMC5883P magnetometer driver
Posted by Andy Shevchenko 2 months ago
On Thu, Apr 09, 2026 at 09:07:11PM +0000, Hardik Phalet wrote:
> This series adds initial Linux support for the QST QMC5883P, a 3-axis
> anisotropic magneto-resistive (AMR) magnetometer with a 16-bit ADC that
> communicates over I2C. To my knowledge there is no existing upstream
> driver for this device.
> 
> The driver supports:
>   - Raw magnetic field readings on X, Y, and Z axes
>   - Four selectable full-scale ranges (±2 G, ±8 G, ±12 G, ±30 G)
>   - Configurable output data rate (10, 50, 100, 200 Hz)
>   - Configurable oversampling ratio (1, 2, 4, 8)
>   - Configurable downsampling ratio (1, 2, 4, 8) via a custom sysfs
>     attribute
>   - Runtime PM with a 2 s autosuspend delay
>   - System suspend/resume via pm_runtime_force_suspend/resume
> 
> Regmap with an rbtree cache is used throughout. CTRL_1 and CTRL_2
> bit fields are accessed via regmap_field to avoid read-modify-write
> races. The STATUS register is marked precious so regmap never reads
> it speculatively and clears the DRDY/OVFL bits unexpectedly.
> 
> The init sequence on probe is: soft reset → wait 1 ms → deassert
> reset → configure SET/RESET control → apply default ODR/OSR/DSR/RNG
> → enter normal mode. This ordering was determined empirically on
> hardware to produce reliable, non-zero axis readings.
> 
> The driver is placed under drivers/staging/iio/magnetometer/ with a
> TODO file tracking the remaining work before it can graduate:
>   - Triggered buffer support (iio_triggered_buffer_setup)
>   - DRDY interrupt support
>   - Self-test implementation
> 
> Patches:
>   1/4 - dt-bindings: vendor-prefixes: Add 'qst' for QST Corporation
>   2/4 - dt-bindings: iio: magnetometer: Add binding for QST QMC5883P
>   3/4 - staging: iio: magnetometer: Add QST QMC5883P driver
>   4/4 - MAINTAINERS: Add entry for QST QMC5883P magnetometer driver
> 
> Testing
> -------
> Tested on a Raspberry Pi 4B running a mainline kernel (aarch64) with a
> GY-271 HM-246 board connected via I2C bus 1. The chip was confirmed to
> enumerate at address 0x2C via i2cdetect.
> 
> The driver was cross-compiled from Fedora (x86_64) targeting aarch64
> and loaded as a module (qmc5883p.ko) with the Device Tree overlay
> pointing at i2c1:0x2c.
> 
> Verification steps performed:
>   - Chip ID register (0x00) reads back 0x80 on probe, confirming the
>     correct device is present
>   - All three axes (in_magn_x_raw, in_magn_y_raw, in_magn_z_raw) return
>     non-zero, stable values when the board is held still and change
>     appropriately when the board is rotated
>   - in_magn_x_scale (and Y, Z) returns the expected fractional value for
>     the default ±8 G range (1/37500000)
>   - in_magn_sampling_frequency / _available, in_magn_oversampling_ratio /
>     _available, and downsampling_ratio / downsampling_ratio_available all
>     read and write correctly; the chip responds without error to each
>     valid setting
>   - Runtime PM: after 2 s of inactivity the device enters suspend mode
>     (MODE = 0x00 confirmed via i2cdump); the next sysfs read correctly
>     resumes the device and returns valid data
>   - System suspend/resume (echo mem > /sys/power/state) leaves the
>     driver in a consistent state; readings remain valid after resume
>   - dt_binding_check passes for patch 2/4
>   - Kernel builds cleanly with W=1 and no new warnings

This driver is rather huge. There are mistakes you made in the process, though:
- never send a new version for such a code (amount and complexity) earlier than
a week; give others a chance to review
- do not put driver to staging, why?
- the investigation is rather poor about existence of the driver — make sure
there is no compatible (by register layout) driver in IIO or even outside it
(for ADCs it might appear as HWMON [drivers/hwmon] or INPUT [drivers/input]
 in some cases)

-- 
With Best Regards,
Andy Shevchenko


Re: [PATCH v2 0/4] Add QST QMC5883P magnetometer driver
Posted by Hardik Phalet 2 months ago
On Fri Apr 10, 2026 at 10:06 AM IST, Andy Shevchenko wrote:
> On Thu, Apr 09, 2026 at 09:07:11PM +0000, Hardik Phalet wrote:
>> Verification steps performed:
>>   - Chip ID register (0x00) reads back 0x80 on probe, confirming the
>>     correct device is present
>>   - All three axes (in_magn_x_raw, in_magn_y_raw, in_magn_z_raw) return
>>     non-zero, stable values when the board is held still and change
>>     appropriately when the board is rotated
>>   - in_magn_x_scale (and Y, Z) returns the expected fractional value for
>>     the default ±8 G range (1/37500000)
>>   - in_magn_sampling_frequency / _available, in_magn_oversampling_ratio /
>>     _available, and downsampling_ratio / downsampling_ratio_available all
>>     read and write correctly; the chip responds without error to each
>>     valid setting
>>   - Runtime PM: after 2 s of inactivity the device enters suspend mode
>>     (MODE = 0x00 confirmed via i2cdump); the next sysfs read correctly
>>     resumes the device and returns valid data
>>   - System suspend/resume (echo mem > /sys/power/state) leaves the
>>     driver in a consistent state; readings remain valid after resume
>>   - dt_binding_check passes for patch 2/4
>>   - Kernel builds cleanly with W=1 and no new warnings
>
> This driver is rather huge. There are mistakes you made in the process, though:
> - never send a new version for such a code (amount and complexity) earlier than
> a week; give others a chance to review
Noted, Andy. I will take care of it from now on.

> - do not put driver to staging, why?
There are some functionality missing. But it has since been made clear
to me that that is not a valid reason. I will move to `drivers/iio`
in the next patch series.

> - the investigation is rather poor about existence of the driver — make sure
> there is no compatible (by register layout) driver in IIO or even outside it
> (for ADCs it might appear as HWMON [drivers/hwmon] or INPUT [drivers/input]
>  in some cases)
I will dig a bit deeper into this. But I could not find any thing
realted to the device I am working on (qmc5883p). 

There is a device hmc5843_core.c that already handles HMC5883L. But the
register layout is different, field ranges, gain encoding etc. are
different and I think warrants a separate driver. Other than that I
could not find something related to device I am working on. 

I will carefully go through HWMON and INPUT too, but do you have a
strategy to help me find somehting similar? It will be very useful.
Would `grep`-ing for 5883 and QST be a right starting point?

>
> --
> With Best Regards,
> Andy Shevchenko

Thank you for the review Andy, I appreciate your time!

Regards,
Hardik

- 
Re: [PATCH v2 0/4] Add QST QMC5883P magnetometer driver
Posted by Andy Shevchenko 2 months ago
On Sun, Apr 12, 2026 at 10:27:36AM +0000, Hardik Phalet wrote:
> On Fri Apr 10, 2026 at 10:06 AM IST, Andy Shevchenko wrote:
> > On Thu, Apr 09, 2026 at 09:07:11PM +0000, Hardik Phalet wrote:

...

> > - the investigation is rather poor about existence of the driver — make sure
> > there is no compatible (by register layout) driver in IIO or even outside it
> > (for ADCs it might appear as HWMON [drivers/hwmon] or INPUT [drivers/input]
> >  in some cases)
> I will dig a bit deeper into this. But I could not find any thing
> realted to the device I am working on (qmc5883p). 

It might be that there is a driver with smaller amount of registers available
(or bigger) or some features missing...

> There is a device hmc5843_core.c that already handles HMC5883L. But the
> register layout is different, field ranges, gain encoding etc. are
> different and I think warrants a separate driver. Other than that I
> could not find something related to device I am working on. 

This paragraph is a particular case, something like this should be put in the
summary in your case if the brand new driver is needed.

> I will carefully go through HWMON and INPUT too, but do you have a
> strategy to help me find somehting similar? It will be very useful.
> Would `grep`-ing for 5883 and QST be a right starting point?

Grep for words that are case insensitive values of the registers offsets.
This can be done recursively, then you need to apply some heuristics on
the definition names to see if they are about the same thing (or similar)
or not at all.

-- 
With Best Regards,
Andy Shevchenko