Oct 11 2010

Linux 2.6.35+ Remote Control Overview

jarod @ 21:46

People have been using remote controls (mostly infrared, but some radio frequency and various other forms) on the Linux systems for quite a number of years now. The Linux Infrared Remote Control project (aka ‘lirc’) has been around for more than a decade, but has also lived the bulk of that life with Linux kernel drivers that were never merged into the Linux kernel for various and sundry reasons. Back in c.2007, iirc, I started really getting involved with the lirc project myself. One thing I started doing was patching the lirc kernel drivers into the Fedora kernels, to make it less work for users to get IR support on their MythTV boxes. One thing led to another, and then I started trying to clean the code up and make it possible to have the code actually merged into the Linux kernel. Well, after a multi-year effort, spanning several thousand lines of change (no small part of which was simply reformatting code to adhere to Linux kernel coding standards), the lirc drivers were finally merged into Linux kernel 2.6.36, under the staging drivers directory. At least, most of them were. Some already had in-kernel counterparts (lirc_atiusb vs. ati_remote and ati_remote2, lirc_i2c vs. ir-kbd-i2c), and some were almost immediately ported to a new in-kernel remote control subsystem that evolved simultaneous with the effort to bring the lirc drivers into the kernel. Long-term, the goal is to port all lirc hardware device drivers over to ir-core device drivers.

Anyhow, following my initial lirc driver posting upstream, there was a lot of push-back on taking in yet another different subsystem that did things entirely its own way. And rightfully so. However, remote controls, at least when raw IR signals are involved, didn’t fit very well into existing subsystems without significant amounts of additions that would only be used by raw IR remotes. Jon Smirl posted an alternate approach to IR, which was very different from lirc, making maximal use of the existing kernel input layer. However, there were a few technical issues remaining with the approach, and it was just an RFC that Jon wasn’t able to devote a whole lot more time to at that point. In stepped Mauro Carvalho Chehab (v4l/dvb tree maintainer), who expanded on some of Jon’s ideas with input from others (David Härdeman, Maxim Levitsky, Christoph Bartelmus, myself), and put together the initial version of what got committed as ir-core. I signed on to start porting a few lirc drivers over to ir-core (started with the imon driver, followed by the mceusb driver), as well as trying to implement a compromise between merging pure lirc and Jon’s initial RFC, which would give us both in-kernel decoding capabilities and userspace (lirc daemon) decoding abilities, so we could minimize fallout porting drivers and leverage the lirc decoder’s years and years of battle-testing.

In the end, it turned out to be relatively easy to write an ir-core “decoder” plugin driver that bridges any raw IR device from ir-core to the traditional lirc device interface (its not so much a “decoder” as a “bi-directional raw IR data pipe” between ir-core and the lirc device interface driver, lirc_dev). The ir-core mceusb, streamzap, ene_ir and nuvoton-cir drivers all support both in-kernel decoding and lirc userspace decoding, as well as lirc userspace IR transmit support (for the drivers where relevant). Out of the box, remotes bundled with the respective receivers Just Work(tm) as Linux input layer devices now, but retain full lirc compatibility. Note that purely scancode-based IR devices, such as the SoundGraph iMON ones, do NOT retain this lirc compatibility, they’re now purely ir-core/input layer devices, as the lirc bridge driver is only for raw IR signal data.

Now, as noted before, most of this didn’t actually land in the upstream Linux kernel until 2.6.36, and some of it is still pending merge for 2.6.37-rc1. But given that I work for Red Hat, and wanted to see this code utilized sooner than that, I’ve (trivially) backported just about all of it into the 2.6.35.x kernel that will be shipping in Fedora 14. Additionally, I talked with some Canonical folks about merging patches into their 2.6.35.x-based kernel for the Ubuntu 10.10 release. (Currently, the Ubuntu code is now a ways behind the Fedora code, but I’ve pointed Canonical folk at the updated patches I’ve put into Fedora, hoping they’ll pull those in as well). So this being the case, users of the latest Fedora and Ubuntu distributions are likely to see some changes in how their remote controls need to be configured.

