Fixing Linux Bluetooth issues with the Microsoft Surface Ergonomic Keyboard

Fixing Linux Bluetooth issues with the Microsoft Surface Ergonomic Keyboard

Microsoft's Surface Ergnomic Keyboard provides a comfortable and great typing experience. It's connected directly via Bluetooth without an dongle. But sadly some quirks in the bluetooth implementation of the keyboard make it harder to get it working on Linux.

During some recent keyboard tests, I ran into an issue connecting my Surface Ergonomic Keyboard to my Gentoo Linux. After some research, I found some other people with the same issue, but no one seemed to have solved the issue. Just out of curiosity I tried with an Fedora VM with a passed-through bluetooth dongle, where it instantly worked. After some investigations I found out my kernel was missing the UHID module, which is normally not needed and defaults to No in the kernel configuration.

input-hog profile accept failed for 00:00:00:00:00:00

The only message showing up in the bluetooth log (journalctl -u bluetoothd), if you are missing the uhid module, is input-hog profile accept failed for 00:00:00:00:00:00, while trying to pair the keyboard.

First make sure your kernel was built with CONFIG_UHID enabled.

$ zgrep -i uhid /proc/config.gz
CONFIG_UHID=m

or if your kernel does not expose it's config via /proc, you can also parse the one in your /boot folder

$ grep -i uhid /boot/config-...
CONFIG_UHID=m

If it's not built as module (m) or built in (y), you need to recompile your kernel (or choose a different one, which includes the it). Else you should load it with modprobe uhid and try pairing it again. If you already tried to pair the device make sure you remove it first (remove 00:00:00:00:00:00).

Connecting the Surface Ergonomic with bluetoothctl

After you made sure the uhid module is loaded, you can pair the Surface Ergonomic with bluetoothctl:

# bluetoothctl

This starts the interactive bluetooth configuration prompt.

Power up the controller
[bluetooth]# power on

Start the default agent
[bluetooth]# default-agent

Set pairable to on
[bluetooth]# pairable on

Set scanning mode on
[bluetooth]# scan on

Wait until the Surface Ergonomic Keyboard shows up
Use the Bluetooth Mac address to pair with it
[bluetooth]# pair 00:00:00:00:00:00
[agent] Passkey: 123456

During the pairing, you need to type in a code on the Surface Ergonomic Keyboard and confirm it by pressing enter.

In order to allow the keyboard to establish a connection to your computer by itself, you need to make it trusted.

[bluetooth]# trust 00:00:00:00:00:00

Next set scanning to off
[bluetooth]# scan off

And quit the bluetoothctl command
[bluetooth]# quit

Now the Surface Ergnonomic Keyboard should be paired with your computer permanently and even after a reboot the keyboard should be connected (as long as the bluetooth.service is enabled).