diff options
Diffstat (limited to 'linux/drivers/media/video/cx88/cx88-mpeg.c')
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-mpeg.c | 270 |
1 files changed, 72 insertions, 198 deletions
diff --git a/linux/drivers/media/video/cx88/cx88-mpeg.c b/linux/drivers/media/video/cx88/cx88-mpeg.c index 9d92fce36..735356325 100644 --- a/linux/drivers/media/video/cx88/cx88-mpeg.c +++ b/linux/drivers/media/video/cx88/cx88-mpeg.c @@ -1,5 +1,5 @@ /* - * $Id: cx88-mpeg.c,v 1.4 2004/07/30 15:26:01 kraxel Exp $ + * $Id: cx88-mpeg.c,v 1.5 2004/08/25 14:47:53 kraxel Exp $ * * Support for the mpeg transport stream transfers * PCI function #2 of the cx2388x. @@ -30,10 +30,6 @@ #include "cx88.h" -#define PACKET_SIZE 512 // smaller ones seem not to work -#define PACKETS_PER_BUFFER 1024 -#define BUFFER_SIZE (PACKET_SIZE * PACKETS_PER_BUFFER) - /* ------------------------------------------------------------------ */ MODULE_DESCRIPTION("mpeg driver for cx2388x based TV cards"); @@ -41,19 +37,13 @@ MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>"); MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); MODULE_LICENSE("GPL"); -static unsigned int mpegbufs = 8; -MODULE_PARM(mpegbufs,"i"); -MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32"); - -static unsigned int mpeg_debug = 0; -MODULE_PARM(mpeg_debug,"i"); -MODULE_PARM_DESC(mpeg_debug,"enable debug messages [mpeg]"); +static unsigned int debug = 0; +MODULE_PARM(debug,"i"); +MODULE_PARM_DESC(debug,"enable debug messages [mpeg]"); -#define dprintk(level,fmt, arg...) if (mpeg_debug >= level) \ +#define dprintk(level,fmt, arg...) if (debug >= level) \ printk(KERN_DEBUG "%s/2: " fmt, dev->core->name , ## arg) -LIST_HEAD(cx8802_devlist); - /* ------------------------------------------------------------------ */ int cx8802_start_dma(struct cx8802_dev *dev, @@ -66,32 +56,37 @@ int cx8802_start_dma(struct cx8802_dev *dev, /* setup fifo + format */ cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], - PACKET_SIZE, buf->risc.dma); - -#if 0 /* config stuff from DVB */ - /* Setup TS portion of chip */ - cx_write(TS_GEN_CNTRL, 0x0c); - - /* write TS length to chip */ - cx_write(MO_TS_LNGTH, buf->bpl); -#endif - -#if 0 /* config stuff for from blackbird ... */ - cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */ - - - cx_write(TS_F2_CMD_STAT_MM, 0x2900106); /* F2_CMD_STAT_MM defaults + master + memory space */ - cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */ - cx_write(MO_TS_LNGTH, MD_TS_LNGHT_VAL); - - udelay(100); + dev->ts_packet_size, buf->risc.dma); + +#if 1 + /* FIXME: this needs a review. + * also: move to cx88-blackbird + cx88-dvb source files? */ + + if (cx88_boards[core->board].dvb) { + /* Setup TS portion of chip */ + cx_write(TS_GEN_CNTRL, 0x0c); + + /* write TS length to chip */ + cx_write(MO_TS_LNGTH, buf->bpl); + } - cx_write(TS_HW_SOP_CNTRL, 0x408); /* mpeg start byte */ - //cx_write(TS_HW_SOP_CNTRL, 0x2F0BC0); /* mpeg start byte ts: 0x2F0BC0 ? */ - cx_write(TS_VALERR_CNTRL, 0x2000); - - cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */ - udelay(100); + if (cx88_boards[core->board].blackbird) { + cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */ + + + // cx_write(TS_F2_CMD_STAT_MM, 0x2900106); /* F2_CMD_STAT_MM defaults + master + memory space */ + cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */ + // cx_write(MO_TS_LNGTH, MD_TS_LNGHT_VAL); + + udelay(100); + + cx_write(TS_HW_SOP_CNTRL, 0x408); /* mpeg start byte */ + //cx_write(TS_HW_SOP_CNTRL, 0x2F0BC0); /* mpeg start byte ts: 0x2F0BC0 ? */ + cx_write(TS_VALERR_CNTRL, 0x2000); + + cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */ + udelay(100); + } #endif /* reset counter */ @@ -131,37 +126,20 @@ int cx8802_restart_queue(struct cx8802_dev *dev, /* ------------------------------------------------------------------ */ -static int -mpeg_buf_setup(struct file *file, unsigned int *count, unsigned int *size) -{ - *size = BUFFER_SIZE; - if (0 == *count) - *count = mpegbufs; - if (*count < 2) - *count = 2; - if (*count > 32) - *count = 32; - return 0; -} - -static int -mpeg_buf_prepare(struct file *file, struct videobuf_buffer *vb, - enum v4l2_field field) +int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf) { - struct cx8802_fh *fh = file->private_data; - struct cx8802_dev *dev = fh->dev; - struct cx88_buffer *buf = (struct cx88_buffer*)vb; + int size = dev->ts_packet_size * dev->ts_packet_count; int rc; dprintk(1, "%s: %p\n", __FUNCTION__, buf); - if (0 != buf->vb.baddr && buf->vb.bsize < BUFFER_SIZE) + if (0 != buf->vb.baddr && buf->vb.bsize < size) return -EINVAL; if (STATE_NEEDS_INIT == buf->vb.state) { - buf->vb.width = PACKET_SIZE; - buf->vb.height = PACKETS_PER_BUFFER; - buf->vb.size = BUFFER_SIZE; - buf->vb.field = field; + buf->vb.width = dev->ts_packet_size; + buf->vb.height = dev->ts_packet_count; + buf->vb.size = size; + buf->vb.field = V4L2_FIELD_TOP; if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL))) goto fail; @@ -179,13 +157,9 @@ mpeg_buf_prepare(struct file *file, struct videobuf_buffer *vb, return rc; } -static void -mpeg_buf_queue(struct file *file, struct videobuf_buffer *vb) +void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) { - struct cx88_buffer *buf = (struct cx88_buffer*)vb; struct cx88_buffer *prev; - struct cx8802_fh *fh = file->private_data; - struct cx8802_dev *dev = fh->dev; struct cx88_dmaqueue *q = &dev->mpegq; /* add jump to stopper */ @@ -212,30 +186,13 @@ mpeg_buf_queue(struct file *file, struct videobuf_buffer *vb) } } -static void mpeg_buf_release(struct file *file, struct videobuf_buffer *vb) +void cx8802_buf_release(struct cx8802_dev *dev, struct cx88_buffer *buf) { - struct cx88_buffer *buf = (struct cx88_buffer*)vb; - struct cx8802_fh *fh = file->private_data; - struct cx8802_dev *dev = fh->dev; - dprintk(1, "%s: %p\n", __FUNCTION__, buf); -#if 0 - /* FIXME: probably wrong place */ - mpegport_api_cmd(fh->dev, IVTV_API_END_CAPTURE, 3, 0, 1, 0, 0x13); -#endif - cx88_free_buffer(fh->dev->pci, buf); } -struct videobuf_queue_ops cx8802_mpeg_qops = { - .buf_setup = mpeg_buf_setup, - .buf_prepare = mpeg_buf_prepare, - .buf_queue = mpeg_buf_queue, - .buf_release = mpeg_buf_release, -}; - /* ----------------------------------------------------------- */ -/* exported stuff */ static void cx8802_timeout(unsigned long data) { @@ -279,7 +236,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) return; cx_write(MO_TS_INTSTAT, status); - if (mpeg_debug || (status & mask & ~0xff)) + if (debug || (status & mask & ~0xff)) cx88_print_irqbits(core->name, "irq mpeg ", cx88_vid_irqs, status, mask); @@ -337,63 +294,27 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs) } /* ----------------------------------------------------------- */ +/* exported stuff */ -static int __devinit cx8802_initdev(struct pci_dev *pci_dev, - const struct pci_device_id *pci_id) +int cx8802_init_common(struct cx8802_dev *dev) { - struct cx8802_dev *dev; - struct cx88_core *core; int err; - dev = kmalloc(sizeof(*dev),GFP_KERNEL); - if (NULL == dev) - return -ENOMEM; - memset(dev,0,sizeof(*dev)); - /* pci init */ - dev->pci = pci_dev; - if (pci_enable_device(pci_dev)) { - err = -EIO; - goto fail_free; - } - core = cx88_core_get(dev->pci); - if (NULL == core) { - err = -EINVAL; - goto fail_free; + if (pci_enable_device(dev->pci)) + return -EIO; + pci_set_master(dev->pci); + if (!pci_dma_supported(dev->pci,0xffffffff)) { + printk("%s/2: Oops: no 32bit PCI DMA ???\n",dev->core->name); + return -EIO; } - dev->core = core; - /* print pci info */ - pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); - pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); + pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev); + pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, " - "latency: %d, mmio: 0x%lx\n", core->name, - pci_name(pci_dev), dev->pci_rev, pci_dev->irq, - dev->pci_lat,pci_resource_start(pci_dev,0)); - - pci_set_master(pci_dev); - if (!pci_dma_supported(pci_dev,0xffffffff)) { - printk("%s/2: Oops: no 32bit PCI DMA ???\n",core->name); - err = -EIO; - goto fail_core; - } - - /* look what exactly we have ... */ - if (cx88_boards[core->board].blackbird) { - printk("%s/2: cx23416 based mpeg encoder (blackbird design)\n", - core->name); - /* todo: register v4l device, init cx23416 encoder */ - } else if (cx88_boards[core->board].dvb) { - printk("%s/2: has DVB support\n", - core->name); - /* todo: register dvb device */ - } else { - printk("%s/2: don't what the mpeg port on this card is used for\n" - "%s/2: going to ignore it, sorry\n", - core->name, core->name); - err = -EINVAL; - goto fail_core; - } + "latency: %d, mmio: 0x%lx\n", dev->core->name, + pci_name(dev->pci), dev->pci_rev, dev->pci->irq, + dev->pci_lat,pci_resource_start(dev->pci,0)); /* initialize driver struct */ init_MUTEX(&dev->lock); @@ -414,12 +335,12 @@ static int __devinit cx8802_initdev(struct pci_dev *pci_dev, #endif /* get irq */ - err = request_irq(pci_dev->irq, cx8802_irq, - SA_SHIRQ | SA_INTERRUPT, core->name, dev); + err = request_irq(dev->pci->irq, cx8802_irq, + SA_SHIRQ | SA_INTERRUPT, dev->core->name, dev); if (err < 0) { printk(KERN_ERR "%s: can't get IRQ %d\n", - core->name,pci_dev->irq); - goto fail_core; + dev->core->name, dev->pci->irq); + return err; } #if 0 /* FIXME */ @@ -428,80 +349,33 @@ static int __devinit cx8802_initdev(struct pci_dev *pci_dev, #endif /* everything worked */ - list_add_tail(&dev->devlist,&cx8802_devlist); - pci_set_drvdata(pci_dev,dev); + pci_set_drvdata(dev->pci,dev); return 0; - - fail_core: - cx88_core_put(core,dev->pci); - fail_free: - kfree(dev); - return err; } -static void __devexit cx8802_finidev(struct pci_dev *pci_dev) +void cx8802_fini_common(struct cx8802_dev *dev) { - struct cx8802_dev *dev = pci_get_drvdata(pci_dev); - #if 0 cx8802_shutdown(dev); #endif - pci_disable_device(pci_dev); + pci_disable_device(dev->pci); /* unregister stuff */ - free_irq(pci_dev->irq, dev); - pci_set_drvdata(pci_dev, NULL); + free_irq(dev->pci->irq, dev); + pci_set_drvdata(dev->pci, NULL); /* free memory */ btcx_riscmem_free(dev->pci,&dev->mpegq.stopper); - list_del(&dev->devlist); cx88_core_put(dev->core,dev->pci); kfree(dev); } +/* ----------------------------------------------------------- */ -struct pci_device_id cx8802_pci_tbl[] = { - { - .vendor = 0x14f1, - .device = 0x8802, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - },{ - /* --- end of list --- */ - } -}; -MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); - -static struct pci_driver cx8802_pci_driver = { - .name = "cx8802", - .id_table = cx8802_pci_tbl, - .probe = cx8802_initdev, - .remove = cx8802_finidev, -#if 0 - .suspend = cx8802_suspend, - .resume = cx8802_resume, -#endif -}; - -static int cx8802_init(void) -{ - printk(KERN_INFO "cx2388x mpeg driver version %d.%d.%d loaded\n", - (CX88_VERSION_CODE >> 16) & 0xff, - (CX88_VERSION_CODE >> 8) & 0xff, - CX88_VERSION_CODE & 0xff); -#ifdef SNAPSHOT - printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", - SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); -#endif - return pci_module_init(&cx8802_pci_driver); -} - -static void cx8802_fini(void) -{ - pci_unregister_driver(&cx8802_pci_driver); -} +EXPORT_SYMBOL(cx8802_buf_prepare); +EXPORT_SYMBOL(cx8802_buf_queue); -module_init(cx8802_init); -module_exit(cx8802_fini); +EXPORT_SYMBOL(cx8802_init_common); +EXPORT_SYMBOL(cx8802_fini_common); /* ----------------------------------------------------------- */ /* |