vserver 1.9.5.x5
[linux-2.6.git] / sound / pci / au88x0 / au88x0_pcm.c
index 6df634e..066e6c6 100644 (file)
@@ -28,7 +28,6 @@
 #include <sound/pcm_params.h>
 #include "au88x0.h"
 
-#define chip_t vortex_t
 #define VORTEX_PCM_TYPE(x) (x->name[40])
 
 /* hardware definition */
@@ -189,7 +188,7 @@ static int
 snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream,
                         snd_pcm_hw_params_t * hw_params)
 {
-       chip_t *chip = snd_pcm_substream_chip(substream);
+       vortex_t *chip = snd_pcm_substream_chip(substream);
        stream_t *stream = (stream_t *) (substream->runtime->private_data);
        snd_pcm_sgbuf_t *sgbuf;
        int err;
@@ -207,6 +206,7 @@ snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream,
           printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
           params_period_bytes(hw_params), params_channels(hw_params));
         */
+       spin_lock_irq(&chip->lock);
        // Make audio routes and config buffer DMA.
        if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
                int dma, type = VORTEX_PCM_TYPE(substream->pcm);
@@ -244,15 +244,17 @@ snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream,
                                        params_periods(hw_params));
        }
 #endif
+       spin_unlock_irq(&chip->lock);
        return 0;
 }
 
 /* hw_free callback */
 static int snd_vortex_pcm_hw_free(snd_pcm_substream_t * substream)
 {
-       chip_t *chip = snd_pcm_substream_chip(substream);
+       vortex_t *chip = snd_pcm_substream_chip(substream);
        stream_t *stream = (stream_t *) (substream->runtime->private_data);
 
+       spin_lock_irq(&chip->lock);
        // Delete audio routes.
        if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
                if (stream != NULL)
@@ -267,6 +269,7 @@ static int snd_vortex_pcm_hw_free(snd_pcm_substream_t * substream)
        }
 #endif
        substream->runtime->private_data = NULL;
+       spin_unlock_irq(&chip->lock);
 
        return snd_pcm_lib_free_pages(substream);
 }
@@ -285,6 +288,7 @@ static int snd_vortex_pcm_prepare(snd_pcm_substream_t * substream)
        else
                dir = 0;
        fmt = vortex_alsafmt_aspfmt(runtime->format);
+       spin_lock_irq(&chip->lock);
        if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
                vortex_adbdma_setmode(chip, dma, 1, dir, fmt, 0 /*? */ ,
                                      0);
@@ -299,23 +303,27 @@ static int snd_vortex_pcm_prepare(snd_pcm_substream_t * substream)
                vortex_wtdma_setstartbuffer(chip, dma, 0);
        }
 #endif
+       spin_unlock_irq(&chip->lock);
        return 0;
 }
 
 /* trigger callback */
 static int snd_vortex_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
 {
-       chip_t *chip = snd_pcm_substream_chip(substream);
+       vortex_t *chip = snd_pcm_substream_chip(substream);
        stream_t *stream = (stream_t *) substream->runtime->private_data;
        int dma = stream->dma;
 
+       spin_lock(&chip->lock);
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
                // do something to start the PCM engine
                //printk(KERN_INFO "vortex: start %d\n", dma);
                stream->fifo_enabled = 1;
-               if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
+               if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
+                       vortex_adbdma_resetup(chip, dma);
                        vortex_adbdma_startfifo(chip, dma);
+               }
 #ifndef CHIP_AU8810
                else {
                        printk(KERN_INFO "vortex: wt start %d\n", dma);
@@ -356,8 +364,10 @@ static int snd_vortex_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
 #endif
                break;
        default:
+               spin_unlock(&chip->lock);
                return -EINVAL;
        }
+       spin_unlock(&chip->lock);
        return 0;
 }