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;
1417module_param (dsp_driver , int , 0444 );
1518MODULE_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
2128struct 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+
306366int 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
356420MODULE_LICENSE ("GPL v2" );
357421MODULE_DESCRIPTION ("Intel DSP config driver" );
422+ MODULE_IMPORT_NS (SOUNDWIRE_INTEL_INIT );
0 commit comments