summaryrefslogtreecommitdiff
path: root/linux/drivers
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <devnull@localhost>2005-08-15 01:49:35 +0000
committerMauro Carvalho Chehab <devnull@localhost>2005-08-15 01:49:35 +0000
commitd787c1bd04c659cf030dbdf82157417ac4e599cc (patch)
tree1bbc7587c1bc97c7e2051fe67b09b9211472968b /linux/drivers
parentf298917ccd7cd74c18668b6a8f4b71b1bc518cd5 (diff)
downloadmediapointer-dvb-s2-d787c1bd04c659cf030dbdf82157417ac4e599cc.tar.gz
mediapointer-dvb-s2-d787c1bd04c659cf030dbdf82157417ac4e599cc.tar.bz2
* cx88-alsa.c:
- some DMA code included. Still incomplete. Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Diffstat (limited to 'linux/drivers')
-rw-r--r--linux/drivers/media/video/cx88/cx88-alsa.c221
1 files changed, 207 insertions, 14 deletions
diff --git a/linux/drivers/media/video/cx88/cx88-alsa.c b/linux/drivers/media/video/cx88/cx88-alsa.c
index 67c885e31..062ea54e3 100644
--- a/linux/drivers/media/video/cx88/cx88-alsa.c
+++ b/linux/drivers/media/video/cx88/cx88-alsa.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-alsa.c,v 1.6 2005/08/13 22:59:49 mchehab Exp $
+ * $Id: cx88-alsa.c,v 1.7 2005/08/15 01:49:36 mchehab Exp $
*
* Support for audio capture
* PCI function #1 of the cx2388x.
@@ -40,6 +40,10 @@
#include "cx88.h"
#include "cx88-reg.h"
+#define dprintk(level,fmt, arg...) if (debug >= level) \
+ printk(KERN_DEBUG "%s/1: " fmt, chip->core->name , ## arg)
+
+
/****************************************************************************
Data type declarations - Can be moded to a header file later
****************************************************************************/
@@ -60,7 +64,7 @@ enum { DEVICE_DIGITAL, DEVICE_ANALOG };
struct cx88_audio_dev {
struct cx88_core *core;
struct cx88_buffer *buf;
- struct cx88_dmaqueue *q;
+ struct cx88_dmaqueue q;
/* pci i/o */
struct pci_dev *pci;
@@ -111,10 +115,177 @@ MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Conexant,23881},"
"{{Conexant,23882},"
"{{Conexant,23883}");
+static unsigned int debug = 0;
+module_param(debug,int,0644);
+MODULE_PARM_DESC(debug,"enable debug messages");
/****************************************************************************
- Module useful unused functions
+ Module specific funtions
****************************************************************************/
+
+/*
+ * BOARD Specific: Sets audio DMA
+ */
+
+int cx88_start_audio_dma(snd_cx88_card_t *chip)
+{
+ struct cx88_core *core=chip->core;
+
+ /* setup fifo + format - out channel */
+ cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26],
+ chip->buf->bpl, chip->buf->risc.dma);
+
+ /* FIXME reset counter */
+ cx_write(MO_VIDY_GPCNTRL,GP_COUNT_CONTROL_RESET);
+
+ /* enable irqs */
+ cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | 0x02);
+
+ /* Enables corresponding bits at AUD_INT_STAT */
+#if 1
+ cx_set(MO_AUD_INTMSK, (1<<21)||(1<<19));
+#endif
+
+ /* start dma */
+ cx_set(MO_DEV_CNTRL2, (1<<5)); /* Enables Risc Processor */
+ cx_set(MO_AUD_DMACNTRL, 0x11); /* audio downstream FIFO and RISC enable */
+
+ return 0;
+}
+
+/*
+ * BOARD Specific: Resets audio DMA
+ */
+int cx88_stop_audio_dma(snd_cx88_card_t *chip)
+{
+ struct cx88_core *core=chip->core;
+ /* stop dma */
+ cx_clear(MO_AUD_DMACNTRL, 0x11);
+
+ /* disable irqs */
+ cx_clear(MO_PCI_INTMSK, 0x000002);
+
+ cx_set(MO_AUD_INTMSK, 0);
+ return 0;
+}
+
+#define MAX_IRQ_LOOP 10
+
+static void cx8801_timeout(unsigned long data)
+{
+ snd_cx88_card_t *chip = (snd_cx88_card_t *)data;
+
+ dprintk(0, "cx88_alsa: %s\n",__FUNCTION__);
+
+ if (debug)
+ cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH26]);
+ cx88_stop_audio_dma(chip);
+#if 0
+ do_cancel_buffers(dev,"timeout",1);
+#endif
+}
+
+/* FIXME: Wrong values*/
+static char *cx88_aud_irqs[32] = {
+ "y_risci1", "u_risci1", "v_risci1", "vbi_risc1",
+ "y_risci2", "u_risci2", "v_risci2", "vbi_risc2",
+ "y_oflow", "u_oflow", "v_oflow", "vbi_oflow",
+ "y_sync", "u_sync", "v_sync", "vbi_sync",
+ "opc_err", "par_err", "rip_err", "pci_abort",
+};
+
+
+static void cx8801_aud_irq(snd_cx88_card_t *chip)
+{
+ struct cx88_core *core = chip->core;
+ u32 status, mask;
+#if 0
+ u32 count;
+#endif
+ status = cx_read(MO_AUD_INTSTAT);
+ mask = cx_read(MO_AUD_INTMSK);
+ if (0 == (status & mask))
+ return;
+ cx_write(MO_AUD_INTSTAT, status);
+ if (debug || (status & mask & ~0xff))
+ cx88_print_irqbits(core->name, "irq aud",
+ cx88_aud_irqs, status, mask);
+#if 0 /* FIXME */
+ /* risc op code error */
+ if (status & (1 << 16)) {
+ printk(KERN_WARNING "%s/0: video risc op code error\n",core->name);
+ cx_clear(MO_VID_DMACNTRL, 0x11);
+ cx_clear(VID_CAPTURE_CONTROL, 0x06);
+ cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH21]);
+ }
+
+ /* risc1 y */
+ if (status & 0x01) {
+ spin_lock(&dev->slock);
+ count = cx_read(MO_VIDY_GPCNT);
+ cx88_wakeup(dev->core, &dev->vidq, count);
+ spin_unlock(&dev->slock);
+ }
+
+ /* risc1 vbi */
+ if (status & 0x08) {
+ spin_lock(&dev->slock);
+ count = cx_read(MO_VBI_GPCNT);
+ cx88_wakeup(dev->core, &dev->vbiq, count);
+ spin_unlock(&dev->slock);
+ }
+
+ /* risc2 y */
+ if (status & 0x10) {
+ dprintk(2,"stopper video\n");
+ spin_lock(&dev->slock);
+ restart_video_queue(dev,&dev->vidq);
+ spin_unlock(&dev->slock);
+ }
+
+ /* risc2 vbi */
+ if (status & 0x80) {
+ dprintk(2,"stopper vbi\n");
+ spin_lock(&dev->slock);
+ cx8800_restart_vbi_queue(dev,&dev->vbiq);
+ spin_unlock(&dev->slock);
+ }
+#endif
+}
+
+static irqreturn_t cx8801_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+ snd_cx88_card_t *chip = dev_id;
+ struct cx88_core *core = chip->core;
+ u32 status;
+ int loop, handled = 0;
+
+ for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
+ status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x02);
+ if (0 == status)
+ goto out;
+ dprintk( 1, "cx8801_irq\n" );
+ dprintk( 1, " loop: %d/%d\n", loop, MAX_IRQ_LOOP );
+ dprintk( 1, " status: %d\n", status );
+ handled = 1;
+ cx_write(MO_PCI_INTSTAT, status);
+
+ if (status & core->pci_irqmask)
+ cx88_core_irq(core,status);
+ if (status & 0x02)
+ cx8801_aud_irq(chip);
+ };
+ if (MAX_IRQ_LOOP == loop) {
+ dprintk( 0, "clearing mask\n" );
+ dprintk(1,"%s/0: irq loop -- clearing mask\n",
+ core->name);
+ cx_write(MO_PCI_INTMSK,0);
+ }
+
+ out:
+ return IRQ_RETVAL(handled);
+}
+
/*
=====================> FIXME
*/
@@ -524,7 +695,6 @@ static int snd_cx88_dev_free(snd_device_t *device)
*/
static int devno=0;
-
static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,
snd_cx88_card_t **rchip)
{
@@ -548,6 +718,13 @@ static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,
}
memset(chip,0,sizeof(*chip));
+ if (!pci_dma_supported(pci,0xffffffff)) {
+ dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name);
+ err = -EIO;
+ kfree (chip);
+ return err;
+ }
+
/* pci init */
chip->card = card;
chip->pci = pci;
@@ -561,26 +738,42 @@ static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,
return err;
}
chip->core = core;
-#if 1
- chip->dig_rate=48000;
+#if 1 /* Should be tested if it is wright */
+ chip->dig_rate=32000;
#endif
+#if 1 /* From cx88-mpeg.c */
+
+ /* init dma queue */
+ INIT_LIST_HEAD(&chip->q.active);
+ INIT_LIST_HEAD(&chip->q.queued);
+ chip->q.timeout.function = cx8801_timeout;
+ chip->q.timeout.data = (unsigned long)chip;
+ init_timer(&chip->q.timeout);
+ cx88_risc_stopper(chip->pci,&chip->q.stopper,
+ MO_AUD_DMACNTRL, 0x11,0x00);
+
+ /* get irq */
+ err = request_irq(chip->pci->irq, cx8801_irq,
+ SA_SHIRQ | SA_INTERRUPT, chip->core->name, chip);
+ if (err < 0) {
+ dprintk(0, "%s: can't get IRQ %d\n",
+ chip->core->name, chip->pci->irq);
+ return err;
+ }
+ cx_set(MO_PCI_INTMSK, core->pci_irqmask);
+#endif
/* print pci info */
pci_read_config_byte(pci, PCI_CLASS_REVISION, &chip->pci_rev);
pci_read_config_byte(pci, PCI_LATENCY_TIMER, &chip->pci_lat);
- printk(KERN_INFO "ALSA %s/%i: found at %s, rev: %d, irq: %d, "
+ dprintk(1,"ALSA %s/%i: found at %s, rev: %d, irq: %d, "
"latency: %d, mmio: 0x%lx\n", core->name, devno,
pci_name(pci), chip->pci_rev, pci->irq,
chip->pci_lat,pci_resource_start(pci,0));
pci_set_master(pci);
- if (!pci_dma_supported(pci,0xffffffff)) {
- printk("%s/1: Oops: no 32bit PCI DMA ???\n",core->name);
- err = -EIO;
- kfree (chip);
- return err;
- }
+ synchronize_irq(chip->irq);
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0) {
@@ -634,7 +827,7 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
card->shortname, pci_resource_start(pci, 0));
strcpy (card->mixername, "CX88");
- printk ("%s/%i: Alsa support for cx2388x boards\n",
+ dprintk (0, "%s/%i: Alsa support for cx2388x boards\n",
card->driver,devno);
err = snd_card_register(card);