acp-pci.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
  2. //
  3. // This file is provided under a dual BSD/GPLv2 license. When using or
  4. // redistributing this file, you may do so under either license.
  5. //
  6. // Copyright(c) 2022 Advanced Micro Devices, Inc. All rights reserved.
  7. //
  8. // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
  9. /*
  10. * Generic PCI interface for ACP device
  11. */
  12. #include <linux/delay.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/pci.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/module.h>
  17. #include <linux/pm_runtime.h>
  18. #include "amd.h"
  19. #include "../mach-config.h"
  20. #define DRV_NAME "acp_pci"
  21. #define ACP3x_REG_START 0x1240000
  22. #define ACP3x_REG_END 0x125C000
  23. static struct platform_device *dmic_dev;
  24. static struct platform_device *pdev;
  25. static const struct resource acp_res[] = {
  26. {
  27. .start = 0,
  28. .end = ACP3x_REG_END - ACP3x_REG_START,
  29. .name = "acp_mem",
  30. .flags = IORESOURCE_MEM,
  31. },
  32. {
  33. .start = 0,
  34. .end = 0,
  35. .name = "acp_dai_irq",
  36. .flags = IORESOURCE_IRQ,
  37. },
  38. };
  39. static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
  40. {
  41. struct platform_device_info pdevinfo;
  42. struct device *dev = &pci->dev;
  43. const struct resource *res_acp;
  44. struct acp_chip_info *chip;
  45. struct resource *res;
  46. unsigned int flag, addr, num_res, i;
  47. int ret;
  48. flag = snd_amd_acp_find_config(pci);
  49. if (flag != FLAG_AMD_LEGACY && flag != FLAG_AMD_LEGACY_ONLY_DMIC)
  50. return -ENODEV;
  51. chip = devm_kzalloc(&pci->dev, sizeof(*chip), GFP_KERNEL);
  52. if (!chip)
  53. return -ENOMEM;
  54. if (pci_enable_device(pci))
  55. return dev_err_probe(&pci->dev, -ENODEV,
  56. "pci_enable_device failed\n");
  57. ret = pci_request_regions(pci, "AMD ACP3x audio");
  58. if (ret < 0) {
  59. dev_err(&pci->dev, "pci_request_regions failed\n");
  60. ret = -ENOMEM;
  61. goto disable_pci;
  62. }
  63. pci_set_master(pci);
  64. res_acp = acp_res;
  65. num_res = ARRAY_SIZE(acp_res);
  66. switch (pci->revision) {
  67. case 0x01:
  68. chip->name = "acp_asoc_renoir";
  69. chip->acp_rev = ACP3X_DEV;
  70. break;
  71. case 0x6f:
  72. chip->name = "acp_asoc_rembrandt";
  73. chip->acp_rev = ACP6X_DEV;
  74. break;
  75. case 0x63:
  76. chip->name = "acp_asoc_acp63";
  77. chip->acp_rev = ACP63_DEV;
  78. break;
  79. case 0x70:
  80. chip->name = "acp_asoc_acp70";
  81. chip->acp_rev = ACP70_DEV;
  82. break;
  83. case 0x71:
  84. chip->name = "acp_asoc_acp70";
  85. chip->acp_rev = ACP71_DEV;
  86. break;
  87. default:
  88. dev_err(dev, "Unsupported device revision:0x%x\n", pci->revision);
  89. ret = -EINVAL;
  90. goto release_regions;
  91. }
  92. chip->flag = flag;
  93. dmic_dev = platform_device_register_data(dev, "dmic-codec", PLATFORM_DEVID_NONE, NULL, 0);
  94. if (IS_ERR(dmic_dev)) {
  95. dev_err(dev, "failed to create DMIC device\n");
  96. ret = PTR_ERR(dmic_dev);
  97. goto release_regions;
  98. }
  99. addr = pci_resource_start(pci, 0);
  100. chip->base = devm_ioremap(&pci->dev, addr, pci_resource_len(pci, 0));
  101. if (!chip->base) {
  102. ret = -ENOMEM;
  103. goto unregister_dmic_dev;
  104. }
  105. ret = acp_init(chip);
  106. if (ret)
  107. goto unregister_dmic_dev;
  108. check_acp_config(pci, chip);
  109. if (!chip->is_pdm_dev && !chip->is_i2s_config)
  110. goto skip_pdev_creation;
  111. res = devm_kcalloc(&pci->dev, num_res, sizeof(struct resource), GFP_KERNEL);
  112. if (!res) {
  113. ret = -ENOMEM;
  114. goto unregister_dmic_dev;
  115. }
  116. for (i = 0; i < num_res; i++, res_acp++) {
  117. res[i].name = res_acp->name;
  118. res[i].flags = res_acp->flags;
  119. res[i].start = addr + res_acp->start;
  120. res[i].end = addr + res_acp->end;
  121. if (res_acp->flags == IORESOURCE_IRQ) {
  122. res[i].start = pci->irq;
  123. res[i].end = res[i].start;
  124. }
  125. }
  126. memset(&pdevinfo, 0, sizeof(pdevinfo));
  127. pdevinfo.name = chip->name;
  128. pdevinfo.id = 0;
  129. pdevinfo.parent = &pci->dev;
  130. pdevinfo.num_res = num_res;
  131. pdevinfo.res = &res[0];
  132. pdevinfo.data = chip;
  133. pdevinfo.size_data = sizeof(*chip);
  134. pdev = platform_device_register_full(&pdevinfo);
  135. if (IS_ERR(pdev)) {
  136. dev_err(&pci->dev, "cannot register %s device\n", pdevinfo.name);
  137. ret = PTR_ERR(pdev);
  138. goto unregister_dmic_dev;
  139. }
  140. skip_pdev_creation:
  141. chip->chip_pdev = pdev;
  142. dev_set_drvdata(&pci->dev, chip);
  143. pm_runtime_set_autosuspend_delay(&pci->dev, 2000);
  144. pm_runtime_use_autosuspend(&pci->dev);
  145. pm_runtime_put_noidle(&pci->dev);
  146. pm_runtime_allow(&pci->dev);
  147. return ret;
  148. unregister_dmic_dev:
  149. platform_device_unregister(dmic_dev);
  150. release_regions:
  151. pci_release_regions(pci);
  152. disable_pci:
  153. pci_disable_device(pci);
  154. return ret;
  155. };
  156. static int __maybe_unused snd_acp_suspend(struct device *dev)
  157. {
  158. struct acp_chip_info *chip;
  159. int ret;
  160. chip = dev_get_drvdata(dev);
  161. ret = acp_deinit(chip);
  162. if (ret)
  163. dev_err(dev, "ACP de-init failed\n");
  164. return ret;
  165. }
  166. static int __maybe_unused snd_acp_resume(struct device *dev)
  167. {
  168. struct acp_chip_info *chip;
  169. struct acp_dev_data *adata;
  170. struct device child;
  171. int ret;
  172. chip = dev_get_drvdata(dev);
  173. ret = acp_init(chip);
  174. if (ret)
  175. dev_err(dev, "ACP init failed\n");
  176. if (chip->chip_pdev) {
  177. child = chip->chip_pdev->dev;
  178. adata = dev_get_drvdata(&child);
  179. if (adata)
  180. acp_enable_interrupts(adata);
  181. }
  182. return ret;
  183. }
  184. static const struct dev_pm_ops acp_pm_ops = {
  185. SET_RUNTIME_PM_OPS(snd_acp_suspend, snd_acp_resume, NULL)
  186. SET_SYSTEM_SLEEP_PM_OPS(snd_acp_suspend, snd_acp_resume)
  187. };
  188. static void acp_pci_remove(struct pci_dev *pci)
  189. {
  190. struct acp_chip_info *chip;
  191. int ret;
  192. chip = pci_get_drvdata(pci);
  193. pm_runtime_forbid(&pci->dev);
  194. pm_runtime_get_noresume(&pci->dev);
  195. if (dmic_dev)
  196. platform_device_unregister(dmic_dev);
  197. if (pdev)
  198. platform_device_unregister(pdev);
  199. ret = acp_deinit(chip);
  200. if (ret)
  201. dev_err(&pci->dev, "ACP de-init failed\n");
  202. }
  203. /* PCI IDs */
  204. static const struct pci_device_id acp_pci_ids[] = {
  205. { PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_PCI_DEV_ID)},
  206. { 0, }
  207. };
  208. MODULE_DEVICE_TABLE(pci, acp_pci_ids);
  209. /* pci_driver definition */
  210. static struct pci_driver snd_amd_acp_pci_driver = {
  211. .name = KBUILD_MODNAME,
  212. .id_table = acp_pci_ids,
  213. .probe = acp_pci_probe,
  214. .remove = acp_pci_remove,
  215. .driver = {
  216. .pm = &acp_pm_ops,
  217. },
  218. };
  219. module_pci_driver(snd_amd_acp_pci_driver);
  220. MODULE_DESCRIPTION("AMD ACP common PCI support");
  221. MODULE_LICENSE("Dual BSD/GPL");
  222. MODULE_IMPORT_NS(SND_SOC_ACP_COMMON);
  223. MODULE_ALIAS(DRV_NAME);