Remote controllers-V4L

From LinuxTVWiki
Jump to navigation Jump to search


Several remote controllers are now supported in the mainline Linux kernel, for example the Ati Remote Wonder (ati_remote module).

Others are still only supported by the lirc project.

Winfast and Hauppauge remotes supported in kernel

Kernel version remote control support for Leadtek Winfast remote controls, shipped with both bttv and cx88 cards, and for Hauppauge Remote Control (the newer, gray remotes; seems there are multiple slightly different versions), shipped with cx88 and ivtv cards, was added in 2.6.12:

Infrared remote control support in video4linux drivers

Documentation/video4linux/ taken from 2.6.12-rc2. For the current version see Hg version of the kernel documentation.


Current versions use the linux input layer to support infrared remote controls. I suggest to download my input layer tools from<date>.tar.gz

Card Modules to load
saa7134 Most cards need only the saa7134 driver, but a few need the ir-kbd-i2c helper. Boards known to require ir-kbd-i2c include the Upmost Purple TV and the latest "i-series" Pinnacle PCTV boards (110i, 50i)
bttv Most cards need only the bttv driver, but a few need the ir-kbd-i2c helper. Known cards needing ir-kbd-i2c include Pixelview and Hauppauge cards.

V4L doesn't support all the cards that lirc supports (yet), mainly for the reason that the code of lirc_i2c and lirc_gpio was very confusing and I decided to basically start over from scratch. Feel free to contact me in case of trouble. Note that the ir-kbd-i2c module works on 2.6.x kernels only through ...

How it works

The modules register the remote as keyboard within the linux input layer, i.e. you'll see the keys of the remote as normal key strokes (if CONFIG_INPUT_KEYBOARD is enabled).

Using the event devices (CONFIG_INPUT_EVDEV) it is possible for applications to access the remote via /dev/input/event<n> devices. You might have to create the special files using "/sbin/MAKEDEV input". The input layer tools mentioned above use the event device.

The input layer tools are nice for troubleshooting, i.e. to check whenever the input device is really present, which of the devices it is, check whenever pressing keys on the remote actually generates events and the like. You can also use the kbd utility to change the keymaps (2.6.x kernels only through).

Using with lircd

lircd versions newer than 0.7.0 support reading events from the linux input layer (via event device). This method replaces lirc_gpio and lirc_i2c, so make sure you don't have any of those modules loaded. The input layer tools tarball comes with a lircd config file.

Quick instructions
  • Check if the support for your remote has been loaded by v4l by running "cat /proc/bus/input/devices". The output is the list of input devices your system has (usually the keyboard, a mouse, and if your remote is working, the remote). Search for a line that start with "N:" (the name of the input device) and contains the name of your v4l board or the driver for that board. Like this:
 I: Bus=0018 Vendor=0000 Product=0000 Version=0000
 N: Name="Pinnacle PCTV"
 P: Phys=i2c-0/0-0047/ir0
 H: Handlers=kbd event2
 B: EV=100003
 B: KEY=108fc010 2100802 0 0 0 0 48000 2180 c0000801 9e1680 7bb80 0 4000

or this

 I: Bus=0001 Vendor=109e Product=036e Version=0001
 N: Name="bttv IR (card=137)"
 P: Phys=pci-0000:00:08.0/ir0
 H: Handlers=kbd event2
 B: EV=100003
 B: KEY=2c0814 100004 0 0 0 4 2008000 2090 2001 1e0000 7ff80 0 0

Now, look at the H: line. See that event2 at the end? Take note of your eventX value (might be different than 2)

  • Now you've identified the input device, it's time to record the keys for your remote so it can be used with LIRC. Type "irrecord -H dev/input -d /dev/input/eventX /tmp/my-remote" (X is the value you got from the H: line in the previous step. In this case, it would be "/dev/input/event2"). If all goes well, LIRC should start giving you instructions to configure your keys. Follow them.
  • In recent versions of LIRC, you can use the device name or physical location as an alternative to the device path at /dev. For the previous example, it would be irrecord -H dev/input -d name="bttv IR (card=137)", or irrecord -H dev/input -d phys=pci-0000:00:08.0/ir0. This is especially useful when the number of the device keeps changing (with Cardbus os USB devices)
  • If during the above configuration you fail at the step "hold down a key" with the error "can not find gap" or similar, repeat the process but instead of holding down a key, press and release a key continuously ("click" a key).
  • When you finish configuring your keys, you'll be left with a /tmp/my-remote file. Copy it to /etc/lircd.conf or, if /etc/lirc exists, /etc/lirc/lircd.conf.
  • Start lircd using the same options you used for irrecord (i.e. lircd -H dev/input -d /dev/input/eventX, or lircd -H dev/input -d name="bttv IR (card=137)" ). If you have a configuration file for lirc (in Fedora Core, for example, it's /etc/sysconfig/lircd; in Debian, it's /etc/lirc/hardware.conf and may be altered via "dpkg-reconfigure lirc"), edit it and add those options there.
  • Run irw and press a few keys on the remote. You should see the names you gave the keys appearing. Congratulations, you now have LIRC running with your remote.

