How to add support for a new remote

So you have a remote, but you can’t find a keymap that works for it. How do you add a new keymap for your remote?

Figure out what IR protocol it uses

For this to work, ideally you want a rc device which has a raw IR receiver. When you plug in your device will get a message in the kernel log (dmesg or journal -k) like:

rc rc0: lirc_dev: driver winbond-cir registered at minor = 0, raw IR receiver, raw IR transmitter

Now, if yours says scancode receiver it might still work, as long as the IR receiver supports the same protocol as remote. Run:

ir-keytable -c -p all -t

And now start pressing buttons on your remote. Hopefully you will start to see messages like:

3630.181420: lirc protocol(rc-5): scancode = 0x1e01

This means the protocol is rc-5.

If you get nothing, then unfortunately you’ll going to have to dig a little deeper. First of all verify that IR actually being received. Run:

ir-ctl -r

And press some buttons again. If you still get nothing, check your batteries and that you have a clear line of sight between your remote and the IR receiver. If you do get something, then most likely you are unlucky and the protocol your remote uses is not one of the standard protocols supported by the linux kernel; a protocol decoder written in BPF would be in order, but that is the subject for another post.

For now I’m assuming that ir-keytable -c -p all -t gave you something like rc-5 or nec and no custom BPF decoder is needed.

Create the kernel rc keymap for your remote

The keymaps in /lib/udev/rc_keymmaps/ are written in toml, but they are generated from the kernel sources and you should create your keymap there so that it can be submitted as a patch for everyone else to use.

git clone the linux kernel tree and go to drives/media/rc/keymaps/. Copy one of the exists files to a new file, e.g. rc-foo.c and edit the file. First of the protocol should be set to one you discovered in the first step (e.g. RC_PROTO_NEC). Now you need to set the individual keys.

Using ir-keytable -c -p all -t you can get the scancode; that needs to be mapped to a linux keycode. All the keycodes are listed in include/uapi/linux/input-event-codes.h in the kernel tree. Note that there are entries for mouse buttons too.

Ensure you have the copyright and license header set correctly; also check you have created a new RC_MAP_FOO entry in include/media/rc-map.h and that your file is included in drivers/media/rc/keymaps/Makefile. Commit your changes.

In principle it is ready now to be submitted, but it should be tested of course.

Create the toml keymap for your keymap

  • In your cloned linux repo, ensure you can build the kernel and run it without errors
  • Do make headers_install
  • Clone v4l-utils git repo
  • Do make sync-with-kernel KERNEL_DIR=path/to/your/linux/repo in v4l-utils
  • Now you should have an additional toml file in utils/keytable/rc_keymaps/
  • Load the keymap with ir-keytable -c -w foo.toml and test

Share your keymap with everyone else

The keymap should be submitted to linux-media kernel list, following all rules for submitting patches for the linux kernel. The patch should be against the kernel tree, and the v4l-utils tree will get updated by us once it’s merged into the linux-media git tree.