X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sound%2Fsoc%2Fsoc-dapm.c;h=97915eb711cc80eb92ebe2749955f0618a4c7386;hb=7bd3a6f34cdd4b1776ca34d0b6fab216e9323759;hp=0c94027c4e3b30c716254776aae9f07231e42cf2;hpb=612a3fec2188c5a85c5057adf60c470a254e800b;p=deliverable%2Flinux.git diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 0c94027c4e3b..97915eb711cc 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -169,6 +169,19 @@ static inline struct snd_soc_card *dapm_get_soc_card( return NULL; } +static void dapm_reset(struct snd_soc_card *card) +{ + struct snd_soc_dapm_widget *w; + + memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); + + list_for_each_entry(w, &card->widgets, list) { + w->power_checked = false; + w->inputs = -1; + w->outputs = -1; + } +} + static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg) { if (w->codec) @@ -1402,13 +1415,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) } } - memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); - - list_for_each_entry(w, &card->widgets, list) { - w->power_checked = false; - w->inputs = -1; - w->outputs = -1; - } + dapm_reset(card); /* Check which widgets we need to power and store them in * lists indicating if they should be powered up or down. We @@ -1509,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); @@ -2644,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; } @@ -2667,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: @@ -2711,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: @@ -2724,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", @@ -2783,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 @@ -2801,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++; } @@ -2818,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: @@ -2847,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); } /** @@ -2864,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; }