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)
- Find the running kernel's source —
uname -ron the phone, match the tree that built it. The rebuild/packaging path is the known sore spot:kernel.ymlhas never gone green and flashing is retired (cold boot only — a warm reboot poisons TZ/remoteproc). - Read
qcom-smbx-charger— mainline file (likelydrivers/power/supply/qcom_smb2.c): does it touch the SMB2 boost/OTG registers at all? What does the vendorswitch-vbusactually drive? Pull Google'sandroid_kernel_google_msm-4.9charger source (the fetched vendor DT already points atpmi8998_gpios 8for extcon VBUS — the GPIO detects, the boost is PMIC-internal). .configon the phone —/proc/config.gz(or the build config):CONFIG_TYPEC,CONFIG_TYPEC_TCPM,CONFIG_TYPEC_QCOM_PMICpresence. The pmi8998 typec block's mainline driver isdrivers/usb/typec/tcpm/qcom_pmic_typec.c— confirm whether it binds pmi8998 or only newer PMICs.- SMB2 register docs — the boost enable is in the charger's register
map; find it in the vendor kernel (that
250inswitch-vbusis a register-relative offset hint).
Phase 2 — the patch
- smb2: expose the OTG boost as a vbus regulator — the silicon is in the SMB2 charger; mainline's driver just never registers it.
- blueline DT:
vbus-supply = <&boost>onusb_1_dwc3— rolehostthen sources 5 V the way every other mainline board sources it. - 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/regulatorshows the vbus/boost regulator and it toggles with the role.- Device mode untouched: plugged into a charger,
pmi8998-chargerstill reportsonline=1charging, 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.