pvrusb2 driver information

$Id: pvrusb2.html 596 2005-09-11 23:19:49Z isely $

Mike Isely <isely at pobox dot com>

The home location for this page is here.

If you have any suggestions for improving either this web page or the driver itself, please drop me a message.

Contents

Contacting People / Discussion List
Background
Download
Setup
Usage
Interactions with other drivers
FAQ
Utilities
Bugs
Change History

Contacting People / Discussion List

If you wish to contact me, my e-mail address is spelled out at the top of this page.

There is also a pvrusb2 e-mail discussion list, hosted here at this site. This is a mailman-operated list, so you can subscribe, unsubscribe, access your subscription, scan archives, etc via the web. (You can also initiate a subscription by sending a message to <pvrusb2-subscribe at isely dot net>.) Any pvrusb2 relevant topic there is fair game. Posting to the pvrusb2 list is limited to just subscribers, but I encourage you to subscribe to the list.

The main web page for the discussion list can be found here.


Background / Intro

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 making changes. This page describes those efforts.

If you have trouble getting the driver to work, please read through this page again - there are a lot of details here and it's easy to miss something. Also, I've written a short FAQ covering common situations that people have found themselves in. If none of that helps, send me a message - it's entirely possible that you might have encountered something new and thus I want to hear about it so I can address the problem for everyone...


Download

Note that the links below only work when viewing this web page at its home location.

Latest driver snapshot:

pvrusb2-mci-20050911.tar.bz2

Older snapshots (version format is yyyymmdd):

pvrusb2-mci-20050828.tar.bz2
pvrusb2-mci-20050824.tar.bz2
pvrusb2-mci-20050804.tar.bz2
pvrusb2-mci-20050722.tar.bz2
pvrusb2-mci-20050717.tar.bz2
pvrusb2-mci-20050716.tar.bz2
pvrusb2-mci-20050626.tar.bz2
pvrusb2-mci-20050620.tar.bz2
pvrusb2-mci-20050619.tar.bz2
pvrusb2-mci-20050605.tar.bz2
pvrusb2-mci-20050527.tar.bz2
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.


Setup

Prerequisites

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. See the next section about firmware extraction for more information.

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. It has also been successfully tested against stock 2.6.11.10, 2.6.12.3, and 2.6.13-rc6 (using the kernel v4l-provided chip drivers or pvrusb2-supplied chip drivers). Probably you will need something at least this recent. (Note: The driver didn't start working in 2.6.13-rcX until the 20050824 snapshot.)

Note: If your driver build fails with a complaint about being unable to find media/tveeprom.h, then your kernel sources are probably too old.

Firmware extraction

There are a couple programs in the util subdirectory of this distribution that can perform the correct extraction of needed firmware data. Full information on firmware extraction can be found on the separate utilities page, but here's a really quick recipe:

  1. Run the contributed script fwfind.sh.

If the above doesn't work, here a "less" quick recipe to follow:

  1. chdir util (Change directory to the util subdirectory.)
  2. mkdir win_driver
  3. chdir win_driver
  4. unzip driver_package.EXE
  5. chdir ..
  6. ./fwextract.pl

Substitute the name of the driver package you got from Hauppauge for "driver_package.EXE" which is just a placeholder above. If you're starting from a CDROM copy of the drivers, then just copy the driver subdirectory contents into "win_driver" instead of doing the unzip step above.

You now should see two files in the current directory:

FileSizeDescription
pvrusb2.f18192 bytes8051 program image
pvrusb2.f2262144 bytesmpeg2 encoder image

If that didn't work, then possibly you're dealing with a later driver version that fwextract.pl doesn't know how to handle yet. Solving this requires a more complex manual extraction. See here for more info.

Failing all of the above, you can still try to extract the firmware using previous methods. Information on that can be found on Björn's web page, mentioned previously. Note that you may need to rename the firmware file names in that case (see table above for clues on the correct names).

Installation

The driver sources and build files can be found in the driver subdirectory of the distribution.

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.

NOTE: Some people have instead just run "make install" to let the build system copy the modules for you. This worked - up until the 20050527 snapshot. Before that point there was an explicit rule in the driver's local Makefile that did this. However I removed this rule in the (perhaps misguided) goal of simplification and outsourcing of everything to Kbuild. Now if you type "make install" you'll be running the kernel build system's "install" target - which will try to install a kernel not the modules! That of course (hopefully) fails. This problem has been fixed in the 20050605 snapshot.

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):

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.


Usage

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.

Hotplug behavior / recovery

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.

V4L interface

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...)

xawtv

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:

mplayer

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...

xine

Similar to mplayer, xine is reported to work provided you treat the device file as just a normal file with mpeg contents. There is a v4l mode apparently for xine (I haven't tried it), but I've heard that it is very immature and definitely does not work with this driver when run in that manner.

MythTV

The MythTV application of course is the holy grail for this driver. I got sucked into this whole effort because of this desire. Several people have since tested this driver against MythTV and are reporting some success.

If want to try MythTV, here are some tips:

Other V4L info

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.

Sysfs Interface

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, most of which can be set by just writing the new value into it (a few of those controls are actually completely read-only). 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, independent 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).

DVB Interface

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.

IR handling

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).

Frequency Table

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.

Note: You do not need to program this frequency table or otherwise even touch it when using this driver with any v4l application. This table is not even visible in the v4l API; it is only present here to make it easier to debug the driver using sysfs.

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...


Interactions with other drivers

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.7i 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).

Playing well with ivtv

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).

Playing well with xbox

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.

Playing well in v4l

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.


FAQ

I've written up a short list of common mis-steps and solutions encountered by people trying the driver. If you have any suggestions for things to add here, please let me know. Hopefully you can find your situation described here: pvrusb2-faq.html


Utilities

The driver package now includes a few utilities related to operation of this device - including a new means for extracting driver firmware. There is a separate page describing all of this: pvrusb2-utils.html


Bugs

This is a fairly immature driver. There are a number of important issues. However since they change with each driver snapshot, please see the driver/README file included in the snapshot sources for a list issues known when the release was made.

Here is a list of issues discovered since the last release:


Change History

pvrusb2-mci-20050911

pvrusb2-mci-20050828

pvrusb2-mci-20050824

pvrusb2-mci-20050804

pvrusb2-mci-20050722

pvrusb2-mci-20050717

pvrusb2-mci-20050716

pvrusb2-mci-20050626

pvrusb2-mci-20050620

pvrusb2-mci-20050619

pvrusb2-mci-20050605

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)


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