aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2006-10-04 07:42:57 -0400
committerJaroslav Kysela <perex@suse.cz>2007-02-09 03:00:02 -0500
commite4f8e656d8c152c08cd44d0e3c21f009fab09952 (patch)
tree09985324ca92cf1e4889fe2626833d4aae1e1ca5 /sound
parent1700f3080d98323e91864d67cb9f6d46f818ccf0 (diff)
[ALSA] usb-audio: allow pausing
Add pause capabilities for both USB playback and capture streams. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound')
-rw-r--r--sound/usb/usbaudio.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 478e504f7028..d2e066dc5d81 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -391,6 +391,16 @@ static int retire_capture_urb(struct snd_usb_substream *subs,
391 return 0; 391 return 0;
392} 392}
393 393
394/*
395 * Process after capture complete when paused. Nothing to do.
396 */
397static int retire_paused_capture_urb(struct snd_usb_substream *subs,
398 struct snd_pcm_runtime *runtime,
399 struct urb *urb)
400{
401 return 0;
402}
403
394 404
395/* 405/*
396 * prepare urb for full speed playback sync pipe 406 * prepare urb for full speed playback sync pipe
@@ -493,13 +503,13 @@ static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs)
493} 503}
494 504
495/* 505/*
496 * Prepare urb for streaming before playback starts. 506 * Prepare urb for streaming before playback starts or when paused.
497 * 507 *
498 * We don't yet have data, so we send a frame of silence. 508 * We don't have any data, so we send a frame of silence.
499 */ 509 */
500static int prepare_startup_playback_urb(struct snd_usb_substream *subs, 510static int prepare_nodata_playback_urb(struct snd_usb_substream *subs,
501 struct snd_pcm_runtime *runtime, 511 struct snd_pcm_runtime *runtime,
502 struct urb *urb) 512 struct urb *urb)
503{ 513{
504 unsigned int i, offs, counts; 514 unsigned int i, offs, counts;
505 struct snd_urb_ctx *ctx = urb->context; 515 struct snd_urb_ctx *ctx = urb->context;
@@ -622,7 +632,7 @@ static int retire_playback_urb(struct snd_usb_substream *subs,
622 */ 632 */
623static struct snd_urb_ops audio_urb_ops[2] = { 633static struct snd_urb_ops audio_urb_ops[2] = {
624 { 634 {
625 .prepare = prepare_startup_playback_urb, 635 .prepare = prepare_nodata_playback_urb,
626 .retire = retire_playback_urb, 636 .retire = retire_playback_urb,
627 .prepare_sync = prepare_playback_sync_urb, 637 .prepare_sync = prepare_playback_sync_urb,
628 .retire_sync = retire_playback_sync_urb, 638 .retire_sync = retire_playback_sync_urb,
@@ -637,7 +647,7 @@ static struct snd_urb_ops audio_urb_ops[2] = {
637 647
638static struct snd_urb_ops audio_urb_ops_high_speed[2] = { 648static struct snd_urb_ops audio_urb_ops_high_speed[2] = {
639 { 649 {
640 .prepare = prepare_startup_playback_urb, 650 .prepare = prepare_nodata_playback_urb,
641 .retire = retire_playback_urb, 651 .retire = retire_playback_urb,
642 .prepare_sync = prepare_playback_sync_urb_hs, 652 .prepare_sync = prepare_playback_sync_urb_hs,
643 .retire_sync = retire_playback_sync_urb_hs, 653 .retire_sync = retire_playback_sync_urb_hs,
@@ -925,10 +935,14 @@ static int snd_usb_pcm_playback_trigger(struct snd_pcm_substream *substream,
925 935
926 switch (cmd) { 936 switch (cmd) {
927 case SNDRV_PCM_TRIGGER_START: 937 case SNDRV_PCM_TRIGGER_START:
938 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
928 subs->ops.prepare = prepare_playback_urb; 939 subs->ops.prepare = prepare_playback_urb;
929 return 0; 940 return 0;
930 case SNDRV_PCM_TRIGGER_STOP: 941 case SNDRV_PCM_TRIGGER_STOP:
931 return deactivate_urbs(subs, 0, 0); 942 return deactivate_urbs(subs, 0, 0);
943 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
944 subs->ops.prepare = prepare_nodata_playback_urb;
945 return 0;
932 default: 946 default:
933 return -EINVAL; 947 return -EINVAL;
934 } 948 }
@@ -944,9 +958,16 @@ static int snd_usb_pcm_capture_trigger(struct snd_pcm_substream *substream,
944 958
945 switch (cmd) { 959 switch (cmd) {
946 case SNDRV_PCM_TRIGGER_START: 960 case SNDRV_PCM_TRIGGER_START:
961 subs->ops.retire = retire_capture_urb;
947 return start_urbs(subs, substream->runtime); 962 return start_urbs(subs, substream->runtime);
948 case SNDRV_PCM_TRIGGER_STOP: 963 case SNDRV_PCM_TRIGGER_STOP:
949 return deactivate_urbs(subs, 0, 0); 964 return deactivate_urbs(subs, 0, 0);
965 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
966 subs->ops.retire = retire_paused_capture_urb;
967 return 0;
968 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
969 subs->ops.retire = retire_capture_urb;
970 return 0;
950 default: 971 default:
951 return -EINVAL; 972 return -EINVAL;
952 } 973 }
@@ -1505,7 +1526,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
1505 /* for playback, submit the URBs now; otherwise, the first hwptr_done 1526 /* for playback, submit the URBs now; otherwise, the first hwptr_done
1506 * updates for all URBs would happen at the same time when starting */ 1527 * updates for all URBs would happen at the same time when starting */
1507 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) { 1528 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
1508 subs->ops.prepare = prepare_startup_playback_urb; 1529 subs->ops.prepare = prepare_nodata_playback_urb;
1509 return start_urbs(subs, runtime); 1530 return start_urbs(subs, runtime);
1510 } else 1531 } else
1511 return 0; 1532 return 0;
@@ -1517,7 +1538,8 @@ static struct snd_pcm_hardware snd_usb_hardware =
1517 SNDRV_PCM_INFO_MMAP_VALID | 1538 SNDRV_PCM_INFO_MMAP_VALID |
1518 SNDRV_PCM_INFO_BATCH | 1539 SNDRV_PCM_INFO_BATCH |
1519 SNDRV_PCM_INFO_INTERLEAVED | 1540 SNDRV_PCM_INFO_INTERLEAVED |
1520 SNDRV_PCM_INFO_BLOCK_TRANSFER, 1541 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1542 SNDRV_PCM_INFO_PAUSE,
1521 .buffer_bytes_max = 1024 * 1024, 1543 .buffer_bytes_max = 1024 * 1024,
1522 .period_bytes_min = 64, 1544 .period_bytes_min = 64,
1523 .period_bytes_max = 512 * 1024, 1545 .period_bytes_max = 512 * 1024,