diff --git a/projects/ArchR/packages/hardware/quirks/devices/R36S Clone/001-device_config b/projects/ArchR/packages/hardware/quirks/devices/R36S Clone/001-device_config index 4f7808b9af..2170dab502 100755 --- a/projects/ArchR/packages/hardware/quirks/devices/R36S Clone/001-device_config +++ b/projects/ArchR/packages/hardware/quirks/devices/R36S Clone/001-device_config @@ -5,8 +5,7 @@ # Minimal per-device config: wire up the temperature sensors so System # Information (archr-info) and EmulationStation show CPU/GPU temps. The # quirks loader matches the folder name against /proc/device-tree/model -# exactly, so this folder name MUST equal the DTS `model` string. Audio -# routing and LED config are intentionally left to the working defaults. +# exactly, so this folder name MUST equal the DTS `model` string. cat </storage/.config/profile.d/001-device_config # LED nodes use color+function (no label), so sysfs is blue:power. # Surfaces the DISABLE POWER LED switch in ES (the var is already in @@ -14,6 +13,13 @@ cat </storage/.config/profile.d/001-device_config # invisible on every device). DEVICE_PWR_LED_CONTROL="true" DEVICE_POWER_LED="blue:power" +# V20-era clone boards route the speaker through the external amp like +# the Soysauce (the eeclone DTS ships the rk817-sound-amplified card), +# so the playback mux and the jack input device must be wired up or the +# speaker stays silent (Arch-R#35, config validated by reporters). +DEVICE_PLAYBACK_PATH_SPK="SPK" +DEVICE_PLAYBACK_PATH_HP="HP" +DEVICE_HEADPHONE_DEV="/dev/input/by-path/platform-rk817-sound-amplified-event" DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone0/temp" DEVICE_GPU_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone1/temp" CONF diff --git a/projects/ArchR/packages/linux-drivers/RTL8188EUS/udev.d/99-rtl8188eus.rules b/projects/ArchR/packages/linux-drivers/RTL8188EUS/udev.d/99-rtl8188eus.rules index 6be61e8de3..0732e25f17 100644 --- a/projects/ArchR/packages/linux-drivers/RTL8188EUS/udev.d/99-rtl8188eus.rules +++ b/projects/ArchR/packages/linux-drivers/RTL8188EUS/udev.d/99-rtl8188eus.rules @@ -1,11 +1,22 @@ # Force the out-of-tree r8188eu driver for RTL8188EUS dongles, instead # of the in-tree rtl8xxxu (which scans but can't complete WPA2 4-way -# handshake on this chip — see archr-linux/Arch-R#19). +# handshake on this chip, see archr-linux/Arch-R#19). # # rtl8xxxu is loaded for many other RTL chips and we don't want to # blacklist it globally. Instead, this rule catches the 8188EUS USB -# IDs at hotplug time, unbinds rtl8xxxu from the interface, and -# (re)loads 8188eu. +# IDs and moves the network interface over to 8188eu. +# +# The first shipped version of this rule matched the usb_device event +# and echoed the device name (e.g. "1-1") into rtl8xxxu's unbind node. +# That never worked: USB drivers bind to the *interface* ("1-1:1.0"), +# and at usb_device add time no driver is bound yet anyway, while a +# plain modprobe never rebinds an interface another driver already +# claimed. Match the usb_interface event instead: by the time RUN +# fires the kernel has finished its synchronous bind, so pulling the +# interface off rtl8xxxu (a no-op when it lost the probe race) and +# writing it into 8188eu's bind node is deterministic. %k is the +# interface name, substituted by udev itself, so no shell expansion +# or `$$` escaping is involved. # # Known RTL8188EUS USB IDs (vendor:product): # 0bda:0179 Realtek RTL8188EUS Wireless Adapter @@ -16,25 +27,17 @@ ACTION!="add", GOTO="rtl8188eus_end" SUBSYSTEM!="usb", GOTO="rtl8188eus_end" -ENV{DEVTYPE}!="usb_device", GOTO="rtl8188eus_end" +ENV{DEVTYPE}!="usb_interface", GOTO="rtl8188eus_end" -ATTR{idVendor}=="0bda", ATTR{idProduct}=="0179", GOTO="rtl8188eus_swap" -ATTR{idVendor}=="0bda", ATTR{idProduct}=="8179", GOTO="rtl8188eus_swap" -ATTR{idVendor}=="0bda", ATTR{idProduct}=="8189", GOTO="rtl8188eus_swap" -ATTR{idVendor}=="7392", ATTR{idProduct}=="7811", GOTO="rtl8188eus_swap" -ATTR{idVendor}=="056e", ATTR{idProduct}=="4008", GOTO="rtl8188eus_swap" +# ATTRS{} walks up to the parent usb_device for the vendor/product IDs. +ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="0179", GOTO="rtl8188eus_swap" +ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="8179", GOTO="rtl8188eus_swap" +ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="8189", GOTO="rtl8188eus_swap" +ATTRS{idVendor}=="7392", ATTRS{idProduct}=="7811", GOTO="rtl8188eus_swap" +ATTRS{idVendor}=="056e", ATTRS{idProduct}=="4008", GOTO="rtl8188eus_swap" GOTO="rtl8188eus_end" LABEL="rtl8188eus_swap" -# Unbind apenas a interface USB específica do rtl8xxxu (não tira o -# módulo do kernel — outros dongles RTL podem estar conectados ao -# mesmo tempo); depois carrega 8188eu, que vai bindar pela alias -# table. ${BUSNUM} e ${DEVNUM} são fornecidos por udev e identificam -# o device USB sem ambiguidade. -# udev parses `$` in RUN as its own specifier prefix, so shell variables -# must be doubled (`$$` -> literal `$`). The previous single-`$` form made -# udev reject the whole rule ("invalid substitution type"), so the rebind -# never ran and the dongle was left on rtl8xxxu by luck of probe order. -RUN+="/usr/bin/sh -c 'busid=$$(basename %p); for drv in /sys/bus/usb/drivers/rtl8xxxu; do [ -e \"$$drv/$$busid\" ] && echo \"$$busid\" > \"$$drv/unbind\" 2>/dev/null; done; modprobe 8188eu 2>/dev/null'" +RUN+="/usr/bin/sh -c 'modprobe 8188eu; echo %k > /sys/bus/usb/drivers/rtl8xxxu/unbind 2>/dev/null; echo %k > /sys/bus/usb/drivers/8188eu/bind 2>/dev/null; exit 0'" LABEL="rtl8188eus_end" diff --git a/projects/ArchR/packages/sysutils/system-utils/sources/scripts/headphone_sense b/projects/ArchR/packages/sysutils/system-utils/sources/scripts/headphone_sense index 47009f00b6..9c6fd784a5 100755 --- a/projects/ArchR/packages/sysutils/system-utils/sources/scripts/headphone_sense +++ b/projects/ArchR/packages/sysutils/system-utils/sources/scripts/headphone_sense @@ -11,8 +11,15 @@ if [[ ${AUDIO_MANAGEMENT} == "UCM" ]]; then exit 0 fi -# Switch to headphones if we have them already connected at boot -GPIO=$(cat /sys/class/gpio/gpio${DEVICE_JACK}/value) +# Switch to headphones if we have them already connected at boot. +# DEVICE_JACK is a legacy gpio sysfs number; mainline kernels don't +# expose /sys/class/gpio, so only trust it when the node really exists +# and otherwise start from the speaker path. +if [ -n "${DEVICE_JACK}" ] && [ -e "/sys/class/gpio/gpio${DEVICE_JACK}/value" ]; then + GPIO=$(cat /sys/class/gpio/gpio${DEVICE_JACK}/value) +else + GPIO=1 +fi [[ "$GPIO" == "0" ]] && set_setting "audio.device" "headphone" || set_setting "audio.device" "speakers" ### Set the default audio path, needed for some devices @@ -24,10 +31,10 @@ fi STARTUP_DEVICE=$(get_setting "audio.device") case "${2}" in "headphone") - amixer -c 0 -M cset name=${DEVICE_PLAYBACK_PATH} ${DEVICE_PLAYBACK_PATH_HP} + amixer -c 0 -M cset "name=${DEVICE_PLAYBACK_PATH}" "${DEVICE_PLAYBACK_PATH_HP}" ;; "auto"|"speakers"|*) - amixer -c 0 -M cset name=${DEVICE_PLAYBACK_PATH} ${DEVICE_PLAYBACK_PATH_SPK} + amixer -c 0 -M cset "name=${DEVICE_PLAYBACK_PATH}" "${DEVICE_PLAYBACK_PATH_SPK}" ;; esac @@ -42,11 +49,11 @@ HP_OFF='*(SW_HEADPHONE_INSERT), value 1*' evtest "${DEVICE}" | while read line; do case $line in (${HP_ON}) - amixer -c 0 cset name=${DEVICE_PLAYBACK_PATH} ${DEVICE_PLAYBACK_PATH_HP} + amixer -c 0 cset "name=${DEVICE_PLAYBACK_PATH}" "${DEVICE_PLAYBACK_PATH_HP}" set_setting "audio.device" "headphone" ;; (${HP_OFF}) - amixer -c 0 cset name=${DEVICE_PLAYBACK_PATH} ${DEVICE_PLAYBACK_PATH_SPK} + amixer -c 0 cset "name=${DEVICE_PLAYBACK_PATH}" "${DEVICE_PLAYBACK_PATH_SPK}" set_setting "audio.device" "speakers" ;; esac