Oct 11 2010

What’s new in IR?

Category: Fedora,Linux,Linux Infrared Remote Controljarod @ 20:39

A whole lot of activity has been going on in the upstream Linux kernel with respect to infrared remote control support lately. The release of kernel 2.6.36 is almost upon us, and that’ll bring the first kernel release with the lirc drivers included. A few have already been ported to the new ir-core in-kernel decoding infrastructure (imon, mceusb, ene and streamzap), with more in the works as time permits. Both Fedora 14 and Ubuntu 10.10 are shipping with backported lirc drivers and ir-core bits (albeit at the moment, the Fedora bits are much newer, but I’ve poked some Canonical folks to see about getting them updated too), as well as lirc 0.8.7-based userspace patched up to work with the in-kernel lirc bits. Fedora 14′s release is still another few weeks out, while Ubuntu 10.10 was just released a few days ago. Seeing a bit of fallout from the changes — mostly Ubuntu users updating and finding things don’t work exactly the way they did before. Stay tuned for an FAQ-ish document on the changes made and how to adapt, will try to get something together sooner than later…

So what else is coming? Well, included in those slightly-newer-ir-core patches in Fedora 14 is a new driver for the Consumer IR functionality in the Nuvoton w836x7hg LPC Super I/O chip, which is found in the ASRock ION 330HT systems. Nuvoton provided me with one of these systems and full documentation on the chip, as well as some sample code in the way of an lirc driver, all of which I’ve used to write a new ir-core driver, which goes by the moniker nuvoton-cir. Seems a few Intel DP55-series motherboards also have these Nuvoton chips on them, so I’m hoping to get ahold of one of those at some point (the ASRock only has RX, the Intel boards may also have TX wired up). The nuvoton-cir driver is currently pending being pulled into the v4l-dvb tree and then along to Linus’ tree for 2.6.37-rc1. Also in the Fedora 14 kernel and already in the v4l-dvb tree, awaiting pull to 2.6.37-rc1 is a fairly large overhaul of the imon driver, which greatly improves locking and key release semantics (mostly courtesy of David Härdeman, with bits and pieces from me mixed in). There’s also a significant amount of updates to core ir-core functionality and the ene_ir driver from Maxim Levitsky (some of which was studied for inspiration in how to write the nuvoton-cir driver). Finally, David also has a port of his winbond-cir driver from a misc input driver to an ir-core driver, which should be merged just after 2.6.37-rc1 (as it depends on some additional code restructuring that depends on some other code, etc…).

Completely unrelated to ir-core, I also picked up a TiVo Slide remote a little while back. Its a hybrid bluetooth/IR remote that comes with its own bluetooth dongle, which when properly paired, results in the remote sending bluetooth commands to the dongle that are delivered to the host system as pure HID usages. Unfortunately, for Linux users, and less unfortunately for me, since it was fun to get it working, it doesn’t yet work right out of the box, as the Linux HID layer didn’t yet fully support all the usages it reported. I’ve submitted a patch for this upstream to the linux-input mailing list, which will hopefully also make 2.6.37-rc1 (its also been backported into the Fedora 14 kernels).

On the userspace side of things, I’ve finally pushed a ton of lirc changes for what will eventually become lirc 0.9.0. Both the still-included kernel modules (many of which I’m thinking of neutering soon) and the in-kernel lirc drivers should work interchangeably with this lirc userspace, if I’ve done things correctly. I haven’t yet cut an lirc 0.9.0-pre1 tarball though, as I’ve been talking with Paul Bender (of minimyth fame) about merging his eventlircd code into the main lirc distribution, as I think its actually a better fit for many use cases where we’re ultimately trying to get linux input layer events translated into commands for a given application (ir-core remotes operating in their native mode send linux input layer events, as do HID devices like my TiVo Slide).


Jul 14 2010

LIRC finally landing upstream

Category: Fedora,Linux,Linux Infrared Remote Controljarod @ 15:41

