summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/cx88/cx88-mpeg.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video/cx88/cx88-mpeg.c')
-rw-r--r--linux/drivers/media/video/cx88/cx88-mpeg.c67
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);
}
/* ----------------------------------------------------------- */