aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/pcm.c')
-rw-r--r--sound/usb/pcm.c20
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
793rep_err:
794 snd_usb_autosuspend(subs->stream->chip);
795 return err;
788} 796}
789 797
790static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) 798static 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