vserver 1.9.5.x5
[linux-2.6.git] / sound / drivers / vx / vx_pcm.c
index 9ee1c80..9858717 100644 (file)
 #include <sound/driver.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/delay.h>
 #include <sound/core.h>
 #include <sound/asoundef.h>
 #include <sound/pcm.h>
 #include <sound/vx_core.h>
 #include "vx_cmd.h"
 
-#define chip_t vx_core_t
-
 
 /*
  * we use a vmalloc'ed (sg-)buffer
@@ -381,7 +380,7 @@ static int vx_send_irqa(vx_core_t *chip)
  */
 static int vx_toggle_pipe(vx_core_t *chip, vx_pipe_t *pipe, int state)
 {
-       int err, i, cur_state, delay;
+       int err, i, cur_state;
 
        /* Check the pipe is not already in the requested state */
        if (vx_get_pipe_state(chip, pipe, &cur_state) < 0)
@@ -394,17 +393,14 @@ static int vx_toggle_pipe(vx_core_t *chip, vx_pipe_t *pipe, int state)
         * enough sound buffer for this pipe)
         */
        if (state) {
-               int delay = CAN_START_DELAY;
                for (i = 0 ; i < MAX_WAIT_FOR_DSP; i++) {
-                       snd_vx_delay(chip, delay);
                        err = vx_pipe_can_start(chip, pipe);
                        if (err > 0)
                                break;
                        /* Wait for a few, before asking again
                         * to avoid flooding the DSP with our requests
                         */
-                       if ((i % 4 ) == 0)
-                               delay <<= 1;
+                       mdelay(1);
                }
        }
     
@@ -418,15 +414,12 @@ static int vx_toggle_pipe(vx_core_t *chip, vx_pipe_t *pipe, int state)
         * reaching the expected state before returning
         * Check one pipe only (since they are synchronous)
         */
-       delay = WAIT_STATE_DELAY;
        for (i = 0; i < MAX_WAIT_FOR_DSP; i++) {
-               snd_vx_delay(chip, delay);
                err = vx_get_pipe_state(chip, pipe, &cur_state);
                if (err < 0 || cur_state == state)
                        break;
                err = -EIO;
-               if ((i % 4 ) == 0)
-                       delay <<= 1;
+               mdelay(1);
        }
        return err < 0 ? -EIO : 0;
 }
