These functions are mainly the result of translations made
from the original disassembly of the au88x0 binary drivers,
written by Aureal before they went down.
- Many thanks to the Jeff Muizelar, Kester Maddock, and whoever
+ Many thanks to the Jeff Muizelaar, Kester Maddock, and whoever
contributed to the OpenVortex project.
The author of this file, put the few available pieces together
and translated the rest of the riddle (Mix, Src and connection stuff).
return delta;
}
+
+static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {
+ stream_t *dma = &vortex->dma_adb[adbdma];
+ int p, pp, i;
+
+ /* refresh hw page table */
+ for (i=0 ; i < 4 && i < dma->nr_periods; i++) {
+ /* p: audio buffer page index */
+ p = dma->period_virt + i;
+ if (p >= dma->nr_periods)
+ p -= dma->nr_periods;
+ /* pp: hardware DMA page index. */
+ pp = dma->period_real + i;
+ if (dma->nr_periods < 4) {
+ if (pp >= dma->nr_periods)
+ pp -= dma->nr_periods;
+ }
+ else {
+ if (pp >= 4)
+ pp -= 4;
+ }
+ hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), snd_sgbuf_get_addr(dma->sgbuf, dma->period_bytes * p));
+ /* Force write thru cache. */
+ hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2));
+ }
+}
+
static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma)
{
stream_t *dma = &vortex->dma_adb[adbdma];
|| ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2)))
return -EBUSY;
- spin_lock(&vortex->lock);
if (dma >= 0) {
en = 0;
vortex_adb_checkinout(vortex,
}
}
vortex->dma_adb[dma].nr_ch = nr_ch;
- spin_unlock(&vortex->lock);
#if 0
/* AC97 Codec channel setup. FIXME: this has no effect on some cards !! */
}
if (source & IRQ_PCMOUT) {
/* ALSA period acknowledge. */
+ spin_lock(&vortex->lock);
for (i = 0; i < NR_ADB; i++) {
if (vortex->dma_adb[i].fifo_status == FIFO_START) {
if (vortex_adbdma_bufshift(vortex, i)) ;
+ spin_unlock(&vortex->lock);
snd_pcm_period_elapsed(vortex->dma_adb[i].
substream);
+ spin_lock(&vortex->lock);
}
}
#ifndef CHIP_AU8810
for (i = 0; i < NR_WT; i++) {
if (vortex->dma_wt[i].fifo_status == FIFO_START) {
if (vortex_wtdma_bufshift(vortex, i)) ;
+ spin_unlock(&vortex->lock);
snd_pcm_period_elapsed(vortex->dma_wt[i].
substream);
+ spin_lock(&vortex->lock);
}
}
#endif
+ spin_unlock(&vortex->lock);
handled = 1;
}
//Acknowledge the Timer interrupt
for (i = 0; i < 32; i++) {
hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), 0);
- udelay(2000);
+ msleep(2);
}
if (0) {
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x8068);
- udelay(1000);
+ msleep(1);
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00e8);
- udelay(1000);
+ msleep(1);
} else {
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00a8);
- udelay(2000);
+ msleep(2);
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80a8);
- udelay(2000);
+ msleep(2);
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80e8);
- udelay(2000);
+ msleep(2);
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80a8);
- udelay(2000);
+ msleep(2);
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00a8);
- udelay(2000);
+ msleep(2);
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00e8);
}
for (i = 0; i < 32; i++) {
hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), 0);
- udelay(5000);
+ msleep(5);
}
hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0xe8);
- udelay(1000);
+ msleep(1);
/* Enable codec channels 0 and 1. */
hwwrite(vortex->mmio, VORTEX_CODEC_EN,
hwread(vortex->mmio, VORTEX_CODEC_EN) | EN_CODEC);
{
vortex_t *card = (vortex_t *) codec->private_data;
- unsigned long flags;
unsigned int lifeboat = 0;
- spin_lock_irqsave(&card->lock, flags);
/* wait for transactions to clear */
while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) {
udelay(100);
if (lifeboat++ > POLL_COUNT) {
printk(KERN_ERR "vortex: ac97 codec stuck busy\n");
- spin_unlock_irqrestore(&card->lock, flags);
return;
}
}
/* Flush Caches. */
hwread(card->mmio, VORTEX_CODEC_IO);
-
- spin_unlock_irqrestore(&card->lock, flags);
}
static unsigned short vortex_codec_read(ac97_t * codec, unsigned short addr)
vortex_t *card = (vortex_t *) codec->private_data;
u32 read_addr, data;
- unsigned long flags;
unsigned lifeboat = 0;
- spin_lock_irqsave(&card->lock, flags);
-
/* wait for transactions to clear */
while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) {
udelay(100);
if (lifeboat++ > POLL_COUNT) {
printk(KERN_ERR "vortex: ac97 codec stuck busy\n");
- spin_unlock_irqrestore(&card->lock, flags);
return 0xffff;
}
}
hwwrite(card->mmio, VORTEX_CODEC_IO, read_addr);
/* wait for address */
- {
+ do {
udelay(100);
data = hwread(card->mmio, VORTEX_CODEC_IO);
if (lifeboat++ > POLL_COUNT) {
printk(KERN_ERR "vortex: ac97 address never arrived\n");
- spin_unlock_irqrestore(&card->lock, flags);
return 0xffff;
}
- }
- while ((data & VORTEX_CODEC_ADDMASK) !=
- (addr << VORTEX_CODEC_ADDSHIFT)) ;
-
- /* Unlock. */
- spin_unlock_irqrestore(&card->lock, flags);
+ } while ((data & VORTEX_CODEC_ADDMASK) !=
+ (addr << VORTEX_CODEC_ADDSHIFT));
/* return data. */
return (u16) (data & VORTEX_CODEC_DATMASK);
printk(KERN_INFO "Vortex: init.... ");
/* Hardware Init. */
hwwrite(vortex->mmio, VORTEX_CTRL, 0xffffffff);
- udelay(5000);
+ msleep(5);
hwwrite(vortex->mmio, VORTEX_CTRL,
hwread(vortex->mmio, VORTEX_CTRL) & 0xffdfffff);
- udelay(5000);
+ msleep(5);
/* Reset IRQ flags */
hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffffffff);
hwread(vortex->mmio, VORTEX_IRQ_STAT);
hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, 0);
hwwrite(vortex->mmio, VORTEX_CTRL, 0);
- udelay(5000);
+ msleep(5);
hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffff);
printk(KERN_INFO "done.\n");