Merge branch 'core/xen' into x86/xen
[safe/jmp/linux-2.6] / drivers / media / video / ivtv / ivtv-driver.c
index b533188..4afc7ea 100644 (file)
@@ -101,7 +101,7 @@ static int radio[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
 static unsigned int cardtype_c = 1;
 static unsigned int tuner_c = 1;
 static unsigned int radio_c = 1;
-static char pal[] = "--";
+static char pal[] = "---";
 static char secam[] = "--";
 static char ntsc[] = "-";
 
@@ -132,6 +132,7 @@ static int ivtv_pci_latency = 1;
 
 int ivtv_debug;
 
+static int tunertype = -1;
 static int newi2c = -1;
 
 module_param_array(tuner, int, &tuner_c, 0644);
@@ -154,6 +155,7 @@ module_param(dec_mpg_buffers, int, 0644);
 module_param(dec_yuv_buffers, int, 0644);
 module_param(dec_vbi_buffers, int, 0644);
 
+module_param(tunertype, int, 0644);
 module_param(newi2c, int, 0644);
 
 MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
@@ -188,11 +190,18 @@ MODULE_PARM_DESC(cardtype,
                 "\t\t\t22 = ASUS Falcon2\n"
                 "\t\t\t23 = AverMedia PVR-150 Plus\n"
                 "\t\t\t24 = AverMedia EZMaker PCI Deluxe\n"
+                "\t\t\t25 = AverMedia M104 (not yet working)\n"
+                "\t\t\t26 = Buffalo PC-MV5L/PCI\n"
                 "\t\t\t 0 = Autodetect (default)\n"
                 "\t\t\t-1 = Ignore this card\n\t\t");
-MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
-MODULE_PARM_DESC(secam, "Set SECAM standard: B, G, H, D, K, L, LC");
-MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J, K");
+MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60");
+MODULE_PARM_DESC(secam, "Set SECAM standard: BGH, DK, L, LC");
+MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J (Japan), K (South Korea)");
+MODULE_PARM_DESC(tunertype,
+               "Specify tuner type:\n"
+               "\t\t\t 0 = tuner for PAL-B/G/H/D/K/I, SECAM-B/G/H/D/K/L/Lc\n"
+               "\t\t\t 1 = tuner for NTSC-M/J/K, PAL-M/N/Nc\n"
+               "\t\t\t-1 = Autodetect (default)\n");
 MODULE_PARM_DESC(debug,
                 "Debug level (bitmask). Default: 0\n"
                 "\t\t\t   1/0x0001: warning\n"
@@ -456,9 +465,8 @@ static void ivtv_process_eeprom(struct ivtv *itv)
        if (itv->options.radio == -1)
                itv->options.radio = (tv.has_radio != 0);
        /* only enable newi2c if an IR blaster is present */
-       /* FIXME: for 2.6.20 the test against 2 should be removed */
-       if (itv->options.newi2c == -1 && tv.has_ir != -1 && tv.has_ir != 2) {
-               itv->options.newi2c = (tv.has_ir & 2) ? 1 : 0;
+       if (itv->options.newi2c == -1 && tv.has_ir) {
+               itv->options.newi2c = (tv.has_ir & 4) ? 1 : 0;
                if (itv->options.newi2c) {
                    IVTV_INFO("Reopen i2c bus for IR-blaster support\n");
                    exit_ivtv_i2c(itv);
@@ -490,30 +498,35 @@ static v4l2_std_id ivtv_parse_std(struct ivtv *itv)
 {
        switch (pal[0]) {
                case '6':
+                       tunertype = 0;
                        return V4L2_STD_PAL_60;
                case 'b':
                case 'B':
                case 'g':
                case 'G':
-                       return V4L2_STD_PAL_BG;
                case 'h':
                case 'H':
-                       return V4L2_STD_PAL_H;
+                       tunertype = 0;
+                       return V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
                case 'n':
                case 'N':
+                       tunertype = 1;
                        if (pal[1] == 'c' || pal[1] == 'C')
                                return V4L2_STD_PAL_Nc;
                        return V4L2_STD_PAL_N;
                case 'i':
                case 'I':
+                       tunertype = 0;
                        return V4L2_STD_PAL_I;
                case 'd':
                case 'D':
                case 'k':
                case 'K':
+                       tunertype = 0;
                        return V4L2_STD_PAL_DK;
                case 'M':
                case 'm':
+                       tunertype = 1;
                        return V4L2_STD_PAL_M;
                case '-':
                        break;
@@ -529,14 +542,17 @@ static v4l2_std_id ivtv_parse_std(struct ivtv *itv)
                case 'G':
                case 'h':
                case 'H':
+                       tunertype = 0;
                        return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
                case 'd':
                case 'D':
                case 'k':
                case 'K':
+                       tunertype = 0;
                        return V4L2_STD_SECAM_DK;
                case 'l':
                case 'L':
+                       tunertype = 0;
                        if (secam[1] == 'C' || secam[1] == 'c')
                                return V4L2_STD_SECAM_LC;
                        return V4L2_STD_SECAM_L;
@@ -550,12 +566,15 @@ static v4l2_std_id ivtv_parse_std(struct ivtv *itv)
        switch (ntsc[0]) {
                case 'm':
                case 'M':
+                       tunertype = 1;
                        return V4L2_STD_NTSC_M;
                case 'j':
                case 'J':
+                       tunertype = 1;
                        return V4L2_STD_NTSC_M_JP;
                case 'k':
                case 'K':
+                       tunertype = 1;
                        return V4L2_STD_NTSC_M_KR;
                case '-':
                        break;
@@ -584,8 +603,13 @@ static void ivtv_process_options(struct ivtv *itv)
        itv->options.tuner = tuner[itv->num];
        itv->options.radio = radio[itv->num];
        itv->options.newi2c = newi2c;
-
+       if (tunertype < -1 || tunertype > 1) {
+               IVTV_WARN("Invalid tunertype argument, will autodetect instead\n");
+               tunertype = -1;
+       }
        itv->std = ivtv_parse_std(itv);
+       if (itv->std == 0 && tunertype >= 0)
+               itv->std = tunertype ? V4L2_STD_MN : (V4L2_STD_ALL & ~V4L2_STD_MN);
        itv->has_cx23415 = (itv->dev->device == PCI_DEVICE_ID_IVTV15);
        chipname = itv->has_cx23415 ? "cx23415" : "cx23416";
        if (itv->options.cardtype == -1) {
@@ -664,7 +688,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
        spin_lock_init(&itv->lock);
        spin_lock_init(&itv->dma_reg_lock);
 
-       itv->irq_work_queues = create_workqueue(itv->name);
+       itv->irq_work_queues = create_singlethread_workqueue(itv->name);
        if (itv->irq_work_queues == NULL) {
                IVTV_ERR("Could not create ivtv workqueue\n");
                return -1;
@@ -711,6 +735,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
        itv->yuv_info.lace_mode = ivtv_yuv_mode;
        itv->yuv_info.lace_threshold = ivtv_yuv_threshold;
        itv->yuv_info.max_frames_buffered = 3;
+       itv->yuv_info.track_osd = 1;
        return 0;
 }
 
@@ -828,6 +853,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
        return 0;
 }
 
+#ifdef MODULE
 static u32 ivtv_request_module(struct ivtv *itv, u32 hw,
                const char *name, u32 id)
 {
@@ -840,14 +866,16 @@ static u32 ivtv_request_module(struct ivtv *itv, u32 hw,
        IVTV_DEBUG_INFO("Loaded module %s\n", name);
        return hw;
 }
+#endif
 
 static void ivtv_load_and_init_modules(struct ivtv *itv)
 {
        u32 hw = itv->card->hw_all;
        unsigned i;
 
+#ifdef MODULE
        /* load modules */
-#ifndef CONFIG_VIDEO_TUNER
+#ifndef CONFIG_MEDIA_TUNER
        hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER);
 #endif
 #ifndef CONFIG_VIDEO_CX25840
@@ -859,7 +887,9 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
 #ifndef CONFIG_VIDEO_SAA7127
        hw = ivtv_request_module(itv, hw, "saa7127", IVTV_HW_SAA7127);
 #endif
+#ifndef CONFIG_VIDEO_SAA717X
        hw = ivtv_request_module(itv, hw, "saa717x", IVTV_HW_SAA717X);
+#endif
 #ifndef CONFIG_VIDEO_UPD64031A
        hw = ivtv_request_module(itv, hw, "upd64031a", IVTV_HW_UPD64031A);
 #endif
@@ -884,6 +914,7 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
 #ifndef CONFIG_VIDEO_M52790
        hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790);
 #endif
+#endif
 
        /* check which i2c devices are actually found */
        for (i = 0; i < 32; i++) {
@@ -988,7 +1019,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
        ivtv_cards[ivtv_cards_active] = itv;
        itv->dev = dev;
        itv->num = ivtv_cards_active++;
-       snprintf(itv->name, sizeof(itv->name) - 1, "ivtv%d", itv->num);
+       snprintf(itv->name, sizeof(itv->name), "ivtv%d", itv->num);
        IVTV_INFO("Initializing card #%d\n", itv->num);
 
        spin_unlock(&ivtv_cards_lock);
@@ -1022,7 +1053,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                                       IVTV_ENCODER_SIZE);
        if (!itv->enc_mem) {
                IVTV_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n");
-               IVTV_ERR("or disabling CONFIG_HIMEM4G into the kernel would help\n");
+               IVTV_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n");
                retval = -ENOMEM;
                goto free_mem;
        }
@@ -1034,7 +1065,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                                IVTV_DECODER_SIZE);
                if (!itv->dec_mem) {
                        IVTV_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n");
-                       IVTV_ERR("or disabling CONFIG_HIMEM4G into the kernel would help\n");
+                       IVTV_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n");
                        retval = -ENOMEM;
                        goto free_mem;
                }
@@ -1050,7 +1081,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
            ioremap_nocache(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
        if (!itv->reg_mem) {
                IVTV_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n");
-               IVTV_ERR("or disabling CONFIG_HIMEM4G into the kernel would help\n");
+               IVTV_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n");
                retval = -ENOMEM;
                goto free_io;
        }
@@ -1071,6 +1102,13 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                   The PCI IDs are not always reliable. */
                ivtv_process_eeprom(itv);
        }
+       if (itv->card->comment)
+               IVTV_INFO("%s", itv->card->comment);
+       if (itv->card->v4l2_capabilities == 0) {
+               /* card was detected but is not supported */
+               retval = -ENODEV;
+               goto free_i2c;
+       }
 
        if (itv->std == 0) {
                itv->std = V4L2_STD_NTSC_M;
@@ -1089,6 +1127,12 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
        /* if no tuner was found, then pick the first tuner in the card list */
        if (itv->options.tuner == -1 && itv->card->tuners[0].std) {
                itv->std = itv->card->tuners[0].std;
+               if (itv->std & V4L2_STD_PAL)
+                       itv->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
+               else if (itv->std & V4L2_STD_NTSC)
+                       itv->std = V4L2_STD_NTSC_M;
+               else if (itv->std & V4L2_STD_SECAM)
+                       itv->std = V4L2_STD_SECAM_L;
                itv->options.tuner = itv->card->tuners[0].tuner;
        }
        if (itv->options.radio == -1)
@@ -1169,13 +1213,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std);
        }
 
-       retval = ivtv_streams_setup(itv);
-       if (retval) {
-               IVTV_ERR("Error %d setting up streams\n", retval);
-               goto free_i2c;
-       }
-
-       IVTV_DEBUG_IRQ("Masking interrupts\n");
        /* clear interrupt mask, effectively disabling interrupts */
        ivtv_set_irq_mask(itv, 0xffffffff);
 
@@ -1184,32 +1221,38 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                             IRQF_SHARED | IRQF_DISABLED, itv->name, (void *)itv);
        if (retval) {
                IVTV_ERR("Failed to register irq %d\n", retval);
-               goto free_streams;
+               goto free_i2c;
+       }
+
+       retval = ivtv_streams_setup(itv);
+       if (retval) {
+               IVTV_ERR("Error %d setting up streams\n", retval);
+               goto free_irq;
        }
        retval = ivtv_streams_register(itv);
        if (retval) {
                IVTV_ERR("Error %d registering devices\n", retval);
-               goto free_irq;
+               goto free_streams;
        }
        IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name);
        return 0;
 
-      free_irq:
+free_streams:
+       ivtv_streams_cleanup(itv, 1);
+free_irq:
        free_irq(itv->dev->irq, (void *)itv);
-      free_streams:
-       ivtv_streams_cleanup(itv);
-      free_i2c:
+free_i2c:
        exit_ivtv_i2c(itv);
-      free_io:
+free_io:
        ivtv_iounmap(itv);
-      free_mem:
+free_mem:
        release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
        release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
        if (itv->has_cx23415)
                release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
-      free_workqueue:
+free_workqueue:
        destroy_workqueue(itv->irq_work_queues);
-      err:
+err:
        if (retval == 0)
                retval = -ENODEV;
        IVTV_ERR("Error %d on initialization\n", retval);
@@ -1224,9 +1267,13 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
 int ivtv_init_on_first_open(struct ivtv *itv)
 {
        struct v4l2_frequency vf;
+       /* Needed to call ioctls later */
+       struct ivtv_open_id fh;
        int fw_retry_count = 3;
        int video_input;
 
+       fh.itv = itv;
+
        if (test_bit(IVTV_F_I_FAILED, &itv->i_flags))
                return -ENXIO;
 
@@ -1274,18 +1321,18 @@ int ivtv_init_on_first_open(struct ivtv *itv)
 
        video_input = itv->active_input;
        itv->active_input++;    /* Force update of input */
-       ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_INPUT, &video_input);
+       ivtv_s_input(NULL, &fh, video_input);
 
        /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
           in one place. */
        itv->std++;             /* Force full standard initialization */
        itv->std_out = itv->std;
-       ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_FREQUENCY, &vf);
+       ivtv_s_frequency(NULL, &fh, &vf);
 
        if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) {
                ivtv_init_mpeg_decoder(itv);
        }
-       ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_STD, &itv->tuner_std);
+       ivtv_s_std(NULL, &fh, &itv->tuner_std);
 
        /* On a cx23416 this seems to be able to enable DMA to the chip? */
        if (!itv->has_cx23415)
@@ -1340,7 +1387,7 @@ static void ivtv_remove(struct pci_dev *pci_dev)
        flush_workqueue(itv->irq_work_queues);
        destroy_workqueue(itv->irq_work_queues);
 
-       ivtv_streams_cleanup(itv);
+       ivtv_streams_cleanup(itv, 1);
        ivtv_udma_free(itv);
 
        exit_ivtv_i2c(itv);