Making Windows Media Center remote work correctly in Arch Linux

2014/05/04

Tags: remotes XBMC linux arch

At some point LIRC drivers became part of the kernel, and now by default remote controls generate normal keyboard key presses.

This should be fine, but my remote seems to generate way more key events than buttons are actually pressed, resulting in going through menus really fast etc. Because of this I decided to stick with the traditional lircd setup.

For reference, my MCE receiver identifies itself as following on startup:

[   14.036297] Registered IR keymap rc-rc6-mce
[   14.036749] input: Media Center Ed. eHome Infrared Remote Transceiver (0471:0815) as /devices/pci0000:00/0000:00:12.0/usb5/5-3/5-3:1.0/rc/rc0/input12
[   14.037577] rc0: Media Center Ed. eHome Infrared Remote Transceiver (0471:0815) as /devices/pci0000:00/0000:00:12.0/usb5/5-3/5-3:1.0/rc/rc0
[   14.216355] mceusb 5-3:1.0: Registered Philips eHome Infrared Transceiver with mce emulator interface version 1
[   14.216372] mceusb 5-3:1.0: 2 tx ports (0x3 cabled) and 2 rx sensors (0x1 active)
[   14.216491] usbcore: registered new interface driver mceusb
[   14.237439] IR JVC protocol handler initialized
[   14.237664] input: MCE IR Keyboard/Mouse (mceusb) as /devices/virtual/input/input13
[   14.239043] IR MCE Keyboard/mouse protocol handler initialized
[   14.239062] IR NEC protocol handler initialized
[   14.239085] IR RC6 protocol handler initialized
[   14.239449] IR SANYO protocol handler initialized
[   14.239468] IR Sony protocol handler initialized
[   14.239482] IR RC5(x) protocol handler initialized
[   14.251169] lirc_dev: IR Remote Control driver registered, major 250 
[   14.252425] rc rc0: lirc_dev: driver ir-lirc-codec (mceusb) registered at minor = 0
[   14.252431] IR LIRC bridge handler initialized

Firstly, I installed the lirc-utils package, and started the lircd daemon

pacman -S lirc-utils
systemctl enable lirc
systemctl start lirc

Then check that remote events are being received. Start irw and press a few buttons:

# irw
000000037ff07be1 00 KEY_UP mceusb
000000037ff07be0 00 KEY_DOWN mceusb
000000037ff07be0 01 KEY_DOWN mceusb
000000037ff07bde 00 KEY_RIGHT mceusb
000000037ff07bde 01 KEY_RIGHT mceusb
000000037ff07bdf 00 KEY_LEFT mceusb
000000037ff07bdf 01 KEY_LEFT mceusb
000000037ff07bdf 00 KEY_LEFT mceusb
000000037ff07bdd 00 KEY_OK mceusb
000000037ff07bdd 01 KEY_OK mceusb
000000037ff07bf0 00 More mceusb
000000037ff07bf0 01 More mceusb
000000037ff07bec 00 KEY_CHANNELDOWN mceusb

If that works, see what protocols are enabled for the rc reciever.

# cat /sys/class/rc/rc0/protocols
[rc-5] [nec] [rc-6] [jvc] [sony] [sanyo] [mce_kbd] [lirc]

We’re only interested in the lirc protocol, so only enable that one:

# echo lirc > /sys/class/rc/rc0/protocols

Only lirc should then show as enabled

# cat /sys/class/rc/rc0/protocols
rc-5 nec rc-6 jvc sony sanyo mce_kbd [lirc]

The final step was getting it to work in XBMC!

If you look in the xbmc systemd unit file /usr/lib/systemd/system/xbmc.service, you’ll see it startx xbmc with the following:

/usr/bin/xinit /usr/bin/dbus-launch /usr/bin/xbmc-standalone -l /run/lirc/lircd -- :0 -nolisten tcp vt7

The -l /run/lirc/lircd is crucial - by default xbmc expects to find the lirc device at /dev/lircd, so you need to pass this whenever starting xbmc.

All in this was pretty straightforward when I finally got it working. I did spend ages messing around with Lircmap.xml etc on the way though!