]> err.no Git - linux-2.6/blobdiff - drivers/media/video/ivtv/ivtv-driver.c
V4L/DVB (6115): ivtv/ivtv-fb: improve locking to avoid initialization problems
[linux-2.6] / drivers / media / video / ivtv / ivtv-driver.c
index 00bdcc2e8f53afd903d94a38ef4144ad3e1a4c01..2a5e0facca7df8d912b1542c597b072a05f27c50 100644 (file)
 #include "ivtv-ioctl.h"
 #include "ivtv-cards.h"
 #include "ivtv-vbi.h"
-#include "ivtv-audio.h"
+#include "ivtv-routing.h"
 #include "ivtv-gpio.h"
 #include "ivtv-yuv.h"
 
 #include <media/tveeprom.h>
+#include <media/saa7115.h>
 #include <media/v4l2-chip-ident.h>
 
 /* var to keep track of the number of array elements in use */
@@ -86,13 +87,6 @@ static struct pci_device_id ivtv_pci_tbl[] __devinitdata = {
 
 MODULE_DEVICE_TABLE(pci,ivtv_pci_tbl);
 
-const u32 yuv_offset[4] = {
-       IVTV_YUV_BUFFER_OFFSET,
-       IVTV_YUV_BUFFER_OFFSET_1,
-       IVTV_YUV_BUFFER_OFFSET_2,
-       IVTV_YUV_BUFFER_OFFSET_3
-};
-
 /* Parameter declarations */
 static int cardtype[IVTV_MAX_CARDS];
 static int tuner[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
@@ -112,6 +106,18 @@ static char secam[] = "--";
 static char ntsc[] = "-";
 
 /* Buffers */
+
+/* DMA Buffers, Default size in MB allocated */
+#define IVTV_DEFAULT_ENC_MPG_BUFFERS 4
+#define IVTV_DEFAULT_ENC_YUV_BUFFERS 2
+#define IVTV_DEFAULT_ENC_VBI_BUFFERS 1
+/* Exception: size in kB for this stream (MB is overkill) */
+#define IVTV_DEFAULT_ENC_PCM_BUFFERS 320
+#define IVTV_DEFAULT_DEC_MPG_BUFFERS 1
+#define IVTV_DEFAULT_DEC_YUV_BUFFERS 1
+/* Exception: size in kB for this stream (MB is way overkill) */
+#define IVTV_DEFAULT_DEC_VBI_BUFFERS 64
+
 static int enc_mpg_buffers = IVTV_DEFAULT_ENC_MPG_BUFFERS;
 static int enc_yuv_buffers = IVTV_DEFAULT_ENC_YUV_BUFFERS;
 static int enc_vbi_buffers = IVTV_DEFAULT_ENC_VBI_BUFFERS;
@@ -176,17 +182,27 @@ MODULE_PARM_DESC(cardtype,
                 "\t\t\t16 = GOTVIEW PCI DVD2 Deluxe\n"
                 "\t\t\t17 = Yuan MPC622\n"
                 "\t\t\t18 = Digital Cowboy DCT-MTVP1\n"
-#ifdef HAVE_XC3028
-                "\t\t\t19 = Yuan PG600V2/GotView PCI DVD Lite/Club3D ZAP-TV1x01\n"
-#endif
+                "\t\t\t19 = Yuan PG600V2/GotView PCI DVD Lite\n"
+                "\t\t\t20 = Club3D ZAP-TV1x01\n"
+                "\t\t\t21 = AverTV MCE 116 Plus\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(debug,
-                "Debug level (bitmask). Default: errors only\n"
-                "\t\t\t(debug = 1023 gives full debugging)");
+                "Debug level (bitmask). Default: 0\n"
+                "\t\t\t   1/0x0001: warning\n"
+                "\t\t\t   2/0x0002: info\n"
+                "\t\t\t   4/0x0004: mailbox\n"
+                "\t\t\t   8/0x0008: ioctl\n"
+                "\t\t\t  16/0x0010: file\n"
+                "\t\t\t  32/0x0020: dma\n"
+                "\t\t\t  64/0x0040: irq\n"
+                "\t\t\t 128/0x0080: decoder\n"
+                "\t\t\t 256/0x0100: yuv\n"
+                "\t\t\t 512/0x0200: i2c\n"
+                "\t\t\t1024/0x0400: high volume\n");
 MODULE_PARM_DESC(ivtv_pci_latency,
                 "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
                 "\t\t\tDefault: Yes");
@@ -207,7 +223,7 @@ MODULE_PARM_DESC(enc_vbi_buffers,
                 "Encoder VBI Buffers (in MB)\n"
                 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_VBI_BUFFERS));
 MODULE_PARM_DESC(enc_pcm_buffers,
-                "Encoder PCM buffers (in MB)\n"
+                "Encoder PCM buffers (in kB)\n"
                 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_PCM_BUFFERS));
 MODULE_PARM_DESC(dec_mpg_buffers,
                 "Decoder MPG buffers (in MB)\n"
@@ -216,7 +232,7 @@ MODULE_PARM_DESC(dec_yuv_buffers,
                 "Decoder YUV buffers (in MB)\n"
                 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_DEC_YUV_BUFFERS));
 MODULE_PARM_DESC(dec_vbi_buffers,
-                "Decoder VBI buffers (in MB)\n"
+                "Decoder VBI buffers (in kB)\n"
                 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_DEC_VBI_BUFFERS));
 MODULE_PARM_DESC(newi2c,
                 "Use new I2C implementation\n"
@@ -546,13 +562,13 @@ static void ivtv_process_options(struct ivtv *itv)
        const char *chipname;
        int i, j;
 
-       itv->options.megabytes[IVTV_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers;
-       itv->options.megabytes[IVTV_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers;
-       itv->options.megabytes[IVTV_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers;
-       itv->options.megabytes[IVTV_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
-       itv->options.megabytes[IVTV_DEC_STREAM_TYPE_MPG] = dec_mpg_buffers;
-       itv->options.megabytes[IVTV_DEC_STREAM_TYPE_YUV] = dec_yuv_buffers;
-       itv->options.megabytes[IVTV_DEC_STREAM_TYPE_VBI] = dec_vbi_buffers;
+       itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers * 1024;
+       itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers * 1024;
+       itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers * 1024;
+       itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
+       itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_MPG] = dec_mpg_buffers * 1024;
+       itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_YUV] = dec_yuv_buffers * 1024;
+       itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_VBI] = dec_vbi_buffers;
        itv->options.cardtype = cardtype[itv->num];
        itv->options.tuner = tuner[itv->num];
        itv->options.radio = radio[itv->num];
@@ -651,7 +667,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
        cx2341x_fill_defaults(&itv->params);
        itv->params.port = CX2341X_PORT_MEMORY;
        itv->params.capabilities = CX2341X_CAP_HAS_SLICED_VBI;
-       init_waitqueue_head(&itv->cap_w);
+       init_waitqueue_head(&itv->eos_waitq);
        init_waitqueue_head(&itv->event_waitq);
        init_waitqueue_head(&itv->vsync_waitq);
        init_waitqueue_head(&itv->dma_waitq);
@@ -697,14 +713,6 @@ static void __devinit ivtv_init_struct2(struct ivtv *itv)
                        break;
        itv->nof_audio_inputs = i;
 
-       /* 0x00EF = saa7114(239) 0x00F0 = saa7115(240) 0x0106 = micro */
-       if (itv->card->hw_all & (IVTV_HW_SAA7115 | IVTV_HW_SAA717X))
-               itv->digitizer = 0xF1;
-       else if (itv->card->hw_all & IVTV_HW_SAA7114)
-               itv->digitizer = 0xEF;
-       else /* cx25840 */
-               itv->digitizer = 0x140;
-
        if (itv->card->hw_all & IVTV_HW_CX25840) {
                itv->vbi.sliced_size = 288;  /* multiple of 16, real size = 284 */
        } else {
@@ -733,6 +741,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
                          const struct pci_device_id *pci_id)
 {
        u16 cmd;
+       u8 card_rev;
        unsigned char pci_latency;
 
        IVTV_DEBUG_INFO("Enabling pci device\n");
@@ -779,7 +788,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
        }
        IVTV_DEBUG_INFO("Bus Mastering Enabled.\n");
 
-       pci_read_config_byte(dev, PCI_CLASS_REVISION, &itv->card_rev);
+       pci_read_config_byte(dev, PCI_CLASS_REVISION, &card_rev);
        pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
 
        if (pci_latency < 64 && ivtv_pci_latency) {
@@ -796,7 +805,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
 
        IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, "
                   "irq: %d, latency: %d, memory: 0x%lx\n",
-                  itv->dev->device, itv->card_rev, dev->bus->number,
+                  itv->dev->device, card_rev, dev->bus->number,
                   PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
                   itv->dev->irq, pci_latency, (unsigned long)itv->base_addr);
 
@@ -820,11 +829,13 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
        /* load modules */
 #ifndef CONFIG_VIDEO_TUNER
        if (hw & IVTV_HW_TUNER) {
-               ivtv_request_module(itv, "tuner");
-#ifdef HAVE_XC3028
-               if (itv->options.tuner == TUNER_XCEIVE_XC3028)
-                       ivtv_request_module(itv, "xc3028-tuner");
-#endif
+               if (itv->options.tuner == TUNER_XCEIVE_XC3028) {
+                       IVTV_INFO("Xceive tuner not yet supported, only composite and S-Video inputs will be available\n");
+                       itv->tunerid = 1;
+               }
+               else {
+                       ivtv_request_module(itv, "tuner");
+               }
        }
 #endif
 #ifndef CONFIG_VIDEO_CX25840
@@ -852,6 +863,10 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
 #ifndef CONFIG_VIDEO_MSP3400
        if (hw & IVTV_HW_MSP34XX)
                ivtv_request_module(itv, "msp3400");
+#endif
+#ifndef CONFIG_VIDEO_VP27SMPX
+       if (hw & IVTV_HW_VP27SMPX)
+               ivtv_request_module(itv, "vp27smpx");
 #endif
        if (hw & IVTV_HW_TVAUDIO)
                ivtv_request_module(itv, "tvaudio");
@@ -893,6 +908,15 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
                else if ((hw & IVTV_HW_UPD64031A) == 0)
                        itv->card = ivtv_get_card(IVTV_CARD_CX23416GYC_NOGR);
        }
+       else if (itv->card->type == IVTV_CARD_GV_MVPRX ||
+                itv->card->type == IVTV_CARD_GV_MVPRX2E) {
+               struct v4l2_crystal_freq crystal_freq;
+
+               /* The crystal frequency of GVMVPRX is 24.576MHz */
+               crystal_freq.freq = SAA7115_FREQ_24_576_MHZ;
+               crystal_freq.flags = SAA7115_FREQ_FL_UCGC;
+               itv->video_dec_func(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);
+       }
 
        if (hw & IVTV_HW_CX25840) {
                itv->vbi.raw_decoder_line_size = 1444;
@@ -979,6 +1003,8 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
 
        IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr);
 
+       mutex_lock(&itv->serialize_lock);
+
        /* PCI Device Setup */
        if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) {
                if (retval == -EIO)
@@ -1116,19 +1142,12 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
        if (itv->options.radio > 0)
                itv->v4l2_cap |= V4L2_CAP_RADIO;
 
-       if (itv->options.tuner > -1) {
+       if (itv->options.tuner > -1 && itv->tunerid == 0) {
                struct tuner_setup setup;
 
                setup.addr = ADDR_UNSET;
                setup.type = itv->options.tuner;
                setup.mode_mask = T_ANALOG_TV;  /* matches TV tuners */
-#ifdef HAVE_XC3028
-               setup.initmode = V4L2_TUNER_ANALOG_TV;
-               if (itv->options.tuner == TUNER_XCEIVE_XC3028) {
-                       setup.gpio_write = ivtv_reset_tuner_gpio;
-                       setup.gpio_priv = itv;
-               }
-#endif
                ivtv_call_i2c_clients(itv, TUNER_SET_TYPE_ADDR, &setup);
        }
 
@@ -1136,6 +1155,10 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
           are not. */
        itv->tuner_std = itv->std;
 
+       if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
+               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);
@@ -1153,6 +1176,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                IVTV_ERR("Failed to register irq %d\n", retval);
                goto free_streams;
        }
