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).
static void vortex_mixer_init(vortex_t * vortex)
{
- unsigned long addr;
+ u32 addr;
int x;
// FIXME: get rid of this crap.
static void vortex_srcblock_init(vortex_t * vortex)
{
- unsigned long addr;
+ u32 addr;
int x;
hwwrite(vortex->mmio, VORTEX_SRC_SOURCESIZE, 0x1ff);
/*
static void vortex_fifo_init(vortex_t * vortex)
{
int x;
- unsigned long addr;
+ u32 addr;
/* ADB DMA channels fifos. */
addr = VORTEX_FIFO_ADBCTRL + ((NR_ADB - 1) * 4);
hwwrite(vortex->mmio, addr, FIFO_U0);
if (hwread(vortex->mmio, addr) != FIFO_U0)
printk(KERN_ERR
- "bad wt fifo reset (0x%08lx, 0x%08x)!\n",
+ "bad wt fifo reset (0x%08x, 0x%08x)!\n",
addr, hwread(vortex->mmio, addr));
vortex_fifo_clearwtdata(vortex, x, FIFO_SIZE);
addr -= 4;
static void
vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
- snd_pcm_sgbuf_t * sgbuf, int psize, int count)
+ struct snd_sg_buf * sgbuf, int psize, int count)
{
stream_t *dma = &vortex->dma_adb[adbdma];
static void
vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, int dir,
- int fmt, int d, unsigned long offset)
+ int fmt, int d, u32 offset)
{
stream_t *dma = &vortex->dma_adb[adbdma];
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];
static void
vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
- snd_pcm_sgbuf_t * sgbuf, int psize, int count)
+ struct snd_sg_buf * sgbuf, int psize, int count)
{
stream_t *dma = &vortex->dma_wt[wtdma];
static void
vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d,
- /*int e, */ unsigned long offset)
+ /*int e, */ u32 offset)
{
stream_t *dma = &vortex->dma_wt[wtdma];
}
}
}
- printk("vortex: FATAL: ResManager: resource type %d exhausted.\n", restype);
+ printk(KERN_ERR "vortex: FATAL: ResManager: resource type %d exhausted.\n", restype);
return -ENOMEM;
}
|| ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2)))
return -EBUSY;
- spin_lock(&vortex->lock);
if (dma >= 0) {
en = 0;
vortex_adb_checkinout(vortex,
memset(stream->resources, 0,
sizeof(unsigned char) *
VORTEX_RESOURCE_LAST);
- printk("vortex: out of A3D sources. Sorry\n");
+ printk(KERN_ERR "vortex: out of A3D sources. Sorry\n");
return -EBUSY;
}
/* (De)Initialize A3D hardware source. */
}
}
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 !! */
hwread(card->mmio, VORTEX_CTRL) & ~CTRL_IRQ_ENABLE);
}
-static irqreturn_t vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t vortex_interrupt(int irq, void *dev_id)
{
- vortex_t *vortex = snd_magic_cast(vortex_t, dev_id, return IRQ_NONE);
+ vortex_t *vortex = dev_id;
int i, handled;
u32 source;
}
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
}
if (source & IRQ_MIDI) {
snd_mpu401_uart_interrupt(vortex->irq,
- vortex->rmidi->private_data, regs);
+ vortex->rmidi->private_data);
handled = 1;
}
int i;
for (i = 0; i < 32; i++) {
- hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), 0);
- udelay(2000);
+ /* the windows driver writes -i, so we write -i */
+ hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), -i);
+ 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);
+ hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), -i);
+ 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);
}
static void
-vortex_codec_write(ac97_t * codec, unsigned short addr, unsigned short data)
+vortex_codec_write(struct snd_ac97 * codec, unsigned short addr, unsigned short data)
{
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;
}
}
hwwrite(card->mmio, VORTEX_CODEC_IO,
((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
((data << VORTEX_CODEC_DATSHIFT) & VORTEX_CODEC_DATMASK) |
- VORTEX_CODEC_WRITE);
+ VORTEX_CODEC_WRITE |
+ (codec->num << VORTEX_CODEC_ID_SHIFT) );
/* 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)
+static unsigned short vortex_codec_read(struct snd_ac97 * 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;
}
}
/* set up read address */
- read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK);
+ read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
+ (codec->num << VORTEX_CODEC_ID_SHIFT) ;
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);
/* Initialization */
-static int vortex_core_init(vortex_t * vortex)
+static int __devinit vortex_core_init(vortex_t * vortex)
{
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);
#ifndef CHIP_AU8820
vortex_eq_init(vortex);
vortex_spdif_init(vortex, 48000, 1);
- vortex_Vort3D(vortex, 1);
+ vortex_Vort3D_enable(vortex);
#endif
#ifndef CHIP_AU8810
vortex_wt_init(vortex);
printk(KERN_INFO "Vortex: shutdown...");
#ifndef CHIP_AU8820
vortex_eq_free(vortex);
- vortex_Vort3D(vortex, 0);
+ vortex_Vort3D_disable(vortex);
#endif
//vortex_disable_timer_int(vortex);
vortex_disable_int(vortex);
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");