Appendix · reference

Voltafield AF8133J magnetometer

Compass on DTS i2c4 addr 0x1c; polled raw-axis sysctls.

Identity

PartVoltafield AF8133J
Role3-axis magnetometer (compass)
Bus / addressDTS &i2c4 addr 0x1c; FreeBSD logs shifted addr 0x38 on iicbus3
GPIO / IRQReset on GPIO1_A1 per mainline Linux DTS; DRDY IRQ delivery is not wired yet
DatasheetAF8133J (Voltafield, datasheet behind login); Linux driver and DTS are the public references
Pine64 wikiPinePhone Pro — Sensors
Schematicsheet 11 (sensor cluster on i2c4, shared with MPU-6500)

Status — ● working

Verified live on 2026-05-03 (kernel #141, head 3b6cb7b):

magnetometer0: <PinePhone Pro magnetometer (AF8133J)> at addr 0x38 on iicbus3
magnetometer0: af8133j detected (reg[0x01]=0x00 reg[0x00]=0x5e)
$ sysctl dev.magnetometer.0
dev.magnetometer.0.x_raw: -1553
dev.magnetometer.0.y_raw: -211
dev.magnetometer.0.z_raw: 992
dev.magnetometer.0.raw_id_reg00: 94      # 0x5e — AF8133J product code
dev.magnetometer.0.chip_variant: af8133j
dev.magnetometer.0.last_sample_error: 0

The earlier “partial” status hid two real bugs that took the 2026-05-02 dtb refresh and a follow-up driver fix to clear:

  1. Stale dtb on the phone. The compass node only entered the PinePhone Pro DTS on 2026-04-30 ( 83ab0d0 magnetometer: i2c4@0x0c probe scaffold (AK09911 vs AF8133J) ), but the phone was still booting the Apr-22 base dtb that lacked it. Without the DT node, FreeBSD’s iicbus probe never reached the driver. Redeploying /boot/dtb/rk3399-pinephone-pro.dtb fixed that half.
  2. Reset-gpio polarity. AF8133J holds its I2C interface in NACK while the active-low reset line is asserted, so the driver’s WIA read returned errno 2 (IIC_ENOACK). The reset-gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_LOW> property in DT was being ignored — the driver did no GPIO setup at all. 31c69f6 magnetometer: deassert reset-gpio before first I2C read added the lookup; 3b6cb7b magnetometer: fix reset-gpio polarity in attach pulse fixed the polarity (the release sequence has to end with set_active(false) for an active-low pin, otherwise the chip stays held in reset).

Earlier project notes mixed the original PinePhone’s AK09911/LIS3MDL alternatives into the PinePhone Pro table. The PPP wiki and mainline Linux DTS identify the populated part as AF8133J at &i2c4/0x1c, so the local DTS uses compatible = "voltafield,af8133j" and reg = <0x1c>. The driver still keeps the AK09911 detection arm as harmless fallback code, but the bench predicate for this phone is AF8133J attach and a moving raw sample:

sysctl dev.magnetometer.0.chip_variant
sysctl dev.magnetometer.0.x_raw dev.magnetometer.0.y_raw dev.magnetometer.0.z_raw
sysctl dev.magnetometer.0.last_status dev.magnetometer.0.last_sample_error

The implementation deliberately stays in polling mode for first bring-up. Single-shot samples are serialized with a sleepable sx lock so the I2C transfer path is not hidden under a default mutex. The DRDY GPIO interrupt path can land after the raw samples move when the phone rotates.

Validation state: working on hardware. The PinePhone Pro boot on 2026-05-03 identified the populated part as AF8133J and returned raw XYZ samples (x_raw=-1553, y_raw=-211, z_raw=992) with the expected chip_variant=af8133j. Remaining work is calibration and event delivery, not first samples.

Driver

The AF8133J needs a periodic temperature-compensation kick. It can report ready samples on a DRDY GPIO; the first FreeBSD pass polls instead at modest power cost.

Parity verification

The artifact set is small but high-signal — it tells us whether the chip answers on the documented address. mise run debug:sensors:phone captures these magnetometer predicates in the same read-only receipt as the proximity, accel/gyro, thermal, and eFuse sysctls:

Implementation plan

The remaining work is now calibration and event delivery, not first samples:

  1. AF8133J path:

    • Raw sysctls perform software reset, select the Linux-default 12-gauss range at attach, put the chip into work state, poll STATUS.ACQ, and read 6 bytes from OUT.
    • Next: add scaled values using Linux’s range table and calibrate against known orientations.
    • Reference: drivers/iio/magnetometer/af8133j.c.
  2. Compass heading in userlandatan2(my, mx) * 180/π, tilt-compensated using the MPU-6500 accelerometer once both sensors are calibrated against a known orientation.

  3. DRDY GPIO IRQ wiring — the DTS currently mirrors mainline Linux’s reset-gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_LOW>. Add a real interrupt resource only after the polled path is proven and the AF8133J DRDY wiring is confirmed.