Infrared Remotes

Modern Linux kernels, like the ones used in LibreELEC, have built-in support for IR remotes. IR signals are decoded by the kernel and programs see button presses from IR remotes in the same way as key presses from a normal keyboard, as Linux input events.

This is the successor to LIRC where a separate program, lircd, decodes the IR signals and programs could get the button presses from a socket as LIRC events.

While this new scheme is really handy, there's a small gotcha: Kodi's remote handling is built for LIRC and it doesn't cope well with Linux input events. In general all buttons also present on a normal keyboard, like arrows and numbers, work fine but rather important buttons like OK and channel up/down don't.

To solve this problem LibreELEC runs a small program in the background, eventlircd, which translates Linux input events from remotes into LIRC events.

So, while under the hood the new scheme can be used, remote buttons still show up as LIRC events in Kodi.

LibreELEC still ships with LIRC so IR remotes with non-standard protocols and rather special setups can be supported. In general, keep LIRC disabled (in LibreELEC Settings → Services) and only enable it in the very few cases where you actually need it.

If you upgraded from LibreELEC 8.0.x to 8.2 and you get double button presses or your remote doesn't work as expected disable LIRC in LibreELEC Settings and then reboot.

LibreELEC 9.0 uses in-kernel decoding with ir-keytable configuration as the main method to support infrared remotes on all platforms.

Lirc is still available but the old lirc-only kernel drivers lirc_rpi and lirc_xbox have been removed and LibreELEC no longer ships with default lircd.conf files.

The option to enable / disable Lirc in LibreELEC settings has been removed as well, lircd will now be started automatically if the /storage/.config/lircd.conf file is present.

RPi specific changes

Change dtoverlay=lirc-rpi to dtoverlay=gpio-ir in /flash/config.txt to switch to the newer gpio-rc-recv driver which replaces lirc-rpi.

Amlogic specific changes

MCE and Xbox 360/One remotes will now work out-of-the-box like on RPi and x86.

Configuration files for Amlogic specific remotes are collected and shared in the LE9.0 remote configs ir-keytable Amlogic devices forum thread.

Most USB IR dongles and IR receivers built into DVB receivers and HTPC cases are supported out of the box. For “home-brew” IR receivers some addition configuration steps are needed:

GPIO IR receiver on RPi

Add the following line to /flash/config.txt (read Raspberry Pi Config.txt for detailed instructions):

dtoverlay=gpio-ir

Add the gpio_pin parameter if you used a custom GPIO (default is 18). eg:

dtoverlay=gpio-ir,gpio_pin=5

Serial port receiver on x86

Create a /storage/.config/autostart.sh file with the following content:

setserial /dev/ttyS0 uart unknown
modprobe serial_ir

Overview

LibreELEC uses ir-keytable to configure IR remotes, just like most current Linux distributions.

Each IR receiver kernel driver installs a default keytable. This keytable specifies which IR protocol to use (eg RC-5, RC-6, NEC, …) and the scancode to Linux keycode mapping.

Most universal receivers default to the rc-rc6-mce table so standard RC-6 MCE remotes can be used without any further configuration.

Drivers for devices that are usually sold together with a remote usually install their own keytable - so that eg the Hauppauge remote that came with a Hauppauge DVB stick works out of the box.

After the driver is loaded, ir-keytable -a is automatically run so that the kernel default configuration can be changed:

  1. /etc/rc_maps.cfg determines which keytable to load.
  2. The corresponding keytable file from the directory /usr/lib/udev/rc_keymaps/ is then used to configure the remote controller driver.

The default configuration in LibreELEC is changed slightly compared to the official ir-keytable configuration:

  • Instead of changing /etc/rc_maps.cfg you have to store your custom configuration in /storage/.config/rc_maps.cfg. /storage/.config/rc_maps.cfg.sample contains some simple examples.
  • Custom keytables need to be stored in /storage/.config/rc_keymaps. Keytables with the same name will override the stock keytables from /usr/lib/udev/rc_keymaps/.
  • In order to support several popular remotes (MCE, Xbox 360 and Xbox One) LibreELEC loads the libreelec_multi keytable instead of the standard rc6_mce keytable. This is configured via the following change in /etc/rc_maps.cfg:
# use combined multi-table on MCE receivers
#*      rc-rc6-mce               rc6_mce
*       rc-rc6-mce               libreelec_multi

Configuring a custom remote

