diff options
author | Mark Brown <broonie@linaro.org> | 2014-01-09 14:34:29 +0000 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-01-09 14:34:29 +0000 |
commit | 0583d21c2ea94121707fc63badb73ffd4c2526c2 (patch) | |
tree | b5e7cced29f4036247c6a70184d4006dc4b651bb | |
parent | 81fd7993c12c5a7029e7f07992fdea410b91adb8 (diff) | |
parent | b893ea5f1cd1adbbd7e0794d16d47bbb46f80733 (diff) |
Merge remote-tracking branch 'asoc/topic/dapm' into asoc-next
-rw-r--r-- | include/sound/soc-dai.h | 2 | ||||
-rw-r--r-- | include/sound/soc-dapm.h | 1 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 1 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 77 | ||||
-rw-r--r-- | sound/soc/soc-utils.c | 7 |
5 files changed, 84 insertions, 4 deletions
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 243d3b689699..71f27c403194 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -123,6 +123,8 @@ int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate); int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute, int direction); +int snd_soc_dai_is_dummy(struct snd_soc_dai *dai); + struct snd_soc_dai_ops { /* * DAI clocking configuration, all optional. diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 56ebdfca6273..68d92e36facd 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -412,6 +412,7 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, struct snd_soc_dai *dai); int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card); +void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card); int snd_soc_dapm_new_pcm(struct snd_soc_card *card, const struct snd_soc_pcm_stream *params, struct snd_soc_dapm_widget *source, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index be88df5eeaf7..3a128f0cd752 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1728,6 +1728,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) } snd_soc_dapm_link_dai_widgets(card); + snd_soc_dapm_connect_dai_link_widgets(card); if (card->controls) snd_soc_add_card_controls(card, card->controls, card->num_controls); diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index dcade130157f..51b4c192f41a 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2868,6 +2868,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, unsigned int val; int connect, change; struct snd_soc_dapm_update update; + int ret = 0; if (snd_soc_volsw_is_stereo(mc)) dev_warn(codec->dapm.dev, @@ -2901,12 +2902,16 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, card->update = &update; } - soc_dapm_mixer_update_power(card, kcontrol, connect); + ret = soc_dapm_mixer_update_power(card, kcontrol, connect); card->update = NULL; } mutex_unlock(&card->dapm_mutex); + + if (ret > 0) + soc_dpcm_runtime_update(card); + return change; } EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw); @@ -2955,6 +2960,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, unsigned int val, mux, change; unsigned int mask; struct snd_soc_dapm_update update; + int ret = 0; if (ucontrol->value.enumerated.item[0] > e->max - 1) return -EINVAL; @@ -2978,12 +2984,16 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, update.val = val; card->update = &update; - soc_dapm_mux_update_power(card, kcontrol, mux, e); + ret = soc_dapm_mux_update_power(card, kcontrol, mux, e); card->update = NULL; } mutex_unlock(&card->dapm_mutex); + + if (ret > 0) + soc_dpcm_runtime_update(card); + return change; } EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); @@ -3019,6 +3029,7 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol, struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; int change; + int ret = 0; if (ucontrol->value.enumerated.item[0] >= e->max) return -EINVAL; @@ -3028,9 +3039,13 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol, value = ucontrol->value.enumerated.item[0]; change = dapm_kcontrol_set_value(kcontrol, value); if (change) - soc_dapm_mux_update_power(card, kcontrol, value, e); + ret = soc_dapm_mux_update_power(card, kcontrol, value, e); mutex_unlock(&card->dapm_mutex); + + if (ret > 0) + soc_dpcm_runtime_update(card); + return change; } EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt); @@ -3097,6 +3112,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, unsigned int val, mux, change; unsigned int mask; struct snd_soc_dapm_update update; + int ret = 0; if (ucontrol->value.enumerated.item[0] > e->max - 1) return -EINVAL; @@ -3120,12 +3136,16 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, update.val = val; card->update = &update; - soc_dapm_mux_update_power(card, kcontrol, mux, e); + ret = soc_dapm_mux_update_power(card, kcontrol, mux, e); card->update = NULL; } mutex_unlock(&card->dapm_mutex); + + if (ret > 0) + soc_dpcm_runtime_update(card); + return change; } EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double); @@ -3614,6 +3634,55 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card) return 0; } +void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card) +{ + struct snd_soc_pcm_runtime *rtd = card->rtd; + struct snd_soc_dai *cpu_dai, *codec_dai; + struct snd_soc_dapm_route r; + int i; + + memset(&r, 0, sizeof(r)); + + /* for each BE DAI link... */ + for (i = 0; i < card->num_rtd; i++) { + rtd = &card->rtd[i]; + cpu_dai = rtd->cpu_dai; + codec_dai = rtd->codec_dai; + + /* dynamic FE links have no fixed DAI mapping */ + if (rtd->dai_link->dynamic) + continue; + + /* there is no point in connecting BE DAI links with dummies */ + if (snd_soc_dai_is_dummy(codec_dai) || + snd_soc_dai_is_dummy(cpu_dai)) + continue; + + /* connect BE DAI playback if widgets are valid */ + if (codec_dai->playback_widget && cpu_dai->playback_widget) { + r.source = cpu_dai->playback_widget->name; + r.sink = codec_dai->playback_widget->name; + dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", + cpu_dai->codec->name, r.source, + codec_dai->platform->name, r.sink); + + snd_soc_dapm_add_route(&card->dapm, &r); + } + + /* connect BE DAI capture if widgets are valid */ + if (codec_dai->capture_widget && cpu_dai->capture_widget) { + r.source = codec_dai->capture_widget->name; + r.sink = cpu_dai->capture_widget->name; + dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", + codec_dai->codec->name, r.source, + cpu_dai->platform->name, r.sink); + + snd_soc_dapm_add_route(&card->dapm, &r); + } + + } +} + static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, int event) { diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 6ebdfd9a1a1d..7f22ca35a413 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -119,6 +119,13 @@ static struct snd_soc_dai_driver dummy_dai = { }, }; +int snd_soc_dai_is_dummy(struct snd_soc_dai *dai) +{ + if (dai->driver == &dummy_dai) + return 1; + return 0; +} + static int snd_soc_dummy_probe(struct platform_device *pdev) { int ret; |