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>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -727,31 +724,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
|
||||
*/
|
||||
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user