Merge branch 'core/xen' into x86/xen
[safe/jmp/linux-2.6] / drivers / media / video / ivtv / ivtv-driver.c
index 8d38765..4afc7ea 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 <linux/vermagic.h>
 #include <media/tveeprom.h>
+#include <media/saa7115.h>
 #include <media/v4l2-chip-ident.h>
+#include "tuner-xc2028.h"
 
 /* var to keep track of the number of array elements in use */
 int ivtv_cards_active = 0;
@@ -74,7 +74,7 @@ int ivtv_first_minor = 0;
 struct ivtv *ivtv_cards[IVTV_MAX_CARDS];
 
 /* Protects ivtv_cards_active */
-spinlock_t ivtv_cards_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(ivtv_cards_lock);
 
 /* add your revision and whatnot here */
 static struct pci_device_id ivtv_pci_tbl[] __devinitdata = {
@@ -87,26 +87,37 @@ 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, -1, -1, -1, -1 };
-static int radio[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
-
-static int cardtype_c = 1;
-static int tuner_c = 1;
-static int radio_c = 1;
-static char pal[] = "--";
+static int tuner[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
+                                    -1, -1, -1, -1, -1, -1, -1, -1,
+                                    -1, -1, -1, -1, -1, -1, -1, -1,
+                                    -1, -1, -1, -1, -1, -1, -1, -1 };
+static int radio[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
+                                    -1, -1, -1, -1, -1, -1, -1, -1,
+                                    -1, -1, -1, -1, -1, -1, -1, -1,
+                                    -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 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;
@@ -115,13 +126,14 @@ static int dec_mpg_buffers = IVTV_DEFAULT_DEC_MPG_BUFFERS;
 static int dec_yuv_buffers = IVTV_DEFAULT_DEC_YUV_BUFFERS;
 static int dec_vbi_buffers = IVTV_DEFAULT_DEC_VBI_BUFFERS;
 
-static int ivtv_yuv_mode = 0;
-static int ivtv_yuv_threshold=480;
+static int ivtv_yuv_mode;
+static int ivtv_yuv_threshold = -1;
 static int ivtv_pci_latency = 1;
 
-int ivtv_debug = 0;
+int ivtv_debug;
 
-int newi2c = -1;
+static int tunertype = -1;
+static int newi2c = -1;
 
 module_param_array(tuner, int, &tuner_c, 0644);
 module_param_array(radio, bool, &radio_c, 0644);
@@ -143,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"
@@ -171,17 +184,37 @@ 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\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: errors only\n"
-                "\t\t\t(debug = 511 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");
@@ -202,7 +235,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"
@@ -211,7 +244,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"
@@ -276,9 +309,10 @@ int ivtv_waitq(wait_queue_head_t *waitq)
 }
 
 /* Generic utility functions */
