|
@@ -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_init_rmh(&rmh, CMD_PIPE_STATE);
|
|
vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
|
|
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)
|
|
if (! err)
|
|
*state = (rmh.Stat[0] & (1 << pipe->number)) ? 1 : 0;
|
|
*state = (rmh.Stat[0] & (1 << pipe->number)) ? 1 : 0;
|
|
return err;
|
|
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);
|
|
vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
|
|
rmh.Cmd[0] |= 1;
|
|
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 (! err) {
|
|
if (rmh.Stat[0])
|
|
if (rmh.Stat[0])
|
|
err = 1;
|
|
err = 1;
|
|
@@ -300,7 +300,7 @@ static int vx_conf_pipe(struct vx_core *chip, struct vx_pipe *pipe)
|
|
if (pipe->is_capture)
|
|
if (pipe->is_capture)
|
|
rmh.Cmd[0] |= COMMAND_RECORD_MASK;
|
|
rmh.Cmd[0] |= COMMAND_RECORD_MASK;
|
|
rmh.Cmd[1] = 1 << pipe->number;
|
|
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;
|
|
struct vx_rmh rmh;
|
|
|
|
|
|
vx_init_rmh(&rmh, CMD_SEND_IRQA);
|
|
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;
|
|
struct vx_rmh rmh;
|
|
vx_init_rmh(&rmh, CMD_STOP_PIPE);
|
|
vx_init_rmh(&rmh, CMD_STOP_PIPE);
|
|
vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
|
|
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_init_rmh(&rmh, CMD_START_ONE_STREAM);
|
|
vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
|
|
vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
|
|
vx_set_differed_time(chip, &rmh, pipe);
|
|
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_init_rmh(&rmh, CMD_STOP_STREAM);
|
|
vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
|
|
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
|
|
* 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->references++;
|
|
|
|
|
|
pipe->substream = subs;
|
|
pipe->substream = subs;
|
|
- tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs);
|
|
|
|
chip->playback_pipes[audio] = pipe;
|
|
chip->playback_pipes[audio] = pipe;
|
|
|
|
|
|
runtime->hw = vx_pcm_playback_hw;
|
|
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
|
|
/* we don't need irqsave here, because this function
|
|
* is called from either trigger callback or irq handler
|
|
* 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);
|
|
vx_pseudo_dma_write(chip, runtime, pipe, size);
|
|
err = vx_notify_end_of_buffer(chip, pipe);
|
|
err = vx_notify_end_of_buffer(chip, pipe);
|
|
/* disconnect the host, SIZE_HBUF command always switches to the stream mode */
|
|
/* disconnect the host, SIZE_HBUF command always switches to the stream mode */
|
|
vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
|
|
vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
|
|
- spin_unlock(&chip->lock);
|
|
|
|
|
|
+ mutex_unlock(&chip->lock);
|
|
return err;
|
|
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
|
|
* 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:
|
|
case SNDRV_PCM_TRIGGER_RESUME:
|
|
if (! pipe->is_capture)
|
|
if (! pipe->is_capture)
|
|
vx_pcm_playback_transfer(chip, subs, pipe, 2);
|
|
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++;
|
|
chip->pcm_running++;
|
|
pipe->running = 1;
|
|
pipe->running = 1;
|
|
break;
|
|
break;
|
|
@@ -955,7 +933,6 @@ static int vx_pcm_capture_open(struct snd_pcm_substream *subs)
|
|
if (err < 0)
|
|
if (err < 0)
|
|
return err;
|
|
return err;
|
|
pipe->substream = subs;
|
|
pipe->substream = subs;
|
|
- tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs);
|
|
|
|
chip->capture_pipes[audio] = pipe;
|
|
chip->capture_pipes[audio] = pipe;
|
|
|
|
|
|
/* check if monitoring is needed */
|
|
/* 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;
|
|
count -= 3;
|
|
}
|
|
}
|
|
/* disconnect the host, SIZE_HBUF command always switches to the stream mode */
|
|
/* 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 */
|
|
/* read the last pending 6 bytes */
|
|
count = DMA_READ_ALIGN;
|
|
count = DMA_READ_ALIGN;
|
|
while (count > 0) {
|
|
while (count > 0) {
|
|
@@ -1099,7 +1076,7 @@ static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream
|
|
|
|
|
|
_error:
|
|
_error:
|
|
/* disconnect the host, SIZE_HBUF command always switches to the stream mode */
|
|
/* 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;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1275,6 +1252,7 @@ int snd_vx_pcm_new(struct vx_core *chip)
|
|
pcm->private_data = chip;
|
|
pcm->private_data = chip;
|
|
pcm->private_free = snd_vx_pcm_free;
|
|
pcm->private_free = snd_vx_pcm_free;
|
|
pcm->info_flags = 0;
|
|
pcm->info_flags = 0;
|
|
|
|
+ pcm->nonatomic = true;
|
|
strcpy(pcm->name, chip->card->shortname);
|
|
strcpy(pcm->name, chip->card->shortname);
|
|
chip->pcm[i] = pcm;
|
|
chip->pcm[i] = pcm;
|
|
}
|
|
}
|