Appendix · reference

Candidate driver audit, 2026-05-01

Second pass over the in-tree phone drivers against working Linux/OpenBSD drivers.

This pass covered the local drivers that were not the focus of the 2026-04-30 cross-driver audit: rk_tsadc, rk_saradc, rk_efuse, rk_adc_keys, stk3311, magnetometer, mpu6500, and gpio_vibrator. The references were Linux mainline where a driver exists, Rockchip downstream for RK818-family battery/charger behavior, and the OpenBSD/FreeBSD style constraint that bus transfers and GPIO operations must not be hidden inside unsafe interrupt/callout paths.

Fixed in this pass

SeverityDriverFindingResolution
Highsrc/sys/arm64/rockchip/rk_tsadc.cThe driver treated RK3399 data, alarm, and shutdown registers as a v3 block. Linux drivers/thermal/rockchip_thermal.c::rk3399_tsadc_data uses rk_tsadcv3_initialize, but still uses the v2 callbacks for get_temp, set_alarm_temp, and set_tshut_temp.Temperature reads now use TSADCV2_DATA(chn) = 0x20 + chn*4; trip programming now uses TSADCV2_COMP_INT(chn) = 0x30 + chn*4 and TSADCV2_COMP_SHUT(chn) = 0x40 + chn*4.
Highsrc/sys/dev/iicbus/stk3311.cThe proximity threshold registers were set to 0x20/0x22. Linux drivers/iio/light/stk3310.c programs high/low proximity thresholds at 0x06/0x08; our data and flag registers already matched Linux.STK3311_REG_THDH_PS and STK3311_REG_THDL_PS now match the working driver. IRQ-backed near/far transitions should no longer depend on chip defaults.
Mediumsrc/sys/arm64/rockchip/rk_saradc.cThe driver acquired vref-supply and used its voltage, but never enabled the regulator. Linux drivers/iio/adc/rockchip_saradc.c enables vref during probe/resume and disables it during remove/suspend.Attach now enables vref-supply before reading voltage, and detach disables/releases it. Attach-fail and detach paths also disable enabled clocks before release.
Mediumsrc/sys/dev/evdev/gpio_vibrator.cThe driver acquired and enabled vcc-supply, then detached without releasing the regulator handle. It also played uploaded rumble effects even when both magnitudes were zero.Detach now disables and releases vcc-supply, guarded by an enable flag. Zero-magnitude rumble now stops instead of buzzing.
Mediumsrc/sys/dev/evdev/gpio_vibrator.cgpio_pin_set_active() was still called from the callout path under sc->mtx, while Linux drivers/input/misc/gpio-vibra.c uses workqueue context and sleepable GPIO helpers.Callouts now only update desired state and enqueue set_task; GPIO and regulator operations run on taskqueue_thread.
Mediumsrc/sys/dev/evdev/gpio_vibrator.cThe regulator remained enabled for the whole attach lifetime. Linux enables the regulator when vibration starts and disables it when vibration stops.vcc-supply is now optional and is enabled only while the motor is requested active. Stop, timeout, suspend, and detach drive the desired state inactive.
Mediumsrc/sys/dev/iicbus/magnetometer.cmagnetometer_axis_sysctl() held an MTX_DEF mutex across I2C transfers and DELAY() in magnetometer_sample_locked(). Linux AF8133J uses a sleepable mutex around regmap transactions.The sampling lock is now an sx lock, so the sysctl path can serialize single-shot samples without holding a non-sleepable mutex across I2C.
Lowsrc/sys/arm64/rockchip/rk_efuse.cThe failure path after a bad efuse read could release MMIO without disabling/releasing pclk. The success detach path did disable/release it.Attach failure now calls the common detach cleanup path. pclk_enabled records whether the gate was actually enabled before detach disables it.
Lowsrc/sys/dev/iicbus/magnetometer.cThe first probe-read failure returned before destroying the newly initialized lock.That path now goes through the common fail: cleanup label.

Still open

SeverityDriverRiskWhy it matters
Lowsrc/sys/dev/iicbus/mpu6500.cNo register mismatch found in the init sequence against Linux inv_mpu_*; remaining concern is only that the driver is still a minimal polled sysctl implementation.Not a correctness finding from this pass.

Looks reasonable

rk_adc_keys matches Linux’s ADC-key threshold shape: our SARADC helper returns microvolts, so the local thresholds correctly stay in microvolts instead of converting to millivolts like Linux’s IIO path.

rk_efuse matches the Rockchip read sequence: strobe address, wait for finish, copy one word at a time, then shut the controller back down.

mpu6500 did not show an obvious register-order bug in the basic reset, clock, range, and DLPF programming pass.

Next patch candidates

  1. Bench-check the fixed TSADC comparator by heating the SoC past the interrupt threshold only after normal idle/load sysctls look sane.
  2. Bench-check haptic rumble with and without vcc-supply in the DTS, because the software state machine now intentionally mirrors Linux’s power shape.
  3. Turn the MPU-6500 scaffold from sysctl polling into an event/consumer shape once a userspace sensor stack is ready.