V4L/DVB (11765): cx23885: Add generic functions for driving GPIO's

The GPIO's on the product can be in one of three places. To date we've
mainly used the GPIO's on the bridge itself, and once on the encoder.
Rather than having the complexity of multiple GPIO writes/reads from
isolated placed in the driver we'll route them through this function,
so we can make intelligent decisions about 1) Where the GPIO lives
and 2) Whether it conflicts (based on board) with some other function
to avoid bugs.

Signed-off-by: Steven Toth <stoth@kernellabs.com>
Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Steven Toth 2009-05-02 11:29:50 -03:00 committed by Mauro Carvalho Chehab
parent ea3b73dc13
commit 6f8bee9b10
2 changed files with 98 additions and 0 deletions

View file

@ -1733,6 +1733,88 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
return IRQ_RETVAL(handled);
}
int encoder_on_portb(struct cx23885_dev *dev)
{
return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER;
}
int encoder_on_portc(struct cx23885_dev *dev)
{
return cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER;
}
/* Mask represents 32 different GPIOs, GPIO's are split into multiple
* registers depending on the board configuration (and whether the
* 417 encoder (wi it's own GPIO's) are present. Each GPIO bit will
* be pushed into the correct hardware register, regardless of the
* physical location. Certain registers are shared so we sanity check
* and report errors if we think we're tampering with a GPIo that might
* be assigned to the encoder (and used for the host bus).
*
* GPIO 2 thru 0 - On the cx23885 bridge
* GPIO 18 thru 3 - On the cx23417 host bus interface
* GPIO 23 thru 19 - On the cx25840 a/v core
*/
void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask)
{
if (mask & 0x7)
cx_set(GP0_IO, mask & 0x7);
if (mask & 0x0007fff8) {
if (encoder_on_portb(dev) || encoder_on_portc(dev))
printk(KERN_ERR
"%s: Setting GPIO on encoder ports\n",
dev->name);
cx_set(MC417_RWD, (mask & 0x0007fff8) >> 3);
}
/* TODO: 23-19 */
if (mask & 0x00f80000)
printk(KERN_INFO "%s: Unsupported\n", dev->name);
}
void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask)
{
if (mask & 0x00000007)
cx_clear(GP0_IO, mask & 0x7);
if (mask & 0x0007fff8) {
if (encoder_on_portb(dev) || encoder_on_portc(dev))
printk(KERN_ERR
"%s: Clearing GPIO moving on encoder ports\n",
dev->name);
cx_clear(MC417_RWD, (mask & 0x7fff8) >> 3);
}
/* TODO: 23-19 */
if (mask & 0x00f80000)
printk(KERN_INFO "%s: Unsupported\n", dev->name);
}
void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput)
{
if ((mask & 0x00000007) && asoutput)
cx_set(GP0_IO, (mask & 0x7) << 16);
else if ((mask & 0x00000007) && !asoutput)
cx_clear(GP0_IO, (mask & 0x7) << 16);
if (mask & 0x0007fff8) {
if (encoder_on_portb(dev) || encoder_on_portc(dev))
printk(KERN_ERR
"%s: Enabling GPIO on encoder ports\n",
dev->name);
}
/* MC417_OEN is active low for output, write 1 for an input */
if ((mask & 0x0007fff8) && asoutput)
cx_clear(MC417_OEN, (mask & 0x7fff8) >> 3);
else if ((mask & 0x0007fff8) && !asoutput)
cx_set(MC417_OEN, (mask & 0x7fff8) >> 3);
/* TODO: 23-19 */
}
static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
const struct pci_device_id *pci_id)
{

View file

@ -72,6 +72,17 @@
#define CX23885_BOARD_DVBWORLD_2005 16
#define CX23885_BOARD_NETUP_DUAL_DVBS2_CI 17
#define GPIO_0 0x00000001
#define GPIO_1 0x00000002
#define GPIO_2 0x00000004
#define GPIO_3 0x00000008
#define GPIO_4 0x00000010
#define GPIO_5 0x00000020
#define GPIO_6 0x00000040
#define GPIO_7 0x00000080
#define GPIO_8 0x00000100
#define GPIO_9 0x00000200
/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
#define CX23885_NORMS (\
V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443 | \
@ -422,6 +433,11 @@ extern int cx23885_restart_queue(struct cx23885_tsport *port,
extern void cx23885_wakeup(struct cx23885_tsport *port,
struct cx23885_dmaqueue *q, u32 count);
extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask);
extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask);
extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask,
int asoutput);
/* ----------------------------------------------------------- */
/* cx23885-cards.c */