Skip to content

Commit 0650857

Browse files
plbossarttiwai
authored andcommitted
ALSA: hda: add autodetection for SoundWire
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>
1 parent 4963d66 commit 0650857

File tree

1 file changed

+81
-16
lines changed

1 file changed

+81
-16
lines changed

sound/hda/intel-dsp-config.c

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
// SPDX-License-Identifier: GPL-2.0
22
// Copyright (c) 2019 Jaroslav Kysela <perex@perex.cz>
33

4+
#include <linux/acpi.h>
45
#include <linux/bits.h>
56
#include <linux/dmi.h>
67
#include <linux/module.h>
78
#include <linux/pci.h>
9+
#include <linux/soundwire/sdw.h>
10+
#include <linux/soundwire/sdw_intel.h>
811
#include <sound/core.h>
912
#include <sound/intel-dsp-config.h>
1013
#include <sound/intel-nhlt.h>
@@ -14,9 +17,13 @@ static int dsp_driver;
1417
module_param(dsp_driver, int, 0444);
1518
MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF)");
1619

17-
#define FLAG_SST BIT(0)
18-
#define FLAG_SOF BIT(1)
19-
#define FLAG_SOF_ONLY_IF_DMIC BIT(16)
20+
#define FLAG_SST BIT(0)
21+
#define FLAG_SOF BIT(1)
22+
#define FLAG_SOF_ONLY_IF_DMIC BIT(16)
23+
#define FLAG_SOF_ONLY_IF_SOUNDWIRE BIT(17)
24+
25+
#define FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE (FLAG_SOF_ONLY_IF_DMIC | \
26+
FLAG_SOF_ONLY_IF_SOUNDWIRE)
2027

2128
struct config_entry {
2229
u32 flags;
@@ -166,7 +173,7 @@ static const struct config_entry config_table[] = {
166173
}
167174
},
168175
{
169-
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
176+
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
170177
.device = 0x9dc8,
171178
},
172179
#endif
@@ -187,7 +194,7 @@ static const struct config_entry config_table[] = {
187194
}
188195
},
189196
{
190-
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
197+
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
191198
.device = 0xa348,
192199
},
193200
#endif
@@ -204,18 +211,50 @@ static const struct config_entry config_table[] = {
204211
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
205212
}
206213
},
214+
{
215+
.matches = {
216+
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
217+
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6")
218+
},
219+
},
220+
{
221+
/* early version of SKU 09C6 */
222+
.matches = {
223+
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
224+
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983")
225+
},
226+
},
207227
{}
208228
}
209229
},
210230
{
211-
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
231+
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
212232
.device = 0x02c8,
213233
},
214234
#endif
215235
/* Cometlake-H */
216236
#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE_H)
217237
{
218-
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
238+
.flags = FLAG_SOF,
239+
.device = 0x06c8,
240+
.dmi_table = (const struct dmi_system_id []) {
241+
{
242+
.matches = {
243+
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
244+
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"),
245+
},
246+
},
247+
{
248+
.matches = {
249+
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
250+
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"),
251+
},
252+
},
253+
{}
254+
}
255+
},
256+
{
257+
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
219258
.device = 0x06c8,
220259
},
221260
#endif
@@ -236,7 +275,7 @@ static const struct config_entry config_table[] = {
236275
}
237276
},
238277
{
239-
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
278+
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
240279
.device = 0x34c8,
241280
},
242281
#endif
@@ -256,9 +295,8 @@ static const struct config_entry config_table[] = {
256295
{}
257296
}
258297
},
259-
260298
{
261-
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
299+
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
262300
.device = 0xa0c8,
263301
},
264302
#endif
@@ -303,6 +341,28 @@ static int snd_intel_dsp_check_dmic(struct pci_dev *pci)
303341
return ret;
304342
}
305343

344+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
345+
static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
346+
{
347+
struct sdw_intel_acpi_info info;
348+
acpi_handle handle;
349+
int ret;
350+
351+
handle = ACPI_HANDLE(&pci->dev);
352+
353+
ret = sdw_intel_acpi_scan(handle, &info);
354+
if (ret < 0)
355+
return ret;
356+
357+
return info.link_mask;
358+
}
359+
#else
360+
static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
361+
{
362+
return 0;
363+
}
364+
#endif
365+
306366
int snd_intel_dsp_driver_probe(struct pci_dev *pci)
307367
{
308368
const struct config_entry *cfg;
@@ -336,14 +396,18 @@ int snd_intel_dsp_driver_probe(struct pci_dev *pci)
336396
return SND_INTEL_DSP_DRIVER_ANY;
337397

338398
if (cfg->flags & FLAG_SOF) {
339-
if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC) {
340-
if (snd_intel_dsp_check_dmic(pci)) {
341-
dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n");
342-
return SND_INTEL_DSP_DRIVER_SOF;
343-
}
344-
} else {
399+
if (cfg->flags & FLAG_SOF_ONLY_IF_SOUNDWIRE &&
400+
snd_intel_dsp_check_soundwire(pci) > 0) {
401+
dev_info(&pci->dev, "SoundWire enabled on CannonLake+ platform, using SOF driver\n");
402+
return SND_INTEL_DSP_DRIVER_SOF;
403+
}
404+
if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC &&
405+
snd_intel_dsp_check_dmic(pci)) {
406+
dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n");
345407
return SND_INTEL_DSP_DRIVER_SOF;
346408
}
409+
if (!(cfg->flags & FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE))
410+
return SND_INTEL_DSP_DRIVER_SOF;
347411
}
348412

349413
if (cfg->flags & FLAG_SST)
@@ -355,3 +419,4 @@ EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe);
355419

356420
MODULE_LICENSE("GPL v2");
357421
MODULE_DESCRIPTION("Intel DSP config driver");
422+
MODULE_IMPORT_NS(SOUNDWIRE_INTEL_INIT);

0 commit comments

Comments
 (0)