diff options
-rw-r--r-- | drivers/extcon/extcon-arizona.c | 12 | ||||
-rw-r--r-- | drivers/input/misc/arizona-haptics.c | 19 | ||||
-rw-r--r-- | include/sound/soc-dapm.h | 10 | ||||
-rw-r--r-- | include/sound/soc.h | 11 | ||||
-rw-r--r-- | sound/soc/codecs/adav80x.c | 17 | ||||
-rw-r--r-- | sound/soc/codecs/wm5100.c | 12 | ||||
-rw-r--r-- | sound/soc/codecs/wm8962.c | 13 | ||||
-rw-r--r-- | sound/soc/codecs/wm8994.c | 45 | ||||
-rw-r--r-- | sound/soc/codecs/wm8996.c | 9 | ||||
-rw-r--r-- | sound/soc/intel/mfld_machine.c | 65 | ||||
-rw-r--r-- | sound/soc/omap/ams-delta.c | 45 | ||||
-rw-r--r-- | sound/soc/omap/n810.c | 22 | ||||
-rw-r--r-- | sound/soc/omap/rx51.c | 22 | ||||
-rw-r--r-- | sound/soc/pxa/corgi.c | 42 | ||||
-rw-r--r-- | sound/soc/pxa/magician.c | 22 | ||||
-rw-r--r-- | sound/soc/pxa/spitz.c | 51 | ||||
-rw-r--r-- | sound/soc/pxa/tosa.c | 28 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 241 |
18 files changed, 458 insertions, 228 deletions
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index c20602f601ee..98a14f6143a7 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c | |||
@@ -222,27 +222,19 @@ static void arizona_extcon_pulse_micbias(struct arizona_extcon_info *info) | |||
222 | struct snd_soc_dapm_context *dapm = arizona->dapm; | 222 | struct snd_soc_dapm_context *dapm = arizona->dapm; |
223 | int ret; | 223 | int ret; |
224 | 224 | ||
225 | mutex_lock(&dapm->card->dapm_mutex); | ||
226 | |||
227 | ret = snd_soc_dapm_force_enable_pin(dapm, widget); | 225 | ret = snd_soc_dapm_force_enable_pin(dapm, widget); |
228 | if (ret != 0) | 226 | if (ret != 0) |
229 | dev_warn(arizona->dev, "Failed to enable %s: %d\n", | 227 | dev_warn(arizona->dev, "Failed to enable %s: %d\n", |
230 | widget, ret); | 228 | widget, ret); |
231 | 229 | ||
232 | mutex_unlock(&dapm->card->dapm_mutex); | ||
233 | |||
234 | snd_soc_dapm_sync(dapm); | 230 | snd_soc_dapm_sync(dapm); |
235 | 231 | ||
236 | if (!arizona->pdata.micd_force_micbias) { | 232 | if (!arizona->pdata.micd_force_micbias) { |
237 | mutex_lock(&dapm->card->dapm_mutex); | ||
238 | |||
239 | ret = snd_soc_dapm_disable_pin(arizona->dapm, widget); | 233 | ret = snd_soc_dapm_disable_pin(arizona->dapm, widget); |
240 | if (ret != 0) | 234 | if (ret != 0) |
241 | dev_warn(arizona->dev, "Failed to disable %s: %d\n", | 235 | dev_warn(arizona->dev, "Failed to disable %s: %d\n", |
242 | widget, ret); | 236 | widget, ret); |
243 | 237 | ||
244 | mutex_unlock(&dapm->card->dapm_mutex); | ||
245 | |||
246 | snd_soc_dapm_sync(dapm); | 238 | snd_soc_dapm_sync(dapm); |
247 | } | 239 | } |
248 | } | 240 | } |
@@ -304,16 +296,12 @@ static void arizona_stop_mic(struct arizona_extcon_info *info) | |||
304 | ARIZONA_MICD_ENA, 0, | 296 | ARIZONA_MICD_ENA, 0, |
305 | &change); | 297 | &change); |
306 | 298 | ||
307 | mutex_lock(&dapm->card->dapm_mutex); | ||
308 | |||
309 | ret = snd_soc_dapm_disable_pin(dapm, widget); | 299 | ret = snd_soc_dapm_disable_pin(dapm, widget); |
310 | if (ret != 0) | 300 | if (ret != 0) |
311 | dev_warn(arizona->dev, | 301 | dev_warn(arizona->dev, |
312 | "Failed to disable %s: %d\n", | 302 | "Failed to disable %s: %d\n", |
313 | widget, ret); | 303 | widget, ret); |
314 | 304 | ||
315 | mutex_unlock(&dapm->card->dapm_mutex); | ||
316 | |||
317 | snd_soc_dapm_sync(dapm); | 305 | snd_soc_dapm_sync(dapm); |
318 | 306 | ||
319 | if (info->micd_reva) { | 307 | if (info->micd_reva) { |
diff --git a/drivers/input/misc/arizona-haptics.c b/drivers/input/misc/arizona-haptics.c index 7a04f54ef961..ef2e281b0a43 100644 --- a/drivers/input/misc/arizona-haptics.c +++ b/drivers/input/misc/arizona-haptics.c | |||
@@ -37,7 +37,6 @@ static void arizona_haptics_work(struct work_struct *work) | |||
37 | struct arizona_haptics, | 37 | struct arizona_haptics, |
38 | work); | 38 | work); |
39 | struct arizona *arizona = haptics->arizona; | 39 | struct arizona *arizona = haptics->arizona; |
40 | struct mutex *dapm_mutex = &arizona->dapm->card->dapm_mutex; | ||
41 | int ret; | 40 | int ret; |
42 | 41 | ||
43 | if (!haptics->arizona->dapm) { | 42 | if (!haptics->arizona->dapm) { |
@@ -67,13 +66,10 @@ static void arizona_haptics_work(struct work_struct *work) | |||
67 | return; | 66 | return; |
68 | } | 67 | } |
69 | 68 | ||
70 | mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
71 | |||
72 | ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS"); | 69 | ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS"); |
73 | if (ret != 0) { | 70 | if (ret != 0) { |
74 | dev_err(arizona->dev, "Failed to start HAPTICS: %d\n", | 71 | dev_err(arizona->dev, "Failed to start HAPTICS: %d\n", |
75 | ret); | 72 | ret); |
76 | mutex_unlock(dapm_mutex); | ||
77 | return; | 73 | return; |
78 | } | 74 | } |
79 | 75 | ||
@@ -81,21 +77,14 @@ static void arizona_haptics_work(struct work_struct *work) | |||
81 | if (ret != 0) { | 77 | if (ret != 0) { |
82 | dev_err(arizona->dev, "Failed to sync DAPM: %d\n", | 78 | dev_err(arizona->dev, "Failed to sync DAPM: %d\n", |
83 | ret); | 79 | ret); |
84 | mutex_unlock(dapm_mutex); | ||
85 | return; | 80 | return; |
86 | } | 81 | } |
87 | |||
88 | mutex_unlock(dapm_mutex); | ||
89 | |||
90 | } else { | 82 | } else { |
91 | /* This disable sequence will be a noop if already enabled */ | 83 | /* This disable sequence will be a noop if already enabled */ |
92 | mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
93 | |||
94 | ret = snd_soc_dapm_disable_pin(arizona->dapm, "HAPTICS"); | 84 | ret = snd_soc_dapm_disable_pin(arizona->dapm, "HAPTICS"); |
95 | if (ret != 0) { | 85 | if (ret != 0) { |
96 | dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n", | 86 | dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n", |
97 | ret); | 87 | ret); |
98 | mutex_unlock(dapm_mutex); | ||
99 | return; | 88 | return; |
100 | } | 89 | } |
101 | 90 | ||
@@ -103,12 +92,9 @@ static void arizona_haptics_work(struct work_struct *work) | |||
103 | if (ret != 0) { | 92 | if (ret != 0) { |
104 | dev_err(arizona->dev, "Failed to sync DAPM: %d\n", | 93 | dev_err(arizona->dev, "Failed to sync DAPM: %d\n", |
105 | ret); | 94 | ret); |
106 | mutex_unlock(dapm_mutex); | ||
107 | return; | 95 | return; |
108 | } | 96 | } |
109 | 97 | ||
110 | mutex_unlock(dapm_mutex); | ||
111 | |||
112 | ret = regmap_update_bits(arizona->regmap, | 98 | ret = regmap_update_bits(arizona->regmap, |
113 | ARIZONA_HAPTICS_CONTROL_1, | 99 | ARIZONA_HAPTICS_CONTROL_1, |
114 | ARIZONA_HAP_CTRL_MASK, | 100 | ARIZONA_HAP_CTRL_MASK, |
@@ -155,16 +141,11 @@ static int arizona_haptics_play(struct input_dev *input, void *data, | |||
155 | static void arizona_haptics_close(struct input_dev *input) | 141 | static void arizona_haptics_close(struct input_dev *input) |
156 | { | 142 | { |
157 | struct arizona_haptics *haptics = input_get_drvdata(input); | 143 | struct arizona_haptics *haptics = input_get_drvdata(input); |
158 | struct mutex *dapm_mutex = &haptics->arizona->dapm->card->dapm_mutex; | ||
159 | 144 | ||
160 | cancel_work_sync(&haptics->work); | 145 | cancel_work_sync(&haptics->work); |
161 | 146 | ||
162 | mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
163 | |||
164 | if (haptics->arizona->dapm) | 147 | if (haptics->arizona->dapm) |
165 | snd_soc_dapm_disable_pin(haptics->arizona->dapm, "HAPTICS"); | 148 | snd_soc_dapm_disable_pin(haptics->arizona->dapm, "HAPTICS"); |
166 | |||
167 | mutex_unlock(dapm_mutex); | ||
168 | } | 149 | } |
169 | 150 | ||
170 | static int arizona_haptics_probe(struct platform_device *pdev) | 151 | static int arizona_haptics_probe(struct platform_device *pdev) |
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 68d92e36facd..05aaaf689ac0 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h | |||
@@ -449,20 +449,28 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm, | |||
449 | /* dapm audio pin control and status */ | 449 | /* dapm audio pin control and status */ |
450 | int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, | 450 | int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, |
451 | const char *pin); | 451 | const char *pin); |
452 | int snd_soc_dapm_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, | ||
453 | const char *pin); | ||
452 | int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, | 454 | int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, |
453 | const char *pin); | 455 | const char *pin); |
456 | int snd_soc_dapm_disable_pin_unlocked(struct snd_soc_dapm_context *dapm, | ||
457 | const char *pin); | ||
454 | int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin); | 458 | int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin); |
459 | int snd_soc_dapm_nc_pin_unlocked(struct snd_soc_dapm_context *dapm, | ||
460 | const char *pin); | ||
455 | int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, | 461 | int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, |
456 | const char *pin); | 462 | const char *pin); |
457 | int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm); | 463 | int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm); |
464 | int snd_soc_dapm_sync_unlocked(struct snd_soc_dapm_context *dapm); | ||
458 | int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, | 465 | int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, |
459 | const char *pin); | 466 | const char *pin); |
467 | int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, | ||
468 | const char *pin); | ||
460 | int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, | 469 | int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, |
461 | const char *pin); | 470 | const char *pin); |
462 | void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec); | 471 | void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec); |
463 | 472 | ||
464 | /* Mostly internal - should not normally be used */ | 473 | /* Mostly internal - should not normally be used */ |
465 | void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason); | ||
466 | void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm); | 474 | void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm); |
467 | 475 | ||
468 | /* dapm path query */ | 476 | /* dapm path query */ |
diff --git a/include/sound/soc.h b/include/sound/soc.h index 9a001472b96a..1e12b66da2cc 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -1188,4 +1188,15 @@ extern struct dentry *snd_soc_debugfs_root; | |||
1188 | 1188 | ||
1189 | extern const struct dev_pm_ops snd_soc_pm_ops; | 1189 | extern const struct dev_pm_ops snd_soc_pm_ops; |
1190 | 1190 | ||
1191 | /* Helper functions */ | ||
1192 | static inline void snd_soc_dapm_mutex_lock(struct snd_soc_dapm_context *dapm) | ||
1193 | { | ||
1194 | mutex_lock(&dapm->card->dapm_mutex); | ||
1195 | } | ||
1196 | |||
1197 | static inline void snd_soc_dapm_mutex_unlock(struct snd_soc_dapm_context *dapm) | ||
1198 | { | ||
1199 | mutex_unlock(&dapm->card->dapm_mutex); | ||
1200 | } | ||
1201 | |||
1191 | #endif | 1202 | #endif |
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) | |||
2100 | int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) | 2100 | int 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) | |||
3089 | int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) | 3089 | int 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 | } |
3122 | EXPORT_SYMBOL_GPL(wm8962_mic_detect); | 3127 | EXPORT_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, | |||
2549 | int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode) | 2549 | int 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 | ||
123 | static void lo_enable_out_pins(struct snd_soc_codec *codec) | 130 | static 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 | ||
93 | static int n810_startup(struct snd_pcm_substream *substream) | 97 | static 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 | ||
99 | static int rx51_startup(struct snd_pcm_substream *substream) | 103 | static 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 | ||
48 | static void corgi_ext_control(struct snd_soc_dapm_context *dapm) | 48 | static 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 | ||
97 | static int corgi_startup(struct snd_pcm_substream *substream) | 101 | static 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 | ||
71 | static int magician_startup(struct snd_pcm_substream *substream) | 75 | static 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 | ||
47 | static void spitz_ext_control(struct snd_soc_dapm_context *dapm) | 47 | static 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 | ||
106 | static int spitz_startup(struct snd_pcm_substream *substream) | 111 | static 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 | ||
78 | static int tosa_startup(struct snd_pcm_substream *substream) | 82 | static 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 | ||
118 | static 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 | |||
118 | static void pop_wait(u32 pop_time) | 124 | static 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 | ||
149 | void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason) | 155 | static 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 | } |
157 | EXPORT_SYMBOL_GPL(dapm_mark_dirty); | ||
158 | 165 | ||
159 | void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm) | 166 | void 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 | ||
389 | static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val) | 398 | static 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 | */ |
2352 | int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) | 2380 | int 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 | } | ||
2391 | EXPORT_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 | */ | ||
2402 | int 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 | */ | ||
3821 | int 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 | } | ||
3826 | EXPORT_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 | */ |
3779 | int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin) | 3839 | int 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 | } |
3783 | EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); | 3851 | EXPORT_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 | */ |
3797 | int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, | 3867 | int 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 | } |
3884 | EXPORT_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 | */ | ||
3898 | int 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 | } | ||
3814 | EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); | 3911 | EXPORT_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 | */ | ||
3925 | int 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 | } | ||
3930 | EXPORT_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 | */ |
3825 | int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, | 3942 | int 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 | } |
3830 | EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); | 3955 | EXPORT_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 | */ | ||
3973 | int 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 | } | ||
3978 | EXPORT_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 | */ |
3846 | int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin) | 3994 | int 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 | } |
3850 | EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); | 4006 | EXPORT_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 | } |
3986 | EXPORT_SYMBOL_GPL(snd_soc_dapm_free); | 4142 | EXPORT_SYMBOL_GPL(snd_soc_dapm_free); |
3987 | 4143 | ||
3988 | static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm) | 4144 | static 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 | */ |
4026 | void snd_soc_dapm_shutdown(struct snd_soc_card *card) | 4182 | void 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 */ |