ASoC: hdmi-codec: fix routing
authorRussell King <rmk+kernel@armlinux.org.uk>
Sat, 14 Jul 2018 15:01:06 +0000 (16:01 +0100)
committerMark Brown <broonie@kernel.org>
Mon, 16 Jul 2018 14:30:03 +0000 (15:30 +0100)
Commit 943fa0228252 ("ASoC: hdmi-codec: Use different name for playback
streams") broke hdmi-codec's routing between it's output "TX" widget
and the S/PDIF or I2S streams by renaming the streams.

Whether an error occurs or not is dependent on whether there is another
widget called "Playback" registered by some other component - if there
is, that widget will be (incorrectly) bound to the HDMI codec's "TX"
output widget.  If we end up connecting "TX" incorrectly, it can result
in components not being started, causing no audio output.

Since the I2S and S/PDIF streams now have different names, we can't
use a static route at component level to describe the relationship, so
arrange to dynamically create the route when the DAI driver is probed.

Fixes: 943fa0228252 ("ASoC: hdmi-codec: Use different name for playback streams")
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/hdmi-codec.c

index 6fa11888672d4ca0c60096205c45e52f647f9ab8..3e5b12de71bb26a286827f14acdb63c52d7e6871 100644 (file)
@@ -291,10 +291,6 @@ static const struct snd_soc_dapm_widget hdmi_widgets[] = {
        SND_SOC_DAPM_OUTPUT("TX"),
 };
 
-static const struct snd_soc_dapm_route hdmi_routes[] = {
-       { "TX", NULL, "Playback" },
-};
-
 enum {
        DAI_ID_I2S = 0,
        DAI_ID_SPDIF,
@@ -689,9 +685,23 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
        return snd_ctl_add(rtd->card->snd_card, kctl);
 }
 
+static int hdmi_dai_probe(struct snd_soc_dai *dai)
+{
+       struct snd_soc_dapm_context *dapm;
+       struct snd_soc_dapm_route route = {
+               .sink = "TX",
+               .source = dai->driver->playback.stream_name,
+       };
+
+       dapm = snd_soc_component_get_dapm(dai->component);
+
+       return snd_soc_dapm_add_routes(dapm, &route, 1);
+}
+
 static const struct snd_soc_dai_driver hdmi_i2s_dai = {
        .name = "i2s-hifi",
        .id = DAI_ID_I2S,
+       .probe = hdmi_dai_probe,
        .playback = {
                .stream_name = "I2S Playback",
                .channels_min = 2,
@@ -707,6 +717,7 @@ static const struct snd_soc_dai_driver hdmi_i2s_dai = {
 static const struct snd_soc_dai_driver hdmi_spdif_dai = {
        .name = "spdif-hifi",
        .id = DAI_ID_SPDIF,
+       .probe = hdmi_dai_probe,
        .playback = {
                .stream_name = "SPDIF Playback",
                .channels_min = 2,
@@ -733,8 +744,6 @@ static int hdmi_of_xlate_dai_id(struct snd_soc_component *component,
 static const struct snd_soc_component_driver hdmi_driver = {
        .dapm_widgets           = hdmi_widgets,
        .num_dapm_widgets       = ARRAY_SIZE(hdmi_widgets),
-       .dapm_routes            = hdmi_routes,
-       .num_dapm_routes        = ARRAY_SIZE(hdmi_routes),
        .of_xlate_dai_id        = hdmi_of_xlate_dai_id,
        .idle_bias_on           = 1,
        .use_pmdown_time        = 1,