aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88/cx88-mpeg.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-11 22:09:32 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-11 22:09:32 -0400
commitc634920abaf9c0a93266a57beff6fce9d3852cb2 (patch)
tree5ac85f54905a8cd3b12b262c66189084cbff54fc /drivers/media/video/cx88/cx88-mpeg.c
parent6abd2c860e34add677de50e8b134f5af6f4b0893 (diff)
parenta991f44b79fa49b281eb078eed4a76a42101012a (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (310 commits) V4L/DVB (6316): Change list_for_each+list_entry to list_for_each_entry V4L/DVB (6315): pvrusb2: Change list_for_each+list_entry to list_for_each_entry V4L/DVB (6314): saa7134: Replace list_for_each+list_entry with list_for_each_entry V4L/DVB (6313): ivtv: Replace list_for_each+list_entry with list_for_each_entry V4L/DVB (6312): cx88: Replace list_for_each+list_entry with list_for_each_entry V4L/DVB (6311): dvb: Replace list_for_each+list_entry with list_for_each_entry V4L/DVB (6308): V4L: zc0301, remove bad usage of ERESTARTSYS V4L/DVB (6307): V4L: w9968cf, remove bad usage of ERESTARTSYS V4L/DVB (6306): Few clenups for saa7134 resume code V4L/DVB (6305): V4L: videobuf-core.c avoid NULL dereferences in videobuf-core V4L/DVB (6301): pvrusb: Update DEBUGIFC sysfs to kernel 2.6.13+ V4L/DVB (6300): CodingStyle cleanup V4L/DVB (6299): dvb: Add dependencies for VIDEOBUF_DVB V4L/DVB (6297): cx23885: remove wrong Kconfig selection of VIDEOBUF V4L/DVB (6296): dib0700: add support for AverMedia DVB-T Express card V4L/DVB (6295): saa7134: add autodetection for KWorld ATSC-115 V4L/DVB (6293): V4L: convert struct class_device to struct device V4L/DVB (6292): videobuf_core init always require callback implementation V4L/DVB (6291): Fix: avoid oops on some SMP machines V4L/DVB (6290): remove videobuf_set_pci_ops ...
Diffstat (limited to 'drivers/media/video/cx88/cx88-mpeg.c')
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c142
1 files changed, 75 insertions, 67 deletions
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index da7a6b591a67..a652f294d23d 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -23,12 +23,10 @@
23 */ 23 */
24 24
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h> 26#include <linux/init.h>
28#include <linux/device.h> 27#include <linux/device.h>
29#include <linux/dma-mapping.h> 28#include <linux/dma-mapping.h>
30#include <linux/interrupt.h> 29#include <linux/interrupt.h>
31#include <linux/dma-mapping.h>
32#include <asm/delay.h> 30#include <asm/delay.h>
33 31
34#include "cx88.h" 32#include "cx88.h"
@@ -56,9 +54,9 @@ static void request_module_async(struct work_struct *work)
56{ 54{
57 struct cx8802_dev *dev=container_of(work, struct cx8802_dev, request_module_wk); 55 struct cx8802_dev *dev=container_of(work, struct cx8802_dev, request_module_wk);
58 56
59 if (cx88_boards[dev->core->board].mpeg & CX88_MPEG_DVB) 57 if (dev->core->board.mpeg & CX88_MPEG_DVB)
60 request_module("cx88-dvb"); 58 request_module("cx88-dvb");
61 if (cx88_boards[dev->core->board].mpeg & CX88_MPEG_BLACKBIRD) 59 if (dev->core->board.mpeg & CX88_MPEG_BLACKBIRD)
62 request_module("cx88-blackbird"); 60 request_module("cx88-blackbird");
63} 61}
64 62
@@ -96,7 +94,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
96 dprintk( 1, "core->active_type_id = 0x%08x\n", core->active_type_id); 94 dprintk( 1, "core->active_type_id = 0x%08x\n", core->active_type_id);
97 95
98 if ( (core->active_type_id == CX88_MPEG_DVB) && 96 if ( (core->active_type_id == CX88_MPEG_DVB) &&
99 (cx88_boards[core->board].mpeg & CX88_MPEG_DVB) ) { 97 (core->board.mpeg & CX88_MPEG_DVB) ) {
100 98
101 dprintk( 1, "cx8802_start_dma doing .dvb\n"); 99 dprintk( 1, "cx8802_start_dma doing .dvb\n");
102 /* negedge driven & software reset */ 100 /* negedge driven & software reset */
@@ -104,7 +102,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
104 udelay(100); 102 udelay(100);
105 cx_write(MO_PINMUX_IO, 0x00); 103 cx_write(MO_PINMUX_IO, 0x00);
106 cx_write(TS_HW_SOP_CNTRL,0x47<<16|188<<4|0x01); 104 cx_write(TS_HW_SOP_CNTRL,0x47<<16|188<<4|0x01);
107 switch (core->board) { 105 switch (core->boardnr) {
108 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: 106 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
109 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: 107 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
110 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: 108 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
@@ -125,7 +123,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
125 cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl); 123 cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl);
126 udelay(100); 124 udelay(100);
127 } else if ( (core->active_type_id == CX88_MPEG_BLACKBIRD) && 125 } else if ( (core->active_type_id == CX88_MPEG_BLACKBIRD) &&
128 (cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD) ) { 126 (core->board.mpeg & CX88_MPEG_BLACKBIRD) ) {
129 dprintk( 1, "cx8802_start_dma doing .blackbird\n"); 127 dprintk( 1, "cx8802_start_dma doing .blackbird\n");
130 cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */ 128 cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */
131 129
@@ -139,7 +137,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
139 udelay(100); 137 udelay(100);
140 } else { 138 } else {
141 printk( "%s() Failed. Unsupported value in .mpeg (0x%08x)\n", __FUNCTION__, 139 printk( "%s() Failed. Unsupported value in .mpeg (0x%08x)\n", __FUNCTION__,
142 cx88_boards[core->board].mpeg ); 140 core->board.mpeg );
143 return -EINVAL; 141 return -EINVAL;
144 } 142 }
145 143
@@ -149,7 +147,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
149 147
150 /* enable irqs */ 148 /* enable irqs */
151 dprintk( 1, "setting the interrupt mask\n" ); 149 dprintk( 1, "setting the interrupt mask\n" );
152 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04); 150 cx_set(MO_PCI_INTMSK, core->pci_irqmask | PCI_INT_TSINT);
153 cx_set(MO_TS_INTMSK, 0x1f0011); 151 cx_set(MO_TS_INTMSK, 0x1f0011);
154 152
155 /* start dma */ 153 /* start dma */
@@ -167,7 +165,7 @@ static int cx8802_stop_dma(struct cx8802_dev *dev)
167 cx_clear(MO_TS_DMACNTRL, 0x11); 165 cx_clear(MO_TS_DMACNTRL, 0x11);
168 166
169 /* disable irqs */ 167 /* disable irqs */
170 cx_clear(MO_PCI_INTMSK, 0x000004); 168 cx_clear(MO_PCI_INTMSK, PCI_INT_TSINT);
171 cx_clear(MO_TS_INTMSK, 0x1f0011); 169 cx_clear(MO_TS_INTMSK, 0x1f0011);
172 170
173 /* Reset the controller */ 171 /* Reset the controller */
@@ -181,43 +179,43 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
181 struct cx88_buffer *buf; 179 struct cx88_buffer *buf;
182 struct list_head *item; 180 struct list_head *item;
183 181
184 dprintk( 1, "cx8802_restart_queue\n" ); 182 dprintk( 1, "cx8802_restart_queue\n" );
185 if (list_empty(&q->active)) 183 if (list_empty(&q->active))
186 { 184 {
187 struct cx88_buffer *prev; 185 struct cx88_buffer *prev;
188 prev = NULL; 186 prev = NULL;
189 187
190 dprintk(1, "cx8802_restart_queue: queue is empty\n" ); 188 dprintk(1, "cx8802_restart_queue: queue is empty\n" );
191 189
192 for (;;) { 190 for (;;) {
193 if (list_empty(&q->queued)) 191 if (list_empty(&q->queued))
194 return 0; 192 return 0;
195 buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue); 193 buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
196 if (NULL == prev) { 194 if (NULL == prev) {
197 list_del(&buf->vb.queue); 195 list_del(&buf->vb.queue);
198 list_add_tail(&buf->vb.queue,&q->active); 196 list_add_tail(&buf->vb.queue,&q->active);
199 cx8802_start_dma(dev, q, buf); 197 cx8802_start_dma(dev, q, buf);
200 buf->vb.state = STATE_ACTIVE; 198 buf->vb.state = STATE_ACTIVE;
201 buf->count = q->count++; 199 buf->count = q->count++;
202 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); 200 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
203 dprintk(1,"[%p/%d] restart_queue - first active\n", 201 dprintk(1,"[%p/%d] restart_queue - first active\n",
204 buf,buf->vb.i); 202 buf,buf->vb.i);
205 203
206 } else if (prev->vb.width == buf->vb.width && 204 } else if (prev->vb.width == buf->vb.width &&
207 prev->vb.height == buf->vb.height && 205 prev->vb.height == buf->vb.height &&
208 prev->fmt == buf->fmt) { 206 prev->fmt == buf->fmt) {
209 list_del(&buf->vb.queue); 207 list_del(&buf->vb.queue);
210 list_add_tail(&buf->vb.queue,&q->active); 208 list_add_tail(&buf->vb.queue,&q->active);
211 buf->vb.state = STATE_ACTIVE; 209 buf->vb.state = STATE_ACTIVE;
212 buf->count = q->count++; 210 buf->count = q->count++;
213 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); 211 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
214 dprintk(1,"[%p/%d] restart_queue - move to active\n", 212 dprintk(1,"[%p/%d] restart_queue - move to active\n",
215 buf,buf->vb.i); 213 buf,buf->vb.i);
216 } else { 214 } else {
217 return 0; 215 return 0;
218 } 216 }
219 prev = buf; 217 prev = buf;
220 } 218 }
221 return 0; 219 return 0;
222 } 220 }
223 221
@@ -239,6 +237,7 @@ int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev,
239 struct cx88_buffer *buf, enum v4l2_field field) 237 struct cx88_buffer *buf, enum v4l2_field field)
240{ 238{
241 int size = dev->ts_packet_size * dev->ts_packet_count; 239 int size = dev->ts_packet_size * dev->ts_packet_count;
240 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
242 int rc; 241 int rc;
243 242
244 dprintk(1, "%s: %p\n", __FUNCTION__, buf); 243 dprintk(1, "%s: %p\n", __FUNCTION__, buf);
@@ -254,8 +253,8 @@ int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev,
254 if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL))) 253 if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
255 goto fail; 254 goto fail;
256 cx88_risc_databuffer(dev->pci, &buf->risc, 255 cx88_risc_databuffer(dev->pci, &buf->risc,
257 buf->vb.dma.sglist, 256 dma->sglist,
258 buf->vb.width, buf->vb.height); 257 buf->vb.width, buf->vb.height, 0);
259 } 258 }
260 buf->vb.state = STATE_PREPARED; 259 buf->vb.state = STATE_PREPARED;
261 return 0; 260 return 0;
@@ -414,7 +413,8 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id)
414 int loop, handled = 0; 413 int loop, handled = 0;
415 414
416 for (loop = 0; loop < MAX_IRQ_LOOP; loop++) { 415 for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
417 status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04); 416 status = cx_read(MO_PCI_INTSTAT) &
417 (core->pci_irqmask | PCI_INT_TSINT);
418 if (0 == status) 418 if (0 == status)
419 goto out; 419 goto out;
420 dprintk( 1, "cx8802_irq\n" ); 420 dprintk( 1, "cx8802_irq\n" );
@@ -425,7 +425,7 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id)
425 425
426 if (status & core->pci_irqmask) 426 if (status & core->pci_irqmask)
427 cx88_core_irq(core,status); 427 cx88_core_irq(core,status);
428 if (status & 0x04) 428 if (status & PCI_INT_TSINT)
429 cx8802_mpeg_irq(dev); 429 cx8802_mpeg_irq(dev);
430 }; 430 };
431 if (MAX_IRQ_LOOP == loop) { 431 if (MAX_IRQ_LOOP == loop) {
@@ -676,22 +676,24 @@ int cx8802_register_driver(struct cx8802_driver *drv)
676 struct list_head *list; 676 struct list_head *list;
677 int err = 0, i = 0; 677 int err = 0, i = 0;
678 678
679 printk(KERN_INFO "%s() ->registering driver type=%s access=%s\n", __FUNCTION__ , 679 printk(KERN_INFO
680 drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird", 680 "cx88/2: registering cx8802 driver, type: %s access: %s\n",
681 drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive"); 681 drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
682 drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
682 683
683 if ((err = cx8802_check_driver(drv)) != 0) { 684 if ((err = cx8802_check_driver(drv)) != 0) {
684 printk(KERN_INFO "%s() cx8802_driver is invalid\n", __FUNCTION__ ); 685 printk(KERN_ERR "cx88/2: cx8802_driver is invalid\n");
685 return err; 686 return err;
686 } 687 }
687 688
688 list_for_each(list,&cx8802_devlist) { 689 list_for_each(list,&cx8802_devlist) {
689 h = list_entry(list, struct cx8802_dev, devlist); 690 h = list_entry(list, struct cx8802_dev, devlist);
690 691
691 printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d]\n", 692 printk(KERN_INFO
692 h->core->name,h->pci->subsystem_vendor, 693 "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
693 h->pci->subsystem_device,cx88_boards[h->core->board].name, 694 h->core->name, h->pci->subsystem_vendor,
694 h->core->board); 695 h->pci->subsystem_device, h->core->board.name,
696 h->core->boardnr);
695 697
696 /* Bring up a new struct for each driver instance */ 698 /* Bring up a new struct for each driver instance */
697 driver = kzalloc(sizeof(*drv),GFP_KERNEL); 699 driver = kzalloc(sizeof(*drv),GFP_KERNEL);
@@ -713,7 +715,9 @@ int cx8802_register_driver(struct cx8802_driver *drv)
713 list_add_tail(&driver->devlist,&h->drvlist.devlist); 715 list_add_tail(&driver->devlist,&h->drvlist.devlist);
714 mutex_unlock(&drv->core->lock); 716 mutex_unlock(&drv->core->lock);
715 } else { 717 } else {
716 printk(KERN_ERR "%s() ->probe failed err = %d\n", __FUNCTION__, err); 718 printk(KERN_ERR
719 "%s/2: cx8802 probe failed, err = %d\n",
720 h->core->name, err);
717 } 721 }
718 722
719 } 723 }
@@ -733,17 +737,20 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
733 struct list_head *list2, *q; 737 struct list_head *list2, *q;
734 int err = 0, i = 0; 738 int err = 0, i = 0;
735 739
736 printk(KERN_INFO "%s() ->unregistering driver type=%s\n", __FUNCTION__ , 740 printk(KERN_INFO
737 drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird"); 741 "cx88/2: unregistering cx8802 driver, type: %s access: %s\n",
742 drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
743 drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
738 744
739 list_for_each(list,&cx8802_devlist) { 745 list_for_each(list,&cx8802_devlist) {
740 i++; 746 i++;
741 h = list_entry(list, struct cx8802_dev, devlist); 747 h = list_entry(list, struct cx8802_dev, devlist);
742 748
743 printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d]\n", 749 printk(KERN_INFO
744 h->core->name,h->pci->subsystem_vendor, 750 "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
745 h->pci->subsystem_device,cx88_boards[h->core->board].name, 751 h->core->name, h->pci->subsystem_vendor,
746 h->core->board); 752 h->pci->subsystem_device, h->core->board.name,
753 h->core->boardnr);
747 754
748 list_for_each_safe(list2, q, &h->drvlist.devlist) { 755 list_for_each_safe(list2, q, &h->drvlist.devlist) {
749 d = list_entry(list2, struct cx8802_driver, devlist); 756 d = list_entry(list2, struct cx8802_driver, devlist);
@@ -758,7 +765,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
758 list_del(list2); 765 list_del(list2);
759 mutex_unlock(&drv->core->lock); 766 mutex_unlock(&drv->core->lock);
760 } else 767 } else
761 printk(KERN_ERR "%s() ->remove failed err = %d\n", __FUNCTION__, err); 768 printk(KERN_ERR "%s/2: cx8802 driver remove "
769 "failed (%d)\n", h->core->name, err);
762 770
763 } 771 }
764 772
@@ -783,7 +791,7 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
783 printk("%s/2: cx2388x 8802 Driver Manager\n", core->name); 791 printk("%s/2: cx2388x 8802 Driver Manager\n", core->name);
784 792
785 err = -ENODEV; 793 err = -ENODEV;
786 if (!cx88_boards[core->board].mpeg) 794 if (!core->board.mpeg)
787 goto fail_core; 795 goto fail_core;
788 796
789 err = -ENOMEM; 797 err = -ENOMEM;
@@ -866,7 +874,7 @@ static struct pci_driver cx8802_pci_driver = {
866 874
867static int cx8802_init(void) 875static int cx8802_init(void)
868{ 876{
869 printk(KERN_INFO "cx2388x cx88-mpeg Driver Manager version %d.%d.%d loaded\n", 877 printk(KERN_INFO "cx88/2: cx2388x MPEG-TS Driver Manager version %d.%d.%d loaded\n",
870 (CX88_VERSION_CODE >> 16) & 0xff, 878 (CX88_VERSION_CODE >> 16) & 0xff,
871 (CX88_VERSION_CODE >> 8) & 0xff, 879 (CX88_VERSION_CODE >> 8) & 0xff,
872 CX88_VERSION_CODE & 0xff); 880 CX88_VERSION_CODE & 0xff);