26 August 2026

Connecting a Nintendo Switch Pro Controller Wirelessly to Ubuntu 26.04

(Courtesy of the Kagi Assistant and saved for posterity...)

Context & Symptoms

System: Ubuntu 26.04 (Linux), using the in-kernel hid_nintendo driver (057e:2009), connecting a Nintendo Switch Pro Controller over Bluetooth.

Symptoms: The controller paired successfully and hid_nintendo bound to it in dmesg, but two problems appeared:

  1. The controller would immediately disconnect when evtest (or any program) tried to read from the device, with the error: expected 24 bytes, got -1 — No such device.
  2. After fixing the disconnect, evtest could see the controller's input node but no button or stick events appeared when pressing anything. The controller worked perfectly when connected via USB-C cable — the problem was Bluetooth-only.

The root causes were two separate BlueZ/Bluetooth configuration issues: a firmware quirk in the controller that rejects adapters with unexpected names, and BlueZ's default UHID transport silently failing to forward HID input reports to the kernel.


Step 1: Rename the Bluetooth adapter to “Nintendo”

The Pro Controller's firmware has a quirk where it disconnects if the Bluetooth adapter name doesn't match what it expects. Renaming the adapter satisfies the handshake.

Edit /etc/bluetooth/main.conf:

sudo nano /etc/bluetooth/main.conf

Under [General], set:

[General]
Name = Nintendo
Alias = Nintendo

Restart Bluetooth:

sudo systemctl restart bluetooth

This fixed the immediate disconnection observed when evtest tried to read from the device.


Step 2: Disable UHID (use kernel HIDP instead)

BlueZ's default UHID (userspace HID) transport was creating the input device but not forwarding input reports from the controller to the kernel — so evtest saw the device but no button events ever arrived. Switching to kernel HIDP fixed this.

The telltale sign in dmesg was the input device path containing /devices/virtual/misc/uhid/, indicating the UHID transport was in use:

input: Pro Controller as /devices/virtual/misc/uhid/0005:057E:2009.000E/input/input31

Edit /etc/bluetooth/input.conf:

sudo nano /etc/bluetooth/input.conf

Under [General], set:

[General]
UserspaceHID=false

Restart Bluetooth:

sudo systemctl restart bluetooth

Note: This requires the hidp kernel module. On stock Ubuntu it should be available, but if the controller fails to connect after this change, load it manually:

sudo modprobe hidp
echo "hidp" | sudo tee /etc/modules-load.d/hidp.conf

Step 3: Re-pair the controller

Remove the old pairing and re-pair fresh, since the Bluetooth configuration has changed:

bluetoothctl
[bluetooth]# remove <MAC_ADDRESS>
[bluetooth]# scan on
# (hold the Sync button on the Pro Controller until LEDs flash)
[bluetooth]# pair <MAC_ADDRESS>
[bluetooth]# trust <MAC_ADDRESS>
[bluetooth]# connect <MAC_ADDRESS>
[bluetooth]# quit

The trust command is important — without it, the controller may disconnect after pairing.


Step 4: Verify

Confirm the input device is no longer on the UHID path:

dmesg | grep -i "057e:2009" | tail -10

The input: line should now reference a real Bluetooth device path rather than /devices/virtual/misc/uhid/.

Test with:

sudo evtest

Select “Pro Controller” (not “Pro Controller (IMU)”) and press buttons — events should now stream.


Summary of problems and fixes

Problem Cause Fix
Controller disconnects when evtest opens it BT adapter name doesn't match controller's firmware expectation Rename adapter to “Nintendo” in main.conf
evtest sees the device but no button events BlueZ UHID transport creates input node but doesn't forward HID reports Set UserspaceHID=false in input.conf to use kernel HIDP
USB worked but Bluetooth didn't USB bypasses BlueZ entirely; Bluetooth was broken at the BlueZ → UHID bridge Same — switching to HIDP bypasses the broken bridge

No comments: