Watch
1
0
Fork
You've already forked SouveraineOS
0
SouveraineOS/USB/README.md
Fimeg 18c58fc079 docs: the day viewtop got its package, its titles and its borders
STATE.md was five days stale. It now carries what is on the phone
(viewtop r76, souveraine r333) and the four defects fixed on the glass:
per-window capture was unreachable because quickshell holds wlr handles and
the ext capture source is named by an ext handle with nothing correlating
them; titles were never republished on commit; the border was a filled slab
that relied on the client covering its middle; capture came back flipped.

Also the packaging hole, which was the important one — viewtop's PKGBUILD
existed and appeared in none of packages.yml's build lists, so nothing ever
built it. Half closed: it builds now, but a viewtop commit still does not
trigger a rebuild.

TASK-15 question 1 is answered and closed: dropping the accelerometer claim
took iio-sensor-proxy from 15.3% to 1.1%, sensors overall 17.2% to 2.6% of
a core. Consequence noted against 08(g) — confidence loses accel's +0.3.

New: 54, 55, 56, and 57/58 (Pi dock head, SMB2 OTG boost) with the USB
notes they point at.
2026-08-04 18:18:17 -04:00

10 KiB

USB — the Pixel 3 as a KVM device

Exploration opened 2026-08-04 from Casey: "start exploring the notion of KVM from this thing." This folder holds USB-related design and measurement; the KVM exploration starts here.

What exists, measured on the phone (2026-08-04)

Piece State
Kernel gadget framework CONFIG_USB_GADGET=y, CONFIG_USB_CONFIGFS=y — built in, no modules
HID gadget CONFIG_USB_CONFIGFS_F_HID=y — the keyboard/mouse half of KVM already ships
FunctionFS CONFIG_USB_CONFIGFS_F_FS=y (flexible userspace gadgets, MTP path)
UVC gadget CONFIG_USB_CONFIGFS_F_UVC not set — the video half is the one missing config line
Other functions NCM, ECM, RNDIS, EEM, ACM, serial, OBEX, mass storage; no UAC1/2, no MIDI
Live configfs Two gadgets bound: dbg (acm.GS0, acm.GS1, ncm.usb0) and usb-signaller-developer (ncm.usb0) on UDC a600000.usb (dwc3, super-speed capable, currently high-speed)
Mode switching usb-signaller 0.3.1-3 active (dev mode at boot via usb-signaller-default-mode); blueline-usb-gadget 1.0.0-2; dev mode = NCM usb0 (172.16.42.1) + ACM
Video hardware Venus encoder /dev/video12 + decoder /dev/video13; CAMSS sensors /dev/video0-11; no v4l2loopback
Other packages v4l-utils, libusb, libgusb, libusbmuxd

Host mode — the dock question (2026-08-04, Casey: "if I plug a USB-C dock into the phone right now…")

DeX-style: the phone as the computer, a dock supplying monitors + keyboard

  • mouse. Measured against the running kernel and Google's own vendor DT (sdm845-b1c1-usb.dtsi, LineageOS kernel lineage-22.2):
Ask Verdict Evidence
Multi-monitor (DP alt mode) Unwired in every tree that exists. Google's board DT wires the port as DRP + USB-PD (pmi8998_pdphy, source 5V@0.9A, sink 5V/9V@3A, try-sink) with no DP alt-mode path — no redriver, no typec mux, no altmode node; the only "mux" is test GPIO104 for HS enumeration. Matches Google's official spec (USB 3.1 Gen 1, no video out). The silicon is capable — mainline sdm845.dtsi fully wires mdss_dp → QMP USB3-DP PHY (usb_1_qmpphy_dp_in) — but no sdm845 board in mainline wires it end-to-end either vendor DT (fetched), mainline dtsi (local tree)
USB keyboard/mouse Yes — this is what LineageOS actually gives you. DRP port + PD = real host mode. Our tree pins dr_mode = "peripheral" and usb-signaller holds the port as a gadget, so we don't do it today — but the hardware does vendor DT, our board DT
Via a plain OTG adapter Works — classic USB-A keyboard/flash-drive case standard OTG
Via a Dell dock (WD19…) Host mode: works on LineageOS, one role-switch away on ours. Monitors over DP alt mode: no. Monitors over DisplayLink (software display over USB host): only with a DisplayLink driver per-dock, plug it in
Charging from the dock Yes (PD sink 5V/9V@3A wired in the vendor DT) vendor DT

The correction (2026-08-04): an earlier draft called the DP gap a "connector mux on the board — hardware." That was asserted from memory and is wrong as stated. The evidence: Google wired the port for data+PD and never enabled DP alt mode in any tree, and the hardware question that remains — whether the PCB even routes DP lanes from the QMP PHY to the connector — is unproven in both directions. If LineageOS drove real monitors over the dock, the lanes exist (via DisplayLink, not alt mode). Decisive physical test: a USB-C→HDMI alt-mode adapter (not DisplayLink) with the port in host mode; if the board routes DP, a wired-up kernel has something to talk to.

The daily-driver catch: the USB-C port is the management port — tethering and dev mode (SSH over usb0) die while it is a host. Deliberate, documented mode switch only; cold boots stay Casey's.

Host mode — the live test (recipe, 2026-08-04)

