LWN.net Logo

Kernel support for infrared receivers

By Jonathan Corbet
December 2, 2009
One of the stated goals of the staging tree is to bring widely-used drivers into the mainline kernel tree. This effort has been quite successful; the number of out-of-tree drivers has dropped considerably over the last year or so. There is one high-profile holdout, though: the Linux Infrared Remote Control (LIRC) subsystem. LIRC is used to obtain input events from remote control devices and feed them through to applications; Linux-based digital video recorder systems are heavy LIRC users, but there are others as well. Back in October, Jarod Wilson posted a new version of LIRC for consideration. One month later, the kernel developers have started talking about it; what they lack in punctuality has been more than made up for in volume.

One might think that merging this longstanding, heavily-used project into the mainline would not require a great deal of discussion. The problem is that LIRC brings with it a new ABI. Since user-space interfaces must be supported indefinitely, they tend to come under a higher degree of scrutiny than other parts of the code. LIRC has never had to freeze its ABI during its many years of out-of-tree existence, a freedom which has made life easier for its developers. But LIRC in mainline would not have this freedom, so any incompatible ABI changes need to be made prior to merging. And, as it happens, some developers would like to see significant changes.

One would think that an IR receiver would be a simple device; all it must do is report button press and release events, much like a keyboard. Often, it seems, the simplest devices are the most complex to deal with. Some receivers have decoders built into them, allowing them to pass scan codes to the driver, which can then map them onto key codes to pass to applications. But others are simple indeed - they simply report the timing and length of pulses received from the remote. In this case, the driver must filter out glitches and perform protocol processing to get to the point where it can generate scan codes. For extra fun, there are a number of protocols in use, and some manufacturers have wisely decided that life would be much more interesting if they were to make their own versions of the protocols which differ from everybody else's. So the protocol processing can be painful and unpleasant.

LIRC handles this mess by having drivers report "raw" pulse-length information via a special device; a user-space daemon then handles the task of turning that information into something that usefully describes a button-press event. In many cases, the low-level driver runs in user space and does not involve the kernel at all. Distribution of these events is also handled by the LIRC daemon, which can direct specific events to different applications, run programs in response to events, and so on in a flexible, scriptable manner. LIRC works, and some developers would like to see it merged into the mainline more-or-less as it stands now. Others, though, dislike the special-purpose "raw" interface used by LIRC. As Jon Smirl put it:

[W]e used to have device specific user space interfaces for mouse and keyboard. These caused all sort of problems. A lot of work went into unifying them under evdev. It will be years until the old, messed up interfaces can be totally removed.

I'm not in favor of repeating the problems with a device specific user space interface for IR. I believe all new input devices should implement the evdev framework.

In other words, these developers want remote control devices to look like any other input device and generate input events through the same interface. Jon has posted a proposed IR input driver for discussion; it is actually a rework of work first posted one year ago. This code moves all processing into the kernel and provides a flexible mechanism for dealing with multiple remote controls.

As it happens, a number of remote control receivers already work this way, even in the absence of Jon's patch. LIRC is not the sole repository of IR receiver drivers; a fair number of them also live in the mainline kernel already, in the Video4Linux2 subsystem. TV cards often come with a bundled remote control and receiver, so it makes sense to write a driver for the receiver as part of the larger V4L2 driver. These drivers do not use the LIRC interface; instead, they generate input events directly. See the Conexant CX2388x IR driver for an example of what this sort of driver looks like.

The discussion covered various approaches to IR receivers without coming to any real resolution. Jon Smirl's attempt to clarify the goals for in-kernel IR support may have brought some focus, but little in the way of solid conclusions. Even so, there are some points of near consensus; these include:

  • There needs to be some sort of API based on the input subsystem, where applications can obtain processed, high-level keycodes for button presses. The goal is to have remote-using applications "just work" whenever possible.

  • There probably needs to be a separate interface where special-purpose applications can get raw timing data from the receiver - at least, for receivers without built-in decoders which can provide this information. This interface can be used to reverse-engineer the sequences sent by new remote control units and to deal with pathologically-bad hardware. There is talk of funneling raw data through the input layer as well, but it's not clear that doing so buys anything; it may be that just adopting the existing LIRC interface for raw data is as good an approach as any.