@@ -465,7 +458,7 @@ static int vx_alloc_pipe(vx_core_t *chip, int capture,
        struct vx_rmh rmh;
        int data_mode;
 
-       *pipep = 0;
+       *pipep = NULL;
        vx_init_rmh(&rmh, CMD_RES_PIPE);
        vx_set_pipe_cmd_params(&rmh, capture, audioid, num_audio);
 #if 0  // NYI
@@ -480,7 +473,7 @@ static int vx_alloc_pipe(vx_core_t *chip, int capture,
                return err;
 
        /* initialize the pipe record */
-       pipe = snd_magic_kcalloc(vx_pipe_t, 0, GFP_KERNEL);
+       pipe = kcalloc(1, sizeof(*pipe), GFP_KERNEL);
        if (! pipe) {
                /* release the pipe */
                vx_init_rmh(&rmh, CMD_FREE_PIPE);
@@ -514,7 +507,7 @@ static int vx_free_pipe(vx_core_t *chip, vx_pipe_t *pipe)
        vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
        vx_send_msg(chip, &rmh);
 
-       snd_magic_kfree(pipe);
+       kfree(pipe);
        return 0;
 }
 
@@ -556,7 +549,8 @@ static int vx_stop_stream(vx_core_t *chip, vx_pipe_t *pipe)
 
 static snd_pcm_hardware_t vx_pcm_playback_hw = {
        .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-                                SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID),
+                                SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID |
+                                SNDRV_PCM_INFO_RESUME),
        .formats =              /*SNDRV_PCM_FMTBIT_U8 |*/ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
        .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
        .rate_min =             5000,
@@ -581,7 +575,7 @@ static int vx_pcm_playback_open(snd_pcm_substream_t *subs)
 {
        snd_pcm_runtime_t *runtime = subs->runtime;
        vx_core_t *chip = snd_pcm_substream_chip(subs);
-       vx_pipe_t *pipe = 0;
+       vx_pipe_t *pipe = NULL;
        unsigned int audio;
        int err;
 
@@ -629,10 +623,10 @@ static int vx_pcm_playback_close(snd_pcm_substream_t *subs)
        if (! subs->runtime->private_data)
                return -EINVAL;
 
-       pipe = snd_magic_cast(vx_pipe_t, subs->runtime->private_data, return -EINVAL);
+       pipe = subs->runtime->private_data;
 
        if (--pipe->references == 0) {
-               chip->playback_pipes[pipe->number] = 0;
+               chip->playback_pipes[pipe->number] = NULL;
                vx_free_pipe(chip, pipe);
        }
 
@@ -778,8 +772,8 @@ static void vx_pcm_playback_update(vx_core_t *chip, snd_pcm_substream_t *subs, v
 static void vx_pcm_delayed_start(unsigned long arg)
 {
        snd_pcm_substream_t *subs = (snd_pcm_substream_t *)arg;
-       vx_core_t *chip = snd_magic_cast(vx_core_t, subs->pcm->private_data, return);
-       vx_pipe_t *pipe = snd_magic_cast(vx_pipe_t, subs->runtime->private_data, return);
+       vx_core_t *chip = subs->pcm->private_data;
+       vx_pipe_t *pipe = subs->runtime->private_data;
        int err;
 
        /*  printk( KERN_DEBUG "DDDD tasklet delayed start jiffies = %ld\n", jiffies);*/
@@ -801,7 +795,7 @@ static void vx_pcm_delayed_start(unsigned long arg)
 static int vx_pcm_trigger(snd_pcm_substream_t *subs, int cmd)
 {
        vx_core_t *chip = snd_pcm_substream_chip(subs);
-       vx_pipe_t *pipe = snd_magic_cast(vx_pipe_t, subs->runtime->private_data, return -EINVAL);
+       vx_pipe_t *pipe = subs->runtime->private_data;
        int err;
 
        if (chip->chip_status & VX_STAT_IS_STALE)
@@ -809,6 +803,7 @@ static int vx_pcm_trigger(snd_pcm_substream_t *subs, int cmd)
                
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_RESUME:
                if (! pipe->is_capture)
                        vx_pcm_playback_transfer(chip, subs, pipe, 2);
                /* FIXME:
@@ -820,6 +815,7 @@ static int vx_pcm_trigger(snd_pcm_substream_t *subs, int cmd)
                pipe->running = 1;
                break;
        case SNDRV_PCM_TRIGGER_STOP:
+       case SNDRV_PCM_TRIGGER_SUSPEND:
                vx_toggle_pipe(chip, pipe, 0);
                vx_stop_pipe(chip, pipe);
                vx_stop_stream(chip, pipe);
@@ -846,7 +842,7 @@ static int vx_pcm_trigger(snd_pcm_substream_t *subs, int cmd)
 static snd_pcm_uframes_t vx_pcm_playback_pointer(snd_pcm_substream_t *subs)
 {
        snd_pcm_runtime_t *runtime = subs->runtime;
-       vx_pipe_t *pipe = snd_magic_cast(vx_pipe_t, runtime->private_data, return -EINVAL);
+       vx_pipe_t *pipe = runtime->private_data;
        return pipe->position;
 }
 
@@ -874,7 +870,7 @@ static int vx_pcm_prepare(snd_pcm_substream_t *subs)
 {
        vx_core_t *chip = snd_pcm_substream_chip(subs);
        snd_pcm_runtime_t *runtime = subs->runtime;
-       vx_pipe_t *pipe = snd_magic_cast(vx_pipe_t, runtime->private_data, return -EINVAL);
+       vx_pipe_t *pipe = runtime->private_data;
        int err, data_mode;
        // int max_size, nchunks;
 
@@ -953,7 +949,8 @@ static snd_pcm_ops_t vx_pcm_playback_ops = {
 
 static snd_pcm_hardware_t vx_pcm_capture_hw = {
        .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-                                SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID),
+                                SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID |
+                                SNDRV_PCM_INFO_RESUME),
        .formats =              /*SNDRV_PCM_FMTBIT_U8 |*/ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
        .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
        .rate_min =             5000,
@@ -1037,8 +1034,8 @@ static int vx_pcm_capture_close(snd_pcm_substream_t *subs)
        
        if (! subs->runtime->private_data)
                return -EINVAL;
-       pipe = snd_magic_cast(vx_pipe_t, subs->runtime->private_data, return -EINVAL);
-       chip->capture_pipes[pipe->number] = 0;
+       pipe = subs->runtime->private_data;
+       chip->capture_pipes[pipe->number] = NULL;
 
        pipe_out_monitoring = pipe->monitoring_pipe;
 
@@ -1049,8 +1046,8 @@ static int vx_pcm_capture_close(snd_pcm_substream_t *subs)
        if (pipe_out_monitoring) {
                if (--pipe_out_monitoring->references == 0) {
                        vx_free_pipe(chip, pipe_out_monitoring);
-                       chip->playback_pipes[pipe->number] = 0;
-                       pipe->monitoring_pipe = 0;
+                       chip->playback_pipes[pipe->number] = NULL;
+                       pipe->monitoring_pipe = NULL;
                }
        }
        
@@ -1141,7 +1138,7 @@ static void vx_pcm_capture_update(vx_core_t *chip, snd_pcm_substream_t *subs, vx
 static snd_pcm_uframes_t vx_pcm_capture_pointer(snd_pcm_substream_t *subs)
 {
        snd_pcm_runtime_t *runtime = subs->runtime;
-       vx_pipe_t *pipe = snd_magic_cast(vx_pipe_t, runtime->private_data, return -EINVAL);
+       vx_pipe_t *pipe = runtime->private_data;
        return bytes_to_frames(runtime, pipe->hw_ptr);
 }
 
@@ -1265,15 +1262,15 @@ static int vx_init_audio_io(vx_core_t *chip)
  */
 static void snd_vx_pcm_free(snd_pcm_t *pcm)
 {
-       vx_core_t *chip = snd_magic_cast(vx_core_t, pcm->private_data, return);
+       vx_core_t *chip = pcm->private_data;
        chip->pcm[pcm->device] = NULL;
        if (chip->playback_pipes) {
                kfree(chip->playback_pipes);
-               chip->playback_pipes = 0;
+               chip->playback_pipes = NULL;
        }
        if (chip->capture_pipes) {
                kfree(chip->capture_pipes);
-               chip->capture_pipes = 0;
+               chip->capture_pipes = NULL;
        }
 }