diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2006-10-04 07:42:57 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2007-02-09 03:00:02 -0500 |
commit | e4f8e656d8c152c08cd44d0e3c21f009fab09952 (patch) | |
tree | 09985324ca92cf1e4889fe2626833d4aae1e1ca5 | |
parent | 1700f3080d98323e91864d67cb9f6d46f818ccf0 (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>
-rw-r--r-- | sound/usb/usbaudio.c | 40 |
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 | */ | ||
397 | static 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 | */ |
500 | static int prepare_startup_playback_urb(struct snd_usb_substream *subs, | 510 | static 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 | */ |
623 | static struct snd_urb_ops audio_urb_ops[2] = { | 633 | static 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 | ||
638 | static struct snd_urb_ops audio_urb_ops_high_speed[2] = { | 648 | static 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, |