diff options
author | Mauro Carvalho Chehab <devnull@localhost> | 2005-08-15 01:49:35 +0000 |
---|---|---|
committer | Mauro Carvalho Chehab <devnull@localhost> | 2005-08-15 01:49:35 +0000 |
commit | d787c1bd04c659cf030dbdf82157417ac4e599cc (patch) | |
tree | 1bbc7587c1bc97c7e2051fe67b09b9211472968b /linux/drivers | |
parent | f298917ccd7cd74c18668b6a8f4b71b1bc518cd5 (diff) | |
download | mediapointer-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.c | 221 |
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); |