$Id: dbgifc.html 1875 2008-02-09 00:26:43Z isely $
Mike Isely <isely at pobox dot com>
You can find the main driver page on the web at http://www.isely.net/pvrusb2/pvrusb2.html.
This page provides additional information related to operation of the driver's debug interface. You don't need to worry about this information unless you're actually trying to debug a problem. (This interface is also used for part of the manual firmware extraction process however in that case, the instructions for that process include the debug interface information you would need.)
Contents
Overview
Debug Interface Basics
Debug Interface Available Commands
The pvrusb2 driver includes a debug interface, which is a method for inspecting driver information and injecting actions into the driver. The interface is command line-based; i.e. you feed the driver a string containing a command and read back results.
Given that we're talking about a Linux kernel mode driver and not some kind of userspace application, then how is it possible to even have a command interface? It's just another sysfs trick. Commands are issued by echoing the string into a particular sysfs file. Reading that same file back returns status information. It's that simple.
First, you need to ensure that the debug interface has been compiled into the driver. Since this interface isn't needed for normal driver operation, then it's likely that a distribution's precompiled kernel with this driver might not have it on. If that is the case for you, then you'll have to rebuild the driver with the appropriate CONFIG option set. Sorry, but that's unavoidable.
The CONFIG option that needs to be on is "CONFIG_VIDEO_PVRUSB2_DEBUGIFC"; it is described as "pvrusb2 debug interface" as an option related to selecting the pvrusb2 driver itself.
If you are using a standalone snapshot of the driver (i.e. you downloaded a tarball from the pvrusb2 web site), then the build process normally always turns on this option for you. In that case, you can ignore the previous two paragraphs.
To access the debug interface, plug in your device as usual, open a shell prompt, then change directory to the driver's sysfs directory. The directory you want will be of the pattern "/sys/class/pvrusb2/sn-XXXXXXXX". (General information about the sysfs interface can be found here.) List that directory and you should find two entries of interest, one named "debugcmd" and the other named "debuginfo". If they aren't present, then odds are that the debug interface has not been compiled into the driver - see above for information on fixing that problem.
The "debugcmd" file is how commands are issued; anything written to here will be parsed and acted upon by the pvrusb2 driver.
You can read from either of "debugcmd" or "debuginfo" to retrieve debugging information from the driver. Different information is produced in each case.
Generally, reading from debugcmd returns information more directly related to specific low level debugging and only really has meaning in the context of other debug commands. Information printed from debugcmd will include a report of USB link speed, GPIO states, and an indication if streaming should be in progress or not.
Reading from "debuginfo" produces information about the driver as a whole - and the mere act of reading this file also triggers a dump of more information into the system log. You'll get 3 categories of information here:
A lot can be learned about what is going on simply by reading "debuginfo" and also examining the system log afterwards.
To make this a little more clear, let's consider an example. Suppose you wanted to force the FX2 processor to reset. The command in that case would be:
echo "reset cpu" >debugcmd
That then causes the driver to issue USB control transfers that ultimately force the FX2 to reset. (However you probably don't want to do this just for kicks, as it will cause the device to momentarily disconnect its USB interface which will look to the kernel like you unplugged then replugged in the cable, which will then cause this sysfs instance to be reset as well. But hey, I said this was a debug interface...)
To summarize:
Below is a list of the currently available debug interface commands. Please remember that these commands are for debugging issues and not for normal operation. Many of these actions can potentially leave the driver in an operable state and/or require power cycling of the PVR USB2 hardware.
reset cpu
reset bus
reset soft
reset deep
reset firmware
reset decoder
reset worker
The driver implements a mechanism for pulling firmware data back out of the device. This refers to only the FX2 firmware - currently there isn't any known means for retrieving the encoder firmware after it has been loaded. This ability is used as part of the manual firmware extraction process (relevant part described here).
The debug interface itself has no means for actually reading large amounts of data (and sysfs itself really isn't that suitable for such a thing). Because of this, the actual act of slurping out the firmware contents happens through the V4L interface. But it is controlled through the debug interface. This works by first issuing a debug interface command to put the driver into "suck firmware mode", then you can grab the contents with a normal cat command from the /dev node (e.g. "/dev/video0") you would normally use to stream video. Finally another debug interface command is issued to return the driver back to normal mode. The debug interface commands are:
cpufw fetch ram
cpufw fetch prom
cpufw done
So, to use this mechanism one must do:
cat /dev/video >tmp/foo.fw
Note that the hardware implementation that makes the "cpufw fetch ram" command possible is somewhat destructive to the device's current state. No permanent harm is done of course, but when the "done" step is performed, the device will reset itself and the driver will re-initialize it. That will also have the effect of causing the driver's sysfs interface to be torn down and recreated (thus affecting this debug interface).
The encoder chip has the ability to control a set of general purpose I/O (GPIO) signals. Various tuner devices use these signals to affect aspects of the device. For example, Hauppauge tuners use one GPIO to control the LED. Other devices might use a GPIO to switch an analog mux that might control selection of the stereo audio input versus the internal FM tuner. Encoder firmware loading also seems to require manipulation of various GPIO signals. As a Linux driver author, there's a certain amount of guesswork needed to figure this out. So the debug interface here includes the ability to directly access GPIO signals.
In our case, there are 3 GPIO registers of interest: an input register, an output register, and a direction register. Generally (there is one important exception), each bit of each register corresponds to a specific GPIO. For example, bit 11 of each register corresponds to hardware GPIO bit 11. The direction register control the in vs out setting of each bit. Reading the input register reads all the GPIO states, while writing the output register sets the GPIO states (for all GPIOs that are set as outputs).
Setting a bit in the direction register sets the corresponding GPIO as an output bit. There is one exception here for our hardware however: GPIO bits 0 through 7 are treated as a unit in the direction register, controlled by direction register bit 7. Said another way, setting bit 7 in the direction register programs all of GPIO bits 0 through 7 as outputs; cleaing direction register bit 7 programs all of GPIO bits 0 through 7 as inputs. Best I can tell right now is that direction register bits 0 through 6 simply have no effect.
So, suppose you wish to clear GPIO bit 11. To do this, you first must ensure that bit position 11 in the direction register has a 1 in it, then put a 0 in bit position 11 of the output register.
To read current GPIO states, just read debugcmd itself; part of the output includes all GPIO states.
With all that said, here are the debug interface commands to control GPIO signals:
gpio dir <mask> <value>
gpio out <mask> <value>
There is no command to control the input register - it is a read-only register and its value is always provided as part of the output when reading the "debugcmd" file itself.
The argument values are expected to be integers. But since they are interpreted as bit mask combinations you will naturally want to use hex values here. Just use the usual C language convention of prefixing 0x to the number and that will have the desired effect.
Given the above and revisiting our example, then to clear GPIO bit 11, the following commands would be issued:
echo "gpio dir 0x0800 0x0800" >debugcmd
echo "gpio out 0x0800 0x0000" >debugcmd