While most IR receivers can be used with a large variety of remotes there's no easy answer to the question “can I use remote X with IR receiver Y”. This depends on a lot of factors:

  • Some IR receivers can't be configured at all and you can only use the remote they came with.
  • Some receivers only support a small subset of all available protocols (eg only RC-5, but not RC-6), so obviously your remote has to be using one of these so it can work.
  • If your remote uses a protocol that is not supported by the IR receiver (or some non-standard protocol that isn't supported by the Linux kernel at all) your only chance to get it working is if the IR receiver driver supports the raw (lirc) protocol, then you can use userspace LIRC with a custom lircd.conf to configure it.

Configuration, the easy way

LibreELEC ships with over 100 different keytable files, so there's a good chance your remote will work with one of these. Even if only some of the buttons work with these files you've got a good starting point and only need to fill in the missing buttons “the hard way”.

  1. Look at the keytable files in /usr/lib/udev/rc_keymaps/.
  2. If one of the filenames there reads like it could match your remote, try using it.
  3. If it doesn't work, go on to the next candidate keytable file.

Loading a keytable file

To configure your remote with a keytable file run ir-keytable -c -w PATH-TO-KEYTABLE-FILE. eg:

LibreELEC:~ # ir-keytable -c -w /usr/lib/udev/rc_keymaps/samsung
Read samsung table
Old keytable cleared
Wrote 30 keycode(s) to driver
Protocols changed to nec

If the output ends with these lines

Invalid protocols selected
Couldn't change the IR protocols

that means the protocol isn't supported by your IR receiver. In this case try the next file.

If the keytable loaded fine press the up/down/left/right and OK buttons and see if navigation in Kodi works.

Making keytable configuration permanent via rc_maps.cfg

If you found a working keytable you can make the configuration permanent by creating a custom /storage/.config/rc_maps.cfg file. Typically you'll have only one IR receiver you need to configure and the file is really simple. eg if you found out that the samsung keytable works, create a /storage/.config/rc_maps.cfg file with the following content:

* * samsung

To test if that rc_maps.cfg file works run ir-keytable -a /storage/.config/rc_maps.cfg

If everything's fine the output should look like this:

LibreELEC:~ # ir-keytable -a /storage/.config/rc_maps.cfg
Old keytable cleared
Wrote 30 keycode(s) to driver
Protocols changed to nec

Test again if the buttons work, if everything's OK reboot.

Configuration, the hard way

If you couldn't find a working keytable “the easy way” you need to create your own from scratch. The format of the keytable file is rather simple: It's a plain text file, the first line contains a header with a descriptive name (you can choose that rather arbitrarily, but better avoid special characters, spaces and such) and the remote protocol to use (the type: - which is very important). After that each line contains a mapping of remote scancode to Linux keycode.

A typical keytable file looks like this:

# table justboom, type: RC5
0x101a KEY_UP
0x101b KEY_DOWN
0x1013 KEY_LEFT
0x1014 KEY_RIGHT
0x1015 KEY_OK

Before you can configure your remote “the hard way” you have to stop Kodi and eventlircd by running these two commands:

systemctl stop kodi
systemctl stop eventlircd

If you miss to do this ir-keytable won't show any input events as Kodi or eventlircd have grabbed the input device (unfortunately ir-keytable doesn't print a warning in that case).

The first step now is to find out which protocol your remote uses.

If you found a partly working keytable file via “the easy way” with only a few non-working buttons you can skip this step. Instead just copy the stock keytable to /storage/.config/rc_keymaps/ eg:

cp /usr/lib/udev/rc_keymaps/samsung /storage/.config/rc_keymaps/my_custom_remote

Then, in the next step, edit and/or fill in the missing keycodes.

Determining the remote protocol

First, run ir-keytable to find out which protocols your IR receiver driver supports - look at the Supported protocols: line. eg:

LibreELEC:~ # ir-keytable
Found /sys/class/rc/rc0/ (/dev/input/event1) with:
        Driver gpio-rc-recv, table rc-rc6-mce
        Supported protocols: lirc rc-5 rc-5-sz jvc sony nec sanyo mce_kbd rc-6 sharp xmp
        Enabled protocols: lirc nec rc-6
        Name: gpio_ir_recv
        bus: 25, vendor/product: 0001:0001, version: 0x0100
        Repeat delay = 500 ms, repeat period = 125 ms