So after several years of existing out-of-tree, we’re finally making some headway with landing lirc in the upstream Linux kernel. As of 2.6.36, the core lirc device interface (lirc_dev) driver will be merged. We also have a new in-kernel IR protocol decoding infrastructure, currently dubbed “ir-core” (possibly to be renamed to “rc-core”, reflecting a desire to generically support remote controls using signaling other than infrared), which allows for zero-configuration, works  just like a keyboard remote control support, right out of the box. IR decoders are “plugins” to this new infrastructure. I’ve also ported the old lirc_imon and lirc_mceusb drivers to this new infrastructure — the “imon” driver is in 2.6.35, the “mceusb” driver will show up in 2.6.36. So what good does this do without any lirc_foo device-specific drivers, you ask? Well, for one, all the current lirc_foo drivers will be able to be built out-of-tree against an in-kernel lirc_dev. I’ve also put together some entirely new code, in the form of an ir-core IR decoder plugin, which bridges between any in-kernel raw IR decoding driver and lirc_dev. This means that while out of the box, the mceusb driver and stock remote Just Work(tm) via the Linux input layer, you can *also* choose to pass the raw IR along to the lirc decoder plugin, which allows you to use lirc exactly as you would have with lirc_mceusb — decoding done in userspace via lircd. Calling the lirc plugin a decoder plugin is also a bit misleading. Its actually bi-directional codec bridge, meaning you can *also* transmit IR via the blasters on the mceusb devices using the mceusb driver with the lirc decoder plugin.

So what’s next? Well, I’ve got some work to do to make the lirc userspace happy with this merged in-kernel lirc_dev, as there were some assorted interface changes required to make lirc_dev suitable for upstream inclusion. After that, I plan to submit most of the current lirc_foo drivers into the Linux kernel staging tree, building against the in-kernel lirc_dev, but with a caveat that they’re all being put there with the intent that they be ported to the ir-core interfaces, or dropped entirely. I plan on working on as many of these as I can myself, but if they’re in staging, hey, maybe some more people jump in and help.

We’re going to release lirc 0.8.7 Real Soon Now(tm) as the last “legacy”-ish lirc release (hopefully), then we’ll be hard at work (actually, I’m already working on) lirc 0.9.0, which should fully support the in-kernel lirc bits.


Jan 20 2010

SoundGraph iMON (and Antec Veris) LCD/VFD/IR devices

Category: Fedora,Linux,Linux Infrared Remote Control,MythTVjarod @ 11:59

Just a quick summary on the state of things with the SoundGraph iMON and Antec Veris LCD/VFD/IR devices, integrated into many Home Theater PC cases these days (as well as available as additions via 5.25″ bays in existing cases)…

So to start out, let it be known that there are three main classes of SoundGraph iMON devices out there these days:

  1. Really old stuff
  2. Device ID 0xffdc stuff
  3. Current stuff

The really old stuff isn’t particularly common. You can’t buy it new anywhere, so far as I know, and I’ve only ever run into a single person that actually *had* some of the really old stuff (by way of a bug report in Red Hat’s bugzilla). Its all usb-based, with the following device IDs (from the lirc_imon Linux kernel driver):


    /* TriGem iMON (IR only) -- TG_iMON.inf */
    { USB_DEVICE(0x0aa8, 0x8001) },
    /* SoundGraph iMON (IR only) -- sg_imon.inf */
    { USB_DEVICE(0x04e8, 0xff30) },
    /* SoundGraph iMON VFD (IR & VFD) -- iMON_VFD.inf */
    { USB_DEVICE(0x0aa8, 0xffda) },
    /* SoundGraph iMON SS (IR & VFD) -- iMON_SS.inf */
    { USB_DEVICE(0x15c2, 0xffda) },

The infrared receiver in these devices passes raw IR signals through to the driver, which the driver then passes to userspace (to the lirc daemon, lircd), which interprets them and maps them to keys, pretty much just like how most other IR receivers interoperate with lircd.

Now, the device ID 0xffdc (more on that in a sec) and the current stuff behave much differently. These devices do NOT pass raw IR signals, they have onboard IR signal decoders, which convert the received IR signals from raw IR to a unique hex code that represents a specific key. Historically, these devices have also been supported by the lirc_imon Linux kernel driver, and instead of passing raw IR signals to lircd, we simply send the hex code, which lircd would happily map to a key. However, the code paths traveled in lirc_imon by the really old stuff and the newer onboard decode devices diverge quite a bit, and with the onboard decode receivers, we can skip the lircd part entirely, and map the keys in the driver itself, since the raw IR signal has already been decoded.

