Guide for setting up lirc for Hauppauge PVR-150 IR Remote on Fedora Core 6
2007-08-06: After upgrading via yum to kernel 2.6.20-1.2962, I was unable to recompile lirc [10]. I ended up editing grub to boot the old 2948 kernel instead. Remeber, Fedora is a test-bed for RHEL and these pitfalls should be expected as bugs get ironed out. As of 2007-08-13, I see a new kernel is available which may address the problems I ran into.
This is a guide for getting your Hauppauge PVR-150 Remote Control working with lirc and mplayer on Fedora Core 6. There are lirc RPM packages available from different repositories but I've not been able to get things completely working with those. This Howto will take you through:
- compiling, installing and configuring lirc from source
- testing and inserting kernel modules
- setting up /etc/modprobe.d/lircmods
- setting up a ~/.lircrc for your Hauppauge PVR-150 remote
testing/configuring the entire setup to work with Mplayer from the livna repo.
First off, removing the Fedora lirc rpm via yum will also remove Mplayer which was installed from Livna (dependancy on liblirc_client.so.0 from FC6) - forget that. I've built Mplayer before and it's something best left for a rainy day. We'll just grab the same version of lirc source which Fedora used and cross our fingers.
The Kernel Module
Lirc must have a kernel module[0] available in order for it to work, and for whatever reason, this doesn't seem to be around with kernel-2.6.20-1.2948.fc6 package or lirc-0.8.1-1.fc6. It may be compiled right into the FC6 kernel but I couldn't get it working. So, you will need the kernel development package installed in order to build Lirc (Lirc will take care of the rest). This is easy enough to do via yum:
$ yum install kernel-devel
Obtaining the Lirc Source
Download the latest lirc source[1] and save to it /tmp or other place you can write to. The source I used was lirc-0.8.1.tar.bz2. It's good practice to check the md5, gpg or sha1 signature of packages you download to make sure they've not been corrupted during the download, or somehow tampered with otherwise. Unfortunately, I haven't found these on the lirc site so here we go. Unwrap the source you downloaded from the lirc homepage and then change to the newly created directory:
$ cd /tmp $ tar xvfj lirc-0.8.1.tar.bz2 $ cd lirc-0.8.1
Building Lirc
In the lirc build directory, you will find a configure script to run. This will be used to tell lirc we are building for a hauppauge remote as well as where to place the fresh binaries when installing. I like to put all non-standard stuff I build under /usr/local. I can tell at a glance what is non-standard on the system and keeping the version numbers intact show me at a glance which version is compiled. Also, if I need to remove whatever I've installed, I can just remove the directory under /usr/local and it's gone. No hunting around in /usr/lib or /usr/local/libexec or other bfugly places for parts of packages. I do make heavy use of symlinks with this method, so when a custom package is removed, I also need to search for broken links[2] and remove them to clean up. I don't have to wonder if I've completely removed a piece of software this way. Ok, so onto configuring. Note that it's also good practice to perform the build process as someone other than root. You will need to be root to install, but just in case something gets wacky during the build, the potential to hose the entire system is minimized. I can also recall one instance of trojaned build scripts many years ago, but the ubiquity of package signatures has minimized that risk quite a bit (but yes, they must be available of course).
$ ./configure --prefix=/usr/local/lirc-0.8.1 --with-driver=hauppauge checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for gawk... gawk checking whether make sets $(MAKE)... yes checking for gcc... gcc ... You will have to use the lirc_i2c kernel module. Now enter 'make' and 'make install' to compile and install the package.
Pay close attention to configure. You may need some other development packages installed such as ncurses or even the C compiler, gcc[3]. After configure completes succesfully, continue building the source by running make.
$ make
cd . \
&& CONFIG_FILES= CONFIG_HEADERS=config.h \
/bin/sh ./config.status
config.status: creating config.h
config.status: config.h is unchanged
config.status: executing default-1 commands
make all-recursive
make[1]: Entering directory `/tmp/lirc-0.8.1'
...
/bin/sh ../libtool --mode=link gcc -O2 -g -Wall -o man2html man2html.o
mkdir .libs
gcc -O2 -g -Wall -o man2html man2html.o
make[3]: Leaving directory `/tmp/lirc-0.8.1/doc'
make[2]: Leaving directory `/tmp/lirc-0.8.1/doc'
make[2]: Entering directory `/tmp/lirc-0.8.1'
make[2]: Leaving directory `/tmp/lirc-0.8.1'
make[1]: Leaving directory `/tmp/lirc-0.8.1'
Installing Lirc
Time to install, so su to root however you have it setup, either via sudo bash, or simply su:
$ su Password: [root@localhost ~ ]
Run make install to move the fresh lirc binaries out of your build directory and into /usr/local/lirc-0.8.1
$ make install Making install in drivers make[1]: Entering directory `/tmp/lirc-0.8.1/drivers' Making install in lirc_dev make[2]: Entering directory `/tmp/lirc-0.8.1/drivers/lirc_dev' make[3]: Entering directory `/tmp/lirc-0.8.1/drivers/lirc_dev' ... /usr/bin/install -c -m 644 ./lircd.8 /usr/local/lirc-0.8.1//man/man8/lircd.8 /usr/bin/install -c -m 644 ./lircmd.8 /usr/local/lirc-0.8.1//man/man8/lircmd.8 ... make[2]: Leaving directory `/tmp/lirc-0.8.1' make[1]: Leaving directory `/tmp/lirc-0.8.1'
Configuring Lirc
With Lirc installed, move onto configuration. You will need two files:
- /etc/lircd.conf - used by the lirc kernel module to map serial data to button presses
- ~/.lircrc - your personal button configuration file which maps buttons to Mplayer commands
From the looks of it, these two files take care of mapping serial data from the remote into "buttons" and finally mapping the "buttons" to Mplayer commands. Mplayer reads ~/.lircrc and picks out it's configuration info so it knows what to do when you hit a button on the remote. The button names and Mplayer commands seem to be different between software versions and remotes, so I'm not sure which button mapping files are exactly correct. There are several sample .lircrc files out there, this is the one I used.
$ wget http://wilsonet.com/mythtv/lircrc-haupgrey-g3.txt -O ~/.lircrc
There is a lircd.conf file specially crafted for the hauppauge remote which is available from the Lirc sourceforge site, and one is also distributed with the lirc source code. Grab either of these and copy the file from to /etc/lircd.conf:
$ cp /tmp/lirc-0.8.1/remotes/hauppauge/lircd.conf /etc/lircd.conf
Installation of Duct Tape for Lirc binaries
Since we have all our lirc binaries under /usr/local/lirc-0.8.1, none of the new files are in the path, or available for other programs to use. Keep in mind the fedora Lirc rpm is still installed and those binaries *are* in the path. At this point we can:
- take a chance that things won't conflict
- ..or forcibily remove the lirc rpm with rpm[5]
- ..or overwrite whatever is installed with symlinks which point to the compiled binaries
I chose to forcibly remove[5] the installed lirc rpm to be certain there weren't any conflicting binaries laying around. This is going to cause a problem with Mplayer however because it is looking[6] for liblirc_client.so and it's been removed via rpm. That's OK, because We'll replace it with a symlink pointing to our compiled one in /usr/local/lirc-0.8.1/lib using lndir below:
create the destination directories if they do not exist already:
$ mkdir -p /usr/local/bin /usr/local/sbin /usr/local/lib
symlink the compiled lirc binaries into some common add-on locations: $ lndir /usr/local/lirc-0.8.1/bin/ /usr/local/bin/ $ lndir /usr/local/lirc-0.8.1/sbin/ /usr/local/sbin/ $ lndir /usr/local/lirc-0.8.1/lib/ /usr/local/lib/ }}}
To remove these links at a later time, I can delete the /usr/local/lirc-0.8.1 directory and then run symlinks[7] to clean up the links which point to the now non-existant files.
If we run ldd[6], we'll see that mplayer still hasn't found the liblirc_client.so.0 file. This is because the system hasn't been setup to use /usr/local/lib as a library directory. By default, the only location it will look is in /lib. We don't want to mess around with /lib. This is where all the libraries reside which are responsible for running the entire system. A mistake here may result in re-installing the entire system. It's silly to risk that when there are other options available, so we install our libraries to /usr/local/lib and then update the system configuration to use our new library location. We do this by adding an entry to /etc/ld.so.conf, as root, and then running ldconfig. We can run ldconfig with -v to get a printout of what it's doing. We can then grep this output to see that it finds our new lirc library. We can then ask mplayer[6] about it again to see that it finds the correct library.
$ echo /usr/local/lib >> /etc/ld.so.conf
$ ldconfig -v | grep lirc
liblirc_client.so.0 -> liblirc_client.so.0.2.0
$ ldd /usr/bin/mplayer | grep lirc
liblirc_client.so.0 => /usr/local/lib/liblirc_client.so.0 (0x00002aaaaaadb000)
}}
==== Verifying the kernel module was built correctly ====
compiling lirc will have resulted in two kernel modules being built against your currently running kernel:
* lirc_dev.ko
* lirc_i2c.ko
Verify that these modules have a current date on them. If they do not, there was most likely a conflict while building lirc wich you did not see. You will need to go back and see what the problem is if you do not see the files as below. A simple check here can save a lot of headaches later.
{{{
$ ls -laRt /lib/modules/`uname -r` | grep -i lirc
-rw-r--r-- 1 root root 170395 Jun 23 08:51 lirc_dev.ko
-rw-r--r-- 1 root root 155362 Jun 23 08:51 lirc_i2c.ko
Testing the lirc kernel modules
Check that the lirc_i2c module is not loaded by using lsmod and grepping appropriately. It should come up empty. If not, run modprobe -r to remove it and verify again:
$ lsmod | grep lirc
lirc_i2c 19332 0
lirc_dev 25320 1 lirc_i2c
i2c_core 32833 12 cx88xx,bttv,lirc_i2c,i2c_ec,msp3400,saa7115,tuner,nvidia,ivtv,i2c_algo_bit,tveeprom,i2c_nforce2
$ modprobe -r lirc_i2c
$ lsmod | grep lirc
}}
Now load the lirc_i2c module and verify that it is running. Also check with dmesg for any information it may have given us about the module loading process, and lastly, check that the /dev/lirc0 device does indeed exist after loading:
{{{
$ modprobe lirc_i2c
$ lsmod | grep lirc
lirc_i2c 19332 0
lirc_dev 25320 1 lirc_i2c
i2c_core 32833 12 lirc_i2c,cx88xx,bttv,i2c_ec,msp3400,saa7115,tuner,nvidia,ivtv,i2c_algo_bit,tveeprom,i2c_nforce2
$ dmesg | grep lirc
lirc_dev: IR Remote Control driver registered, at major 61
lirc_i2c: no version for "lirc_unregister_plugin" found: kernel tainted.
lirc_i2c: chip found @ 0x18 (Hauppauge IR)
lirc_dev: lirc_register_plugin: sample_rate: 10
lirc_dev: IR Remote Control driver registered, at major 61
lirc_i2c: chip found @ 0x18 (Hauppauge IR)
lirc_dev: lirc_register_plugin: sample_rate: 10
$ ls -lart /dev/lirc*
crw------- 1 root root 61, 0 Jun 23 11:33 /dev/lirc0
You will notice that modprobe loaded the lirc_dev module for us, which is needed by lirc_i2c.
One problem above is that root is the only person which can access the /dev/lirc0 device. We want to be able to access this as regular users, so certainly this will need to be addressed. Usually these permissions are taken care of with module loading parameters. There is some information about module loading in the lirc documentation[8] but there is talk of /etc/modules.conf and /etc/conf.modules which have been done away with for quite some time. Udev and sysfs are quite new, althogh I'm not clear how these mechanisms are used. The lirc documentation says to copy lirc.rules into the udev directory as follows:
$ cp /tmp/lirc-0.8.1/contrib/lirc.rules /etc/udev/rules.d/ `/tmp/lirc-0.8.1/contrib/lirc.rules' -> `/etc/udev/rules.d/lirc.rules'
...but things didn't work
$ rm /etc/udev/rules.d/lirc.rules
Finally getting to some button pressing
There is another way. I can just load the modules "by hand" at boot time in /etc/rc.local (which is a symlink to /etc/rc.d/rc.local) and make the neccesary adjustments to the device permissions there.
We know the modules we want, the device we need for communication, and the permissions that need to be set. I'm edit /etc/rc.local and load the module, start up lircd, and set the permissions on the device:
/sbin/modprobe lirc_i2c /usr/local/sbin/lircd -d /dev/lirc0 chmod 0666 /dev/lirc0
Lastly, we want to make sure /etc/rc.local is indeed a symlink to /etc/rc.d/rc.local. If we broke the symlink somehow, editing this file will do nothing. ultimately, we want to be editing /etc/rc.d/rc.local. /etc/rc.local is just a shortcut.
ls -l /etc/rc.local lrwxrwxrwx 1 root root 13 Jan 13 08:27 /etc/rc.local -> rc.d/rc.local
Looks good.
For now, we can just run the three lines we entered into /etc/rc.local (/etc/rc.d/rc.local) by had to get our remote working with lirc. When/if we reboot rc.local will get executed and do the same thing.
Next we check the remote with irw, and hit a few buttons to see if it's sending and receiving.
$ irw 0000000000001792 00 Prev.Ch Hauppauge_350 0000000000001792 01 Prev.Ch Hauppauge_350
The button names come from /etc/lircd.conf that we copied into place earlier. When a button is pressed on the remote, the IR receiver hardware and the kernel modules talk to lircd to let it know what happened. The /etc/lircd.conf file contains button mapping data for several remotes. In this case, it's the Hauppage 350.
So, now that lircd, the kernel module, and the remote are all functional we configure mplayer to let it know it should be listening to /dev/lirc0 for remote control information.
in the source directory for lirc (src-0.8.1/contrib/lircrc) is a lircrc file. This file doesn't contain mplayer button info, so we need to use this one I gleaned from the mythtv dox.
# ~/.mythtv/lircrc # # MythTV native LIRC config file for # the new grey Hauppauge remote # # Modified from Jarod Wilson's which came from Jeff Campbell's # By Brad Templeton # Modified by digitek for mplayer # ### MPlayer lirc setup # Show OSD begin prog = mplayer button = MENU repeat = 3 config = osd end # Pause playback begin prog = mplayer button = PAUSE repeat = 3 config = pause end # Skip ahead a minute if playing # If paused, resume playing begin prog = mplayer button = PLAY repeat = 3 config = seek +1 end # Stop playback and exit begin prog = mplayer button = STOP repeat = 3 config = quit end # Mute begin prog = mplayer button = MUTE repeat = 3 config = mute end # Seek forward 30 seconds begin prog = mplayer button = Forward repeat = 3 config = seek +10 end # Quit begin prog = mplayer button = BACK/EXIT repeat = 3 config = quit end # Seek backward 10 minutes begin prog = mplayer button = Rewind repeat = 3 config = seek -10 end # fullscreen begin prog = mplayer button = OK repeat = 3 config = vo_fullscreen config = vo_ontop end # volume up begin prog = mplayer button = Vol+ repeat = 3 config = volume +1 end # volume down begin prog = mplayer button = Vol- repeat = 3 config = volume -1 end
After saving this file, you should be able to start-up mplayer (from a terminal window) and control it via the hauppauge remote. Watch for the first few lines of mplayer to spit out errors about lirc indicating something is amiss.
mplayer: bad file format, /home/yagi/.lircrc:386 Failed to read LIRC config file ~/.lircrc.
Also, don't forget to plug in the IR receiver
Notes/References[0] - lirc_i2c
[1] - http://www.lirc.org/software.html
[2] - man symlinks or symlinks -dr /usr/local
[3] - yum install ncurses-devel; yum install gcc
[4] - http://wilsonet.com/mythtv/lircrc-haupgrey-g3.txt
[5] - $ rpm -e --nodeps lirc-0.8.1-1.fc6
warning: /etc/sysconfig/lirc saved as /etc/sysconfig/lirc.rpmsave
[6] - $ ldd /usr/bin/mplayer | grep lirc liblirc_client.so.0 => not found
[7] - $ symlinks -dr /usr/local/sbin /usr/local/bin /usr/local/lib
dangling: /sbin/lircmd -> /usr/local/lirc-0.8.1/sbin/lircmd
deleted: /sbin/lircmd -> /usr/local/lirc-0.8.1/sbin/lircmd
dangling: /sbin/lircd -> /usr/local/lirc-0.8.1/sbin/lircd
deleted: /sbin/lircd -> /usr/local/lirc-0.8.1/sbin/lircd
[8] - http://www.lirc.org/html/install.html#installing
[9] - Failed to open LIRC support. You will not be able to use your remote control.
[10] - after upgrading via yum ....
make[3]: Entering directory `/usr/local/lirc-0.8.1/src/lirc-0.8.1/drivers/lirc_i2c' mv Makefile Makefile.automake cp ../Makefile.kernel Makefile make -C /lib/modules/2.6.20-1.2962.fc6/build/ SUBDIRS=/usr/local/lirc-0.8.1/src/lirc-0.8.1/drivers/lirc_i2c modules \ KBUILD_VERBOSE=1 make[4]: Entering directory `/usr/src/kernels/2.6.20-1.2962.fc6-x86_64' test -e include/linux/autoconf.h -a -e include/config/auto.conf || ( \ echo; \ echo " ERROR: Kernel configuration is invalid."; \ echo " include/linux/autoconf.h or include/config/auto.conf are missing."; \ echo " Run 'make oldconfig && make prepare' on kernel src to fix it."; \ echo; \ /bin/false) mkdir -p /usr/local/lirc-0.8.1/src/lirc-0.8.1/drivers/lirc_i2c/.tmp_versions
ok.. so..
cp /boot/config-2.6.20-1.2962.fc6 .config make oldconfig #[1]$ make bzImage CHK include/linux/version.h CHK include/linux/utsrelease.h HOSTCC scripts/genksyms/genksyms.o HOSTCC scripts/genksyms/lex.o HOSTCC scripts/genksyms/parse.o HOSTLD scripts/genksyms/genksyms CC scripts/mod/empty.o HOSTCC scripts/mod/mk_elfconfig MKELF scripts/mod/elfconfig.h HOSTCC scripts/mod/file2alias.o HOSTCC scripts/mod/modpost.o HOSTCC scripts/mod/sumversion.o HOSTLD scripts/mod/modpost HOSTCC scripts/kallsyms HOSTCC scripts/pnmtologo HOSTCC scripts/conmakehash make[1]: *** No rule to make target `init/main.o', needed by `init/built-in.o'. Stop. make: *** [init] Error 2
..and still borked.