-int ivtv_sleep_timeout(int timeout, int intr)
+int ivtv_msleep_timeout(unsigned int msecs, int intr)
 {
        int ret;
+       int timeout = msecs_to_jiffies(msecs);
 
        do {
                set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
@@ -339,6 +373,7 @@ static void ivtv_process_eeprom(struct ivtv *itv)
                /* In a few cases the PCI subsystem IDs do not correctly
                   identify the card. A better method is to check the
                   model number from the eeprom instead. */
+               case 30012 ... 30039:  /* Low profile PVR250 */
                case 32000 ... 32999:
                case 48000 ... 48099:  /* 48??? range are PVR250s with a cx23415 */
                case 48400 ... 48599:
@@ -374,6 +409,7 @@ static void ivtv_process_eeprom(struct ivtv *itv)
 
        itv->v4l2_cap = itv->card->v4l2_capabilities;
        itv->card_name = itv->card->name;
+       itv->card_i2c = itv->card->i2c;
 
        /* If this is a PVR500 then it should be possible to detect whether it is the
           first or second unit by looking at the subsystem device ID: is bit 4 is
@@ -391,7 +427,14 @@ static void ivtv_process_eeprom(struct ivtv *itv)
           This detection is needed since the eeprom reports incorrectly that a radio is
           present on the second unit. */
        if (tv.model / 1000 == 23) {
+               static const struct ivtv_card_tuner_i2c ivtv_i2c_radio = {
+                       .radio = { 0x60, I2C_CLIENT_END },
+                       .demod = { 0x43, I2C_CLIENT_END },
+                       .tv = { 0x61, I2C_CLIENT_END },
+               };
+
                itv->card_name = "WinTV PVR 500";
+               itv->card_i2c = &ivtv_i2c_radio;
                if (pci_slot == 8 || pci_slot == 9) {
                        int is_first = (pci_slot & 1) == 0;
 
@@ -422,11 +465,10 @@ 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");
+                   IVTV_INFO("Reopen i2c bus for IR-blaster support\n");
                    exit_ivtv_i2c(itv);
                    init_ivtv_i2c(itv);
                }
@@ -456,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;
@@ -495,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;
@@ -516,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;
@@ -539,19 +592,24 @@ 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];
        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) {
@@ -605,10 +663,11 @@ done:
                IVTV_ERR("Defaulting to %s card\n", itv->card->name);
                IVTV_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
                IVTV_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
-               IVTV_ERR("Prefix your subject line with [UNKNOWN CARD].\n");
+               IVTV_ERR("Prefix your subject line with [UNKNOWN IVTV CARD].\n");
        }
        itv->v4l2_cap = itv->card->v4l2_capabilities;
        itv->card_name = itv->card->name;
+       itv->card_i2c = itv->card->i2c;
 }
 
 /* Precondition: the ivtv structure has been memset to 0. Only
@@ -622,27 +681,20 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
        itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */
        itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */
 
+       mutex_init(&itv->serialize_lock);
        mutex_init(&itv->i2c_bus_lock);
        mutex_init(&itv->udma.lock);
 
-       itv->lock = SPIN_LOCK_UNLOCKED;
-       itv->dma_reg_lock = SPIN_LOCK_UNLOCKED;
-
-       itv->vbi.work_queues = create_workqueue("ivtv_vbi");
-       if (itv->vbi.work_queues == NULL) {
-               IVTV_ERR("Could not create VBI workqueue\n");
-               return -1;
-       }
+       spin_lock_init(&itv->lock);
+       spin_lock_init(&itv->dma_reg_lock);
 
-       itv->yuv_info.work_queues = create_workqueue("ivtv_yuv");
-       if (itv->yuv_info.work_queues == NULL) {
-               IVTV_ERR("Could not create YUV workqueue\n");
-               destroy_workqueue(itv->vbi.work_queues);
+       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;
        }
 
-       INIT_WORK(&itv->vbi.work_queue, vbi_work_handler);
-       INIT_WORK(&itv->yuv_info.work_queue, ivtv_yuv_work_handler);
+       INIT_WORK(&itv->irq_work_queue, ivtv_irq_work_handler);
 
        /* start counting open_id at 1 */
        itv->open_id = 1;
@@ -651,7 +703,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);
@@ -660,6 +712,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
        itv->dma_timer.data = (unsigned long)itv;
 
        itv->cur_dma_stream = -1;
+       itv->cur_pio_stream = -1;
        itv->audio_stereo_mode = AUDIO_STEREO;
        itv->audio_bilingual_mode = AUDIO_MONO_LEFT;
 
@@ -670,6 +723,9 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
        itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
        itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced;
 
+       /* Init the sg table for osd/yuv output */
+       sg_init_table(itv->udma.SGlist, IVTV_DMA_SG_OSD_ENT);
+
        /* OSD */
        itv->osd_global_alpha_state = 1;
        itv->osd_global_alpha = 255;
@@ -678,6 +734,8 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
        atomic_set(&itv->yuv_info.next_dma_frame, -1);
        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;
 }
 
