ASoC: intel/skl/hda - add no-HDMI cases to generic HDA driver
authorKai Vehmanen <kai.vehmanen@linux.intel.com>
Thu, 20 Feb 2020 17:10:27 +0000 (19:10 +0200)
committerMark Brown <broonie@kernel.org>
Thu, 20 Feb 2020 20:28:44 +0000 (20:28 +0000)
Extend the generic HDA driver to support systems where iDisp/HDMI
audio codecs are disabled for some reason. Switch codecs to
SoC dummy in the affected DAI links. This allows to reuse
existing topologies for this case.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=206085
BugLink: https://bugzilla.opensuse.org/show_bug.cgi?id=1163677
BugLink: https://github.com/thesofproject/linux/issues/1658
Link: https://lore.kernel.org/r/20200220171028.22023-2-kai.vehmanen@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/boards/skl_hda_dsp_common.h
sound/soc/intel/boards/skl_hda_dsp_generic.c

index d6150670ca05471a0e0e097525a184bf6784a2e5..e8545d13062fd0cf37ec3b615caf3ffd679e9050 100644 (file)
@@ -49,6 +49,10 @@ static inline int skl_hda_hdmi_build_controls(struct snd_soc_card *card)
        struct snd_soc_component *component;
        struct skl_hda_hdmi_pcm *pcm;
 
+       /* HDMI disabled, do not create controls */
+       if (list_empty(&ctx->hdmi_pcm_list))
+               return 0;
+
        pcm = list_first_entry(&ctx->hdmi_pcm_list, struct skl_hda_hdmi_pcm,
                               head);
        component = pcm->codec_dai->component;
index 11eaee9ae41f72ce4354b8d7a676b05c8e0eb05b..fe2d3a23a4efe260407a015d0a21b69271cbf981 100644 (file)
@@ -61,6 +61,9 @@ static const struct snd_soc_dapm_route skl_hda_map[] = {
        { "Alt Analog CPU Capture", NULL, "Alt Analog Codec Capture" },
 };
 
+SND_SOC_DAILINK_DEF(dummy_codec,
+       DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")));
+
 static int skl_hda_card_late_probe(struct snd_soc_card *card)
 {
        return skl_hda_hdmi_jack_init(card);
@@ -114,13 +117,19 @@ static int skl_hda_fill_card_info(struct snd_soc_acpi_mach_params *mach_params)
 {
        struct snd_soc_card *card = &hda_soc_card;
        struct snd_soc_dai_link *dai_link;
-       u32 codec_count, codec_mask;
+       u32 codec_count, codec_mask, idisp_mask;
        int i, num_links, num_route;
 
        codec_mask = mach_params->codec_mask;
        codec_count = hweight_long(codec_mask);
+       idisp_mask = codec_mask & IDISP_CODEC_MASK;
+
+       if (!codec_count || codec_count > 2 ||
+           (codec_count == 2 && !idisp_mask))
+               return -EINVAL;
 
-       if (codec_count == 1 && codec_mask & IDISP_CODEC_MASK) {
+       if (codec_mask == idisp_mask) {
+               /* topology with iDisp as the only HDA codec */
                num_links = IDISP_DAI_COUNT + DMIC_DAI_COUNT;
                num_route = IDISP_ROUTE_COUNT;
 
@@ -135,13 +144,19 @@ static int skl_hda_fill_card_info(struct snd_soc_acpi_mach_params *mach_params)
                                skl_hda_be_dai_links[IDISP_DAI_COUNT +
                                        HDAC_DAI_COUNT + i];
                }
-       } else if (codec_count == 2 && codec_mask & IDISP_CODEC_MASK) {
+       } else {
+               /* topology with external and iDisp HDA codecs */
                num_links = ARRAY_SIZE(skl_hda_be_dai_links);
                num_route = ARRAY_SIZE(skl_hda_map);
                card->dapm_widgets = skl_hda_widgets;
                card->num_dapm_widgets = ARRAY_SIZE(skl_hda_widgets);
-       } else {
-               return -EINVAL;
+               if (!idisp_mask) {
+                       for (i = 0; i < IDISP_DAI_COUNT; i++) {
+                               skl_hda_be_dai_links[i].codecs = dummy_codec;
+                               skl_hda_be_dai_links[i].num_codecs =
+                                       ARRAY_SIZE(dummy_codec);
+                       }
+               }
        }
 
        card->num_links = num_links;