aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2014-03-13 05:40:56 -0400
committerMark Brown <broonie@linaro.org>2014-03-13 05:40:56 -0400
commit7a87ac1f66800460e82b7ff3286dfec1c5bb9b84 (patch)
tree5907ca9eee5d390d6817b5625780aa1505a6a132 /sound
parenta9576cbbbafa2c687121638dadebfb136562a522 (diff)
parente95d73c437a09e7febea18f8e998f958ef6d7a72 (diff)
Merge branch 'topic/dapm' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-pxa
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/adav80x.c17
-rw-r--r--sound/soc/codecs/wm5100.c12
-rw-r--r--sound/soc/codecs/wm8962.c13
-rw-r--r--sound/soc/codecs/wm8994.c45
-rw-r--r--sound/soc/codecs/wm8996.c9
-rw-r--r--sound/soc/intel/mfld_machine.c65
-rw-r--r--sound/soc/omap/ams-delta.c45
-rw-r--r--sound/soc/omap/n810.c22
-rw-r--r--sound/soc/omap/rx51.c22
-rw-r--r--sound/soc/pxa/corgi.c42
-rw-r--r--sound/soc/pxa/magician.c22
-rw-r--r--sound/soc/pxa/spitz.c51
-rw-r--r--sound/soc/pxa/tosa.c28
-rw-r--r--sound/soc/soc-dapm.c241
14 files changed, 438 insertions, 196 deletions
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index f78b27a7c461..ab790d5fe53d 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -541,6 +541,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
541 unsigned int freq, int dir) 541 unsigned int freq, int dir)
542{ 542{
543 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); 543 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
544 struct snd_soc_dapm_context *dapm = &codec->dapm;
544 545
545 if (dir == SND_SOC_CLOCK_IN) { 546 if (dir == SND_SOC_CLOCK_IN) {
546 switch (clk_id) { 547 switch (clk_id) {
@@ -573,7 +574,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
573 regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL2, 574 regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL2,
574 iclk_ctrl2); 575 iclk_ctrl2);
575 576
576 snd_soc_dapm_sync(&codec->dapm); 577 snd_soc_dapm_sync(dapm);
577 } 578 }
578 } else { 579 } else {
579 unsigned int mask; 580 unsigned int mask;
@@ -600,17 +601,21 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
600 adav80x->sysclk_pd[clk_id] = false; 601 adav80x->sysclk_pd[clk_id] = false;
601 } 602 }
602 603
604 snd_soc_dapm_mutex_lock(dapm);
605
603 if (adav80x->sysclk_pd[0]) 606 if (adav80x->sysclk_pd[0])
604 snd_soc_dapm_disable_pin(&codec->dapm, "PLL1"); 607 snd_soc_dapm_disable_pin_unlocked(dapm, "PLL1");
605 else 608 else
606 snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1"); 609 snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL1");
607 610
608 if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2]) 611 if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2])
609 snd_soc_dapm_disable_pin(&codec->dapm, "PLL2"); 612 snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2");
610 else 613 else
611 snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2"); 614 snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2");
612 615
613 snd_soc_dapm_sync(&codec->dapm); 616 snd_soc_dapm_sync_unlocked(dapm);
617
618 snd_soc_dapm_mutex_unlock(dapm);
614 } 619 }
615 620
616 return 0; 621 return 0;
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 4e3e31aaf509..492fe846ae68 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -2100,6 +2100,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2100int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) 2100int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
2101{ 2101{
2102 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); 2102 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2103 struct snd_soc_dapm_context *dapm = &codec->dapm;
2103 2104
2104 if (jack) { 2105 if (jack) {
2105 wm5100->jack = jack; 2106 wm5100->jack = jack;
@@ -2117,9 +2118,14 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
2117 WM5100_ACCDET_RATE_MASK); 2118 WM5100_ACCDET_RATE_MASK);
2118 2119
2119 /* We need the charge pump to power MICBIAS */ 2120 /* We need the charge pump to power MICBIAS */
2120 snd_soc_dapm_force_enable_pin(&codec->dapm, "CP2"); 2121 snd_soc_dapm_mutex_lock(dapm);
2121 snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); 2122
2122 snd_soc_dapm_sync(&codec->dapm); 2123 snd_soc_dapm_force_enable_pin_unlocked(dapm, "CP2");
2124 snd_soc_dapm_force_enable_pin_unlocked(dapm, "SYSCLK");
2125
2126 snd_soc_dapm_sync_unlocked(dapm);
2127
2128 snd_soc_dapm_mutex_unlock(dapm);
2123 2129
2124 /* We start off just enabling microphone detection - even a 2130 /* We start off just enabling microphone detection - even a
2125 * plain headphone will trigger detection. 2131 * plain headphone will trigger detection.
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 97db3b45b411..9e6233633c44 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -3089,6 +3089,7 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3089int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) 3089int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
3090{ 3090{
3091 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 3091 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3092 struct snd_soc_dapm_context *dapm = &codec->dapm;
3092 int irq_mask, enable; 3093 int irq_mask, enable;
3093 3094
3094 wm8962->jack = jack; 3095 wm8962->jack = jack;
@@ -3109,14 +3110,18 @@ int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
3109 snd_soc_jack_report(wm8962->jack, 0, 3110 snd_soc_jack_report(wm8962->jack, 0,
3110 SND_JACK_MICROPHONE | SND_JACK_BTN_0); 3111 SND_JACK_MICROPHONE | SND_JACK_BTN_0);
3111 3112
3113 snd_soc_dapm_mutex_lock(dapm);
3114
3112 if (jack) { 3115 if (jack) {
3113 snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); 3116 snd_soc_dapm_force_enable_pin_unlocked(dapm, "SYSCLK");
3114 snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS"); 3117 snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS");
3115 } else { 3118 } else {
3116 snd_soc_dapm_disable_pin(&codec->dapm, "SYSCLK"); 3119 snd_soc_dapm_disable_pin_unlocked(dapm, "SYSCLK");
3117 snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS"); 3120 snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS");
3118 } 3121 }
3119 3122
3123 snd_soc_dapm_mutex_unlock(dapm);
3124
3120 return 0; 3125 return 0;
3121} 3126}
3122EXPORT_SYMBOL_GPL(wm8962_mic_detect); 3127EXPORT_SYMBOL_GPL(wm8962_mic_detect);
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index b9be9cbc4603..e8daf55d37e3 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -2549,43 +2549,52 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2549int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode) 2549int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode)
2550{ 2550{
2551 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2551 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2552 struct snd_soc_dapm_context *dapm = &codec->dapm;
2552 2553
2553 switch (mode) { 2554 switch (mode) {
2554 case WM8994_VMID_NORMAL: 2555 case WM8994_VMID_NORMAL:
2556 snd_soc_dapm_mutex_lock(dapm);
2557
2555 if (wm8994->hubs.lineout1_se) { 2558 if (wm8994->hubs.lineout1_se) {
2556 snd_soc_dapm_disable_pin(&codec->dapm, 2559 snd_soc_dapm_disable_pin_unlocked(dapm,
2557 "LINEOUT1N Driver"); 2560 "LINEOUT1N Driver");
2558 snd_soc_dapm_disable_pin(&codec->dapm, 2561 snd_soc_dapm_disable_pin_unlocked(dapm,
2559 "LINEOUT1P Driver"); 2562 "LINEOUT1P Driver");
2560 } 2563 }
2561 if (wm8994->hubs.lineout2_se) { 2564 if (wm8994->hubs.lineout2_se) {
2562 snd_soc_dapm_disable_pin(&codec->dapm, 2565 snd_soc_dapm_disable_pin_unlocked(dapm,
2563 "LINEOUT2N Driver"); 2566 "LINEOUT2N Driver");
2564 snd_soc_dapm_disable_pin(&codec->dapm, 2567 snd_soc_dapm_disable_pin_unlocked(dapm,
2565 "LINEOUT2P Driver"); 2568 "LINEOUT2P Driver");
2566 } 2569 }
2567 2570
2568 /* Do the sync with the old mode to allow it to clean up */ 2571 /* Do the sync with the old mode to allow it to clean up */
2569 snd_soc_dapm_sync(&codec->dapm); 2572 snd_soc_dapm_sync_unlocked(dapm);
2570 wm8994->vmid_mode = mode; 2573 wm8994->vmid_mode = mode;
2574
2575 snd_soc_dapm_mutex_unlock(dapm);
2571 break; 2576 break;
2572 2577
2573 case WM8994_VMID_FORCE: 2578 case WM8994_VMID_FORCE:
2579 snd_soc_dapm_mutex_lock(dapm);
2580
2574 if (wm8994->hubs.lineout1_se) { 2581 if (wm8994->hubs.lineout1_se) {
2575 snd_soc_dapm_force_enable_pin(&codec->dapm, 2582 snd_soc_dapm_force_enable_pin_unlocked(dapm,
2576 "LINEOUT1N Driver"); 2583 "LINEOUT1N Driver");
2577 snd_soc_dapm_force_enable_pin(&codec->dapm, 2584 snd_soc_dapm_force_enable_pin_unlocked(dapm,
2578 "LINEOUT1P Driver"); 2585 "LINEOUT1P Driver");
2579 } 2586 }
2580 if (wm8994->hubs.lineout2_se) { 2587 if (wm8994->hubs.lineout2_se) {
2581 snd_soc_dapm_force_enable_pin(&codec->dapm, 2588 snd_soc_dapm_force_enable_pin_unlocked(dapm,
2582 "LINEOUT2N Driver"); 2589 "LINEOUT2N Driver");
2583 snd_soc_dapm_force_enable_pin(&codec->dapm, 2590 snd_soc_dapm_force_enable_pin_unlocked(dapm,
2584 "LINEOUT2P Driver"); 2591 "LINEOUT2P Driver");
2585 } 2592 }
2586 2593
2587 wm8994->vmid_mode = mode; 2594 wm8994->vmid_mode = mode;
2588 snd_soc_dapm_sync(&codec->dapm); 2595 snd_soc_dapm_sync_unlocked(dapm);
2596
2597 snd_soc_dapm_mutex_unlock(dapm);
2589 break; 2598 break;
2590 2599
2591 default: 2600 default:
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index 1a7655b0aa22..d565d0ac7a11 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -2251,6 +2251,7 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2251 wm8996_polarity_fn polarity_cb) 2251 wm8996_polarity_fn polarity_cb)
2252{ 2252{
2253 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 2253 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
2254 struct snd_soc_dapm_context *dapm = &codec->dapm;
2254 2255
2255 wm8996->jack = jack; 2256 wm8996->jack = jack;
2256 wm8996->detecting = true; 2257 wm8996->detecting = true;
@@ -2267,8 +2268,12 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2267 WM8996_MICB2_DISCH, 0); 2268 WM8996_MICB2_DISCH, 0);
2268 2269
2269 /* LDO2 powers the microphones, SYSCLK clocks detection */ 2270 /* LDO2 powers the microphones, SYSCLK clocks detection */
2270 snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2"); 2271 snd_soc_dapm_mutex_lock(dapm);
2271 snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); 2272
2273 snd_soc_dapm_force_enable_pin_unlocked(dapm, "LDO2");
2274 snd_soc_dapm_force_enable_pin_unlocked(dapm, "SYSCLK");
2275
2276 snd_soc_dapm_mutex_unlock(dapm);
2272 2277
2273 /* We start off just enabling microphone detection - even a 2278 /* We start off just enabling microphone detection - even a
2274 * plain headphone will trigger detection. 2279 * plain headphone will trigger detection.
diff --git a/sound/soc/intel/mfld_machine.c b/sound/soc/intel/mfld_machine.c
index d3d4c32434f7..0cef32e9d402 100644
--- a/sound/soc/intel/mfld_machine.c
+++ b/sound/soc/intel/mfld_machine.c
@@ -101,20 +101,27 @@ static int headset_set_switch(struct snd_kcontrol *kcontrol,
101 struct snd_ctl_elem_value *ucontrol) 101 struct snd_ctl_elem_value *ucontrol)
102{ 102{
103 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 103 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
104 struct snd_soc_dapm_context *dapm = &codec->dapm;
104 105
105 if (ucontrol->value.integer.value[0] == hs_switch) 106 if (ucontrol->value.integer.value[0] == hs_switch)
106 return 0; 107 return 0;
107 108
109 snd_soc_dapm_mutex_lock(dapm);
110
108 if (ucontrol->value.integer.value[0]) { 111 if (ucontrol->value.integer.value[0]) {
109 pr_debug("hs_set HS path\n"); 112 pr_debug("hs_set HS path\n");
110 snd_soc_dapm_enable_pin(&codec->dapm, "Headphones"); 113 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphones");
111 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); 114 snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT");
112 } else { 115 } else {
113 pr_debug("hs_set EP path\n"); 116 pr_debug("hs_set EP path\n");
114 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones"); 117 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones");
115 snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT"); 118 snd_soc_dapm_enable_pin_unlocked(dapm, "EPOUT");
116 } 119 }
117 snd_soc_dapm_sync(&codec->dapm); 120
121 snd_soc_dapm_sync_unlocked(dapm);
122
123 snd_soc_dapm_mutex_unlock(dapm);
124
118 hs_switch = ucontrol->value.integer.value[0]; 125 hs_switch = ucontrol->value.integer.value[0];
119 126
120 return 0; 127 return 0;
@@ -122,18 +129,20 @@ static int headset_set_switch(struct snd_kcontrol *kcontrol,
122 129
123static void lo_enable_out_pins(struct snd_soc_codec *codec) 130static void lo_enable_out_pins(struct snd_soc_codec *codec)
124{ 131{
125 snd_soc_dapm_enable_pin(&codec->dapm, "IHFOUTL"); 132 struct snd_soc_dapm_context *dapm = &codec->dapm;
126 snd_soc_dapm_enable_pin(&codec->dapm, "IHFOUTR"); 133
127 snd_soc_dapm_enable_pin(&codec->dapm, "LINEOUTL"); 134 snd_soc_dapm_enable_pin_unlocked(dapm, "IHFOUTL");
128 snd_soc_dapm_enable_pin(&codec->dapm, "LINEOUTR"); 135 snd_soc_dapm_enable_pin_unlocked(dapm, "IHFOUTR");
129 snd_soc_dapm_enable_pin(&codec->dapm, "VIB1OUT"); 136 snd_soc_dapm_enable_pin_unlocked(dapm, "LINEOUTL");
130 snd_soc_dapm_enable_pin(&codec->dapm, "VIB2OUT"); 137 snd_soc_dapm_enable_pin_unlocked(dapm, "LINEOUTR");
138 snd_soc_dapm_enable_pin_unlocked(dapm, "VIB1OUT");
139 snd_soc_dapm_enable_pin_unlocked(dapm, "VIB2OUT");
131 if (hs_switch) { 140 if (hs_switch) {
132 snd_soc_dapm_enable_pin(&codec->dapm, "Headphones"); 141 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphones");
133 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); 142 snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT");
134 } else { 143 } else {
135 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones"); 144 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones");
136 snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT"); 145 snd_soc_dapm_enable_pin_unlocked(dapm, "EPOUT");
137 } 146 }
138} 147}
139 148
@@ -148,44 +157,52 @@ static int lo_set_switch(struct snd_kcontrol *kcontrol,
148 struct snd_ctl_elem_value *ucontrol) 157 struct snd_ctl_elem_value *ucontrol)
149{ 158{
150 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 159 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
160 struct snd_soc_dapm_context *dapm = &codec->dapm;
151 161
152 if (ucontrol->value.integer.value[0] == lo_dac) 162 if (ucontrol->value.integer.value[0] == lo_dac)
153 return 0; 163 return 0;
154 164
165 snd_soc_dapm_mutex_lock(dapm);
166
155 /* we dont want to work with last state of lineout so just enable all 167 /* we dont want to work with last state of lineout so just enable all
156 * pins and then disable pins not required 168 * pins and then disable pins not required
157 */ 169 */
158 lo_enable_out_pins(codec); 170 lo_enable_out_pins(codec);
171
159 switch (ucontrol->value.integer.value[0]) { 172 switch (ucontrol->value.integer.value[0]) {
160 case 0: 173 case 0:
161 pr_debug("set vibra path\n"); 174 pr_debug("set vibra path\n");
162 snd_soc_dapm_disable_pin(&codec->dapm, "VIB1OUT"); 175 snd_soc_dapm_disable_pin_unlocked(dapm, "VIB1OUT");
163 snd_soc_dapm_disable_pin(&codec->dapm, "VIB2OUT"); 176 snd_soc_dapm_disable_pin_unlocked(dapm, "VIB2OUT");
164 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0); 177 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0);
165 break; 178 break;
166 179
167 case 1: 180 case 1:
168 pr_debug("set hs path\n"); 181 pr_debug("set hs path\n");
169 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones"); 182 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones");
170 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); 183 snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT");
171 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x22); 184 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x22);
172 break; 185 break;
173 186
174 case 2: 187 case 2:
175 pr_debug("set spkr path\n"); 188 pr_debug("set spkr path\n");
176 snd_soc_dapm_disable_pin(&codec->dapm, "IHFOUTL"); 189 snd_soc_dapm_disable_pin_unlocked(dapm, "IHFOUTL");
177 snd_soc_dapm_disable_pin(&codec->dapm, "IHFOUTR"); 190 snd_soc_dapm_disable_pin_unlocked(dapm, "IHFOUTR");
178 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x44); 191 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x44);
179 break; 192 break;
180 193
181 case 3: 194 case 3:
182 pr_debug("set null path\n"); 195 pr_debug("set null path\n");
183 snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTL"); 196 snd_soc_dapm_disable_pin_unlocked(dapm, "LINEOUTL");
184 snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTR"); 197 snd_soc_dapm_disable_pin_unlocked(dapm, "LINEOUTR");
185 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x66); 198 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x66);
186 break; 199 break;
187 } 200 }
188 snd_soc_dapm_sync(&codec->dapm); 201
202 snd_soc_dapm_sync_unlocked(dapm);
203
204 snd_soc_dapm_mutex_unlock(dapm);
205
189 lo_dac = ucontrol->value.integer.value[0]; 206 lo_dac = ucontrol->value.integer.value[0];
190 return 0; 207 return 0;
191} 208}
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 629446482a91..14718cd6c29f 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -106,57 +106,59 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
106 if (ucontrol->value.enumerated.item[0] >= control->max) 106 if (ucontrol->value.enumerated.item[0] >= control->max)
107 return -EINVAL; 107 return -EINVAL;
108 108
109 mutex_lock(&codec->mutex); 109 snd_soc_dapm_mutex_lock(dapm);
110 110
111 /* Translate selection to bitmap */ 111 /* Translate selection to bitmap */
112 pins = ams_delta_audio_mode_pins[ucontrol->value.enumerated.item[0]]; 112 pins = ams_delta_audio_mode_pins[ucontrol->value.enumerated.item[0]];
113 113
114 /* Setup pins after corresponding bits if changed */ 114 /* Setup pins after corresponding bits if changed */
115 pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE)); 115 pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE));
116
116 if (pin != snd_soc_dapm_get_pin_status(dapm, "Mouthpiece")) { 117 if (pin != snd_soc_dapm_get_pin_status(dapm, "Mouthpiece")) {
117 changed = 1; 118 changed = 1;
118 if (pin) 119 if (pin)
119 snd_soc_dapm_enable_pin(dapm, "Mouthpiece"); 120 snd_soc_dapm_enable_pin_unlocked(dapm, "Mouthpiece");
120 else 121 else
121 snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); 122 snd_soc_dapm_disable_pin_unlocked(dapm, "Mouthpiece");
122 } 123 }
123 pin = !!(pins & (1 << AMS_DELTA_EARPIECE)); 124 pin = !!(pins & (1 << AMS_DELTA_EARPIECE));
124 if (pin != snd_soc_dapm_get_pin_status(dapm, "Earpiece")) { 125 if (pin != snd_soc_dapm_get_pin_status(dapm, "Earpiece")) {
125 changed = 1; 126 changed = 1;
126 if (pin) 127 if (pin)
127 snd_soc_dapm_enable_pin(dapm, "Earpiece"); 128 snd_soc_dapm_enable_pin_unlocked(dapm, "Earpiece");
128 else 129 else
129 snd_soc_dapm_disable_pin(dapm, "Earpiece"); 130 snd_soc_dapm_disable_pin_unlocked(dapm, "Earpiece");
130 } 131 }
131 pin = !!(pins & (1 << AMS_DELTA_MICROPHONE)); 132 pin = !!(pins & (1 << AMS_DELTA_MICROPHONE));
132 if (pin != snd_soc_dapm_get_pin_status(dapm, "Microphone")) { 133 if (pin != snd_soc_dapm_get_pin_status(dapm, "Microphone")) {
133 changed = 1; 134 changed = 1;
134 if (pin) 135 if (pin)
135 snd_soc_dapm_enable_pin(dapm, "Microphone"); 136 snd_soc_dapm_enable_pin_unlocked(dapm, "Microphone");
136 else 137 else
137 snd_soc_dapm_disable_pin(dapm, "Microphone"); 138 snd_soc_dapm_disable_pin_unlocked(dapm, "Microphone");
138 } 139 }
139 pin = !!(pins & (1 << AMS_DELTA_SPEAKER)); 140 pin = !!(pins & (1 << AMS_DELTA_SPEAKER));
140 if (pin != snd_soc_dapm_get_pin_status(dapm, "Speaker")) { 141 if (pin != snd_soc_dapm_get_pin_status(dapm, "Speaker")) {
141 changed = 1; 142 changed = 1;
142 if (pin) 143 if (pin)
143 snd_soc_dapm_enable_pin(dapm, "Speaker"); 144 snd_soc_dapm_enable_pin_unlocked(dapm, "Speaker");
144 else 145 else
145 snd_soc_dapm_disable_pin(dapm, "Speaker"); 146 snd_soc_dapm_disable_pin_unlocked(dapm, "Speaker");
146 } 147 }
147 pin = !!(pins & (1 << AMS_DELTA_AGC)); 148 pin = !!(pins & (1 << AMS_DELTA_AGC));
148 if (pin != ams_delta_audio_agc) { 149 if (pin != ams_delta_audio_agc) {
149 ams_delta_audio_agc = pin; 150 ams_delta_audio_agc = pin;
150 changed = 1; 151 changed = 1;
151 if (pin) 152 if (pin)
152 snd_soc_dapm_enable_pin(dapm, "AGCIN"); 153 snd_soc_dapm_enable_pin_unlocked(dapm, "AGCIN");
153 else 154 else
154 snd_soc_dapm_disable_pin(dapm, "AGCIN"); 155 snd_soc_dapm_disable_pin_unlocked(dapm, "AGCIN");
155 } 156 }
157
156 if (changed) 158 if (changed)
157 snd_soc_dapm_sync(dapm); 159 snd_soc_dapm_sync_unlocked(dapm);
158 160
159 mutex_unlock(&codec->mutex); 161 snd_soc_dapm_mutex_unlock(dapm);
160 162
161 return changed; 163 return changed;
162} 164}
@@ -315,12 +317,17 @@ static void cx81801_close(struct tty_struct *tty)
315 v253_ops.close(tty); 317 v253_ops.close(tty);
316 318
317 /* Revert back to default audio input/output constellation */ 319 /* Revert back to default audio input/output constellation */
318 snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); 320 snd_soc_dapm_mutex_lock(dapm);
319 snd_soc_dapm_enable_pin(dapm, "Earpiece"); 321
320 snd_soc_dapm_enable_pin(dapm, "Microphone"); 322 snd_soc_dapm_disable_pin_unlocked(dapm, "Mouthpiece");
321 snd_soc_dapm_disable_pin(dapm, "Speaker"); 323 snd_soc_dapm_enable_pin_unlocked(dapm, "Earpiece");
322 snd_soc_dapm_disable_pin(dapm, "AGCIN"); 324 snd_soc_dapm_enable_pin_unlocked(dapm, "Microphone");
323 snd_soc_dapm_sync(dapm); 325 snd_soc_dapm_disable_pin_unlocked(dapm, "Speaker");
326 snd_soc_dapm_disable_pin_unlocked(dapm, "AGCIN");
327
328 snd_soc_dapm_sync_unlocked(dapm);
329
330 snd_soc_dapm_mutex_unlock(dapm);
324} 331}
325 332
326/* Line discipline .hangup() */ 333/* Line discipline .hangup() */
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 3fde9e402710..480a39ce02bc 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -68,26 +68,30 @@ static void n810_ext_control(struct snd_soc_dapm_context *dapm)
68 break; 68 break;
69 } 69 }
70 70
71 snd_soc_dapm_mutex_lock(dapm);
72
71 if (n810_spk_func) 73 if (n810_spk_func)
72 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 74 snd_soc_dapm_enable_pin_unlocked(dapm, "Ext Spk");
73 else 75 else
74 snd_soc_dapm_disable_pin(dapm, "Ext Spk"); 76 snd_soc_dapm_disable_pin_unlocked(dapm, "Ext Spk");
75 77
76 if (hp) 78 if (hp)
77 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 79 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack");
78 else 80 else
79 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 81 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
80 if (line1l) 82 if (line1l)
81 snd_soc_dapm_enable_pin(dapm, "LINE1L"); 83 snd_soc_dapm_enable_pin_unlocked(dapm, "LINE1L");
82 else 84 else
83 snd_soc_dapm_disable_pin(dapm, "LINE1L"); 85 snd_soc_dapm_disable_pin_unlocked(dapm, "LINE1L");
84 86
85 if (n810_dmic_func) 87 if (n810_dmic_func)
86 snd_soc_dapm_enable_pin(dapm, "DMic"); 88 snd_soc_dapm_enable_pin_unlocked(dapm, "DMic");
87 else 89 else
88 snd_soc_dapm_disable_pin(dapm, "DMic"); 90 snd_soc_dapm_disable_pin_unlocked(dapm, "DMic");
91
92 snd_soc_dapm_sync_unlocked(dapm);
89 93
90 snd_soc_dapm_sync(dapm); 94 snd_soc_dapm_mutex_unlock(dapm);
91} 95}
92 96
93static int n810_startup(struct snd_pcm_substream *substream) 97static int n810_startup(struct snd_pcm_substream *substream)
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 611179c3bca4..7fb3d4b10370 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -74,26 +74,30 @@ static void rx51_ext_control(struct snd_soc_dapm_context *dapm)
74 break; 74 break;
75 } 75 }
76 76
77 snd_soc_dapm_mutex_lock(dapm);
78
77 if (rx51_spk_func) 79 if (rx51_spk_func)
78 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 80 snd_soc_dapm_enable_pin_unlocked(dapm, "Ext Spk");
79 else 81 else
80 snd_soc_dapm_disable_pin(dapm, "Ext Spk"); 82 snd_soc_dapm_disable_pin_unlocked(dapm, "Ext Spk");
81 if (rx51_dmic_func) 83 if (rx51_dmic_func)
82 snd_soc_dapm_enable_pin(dapm, "DMic"); 84 snd_soc_dapm_enable_pin_unlocked(dapm, "DMic");
83 else 85 else
84 snd_soc_dapm_disable_pin(dapm, "DMic"); 86 snd_soc_dapm_disable_pin_unlocked(dapm, "DMic");
85 if (hp) 87 if (hp)
86 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 88 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack");
87 else 89 else
88 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 90 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
89 if (hs) 91 if (hs)
90 snd_soc_dapm_enable_pin(dapm, "HS Mic"); 92 snd_soc_dapm_enable_pin_unlocked(dapm, "HS Mic");
91 else 93 else
92 snd_soc_dapm_disable_pin(dapm, "HS Mic"); 94 snd_soc_dapm_disable_pin_unlocked(dapm, "HS Mic");
93 95
94 gpio_set_value(RX51_TVOUT_SEL_GPIO, tvout); 96 gpio_set_value(RX51_TVOUT_SEL_GPIO, tvout);
95 97
96 snd_soc_dapm_sync(dapm); 98 snd_soc_dapm_sync_unlocked(dapm);
99
100 snd_soc_dapm_mutex_unlock(dapm);
97} 101}
98 102
99static int rx51_startup(struct snd_pcm_substream *substream) 103static int rx51_startup(struct snd_pcm_substream *substream)
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 916ff63d85d0..5a88136aa800 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -47,51 +47,55 @@ static int corgi_spk_func;
47 47
48static void corgi_ext_control(struct snd_soc_dapm_context *dapm) 48static void corgi_ext_control(struct snd_soc_dapm_context *dapm)
49{ 49{
50 snd_soc_dapm_mutex_lock(dapm);
51
50 /* set up jack connection */ 52 /* set up jack connection */
51 switch (corgi_jack_func) { 53 switch (corgi_jack_func) {
52 case CORGI_HP: 54 case CORGI_HP:
53 /* set = unmute headphone */ 55 /* set = unmute headphone */
54 gpio_set_value(CORGI_GPIO_MUTE_L, 1); 56 gpio_set_value(CORGI_GPIO_MUTE_L, 1);
55 gpio_set_value(CORGI_GPIO_MUTE_R, 1); 57 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
56 snd_soc_dapm_disable_pin(dapm, "Mic Jack"); 58 snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack");
57 snd_soc_dapm_disable_pin(dapm, "Line Jack"); 59 snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
58 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 60 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack");
59 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 61 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
60 break; 62 break;
61 case CORGI_MIC: 63 case CORGI_MIC:
62 /* reset = mute headphone */ 64 /* reset = mute headphone */
63 gpio_set_value(CORGI_GPIO_MUTE_L, 0); 65 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
64 gpio_set_value(CORGI_GPIO_MUTE_R, 0); 66 gpio_set_value(CORGI_GPIO_MUTE_R, 0);
65 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 67 snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack");
66 snd_soc_dapm_disable_pin(dapm, "Line Jack"); 68 snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
67 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 69 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
68 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 70 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
69 break; 71 break;
70 case CORGI_LINE: 72 case CORGI_LINE:
71 gpio_set_value(CORGI_GPIO_MUTE_L, 0); 73 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
72 gpio_set_value(CORGI_GPIO_MUTE_R, 0); 74 gpio_set_value(CORGI_GPIO_MUTE_R, 0);
73 snd_soc_dapm_disable_pin(dapm, "Mic Jack"); 75 snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack");
74 snd_soc_dapm_enable_pin(dapm, "Line Jack"); 76 snd_soc_dapm_enable_pin_unlocked(dapm, "Line Jack");
75 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 77 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
76 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 78 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
77 break; 79 break;
78 case CORGI_HEADSET: 80 case CORGI_HEADSET:
79 gpio_set_value(CORGI_GPIO_MUTE_L, 0); 81 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
80 gpio_set_value(CORGI_GPIO_MUTE_R, 1); 82 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
81 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 83 snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack");
82 snd_soc_dapm_disable_pin(dapm, "Line Jack"); 84 snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
83 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 85 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
84 snd_soc_dapm_enable_pin(dapm, "Headset Jack"); 86 snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Jack");
85 break; 87 break;
86 } 88 }
87 89
88 if (corgi_spk_func == CORGI_SPK_ON) 90 if (corgi_spk_func == CORGI_SPK_ON)
89 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 91 snd_soc_dapm_enable_pin_unlocked(dapm, "Ext Spk");
90 else 92 else
91 snd_soc_dapm_disable_pin(dapm, "Ext Spk"); 93 snd_soc_dapm_disable_pin_unlocked(dapm, "Ext Spk");
92 94
93 /* signal a DAPM event */ 95 /* signal a DAPM event */
94 snd_soc_dapm_sync(dapm); 96 snd_soc_dapm_sync_unlocked(dapm);
97
98 snd_soc_dapm_mutex_unlock(dapm);
95} 99}
96 100
97static int corgi_startup(struct snd_pcm_substream *substream) 101static int corgi_startup(struct snd_pcm_substream *substream)
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index aeb08f5f3e1c..41ab6678b65d 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -45,27 +45,31 @@ static void magician_ext_control(struct snd_soc_codec *codec)
45{ 45{
46 struct snd_soc_dapm_context *dapm = &codec->dapm; 46 struct snd_soc_dapm_context *dapm = &codec->dapm;
47 47
48 snd_soc_dapm_mutex_lock(dapm);
49
48 if (magician_spk_switch) 50 if (magician_spk_switch)
49 snd_soc_dapm_enable_pin(dapm, "Speaker"); 51 snd_soc_dapm_enable_pin_unlocked(dapm, "Speaker");
50 else 52 else
51 snd_soc_dapm_disable_pin(dapm, "Speaker"); 53 snd_soc_dapm_disable_pin_unlocked(dapm, "Speaker");
52 if (magician_hp_switch) 54 if (magician_hp_switch)
53 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 55 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack");
54 else 56 else
55 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 57 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
56 58
57 switch (magician_in_sel) { 59 switch (magician_in_sel) {
58 case MAGICIAN_MIC: 60 case MAGICIAN_MIC:
59 snd_soc_dapm_disable_pin(dapm, "Headset Mic"); 61 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Mic");
60 snd_soc_dapm_enable_pin(dapm, "Call Mic"); 62 snd_soc_dapm_enable_pin_unlocked(dapm, "Call Mic");
61 break; 63 break;
62 case MAGICIAN_MIC_EXT: 64 case MAGICIAN_MIC_EXT:
63 snd_soc_dapm_disable_pin(dapm, "Call Mic"); 65 snd_soc_dapm_disable_pin_unlocked(dapm, "Call Mic");
64 snd_soc_dapm_enable_pin(dapm, "Headset Mic"); 66 snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Mic");
65 break; 67 break;
66 } 68 }
67 69
68 snd_soc_dapm_sync(dapm); 70 snd_soc_dapm_sync_unlocked(dapm);
71
72 snd_soc_dapm_mutex_unlock(dapm);
69} 73}
70 74
71static int magician_startup(struct snd_pcm_substream *substream) 75static int magician_startup(struct snd_pcm_substream *substream)
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index d1b6bf9c8583..1373b017a951 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -46,61 +46,66 @@ static int spitz_mic_gpio;
46 46
47static void spitz_ext_control(struct snd_soc_dapm_context *dapm) 47static void spitz_ext_control(struct snd_soc_dapm_context *dapm)
48{ 48{
49 snd_soc_dapm_mutex_lock(dapm);
50
49 if (spitz_spk_func == SPITZ_SPK_ON) 51 if (spitz_spk_func == SPITZ_SPK_ON)
50 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 52 snd_soc_dapm_enable_pin_unlocked(dapm, "Ext Spk");
51 else 53 else
52 snd_soc_dapm_disable_pin(dapm, "Ext Spk"); 54 snd_soc_dapm_disable_pin_unlocked(dapm, "Ext Spk");
53 55
54 /* set up jack connection */ 56 /* set up jack connection */
55 switch (spitz_jack_func) { 57 switch (spitz_jack_func) {
56 case SPITZ_HP: 58 case SPITZ_HP:
57 /* enable and unmute hp jack, disable mic bias */ 59 /* enable and unmute hp jack, disable mic bias */
58 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 60 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
59 snd_soc_dapm_disable_pin(dapm, "Mic Jack"); 61 snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack");
60 snd_soc_dapm_disable_pin(dapm, "Line Jack"); 62 snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
61 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 63 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack");
62 gpio_set_value(SPITZ_GPIO_MUTE_L, 1); 64 gpio_set_value(SPITZ_GPIO_MUTE_L, 1);
63 gpio_set_value(SPITZ_GPIO_MUTE_R, 1); 65 gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
64 break; 66 break;
65 case SPITZ_MIC: 67 case SPITZ_MIC:
66 /* enable mic jack and bias, mute hp */ 68 /* enable mic jack and bias, mute hp */
67 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 69 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
68 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 70 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
69 snd_soc_dapm_disable_pin(dapm, "Line Jack"); 71 snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
70 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 72 snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack");
71 gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 73 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
72 gpio_set_value(SPITZ_GPIO_MUTE_R, 0); 74 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
73 break; 75 break;
74 case SPITZ_LINE: 76 case SPITZ_LINE:
75 /* enable line jack, disable mic bias and mute hp */ 77 /* enable line jack, disable mic bias and mute hp */
76 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 78 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
77 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 79 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
78 snd_soc_dapm_disable_pin(dapm, "Mic Jack"); 80 snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack");
79 snd_soc_dapm_enable_pin(dapm, "Line Jack"); 81 snd_soc_dapm_enable_pin_unlocked(dapm, "Line Jack");
80 gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 82 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
81 gpio_set_value(SPITZ_GPIO_MUTE_R, 0); 83 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
82 break; 84 break;
83 case SPITZ_HEADSET: 85 case SPITZ_HEADSET:
84 /* enable and unmute headset jack enable mic bias, mute L hp */ 86 /* enable and unmute headset jack enable mic bias, mute L hp */
85 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 87 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
86 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 88 snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack");
87 snd_soc_dapm_disable_pin(dapm, "Line Jack"); 89 snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
88 snd_soc_dapm_enable_pin(dapm, "Headset Jack"); 90 snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Jack");
89 gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 91 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
90 gpio_set_value(SPITZ_GPIO_MUTE_R, 1); 92 gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
91 break; 93 break;
92 case SPITZ_HP_OFF: 94 case SPITZ_HP_OFF:
93 95
94 /* jack removed, everything off */ 96 /* jack removed, everything off */
95 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 97 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
96 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 98 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
97 snd_soc_dapm_disable_pin(dapm, "Mic Jack"); 99 snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack");
98 snd_soc_dapm_disable_pin(dapm, "Line Jack"); 100 snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
99 gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 101 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
100 gpio_set_value(SPITZ_GPIO_MUTE_R, 0); 102 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
101 break; 103 break;
102 } 104 }
103 snd_soc_dapm_sync(dapm); 105
106 snd_soc_dapm_sync_unlocked(dapm);
107
108 snd_soc_dapm_mutex_unlock(dapm);
104} 109}
105 110
106static int spitz_startup(struct snd_pcm_substream *substream) 111static int spitz_startup(struct snd_pcm_substream *substream)
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index d6f38d7ecc1c..cead1658d10a 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -48,31 +48,35 @@ static void tosa_ext_control(struct snd_soc_codec *codec)
48{ 48{
49 struct snd_soc_dapm_context *dapm = &codec->dapm; 49 struct snd_soc_dapm_context *dapm = &codec->dapm;
50 50
51 snd_soc_dapm_mutex_lock(dapm);
52
51 /* set up jack connection */ 53 /* set up jack connection */
52 switch (tosa_jack_func) { 54 switch (tosa_jack_func) {
53 case TOSA_HP: 55 case TOSA_HP:
54 snd_soc_dapm_disable_pin(dapm, "Mic (Internal)"); 56 snd_soc_dapm_disable_pin_unlocked(dapm, "Mic (Internal)");
55 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 57 snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack");
56 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 58 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
57 break; 59 break;
58 case TOSA_MIC_INT: 60 case TOSA_MIC_INT:
59 snd_soc_dapm_enable_pin(dapm, "Mic (Internal)"); 61 snd_soc_dapm_enable_pin_unlocked(dapm, "Mic (Internal)");
60 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 62 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
61 snd_soc_dapm_disable_pin(dapm, "Headset Jack"); 63 snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
62 break; 64 break;
63 case TOSA_HEADSET: 65 case TOSA_HEADSET:
64 snd_soc_dapm_disable_pin(dapm, "Mic (Internal)"); 66 snd_soc_dapm_disable_pin_unlocked(dapm, "Mic (Internal)");
65 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 67 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
66 snd_soc_dapm_enable_pin(dapm, "Headset Jack"); 68 snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Jack");
67 break; 69 break;
68 } 70 }
69 71
70 if (tosa_spk_func == TOSA_SPK_ON) 72 if (tosa_spk_func == TOSA_SPK_ON)
71 snd_soc_dapm_enable_pin(dapm, "Speaker"); 73 snd_soc_dapm_enable_pin_unlocked(dapm, "Speaker");
72 else 74 else
73 snd_soc_dapm_disable_pin(dapm, "Speaker"); 75 snd_soc_dapm_disable_pin_unlocked(dapm, "Speaker");
76
77 snd_soc_dapm_sync_unlocked(dapm);
74 78
75 snd_soc_dapm_sync(dapm); 79 snd_soc_dapm_mutex_unlock(dapm);
76} 80}
77 81
78static int tosa_startup(struct snd_pcm_substream *substream) 82static int tosa_startup(struct snd_pcm_substream *substream)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index dc8ff13187f7..5c01ac1cfc0a 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -115,6 +115,12 @@ static int dapm_down_seq[] = {
115 [snd_soc_dapm_post] = 14, 115 [snd_soc_dapm_post] = 14,
116}; 116};
117 117
118static void dapm_assert_locked(struct snd_soc_dapm_context *dapm)
119{
120 if (dapm->card && dapm->card->instantiated)
121 lockdep_assert_held(&dapm->card->dapm_mutex);
122}
123
118static void pop_wait(u32 pop_time) 124static void pop_wait(u32 pop_time)
119{ 125{
120 if (pop_time) 126 if (pop_time)
@@ -146,15 +152,16 @@ static bool dapm_dirty_widget(struct snd_soc_dapm_widget *w)
146 return !list_empty(&w->dirty); 152 return !list_empty(&w->dirty);
147} 153}
148 154
149void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason) 155static void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason)
150{ 156{
157 dapm_assert_locked(w->dapm);
158
151 if (!dapm_dirty_widget(w)) { 159 if (!dapm_dirty_widget(w)) {
152 dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n", 160 dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n",
153 w->name, reason); 161 w->name, reason);
154 list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty); 162 list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty);
155 } 163 }
156} 164}
157EXPORT_SYMBOL_GPL(dapm_mark_dirty);
158 165
159void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm) 166void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm)
160{ 167{
@@ -361,6 +368,8 @@ static void dapm_reset(struct snd_soc_card *card)
361{ 368{
362 struct snd_soc_dapm_widget *w; 369 struct snd_soc_dapm_widget *w;
363 370
371 lockdep_assert_held(&card->dapm_mutex);
372
364 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); 373 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats));
365 374
366 list_for_each_entry(w, &card->widgets, list) { 375 list_for_each_entry(w, &card->widgets, list) {
@@ -386,7 +395,8 @@ static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg,
386 return -1; 395 return -1;
387} 396}
388 397
389static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val) 398static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg,
399 unsigned int val)
390{ 400{
391 if (w->codec) 401 if (w->codec)
392 return snd_soc_write(w->codec, reg, val); 402 return snd_soc_write(w->codec, reg, val);
@@ -506,7 +516,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
506 case snd_soc_dapm_switch: 516 case snd_soc_dapm_switch:
507 case snd_soc_dapm_mixer: 517 case snd_soc_dapm_mixer:
508 case snd_soc_dapm_mixer_named_ctl: { 518 case snd_soc_dapm_mixer_named_ctl: {
509 int val; 519 unsigned int val;
510 struct soc_mixer_control *mc = (struct soc_mixer_control *) 520 struct soc_mixer_control *mc = (struct soc_mixer_control *)
511 w->kcontrol_news[i].private_value; 521 w->kcontrol_news[i].private_value;
512 int reg = mc->reg; 522 int reg = mc->reg;
@@ -530,7 +540,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
530 case snd_soc_dapm_mux: { 540 case snd_soc_dapm_mux: {
531 struct soc_enum *e = (struct soc_enum *) 541 struct soc_enum *e = (struct soc_enum *)
532 w->kcontrol_news[i].private_value; 542 w->kcontrol_news[i].private_value;
533 int val, item; 543 unsigned int val, item;
534 544
535 soc_widget_read(w, e->reg, &val); 545 soc_widget_read(w, e->reg, &val);
536 item = (val >> e->shift_l) & e->mask; 546 item = (val >> e->shift_l) & e->mask;
@@ -559,7 +569,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
559 case snd_soc_dapm_value_mux: { 569 case snd_soc_dapm_value_mux: {
560 struct soc_enum *e = (struct soc_enum *) 570 struct soc_enum *e = (struct soc_enum *)
561 w->kcontrol_news[i].private_value; 571 w->kcontrol_news[i].private_value;
562 int val, item; 572 unsigned int val, item;
563 573
564 soc_widget_read(w, e->reg, &val); 574 soc_widget_read(w, e->reg, &val);
565 val = (val >> e->shift_l) & e->mask; 575 val = (val >> e->shift_l) & e->mask;
@@ -1218,7 +1228,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
1218 ret = regulator_allow_bypass(w->regulator, false); 1228 ret = regulator_allow_bypass(w->regulator, false);
1219 if (ret != 0) 1229 if (ret != 0)
1220 dev_warn(w->dapm->dev, 1230 dev_warn(w->dapm->dev,
1221 "ASoC: Failed to bypass %s: %d\n", 1231 "ASoC: Failed to unbypass %s: %d\n",
1222 w->name, ret); 1232 w->name, ret);
1223 } 1233 }
1224 1234
@@ -1228,7 +1238,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
1228 ret = regulator_allow_bypass(w->regulator, true); 1238 ret = regulator_allow_bypass(w->regulator, true);
1229 if (ret != 0) 1239 if (ret != 0)
1230 dev_warn(w->dapm->dev, 1240 dev_warn(w->dapm->dev,
1231 "ASoC: Failed to unbypass %s: %d\n", 1241 "ASoC: Failed to bypass %s: %d\n",
1232 w->name, ret); 1242 w->name, ret);
1233 } 1243 }
1234 1244
@@ -1823,6 +1833,8 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
1823 ASYNC_DOMAIN_EXCLUSIVE(async_domain); 1833 ASYNC_DOMAIN_EXCLUSIVE(async_domain);
1824 enum snd_soc_bias_level bias; 1834 enum snd_soc_bias_level bias;
1825 1835
1836 lockdep_assert_held(&card->dapm_mutex);
1837
1826 trace_snd_soc_dapm_start(card); 1838 trace_snd_soc_dapm_start(card);
1827 1839
1828 list_for_each_entry(d, &card->dapm_list, list) { 1840 list_for_each_entry(d, &card->dapm_list, list) {
@@ -1897,10 +1909,14 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
1897 1909
1898 trace_snd_soc_dapm_walk_done(card); 1910 trace_snd_soc_dapm_walk_done(card);
1899 1911
1900 /* Run all the bias changes in parallel */ 1912 /* Run card bias changes at first */
1901 list_for_each_entry(d, &card->dapm_list, list) 1913 dapm_pre_sequence_async(&card->dapm, 0);
1902 async_schedule_domain(dapm_pre_sequence_async, d, 1914 /* Run other bias changes in parallel */
1903 &async_domain); 1915 list_for_each_entry(d, &card->dapm_list, list) {
1916 if (d != &card->dapm)
1917 async_schedule_domain(dapm_pre_sequence_async, d,
1918 &async_domain);
1919 }
1904 async_synchronize_full_domain(&async_domain); 1920 async_synchronize_full_domain(&async_domain);
1905 1921
1906 list_for_each_entry(w, &down_list, power_list) { 1922 list_for_each_entry(w, &down_list, power_list) {
@@ -1920,10 +1936,14 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
1920 dapm_seq_run(card, &up_list, event, true); 1936 dapm_seq_run(card, &up_list, event, true);
1921 1937
1922 /* Run all the bias changes in parallel */ 1938 /* Run all the bias changes in parallel */
1923 list_for_each_entry(d, &card->dapm_list, list) 1939 list_for_each_entry(d, &card->dapm_list, list) {
1924 async_schedule_domain(dapm_post_sequence_async, d, 1940 if (d != &card->dapm)
1925 &async_domain); 1941 async_schedule_domain(dapm_post_sequence_async, d,
1942 &async_domain);
1943 }
1926 async_synchronize_full_domain(&async_domain); 1944 async_synchronize_full_domain(&async_domain);
1945 /* Run card bias changes at last */
1946 dapm_post_sequence_async(&card->dapm, 0);
1927 1947
1928 /* do we need to notify any clients that DAPM event is complete */ 1948 /* do we need to notify any clients that DAPM event is complete */
1929 list_for_each_entry(d, &card->dapm_list, list) { 1949 list_for_each_entry(d, &card->dapm_list, list) {
@@ -2110,6 +2130,8 @@ static int soc_dapm_mux_update_power(struct snd_soc_card *card,
2110 struct snd_soc_dapm_path *path; 2130 struct snd_soc_dapm_path *path;
2111 int found = 0; 2131 int found = 0;
2112 2132
2133 lockdep_assert_held(&card->dapm_mutex);
2134
2113 /* find dapm widget path assoc with kcontrol */ 2135 /* find dapm widget path assoc with kcontrol */
2114 dapm_kcontrol_for_each_path(path, kcontrol) { 2136 dapm_kcontrol_for_each_path(path, kcontrol) {
2115 if (!path->name || !e->texts[mux]) 2137 if (!path->name || !e->texts[mux])
@@ -2160,6 +2182,8 @@ static int soc_dapm_mixer_update_power(struct snd_soc_card *card,
2160 struct snd_soc_dapm_path *path; 2182 struct snd_soc_dapm_path *path;
2161 int found = 0; 2183 int found = 0;
2162 2184
2185 lockdep_assert_held(&card->dapm_mutex);
2186
2163 /* find dapm widget path assoc with kcontrol */ 2187 /* find dapm widget path assoc with kcontrol */
2164 dapm_kcontrol_for_each_path(path, kcontrol) { 2188 dapm_kcontrol_for_each_path(path, kcontrol) {
2165 found = 1; 2189 found = 1;
@@ -2325,6 +2349,8 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
2325{ 2349{
2326 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); 2350 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
2327 2351
2352 dapm_assert_locked(dapm);
2353
2328 if (!w) { 2354 if (!w) {
2329 dev_err(dapm->dev, "ASoC: DAPM unknown pin %s\n", pin); 2355 dev_err(dapm->dev, "ASoC: DAPM unknown pin %s\n", pin);
2330 return -EINVAL; 2356 return -EINVAL;
@@ -2341,18 +2367,18 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
2341} 2367}
2342 2368
2343/** 2369/**
2344 * snd_soc_dapm_sync - scan and power dapm paths 2370 * snd_soc_dapm_sync_unlocked - scan and power dapm paths
2345 * @dapm: DAPM context 2371 * @dapm: DAPM context
2346 * 2372 *
2347 * Walks all dapm audio paths and powers widgets according to their 2373 * Walks all dapm audio paths and powers widgets according to their
2348 * stream or path usage. 2374 * stream or path usage.
2349 * 2375 *
2376 * Requires external locking.
2377 *
2350 * Returns 0 for success. 2378 * Returns 0 for success.
2351 */ 2379 */
2352int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) 2380int snd_soc_dapm_sync_unlocked(struct snd_soc_dapm_context *dapm)
2353{ 2381{
2354 int ret;
2355
2356 /* 2382 /*
2357 * Suppress early reports (eg, jacks syncing their state) to avoid 2383 * Suppress early reports (eg, jacks syncing their state) to avoid
2358 * silly DAPM runs during card startup. 2384 * silly DAPM runs during card startup.
@@ -2360,8 +2386,25 @@ int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
2360 if (!dapm->card || !dapm->card->instantiated) 2386 if (!dapm->card || !dapm->card->instantiated)
2361 return 0; 2387 return 0;
2362 2388
2389 return dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP);
2390}
2391EXPORT_SYMBOL_GPL(snd_soc_dapm_sync_unlocked);
2392
2393/**
2394 * snd_soc_dapm_sync - scan and power dapm paths
2395 * @dapm: DAPM context
2396 *
2397 * Walks all dapm audio paths and powers widgets according to their
2398 * stream or path usage.
2399 *
2400 * Returns 0 for success.
2401 */
2402int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
2403{
2404 int ret;
2405
2363 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2406 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2364 ret = dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP); 2407 ret = snd_soc_dapm_sync_unlocked(dapm);
2365 mutex_unlock(&dapm->card->dapm_mutex); 2408 mutex_unlock(&dapm->card->dapm_mutex);
2366 return ret; 2409 return ret;
2367} 2410}
@@ -3210,15 +3253,11 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
3210 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); 3253 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
3211 const char *pin = (const char *)kcontrol->private_value; 3254 const char *pin = (const char *)kcontrol->private_value;
3212 3255
3213 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3214
3215 if (ucontrol->value.integer.value[0]) 3256 if (ucontrol->value.integer.value[0])
3216 snd_soc_dapm_enable_pin(&card->dapm, pin); 3257 snd_soc_dapm_enable_pin(&card->dapm, pin);
3217 else 3258 else
3218 snd_soc_dapm_disable_pin(&card->dapm, pin); 3259 snd_soc_dapm_disable_pin(&card->dapm, pin);
3219 3260
3220 mutex_unlock(&card->dapm_mutex);
3221
3222 snd_soc_dapm_sync(&card->dapm); 3261 snd_soc_dapm_sync(&card->dapm);
3223 return 0; 3262 return 0;
3224} 3263}
@@ -3248,7 +3287,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3248 ret = regulator_allow_bypass(w->regulator, true); 3287 ret = regulator_allow_bypass(w->regulator, true);
3249 if (ret != 0) 3288 if (ret != 0)
3250 dev_warn(w->dapm->dev, 3289 dev_warn(w->dapm->dev,
3251 "ASoC: Failed to unbypass %s: %d\n", 3290 "ASoC: Failed to bypass %s: %d\n",
3252 w->name, ret); 3291 w->name, ret);
3253 } 3292 }
3254 break; 3293 break;
@@ -3767,23 +3806,52 @@ void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
3767} 3806}
3768 3807
3769/** 3808/**
3809 * snd_soc_dapm_enable_pin_unlocked - enable pin.
3810 * @dapm: DAPM context
3811 * @pin: pin name
3812 *
3813 * Enables input/output pin and its parents or children widgets iff there is
3814 * a valid audio route and active audio stream.
3815 *
3816 * Requires external locking.
3817 *
3818 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3819 * do any widget power switching.
3820 */
3821int snd_soc_dapm_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
3822 const char *pin)
3823{
3824 return snd_soc_dapm_set_pin(dapm, pin, 1);
3825}
3826EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin_unlocked);
3827
3828/**
3770 * snd_soc_dapm_enable_pin - enable pin. 3829 * snd_soc_dapm_enable_pin - enable pin.
3771 * @dapm: DAPM context 3830 * @dapm: DAPM context
3772 * @pin: pin name 3831 * @pin: pin name
3773 * 3832 *
3774 * Enables input/output pin and its parents or children widgets iff there is 3833 * Enables input/output pin and its parents or children widgets iff there is
3775 * a valid audio route and active audio stream. 3834 * a valid audio route and active audio stream.
3835 *
3776 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 3836 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3777 * do any widget power switching. 3837 * do any widget power switching.
3778 */ 3838 */
3779int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin) 3839int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin)
3780{ 3840{
3781 return snd_soc_dapm_set_pin(dapm, pin, 1); 3841 int ret;
3842
3843 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3844
3845 ret = snd_soc_dapm_set_pin(dapm, pin, 1);
3846
3847 mutex_unlock(&dapm->card->dapm_mutex);
3848
3849 return ret;
3782} 3850}
3783EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); 3851EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
3784 3852
3785/** 3853/**
3786 * snd_soc_dapm_force_enable_pin - force a pin to be enabled 3854 * snd_soc_dapm_force_enable_pin_unlocked - force a pin to be enabled
3787 * @dapm: DAPM context 3855 * @dapm: DAPM context
3788 * @pin: pin name 3856 * @pin: pin name
3789 * 3857 *
@@ -3791,11 +3859,13 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
3791 * intended for use with microphone bias supplies used in microphone 3859 * intended for use with microphone bias supplies used in microphone
3792 * jack detection. 3860 * jack detection.
3793 * 3861 *
3862 * Requires external locking.
3863 *
3794 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 3864 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3795 * do any widget power switching. 3865 * do any widget power switching.
3796 */ 3866 */
3797int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, 3867int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
3798 const char *pin) 3868 const char *pin)
3799{ 3869{
3800 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); 3870 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
3801 3871
@@ -3811,25 +3881,103 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
3811 3881
3812 return 0; 3882 return 0;
3813} 3883}
3884EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin_unlocked);
3885
3886/**
3887 * snd_soc_dapm_force_enable_pin - force a pin to be enabled
3888 * @dapm: DAPM context
3889 * @pin: pin name
3890 *
3891 * Enables input/output pin regardless of any other state. This is
3892 * intended for use with microphone bias supplies used in microphone
3893 * jack detection.
3894 *
3895 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3896 * do any widget power switching.
3897 */
3898int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
3899 const char *pin)
3900{
3901 int ret;
3902
3903 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3904
3905 ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, pin);
3906
3907 mutex_unlock(&dapm->card->dapm_mutex);
3908
3909 return ret;
3910}
3814EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); 3911EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin);
3815 3912
3816/** 3913/**
3914 * snd_soc_dapm_disable_pin_unlocked - disable pin.
3915 * @dapm: DAPM context
3916 * @pin: pin name
3917 *
3918 * Disables input/output pin and its parents or children widgets.
3919 *
3920 * Requires external locking.
3921 *
3922 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3923 * do any widget power switching.
3924 */
3925int snd_soc_dapm_disable_pin_unlocked(struct snd_soc_dapm_context *dapm,
3926 const char *pin)
3927{
3928 return snd_soc_dapm_set_pin(dapm, pin, 0);
3929}
3930EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin_unlocked);
3931
3932/**
3817 * snd_soc_dapm_disable_pin - disable pin. 3933 * snd_soc_dapm_disable_pin - disable pin.
3818 * @dapm: DAPM context 3934 * @dapm: DAPM context
3819 * @pin: pin name 3935 * @pin: pin name
3820 * 3936 *
3821 * Disables input/output pin and its parents or children widgets. 3937 * Disables input/output pin and its parents or children widgets.
3938 *
3822 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 3939 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3823 * do any widget power switching. 3940 * do any widget power switching.
3824 */ 3941 */
3825int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, 3942int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm,
3826 const char *pin) 3943 const char *pin)
3827{ 3944{
3828 return snd_soc_dapm_set_pin(dapm, pin, 0); 3945 int ret;
3946
3947 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3948
3949 ret = snd_soc_dapm_set_pin(dapm, pin, 0);
3950
3951 mutex_unlock(&dapm->card->dapm_mutex);
3952
3953 return ret;
3829} 3954}
3830EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); 3955EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
3831 3956
3832/** 3957/**
3958 * snd_soc_dapm_nc_pin_unlocked - permanently disable pin.
3959 * @dapm: DAPM context
3960 * @pin: pin name
3961 *
3962 * Marks the specified pin as being not connected, disabling it along
3963 * any parent or child widgets. At present this is identical to
3964 * snd_soc_dapm_disable_pin() but in future it will be extended to do
3965 * additional things such as disabling controls which only affect
3966 * paths through the pin.
3967 *
3968 * Requires external locking.
3969 *
3970 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3971 * do any widget power switching.
3972 */
3973int snd_soc_dapm_nc_pin_unlocked(struct snd_soc_dapm_context *dapm,
3974 const char *pin)
3975{
3976 return snd_soc_dapm_set_pin(dapm, pin, 0);
3977}
3978EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin_unlocked);
3979
3980/**
3833 * snd_soc_dapm_nc_pin - permanently disable pin. 3981 * snd_soc_dapm_nc_pin - permanently disable pin.
3834 * @dapm: DAPM context 3982 * @dapm: DAPM context
3835 * @pin: pin name 3983 * @pin: pin name
@@ -3845,7 +3993,15 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
3845 */ 3993 */
3846int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin) 3994int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin)
3847{ 3995{
3848 return snd_soc_dapm_set_pin(dapm, pin, 0); 3996 int ret;
3997
3998 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3999
4000 ret = snd_soc_dapm_set_pin(dapm, pin, 0);
4001
4002 mutex_unlock(&dapm->card->dapm_mutex);
4003
4004 return ret;
3849} 4005}
3850EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); 4006EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
3851 4007
@@ -3985,7 +4141,7 @@ void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm)
3985} 4141}
3986EXPORT_SYMBOL_GPL(snd_soc_dapm_free); 4142EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
3987 4143
3988static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm) 4144static void soc_dapm_shutdown_dapm(struct snd_soc_dapm_context *dapm)
3989{ 4145{
3990 struct snd_soc_card *card = dapm->card; 4146 struct snd_soc_card *card = dapm->card;
3991 struct snd_soc_dapm_widget *w; 4147 struct snd_soc_dapm_widget *w;
@@ -4025,14 +4181,21 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
4025 */ 4181 */
4026void snd_soc_dapm_shutdown(struct snd_soc_card *card) 4182void snd_soc_dapm_shutdown(struct snd_soc_card *card)
4027{ 4183{
4028 struct snd_soc_codec *codec; 4184 struct snd_soc_dapm_context *dapm;
4029 4185
4030 list_for_each_entry(codec, &card->codec_dev_list, card_list) { 4186 list_for_each_entry(dapm, &card->dapm_list, list) {
4031 soc_dapm_shutdown_codec(&codec->dapm); 4187 if (dapm != &card->dapm) {
4032 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) 4188 soc_dapm_shutdown_dapm(dapm);
4033 snd_soc_dapm_set_bias_level(&codec->dapm, 4189 if (dapm->bias_level == SND_SOC_BIAS_STANDBY)
4034 SND_SOC_BIAS_OFF); 4190 snd_soc_dapm_set_bias_level(dapm,
4191 SND_SOC_BIAS_OFF);
4192 }
4035 } 4193 }
4194
4195 soc_dapm_shutdown_dapm(&card->dapm);
4196 if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY)
4197 snd_soc_dapm_set_bias_level(&card->dapm,
4198 SND_SOC_BIAS_OFF);
4036} 4199}
4037 4200
4038/* Module information */ 4201/* Module information */