aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/video/cx23885/cx23885-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx23885/cx23885-core.c')
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c92
1 files changed, 89 insertions, 3 deletions
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index beda42925ce..bf7bb1c412f 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -1700,9 +1700,13 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
}
if (cx23885_boards[dev->board].cimax > 0 &&
- ((pci_status & PCI_MSK_GPIO0) || (pci_status & PCI_MSK_GPIO1)))
- /* handled += cx23885_irq_gpio(dev, pci_status); */
- handled += netup_ci_slot_status(dev, pci_status);
+ ((pci_status & PCI_MSK_GPIO0) ||
+ (pci_status & PCI_MSK_GPIO1))) {
+
+ if (cx23885_boards[dev->board].cimax > 0)
+ handled += netup_ci_slot_status(dev, pci_status);
+
+ }
if (ts1_status) {
if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
@@ -1729,6 +1733,88 @@ out:
return IRQ_RETVAL(handled);
}
+static inline int encoder_on_portb(struct cx23885_dev *dev)
+{
+ return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER;
+}
+
+static inline 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)
{