Fedora users have actually been coping with some work-in-progress changes in this arena for some time (an input layer imon driver has been around in Fedora for some time now, the lirc_zilog driver has been included for ages, i2c changes that hit the kernel back in 2.6.33 have long since been encountered), but Ubuntu users jumping from the 2.6.32.x based kernel in the prior release to a 2.6.35.x plus newer upstream based kernel are likely going to encounter a slightly more bumpy ride.

First up, and I’ve seen multiple users baffled by this already, there were i2c changes in 2.6.33 (iirc) that necessitated some major changes in core device drivers exporting i2c interface ids, as well as in device drivers looking to bind to those exported i2c interfaces. Historically, lirc_i2c would bind to just about anything that was listening at the right i2c address. Now the i2c subsystem enforces only allowing the driver to bind to an interface that actually advertises an exported id the driver claims to support. So certain Hauppauge WinTV PVR-150 cards that have a Zilog z8 IR chip on them used to work with lirc_i2c stopped working, as the lirc_i2c driver doesn’t claim to support an i2c device id of ir_rx_z8f0811_haup. However, the lirc_zilog driver *does* claim to support ir_rx_z8f0811_haup. So the answer to this problem is for people to use lirc_zilog instead (after acquiring the requisite “firmware” blob that it needs — google knows where to find it, its also covered somewhere on this site in a blog posting on the hdpvr’s IR part). Note that lirc_i2c is likely to disappear entirely in the relatively near future, supplanted entirely by ir-kbd-i2c, which is now ported to ir-core, and its input layer event device can be snarfed for keypress data. It even works with ir_rx_z8f0811_haup devices (lirc_i2c *could* be made to support them as well, but I see no point in it, when its going away anyway).

Second up, imon users keep being informed by some helpful configuration scripts or something that they need to use the lirc_imon driver. Unless you have one of the really REALLY old (like, 10 years old, and I’ve only ever encountered one in existence) imon device, you now need the imon driver, not lirc_imon, and you’re not going to see an lirc device interface for it. See earlier note about ir-core drivers and the lirc bridge driver being only for raw IR data. The imon devices all deal in scancodes, so you’re going to need to use lircd in devinput mode, or use inputlirc or eventlircd to get imon input layer keypress data converted into lirc data. (Nb: there are plans underway to merge eventlircd into the main lirc userspace source distribution for the lirc 0.9.0 release).

Third up, DO NOT INSTALL the lirc-module-sources package on Ubuntu, unless you really know what you’re doing and know you need/want it installed. I’ve seen someone with that installed and the resulting modules dropped in place, and suddenly, they had both the new ir-core mceusb driver and the old lirc_mceusb driver loading. Two drivers for the same hardware is… well, bad. The only legitimate reasons for installing that package, imo, is a) to get lirc_atiusb if for some reason you can’t live without it and ati_remote/ati_remote2 or the atilibusb userspace lirc driver don’t work for you and b) an ir-core driver (or kernel-provided lirc driver) is horribly broken for you for some reason. In any of those cases, you’d need to be certain to blacklist the kernel-provided modules, lest you wind up with two drivers loading for the same hardware, which as noted before, is very un-good.

Fourth and finally, provide detailed bug reports if something isn’t working. I’ve seen a few bugs reported that were along the lines of “I upgraded and now my remote doesn’t work”. These are less than useful. You need to provide details on the hardware you have, what drivers you’re using, exactly what isn’t working, and so on. Pointing me directly at bugs helps too. Most Fedora lirc/IR bugs will wind up in my lap already, but if you’re using another distribution, you’ll need to get my attention. I do have a Launchpad account, and will subscribe to bugs where relevant. I’ve also got an upstream bugzilla.kernel.org account, and will try to handle any bugs there I’m made aware of. I’m also fielding questions on the lirc mailing list, the linux-media mailing list and the mythtv-users mailing list. Please don’t email me off-list about this though, as your question may be answerable by others who have already been where you are and/or the answer may help the next person to come along, so ask questions on the mailing lists. If you really need some direct and interactive help, I can also be found on irc.freenode.net in #lirc (and #mythtv and #fedora-kernel) most weekdays from 9 to 5 east coast US time (give or take an hour either side of those).

Leave a Reply

You must be logged in to post a comment. Login now.