diff options
Diffstat (limited to 'sound/drivers/vx/vx_pcm.c')
-rw-r--r-- | sound/drivers/vx/vx_pcm.c | 68 |
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 | |||
229 | 229 | ||
230 | vx_init_rmh(&rmh, CMD_PIPE_STATE); | 230 | vx_init_rmh(&rmh, CMD_PIPE_STATE); |
231 | vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0); | 231 | vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0); |
232 | err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ | 232 | err = vx_send_msg(chip, &rmh); |
233 | if (! err) | 233 | if (! err) |
234 | *state = (rmh.Stat[0] & (1 << pipe->number)) ? 1 : 0; | 234 | *state = (rmh.Stat[0] & (1 << pipe->number)) ? 1 : 0; |
235 | return err; | 235 | return err; |
@@ -280,7 +280,7 @@ static int vx_pipe_can_start(struct vx_core *chip, struct vx_pipe *pipe) | |||
280 | vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0); | 280 | vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0); |
281 | rmh.Cmd[0] |= 1; | 281 | rmh.Cmd[0] |= 1; |
282 | 282 | ||
283 | err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ | 283 | err = vx_send_msg(chip, &rmh); |
284 | if (! err) { | 284 | if (! err) { |
285 | if (rmh.Stat[0]) | 285 | if (rmh.Stat[0]) |
286 | err = 1; | 286 | err = 1; |
@@ -300,7 +300,7 @@ static int vx_conf_pipe(struct vx_core *chip, struct vx_pipe *pipe) | |||
300 | if (pipe->is_capture) | 300 | if (pipe->is_capture) |
301 | rmh.Cmd[0] |= COMMAND_RECORD_MASK; | 301 | rmh.Cmd[0] |= COMMAND_RECORD_MASK; |
302 | rmh.Cmd[1] = 1 << pipe->number; | 302 | rmh.Cmd[1] = 1 << pipe->number; |
303 | return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ | 303 | return vx_send_msg(chip, &rmh); |
304 | } | 304 | } |
305 | 305 | ||
306 | /* | 306 | /* |
@@ -311,7 +311,7 @@ static int vx_send_irqa(struct vx_core *chip) | |||
311 | struct vx_rmh rmh; | 311 | struct vx_rmh rmh; |
312 | 312 | ||
313 | vx_init_rmh(&rmh, CMD_SEND_IRQA); | 313 | vx_init_rmh(&rmh, CMD_SEND_IRQA); |
314 | return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ | 314 | return vx_send_msg(chip, &rmh); |
315 | } | 315 | } |
316 | 316 | ||
317 | 317 | ||
@@ -389,7 +389,7 @@ static int vx_stop_pipe(struct vx_core *chip, struct vx_pipe *pipe) | |||
389 | struct vx_rmh rmh; | 389 | struct vx_rmh rmh; |
390 | vx_init_rmh(&rmh, CMD_STOP_PIPE); | 390 | vx_init_rmh(&rmh, CMD_STOP_PIPE); |
391 | vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0); | 391 | vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0); |
392 | return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ | 392 | return vx_send_msg(chip, &rmh); |
393 | } | 393 | } |
394 | 394 | ||
395 | 395 | ||
@@ -477,7 +477,7 @@ static int vx_start_stream(struct vx_core *chip, struct vx_pipe *pipe) | |||
477 | vx_init_rmh(&rmh, CMD_START_ONE_STREAM); | 477 | vx_init_rmh(&rmh, CMD_START_ONE_STREAM); |
478 | vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number); | 478 | vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number); |
479 | vx_set_differed_time(chip, &rmh, pipe); | 479 | vx_set_differed_time(chip, &rmh, pipe); |
480 | return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ | 480 | return vx_send_msg(chip, &rmh); |
481 | } | 481 | } |
482 | 482 | ||
483 | 483 | ||
@@ -492,7 +492,7 @@ static int vx_stop_stream(struct vx_core *chip, struct vx_pipe *pipe) | |||
492 | 492 | ||
493 | vx_init_rmh(&rmh, CMD_STOP_STREAM); | 493 | vx_init_rmh(&rmh, CMD_STOP_STREAM); |
494 | vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number); | 494 | vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number); |
495 | return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ | 495 | return vx_send_msg(chip, &rmh); |
496 | } | 496 | } |
497 | 497 | ||
498 | 498 | ||
@@ -520,8 +520,6 @@ static struct snd_pcm_hardware vx_pcm_playback_hw = { | |||
520 | }; | 520 | }; |
521 | 521 | ||
522 | 522 | ||
523 | static void vx_pcm_delayed_start(unsigned long arg); | ||
524 | |||
525 | /* | 523 | /* |
526 | * vx_pcm_playback_open - open callback for playback | 524 | * vx_pcm_playback_open - open callback for playback |
527 | */ | 525 | */ |
@@ -553,7 +551,6 @@ static int vx_pcm_playback_open(struct snd_pcm_substream *subs) | |||
553 | pipe->references++; | 551 | pipe->references++; |
554 | 552 | ||
555 | pipe->substream = subs; | 553 | pipe->substream = subs; |
556 | tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs); | ||
557 | chip->playback_pipes[audio] = pipe; | 554 | chip->playback_pipes[audio] = pipe; |
558 | 555 | ||
559 | runtime->hw = vx_pcm_playback_hw; | 556 | runtime->hw = vx_pcm_playback_hw; |
@@ -646,12 +643,12 @@ static int vx_pcm_playback_transfer_chunk(struct vx_core *chip, | |||
646 | /* we don't need irqsave here, because this function | 643 | /* we don't need irqsave here, because this function |
647 | * is called from either trigger callback or irq handler | 644 | * is called from either trigger callback or irq handler |
648 | */ | 645 | */ |
649 | spin_lock(&chip->lock); | 646 | mutex_lock(&chip->lock); |
650 | vx_pseudo_dma_write(chip, runtime, pipe, size); | 647 | vx_pseudo_dma_write(chip, runtime, pipe, size); |
651 | err = vx_notify_end_of_buffer(chip, pipe); | 648 | err = vx_notify_end_of_buffer(chip, pipe); |
652 | /* disconnect the host, SIZE_HBUF command always switches to the stream mode */ | 649 | /* disconnect the host, SIZE_HBUF command always switches to the stream mode */ |
653 | vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT); | 650 | vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT); |
654 | spin_unlock(&chip->lock); | 651 | mutex_unlock(&chip->lock); |
655 | return err; | 652 | return err; |
656 | } | 653 | } |
657 | 654 | ||
@@ -728,31 +725,6 @@ static void vx_pcm_playback_update(struct vx_core *chip, | |||
728 | } | 725 | } |
729 | 726 | ||
730 | /* | 727 | /* |
731 | * start the stream and pipe. | ||
732 | * this function is called from tasklet, which is invoked by the trigger | ||
733 | * START callback. | ||
734 | */ | ||
735 | static void vx_pcm_delayed_start(unsigned long arg) | ||
736 | { | ||
737 | struct snd_pcm_substream *subs = (struct snd_pcm_substream *)arg; | ||
738 | struct vx_core *chip = subs->pcm->private_data; | ||
739 | struct vx_pipe *pipe = subs->runtime->private_data; | ||
740 | int err; | ||
741 | |||
742 | /* printk( KERN_DEBUG "DDDD tasklet delayed start jiffies = %ld\n", jiffies);*/ | ||
743 | |||
744 | if ((err = vx_start_stream(chip, pipe)) < 0) { | ||
745 | snd_printk(KERN_ERR "vx: cannot start stream\n"); | ||
746 | return; | ||
747 | } | ||
748 | if ((err = vx_toggle_pipe(chip, pipe, 1)) < 0) { | ||
749 | snd_printk(KERN_ERR "vx: cannot start pipe\n"); | ||
750 | return; | ||
751 | } | ||
752 | /* printk( KERN_DEBUG "dddd tasklet delayed start jiffies = %ld \n", jiffies);*/ | ||
753 | } | ||
754 | |||
755 | /* | ||
756 | * vx_pcm_playback_trigger - trigger callback for playback | 728 | * vx_pcm_playback_trigger - trigger callback for playback |
757 | */ | 729 | */ |
758 | static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd) | 730 | 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) | |||
769 | case SNDRV_PCM_TRIGGER_RESUME: | 741 | case SNDRV_PCM_TRIGGER_RESUME: |
770 | if (! pipe->is_capture) | 742 | if (! pipe->is_capture) |
771 | vx_pcm_playback_transfer(chip, subs, pipe, 2); | 743 | vx_pcm_playback_transfer(chip, subs, pipe, 2); |
772 | /* FIXME: | 744 | err = vx_start_stream(chip, pipe); |
773 | * we trigger the pipe using tasklet, so that the interrupts are | 745 | if (err < 0) { |
774 | * issued surely after the trigger is completed. | 746 | pr_debug("vx: cannot start stream\n"); |
775 | */ | 747 | return err; |
776 | tasklet_schedule(&pipe->start_tq); | 748 | } |
749 | err = vx_toggle_pipe(chip, pipe, 1); | ||
750 | if (err < 0) { | ||
751 | pr_debug("vx: cannot start pipe\n"); | ||
752 | vx_stop_stream(chip, pipe); | ||
753 | return err; | ||
754 | } | ||
777 | chip->pcm_running++; | 755 | chip->pcm_running++; |
778 | pipe->running = 1; | 756 | pipe->running = 1; |
779 | break; | 757 | break; |
@@ -955,7 +933,6 @@ static int vx_pcm_capture_open(struct snd_pcm_substream *subs) | |||
955 | if (err < 0) | 933 | if (err < 0) |
956 | return err; | 934 | return err; |
957 | pipe->substream = subs; | 935 | pipe->substream = subs; |
958 | tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs); | ||
959 | chip->capture_pipes[audio] = pipe; | 936 | chip->capture_pipes[audio] = pipe; |
960 | 937 | ||
961 | /* check if monitoring is needed */ | 938 | /* check if monitoring is needed */ |
@@ -1082,7 +1059,7 @@ static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream | |||
1082 | count -= 3; | 1059 | count -= 3; |
1083 | } | 1060 | } |
1084 | /* disconnect the host, SIZE_HBUF command always switches to the stream mode */ | 1061 | /* disconnect the host, SIZE_HBUF command always switches to the stream mode */ |
1085 | vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT); | 1062 | vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT); |
1086 | /* read the last pending 6 bytes */ | 1063 | /* read the last pending 6 bytes */ |
1087 | count = DMA_READ_ALIGN; | 1064 | count = DMA_READ_ALIGN; |
1088 | while (count > 0) { | 1065 | while (count > 0) { |
@@ -1099,7 +1076,7 @@ static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream | |||
1099 | 1076 | ||
1100 | _error: | 1077 | _error: |
1101 | /* disconnect the host, SIZE_HBUF command always switches to the stream mode */ | 1078 | /* disconnect the host, SIZE_HBUF command always switches to the stream mode */ |
1102 | vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT); | 1079 | vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT); |
1103 | return; | 1080 | return; |
1104 | } | 1081 | } |
1105 | 1082 | ||
@@ -1275,6 +1252,7 @@ int snd_vx_pcm_new(struct vx_core *chip) | |||
1275 | pcm->private_data = chip; | 1252 | pcm->private_data = chip; |
1276 | pcm->private_free = snd_vx_pcm_free; | 1253 | pcm->private_free = snd_vx_pcm_free; |
1277 | pcm->info_flags = 0; | 1254 | pcm->info_flags = 0; |
1255 | pcm->nonatomic = true; | ||
1278 | strcpy(pcm->name, chip->card->shortname); | 1256 | strcpy(pcm->name, chip->card->shortname); |
1279 | chip->pcm[i] = pcm; | 1257 | chip->pcm[i] = pcm; |
1280 | } | 1258 | } |