Nokia Game Controller 5000 rumbles!

I reverse-engineered the rumble protocol of the Nokia Game Controller 5000 and wrote a Linux FF proxy daemon — force feedback now works in Steam

The Nokia Game Controller 5000 (GC5000) is a Bluetooth gamepad (1D5A:1802) that works fine as an input device on Linux, but the kernel driver (hid-generic) exposes no force feedback at all — ff=0. On Android the two rumble motors work fine, so the hardware is there. USB-C is charge-only, no wired mode.

I got rumble working anyway, without touching the kernel:

  1. Reverse-engineered the rumble protocol via hidraw: the pad accepts an undeclared output report (ID 0x01, 2 bytes — one byte per motor). Amplitude is strictly binary (0x01 == 0xFF), and the firmware only vibrates for a short burst per report, so continuous rumble needs a heartbeat (~every 70–100 ms).

  2. Wrote a small Python daemon (stdlib only, no dependencies) that creates a uinput proxy gamepad with real FF capabilities, forwards all input 1:1, grabs the real pad, and translates FF effects from games/SDL into hidraw reports. Periodic (sine) effects are quantized onto the three levels this hardware can actually express: off / weak motor only / both motors.

  3. It ships with a systemd unit + udev rule — the daemon auto-starts whenever the controller connects and exits cleanly on Bluetooth disconnect.

Result: rumble works in Steam and FF-aware games. Setup is sudo ./install.sh, done.

Repo: https://github.com/Grothesk242/gc5000-rumble-linux

Also included: the hidraw probe script I used to find the protocol. If you own another cheap Bluetooth pad whose rumble is “unsupported” on Linux, it may be hiding a similar undeclared output report — this script helps you find it.

Limitations (honest edition): motors are binary, so no analog intensity; sine-style “swells” are a 3-level approximation. Spring/damper effects are rejected (EINVAL) on purpose.

Would love testers on other distros/kernels! Protocol findings and troubleshooting are in the README — including a nasty udev gotcha: Bluetooth HID devices don’t expose idVendor/idProduct sysfs attributes (those are USB-only), so udev rules have to match the parent device name.