aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18/cx18-driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx18/cx18-driver.c')
-rw-r--r--drivers/media/video/cx18/cx18-driver.c51
1 files changed, 36 insertions, 15 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index bd18afebbf86..085121c2b47f 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -4,6 +4,7 @@
4 * Derived from ivtv-driver.c 4 * Derived from ivtv-driver.c
5 * 5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -22,6 +23,7 @@
22 */ 23 */
23 24
24#include "cx18-driver.h" 25#include "cx18-driver.h"
26#include "cx18-io.h"
25#include "cx18-version.h" 27#include "cx18-version.h"
26#include "cx18-cards.h" 28#include "cx18-cards.h"
27#include "cx18-i2c.h" 29#include "cx18-i2c.h"
@@ -73,10 +75,14 @@ static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
73 -1, -1, -1, -1, -1, -1, -1, -1, 75 -1, -1, -1, -1, -1, -1, -1, -1,
74 -1, -1, -1, -1, -1, -1, -1, -1, 76 -1, -1, -1, -1, -1, -1, -1, -1,
75 -1, -1, -1, -1, -1, -1, -1, -1 }; 77 -1, -1, -1, -1, -1, -1, -1, -1 };
76 78static int mmio_ndelay[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
79 -1, -1, -1, -1, -1, -1, -1, -1,
80 -1, -1, -1, -1, -1, -1, -1, -1,
81 -1, -1, -1, -1, -1, -1, -1, -1 };
77static unsigned cardtype_c = 1; 82static unsigned cardtype_c = 1;
78static unsigned tuner_c = 1; 83static unsigned tuner_c = 1;
79static unsigned radio_c = 1; 84static unsigned radio_c = 1;
85static unsigned mmio_ndelay_c = 1;
80static char pal[] = "--"; 86static char pal[] = "--";
81static char secam[] = "--"; 87static char secam[] = "--";
82static char ntsc[] = "-"; 88static char ntsc[] = "-";
@@ -90,15 +96,18 @@ static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS;
90 96
91static int cx18_pci_latency = 1; 97static int cx18_pci_latency = 1;
92 98
99int cx18_retry_mmio = 1;
93int cx18_debug; 100int cx18_debug;
94 101
95module_param_array(tuner, int, &tuner_c, 0644); 102module_param_array(tuner, int, &tuner_c, 0644);
96module_param_array(radio, bool, &radio_c, 0644); 103module_param_array(radio, bool, &radio_c, 0644);
97module_param_array(cardtype, int, &cardtype_c, 0644); 104module_param_array(cardtype, int, &cardtype_c, 0644);
105module_param_array(mmio_ndelay, int, &mmio_ndelay_c, 0644);
98module_param_string(pal, pal, sizeof(pal), 0644); 106module_param_string(pal, pal, sizeof(pal), 0644);
99module_param_string(secam, secam, sizeof(secam), 0644); 107module_param_string(secam, secam, sizeof(secam), 0644);
100module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); 108module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
101module_param_named(debug, cx18_debug, int, 0644); 109module_param_named(debug, cx18_debug, int, 0644);
110module_param_named(retry_mmio, cx18_retry_mmio, int, 0644);
102module_param(cx18_pci_latency, int, 0644); 111module_param(cx18_pci_latency, int, 0644);
103module_param(cx18_first_minor, int, 0644); 112module_param(cx18_first_minor, int, 0644);
104 113
@@ -121,6 +130,8 @@ MODULE_PARM_DESC(cardtype,
121 "\t\t\t 3 = Compro VideoMate H900\n" 130 "\t\t\t 3 = Compro VideoMate H900\n"
122 "\t\t\t 4 = Yuan MPC718\n" 131 "\t\t\t 4 = Yuan MPC718\n"
123 "\t\t\t 5 = Conexant Raptor PAL/SECAM\n" 132 "\t\t\t 5 = Conexant Raptor PAL/SECAM\n"
133 "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n"
134 "\t\t\t 7 = Leadtek WinFast PVR2100\n"
124 "\t\t\t 0 = Autodetect (default)\n" 135 "\t\t\t 0 = Autodetect (default)\n"
125 "\t\t\t-1 = Ignore this card\n\t\t"); 136 "\t\t\t-1 = Ignore this card\n\t\t");
126MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); 137MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
@@ -140,6 +151,14 @@ MODULE_PARM_DESC(debug,
140MODULE_PARM_DESC(cx18_pci_latency, 151MODULE_PARM_DESC(cx18_pci_latency,
141 "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n" 152 "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
142 "\t\t\tDefault: Yes"); 153 "\t\t\tDefault: Yes");
154MODULE_PARM_DESC(retry_mmio,
155 "Check and retry memory mapped IO accesses\n"
156 "\t\t\tDefault: 1 [Yes]");
157MODULE_PARM_DESC(mmio_ndelay,
158 "Delay (ns) for each CX23418 memory mapped IO access.\n"
159 "\t\t\tTry larger values that are close to a multiple of the\n"
160 "\t\t\tPCI clock period, 30.3 ns, if your card doesn't work.\n"
161 "\t\t\tDefault: " __stringify(CX18_DEFAULT_MMIO_NDELAY));
143MODULE_PARM_DESC(enc_mpg_buffers, 162MODULE_PARM_DESC(enc_mpg_buffers,
144 "Encoder MPG Buffers (in MB)\n" 163 "Encoder MPG Buffers (in MB)\n"
145 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS)); 164 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
@@ -156,7 +175,7 @@ MODULE_PARM_DESC(enc_pcm_buffers,
156 "Encoder PCM buffers (in MB)\n" 175 "Encoder PCM buffers (in MB)\n"
157 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS)); 176 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS));
158 177
159MODULE_PARM_DESC(cx18_first_minor, "Set minor assigned to first card"); 178MODULE_PARM_DESC(cx18_first_minor, "Set kernel number assigned to first card");
160 179
161MODULE_AUTHOR("Hans Verkuil"); 180MODULE_AUTHOR("Hans Verkuil");
162MODULE_DESCRIPTION("CX23418 driver"); 181MODULE_DESCRIPTION("CX23418 driver");
@@ -356,6 +375,11 @@ static void cx18_process_options(struct cx18 *cx)
356 cx->options.tuner = tuner[cx->num]; 375 cx->options.tuner = tuner[cx->num];
357 cx->options.radio = radio[cx->num]; 376 cx->options.radio = radio[cx->num];
358 377
378 if (mmio_ndelay[cx->num] < 0)
379 cx->options.mmio_ndelay = CX18_DEFAULT_MMIO_NDELAY;
380 else
381 cx->options.mmio_ndelay = mmio_ndelay[cx->num];
382
359 cx->std = cx18_parse_std(cx); 383 cx->std = cx18_parse_std(cx);
360 if (cx->options.cardtype == -1) { 384 if (cx->options.cardtype == -1) {
361 CX18_INFO("Ignore card\n"); 385 CX18_INFO("Ignore card\n");
@@ -395,9 +419,9 @@ done:
395 419
396 if (cx->card == NULL) { 420 if (cx->card == NULL) {
397 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); 421 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
398 CX18_ERR("Unknown card: vendor/device: %04x/%04x\n", 422 CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
399 cx->dev->vendor, cx->dev->device); 423 cx->dev->vendor, cx->dev->device);
400 CX18_ERR(" subsystem vendor/device: %04x/%04x\n", 424 CX18_ERR(" subsystem vendor/device: [%04x:%04x]\n",
401 cx->dev->subsystem_vendor, cx->dev->subsystem_device); 425 cx->dev->subsystem_vendor, cx->dev->subsystem_device);
402 CX18_ERR("Defaulting to %s card\n", cx->card->name); 426 CX18_ERR("Defaulting to %s card\n", cx->card->name);
403 CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n"); 427 CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
@@ -511,9 +535,9 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev,
511 return -EIO; 535 return -EIO;
512 } 536 }
513 537
514 /* Check for bus mastering */ 538 /* Enable bus mastering and memory mapped IO for the CX23418 */
515 pci_read_config_word(dev, PCI_COMMAND, &cmd); 539 pci_read_config_word(dev, PCI_COMMAND, &cmd);
516 cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; 540 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
517 pci_write_config_word(dev, PCI_COMMAND, cmd); 541 pci_write_config_word(dev, PCI_COMMAND, cmd);
518 542
519 pci_read_config_byte(dev, PCI_CLASS_REVISION, &cx->card_rev); 543 pci_read_config_byte(dev, PCI_CLASS_REVISION, &cx->card_rev);
@@ -525,11 +549,6 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev,
525 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); 549 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
526 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency); 550 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
527 } 551 }
528 /* This config space value relates to DMA latencies. The
529 default value 0x8080 is too low however and will lead
530 to DMA errors. 0xffff is the max value which solves
531 these problems. */
532 pci_write_config_dword(dev, 0x40, 0xffff);
533 552
534 CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, " 553 CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, "
535 "irq: %d, latency: %d, memory: 0x%lx\n", 554 "irq: %d, latency: %d, memory: 0x%lx\n",
@@ -656,7 +675,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
656 goto free_mem; 675 goto free_mem;
657 } 676 }
658 cx->reg_mem = cx->enc_mem + CX18_REG_OFFSET; 677 cx->reg_mem = cx->enc_mem + CX18_REG_OFFSET;
659 devtype = read_reg(0xC72028); 678 devtype = cx18_read_reg(cx, 0xC72028);
660 switch (devtype & 0xff000000) { 679 switch (devtype & 0xff000000) {
661 case 0xff000000: 680 case 0xff000000:
662 CX18_INFO("cx23418 revision %08x (A)\n", devtype); 681 CX18_INFO("cx23418 revision %08x (A)\n", devtype);
@@ -815,6 +834,7 @@ err:
815 if (retval == 0) 834 if (retval == 0)
816 retval = -ENODEV; 835 retval = -ENODEV;
817 CX18_ERR("Error %d on initialization\n", retval); 836 CX18_ERR("Error %d on initialization\n", retval);
837 cx18_log_statistics(cx);
818 838
819 kfree(cx18_cards[cx18_cards_active]); 839 kfree(cx18_cards[cx18_cards_active]);
820 cx18_cards[cx18_cards_active] = NULL; 840 cx18_cards[cx18_cards_active] = NULL;
@@ -902,8 +922,8 @@ static void cx18_remove(struct pci_dev *pci_dev)
902 cx18_stop_all_captures(cx); 922 cx18_stop_all_captures(cx);
903 923
904 /* Interrupts */ 924 /* Interrupts */
905 sw1_irq_disable(IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); 925 cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
906 sw2_irq_disable(IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); 926 cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
907 927
908 cx18_halt_firmware(cx); 928 cx18_halt_firmware(cx);
909 929
@@ -919,6 +939,7 @@ static void cx18_remove(struct pci_dev *pci_dev)
919 939
920 pci_disable_device(cx->dev); 940 pci_disable_device(cx->dev);
921 941
942 cx18_log_statistics(cx);
922 CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num); 943 CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num);
923} 944}
924 945
@@ -938,7 +959,7 @@ static int module_start(void)
938 959
939 /* Validate parameters */ 960 /* Validate parameters */
940 if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) { 961 if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
941 printk(KERN_ERR "cx18: Exiting, ivtv_first_minor must be between 0 and %d\n", 962 printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n",
942 CX18_MAX_CARDS - 1); 963 CX18_MAX_CARDS - 1);
943 return -1; 964 return -1;
944 } 965 }