V4L/DVB (6252): Adapt drivers to use the newer videobuf modules
[powerpc.git] / drivers / media / video / saa7134 / saa7134-core.c
index be3a81f..a1d986e 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/kmod.h>
@@ -117,6 +116,64 @@ void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
               dev->name, mode, (~mode) & status, mode & status, msg);
 }
 
+void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value)
+{
+       u32 index, bitval;
+
+       index = 1 << bit_no;
+       switch (value) {
+       case 0: /* static value */
+       case 1: dprintk("setting GPIO%d to static %d\n", bit_no, value);
+               /* turn sync mode off if necessary */
+               if (index & 0x00c00000)
+                       saa_andorb(SAA7134_VIDEO_PORT_CTRL6, 0x0f, 0x00);
+               if (value)
+                       bitval = index;
+               else
+                       bitval = 0;
+               saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, index, index);
+               saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, index, bitval);
+               break;
+       case 3: /* tristate */
+               dprintk("setting GPIO%d to tristate\n", bit_no);
+               saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, index, 0);
+               break;
+       }
+}
+
+int saa7134_tuner_callback(void *ptr, int command, int arg)
+{
+       u8 sync_control;
+       struct saa7134_dev *dev = ptr;
+
+       switch (dev->tuner_type) {
+       case TUNER_PHILIPS_TDA8290:
+               switch (command) {
+               case 0: /* switch LNA gain through GPIO 22*/
+                       saa7134_set_gpio(dev, 22, arg) ;
+                       break;
+               case 1: /* vsync output at GPIO22. 50 / 60Hz */
+                       dprintk("setting GPIO22 to vsync %d\n", arg);
+                       saa_andorb(SAA7134_VIDEO_PORT_CTRL3, 0x80, 0x80);
+                       saa_andorb(SAA7134_VIDEO_PORT_CTRL6, 0x0f, 0x03);
+                       if (arg == 1)
+                               sync_control = 11;
+                       else
+                               sync_control = 17;
+                       saa_writeb(SAA7134_VGATE_START, sync_control);
+                       saa_writeb(SAA7134_VGATE_STOP, sync_control + 1);
+                       saa_andorb(SAA7134_MISC_VGATE_MSB, 0x03, 0x00);
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+       default:
+               return -ENODEV;
+       }
+       return 0;
+}
+
 /* ------------------------------------------------------------------ */
 
 
@@ -124,55 +181,28 @@ void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
 /* delayed request_module                                      */
 
 #if defined(CONFIG_MODULES) && defined(MODULE)
-static int need_empress;
-static int need_dvb;
-static int need_alsa;
-static int need_oss;
 
-static int pending_call(struct notifier_block *self, unsigned long state,
-                       void *module)
-{
-       if (module != THIS_MODULE || state != MODULE_STATE_LIVE)
-               return NOTIFY_DONE;
 
-       if (need_empress)
+static void request_module_async(struct work_struct *work){
+       struct saa7134_dev* dev = container_of(work, struct saa7134_dev, request_module_wk);
+       if (card_is_empress(dev))
                request_module("saa7134-empress");
-       if (need_dvb)
+       if (card_is_dvb(dev))
                request_module("saa7134-dvb");
-       if (need_alsa)
+       if (alsa)
                request_module("saa7134-alsa");
-       if (need_oss)
+       if (oss)
                request_module("saa7134-oss");
-       return NOTIFY_DONE;
 }
 
-static int pending_registered;
-static struct notifier_block pending_notifier = {
-       .notifier_call = pending_call,
-};
-
-static void request_module_depend(char *name, int *flag)
+static void request_submodules(struct saa7134_dev *dev)
 {
-       int err;
-       switch (THIS_MODULE->state) {
-       case MODULE_STATE_COMING:
-               if (!pending_registered) {
-                       err = register_module_notifier(&pending_notifier);
-                       pending_registered = 1;
-               }
-               *flag = 1;
-               break;
-       case MODULE_STATE_LIVE:
-               request_module(name);
-               break;
-       default:
-               /* nothing */;
-               break;
-       }
+       INIT_WORK(&dev->request_module_wk, request_module_async);
+       schedule_work(&dev->request_module_wk);
 }
 
 #else
-#define request_module_depend(name,flag)
+#define request_submodules(dev)
 #endif /* CONFIG_MODULES */
 
 /* ------------------------------------------------------------------ */
@@ -206,9 +236,10 @@ int saa7134_buffer_startpage(struct saa7134_buf *buf)
 unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
 {
        unsigned long base;
+       struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
 
        base  = saa7134_buffer_startpage(buf) * 4096;
-       base += buf->vb.dma.sglist[0].offset;
+       base += dma->sglist[0].offset;
        return base;
 }
 
@@ -256,11 +287,12 @@ void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt)
 
 void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf)
 {
+       struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
        BUG_ON(in_interrupt());
 
        videobuf_waiton(&buf->vb,0,0);
-       videobuf_dma_unmap(q, &buf->vb.dma);
-       videobuf_dma_free(&buf->vb.dma);
+       videobuf_dma_unmap(q, dma);
+       videobuf_dma_free(dma);
        buf->vb.state = STATE_NEEDS_INIT;
 }
 