Enter the imon Linux kernel input layer driver. I’ve split support for the onboard decode devices out of the lirc_imon driver and into a new driver, simply called ‘imon’. The decoded IR signal hex values are all mapped inside the kernel to standard input layer keys, so the driver works “out of the box”, without having to configure anything in userspace (such as lircd, which needs a config file mapping codes to keys, in addition to having to install and run the lircd program itself). I’ve submitted this driver for inclusion in the linux kernel, though my v2 submission (following v1 review fixes, cleanups and refactoring) seems to be stalled at the moment.

Back to the device ID 0xffdc stuff for a second… This snippet from the imon driver begins to explain the problem:


    /*
     * Several devices with this same device ID, all use iMON_PAD.inf
     * SoundGraph iMON PAD (IR & VFD)
     * SoundGraph iMON PAD (IR & LCD)
     * SoundGraph iMON Knob (IR only)
     */
    { USB_DEVICE(0x15c2, 0xffdc) },

As you can see, the *exact* same device ID was used for several different devices, and to date, we don’t have any way in the Linux driver to differentiate between them. This is problematic, because we need to use different display write operations for the VFD and LCD, and of course, it makes no sense to set up a character display on a device without one. As a result, we currently offer a module parameter to specify attached display type, solely so that people can actually use their 0xffdc devices. Now, if I actually had one of these devices myself, with some spare time to snoop usb traffic under Windows, I might be able to figure out what the Windows drivers are looking at to determine which device type they’re talking to…

Fortunately, SoundGraph got a clue for their current lineup of stuff, and we’ve got things as they should be, with unique device IDs per device type, no overlapping. For these devices, we can auto-configure all driver parameters automatically, since we know based on device ID alone exactly what sort of device it is (well, except for the devices we don’t know details on yet, because either they’ve not yet been made/shipped, or nobody that has one cares about Linux…). The imon driver’s device ID table for the current stuff looks like so:


    /*
     * Newer devices, all driven by the latest iMON Windows driver, full
     * list of device IDs extracted via 'strings Setup/data1.hdr |grep 15c2'
     * Need user input to fill in details on unknown devices.
     */
    /* SoundGraph iMON OEM Touch LCD (IR & 7" VGA LCD) */
    { USB_DEVICE(0x15c2, 0x0034) },
    /* SoundGraph iMON OEM Touch LCD (IR & 4.3" VGA LCD) */
    { USB_DEVICE(0x15c2, 0x0035) },
    /* SoundGraph iMON OEM VFD (IR & VFD) */
    { USB_DEVICE(0x15c2, 0x0036) },
    /* device specifics unknown */
    { USB_DEVICE(0x15c2, 0x0037) },
    /* SoundGraph iMON OEM LCD (IR & LCD) */
    { USB_DEVICE(0x15c2, 0x0038) },
    /* SoundGraph iMON UltraBay (IR & LCD) */
    { USB_DEVICE(0x15c2, 0x0039) },
    /* device specifics unknown */
    { USB_DEVICE(0x15c2, 0x003a) },
    /* device specifics unknown */
    { USB_DEVICE(0x15c2, 0x003b) },
    /* SoundGraph iMON OEM Inside (IR only) */
    { USB_DEVICE(0x15c2, 0x003c) },
    /* device specifics unknown */
    { USB_DEVICE(0x15c2, 0x003d) },
    /* device specifics unknown */
    { USB_DEVICE(0x15c2, 0x003e) },
    /* device specifics unknown */
    { USB_DEVICE(0x15c2, 0x003f) },
    /* device specifics unknown */
    { USB_DEVICE(0x15c2, 0x0040) },
    /* SoundGraph iMON MINI (IR only) */
    { USB_DEVICE(0x15c2, 0x0041) },
    /* Antec Veris Multimedia Station EZ External (IR only) */
    { USB_DEVICE(0x15c2, 0x0042) },
    /* Antec Veris Multimedia Station Basic Internal (IR only) */
    { USB_DEVICE(0x15c2, 0x0043) },
    /* Antec Veris Multimedia Station Elite (IR & VFD) */
    { USB_DEVICE(0x15c2, 0x0044) },
    /* Antec Veris Multimedia Station Premiere (IR & LCD) */
    { USB_DEVICE(0x15c2, 0x0045) },
    /* device specifics unknown */
    { USB_DEVICE(0x15c2, 0x0046) },