@@ -696,14 +754,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 {
@@ -732,6 +782,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");
@@ -778,7 +829,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) {
@@ -795,77 +846,74 @@ 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);
 
        return 0;
 }
 
-static void ivtv_request_module(struct ivtv *itv, const char *name)
+#ifdef MODULE
+static u32 ivtv_request_module(struct ivtv *itv, u32 hw,
+               const char *name, u32 id)
 {
+       if ((hw & id) == 0)
+               return hw;
        if (request_module(name) != 0) {
                IVTV_ERR("Failed to load module %s\n", name);
-       } else {
-               IVTV_DEBUG_INFO("Loaded module %s\n", name);
+               return hw & ~id;
        }
+       IVTV_DEBUG_INFO("Loaded module %s\n", name);
+       return hw;
 }
+#endif
 
 static void ivtv_load_and_init_modules(struct ivtv *itv)
 {
-       struct v4l2_control ctrl;
        u32 hw = itv->card->hw_all;
-       int i;
+       unsigned i;
 
+#ifdef MODULE
        /* 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
-       }
+#ifndef CONFIG_MEDIA_TUNER
+       hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER);
 #endif
 #ifndef CONFIG_VIDEO_CX25840
-       if (hw & IVTV_HW_CX25840)
-               ivtv_request_module(itv, "cx25840");
+       hw = ivtv_request_module(itv, hw, "cx25840", IVTV_HW_CX25840);
 #endif
 #ifndef CONFIG_VIDEO_SAA711X
-       if (hw & IVTV_HW_SAA711X)
-               ivtv_request_module(itv, "saa7115");
+       hw = ivtv_request_module(itv, hw, "saa7115", IVTV_HW_SAA711X);
 #endif
 #ifndef CONFIG_VIDEO_SAA7127
-       if (hw & IVTV_HW_SAA7127)
-               ivtv_request_module(itv, "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
-       if (hw & IVTV_HW_SAA717X)
-               ivtv_request_module(itv, "saa717x");
 #ifndef CONFIG_VIDEO_UPD64031A
-       if (hw & IVTV_HW_UPD64031A)
-               ivtv_request_module(itv, "upd64031a");
+       hw = ivtv_request_module(itv, hw, "upd64031a", IVTV_HW_UPD64031A);
 #endif
 #ifndef CONFIG_VIDEO_UPD64083
-       if (hw & IVTV_HW_UPD6408X)
-               ivtv_request_module(itv, "upd64083");
+       hw = ivtv_request_module(itv, hw, "upd64083", IVTV_HW_UPD6408X);
 #endif
 #ifndef CONFIG_VIDEO_MSP3400
-       if (hw & IVTV_HW_MSP34XX)
-               ivtv_request_module(itv, "msp3400");
+       hw = ivtv_request_module(itv, hw, "msp3400", IVTV_HW_MSP34XX);
+#endif
+#ifndef CONFIG_VIDEO_VP27SMPX
+       hw = ivtv_request_module(itv, hw, "vp27smpx", IVTV_HW_VP27SMPX);
 #endif
-       if (hw & IVTV_HW_TVAUDIO)
-               ivtv_request_module(itv, "tvaudio");
 #ifndef CONFIG_VIDEO_WM8775
-       if (hw & IVTV_HW_WM8775)
-               ivtv_request_module(itv, "wm8775");
+       hw = ivtv_request_module(itv, hw, "wm8775", IVTV_HW_WM8775);
 #endif
 #ifndef CONFIG_VIDEO_WM8739
-       if (hw & IVTV_HW_WM8739)
-               ivtv_request_module(itv, "wm8739");
+       hw = ivtv_request_module(itv, hw, "wm8739", IVTV_HW_WM8739);
 #endif
 #ifndef CONFIG_VIDEO_CS53L32A
-       if (hw & IVTV_HW_CS53L32A)
-               ivtv_request_module(itv, "cs53l32a");
+       hw = ivtv_request_module(itv, hw, "cs53l32a", IVTV_HW_CS53L32A);
+#endif
+#ifndef CONFIG_VIDEO_M52790
+       hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790);
+#endif
 #endif
 
        /* check which i2c devices are actually found */
@@ -874,11 +922,12 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
 
                if (!(device & hw))
                        continue;
-               if (device == IVTV_HW_GPIO) {
-                       /* GPIO is always available */
-                       itv->hw_flags |= IVTV_HW_GPIO;
+               if (device == IVTV_HW_GPIO || device == IVTV_HW_TVEEPROM) {
+                       /* GPIO and TVEEPROM do not use i2c probing */
+                       itv->hw_flags |= device;
                        continue;
                }
+               ivtv_i2c_register(itv, i);
                if (ivtv_i2c_hw_addr(itv, device) > 0)
                        itv->hw_flags |= device;
        }
@@ -893,13 +942,17 @@ 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;
 
-       if (hw & IVTV_HW_CX25840) {
-               /* CX25840_CID_ENABLE_PVR150_WORKAROUND */
-               ctrl.id = V4L2_CID_PRIVATE_BASE;
-               ctrl.value = itv->pvr150_workaround;
-               itv->video_dec_func(itv, VIDIOC_S_CTRL, &ctrl);
+               /* 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;
                itv->vbi.raw_decoder_sav_odd_field = 0x20;
                itv->vbi.raw_decoder_sav_even_field = 0x60;
@@ -945,35 +998,29 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                                const struct pci_device_id *pci_id)
 {
        int retval = 0;
-       int video_input;
-       int yuv_buf_size;
        int vbi_buf_size;
-       int fw_retry_count = 3;
        struct ivtv *itv;
-       struct v4l2_frequency vf;
 
        spin_lock(&ivtv_cards_lock);
 
        /* Make sure we've got a place for this card */
        if (ivtv_cards_active == IVTV_MAX_CARDS) {
-               printk(KERN_ERR "ivtv:  Maximum number of cards detected (%d).\n",
+               printk(KERN_ERR "ivtv:  Maximum number of cards detected (%d)\n",
                              ivtv_cards_active);
                spin_unlock(&ivtv_cards_lock);
                return -ENOMEM;
        }
 
        itv = kzalloc(sizeof(struct ivtv), GFP_ATOMIC);
-       if (itv == 0) {
+       if (itv == NULL) {
                spin_unlock(&ivtv_cards_lock);
                return -ENOMEM;
        }
        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);
-       if (itv->num) {
-               printk(KERN_INFO "ivtv:  ======================  NEXT CARD  ======================\n");
-       }
+       snprintf(itv->name, sizeof(itv->name), "ivtv%d", itv->num);
+       IVTV_INFO("Initializing card #%d\n", itv->num);
 
        spin_unlock(&ivtv_cards_lock);
 
@@ -1006,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;
        }
@@ -1018,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;
                }
@@ -1034,49 +1081,34 @@ 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;
        }
 
