intel-dsp-config.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (c) 2019 Jaroslav Kysela <perex@perex.cz>
  3. #include <linux/acpi.h>
  4. #include <linux/bits.h>
  5. #include <linux/dmi.h>
  6. #include <linux/module.h>
  7. #include <linux/pci.h>
  8. #include <linux/soundwire/sdw.h>
  9. #include <linux/soundwire/sdw_intel.h>
  10. #include <sound/core.h>
  11. #include <sound/intel-dsp-config.h>
  12. #include <sound/intel-nhlt.h>
  13. #include <sound/soc-acpi.h>
  14. #include <acpi/nhlt.h>
  15. static int dsp_driver;
  16. module_param(dsp_driver, int, 0444);
  17. MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF, 4=AVS)");
  18. #define FLAG_SST BIT(0)
  19. #define FLAG_SOF BIT(1)
  20. #define FLAG_SST_ONLY_IF_DMIC BIT(15)
  21. #define FLAG_SOF_ONLY_IF_DMIC BIT(16)
  22. #define FLAG_SOF_ONLY_IF_SOUNDWIRE BIT(17)
  23. #define FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE (FLAG_SOF_ONLY_IF_DMIC | \
  24. FLAG_SOF_ONLY_IF_SOUNDWIRE)
  25. struct config_entry {
  26. u32 flags;
  27. u16 device;
  28. u8 acpi_hid[ACPI_ID_LEN];
  29. const struct dmi_system_id *dmi_table;
  30. const struct snd_soc_acpi_codecs *codec_hid;
  31. };
  32. static const struct snd_soc_acpi_codecs __maybe_unused essx_83x6 = {
  33. .num_codecs = 3,
  34. .codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
  35. };
  36. /*
  37. * configuration table
  38. * - the order of similar PCI ID entries is important!
  39. * - the first successful match will win
  40. */
  41. static const struct config_entry config_table[] = {
  42. /* Merrifield */
  43. #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD)
  44. {
  45. .flags = FLAG_SOF,
  46. .device = PCI_DEVICE_ID_INTEL_SST_TNG,
  47. },
  48. #endif
  49. /*
  50. * Skylake, Kabylake, Apollolake
  51. * the legacy HDAudio driver is used except on Up Squared (SOF) and
  52. * Chromebooks (SST), as well as devices based on the ES8336 codec
  53. */
  54. #if IS_ENABLED(CONFIG_SND_SOC_INTEL_AVS)
  55. {
  56. .flags = FLAG_SST,
  57. .device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP,
  58. .dmi_table = (const struct dmi_system_id []) {
  59. {
  60. .ident = "Google Chromebooks",
  61. .matches = {
  62. DMI_MATCH(DMI_SYS_VENDOR, "Google"),
  63. }
  64. },
  65. {}
  66. }
  67. },
  68. {
  69. .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
  70. .device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP,
  71. },
  72. {
  73. .flags = FLAG_SST,
  74. .device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP,
  75. .dmi_table = (const struct dmi_system_id []) {
  76. {
  77. .ident = "Google Chromebooks",
  78. .matches = {
  79. DMI_MATCH(DMI_SYS_VENDOR, "Google"),
  80. }
  81. },
  82. {}
  83. }
  84. },
  85. {
  86. .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
  87. .device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP,
  88. },
  89. {
  90. .flags = FLAG_SST,
  91. .device = PCI_DEVICE_ID_INTEL_HDA_APL,
  92. .dmi_table = (const struct dmi_system_id []) {
  93. {
  94. .ident = "Google Chromebooks",
  95. .matches = {
  96. DMI_MATCH(DMI_SYS_VENDOR, "Google"),
  97. }
  98. },
  99. {}
  100. }
  101. },
  102. {
  103. .flags = FLAG_SST,
  104. .device = PCI_DEVICE_ID_INTEL_HDA_RPL_M,
  105. },
  106. {
  107. .flags = FLAG_SST,
  108. .device = PCI_DEVICE_ID_INTEL_HDA_FCL,
  109. },
  110. #else /* AVS disabled; force to legacy as SOF doesn't work for SKL or KBL */
  111. {
  112. .device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP,
  113. },
  114. {
  115. .device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP,
  116. },
  117. #endif
  118. #if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)
  119. {
  120. .flags = FLAG_SOF,
  121. .device = PCI_DEVICE_ID_INTEL_HDA_APL,
  122. .dmi_table = (const struct dmi_system_id []) {
  123. {
  124. .ident = "Up Squared",
  125. .matches = {
  126. DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
  127. DMI_MATCH(DMI_BOARD_NAME, "UP-APL01"),
  128. }
  129. },
  130. {}
  131. }
  132. },
  133. {
  134. .flags = FLAG_SOF,
  135. .device = PCI_DEVICE_ID_INTEL_HDA_APL,
  136. .codec_hid = &essx_83x6,
  137. },
  138. #endif
  139. /*
  140. * Geminilake uses legacy HDAudio driver except for Google
  141. * Chromebooks and devices based on the ES8336 codec
  142. */
  143. /* Geminilake */
  144. #if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE)
  145. {
  146. .flags = FLAG_SOF,
  147. .device = PCI_DEVICE_ID_INTEL_HDA_GLK,
  148. .dmi_table = (const struct dmi_system_id []) {
  149. {
  150. .ident = "Google Chromebooks",
  151. .matches = {
  152. DMI_MATCH(DMI_SYS_VENDOR, "Google"),
  153. }
  154. },
  155. {}
  156. }
  157. },
  158. {
  159. .flags = FLAG_SOF,
  160. .device = PCI_DEVICE_ID_INTEL_HDA_GLK,
  161. .codec_hid = &essx_83x6,
  162. },
  163. #endif
  164. /*
  165. * CoffeeLake, CannonLake, CometLake, IceLake, TigerLake, AlderLake,
  166. * RaptorLake, MeteorLake use legacy HDAudio driver except for Google
  167. * Chromebooks and when DMICs are present. Two cases are required since
  168. * Coreboot does not expose NHLT tables.
  169. *
  170. * When the Chromebook quirk is not present, it's based on information
  171. * that no such device exists. When the quirk is present, it could be
  172. * either based on product information or a placeholder.
  173. */
  174. /* Cannonlake */
  175. #if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE)
  176. {
  177. .flags = FLAG_SOF,
  178. .device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP,
  179. .dmi_table = (const struct dmi_system_id []) {
  180. {
  181. .ident = "Google Chromebooks",
  182. .matches = {
  183. DMI_MATCH(DMI_SYS_VENDOR, "Google"),
  184. }
  185. },
  186. {
  187. .ident = "UP-WHL",
  188. .matches = {
  189. DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
  190. }
  191. },
  192. {}
  193. }
  194. },
  195. {
  196. .flags = FLAG_SOF,
  197. .device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP,
  198. .codec_hid = &essx_83x6,
  199. },
  200. {
  201. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  202. .device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP,
  203. },
  204. #endif
  205. /* Coffelake */
  206. #if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE)
  207. {
  208. .flags = FLAG_SOF,
  209. .device = PCI_DEVICE_ID_INTEL_HDA_CNL_H,
  210. .dmi_table = (const struct dmi_system_id []) {
  211. {
  212. .ident = "Google Chromebooks",
  213. .matches = {
  214. DMI_MATCH(DMI_SYS_VENDOR, "Google"),
  215. }
  216. },
  217. {}
  218. }
  219. },
  220. {
  221. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  222. .device = PCI_DEVICE_ID_INTEL_HDA_CNL_H,
  223. },
  224. #endif
  225. #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE)
  226. /* Cometlake-LP */
  227. {
  228. .flags = FLAG_SOF,
  229. .device = PCI_DEVICE_ID_INTEL_HDA_CML_LP,
  230. .dmi_table = (const struct dmi_system_id []) {
  231. {
  232. .ident = "Google Chromebooks",
  233. .matches = {
  234. DMI_MATCH(DMI_SYS_VENDOR, "Google"),
  235. }
  236. },
  237. {
  238. .matches = {
  239. DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
  240. DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6")
  241. },
  242. },
  243. {
  244. /* early version of SKU 09C6 */
  245. .matches = {
  246. DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
  247. DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983")
  248. },
  249. },
  250. {}
  251. }
  252. },
  253. {
  254. .flags = FLAG_SOF,
  255. .device = PCI_DEVICE_ID_INTEL_HDA_CML_LP,
  256. .codec_hid = &essx_83x6,
  257. },
  258. {
  259. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  260. .device = PCI_DEVICE_ID_INTEL_HDA_CML_LP,
  261. },
  262. /* Cometlake-H */
  263. {
  264. .flags = FLAG_SOF,
  265. .device = PCI_DEVICE_ID_INTEL_HDA_CML_H,
  266. .dmi_table = (const struct dmi_system_id []) {
  267. {
  268. .matches = {
  269. DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
  270. DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"),
  271. },
  272. },
  273. {
  274. .matches = {
  275. DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
  276. DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"),
  277. },
  278. },
  279. {}
  280. }
  281. },
  282. {
  283. .flags = FLAG_SOF,
  284. .device = PCI_DEVICE_ID_INTEL_HDA_CML_H,
  285. .codec_hid = &essx_83x6,
  286. },
  287. {
  288. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  289. .device = PCI_DEVICE_ID_INTEL_HDA_CML_H,
  290. },
  291. #endif
  292. /* Icelake */
  293. #if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE)
  294. {
  295. .flags = FLAG_SOF,
  296. .device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP,
  297. .dmi_table = (const struct dmi_system_id []) {
  298. {
  299. .ident = "Google Chromebooks",
  300. .matches = {
  301. DMI_MATCH(DMI_SYS_VENDOR, "Google"),
  302. }
  303. },
  304. {}
  305. }
  306. },
  307. {
  308. .flags = FLAG_SOF,
  309. .device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP,
  310. .codec_hid = &essx_83x6,
  311. },
  312. {
  313. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  314. .device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP,
  315. },
  316. #endif
  317. /* Jasper Lake */
  318. #if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE)
  319. {
  320. .flags = FLAG_SOF,
  321. .device = PCI_DEVICE_ID_INTEL_HDA_JSL_N,
  322. .dmi_table = (const struct dmi_system_id []) {
  323. {
  324. .ident = "Google Chromebooks",
  325. .matches = {
  326. DMI_MATCH(DMI_SYS_VENDOR, "Google"),
  327. }
  328. },
  329. {
  330. .ident = "Google firmware",
  331. .matches = {
  332. DMI_MATCH(DMI_BIOS_VERSION, "Google"),
  333. }
  334. },
  335. {}
  336. }
  337. },
  338. {
  339. .flags = FLAG_SOF,
  340. .device = PCI_DEVICE_ID_INTEL_HDA_JSL_N,
  341. .codec_hid = &essx_83x6,
  342. },
  343. {
  344. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
  345. .device = PCI_DEVICE_ID_INTEL_HDA_JSL_N,
  346. },
  347. #endif
  348. /* Tigerlake */
  349. #if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE)
  350. {
  351. .flags = FLAG_SOF,
  352. .device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP,
  353. .dmi_table = (const struct dmi_system_id []) {
  354. {
  355. .ident = "Google Chromebooks",
  356. .matches = {
  357. DMI_MATCH(DMI_SYS_VENDOR, "Google"),
  358. }
  359. },
  360. {
  361. .ident = "UPX-TGL",
  362. .matches = {
  363. DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
  364. }
  365. },
  366. {}
  367. }
  368. },
  369. {
  370. .flags = FLAG_SOF,
  371. .device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP,
  372. .codec_hid = &essx_83x6,
  373. },
  374. {
  375. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  376. .device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP,
  377. },
  378. {
  379. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  380. .device = PCI_DEVICE_ID_INTEL_HDA_TGL_H,
  381. },
  382. #endif
  383. /* Elkhart Lake */
  384. #if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE)
  385. {
  386. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
  387. .device = PCI_DEVICE_ID_INTEL_HDA_EHL_0,
  388. },
  389. {
  390. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
  391. .device = PCI_DEVICE_ID_INTEL_HDA_EHL_3,
  392. },
  393. #endif
  394. /* Alder Lake / Raptor Lake */
  395. #if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE)
  396. {
  397. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  398. .device = PCI_DEVICE_ID_INTEL_HDA_ADL_S,
  399. },
  400. {
  401. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  402. .device = PCI_DEVICE_ID_INTEL_HDA_RPL_S,
  403. },
  404. {
  405. .flags = FLAG_SOF,
  406. .device = PCI_DEVICE_ID_INTEL_HDA_ADL_P,
  407. .dmi_table = (const struct dmi_system_id []) {
  408. {
  409. .ident = "Google Chromebooks",
  410. .matches = {
  411. DMI_MATCH(DMI_SYS_VENDOR, "Google"),
  412. }
  413. },
  414. {}
  415. }
  416. },
  417. {
  418. .flags = FLAG_SOF,
  419. .device = PCI_DEVICE_ID_INTEL_HDA_ADL_P,
  420. .codec_hid = &essx_83x6,
  421. },
  422. {
  423. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  424. .device = PCI_DEVICE_ID_INTEL_HDA_ADL_P,
  425. },
  426. {
  427. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  428. .device = PCI_DEVICE_ID_INTEL_HDA_ADL_PX,
  429. },
  430. {
  431. .flags = FLAG_SOF,
  432. .device = PCI_DEVICE_ID_INTEL_HDA_ADL_PS,
  433. .codec_hid = &essx_83x6,
  434. },
  435. {
  436. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  437. .device = PCI_DEVICE_ID_INTEL_HDA_ADL_PS,
  438. },
  439. {
  440. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  441. .device = PCI_DEVICE_ID_INTEL_HDA_ADL_M,
  442. },
  443. {
  444. .flags = FLAG_SOF,
  445. .device = PCI_DEVICE_ID_INTEL_HDA_ADL_N,
  446. .dmi_table = (const struct dmi_system_id []) {
  447. {
  448. .ident = "Google Chromebooks",
  449. .matches = {
  450. DMI_MATCH(DMI_SYS_VENDOR, "Google"),
  451. }
  452. },
  453. {}
  454. }
  455. },
  456. {
  457. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  458. .device = PCI_DEVICE_ID_INTEL_HDA_ADL_N,
  459. },
  460. {
  461. .flags = FLAG_SOF,
  462. .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_0,
  463. .dmi_table = (const struct dmi_system_id []) {
  464. {
  465. .ident = "Google Chromebooks",
  466. .matches = {
  467. DMI_MATCH(DMI_SYS_VENDOR, "Google"),
  468. }
  469. },
  470. {}
  471. }
  472. },
  473. {
  474. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  475. .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_0,
  476. },
  477. {
  478. .flags = FLAG_SOF,
  479. .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_1,
  480. .dmi_table = (const struct dmi_system_id []) {
  481. {
  482. .ident = "Google Chromebooks",
  483. .matches = {
  484. DMI_MATCH(DMI_SYS_VENDOR, "Google"),
  485. }
  486. },
  487. {}
  488. }
  489. },
  490. {
  491. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  492. .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_1,
  493. },
  494. {
  495. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  496. .device = PCI_DEVICE_ID_INTEL_HDA_RPL_M,
  497. },
  498. {
  499. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  500. .device = PCI_DEVICE_ID_INTEL_HDA_RPL_PX,
  501. },
  502. #endif
  503. /* Meteor Lake */
  504. #if IS_ENABLED(CONFIG_SND_SOC_SOF_METEORLAKE)
  505. /* Meteorlake-P */
  506. {
  507. .flags = FLAG_SOF,
  508. .device = PCI_DEVICE_ID_INTEL_HDA_MTL,
  509. .dmi_table = (const struct dmi_system_id []) {
  510. {
  511. .ident = "Google Chromebooks",
  512. .matches = {
  513. DMI_MATCH(DMI_SYS_VENDOR, "Google"),
  514. }
  515. },
  516. {}
  517. }
  518. },
  519. {
  520. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  521. .device = PCI_DEVICE_ID_INTEL_HDA_MTL,
  522. },
  523. /* ArrowLake-S */
  524. {
  525. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  526. .device = PCI_DEVICE_ID_INTEL_HDA_ARL_S,
  527. },
  528. /* ArrowLake */
  529. {
  530. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  531. .device = PCI_DEVICE_ID_INTEL_HDA_ARL,
  532. },
  533. #endif
  534. /* Lunar Lake */
  535. #if IS_ENABLED(CONFIG_SND_SOC_SOF_LUNARLAKE)
  536. /* Lunarlake-P */
  537. {
  538. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  539. .device = PCI_DEVICE_ID_INTEL_HDA_LNL_P,
  540. },
  541. #endif
  542. /* Panther Lake, Wildcat Lake */
  543. #if IS_ENABLED(CONFIG_SND_SOC_SOF_PANTHERLAKE)
  544. {
  545. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  546. .device = PCI_DEVICE_ID_INTEL_HDA_PTL,
  547. },
  548. {
  549. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  550. .device = PCI_DEVICE_ID_INTEL_HDA_PTL_H,
  551. },
  552. {
  553. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  554. .device = PCI_DEVICE_ID_INTEL_HDA_WCL,
  555. },
  556. #endif
  557. /* Nova Lake */
  558. #if IS_ENABLED(CONFIG_SND_SOC_SOF_NOVALAKE)
  559. {
  560. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  561. .device = PCI_DEVICE_ID_INTEL_HDA_NVL,
  562. },
  563. {
  564. .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
  565. .device = PCI_DEVICE_ID_INTEL_HDA_NVL_S,
  566. },
  567. #endif
  568. };
  569. static const struct config_entry *snd_intel_dsp_find_config
  570. (struct pci_dev *pci, const struct config_entry *table, u32 len)
  571. {
  572. u16 device;
  573. device = pci->device;
  574. for (; len > 0; len--, table++) {
  575. if (table->device != device)
  576. continue;
  577. if (table->dmi_table && !dmi_check_system(table->dmi_table))
  578. continue;
  579. if (table->codec_hid) {
  580. int i;
  581. for (i = 0; i < table->codec_hid->num_codecs; i++) {
  582. struct nhlt_acpi_table *nhlt;
  583. bool ssp_found = false;
  584. if (!acpi_dev_present(table->codec_hid->codecs[i], NULL, -1))
  585. continue;
  586. nhlt = intel_nhlt_init(&pci->dev);
  587. if (!nhlt) {
  588. dev_warn(&pci->dev, "%s: NHLT table not found, skipped HID %s\n",
  589. __func__, table->codec_hid->codecs[i]);
  590. continue;
  591. }
  592. if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_SSP) &&
  593. intel_nhlt_ssp_endpoint_mask(nhlt, NHLT_DEVICE_I2S))
  594. ssp_found = true;
  595. intel_nhlt_free(nhlt);
  596. if (ssp_found)
  597. break;
  598. dev_warn(&pci->dev, "%s: no valid SSP found for HID %s, skipped\n",
  599. __func__, table->codec_hid->codecs[i]);
  600. }
  601. if (i == table->codec_hid->num_codecs)
  602. continue;
  603. }
  604. return table;
  605. }
  606. return NULL;
  607. }
  608. static int snd_intel_dsp_check_dmic(struct pci_dev *pci)
  609. {
  610. int ret = 0;
  611. acpi_nhlt_get_gbl_table();
  612. if (acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_PDM, -1, -1, -1))
  613. ret = 1;
  614. acpi_nhlt_put_gbl_table();
  615. return ret;
  616. }
  617. #if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
  618. static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
  619. {
  620. struct sdw_intel_acpi_info info;
  621. acpi_handle handle;
  622. int ret;
  623. handle = ACPI_HANDLE(&pci->dev);
  624. if (!handle)
  625. return -ENODEV;
  626. ret = sdw_intel_acpi_scan(handle, &info);
  627. if (ret < 0)
  628. return ret;
  629. return info.link_mask;
  630. }
  631. #else
  632. static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
  633. {
  634. return 0;
  635. }
  636. #endif
  637. int snd_intel_dsp_driver_probe(struct pci_dev *pci)
  638. {
  639. const struct config_entry *cfg;
  640. /* Intel vendor only */
  641. if (pci->vendor != PCI_VENDOR_ID_INTEL)
  642. return SND_INTEL_DSP_DRIVER_ANY;
  643. /*
  644. * Legacy devices don't have a PCI-based DSP and use HDaudio
  645. * for HDMI/DP support, ignore kernel parameter
  646. */
  647. switch (pci->device) {
  648. case PCI_DEVICE_ID_INTEL_HDA_BDW:
  649. case PCI_DEVICE_ID_INTEL_HDA_HSW_0:
  650. case PCI_DEVICE_ID_INTEL_HDA_HSW_2:
  651. case PCI_DEVICE_ID_INTEL_HDA_HSW_3:
  652. case PCI_DEVICE_ID_INTEL_HDA_BYT:
  653. case PCI_DEVICE_ID_INTEL_HDA_BSW:
  654. return SND_INTEL_DSP_DRIVER_ANY;
  655. }
  656. if (dsp_driver > 0 && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST)
  657. return dsp_driver;
  658. /*
  659. * detect DSP by checking class/subclass/prog-id information
  660. * class=04 subclass 03 prog-if 00: no DSP, use legacy driver
  661. * class=04 subclass 01 prog-if 00: DSP is present
  662. * (and may be required e.g. for DMIC or SSP support)
  663. * class=04 subclass 03 prog-if 80: use DSP or legacy mode
  664. */
  665. if (pci->class == 0x040300)
  666. return SND_INTEL_DSP_DRIVER_LEGACY;
  667. if (pci->class != 0x040100 && pci->class != 0x040380) {
  668. dev_err(&pci->dev, "Unknown PCI class/subclass/prog-if information (0x%06x) found, selecting HDAudio legacy driver\n", pci->class);
  669. return SND_INTEL_DSP_DRIVER_LEGACY;
  670. }
  671. dev_dbg(&pci->dev, "DSP detected with PCI class/subclass/prog-if info 0x%06x\n", pci->class);
  672. /* find the configuration for the specific device */
  673. cfg = snd_intel_dsp_find_config(pci, config_table, ARRAY_SIZE(config_table));
  674. if (!cfg)
  675. return IS_ENABLED(CONFIG_SND_HDA_INTEL) ?
  676. SND_INTEL_DSP_DRIVER_LEGACY : SND_INTEL_DSP_DRIVER_ANY;
  677. if (cfg->flags & FLAG_SOF) {
  678. if (cfg->flags & FLAG_SOF_ONLY_IF_SOUNDWIRE &&
  679. snd_intel_dsp_check_soundwire(pci) > 0) {
  680. dev_info_once(&pci->dev, "SoundWire enabled on CannonLake+ platform, using SOF driver\n");
  681. return SND_INTEL_DSP_DRIVER_SOF;
  682. }
  683. if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC &&
  684. snd_intel_dsp_check_dmic(pci)) {
  685. dev_info_once(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n");
  686. return SND_INTEL_DSP_DRIVER_SOF;
  687. }
  688. if (!(cfg->flags & FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE))
  689. return SND_INTEL_DSP_DRIVER_SOF;
  690. }
  691. if (cfg->flags & FLAG_SST) {
  692. if (cfg->flags & FLAG_SST_ONLY_IF_DMIC) {
  693. if (snd_intel_dsp_check_dmic(pci)) {
  694. dev_info_once(&pci->dev, "Digital mics found on Skylake+ platform, using SST driver\n");
  695. return SND_INTEL_DSP_DRIVER_SST;
  696. }
  697. } else {
  698. return SND_INTEL_DSP_DRIVER_SST;
  699. }
  700. }
  701. return SND_INTEL_DSP_DRIVER_LEGACY;
  702. }
  703. EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe);
  704. /* Should we default to SOF or SST for BYT/CHT ? */
  705. #if IS_ENABLED(CONFIG_SND_INTEL_BYT_PREFER_SOF) || \
  706. !IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI)
  707. #define FLAG_SST_OR_SOF_BYT FLAG_SOF
  708. #else
  709. #define FLAG_SST_OR_SOF_BYT FLAG_SST
  710. #endif
  711. /*
  712. * configuration table
  713. * - the order of similar ACPI ID entries is important!
  714. * - the first successful match will win
  715. */
  716. static const struct config_entry acpi_config_table[] = {
  717. #if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) || \
  718. IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
  719. /* BayTrail */
  720. {
  721. .flags = FLAG_SST_OR_SOF_BYT,
  722. .acpi_hid = "LPE0F28",
  723. },
  724. {
  725. .flags = FLAG_SST_OR_SOF_BYT,
  726. .acpi_hid = "80860F28",
  727. },
  728. /* CherryTrail */
  729. {
  730. .flags = FLAG_SST_OR_SOF_BYT,
  731. .acpi_hid = "808622A8",
  732. },
  733. #endif
  734. /* Broadwell */
  735. #if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT)
  736. {
  737. .flags = FLAG_SST,
  738. .acpi_hid = "INT3438"
  739. },
  740. #endif
  741. #if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
  742. {
  743. .flags = FLAG_SOF,
  744. .acpi_hid = "INT3438"
  745. },
  746. #endif
  747. /* Haswell - not supported by SOF but added for consistency */
  748. #if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT)
  749. {
  750. .flags = FLAG_SST,
  751. .acpi_hid = "INT33C8"
  752. },
  753. #endif
  754. };
  755. static const struct config_entry *snd_intel_acpi_dsp_find_config(const u8 acpi_hid[ACPI_ID_LEN],
  756. const struct config_entry *table,
  757. u32 len)
  758. {
  759. for (; len > 0; len--, table++) {
  760. if (memcmp(table->acpi_hid, acpi_hid, ACPI_ID_LEN))
  761. continue;
  762. if (table->dmi_table && !dmi_check_system(table->dmi_table))
  763. continue;
  764. return table;
  765. }
  766. return NULL;
  767. }
  768. int snd_intel_acpi_dsp_driver_probe(struct device *dev, const u8 acpi_hid[ACPI_ID_LEN])
  769. {
  770. const struct config_entry *cfg;
  771. if (dsp_driver > SND_INTEL_DSP_DRIVER_LEGACY && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST)
  772. return dsp_driver;
  773. if (dsp_driver == SND_INTEL_DSP_DRIVER_LEGACY) {
  774. dev_warn(dev, "dsp_driver parameter %d not supported, using automatic detection\n",
  775. SND_INTEL_DSP_DRIVER_LEGACY);
  776. }
  777. /* find the configuration for the specific device */
  778. cfg = snd_intel_acpi_dsp_find_config(acpi_hid, acpi_config_table,
  779. ARRAY_SIZE(acpi_config_table));
  780. if (!cfg)
  781. return SND_INTEL_DSP_DRIVER_ANY;
  782. if (cfg->flags & FLAG_SST)
  783. return SND_INTEL_DSP_DRIVER_SST;
  784. if (cfg->flags & FLAG_SOF)
  785. return SND_INTEL_DSP_DRIVER_SOF;
  786. return SND_INTEL_DSP_DRIVER_SST;
  787. }
  788. EXPORT_SYMBOL_GPL(snd_intel_acpi_dsp_driver_probe);
  789. MODULE_LICENSE("GPL v2");
  790. MODULE_DESCRIPTION("Intel DSP config driver");
  791. MODULE_IMPORT_NS("SND_INTEL_SOUNDWIRE_ACPI");