|
@@ -1949,6 +1949,8 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
|
|
|
*/
|
|
|
int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
|
|
|
{
|
|
|
+ int ret;
|
|
|
+
|
|
|
/*
|
|
|
* Suppress early reports (eg, jacks syncing their state) to avoid
|
|
|
* silly DAPM runs during card startup.
|
|
@@ -1956,7 +1958,10 @@ int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
|
|
|
if (!dapm->card || !dapm->card->instantiated)
|
|
|
return 0;
|
|
|
|
|
|
- return dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
|
|
|
+ mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
|
|
|
+ ret = dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
|
|
|
+ mutex_unlock(&dapm->card->dapm_mutex);
|
|
|
+ return ret;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
|
|
|
|
|
@@ -2122,6 +2127,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
|
|
|
{
|
|
|
int i, ret;
|
|
|
|
|
|
+ mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
|
|
|
for (i = 0; i < num; i++) {
|
|
|
ret = snd_soc_dapm_add_route(dapm, route);
|
|
|
if (ret < 0) {
|
|
@@ -2131,6 +2137,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
|
|
|
}
|
|
|
route++;
|
|
|
}
|
|
|
+ mutex_unlock(&dapm->card->dapm_mutex);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -2203,12 +2210,14 @@ int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm,
|
|
|
int i, err;
|
|
|
int ret = 0;
|
|
|
|
|
|
+ mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
|
|
|
for (i = 0; i < num; i++) {
|
|
|
err = snd_soc_dapm_weak_route(dapm, route);
|
|
|
if (err)
|
|
|
ret = err;
|
|
|
route++;
|
|
|
}
|
|
|
+ mutex_unlock(&dapm->card->dapm_mutex);
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
@@ -2227,6 +2236,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
|
|
|
struct snd_soc_dapm_widget *w;
|
|
|
unsigned int val;
|
|
|
|
|
|
+ mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
|
|
|
+
|
|
|
list_for_each_entry(w, &dapm->card->widgets, list)
|
|
|
{
|
|
|
if (w->new)
|
|
@@ -2236,8 +2247,10 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
|
|
|
w->kcontrols = kzalloc(w->num_kcontrols *
|
|
|
sizeof(struct snd_kcontrol *),
|
|
|
GFP_KERNEL);
|
|
|
- if (!w->kcontrols)
|
|
|
+ if (!w->kcontrols) {
|
|
|
+ mutex_unlock(&dapm->card->dapm_mutex);
|
|
|
return -ENOMEM;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
switch(w->id) {
|
|
@@ -2277,6 +2290,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
|
|
|
}
|
|
|
|
|
|
dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
|
|
|
+ mutex_unlock(&dapm->card->dapm_mutex);
|
|
|
return 0;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
|
|
@@ -2336,6 +2350,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
|
|
|
struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
|
|
|
struct snd_soc_dapm_widget *widget = wlist->widgets[0];
|
|
|
struct snd_soc_codec *codec = widget->codec;
|
|
|
+ struct snd_soc_card *card = codec->card;
|
|
|
struct soc_mixer_control *mc =
|
|
|
(struct soc_mixer_control *)kcontrol->private_value;
|
|
|
unsigned int reg = mc->reg;
|
|
@@ -2362,7 +2377,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
|
|
|
/* old connection must be powered down */
|
|
|
connect = invert ? 1 : 0;
|
|
|
|
|
|
- mutex_lock(&codec->mutex);
|
|
|
+ mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
|
|
|
|
|
|
change = snd_soc_test_bits(widget->codec, reg, mask, val);
|
|
|
if (change) {
|
|
@@ -2384,7 +2399,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- mutex_unlock(&codec->mutex);
|
|
|
+ mutex_unlock(&card->dapm_mutex);
|
|
|
return 0;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
|
|
@@ -2433,6 +2448,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
|
|
|
struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
|
|
|
struct snd_soc_dapm_widget *widget = wlist->widgets[0];
|
|
|
struct snd_soc_codec *codec = widget->codec;
|
|
|
+ struct snd_soc_card *card = codec->card;
|
|
|
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
|
|
|
unsigned int val, mux, change;
|
|
|
unsigned int mask, bitmask;
|
|
@@ -2453,7 +2469,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
|
|
|
mask |= (bitmask - 1) << e->shift_r;
|
|
|
}
|
|
|
|
|
|
- mutex_lock(&codec->mutex);
|
|
|
+ mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
|
|
|
|
|
|
change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
|
|
|
if (change) {
|
|
@@ -2475,7 +2491,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- mutex_unlock(&codec->mutex);
|
|
|
+ mutex_unlock(&card->dapm_mutex);
|
|
|
return change;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
|
|
@@ -2512,6 +2528,7 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
|
|
|
struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
|
|
|
struct snd_soc_dapm_widget *widget = wlist->widgets[0];
|
|
|
struct snd_soc_codec *codec = widget->codec;
|
|
|
+ struct snd_soc_card *card = codec->card;
|
|
|
struct soc_enum *e =
|
|
|
(struct soc_enum *)kcontrol->private_value;
|
|
|
int change;
|
|
@@ -2521,7 +2538,7 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
|
|
|
if (ucontrol->value.enumerated.item[0] >= e->max)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- mutex_lock(&codec->mutex);
|
|
|
+ mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
|
|
|
|
|
|
change = widget->value != ucontrol->value.enumerated.item[0];
|
|
|
if (change) {
|
|
@@ -2534,7 +2551,7 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- mutex_unlock(&codec->mutex);
|
|
|
+ mutex_unlock(&card->dapm_mutex);
|
|
|
return ret;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
|
|
@@ -2599,6 +2616,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
|
|
|
struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
|
|
|
struct snd_soc_dapm_widget *widget = wlist->widgets[0];
|
|
|
struct snd_soc_codec *codec = widget->codec;
|
|
|
+ struct snd_soc_card *card = codec->card;
|
|
|
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
|
|
|
unsigned int val, mux, change;
|
|
|
unsigned int mask;
|
|
@@ -2617,7 +2635,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
|
|
|
mask |= e->mask << e->shift_r;
|
|
|
}
|
|
|
|
|
|
- mutex_lock(&codec->mutex);
|
|
|
+ mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
|
|
|
|
|
|
change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
|
|
|
if (change) {
|
|
@@ -2639,7 +2657,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- mutex_unlock(&codec->mutex);
|
|
|
+ mutex_unlock(&card->dapm_mutex);
|
|
|
return change;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double);
|
|
@@ -2676,12 +2694,12 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
|
|
|
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
|
|
|
const char *pin = (const char *)kcontrol->private_value;
|
|
|
|
|
|
- mutex_lock(&card->mutex);
|
|
|
+ mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
|
|
|
|
|
|
ucontrol->value.integer.value[0] =
|
|
|
snd_soc_dapm_get_pin_status(&card->dapm, pin);
|
|
|
|
|
|
- mutex_unlock(&card->mutex);
|
|
|
+ mutex_unlock(&card->dapm_mutex);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -2699,17 +2717,16 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
|
|
|
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
|
|
|
const char *pin = (const char *)kcontrol->private_value;
|
|
|
|
|
|
- mutex_lock(&card->mutex);
|
|
|
+ mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
|
|
|
|
|
|
if (ucontrol->value.integer.value[0])
|
|
|
snd_soc_dapm_enable_pin(&card->dapm, pin);
|
|
|
else
|
|
|
snd_soc_dapm_disable_pin(&card->dapm, pin);
|
|
|
|
|
|
- snd_soc_dapm_sync(&card->dapm);
|
|
|
-
|
|
|
- mutex_unlock(&card->mutex);
|
|
|
+ mutex_unlock(&card->dapm_mutex);
|
|
|
|
|
|
+ snd_soc_dapm_sync(&card->dapm);
|
|
|
return 0;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch);
|
|
@@ -2827,6 +2844,7 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
|
|
|
struct snd_soc_dapm_widget *w;
|
|
|
int i;
|
|
|
|
|
|
+ mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
|
|
|
for (i = 0; i < num; i++) {
|
|
|
w = snd_soc_dapm_new_control(dapm, widget);
|
|
|
if (!w) {
|
|
@@ -2837,6 +2855,7 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
|
|
|
}
|
|
|
widget++;
|
|
|
}
|
|
|
+ mutex_unlock(&dapm->card->dapm_mutex);
|
|
|
return 0;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
|
|
@@ -2991,11 +3010,11 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
|
|
|
int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
|
|
|
struct snd_soc_dai *dai, int event)
|
|
|
{
|
|
|
- struct snd_soc_codec *codec = rtd->codec;
|
|
|
+ struct snd_soc_card *card = rtd->card;
|
|
|
|
|
|
- mutex_lock(&codec->mutex);
|
|
|
- soc_dapm_stream_event(&codec->dapm, stream, dai, event);
|
|
|
- mutex_unlock(&codec->mutex);
|
|
|
+ mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
|
|
|
+ soc_dapm_stream_event(&card->dapm, stream, dai, event);
|
|
|
+ mutex_unlock(&card->dapm_mutex);
|
|
|
return 0;
|
|
|
}
|
|
|
|