diff options
Diffstat (limited to 'drivers/media/dvb/ngene')
-rw-r--r-- | drivers/media/dvb/ngene/ngene-cards.c | 15 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene-core.c | 80 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene-dvb.c | 15 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene-i2c.c | 1 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene.h | 3 |
5 files changed, 76 insertions, 38 deletions
diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c index 692c3e226e8..4692a41ad95 100644 --- a/drivers/media/dvb/ngene/ngene-cards.c +++ b/drivers/media/dvb/ngene/ngene-cards.c | |||
@@ -217,6 +217,19 @@ static struct ngene_info ngene_info_cineS2v5 = { | |||
217 | .fw_version = 15, | 217 | .fw_version = 15, |
218 | }; | 218 | }; |
219 | 219 | ||
220 | static struct ngene_info ngene_info_duoFlexS2 = { | ||
221 | .type = NGENE_SIDEWINDER, | ||
222 | .name = "Digital Devices DuoFlex S2 miniPCIe", | ||
223 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, | ||
224 | .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, | ||
225 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, | ||
226 | .fe_config = {&fe_cineS2, &fe_cineS2}, | ||
227 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, | ||
228 | .lnb = {0x0a, 0x08}, | ||
229 | .tsf = {3, 3}, | ||
230 | .fw_version = 15, | ||
231 | }; | ||
232 | |||
220 | static struct ngene_info ngene_info_m780 = { | 233 | static struct ngene_info ngene_info_m780 = { |
221 | .type = NGENE_APP, | 234 | .type = NGENE_APP, |
222 | .name = "Aver M780 ATSC/QAM-B", | 235 | .name = "Aver M780 ATSC/QAM-B", |
@@ -256,6 +269,8 @@ static const struct pci_device_id ngene_id_tbl[] __devinitdata = { | |||
256 | NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2), | 269 | NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2), |
257 | NGENE_ID(0x18c3, 0xdb02, ngene_info_satixS2v2), | 270 | NGENE_ID(0x18c3, 0xdb02, ngene_info_satixS2v2), |
258 | NGENE_ID(0x18c3, 0xdd00, ngene_info_cineS2v5), | 271 | NGENE_ID(0x18c3, 0xdd00, ngene_info_cineS2v5), |
272 | NGENE_ID(0x18c3, 0xdd10, ngene_info_duoFlexS2), | ||
273 | NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlexS2), | ||
259 | NGENE_ID(0x1461, 0x062e, ngene_info_m780), | 274 | NGENE_ID(0x1461, 0x062e, ngene_info_m780), |
260 | {0} | 275 | {0} |
261 | }; | 276 | }; |
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c index c8b4dfa0ab5..4caeb163a66 100644 --- a/drivers/media/dvb/ngene/ngene-core.c +++ b/drivers/media/dvb/ngene/ngene-core.c | |||
@@ -53,8 +53,6 @@ MODULE_PARM_DESC(debug, "Print debugging information."); | |||
53 | 53 | ||
54 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 54 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
55 | 55 | ||
56 | #define COMMAND_TIMEOUT_WORKAROUND | ||
57 | |||
58 | #define dprintk if (debug) printk | 56 | #define dprintk if (debug) printk |
59 | 57 | ||
60 | #define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr))) | 58 | #define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr))) |
@@ -147,24 +145,24 @@ static void demux_tasklet(unsigned long data) | |||
147 | } else { | 145 | } else { |
148 | if (chan->HWState == HWSTATE_RUN) { | 146 | if (chan->HWState == HWSTATE_RUN) { |
149 | u32 Flags = 0; | 147 | u32 Flags = 0; |
148 | IBufferExchange *exch1 = chan->pBufferExchange; | ||
149 | IBufferExchange *exch2 = chan->pBufferExchange2; | ||
150 | if (Cur->ngeneBuffer.SR.Flags & 0x01) | 150 | if (Cur->ngeneBuffer.SR.Flags & 0x01) |
151 | Flags |= BEF_EVEN_FIELD; | 151 | Flags |= BEF_EVEN_FIELD; |
152 | if (Cur->ngeneBuffer.SR.Flags & 0x20) | 152 | if (Cur->ngeneBuffer.SR.Flags & 0x20) |
153 | Flags |= BEF_OVERFLOW; | 153 | Flags |= BEF_OVERFLOW; |
154 | if (chan->pBufferExchange) | 154 | spin_unlock_irq(&chan->state_lock); |
155 | chan->pBufferExchange(chan, | 155 | if (exch1) |
156 | Cur->Buffer1, | 156 | exch1(chan, Cur->Buffer1, |
157 | chan-> | 157 | chan->Capture1Length, |
158 | Capture1Length, | 158 | Cur->ngeneBuffer.SR.Clock, |
159 | Cur->ngeneBuffer. | 159 | Flags); |
160 | SR.Clock, Flags); | 160 | if (exch2) |
161 | if (chan->pBufferExchange2) | 161 | exch2(chan, Cur->Buffer2, |
162 | chan->pBufferExchange2(chan, | 162 | chan->Capture2Length, |
163 | Cur->Buffer2, | 163 | Cur->ngeneBuffer.SR.Clock, |
164 | chan-> | 164 | Flags); |
165 | Capture2Length, | 165 | spin_lock_irq(&chan->state_lock); |
166 | Cur->ngeneBuffer. | ||
167 | SR.Clock, Flags); | ||
168 | } else if (chan->HWState != HWSTATE_STOP) | 166 | } else if (chan->HWState != HWSTATE_STOP) |
169 | chan->HWState = HWSTATE_RUN; | 167 | chan->HWState = HWSTATE_RUN; |
170 | } | 168 | } |
@@ -572,11 +570,7 @@ static int ngene_command_stream_control(struct ngene *dev, u8 stream, | |||
572 | u16 BsSPI = ((stream & 1) ? 0x9800 : 0x9700); | 570 | u16 BsSPI = ((stream & 1) ? 0x9800 : 0x9700); |
573 | u16 BsSDO = 0x9B00; | 571 | u16 BsSDO = 0x9B00; |
574 | 572 | ||
575 | /* down(&dev->stream_mutex); */ | 573 | down(&dev->stream_mutex); |
576 | while (down_trylock(&dev->stream_mutex)) { | ||
577 | printk(KERN_INFO DEVICE_NAME ": SC locked\n"); | ||
578 | msleep(1); | ||
579 | } | ||
580 | memset(&com, 0, sizeof(com)); | 574 | memset(&com, 0, sizeof(com)); |
581 | com.cmd.hdr.Opcode = CMD_CONTROL; | 575 | com.cmd.hdr.Opcode = CMD_CONTROL; |
582 | com.cmd.hdr.Length = sizeof(struct FW_STREAM_CONTROL) - 2; | 576 | com.cmd.hdr.Length = sizeof(struct FW_STREAM_CONTROL) - 2; |
@@ -1252,14 +1246,17 @@ static int ngene_load_firm(struct ngene *dev) | |||
1252 | version = 15; | 1246 | version = 15; |
1253 | size = 23466; | 1247 | size = 23466; |
1254 | fw_name = "ngene_15.fw"; | 1248 | fw_name = "ngene_15.fw"; |
1249 | dev->cmd_timeout_workaround = true; | ||
1255 | break; | 1250 | break; |
1256 | case 16: | 1251 | case 16: |
1257 | size = 23498; | 1252 | size = 23498; |
1258 | fw_name = "ngene_16.fw"; | 1253 | fw_name = "ngene_16.fw"; |
1254 | dev->cmd_timeout_workaround = true; | ||
1259 | break; | 1255 | break; |
1260 | case 17: | 1256 | case 17: |
1261 | size = 24446; | 1257 | size = 24446; |
1262 | fw_name = "ngene_17.fw"; | 1258 | fw_name = "ngene_17.fw"; |
1259 | dev->cmd_timeout_workaround = true; | ||
1263 | break; | 1260 | break; |
1264 | } | 1261 | } |
1265 | 1262 | ||
@@ -1299,11 +1296,16 @@ static void ngene_stop(struct ngene *dev) | |||
1299 | ngwritel(0, NGENE_EVENT); | 1296 | ngwritel(0, NGENE_EVENT); |
1300 | ngwritel(0, NGENE_EVENT_HI); | 1297 | ngwritel(0, NGENE_EVENT_HI); |
1301 | free_irq(dev->pci_dev->irq, dev); | 1298 | free_irq(dev->pci_dev->irq, dev); |
1299 | #ifdef CONFIG_PCI_MSI | ||
1300 | if (dev->msi_enabled) | ||
1301 | pci_disable_msi(dev->pci_dev); | ||
1302 | #endif | ||
1302 | } | 1303 | } |
1303 | 1304 | ||
1304 | static int ngene_start(struct ngene *dev) | 1305 | static int ngene_start(struct ngene *dev) |
1305 | { | 1306 | { |
1306 | int stat; | 1307 | int stat; |
1308 | unsigned long flags; | ||
1307 | int i; | 1309 | int i; |
1308 | 1310 | ||
1309 | pci_set_master(dev->pci_dev); | 1311 | pci_set_master(dev->pci_dev); |
@@ -1333,6 +1335,28 @@ static int ngene_start(struct ngene *dev) | |||
1333 | if (stat < 0) | 1335 | if (stat < 0) |
1334 | goto fail; | 1336 | goto fail; |
1335 | 1337 | ||
1338 | #ifdef CONFIG_PCI_MSI | ||
1339 | /* enable MSI if kernel and card support it */ | ||
1340 | if (pci_msi_enabled() && dev->card_info->msi_supported) { | ||
1341 | ngwritel(0, NGENE_INT_ENABLE); | ||
1342 | free_irq(dev->pci_dev->irq, dev); | ||
1343 | stat = pci_enable_msi(dev->pci_dev); | ||
1344 | if (stat) { | ||
1345 | printk(KERN_INFO DEVICE_NAME | ||
1346 | ": MSI not available\n"); | ||
1347 | flags = IRQF_SHARED; | ||
1348 | } else { | ||
1349 | flags = 0; | ||
1350 | dev->msi_enabled = true; | ||
1351 | } | ||
1352 | stat = request_irq(dev->pci_dev->irq, irq_handler, | ||
1353 | flags, "nGene", dev); | ||
1354 | if (stat < 0) | ||
1355 | goto fail2; | ||
1356 | ngwritel(1, NGENE_INT_ENABLE); | ||
1357 | } | ||
1358 | #endif | ||
1359 | |||
1336 | stat = ngene_i2c_init(dev, 0); | 1360 | stat = ngene_i2c_init(dev, 0); |
1337 | if (stat < 0) | 1361 | if (stat < 0) |
1338 | goto fail; | 1362 | goto fail; |
@@ -1358,10 +1382,18 @@ static int ngene_start(struct ngene *dev) | |||
1358 | bconf = BUFFER_CONFIG_3333; | 1382 | bconf = BUFFER_CONFIG_3333; |
1359 | stat = ngene_command_config_buf(dev, bconf); | 1383 | stat = ngene_command_config_buf(dev, bconf); |
1360 | } | 1384 | } |
1361 | return stat; | 1385 | if (!stat) |
1386 | return stat; | ||
1387 | |||
1388 | /* otherwise error: fall through */ | ||
1362 | fail: | 1389 | fail: |
1363 | ngwritel(0, NGENE_INT_ENABLE); | 1390 | ngwritel(0, NGENE_INT_ENABLE); |
1364 | free_irq(dev->pci_dev->irq, dev); | 1391 | free_irq(dev->pci_dev->irq, dev); |
1392 | #ifdef CONFIG_PCI_MSI | ||
1393 | fail2: | ||
1394 | if (dev->msi_enabled) | ||
1395 | pci_disable_msi(dev->pci_dev); | ||
1396 | #endif | ||
1365 | return stat; | 1397 | return stat; |
1366 | } | 1398 | } |
1367 | 1399 | ||
@@ -1379,10 +1411,8 @@ static void release_channel(struct ngene_channel *chan) | |||
1379 | struct ngene_info *ni = dev->card_info; | 1411 | struct ngene_info *ni = dev->card_info; |
1380 | int io = ni->io_type[chan->number]; | 1412 | int io = ni->io_type[chan->number]; |
1381 | 1413 | ||
1382 | #ifdef COMMAND_TIMEOUT_WORKAROUND | 1414 | if (chan->dev->cmd_timeout_workaround && chan->running) |
1383 | if (chan->running) | ||
1384 | set_transfer(chan, 0); | 1415 | set_transfer(chan, 0); |
1385 | #endif | ||
1386 | 1416 | ||
1387 | tasklet_kill(&chan->demux_tasklet); | 1417 | tasklet_kill(&chan->demux_tasklet); |
1388 | 1418 | ||
diff --git a/drivers/media/dvb/ngene/ngene-dvb.c b/drivers/media/dvb/ngene/ngene-dvb.c index 96013eb353c..48f980b21d6 100644 --- a/drivers/media/dvb/ngene/ngene-dvb.c +++ b/drivers/media/dvb/ngene/ngene-dvb.c | |||
@@ -37,15 +37,12 @@ | |||
37 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <linux/smp_lock.h> | 38 | #include <linux/smp_lock.h> |
39 | #include <linux/timer.h> | 39 | #include <linux/timer.h> |
40 | #include <linux/version.h> | ||
41 | #include <linux/byteorder/generic.h> | 40 | #include <linux/byteorder/generic.h> |
42 | #include <linux/firmware.h> | 41 | #include <linux/firmware.h> |
43 | #include <linux/vmalloc.h> | 42 | #include <linux/vmalloc.h> |
44 | 43 | ||
45 | #include "ngene.h" | 44 | #include "ngene.h" |
46 | 45 | ||
47 | #define COMMAND_TIMEOUT_WORKAROUND | ||
48 | |||
49 | 46 | ||
50 | /****************************************************************************/ | 47 | /****************************************************************************/ |
51 | /* COMMAND API interface ****************************************************/ | 48 | /* COMMAND API interface ****************************************************/ |
@@ -69,9 +66,7 @@ void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) | |||
69 | struct ngene_channel *chan = priv; | 66 | struct ngene_channel *chan = priv; |
70 | 67 | ||
71 | 68 | ||
72 | #ifdef COMMAND_TIMEOUT_WORKAROUND | ||
73 | if (chan->users > 0) | 69 | if (chan->users > 0) |
74 | #endif | ||
75 | dvb_dmx_swfilter(&chan->demux, buf, len); | 70 | dvb_dmx_swfilter(&chan->demux, buf, len); |
76 | return NULL; | 71 | return NULL; |
77 | } | 72 | } |
@@ -106,11 +101,8 @@ int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
106 | struct ngene_channel *chan = dvbdmx->priv; | 101 | struct ngene_channel *chan = dvbdmx->priv; |
107 | 102 | ||
108 | if (chan->users == 0) { | 103 | if (chan->users == 0) { |
109 | #ifdef COMMAND_TIMEOUT_WORKAROUND | 104 | if (!chan->dev->cmd_timeout_workaround || !chan->running) |
110 | if (!chan->running) | ||
111 | #endif | ||
112 | set_transfer(chan, 1); | 105 | set_transfer(chan, 1); |
113 | /* msleep(10); */ | ||
114 | } | 106 | } |
115 | 107 | ||
116 | return ++chan->users; | 108 | return ++chan->users; |
@@ -124,9 +116,8 @@ int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
124 | if (--chan->users) | 116 | if (--chan->users) |
125 | return chan->users; | 117 | return chan->users; |
126 | 118 | ||
127 | #ifndef COMMAND_TIMEOUT_WORKAROUND | 119 | if (!chan->dev->cmd_timeout_workaround) |
128 | set_transfer(chan, 0); | 120 | set_transfer(chan, 0); |
129 | #endif | ||
130 | 121 | ||
131 | return 0; | 122 | return 0; |
132 | } | 123 | } |
diff --git a/drivers/media/dvb/ngene/ngene-i2c.c b/drivers/media/dvb/ngene/ngene-i2c.c index 2ef54ca6bad..477fe0aade8 100644 --- a/drivers/media/dvb/ngene/ngene-i2c.c +++ b/drivers/media/dvb/ngene/ngene-i2c.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/pci_ids.h> | 39 | #include <linux/pci_ids.h> |
40 | #include <linux/smp_lock.h> | 40 | #include <linux/smp_lock.h> |
41 | #include <linux/timer.h> | 41 | #include <linux/timer.h> |
42 | #include <linux/version.h> | ||
43 | #include <linux/byteorder/generic.h> | 42 | #include <linux/byteorder/generic.h> |
44 | #include <linux/firmware.h> | 43 | #include <linux/firmware.h> |
45 | #include <linux/vmalloc.h> | 44 | #include <linux/vmalloc.h> |
diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h index 676fcbb7902..8fb4200f83f 100644 --- a/drivers/media/dvb/ngene/ngene.h +++ b/drivers/media/dvb/ngene/ngene.h | |||
@@ -725,6 +725,8 @@ struct ngene { | |||
725 | u32 device_version; | 725 | u32 device_version; |
726 | u32 fw_interface_version; | 726 | u32 fw_interface_version; |
727 | u32 icounts; | 727 | u32 icounts; |
728 | bool msi_enabled; | ||
729 | bool cmd_timeout_workaround; | ||
728 | 730 | ||
729 | u8 *CmdDoneByte; | 731 | u8 *CmdDoneByte; |
730 | int BootFirmware; | 732 | int BootFirmware; |
@@ -797,6 +799,7 @@ struct ngene_info { | |||
797 | #define NGENE_VBOX_V2 7 | 799 | #define NGENE_VBOX_V2 7 |
798 | 800 | ||
799 | int fw_version; | 801 | int fw_version; |
802 | bool msi_supported; | ||
800 | char *name; | 803 | char *name; |
801 | 804 | ||
802 | int io_type[MAX_STREAM]; | 805 | int io_type[MAX_STREAM]; |