sysdev: Convert cpu driver sysdev class attributes
[safe/jmp/linux-2.6] / sound / soc / soc-dapm.c
index 846678a..6c33510 100644 (file)
 #include <sound/soc-dapm.h>
 #include <sound/initval.h>
 
-/* debug */
-#ifdef DEBUG
-#define dump_dapm(codec, action) dbg_dump_dapm(codec, action)
-#else
-#define dump_dapm(codec, action)
-#endif
-
 /* dapm power sequences - make this per codec in the future */
 static int dapm_up_seq[] = {
        [snd_soc_dapm_pre] = 0,
@@ -739,6 +732,8 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
                            struct snd_soc_dapm_widget *b,
                            int sort[])
 {
+       if (a->codec != b->codec)
+               return (unsigned long)a - (unsigned long)b;
        if (sort[a->id] != sort[b->id])
                return sort[a->id] - sort[b->id];
        if (a->reg != b->reg)
@@ -1017,13 +1012,28 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
                        sys_power = 0;
                        break;
                case SND_SOC_DAPM_STREAM_NOP:
-                       sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY;
+                       switch (codec->bias_level) {
+                               case SND_SOC_BIAS_STANDBY:
+                               case SND_SOC_BIAS_OFF:
+                                       sys_power = 0;
+                                       break;
+                               default:
+                                       sys_power = 1;
+                                       break;
+                       }
                        break;
                default:
                        break;
                }
        }
 
+       if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) {
+               ret = snd_soc_dapm_set_bias_level(socdev,
+                                                 SND_SOC_BIAS_STANDBY);
+               if (ret != 0)
+                       pr_err("Failed to turn on bias: %d\n", ret);
+       }
+
        /* If we're changing to all on or all off then prepare */
        if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) ||
            (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) {
@@ -1047,6 +1057,14 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
                        pr_err("Failed to apply standby bias: %d\n", ret);
        }
 
+       /* If we're in standby and can support bias off then do that */
+       if (codec->bias_level == SND_SOC_BIAS_STANDBY &&
+           codec->idle_bias_off) {
+               ret = snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_OFF);
+               if (ret != 0)
+                       pr_err("Failed to turn off bias: %d\n", ret);
+       }
+
        /* If we just powered up then move to active bias */
        if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) {
                ret = snd_soc_dapm_set_bias_level(socdev,
@@ -1061,66 +1079,6 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
        return 0;
 }
 
-#ifdef DEBUG
-static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
-{
-       struct snd_soc_dapm_widget *w;
-       struct snd_soc_dapm_path *p = NULL;
-       int in, out;
-
-       printk("DAPM %s %s\n", codec->name, action);
-
-       list_for_each_entry(w, &codec->dapm_widgets, list) {
-
-               /* only display widgets that effect routing */
-               switch (w->id) {
-               case snd_soc_dapm_pre:
-               case snd_soc_dapm_post:
-               case snd_soc_dapm_vmid:
-                       continue;
-               case snd_soc_dapm_mux:
-               case snd_soc_dapm_value_mux:
-               case snd_soc_dapm_output:
-               case snd_soc_dapm_input:
-               case snd_soc_dapm_switch:
-               case snd_soc_dapm_hp:
-               case snd_soc_dapm_mic:
-               case snd_soc_dapm_spk:
-               case snd_soc_dapm_line:
-               case snd_soc_dapm_micbias:
-               case snd_soc_dapm_dac:
-               case snd_soc_dapm_adc:
-               case snd_soc_dapm_pga:
-               case snd_soc_dapm_mixer:
-               case snd_soc_dapm_mixer_named_ctl:
-               case snd_soc_dapm_supply:
-               case snd_soc_dapm_aif_in:
-               case snd_soc_dapm_aif_out:
-                       if (w->name) {
-                               in = is_connected_input_ep(w);
-                               dapm_clear_walk(w->codec);
-                               out = is_connected_output_ep(w);
-                               dapm_clear_walk(w->codec);
-                               printk("%s: %s  in %d out %d\n", w->name,
-                                       w->power ? "On":"Off",in, out);
-
-                               list_for_each_entry(p, &w->sources, list_sink) {
-                                       if (p->connect)
-                                               printk(" in  %s %s\n", p->name ? p->name : "static",
-                                                       p->source->name);
-                               }
-                               list_for_each_entry(p, &w->sinks, list_source) {
-                                       if (p->connect)
-                                               printk(" out %s %s\n", p->name ? p->name : "static",
-                                                       p->sink->name);
-                               }
-                       }
-               break;
-               }
-       }
-}
-#endif
-
 #ifdef CONFIG_DEBUG_FS
 static int dapm_widget_power_open_file(struct inode *inode, struct file *file)
 {
@@ -1252,18 +1210,15 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
                        path->connect = 0; /* old connection must be powered down */
        }
 
-       if (found) {
+       if (found)
                dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
-               dump_dapm(widget->codec, "mux power update");
-       }
 
        return 0;
 }
 
 /* test and update the power status of a mixer or switch widget */
 static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
-                                  struct snd_kcontrol *kcontrol, int reg,
-                                  int val_mask, int val, int invert)
+                                  struct snd_kcontrol *kcontrol, int connect)
 {
        struct snd_soc_dapm_path *path;
        int found = 0;
@@ -1273,9 +1228,6 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
            widget->id != snd_soc_dapm_switch)
                return -ENODEV;
 
-       if (!snd_soc_test_bits(widget->codec, reg, val_mask, val))
-               return 0;
-
        /* find dapm widget path assoc with kcontrol */
        list_for_each_entry(path, &widget->codec->dapm_paths, list) {
                if (path->kcontrol != kcontrol)
@@ -1283,19 +1235,12 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
 
                /* found, now check type */
                found = 1;
-               if (val)
-                       /* new connection */
-                       path->connect = invert ? 0:1;
-               else
-                       /* old connection must be powered down */
-                       path->connect = invert ? 1:0;
+               path->connect = connect;
                break;
        }
 
-       if (found) {
+       if (found)
                dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
-               dump_dapm(widget->codec, "mixer power update");
-       }
 
        return 0;
 }
@@ -1411,9 +1356,7 @@ static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec,
  */
 int snd_soc_dapm_sync(struct snd_soc_codec *codec)
 {
-       int ret = dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP);
-       dump_dapm(codec, "sync");
-       return ret;
+       return dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP);
 }
 EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
 
@@ -1695,6 +1638,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
        unsigned int mask = (1 << fls(max)) - 1;
        unsigned int invert = mc->invert;
        unsigned int val, val2, val_mask;
+       int connect;
        int ret;
 
        val = (ucontrol->value.integer.value[0] & mask);
@@ -1721,7 +1665,17 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
                return 1;
        }
 
-       dapm_mixer_update_power(widget, kcontrol, reg, val_mask, val, invert);
+       if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
+               if (val)
+                       /* new connection */
+                       connect = invert ? 0:1;
+               else
+                       /* old connection must be powered down */
+                       connect = invert ? 1:0;
+
+               dapm_mixer_update_power(widget, kcontrol, connect);
+       }
+
        if (widget->event) {
                if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
                        ret = widget->event(widget, kcontrol,
@@ -2159,7 +2113,6 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec,
 
        dapm_power_widgets(codec, event);
        mutex_unlock(&codec->mutex);
-       dump_dapm(codec, __func__);
        return 0;
 }
 EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);