$Id: pvrusb2.html,v 1.37 2005/05/28 01:44:57 isely Exp $
Mike Isely <isely at pobox dot com>
The home location for this page is here.
This driver is intended for the Hauppauge WinTV PVR USB 2.0, which is a USB 2.0 hosted TV Tuner. Examples for sale can be found at pricegrabber.
This driver is very much a work in progress. Its history started with the reverse-engineering effort by Björn Danielsson whose web page can be found here. From there Aurelien Alleaume began an effort to create a video4linux compatible driver. His web page about this driver can be found here. Unfortunately it seems that Aurelien has stopped working on this driver. Repeated attempts to contact him over several months have not been successful. Thus I have for now taken Aurelien's latest snapshot and begun another round of changes. This page describes those efforts.
Latest driver snapshot:
pvrusb2-mci-20050527.tar.bz2
Older snapshots (version format is yyyymmdd):
pvrusb2-mci-20050520.tar.bz2 pvrusb2-mci-20050516.tar.bz2 pvrusb2-mci-20050515.tar.bz2 pvrusb2-mci-20050505.tar.bz2 pvrusb2-mci-20050430.tar.bz2 pvrusb2-mci-20050427.tar.bz2
pvrusb2-mci-20050423.tar.bz2
pvrusb2-mci-20050421.tar.bz2
pvrusb2-mci-20050313.tar.bz2
pvrusb2-mci-20050227.tar.bz2
Drop me a message (address at top of page) and I'll add you to a notification list for driver updates.
This driver only works under Linux 2.6.x. I have not made any attempt to even try it in 2.4.x and I know there are environmental differences which likely prevent it from running or even loading.
The WinTV-PVR-USB-2.0 tuner is a device containing an 8051 microcontroller and another programmable part (either the FPGA or the cx23416 mpeg2 encoder, not exactly sure), both of which must be loaded with vendor firmware before the driver will run. That firmware is not included here; you must extract it from the Windows driver package that came with your device and then place that firmware in a location where the hotplug system can find it. The best instructions for doing this can be found on Björn's web page, mentioned previously above. Note that you may need to rename the firmware file names. The two files should be:
File | Size | Description |
---|---|---|
pvrusb2.f1 | 8192 bytes | 8051 program image |
pvrusb2.f2 | 262144 bytes | mpeg2 encoder image? |
The main driver module (pvrusb2.ko) specifically depends on several other kernel modules in order to function correctly. These are tveeprom.ko, tuner.ko, msp3400.ko, and saa7115.ko. All except saa7115.ko can be built as part of the core v4l kernel implementation, or they can all be found as part of the ivtv driver. A snapshot from ivtv of these modules is included in this snapshot and is built alongside everything else here. However you may elect to use later (and perhaps improved) versions from elsewhere. More details on this can be found further down. Regardless of the ultimate source for these drivers, they must be loaded into the kernel in order for the pvrusb2 driver to function correctly. If tveeprom.ko is not present, then pvrusb2.ko will fail to load (and probably complain about a symbol tveeprom_hauppauge_analog being undefined). But the other modules are all bound late into the driver via the I2C abstraction layer so their absence will be harder to figure out.
This driver has been tested against 2.6.10-ac12 and 2.6.11.7 with the "-3" v4l release applied against it. Probably you will need something at least this recent.
Compile this driver more or less in the usual way one does to build 2.6.x kernel modules outside of the kernel source tree. Said another way, you need a kernel source tree somewhere nearby, and you need to run make here with KDIR or KREL variables set to help make find where you put that source tree. For example:
export KREL=`uname -r`
export KDIR=/lib/modules/$KREL/source
make
If you set neither KDIR nor KREL, then KREL is assumed to be the output of uname -r and KDIR is assumed to be /lib/modules/$(KREL)/source (same as the example above). Since nothing else except the default KDIR value needs KREL, then you can skip setting KREL if you set KDIR. This is all explained in the comments that you can find within the Makefile itself.
Before going on, you did extract and install the 2 required vendor firmware files, right? If not, go back and read the second paragraph of the Prerequisites section above before continuing any further.
Once you have the driver compiled, you must copy the the binary modules into your kernel's module area. The target directory is typically under /lib/modules/$(KREL). I usually use /lib/modules/$(KREL)/pvrusb2/ as the destination. Note that there are multiple modules (*.ko) to copy. The actual driver is pvrusb2.ko and you must copy that. The other modules as mentioned earlier function in a support role; copy them as well if you want to use them. Otherwise, ensure that equivalents are available through some other means. After everything is copied, run depmod -a so that the module loader will recognize any needed dependencies.
A few important notes need to be said here about those "support" modules before we continue (this comes from feedback from various people trying out the driver):
find /lib/modules/$(KREL)/ -name tuner.ko -print
If you miss this detail, you may end up loading the wrong module. Do
this before you execute the depmod -a step.tveeprom: tuner = Philips FM1236 MK3 (idx = 58, type = 4)
Then you are using a type 58 tuner. This is a problem for the version
of tveeprom.ko included with the Linux kernel - it doesn't
correctly map that type to a v4l tuner definition. Thus you won't be
able to tune anything and you'll get static. The solution in this
case is to use the tveeprom.ko included in this snapshot (or
tveeprom.ko included in ivtv; they're the same).You can next execute modprobe pvrusb2 to load the driver. After this point, lsmod should show pvrusb2, tveeprom, tuner, msp3400, and saa7115 all present. With hotplug running, this step is not strictly needed, as hotplug will do the needed module loading when the device appears in the system.
Plug in your WinTV-PVR-USB-2.0 device and after a few seconds the driver should be ready to go. Progress can be noticed by watching the kernel log.
Note that the level of log verbosity is controlled through a global bit mask variable whose name is debug. This mask is set initially at compile time from within pvrusb2-main.c, using defined values found in pvrusb2-debug.h. This variable is also a module parameter and may be assigned at loading time. Also, like all other module parameters, the debug mask can be adjusted at any time via sysfs. Read the file /sys/module/pvrusb2/parameters/debug to find the current mask, and echo a new value into that file to adjust the mask.
If the driver isn't loaded when you plug in the device, that's OK because if you're running hotplug, then the driver should be automatically found and loaded for you.
The pvrusb2 driver should be robust enough now that it can survive about any hardware abuse you can throw at it. There are no known situations where it should ever generate a kernel oops. You should be able to plug / unplug the hardware or insert / remove the device to your devious heart's content and the Linux kernel should just keep merrily going on its way. (Obviously if you find out otherwise, please let me know.)
There is one issue however with the device itself. From experiments I have done, it seems that if the device is in the middle of transaction with the driver, that unplugging the device at that instant can leave it in a useless (maybe crashed?) state. The only recovery is to power cycle the device. I have tried numerous approaches to implementing automatic recovery in the driver, but there doesn't seem to be any strategy possible that guarantees recovery. However I did the next best thing: If the driver detects that the device might be jammed, it will log a message suggesting that the device be power cycled. The driver should come through all this just fine of course.
This driver provides an implementation of the video4linux driver API. Any v4l application which can handle an mpeg2 stream should in theory be able to use this driver. (Unfortunately there seem to be very few v4l apps which can...)
One application you can try is xawtv 4.x. Note that anything before version 4 will definitely not work with this since earlier versions did not support mpeg2 decoding. Obviously, make sure you've built xawtv with mpeg2 video and mp3 audio support configured into it.
The xawtv application seems to have a number of rough edges. I've been testing with a snapshot from February which has worked well enough for me, but there are issues. More recent snapshots - as recent as 20050518-16206 have a bug which completely breaks the ability to stream mpeg2 video. The maintainer has been contacted and he's committed a fix to his CVS repository. So hopefully anything after that point should work a lot better. Here is a list of known issues to watch out for when trying xawtv:
Another application that works is mplayer. There are two ways to use mplayer: You can tell mplayer it's dealing with a tv device, or just pass it /dev/video0 (or whatever the right name is on your system) as the "file" to play. The first method has not been well tested, and is suspected to have problems. The second method however works well. More debugging is needed here with the first method...
The MythTV application of course is the holy grail application for this driver. I got sucked into this because of this desire. But alas right now I seriously doubt that the pvrusb2 driver will work with MythTV. This is the end goal, though.
If you really feel adventurous and want to try MythTV anyway, I suspect your best chance of it working is if you tell MythTV that it is talking to an ivtv type of device (e.g. PVR-250).
Please contact me if you find other apps which work, and I'll list them here.
This v4l implementation should allow for multiple opens. Said another way, if you have one application reading video from /dev/video0, it should be possible to have another application still open /dev/video0 and successfully manipulate driver controls. Of course, only one application at a time can stream video. A second attempt at streaming will be greeted with an I/O error.
There is an additional interface available with this driver. In parallel with the v4l interface, you can now access all driver controls via sysfs. Once the device is plugged in and the driver is loaded, try this:
# cd /sys/class/pvrusb2/sn-XXXX
where XXXX is the serial number of your device (just let tab-completion do the hard work here since unless you have multiple tuners there will only be one file there). Now use "ls" and you'll see a whole bunch of directories all starting with "ctl_". Here is what my system looks like:
londo:~# cd /sys/class/pvrusb2/sn-6829718/ londo:/sys/class/pvrusb2/sn-6829718# ls ctl_audio_bitrate ctl_freq_table_value ctl_streaming_enabled ctl_audio_crc ctl_frequency ctl_streaming_force_suspend ctl_audio_emphasis ctl_hue ctl_treble ctl_audio_layer ctl_input ctl_vbr ctl_audio_mode ctl_interlace ctl_video_average_bitrate ctl_balance ctl_mute ctl_video_peak_bitrate ctl_bass ctl_resolution_hor ctl_video_standard ctl_brightness ctl_resolution_ver ctl_volume ctl_channel ctl_saturation device ctl_contrast ctl_signal_present driver ctl_freq_table_channel ctl_srate londo:/sys/class/pvrusb2/sn-6829718#
(The device and driver links you see there by the way point off to other parts of sysfs where the driver's and device's lower level control files can be found.)
Each ctl_ directory has some subset of these files:
You can read any of these files just by cat'ing it out. All are read-only except for cur_val, which can be set by just writing the new value into it. The incoming value must be either a legal enumeration constant (for enumerated controls) or an integer within the legal range specified by min_val and max_val in order for the assignment to "take". Otherwise the program doing the write should get back an EINVAL error status.
I put together this interface to make it easier to debug the driver, independant of an application like xawtv. The possibilities here are obvious. For example, it should be possible open the /dev/ entry into mplayer and then completely control everything else with this sysfs interface while mplayer is running. One could write a control program in Perl with this interface...
Please be aware that with this interface one has complete run of all the driver's controls. There are certainly combinations of settings which, uh, won't work very well. For example, changing the capture resolution is not a pathway very well trodden yet. But as I said, I put this here to make it easier to debug the driver. It was either this or invent a pile of new ioctl()'s and write a test program to operate those settings (the ioctl() approach I believe is what ivtv does).
I have several interesting thoughts towards also making a DVB interface concurrently available. This device after all deals in mpeg2 streams not video frames, so from a purist standpoint it's probably closer to DVB in behavior than v4l. The internal structure of the driver now should make this sort of stunt possible, but I need to do more research before I can determine if it is truly feasible. In the mean time, there's no DVB interface.
The IR receiver within the device is an I2C part that is understood by the lircd software package (0.7 or later). Previously Aurelien's driver hardcoded something here which made the IR receiver into another source for /dev/input, but I had stability problems with this and just decided to rip it out in favor of letting more stable external software handle this function.
You should do here precisely the same solution as that needed for ivtv. In other words, grab lircd 0.7 or later, build it, modprobe the I2C driver into the kernel and when configured with the appropriate lircd.conf (one is included with the pvrusb2 driver), it should "just work". The I2C driver should discover the internal I2C bus made available by the pvrusb2 driver, probe that bus, and attach itself when it finds the IR receiver chip it will be looking for.
I have received one report that this in fact does work (I haven't tested it myself yet).
There is a frequency table implemented inside this driver. It is not available for v4l, but it can be used with the sysfs control interface. You must program it first before using it, but once programmed it becomes possible to change the channel just by, well, writing the new channel number to the driver. The table size is currently limited to channel numbers 1 through 500 (far in excess of anything anyone should need), and the channel ids must be integers not something cute like station call letters.
The frequency table must be programmed a slot at a time. You do this by first selecting the slot's id (a.k.a. the channel number) into the freq_table_channel variable through sysfs. Once selected, you can read / write the frequency (in Hz) for that slot using the freq_table_value variable through sysfs. Repeat this process for all channels to be programmed. Yes, this is just begging for a shell script to do the dirty work. Anyone care to write one?
Once you've programmed the desired slots in the table, just "change the channel" by writing the desired channel number to the channel variable through sysfs. That's it.
The frequency can still be set as before by writing the actual frequency to the frequency variable. If that is done, then the channel will be implicitly set to zero, which means "none". Thus the channel and frequency variables at all times stay consistent with each other and there's no loss of flexible or any implied confusion.
The frequency variable can of course be read back at any time to see what the actual frequency is, regardless of whether it was set directly or implied by a channel setting. And of course the channel variable can be read back at any time to find out what the current channel is or if it is not being used due to the frequency being directly set (in which case the value read back will be zero).
Why do this? Well it was dirt-cheap easy to implement, and it does help with debugging, though in a minor way. Besides it's cool to do. OK, OK. Enough playing and back to the real rework...
Aurelien's version of this driver implemented all chip-level functionality directly inside the pvrusb2 source code. All of these chips are accessed via an internal I2C bus, and it so happens that the Linux kernel has a fairly decent I2C abstraction layer in it. In addition, there already exist more complete and better-tested chip level drivers out there that use this I2C abstraction layer. So the first thing I did was to implement a proper I2C adapter driver within pvrusb2, and then (similar to the IR remote description earlier) I proceeded to rip out the redundant code in favor of using the better external implementations. The external chip-level drivers currently being used are:
This driver snapshot includes copies of all of the above listed chip-level drivers, however they are just exact copies from version 0.3.3h of the ivtv driver. They are merely included here for convenience. It is my intention to leave the corresponding source files unchanged, in order to better track the upstream source.
All of the above chip-level driver except saa7115.ko are also available as part of the core v4l distribution. They are known to work, but the v4l implementation of tveeprom.ko does not handle type 58 tuners (look back to the Installation section of these notes for more information on this).
Even though the PVR USB2 is a USB device while everything else driven by ivtv is a PCI device, there really is more than a passing resemblance among them. As such it's no coincidence that all the listed chip-level drivers above also happen to come from ivtv. (In fact, the same NDA-protected, no-datasheet-available cx23416 mpeg2 encoder - which is the heart of ivtv - is also used in this device.) If you have / need to also use ivtv, it should be possible for this driver to coexist with it. You can discard all the chip-level drivers list earlier from this package in favor of the versions from ivtv (which likely will have additional fixes).
The X-box has an internal I2C bus, and the code that was hacked together for it makes the assumption that it is the only I2C bus that can possibly exist on an xbox. That assumption becomes false when a PVR USB2 device is introduced, unfortunately. The problem here is that the I2C driver code for the xbox tries to attach to the PVR USB2's I2C bus, causing dangling pointers in the xbox driver code and chaos ensues. If you have an xbox, I have a patch for the xbox I2C driver code that makes it play nicer (it's still a horrible hack though). I will try to get that code submitted back to the xbox author(s). In the mean time, contact me for the patch.
The v4l implementation is still undergoing development - and recently there has been some maintainership turmoil. There's a risk that a later snapshot may cause this driver to break. Indeed, it is already known that you need at least 2.6.10-3 of the v4l kernel patch for the driver to even work. There isn't anything really that can be done here yet about this problem, except to warn the reader to watch out for trouble.
pvrusb2-mci-20050527
pvrusb2-mci-20050520
pvrusb2-mci-20050516
pvrusb2-mci-20050515
pvrusb2-mci-20050505
pvrusb2-mci-20050430
pvrusb2-mci-20050427
pvrusb2-mci-20050423
pvrusb2-mci-20050421
pvrusb2-mci-20050313
pvrusb2-mci-20050311
pvrusb2-mci-20050227
pvrusb2-mci-20050217
(Aurelien's 07112004 snapshot starting point)
This is a very immature driver. There are a number of issues. However since they change with each driver snapshot, please see the README file included in the snapshot sources for a list issues known when the release was made.
Feel free to e-mail me (address at the top of this page) if you have any questions or just want to say hello...
Mike Isely