-       while (--fw_retry_count > 0) {
-               /* load firmware */
-               if (ivtv_firmware_init(itv) == 0)
-                       break;
-               if (fw_retry_count > 1)
-                       IVTV_WARN("Retry loading firmware\n");
-       }
-       if (fw_retry_count == 0) {
-               IVTV_ERR("Error initializing firmware\n");
-               goto free_i2c;
-       }
-
-       /* Try and get firmware versions */
-       IVTV_DEBUG_INFO("Getting firmware version..\n");
-       ivtv_firmware_versions(itv);
-
-       /* Check yuv output filter table */
-       if (itv->has_cx23415) ivtv_yuv_filter_check(itv);
-
        ivtv_gpio_init(itv);
 
        /* active i2c  */
        IVTV_DEBUG_INFO("activating i2c...\n");
        if (init_ivtv_i2c(itv)) {
                IVTV_ERR("Could not initialize i2c\n");
-               goto free_irq;
+               goto free_io;
        }
 
        IVTV_DEBUG_INFO("Active card count: %d.\n", ivtv_cards_active);
 
        if (itv->card->hw_all & IVTV_HW_TVEEPROM) {
-#ifdef CONFIG_VIDEO_TVEEPROM_MODULE
-               ivtv_request_module(itv, "tveeprom");
-#endif
                /* Based on the model number the cardtype may be changed.
                   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;
@@ -1095,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)
@@ -1113,16 +1151,19 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                itv->is_50hz = 1;
                itv->is_out_50hz = 1;
        }
+
+       itv->yuv_info.osd_full_w = 720;
+       itv->yuv_info.osd_full_h = itv->is_out_50hz ? 576 : 480;
+       itv->yuv_info.v4l2_src_w = itv->yuv_info.osd_full_w;
+       itv->yuv_info.v4l2_src_h = itv->yuv_info.osd_full_h;
+
        itv->params.video_gop_size = itv->is_60hz ? 15 : 12;
 
        itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_MPG] = 0x08000;
        itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_PCM] = 0x01200;
        itv->stream_buf_size[IVTV_DEC_STREAM_TYPE_MPG] = 0x10000;
-
-       /* 0x15180 == 720 * 480 / 4, 0x19500 == 720 * 576 / 4 */
-       yuv_buf_size = itv->is_60hz ? 0x15180 : 0x19500;
-       itv->stream_buf_size[IVTV_DEC_STREAM_TYPE_YUV] = yuv_buf_size / 2;
-       itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_YUV] = yuv_buf_size / 8;
+       itv->stream_buf_size[IVTV_DEC_STREAM_TYPE_YUV] = 0x10000;
+       itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_YUV] = 0x08000;
 
        /* Setup VBI Raw Size. Should be big enough to hold PAL.
           It is possible to switch between PAL and NTSC, so we need to
@@ -1142,171 +1183,218 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
        if (itv->options.radio > 0)
                itv->v4l2_cap |= V4L2_CAP_RADIO;
 
-       retval = ivtv_streams_setup(itv);
-       if (retval) {
-               IVTV_ERR("Error %d setting up streams\n", retval);
-               goto free_i2c;
+       if (itv->options.tuner > -1) {
+               struct tuner_setup setup;
+
+               setup.addr = ADDR_UNSET;
+               setup.type = itv->options.tuner;
+               setup.mode_mask = T_ANALOG_TV;  /* matches TV tuners */
+               setup.tuner_callback = (setup.type == TUNER_XC2028) ?
+                       ivtv_reset_tuner_gpio : NULL;
+               ivtv_call_i2c_clients(itv, TUNER_SET_TYPE_ADDR, &setup);
+               if (setup.type == TUNER_XC2028) {
+                       static struct xc2028_ctrl ctrl = {
+                               .fname = XC2028_DEFAULT_FIRMWARE,
+                               .max_len = 64,
+                       };
+                       struct v4l2_priv_tun_config cfg = {
+                               .tuner = itv->options.tuner,
+                               .priv = &ctrl,
+                       };
+                       ivtv_call_i2c_clients(itv, TUNER_SET_CONFIG, &cfg);
+               }
        }
 
