diff options
Diffstat (limited to 'sound/usb/pcm.c')
-rw-r--r-- | sound/usb/pcm.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index e3f680526cb5..b8dcbf407bbb 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "helper.h" | 32 | #include "helper.h" |
33 | #include "pcm.h" | 33 | #include "pcm.h" |
34 | #include "clock.h" | 34 | #include "clock.h" |
35 | #include "power.h" | ||
35 | 36 | ||
36 | /* | 37 | /* |
37 | * return the current pcm pointer. just based on the hwptr_done value. | 38 | * return the current pcm pointer. just based on the hwptr_done value. |
@@ -739,6 +740,9 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre | |||
739 | pt = 125 * (1 << fp->datainterval); | 740 | pt = 125 * (1 << fp->datainterval); |
740 | ptmin = min(ptmin, pt); | 741 | ptmin = min(ptmin, pt); |
741 | } | 742 | } |
743 | err = snd_usb_autoresume(subs->stream->chip); | ||
744 | if (err < 0) | ||
745 | return err; | ||
742 | 746 | ||
743 | param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; | 747 | param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; |
744 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) | 748 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) |
@@ -756,21 +760,21 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre | |||
756 | SNDRV_PCM_HW_PARAM_CHANNELS, | 760 | SNDRV_PCM_HW_PARAM_CHANNELS, |
757 | param_period_time_if_needed, | 761 | param_period_time_if_needed, |
758 | -1)) < 0) | 762 | -1)) < 0) |
759 | return err; | 763 | goto rep_err; |
760 | if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 764 | if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
761 | hw_rule_channels, subs, | 765 | hw_rule_channels, subs, |
762 | SNDRV_PCM_HW_PARAM_FORMAT, | 766 | SNDRV_PCM_HW_PARAM_FORMAT, |
763 | SNDRV_PCM_HW_PARAM_RATE, | 767 | SNDRV_PCM_HW_PARAM_RATE, |
764 | param_period_time_if_needed, | 768 | param_period_time_if_needed, |
765 | -1)) < 0) | 769 | -1)) < 0) |
766 | return err; | 770 | goto rep_err; |
767 | if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, | 771 | if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, |
768 | hw_rule_format, subs, | 772 | hw_rule_format, subs, |
769 | SNDRV_PCM_HW_PARAM_RATE, | 773 | SNDRV_PCM_HW_PARAM_RATE, |
770 | SNDRV_PCM_HW_PARAM_CHANNELS, | 774 | SNDRV_PCM_HW_PARAM_CHANNELS, |
771 | param_period_time_if_needed, | 775 | param_period_time_if_needed, |
772 | -1)) < 0) | 776 | -1)) < 0) |
773 | return err; | 777 | goto rep_err; |
774 | if (param_period_time_if_needed >= 0) { | 778 | if (param_period_time_if_needed >= 0) { |
775 | err = snd_pcm_hw_rule_add(runtime, 0, | 779 | err = snd_pcm_hw_rule_add(runtime, 0, |
776 | SNDRV_PCM_HW_PARAM_PERIOD_TIME, | 780 | SNDRV_PCM_HW_PARAM_PERIOD_TIME, |
@@ -780,11 +784,15 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre | |||
780 | SNDRV_PCM_HW_PARAM_RATE, | 784 | SNDRV_PCM_HW_PARAM_RATE, |
781 | -1); | 785 | -1); |
782 | if (err < 0) | 786 | if (err < 0) |
783 | return err; | 787 | goto rep_err; |
784 | } | 788 | } |
785 | if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0) | 789 | if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0) |
786 | return err; | 790 | goto rep_err; |
787 | return 0; | 791 | return 0; |
792 | |||
793 | rep_err: | ||
794 | snd_usb_autosuspend(subs->stream->chip); | ||
795 | return err; | ||
788 | } | 796 | } |
789 | 797 | ||
790 | static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) | 798 | static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) |
@@ -798,6 +806,7 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) | |||
798 | runtime->hw = snd_usb_hardware; | 806 | runtime->hw = snd_usb_hardware; |
799 | runtime->private_data = subs; | 807 | runtime->private_data = subs; |
800 | subs->pcm_substream = substream; | 808 | subs->pcm_substream = substream; |
809 | /* runtime PM is also done there */ | ||
801 | return setup_hw_info(runtime, subs); | 810 | return setup_hw_info(runtime, subs); |
802 | } | 811 | } |
803 | 812 | ||
@@ -811,6 +820,7 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) | |||
811 | subs->interface = -1; | 820 | subs->interface = -1; |
812 | } | 821 | } |
813 | subs->pcm_substream = NULL; | 822 | subs->pcm_substream = NULL; |
823 | snd_usb_autosuspend(subs->stream->chip); | ||
814 | return 0; | 824 | return 0; |
815 | } | 825 | } |
816 | 826 | ||