mt8186.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
  2. //
  3. // Copyright(c) 2022 Mediatek Inc. All rights reserved.
  4. //
  5. // Author: Allen-KH Cheng <[email protected]>
  6. // Tinghan Shen <[email protected]>
  7. /*
  8. * Hardware interface for audio DSP on mt8186
  9. */
  10. #include <linux/delay.h>
  11. #include <linux/firmware.h>
  12. #include <linux/io.h>
  13. #include <linux/of_address.h>
  14. #include <linux/of_irq.h>
  15. #include <linux/of_platform.h>
  16. #include <linux/of_reserved_mem.h>
  17. #include <linux/module.h>
  18. #include <sound/sof.h>
  19. #include <sound/sof/xtensa.h>
  20. #include "../../ops.h"
  21. #include "../../sof-of-dev.h"
  22. #include "../../sof-audio.h"
  23. #include "../adsp_helper.h"
  24. #include "mt8186.h"
  25. #include "mt8186-clk.h"
  26. static int mt8186_get_mailbox_offset(struct snd_sof_dev *sdev)
  27. {
  28. return MBOX_OFFSET;
  29. }
  30. static int mt8186_get_window_offset(struct snd_sof_dev *sdev, u32 id)
  31. {
  32. return MBOX_OFFSET;
  33. }
  34. static int mt8186_send_msg(struct snd_sof_dev *sdev,
  35. struct snd_sof_ipc_msg *msg)
  36. {
  37. struct adsp_priv *priv = sdev->pdata->hw_pdata;
  38. sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
  39. msg->msg_size);
  40. return mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_REQ, MTK_ADSP_IPC_OP_REQ);
  41. }
  42. static void mt8186_get_reply(struct snd_sof_dev *sdev)
  43. {
  44. struct snd_sof_ipc_msg *msg = sdev->msg;
  45. struct sof_ipc_reply reply;
  46. int ret = 0;
  47. if (!msg) {
  48. dev_warn(sdev->dev, "unexpected ipc interrupt\n");
  49. return;
  50. }
  51. /* get reply */
  52. sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply));
  53. if (reply.error < 0) {
  54. memcpy(msg->reply_data, &reply, sizeof(reply));
  55. ret = reply.error;
  56. } else {
  57. /* reply has correct size? */
  58. if (reply.hdr.size != msg->reply_size) {
  59. dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n",
  60. msg->reply_size, reply.hdr.size);
  61. ret = -EINVAL;
  62. }
  63. /* read the message */
  64. if (msg->reply_size > 0)
  65. sof_mailbox_read(sdev, sdev->host_box.offset,
  66. msg->reply_data, msg->reply_size);
  67. }
  68. msg->reply_error = ret;
  69. }
  70. static void mt8186_dsp_handle_reply(struct mtk_adsp_ipc *ipc)
  71. {
  72. struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc);
  73. unsigned long flags;
  74. spin_lock_irqsave(&priv->sdev->ipc_lock, flags);
  75. mt8186_get_reply(priv->sdev);
  76. snd_sof_ipc_reply(priv->sdev, 0);
  77. spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags);
  78. }
  79. static void mt8186_dsp_handle_request(struct mtk_adsp_ipc *ipc)
  80. {
  81. struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc);
  82. u32 p; /* panic code */
  83. int ret;
  84. /* Read the message from the debug box. */
  85. sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4,
  86. &p, sizeof(p));
  87. /* Check to see if the message is a panic code 0x0dead*** */
  88. if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
  89. snd_sof_dsp_panic(priv->sdev, p, true);
  90. } else {
  91. snd_sof_ipc_msgs_rx(priv->sdev);
  92. /* tell DSP cmd is done */
  93. ret = mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_RSP, MTK_ADSP_IPC_OP_RSP);
  94. if (ret)
  95. dev_err(priv->dev, "request send ipc failed");
  96. }
  97. }
  98. static struct mtk_adsp_ipc_ops dsp_ops = {
  99. .handle_reply = mt8186_dsp_handle_reply,
  100. .handle_request = mt8186_dsp_handle_request,
  101. };
  102. static int platform_parse_resource(struct platform_device *pdev, void *data)
  103. {
  104. struct resource *mmio;
  105. struct resource res;
  106. struct device_node *mem_region;
  107. struct device *dev = &pdev->dev;
  108. struct mtk_adsp_chip_info *adsp = data;
  109. int ret;
  110. mem_region = of_parse_phandle(dev->of_node, "memory-region", 0);
  111. if (!mem_region) {
  112. dev_err(dev, "no dma memory-region phandle\n");
  113. return -ENODEV;
  114. }
  115. ret = of_address_to_resource(mem_region, 0, &res);
  116. of_node_put(mem_region);
  117. if (ret) {
  118. dev_err(dev, "of_address_to_resource dma failed\n");
  119. return ret;
  120. }
  121. dev_dbg(dev, "DMA %pR\n", &res);
  122. ret = of_reserved_mem_device_init(dev);
  123. if (ret) {
  124. dev_err(dev, "of_reserved_mem_device_init failed\n");
  125. return ret;
  126. }
  127. mem_region = of_parse_phandle(dev->of_node, "memory-region", 1);
  128. if (!mem_region) {
  129. dev_err(dev, "no memory-region sysmem phandle\n");
  130. return -ENODEV;
  131. }
  132. ret = of_address_to_resource(mem_region, 0, &res);
  133. of_node_put(mem_region);
  134. if (ret) {
  135. dev_err(dev, "of_address_to_resource sysmem failed\n");
  136. return ret;
  137. }
  138. adsp->pa_dram = (phys_addr_t)res.start;
  139. if (adsp->pa_dram & DRAM_REMAP_MASK) {
  140. dev_err(dev, "adsp memory(%#x) is not 4K-aligned\n",
  141. (u32)adsp->pa_dram);
  142. return -EINVAL;
  143. }
  144. adsp->dramsize = resource_size(&res);
  145. if (adsp->dramsize < TOTAL_SIZE_SHARED_DRAM_FROM_TAIL) {
  146. dev_err(dev, "adsp memory(%#x) is not enough for share\n",
  147. adsp->dramsize);
  148. return -EINVAL;
  149. }
  150. dev_dbg(dev, "dram pbase=%pa size=%#x\n", &adsp->pa_dram, adsp->dramsize);
  151. mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
  152. if (!mmio) {
  153. dev_err(dev, "no ADSP-CFG register resource\n");
  154. return -ENXIO;
  155. }
  156. adsp->va_cfgreg = devm_ioremap_resource(dev, mmio);
  157. if (IS_ERR(adsp->va_cfgreg))
  158. return PTR_ERR(adsp->va_cfgreg);
  159. adsp->pa_cfgreg = (phys_addr_t)mmio->start;
  160. adsp->cfgregsize = resource_size(mmio);
  161. dev_dbg(dev, "cfgreg pbase=%pa size=%#x\n", &adsp->pa_cfgreg, adsp->cfgregsize);
  162. mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
  163. if (!mmio) {
  164. dev_err(dev, "no SRAM resource\n");
  165. return -ENXIO;
  166. }
  167. adsp->pa_sram = (phys_addr_t)mmio->start;
  168. adsp->sramsize = resource_size(mmio);
  169. dev_dbg(dev, "sram pbase=%pa size=%#x\n", &adsp->pa_sram, adsp->sramsize);
  170. mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sec");
  171. if (!mmio) {
  172. dev_err(dev, "no SEC register resource\n");
  173. return -ENXIO;
  174. }
  175. adsp->va_secreg = devm_ioremap_resource(dev, mmio);
  176. if (IS_ERR(adsp->va_secreg))
  177. return PTR_ERR(adsp->va_secreg);
  178. adsp->pa_secreg = (phys_addr_t)mmio->start;
  179. adsp->secregsize = resource_size(mmio);
  180. dev_dbg(dev, "secreg pbase=%pa size=%#x\n", &adsp->pa_secreg, adsp->secregsize);
  181. mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bus");
  182. if (!mmio) {
  183. dev_err(dev, "no BUS register resource\n");
  184. return -ENXIO;
  185. }
  186. adsp->va_busreg = devm_ioremap_resource(dev, mmio);
  187. if (IS_ERR(adsp->va_busreg))
  188. return PTR_ERR(adsp->va_busreg);
  189. adsp->pa_busreg = (phys_addr_t)mmio->start;
  190. adsp->busregsize = resource_size(mmio);
  191. dev_dbg(dev, "busreg pbase=%pa size=%#x\n", &adsp->pa_busreg, adsp->busregsize);
  192. return 0;
  193. }
  194. static void adsp_sram_power_on(struct snd_sof_dev *sdev)
  195. {
  196. snd_sof_dsp_update_bits(sdev, DSP_BUSREG_BAR, ADSP_SRAM_POOL_CON,
  197. DSP_SRAM_POOL_PD_MASK, 0);
  198. }
  199. static void adsp_sram_power_off(struct snd_sof_dev *sdev)
  200. {
  201. snd_sof_dsp_update_bits(sdev, DSP_BUSREG_BAR, ADSP_SRAM_POOL_CON,
  202. DSP_SRAM_POOL_PD_MASK, DSP_SRAM_POOL_PD_MASK);
  203. }
  204. /* Init the basic DSP DRAM address */
  205. static int adsp_memory_remap_init(struct snd_sof_dev *sdev, struct mtk_adsp_chip_info *adsp)
  206. {
  207. u32 offset;
  208. offset = adsp->pa_dram - DRAM_PHYS_BASE_FROM_DSP_VIEW;
  209. adsp->dram_offset = offset;
  210. offset >>= DRAM_REMAP_SHIFT;
  211. dev_dbg(sdev->dev, "adsp->pa_dram %pa, offset %#x\n", &adsp->pa_dram, offset);
  212. snd_sof_dsp_write(sdev, DSP_BUSREG_BAR, DSP_C0_EMI_MAP_ADDR, offset);
  213. snd_sof_dsp_write(sdev, DSP_BUSREG_BAR, DSP_C0_DMAEMI_MAP_ADDR, offset);
  214. if (offset != snd_sof_dsp_read(sdev, DSP_BUSREG_BAR, DSP_C0_EMI_MAP_ADDR) ||
  215. offset != snd_sof_dsp_read(sdev, DSP_BUSREG_BAR, DSP_C0_DMAEMI_MAP_ADDR)) {
  216. dev_err(sdev->dev, "emi remap fail\n");
  217. return -EIO;
  218. }
  219. return 0;
  220. }
  221. static int adsp_shared_base_ioremap(struct platform_device *pdev, void *data)
  222. {
  223. struct device *dev = &pdev->dev;
  224. struct mtk_adsp_chip_info *adsp = data;
  225. u32 shared_size;
  226. /* remap shared-dram base to be non-cachable */
  227. shared_size = TOTAL_SIZE_SHARED_DRAM_FROM_TAIL;
  228. adsp->pa_shared_dram = adsp->pa_dram + adsp->dramsize - shared_size;
  229. if (adsp->va_dram) {
  230. adsp->shared_dram = adsp->va_dram + DSP_DRAM_SIZE - shared_size;
  231. } else {
  232. adsp->shared_dram = devm_ioremap(dev, adsp->pa_shared_dram,
  233. shared_size);
  234. if (!adsp->shared_dram) {
  235. dev_err(dev, "ioremap failed for shared DRAM\n");
  236. return -ENOMEM;
  237. }
  238. }
  239. dev_dbg(dev, "shared-dram vbase=%p, phy addr :%pa, size=%#x\n",
  240. adsp->shared_dram, &adsp->pa_shared_dram, shared_size);
  241. return 0;
  242. }
  243. static int mt8186_run(struct snd_sof_dev *sdev)
  244. {
  245. u32 adsp_bootup_addr;
  246. adsp_bootup_addr = SRAM_PHYS_BASE_FROM_DSP_VIEW;
  247. dev_dbg(sdev->dev, "HIFIxDSP boot from base : 0x%08X\n", adsp_bootup_addr);
  248. mt8186_sof_hifixdsp_boot_sequence(sdev, adsp_bootup_addr);
  249. return 0;
  250. }
  251. static int mt8186_dsp_probe(struct snd_sof_dev *sdev)
  252. {
  253. struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev);
  254. struct adsp_priv *priv;
  255. int ret;
  256. priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  257. if (!priv)
  258. return -ENOMEM;
  259. sdev->pdata->hw_pdata = priv;
  260. priv->dev = sdev->dev;
  261. priv->sdev = sdev;
  262. priv->adsp = devm_kzalloc(&pdev->dev, sizeof(struct mtk_adsp_chip_info), GFP_KERNEL);
  263. if (!priv->adsp)
  264. return -ENOMEM;
  265. ret = platform_parse_resource(pdev, priv->adsp);
  266. if (ret)
  267. return ret;
  268. sdev->bar[SOF_FW_BLK_TYPE_IRAM] = devm_ioremap(sdev->dev,
  269. priv->adsp->pa_sram,
  270. priv->adsp->sramsize);
  271. if (!sdev->bar[SOF_FW_BLK_TYPE_IRAM]) {
  272. dev_err(sdev->dev, "failed to ioremap base %pa size %#x\n",
  273. &priv->adsp->pa_sram, priv->adsp->sramsize);
  274. return -ENOMEM;
  275. }
  276. sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap_wc(sdev->dev,
  277. priv->adsp->pa_dram,
  278. priv->adsp->dramsize);
  279. if (!sdev->bar[SOF_FW_BLK_TYPE_SRAM]) {
  280. dev_err(sdev->dev, "failed to ioremap base %pa size %#x\n",
  281. &priv->adsp->pa_dram, priv->adsp->dramsize);
  282. return -ENOMEM;
  283. }
  284. priv->adsp->va_dram = sdev->bar[SOF_FW_BLK_TYPE_SRAM];
  285. ret = adsp_shared_base_ioremap(pdev, priv->adsp);
  286. if (ret) {
  287. dev_err(sdev->dev, "adsp_shared_base_ioremap fail!\n");
  288. return ret;
  289. }
  290. sdev->bar[DSP_REG_BAR] = priv->adsp->va_cfgreg;
  291. sdev->bar[DSP_SECREG_BAR] = priv->adsp->va_secreg;
  292. sdev->bar[DSP_BUSREG_BAR] = priv->adsp->va_busreg;
  293. sdev->mmio_bar = SOF_FW_BLK_TYPE_SRAM;
  294. sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM;
  295. /* set default mailbox offset for FW ready message */
  296. sdev->dsp_box.offset = mt8186_get_mailbox_offset(sdev);
  297. ret = adsp_memory_remap_init(sdev, priv->adsp);
  298. if (ret) {
  299. dev_err(sdev->dev, "adsp_memory_remap_init fail!\n");
  300. return ret;
  301. }
  302. /* enable adsp clock before touching registers */
  303. ret = mt8186_adsp_init_clock(sdev);
  304. if (ret) {
  305. dev_err(sdev->dev, "mt8186_adsp_init_clock failed\n");
  306. return ret;
  307. }
  308. ret = mt8186_adsp_clock_on(sdev);
  309. if (ret) {
  310. dev_err(sdev->dev, "mt8186_adsp_clock_on fail!\n");
  311. return ret;
  312. }
  313. adsp_sram_power_on(sdev);
  314. priv->ipc_dev = platform_device_register_data(&pdev->dev, "mtk-adsp-ipc",
  315. PLATFORM_DEVID_NONE,
  316. pdev, sizeof(*pdev));
  317. if (IS_ERR(priv->ipc_dev)) {
  318. ret = PTR_ERR(priv->ipc_dev);
  319. dev_err(sdev->dev, "failed to create mtk-adsp-ipc device\n");
  320. goto err_adsp_off;
  321. }
  322. priv->dsp_ipc = dev_get_drvdata(&priv->ipc_dev->dev);
  323. if (!priv->dsp_ipc) {
  324. ret = -EPROBE_DEFER;
  325. dev_err(sdev->dev, "failed to get drvdata\n");
  326. goto exit_pdev_unregister;
  327. }
  328. mtk_adsp_ipc_set_data(priv->dsp_ipc, priv);
  329. priv->dsp_ipc->ops = &dsp_ops;
  330. return 0;
  331. exit_pdev_unregister:
  332. platform_device_unregister(priv->ipc_dev);
  333. err_adsp_off:
  334. adsp_sram_power_off(sdev);
  335. mt8186_adsp_clock_off(sdev);
  336. return ret;
  337. }
  338. static int mt8186_dsp_remove(struct snd_sof_dev *sdev)
  339. {
  340. struct adsp_priv *priv = sdev->pdata->hw_pdata;
  341. platform_device_unregister(priv->ipc_dev);
  342. mt8186_sof_hifixdsp_shutdown(sdev);
  343. adsp_sram_power_off(sdev);
  344. mt8186_adsp_clock_off(sdev);
  345. return 0;
  346. }
  347. static int mt8186_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
  348. {
  349. mt8186_sof_hifixdsp_shutdown(sdev);
  350. adsp_sram_power_off(sdev);
  351. mt8186_adsp_clock_off(sdev);
  352. return 0;
  353. }
  354. static int mt8186_dsp_resume(struct snd_sof_dev *sdev)
  355. {
  356. int ret;
  357. ret = mt8186_adsp_clock_on(sdev);
  358. if (ret) {
  359. dev_err(sdev->dev, "mt8186_adsp_clock_on fail!\n");
  360. return ret;
  361. }
  362. adsp_sram_power_on(sdev);
  363. return ret;
  364. }
  365. /* on mt8186 there is 1 to 1 match between type and BAR idx */
  366. static int mt8186_get_bar_index(struct snd_sof_dev *sdev, u32 type)
  367. {
  368. return type;
  369. }
  370. static int mt8186_pcm_hw_params(struct snd_sof_dev *sdev,
  371. struct snd_pcm_substream *substream,
  372. struct snd_pcm_hw_params *params,
  373. struct snd_sof_platform_stream_params *platform_params)
  374. {
  375. platform_params->cont_update_posn = 1;
  376. return 0;
  377. }
  378. static snd_pcm_uframes_t mt8186_pcm_pointer(struct snd_sof_dev *sdev,
  379. struct snd_pcm_substream *substream)
  380. {
  381. int ret;
  382. snd_pcm_uframes_t pos;
  383. struct snd_sof_pcm *spcm;
  384. struct sof_ipc_stream_posn posn;
  385. struct snd_sof_pcm_stream *stream;
  386. struct snd_soc_component *scomp = sdev->component;
  387. struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  388. spcm = snd_sof_find_spcm_dai(scomp, rtd);
  389. if (!spcm) {
  390. dev_warn_ratelimited(sdev->dev, "warn: can't find PCM with DAI ID %d\n",
  391. rtd->dai_link->id);
  392. return 0;
  393. }
  394. stream = &spcm->stream[substream->stream];
  395. ret = snd_sof_ipc_msg_data(sdev, stream->substream, &posn, sizeof(posn));
  396. if (ret < 0) {
  397. dev_warn(sdev->dev, "failed to read stream position: %d\n", ret);
  398. return 0;
  399. }
  400. memcpy(&stream->posn, &posn, sizeof(posn));
  401. pos = spcm->stream[substream->stream].posn.host_posn;
  402. pos = bytes_to_frames(substream->runtime, pos);
  403. return pos;
  404. }
  405. static struct snd_soc_dai_driver mt8186_dai[] = {
  406. {
  407. .name = "SOF_DL1",
  408. .playback = {
  409. .channels_min = 1,
  410. .channels_max = 2,
  411. },
  412. },
  413. {
  414. .name = "SOF_DL2",
  415. .playback = {
  416. .channels_min = 1,
  417. .channels_max = 2,
  418. },
  419. },
  420. {
  421. .name = "SOF_UL1",
  422. .capture = {
  423. .channels_min = 1,
  424. .channels_max = 2,
  425. },
  426. },
  427. {
  428. .name = "SOF_UL2",
  429. .capture = {
  430. .channels_min = 1,
  431. .channels_max = 2,
  432. },
  433. },
  434. };
  435. /* mt8186 ops */
  436. static struct snd_sof_dsp_ops sof_mt8186_ops = {
  437. /* probe and remove */
  438. .probe = mt8186_dsp_probe,
  439. .remove = mt8186_dsp_remove,
  440. /* DSP core boot */
  441. .run = mt8186_run,
  442. /* Block IO */
  443. .block_read = sof_block_read,
  444. .block_write = sof_block_write,
  445. /* Mailbox IO */
  446. .mailbox_read = sof_mailbox_read,
  447. .mailbox_write = sof_mailbox_write,
  448. /* Register IO */
  449. .write = sof_io_write,
  450. .read = sof_io_read,
  451. .write64 = sof_io_write64,
  452. .read64 = sof_io_read64,
  453. /* ipc */
  454. .send_msg = mt8186_send_msg,
  455. .get_mailbox_offset = mt8186_get_mailbox_offset,
  456. .get_window_offset = mt8186_get_window_offset,
  457. .ipc_msg_data = sof_ipc_msg_data,
  458. .set_stream_data_offset = sof_set_stream_data_offset,
  459. /* misc */
  460. .get_bar_index = mt8186_get_bar_index,
  461. /* stream callbacks */
  462. .pcm_open = sof_stream_pcm_open,
  463. .pcm_hw_params = mt8186_pcm_hw_params,
  464. .pcm_pointer = mt8186_pcm_pointer,
  465. .pcm_close = sof_stream_pcm_close,
  466. /* firmware loading */
  467. .load_firmware = snd_sof_load_firmware_memcpy,
  468. /* Firmware ops */
  469. .dsp_arch_ops = &sof_xtensa_arch_ops,
  470. /* DAI drivers */
  471. .drv = mt8186_dai,
  472. .num_drv = ARRAY_SIZE(mt8186_dai),
  473. /* PM */
  474. .suspend = mt8186_dsp_suspend,
  475. .resume = mt8186_dsp_resume,
  476. /* ALSA HW info flags */
  477. .hw_info = SNDRV_PCM_INFO_MMAP |
  478. SNDRV_PCM_INFO_MMAP_VALID |
  479. SNDRV_PCM_INFO_INTERLEAVED |
  480. SNDRV_PCM_INFO_PAUSE |
  481. SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
  482. };
  483. static struct snd_sof_of_mach sof_mt8186_machs[] = {
  484. {
  485. .compatible = "mediatek,mt8186",
  486. .sof_tplg_filename = "sof-mt8186.tplg",
  487. },
  488. {}
  489. };
  490. static const struct sof_dev_desc sof_of_mt8186_desc = {
  491. .of_machines = sof_mt8186_machs,
  492. .ipc_supported_mask = BIT(SOF_IPC),
  493. .ipc_default = SOF_IPC,
  494. .default_fw_path = {
  495. [SOF_IPC] = "mediatek/sof",
  496. },
  497. .default_tplg_path = {
  498. [SOF_IPC] = "mediatek/sof-tplg",
  499. },
  500. .default_fw_filename = {
  501. [SOF_IPC] = "sof-mt8186.ri",
  502. },
  503. .nocodec_tplg_filename = "sof-mt8186-nocodec.tplg",
  504. .ops = &sof_mt8186_ops,
  505. };
  506. static const struct of_device_id sof_of_mt8186_ids[] = {
  507. { .compatible = "mediatek,mt8186-dsp", .data = &sof_of_mt8186_desc},
  508. { }
  509. };
  510. MODULE_DEVICE_TABLE(of, sof_of_mt8186_ids);
  511. /* DT driver definition */
  512. static struct platform_driver snd_sof_of_mt8186_driver = {
  513. .probe = sof_of_probe,
  514. .remove = sof_of_remove,
  515. .driver = {
  516. .name = "sof-audio-of-mt8186",
  517. .pm = &sof_of_pm,
  518. .of_match_table = sof_of_mt8186_ids,
  519. },
  520. };
  521. module_platform_driver(snd_sof_of_mt8186_driver);
  522. MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
  523. MODULE_IMPORT_NS(SND_SOC_SOF_MTK_COMMON);
  524. MODULE_LICENSE("Dual BSD/GPL");