#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
*/
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)
* 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);
}
}
* 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;
}
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);
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;
}
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,
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] = NULL;
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);*/
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)
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:
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);
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;
}
{
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;
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,
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;
chip->capture_pipes[pipe->number] = NULL;
pipe_out_monitoring = pipe->monitoring_pipe;
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);
}
*/
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);