Then, for each of the protocols (except lirc, which isn't a real protocol) run ir-keytable -p PROTOCOL -t, then press some buttons on your remote.

If you discovered the correct protocol you should see EV_MSC events together with the scancode of the button. eg:

LibreELEC:~ # ir-keytable -p rc-5 -t
Protocols changed to rc-5
Testing events. Please, press CTRL-C to abort.
1503592437.660155: event type EV_MSC(0x04): scancode = 0x101a
1503592437.660155: event type EV_SYN(0x00).
1503592437.774129: event type EV_MSC(0x04): scancode = 0x101a
1503592437.774129: event type EV_SYN(0x00).
1503592437.921009: event type EV_MSC(0x04): scancode = 0x101a

If you see no events stop ir-keytable with CTRL-C and try the next protocol from the list.

Once you found out the protocol create the keytable file, eg /storage/.config/rc_keymaps/my_custom_remote and create the header line (eg here with protocol / type rc-5

# table my_custom_remote, type: rc-5

Creating scancode to keycode mapping

Open a second ssh connection. In one connection open an editor with your keytable, eg

nano /storage/.config/rc_keymaps/my_custom_remote

In the second connection run ir-keytable -t to find out the scancode of each button.

Now for each button do the following steps

  • Press the button and note the scancode it generates (the 0x… value after scancode: )
  • Add a new line with the scancode (including 0x).
  • After the scancode enter the Linux keycode, separated with a blank.

The keycode must be one of the standard Linux keycodes. You can get a list of all supported keycodes via irrecord -l | grep ^KEY.

It's best to use those keycodes that are listed in /usr/share/kodi/system/Lircmap.xml in the <remote device=“devinput”> section. If you use other keycodes you'll have to create a Kodi lircmap.xml with keycode to Kodi action mappings.

When you're finished with all buttons, save the keytable, stop ir-keytable -t with CTRL+C and then test if it works. If testing succeeds, make it permanent via a /storage/.config/rc_maps.cfg file like this:

* * my_custom_remote

Then reboot and you should have a working remote in Kodi.

Testing a custom keytable

First load your custom keytable via ir-keytable -c -w PATH_TO_MY_KEYTABE. eg:

LibreELEC:~ # ir-keytable -c -w /storage/.config/rc_keymaps/my_custom_remote
Read justboom table
Old keytable cleared
Wrote 12 keycode(s) to driver
Protocols changed to rc-5

Then run ir-keytable -t and press buttons on your remote.

In addition to the EV_MSC scancode events you should now also see EV_KEY events with the Linux keycode. eg:

LibreELEC:~ # ir-keytable -t
Testing events. Please, press CTRL-C to abort.
1503599395.150849: event type EV_MSC(0x04): scancode = 0x1019
1503599395.150849: event type EV_KEY(0x01) key_down: KEY_VOLUMEUP(0x0073)
1503599395.150849: event type EV_SYN(0x00).
1503599395.264827: event type EV_MSC(0x04): scancode = 0x1019
1503599395.264827: event type EV_SYN(0x00).
1503599395.413668: event type EV_MSC(0x04): scancode = 0x1019
1503599395.413668: event type EV_SYN(0x00).
1503599395.673626: event type EV_KEY(0x01) key_up: KEY_VOLUMEUP(0x0073)
1503599395.673626: event type EV_SYN(0x00).

Common tests

There are several steps until a button press on your remote finally triggers an action in Kodi. Use this guide to check if each of the steps works.

Check if the remote is transmitting signals

Batteries can run flat and make the remote stop working. While the human eye can't see infrared signals, digital cameras and smartphone cameras can. Close the curtains, point the camera at the IR transmitter of your remote and press buttons. If the IR transmitter works, you should see it lighting up on your camera / smartphone screen.

Check if the IR receiver driver is loaded

Run ir-keytable. If you get the error message /sys/class/rc/: No such file or directory it means no driver is loaded.

Check if the IR receiver is receiving any signals.

Several IR receivers support the raw lirc protocol and programs can get the raw, undecoded signals from the receiver.

If lirc shows up under Supported protocols in ir-keytable output you can run ir-ctl -r to display those raw signals.

If IR receptions works you should see a lot of pulse and space lines when you press a button.

Note: On kernels before 4.3 lirc may be listed in Supported protocols but not in Enabled protocols. In this case run ir-keytable -p lirc to enable it. Keep in mind that this will disable the other protocol decoders.

Verify that lircd is NOT running

Run ir-keytable. If only lirc shows up Enabled protocols: most certainly lircd is running (when it starts it will disable all other protocols).

You can also check via ps | grep /usr/sbin/lircd, if you see /usr/sbin/lircd and /usr/sbin/lircd-uinput processes LIRC is enabled.

In this case, disable Lirc in LibreELEC Settings → Services and then reboot.

Verify that the correct keytable is loaded

Run ir-keytable -r to show the currently used keytable and protocol. Verify that the scancode to keycode mapping and the enabled protocol matches the contents of the (custom) keytable.

If there's a mismatch check if your /storage/.config/rc_maps.cfg file is setup correctly.

Check if IR decoding works correctly

First stop Kodi and eventlircd as we need exclusive access to the IR input device

systemctl stop kodi
systemctl stop eventlircd

Then run ir-keytable -t. You should see both EV_MSC events with the scancode and EV_KEY events with the mapped Linux keycode. eg:

LibreELEC:~ # ir-keytable -t
Testing events. Please, press CTRL-C to abort.
1503599395.150849: event type EV_MSC(0x04): scancode = 0x1019
1503599395.150849: event type EV_KEY(0x01) key_down: KEY_VOLUMEUP(0x0073)

If you only get EV_MSC but no EV_KEY events, verify if the correct keytable is setup.

After this test, start eventlircd and Kodi again via these commands (or simply reboot)

systemctl start eventlircd
systemctl start kodi

Check if eventlircd translates the input events to LIRC events

Run irw. This will output the translated LIRC events that Kodi sees. When you press a button you should see messages like this:

LibreELEC:~ # irw
72 0 KEY_VOLUMEDOWN devinput
72 1 KEY_VOLUMEDOWN devinput
72 2 KEY_VOLUMEDOWN devinput

Check if Kodi receives the translated LIRC events

Enable debug logging in System Settings → Logging. Then run tail -f /storage/.kodi/temp/kodi.log

When you press a button you should see log entries with LIRC: Update like this:

21:55:33.891 T:1945866240   DEBUG: LIRC: Update - NEW at 60659:6c 0 KEY_DOWN devinput (KEY_DOWN)
21:55:33.891 T:1945866240   DEBUG: OnKey: 167 (0xa7, obc88) pressed, action is Down

The LIRC line indicates that Kodi successfully received the LIRC event. The OnKey: line shows the resulting action after applying Lircmap.xml and remote.xml.

If you see the LIRC lines but the action isn't as you expect, check if your Kodi Lircmap.xml and remote.xml config files are correct.

Common problems

GPIO IR receiver on Raspberry Pi works intermittently

USB data transfers can interfere with proper operation of GPIO IR receivers. As ethernet is connected via USB on the RPi this can also happen when playing movies from a NAS.

This is a well known issue (see https://github.com/raspberrypi/linux/issues/906 for details) but unfortunately there's nothing we can do about it.

If you are affected by the issue you can use a USB IR receiver or CEC as an alternative.

Although most remotes are now supported by the Linux kernel LIRC (the userspace lircd daemon plus tools) is far from being obsolete. It is still very useful if you want to use uncommon remotes with odd protocols or setups that are not supported by the remote drivers in the Linux kernel.

Starting with LibreELEC 8.2 we've changed the way how we use LIRC so it's now (almost) identical to the way it's used on standard Linux distributions: it can be configured via lircd.conf and lirc_options.conf files.

On a fresh LibreELEC 8.2 installation LIRC is disabled by default, you have to manually enable it via LibreELEC Settings → Services → Lirc.

The /etc/lirc/lirc_options.conf file in LibreELEC configures LIRC to use the default driver and the device /dev/lirc0.

The /etc/lirc/lircd.conf includes remote configurations for MCE and Xbox 360 / one remotes, plus a few others.

This setup was chosen so that users of the older lirc-only drivers (especially lirc_rpi on the Raspberry Pi) get a similar out-of-the-box experience as users with universal IR receivers that support in-kernel decoding.

Creating a custom lircd.conf and/or lirc_options.conf file in /storage/.config will override the default LibreELEC configuration files in /etc/lirc.

LIRC integration with eventlircd / Kodi

In LibreELEC lircd provides the decoded LIRC events on /run/lirc/lircd.socket. lircd-uinput reads the LIRC events from that socket and translates these to Linux input events (via the Linux uinput driver).

The Linux input events from lircd-uinput are then picked up by eventlircd and fed to Kodi as LIRC events via the /run/lirc/lircd socket.

Although, at a first glance, it might seem odd to translate between LIRC, Linux input and then again LIRC events there's a rather simple reason for that: Kodi can receive LIRC events only from a single LIRC socket and with eventlircd collecting all remote events and feeding them to Kodi LibreELEC can support both LIRC-decoded and kernel-decoded remotes without needing the user (or some sophisticated script) having to change the configuration.

Using LIRC with an IR receiver that supports in-kernel decoding

If the IR receiver driver can be configured via ir-keytable it's best to disable ir-keytable auto-configuration by creating an empty /storage/.config/rc_maps.cfg file, eg with this command:

: > /storage/.config/rc_maps.cfg

Although lircd disables all remote protocols on startup (and thus disables in-kernel decoding), ir-keytable auto-configuration (which is run in parallel) can interfere with that and re-enable in-kernel decoding - if it happens to run after lircd.

The effect of this is that you can get unwanted decodes as both lircd and the kernel will decode the IR signals.

This issue might happen intermittent across reboots, there's also a chance lircd runs after ir-keytable and in-kernel decoding is disabled.

Another thing to keep in mind is that stopping lircd will not re-enable in-kernel decoding. eg if you disable LIRC in LibreELEC Settings you'll have to reboot (or manually run the ir-keytable configuration), otherwise neither the kernel nor lircd will decode the IR signals.