-       /* Start Threads */
-       IVTV_DEBUG_INFO("Starting Threads\n");
+       /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
+          are not. */
+       itv->tuner_std = itv->std;
 
-       /* Decoder Thread */
-       if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) {
-               ivtv_init_mpeg_decoder(itv);
+       if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
+               ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std);
        }
 
-       IVTV_DEBUG_IRQ("Masking interrupts\n");
        /* clear interrupt mask, effectively disabling interrupts */
        ivtv_set_irq_mask(itv, 0xffffffff);
 
        /* Register IRQ */
        retval = request_irq(itv->dev->irq, ivtv_irq_handler,
-                            SA_SHIRQ | SA_INTERRUPT, itv->name, (void *)itv);
+                            IRQF_SHARED | IRQF_DISABLED, itv->name, (void *)itv);
        if (retval) {
                IVTV_ERR("Failed to register irq %d\n", retval);
+               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_streams;
        }
+       IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name);
+       return 0;
 
-       /* On a cx23416 this seems to be able to enable DMA to the chip? */
-       if (!itv->has_cx23415)
-               write_reg_sync(0x03, IVTV_REG_DMACONTROL);
+free_streams:
+       ivtv_streams_cleanup(itv, 1);
+free_irq:
+       free_irq(itv->dev->irq, (void *)itv);
+free_i2c:
+       exit_ivtv_i2c(itv);
+free_io:
+       ivtv_iounmap(itv);
+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:
+       destroy_workqueue(itv->irq_work_queues);
+err:
+       if (retval == 0)
+               retval = -ENODEV;
+       IVTV_ERR("Error %d on initialization\n", retval);
 
