summaryrefslogtreecommitdiff
path: root/linux/drivers
diff options
context:
space:
mode:
authorRicardo Cerqueira <devnull@localhost>2006-01-03 13:39:32 +0000
committerRicardo Cerqueira <devnull@localhost>2006-01-03 13:39:32 +0000
commit3381470ddd2164da2e33c1319a55f2deaac33baa (patch)
tree75472aaec8ae2a93f109474d98bdacbcd9b9adb3 /linux/drivers
parent7330a69cebde835c35bcede119a03dc8f1982e33 (diff)
downloadmediapointer-dvb-s2-3381470ddd2164da2e33c1319a55f2deaac33baa.tar.gz
mediapointer-dvb-s2-3381470ddd2164da2e33c1319a55f2deaac33baa.tar.bz2
cx88-alsa, now with working sound goodness
From: Ricardo Cerqueira <v4l@cerqueira.org> It's still not perfect (lots of over and underruns), but there's now working audio. Dropped the videobuf queues (too geared for video...) in favor of a single RISC databuffer, and changed the remaining code accordingly. And it works ;) Signed-off-by:
Diffstat (limited to 'linux/drivers')
-rw-r--r--linux/drivers/media/video/cx88/cx88-alsa.c557
1 files changed, 155 insertions, 402 deletions
diff --git a/linux/drivers/media/video/cx88/cx88-alsa.c b/linux/drivers/media/video/cx88/cx88-alsa.c
index 9040fcc92..5d23b7347 100644
--- a/linux/drivers/media/video/cx88/cx88-alsa.c
+++ b/linux/drivers/media/video/cx88/cx88-alsa.c
@@ -1,9 +1,10 @@
/*
- * $Id: cx88-alsa.c,v 1.21 2005/12/30 15:57:25 rmcc Exp $
+ * $Id: cx88-alsa.c,v 1.22 2006/01/03 13:39:32 rmcc Exp $
*
* Support for audio capture
* PCI function #1 of the cx2388x.
*
+ * (c) 2006 Ricardo Cerqueira <v4l@cerqueira.org>
* (c) 2005 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
* Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org>
* Based on bt87x.c by Clemens Ladisch <clemens@ladisch.de>
@@ -91,13 +92,19 @@ struct cx88_audio_dev {
unsigned int dma_size;
unsigned int period_size;
+ unsigned int num_periods;
+ unsigned int current_period;
+
struct videobuf_dmabuf dma_risc;
+ struct snd_dma_buffer alsa_risc;
int mixer_volume[MIXER_ADDR_LAST+1][2];
int capture_source[MIXER_ADDR_LAST+1][2];
long int bufsize;
+ long int read_count;
long int read_offset;
+ struct cx88_buffer *buf;
u32 __iomem *mmio;
long opened;
@@ -146,6 +153,7 @@ MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled.");
****************************************************************************/
MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards");
+MODULE_AUTHOR("Ricardo Cerqueira");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@brturbo.com.br>");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Conexant,23881},"
@@ -163,24 +171,28 @@ MODULE_PARM_DESC(debug,"enable debug messages");
* BOARD Specific: Sets audio DMA
*/
-int _cx88_start_audio_dma(snd_cx88_card_t *chip,
- struct cx88_dmaqueue *q,
- struct cx88_buffer *buf)
+int _cx88_start_audio_dma(snd_cx88_card_t *chip)
{
+ struct cx88_buffer *buf = chip->buf;
struct cx88_core *core=chip->core;
+ struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25];
+
- dprintk(1, "Starting audio DMA\n");
+ dprintk(1, "Starting audio DMA for %i bpl and %i (%i) lines at ptr2 %08x\n",buf->bpl, chip->num_periods, audio_ch->fifo_size / buf->bpl, audio_ch->fifo_start);
+ //dprintk(1, "Starting audio DMA at RISC %08lx for %i bpl\n",(unsigned long)buf->risc.dma,buf->bpl);
/* setup fifo + format - out channel */
+ //cx88_sram_channel_setup(chip->core, audio_ch, buf->bpl, 0);
+
+ //snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), audio_ch->fifo_size, &chip->alsa_risc);
cx88_sram_channel_setup(chip->core, &cx88_sram_channels[SRAM_CH25],
buf->bpl, buf->risc.dma);
/* sets bpl size */
cx_write(MO_AUDD_LNGTH, buf->bpl);
- cx_write(MO_AUDR_LNGTH, buf->bpl);
/* reset counter */
- cx_write(MO_AUDD_GPCNTRL,GP_COUNT_CONTROL_RESET);
+ //cx_write(MO_AUDD_GPCNTRL,GP_COUNT_CONTROL_RESET);
dprintk(1,"Enabling IRQ, setting mask from 0x%x to 0x%x\n",chip->core->pci_irqmask,(chip->core->pci_irqmask | 0x02));
/* enable irqs */
@@ -204,12 +216,16 @@ int _cx88_start_audio_dma(snd_cx88_card_t *chip,
);
#endif
+ //dprintk(2, "Is queue reading? A: %x\n",chip->fh->vb_q.reading);
+
/* start dma */
cx_set(MO_DEV_CNTRL2, (1<<5)); /* Enables Risc Processor */
cx_set(MO_AUD_DMACNTRL, 0x11); /* audio downstream FIFO and RISC enable */
+ chip->current_period = 0;
- q->count = 1;
+ if (debug)
+ cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH25]);
return 0;
}
@@ -227,28 +243,15 @@ int _cx88_stop_audio_dma(snd_cx88_card_t *chip)
/* disable irqs */
cx_clear(MO_PCI_INTMSK, 0x000002);
cx_set(MO_AUD_INTMSK, 0);
- return 0;
-}
-
-#define MAX_IRQ_LOOP 10
-
-/*
- * BOARD Specific: Threats timeouts
- */
-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_CH25]);
- _cx88_stop_audio_dma(chip);
-#if 0
- do_cancel_buffers(dev,"timeout",1);
-#endif
+
+ return 0;
}
+#define MAX_IRQ_LOOP 10
+
/*
* BOARD Specific: IRQ dma bits
*/
@@ -276,30 +279,43 @@ static void cx8801_aud_irq(snd_cx88_card_t *chip)
status = cx_read(MO_AUD_INTSTAT);
mask = cx_read(MO_AUD_INTMSK);
- if (0 == (status & mask))
+ if (0 == (status & mask)) {
+ spin_unlock(&chip->reg_lock);
return;
+ }
cx_write(MO_AUD_INTSTAT, status);
if (debug || (status & mask & ~0xff))
cx88_print_irqbits(core->name, "irq aud",
cx88_aud_irqs, status, mask);
/* risc op code error */
if (status & (1 << 16)) {
- printk(KERN_WARNING "%s/0: video risc op code error\n",core->name);
+ printk(KERN_WARNING "%s/0: audio risc op code error\n",core->name);
cx_clear(MO_AUD_DMACNTRL, 0x11);
-#if 0 /* FIXME: anything else? */
- cx_clear(VID_CAPTURE_CONTROL, 0x06);
-#endif
cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH25]);
}
/* risc1 downstream */
if (status & 0x01) {
+ printk("AUDIO DATA!\n");
spin_lock(&chip->reg_lock);
count = cx_read(MO_AUDD_GPCNT);
- cx88_wakeup(core, &chip->q, count);
+// cx88_wakeup(core, &chip->q, count);
spin_unlock(&chip->reg_lock);
+ chip->read_count += chip->dma_size;
+ chip->current_period = (chip->current_period + 1) % chip->num_periods;
+ snd_pcm_period_elapsed(chip->substream);
}
+ printk("Still kicking...\n");
+ if (chip->read_count >= chip->period_size) {
+ printk("Elapsing?\n");
+ spin_lock(&chip->reg_lock);
+ //snd_pcm_period_elapsed(chip->substream);
+ spin_unlock(&chip->reg_lock);
+ }
+
+ printk("Leaving audio IRQ handler...\n");
+
/* FIXME: Any other status should deserve a special handling? */
}
@@ -317,22 +333,17 @@ static irqreturn_t cx8801_irq(int irq, void *dev_id, struct pt_regs *regs)
status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x02);
if (0 == status)
goto out;
- dprintk( 3, "cx8801_irq\n" );
- dprintk( 3, " loop: %d/%d\n", loop, MAX_IRQ_LOOP );
- dprintk( 3, " status: %d\n", status );
+ //dprintk( 3, "cx8801_irq\n" );
+ //dprintk( 3, " loop: %d/%d\n", loop, MAX_IRQ_LOOP );
+ //dprintk( 3, " status: %d\n", status );
handled = 1;
cx_write(MO_PCI_INTSTAT, status);
- if (status & core->pci_irqmask)
- {
- dprintk( 3, " passing to core\n" );
- cx88_core_irq(core,status);
- }
if (status & 0x02)
- {
+ {
dprintk( 1, " ALSA IRQ handling\n" );
cx8801_aud_irq(chip);
- }
+ }
};
if (MAX_IRQ_LOOP == loop) {
@@ -346,233 +357,12 @@ static irqreturn_t cx8801_irq(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_RETVAL(handled);
}
-/*
- =====================> FIXME
- */
-
-#if 0
-static void snd_cx88_pci_error(bt87x_t *chip, unsigned int status)
-{
- u16 pci_status;
-
- pci_read_config_word(chip->pci, PCI_STATUS, &pci_status);
- pci_status &= PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT |
- PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT |
- PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY;
- pci_write_config_word(chip->pci, PCI_STATUS, pci_status);
- if (pci_status != PCI_STATUS_DETECTED_PARITY)
- snd_printk(KERN_ERR "Aieee - PCI error! status %#08x, PCI status %#04x\n",
- status & ERROR_INTERRUPTS, pci_status);
- else {
- snd_printk(KERN_ERR "Aieee - PCI parity error detected!\n");
- /* error 'handling' similar to aic7xxx_pci.c: */
- chip->pci_parity_errors++;
- if (chip->pci_parity_errors > 20) {
- snd_printk(KERN_ERR "Too many PCI parity errors observed.\n");
- snd_printk(KERN_ERR "Some device on this bus is generating bad parity.\n");
- snd_printk(KERN_ERR "This is an error *observed by*, not *generated by*, this card.\n");
- snd_printk(KERN_ERR "PCI parity error checking has been disabled.\n");
- chip->interrupt_mask &= ~(INT_PPERR | INT_RIPERR);
- snd_bt87x_writel(chip, REG_INT_MASK, chip->interrupt_mask);
- }
- }
-}
-#endif
-
-/****************************************************************************
- Videobuf setup code
- ****************************************************************************/
-
-static int
-buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
-{
- struct cx8801_fh *fh = q->priv_data;
- struct cx88_audio_dev *chip = fh->dev;
-
- *size = fh->size;
- if (0 == *count)
- *count = 32;
-
- if (*count < 2)
- *count = 2;
- if (*count > 32)
- *count = 32;
-
- dprintk(2,"Count=%d, size=%d\n" ,*count,*size);
- return 0;
-}
-
-static int
-buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
- enum v4l2_field field)
-{
- struct cx8801_fh *fh = q->priv_data;
- struct cx88_audio_dev *chip = fh->dev;
- struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
- int rc;
- unsigned int size=fh->size;
-
- if (0 != buf->vb.baddr && buf->vb.bsize < size)
- return -EINVAL;
-
- if (STATE_NEEDS_INIT == buf->vb.state) {
- buf->vb.width = size;
- buf->vb.height = 1;
- buf->vb.size = size;
- buf->vb.field = V4L2_FIELD_SEQ_TB;
-
- if (0 != (rc = videobuf_iolock(chip->pci,&buf->vb,NULL)))
- goto fail;
- cx88_risc_buffer(chip->pci, &buf->risc,
- buf->vb.dma.sglist,
- 0, buf->vb.width * buf->vb.height,
- buf->vb.width, 0,
- buf->vb.height);
- }
- buf->vb.state = STATE_PREPARED;
-
- dprintk_core(2,"[%p/%d] buffer_prepare - size: %d - dma=0x%08lx\n",
- buf, buf->vb.i,
- fh->size,
- (unsigned long)buf->risc.dma);
-
- chip->dma_risc = buf->vb.dma;
- return 0;
-
- fail:
- cx88_free_buffer(chip->pci,buf);
- return rc;
-}
-
-static void
-buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
- struct cx88_buffer *prev;
- struct cx8801_fh *fh = vq->priv_data;
- struct cx88_audio_dev *chip = fh->dev;
- struct cx88_dmaqueue *q = &chip->q;
-
-
- dprintk(2,"Buffer queue\n");
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
- if (!buf->bpl && chip->period_size)
- buf->bpl = chip->period_size;
-
-
- if (!list_empty(&q->queued)) {
- list_add_tail(&buf->vb.queue,&q->queued);
- buf->vb.state = STATE_QUEUED;
- dprintk(2,"[%p/%d] buffer_queue - append to queued\n",
- buf, buf->vb.i);
-
- } else if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue,&q->active);
- _cx88_start_audio_dma(chip, q, buf);
- printk("DEBUG TEMP: buf bpl is %d\n",buf->bpl);
- buf->vb.state = STATE_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- dprintk(2,"[%p/%d] buffer_queue - first active\n",
- buf, buf->vb.i);
-
- } else {
- prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
- if (prev->vb.width == buf->vb.width &&
- prev->vb.height == buf->vb.height &&
- prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue,&q->active);
- buf->vb.state = STATE_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- dprintk(2,"[%p/%d] buffer_queue - append to active\n",
- buf, buf->vb.i);
-
- } else {
- list_add_tail(&buf->vb.queue,&q->queued);
- buf->vb.state = STATE_QUEUED;
- dprintk(2,"[%p/%d] buffer_queue - first queued\n",
- buf, buf->vb.i);
- }
- }
-}
-
-static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
-{
- struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
- struct cx8801_fh *fh = q->priv_data;
-
- cx88_free_buffer(fh->dev->pci,buf);
-}
-
-static struct videobuf_queue_ops audio_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
-};
-
-static int dsp_buffer_init(snd_cx88_card_t *chip)
-{
- int err = 0;
- struct cx8801_fh *fh;
- struct v4l2_requestbuffers req;
- int deb;
-
- BUG_ON(!chip->dma_size);
-
- /* allocate + initialize per filehandle data */
- fh = kmalloc(sizeof(*fh),GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
- memset(fh,0,sizeof(*fh));
- fh->dev = chip;
- fh->size = chip->dma_size;
-
- dprintk(1,"queue init\n");
- videobuf_queue_init(&fh->vb_q, &audio_qops,
- chip->pci, &chip->reg_lock,
- V4L2_BUF_TYPE_PRIVATE,
- V4L2_FIELD_NONE,
- sizeof(struct cx88_buffer),
- fh);
-
- chip->fh=fh;
- dprintk(1,"queue read start (coming from %d)\n",err);
- deb = videobuf_read_start(&fh->vb_q);
- dprintk(1,"dma init (coming from %d)\n",deb);
- videobuf_dma_init(&chip->dma_risc);
- dprintk(1,"dma init kernel\n");
- err = videobuf_dma_init_kernel(&chip->dma_risc, PCI_DMA_FROMDEVICE,
- (chip->dma_size + PAGE_SIZE) >> PAGE_SHIFT);
- if (0 != err)
- return err;
-
- memset(&req,0,sizeof(req));
- req.type = fh->vb_q.type;
- req.count = 2;
- req.memory = V4L2_MEMORY_MMAP;
-
- //dprintk(1,"request bufers\n");
-// videobuf_reqbufs(&fh->vb_q, &req);
-
-// dprintk(1,"prepare bufers\n");
-// videobuf_qbuf(&fh->vb_q, &req);
-
-// dprintk(1,"start stream\n");
-// err=videobuf_streamon(&fh->vb_q);
-
- return 0;
-}
static int dsp_buffer_free(snd_cx88_card_t *chip)
{
BUG_ON(!chip->dma_size);
- videobuf_dma_free(&chip->dma_risc);
+// videobuf_dma_free(&chip->dma_risc);
chip->dma_size = 0;
@@ -593,16 +383,16 @@ static snd_pcm_hardware_t snd_cx88_digital_hw = {
SNDRV_PCM_INFO_MMAP_VALID,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
+ .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000,
+ .rate_min = 32000,
+ .rate_max = 96000,
+ .channels_min = 1,
.channels_max = 2,
- .buffer_bytes_max = (1024*256),
- .period_bytes_min = 64,
- .period_bytes_max = 256,
- .periods_min = 2,
- .periods_max = 1024,
+ .buffer_bytes_max = (4*128),
+ .period_bytes_min = 128,
+ .period_bytes_max = 128,
+ .periods_min = 4,
+ .periods_max = 4,
};
/*
@@ -634,6 +424,9 @@ static int snd_cx88_pcm_open(snd_pcm_substream_t *substream)
chip->substream = substream;
+ chip->read_count = 0;
+ chip->read_offset = 0;
+
pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
if (pcm == NULL) {
err=-ENOMEM;
@@ -663,9 +456,11 @@ static int snd_cx88_close(snd_pcm_substream_t *substream)
{
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
- chip->substream = NULL;
+
+ dprintk(2,"PCM close\n");
clear_bit(0, &chip->opened);
smp_mb__after_clear_bit();
+ dprintk(2,"Returning from PCM close\n");
return 0;
}
@@ -675,36 +470,72 @@ static int snd_cx88_close(snd_pcm_substream_t *substream)
static int snd_cx88_hw_params(snd_pcm_substream_t * substream,
snd_pcm_hw_params_t * hw_params)
{
- int err;
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
+ struct cx88_buffer *buf;
printk("ALSA HW_params\n");
+
if (substream->runtime->dma_area) {
- videobuf_queue_cancel(&chip->fh->vb_q);
- videobuf_dma_pci_unmap(chip->pci, &chip->dma_risc);
- dsp_buffer_free(chip);
+ //videobuf_read_stop(&chip->fh->vb_q);
+ //videobuf_dma_pci_unmap(chip->pci, &chip->dma_risc);
+ //dsp_buffer_free(chip);
substream->runtime->dma_area = NULL;
}
chip->period_size = params_period_bytes(hw_params);
+ chip->num_periods = params_periods(hw_params);
chip->dma_size = chip->period_size * params_periods(hw_params);
+ BUG_ON(!chip->dma_size);
+
dprintk(1,"Setting buffer\n");
- dsp_buffer_init(chip);
+ //dsp_buffer_init(chip);
- if (0 != (err = videobuf_dma_pci_map(chip->pci, &chip->dma_risc))) {
- dsp_buffer_free(chip);
- return err;
- }
+ buf = kmalloc(sizeof(*buf),GFP_KERNEL);
+ if (NULL == buf)
+ return -ENOMEM;
+ memset(buf,0,sizeof(*buf));
+
+
+ buf->vb.memory = V4L2_MEMORY_MMAP;
+ buf->vb.width = chip->period_size;
+ buf->vb.height = chip->num_periods;
+ buf->vb.size = chip->dma_size;
+ buf->vb.field = V4L2_FIELD_NONE;
+
+ videobuf_dma_init(&buf->vb.dma);
+ videobuf_dma_init_kernel(&buf->vb.dma,PCI_DMA_FROMDEVICE,
+ (PAGE_ALIGN(buf->vb.size) >> PAGE_SHIFT));
+
+ videobuf_dma_pci_map(chip->pci,&buf->vb.dma);
- dprintk(1,"Buffer ready at 0x%x\n",(int )chip->dma_risc.vmalloc);
+ cx88_risc_databuffer(chip->pci, &buf->risc,
+ buf->vb.dma.sglist,
+ buf->vb.width, buf->vb.height);
+#if 0
+ cx88_risc_buffer(chip->pci, &buf->risc,
+ buf->vb.dma.sglist,
+ 0, buf->vb.width * buf->vb.height,
+ buf->vb.width, 0,
+ buf->vb.height);
+#endif
+
+ buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+ buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+
+ buf->vb.state = STATE_PREPARED;
+
+ buf->bpl = chip->period_size;
+ chip->buf = buf;
+ chip->dma_risc = buf->vb.dma;
+
+ dprintk(1,"Buffer ready at %u\n",chip->dma_risc.nr_pages);
substream->runtime->dma_area = chip->dma_risc.vmalloc;
- //return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
return 0;
}
@@ -716,13 +547,18 @@ static int snd_cx88_hw_free(snd_pcm_substream_t * substream)
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
- if (substream->runtime->dma_area) {
- videobuf_queue_cancel(&chip->fh->vb_q);
+ dprintk(2,"HW free\n");
+ if (substream->runtime->dma_area) {
+ dprintk(2,"Freeing buffer\n");
videobuf_dma_pci_unmap(chip->pci, &chip->dma_risc);
+ videobuf_dma_free(&chip->dma_risc);
+ btcx_riscmem_free(chip->pci,&chip->buf->risc);
+ kfree(chip->buf);
dsp_buffer_free(chip);
substream->runtime->dma_area = NULL;
}
- //return snd_pcm_lib_free_pages(substream);
+ dprintk(2,"Returning from HW free\n");
+ return 0;
}
/*
@@ -730,8 +566,7 @@ static int snd_cx88_hw_free(snd_pcm_substream_t * substream)
*/
static int snd_cx88_prepare(snd_pcm_substream_t *substream)
{
- snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
- struct cx88_core *core=chip->core;
+ //snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
printk("ALSA Prepare\n");
//spin_lock_irq(&chip->reg_lock);
@@ -749,7 +584,7 @@ static int snd_cx88_prepare(snd_pcm_substream_t *substream)
static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd)
{
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
- struct cx8801_fh *fh = chip->fh;
+ //struct cx8801_fh *fh = chip->fh;
int err;
dprintk(2,"PCM Trigger cmd=%d\n",cmd);
@@ -757,12 +592,14 @@ static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd)
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
+ dprintk(1,"start stream\n");
//err=videobuf_streamon(&fh->vb_q);
- //err=_cx88_start_audio_dma(chip);
+ err=_cx88_start_audio_dma(chip);
break;
case SNDRV_PCM_TRIGGER_STOP:
- // err=videobuf_streamoff(&fh->vb_q);
- //err=_cx88_stop_audio_dma(chip);
+ dprintk(1,"stop stream\n");
+ //err=videobuf_streamoff(&fh->vb_q);
+ err=_cx88_stop_audio_dma(chip);
break;
default:
err=-EINVAL;
@@ -771,7 +608,7 @@ static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd)
spin_unlock(&chip->reg_lock);
- return 0;
+ dprintk(2,"Leaving PCM Trigger\n");
return err;
}
@@ -782,8 +619,19 @@ static snd_pcm_uframes_t snd_cx88_pointer(snd_pcm_substream_t *substream)
{
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
+ //struct cx88_core *core = chip->core;
+
+ if (chip->read_count) {
+ chip->read_count -= snd_pcm_lib_period_bytes(substream);
+ chip->read_offset += snd_pcm_lib_period_bytes(substream);
+ if (chip->read_offset == chip->dma_size)
+ chip->read_offset = 0;
+ }
+ printk("Pointer time, will return %li, read %li\n",chip->read_offset,chip->read_count);
+ return bytes_to_frames(runtime, chip->read_offset);
-// return (snd_pcm_uframes_t)bytes_to_frames(runtime, chip->current_line * chip->line_bytes);
+// printk("Pointer time, will return %li\n",chip->current_period * chip->period_size);
+// return (snd_pcm_uframes_t)bytes_to_frames(runtime, chip->current_period * chip->period_size);
}
/*
@@ -798,7 +646,7 @@ static snd_pcm_ops_t snd_cx88_pcm_ops = {
.prepare = snd_cx88_prepare,
.trigger = snd_cx88_card_trigger,
.pointer = snd_cx88_pointer,
- .page = snd_pcm_sgbuf_ops_page,
+ //.page = snd_pcm_sgbuf_ops_page,
};
/*
@@ -815,11 +663,8 @@ static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name)
pcm->private_data = chip;
strcpy(pcm->name, name);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx88_pcm_ops);
- return snd_pcm_lib_preallocate_pages_for_all(pcm,
- SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci),
- 128 * 1024,
- (255 * 4092 + 1023) & ~1023);
+
+ return 0;
}
/****************************************************************************
@@ -871,58 +716,6 @@ static snd_kcontrol_new_t snd_cx88_capture_volume = {
.put = snd_cx88_capture_volume_put,
};
-/*
- ***************************************
- */
-#if 0
-static int snd_cx88_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
-{
- static char *texts[3] = {"TV Tuner", "FM", "Mic/Line"};
-
- info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- info->count = 1;
- info->value.enumerated.items = 3;
- if (info->value.enumerated.item > 2)
- info->value.enumerated.item = 2;
- strcpy(info->value.enumerated.name, texts[info->value.enumerated.item]);
- return 0;
-}
-
-static int snd_cx88_capture_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
-{
- snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
-/*#if 0*/
- value->value.enumerated.item[0] = (chip->reg_control & CTL_A_SEL_MASK) >> CTL_A_SEL_SHIFT;
-/*#endif*/
- return 0;
-}
-
-static int snd_cx88_capture_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
-{
- snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
- u32 old_control;
- int changed;
-/*#if 0*/
- spin_lock_irq(&chip->reg_lock);
- old_control = chip->reg_control;
- chip->reg_control = (chip->reg_control & ~CTL_A_SEL_MASK)
- | (value->value.enumerated.item[0] << CTL_A_SEL_SHIFT);
- snd_cx88_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
- changed = chip->reg_control != old_control;
- spin_unlock_irq(&chip->reg_lock);
-/*#endif*/
- return changed;
-}
-
-static snd_kcontrol_new_t snd_cx88_capture_source = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = snd_cx88_capture_source_info,
- .get = snd_cx88_capture_source_get,
- .put = snd_cx88_capture_source_put,
-};
-
-#endif
/****************************************************************************
Basic Flow for Sound Devices
@@ -947,28 +740,15 @@ MODULE_DEVICE_TABLE(pci, cx88_audio_pci_tbl);
static int snd_cx88_free(snd_cx88_card_t *chip)
{
dprintk(1,"cx88 free\n");
-#if 0
- if (chip->mmio) {
- snd_bt87x_stop(chip);
- if (chip->irq >= 0)
- synchronize_irq(chip->irq);
-
- iounmap(chip->mmio);
- }
-#endif
if (chip->irq >= 0){
synchronize_irq(chip->irq);
free_irq(chip->irq, chip);
}
- /* free memory */
-
- //pci_release_regions(chip->pci);
-
-// btcx_riscmem_free(chip->pci,&chip->q.stopper);
+ //btcx_riscmem_free(chip->pci,&chip->q.stopper);
cx88_core_put(chip->core,chip->pci);
- //kfree(chip);
+
pci_disable_device(chip->pci);
return 0;
}
@@ -976,12 +756,12 @@ static int snd_cx88_free(snd_cx88_card_t *chip)
/*
* Component Destructor
*/
-static int snd_cx88_dev_free(snd_card_t * card)
+static void snd_cx88_dev_free(snd_card_t * card)
{
snd_cx88_card_t *chip = card->private_data;
dprintk(1,"cx88 dev free\n");
- return snd_cx88_free(chip);
+ snd_cx88_free(chip);
}
@@ -1019,27 +799,8 @@ static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,
chip->irq = -1;
spin_lock_init(&chip->reg_lock);
-#if 0
- if (!request_mem_region(pci_resource_start(pci,0),
- pci_resource_len(pci,0),
- "CX88 audio")) {
- err = -EBUSY;
- printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n",
- "CX88 audio",pci_resource_start(pci,0));
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
- chip->mmio = ioremap_nocache(pci_resource_start(pci, 0),
- pci_resource_len(pci, 0));
- if (!chip->mmio) {
- kfree(chip);
- snd_printk(KERN_ERR "cannot remap io memory\n");
- return -ENOMEM;
- }
-#endif
-
core = cx88_core_get(chip->pci);
+ cx88_reset(core);
if (NULL == core) {
err = -EINVAL;
kfree (chip);
@@ -1054,15 +815,6 @@ static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,
#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);
@@ -1158,7 +910,7 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
static void __devexit cx88_audio_finidev(struct pci_dev *pci)
{
struct cx88_audio_dev *card = pci_get_drvdata(pci);
- struct cx88_core *core = card->core;
+ //struct cx88_core *core = card->core;
//_cx88_stop_audio_dma(card);
@@ -1223,9 +975,10 @@ static int cx88_audio_init(void)
*/
static void cx88_audio_fini(void)
{
- int idx;
-/* printk(KERN_INFO "cx88 fini\n");
+/*
+ int idx;
+ printk(KERN_INFO "cx88 fini\n");
for (idx = 0; idx < SNDRV_CARDS; idx++) {
snd_card_free(snd_cx88_cards[idx]);
snd_cx88_cards[idx] = NULL;