aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c1
-rw-r--r--sound/soc/samsung/dma.c18
-rw-r--r--sound/soc/tegra/Kconfig10
-rw-r--r--sound/soc/tegra/tegra20_i2s.c4
-rw-r--r--sound/soc/tegra/tegra20_spdif.c4
-rw-r--r--sound/soc/tegra/tegra30_ahub.c8
-rw-r--r--sound/soc/tegra/tegra30_i2s.c4
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.c12
-rw-r--r--sound/usb/endpoint.c73
-rw-r--r--sound/usb/pcm.c61
10 files changed, 71 insertions, 124 deletions
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index 456b7d723d66..ee27ba3933bd 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -29,6 +29,7 @@
29 29
30#include <asm/fiq.h> 30#include <asm/fiq.h>
31 31
32#include <mach/irqs.h>
32#include <mach/ssi.h> 33#include <mach/ssi.h>
33 34
34#include "imx-ssi.h" 35#include "imx-ssi.h"
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index ddc6cde14e2a..f3ebc38c10fe 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -74,7 +74,7 @@ static void dma_enqueue(struct snd_pcm_substream *substream)
74 struct runtime_data *prtd = substream->runtime->private_data; 74 struct runtime_data *prtd = substream->runtime->private_data;
75 dma_addr_t pos = prtd->dma_pos; 75 dma_addr_t pos = prtd->dma_pos;
76 unsigned int limit; 76 unsigned int limit;
77 struct samsung_dma_prep_info dma_info; 77 struct samsung_dma_prep dma_info;
78 78
79 pr_debug("Entered %s\n", __func__); 79 pr_debug("Entered %s\n", __func__);
80 80
@@ -146,7 +146,8 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
146 unsigned long totbytes = params_buffer_bytes(params); 146 unsigned long totbytes = params_buffer_bytes(params);
147 struct s3c_dma_params *dma = 147 struct s3c_dma_params *dma =
148 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 148 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
149 struct samsung_dma_info dma_info; 149 struct samsung_dma_req req;
150 struct samsung_dma_config config;
150 151
151 pr_debug("Entered %s\n", __func__); 152 pr_debug("Entered %s\n", __func__);
152 153
@@ -166,16 +167,17 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
166 167
167 prtd->params->ops = samsung_dma_get_ops(); 168 prtd->params->ops = samsung_dma_get_ops();
168 169
169 dma_info.cap = (samsung_dma_has_circular() ? 170 req.cap = (samsung_dma_has_circular() ?
170 DMA_CYCLIC : DMA_SLAVE); 171 DMA_CYCLIC : DMA_SLAVE);
171 dma_info.client = prtd->params->client; 172 req.client = prtd->params->client;
172 dma_info.direction = 173 config.direction =
173 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK 174 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK
174 ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM); 175 ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM);
175 dma_info.width = prtd->params->dma_size; 176 config.width = prtd->params->dma_size;
176 dma_info.fifo = prtd->params->dma_addr; 177 config.fifo = prtd->params->dma_addr;
177 prtd->params->ch = prtd->params->ops->request( 178 prtd->params->ch = prtd->params->ops->request(
178 prtd->params->channel, &dma_info); 179 prtd->params->channel, &req);
180 prtd->params->ops->config(prtd->params->ch, &config);
179 } 181 }
180 182
181 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 183 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index c1c8e955f4d3..76dc230f2bb0 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -58,17 +58,9 @@ config SND_SOC_TEGRA_WM8753
58 Say Y or M here if you want to add support for SoC audio on Tegra 58 Say Y or M here if you want to add support for SoC audio on Tegra
59 boards using the WM8753 codec, such as Whistler. 59 boards using the WM8753 codec, such as Whistler.
60 60
61config MACH_HAS_SND_SOC_TEGRA_WM8903
62 bool
63 help
64 Machines that use the SND_SOC_TEGRA_WM8903 driver should select
65 this config option, in order to allow the user to enable
66 SND_SOC_TEGRA_WM8903.
67
68config SND_SOC_TEGRA_WM8903 61config SND_SOC_TEGRA_WM8903
69 tristate "SoC Audio support for Tegra boards using a WM8903 codec" 62 tristate "SoC Audio support for Tegra boards using a WM8903 codec"
70 depends on SND_SOC_TEGRA && I2C 63 depends on SND_SOC_TEGRA && I2C
71 depends on MACH_HAS_SND_SOC_TEGRA_WM8903
72 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC 64 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
73 select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC 65 select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC
74 select SND_SOC_WM8903 66 select SND_SOC_WM8903
@@ -79,7 +71,7 @@ config SND_SOC_TEGRA_WM8903
79 71
80config SND_SOC_TEGRA_TRIMSLICE 72config SND_SOC_TEGRA_TRIMSLICE
81 tristate "SoC Audio support for TrimSlice board" 73 tristate "SoC Audio support for TrimSlice board"
82 depends on SND_SOC_TEGRA && MACH_TRIMSLICE && I2C 74 depends on SND_SOC_TEGRA && I2C
83 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC 75 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
84 select SND_SOC_TLV320AIC23 76 select SND_SOC_TLV320AIC23
85 help 77 help
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c
index 0c7af63d444b..1647dbfe74b5 100644
--- a/sound/soc/tegra/tegra20_i2s.c
+++ b/sound/soc/tegra/tegra20_i2s.c
@@ -62,7 +62,7 @@ static int tegra20_i2s_runtime_suspend(struct device *dev)
62{ 62{
63 struct tegra20_i2s *i2s = dev_get_drvdata(dev); 63 struct tegra20_i2s *i2s = dev_get_drvdata(dev);
64 64
65 clk_disable(i2s->clk_i2s); 65 clk_disable_unprepare(i2s->clk_i2s);
66 66
67 return 0; 67 return 0;
68} 68}
@@ -72,7 +72,7 @@ static int tegra20_i2s_runtime_resume(struct device *dev)
72 struct tegra20_i2s *i2s = dev_get_drvdata(dev); 72 struct tegra20_i2s *i2s = dev_get_drvdata(dev);
73 int ret; 73 int ret;
74 74
75 ret = clk_enable(i2s->clk_i2s); 75 ret = clk_prepare_enable(i2s->clk_i2s);
76 if (ret) { 76 if (ret) {
77 dev_err(dev, "clk_enable failed: %d\n", ret); 77 dev_err(dev, "clk_enable failed: %d\n", ret);
78 return ret; 78 return ret;
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c
index f9b57418bd08..2262e4fdec2a 100644
--- a/sound/soc/tegra/tegra20_spdif.c
+++ b/sound/soc/tegra/tegra20_spdif.c
@@ -54,7 +54,7 @@ static int tegra20_spdif_runtime_suspend(struct device *dev)
54{ 54{
55 struct tegra20_spdif *spdif = dev_get_drvdata(dev); 55 struct tegra20_spdif *spdif = dev_get_drvdata(dev);
56 56
57 clk_disable(spdif->clk_spdif_out); 57 clk_disable_unprepare(spdif->clk_spdif_out);
58 58
59 return 0; 59 return 0;
60} 60}
@@ -64,7 +64,7 @@ static int tegra20_spdif_runtime_resume(struct device *dev)
64 struct tegra20_spdif *spdif = dev_get_drvdata(dev); 64 struct tegra20_spdif *spdif = dev_get_drvdata(dev);
65 int ret; 65 int ret;
66 66
67 ret = clk_enable(spdif->clk_spdif_out); 67 ret = clk_prepare_enable(spdif->clk_spdif_out);
68 if (ret) { 68 if (ret) {
69 dev_err(dev, "clk_enable failed: %d\n", ret); 69 dev_err(dev, "clk_enable failed: %d\n", ret);
70 return ret; 70 return ret;
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index f43edb364a18..bf5610122c76 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -56,8 +56,8 @@ static int tegra30_ahub_runtime_suspend(struct device *dev)
56 regcache_cache_only(ahub->regmap_apbif, true); 56 regcache_cache_only(ahub->regmap_apbif, true);
57 regcache_cache_only(ahub->regmap_ahub, true); 57 regcache_cache_only(ahub->regmap_ahub, true);
58 58
59 clk_disable(ahub->clk_apbif); 59 clk_disable_unprepare(ahub->clk_apbif);
60 clk_disable(ahub->clk_d_audio); 60 clk_disable_unprepare(ahub->clk_d_audio);
61 61
62 return 0; 62 return 0;
63} 63}
@@ -77,12 +77,12 @@ static int tegra30_ahub_runtime_resume(struct device *dev)
77{ 77{
78 int ret; 78 int ret;
79 79
80 ret = clk_enable(ahub->clk_d_audio); 80 ret = clk_prepare_enable(ahub->clk_d_audio);
81 if (ret) { 81 if (ret) {
82 dev_err(dev, "clk_enable d_audio failed: %d\n", ret); 82 dev_err(dev, "clk_enable d_audio failed: %d\n", ret);
83 return ret; 83 return ret;
84 } 84 }
85 ret = clk_enable(ahub->clk_apbif); 85 ret = clk_prepare_enable(ahub->clk_apbif);
86 if (ret) { 86 if (ret) {
87 dev_err(dev, "clk_enable apbif failed: %d\n", ret); 87 dev_err(dev, "clk_enable apbif failed: %d\n", ret);
88 clk_disable(ahub->clk_d_audio); 88 clk_disable(ahub->clk_d_audio);
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index 8596032985dc..d308faaae148 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -62,7 +62,7 @@ static int tegra30_i2s_runtime_suspend(struct device *dev)
62 62
63 regcache_cache_only(i2s->regmap, true); 63 regcache_cache_only(i2s->regmap, true);
64 64
65 clk_disable(i2s->clk_i2s); 65 clk_disable_unprepare(i2s->clk_i2s);
66 66
67 return 0; 67 return 0;
68} 68}
@@ -72,7 +72,7 @@ static int tegra30_i2s_runtime_resume(struct device *dev)
72 struct tegra30_i2s *i2s = dev_get_drvdata(dev); 72 struct tegra30_i2s *i2s = dev_get_drvdata(dev);
73 int ret; 73 int ret;
74 74
75 ret = clk_enable(i2s->clk_i2s); 75 ret = clk_prepare_enable(i2s->clk_i2s);
76 if (ret) { 76 if (ret) {
77 dev_err(dev, "clk_enable failed: %d\n", ret); 77 dev_err(dev, "clk_enable failed: %d\n", ret);
78 return ret; 78 return ret;
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c
index 9515ce58ea02..6872c77a1196 100644
--- a/sound/soc/tegra/tegra_asoc_utils.c
+++ b/sound/soc/tegra/tegra_asoc_utils.c
@@ -69,9 +69,9 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
69 data->set_baseclock = 0; 69 data->set_baseclock = 0;
70 data->set_mclk = 0; 70 data->set_mclk = 0;
71 71
72 clk_disable(data->clk_cdev1); 72 clk_disable_unprepare(data->clk_cdev1);
73 clk_disable(data->clk_pll_a_out0); 73 clk_disable_unprepare(data->clk_pll_a_out0);
74 clk_disable(data->clk_pll_a); 74 clk_disable_unprepare(data->clk_pll_a);
75 75
76 err = clk_set_rate(data->clk_pll_a, new_baseclock); 76 err = clk_set_rate(data->clk_pll_a, new_baseclock);
77 if (err) { 77 if (err) {
@@ -87,19 +87,19 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
87 87
88 /* Don't set cdev1/extern1 rate; it's locked to pll_a_out0 */ 88 /* Don't set cdev1/extern1 rate; it's locked to pll_a_out0 */
89 89
90 err = clk_enable(data->clk_pll_a); 90 err = clk_prepare_enable(data->clk_pll_a);
91 if (err) { 91 if (err) {
92 dev_err(data->dev, "Can't enable pll_a: %d\n", err); 92 dev_err(data->dev, "Can't enable pll_a: %d\n", err);
93 return err; 93 return err;
94 } 94 }
95 95
96 err = clk_enable(data->clk_pll_a_out0); 96 err = clk_prepare_enable(data->clk_pll_a_out0);
97 if (err) { 97 if (err) {
98 dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err); 98 dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err);
99 return err; 99 return err;
100 } 100 }
101 101
102 err = clk_enable(data->clk_cdev1); 102 err = clk_prepare_enable(data->clk_cdev1);
103 if (err) { 103 if (err) {
104 dev_err(data->dev, "Can't enable cdev1: %d\n", err); 104 dev_err(data->dev, "Can't enable cdev1: %d\n", err);
105 return err; 105 return err;
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index e6906901debb..0f647d22cb4a 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -414,7 +414,7 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
414{ 414{
415 struct list_head *p; 415 struct list_head *p;
416 struct snd_usb_endpoint *ep; 416 struct snd_usb_endpoint *ep;
417 int ret, is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK; 417 int is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK;
418 418
419 mutex_lock(&chip->mutex); 419 mutex_lock(&chip->mutex);
420 420
@@ -434,16 +434,6 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
434 type == SND_USB_ENDPOINT_TYPE_DATA ? "data" : "sync", 434 type == SND_USB_ENDPOINT_TYPE_DATA ? "data" : "sync",
435 ep_num); 435 ep_num);
436 436
437 /* select the alt setting once so the endpoints become valid */
438 ret = usb_set_interface(chip->dev, alts->desc.bInterfaceNumber,
439 alts->desc.bAlternateSetting);
440 if (ret < 0) {
441 snd_printk(KERN_ERR "%s(): usb_set_interface() failed, ret = %d\n",
442 __func__, ret);
443 ep = NULL;
444 goto __exit_unlock;
445 }
446
447 ep = kzalloc(sizeof(*ep), GFP_KERNEL); 437 ep = kzalloc(sizeof(*ep), GFP_KERNEL);
448 if (!ep) 438 if (!ep)
449 goto __exit_unlock; 439 goto __exit_unlock;
@@ -831,9 +821,6 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
831 if (++ep->use_count != 1) 821 if (++ep->use_count != 1)
832 return 0; 822 return 0;
833 823
834 if (snd_BUG_ON(!test_bit(EP_FLAG_ACTIVATED, &ep->flags)))
835 return -EINVAL;
836
837 /* just to be sure */ 824 /* just to be sure */
838 deactivate_urbs(ep, 0, 1); 825 deactivate_urbs(ep, 0, 1);
839 wait_clear_urbs(ep); 826 wait_clear_urbs(ep);
@@ -911,9 +898,6 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep,
911 if (snd_BUG_ON(ep->use_count == 0)) 898 if (snd_BUG_ON(ep->use_count == 0))
912 return; 899 return;
913 900
914 if (snd_BUG_ON(!test_bit(EP_FLAG_ACTIVATED, &ep->flags)))
915 return;
916
917 if (--ep->use_count == 0) { 901 if (--ep->use_count == 0) {
918 deactivate_urbs(ep, force, can_sleep); 902 deactivate_urbs(ep, force, can_sleep);
919 ep->data_subs = NULL; 903 ep->data_subs = NULL;
@@ -927,42 +911,6 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep,
927} 911}
928 912
929/** 913/**
930 * snd_usb_endpoint_activate: activate an snd_usb_endpoint
931 *
932 * @ep: the endpoint to activate
933 *
934 * If the endpoint is not currently in use, this functions will select the
935 * correct alternate interface setting for the interface of this endpoint.
936 *
937 * In case of any active users, this functions does nothing.
938 *
939 * Returns an error if usb_set_interface() failed, 0 in all other
940 * cases.
941 */
942int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep)
943{
944 if (ep->use_count != 0)
945 return 0;
946
947 if (!ep->chip->shutdown &&
948 !test_and_set_bit(EP_FLAG_ACTIVATED, &ep->flags)) {
949 int ret;
950
951 ret = usb_set_interface(ep->chip->dev, ep->iface, ep->alt_idx);
952 if (ret < 0) {
953 snd_printk(KERN_ERR "%s() usb_set_interface() failed, ret = %d\n",
954 __func__, ret);
955 clear_bit(EP_FLAG_ACTIVATED, &ep->flags);
956 return ret;
957 }
958
959 return 0;
960 }
961
962 return -EBUSY;
963}
964
965/**
966 * snd_usb_endpoint_deactivate: deactivate an snd_usb_endpoint 914 * snd_usb_endpoint_deactivate: deactivate an snd_usb_endpoint
967 * 915 *
968 * @ep: the endpoint to deactivate 916 * @ep: the endpoint to deactivate
@@ -980,24 +928,15 @@ int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep)
980 if (!ep) 928 if (!ep)
981 return -EINVAL; 929 return -EINVAL;
982 930
931 deactivate_urbs(ep, 1, 1);
932 wait_clear_urbs(ep);
933
983 if (ep->use_count != 0) 934 if (ep->use_count != 0)
984 return 0; 935 return 0;
985 936
986 if (!ep->chip->shutdown && 937 clear_bit(EP_FLAG_ACTIVATED, &ep->flags);
987 test_and_clear_bit(EP_FLAG_ACTIVATED, &ep->flags)) {
988 int ret;
989
990 ret = usb_set_interface(ep->chip->dev, ep->iface, 0);
991 if (ret < 0) {
992 snd_printk(KERN_ERR "%s(): usb_set_interface() failed, ret = %d\n",
993 __func__, ret);
994 return ret;
995 }
996 938
997 return 0; 939 return 0;
998 }
999
1000 return -EBUSY;
1001} 940}
1002 941
1003/** 942/**
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 54607f8c4f66..a1298f379428 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -261,19 +261,6 @@ static void stop_endpoints(struct snd_usb_substream *subs,
261 force, can_sleep, wait); 261 force, can_sleep, wait);
262} 262}
263 263
264static int activate_endpoints(struct snd_usb_substream *subs)
265{
266 if (subs->sync_endpoint) {
267 int ret;
268
269 ret = snd_usb_endpoint_activate(subs->sync_endpoint);
270 if (ret < 0)
271 return ret;
272 }
273
274 return snd_usb_endpoint_activate(subs->data_endpoint);
275}
276
277static int deactivate_endpoints(struct snd_usb_substream *subs) 264static int deactivate_endpoints(struct snd_usb_substream *subs)
278{ 265{
279 int reta, retb; 266 int reta, retb;
@@ -314,6 +301,33 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
314 if (fmt == subs->cur_audiofmt) 301 if (fmt == subs->cur_audiofmt)
315 return 0; 302 return 0;
316 303
304 /* close the old interface */
305 if (subs->interface >= 0 && subs->interface != fmt->iface) {
306 err = usb_set_interface(subs->dev, subs->interface, 0);
307 if (err < 0) {
308 snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed (%d)\n",
309 dev->devnum, fmt->iface, fmt->altsetting, err);
310 return -EIO;
311 }
312 subs->interface = -1;
313 subs->altset_idx = 0;
314 }
315
316 /* set interface */
317 if (subs->interface != fmt->iface ||
318 subs->altset_idx != fmt->altset_idx) {
319 err = usb_set_interface(dev, fmt->iface, fmt->altsetting);
320 if (err < 0) {
321 snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed (%d)\n",
322 dev->devnum, fmt->iface, fmt->altsetting, err);
323 return -EIO;
324 }
325 snd_printdd(KERN_INFO "setting usb interface %d:%d\n",
326 fmt->iface, fmt->altsetting);
327 subs->interface = fmt->iface;
328 subs->altset_idx = fmt->altset_idx;
329 }
330
317 subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip, 331 subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip,
318 alts, fmt->endpoint, subs->direction, 332 alts, fmt->endpoint, subs->direction,
319 SND_USB_ENDPOINT_TYPE_DATA); 333 SND_USB_ENDPOINT_TYPE_DATA);
@@ -387,7 +401,7 @@ add_sync_ep:
387 subs->data_endpoint->sync_master = subs->sync_endpoint; 401 subs->data_endpoint->sync_master = subs->sync_endpoint;
388 } 402 }
389 403
390 if ((err = snd_usb_init_pitch(subs->stream->chip, subs->interface, alts, fmt)) < 0) 404 if ((err = snd_usb_init_pitch(subs->stream->chip, fmt->iface, alts, fmt)) < 0)
391 return err; 405 return err;
392 406
393 subs->cur_audiofmt = fmt; 407 subs->cur_audiofmt = fmt;
@@ -450,7 +464,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
450 struct usb_interface *iface; 464 struct usb_interface *iface;
451 iface = usb_ifnum_to_if(subs->dev, fmt->iface); 465 iface = usb_ifnum_to_if(subs->dev, fmt->iface);
452 alts = &iface->altsetting[fmt->altset_idx]; 466 alts = &iface->altsetting[fmt->altset_idx];
453 ret = snd_usb_init_sample_rate(subs->stream->chip, subs->interface, alts, fmt, rate); 467 ret = snd_usb_init_sample_rate(subs->stream->chip, fmt->iface, alts, fmt, rate);
454 if (ret < 0) 468 if (ret < 0)
455 return ret; 469 return ret;
456 subs->cur_rate = rate; 470 subs->cur_rate = rate;
@@ -460,12 +474,6 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
460 mutex_lock(&subs->stream->chip->shutdown_mutex); 474 mutex_lock(&subs->stream->chip->shutdown_mutex);
461 /* format changed */ 475 /* format changed */
462 stop_endpoints(subs, 0, 0, 0); 476 stop_endpoints(subs, 0, 0, 0);
463 deactivate_endpoints(subs);
464
465 ret = activate_endpoints(subs);
466 if (ret < 0)
467 goto unlock;
468
469 ret = snd_usb_endpoint_set_params(subs->data_endpoint, hw_params, fmt, 477 ret = snd_usb_endpoint_set_params(subs->data_endpoint, hw_params, fmt,
470 subs->sync_endpoint); 478 subs->sync_endpoint);
471 if (ret < 0) 479 if (ret < 0)
@@ -500,6 +508,7 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
500 subs->period_bytes = 0; 508 subs->period_bytes = 0;
501 mutex_lock(&subs->stream->chip->shutdown_mutex); 509 mutex_lock(&subs->stream->chip->shutdown_mutex);
502 stop_endpoints(subs, 0, 1, 1); 510 stop_endpoints(subs, 0, 1, 1);
511 deactivate_endpoints(subs);
503 mutex_unlock(&subs->stream->chip->shutdown_mutex); 512 mutex_unlock(&subs->stream->chip->shutdown_mutex);
504 return snd_pcm_lib_free_vmalloc_buffer(substream); 513 return snd_pcm_lib_free_vmalloc_buffer(substream);
505} 514}
@@ -938,16 +947,20 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
938 947
939static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) 948static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
940{ 949{
941 int ret;
942 struct snd_usb_stream *as = snd_pcm_substream_chip(substream); 950 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
943 struct snd_usb_substream *subs = &as->substream[direction]; 951 struct snd_usb_substream *subs = &as->substream[direction];
944 952
945 stop_endpoints(subs, 0, 0, 0); 953 stop_endpoints(subs, 0, 0, 0);
946 ret = deactivate_endpoints(subs); 954
955 if (!as->chip->shutdown && subs->interface >= 0) {
956 usb_set_interface(subs->dev, subs->interface, 0);
957 subs->interface = -1;
958 }
959
947 subs->pcm_substream = NULL; 960 subs->pcm_substream = NULL;
948 snd_usb_autosuspend(subs->stream->chip); 961 snd_usb_autosuspend(subs->stream->chip);
949 962
950 return ret; 963 return 0;
951} 964}
952 965
953/* Since a URB can handle only a single linear buffer, we must use double 966/* Since a URB can handle only a single linear buffer, we must use double