|
@@ -1733,6 +1733,88 @@ out:
|
|
|
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)
|
|
|
{
|