aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2014-03-12 19:03:58 -0400
committerMark Brown <broonie@linaro.org>2014-03-12 19:03:58 -0400
commitda8ab21cfea80655a0f7bbbc3f2fa0975970b8cb (patch)
tree66d5a4804f0a15b5dc224bb2de9b0d9cb208eb91
parentc6c124225f9551d78a19c291a2e204618f7e1e92 (diff)
parent5c1d5f091dc39eecf9a34a8be01492d14c23ad91 (diff)
Merge remote-tracking branch 'asoc/topic/core' into asoc-next
-rw-r--r--drivers/base/regmap/regmap.c12
-rw-r--r--include/linux/regmap.h9
-rw-r--r--include/sound/soc-dai.h1
-rw-r--r--include/sound/soc.h24
-rw-r--r--sound/soc/codecs/adav80x.c4
-rw-r--r--sound/soc/codecs/tlv320aic23.c2
-rw-r--r--sound/soc/codecs/tlv320dac33.c2
-rw-r--r--sound/soc/codecs/uda1380.c2
-rw-r--r--sound/soc/codecs/wl1273.c2
-rw-r--r--sound/soc/codecs/wm8711.c2
-rw-r--r--sound/soc/codecs/wm8753.c4
-rw-r--r--sound/soc/soc-cache.c13
-rw-r--r--sound/soc/soc-compress.c65
-rw-r--r--sound/soc/soc-core.c285
-rw-r--r--sound/soc/soc-pcm.c109
15 files changed, 275 insertions, 261 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 6a19515f8a45..4b2ed0c9e80d 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -2240,6 +2240,18 @@ int regmap_get_val_bytes(struct regmap *map)
2240} 2240}
2241EXPORT_SYMBOL_GPL(regmap_get_val_bytes); 2241EXPORT_SYMBOL_GPL(regmap_get_val_bytes);
2242 2242
2243int regmap_parse_val(struct regmap *map, const void *buf,
2244 unsigned int *val)
2245{
2246 if (!map->format.parse_val)
2247 return -EINVAL;
2248
2249 *val = map->format.parse_val(buf);
2250
2251 return 0;
2252}
2253EXPORT_SYMBOL_GPL(regmap_parse_val);
2254
2243static int __init regmap_initcall(void) 2255static int __init regmap_initcall(void)
2244{ 2256{
2245 regmap_debugfs_initcall(); 2257 regmap_debugfs_initcall();
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 4149f1a9b003..3e1a2e4a92ad 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -423,6 +423,8 @@ bool regmap_check_range_table(struct regmap *map, unsigned int reg,
423 423
424int regmap_register_patch(struct regmap *map, const struct reg_default *regs, 424int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
425 int num_regs); 425 int num_regs);
426int regmap_parse_val(struct regmap *map, const void *buf,
427 unsigned int *val);
426 428
427static inline bool regmap_reg_in_range(unsigned int reg, 429static inline bool regmap_reg_in_range(unsigned int reg,
428 const struct regmap_range *range) 430 const struct regmap_range *range)
@@ -695,6 +697,13 @@ static inline int regmap_register_patch(struct regmap *map,
695 return -EINVAL; 697 return -EINVAL;
696} 698}
697 699
700static inline int regmap_parse_val(struct regmap *map, const void *buf,
701 unsigned int *val)
702{
703 WARN_ONCE(1, "regmap API is disabled");
704 return -EINVAL;
705}
706
698static inline struct regmap *dev_get_regmap(struct device *dev, 707static inline struct regmap *dev_get_regmap(struct device *dev,
699 const char *name) 708 const char *name)
700{ 709{
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 71f27c403194..8763e539c487 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -270,6 +270,7 @@ struct snd_soc_dai {
270 /* parent platform/codec */ 270 /* parent platform/codec */
271 struct snd_soc_platform *platform; 271 struct snd_soc_platform *platform;
272 struct snd_soc_codec *codec; 272 struct snd_soc_codec *codec;
273 struct snd_soc_component *component;
273 274
274 struct snd_soc_card *card; 275 struct snd_soc_card *card;
275 276
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 9a001472b96a..37b470c1e127 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -413,6 +413,10 @@ struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
413struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card, 413struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card,
414 const char *dai_link); 414 const char *dai_link);
415 415
416bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd);
417void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream);
418void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream);
419
416/* Utility functions to get clock rates from various things */ 420/* Utility functions to get clock rates from various things */
417int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots); 421int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
418int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params); 422int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params);
@@ -656,12 +660,19 @@ struct snd_soc_component {
656 const char *name; 660 const char *name;
657 int id; 661 int id;
658 struct device *dev; 662 struct device *dev;
663
664 unsigned int active;
665
666 unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
667
659 struct list_head list; 668 struct list_head list;
660 669
661 struct snd_soc_dai_driver *dai_drv; 670 struct snd_soc_dai_driver *dai_drv;
662 int num_dai; 671 int num_dai;
663 672
664 const struct snd_soc_component_driver *driver; 673 const struct snd_soc_component_driver *driver;
674
675 struct list_head dai_list;
665}; 676};
666 677
667/* SoC Audio Codec device */ 678/* SoC Audio Codec device */
@@ -683,7 +694,6 @@ struct snd_soc_codec {
683 694
684 /* runtime */ 695 /* runtime */
685 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ 696 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */
686 unsigned int active;
687 unsigned int cache_bypass:1; /* Suppress access to the cache */ 697 unsigned int cache_bypass:1; /* Suppress access to the cache */
688 unsigned int suspended:1; /* Codec is in suspend PM state */ 698 unsigned int suspended:1; /* Codec is in suspend PM state */
689 unsigned int probed:1; /* Codec has been probed */ 699 unsigned int probed:1; /* Codec has been probed */
@@ -709,7 +719,6 @@ struct snd_soc_codec {
709 719
710 /* dapm */ 720 /* dapm */
711 struct snd_soc_dapm_context dapm; 721 struct snd_soc_dapm_context dapm;
712 unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
713 722
714#ifdef CONFIG_DEBUG_FS 723#ifdef CONFIG_DEBUG_FS
715 struct dentry *debugfs_codec_root; 724 struct dentry *debugfs_codec_root;
@@ -1168,6 +1177,17 @@ static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc)
1168 return 1; 1177 return 1;
1169} 1178}
1170 1179
1180static inline bool snd_soc_component_is_active(
1181 struct snd_soc_component *component)
1182{
1183 return component->active != 0;
1184}
1185
1186static inline bool snd_soc_codec_is_active(struct snd_soc_codec *codec)
1187{
1188 return snd_soc_component_is_active(&codec->component);
1189}
1190
1171int snd_soc_util_init(void); 1191int snd_soc_util_init(void);
1172void snd_soc_util_exit(void); 1192void snd_soc_util_exit(void);
1173 1193
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index f78b27a7c461..d50cf5b29a27 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -722,7 +722,7 @@ static int adav80x_dai_startup(struct snd_pcm_substream *substream,
722 struct snd_soc_codec *codec = dai->codec; 722 struct snd_soc_codec *codec = dai->codec;
723 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); 723 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
724 724
725 if (!codec->active || !adav80x->rate) 725 if (!snd_soc_codec_is_active(codec) || !adav80x->rate)
726 return 0; 726 return 0;
727 727
728 return snd_pcm_hw_constraint_minmax(substream->runtime, 728 return snd_pcm_hw_constraint_minmax(substream->runtime,
@@ -735,7 +735,7 @@ static void adav80x_dai_shutdown(struct snd_pcm_substream *substream,
735 struct snd_soc_codec *codec = dai->codec; 735 struct snd_soc_codec *codec = dai->codec;
736 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); 736 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
737 737
738 if (!codec->active) 738 if (!snd_soc_codec_is_active(codec))
739 adav80x->rate = 0; 739 adav80x->rate = 0;
740} 740}
741 741
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 5d430cc56f51..458a6aed203e 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -400,7 +400,7 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
400 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); 400 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
401 401
402 /* deactivate */ 402 /* deactivate */
403 if (!codec->active) { 403 if (!snd_soc_codec_is_active(codec)) {
404 udelay(50); 404 udelay(50);
405 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0); 405 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
406 } 406 }
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 4f358393d6d6..35b2d244e42e 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -461,7 +461,7 @@ static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol,
461 if (dac33->fifo_mode == ucontrol->value.integer.value[0]) 461 if (dac33->fifo_mode == ucontrol->value.integer.value[0])
462 return 0; 462 return 0;
463 /* Do not allow changes while stream is running*/ 463 /* Do not allow changes while stream is running*/
464 if (codec->active) 464 if (snd_soc_codec_is_active(codec))
465 return -EPERM; 465 return -EPERM;
466 466
467 if (ucontrol->value.integer.value[0] < 0 || 467 if (ucontrol->value.integer.value[0] < 0 ||
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 726df6d43c2b..8e3940dcff20 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -108,7 +108,7 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
108 /* the interpolator & decimator regs must only be written when the 108 /* the interpolator & decimator regs must only be written when the
109 * codec DAI is active. 109 * codec DAI is active.
110 */ 110 */
111 if (!codec->active && (reg >= UDA1380_MVOL)) 111 if (!snd_soc_codec_is_active(codec) && (reg >= UDA1380_MVOL))
112 return 0; 112 return 0;
113 pr_debug("uda1380: hw write %x val %x\n", reg, value); 113 pr_debug("uda1380: hw write %x val %x\n", reg, value);
114 if (codec->hw_write(codec->control_data, data, 3) == 3) { 114 if (codec->hw_write(codec->control_data, data, 3) == 3) {
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index b7ab2ef567c8..47e96ff30064 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -197,7 +197,7 @@ static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol,
197 return 0; 197 return 0;
198 198
199 /* Do not allow changes while stream is running */ 199 /* Do not allow changes while stream is running */
200 if (codec->active) 200 if (snd_soc_codec_is_active(codec))
201 return -EPERM; 201 return -EPERM;
202 202
203 if (ucontrol->value.integer.value[0] < 0 || 203 if (ucontrol->value.integer.value[0] < 0 ||
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index d99f948c513c..6efcc40a7cb3 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -201,7 +201,7 @@ static void wm8711_shutdown(struct snd_pcm_substream *substream,
201 struct snd_soc_codec *codec = dai->codec; 201 struct snd_soc_codec *codec = dai->codec;
202 202
203 /* deactivate */ 203 /* deactivate */
204 if (!codec->active) { 204 if (!snd_soc_codec_is_active(codec)) {
205 udelay(50); 205 udelay(50);
206 snd_soc_write(codec, WM8711_ACTIVE, 0x0); 206 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
207 } 207 }
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index be85da93a268..5cf4bebc5d89 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -251,7 +251,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
251 if (wm8753->dai_func == ucontrol->value.integer.value[0]) 251 if (wm8753->dai_func == ucontrol->value.integer.value[0])
252 return 0; 252 return 0;
253 253
254 if (codec->active) 254 if (snd_soc_codec_is_active(codec))
255 return -EBUSY; 255 return -EBUSY;
256 256
257 ioctl = snd_soc_read(codec, WM8753_IOCTL); 257 ioctl = snd_soc_read(codec, WM8753_IOCTL);
@@ -1314,7 +1314,7 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
1314 /* the digital mute covers the HiFi and Voice DAC's on the WM8753. 1314 /* the digital mute covers the HiFi and Voice DAC's on the WM8753.
1315 * make sure we check if they are not both active when we mute */ 1315 * make sure we check if they are not both active when we mute */
1316 if (mute && wm8753->dai_func == 1) { 1316 if (mute && wm8753->dai_func == 1) {
1317 if (!codec->active) 1317 if (!snd_soc_codec_is_active(codec))
1318 snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8); 1318 snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
1319 } else { 1319 } else {
1320 if (mute) 1320 if (mute)
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 375dc6dfba4e..bfed3e4c45ff 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -96,8 +96,7 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec)
96{ 96{
97 dev_dbg(codec->dev, "ASoC: Destroying cache for %s codec\n", 97 dev_dbg(codec->dev, "ASoC: Destroying cache for %s codec\n",
98 codec->name); 98 codec->name);
99 if (!codec->reg_cache) 99
100 return 0;
101 kfree(codec->reg_cache); 100 kfree(codec->reg_cache);
102 codec->reg_cache = NULL; 101 codec->reg_cache = NULL;
103 return 0; 102 return 0;
@@ -117,8 +116,9 @@ int snd_soc_cache_read(struct snd_soc_codec *codec,
117 return -EINVAL; 116 return -EINVAL;
118 117
119 mutex_lock(&codec->cache_rw_mutex); 118 mutex_lock(&codec->cache_rw_mutex);
120 *value = snd_soc_get_cache_val(codec->reg_cache, reg, 119 if (!ZERO_OR_NULL_PTR(codec->reg_cache))
121 codec->driver->reg_word_size); 120 *value = snd_soc_get_cache_val(codec->reg_cache, reg,
121 codec->driver->reg_word_size);
122 mutex_unlock(&codec->cache_rw_mutex); 122 mutex_unlock(&codec->cache_rw_mutex);
123 123
124 return 0; 124 return 0;
@@ -136,8 +136,9 @@ int snd_soc_cache_write(struct snd_soc_codec *codec,
136 unsigned int reg, unsigned int value) 136 unsigned int reg, unsigned int value)
137{ 137{
138 mutex_lock(&codec->cache_rw_mutex); 138 mutex_lock(&codec->cache_rw_mutex);
139 snd_soc_set_cache_val(codec->reg_cache, reg, value, 139 if (!ZERO_OR_NULL_PTR(codec->reg_cache))
140 codec->driver->reg_word_size); 140 snd_soc_set_cache_val(codec->reg_cache, reg, value,
141 codec->driver->reg_word_size);
141 mutex_unlock(&codec->cache_rw_mutex); 142 mutex_unlock(&codec->cache_rw_mutex);
142 143
143 return 0; 144 return 0;
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 5e9690c85d8f..91083e6a6b38 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -30,8 +30,6 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
30{ 30{
31 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 31 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
32 struct snd_soc_platform *platform = rtd->platform; 32 struct snd_soc_platform *platform = rtd->platform;
33 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
34 struct snd_soc_dai *codec_dai = rtd->codec_dai;
35 int ret = 0; 33 int ret = 0;
36 34
37 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 35 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@@ -52,17 +50,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
52 } 50 }
53 } 51 }
54 52
55 if (cstream->direction == SND_COMPRESS_PLAYBACK) { 53 snd_soc_runtime_activate(rtd, cstream->direction);
56 cpu_dai->playback_active++;
57 codec_dai->playback_active++;
58 } else {
59 cpu_dai->capture_active++;
60 codec_dai->capture_active++;
61 }
62
63 cpu_dai->active++;
64 codec_dai->active++;
65 rtd->codec->active++;
66 54
67 mutex_unlock(&rtd->pcm_mutex); 55 mutex_unlock(&rtd->pcm_mutex);
68 56
@@ -81,8 +69,6 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
81 struct snd_soc_pcm_runtime *fe = cstream->private_data; 69 struct snd_soc_pcm_runtime *fe = cstream->private_data;
82 struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream; 70 struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
83 struct snd_soc_platform *platform = fe->platform; 71 struct snd_soc_platform *platform = fe->platform;
84 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
85 struct snd_soc_dai *codec_dai = fe->codec_dai;
86 struct snd_soc_dpcm *dpcm; 72 struct snd_soc_dpcm *dpcm;
87 struct snd_soc_dapm_widget_list *list; 73 struct snd_soc_dapm_widget_list *list;
88 int stream; 74 int stream;
@@ -140,17 +126,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
140 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN; 126 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
141 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 127 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
142 128
143 if (cstream->direction == SND_COMPRESS_PLAYBACK) { 129 snd_soc_runtime_activate(fe, stream);
144 cpu_dai->playback_active++;
145 codec_dai->playback_active++;
146 } else {
147 cpu_dai->capture_active++;
148 codec_dai->capture_active++;
149 }
150
151 cpu_dai->active++;
152 codec_dai->active++;
153 fe->codec->active++;
154 130
155 mutex_unlock(&fe->card->mutex); 131 mutex_unlock(&fe->card->mutex);
156 132
@@ -202,23 +178,18 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
202 struct snd_soc_platform *platform = rtd->platform; 178 struct snd_soc_platform *platform = rtd->platform;
203 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 179 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
204 struct snd_soc_dai *codec_dai = rtd->codec_dai; 180 struct snd_soc_dai *codec_dai = rtd->codec_dai;
205 struct snd_soc_codec *codec = rtd->codec; 181 int stream;
206 182
207 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 183 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
208 184
209 if (cstream->direction == SND_COMPRESS_PLAYBACK) { 185 if (cstream->direction == SND_COMPRESS_PLAYBACK)
210 cpu_dai->playback_active--; 186 stream = SNDRV_PCM_STREAM_PLAYBACK;
211 codec_dai->playback_active--; 187 else
212 } else { 188 stream = SNDRV_PCM_STREAM_CAPTURE;
213 cpu_dai->capture_active--;
214 codec_dai->capture_active--;
215 }
216 189
217 snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction); 190 snd_soc_runtime_deactivate(rtd, stream);
218 191
219 cpu_dai->active--; 192 snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
220 codec_dai->active--;
221 codec->active--;
222 193
223 if (!cpu_dai->active) 194 if (!cpu_dai->active)
224 cpu_dai->rate = 0; 195 cpu_dai->rate = 0;
@@ -235,8 +206,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
235 cpu_dai->runtime = NULL; 206 cpu_dai->runtime = NULL;
236 207
237 if (cstream->direction == SND_COMPRESS_PLAYBACK) { 208 if (cstream->direction == SND_COMPRESS_PLAYBACK) {
238 if (!rtd->pmdown_time || codec->ignore_pmdown_time || 209 if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
239 rtd->dai_link->ignore_pmdown_time) {
240 snd_soc_dapm_stream_event(rtd, 210 snd_soc_dapm_stream_event(rtd,
241 SNDRV_PCM_STREAM_PLAYBACK, 211 SNDRV_PCM_STREAM_PLAYBACK,
242 SND_SOC_DAPM_STREAM_STOP); 212 SND_SOC_DAPM_STREAM_STOP);
@@ -261,26 +231,17 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
261{ 231{
262 struct snd_soc_pcm_runtime *fe = cstream->private_data; 232 struct snd_soc_pcm_runtime *fe = cstream->private_data;
263 struct snd_soc_platform *platform = fe->platform; 233 struct snd_soc_platform *platform = fe->platform;
264 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
265 struct snd_soc_dai *codec_dai = fe->codec_dai;
266 struct snd_soc_dpcm *dpcm; 234 struct snd_soc_dpcm *dpcm;
267 int stream, ret; 235 int stream, ret;
268 236
269 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 237 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
270 238
271 if (cstream->direction == SND_COMPRESS_PLAYBACK) { 239 if (cstream->direction == SND_COMPRESS_PLAYBACK)
272 stream = SNDRV_PCM_STREAM_PLAYBACK; 240 stream = SNDRV_PCM_STREAM_PLAYBACK;
273 cpu_dai->playback_active--; 241 else
274 codec_dai->playback_active--;
275 } else {
276 stream = SNDRV_PCM_STREAM_CAPTURE; 242 stream = SNDRV_PCM_STREAM_CAPTURE;
277 cpu_dai->capture_active--;
278 codec_dai->capture_active--;
279 }
280 243
281 cpu_dai->active--; 244 snd_soc_runtime_deactivate(fe, stream);
282 codec_dai->active--;
283 fe->codec->active--;
284 245
285 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; 246 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
286 247
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index fe1df50805a3..a78bba4d52fb 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -56,7 +56,6 @@ EXPORT_SYMBOL_GPL(snd_soc_debugfs_root);
56#endif 56#endif
57 57
58static DEFINE_MUTEX(client_mutex); 58static DEFINE_MUTEX(client_mutex);
59static LIST_HEAD(dai_list);
60static LIST_HEAD(platform_list); 59static LIST_HEAD(platform_list);
61static LIST_HEAD(codec_list); 60static LIST_HEAD(codec_list);
62static LIST_HEAD(component_list); 61static LIST_HEAD(component_list);
@@ -370,18 +369,22 @@ static ssize_t dai_list_read_file(struct file *file, char __user *user_buf,
370{ 369{
371 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 370 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
372 ssize_t len, ret = 0; 371 ssize_t len, ret = 0;
372 struct snd_soc_component *component;
373 struct snd_soc_dai *dai; 373 struct snd_soc_dai *dai;
374 374
375 if (!buf) 375 if (!buf)
376 return -ENOMEM; 376 return -ENOMEM;
377 377
378 list_for_each_entry(dai, &dai_list, list) { 378 list_for_each_entry(component, &component_list, list) {
379 len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", dai->name); 379 list_for_each_entry(dai, &component->dai_list, list) {
380 if (len >= 0) 380 len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
381 ret += len; 381 dai->name);
382 if (ret > PAGE_SIZE) { 382 if (len >= 0)
383 ret = PAGE_SIZE; 383 ret += len;
384 break; 384 if (ret > PAGE_SIZE) {
385 ret = PAGE_SIZE;
386 break;
387 }
385 } 388 }
386 } 389 }
387 390
@@ -855,6 +858,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
855{ 858{
856 struct snd_soc_dai_link *dai_link = &card->dai_link[num]; 859 struct snd_soc_dai_link *dai_link = &card->dai_link[num];
857 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 860 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
861 struct snd_soc_component *component;
858 struct snd_soc_codec *codec; 862 struct snd_soc_codec *codec;
859 struct snd_soc_platform *platform; 863 struct snd_soc_platform *platform;
860 struct snd_soc_dai *codec_dai, *cpu_dai; 864 struct snd_soc_dai *codec_dai, *cpu_dai;
@@ -863,18 +867,20 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
863 dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); 867 dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num);
864 868
865 /* Find CPU DAI from registered DAIs*/ 869 /* Find CPU DAI from registered DAIs*/
866 list_for_each_entry(cpu_dai, &dai_list, list) { 870 list_for_each_entry(component, &component_list, list) {
867 if (dai_link->cpu_of_node && 871 if (dai_link->cpu_of_node &&
868 (cpu_dai->dev->of_node != dai_link->cpu_of_node)) 872 component->dev->of_node != dai_link->cpu_of_node)
869 continue; 873 continue;
870 if (dai_link->cpu_name && 874 if (dai_link->cpu_name &&
871 strcmp(dev_name(cpu_dai->dev), dai_link->cpu_name)) 875 strcmp(dev_name(component->dev), dai_link->cpu_name))
872 continue;
873 if (dai_link->cpu_dai_name &&
874 strcmp(cpu_dai->name, dai_link->cpu_dai_name))
875 continue; 876 continue;
877 list_for_each_entry(cpu_dai, &component->dai_list, list) {
878 if (dai_link->cpu_dai_name &&
879 strcmp(cpu_dai->name, dai_link->cpu_dai_name))
880 continue;
876 881
877 rtd->cpu_dai = cpu_dai; 882 rtd->cpu_dai = cpu_dai;
883 }
878 } 884 }
879 885
880 if (!rtd->cpu_dai) { 886 if (!rtd->cpu_dai) {
@@ -899,12 +905,10 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
899 * CODEC found, so find CODEC DAI from registered DAIs from 905 * CODEC found, so find CODEC DAI from registered DAIs from
900 * this CODEC 906 * this CODEC
901 */ 907 */
902 list_for_each_entry(codec_dai, &dai_list, list) { 908 list_for_each_entry(codec_dai, &codec->component.dai_list, list) {
903 if (codec->dev == codec_dai->dev && 909 if (!strcmp(codec_dai->name, dai_link->codec_dai_name)) {
904 !strcmp(codec_dai->name,
905 dai_link->codec_dai_name)) {
906
907 rtd->codec_dai = codec_dai; 910 rtd->codec_dai = codec_dai;
911 break;
908 } 912 }
909 } 913 }
910 914
@@ -1128,12 +1132,8 @@ static int soc_probe_codec(struct snd_soc_card *card,
1128 driver->num_dapm_widgets); 1132 driver->num_dapm_widgets);
1129 1133
1130 /* Create DAPM widgets for each DAI stream */ 1134 /* Create DAPM widgets for each DAI stream */
1131 list_for_each_entry(dai, &dai_list, list) { 1135 list_for_each_entry(dai, &codec->component.dai_list, list)
1132 if (dai->dev != codec->dev)
1133 continue;
1134
1135 snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); 1136 snd_soc_dapm_new_dai_widgets(&codec->dapm, dai);
1136 }
1137 1137
1138 codec->dapm.idle_bias_off = driver->idle_bias_off; 1138 codec->dapm.idle_bias_off = driver->idle_bias_off;
1139 1139
@@ -1180,6 +1180,7 @@ static int soc_probe_platform(struct snd_soc_card *card,
1180{ 1180{
1181 int ret = 0; 1181 int ret = 0;
1182 const struct snd_soc_platform_driver *driver = platform->driver; 1182 const struct snd_soc_platform_driver *driver = platform->driver;
1183 struct snd_soc_component *component;
1183 struct snd_soc_dai *dai; 1184 struct snd_soc_dai *dai;
1184 1185
1185 platform->card = card; 1186 platform->card = card;
@@ -1195,11 +1196,11 @@ static int soc_probe_platform(struct snd_soc_card *card,
1195 driver->dapm_widgets, driver->num_dapm_widgets); 1196 driver->dapm_widgets, driver->num_dapm_widgets);
1196 1197
1197 /* Create DAPM widgets for each DAI stream */ 1198 /* Create DAPM widgets for each DAI stream */
1198 list_for_each_entry(dai, &dai_list, list) { 1199 list_for_each_entry(component, &component_list, list) {
1199 if (dai->dev != platform->dev) 1200 if (component->dev != platform->dev)
1200 continue; 1201 continue;
1201 1202 list_for_each_entry(dai, &component->dai_list, list)
1202 snd_soc_dapm_new_dai_widgets(&platform->dapm, dai); 1203 snd_soc_dapm_new_dai_widgets(&platform->dapm, dai);
1203 } 1204 }
1204 1205
1205 platform->dapm.idle_bias_off = 1; 1206 platform->dapm.idle_bias_off = 1;
@@ -2818,7 +2819,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
2818 unsigned int mask = (1 << fls(max)) - 1; 2819 unsigned int mask = (1 << fls(max)) - 1;
2819 unsigned int invert = mc->invert; 2820 unsigned int invert = mc->invert;
2820 int err; 2821 int err;
2821 bool type_2r = 0; 2822 bool type_2r = false;
2822 unsigned int val2 = 0; 2823 unsigned int val2 = 0;
2823 unsigned int val, val_mask; 2824 unsigned int val, val_mask;
2824 2825
@@ -2836,7 +2837,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
2836 val |= val2 << rshift; 2837 val |= val2 << rshift;
2837 } else { 2838 } else {
2838 val2 = val2 << shift; 2839 val2 = val2 << shift;
2839 type_2r = 1; 2840 type_2r = true;
2840 } 2841 }
2841 } 2842 }
2842 err = snd_soc_update_bits_locked(codec, reg, val_mask, val); 2843 err = snd_soc_update_bits_locked(codec, reg, val_mask, val);
@@ -3234,7 +3235,7 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
3234 struct soc_bytes *params = (void *)kcontrol->private_value; 3235 struct soc_bytes *params = (void *)kcontrol->private_value;
3235 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 3236 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
3236 int ret, len; 3237 int ret, len;
3237 unsigned int val; 3238 unsigned int val, mask;
3238 void *data; 3239 void *data;
3239 3240
3240 if (!codec->using_regmap) 3241 if (!codec->using_regmap)
@@ -3264,12 +3265,36 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
3264 ((u8 *)data)[0] |= val; 3265 ((u8 *)data)[0] |= val;
3265 break; 3266 break;
3266 case 2: 3267 case 2:
3267 ((u16 *)data)[0] &= cpu_to_be16(~params->mask); 3268 mask = ~params->mask;
3268 ((u16 *)data)[0] |= cpu_to_be16(val); 3269 ret = regmap_parse_val(codec->control_data,
3270 &mask, &mask);
3271 if (ret != 0)
3272 goto out;
3273
3274 ((u16 *)data)[0] &= mask;
3275
3276 ret = regmap_parse_val(codec->control_data,
3277 &val, &val);
3278 if (ret != 0)
3279 goto out;
3280
3281 ((u16 *)data)[0] |= val;
3269 break; 3282 break;
3270 case 4: 3283 case 4:
3271 ((u32 *)data)[0] &= cpu_to_be32(~params->mask); 3284 mask = ~params->mask;
3272 ((u32 *)data)[0] |= cpu_to_be32(val); 3285 ret = regmap_parse_val(codec->control_data,
3286 &mask, &mask);
3287 if (ret != 0)
3288 goto out;
3289
3290 ((u32 *)data)[0] &= mask;
3291
3292 ret = regmap_parse_val(codec->control_data,
3293 &val, &val);
3294 if (ret != 0)
3295 goto out;
3296
3297 ((u32 *)data)[0] |= val;
3273 break; 3298 break;
3274 default: 3299 default:
3275 ret = -EINVAL; 3300 ret = -EINVAL;
@@ -3626,7 +3651,7 @@ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
3626 return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask, 3651 return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
3627 slots, slot_width); 3652 slots, slot_width);
3628 else 3653 else
3629 return -EINVAL; 3654 return -ENOTSUPP;
3630} 3655}
3631EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot); 3656EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
3632 3657
@@ -3882,95 +3907,42 @@ static inline char *fmt_multiple_name(struct device *dev,
3882} 3907}
3883 3908
3884/** 3909/**
3885 * snd_soc_register_dai - Register a DAI with the ASoC core 3910 * snd_soc_unregister_dai - Unregister DAIs from the ASoC core
3886 * 3911 *
3887 * @dai: DAI to register 3912 * @component: The component for which the DAIs should be unregistered
3888 */ 3913 */
3889static int snd_soc_register_dai(struct device *dev, 3914static void snd_soc_unregister_dais(struct snd_soc_component *component)
3890 struct snd_soc_dai_driver *dai_drv)
3891{ 3915{
3892 struct snd_soc_codec *codec; 3916 struct snd_soc_dai *dai, *_dai;
3893 struct snd_soc_dai *dai;
3894
3895 dev_dbg(dev, "ASoC: dai register %s\n", dev_name(dev));
3896 3917
3897 dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); 3918 list_for_each_entry_safe(dai, _dai, &component->dai_list, list) {
3898 if (dai == NULL) 3919 dev_dbg(component->dev, "ASoC: Unregistered DAI '%s'\n",
3899 return -ENOMEM; 3920 dai->name);
3900 3921 list_del(&dai->list);
3901 /* create DAI component name */ 3922 kfree(dai->name);
3902 dai->name = fmt_single_name(dev, &dai->id);
3903 if (dai->name == NULL) {
3904 kfree(dai); 3923 kfree(dai);
3905 return -ENOMEM;
3906 }
3907
3908 dai->dev = dev;
3909 dai->driver = dai_drv;
3910 dai->dapm.dev = dev;
3911 if (!dai->driver->ops)
3912 dai->driver->ops = &null_dai_ops;
3913
3914 mutex_lock(&client_mutex);
3915
3916 list_for_each_entry(codec, &codec_list, list) {
3917 if (codec->dev == dev) {
3918 dev_dbg(dev, "ASoC: Mapped DAI %s to CODEC %s\n",
3919 dai->name, codec->name);
3920 dai->codec = codec;
3921 break;
3922 }
3923 }
3924
3925 if (!dai->codec)
3926 dai->dapm.idle_bias_off = 1;
3927
3928 list_add(&dai->list, &dai_list);
3929
3930 mutex_unlock(&client_mutex);
3931
3932 dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name);
3933
3934 return 0;
3935}
3936
3937/**
3938 * snd_soc_unregister_dai - Unregister a DAI from the ASoC core
3939 *
3940 * @dai: DAI to unregister
3941 */
3942static void snd_soc_unregister_dai(struct device *dev)
3943{
3944 struct snd_soc_dai *dai;
3945
3946 list_for_each_entry(dai, &dai_list, list) {
3947 if (dev == dai->dev)
3948 goto found;
3949 } 3924 }
3950 return;
3951
3952found:
3953 mutex_lock(&client_mutex);
3954 list_del(&dai->list);
3955 mutex_unlock(&client_mutex);
3956
3957 dev_dbg(dev, "ASoC: Unregistered DAI '%s'\n", dai->name);
3958 kfree(dai->name);
3959 kfree(dai);
3960} 3925}
3961 3926
3962/** 3927/**
3963 * snd_soc_register_dais - Register multiple DAIs with the ASoC core 3928 * snd_soc_register_dais - Register a DAI with the ASoC core
3964 * 3929 *
3965 * @dai: Array of DAIs to register 3930 * @component: The component the DAIs are registered for
3931 * @codec: The CODEC that the DAIs are registered for, NULL if the component is
3932 * not a CODEC.
3933 * @dai_drv: DAI driver to use for the DAIs
3966 * @count: Number of DAIs 3934 * @count: Number of DAIs
3935 * @legacy_dai_naming: Use the legacy naming scheme and let the DAI inherit the
3936 * parent's name.
3967 */ 3937 */
3968static int snd_soc_register_dais(struct device *dev, 3938static int snd_soc_register_dais(struct snd_soc_component *component,
3969 struct snd_soc_dai_driver *dai_drv, size_t count) 3939 struct snd_soc_codec *codec, struct snd_soc_dai_driver *dai_drv,
3940 size_t count, bool legacy_dai_naming)
3970{ 3941{
3971 struct snd_soc_codec *codec; 3942 struct device *dev = component->dev;
3972 struct snd_soc_dai *dai; 3943 struct snd_soc_dai *dai;
3973 int i, ret = 0; 3944 unsigned int i;
3945 int ret;
3974 3946
3975 dev_dbg(dev, "ASoC: dai register %s #%Zu\n", dev_name(dev), count); 3947 dev_dbg(dev, "ASoC: dai register %s #%Zu\n", dev_name(dev), count);
3976 3948
@@ -3982,70 +3954,54 @@ static int snd_soc_register_dais(struct device *dev,
3982 goto err; 3954 goto err;
3983 } 3955 }
3984 3956
3985 /* create DAI component name */ 3957 /*
3986 dai->name = fmt_multiple_name(dev, &dai_drv[i]); 3958 * Back in the old days when we still had component-less DAIs,
3959 * instead of having a static name, component-less DAIs would
3960 * inherit the name of the parent device so it is possible to
3961 * register multiple instances of the DAI. We still need to keep
3962 * the same naming style even though those DAIs are not
3963 * component-less anymore.
3964 */
3965 if (count == 1 && legacy_dai_naming) {
3966 dai->name = fmt_single_name(dev, &dai->id);
3967 } else {
3968 dai->name = fmt_multiple_name(dev, &dai_drv[i]);
3969 if (dai_drv[i].id)
3970 dai->id = dai_drv[i].id;
3971 else
3972 dai->id = i;
3973 }
3987 if (dai->name == NULL) { 3974 if (dai->name == NULL) {
3988 kfree(dai); 3975 kfree(dai);
3989 ret = -EINVAL; 3976 ret = -ENOMEM;
3990 goto err; 3977 goto err;
3991 } 3978 }
3992 3979
3980 dai->component = component;
3981 dai->codec = codec;
3993 dai->dev = dev; 3982 dai->dev = dev;
3994 dai->driver = &dai_drv[i]; 3983 dai->driver = &dai_drv[i];
3995 if (dai->driver->id)
3996 dai->id = dai->driver->id;
3997 else
3998 dai->id = i;
3999 dai->dapm.dev = dev; 3984 dai->dapm.dev = dev;
4000 if (!dai->driver->ops) 3985 if (!dai->driver->ops)
4001 dai->driver->ops = &null_dai_ops; 3986 dai->driver->ops = &null_dai_ops;
4002 3987
4003 mutex_lock(&client_mutex);
4004
4005 list_for_each_entry(codec, &codec_list, list) {
4006 if (codec->dev == dev) {
4007 dev_dbg(dev,
4008 "ASoC: Mapped DAI %s to CODEC %s\n",
4009 dai->name, codec->name);
4010 dai->codec = codec;
4011 break;
4012 }
4013 }
4014
4015 if (!dai->codec) 3988 if (!dai->codec)
4016 dai->dapm.idle_bias_off = 1; 3989 dai->dapm.idle_bias_off = 1;
4017 3990
4018 list_add(&dai->list, &dai_list); 3991 list_add(&dai->list, &component->dai_list);
4019
4020 mutex_unlock(&client_mutex);
4021 3992
4022 dev_dbg(dai->dev, "ASoC: Registered DAI '%s'\n", dai->name); 3993 dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name);
4023 } 3994 }
4024 3995
4025 return 0; 3996 return 0;
4026 3997
4027err: 3998err:
4028 for (i--; i >= 0; i--) 3999 snd_soc_unregister_dais(component);
4029 snd_soc_unregister_dai(dev);
4030 4000
4031 return ret; 4001 return ret;
4032} 4002}
4033 4003
4034/** 4004/**
4035 * snd_soc_unregister_dais - Unregister multiple DAIs from the ASoC core
4036 *
4037 * @dai: Array of DAIs to unregister
4038 * @count: Number of DAIs
4039 */
4040static void snd_soc_unregister_dais(struct device *dev, size_t count)
4041{
4042 int i;
4043
4044 for (i = 0; i < count; i++)
4045 snd_soc_unregister_dai(dev);
4046}
4047
4048/**
4049 * snd_soc_register_component - Register a component with the ASoC core 4005 * snd_soc_register_component - Register a component with the ASoC core
4050 * 4006 *
4051 */ 4007 */
@@ -4053,6 +4009,7 @@ static int
4053__snd_soc_register_component(struct device *dev, 4009__snd_soc_register_component(struct device *dev,
4054 struct snd_soc_component *cmpnt, 4010 struct snd_soc_component *cmpnt,
4055 const struct snd_soc_component_driver *cmpnt_drv, 4011 const struct snd_soc_component_driver *cmpnt_drv,
4012 struct snd_soc_codec *codec,
4056 struct snd_soc_dai_driver *dai_drv, 4013 struct snd_soc_dai_driver *dai_drv,
4057 int num_dai, bool allow_single_dai) 4014 int num_dai, bool allow_single_dai)
4058{ 4015{
@@ -4075,20 +4032,10 @@ __snd_soc_register_component(struct device *dev,
4075 cmpnt->driver = cmpnt_drv; 4032 cmpnt->driver = cmpnt_drv;
4076 cmpnt->dai_drv = dai_drv; 4033 cmpnt->dai_drv = dai_drv;
4077 cmpnt->num_dai = num_dai; 4034 cmpnt->num_dai = num_dai;
4035 INIT_LIST_HEAD(&cmpnt->dai_list);
4078 4036
4079 /* 4037 ret = snd_soc_register_dais(cmpnt, codec, dai_drv, num_dai,
4080 * snd_soc_register_dai() uses fmt_single_name(), and 4038 allow_single_dai);
4081 * snd_soc_register_dais() uses fmt_multiple_name()
4082 * for dai->name which is used for name based matching
4083 *
4084 * this function is used from cpu/codec.
4085 * allow_single_dai flag can ignore "codec" driver reworking
4086 * since it had been used snd_soc_register_dais(),
4087 */
4088 if ((1 == num_dai) && allow_single_dai)
4089 ret = snd_soc_register_dai(dev, dai_drv);
4090 else
4091 ret = snd_soc_register_dais(dev, dai_drv, num_dai);
4092 if (ret < 0) { 4039 if (ret < 0) {
4093 dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret); 4040 dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret);
4094 goto error_component_name; 4041 goto error_component_name;
@@ -4121,7 +4068,9 @@ int snd_soc_register_component(struct device *dev,
4121 return -ENOMEM; 4068 return -ENOMEM;
4122 } 4069 }
4123 4070
4124 return __snd_soc_register_component(dev, cmpnt, cmpnt_drv, 4071 cmpnt->ignore_pmdown_time = true;
4072
4073 return __snd_soc_register_component(dev, cmpnt, cmpnt_drv, NULL,
4125 dai_drv, num_dai, true); 4074 dai_drv, num_dai, true);
4126} 4075}
4127EXPORT_SYMBOL_GPL(snd_soc_register_component); 4076EXPORT_SYMBOL_GPL(snd_soc_register_component);
@@ -4141,7 +4090,7 @@ void snd_soc_unregister_component(struct device *dev)
4141 return; 4090 return;
4142 4091
4143found: 4092found:
4144 snd_soc_unregister_dais(dev, cmpnt->num_dai); 4093 snd_soc_unregister_dais(cmpnt);
4145 4094
4146 mutex_lock(&client_mutex); 4095 mutex_lock(&client_mutex);
4147 list_del(&cmpnt->list); 4096 list_del(&cmpnt->list);
@@ -4319,7 +4268,7 @@ int snd_soc_register_codec(struct device *dev,
4319 codec->volatile_register = codec_drv->volatile_register; 4268 codec->volatile_register = codec_drv->volatile_register;
4320 codec->readable_register = codec_drv->readable_register; 4269 codec->readable_register = codec_drv->readable_register;
4321 codec->writable_register = codec_drv->writable_register; 4270 codec->writable_register = codec_drv->writable_register;
4322 codec->ignore_pmdown_time = codec_drv->ignore_pmdown_time; 4271 codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time;
4323 codec->dapm.bias_level = SND_SOC_BIAS_OFF; 4272 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
4324 codec->dapm.dev = dev; 4273 codec->dapm.dev = dev;
4325 codec->dapm.codec = codec; 4274 codec->dapm.codec = codec;
@@ -4342,7 +4291,7 @@ int snd_soc_register_codec(struct device *dev,
4342 /* register component */ 4291 /* register component */
4343 ret = __snd_soc_register_component(dev, &codec->component, 4292 ret = __snd_soc_register_component(dev, &codec->component,
4344 &codec_drv->component_driver, 4293 &codec_drv->component_driver,
4345 dai_drv, num_dai, false); 4294 codec, dai_drv, num_dai, false);
4346 if (ret < 0) { 4295 if (ret < 0) {
4347 dev_err(codec->dev, "ASoC: Failed to regster component: %d\n", ret); 4296 dev_err(codec->dev, "ASoC: Failed to regster component: %d\n", ret);
4348 goto fail_codec_name; 4297 goto fail_codec_name;
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 28522bd03b8e..330eaf007d89 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -35,6 +35,86 @@
35#define DPCM_MAX_BE_USERS 8 35#define DPCM_MAX_BE_USERS 8
36 36
37/** 37/**
38 * snd_soc_runtime_activate() - Increment active count for PCM runtime components
39 * @rtd: ASoC PCM runtime that is activated
40 * @stream: Direction of the PCM stream
41 *
42 * Increments the active count for all the DAIs and components attached to a PCM
43 * runtime. Should typically be called when a stream is opened.
44 *
45 * Must be called with the rtd->pcm_mutex being held
46 */
47void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream)
48{
49 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
50 struct snd_soc_dai *codec_dai = rtd->codec_dai;
51
52 lockdep_assert_held(&rtd->pcm_mutex);
53
54 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
55 cpu_dai->playback_active++;
56 codec_dai->playback_active++;
57 } else {
58 cpu_dai->capture_active++;
59 codec_dai->capture_active++;
60 }
61
62 cpu_dai->active++;
63 codec_dai->active++;
64 cpu_dai->component->active++;
65 codec_dai->component->active++;
66}
67
68/**
69 * snd_soc_runtime_deactivate() - Decrement active count for PCM runtime components
70 * @rtd: ASoC PCM runtime that is deactivated
71 * @stream: Direction of the PCM stream
72 *
73 * Decrements the active count for all the DAIs and components attached to a PCM
74 * runtime. Should typically be called when a stream is closed.
75 *
76 * Must be called with the rtd->pcm_mutex being held
77 */
78void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream)
79{
80 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
81 struct snd_soc_dai *codec_dai = rtd->codec_dai;
82
83 lockdep_assert_held(&rtd->pcm_mutex);
84
85 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
86 cpu_dai->playback_active--;
87 codec_dai->playback_active--;
88 } else {
89 cpu_dai->capture_active--;
90 codec_dai->capture_active--;
91 }
92
93 cpu_dai->active--;
94 codec_dai->active--;
95 cpu_dai->component->active--;
96 codec_dai->component->active--;
97}
98
99/**
100 * snd_soc_runtime_ignore_pmdown_time() - Check whether to ignore the power down delay
101 * @rtd: The ASoC PCM runtime that should be checked.
102 *
103 * This function checks whether the power down delay should be ignored for a
104 * specific PCM runtime. Returns true if the delay is 0, if it the DAI link has
105 * been configured to ignore the delay, or if none of the components benefits
106 * from having the delay.
107 */
108bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd)
109{
110 if (!rtd->pmdown_time || rtd->dai_link->ignore_pmdown_time)
111 return true;
112
113 return rtd->cpu_dai->component->ignore_pmdown_time &&
114 rtd->codec_dai->component->ignore_pmdown_time;
115}
116
117/**
38 * snd_soc_set_runtime_hwparams - set the runtime hardware parameters 118 * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
39 * @substream: the pcm substream 119 * @substream: the pcm substream
40 * @hw: the hardware parameters 120 * @hw: the hardware parameters
@@ -378,16 +458,9 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
378 runtime->hw.rate_max); 458 runtime->hw.rate_max);
379 459
380dynamic: 460dynamic:
381 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 461
382 cpu_dai->playback_active++; 462 snd_soc_runtime_activate(rtd, substream->stream);
383 codec_dai->playback_active++; 463
384 } else {
385 cpu_dai->capture_active++;
386 codec_dai->capture_active++;
387 }
388 cpu_dai->active++;
389 codec_dai->active++;
390 rtd->codec->active++;
391 mutex_unlock(&rtd->pcm_mutex); 464 mutex_unlock(&rtd->pcm_mutex);
392 return 0; 465 return 0;
393 466
@@ -459,21 +532,10 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
459 struct snd_soc_platform *platform = rtd->platform; 532 struct snd_soc_platform *platform = rtd->platform;
460 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 533 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
461 struct snd_soc_dai *codec_dai = rtd->codec_dai; 534 struct snd_soc_dai *codec_dai = rtd->codec_dai;
462 struct snd_soc_codec *codec = rtd->codec;
463 535
464 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 536 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
465 537
466 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 538 snd_soc_runtime_deactivate(rtd, substream->stream);
467 cpu_dai->playback_active--;
468 codec_dai->playback_active--;
469 } else {
470 cpu_dai->capture_active--;
471 codec_dai->capture_active--;
472 }
473
474 cpu_dai->active--;
475 codec_dai->active--;
476 codec->active--;
477 539
478 /* clear the corresponding DAIs rate when inactive */ 540 /* clear the corresponding DAIs rate when inactive */
479 if (!cpu_dai->active) 541 if (!cpu_dai->active)
@@ -496,8 +558,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
496 cpu_dai->runtime = NULL; 558 cpu_dai->runtime = NULL;
497 559
498 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 560 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
499 if (!rtd->pmdown_time || codec->ignore_pmdown_time || 561 if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
500 rtd->dai_link->ignore_pmdown_time) {
501 /* powered down playback stream now */ 562 /* powered down playback stream now */
502 snd_soc_dapm_stream_event(rtd, 563 snd_soc_dapm_stream_event(rtd,
503 SNDRV_PCM_STREAM_PLAYBACK, 564 SNDRV_PCM_STREAM_PLAYBACK,