#!/bin/bash # detect-usb-role.sh — Detect whether USB-C should be gadget or host. # Writes result to /run/usb-role for consumption by pd-synth-auto.service. # # Detection methods (tried in order): # 1. extcon — USB cable detection (most reliable on Qualcomm) # 2. dwc3 debug — USB controller mode # 3. UDC state — if a UDC is bound as configured, we're in gadget mode # 4. lsusb — if USB devices appear (after host controller init), we're host # # Exit code: 0 if role detected, 1 if unknown set -euo pipefail ROLE_FILE="/run/usb-role" unset ROLE die() { echo "[USB-ROLE] $*" >&2; exit 1; } # --- Method 1: extcon --- check_extcon() { for path in /sys/class/extcon/*/state; do [ -f "$path" ] || continue local state state=$(cat "$path" 2>/dev/null || true) if echo "$state" | grep -q "USB=1"; then echo "gadget" return 0 fi done return 1 } # --- Method 2: dwc3 debugfs --- check_dwc3() { local mode_file for mode_file in /sys/kernel/debug/usb/dwc3*/mode; do [ -f "$mode_file" ] || continue local mode mode=$(cat "$mode_file" 2>/dev/null || true) case "$mode" in *peripheral*) echo "gadget"; return 0 ;; *host*) echo "host"; return 0 ;; esac done return 1 } # --- Method 3: UDC state --- check_udc() { for path in /sys/class/udc/*/state; do [ -f "$path" ] || continue local state state=$(cat "$path" 2>/dev/null || true) case "$state" in configured) echo "gadget"; return 0 ;; esac done return 1 } # --- Method 4: USB host devices --- check_lsusb() { if command -v lsusb &>/dev/null; then local count count=$(lsusb 2>/dev/null | grep -v "Linux Foundation" | wc -l) # If we see non-root-hub devices, likely we're the host if [ "$count" -gt 1 ]; then echo "host" return 0 fi fi return 1 } # Try methods in order ROLE=$(check_extcon || check_dwc3 || check_udc || echo "") # If still unknown, check lsusb after brief delay (host controller needs time) if [ -z "$ROLE" ]; then sleep 2 ROLE=$(check_lsusb || echo "") fi # Write result if [ -n "$ROLE" ]; then echo "$ROLE" > "$ROLE_FILE" echo "[USB-ROLE] Detected: $ROLE" exit 0 else echo "[USB-ROLE] Unknown — defaulting to gadget" echo "gadget" > "$ROLE_FILE" exit 0 fi