I’ve personally got the Antec Veris Multimedia Station Elite (VFD, device ID 0×0044) and Premiere (LCD, device ID 0×0045) devices. Both work out of the box with the latest Fedora development kernels, and their displays, when coupled with lcdproc 0.5.3 (or later). No lirc involved at all (though I could use it if I wanted to, talking to the imon driver via lircd’s userspace devinput driver). The only thing that really required any config work was lcdproc — LCDd needs to be told which of its drivers to use, which is ‘imon’ for the iMON VFD devices, and ‘imonlcd’ for the iMON LCD devices, with Protocol=0 for an 0xffdc LCD and Protocol=1 for the newer/saner LCD.


Jan 17 2010

IR send/receive and the Hauppauge HD-PVR

Category: Fedora,Linux,Linux Infrared Remote Controljarod @ 14:43

The Hauppauge HD PVR has been a supported video capture device under Linux for quite some time now. The MythTV 0.22 release officially added support for it as a capture device under Linux. However, because the HD PVR records via an analog input, not via a tuner, you need a way to change channels on the device feeding it. The HD PVR has a built-in IR receiver and transmitter, sitting on an i2c bus on the device, not unlike a number of other Hauppauge devices. Well, with a wee bit of hacking on the hdpvr driver and the lirc_zilog driver, we *can* enable the IR part and use lirc with it.

Here’s a patch against the hdpvr v4l/dvb driver to enable the IR part:
* http://wilsonet.com/jarod/junk/hdpvr-ir/hdpvr-ir-enable.patch

Then you need lirc_zilog, which isn’t in the upstream lirc tree due to concerns over its use of a ‘firmware’ image for its IR transmit tables. I’m maintaining lirc_zilog in my lirc kernel driver git tree though:

* http://git.kernel.org/?p=linux/kernel/git/jarod/linux-2.6-lirc.git;a=tree;f=drivers/input/lirc;hb=HEAD

Note that lirc_zilog started out as a rename of the old lirc_pvr150 driver, which started out as a fork of lirc_i2c, maintained by Mark Weaver, with details on it in his blog. lirc_zilog has been updated for use with newer kernels and more devices though, while the original is only targeted at the PVR-150 and no longer builds on current kernels. Another thing to note is that kernel 2.6.31 introduced a ton of i2c changes, so the lirc_zilog from my git tree won’t work with kernels prior to 2.6.31 anymore, unless you back out the i2c changes.

Once you have the driver built, there are still a few more steps to get things working. Oh yeah. Note that if you’re running Fedora 12 and its latest kernel, you don’t need to worry about any of the above, I already patched all the necessary bits into the Fedora kernel.

Either way, you still need a firmware image, a config file and some scripts to figure out which config stanza you need. Mark’s page includes links to the ‘firmware‘, which is really just a signal lookup table, extracted from the Windows driver. This file needs to go into /lib/firmware/ or wherever it is your distro puts kernel driver firmware images (any sane distro, it should be /lib/firmware these days). At this point, you should be able to load the lirc_zilog driver successfully and without any oopses (I still need to make it so the driver doesn’t oops if the firmware image isn’t found…). To be perfectly clear: the transmitter cannot transmit arbitrary IR commands, only those for which there’s a mapping in this pseudo-firmware table. If your device isn’t in the table, its probably not going to work. At least, not without a newer lookup table. A recommended step to take if you can’t get it working is to try under Windows with the latest Windows driver, which may have a newer table. If that works, we’ll probably want to get that table extracted from the Windows driver and make it available for the Linux driver to use.

