]> Pileus Git - ~andy/linux/blobdiff - sound/soc/soc-dapm.c
Merge branch 'for-3.5' into for-3.6
[~andy/linux] / sound / soc / soc-dapm.c
index f7a13f720529966f011fd767b224b6503eed68f4..4d181df95dc3069ef58efcff1cd50de0d522fa7e 100644 (file)
@@ -291,9 +291,9 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm,
                if (dapm->codec->driver->set_bias_level)
                        ret = dapm->codec->driver->set_bias_level(dapm->codec,
                                                                  level);
-               else
-                       dapm->bias_level = level;
-       }
+       } else
+               dapm->bias_level = level;
+
        if (ret != 0)
                goto out;
 
@@ -324,11 +324,10 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
 
                val = soc_widget_read(w, reg);
                val = (val >> shift) & mask;
+               if (invert)
+                       val = max - val;
 
-               if ((invert && !val) || (!invert && val))
-                       p->connect = 1;
-               else
-                       p->connect = 0;
+               p->connect = !!val;
        }
        break;
        case snd_soc_dapm_mux: {
@@ -1598,7 +1597,15 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
        }
 
        list_for_each_entry(w, &card->widgets, list) {
-               list_del_init(&w->dirty);
+               switch (w->id) {
+               case snd_soc_dapm_pre:
+               case snd_soc_dapm_post:
+                       /* These widgets always need to be powered */
+                       break;
+               default:
+                       list_del_init(&w->dirty);
+                       break;
+               }
 
                if (w->power) {
                        d = w->dapm;
@@ -3660,10 +3667,13 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
 
 static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
 {
+       struct snd_soc_card *card = dapm->card;
        struct snd_soc_dapm_widget *w;
        LIST_HEAD(down_list);
        int powerdown = 0;
 
+       mutex_lock(&card->dapm_mutex);
+
        list_for_each_entry(w, &dapm->card->widgets, list) {
                if (w->dapm != dapm)
                        continue;
@@ -3686,6 +3696,8 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
                        snd_soc_dapm_set_bias_level(dapm,
                                                    SND_SOC_BIAS_STANDBY);
        }
+
+       mutex_unlock(&card->dapm_mutex);
 }
 
 /*