ASoC: dapm: Supply the DAI and substream when calling stream events
[deliverable/linux.git] / sound / soc / soc-dapm.c
index 227887e05b708d998b21264fe523ff49f366396c..97915eb711cc80eb92ebe2749955f0618a4c7386 100644 (file)
@@ -1516,6 +1516,12 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
                                        &async_domain);
        async_synchronize_full_domain(&async_domain);
 
+       /* do we need to notify any clients that DAPM event is complete */
+       list_for_each_entry(d, &card->dapm_list, list) {
+               if (d->stream_event)
+                       d->stream_event(d, event);
+       }
+
        pop_dbg(dapm->dev, card->pop_time,
                "DAPM sequencing finished, waiting %dms\n", card->pop_time);
        pop_wait(card->pop_time);
@@ -2651,15 +2657,15 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch);
 int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
        const char *pin = (const char *)kcontrol->private_value;
 
-       mutex_lock(&codec->mutex);
+       mutex_lock(&card->mutex);
 
        ucontrol->value.integer.value[0] =
-               snd_soc_dapm_get_pin_status(&codec->dapm, pin);
+               snd_soc_dapm_get_pin_status(&card->dapm, pin);
 
-       mutex_unlock(&codec->mutex);
+       mutex_unlock(&card->mutex);
 
        return 0;
 }
@@ -2674,42 +2680,34 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch);
 int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
        const char *pin = (const char *)kcontrol->private_value;
 
-       mutex_lock(&codec->mutex);
+       mutex_lock(&card->mutex);
 
        if (ucontrol->value.integer.value[0])
-               snd_soc_dapm_enable_pin(&codec->dapm, pin);
+               snd_soc_dapm_enable_pin(&card->dapm, pin);
        else
-               snd_soc_dapm_disable_pin(&codec->dapm, pin);
+               snd_soc_dapm_disable_pin(&card->dapm, pin);
 
-       snd_soc_dapm_sync(&codec->dapm);
+       snd_soc_dapm_sync(&card->dapm);
 
-       mutex_unlock(&codec->mutex);
+       mutex_unlock(&card->mutex);
 
        return 0;
 }
 EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch);
 
-/**
- * snd_soc_dapm_new_control - create new dapm control
- * @dapm: DAPM context
- * @widget: widget template
- *
- * Creates a new dapm control based upon the template.
- *
- * Returns 0 for success else error.
- */
-int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
-       const struct snd_soc_dapm_widget *widget)
+static struct snd_soc_dapm_widget *
+snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
+                        const struct snd_soc_dapm_widget *widget)
 {
        struct snd_soc_dapm_widget *w;
        size_t name_len;
        int ret;
 
        if ((w = dapm_cnew_widget(widget)) == NULL)
-               return -ENOMEM;
+               return NULL;
 
        switch (w->id) {
        case snd_soc_dapm_regulator_supply:
@@ -2718,7 +2716,7 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
                        ret = PTR_ERR(w->priv);
                        dev_err(dapm->dev, "Failed to request %s: %d\n",
                                w->name, ret);
-                       return ret;
+                       return NULL;
                }
                break;
        default:
@@ -2731,7 +2729,7 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
        w->name = kmalloc(name_len, GFP_KERNEL);
        if (w->name == NULL) {
                kfree(w);
-               return -ENOMEM;
+               return NULL;
        }
        if (dapm->codec && dapm->codec->name_prefix)
                snprintf(w->name, name_len, "%s %s",
@@ -2790,9 +2788,8 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
 
        /* machine layer set ups unconnected pins and insertions */
        w->connected = 1;
-       return 0;
+       return w;
 }
-EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control);
 
 /**
  * snd_soc_dapm_new_controls - create new dapm controls
@@ -2808,15 +2805,16 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
        const struct snd_soc_dapm_widget *widget,
        int num)
 {
-       int i, ret;
+       struct snd_soc_dapm_widget *w;
+       int i;
 
        for (i = 0; i < num; i++) {
-               ret = snd_soc_dapm_new_control(dapm, widget);
-               if (ret < 0) {
+               w = snd_soc_dapm_new_control(dapm, widget);
+               if (!w) {
                        dev_err(dapm->dev,
-                               "ASoC: Failed to create DAPM control %s: %d\n",
-                               widget->name, ret);
-                       return ret;
+                               "ASoC: Failed to create DAPM control %s\n",
+                               widget->name);
+                       return -ENOMEM;
                }
                widget++;
        }
@@ -2825,17 +2823,27 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
 EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
 
 static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
-       const char *stream, int event)
+                                 int stream, struct snd_soc_dai *dai,
+                                 int event)
 {
        struct snd_soc_dapm_widget *w;
+       const char *stream_name;
+
+       if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+               stream_name = dai->driver->playback.stream_name;
+       else
+               stream_name = dai->driver->capture.stream_name;
+
+       if (!stream_name)
+               return;
 
        list_for_each_entry(w, &dapm->card->widgets, list)
        {
                if (!w->sname || w->dapm != dapm)
                        continue;
                dev_vdbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n",
-                       w->name, w->sname, stream, event);
-               if (strstr(w->sname, stream)) {
+                       w->name, w->sname, stream_name, event);
+               if (strstr(w->sname, stream_name)) {
                        dapm_mark_dirty(w, "stream event");
                        switch(event) {
                        case SND_SOC_DAPM_STREAM_START:
@@ -2854,10 +2862,6 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
        }
 
        dapm_power_widgets(dapm, event);
-
-       /* do we need to notify any clients that DAPM stream is complete */
-       if (dapm->stream_event)
-               dapm->stream_event(dapm, event);
 }
 
 /**
@@ -2871,16 +2875,13 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
  *
  * Returns 0 for success else error.
  */
-int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
-       const char *stream, int event)
+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;
 
-       if (stream == NULL)
-               return 0;
-
        mutex_lock(&codec->mutex);
-       soc_dapm_stream_event(&codec->dapm, stream, event);
+       soc_dapm_stream_event(&codec->dapm, stream, dai, event);
        mutex_unlock(&codec->mutex);
        return 0;
 }
This page took 0.030097 seconds and 5 git commands to generate.