diff mbox series

[SRU,OEM-5.6,01/15] ALSA: hda: add autodetection for SoundWire

Message ID 20201016012237.16530-2-hui.wang@canonical.com
State New
Headers show
Series alsa: add Dell tgl soundwire machines support | expand

Commit Message

Hui Wang Oct. 16, 2020, 1:22 a.m. UTC
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

BugLink: https://bugs.launchpad.net/bugs/1900069

When an ACPI companion device is present and the SoundWire link mask
information is available, use SoundWire instead of legacy HDA or
Skylake drivers.

The SOF driver is selected when SoundWire or DMIC are detected. There
is no precedence at this level. In the SOF driver proper, SoundWire
will be handled first since it is mutually exclusive with HDaudio.

Known devices with an existing DMI quirk bypass this detection to
avoid any dependency on ACPI/DSDT tables.

Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20200409190251.16569-1-pierre-louis.bossart@linux.intel.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
(backported from commit 0650857570d161486a95d37bc8682628881ae2da)
Signed-off-by: Hui Wang <hui.wang@canonical.com>
---
 sound/hda/intel-dsp-config.c | 65 +++++++++++++++++++++++++++---------
 1 file changed, 49 insertions(+), 16 deletions(-)
diff mbox series

Patch

diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c
index a4f8149cac74..efa758adb62b 100644
--- a/sound/hda/intel-dsp-config.c
+++ b/sound/hda/intel-dsp-config.c
@@ -1,10 +1,13 @@ 
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (c) 2019 Jaroslav Kysela <perex@perex.cz>
 
+#include <linux/acpi.h>
 #include <linux/bits.h>
 #include <linux/dmi.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_intel.h>
 #include <sound/core.h>
 #include <sound/intel-dsp-config.h>
 #include <sound/intel-nhlt.h>
@@ -14,9 +17,13 @@  static int dsp_driver;
 module_param(dsp_driver, int, 0444);
 MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF)");
 
-#define FLAG_SST		BIT(0)
-#define FLAG_SOF		BIT(1)
-#define FLAG_SOF_ONLY_IF_DMIC	BIT(16)
+#define FLAG_SST			BIT(0)
+#define FLAG_SOF			BIT(1)
+#define FLAG_SOF_ONLY_IF_DMIC		BIT(16)
+#define FLAG_SOF_ONLY_IF_SOUNDWIRE	BIT(17)
+
+#define FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE (FLAG_SOF_ONLY_IF_DMIC | \
+					    FLAG_SOF_ONLY_IF_SOUNDWIRE)
 
 struct config_entry {
 	u32 flags;
@@ -166,7 +173,7 @@  static const struct config_entry config_table[] = {
 		}
 	},
 	{
-		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
 		.device = 0x9dc8,
 	},
 #endif
@@ -187,7 +194,7 @@  static const struct config_entry config_table[] = {
 		}
 	},
 	{
-		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
 		.device = 0xa348,
 	},
 #endif
@@ -221,7 +228,7 @@  static const struct config_entry config_table[] = {
 		}
 	},
 	{
-		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
 		.device = 0x02c8,
 	},
 #endif
@@ -247,7 +254,7 @@  static const struct config_entry config_table[] = {
 		}
 	},
 	{
-		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
 		.device = 0x06c8,
 	},
 #endif
@@ -268,7 +275,7 @@  static const struct config_entry config_table[] = {
 		}
 	},
 	{
-		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
 		.device = 0x34c8,
 	},
 #endif
@@ -288,9 +295,8 @@  static const struct config_entry config_table[] = {
 			{}
 		}
 	},
-
 	{
-		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
 		.device = 0xa0c8,
 	},
 #endif
@@ -335,6 +341,28 @@  static int snd_intel_dsp_check_dmic(struct pci_dev *pci)
 	return ret;
 }
 
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
+static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
+{
+	struct sdw_intel_acpi_info info = { 0 };
+	acpi_handle handle;
+	int ret;
+
+	handle = ACPI_HANDLE(&pci->dev);
+
+	ret = sdw_intel_acpi_scan(handle, &info);
+	if (ret < 0)
+		return ret;
+
+	return info.link_mask;
+}
+#else
+static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
+{
+	return 0;
+}
+#endif
+
 int snd_intel_dsp_driver_probe(struct pci_dev *pci)
 {
 	const struct config_entry *cfg;
@@ -368,14 +396,18 @@  int snd_intel_dsp_driver_probe(struct pci_dev *pci)
 		return SND_INTEL_DSP_DRIVER_ANY;
 
 	if (cfg->flags & FLAG_SOF) {
-		if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC) {
-			if (snd_intel_dsp_check_dmic(pci)) {
-				dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n");
-				return SND_INTEL_DSP_DRIVER_SOF;
-			}
-		} else {
+		if (cfg->flags & FLAG_SOF_ONLY_IF_SOUNDWIRE &&
+		    snd_intel_dsp_check_soundwire(pci) > 0) {
+			dev_info(&pci->dev, "SoundWire enabled on CannonLake+ platform, using SOF driver\n");
 			return SND_INTEL_DSP_DRIVER_SOF;
 		}
+		if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC &&
+		    snd_intel_dsp_check_dmic(pci)) {
+			dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n");
+			return SND_INTEL_DSP_DRIVER_SOF;
+		}
+		if (!(cfg->flags & FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE))
+			return SND_INTEL_DSP_DRIVER_SOF;
 	}
 
 	if (cfg->flags & FLAG_SST)
@@ -387,3 +419,4 @@  EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("Intel DSP config driver");
+MODULE_IMPORT_NS(SOUNDWIRE_INTEL_INIT);