+       mutex_unlock(&itv->serialize_lock);
        IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name);
        return 0;
 
@@ -1171,6 +1195,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
       free_workqueue:
        destroy_workqueue(itv->irq_work_queues);
+       mutex_unlock(&itv->serialize_lock);
       err:
        if (retval == 0)
                retval = -ENODEV;
@@ -1189,6 +1214,12 @@ int ivtv_init_on_first_open(struct ivtv *itv)
        int fw_retry_count = 3;
        int video_input;
 
+       if (test_bit(IVTV_F_I_FAILED, &itv->i_flags))
+               return -ENXIO;
+
+       if (test_and_set_bit(IVTV_F_I_INITED, &itv->i_flags))
+               return 0;
+
        while (--fw_retry_count > 0) {
                /* load firmware */
                if (ivtv_firmware_init(itv) == 0)
@@ -1196,9 +1227,10 @@ int ivtv_init_on_first_open(struct ivtv *itv)
                if (fw_retry_count > 1)
                        IVTV_WARN("Retry loading firmware\n");
        }
+
        if (fw_retry_count == 0) {
-               IVTV_ERR("Error initializing firmware\n");
-               return -1;
+               set_bit(IVTV_F_I_FAILED, &itv->i_flags);
+               return -ENXIO;
        }
 
        /* Try and get firmware versions */
@@ -1334,9 +1366,9 @@ static int module_start(void)
                return -1;
        }
 
-       if (ivtv_debug < 0 || ivtv_debug > 1023) {
+       if (ivtv_debug < 0 || ivtv_debug > 2047) {
                ivtv_debug = 0;
-               printk(KERN_INFO "ivtv:  Debug value must be >= 0 and <= 1023\n");
+               printk(KERN_INFO "ivtv:  Debug value must be >= 0 and <= 2047\n");
        }
 
        if (pci_register_driver(&ivtv_pci_driver)) {
@@ -1381,6 +1413,7 @@ EXPORT_SYMBOL(ivtv_udma_setup);
 EXPORT_SYMBOL(ivtv_udma_unmap);
 EXPORT_SYMBOL(ivtv_udma_alloc);
 EXPORT_SYMBOL(ivtv_udma_prepare);
+EXPORT_SYMBOL(ivtv_init_on_first_open);
 
 module_init(module_start);
 module_exit(module_cleanup);