ASoC: SOF: Intel: add support for snd-hda-codec-hdmi
authorKai Vehmanen <kai.vehmanen@linux.intel.com>
Tue, 29 Oct 2019 13:40:13 +0000 (15:40 +0200)
committerMark Brown <broonie@kernel.org>
Tue, 29 Oct 2019 17:32:04 +0000 (17:32 +0000)
Add support to implement HDMI/DP audio by using the common
snd-hda-codec-hdmi driver.

Change of codec driver affects user-space as the two
drivers expose different mixer controls. A new kernel
module option "use_common_hdmi" is added to user-space
to indicate which interface should be used. The default
driver can be selected via a Kconfig option.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20191029134017.18901-6-kai.vehmanen@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/intel/Kconfig
sound/soc/sof/intel/hda-codec.c
sound/soc/sof/intel/hda.c
sound/soc/sof/intel/hda.h

index 342f22a7c64f93422f4bd20ac1cb3fe766b6bfc3..d52298946c00c1e510ef093ee80370ad1540de68 100644 (file)
@@ -299,6 +299,16 @@ config SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1
          Say Y if you want to enable DMI Link L1
          If unsure, select "N".
 
+config SND_SOC_SOF_HDA_COMMON_HDMI_CODEC
+       bool "SOF common HDA HDMI codec driver"
+       depends on SND_SOC_SOF_HDA_LINK
+       depends on SND_HDA_CODEC_HDMI
+       help
+         This adds support for HDMI audio by using the common HDA
+         HDMI/DisplayPort codec driver.
+         Say Y if you want to use the common codec driver with SOF.
+         If unsure select "Y".
+
 endif ## SND_SOC_SOF_HDA_COMMON
 
 config SND_SOC_SOF_HDA_LINK_BASELINE
index 3ca6795a89ba3a042c9cfacc989aaea3c400073f..827f84a0722e91d7266d5729f5bc6273cbd42f51 100644 (file)
@@ -84,6 +84,8 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address)
 {
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
        struct hdac_hda_priv *hda_priv;
+       struct snd_soc_acpi_mach_params *mach_params = NULL;
+       struct snd_sof_pdata *pdata = sdev->pdata;
 #endif
        struct hda_bus *hbus = sof_to_hbus(sdev);
        struct hdac_device *hdev;
@@ -113,8 +115,19 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address)
        if (ret < 0)
                return ret;
 
-       /* use legacy bus only for HDA codecs, idisp uses ext bus */
-       if ((resp & 0xFFFF0000) != IDISP_VID_INTEL) {
+       if (pdata->machine)
+               mach_params = (struct snd_soc_acpi_mach_params *)
+                       &pdata->machine->mach_params;
+
+       if ((resp & 0xFFFF0000) == IDISP_VID_INTEL)
+               hda_priv->need_display_power = true;
+
+       /*
+        * if common HDMI codec driver is not used, codec load
+        * is skipped here and hdac_hdmi is used instead
+        */
+       if ((mach_params && mach_params->common_hdmi_codec_drv) ||
+           (resp & 0xFFFF0000) != IDISP_VID_INTEL) {
                hdev->type = HDA_DEV_LEGACY;
                hda_codec_load_module(&hda_priv->codec);
        }
@@ -155,7 +168,8 @@ int hda_codec_probe_bus(struct snd_sof_dev *sdev)
 }
 EXPORT_SYMBOL(hda_codec_probe_bus);
 
-#if IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)
+#if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) || \
+       IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)
 
 void hda_codec_i915_get(struct snd_sof_dev *sdev)
 {
@@ -204,6 +218,6 @@ int hda_codec_i915_exit(struct snd_sof_dev *sdev)
 }
 EXPORT_SYMBOL(hda_codec_i915_exit);
 
-#endif /* CONFIG_SND_SOC_HDAC_HDMI */
+#endif
 
 MODULE_LICENSE("Dual BSD/GPL");
index 103f4273c4d34f6964491cfb6aac18f0616c5403..7dc0018dc4c3a4cae3f20abbbc7c8b545b6c5d49 100644 (file)
@@ -53,6 +53,11 @@ MODULE_PARM_DESC(use_msi, "SOF HDA use PCI MSI mode");
 static int hda_dmic_num = -1;
 module_param_named(dmic_num, hda_dmic_num, int, 0444);
 MODULE_PARM_DESC(dmic_num, "SOF HDA DMIC number");
+
+static bool hda_codec_use_common_hdmi =
+       IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_COMMON_HDMI_CODEC);
+module_param_named(use_common_hdmi, hda_codec_use_common_hdmi, bool, 0444);
+MODULE_PARM_DESC(use_common_hdmi, "SOF HDA use common HDMI codec driver");
 #endif
 
 static const struct hda_dsp_msg_code hda_dsp_rom_msg[] = {
@@ -459,6 +464,7 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
                        &pdata->machine->mach_params;
                mach_params->codec_mask = bus->codec_mask;
                mach_params->platform = dev_name(sdev->dev);
+               mach_params->common_hdmi_codec_drv = hda_codec_use_common_hdmi;
        }
 
        /* create codec instances */
index 16376f55e420c7f4a07032a99d6739e94624f8be..5ad73a34b09c6074bb57acd0a508f955cf13d292 100644 (file)
@@ -577,7 +577,9 @@ void hda_codec_jack_check(struct snd_sof_dev *sdev);
 
 #endif /* CONFIG_SND_SOC_SOF_HDA */
 
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) && IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) && \
+       (IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) || \
+        IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI))
 
 void hda_codec_i915_get(struct snd_sof_dev *sdev);
 void hda_codec_i915_put(struct snd_sof_dev *sdev);
@@ -591,7 +593,7 @@ static inline void hda_codec_i915_put(struct snd_sof_dev *sdev)  { }
 static inline int hda_codec_i915_init(struct snd_sof_dev *sdev) { return 0; }
 static inline int hda_codec_i915_exit(struct snd_sof_dev *sdev) { return 0; }
 
-#endif /* CONFIG_SND_SOC_SOF_HDA && CONFIG_SND_SOC_HDAC_HDMI */
+#endif
 
 /*
  * Trace Control.