With regard to the keycode interface, there is still a lot of disagreement over where the keycodes should come from. Some developers want all of the IR drivers to be in the kernel, while others are happy with using the LIRC daemon (or something like it) to generate keycodes and push them back into the kernel from user space. In-kernel drivers have the potential to work with no daemon process and they can use the current module loading mechanism. Kernel-based drivers will also have lower response latency than a user-space daemon, saving precious milliseconds for desperate users who want to change channels and evade that "too much information" pharmaceuticals commercial.

On the other hand, in-kernel drivers are kernel code, with the higher level of risk that always implies. Filtering of input sequences and protocol processing can be a significant amount of work that some would rather see done in user space. It may never be possible to support the more problematic hardware in the kernel. Then, there are the truly wild ideas, such as wiring an IR receiver to a sound card's microphone input - something people actually do, evidently. The fact that some IR protocols may be patent-encumbered also needs to be kept in mind.

Another detail worth bearing in mind: a number of IR receivers are also capable of transmitting information. A solution based solely on the input layer will not be able to handle the output case.

There is one final, simple point: the LIRC drivers have seen many years of development, and they work. If LIRC is merged directly, the kernel will benefit from that work and the associated lessons learned. If LIRC is dropped in favor of fully in-kernel drivers, chances are good that some of those lessons will have to be learned anew. If the kernel were to go with a non-LIRC approach to IR drivers, it would probably, eventually, reach a point where it had a more capable and flexible system with wider device support than is available now. But, between here and there would be a period - perhaps a long period - where in-kernel IR support was not as good as LIRC.

Still, that might just be how things go in the end. The kernel development community, always concerned about what it will have to maintain five or ten years in the future, tends not to be in a hurry to merge something now just because it is seen to work. So, while it is yet possible that LIRC could be merged in something close to its current form, it's also possible that it could lurk on the sidelines while something significantly different is created for the mainline.


(Log in to post comments)

Kernel support for infrared receivers