Confirmed on the device: the role switch is real (/sys/class/usb_role/ a600000.usb-role-switch, role currently device), passwordless sudo works, and usb-signaller owns com.meego.usb_moded on the system bus (its modes are all device-side today — Developer/Tethering/MTP — so host mode is a direct sysfs switch, and usb-signaller's restart is the way back).

# 1. give up the gadget first — a bound gadget + host role breaks
echo "" | sudo tee /sys/kernel/config/usb_gadget/usb-signaller-developer/UDC

# 2. switch the port to host
echo host | sudo tee /sys/class/usb_role/a600000.usb-role-switch/role

# 3. plug the dock, then observe:
lsusb
dmesg | tail -30

# 4. back — WiFi SSH survives the whole trip, so this always works:
echo device | sudo tee /sys/class/usb_role/a600000.usb-role-switch/role
sudo systemctl restart usb-signaller    # re-provisions the developer gadget
cat /sys/class/usb_role/a600000.usb-role-switch/role

Gotchas: the dock is self-powered (Dell docks carry their own PSU), so its hub can enumerate even if the phone's VBUS sourcing is weak or absent — the dwc3 node has no vbus-supply, so bus-powered OTG peripherals (plain keyboards) may not power, which is itself a measurement. If the dock's hub enumerates, its keyboard/mouse are just kernel HID input — the shell gets a real keyboard for free. If the dock's monitors ever light up, the DP lanes exist and we go hunt the mux wiring; with no typec/altmode wired, expect nothing from them.

The KVM notion

Plug the phone into another machine's USB port. The phone controls that machine and sees its screen — keyboard, mouse, monitor, in one cable. Two halves, with very different states of readiness:

Input half — HID gadget: already built. The kernel handles the USB HID descriptors; userspace writes 8-byte keyboard reports to /dev/hidg0 and 4-byte mouse reports to /dev/hidg1. This is the half that reaches bootloaders/BIOS (the pelya project proved it) — no video ever reaches a BIOS, so a BIOS-stage KVM is HID plus whatever screen the machine itself has.

Display half — two routes:

  • Route A (works today, zero kernel change): the live NCM link. The controlled machine serves its display over the USB network (VNC/waypipe); the phone shows it in a surface. Touches become HID reports. Worst part is latency, and the link is super-speed-capable.
  • Route B (one config line away): UVC gadget. The phone presents as a UVC camera; the controlled machine runs a "screen-as-webcam" tool (OBS virtual cam and friends) which is the stream source; the phone decodes (Venus decoder ✓) and shows it. The reverse direction also exists: Venus encoder + UVC = the PC sees the phone's own screen as a webcam — an in-the-cable scrcpy.

Prior art (verified)

  • tejado/android-usb-gadget — USB Gadget Tool (F-Droid): configfs roles for keyboard/mouse, FIDO CTAP, CCID, UVC camera; activates gadgets at boot.
  • Android 14 "Device as Webcam"CONFIG_USB_CONFIGFS_F_UVC + configfs recipe (MJPEG 1080p30, dwMaxVideoFrameBufferSize etc.); enabled by default in GKI since android12-5.10. The configfs UVC setup pattern is the one to copy.
  • pelya/android-keyboard-gadget — the classic: /dev/hidg0 keyboard, /dev/hidg1 mouse, hid-gadget-test; works into BIOS/bootloader.
  • Kernel docsusb/gadget_hid.rst (hid_gadget_test) and usb/gadget_uvc.html; the UVC reference app is gitlab.freedesktop.org/camera/uvc-gadget — "queue image buffers from a variety of sources", i.e. the phone-side userspace we would adapt to feed viewtop/compositor frames into the gadget.

Questions to settle, in order

  1. Directions: KVM-into-another-machine only, or also the reverse (phone screen out as webcam)? Both share the UVC config; the userspace differs.
  2. Route A or B first? A proves the whole loop today with no rebuild; B is the "real peripheral" feel but needs a kernel rebuild + cold boot — and that is Casey's call, on the daily driver.
  3. Touch → HID mapping: a KVM mode turns the phone's screen into a touchpad/screen for the target machine. The machinery is the mirror of TASK-50's touch intent — same input-routing problem, other direction.
  4. Where does the mode live? usb-signaller gains a "kvm" mode (profile
    • service), or sessiond owns it as a mode with a verb. The agent angle is real: Ani gets a keyboard/mouse that reaches any host — doctrine §13 says she should have the verb, not a config file.
  5. The kernel path: enabling F_UVC is one config line, but the kernel package still publishes unsigned raw .pkg.tar.zst (TASK-25's repo-add --sign is unbuilt) and installs are cold-boot events.

Next steps (ordered, each measurable)

  1. Prove HID today — provision a HID keyboard function into a scratch gadget on the phone (configfs, no reboot), bind it, write hid-gadget-test key reports, watch the laptop enumerate a second keyboard. One session, no rebuild.
  2. Route A latency test — laptop serves its screen (VNC/waypipe) over the live 172.16.42.1 link; phone displays it; measure.
  3. Route B — config one-liner + rebuild + cold boot (Casey); configfs UVC setup per the AOSP recipe; uvc-gadget userspace fed by a capture surface.
  4. usb-signaller "kvm" mode once the pieces exist, with clean teardown/provision against the dev mode.

Acceptance (measured)

  • Phone plugged into the laptop enumerates as keyboard+mouse; typing from the phone lands in the laptop's focused app.
  • Route A: the laptop's screen renders on the phone with usable latency.
  • Route B: the laptop's virtual-cam tool lists the phone as a camera; the phone shows the stream.
  • Switching modes never strands the daily driver's tethering/dev mode.

Connects to

TASK-25 (kernel package signing — the rebuild path), TASK-50 (her hand on the glass — the touch→HID bridge is the mirror of the touch intent), doctrine §13 (the KVM mode as a verb), usb-signaller (the mode host), souveraine-viewtop (the display surface and capture path).

The buildable work lives here

TASK-57 (the Pi dock head — phone as gadget, Pi as display/input head over NCM) and TASK-58 (host power — the SMB2 OTG boost, one kernel change that unlocks host-mode power, power sharing, and phone→Pi power).