diff options
Diffstat (limited to 'sound/soc/soc-dapm.c')
| -rw-r--r-- | sound/soc/soc-dapm.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 7466e8c6815d..c47962c12c16 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -78,8 +78,7 @@ static int dapm_up_seq[] = { [snd_soc_dapm_dai_link] = 2, [snd_soc_dapm_dai_in] = 4, [snd_soc_dapm_dai_out] = 4, - [snd_soc_dapm_aif_in] = 4, - [snd_soc_dapm_aif_out] = 4, + [snd_soc_dapm_adc] = 4, [snd_soc_dapm_mic] = 5, [snd_soc_dapm_mux] = 6, [snd_soc_dapm_demux] = 6, @@ -88,7 +87,8 @@ static int dapm_up_seq[] = { [snd_soc_dapm_mixer] = 8, [snd_soc_dapm_mixer_named_ctl] = 8, [snd_soc_dapm_pga] = 9, - [snd_soc_dapm_adc] = 10, + [snd_soc_dapm_aif_in] = 9, + [snd_soc_dapm_aif_out] = 9, [snd_soc_dapm_out_drv] = 11, [snd_soc_dapm_hp] = 11, [snd_soc_dapm_spk] = 11, @@ -100,7 +100,9 @@ static int dapm_up_seq[] = { static int dapm_down_seq[] = { [snd_soc_dapm_pre] = 0, [snd_soc_dapm_kcontrol] = 1, - [snd_soc_dapm_adc] = 2, + [snd_soc_dapm_aif_in] = 2, + [snd_soc_dapm_aif_out] = 2, + [snd_soc_dapm_adc] = 5, [snd_soc_dapm_hp] = 3, [snd_soc_dapm_spk] = 3, [snd_soc_dapm_line] = 3, @@ -114,8 +116,6 @@ static int dapm_down_seq[] = { [snd_soc_dapm_micbias] = 8, [snd_soc_dapm_mux] = 9, [snd_soc_dapm_demux] = 9, - [snd_soc_dapm_aif_in] = 10, - [snd_soc_dapm_aif_out] = 10, [snd_soc_dapm_dai_in] = 10, [snd_soc_dapm_dai_out] = 10, [snd_soc_dapm_dai_link] = 11, @@ -282,6 +282,8 @@ void dapm_mark_endpoints_dirty(struct snd_soc_card *card) mutex_lock(&card->dapm_mutex); list_for_each_entry(w, &card->widgets, list) { + if (w->ignore_suspend) + continue; if (w->is_ep) { dapm_mark_dirty(w, "Rechecking endpoints"); if (w->is_ep & SND_SOC_DAPM_EP_SINK) @@ -431,13 +433,14 @@ static void dapm_kcontrol_free(struct snd_kcontrol *kctl) kfree(data); } -static struct snd_soc_dapm_widget_list *dapm_kcontrol_get_wlist( +struct snd_soc_dapm_widget_list *dapm_kcontrol_get_wlist( const struct snd_kcontrol *kcontrol) { struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol); return data->wlist; } +EXPORT_SYMBOL(dapm_kcontrol_get_wlist); static int dapm_kcontrol_add_widget(struct snd_kcontrol *kcontrol, struct snd_soc_dapm_widget *widget) @@ -756,7 +759,7 @@ static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i) unsigned int max = mc->max; unsigned int mask = (1 << fls(max)) - 1; unsigned int invert = mc->invert; - unsigned int val; + unsigned int val = 0; if (reg != SND_SOC_NOPM) { soc_dapm_read(p->sink->dapm, reg, &val); @@ -1512,7 +1515,7 @@ static void dapm_seq_run(struct snd_soc_card *card, /* Do we need to apply any queued changes? */ if (sort[w->id] != cur_sort || w->reg != cur_reg || w->dapm != cur_dapm || w->subseq != cur_subseq) { - if (!list_empty(&pending)) + if (cur_dapm && !list_empty(&pending)) dapm_seq_run_coalesced(card, &pending); if (cur_dapm && cur_dapm->seq_notifier) { @@ -1570,12 +1573,17 @@ static void dapm_seq_run(struct snd_soc_card *card, break; } + /* Add this debug log to keep track of widgets being + * powered-up and powered-down */ + dev_dbg(w->dapm->dev, "dapm: powering %s widget %s\n", + power_up ? "up" : "down", w->name); + if (ret < 0) dev_err(w->dapm->dev, "ASoC: Failed to apply widget power: %d\n", ret); } - if (!list_empty(&pending)) + if (cur_dapm && !list_empty(&pending)) dapm_seq_run_coalesced(card, &pending); if (cur_dapm && cur_dapm->seq_notifier) { @@ -1807,10 +1815,13 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event) LIST_HEAD(down_list); ASYNC_DOMAIN_EXCLUSIVE(async_domain); enum snd_soc_bias_level bias; + struct snd_soc_platform *p; + struct snd_soc_codec *c; lockdep_assert_held(&card->dapm_mutex); trace_snd_soc_dapm_start(card); + mutex_lock(&card->dapm_power_mutex); list_for_each_entry(d, &card->dapm_list, list) { if (dapm_idle_bias_off(d)) @@ -1888,7 +1899,9 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event) dapm_pre_sequence_async(&card->dapm, 0); /* Run other bias changes in parallel */ list_for_each_entry(d, &card->dapm_list, list) { - if (d != &card->dapm) + p = snd_soc_dapm_to_platform(d); + c = snd_soc_dapm_to_codec(d); + if ((d != &card->dapm) && (c || p)) async_schedule_domain(dapm_pre_sequence_async, d, &async_domain); } @@ -1912,7 +1925,9 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event) /* Run all the bias changes in parallel */ list_for_each_entry(d, &card->dapm_list, list) { - if (d != &card->dapm) + p = snd_soc_dapm_to_platform(d); + c = snd_soc_dapm_to_codec(d); + if ((d != &card->dapm) && (c || p)) async_schedule_domain(dapm_post_sequence_async, d, &async_domain); } @@ -1929,6 +1944,7 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event) pop_dbg(card->dev, card->pop_time, "DAPM sequencing finished, waiting %dms\n", card->pop_time); pop_wait(card->pop_time); + mutex_unlock(&card->dapm_power_mutex); trace_snd_soc_dapm_done(card); @@ -2639,8 +2655,7 @@ static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm, dapm_mark_dirty(widgets[dir], "Route added"); } - if (dapm->card->instantiated && path->connect) - dapm_path_invalidate(path); + dapm_path_invalidate(path); return 0; err: @@ -3935,6 +3950,9 @@ static void dapm_connect_dai_link_widgets(struct snd_soc_card *card, for (i = 0; i < rtd->num_codecs; i++) { struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; + if (!cpu_dai->component->codec) + continue; + /* connect BE DAI playback if widgets are valid */ if (codec_dai->playback_widget && cpu_dai->playback_widget) { source = cpu_dai->playback_widget; |