@@ -495,7 +527,7 @@ static void print_irqstatus(struct saa7134_dev *dev, int loop,
        printk("\n");
 }
 
-static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t saa7134_irq(int irq, void *dev_id)
 {
        struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
        unsigned long report,status;
@@ -703,7 +735,6 @@ static int saa7134_hwfini(struct saa7134_dev *dev)
                saa7134_ts_fini(dev);
        saa7134_input_fini(dev);
        saa7134_vbi_fini(dev);
-       saa7134_video_fini(dev);
        saa7134_tvaudio_fini(dev);
        return 0;
 }
@@ -843,7 +874,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
                        latency = 0x0A;
                }
 #endif
-               if (pci_pci_problems & PCIPCI_FAIL) {
+               if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL)) {
                        printk(KERN_INFO "%s: quirk: this driver and your "
                                        "chipset may not work together"
                                        " in overlay mode.\n",dev->name);
@@ -889,15 +920,16 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
                must_configure_manually();
                dev->board = SAA7134_BOARD_UNKNOWN;
        }
+       dev->autodetected = card[dev->nr] != dev->board;
        dev->tuner_type   = saa7134_boards[dev->board].tuner_type;
        dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
        if (UNSET != tuner[dev->nr])
                dev->tuner_type = tuner[dev->nr];
-       printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
-              dev->name,pci_dev->subsystem_vendor,
-              pci_dev->subsystem_device,saa7134_boards[dev->board].name,
-              dev->board, card[dev->nr] == dev->board ?
-              "insmod option" : "autodetected");
+               printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
+               dev->name,pci_dev->subsystem_vendor,
+               pci_dev->subsystem_device,saa7134_boards[dev->board].name,
+               dev->board, dev->autodetected ?
+               "autodetected" : "insmod option");
 
        /* get mmio */
        if (!request_mem_region(pci_resource_start(pci_dev,0),
@@ -943,18 +975,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
                request_module("tuner");
        if (card_is_empress(dev)) {
                request_module("saa6752hs");
-               request_module_depend("saa7134-empress",&need_empress);
        }
 
-       if (card_is_dvb(dev))
-               request_module_depend("saa7134-dvb",&need_dvb);
-
-
-       if (alsa)
-               request_module_depend("saa7134-alsa",&need_alsa);
-
-       if (oss)
-               request_module_depend("saa7134-oss",&need_oss);
+       request_submodules(dev);
 
        v4l2_prio_init(&dev->prio);
 
@@ -1012,6 +1035,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
                saa7134_dmasound_init(dev);
        }
 
+       if (TUNER_ABSENT != dev->tuner_type)
+               saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
+
        return 0;
 
  fail4:
@@ -1151,10 +1177,6 @@ static int saa7134_init(void)
 
 static void saa7134_fini(void)
 {
-#if defined(CONFIG_MODULES) && defined(MODULE)
-       if (pending_registered)
-               unregister_module_notifier(&pending_notifier);
-#endif /* CONFIG_MODULES */
        pci_unregister_driver(&saa7134_pci_driver);
 }
 
@@ -1163,6 +1185,7 @@ module_exit(saa7134_fini);
 
 /* ----------------------------------------------------------- */
 
+EXPORT_SYMBOL(saa7134_set_gpio);
 EXPORT_SYMBOL(saa7134_i2c_call_clients);
 EXPORT_SYMBOL(saa7134_devlist);
 EXPORT_SYMBOL(saa7134_boards);