Commit | Line | Data |
---|---|---|
82d9d54a JK |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // Copyright (c) 2019 Jaroslav Kysela <perex@perex.cz> | |
3 | ||
06508575 | 4 | #include <linux/acpi.h> |
82d9d54a JK |
5 | #include <linux/bits.h> |
6 | #include <linux/dmi.h> | |
7 | #include <linux/module.h> | |
8 | #include <linux/pci.h> | |
06508575 PLB |
9 | #include <linux/soundwire/sdw.h> |
10 | #include <linux/soundwire/sdw_intel.h> | |
82d9d54a JK |
11 | #include <sound/core.h> |
12 | #include <sound/intel-dsp-config.h> | |
13 | #include <sound/intel-nhlt.h> | |
14 | ||
15 | static int dsp_driver; | |
16 | ||
17 | module_param(dsp_driver, int, 0444); | |
18 | MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF)"); | |
19 | ||
06508575 PLB |
20 | #define FLAG_SST BIT(0) |
21 | #define FLAG_SOF BIT(1) | |
df1fceac | 22 | #define FLAG_SST_ONLY_IF_DMIC BIT(15) |
06508575 PLB |
23 | #define FLAG_SOF_ONLY_IF_DMIC BIT(16) |
24 | #define FLAG_SOF_ONLY_IF_SOUNDWIRE BIT(17) | |
25 | ||
26 | #define FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE (FLAG_SOF_ONLY_IF_DMIC | \ | |
27 | FLAG_SOF_ONLY_IF_SOUNDWIRE) | |
82d9d54a JK |
28 | |
29 | struct config_entry { | |
30 | u32 flags; | |
31 | u16 device; | |
b5682305 | 32 | u8 acpi_hid[ACPI_ID_LEN]; |
82d9d54a | 33 | const struct dmi_system_id *dmi_table; |
9d36ceab | 34 | u8 codec_hid[ACPI_ID_LEN]; |
82d9d54a JK |
35 | }; |
36 | ||
37 | /* | |
38 | * configuration table | |
39 | * - the order of similar PCI ID entries is important! | |
40 | * - the first successful match will win | |
41 | */ | |
42 | static const struct config_entry config_table[] = { | |
cc8f81c7 PLB |
43 | /* Merrifield */ |
44 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD) | |
82d9d54a | 45 | { |
cc8f81c7 PLB |
46 | .flags = FLAG_SOF, |
47 | .device = 0x119a, | |
82d9d54a | 48 | }, |
cc8f81c7 PLB |
49 | #endif |
50 | /* Broxton-T */ | |
51 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE) | |
82d9d54a JK |
52 | { |
53 | .flags = FLAG_SOF, | |
cc8f81c7 | 54 | .device = 0x1a98, |
82d9d54a JK |
55 | }, |
56 | #endif | |
cc8f81c7 PLB |
57 | /* |
58 | * Apollolake (Broxton-P) | |
b79de57b | 59 | * the legacy HDAudio driver is used except on Up Squared (SOF) and |
9d36ceab | 60 | * Chromebooks (SST), as well as devices based on the ES8336 codec |
cc8f81c7 PLB |
61 | */ |
62 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE) | |
82d9d54a | 63 | { |
cc8f81c7 PLB |
64 | .flags = FLAG_SOF, |
65 | .device = 0x5a98, | |
66 | .dmi_table = (const struct dmi_system_id []) { | |
67 | { | |
68 | .ident = "Up Squared", | |
69 | .matches = { | |
70 | DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), | |
71 | DMI_MATCH(DMI_BOARD_NAME, "UP-APL01"), | |
72 | } | |
73 | }, | |
74 | {} | |
75 | } | |
82d9d54a | 76 | }, |
9d36ceab PLB |
77 | { |
78 | .flags = FLAG_SOF, | |
79 | .device = 0x5a98, | |
80 | .codec_hid = "ESSX8336", | |
81 | }, | |
cc8f81c7 PLB |
82 | #endif |
83 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL) | |
82d9d54a | 84 | { |
cc8f81c7 PLB |
85 | .flags = FLAG_SST, |
86 | .device = 0x5a98, | |
87 | .dmi_table = (const struct dmi_system_id []) { | |
88 | { | |
89 | .ident = "Google Chromebooks", | |
90 | .matches = { | |
91 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
92 | } | |
93 | }, | |
94 | {} | |
95 | } | |
82d9d54a JK |
96 | }, |
97 | #endif | |
cc8f81c7 | 98 | /* |
b79de57b | 99 | * Skylake and Kabylake use legacy HDAudio driver except for Google |
cc8f81c7 PLB |
100 | * Chromebooks (SST) |
101 | */ | |
102 | ||
103 | /* Sunrise Point-LP */ | |
104 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKL) | |
82d9d54a | 105 | { |
cc8f81c7 PLB |
106 | .flags = FLAG_SST, |
107 | .device = 0x9d70, | |
108 | .dmi_table = (const struct dmi_system_id []) { | |
109 | { | |
110 | .ident = "Google Chromebooks", | |
111 | .matches = { | |
112 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
113 | } | |
114 | }, | |
115 | {} | |
116 | } | |
82d9d54a | 117 | }, |
df1fceac CR |
118 | { |
119 | .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC, | |
120 | .device = 0x9d70, | |
121 | }, | |
82d9d54a | 122 | #endif |
cc8f81c7 PLB |
123 | /* Kabylake-LP */ |
124 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_KBL) | |
82d9d54a | 125 | { |
cc8f81c7 PLB |
126 | .flags = FLAG_SST, |
127 | .device = 0x9d71, | |
128 | .dmi_table = (const struct dmi_system_id []) { | |
129 | { | |
130 | .ident = "Google Chromebooks", | |
131 | .matches = { | |
132 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
133 | } | |
134 | }, | |
135 | {} | |
136 | } | |
82d9d54a | 137 | }, |
df1fceac CR |
138 | { |
139 | .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC, | |
140 | .device = 0x9d71, | |
141 | }, | |
82d9d54a | 142 | #endif |
cc8f81c7 PLB |
143 | |
144 | /* | |
b79de57b | 145 | * Geminilake uses legacy HDAudio driver except for Google |
9d36ceab | 146 | * Chromebooks and devices based on the ES8336 codec |
cc8f81c7 | 147 | */ |
82d9d54a JK |
148 | /* Geminilake */ |
149 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE) | |
150 | { | |
151 | .flags = FLAG_SOF, | |
152 | .device = 0x3198, | |
153 | .dmi_table = (const struct dmi_system_id []) { | |
154 | { | |
155 | .ident = "Google Chromebooks", | |
156 | .matches = { | |
157 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
158 | } | |
159 | }, | |
160 | {} | |
161 | } | |
162 | }, | |
9d36ceab PLB |
163 | { |
164 | .flags = FLAG_SOF, | |
165 | .device = 0x3198, | |
166 | .codec_hid = "ESSX8336", | |
167 | }, | |
82d9d54a | 168 | #endif |
cc8f81c7 PLB |
169 | |
170 | /* | |
171 | * CoffeeLake, CannonLake, CometLake, IceLake, TigerLake use legacy | |
b79de57b | 172 | * HDAudio driver except for Google Chromebooks and when DMICs are |
cc8f81c7 PLB |
173 | * present. Two cases are required since Coreboot does not expose NHLT |
174 | * tables. | |
175 | * | |
176 | * When the Chromebook quirk is not present, it's based on information | |
177 | * that no such device exists. When the quirk is present, it could be | |
178 | * either based on product information or a placeholder. | |
179 | */ | |
180 | ||
181 | /* Cannonlake */ | |
182 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE) | |
82d9d54a | 183 | { |
cc8f81c7 PLB |
184 | .flags = FLAG_SOF, |
185 | .device = 0x9dc8, | |
186 | .dmi_table = (const struct dmi_system_id []) { | |
187 | { | |
188 | .ident = "Google Chromebooks", | |
189 | .matches = { | |
190 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
191 | } | |
192 | }, | |
193 | {} | |
194 | } | |
82d9d54a | 195 | }, |
82d9d54a | 196 | { |
06508575 | 197 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, |
cc8f81c7 | 198 | .device = 0x9dc8, |
82d9d54a JK |
199 | }, |
200 | #endif | |
cc8f81c7 PLB |
201 | |
202 | /* Coffelake */ | |
203 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE) | |
204 | { | |
205 | .flags = FLAG_SOF, | |
206 | .device = 0xa348, | |
207 | .dmi_table = (const struct dmi_system_id []) { | |
208 | { | |
209 | .ident = "Google Chromebooks", | |
210 | .matches = { | |
211 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
212 | } | |
213 | }, | |
214 | {} | |
215 | } | |
216 | }, | |
82d9d54a | 217 | { |
06508575 | 218 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, |
cc8f81c7 | 219 | .device = 0xa348, |
82d9d54a JK |
220 | }, |
221 | #endif | |
cc8f81c7 | 222 | |
4228668e | 223 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE) |
cc8f81c7 | 224 | /* Cometlake-LP */ |
82d9d54a JK |
225 | { |
226 | .flags = FLAG_SOF, | |
cc8f81c7 | 227 | .device = 0x02c8, |
82d9d54a JK |
228 | .dmi_table = (const struct dmi_system_id []) { |
229 | { | |
cc8f81c7 | 230 | .ident = "Google Chromebooks", |
82d9d54a | 231 | .matches = { |
cc8f81c7 | 232 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), |
82d9d54a JK |
233 | } |
234 | }, | |
06508575 PLB |
235 | { |
236 | .matches = { | |
237 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | |
238 | DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6") | |
239 | }, | |
240 | }, | |
241 | { | |
242 | /* early version of SKU 09C6 */ | |
243 | .matches = { | |
244 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | |
245 | DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983") | |
246 | }, | |
247 | }, | |
82d9d54a JK |
248 | {} |
249 | } | |
250 | }, | |
82d9d54a | 251 | { |
06508575 | 252 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, |
cc8f81c7 | 253 | .device = 0x02c8, |
82d9d54a | 254 | }, |
cc8f81c7 | 255 | /* Cometlake-H */ |
82d9d54a | 256 | { |
06508575 PLB |
257 | .flags = FLAG_SOF, |
258 | .device = 0x06c8, | |
259 | .dmi_table = (const struct dmi_system_id []) { | |
260 | { | |
261 | .matches = { | |
262 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | |
263 | DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"), | |
264 | }, | |
265 | }, | |
266 | { | |
267 | .matches = { | |
268 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | |
269 | DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"), | |
270 | }, | |
271 | }, | |
272 | {} | |
273 | } | |
274 | }, | |
275 | { | |
276 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
cc8f81c7 | 277 | .device = 0x06c8, |
82d9d54a JK |
278 | }, |
279 | #endif | |
cc8f81c7 PLB |
280 | |
281 | /* Icelake */ | |
282 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE) | |
82d9d54a | 283 | { |
cc8f81c7 PLB |
284 | .flags = FLAG_SOF, |
285 | .device = 0x34c8, | |
286 | .dmi_table = (const struct dmi_system_id []) { | |
287 | { | |
288 | .ident = "Google Chromebooks", | |
289 | .matches = { | |
290 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
291 | } | |
292 | }, | |
293 | {} | |
294 | } | |
82d9d54a | 295 | }, |
82d9d54a | 296 | { |
06508575 | 297 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, |
cc8f81c7 | 298 | .device = 0x34c8, |
82d9d54a JK |
299 | }, |
300 | #endif | |
cc8f81c7 | 301 | |
82d9d54a JK |
302 | /* Tigerlake */ |
303 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE) | |
cc8f81c7 PLB |
304 | { |
305 | .flags = FLAG_SOF, | |
306 | .device = 0xa0c8, | |
307 | .dmi_table = (const struct dmi_system_id []) { | |
308 | { | |
309 | .ident = "Google Chromebooks", | |
310 | .matches = { | |
311 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
312 | } | |
313 | }, | |
314 | {} | |
315 | } | |
316 | }, | |
82d9d54a | 317 | { |
06508575 | 318 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, |
82d9d54a JK |
319 | .device = 0xa0c8, |
320 | }, | |
c5b5ff60 BL |
321 | { |
322 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
323 | .device = 0x43c8, | |
324 | }, | |
9d36ceab PLB |
325 | { |
326 | .flags = FLAG_SOF, | |
327 | .device = 0xa0c8, | |
328 | .codec_hid = "ESSX8336", | |
329 | }, | |
82d9d54a | 330 | #endif |
cc8f81c7 PLB |
331 | |
332 | /* Elkhart Lake */ | |
333 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE) | |
82d9d54a JK |
334 | { |
335 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC, | |
cc8f81c7 | 336 | .device = 0x4b55, |
82d9d54a | 337 | }, |
114613f6 PLB |
338 | { |
339 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC, | |
340 | .device = 0x4b58, | |
341 | }, | |
82d9d54a | 342 | #endif |
cc8f81c7 | 343 | |
c4294d7f KV |
344 | /* Alder Lake */ |
345 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE) | |
346 | { | |
347 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
348 | .device = 0x7ad0, | |
349 | }, | |
350 | { | |
351 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
352 | .device = 0x51c8, | |
353 | }, | |
4ad7935d KV |
354 | { |
355 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
356 | .device = 0x51cc, | |
357 | }, | |
4d5a628d KV |
358 | { |
359 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | |
360 | .device = 0x54c8, | |
361 | }, | |
c4294d7f KV |
362 | #endif |
363 | ||
82d9d54a JK |
364 | }; |
365 | ||
366 | static const struct config_entry *snd_intel_dsp_find_config | |
367 | (struct pci_dev *pci, const struct config_entry *table, u32 len) | |
368 | { | |
369 | u16 device; | |
370 | ||
371 | device = pci->device; | |
372 | for (; len > 0; len--, table++) { | |
373 | if (table->device != device) | |
374 | continue; | |
375 | if (table->dmi_table && !dmi_check_system(table->dmi_table)) | |
376 | continue; | |
9d36ceab PLB |
377 | if (table->codec_hid[0] && !acpi_dev_present(table->codec_hid, NULL, -1)) |
378 | continue; | |
82d9d54a JK |
379 | return table; |
380 | } | |
381 | return NULL; | |
382 | } | |
383 | ||
384 | static int snd_intel_dsp_check_dmic(struct pci_dev *pci) | |
385 | { | |
386 | struct nhlt_acpi_table *nhlt; | |
387 | int ret = 0; | |
388 | ||
389 | nhlt = intel_nhlt_init(&pci->dev); | |
390 | if (nhlt) { | |
8235a08b | 391 | if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_DMIC)) |
82d9d54a JK |
392 | ret = 1; |
393 | intel_nhlt_free(nhlt); | |
394 | } | |
395 | return ret; | |
396 | } | |
397 | ||
06508575 PLB |
398 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) |
399 | static int snd_intel_dsp_check_soundwire(struct pci_dev *pci) | |
400 | { | |
401 | struct sdw_intel_acpi_info info; | |
402 | acpi_handle handle; | |
403 | int ret; | |
404 | ||
405 | handle = ACPI_HANDLE(&pci->dev); | |
406 | ||
407 | ret = sdw_intel_acpi_scan(handle, &info); | |
408 | if (ret < 0) | |
409 | return ret; | |
410 | ||
411 | return info.link_mask; | |
412 | } | |
413 | #else | |
414 | static int snd_intel_dsp_check_soundwire(struct pci_dev *pci) | |
415 | { | |
416 | return 0; | |
417 | } | |
418 | #endif | |
419 | ||
82d9d54a JK |
420 | int snd_intel_dsp_driver_probe(struct pci_dev *pci) |
421 | { | |
422 | const struct config_entry *cfg; | |
423 | ||
82d9d54a | 424 | /* Intel vendor only */ |
91636a82 | 425 | if (pci->vendor != 0x8086) |
82d9d54a JK |
426 | return SND_INTEL_DSP_DRIVER_ANY; |
427 | ||
0e5cc221 PLB |
428 | /* |
429 | * Legacy devices don't have a PCI-based DSP and use HDaudio | |
430 | * for HDMI/DP support, ignore kernel parameter | |
431 | */ | |
432 | switch (pci->device) { | |
433 | case 0x160c: /* Broadwell */ | |
434 | case 0x0a0c: /* Haswell */ | |
435 | case 0x0c0c: | |
436 | case 0x0d0c: | |
437 | case 0x0f04: /* Baytrail */ | |
438 | case 0x2284: /* Braswell */ | |
439 | return SND_INTEL_DSP_DRIVER_ANY; | |
440 | } | |
441 | ||
91636a82 TI |
442 | if (dsp_driver > 0 && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST) |
443 | return dsp_driver; | |
444 | ||
82d9d54a JK |
445 | /* |
446 | * detect DSP by checking class/subclass/prog-id information | |
447 | * class=04 subclass 03 prog-if 00: no DSP, use legacy driver | |
448 | * class=04 subclass 01 prog-if 00: DSP is present | |
449 | * (and may be required e.g. for DMIC or SSP support) | |
450 | * class=04 subclass 03 prog-if 80: use DSP or legacy mode | |
451 | */ | |
452 | if (pci->class == 0x040300) | |
453 | return SND_INTEL_DSP_DRIVER_LEGACY; | |
454 | if (pci->class != 0x040100 && pci->class != 0x040380) { | |
b79de57b | 455 | dev_err(&pci->dev, "Unknown PCI class/subclass/prog-if information (0x%06x) found, selecting HDAudio legacy driver\n", pci->class); |
82d9d54a JK |
456 | return SND_INTEL_DSP_DRIVER_LEGACY; |
457 | } | |
458 | ||
459 | dev_info(&pci->dev, "DSP detected with PCI class/subclass/prog-if info 0x%06x\n", pci->class); | |
460 | ||
461 | /* find the configuration for the specific device */ | |
462 | cfg = snd_intel_dsp_find_config(pci, config_table, ARRAY_SIZE(config_table)); | |
463 | if (!cfg) | |
464 | return SND_INTEL_DSP_DRIVER_ANY; | |
465 | ||
466 | if (cfg->flags & FLAG_SOF) { | |
06508575 PLB |
467 | if (cfg->flags & FLAG_SOF_ONLY_IF_SOUNDWIRE && |
468 | snd_intel_dsp_check_soundwire(pci) > 0) { | |
469 | dev_info(&pci->dev, "SoundWire enabled on CannonLake+ platform, using SOF driver\n"); | |
470 | return SND_INTEL_DSP_DRIVER_SOF; | |
471 | } | |
472 | if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC && | |
473 | snd_intel_dsp_check_dmic(pci)) { | |
474 | dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n"); | |
82d9d54a JK |
475 | return SND_INTEL_DSP_DRIVER_SOF; |
476 | } | |
06508575 PLB |
477 | if (!(cfg->flags & FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE)) |
478 | return SND_INTEL_DSP_DRIVER_SOF; | |
82d9d54a JK |
479 | } |
480 | ||
df1fceac CR |
481 | |
482 | if (cfg->flags & FLAG_SST) { | |
483 | if (cfg->flags & FLAG_SST_ONLY_IF_DMIC) { | |
484 | if (snd_intel_dsp_check_dmic(pci)) { | |
485 | dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SST driver\n"); | |
486 | return SND_INTEL_DSP_DRIVER_SST; | |
487 | } | |
488 | } else { | |
489 | return SND_INTEL_DSP_DRIVER_SST; | |
490 | } | |
491 | } | |
82d9d54a JK |
492 | |
493 | return SND_INTEL_DSP_DRIVER_LEGACY; | |
494 | } | |
495 | EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe); | |
496 | ||
5427c7d6 HG |
497 | /* Should we default to SOF or SST for BYT/CHT ? */ |
498 | #if IS_ENABLED(CONFIG_SND_INTEL_BYT_PREFER_SOF) || \ | |
499 | !IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) | |
500 | #define FLAG_SST_OR_SOF_BYT FLAG_SOF | |
501 | #else | |
502 | #define FLAG_SST_OR_SOF_BYT FLAG_SST | |
503 | #endif | |
504 | ||
b5682305 PLB |
505 | /* |
506 | * configuration table | |
507 | * - the order of similar ACPI ID entries is important! | |
508 | * - the first successful match will win | |
509 | */ | |
510 | static const struct config_entry acpi_config_table[] = { | |
5427c7d6 HG |
511 | #if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) || \ |
512 | IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) | |
b5682305 | 513 | /* BayTrail */ |
b5682305 | 514 | { |
5427c7d6 | 515 | .flags = FLAG_SST_OR_SOF_BYT, |
b5682305 PLB |
516 | .acpi_hid = "80860F28", |
517 | }, | |
b5682305 | 518 | /* CherryTrail */ |
b5682305 | 519 | { |
5427c7d6 | 520 | .flags = FLAG_SST_OR_SOF_BYT, |
b5682305 PLB |
521 | .acpi_hid = "808622A8", |
522 | }, | |
523 | #endif | |
803e5913 PLB |
524 | /* Broadwell */ |
525 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT) | |
526 | { | |
527 | .flags = FLAG_SST, | |
528 | .acpi_hid = "INT3438" | |
529 | }, | |
530 | #endif | |
531 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) | |
532 | { | |
533 | .flags = FLAG_SOF, | |
534 | .acpi_hid = "INT3438" | |
535 | }, | |
536 | #endif | |
537 | /* Haswell - not supported by SOF but added for consistency */ | |
538 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT) | |
539 | { | |
540 | .flags = FLAG_SST, | |
541 | .acpi_hid = "INT33C8" | |
542 | }, | |
543 | #endif | |
b5682305 PLB |
544 | }; |
545 | ||
546 | static const struct config_entry *snd_intel_acpi_dsp_find_config(const u8 acpi_hid[ACPI_ID_LEN], | |
547 | const struct config_entry *table, | |
548 | u32 len) | |
549 | { | |
550 | for (; len > 0; len--, table++) { | |
551 | if (memcmp(table->acpi_hid, acpi_hid, ACPI_ID_LEN)) | |
552 | continue; | |
553 | if (table->dmi_table && !dmi_check_system(table->dmi_table)) | |
554 | continue; | |
555 | return table; | |
556 | } | |
557 | return NULL; | |
558 | } | |
559 | ||
560 | int snd_intel_acpi_dsp_driver_probe(struct device *dev, const u8 acpi_hid[ACPI_ID_LEN]) | |
561 | { | |
562 | const struct config_entry *cfg; | |
563 | ||
564 | if (dsp_driver > SND_INTEL_DSP_DRIVER_LEGACY && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST) | |
565 | return dsp_driver; | |
566 | ||
567 | if (dsp_driver == SND_INTEL_DSP_DRIVER_LEGACY) { | |
568 | dev_warn(dev, "dsp_driver parameter %d not supported, using automatic detection\n", | |
569 | SND_INTEL_DSP_DRIVER_LEGACY); | |
570 | } | |
571 | ||
572 | /* find the configuration for the specific device */ | |
573 | cfg = snd_intel_acpi_dsp_find_config(acpi_hid, acpi_config_table, | |
574 | ARRAY_SIZE(acpi_config_table)); | |
575 | if (!cfg) | |
576 | return SND_INTEL_DSP_DRIVER_ANY; | |
577 | ||
578 | if (cfg->flags & FLAG_SST) | |
579 | return SND_INTEL_DSP_DRIVER_SST; | |
580 | ||
581 | if (cfg->flags & FLAG_SOF) | |
582 | return SND_INTEL_DSP_DRIVER_SOF; | |
583 | ||
584 | return SND_INTEL_DSP_DRIVER_SST; | |
585 | } | |
586 | EXPORT_SYMBOL_GPL(snd_intel_acpi_dsp_driver_probe); | |
587 | ||
82d9d54a JK |
588 | MODULE_LICENSE("GPL v2"); |
589 | MODULE_DESCRIPTION("Intel DSP config driver"); | |
08c2a4bc | 590 | MODULE_IMPORT_NS(SND_INTEL_SOUNDWIRE_ACPI); |