sof-acpi-dev.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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) 2018 Intel Corporation. All rights reserved.
  7. //
  8. // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
  9. //
  10. #include <linux/acpi.h>
  11. #include <linux/firmware.h>
  12. #include <linux/module.h>
  13. #include <linux/pm_runtime.h>
  14. #include <sound/soc-acpi.h>
  15. #include <sound/soc-acpi-intel-match.h>
  16. #include <sound/sof.h>
  17. #include "../intel/common/soc-intel-quirks.h"
  18. #include "ops.h"
  19. /* platform specific devices */
  20. #include "intel/shim.h"
  21. static char *fw_path;
  22. module_param(fw_path, charp, 0444);
  23. MODULE_PARM_DESC(fw_path, "alternate path for SOF firmware.");
  24. static char *tplg_path;
  25. module_param(tplg_path, charp, 0444);
  26. MODULE_PARM_DESC(tplg_path, "alternate path for SOF topology.");
  27. static int sof_acpi_debug;
  28. module_param_named(sof_acpi_debug, sof_acpi_debug, int, 0444);
  29. MODULE_PARM_DESC(sof_acpi_debug, "SOF ACPI debug options (0x0 all off)");
  30. #define SOF_ACPI_DISABLE_PM_RUNTIME BIT(0)
  31. #if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
  32. static const struct sof_dev_desc sof_acpi_broadwell_desc = {
  33. .machines = snd_soc_acpi_intel_broadwell_machines,
  34. .resindex_lpe_base = 0,
  35. .resindex_pcicfg_base = 1,
  36. .resindex_imr_base = -1,
  37. .irqindex_host_ipc = 0,
  38. .chip_info = &bdw_chip_info,
  39. .default_fw_path = "intel/sof",
  40. .default_tplg_path = "intel/sof-tplg",
  41. .default_fw_filename = "sof-bdw.ri",
  42. .nocodec_tplg_filename = "sof-bdw-nocodec.tplg",
  43. .ops = &sof_bdw_ops,
  44. };
  45. #endif
  46. #if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
  47. /* BYTCR uses different IRQ index */
  48. static const struct sof_dev_desc sof_acpi_baytrailcr_desc = {
  49. .machines = snd_soc_acpi_intel_baytrail_machines,
  50. .resindex_lpe_base = 0,
  51. .resindex_pcicfg_base = 1,
  52. .resindex_imr_base = 2,
  53. .irqindex_host_ipc = 0,
  54. .chip_info = &byt_chip_info,
  55. .default_fw_path = "intel/sof",
  56. .default_tplg_path = "intel/sof-tplg",
  57. .default_fw_filename = "sof-byt.ri",
  58. .nocodec_tplg_filename = "sof-byt-nocodec.tplg",
  59. .ops = &sof_byt_ops,
  60. };
  61. static const struct sof_dev_desc sof_acpi_baytrail_desc = {
  62. .machines = snd_soc_acpi_intel_baytrail_machines,
  63. .resindex_lpe_base = 0,
  64. .resindex_pcicfg_base = 1,
  65. .resindex_imr_base = 2,
  66. .irqindex_host_ipc = 5,
  67. .chip_info = &byt_chip_info,
  68. .default_fw_path = "intel/sof",
  69. .default_tplg_path = "intel/sof-tplg",
  70. .default_fw_filename = "sof-byt.ri",
  71. .nocodec_tplg_filename = "sof-byt-nocodec.tplg",
  72. .ops = &sof_byt_ops,
  73. };
  74. static const struct sof_dev_desc sof_acpi_cherrytrail_desc = {
  75. .machines = snd_soc_acpi_intel_cherrytrail_machines,
  76. .resindex_lpe_base = 0,
  77. .resindex_pcicfg_base = 1,
  78. .resindex_imr_base = 2,
  79. .irqindex_host_ipc = 5,
  80. .chip_info = &cht_chip_info,
  81. .default_fw_path = "intel/sof",
  82. .default_tplg_path = "intel/sof-tplg",
  83. .default_fw_filename = "sof-cht.ri",
  84. .nocodec_tplg_filename = "sof-cht-nocodec.tplg",
  85. .ops = &sof_cht_ops,
  86. };
  87. #endif
  88. static const struct dev_pm_ops sof_acpi_pm = {
  89. SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume)
  90. SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume,
  91. snd_sof_runtime_idle)
  92. };
  93. static void sof_acpi_probe_complete(struct device *dev)
  94. {
  95. dev_dbg(dev, "Completing SOF ACPI probe");
  96. if (sof_acpi_debug & SOF_ACPI_DISABLE_PM_RUNTIME)
  97. return;
  98. /* allow runtime_pm */
  99. pm_runtime_set_autosuspend_delay(dev, SND_SOF_SUSPEND_DELAY_MS);
  100. pm_runtime_use_autosuspend(dev);
  101. pm_runtime_enable(dev);
  102. }
  103. static int sof_acpi_probe(struct platform_device *pdev)
  104. {
  105. struct device *dev = &pdev->dev;
  106. const struct sof_dev_desc *desc;
  107. struct snd_sof_pdata *sof_pdata;
  108. const struct snd_sof_dsp_ops *ops;
  109. int ret;
  110. dev_dbg(&pdev->dev, "ACPI DSP detected");
  111. sof_pdata = devm_kzalloc(dev, sizeof(*sof_pdata), GFP_KERNEL);
  112. if (!sof_pdata)
  113. return -ENOMEM;
  114. desc = device_get_match_data(dev);
  115. if (!desc)
  116. return -ENODEV;
  117. #if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
  118. if (desc == &sof_acpi_baytrail_desc && soc_intel_is_byt_cr(pdev))
  119. desc = &sof_acpi_baytrailcr_desc;
  120. #endif
  121. /* get ops for platform */
  122. ops = desc->ops;
  123. if (!ops) {
  124. dev_err(dev, "error: no matching ACPI descriptor ops\n");
  125. return -ENODEV;
  126. }
  127. sof_pdata->desc = desc;
  128. sof_pdata->dev = &pdev->dev;
  129. sof_pdata->fw_filename = desc->default_fw_filename;
  130. /* alternate fw and tplg filenames ? */
  131. if (fw_path)
  132. sof_pdata->fw_filename_prefix = fw_path;
  133. else
  134. sof_pdata->fw_filename_prefix =
  135. sof_pdata->desc->default_fw_path;
  136. if (tplg_path)
  137. sof_pdata->tplg_filename_prefix = tplg_path;
  138. else
  139. sof_pdata->tplg_filename_prefix =
  140. sof_pdata->desc->default_tplg_path;
  141. #if IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)
  142. /* set callback to enable runtime_pm */
  143. sof_pdata->sof_probe_complete = sof_acpi_probe_complete;
  144. #endif
  145. /* call sof helper for DSP hardware probe */
  146. ret = snd_sof_device_probe(dev, sof_pdata);
  147. if (ret) {
  148. dev_err(dev, "error: failed to probe DSP hardware!\n");
  149. return ret;
  150. }
  151. #if !IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)
  152. sof_acpi_probe_complete(dev);
  153. #endif
  154. return ret;
  155. }
  156. static int sof_acpi_remove(struct platform_device *pdev)
  157. {
  158. if (!(sof_acpi_debug & SOF_ACPI_DISABLE_PM_RUNTIME))
  159. pm_runtime_disable(&pdev->dev);
  160. /* call sof helper for DSP hardware remove */
  161. snd_sof_device_remove(&pdev->dev);
  162. return 0;
  163. }
  164. #ifdef CONFIG_ACPI
  165. static const struct acpi_device_id sof_acpi_match[] = {
  166. #if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
  167. { "INT3438", (unsigned long)&sof_acpi_broadwell_desc },
  168. #endif
  169. #if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
  170. { "80860F28", (unsigned long)&sof_acpi_baytrail_desc },
  171. { "808622A8", (unsigned long)&sof_acpi_cherrytrail_desc },
  172. #endif
  173. { }
  174. };
  175. MODULE_DEVICE_TABLE(acpi, sof_acpi_match);
  176. #endif
  177. /* acpi_driver definition */
  178. static struct platform_driver snd_sof_acpi_driver = {
  179. .probe = sof_acpi_probe,
  180. .remove = sof_acpi_remove,
  181. .driver = {
  182. .name = "sof-audio-acpi",
  183. .pm = &sof_acpi_pm,
  184. .acpi_match_table = ACPI_PTR(sof_acpi_match),
  185. },
  186. };
  187. module_platform_driver(snd_sof_acpi_driver);
  188. MODULE_LICENSE("Dual BSD/GPL");
  189. MODULE_IMPORT_NS(SND_SOC_SOF_BAYTRAIL);
  190. MODULE_IMPORT_NS(SND_SOC_SOF_BROADWELL);