summaryrefslogtreecommitdiffstats
path: root/sound/drivers/vx/vx_pcm.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-09-09 17:17:20 +0200
committerTakashi Iwai <tiwai@suse.de>2014-09-15 15:52:03 +0200
commitdb0a5214b8d6cc7a90ce3336d24a85b90cbb4e67 (patch)
treefdfcfaee149e83613d9854a763bbe3fe95f60292 /sound/drivers/vx/vx_pcm.c
parente7e69265b6269763799a5de9c263fbbce32cd3a3 (diff)
downloadlinux-db0a5214b8d6cc7a90ce3336d24a85b90cbb4e67.tar.bz2
ALSA: vx: Use nonatomic PCM ops
Rewrite VXpocket and VX222 drivers to use the new PCM nonatomic ops. The former irq tasklet is replaced with a threaded irq handler, and the tasklet for the PCM delayed start is simply merged into the normal PCM trigger, as well as the replacement of spinlock with mutex. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/drivers/vx/vx_pcm.c')
-rw-r--r--sound/drivers/vx/vx_pcm.c68
1 files changed, 23 insertions, 45 deletions
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index deed5efff33c..11467272089e 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -229,7 +229,7 @@ static int vx_get_pipe_state(struct vx_core *chip, struct vx_pipe *pipe, int *st
vx_init_rmh(&rmh, CMD_PIPE_STATE);
vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
- err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
+ err = vx_send_msg(chip, &rmh);
if (! err)
*state = (rmh.Stat[0] & (1 << pipe->number)) ? 1 : 0;
return err;
@@ -280,7 +280,7 @@ static int vx_pipe_can_start(struct vx_core *chip, struct vx_pipe *pipe)
vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
rmh.Cmd[0] |= 1;
- err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
+ err = vx_send_msg(chip, &rmh);
if (! err) {
if (rmh.Stat[0])
err = 1;
@@ -300,7 +300,7 @@ static int vx_conf_pipe(struct vx_core *chip, struct vx_pipe *pipe)
if (pipe->is_capture)
rmh.Cmd[0] |= COMMAND_RECORD_MASK;
rmh.Cmd[1] = 1 << pipe->number;
- return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
+ return vx_send_msg(chip, &rmh);
}
/*
@@ -311,7 +311,7 @@ static int vx_send_irqa(struct vx_core *chip)
struct vx_rmh rmh;
vx_init_rmh(&rmh, CMD_SEND_IRQA);
- return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
+ return vx_send_msg(chip, &rmh);
}
@@ -389,7 +389,7 @@ static int vx_stop_pipe(struct vx_core *chip, struct vx_pipe *pipe)
struct vx_rmh rmh;
vx_init_rmh(&rmh, CMD_STOP_PIPE);
vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
- return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
+ return vx_send_msg(chip, &rmh);
}
@@ -477,7 +477,7 @@ static int vx_start_stream(struct vx_core *chip, struct vx_pipe *pipe)
vx_init_rmh(&rmh, CMD_START_ONE_STREAM);
vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
vx_set_differed_time(chip, &rmh, pipe);
- return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
+ return vx_send_msg(chip, &rmh);
}
@@ -492,7 +492,7 @@ static int vx_stop_stream(struct vx_core *chip, struct vx_pipe *pipe)
vx_init_rmh(&rmh, CMD_STOP_STREAM);
vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
- return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
+ return vx_send_msg(chip, &rmh);
}
@@ -520,8 +520,6 @@ static struct snd_pcm_hardware vx_pcm_playback_hw = {
};
-static void vx_pcm_delayed_start(unsigned long arg);
-
/*
* vx_pcm_playback_open - open callback for playback
*/
@@ -553,7 +551,6 @@ static int vx_pcm_playback_open(struct snd_pcm_substream *subs)
pipe->references++;
pipe->substream = subs;
- tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs);
chip->playback_pipes[audio] = pipe;
runtime->hw = vx_pcm_playback_hw;
@@ -646,12 +643,12 @@ static int vx_pcm_playback_transfer_chunk(struct vx_core *chip,
/* we don't need irqsave here, because this function
* is called from either trigger callback or irq handler
*/
- spin_lock(&chip->lock);
+ mutex_lock(&chip->lock);
vx_pseudo_dma_write(chip, runtime, pipe, size);
err = vx_notify_end_of_buffer(chip, pipe);
/* disconnect the host, SIZE_HBUF command always switches to the stream mode */
vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
- spin_unlock(&chip->lock);
+ mutex_unlock(&chip->lock);
return err;
}
@@ -728,31 +725,6 @@ static void vx_pcm_playback_update(struct vx_core *chip,
}
/*
- * start the stream and pipe.
- * this function is called from tasklet, which is invoked by the trigger
- * START callback.
- */
-static void vx_pcm_delayed_start(unsigned long arg)
-{
- struct snd_pcm_substream *subs = (struct snd_pcm_substream *)arg;
- struct vx_core *chip = subs->pcm->private_data;
- struct vx_pipe *pipe = subs->runtime->private_data;
- int err;
-
- /* printk( KERN_DEBUG "DDDD tasklet delayed start jiffies = %ld\n", jiffies);*/
-
- if ((err = vx_start_stream(chip, pipe)) < 0) {
- snd_printk(KERN_ERR "vx: cannot start stream\n");
- return;
- }
- if ((err = vx_toggle_pipe(chip, pipe, 1)) < 0) {
- snd_printk(KERN_ERR "vx: cannot start pipe\n");
- return;
- }
- /* printk( KERN_DEBUG "dddd tasklet delayed start jiffies = %ld \n", jiffies);*/
-}
-
-/*
* vx_pcm_playback_trigger - trigger callback for playback
*/
static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
@@ -769,11 +741,17 @@ static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
case SNDRV_PCM_TRIGGER_RESUME:
if (! pipe->is_capture)
vx_pcm_playback_transfer(chip, subs, pipe, 2);
- /* FIXME:
- * we trigger the pipe using tasklet, so that the interrupts are
- * issued surely after the trigger is completed.
- */
- tasklet_schedule(&pipe->start_tq);
+ err = vx_start_stream(chip, pipe);
+ if (err < 0) {
+ pr_debug("vx: cannot start stream\n");
+ return err;
+ }
+ err = vx_toggle_pipe(chip, pipe, 1);
+ if (err < 0) {
+ pr_debug("vx: cannot start pipe\n");
+ vx_stop_stream(chip, pipe);
+ return err;
+ }
chip->pcm_running++;
pipe->running = 1;
break;
@@ -955,7 +933,6 @@ static int vx_pcm_capture_open(struct snd_pcm_substream *subs)
if (err < 0)
return err;
pipe->substream = subs;
- tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs);
chip->capture_pipes[audio] = pipe;
/* check if monitoring is needed */
@@ -1082,7 +1059,7 @@ static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream
count -= 3;
}
/* disconnect the host, SIZE_HBUF command always switches to the stream mode */
- vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
+ vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT);
/* read the last pending 6 bytes */
count = DMA_READ_ALIGN;
while (count > 0) {
@@ -1099,7 +1076,7 @@ static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream
_error:
/* disconnect the host, SIZE_HBUF command always switches to the stream mode */
- vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
+ vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT);
return;
}
@@ -1275,6 +1252,7 @@ int snd_vx_pcm_new(struct vx_core *chip)
pcm->private_data = chip;
pcm->private_free = snd_vx_pcm_free;
pcm->info_flags = 0;
+ pcm->nonatomic = true;
strcpy(pcm->name, chip->card->shortname);
chip->pcm[i] = pcm;
}