]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/video/cx18/cx18-driver.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[linux-2.6-omap-h63xx.git] / drivers / media / video / cx18 / cx18-driver.c
index d31e1ec8d14c0a98ad9694a97801d0e761abee84..7a1a7830a6b3fcc49ec0b1ff86c049c816c13b38 100644 (file)
@@ -4,6 +4,7 @@
  *  Derived from ivtv-driver.c
  *
  *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
+ *  Copyright (C) 2008  Andy Walls <awalls@radix.net>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -74,10 +75,14 @@ static int radio[CX18_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 mmio_ndelay[CX18_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 cardtype_c = 1;
 static unsigned tuner_c = 1;
 static unsigned radio_c = 1;
+static unsigned mmio_ndelay_c = 1;
 static char pal[] = "--";
 static char secam[] = "--";
 static char ntsc[] = "-";
@@ -91,15 +96,18 @@ static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS;
 
 static int cx18_pci_latency = 1;
 
+int cx18_retry_mmio = 1;
 int cx18_debug;
 
 module_param_array(tuner, int, &tuner_c, 0644);
 module_param_array(radio, bool, &radio_c, 0644);
 module_param_array(cardtype, int, &cardtype_c, 0644);
+module_param_array(mmio_ndelay, int, &mmio_ndelay_c, 0644);
 module_param_string(pal, pal, sizeof(pal), 0644);
 module_param_string(secam, secam, sizeof(secam), 0644);
 module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
 module_param_named(debug, cx18_debug, int, 0644);
+module_param_named(retry_mmio, cx18_retry_mmio, int, 0644);
 module_param(cx18_pci_latency, int, 0644);
 module_param(cx18_first_minor, int, 0644);
 
@@ -122,6 +130,8 @@ MODULE_PARM_DESC(cardtype,
                 "\t\t\t 3 = Compro VideoMate H900\n"
                 "\t\t\t 4 = Yuan MPC718\n"
                 "\t\t\t 5 = Conexant Raptor PAL/SECAM\n"
+                "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n"
+                "\t\t\t 7 = Leadtek WinFast PVR2100\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");
@@ -141,6 +151,14 @@ MODULE_PARM_DESC(debug,
 MODULE_PARM_DESC(cx18_pci_latency,
                 "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
                 "\t\t\tDefault: Yes");
+MODULE_PARM_DESC(retry_mmio,
+                "Check and retry memory mapped IO accesses\n"
+                "\t\t\tDefault: 1 [Yes]");
+MODULE_PARM_DESC(mmio_ndelay,
+                "Delay (ns) for each CX23418 memory mapped IO access.\n"
+                "\t\t\tTry larger values that are close to a multiple of the\n"
+                "\t\t\tPCI clock period, 30.3 ns, if your card doesn't work.\n"
+                "\t\t\tDefault: " __stringify(CX18_DEFAULT_MMIO_NDELAY));
 MODULE_PARM_DESC(enc_mpg_buffers,
                 "Encoder MPG Buffers (in MB)\n"
                 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
@@ -157,7 +175,7 @@ MODULE_PARM_DESC(enc_pcm_buffers,
                 "Encoder PCM buffers (in MB)\n"
                 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS));
 
-MODULE_PARM_DESC(cx18_first_minor, "Set minor assigned to first card");
+MODULE_PARM_DESC(cx18_first_minor, "Set kernel number assigned to first card");
 
 MODULE_AUTHOR("Hans Verkuil");
 MODULE_DESCRIPTION("CX23418 driver");
@@ -357,6 +375,11 @@ static void cx18_process_options(struct cx18 *cx)
        cx->options.tuner = tuner[cx->num];
        cx->options.radio = radio[cx->num];
 
+       if (mmio_ndelay[cx->num] < 0)
+               cx->options.mmio_ndelay = CX18_DEFAULT_MMIO_NDELAY;
+       else
+               cx->options.mmio_ndelay = mmio_ndelay[cx->num];
+
        cx->std = cx18_parse_std(cx);
        if (cx->options.cardtype == -1) {
                CX18_INFO("Ignore card\n");
@@ -590,6 +613,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
                                const struct pci_device_id *pci_id)
 {
        int retval = 0;
+       int i;
        int vbi_buf_size;
        u32 devtype;
        struct cx18 *cx;
@@ -675,7 +699,8 @@ static int __devinit cx18_probe(struct pci_dev *dev,
 
        /* active i2c  */
        CX18_DEBUG_INFO("activating i2c...\n");
-       if (init_cx18_i2c(cx)) {
+       retval = init_cx18_i2c(cx);
+       if (retval) {
                CX18_ERR("Could not initialize i2c\n");
                goto free_map;
        }
@@ -811,9 +836,13 @@ err:
        if (retval == 0)
                retval = -ENODEV;
        CX18_ERR("Error %d on initialization\n", retval);
+       cx18_log_statistics(cx);
 
-       kfree(cx18_cards[cx18_cards_active]);
-       cx18_cards[cx18_cards_active] = NULL;
+       i = cx->num;
+       spin_lock(&cx18_cards_lock);
+       kfree(cx18_cards[i]);
+       cx18_cards[i] = NULL;
+       spin_unlock(&cx18_cards_lock);
        return retval;
 }
 
@@ -915,6 +944,7 @@ static void cx18_remove(struct pci_dev *pci_dev)
 
        pci_disable_device(cx->dev);
 
+       cx18_log_statistics(cx);
        CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num);
 }
 
@@ -934,7 +964,7 @@ static int module_start(void)
 
        /* Validate parameters */
        if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
-               printk(KERN_ERR "cx18:  Exiting, ivtv_first_minor must be between 0 and %d\n",
+               printk(KERN_ERR "cx18:  Exiting, cx18_first_minor must be between 0 and %d\n",
                     CX18_MAX_CARDS - 1);
                return -1;
        }