Using without lircd

XFree86 likely can be configured to recognise the remote keys. Once I simply tried to configure one of the multimedia keyboards as an input device, which had the effect that XFree86 recognised some of the keys of my remote control and passed volume up/down key-presses as XF86AudioRaiseVolume and XF86AudioLowerVolume key events to the X11 clients.

It likely is possible to make that fly with a nice xkb config file, I know next to nothing about that through.

Note that the linux keyboard driver interface (the really old one, not the linux input layer added in 2.4) has a limitation on the number of keys it can distingish -- it's 200 plus something. That is inherited from PS/2. As long as X11 still used the old kbd driver instead of the linux input layer, it will have problems supporting all keys :-/

How to add remote control support to a card (GPIO remotes)

The operation is as follows (at least it is how i did it):

  1. you make definitions for your board to have remote control (in saa7134-cards.c).
  2. in saa7134-input.c, you add a case for it into the switch statement, with mask_keycode=0. Use any ir_codes array for the start. Well, you should also determine whenever polling is needed, too.
  3. Load saa7134 module with ir_debug=1 parameter.
  4. press the keys on your remote control and watch syslog (dmesg). You will see something like
build_key gpio=0x12345 mask=0x0 data=0

in dmesg output after each key press/release.

Pay attention to gpio=0x... stuff. You will see some bits which does not change, and some which do. The ones which changes should be in your mask_keycode and mask_keydown (mask_keycode should contain not more than 8 bits set to 1, others should be set to 0). Mask_keyup and mask_keydown - those are easy to determine if you see some bit is always on when you press a key and off when you release it, or the reverse.

Ie, you will have to determine which bits in gpio value represents the key# pressed/released, and which indicate whenever it is the press or release.

After this, recompile saa7134 module with correct mask_* stuff in your saa7134_input_init1() routine. Now, the dmesg output should look like

build_key gpio=0x12345 mask=0x<mask_value> data=5

Ensure the data= value is different for each key, if not, you'll have to modify mask_keycode again.

Next, build the key table, by writing a file with one line for every of your key, with two fields -- key name and the data=value assotiated with it.

Try to find existing table matching your one. If there's one, use it. If none is found, build your own.

Please note that sometimes gpio is enabled by some gpio output chip. In that case I would recommend to collect regspy output first. It will show if gpio values really change.

Combined GPIO remotes

Sometimes remotes are not pure gpio and acts a bit differently. For example, keypress can be signalled by gpio and keyvalue can be read from i2c device. If you seen only 1 bit is changing in gpio once it's probably this situation.

saa7133[0]/ir: build_key gpio=0x0 mask=0x0 data=0
saa7133[0]/ir: build_key gpio=0x40 mask=0x0 data=0

Sometimes the rc5 value is delivered directly to gpio. In that case you'll see a lot of changes when you press a single key

saa7133[0]/ir: build_key gpio=0x0 mask=0x0 data=0
saa7133[0]/ir: build_key gpio=0x40 mask=0x0 data=0
saa7133[0]/ir: build_key gpio=0x0 mask=0x0 data=0
saa7133[0]/ir: build_key gpio=0x40 mask=0x0 data=0
saa7133[0]/ir: build_key gpio=0x0 mask=0x0 data=0
saa7133[0]/ir: build_key gpio=0x40 mask=0x0 data=0
saa7133[0]/ir: build_key gpio=0x0 mask=0x0 data=0
saa7133[0]/ir: build_key gpio=0x40 mask=0x0 data=0