-       /* Default interrupts enabled. For the PVR350 this includes the
-          decoder VSYNC interrupt, which is always on. It is not only used
-          during decoding but also by the OSD.
-          Some old PVR250 cards had a cx23415, so testing for that is too
-          general. Instead test if the card has video output capability. */
-       if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
-               ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC);
-       else
-               ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT);
+       spin_lock(&ivtv_cards_lock);
+       kfree(ivtv_cards[ivtv_cards_active]);
+       ivtv_cards[ivtv_cards_active] = NULL;
+       spin_unlock(&ivtv_cards_lock);
+       return retval;
+}
 
-       if (itv->options.tuner > -1) {
-               struct tuner_setup setup;
+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;
 
-               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);
+       fh.itv = itv;
+
+       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)
+                       break;
+               if (fw_retry_count > 1)
+                       IVTV_WARN("Retry loading firmware\n");
+       }
+
+       if (fw_retry_count == 0) {
+               set_bit(IVTV_F_I_FAILED, &itv->i_flags);
+               return -ENXIO;
+       }
+
+       /* Try and get firmware versions */
+       IVTV_DEBUG_INFO("Getting firmware version..\n");
+       ivtv_firmware_versions(itv);
+
+       if (itv->card->hw_all & IVTV_HW_CX25840) {
+               struct v4l2_control ctrl;
+
+               /* CX25840_CID_ENABLE_PVR150_WORKAROUND */
+               ctrl.id = V4L2_CID_PRIVATE_BASE;
+               ctrl.value = itv->pvr150_workaround;
+               itv->video_dec_func(itv, VIDIOC_S_CTRL, &ctrl);
        }
 
        vf.tuner = 0;
        vf.type = V4L2_TUNER_ANALOG_TV;
        vf.frequency = 6400; /* the tuner 'baseline' frequency */
-       if (itv->std & V4L2_STD_NTSC_M) {
-               /* Why on earth? */
+
+       /* Set initial frequency. For PAL/SECAM broadcasts no
+          'default' channel exists AFAIK. */
+       if (itv->std == V4L2_STD_NTSC_M_JP) {
+               vf.frequency = 1460;    /* ch. 1 91250*16/1000 */
+       }
+       else if (itv->std & V4L2_STD_NTSC_M) {
                vf.frequency = 1076;    /* ch. 4 67250*16/1000 */
        }
 
-       /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
-          are not. */
-       itv->tuner_std = itv->std;
-
        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_STD, &itv->tuner_std);
-       ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_FREQUENCY, &vf);
-       if (itv->has_cx23415)
-               ivtv_set_osd_alpha(itv);
-
-       IVTV_INFO("Initialized %s, card #%d\n", itv->card_name, itv->num);
+       ivtv_s_frequency(NULL, &fh, &vf);
 
-       return 0;
+       if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) {
+               ivtv_init_mpeg_decoder(itv);
+       }
+       ivtv_s_std(NULL, &fh, &itv->tuner_std);
 
