aboutsummaryrefslogtreecommitdiffstats
path: root/sound/drivers/vx/vx_pcm.c
diff options
context:
space:
mode:
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
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
523static 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 */
735static 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 */
758static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd) 730static 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 }