GPIO pins: Difference between revisions
(rewrote cx88 regs section, added example) |
(More examples for cx88xx, rewrote to clarify and reduce repeats) |
||
Line 89: | Line 89: | ||
===GPIOs of CX2388x=== |
===GPIOs of CX2388x=== |
||
To program gpio for card definitions inside cx88-cards.c using RegSpy, included with DScaler - http://dscaler.org , Follow the directions above for the bt8xx cards, but |
To program gpio for card definitions inside cx88-cards.c using RegSpy, included with DScaler - http://dscaler.org , Follow the directions above for the bt8xx cards, but you'll want to consider a different set of values, namely MO_GPx_IO (x=0 to 3). The relevant part of RegSpy's output will look basically like this: |
||
MO_GP0_IO |
|||
MO_GP1_IO |
|||
MO_GP2_IO |
|||
MO_GP3_IO |
|||
The relevant part of RegSpy's output will look basically like this: |
|||
MO_GP0_IO: 000000ff (00000000 00000000 00000000 11111111) |
MO_GP0_IO: 000000ff (00000000 00000000 00000000 11111111) |
||
Line 103: | Line 96: | ||
MO_GP3_IO: 00000000 (00000000 00000000 00000000 00000000) |
MO_GP3_IO: 00000000 (00000000 00000000 00000000 00000000) |
||
Ignoring the binary values in parenthesis, copy the hex values just to the left of them over to the appropriate fields for |
Ignoring the binary values in parenthesis, find the entry in cx88-cards.c for the card you want to edit, and copy the hex values just to the left of them over to the appropriate fields for the mode you want to change. |
||
In the case of an analog TV tuner, the result of your changes should look something like this: |
|||
.type = CX88_VMUX_TELEVISION, |
|||
.vmux = 0, |
|||
.gpio0 = 0x000000ff, |
|||
.gpio1 = 0x0000f35d, |
|||
.gpio2 = 0x00000000, |
|||
.gpio3 = 0x00000000, |
|||
As with all cards, some GPIO pins may be defined as inputs, from the CX2388x's viewpoint. Those GPIO values can just be replaced with all 0's. For the example above, the relevant card defines .gpio2 as input, so we ignored the value RegSpy returned for MO_GP2_IO. |
|||
===GPIO for remotes=== |
===GPIO for remotes=== |
Revision as of 18:38, 7 March 2008
Please note that playing with gpio pins can damage your card
What are GPIO pins?
GPIO means General Purpose I/O. Video decoder chips like the SAA713x or the BT8x8 have a number of I/O pins that are not used by the video decoder itself. They have no special purpose, each manufacturer can do with them whatever he wants.
That makes it hard to answer questions like "What I'll have to fill into these gpio fields when adding a new card", because there simply is no general answer to that question, it completely depends on the board design. Some hopefully useful hints:
- First ignore them completely. Especially with non-bt878 cards (saa7134, cx88 drivers) they might not be used at all or at least not needed for the basic functionality of the board.
- Failing that check out whenever there are already entries for other cards from the same vendor and try these settings. Vendors usually don't redesign everything from scratch for a new card, so chances are good that a identical or very simliar configuation works fine.
What the gpio pins are used for:
- Sometimes, 2 or 3 of them are used to control an audio multiplexer. That is especially true for bt878-based cards, because that chip hasn't a audio mux built-in.
- IR receiver chips are also often connected via GPIO. Thats not the only way though. i2c is common as well, and the cx2388x has built-in support for IR signal sampling.
- Sometimes it is possible to reset external chips via gpio. For example bt878-designs with a msp34xx audio processor usually have the msp34xx reset line linked to one of the gpio pins.
- Sometimes external chips can be enabled/disabled via GPIO. saa7134-based cardbus devices often have the tuner chip disabled, it's impossible to see the device on the i2c bus without waking it up by programming the correct GPIO pin. Probably done to power-down the tuner when unused for a longer battery life. For example, the Terratec Cinergy 400TV mobile uses GPIO 18 to switch the tuner on (0) or off (1).
That list likely isn't complete, but should give an idea what GPIO pins are used for. They might also be completely unused.
It's also noteworthy that some of the GPIO lines can be used to trigger interrupts, i.e. the video chip can raise an IRQ on the PCI bus on GPIO state changes.
Unused Pins are usually programmed as inputs.
These GPIOs can not be read/written from user space. There is no IOCTL for them. They can only be used from within the kernel driver.
GPIOs of SAA713x
The SAA713x has 27 of these pins. Each of them can be programmed to be an input or an output. Unused inputs are usually programmed as inputs. Because of weak internal pull-down resistors in the SAA713x, open inputs are read as zeroes. If a bit is read as "1" after loading the saa7134 module, this means the manufacturer soldered a pull-up resistor to that pin. As they have no resistors to waste, this usually means, they do something with that pin...
So, if you're looking for a GPIO output, and you have a bit that is set to "1" after reset, this pin is a good candidate. Hack the driver to pull this bit low, and see if it does what you want.
If all your GPIO bits are "0" after reset -- bad luck. If there are outputs, they have to be active high. Try to set them high, one by one or groupwise, until you find what you are looking for.
Warning: If that pin is really used as an input, it is probably connected to an other chip's output. If you come and configure it as an output, you have two outputs connected together. Though it is unlikely, this might damage your card. You've been warned.
GPIOs of BT8x8
Here's how to program gpio for card definitions inside bttv-cards.c using RegSpy, included with DScaler - http://dscaler.org Another utility that can come in handy during this process is BtSpy - http://btwincap.sourceforge.net/custom.html
Attach RegSpy to your TV App. Switch some channels around in analog video mode. Take note of the following values:
BT848_GPIO_OUT_EN BT848_GPIO_DATA
Use value of BT848_GPIO_OUT_EN for .gpiomask.
Use the following formula to arrive at values to be inserted into .audiomux array:
(maskedf's) - BT848_GPIO_OUT_EN + (value) = BT848_GPIO_DATA
For example, for card#135, DViCO FusionHDTV5 Lite, I got the following from RegSpy:
BT848_GPIO_OUT_EN: 00e00007 (00000000 11100000 00000000 00000111) BT848_GPIO_DATA: 005ffffd (00000000 01011111 11111111 11111101)
Using the above formula, where "maskedfs" is found by taking gpiomask, and changing all non-zeros to f's. All the zeroed bits in the gpiomask should be ignored, for the purposes of the equation.
maskedfs - gpiomask + (value) = gpiodata 00f0000f - 00e00007 + audiomux = 005ffffd audiomux = 00400005
The following equation gets the same thing done:
(value) = gpiodata + gpiomask - maskedfs
Each .audiomux array member is for a different input:
audiomux[0] - tuner audiomux[1] - radio audiomux[2] - extern audiomux[3] - intern audiomux[4] - off audiomux[5] - on audiomux[6] - extern2
This led me to create the following:
/* ---- card 0x87 --------------------------- */ .audio_inputs = 1, .gpiomask = 0x00e00007, .audiomux = { 0x00400005, 0, 0, 0, 0, 0 },
BtSpy works in a similar method, except that the formula for calculating the gpiodata isn't necessary. The output from BtSpy can be used directly to populate the fields in bttv-cards.c, without the need to interpret the data, as described for use with regspy, above.
GPIOs of CX2388x
To program gpio for card definitions inside cx88-cards.c using RegSpy, included with DScaler - http://dscaler.org , Follow the directions above for the bt8xx cards, but you'll want to consider a different set of values, namely MO_GPx_IO (x=0 to 3). The relevant part of RegSpy's output will look basically like this:
MO_GP0_IO: 000000ff (00000000 00000000 00000000 11111111) MO_GP1_IO: 0000f35d (00000000 00000000 11110011 01011101) MO_GP2_IO: 00000001 (00000000 00000000 00000000 00000001) MO_GP3_IO: 00000000 (00000000 00000000 00000000 00000000)
Ignoring the binary values in parenthesis, find the entry in cx88-cards.c for the card you want to edit, and copy the hex values just to the left of them over to the appropriate fields for the mode you want to change.
In the case of an analog TV tuner, the result of your changes should look something like this:
.type = CX88_VMUX_TELEVISION, .vmux = 0, .gpio0 = 0x000000ff, .gpio1 = 0x0000f35d, .gpio2 = 0x00000000, .gpio3 = 0x00000000,
As with all cards, some GPIO pins may be defined as inputs, from the CX2388x's viewpoint. Those GPIO values can just be replaced with all 0's. For the example above, the relevant card defines .gpio2 as input, so we ignored the value RegSpy returned for MO_GP2_IO.
GPIO for remotes
Sometimes the remote is handled via GPIO. It works according to the following scheme:
There are data bits and signal bits. Signal bits show whether a key is pressed or released; data bits show the key code. Signal bits can be of two types:
- The first type is 1 when the key is released and 0 when the key is pressed
- The second type is 0 when the key is released and 1 when the key is pressed
The mask_keycode should contain only data bits.
The mask_keyup should contain signal bits of first type.
The mask_keydown should contain signal bits of second type.
A good test is that all these masks should not intersect. See also Remote_controllers
Overkilling debug tool
Beside Regspy, which is very useful, a good old magnifying glass is a great tool. GPIO inputs are just pins on video chip and remote or mux switch or audio chip should be standalone. Find them on a board and use a magnifier. You should find the track between them and from a datasheet you'll easily find the correct GPIO values.