diff options
Diffstat (limited to 'linux/drivers/media/video/cx88/cx88-mpeg.c')
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-mpeg.c | 67 |
1 files changed, 40 insertions, 27 deletions
diff --git a/linux/drivers/media/video/cx88/cx88-mpeg.c b/linux/drivers/media/video/cx88/cx88-mpeg.c index 735356325..a0445baf5 100644 --- a/linux/drivers/media/video/cx88/cx88-mpeg.c +++ b/linux/drivers/media/video/cx88/cx88-mpeg.c @@ -1,10 +1,11 @@ /* - * $Id: cx88-mpeg.c,v 1.5 2004/08/25 14:47:53 kraxel Exp $ + * $Id: cx88-mpeg.c,v 1.6 2004/08/31 11:58:53 kraxel Exp $ * * Support for the mpeg transport stream transfers * PCI function #2 of the cx2388x. * * (c) 2004 Jelle Foks <jelle@foks.8m.com> + * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au> * (c) 2004 Gerd Knorr <kraxel@bytesex.org> * * This program is free software; you can redistribute it and/or modify @@ -34,6 +35,7 @@ MODULE_DESCRIPTION("mpeg driver for cx2388x based TV cards"); MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>"); +MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); MODULE_LICENSE("GPL"); @@ -58,6 +60,9 @@ int cx8802_start_dma(struct cx8802_dev *dev, cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], dev->ts_packet_size, buf->risc.dma); + /* write TS length to chip */ + cx_write(MO_TS_LNGTH, buf->vb.width); + #if 1 /* FIXME: this needs a review. * also: move to cx88-blackbird + cx88-dvb source files? */ @@ -65,19 +70,13 @@ int cx8802_start_dma(struct cx8802_dev *dev, 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); } 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 */ @@ -95,14 +94,30 @@ int cx8802_start_dma(struct cx8802_dev *dev, /* enable irqs */ cx_set(MO_PCI_INTMSK, 0x00fc04); - cx_set(MO_TS_INTMSK, 0x1f0011); + cx_write(MO_TS_INTMSK, 0x1f0011); /* start dma */ - cx_set(MO_DEV_CNTRL2, (1<<5)); - cx_set(MO_TS_DMACNTRL, 0x11); + cx_write(MO_DEV_CNTRL2, (1<<5)); /* FIXME: s/write/set/ ??? */ + cx_write(MO_TS_DMACNTRL, 0x11); return 0; } +void cx8802_shutdown(struct cx8802_dev *dev) +{ + struct cx88_core *core = dev->core; + + /* disable and clear irqs */ + cx_write(MO_TS_INTMSK, 0x0); + cx_write(MO_TS_INTSTAT, 0x1f1111); + + /* stop dma */ + cx_clear(MO_TS_DMACNTRL, 0x11); + cx_write(MO_DEV_CNTRL2, 0); /* FIXME: affects other pci functions ??? */ + + /* Reset the controller */ + cx_write(TS_GEN_CNTRL, 0xcd); +} + int cx8802_restart_queue(struct cx8802_dev *dev, struct cx88_dmaqueue *q) { @@ -143,11 +158,9 @@ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf) if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL))) goto fail; - cx88_risc_buffer(dev->pci, &buf->risc, - buf->vb.dma.sglist, - 0, UNSET, - buf->vb.width, 0, - buf->vb.height); + cx88_risc_databuffer(dev->pci, &buf->risc, + buf->vb.dma.sglist, + buf->vb.width, buf->vb.height); } buf->vb.state = STATE_PREPARED; return 0; @@ -186,12 +199,6 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) } } -void cx8802_buf_release(struct cx8802_dev *dev, struct cx88_buffer *buf) -{ - dprintk(1, "%s: %p\n", __FUNCTION__, buf); - -} - /* ----------------------------------------------------------- */ static void cx8802_timeout(unsigned long data) @@ -238,7 +245,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) cx_write(MO_TS_INTSTAT, status); if (debug || (status & mask & ~0xff)) cx88_print_irqbits(core->name, "irq mpeg ", - cx88_vid_irqs, status, mask); + cx88_mpeg_irqs, status, mask); /* risc op code error */ if (status & (1 << 16)) { @@ -256,11 +263,21 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) } /* risc2 y */ - if (status & 0x10) { /* I don't know what this does/when it's needed */ + if (status & 0x10) { spin_lock(&dev->slock); + dev->stopper_count++; cx8802_restart_queue(dev,&dev->mpegq); spin_unlock(&dev->slock); } + + /* other general errors */ + if (status & 0x1f0100) { + spin_lock(&dev->slock); + dev->error_count++; + cx8802_shutdown(dev); + cx8802_restart_queue(dev,&dev->mpegq); + spin_unlock(&dev->slock); + } } static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs) @@ -355,9 +372,7 @@ int cx8802_init_common(struct cx8802_dev *dev) void cx8802_fini_common(struct cx8802_dev *dev) { -#if 0 cx8802_shutdown(dev); -#endif pci_disable_device(dev->pci); /* unregister stuff */ @@ -366,8 +381,6 @@ void cx8802_fini_common(struct cx8802_dev *dev) /* free memory */ btcx_riscmem_free(dev->pci,&dev->mpegq.stopper); - cx88_core_put(dev->core,dev->pci); - kfree(dev); } /* ----------------------------------------------------------- */ |