Installing a Hauppauge WinTV PVR USB2
(Simplified instructions for OpenSlug 2.7/3.10 are at the end.)
Unfortunately this package for whatever reason got dropped from SlugOS 3.10. It is in the unstable feed. This version does not require you to copy the hotplug functions.
There are new hardware versions of the WinTV PVR USB2, the driver is still in development! Read more here http://www.isely.net/pvrusb2.html#Caveat. The latest version in the head supports this new hardware version, but it is not as well tested as the old hardware.
Note: this howto is for the 2.6.12 kernel (e.g. OpenSlug 2.5). However, there is a flaw in the x1205 RTC driver in that release which causes a crash when you have multiple I²C busses present (1 in the NSLU2 for the RTC and 1 in the WinTV PVR USB2). When using the WinTV PVR USB2 with a 2.6.12 kernel, you will have to disable or remove the x1205 RTC driver. This will disable the ability for the NSLU2 to keep track of the time whilst off however.
It is also possible to get the WinTV PVR USB2 working under 2.6.14. However, this requires some code changes and is still quite messy. If you are interested, drop me (eFfeM) a note...
Introduction
This howto describes how to install the Hauppauge WinTV PVR USB2 on your
NSLU2. This howto and linked drivers are only for this specific model. Other WinTV PVR devices exist which are incompatible because they are PCI cards. A special note is that it must be the USB2 version of the PVR, there is an older model which is USB1 only which is also not compatible.
This howto has been tested with OpenSlug 2.5. It should also work on the OpenSlug head. You will have to work out the necessary steps for Unslung if you wish to use it under that distribution.
Note: This howto assumes you have experience of Linux, that you have a cross development environment and that you know how to build and flash a kernel.
Building the drivers
There are two different methods to build the drivers.
Method 1: Use the pvrusb2-mci package
This uses the package built by dyoung. It is available as the pvrusb2-mci package on the development head. You might be able to use this with OpenSlug 2.5 as well (I haven't tested this). After building the head copy pvrusb2-mci.ipk to the slug and do a ipkg install pvrusb2-mci
Method 2: Adding it into OpenSlug 2.5
Alternatively one can add the driver into OpenSlug 2.5. This is a little bit more tricky but has the benefit that the kernel itself is more stable (you won't be bitten by unexpected changes elsewhere in the head).
First you'll need to obtain the driver software. This can be found at pvrusb2 Linux driver page. It is a good idea to read this page and the FAQ to learn a little bit about what is going on. I used driver snapshot pvrusb2-mci-20050921.tar.bz2.
The steps to get to the software (all modules) is as follows:
- Build the stock kernel (
source setup-env;bb openslug-kernel
cd tmp/work/openslug-kernel-2.6.12.2-r6/linux-2.6.12.2/drivers
- Unzip and untar your snapshot. If you used the snapshot above that will give you a directory
pvrusb2-mci-20050921/driver. Rename this directory to pvrusb2. Move the files from the driver subdirectory to the pvrusb2 directory.
- In the Makefile in the drivers directory add a line:
obj-y += pvrusb2/
also change the line
obj-y += firmware/
into
obj-m += firmware/
- Change directory to
../../../../stamps and remove
openslug-kernel-2.6.12.2-r6.do_compile; do not do a bb -cclean as this will remove the pvrusb2 directory and your edit in the makefile
- Build the kernel again.
- In
tmp/work/openslug-kernel-2.6.12.2-r6/linux-2.6.12.2/drivers/pvrusb2
you'll now find msp3400.ko pvrusb2.ko saa7115.ko tuner.ko tveeprom.ko
Copy these to the slug. I've stuffed them into /lib/modules/2.6.12.2/pvrusb2 (you'll need to make this directory first)
- In
tmp/work/openslug-kernel-2.6.12.2-r6/linux-2.6.12.2/drivers/base you'll find firmware_class.ko. Also copy this to the slug (in /lib/modules/2.6.12.2/pvrusb2). Apparently pvrusb2.ko requires this as a module. If you find a way to do without this, update this wiki (it should be possible to do without this as firmware loading support is already present in the kernel).
Loading the modules
Assuming all the above succeeded you now need to load all modules on the slug.
Just issue the following commands on the slug:
cd /lib/modules/2.6.12.2
insmod ./kernel/drivers/media/video/v4l1-compat.ko
insmod ./kernel/drivers/media/video/v4l2-common.ko
insmod ./kernel/drivers/media/video/videodev.ko
insmod ./pvrusb2/firmware_class.ko
insmod ./pvrusb2/msp3400.ko
insmod ./pvrusb2/saa7115.ko
insmod ./pvrusb2/tveeprom.ko
insmod ./pvrusb2/tuner.ko
insmod ./pvrusb2/pvrusb2.ko (this one must be last!)
- depmod -a
If insmod complains that a module is already loaded (e.g. tveeprom, or tuner) unload that one first (using rmmod).
For other errors look at the message log (using dmesg).
One issue is that when you reboot, the pvrusb2 module is not automatically reloaded. Fortunately there is an easy solution for this. As root do the following:
echo pvrusb2 >/etc/modutils/pvrusb2
update-modules
Loading the firmware
Next you'll need to extract the firmware. See details at the pvrusb2 Linux driver page. I used fwfind.sh (found in the utils section. The firmware was extracted from wintv_usb2_11_23074.exe. For some reason I had to do fwfind.sh twice to get the firmware files.
Extracting will give you two files:
pvrusb2.f1 8192 bytes 8051 program image
pvrusb2.f2 262144 bytes mpeg2 encoder image
On the slug, create the directory /lib/firmware and copy the two firmware files to this directory.
Next hotplug must be enabled. You might want to peek at OpenSlug/Hotplug for some more info on hotplug and how to enable it.
- Create a directory
/etc/hotplug.d/firmware
- Create a file
firmware.hotplug. Fill it with the contents as specified below. This is a renamed and slightly modified (pathnames) firmware.agent file.
- Create a file
hotplug.functions. Fill it with the contents as specified below. Alternately you could rip it from another system.
- Make both files executable.
Making devices
Next you'll need to make the entries in /dev. I used a script called MAKEDEV.v4l that I got from the Video4Linux sources.
However you can easily issue the needed mknod commands yourself. The major device number is 81, and actually you only need /dev/video0. The others (/dev/radio, /dev/vbi, /dev/vtx) are still unexplored territory.
Below is the full listing of major 81 on my system.
lrwxrwxrwx 1 root root 11 Sep 24 12:52 /dev/radio -> /dev/radio0
crw-rw-rw- 1 root root 81, 64 Sep 24 12:52 /dev/radio0
crw-rw-rw- 1 root root 81, 65 Sep 24 12:52 /dev/radio1
crw-rw-rw- 1 root root 81, 66 Sep 24 12:52 /dev/radio2
crw-rw-rw- 1 root root 81, 67 Sep 24 12:52 /dev/radio3
lrwxrwxrwx 1 root root 9 Sep 24 12:52 /dev/vbi -> /dev/vbi0
crw-rw-rw- 1 root root 81, 224 Sep 24 12:52 /dev/vbi0
crw-rw-rw- 1 root root 81, 225 Sep 24 12:52 /dev/vbi1
crw-rw-rw- 1 root root 81, 226 Sep 24 12:52 /dev/vbi2
crw-rw-rw- 1 root root 81, 227 Sep 24 12:52 /dev/vbi3
lrwxrwxrwx 1 root root 11 Sep 24 12:52 /dev/video -> /dev/video0
crw-rw-rw- 1 root root 81, 0 Sep 24 12:52 /dev/video0
crw-rw-rw- 1 root root 81, 1 Sep 24 12:52 /dev/video1
crw-rw-rw- 1 root root 81, 2 Sep 24 12:52 /dev/video2
crw-rw-rw- 1 root root 81, 3 Sep 24 12:52 /dev/video3
lrwxrwxrwx 1 root root 9 Sep 24 12:52 /dev/vtx -> /dev/vtx0
crw-rw-rw- 1 root root 81, 192 Sep 24 12:52 /dev/vtx0
crw-rw-rw- 1 root root 81, 193 Sep 24 12:52 /dev/vtx1
crw-rw-rw- 1 root root 81, 194 Sep 24 12:52 /dev/vtx2
crw-rw-rw- 1 root root 81, 195 Sep 24 12:52 /dev/vtx3
Testing your work
Testing is not very difficult.
- Power the WinTV PVR USB2 using the supplied PSU. Make sure an antenna is connected with a good signal. Connect the WinTV PVR USB2 via USB to the USB port of a running and booted slug. Hotplug is used to load the modules and firmware, and loading the firmware at slug startup is still untested.
After doing this you might want to do a dmesg | tail and check for the following lines at the end:
pvrusb2 /*--TRACE_COMMIT--*/ "Channel" <-- 0 (<integer>)
pvrusb2 /*--TRACE_COMMIT--*/ "Channel Program ID" <-- 0 (<integer>)
pvrusb2 pvr2_stream_create: sp=c0ff4960
pvrusb2 pvr2_hdw_setup: video stream is c0ff4960
pvrusb2 pvr2_hdw_setup(hdw=c0f6d000) done, ok=1 init_ok=1
pvrusb2 Device initialization completed successfully.
pvrusb2 Registered pvrusb2 v4l device, minor=0
If you got this the hotplugging worked and your driver modules are loaded.
Next do the following (substituting sn-9508240 with whatever is in your pvrusb2 directory):
cd /sys/class/pvrusb2/sn-9508240/ctl_video_standard
- make sure
cur_val has the right value. If not check enum_val for a list of values and do echo newvalue >cur_val
cd /sys/class/pvrusb2/sn-9508240/ctl_frequency
- Find a suitable frequency (not channel!) for your region and type
echo frequency >cur_val. Note that frequency is in Hz, so it will look something like 528000000.
- Type
cat /dev/video0 >/tmp/slug.mpg
- Hit ^C after 10 seconds or so
- Copy /tmp/slug.mpg to a system where you can watch MPEG video (e.g. your Linux or Windows box) and see if it plays.
Report your results
If you manage to get this running, I'd like to hear from you. Please add your name to the list below and/or drop eFfeM an email (fransmeulenbroeks at yahoo dot com). In the evenings (CET+2) and weekends I might also be found on one of the IRC channels
People who got this working:
eFfeM
<yournamegoeshere>
firmware.hotplug
#!/bin/sh
#
# Firmware-specific hotplug policy agent.
#
# Kernel firmware hotplug params include:
#
# ACTION=%s [add or remove]
# DEVPATH=%s [in 2.5 kernels, /sys/$DEVPATH]
# FIRMWARE=%s
#
# HISTORY:
#
# 24-Jul-2003 Initial version of "new" hotplug agent.
#
# $Id: firmware.agent,v 1.3 2004/03/14 15:52:56 ukai Exp $
#
cd /etc/hotplug.d/firmware
. ./hotplug.functions
# DEBUG=yes export DEBUG
# directory of the firmware files
FIRMWARE_DIR=/lib/firmware
# mountpoint of sysfs
SYSFS=$(sed -n 's/^.* \([^ ]*\) sysfs .*$/\1/p' /proc/mounts)
# use /proc for 2.4 kernels
if [ "$SYSFS" = "" ]; then
SYSFS=/proc
fi
#
# What to do with this firmware hotplug event?
#
case "$ACTION" in
add)
if [ ! -e $SYSFS/$DEVPATH/loading ]; then
sleep 1
fi
if [ -f "$FIRMWARE_DIR/$FIRMWARE" ]; then
echo 1 > $SYSFS/$DEVPATH/loading
cp "$FIRMWARE_DIR/$FIRMWARE" $SYSFS/$DEVPATH/data
ls -l "$FIRMWARE_DIR/$FIRMWARE" $SYSFS/$DEVPATH/data $SYSFS/$DEVPATH >>//LOG
echo cp "$FIRMWARE_DIR/$FIRMWARE" $SYSFS/$DEVPATH/data >>/LOG
echo 0 > $SYSFS/$DEVPATH/loading
else
echo -1 > $SYSFS/$DEVPATH/loading
fi
;;
remove)
;;
*)
mesg "Firmware '$ACTION' event not supported"
exit 1
;;
esac
|
hotplug.functions
#
# Setup and BASH utility functions for use in hotplug agents
#
# Most essential parameters are passed from the kernel using
# environment variables. For more information, see the docs
# on-line at http://linux-hotplug.sourceforge.net or the
# sources for each hotplug-aware kernel subsystem.
#
# $Id: hotplug.functions,v 1.26 2004/04/01 07:33:32 kroah Exp $
#
#
# DEBUG=yes; export DEBUG
PATH=/bin:/sbin:/usr/sbin:/usr/bin
KERNEL=`uname -r`
MODULE_DIR=/lib/modules/$KERNEL
HOTPLUG_DIR=/etc/hotplug
if [ -f /etc/sysconfig/hotplug ]; then
. /etc/sysconfig/hotplug
fi
if [ -x /usr/bin/logger ]; then
LOGGER=/usr/bin/logger
elif [ -x /bin/logger ]; then
LOGGER=/bin/logger
else
unset LOGGER
fi
#
# for diagnostics
#
if [ -t 1 -o -z "$LOGGER" ]; then
mesg () {
echo "$@"
}
else
mesg () {
$LOGGER -t $(basename $0)"[$$]" "$@"
}
fi
debug_mesg () {
test "$DEBUG" = "" -o "$DEBUG" = no && return
mesg "$@"
}
#
# Not "modprobe --autoclean" ... one driver module can handle many
# devices. Unloading should be done when no devices are present.
# Autocleaning happens if none of the devices are open, once any of
# them gets opened; wrong timing.
#
MODPROBE="/sbin/modprobe -s -q"
#MODPROBE="/sbin/modprobe -vs"
####################################################################
#
# usage: load_driver type filename description
#
# modprobes driver module(s) if appropriate, and optionally
# invokes a driver-specific setup script (or user-mode driver).
#
# the "modules.*map" format file is guaranteed to exist
#
load_drivers ()
{
local LOADED TYPE FILENAME DESCRIPTION LISTER
DRIVERS=""
# make this routine more readable
TYPE=$1
FILENAME=$2
DESCRIPTION=$3
# should we use usbmodules, pcimodules? not on 2.5+, because sysfs
# ought to expose the data we need to find all candidate drivers.
# (on 2.5.48 it does for usb; but maybe not yet for pci.)
case "$KERNEL" in
2.2*|2.3*|2.4*) LISTER=`which ${TYPE}modules` ;;
*) LISTER="" ;;
esac
if [ "$LISTER" != "" ]; then
# lister programs MIGHT be preferable to parsing from shell scripts:
# - usbmodules used for (a) multi-interface devices, (b) coldplug
# - pcimodules used only for coldplug
case $TYPE in
usb)
# "usbutils-0.8" (or later) is needed in $PATH
# only works if we have usbfs
# ... reads more descriptors than are passed in env
# ... doesn't handle comment syntax either
if [ "$DEVICE" = "" -o ! -f "$DEVICE" ]; then
LISTER=
else
DRIVERS=`$LISTER --mapfile $FILENAME --device $DEVICE`
fi ;;
pci)
debug_mesg "pcimodules is scanning more than $PCI_SLOT ..."
DRIVERS=`$LISTER`
;;
esac
fi
# try parsing by shell scripts if no luck yet
if [ "$DRIVERS" = "" ]; then
${TYPE}_map_modules < $FILENAME
fi
# FIXME remove dups and blacklisted modules from $DRIVERS here
if [ "$DRIVERS" = "" ]; then
return
fi
# Note that DRIVERS aren't all going to be modules.
# For USB, some user-mode drivers or setup scripts may be listed.
debug_mesg Setup $DRIVERS for $DESCRIPTION
# either kernel or user mode drivers may need to be set up
for MODULE in $DRIVERS
do
# maybe driver modules need loading
LOADED=false
if ! lsmod | grep -q "^$(echo $MODULE|sed -e 's/-/_/g') " > /dev/null 2>&1; then
if grep -q "^$MODULE\$" $HOTPLUG_DIR/blacklist \
>/dev/null 2>&1; then
debug_mesg "... blacklisted module: $MODULE"
continue
fi
# statically linked modules aren't shown by 'lsmod',
# and user mode drivers will ONLY have a setup script;
# it's not an error if a module doesn't exist or won't load.
if $MODPROBE -n $MODULE >/dev/null 2>&1 &&
! $MODPROBE $MODULE >/dev/null 2>&1 ; then
mesg "... can't load module $MODULE"
else
# /etc/modules.conf may have set non-default module
# parameters ... handle per-device parameters in apps
# (ioctls etc) not in setup scripts or modules.conf
LOADED=true
fi
else
# This module is already loaded
LOADED=true
fi
# always run setup scripts after any matching kernel code has had
# a chance to do its thing, no matter whether it was dynamically
# or statically linked, or if there is only a user mode driver.
# the script might re-enumerate usb devices after firmware download,
# giving kernel code another chance.
if [ -x $HOTPLUG_DIR/$TYPE/$MODULE ]; then
debug_mesg Module setup $MODULE for $DESCRIPTION
$HOTPLUG_DIR/$TYPE/$MODULE
LOADED=true
fi
if [ "$LOADED" = "false" ]; then
mesg "missing kernel or user mode driver $MODULE "
fi
if echo "$MODULE" | grep -q "usb-storage" > /dev/null 2>&1 ; then
[ -x /usr/sbin/updfstab ] && /usr/sbin/updfstab
fi
done
}
####################################################################
#
# usage: log_to_stdout filename
#
# writes a copy of the current hotplug event to stdout.
# add buffering, to avoid interleaving reports!
#
log_to_stdout ()
{
if [ -x /bin/date ]; then
echo "HOTPLUG_TIME='$(/bin/date)'"
fi
env | egrep -v '^PATH=|^PWD=|^_=|^OLDPWD=|^SHLVL=|^HOME='
echo ''
# empty line terminates events
}
# vim:syntax=sh
|
Simplified instructions for OpenSlug 2.7 / 3.10
It seems that installation is now simpler than suggested by the above, as more things are included in the feed. The following worked for me:
use the same procedure for Openslug 3.10 but you can skip step 7. (Hotplug setup)
- Install OpenSlug 2.7
- Remove ANYTHING related to ntp. The combination PVR and ntp crashs the slug after some seconds. Killing ntp-related processes before connecting the PVR-Box does not solve this.
- ipkg install pvrusb2-mci kernel-module-v4l1-compat kernel-module-v4l2-common kernel-module-videodev kernel-module-firmware-class
- depmod -a
- modprobe pvrusb2
- Install firmware in /lib/firmware as above.
- Add /etc/hotplug.d/firmware/firmware.hotplug and /etc/hotplug.d/firmware/hotplug.functions as above (They must be executable).
- To test, cat /dev/video0 > /tmp/vid.mpeg
That's all there is to it.
This page is password protected.
The password is "wintv". Let's see if that stops the automated wiki spam.