.../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
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
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.
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
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
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 -
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
© 2016 - 2026 Red Hat, Inc.