Wake a Lenovo Legion Go S with a Steam Controller

I wanted my Lenovo Legion Go S to wake up when I turned on a Steam Controller. It sounds like something that should just work, especially on SteamOS, but in my case it did not.

The important detail is that the Steam Controller puck is not a Bluetooth device in this setup. Treat it as a USB receiver. The fix is telling Linux that this USB device, or the USB port it is connected to, is allowed to wake the system.

Find the USB device

Connect the Steam Controller receiver directly to the Legion Go S or through your dock. Then switch to Desktop Mode, open Konsole, and list USB devices:

lsusb

Now check which USB devices expose the wakeup setting:

grep . /sys/bus/usb/devices/*/power/wakeup 2>/dev/null

You will see paths like this:

/sys/bus/usb/devices/1-5/power/wakeup:disabled

The 1-5 part will almost certainly be different on your machine.

The easiest way to find the right path is low-tech but reliable:

  1. Run the grep command with the receiver plugged in.
  2. Unplug the receiver.
  3. Run it again.
  4. Plug the receiver back in.
  5. Run it one more time.

The path that appears and disappears is the one you care about.

Test wakeup manually

Once you know the path, enable wakeup for that USB device:

echo enabled | sudo tee /sys/bus/usb/devices/1-5/power/wakeup

Replace 1-5 with the device path you found.

Now put the Legion Go S to sleep and press the Steam/Home button on the controller. If everything is mapped correctly, the console should wake up.

Make it survive reboot

The annoying part is that this setting usually disappears after reboot. Sysfs state is runtime state, not permanent configuration.

So I created a small systemd service that enables wakeup on boot.

sudo nano /etc/systemd/system/steam-controller-puck-wakeup.service

In my setup the whole dock is on USB bus 7, so I enable wakeup for the root bus and all devices under it:

[Unit]
Description=Enable Steam Controller Puck wakeup on USB bus 7
After=multi-user.target

[Service]
Type=oneshot
ExecStart=/usr/bin/bash -c 'for f in /sys/bus/usb/devices/usb7/power/wakeup /sys/bus/usb/devices/7-*/power/wakeup; do [ -e "$f" ] && echo enabled > "$f"; done'

[Install]
WantedBy=multi-user.target

If your receiver is not on bus 7, change usb7 and 7-* to match your own USB bus.

Then enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable steam-controller-puck-wakeup.service
sudo systemctl start steam-controller-puck-wakeup.service

Or shorter:

sudo systemctl daemon-reload
sudo systemctl enable --now steam-controller-puck-wakeup.service

Summary

The whole trick is realizing that the Steam Controller receiver is just a USB wakeup problem.

Find the right /sys/bus/usb/devices/.../power/wakeup path, set it to enabled, test suspend, and then persist it with a tiny systemd service. Not elegant, but it works.