Watch
1
0
Fork
You've already forked SouveraineOS
0
SouveraineOS/docs/tasks/58-host-power-smb2-boost.md

7.2 KiB

TASK 58 — host power: the SMB2 OTG boost

Status: open — investigation first, patch second. 2026-08-06: an existing out-of-tree driver may already cover most of Phase 2 — see the section before Phase 1 and read it before writing register code. Created 2026-08-04, from Casey: "host mode still — what about the phone sharing its power to another device?" One kernel change unlocks host-mode power, power sharing (power-bank mode), and docks without a Pi in between. Repos: Pixel3Arch (kernel build/packaging), the running kernel tree (identify first).

The measured wall

Fact Evidence
Host data works Role flip to host via /sys/class/usb_role/a600000.usb-role-switch; xHCI registered, SuperSpeed, uptime clean — proven live
The missing half is power Plugged a bus-powered NVMe: no LED, zero enumeration (only root hubs on the bus). The phone does not source VBUS
Charger is mainline pmi8998-charger bound by qcom-smbx-charger (qcom,pmi8998-charger @ spmi c440000 pmic@2 charger@1000)
Boost not exposed 41 regulators in /sys/class/regulator, zero boost/otg/vbus — the driver never registers it
No typec /sys/class/typec empty — no tcpm, no Rp on CC, so no C-to-C sink/source detection
dwc3 wires no power usb_1_dwc3 has no vbus-supply; the only VBUS model in mainline is db845c's GPIO fixed regulator with a "FIXME: this regulator is responsible for VBUS on the left USB port"
The hardware exists Google's vendor DT drives the SMB2's 5 V boost device-side (ext_5v_boost + usb0 { google,switch-vbus = <250>; }, pmi8998_pdphy as TYPEC_PORT_DRP default TYPEC_SINK) — the boost is in silicon, hidden behind the SLPI-era vendor stack
Ceiling 5 V/~1.5 A out. USB-PD at 12/20 V lives in the SLPI firmware, which mainline does not run — that wall stands; nothing this task wants needs it

Dylan Van Assche's usb-signaller (the mode host) never touches VBUS either — his design contract is "the kernel owns power": his platforms' kernels auto-switch role on cable plug and source VBUS. The role half of that contract works on blueline; the power half is exactly what this task is.

Most of Phase 2 may already be written — read this before writing any of it

https://github.com/samcday/qcom-pmic-typec-smb2 (from Casey, 2026-08-06). An out-of-tree TCPM driver for PM660 and PMI8998 — the SMB2-generation Type-C block, which is this phone's. Per its README it does CC detection, role control, VCONN and VBUS management, power/data role negotiation, and a PD PHY, and "for PMI8998 it manages the internal SMB2 OTG regulator for source VBUS". It negotiates current limits through qcom_smbx — the same driver this task measured pmi8998-charger bound to.

Line it up against the wall above and it is not adjacent, it is the same thing:

This task's gap What that driver claims
Phase 2.1 — "the silicon is in the SMB2 charger; mainline's driver just never registers it" manages the PMI8998 internal SMB2 OTG regulator for source VBUS
Phase 2.3 — TYPEC/TCPM, Rp on CC so a C-to-C sink sees a source it is a TCPM driver: CC detection, role control, VCONN, PD PHY
Phase 1.2 — read qcom-smbx-charger, does it touch boost/OTG at all integrates with qcom_smbx for current-limit negotiation

Its target list includes Google crosshatch — Pixel 3 XL, blueline's sibling on the same PMI8998 — plus sargo/bonito (PM660) and enchilada/fajita. blueline itself is not named, which is the porting question, not a blocker.

The caveat is the whole reason this is a lead and not a fix: the README says the build matrix and DT artifacts passed static validation and "no phone has run this driver yet." So it is unproven silicon-side by its own author. PD is disabled in every default profile, which matches this task's ceiling finding (PD at 12/20 V lives in SLPI firmware mainline does not run) — nothing here needs PD.

This does not shrink Phase 1; it re-points it. The register archaeology in Phase 1.2/1.4 becomes "read how this driver already does it", and Phase 2 becomes a port-and-test rather than a write. Casey already tracks this upstream for pocketboot, so the fork path is established.

Phase 1 — investigate (do this before any patch)

  1. Find the running kernel's sourceuname -r on the phone, match the tree that built it. The rebuild/packaging path is the known sore spot: kernel.yml has never gone green and flashing is retired (cold boot only — a warm reboot poisons TZ/remoteproc).
  2. Read qcom-smbx-charger — mainline file (likely drivers/power/supply/qcom_smb2.c): does it touch the SMB2 boost/OTG registers at all? What does the vendor switch-vbus actually drive? Pull Google's android_kernel_google_msm-4.9 charger source (the fetched vendor DT already points at pmi8998_gpios 8 for extcon VBUS — the GPIO detects, the boost is PMIC-internal).
  3. .config on the phone/proc/config.gz (or the build config): CONFIG_TYPEC, CONFIG_TYPEC_TCPM, CONFIG_TYPEC_QCOM_PMIC presence. The pmi8998 typec block's mainline driver is drivers/usb/typec/tcpm/qcom_pmic_typec.c — confirm whether it binds pmi8998 or only newer PMICs.
  4. SMB2 register docs — the boost enable is in the charger's register map; find it in the vendor kernel (that 250 in switch-vbus is a register-relative offset hint).

Phase 2 — the patch

  1. smb2: expose the OTG boost as a vbus regulator — the silicon is in the SMB2 charger; mainline's driver just never registers it.
  2. blueline DT: vbus-supply = <&boost> on usb_1_dwc3 — role host then sources 5 V the way every other mainline board sources it.
  3. TYPEC/TCPM + qcom_pmic_typec (or the minimal path if it doesn't bind) — Rp on CC so C-to-C sinks (the Dell dock's cable, USB-C peripherals) see a source. Without this, only legacy USB-A targets via adapter can be powered; with it, proper OTG.

Then the phone in role=host: powered and enumerating. The same lock also lets the phone power the Pi in TASK-57's topology — one cable, no wall wart.

Acceptance (measured on the phone)

  • role=host + a bus-powered device on a USB-A adapter: device lights up and enumerates (/sys/bus/usb/devices), where today it does nothing.
  • The first-test NVMe lights up.
  • /sys/class/regulator shows the vbus/boost regulator and it toggles with the role.
  • Device mode untouched: plugged into a charger, pmi8998-charger still reports online=1 charging, tethering/dev gadget still provision.
  • Role flips stay safe under the WiFi SSH path; usb-signaller restart re-provisions after any manual flip.

Connects to

TASK-57 (the Pi dock head — this unlocks phone→Pi power over the same cable), USB/README.md (the exploration record: evidence table, correction, live role-switch recipe), NET_KERNEL_GAPS.md (the kernel rebuild/reflash path — tier 3's blocker is the same gating), TASK-25 (kernel package signing), usb-signaller (the userspace that will switch roles against the kernel's power contract), and samcday/qcom-pmic-typec-smb2 — the same upstream pocketboot already forks, which is why the porting path is a known one rather than a new relationship.