V4L/DVB (12304): cx23885: Remove hardcoded gpio bits from the encoder driver
authorSteven Toth <stoth@kernellabs.com>
Fri, 26 Jun 2009 02:43:31 +0000 (23:43 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sat, 12 Sep 2009 15:17:53 +0000 (12:17 -0300)
The encoder driver has hardcoded GPIO bits set for the HVR1800, regardless
of whether it's being used by a HVR1800 or not. I've implemented some generic
GPIO manipulation routines and I'm calling them only when appropriate.

Signed-off-by: Steven Toth <stoth@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/cx23885/cx23885-417.c
drivers/media/video/cx23885/cx23885-cards.c
drivers/media/video/cx23885/cx23885-core.c
drivers/media/video/cx23885/cx23885.h

index 1a1048b..6c3b51c 100644 (file)
@@ -630,6 +630,39 @@ int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value)
        return retval;
 }
 
+void mc417_gpio_set(struct cx23885_dev *dev, u32 mask)
+{
+       u32 val;
+
+       /* Set the gpio value */
+       mc417_register_read(dev, 0x900C, &val);
+       val |= (mask & 0x000ffff);
+       mc417_register_write(dev, 0x900C, val);
+}
+
+void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask)
+{
+       u32 val;
+
+       /* Clear the gpio value */
+       mc417_register_read(dev, 0x900C, &val);
+       val &= ~(mask & 0x0000ffff);
+       mc417_register_write(dev, 0x900C, val);
+}
+
+void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput)
+{
+       u32 val;
+
+       /* Enable GPIO direction bits */
+       mc417_register_read(dev, 0x9020, &val);
+       if (asoutput)
+               val |= (mask & 0x0000ffff);
+       else
+               val &= ~(mask & 0x0000ffff);
+
+       mc417_register_write(dev, 0x9020, val);
+}
 /* ------------------------------------------------------------------ */
 
 /* MPEG encoder API */
@@ -955,25 +988,8 @@ static int cx23885_load_firmware(struct cx23885_dev *dev)
        retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS,
                IVTV_CMD_HW_BLOCKS_RST);
 
-       /* Restore GPIO settings, make sure EIO14 is enabled as an output. */
-       dprintk(2, "%s: GPIO output EIO 0-15 was = 0x%x\n",
-               __func__, gpio_output);
-       /* Power-up seems to have GPIOs AFU. This was causing digital side
-        * to fail at power-up. Seems GPIOs should be set to 0x10ff0411 at
-        * power-up.
-        * gpio_output |= (1<<14);
-        */
-       /* Note: GPIO14 is specific to the HVR1800 here */
-       gpio_output = 0x10ff0411 | (1<<14);
-       retval |= mc417_register_write(dev, 0x9020, gpio_output | (1<<14));
-       dprintk(2, "%s: GPIO output EIO 0-15 now = 0x%x\n",
-               __func__, gpio_output);
-
-       dprintk(1, "%s: GPIO value  EIO 0-15 was = 0x%x\n",
-               __func__, value);
-       value |= (1<<14);
-       dprintk(1, "%s: GPIO value  EIO 0-15 now = 0x%x\n",
-               __func__, value);
+       /* F/W power up disturbs the GPIOs, restore state */
+       retval |= mc417_register_write(dev, 0x9020, gpio_output);
        retval |= mc417_register_write(dev, 0x900C, value);
 
        retval |= mc417_register_read(dev, IVTV_REG_VPU, &value);
@@ -1788,9 +1804,6 @@ int cx23885_417_register(struct cx23885_dev *dev)
                return err;
        }
 
-       /* Initialize MC417 registers */
-       cx23885_mc417_init(dev);
-
        printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
               dev->name, dev->v4l_device->num);
 
index a9d3629..742af19 100644 (file)
@@ -582,6 +582,15 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
                /* CX23417 GPIO's */
                /* EIO15 Zilog Reset */
                /* EIO14 S5H1409/CX24227 Reset */
+               mc417_gpio_enable(dev, GPIO_15 | GPIO_14, 1);
+
+               /* Put the demod into reset and protect the eeprom */
+               mc417_gpio_clear(dev, GPIO_15 | GPIO_14);
+               mdelay(100);
+
+               /* Bring the demod and blaster out of reset */
+               mc417_gpio_set(dev, GPIO_15 | GPIO_14);
+               mdelay(100);
 
                /* Force the TDA8295A into reset and back */
                cx_set(GP0_IO, 0x00040004);
index bf7bb1c..554f085 100644 (file)
@@ -868,6 +868,14 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
        dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n",
                __func__, dev->radio_type, dev->radio_addr);
 
+       /* The cx23417 encoder has GPIO's that need to be initialised
+        * before DVB, so that demodulators and tuners are out of
+        * reset before DVB uses them.
+        */
+       if ((cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) ||
+               (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER))
+                       cx23885_mc417_init(dev);
+
        /* init hardware */
        cx23885_reset(dev);
 
index d68574d..0958d6a 100644 (file)
 #define GPIO_7 0x00000080
 #define GPIO_8 0x00000100
 #define GPIO_9 0x00000200
+#define GPIO_10 0x00000400
+#define GPIO_11 0x00000800
+#define GPIO_12 0x00001000
+#define GPIO_13 0x00002000
+#define GPIO_14 0x00004000
+#define GPIO_15 0x00008000
 
 /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
 #define CX23885_NORMS (\
@@ -505,6 +511,9 @@ extern void cx23885_417_check_encoder(struct cx23885_dev *dev);
 extern void cx23885_mc417_init(struct cx23885_dev *dev);
 extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value);
 extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value);
+extern void mc417_gpio_set(struct cx23885_dev *dev, u32 mask);
+extern void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask);
+extern void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput);
 
 
 /* ----------------------------------------------------------- */