acp6x-mach.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Machine driver for AMD Yellow Carp platform using DMIC
  4. *
  5. * Copyright 2021 Advanced Micro Devices, Inc.
  6. */
  7. #include <sound/soc.h>
  8. #include <sound/soc-dapm.h>
  9. #include <linux/module.h>
  10. #include <sound/pcm.h>
  11. #include <sound/pcm_params.h>
  12. #include <linux/io.h>
  13. #include <linux/dmi.h>
  14. #include <linux/acpi.h>
  15. #include "acp6x.h"
  16. #define DRV_NAME "acp_yc_mach"
  17. SND_SOC_DAILINK_DEF(acp6x_pdm,
  18. DAILINK_COMP_ARRAY(COMP_CPU("acp_yc_pdm_dma.0")));
  19. SND_SOC_DAILINK_DEF(dmic_codec,
  20. DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec.0",
  21. "dmic-hifi")));
  22. SND_SOC_DAILINK_DEF(pdm_platform,
  23. DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_yc_pdm_dma.0")));
  24. static struct snd_soc_dai_link acp6x_dai_pdm[] = {
  25. {
  26. .name = "acp6x-dmic-capture",
  27. .stream_name = "DMIC capture",
  28. .capture_only = 1,
  29. SND_SOC_DAILINK_REG(acp6x_pdm, dmic_codec, pdm_platform),
  30. },
  31. };
  32. static struct snd_soc_card acp6x_card = {
  33. .name = "acp6x",
  34. .owner = THIS_MODULE,
  35. .dai_link = acp6x_dai_pdm,
  36. .num_links = 1,
  37. };
  38. static const struct dmi_system_id yc_acp_quirk_table[] = {
  39. {
  40. .driver_data = &acp6x_card,
  41. .matches = {
  42. DMI_MATCH(DMI_BOARD_VENDOR, "Dell Inc."),
  43. DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5525"),
  44. }
  45. },
  46. {
  47. .driver_data = &acp6x_card,
  48. .matches = {
  49. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  50. DMI_MATCH(DMI_PRODUCT_NAME, "21D0"),
  51. }
  52. },
  53. {
  54. .driver_data = &acp6x_card,
  55. .matches = {
  56. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  57. DMI_MATCH(DMI_PRODUCT_NAME, "21D0"),
  58. }
  59. },
  60. {
  61. .driver_data = &acp6x_card,
  62. .matches = {
  63. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  64. DMI_MATCH(DMI_PRODUCT_NAME, "21D1"),
  65. }
  66. },
  67. {
  68. .driver_data = &acp6x_card,
  69. .matches = {
  70. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  71. DMI_MATCH(DMI_PRODUCT_NAME, "21D2"),
  72. }
  73. },
  74. {
  75. .driver_data = &acp6x_card,
  76. .matches = {
  77. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  78. DMI_MATCH(DMI_PRODUCT_NAME, "21D3"),
  79. }
  80. },
  81. {
  82. .driver_data = &acp6x_card,
  83. .matches = {
  84. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  85. DMI_MATCH(DMI_PRODUCT_NAME, "21D4"),
  86. }
  87. },
  88. {
  89. .driver_data = &acp6x_card,
  90. .matches = {
  91. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  92. DMI_MATCH(DMI_PRODUCT_NAME, "21D5"),
  93. }
  94. },
  95. {
  96. .driver_data = &acp6x_card,
  97. .matches = {
  98. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  99. DMI_MATCH(DMI_PRODUCT_NAME, "21CF"),
  100. }
  101. },
  102. {
  103. .driver_data = &acp6x_card,
  104. .matches = {
  105. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  106. DMI_MATCH(DMI_PRODUCT_NAME, "21CG"),
  107. }
  108. },
  109. {
  110. .driver_data = &acp6x_card,
  111. .matches = {
  112. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  113. DMI_MATCH(DMI_PRODUCT_NAME, "21CQ"),
  114. }
  115. },
  116. {
  117. .driver_data = &acp6x_card,
  118. .matches = {
  119. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  120. DMI_MATCH(DMI_PRODUCT_NAME, "21CR"),
  121. }
  122. },
  123. {
  124. .driver_data = &acp6x_card,
  125. .matches = {
  126. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  127. DMI_MATCH(DMI_PRODUCT_NAME, "21CM"),
  128. }
  129. },
  130. {
  131. .driver_data = &acp6x_card,
  132. .matches = {
  133. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  134. DMI_MATCH(DMI_PRODUCT_NAME, "21CN"),
  135. }
  136. },
  137. {
  138. .driver_data = &acp6x_card,
  139. .matches = {
  140. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  141. DMI_MATCH(DMI_PRODUCT_NAME, "21CH"),
  142. }
  143. },
  144. {
  145. .driver_data = &acp6x_card,
  146. .matches = {
  147. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  148. DMI_MATCH(DMI_PRODUCT_NAME, "21CJ"),
  149. }
  150. },
  151. {
  152. .driver_data = &acp6x_card,
  153. .matches = {
  154. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  155. DMI_MATCH(DMI_PRODUCT_NAME, "21CK"),
  156. }
  157. },
  158. {
  159. .driver_data = &acp6x_card,
  160. .matches = {
  161. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  162. DMI_MATCH(DMI_PRODUCT_NAME, "21CL"),
  163. }
  164. },
  165. {
  166. .driver_data = &acp6x_card,
  167. .matches = {
  168. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  169. DMI_MATCH(DMI_PRODUCT_NAME, "21EF"),
  170. }
  171. },
  172. {
  173. .driver_data = &acp6x_card,
  174. .matches = {
  175. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  176. DMI_MATCH(DMI_PRODUCT_NAME, "21EM"),
  177. }
  178. },
  179. {
  180. .driver_data = &acp6x_card,
  181. .matches = {
  182. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  183. DMI_MATCH(DMI_PRODUCT_NAME, "21EN"),
  184. }
  185. },
  186. {
  187. .driver_data = &acp6x_card,
  188. .matches = {
  189. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  190. DMI_MATCH(DMI_PRODUCT_NAME, "21HY"),
  191. }
  192. },
  193. {
  194. .driver_data = &acp6x_card,
  195. .matches = {
  196. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  197. DMI_MATCH(DMI_PRODUCT_NAME, "21J5"),
  198. }
  199. },
  200. {
  201. .driver_data = &acp6x_card,
  202. .matches = {
  203. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  204. DMI_MATCH(DMI_PRODUCT_NAME, "21J6"),
  205. }
  206. },
  207. {
  208. .driver_data = &acp6x_card,
  209. .matches = {
  210. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  211. DMI_MATCH(DMI_PRODUCT_NAME, "82TL"),
  212. }
  213. },
  214. {
  215. .driver_data = &acp6x_card,
  216. .matches = {
  217. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  218. DMI_MATCH(DMI_PRODUCT_NAME, "82QF"),
  219. }
  220. },
  221. {
  222. .driver_data = &acp6x_card,
  223. .matches = {
  224. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  225. DMI_MATCH(DMI_PRODUCT_NAME, "82V2"),
  226. }
  227. },
  228. {
  229. .driver_data = &acp6x_card,
  230. .matches = {
  231. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  232. DMI_MATCH(DMI_PRODUCT_NAME, "82YM"),
  233. }
  234. },
  235. {
  236. .driver_data = &acp6x_card,
  237. .matches = {
  238. DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
  239. DMI_MATCH(DMI_PRODUCT_NAME, "82UG"),
  240. }
  241. },
  242. {
  243. .driver_data = &acp6x_card,
  244. .matches = {
  245. DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
  246. DMI_MATCH(DMI_PRODUCT_NAME, "UM5302TA"),
  247. }
  248. },
  249. {
  250. .driver_data = &acp6x_card,
  251. .matches = {
  252. DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
  253. DMI_MATCH(DMI_PRODUCT_NAME, "M5402RA"),
  254. }
  255. },
  256. {
  257. .driver_data = &acp6x_card,
  258. .matches = {
  259. DMI_MATCH(DMI_BOARD_VENDOR, "Alienware"),
  260. DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
  261. }
  262. },
  263. {
  264. .driver_data = &acp6x_card,
  265. .matches = {
  266. DMI_MATCH(DMI_BOARD_VENDOR, "TIMI"),
  267. DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 14 2022"),
  268. }
  269. },
  270. {
  271. .driver_data = &acp6x_card,
  272. .matches = {
  273. DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
  274. DMI_MATCH(DMI_PRODUCT_NAME, "M6500RC"),
  275. }
  276. },
  277. {
  278. .driver_data = &acp6x_card,
  279. .matches = {
  280. DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
  281. DMI_MATCH(DMI_PRODUCT_NAME, "E1504FA"),
  282. }
  283. },
  284. {
  285. .driver_data = &acp6x_card,
  286. .matches = {
  287. DMI_MATCH(DMI_BOARD_VENDOR, "TIMI"),
  288. DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 15 2022"),
  289. }
  290. },
  291. {
  292. .driver_data = &acp6x_card,
  293. .matches = {
  294. DMI_MATCH(DMI_BOARD_VENDOR, "Razer"),
  295. DMI_MATCH(DMI_PRODUCT_NAME, "Blade 14 (2022) - RZ09-0427"),
  296. }
  297. },
  298. {
  299. .driver_data = &acp6x_card,
  300. .matches = {
  301. DMI_MATCH(DMI_BOARD_VENDOR, "RB"),
  302. DMI_MATCH(DMI_PRODUCT_NAME, "Swift SFA16-41"),
  303. }
  304. },
  305. {
  306. .driver_data = &acp6x_card,
  307. .matches = {
  308. DMI_MATCH(DMI_BOARD_VENDOR, "IRBIS"),
  309. DMI_MATCH(DMI_PRODUCT_NAME, "15NBC1011"),
  310. }
  311. },
  312. {
  313. .driver_data = &acp6x_card,
  314. .matches = {
  315. DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
  316. DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16z-n000"),
  317. }
  318. },
  319. {
  320. .driver_data = &acp6x_card,
  321. .matches = {
  322. DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
  323. DMI_MATCH(DMI_BOARD_NAME, "8A42"),
  324. }
  325. },
  326. {
  327. .driver_data = &acp6x_card,
  328. .matches = {
  329. DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
  330. DMI_MATCH(DMI_BOARD_NAME, "8A43"),
  331. }
  332. },
  333. {
  334. .driver_data = &acp6x_card,
  335. .matches = {
  336. DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
  337. DMI_MATCH(DMI_BOARD_NAME, "8A22"),
  338. }
  339. },
  340. {
  341. .driver_data = &acp6x_card,
  342. .matches = {
  343. DMI_MATCH(DMI_BOARD_VENDOR, "System76"),
  344. DMI_MATCH(DMI_PRODUCT_VERSION, "pang12"),
  345. }
  346. },
  347. {}
  348. };
  349. static int acp6x_probe(struct platform_device *pdev)
  350. {
  351. const struct dmi_system_id *dmi_id;
  352. struct acp6x_pdm *machine = NULL;
  353. struct snd_soc_card *card;
  354. struct acpi_device *adev;
  355. int ret;
  356. /* check the parent device's firmware node has _DSD or not */
  357. adev = ACPI_COMPANION(pdev->dev.parent);
  358. if (adev) {
  359. const union acpi_object *obj;
  360. if (!acpi_dev_get_property(adev, "AcpDmicConnected", ACPI_TYPE_INTEGER, &obj) &&
  361. obj->integer.value == 1)
  362. platform_set_drvdata(pdev, &acp6x_card);
  363. }
  364. /* check for any DMI overrides */
  365. dmi_id = dmi_first_match(yc_acp_quirk_table);
  366. if (dmi_id)
  367. platform_set_drvdata(pdev, dmi_id->driver_data);
  368. card = platform_get_drvdata(pdev);
  369. if (!card)
  370. return -ENODEV;
  371. dev_info(&pdev->dev, "Enabling ACP DMIC support via %s", dmi_id ? "DMI" : "ACPI");
  372. acp6x_card.dev = &pdev->dev;
  373. snd_soc_card_set_drvdata(card, machine);
  374. ret = devm_snd_soc_register_card(&pdev->dev, card);
  375. if (ret) {
  376. return dev_err_probe(&pdev->dev, ret,
  377. "snd_soc_register_card(%s) failed\n",
  378. card->name);
  379. }
  380. return 0;
  381. }
  382. static struct platform_driver acp6x_mach_driver = {
  383. .driver = {
  384. .name = "acp_yc_mach",
  385. .pm = &snd_soc_pm_ops,
  386. },
  387. .probe = acp6x_probe,
  388. };
  389. module_platform_driver(acp6x_mach_driver);
  390. MODULE_AUTHOR("[email protected]");
  391. MODULE_LICENSE("GPL v2");
  392. MODULE_ALIAS("platform:" DRV_NAME);