Again, we’ll defer to Mark’s page, which includes a link to an lircd config file for the IR blaster to get you started. This file contains config stanzas for every device supported in the binary-only lookup table (aka ‘firmware’) you’ve loaded into the driver. Download it, drop it into /etc/lirc/lircd.conf, and start up lircd. Now you need to figure out which config stanza is the correct one for the device you need to transmit IR commands to. At this point, you should also be able to run irw, and see key presses registered from the flimsy little grey remote included with the HD PVR. Anyhow, back to figuring out the correct device… For me, the simplest thing to do was simply look at the table Mark put together and pick out the closest match to my device — which is cable box codeset 85 for the Motorola DCT6200 (I actually have a QIP6200, but same difference). If its not obvious at a glance which codeset you need, grab Mark’s script to cycle through sending the power button code for each possible config until it happens upon the right one. Once you’ve found the right one, you can edit /etc/lirc/lircd.conf, and strip out all the codesets that *aren’t* the right one. The last step is to then wire up a channel-change script in MythTV for your HD PVR capture device to use. Once again, we turn to Mark, and his channel changer, which you’ll simply need to edit to make sure its using the right codeset.

If during the above, or any time after, you’re having trouble getting any IR transmissions to register, there are a few things to note. First up, the transmitter should light up with each irsend command. If yours isn’t lighting up, its not properly connected, broken, or the driver isn’t actually working. Second, the transmit range is REALLY short, the transmitter needs to be positioned quite precisely over the reception target, or its not going to work — even a few centimeters to the left or right of the reception target, and its probably not going to work.

Now for the big caveat emptor: I believe at this stage, very few (if any) people have been able to actually use the IR part on their HD PVR under Linux reliably. At some point or another, while in the middle of video capture, the device completely deadlocks, and has to be reinitialized. Looking into the root cause of this is on my TODO list, but its a long list…


Jan 17 2010

lirc fail in Fedora

Category: Fedora,Linux,Linux Infrared Remote Controljarod @ 11:04

Ugh. Seems lirc_i2c doesn’t like to work when running the latest Fedora 11 kernel. I fixed the problem in 12, but never got the fix into 11, apparently. And in the latest pushed update kernel for Fedora 12, lirc_serial blows up (while it works in 11). Prime example of why we need to finally get lirc upstreamed, dammit… Anyway, the latest Fedora 11 and 12 2.6.32.x kernel builds have *both* fixed, so if you need either/both, try updating to that — they may be in updates-testing, or you may have to grab them straight out of the Fedora build system, not sure right now…


Jan 17 2010

The lirc_mceusb/lirc_mceusb2 confusion

Category: Linux,Linux Infrared Remote Controljarod @ 10:17

Somehow, despite the fact it says in the lirc 0.8.6 release notes (and I quote):

* merged 1st-gen mceusb device support into lirc_mceusb2,
renamed lirc_mceusb2 to lirc_mceusb

And at the top of lirc_mceusb.c it says:

* Original lirc_mceusb driver deprecated in favor of this driver, which
* supports the 1st-gen device now too. Transmit and receive support for
* the 1st-gen device added June-September 2009,
* by Jarod Wilson and Patrick Calhoun

I also announced this merge on the lirc and mythtv mailing lists. And yet, people *still* keep asking for clarification on the matter. What’s not clear? Can’t people read anymore?

So one last time: Yes, lirc_mceusb2 and lirc_mceusb were merged into a single driver, now called simply lirc_mceusb. Yes, both the older and newer mceusb transceivers are supported by it. Yes, transmit (aka IR blasting) works on ALL of them. And yes, when I say all, that does include on both ports on the older v1 device. Clear enough?


Jan 13 2010

Fun with remotes

Category: Fedora,Linux,Linux Infrared Remote Controljarod @ 23:30

So the Linux Infrared Remote Control project has been around for 10+ years now, with kernel modules that have never ever been incorporated into the Linux kernel. Back in September of 2008, I posted all current lirc kernel drivers on the Linux kernel mailing list (aka lkml). Got tons and tons of feedback, mostly things that needed fixing. :) (And this was after myself, Eric Sandeen, Janne Grunau and a handful of other people to a lesser degree, spent a bunch of time and effort simply cleaning up the code to meet kernel coding standards — see scripts/checkpatch.pl in the linux kernel source tree).

