1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2 // 3 // Copyright(c) 2021 Mediatek Inc. All rights reserved. 4 // 5 // Author: YC Hung <yc.hung@mediatek.com> 6 // 7 8 /* 9 * Hardware interface for audio DSP on mt8195 10 */ 11 12 #include <linux/delay.h> 13 #include <linux/firmware.h> 14 #include <linux/io.h> 15 #include <linux/of_address.h> 16 #include <linux/of_irq.h> 17 #include <linux/of_platform.h> 18 #include <linux/of_reserved_mem.h> 19 #include <linux/module.h> 20 21 #include <sound/sof.h> 22 #include <sound/sof/xtensa.h> 23 #include "../../ops.h" 24 #include "../../sof-of-dev.h" 25 #include "../../sof-audio.h" 26 #include "../adsp_helper.h" 27 #include "../mtk-adsp-common.h" 28 #include "mt8195.h" 29 #include "mt8195-clk.h" 30 31 static int mt8195_get_mailbox_offset(struct snd_sof_dev *sdev) 32 { 33 return MBOX_OFFSET; 34 } 35 36 static int mt8195_get_window_offset(struct snd_sof_dev *sdev, u32 id) 37 { 38 return MBOX_OFFSET; 39 } 40 41 static int mt8195_send_msg(struct snd_sof_dev *sdev, 42 struct snd_sof_ipc_msg *msg) 43 { 44 struct adsp_priv *priv = sdev->pdata->hw_pdata; 45 46 sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, 47 msg->msg_size); 48 49 return mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_REQ, MTK_ADSP_IPC_OP_REQ); 50 } 51 52 static void mt8195_get_reply(struct snd_sof_dev *sdev) 53 { 54 struct snd_sof_ipc_msg *msg = sdev->msg; 55 struct sof_ipc_reply reply; 56 int ret = 0; 57 58 if (!msg) { 59 dev_warn(sdev->dev, "unexpected ipc interrupt\n"); 60 return; 61 } 62 63 /* get reply */ 64 sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply)); 65 if (reply.error < 0) { 66 memcpy(msg->reply_data, &reply, sizeof(reply)); 67 ret = reply.error; 68 } else { 69 /* reply has correct size? */ 70 if (reply.hdr.size != msg->reply_size) { 71 dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n", 72 msg->reply_size, reply.hdr.size); 73 ret = -EINVAL; 74 } 75 76 /* read the message */ 77 if (msg->reply_size > 0) 78 sof_mailbox_read(sdev, sdev->host_box.offset, 79 msg->reply_data, msg->reply_size); 80 } 81 82 msg->reply_error = ret; 83 } 84 85 static void mt8195_dsp_handle_reply(struct mtk_adsp_ipc *ipc) 86 { 87 struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc); 88 unsigned long flags; 89 90 spin_lock_irqsave(&priv->sdev->ipc_lock, flags); 91 mt8195_get_reply(priv->sdev); 92 snd_sof_ipc_reply(priv->sdev, 0); 93 spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags); 94 } 95 96 static void mt8195_dsp_handle_request(struct mtk_adsp_ipc *ipc) 97 { 98 struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc); 99 u32 p; /* panic code */ 100 int ret; 101 102 /* Read the message from the debug box. */ 103 sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4, 104 &p, sizeof(p)); 105 106 /* Check to see if the message is a panic code 0x0dead*** */ 107 if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) { 108 snd_sof_dsp_panic(priv->sdev, p, true); 109 } else { 110 snd_sof_ipc_msgs_rx(priv->sdev); 111 112 /* tell DSP cmd is done */ 113 ret = mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_RSP, MTK_ADSP_IPC_OP_RSP); 114 if (ret) 115 dev_err(priv->dev, "request send ipc failed"); 116 } 117 } 118 119 static struct mtk_adsp_ipc_ops dsp_ops = { 120 .handle_reply = mt8195_dsp_handle_reply, 121 .handle_request = mt8195_dsp_handle_request, 122 }; 123 124 static int platform_parse_resource(struct platform_device *pdev, void *data) 125 { 126 struct resource *mmio; 127 struct resource res; 128 struct device_node *mem_region; 129 struct device *dev = &pdev->dev; 130 struct mtk_adsp_chip_info *adsp = data; 131 int ret; 132 133 mem_region = of_parse_phandle(dev->of_node, "memory-region", 0); 134 if (!mem_region) { 135 dev_err(dev, "no dma memory-region phandle\n"); 136 return -ENODEV; 137 } 138 139 ret = of_address_to_resource(mem_region, 0, &res); 140 of_node_put(mem_region); 141 if (ret) { 142 dev_err(dev, "of_address_to_resource dma failed\n"); 143 return ret; 144 } 145 146 dev_dbg(dev, "DMA %pR\n", &res); 147 148 ret = of_reserved_mem_device_init(dev); 149 if (ret) { 150 dev_err(dev, "of_reserved_mem_device_init failed\n"); 151 return ret; 152 } 153 154 mem_region = of_parse_phandle(dev->of_node, "memory-region", 1); 155 if (!mem_region) { 156 dev_err(dev, "no memory-region sysmem phandle\n"); 157 return -ENODEV; 158 } 159 160 ret = of_address_to_resource(mem_region, 0, &res); 161 of_node_put(mem_region); 162 if (ret) { 163 dev_err(dev, "of_address_to_resource sysmem failed\n"); 164 return ret; 165 } 166 167 adsp->pa_dram = (phys_addr_t)res.start; 168 adsp->dramsize = resource_size(&res); 169 if (adsp->pa_dram & DRAM_REMAP_MASK) { 170 dev_err(dev, "adsp memory(%#x) is not 4K-aligned\n", 171 (u32)adsp->pa_dram); 172 return -EINVAL; 173 } 174 175 if (adsp->dramsize < TOTAL_SIZE_SHARED_DRAM_FROM_TAIL) { 176 dev_err(dev, "adsp memory(%#x) is not enough for share\n", 177 adsp->dramsize); 178 return -EINVAL; 179 } 180 181 dev_dbg(dev, "dram pbase=%pa, dramsize=%#x\n", 182 &adsp->pa_dram, adsp->dramsize); 183 184 /* Parse CFG base */ 185 mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg"); 186 if (!mmio) { 187 dev_err(dev, "no ADSP-CFG register resource\n"); 188 return -ENXIO; 189 } 190 /* remap for DSP register accessing */ 191 adsp->va_cfgreg = devm_ioremap_resource(dev, mmio); 192 if (IS_ERR(adsp->va_cfgreg)) 193 return PTR_ERR(adsp->va_cfgreg); 194 195 adsp->pa_cfgreg = (phys_addr_t)mmio->start; 196 adsp->cfgregsize = resource_size(mmio); 197 198 dev_dbg(dev, "cfgreg-vbase=%p, cfgregsize=%#x\n", 199 adsp->va_cfgreg, adsp->cfgregsize); 200 201 /* Parse SRAM */ 202 mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram"); 203 if (!mmio) { 204 dev_err(dev, "no SRAM resource\n"); 205 return -ENXIO; 206 } 207 208 adsp->pa_sram = (phys_addr_t)mmio->start; 209 adsp->sramsize = resource_size(mmio); 210 if (adsp->sramsize < TOTAL_SIZE_SHARED_SRAM_FROM_TAIL) { 211 dev_err(dev, "adsp SRAM(%#x) is not enough for share\n", 212 adsp->sramsize); 213 return -EINVAL; 214 } 215 216 dev_dbg(dev, "sram pbase=%pa,%#x\n", &adsp->pa_sram, adsp->sramsize); 217 218 return ret; 219 } 220 221 static int adsp_sram_power_on(struct device *dev, bool on) 222 { 223 void __iomem *va_dspsysreg; 224 u32 srampool_con; 225 226 va_dspsysreg = ioremap(ADSP_SRAM_POOL_CON, 0x4); 227 if (!va_dspsysreg) { 228 dev_err(dev, "failed to ioremap sram pool base %#x\n", 229 ADSP_SRAM_POOL_CON); 230 return -ENOMEM; 231 } 232 233 srampool_con = readl(va_dspsysreg); 234 if (on) 235 writel(srampool_con & ~DSP_SRAM_POOL_PD_MASK, va_dspsysreg); 236 else 237 writel(srampool_con | DSP_SRAM_POOL_PD_MASK, va_dspsysreg); 238 239 iounmap(va_dspsysreg); 240 return 0; 241 } 242 243 /* Init the basic DSP DRAM address */ 244 static int adsp_memory_remap_init(struct device *dev, struct mtk_adsp_chip_info *adsp) 245 { 246 void __iomem *vaddr_emi_map; 247 int offset; 248 249 if (!adsp) 250 return -ENXIO; 251 252 vaddr_emi_map = devm_ioremap(dev, DSP_EMI_MAP_ADDR, 0x4); 253 if (!vaddr_emi_map) { 254 dev_err(dev, "failed to ioremap emi map base %#x\n", 255 DSP_EMI_MAP_ADDR); 256 return -ENOMEM; 257 } 258 259 offset = adsp->pa_dram - DRAM_PHYS_BASE_FROM_DSP_VIEW; 260 adsp->dram_offset = offset; 261 offset >>= DRAM_REMAP_SHIFT; 262 dev_dbg(dev, "adsp->pa_dram %pa, offset %#x\n", &adsp->pa_dram, offset); 263 writel(offset, vaddr_emi_map); 264 if (offset != readl(vaddr_emi_map)) { 265 dev_err(dev, "write emi map fail : %#x\n", readl(vaddr_emi_map)); 266 return -EIO; 267 } 268 269 return 0; 270 } 271 272 static int adsp_shared_base_ioremap(struct platform_device *pdev, void *data) 273 { 274 struct device *dev = &pdev->dev; 275 struct mtk_adsp_chip_info *adsp = data; 276 u32 shared_size; 277 278 /* remap shared-dram base to be non-cachable */ 279 shared_size = TOTAL_SIZE_SHARED_DRAM_FROM_TAIL; 280 adsp->pa_shared_dram = adsp->pa_dram + adsp->dramsize - shared_size; 281 if (adsp->va_dram) { 282 adsp->shared_dram = adsp->va_dram + DSP_DRAM_SIZE - shared_size; 283 } else { 284 adsp->shared_dram = devm_ioremap(dev, adsp->pa_shared_dram, 285 shared_size); 286 if (!adsp->shared_dram) { 287 dev_err(dev, "ioremap failed for shared DRAM\n"); 288 return -ENOMEM; 289 } 290 } 291 dev_dbg(dev, "shared-dram vbase=%p, phy addr :%pa, size=%#x\n", 292 adsp->shared_dram, &adsp->pa_shared_dram, shared_size); 293 294 return 0; 295 } 296 297 static int mt8195_run(struct snd_sof_dev *sdev) 298 { 299 u32 adsp_bootup_addr; 300 301 adsp_bootup_addr = SRAM_PHYS_BASE_FROM_DSP_VIEW; 302 dev_dbg(sdev->dev, "HIFIxDSP boot from base : 0x%08X\n", adsp_bootup_addr); 303 sof_hifixdsp_boot_sequence(sdev, adsp_bootup_addr); 304 305 return 0; 306 } 307 308 static int mt8195_dsp_probe(struct snd_sof_dev *sdev) 309 { 310 struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev); 311 struct adsp_priv *priv; 312 int ret; 313 314 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 315 if (!priv) 316 return -ENOMEM; 317 318 sdev->pdata->hw_pdata = priv; 319 priv->dev = sdev->dev; 320 priv->sdev = sdev; 321 322 priv->adsp = devm_kzalloc(&pdev->dev, sizeof(struct mtk_adsp_chip_info), GFP_KERNEL); 323 if (!priv->adsp) 324 return -ENOMEM; 325 326 ret = platform_parse_resource(pdev, priv->adsp); 327 if (ret) 328 return ret; 329 330 ret = mt8195_adsp_init_clock(sdev); 331 if (ret) { 332 dev_err(sdev->dev, "mt8195_adsp_init_clock failed\n"); 333 return -EINVAL; 334 } 335 336 ret = adsp_clock_on(sdev); 337 if (ret) { 338 dev_err(sdev->dev, "adsp_clock_on fail!\n"); 339 return -EINVAL; 340 } 341 342 ret = adsp_sram_power_on(sdev->dev, true); 343 if (ret) { 344 dev_err(sdev->dev, "adsp_sram_power_on fail!\n"); 345 goto exit_clk_disable; 346 } 347 348 ret = adsp_memory_remap_init(&pdev->dev, priv->adsp); 349 if (ret) { 350 dev_err(sdev->dev, "adsp_memory_remap_init fail!\n"); 351 goto err_adsp_sram_power_off; 352 } 353 354 sdev->bar[SOF_FW_BLK_TYPE_IRAM] = devm_ioremap(sdev->dev, 355 priv->adsp->pa_sram, 356 priv->adsp->sramsize); 357 if (!sdev->bar[SOF_FW_BLK_TYPE_IRAM]) { 358 dev_err(sdev->dev, "failed to ioremap base %pa size %#x\n", 359 &priv->adsp->pa_sram, priv->adsp->sramsize); 360 ret = -EINVAL; 361 goto err_adsp_sram_power_off; 362 } 363 364 sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap_wc(sdev->dev, 365 priv->adsp->pa_dram, 366 priv->adsp->dramsize); 367 if (!sdev->bar[SOF_FW_BLK_TYPE_SRAM]) { 368 dev_err(sdev->dev, "failed to ioremap base %pa size %#x\n", 369 &priv->adsp->pa_dram, priv->adsp->dramsize); 370 ret = -EINVAL; 371 goto err_adsp_sram_power_off; 372 } 373 priv->adsp->va_dram = sdev->bar[SOF_FW_BLK_TYPE_SRAM]; 374 375 ret = adsp_shared_base_ioremap(pdev, priv->adsp); 376 if (ret) { 377 dev_err(sdev->dev, "adsp_shared_base_ioremap fail!\n"); 378 goto err_adsp_sram_power_off; 379 } 380 381 sdev->bar[DSP_REG_BAR] = priv->adsp->va_cfgreg; 382 383 sdev->mmio_bar = SOF_FW_BLK_TYPE_SRAM; 384 sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM; 385 386 /* set default mailbox offset for FW ready message */ 387 sdev->dsp_box.offset = mt8195_get_mailbox_offset(sdev); 388 389 priv->ipc_dev = platform_device_register_data(&pdev->dev, "mtk-adsp-ipc", 390 PLATFORM_DEVID_NONE, 391 pdev, sizeof(*pdev)); 392 if (IS_ERR(priv->ipc_dev)) { 393 ret = PTR_ERR(priv->ipc_dev); 394 dev_err(sdev->dev, "failed to register mtk-adsp-ipc device\n"); 395 goto err_adsp_sram_power_off; 396 } 397 398 priv->dsp_ipc = dev_get_drvdata(&priv->ipc_dev->dev); 399 if (!priv->dsp_ipc) { 400 ret = -EPROBE_DEFER; 401 dev_err(sdev->dev, "failed to get drvdata\n"); 402 goto exit_pdev_unregister; 403 } 404 405 mtk_adsp_ipc_set_data(priv->dsp_ipc, priv); 406 priv->dsp_ipc->ops = &dsp_ops; 407 408 return 0; 409 410 exit_pdev_unregister: 411 platform_device_unregister(priv->ipc_dev); 412 err_adsp_sram_power_off: 413 adsp_sram_power_on(&pdev->dev, false); 414 exit_clk_disable: 415 adsp_clock_off(sdev); 416 417 return ret; 418 } 419 420 static int mt8195_dsp_shutdown(struct snd_sof_dev *sdev) 421 { 422 return snd_sof_suspend(sdev->dev); 423 } 424 425 static int mt8195_dsp_remove(struct snd_sof_dev *sdev) 426 { 427 struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev); 428 struct adsp_priv *priv = sdev->pdata->hw_pdata; 429 430 platform_device_unregister(priv->ipc_dev); 431 adsp_sram_power_on(&pdev->dev, false); 432 adsp_clock_off(sdev); 433 434 return 0; 435 } 436 437 static int mt8195_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state) 438 { 439 struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev); 440 int ret; 441 442 /* stall and reset dsp */ 443 sof_hifixdsp_shutdown(sdev); 444 445 /* power down adsp sram */ 446 ret = adsp_sram_power_on(&pdev->dev, false); 447 if (ret) { 448 dev_err(sdev->dev, "adsp_sram_power_off fail!\n"); 449 return ret; 450 } 451 452 /* turn off adsp clock */ 453 return adsp_clock_off(sdev); 454 } 455 456 static int mt8195_dsp_resume(struct snd_sof_dev *sdev) 457 { 458 int ret; 459 460 /* turn on adsp clock */ 461 ret = adsp_clock_on(sdev); 462 if (ret) { 463 dev_err(sdev->dev, "adsp_clock_on fail!\n"); 464 return ret; 465 } 466 467 /* power on adsp sram */ 468 ret = adsp_sram_power_on(sdev->dev, true); 469 if (ret) 470 dev_err(sdev->dev, "adsp_sram_power_on fail!\n"); 471 472 return ret; 473 } 474 475 /* on mt8195 there is 1 to 1 match between type and BAR idx */ 476 static int mt8195_get_bar_index(struct snd_sof_dev *sdev, u32 type) 477 { 478 return type; 479 } 480 481 static int mt8195_ipc_msg_data(struct snd_sof_dev *sdev, 482 struct snd_pcm_substream *substream, 483 void *p, size_t sz) 484 { 485 sof_mailbox_read(sdev, sdev->dsp_box.offset, p, sz); 486 return 0; 487 } 488 489 static void mt8195_adsp_dump(struct snd_sof_dev *sdev, u32 flags) 490 { 491 u32 dbg_pc, dbg_data, dbg_bus0, dbg_bus1, dbg_inst; 492 u32 dbg_ls0stat, dbg_ls1stat, faultbus, faultinfo, swrest; 493 494 /* dump debug registers */ 495 dbg_pc = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGPC); 496 dbg_data = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGDATA); 497 dbg_bus0 = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGBUS0); 498 dbg_bus1 = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGBUS1); 499 dbg_inst = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGINST); 500 dbg_ls0stat = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGLS0STAT); 501 dbg_ls1stat = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGLS1STAT); 502 faultbus = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PFAULTBUS); 503 faultinfo = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PFAULTINFO); 504 swrest = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_RESET_SW); 505 506 dev_info(sdev->dev, "adsp dump : pc %#x, data %#x, bus0 %#x, bus1 %#x, swrest %#x", 507 dbg_pc, dbg_data, dbg_bus0, dbg_bus1, swrest); 508 dev_info(sdev->dev, "dbg_inst %#x, ls0stat %#x, ls1stat %#x, faultbus %#x, faultinfo %#x", 509 dbg_inst, dbg_ls0stat, dbg_ls1stat, faultbus, faultinfo); 510 511 mtk_adsp_dump(sdev, flags); 512 } 513 514 static struct snd_soc_dai_driver mt8195_dai[] = { 515 { 516 .name = "SOF_DL2", 517 .playback = { 518 .channels_min = 1, 519 .channels_max = 2, 520 }, 521 }, 522 { 523 .name = "SOF_DL3", 524 .playback = { 525 .channels_min = 1, 526 .channels_max = 2, 527 }, 528 }, 529 { 530 .name = "SOF_UL4", 531 .capture = { 532 .channels_min = 1, 533 .channels_max = 2, 534 }, 535 }, 536 { 537 .name = "SOF_UL5", 538 .capture = { 539 .channels_min = 1, 540 .channels_max = 2, 541 }, 542 }, 543 }; 544 545 /* mt8195 ops */ 546 static struct snd_sof_dsp_ops sof_mt8195_ops = { 547 /* probe and remove */ 548 .probe = mt8195_dsp_probe, 549 .remove = mt8195_dsp_remove, 550 .shutdown = mt8195_dsp_shutdown, 551 552 /* DSP core boot */ 553 .run = mt8195_run, 554 555 /* Block IO */ 556 .block_read = sof_block_read, 557 .block_write = sof_block_write, 558 559 /* Register IO */ 560 .write = sof_io_write, 561 .read = sof_io_read, 562 .write64 = sof_io_write64, 563 .read64 = sof_io_read64, 564 565 /* ipc */ 566 .send_msg = mt8195_send_msg, 567 .get_mailbox_offset = mt8195_get_mailbox_offset, 568 .get_window_offset = mt8195_get_window_offset, 569 .ipc_msg_data = mt8195_ipc_msg_data, 570 .set_stream_data_offset = sof_set_stream_data_offset, 571 572 /* misc */ 573 .get_bar_index = mt8195_get_bar_index, 574 575 /* firmware loading */ 576 .load_firmware = snd_sof_load_firmware_memcpy, 577 578 /* Firmware ops */ 579 .dsp_arch_ops = &sof_xtensa_arch_ops, 580 581 /* Debug information */ 582 .dbg_dump = mt8195_adsp_dump, 583 584 /* DAI drivers */ 585 .drv = mt8195_dai, 586 .num_drv = ARRAY_SIZE(mt8195_dai), 587 588 /* PM */ 589 .suspend = mt8195_dsp_suspend, 590 .resume = mt8195_dsp_resume, 591 592 /* ALSA HW info flags */ 593 .hw_info = SNDRV_PCM_INFO_MMAP | 594 SNDRV_PCM_INFO_MMAP_VALID | 595 SNDRV_PCM_INFO_INTERLEAVED | 596 SNDRV_PCM_INFO_PAUSE | 597 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, 598 }; 599 600 static const struct sof_dev_desc sof_of_mt8195_desc = { 601 .ipc_supported_mask = BIT(SOF_IPC), 602 .ipc_default = SOF_IPC, 603 .default_fw_path = { 604 [SOF_IPC] = "mediatek/sof", 605 }, 606 .default_tplg_path = { 607 [SOF_IPC] = "mediatek/sof-tplg", 608 }, 609 .default_fw_filename = { 610 [SOF_IPC] = "sof-mt8195.ri", 611 }, 612 .nocodec_tplg_filename = "sof-mt8195-nocodec.tplg", 613 .ops = &sof_mt8195_ops, 614 .ipc_timeout = 1000, 615 }; 616 617 static const struct of_device_id sof_of_mt8195_ids[] = { 618 { .compatible = "mediatek,mt8195-dsp", .data = &sof_of_mt8195_desc}, 619 { } 620 }; 621 MODULE_DEVICE_TABLE(of, sof_of_mt8195_ids); 622 623 /* DT driver definition */ 624 static struct platform_driver snd_sof_of_mt8195_driver = { 625 .probe = sof_of_probe, 626 .remove = sof_of_remove, 627 .shutdown = sof_of_shutdown, 628 .driver = { 629 .name = "sof-audio-of-mt8195", 630 .pm = &sof_of_pm, 631 .of_match_table = sof_of_mt8195_ids, 632 }, 633 }; 634 module_platform_driver(snd_sof_of_mt8195_driver); 635 636 MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); 637 MODULE_LICENSE("Dual BSD/GPL"); 638