mmc: msm: fix compile error on MSM7x30
[safe/jmp/linux-2.6] / sound / soc / soc-dapm.c
index 476dbe6..03cb7c0 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/platform_device.h>
 #include <linux/jiffies.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -430,6 +431,25 @@ static inline void dapm_clear_walk(struct snd_soc_codec *codec)
                p->walked = 0;
 }
 
+/* We implement power down on suspend by checking the power state of
+ * the ALSA card - when we are suspending the ALSA state for the card
+ * is set to D3.
+ */
+static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget)
+{
+       struct snd_soc_codec *codec = widget->codec;
+
+       switch (snd_power_get_state(codec->card)) {
+       case SNDRV_CTL_POWER_D3hot:
+       case SNDRV_CTL_POWER_D3cold:
+               if (widget->ignore_suspend)
+                       pr_debug("%s ignoring suspend\n", widget->name);
+               return widget->ignore_suspend;
+       default:
+               return 1;
+       }
+}
+
 /*
  * Recursively check for a completed path to an active or physically connected
  * output widget. Returns number of complete paths.
@@ -446,7 +466,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
        case snd_soc_dapm_adc:
        case snd_soc_dapm_aif_out:
                if (widget->active)
-                       return 1;
+                       return snd_soc_dapm_suspend_check(widget);
        default:
                break;
        }
@@ -454,12 +474,12 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
        if (widget->connected) {
                /* connected pin ? */
                if (widget->id == snd_soc_dapm_output && !widget->ext)
-                       return 1;
+                       return snd_soc_dapm_suspend_check(widget);
 
                /* connected jack or spk ? */
                if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk ||
                    (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources)))
-                       return 1;
+                       return snd_soc_dapm_suspend_check(widget);
        }
 
        list_for_each_entry(path, &widget->sinks, list_source) {
@@ -492,7 +512,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
        case snd_soc_dapm_dac:
        case snd_soc_dapm_aif_in:
                if (widget->active)
-                       return 1;
+                       return snd_soc_dapm_suspend_check(widget);
        default:
                break;
        }
@@ -500,16 +520,16 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
        if (widget->connected) {
                /* connected pin ? */
                if (widget->id == snd_soc_dapm_input && !widget->ext)
-                       return 1;
+                       return snd_soc_dapm_suspend_check(widget);
 
                /* connected VMID/Bias for lower pops */
                if (widget->id == snd_soc_dapm_vmid)
-                       return 1;
+                       return snd_soc_dapm_suspend_check(widget);
 
                /* connected jack ? */
                if (widget->id == snd_soc_dapm_mic ||
                    (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks)))
-                       return 1;
+                       return snd_soc_dapm_suspend_check(widget);
        }
 
        list_for_each_entry(path, &widget->sources, list_sink) {
@@ -897,22 +917,12 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
                        if (!w->power_check)
                                continue;
 
-                       /* If we're suspending then pull down all the 
-                        * power. */
-                       switch (event) {
-                       case SND_SOC_DAPM_STREAM_SUSPEND:
-                               power = 0;
-                               break;
-
-                       default:
-                               if (!w->force)
-                                       power = w->power_check(w);
-                               else
-                                       power = 1;
-                               if (power)
-                                       sys_power = 1;
-                               break;
-                       }
+                       if (!w->force)
+                               power = w->power_check(w);
+                       else
+                               power = 1;
+                       if (power)
+                               sys_power = 1;
 
                        if (w->power == power)
                                continue;
@@ -2012,18 +2022,8 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec,
                                w->active = 0;
                                break;
                        case SND_SOC_DAPM_STREAM_SUSPEND:
-                               if (w->active)
-                                       w->suspend = 1;
-                               w->active = 0;
-                               break;
                        case SND_SOC_DAPM_STREAM_RESUME:
-                               if (w->suspend) {
-                                       w->active = 1;
-                                       w->suspend = 0;
-                               }
-                               break;
                        case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
-                               break;
                        case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
                                break;
                        }
@@ -2140,6 +2140,33 @@ int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin)
 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
 
 /**
+ * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint
+ * @codec: audio codec
+ * @pin: audio signal pin endpoint (or start point)
+ *
+ * Mark the given endpoint or pin as ignoring suspend.  When the
+ * system is disabled a path between two endpoints flagged as ignoring
+ * suspend will not be disabled.  The path must already be enabled via
+ * normal means at suspend time, it will not be turned on if it was not
+ * already enabled.
+ */
+int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin)
+{
+       struct snd_soc_dapm_widget *w;
+
+       list_for_each_entry(w, &codec->dapm_widgets, list) {
+               if (!strcmp(w->name, pin)) {
+                       w->ignore_suspend = 1;
+                       return 0;
+               }
+       }
+
+       pr_err("Unknown DAPM pin: %s\n", pin);
+       return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
+
+/**
  * snd_soc_dapm_free - free dapm resources
  * @socdev: SoC device
  *