-      free_irq:
-       free_irq(itv->dev->irq, (void *)itv);
-      free_streams:
-       ivtv_streams_cleanup(itv);
-      free_i2c:
-       exit_ivtv_i2c(itv);
-      free_io:
-       ivtv_iounmap(itv);
-      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:
-       destroy_workqueue(itv->vbi.work_queues);
-       destroy_workqueue(itv->yuv_info.work_queues);
-      err:
-       if (retval == 0)
-               retval = -ENODEV;
-       IVTV_ERR("Error %d on initialization\n", retval);
+       /* On a cx23416 this seems to be able to enable DMA to the chip? */
+       if (!itv->has_cx23415)
+               write_reg_sync(0x03, IVTV_REG_DMACONTROL);
 
-       kfree(ivtv_cards[ivtv_cards_active]);
-       ivtv_cards[ivtv_cards_active] = NULL;
-       return retval;
+       /* Default interrupts enabled. For the PVR350 this includes the
+          decoder VSYNC interrupt, which is always on. It is not only used
+          during decoding but also by the OSD.
+          Some old PVR250 cards had a cx23415, so testing for that is too
+          general. Instead test if the card has video output capability. */
+       if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
+               ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC);
+               ivtv_set_osd_alpha(itv);
+       }
+       else
+               ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT);
+       return 0;
 }
 
 static void ivtv_remove(struct pci_dev *pci_dev)
 {
        struct ivtv *itv = pci_get_drvdata(pci_dev);
 
-       IVTV_DEBUG_INFO("Removing Card #%d.\n", itv->num);
-
-       /* Stop all captures */
-       IVTV_DEBUG_INFO(" Stopping all streams.\n");
-       if (atomic_read(&itv->capturing) > 0)
-               ivtv_stop_all_captures(itv);
-
-       /* Stop all decoding */
-       IVTV_DEBUG_INFO(" Stopping decoding.\n");
-       if (atomic_read(&itv->decoding) > 0) {
-               int type;
-
-               if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
-                       type = IVTV_DEC_STREAM_TYPE_YUV;
-               else
-                       type = IVTV_DEC_STREAM_TYPE_MPG;
-               ivtv_stop_v4l2_decode_stream(&itv->streams[type],
-                       VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0);
+       IVTV_DEBUG_INFO("Removing Card #%d\n", itv->num);
+
+       if (test_bit(IVTV_F_I_INITED, &itv->i_flags)) {
+               /* Stop all captures */
+               IVTV_DEBUG_INFO("Stopping all streams\n");
+               if (atomic_read(&itv->capturing) > 0)
+                       ivtv_stop_all_captures(itv);
+
+               /* Stop all decoding */
+               IVTV_DEBUG_INFO("Stopping decoding\n");
+               if (atomic_read(&itv->decoding) > 0) {
+                       int type;
+
+                       if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
+                               type = IVTV_DEC_STREAM_TYPE_YUV;
+                       else
+                               type = IVTV_DEC_STREAM_TYPE_MPG;
+                       ivtv_stop_v4l2_decode_stream(&itv->streams[type],
+                               VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0);
+               }
+               ivtv_halt_firmware(itv);
        }
 
        /* Interrupts */
-       IVTV_DEBUG_INFO(" Disabling interrupts.\n");
        ivtv_set_irq_mask(itv, 0xffffffff);
        del_timer_sync(&itv->dma_timer);
 
        /* Stop all Work Queues */
-       IVTV_DEBUG_INFO(" Stop Work Queues.\n");
-       flush_workqueue(itv->vbi.work_queues);
-       flush_workqueue(itv->yuv_info.work_queues);
-       destroy_workqueue(itv->vbi.work_queues);
-       destroy_workqueue(itv->yuv_info.work_queues);
-
-       IVTV_DEBUG_INFO(" Stopping Firmware.\n");
-       ivtv_halt_firmware(itv);
-
-       IVTV_DEBUG_INFO(" Unregistering v4l devices.\n");
-       ivtv_streams_cleanup(itv);
-       IVTV_DEBUG_INFO(" Freeing dma resources.\n");
+       flush_workqueue(itv->irq_work_queues);
+       destroy_workqueue(itv->irq_work_queues);
+
+       ivtv_streams_cleanup(itv, 1);
        ivtv_udma_free(itv);
 
        exit_ivtv_i2c(itv);
 
-       IVTV_DEBUG_INFO(" Releasing irq.\n");
        free_irq(itv->dev->irq, (void *)itv);
+       ivtv_iounmap(itv);
 
-       if (itv->dev) {
-               ivtv_iounmap(itv);
-       }
-
-       IVTV_DEBUG_INFO(" Releasing mem.\n");
        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)
@@ -1327,28 +1415,27 @@ static struct pci_driver ivtv_pci_driver = {
 
 static int module_start(void)
 {
-       printk(KERN_INFO "ivtv:  ==================== START INIT IVTV ====================\n");
-       printk(KERN_INFO "ivtv:  version %s (" VERMAGIC_STRING ") loading\n", IVTV_VERSION);
+       printk(KERN_INFO "ivtv:  Start initialization, version %s\n", IVTV_VERSION);
 
        memset(ivtv_cards, 0, sizeof(ivtv_cards));
 
        /* Validate parameters */
        if (ivtv_first_minor < 0 || ivtv_first_minor >= IVTV_MAX_CARDS) {
-               printk(KERN_ERR "ivtv:  ivtv_first_minor must be between 0 and %d. Exiting...\n",
+               printk(KERN_ERR "ivtv:  Exiting, ivtv_first_minor must be between 0 and %d\n",
                     IVTV_MAX_CARDS - 1);
                return -1;
        }
 
-       if (ivtv_debug < 0 || ivtv_debug > 511) {
+       if (ivtv_debug < 0 || ivtv_debug > 2047) {
                ivtv_debug = 0;
-               printk(KERN_INFO "ivtv:  debug value must be >= 0 and <= 511!\n");
+               printk(KERN_INFO "ivtv:  Debug value must be >= 0 and <= 2047\n");
        }
 
-       if (pci_module_init(&ivtv_pci_driver)) {
+       if (pci_register_driver(&ivtv_pci_driver)) {
                printk(KERN_ERR "ivtv:  Error detecting PCI card\n");
                return -ENODEV;
        }
-       printk(KERN_INFO "ivtv:  ====================  END INIT IVTV  ====================\n");
+       printk(KERN_INFO "ivtv:  End initialization\n");
        return 0;
 }
 
@@ -1356,6 +1443,9 @@ static void module_cleanup(void)
 {
        int i, j;
 
+       pci_unregister_driver(&ivtv_pci_driver);
+
+       spin_lock(&ivtv_cards_lock);
        for (i = 0; i < ivtv_cards_active; i++) {
                if (ivtv_cards[i] == NULL)
                        continue;
@@ -1364,12 +1454,15 @@ static void module_cleanup(void)
                }
                kfree(ivtv_cards[i]);
        }
-       pci_unregister_driver(&ivtv_pci_driver);
+       spin_unlock(&ivtv_cards_lock);
 }
 
+/* Note: These symbols are exported because they are used by the ivtvfb
+   framebuffer module and an infrared module for the IR-blaster. */
 EXPORT_SYMBOL(ivtv_set_irq_mask);
 EXPORT_SYMBOL(ivtv_cards_active);
 EXPORT_SYMBOL(ivtv_cards);
+EXPORT_SYMBOL(ivtv_cards_lock);
 EXPORT_SYMBOL(ivtv_api);
 EXPORT_SYMBOL(ivtv_vapi);
 EXPORT_SYMBOL(ivtv_vapi_result);
@@ -1380,6 +1473,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);