Appendix · reference

Rockchip RK818 (PMIC)

Multi-function PMIC: regulators, RTC, charger, OTG boost, fuel gauge

Identity

PartRockchip RK818
RoleSystem PMIC — DCDC and LDO regulators, RTC, USB / DC charger, battery fuel gauge, 5 V OTG boost (boost_otg + otg_switch), SWITCH2 switched output
Bus / addressi2c0 addr 0x1c
GPIO / IRQPMIC IRQ on the RK3399 PMU domain; charger and battery interrupts surface through the same line
DatasheetRK818 datasheet (community archive)
Pine64 wikiPinePhone Pro hardware
Schematicsheets 9–10 (PMIC, regulators, charger)

Status — ● working

Regulators come up at boot via U-Boot’s PMIC defaults; the RTC, charger, and battery driver all attach. Charging now works after 8da75ba rk818: clear OTG/SWITCH2 in DCDC_EN — battery now charges from PD cleared DCDC_EN_REG[7] (OTG_EN) at init — the chip’s own 5 V boost was back-driving VBUS while the PD source was sourcing it, parking the charger FSM at “discharging” even with CHRG_EN set. The input-current limit follows the FUSB302 PD contract ( ef6035e fusb302+rk818: apply PD-negotiated input current to the charger ). SWITCH2_EN is deliberately separate from Type-C role handling after the Linux parity cleanup in 4d190f3 rk818: decouple SWITCH2 from Type-C OTG . The latest cleanup puts that handoff behind the local power_supply coordinator instead of letting fusb302(4) include RK818 headers directly ( 6469f2e power: add charger coordination layer ), and the prepared-sink contract from 06348c6 fusb302: prepare sink path after TCPC attach + 9041600 rk818: hold SWITCH2 through TCPC probe + 544bd86 rk818: preserve prepared Type-C sink path keeps DCDC_EN at 0x3f across the IRQ-driven enforce path so PD Request TX succeeds on both CC orientations.

Verified live on 2026-05-03 (kernel #138+, head 544bd86 at the relevant boot): with a 65 W PD wall on CC1, dev.fusb302.0.negotiated_voltage_mv: 9000, dev.rk818_pmu.0.rk818_hw_input_current_limit_ma: 3000, USB_CTRL 0xcb, DCDC_EN held at 0x3f across rk818[irq]: enforced sink mode (mask=0xc0, DCDC_EN 0xff->0x3f). Battery rate goes positive (charging) once the input-limit is raised. PMIC IRQ migration ( d1b3a0b rk818: drive charger updates from PMIC IRQ ) means charger state updates are event-driven rather than polled.

What’s missing: no suspend/resume integration; TSADC readout and soft caps are now sane, but hardware thermal trips remain separate work and not RK818-side. The noisy decoded rk818[poll] register dump is gone from the normal path; decoded state is now on-demand via hw.acpi.battery.charger_dump=1 or dev.rk818_pmu.0.rk818_debug=1. The fuel-gauge sysctls now expose chip-reported state (see Parity verification below), and the ACPI compatibility status bit is fixed (2 means charging).

Driver

Linux splits this chip across MFD core + regulator + battery + charger. We collapse it into a single battery + charger driver and let U-Boot own the regulators, which is enough for boot but means we don’t have runtime regulator control. The charger / fuel-gauge logic is loosely modelled on the Linux drivers but the FSM interpretation in rk818-charger-not-actually-charging documents how much had to be relearned by hand because the chip’s actual behaviour diverged from both Megi’s downstream driver and the public datasheet.

The decoupling of OTG and SWITCH2 (cross-driver audit §fusb302) is a prerequisite for any future source-role / DP-alt-mode work.

Open work

Parity verification

The fuel-gauge readout refreshes once per second from rk818_battery_thread and caches values for sysctl readers. Compare against a Linux PinePhone Pro image’s /sys/class/power_supply/rk818-battery/* files (note: Linux reports voltage/current in microvolts/microamps, FreeBSD here in mV/mA).

FreeBSD (dev.rk818_pmu.0.*)Linux (/sys/class/power_supply/rk818-battery/*)Expected
rk818_voltage_mvvoltage_now / 10003000–4350 mV depending on SoC
rk818_current_macurrent_now / 1000sign and magnitude move with charge/discharge state
rk818_capacity_pctcapacity0–100 from the current voltage approximation
rk818_onlineUSB online / present properties1 when SUP_STS.USB_EXS and SUP_STS.USB_EFF are both set
rk818_statusstatuscharging / not-charging / full / fault strings
rk818_input_current_limit_mainput current limitrequested Type-C / PD limit
rk818_hw_input_current_limit_mainput current limitRK818-supported value actually written to USB_CTRL[3:0]

Falsifiers