Setting up USB Wakeup on Bazzite
Earlier this year, I got a laptop that used to be a family member’s. This laptop has a broken hinge. Specifically, it can’t be opened because the hinge ends up acting as a lever that pulls the computer apart. Opening it would destroy it. Beyond this, it’s a perfectly fine computer! It just can’t be used as a laptop.
I decided to use it as a console instead. Setting it up as a console is easy (just have Steam Big Picture Mode run on startup). It’s everything else about using a computer as a console that’s hard. I had it on Windows 11 before[1] (what it came with), before the Windows install just spontaneously died. Then I switched it to Fedora Linux, which was better, but not without it’s issues. (Automatic updates wouldn’t work, so I’d have to update everything manually. Or, they would work, but they killed KDE so I have to restart the computer manually). Windows or Linux, one major issue that comes up is you can’t let the computer sleep. Controllers can’t wake the computer, and even if they could, you have to enter your password to unlock it.
Fed up with having to do so much maintenance on my laptop-console, I decided to switch to Bazzite. Bazzite is an immutable Linux distro based on Fedora Atomic Desktops that provides the Steam Deck Game Mode. Essentially, it’s a replacement for SteamOS since SteamOS still only available on the Steam Deck. Automatic updates should be easier on account of it being an immutable OS, and hopefully I won’t have to do as much maintenance.
Since Steam Game Mode doesn’t require a keyboard to log in, I thought that maybe I could wake the computer with a controller. You can, but the path to getting there wasn’t easy!
Not Working udev Solution #
The main controller I’m using is an 8BitDo Ultimate C 2.4GHz controller. It’s a very nice controller, and I like that it’s wireless with a dongle (I’ve had trouble with Bluetooth controllers on this computer in the past).
The first solution I came across[2] was to set a udev rule to enable wakeup for the device.
ACTION=="add|change", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="2dc8", ATTRS{idProduct}=="3106", ATTR{power/wakeup}="enabled"
This will trigger when a device with attribute the vendor id 2dc8
and product id 3106
is connected, and set the wakeup
attribute to enabled
. These values match the 8BitDo controller, and are found with lsusb
. There’s only one problem with this solution: It doesn’t work. The rule works, but setting the wakeup
attribute fails. I think it’s just not supported by the 8BitDo controller.
Technically Working udev Solution #
I was thinking that it might not be possible, but I found a solution that does work[3].
ACTION=="add|change", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="2dc8", ATTRS{idProduct}=="3106", RUN+="/bin/sh -c 'echo enabled > /sys/bus/usb/devices/usb1/power/wakeup'"
This udev rule runs a script to set the wakeup attribute for the first USB root hub when the controller is plugged in. It works but it’s also not necessarily a clean solution. This makes it so that any USB device added to the first USB root hub will wake the device. This doesn’t need to be a udev rule, since it doesn’t need to run every time the controller is connected; it only needs to be run once at startup.
Systemd Solution #
A systemd service would be a better fit for this task. A couple other solutions I found use init scripts.[4] I thought those wouldn’t work on systemd, but apparently they do![5] So you can use rc.local
or an init script if you want. Regardless, I wrote a systemd service to do the same thing.
This systemd service runs the enable_wakeup.sh
script on startup. I have it saved as /etc/systemd/system/usb_wake.service
.
[Unit]
Description=Enables wakeup for all usb devices
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/enable_wakeup.sh
[Install]
WantedBy=multi-user.target
This shell script sets the wakeup attribute for every USB root hub (/sys/bus/usb/devices/usb*
). I have it saved as /usr/local/sbin/enable_wakeup.sh
.
#!/bin/sh
# Enables wakeup for all usb devices
for device in /sys/bus/usb/devices/usb*; do
echo enabled > "$device"/power/wakeup
done
Then, just enable the service with sudo systemctl enable --now usb_wake
!
It works great for me. And it lets me wake up the system with any controller[6], not just my 8BitDo controller, which is better than I was expecting when I started.
Caveats #
When you turn off the 8BitDo Ultimate C, the computer wakes up. This is because the dongle appears as a device. (8BitDo IDLE
in lsusb
). When you turn off the controller, the controller disconnects and 8BitDo IDLE
connects instead. I don’t know if there’s a way to prevent this. Other controller dongles (like the Steam Controller) don’t do this.
Since my computer is a laptop with the lid shut, it actually goes to sleep when I turn off the TV, so this doesn’t matter for my use case. (If anyone reading this also uses a laptop as a console and you don’t want it to go to sleep when the lid is shut, you just need to add IgnoreLid=true
to /etc/UPower/UPower.conf
)[7]
This also doesn’t work with Bluetooth controllers. I’ve found some posts saying that they have wake on Bluetooth working[8], but I haven’t tried it.
This is what resulted in my Steam Replay showing 14% playtime on Windows ↩︎
Comment by runningferret on “Wake from sleep with 8bitdo?” by amruthwo - Reddit
“Power management/Wakeup triggers” - Event-driven with udev - ArchWiki ↩︎Answer by Pavlos Theodorou on “Wake up from suspend using USB Device” - AskUbuntu ↩︎
rc.local
solution - Answer by Pavlos Theodorou on “Wake up from suspend using USB Device” - AskUbuntu
Init script solution - Answer by call0fcode on “Wake up from suspend using USB Device” - AskUbuntu ↩︎From
/etc/rc.d/init.d/README
on my Fedora system: “Note that traditional init scripts continue to function on a systemd system. An init script /etc/rc.d/init.d/foobar is implicitly mapped into a service unit foobar.service during system initialization.” ↩︎I have tested this with my 8BitDo Ultimate C, the Steam Controller, and a wired PDP Xbox One. This doesn’t work with Bluetooth controllers. ↩︎
Answer by mrfromage on “How can I tell Ubuntu to do nothing when I close my laptop lid?” - AskUbuntu ↩︎
“I got wake on bluetooth to work on my system” by physicsme - Reddit ↩︎