So anyhow, I said thanks much for the feedback (particularly that from Jon Corbet), but hold off on further reviews until we address everything brought up so far, and we’ll resubmit a smaller set of patches for the best of the drivers to keep from being overwhelmed (18 drivers at once was probably a bit much…). Fast-forward slightly over a year. Took way longer to get round two posted than I would have liked, but in October of 2009, I posted just lirc_dev, lirc_imon and lirc_mceusb. Largely no response for a few weeks, then an explosion of north of 250 emails over a couple of weeks bouncing back and forth about how we should do IR in the kernel…

Basically, there are two ways to do things:

1) decode the IR signal inside the kernel and map it to an input subsystem key, i.e. map the IR signal for the Volume Down key on your remote to the input subsystem’s KEY_VOLUMEUP.

2) decode the IR signal in userspace (using lircd) and do with it as you please (ultimately, you can do the exact same thing as #1, but it requires a userspace process and configuration).

So now, one camp insisted that in-kernel decoding was the only true way to do things, because then it’ll Just Work with no configuration required. Except when it doesn’t… See, many IR receivers can handle a myriad of IR protocols and work with nearly any remote control. And an IR signal of protocol X may map to key Y on remote Z, but protocol X may map to key F on remote Q. There is, of course, some low-hanging fruit, where we can set things up to Just Work for the default remotes for a number of receivers, but that winds up being a somewhat limited set of devices — and sometimes the same receiver can be bundled with different remotes. In short, its a mess trying to support everything Just Working. The other major issue on this side of the fence is that userspace decoding requires adding new kernel interfaces and/or significantly altering the existing ones to support IR.

The other camp insisted that in-kernel decoding was a horribly bad idea, and that it should always be done in userspace, mostly because of the aforementioned issues. You’ll just never always get it right, and making changes in userspace is easier for users (imagine that). This is the way lirc has been doing things for 10+ years. Which means, by now, most of the kinks have been worked out (outside of automagic configuration).

I like to play the role of diplomat. And I can see uses for both. So what I *want* to do is work towards a hybrid approach, where driver authors can have their devices support either in-kernel or userspace decoding, or even both, leaving it up to the user to pick which one they want (defaulting to in-kernel, of course, since it ought to be possible to make that Just Work for receiver’s stock remote). The lirc interface and userspace daemon has proven itself stable and reliable over the years, so that’s what we ought to move forward with as the way for doing userspace decoding — we can even feed key presses back into the input subsystem via uinput, if so desired. And for in-kernel decoding, we’ll need to add protocol handlers for at least the major IR protocols (RC5, RC6, NEC, Sony, JVC and a handful of others — see http://www.sbprojects.com/knowledge/ir/ir.htm for a wealth of information on various protocols).

I actually had the SoundGraph iMON driver supporting something of a hybrid approach when I submitted version two of my patches. However, the iMON devices (at least, all recent ones) do onboard decoding, so there isn’t actually any raw IR that can be passed to the lircd userspace, only already-decoded hex values. That being the case, I completely gutted the lirc_imon driver, and it now (at least in my git tree) only supports the really old iMON devices that do pass raw IR, while the recent iMON devices (found in many HTPC cases) are now supported by a pure kernel input layer driver called simply ‘imon’, which I submitted for kernel inclusion a few weeks back (need to get back on that, see if I can figure out what’s holding up it getting merged).

So next up on the docket, after a detour reworking lirc’s core kernel interface driver to support the new kfifo api in linux kernel 2.6.33, is to get lirc_mceusb and maybe one more driver back up to snuff, and submit a version 3 patch, this time for inclusion in the drivers/staging/ tree. There’s some concern that once we add the lirc device interface, it’ll be set in stone, but if we bring it in via staging, its implied that the interface isn’t yet set in stone, so we can alter it if need be. But again, its been around for 10+ years, so I suspect there isn’t much that’ll require changing.

The current work-in-progress stuff can all be found in the kernel git tree I maintain up here: http://git.kernel.org/?p=linux/kernel/git/jarod/linux-2.6-lirc.git;a=summary.

Its also patched into the latest Fedora kernels. Now I just need the time to finish up that v3. And some more sleep.