Posted Dec 2, 2009 19:34 UTC (Wed) by fb (subscriber, #53265) [Link]

Having gone through the adventure of configuring LIRC for a number of applications, I very much welcome its inclusion in the kernel, and hopefully a standardization of its input codes.

Having to manually configure what each button will do for each application is very annoying, and it seems like a waste. Specially when you compare with multimedia keyboards that will send all sorts of standard X codes that all applications accept, and know how to act upon.

Kernel support for infrared receivers

Posted Dec 11, 2009 7:22 UTC (Fri) by Russ.Dill@gmail.com (subscriber, #52805) [Link]

I don't think that any of these plans save you. Sure you have a standard receiver that can push events to evdev, but there are still 5 bazillion remotes. You could even have two remotes that same the same code for different events. I get the impression that evdev would be sending the ir code.

Kernel support for infrared receivers

Posted Dec 2, 2009 19:59 UTC (Wed) by daney (subscriber, #24551) [Link]

I think the people proposing that protocol decoding for raw IR pulse data be done in the kernel have never dealt with the corresponding devices. There are literally hundreds of different incompatible protocols, and the data is often dirty and can have interference from things like fluorescent lights.

Kernel support for infrared receivers

Posted Dec 3, 2009 8:29 UTC (Thu) by Alphix (subscriber, #7543) [Link]

Thinking that everyone who argues for in-kernel decoding lacks the necessary experience and knowledge is a bit presumptuous of you.

I have dealt with the devices (and I wrote the winbond-cir.c driver which is in the 2.6.32 kernel).

There aren't nearly as many protocols as you seem to think, especially not if you weigh the different protocols by market share. Providing in-kernel decoders for RC5, RC6, Sony12/15/20 and NEC(x)1/2 would mean that the vast majority of all remotes you're likely to find in someone's home would work out-of-the-box (for less than 20k of code). It would be easy to support further protocols by providing an additional kernel module if size is an issue.

Saying that the kernel should have no protocol understanding because you might wish to decode the signals from the remote to your 1976 airconditioner using a diode hooked to the mic connector on your soundcard sound to me like saying TCP/IP and the e1000 driver shouldn't be in the kernel because you might want to run SNA/SDLC over your homebrew hardware connected to a serial port (hint, you can - from userspace).

It's not like LIRC is a magic solution that can decode every single protocol either, some protocols will require a very high frequency sampling for a robust decode, which means hardware will have to be setup in advance, which in turn means that you need to know in advance which mode you want the hardware to operate in...LIRC doesn't have any framework for that as far as I know.

In-kernel decoding means that you abstract away the differences between hardware that does the decoding for you and hardware which doesn't (which sounds like a perfect description of why we want device drivers in the first place - to abstract away hardware differences).

Finally, if you do have a truly bizarre remote, the ability to decode raw signals in userspace isn't something any of the people discussing in-kernel LIRC want to remove - they just want to provide something which is more user-friendly in the vast majority of cases.

Kernel support for infrared receivers

Posted Dec 2, 2009 21:32 UTC (Wed) by PhracturedBlue (subscriber, #4193) [Link]

Just this week I went through the process of setting up an LIRC config. IN my case I have an MCE IR receiver, but for various reasons I'm not using an MCE Remote, and didn't want to use an MCE protocol. With LIRC, I could (with a bit of work) specify a config file that maps an RC-5 protocol with a bunch of special buttons to something usable by MythTV. I could never have done that in Windows, and I hope they keep the flexibility of being able to use the hardware to its fullest potential should they move stuff into the kernel. I had the fun of trying to tweak a v4l kernel module for a TV card with a built-in IR receiver a few years back to not send key-repeats so quickly, and it involved writing a bunch of code and a lot of trial and error. Using LIRC's config files is a joy in comparison.

Reminds me of a recent touch-screen debate.

Posted Dec 2, 2009 22:34 UTC (Wed) by neilbrown (subscriber, #359) [Link]

touch screens - such as on the Openmoko freerunner - tend to deliver noisy data, particularly when touched lightly. Should this be processed in-kernel then passed out as nice clean mouse events, or should the raw data get to user space to be processed, and then possibly sent back through the kernel (via uevent) or directly to the application?

It sounds like much the same problem, and it seems likely that the same theme will keep coming up as Linux gets used in more interesting devices.

To my mind, the principles of freedom and openness suggest that the author of a particular driver should be free to manage the processing however (s)he wants. As long as we do get the fully processed events coming from the input subsystem in the kernel, the path they take to get there must be left to the author or maintainer of the code.

Putting it a different way, I think that the interface that needs to be stable is the interface to applications, not the interface to the kernel. More and more, there are user-space programs that work closely with the kernel to provide particular functionality. Freezing the interface between those programs and the kernel seems silly. Freezing the interface between the functionality and the applications is where the focus should be. For both LIRC and touch screens, the frozen interface should be the input subsystem. Where raw noisy inputs are processed is just an implementation detail.

Reminds me of a recent touch-screen debate.

Posted Dec 3, 2009 5:41 UTC (Thu) by xtifr (subscriber, #143) [Link]

"Principles of openness and freedom" are great when you're working on your own stuff, more-or-less independent of others, as the LIRC folks seem to have been doing for some time, but when you start to work with others, new considerations can come into play, such as compatibility, comprehensibility, not stepping on toes, demarcation of boundaries, etc., etc. It's called cooperation, and if LIRC is going to be accepted into the main kernel source tree, then the devs are going to have to cooperate with the folks in charge of the main tree.

If everyone working on drivers were to just do whatever they want, without consideration for how the rest of the kernel operates and is maintained, the kernel would have collapsed under the weight of a million tiny incomprehensibly incompatible interfaces (III) a long time ago! That's why "benevolent dictators" are so critical to successful projects.

Kernel support for infrared receivers

Posted Dec 3, 2009 13:35 UTC (Thu) by seanyoung (subscriber, #28711) [Link]

I've been following this discussion on lkml and found it really painful to watch. The discussion on whether this belongs in kernel space or not seems to be ignored and in stead the debate focusses on how to translate IR codes to key codes.

Doing this in kernel-space is not the right place IMHO.
- IR drivers can exist in user-space too (e.g. libusb) and are perfectly valid, many of the current IR drivers are in user-space. Decoding IR in kernel-space for a user-space IR driver can't be right
- Decoding IR is not trivial at all. I've written a NEC decoder for a laserdisc emulator[3] and I've had to make any tweaks to make it match the behaviour of the original laserdisc player. I'd rather not reboot to apply changes to a IR decoder
- Having another daemon in user-space is not a problem at all, this allows extra security, can be swapped out, etc etc

Now my opinion is of no consequence, however noone has convinced Alan Cox either[1][2] which I find telling for whole thread.

[2] http://lkml.indiana.edu/hypermail/linux/kernel/0911.3/023...
[1] http://lkml.indiana.edu/hypermail/linux/kernel/0911.3/023...
[3] http://openmsx.svn.sourceforge.net/viewvc/openmsx/openmsx...

Kernel support for infrared receivers

Posted Dec 3, 2009 19:52 UTC (Thu) by guus (subscriber, #41608) [Link]

One objection to use evdev I saw was that some LIRC specific behaviour, like mode switch, is then not possible anymore. I have however written a utility that allows input events to be translated into LIRC events, allowing legacy LIRC clients to work with any evdev based remote control.

http://packages.debian.org/inputlirc
http://git.sliepen.org/inputlirc/

Kernel support for infrared receivers

Posted Dec 13, 2009 1:59 UTC (Sun) by cybernytrix (guest, #5727) [Link]

Looks like all you need is a LIRC config => C code generator that can be loaded into the kernel. Any takers?

Kernel support for infrared receivers

Posted Dec 14, 2009 11:25 UTC (Mon) by incase (subscriber, #37115) [Link]

I really don't know wether I want the kernel to "just work" in the sense of generating evdev events for any IR code received.

One reason is that IR codes are not standardized, I once had a TV remote that would turn up the volume on my HiFi amplifier when hitting the key for teletext. In other words: I could have a remote that has the same keycode for the "1" key as some other remote has for the "channel up" key. So which translation should the kernel provide as an evdev event?

The other problem is which remote codes I want the Linux machine to interpret and which ones I don't want it to "see". I don't want Linux to turn up the volume if I hit the "volume up" key on my amplifiers remote (or on my universal remote when in amplifier mode).

Which all boils down to: Even if the kernel could provide a standardized evdev interface for IR events, it would still require configuration. Also I sometimes want to have some IR events routed to one application and others to a different one, which is possible with current LIRC, but I don't see too many options how this could be done with an evdev interface, especially if none of those applications run under X11 (like my VDR and some background tools I control via IR right now).

All in all, I would probably prefer to have LIRC merged mainly "as-is", unless the evdev approach can tackle my "problems" above.

Kernel support for infrared receivers

Posted Dec 14, 2009 18:02 UTC (Mon) by dlang (✭ supporter ✭, #313) [Link]

no scheme can address those problems, but what you can get from evdev is that the application doesn't have to know about IR remotes specificly.

the app can watch for 'volume_up', and do the right thing no matter if the button pressed in on a multimedia keyboard, an IR remote, a RF remote, a USB device, etc.

wither you use LIRC or evdev, there has to be a mapping loaded to map the particular keystrokes to particular scancodes.

this is just like keyboards. different keyboards put the letters in different places without the system having any way to detect this. this doesn't prevent the system from defaulting to a common keymap, but providing the ability to load more specific ones.

Kernel support for infrared receivers

Posted Dec 15, 2009 9:28 UTC (Tue) by incase (subscriber, #37115) [Link]

Well, the problem with IR is that most people I know of have multiple remotes, of which only one should actually be handled by Linux. So if "all" (well, most) remotes "just work" with Linux, too many events will be handled by the Linux apps.
From the application point of view, you are right, the application should just check for "volume up" (and any other type of event it is interested in) and do the right thing.
From the user point of view however, it must be possible to ignore some "volume up" events.
The easiest way to achieve that is to actually provide
"remote_type/vol_up" events and allow the user to tell the system to ignore (or only process) "sony_tv/*" events for example (though I'm not sure how this should work, via a userspace tools, sysfs, ioctl or whatever).

The filtering/routing to different applications is a secondary concern for me. I can solve that in other ways.

Kernel support for infrared receivers

Posted Dec 15, 2009 20:26 UTC (Tue) by dlang (✭ supporter ✭, #313) [Link]

it makes sense to have a default keymap that responds to all volume_up keys, but then have the option of loading a different keymap that only responds to specific volume_up keys.

it's not as simple as saying 'respond to sony_tv/* events' there are many different sony_tv mappings, some of which overlap

Copyright © 2009, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds