Merge tag 'mediatek-drm-fixes-20231211' of https://git.kernel.org/pub/scm/linux/kerne...
[linux-2.6-microblaze.git] / sound / soc / sof / mediatek / mt8186 / mt8186.c
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 <allen-kh.cheng@mediatek.com>
6 //         Tinghan Shen <tinghan.shen@mediatek.com>
7
8 /*
9  * Hardware interface for audio DSP on mt8186
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 "mt8186.h"
29 #include "mt8186-clk.h"
30
31 static int mt8186_get_mailbox_offset(struct snd_sof_dev *sdev)
32 {
33         return MBOX_OFFSET;
34 }
35
36 static int mt8186_get_window_offset(struct snd_sof_dev *sdev, u32 id)
37 {
38         return MBOX_OFFSET;
39 }
40
41 static int mt8186_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 mt8186_dsp_handle_reply(struct mtk_adsp_ipc *ipc)
53 {
54         struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc);
55         unsigned long flags;
56
57         spin_lock_irqsave(&priv->sdev->ipc_lock, flags);
58         snd_sof_ipc_process_reply(priv->sdev, 0);
59         spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags);
60 }
61
62 static void mt8186_dsp_handle_request(struct mtk_adsp_ipc *ipc)
63 {
64         struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc);
65         u32 p; /* panic code */
66         int ret;
67
68         /* Read the message from the debug box. */
69         sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4,
70                          &p, sizeof(p));
71
72         /* Check to see if the message is a panic code 0x0dead*** */
73         if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
74                 snd_sof_dsp_panic(priv->sdev, p, true);
75         } else {
76                 snd_sof_ipc_msgs_rx(priv->sdev);
77
78                 /* tell DSP cmd is done */
79                 ret = mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_RSP, MTK_ADSP_IPC_OP_RSP);
80                 if (ret)
81                         dev_err(priv->dev, "request send ipc failed");
82         }
83 }
84
85 static struct mtk_adsp_ipc_ops dsp_ops = {
86         .handle_reply           = mt8186_dsp_handle_reply,
87         .handle_request         = mt8186_dsp_handle_request,
88 };
89
90 static int platform_parse_resource(struct platform_device *pdev, void *data)
91 {
92         struct resource *mmio;
93         struct resource res;
94         struct device_node *mem_region;
95         struct device *dev = &pdev->dev;
96         struct mtk_adsp_chip_info *adsp = data;
97         int ret;
98
99         mem_region = of_parse_phandle(dev->of_node, "memory-region", 0);
100         if (!mem_region) {
101                 dev_err(dev, "no dma memory-region phandle\n");
102                 return -ENODEV;
103         }
104
105         ret = of_address_to_resource(mem_region, 0, &res);
106         of_node_put(mem_region);
107         if (ret) {
108                 dev_err(dev, "of_address_to_resource dma failed\n");
109                 return ret;
110         }
111
112         dev_dbg(dev, "DMA %pR\n", &res);
113
114         adsp->pa_shared_dram = (phys_addr_t)res.start;
115         adsp->shared_size = resource_size(&res);
116         if (adsp->pa_shared_dram & DRAM_REMAP_MASK) {
117                 dev_err(dev, "adsp shared dma memory(%#x) is not 4K-aligned\n",
118                         (u32)adsp->pa_shared_dram);
119                 return -EINVAL;
120         }
121
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
128         mem_region = of_parse_phandle(dev->of_node, "memory-region", 1);
129         if (!mem_region) {
130                 dev_err(dev, "no memory-region sysmem phandle\n");
131                 return -ENODEV;
132         }
133
134         ret = of_address_to_resource(mem_region, 0, &res);
135         of_node_put(mem_region);
136         if (ret) {
137                 dev_err(dev, "of_address_to_resource sysmem failed\n");
138                 return ret;
139         }
140
141         adsp->pa_dram = (phys_addr_t)res.start;
142         if (adsp->pa_dram & DRAM_REMAP_MASK) {
143                 dev_err(dev, "adsp memory(%#x) is not 4K-aligned\n",
144                         (u32)adsp->pa_dram);
145                 return -EINVAL;
146         }
147
148         adsp->dramsize = resource_size(&res);
149         if (adsp->dramsize < TOTAL_SIZE_SHARED_DRAM_FROM_TAIL) {
150                 dev_err(dev, "adsp memory(%#x) is not enough for share\n",
151                         adsp->dramsize);
152                 return -EINVAL;
153         }
154
155         dev_dbg(dev, "dram pbase=%pa size=%#x\n", &adsp->pa_dram, adsp->dramsize);
156
157         mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
158         if (!mmio) {
159                 dev_err(dev, "no ADSP-CFG register resource\n");
160                 return -ENXIO;
161         }
162
163         adsp->va_cfgreg = devm_ioremap_resource(dev, mmio);
164         if (IS_ERR(adsp->va_cfgreg))
165                 return PTR_ERR(adsp->va_cfgreg);
166
167         adsp->pa_cfgreg = (phys_addr_t)mmio->start;
168         adsp->cfgregsize = resource_size(mmio);
169
170         dev_dbg(dev, "cfgreg pbase=%pa size=%#x\n", &adsp->pa_cfgreg, adsp->cfgregsize);
171
172         mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
173         if (!mmio) {
174                 dev_err(dev, "no SRAM resource\n");
175                 return -ENXIO;
176         }
177
178         adsp->pa_sram = (phys_addr_t)mmio->start;
179         adsp->sramsize = resource_size(mmio);
180
181         dev_dbg(dev, "sram pbase=%pa size=%#x\n", &adsp->pa_sram, adsp->sramsize);
182
183         mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sec");
184         if (!mmio) {
185                 dev_err(dev, "no SEC register resource\n");
186                 return -ENXIO;
187         }
188
189         adsp->va_secreg = devm_ioremap_resource(dev, mmio);
190         if (IS_ERR(adsp->va_secreg))
191                 return PTR_ERR(adsp->va_secreg);
192
193         adsp->pa_secreg = (phys_addr_t)mmio->start;
194         adsp->secregsize = resource_size(mmio);
195
196         dev_dbg(dev, "secreg pbase=%pa size=%#x\n", &adsp->pa_secreg, adsp->secregsize);
197
198         mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bus");
199         if (!mmio) {
200                 dev_err(dev, "no BUS register resource\n");
201                 return -ENXIO;
202         }
203
204         adsp->va_busreg = devm_ioremap_resource(dev, mmio);
205         if (IS_ERR(adsp->va_busreg))
206                 return PTR_ERR(adsp->va_busreg);
207
208         adsp->pa_busreg = (phys_addr_t)mmio->start;
209         adsp->busregsize = resource_size(mmio);
210
211         dev_dbg(dev, "busreg pbase=%pa size=%#x\n", &adsp->pa_busreg, adsp->busregsize);
212
213         return 0;
214 }
215
216 static void adsp_sram_power_on(struct snd_sof_dev *sdev)
217 {
218         snd_sof_dsp_update_bits(sdev, DSP_BUSREG_BAR, ADSP_SRAM_POOL_CON,
219                                 DSP_SRAM_POOL_PD_MASK, 0);
220 }
221
222 static void adsp_sram_power_off(struct snd_sof_dev *sdev)
223 {
224         snd_sof_dsp_update_bits(sdev, DSP_BUSREG_BAR, ADSP_SRAM_POOL_CON,
225                                 DSP_SRAM_POOL_PD_MASK, DSP_SRAM_POOL_PD_MASK);
226 }
227
228 /*  Init the basic DSP DRAM address */
229 static int adsp_memory_remap_init(struct snd_sof_dev *sdev, struct mtk_adsp_chip_info *adsp)
230 {
231         u32 offset;
232
233         offset = adsp->pa_dram - DRAM_PHYS_BASE_FROM_DSP_VIEW;
234         adsp->dram_offset = offset;
235         offset >>= DRAM_REMAP_SHIFT;
236
237         dev_dbg(sdev->dev, "adsp->pa_dram %pa, offset %#x\n", &adsp->pa_dram, offset);
238
239         snd_sof_dsp_write(sdev, DSP_BUSREG_BAR, DSP_C0_EMI_MAP_ADDR, offset);
240         snd_sof_dsp_write(sdev, DSP_BUSREG_BAR, DSP_C0_DMAEMI_MAP_ADDR, offset);
241
242         if (offset != snd_sof_dsp_read(sdev, DSP_BUSREG_BAR, DSP_C0_EMI_MAP_ADDR) ||
243             offset != snd_sof_dsp_read(sdev, DSP_BUSREG_BAR, DSP_C0_DMAEMI_MAP_ADDR)) {
244                 dev_err(sdev->dev, "emi remap fail\n");
245                 return -EIO;
246         }
247
248         return 0;
249 }
250
251 static int adsp_shared_base_ioremap(struct platform_device *pdev, void *data)
252 {
253         struct device *dev = &pdev->dev;
254         struct mtk_adsp_chip_info *adsp = data;
255
256         /* remap shared-dram base to be non-cachable */
257         adsp->shared_dram = devm_ioremap(dev, adsp->pa_shared_dram,
258                                          adsp->shared_size);
259         if (!adsp->shared_dram) {
260                 dev_err(dev, "failed to ioremap base %pa size %#x\n",
261                         adsp->shared_dram, adsp->shared_size);
262                 return -ENOMEM;
263         }
264
265         dev_dbg(dev, "shared-dram vbase=%p, phy addr :%pa,  size=%#x\n",
266                 adsp->shared_dram, &adsp->pa_shared_dram, adsp->shared_size);
267
268         return 0;
269 }
270
271 static int mt8186_run(struct snd_sof_dev *sdev)
272 {
273         u32 adsp_bootup_addr;
274
275         adsp_bootup_addr = SRAM_PHYS_BASE_FROM_DSP_VIEW;
276         dev_dbg(sdev->dev, "HIFIxDSP boot from base : 0x%08X\n", adsp_bootup_addr);
277         mt8186_sof_hifixdsp_boot_sequence(sdev, adsp_bootup_addr);
278
279         return 0;
280 }
281
282 static int mt8186_dsp_probe(struct snd_sof_dev *sdev)
283 {
284         struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev);
285         struct adsp_priv *priv;
286         int ret;
287
288         priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
289         if (!priv)
290                 return -ENOMEM;
291
292         sdev->pdata->hw_pdata = priv;
293         priv->dev = sdev->dev;
294         priv->sdev = sdev;
295
296         priv->adsp = devm_kzalloc(&pdev->dev, sizeof(struct mtk_adsp_chip_info), GFP_KERNEL);
297         if (!priv->adsp)
298                 return -ENOMEM;
299
300         ret = platform_parse_resource(pdev, priv->adsp);
301         if (ret)
302                 return ret;
303
304         sdev->bar[SOF_FW_BLK_TYPE_IRAM] = devm_ioremap(sdev->dev,
305                                                        priv->adsp->pa_sram,
306                                                        priv->adsp->sramsize);
307         if (!sdev->bar[SOF_FW_BLK_TYPE_IRAM]) {
308                 dev_err(sdev->dev, "failed to ioremap base %pa size %#x\n",
309                         &priv->adsp->pa_sram, priv->adsp->sramsize);
310                 return -ENOMEM;
311         }
312
313         priv->adsp->va_sram = sdev->bar[SOF_FW_BLK_TYPE_IRAM];
314
315         sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap(sdev->dev,
316                                                        priv->adsp->pa_dram,
317                                                        priv->adsp->dramsize);
318
319         if (!sdev->bar[SOF_FW_BLK_TYPE_SRAM]) {
320                 dev_err(sdev->dev, "failed to ioremap base %pa size %#x\n",
321                         &priv->adsp->pa_dram, priv->adsp->dramsize);
322                 return -ENOMEM;
323         }
324
325         priv->adsp->va_dram = sdev->bar[SOF_FW_BLK_TYPE_SRAM];
326
327         ret = adsp_shared_base_ioremap(pdev, priv->adsp);
328         if (ret) {
329                 dev_err(sdev->dev, "adsp_shared_base_ioremap fail!\n");
330                 return ret;
331         }
332
333         sdev->bar[DSP_REG_BAR] = priv->adsp->va_cfgreg;
334         sdev->bar[DSP_SECREG_BAR] = priv->adsp->va_secreg;
335         sdev->bar[DSP_BUSREG_BAR] = priv->adsp->va_busreg;
336
337         sdev->mmio_bar = SOF_FW_BLK_TYPE_SRAM;
338         sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM;
339
340         /* set default mailbox offset for FW ready message */
341         sdev->dsp_box.offset = mt8186_get_mailbox_offset(sdev);
342
343         ret = adsp_memory_remap_init(sdev, priv->adsp);
344         if (ret) {
345                 dev_err(sdev->dev, "adsp_memory_remap_init fail!\n");
346                 return ret;
347         }
348
349         /* enable adsp clock before touching registers */
350         ret = mt8186_adsp_init_clock(sdev);
351         if (ret) {
352                 dev_err(sdev->dev, "mt8186_adsp_init_clock failed\n");
353                 return ret;
354         }
355
356         ret = mt8186_adsp_clock_on(sdev);
357         if (ret) {
358                 dev_err(sdev->dev, "mt8186_adsp_clock_on fail!\n");
359                 return ret;
360         }
361
362         adsp_sram_power_on(sdev);
363
364         priv->ipc_dev = platform_device_register_data(&pdev->dev, "mtk-adsp-ipc",
365                                                       PLATFORM_DEVID_NONE,
366                                                       pdev, sizeof(*pdev));
367         if (IS_ERR(priv->ipc_dev)) {
368                 ret = PTR_ERR(priv->ipc_dev);
369                 dev_err(sdev->dev, "failed to create mtk-adsp-ipc device\n");
370                 goto err_adsp_off;
371         }
372
373         priv->dsp_ipc = dev_get_drvdata(&priv->ipc_dev->dev);
374         if (!priv->dsp_ipc) {
375                 ret = -EPROBE_DEFER;
376                 dev_err(sdev->dev, "failed to get drvdata\n");
377                 goto exit_pdev_unregister;
378         }
379
380         mtk_adsp_ipc_set_data(priv->dsp_ipc, priv);
381         priv->dsp_ipc->ops = &dsp_ops;
382
383         return 0;
384
385 exit_pdev_unregister:
386         platform_device_unregister(priv->ipc_dev);
387 err_adsp_off:
388         adsp_sram_power_off(sdev);
389         mt8186_adsp_clock_off(sdev);
390
391         return ret;
392 }
393
394 static void mt8186_dsp_remove(struct snd_sof_dev *sdev)
395 {
396         struct adsp_priv *priv = sdev->pdata->hw_pdata;
397
398         platform_device_unregister(priv->ipc_dev);
399         mt8186_sof_hifixdsp_shutdown(sdev);
400         adsp_sram_power_off(sdev);
401         mt8186_adsp_clock_off(sdev);
402 }
403
404 static int mt8186_dsp_shutdown(struct snd_sof_dev *sdev)
405 {
406         return snd_sof_suspend(sdev->dev);
407 }
408
409 static int mt8186_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
410 {
411         mt8186_sof_hifixdsp_shutdown(sdev);
412         adsp_sram_power_off(sdev);
413         mt8186_adsp_clock_off(sdev);
414
415         return 0;
416 }
417
418 static int mt8186_dsp_resume(struct snd_sof_dev *sdev)
419 {
420         int ret;
421
422         ret = mt8186_adsp_clock_on(sdev);
423         if (ret) {
424                 dev_err(sdev->dev, "mt8186_adsp_clock_on fail!\n");
425                 return ret;
426         }
427
428         adsp_sram_power_on(sdev);
429
430         return ret;
431 }
432
433 /* on mt8186 there is 1 to 1 match between type and BAR idx */
434 static int mt8186_get_bar_index(struct snd_sof_dev *sdev, u32 type)
435 {
436         return type;
437 }
438
439 static int mt8186_pcm_hw_params(struct snd_sof_dev *sdev,
440                                 struct snd_pcm_substream *substream,
441                                 struct snd_pcm_hw_params *params,
442                                 struct snd_sof_platform_stream_params *platform_params)
443 {
444         platform_params->cont_update_posn = 1;
445
446         return 0;
447 }
448
449 static snd_pcm_uframes_t mt8186_pcm_pointer(struct snd_sof_dev *sdev,
450                                             struct snd_pcm_substream *substream)
451 {
452         int ret;
453         snd_pcm_uframes_t pos;
454         struct snd_sof_pcm *spcm;
455         struct sof_ipc_stream_posn posn;
456         struct snd_sof_pcm_stream *stream;
457         struct snd_soc_component *scomp = sdev->component;
458         struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
459
460         spcm = snd_sof_find_spcm_dai(scomp, rtd);
461         if (!spcm) {
462                 dev_warn_ratelimited(sdev->dev, "warn: can't find PCM with DAI ID %d\n",
463                                      rtd->dai_link->id);
464                 return 0;
465         }
466
467         stream = &spcm->stream[substream->stream];
468         ret = snd_sof_ipc_msg_data(sdev, stream, &posn, sizeof(posn));
469         if (ret < 0) {
470                 dev_warn(sdev->dev, "failed to read stream position: %d\n", ret);
471                 return 0;
472         }
473
474         memcpy(&stream->posn, &posn, sizeof(posn));
475         pos = spcm->stream[substream->stream].posn.host_posn;
476         pos = bytes_to_frames(substream->runtime, pos);
477
478         return pos;
479 }
480
481 static void mt8186_adsp_dump(struct snd_sof_dev *sdev, u32 flags)
482 {
483         u32 dbg_pc, dbg_data, dbg_inst, dbg_ls0stat, dbg_status, faultinfo;
484
485         /* dump debug registers */
486         dbg_pc = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGPC);
487         dbg_data = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGDATA);
488         dbg_inst = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGINST);
489         dbg_ls0stat = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGLS0STAT);
490         dbg_status = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGSTATUS);
491         faultinfo = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PFAULTINFO);
492
493         dev_info(sdev->dev, "adsp dump : pc %#x, data %#x, dbg_inst %#x,",
494                  dbg_pc, dbg_data, dbg_inst);
495         dev_info(sdev->dev, "ls0stat %#x, status %#x, faultinfo %#x",
496                  dbg_ls0stat, dbg_status, faultinfo);
497
498         mtk_adsp_dump(sdev, flags);
499 }
500
501 static struct snd_soc_dai_driver mt8186_dai[] = {
502 {
503         .name = "SOF_DL1",
504         .playback = {
505                 .channels_min = 1,
506                 .channels_max = 2,
507         },
508 },
509 {
510         .name = "SOF_DL2",
511         .playback = {
512                 .channels_min = 1,
513                 .channels_max = 2,
514         },
515 },
516 {
517         .name = "SOF_UL1",
518         .capture = {
519                 .channels_min = 1,
520                 .channels_max = 2,
521         },
522 },
523 {
524         .name = "SOF_UL2",
525         .capture = {
526                 .channels_min = 1,
527                 .channels_max = 2,
528         },
529 },
530 };
531
532 /* mt8186 ops */
533 static struct snd_sof_dsp_ops sof_mt8186_ops = {
534         /* probe and remove */
535         .probe          = mt8186_dsp_probe,
536         .remove         = mt8186_dsp_remove,
537         .shutdown       = mt8186_dsp_shutdown,
538
539         /* DSP core boot */
540         .run            = mt8186_run,
541
542         /* Block IO */
543         .block_read     = sof_block_read,
544         .block_write    = sof_block_write,
545
546         /* Mailbox IO */
547         .mailbox_read   = sof_mailbox_read,
548         .mailbox_write  = sof_mailbox_write,
549
550         /* Register IO */
551         .write          = sof_io_write,
552         .read           = sof_io_read,
553         .write64        = sof_io_write64,
554         .read64         = sof_io_read64,
555
556         /* ipc */
557         .send_msg               = mt8186_send_msg,
558         .get_mailbox_offset     = mt8186_get_mailbox_offset,
559         .get_window_offset      = mt8186_get_window_offset,
560         .ipc_msg_data           = sof_ipc_msg_data,
561         .set_stream_data_offset = sof_set_stream_data_offset,
562
563         /* misc */
564         .get_bar_index  = mt8186_get_bar_index,
565
566         /* stream callbacks */
567         .pcm_open       = sof_stream_pcm_open,
568         .pcm_hw_params  = mt8186_pcm_hw_params,
569         .pcm_pointer    = mt8186_pcm_pointer,
570         .pcm_close      = sof_stream_pcm_close,
571
572         /* firmware loading */
573         .load_firmware  = snd_sof_load_firmware_memcpy,
574
575         /* Firmware ops */
576         .dsp_arch_ops = &sof_xtensa_arch_ops,
577
578         /* DAI drivers */
579         .drv            = mt8186_dai,
580         .num_drv        = ARRAY_SIZE(mt8186_dai),
581
582         /* Debug information */
583         .dbg_dump = mt8186_adsp_dump,
584         .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
585
586         /* PM */
587         .suspend        = mt8186_dsp_suspend,
588         .resume         = mt8186_dsp_resume,
589
590         /* ALSA HW info flags */
591         .hw_info =      SNDRV_PCM_INFO_MMAP |
592                         SNDRV_PCM_INFO_MMAP_VALID |
593                         SNDRV_PCM_INFO_INTERLEAVED |
594                         SNDRV_PCM_INFO_PAUSE |
595                         SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
596 };
597
598 static struct snd_sof_of_mach sof_mt8186_machs[] = {
599         {
600                 .compatible = "google,steelix",
601                 .sof_tplg_filename = "sof-mt8186-google-steelix.tplg"
602         }, {
603                 .compatible = "mediatek,mt8186",
604                 .sof_tplg_filename = "sof-mt8186.tplg",
605         },
606         {}
607 };
608
609 static const struct sof_dev_desc sof_of_mt8186_desc = {
610         .of_machines = sof_mt8186_machs,
611         .ipc_supported_mask     = BIT(SOF_IPC_TYPE_3),
612         .ipc_default            = SOF_IPC_TYPE_3,
613         .default_fw_path = {
614                 [SOF_IPC_TYPE_3] = "mediatek/sof",
615         },
616         .default_tplg_path = {
617                 [SOF_IPC_TYPE_3] = "mediatek/sof-tplg",
618         },
619         .default_fw_filename = {
620                 [SOF_IPC_TYPE_3] = "sof-mt8186.ri",
621         },
622         .nocodec_tplg_filename = "sof-mt8186-nocodec.tplg",
623         .ops = &sof_mt8186_ops,
624 };
625
626 /*
627  * DL2, DL3, UL4, UL5 are registered as SOF FE, so creating the corresponding
628  * SOF BE to complete the pipeline.
629  */
630 static struct snd_soc_dai_driver mt8188_dai[] = {
631 {
632         .name = "SOF_DL2",
633         .playback = {
634                 .channels_min = 1,
635                 .channels_max = 2,
636         },
637 },
638 {
639         .name = "SOF_DL3",
640         .playback = {
641                 .channels_min = 1,
642                 .channels_max = 2,
643         },
644 },
645 {
646         .name = "SOF_UL4",
647         .capture = {
648                 .channels_min = 1,
649                 .channels_max = 2,
650         },
651 },
652 {
653         .name = "SOF_UL5",
654         .capture = {
655                 .channels_min = 1,
656                 .channels_max = 2,
657         },
658 },
659 };
660
661 /* mt8188 ops */
662 static struct snd_sof_dsp_ops sof_mt8188_ops;
663
664 static int sof_mt8188_ops_init(struct snd_sof_dev *sdev)
665 {
666         /* common defaults */
667         memcpy(&sof_mt8188_ops, &sof_mt8186_ops, sizeof(sof_mt8188_ops));
668
669         sof_mt8188_ops.drv = mt8188_dai;
670         sof_mt8188_ops.num_drv = ARRAY_SIZE(mt8188_dai);
671
672         return 0;
673 }
674
675 static struct snd_sof_of_mach sof_mt8188_machs[] = {
676         {
677                 .compatible = "mediatek,mt8188",
678                 .sof_tplg_filename = "sof-mt8188.tplg",
679         },
680         {}
681 };
682
683 static const struct sof_dev_desc sof_of_mt8188_desc = {
684         .of_machines = sof_mt8188_machs,
685         .ipc_supported_mask     = BIT(SOF_IPC_TYPE_3),
686         .ipc_default            = SOF_IPC_TYPE_3,
687         .default_fw_path = {
688                 [SOF_IPC_TYPE_3] = "mediatek/sof",
689         },
690         .default_tplg_path = {
691                 [SOF_IPC_TYPE_3] = "mediatek/sof-tplg",
692         },
693         .default_fw_filename = {
694                 [SOF_IPC_TYPE_3] = "sof-mt8188.ri",
695         },
696         .nocodec_tplg_filename = "sof-mt8188-nocodec.tplg",
697         .ops = &sof_mt8188_ops,
698         .ops_init = sof_mt8188_ops_init,
699 };
700
701 static const struct of_device_id sof_of_mt8186_ids[] = {
702         { .compatible = "mediatek,mt8186-dsp", .data = &sof_of_mt8186_desc},
703         { .compatible = "mediatek,mt8188-dsp", .data = &sof_of_mt8188_desc},
704         { }
705 };
706 MODULE_DEVICE_TABLE(of, sof_of_mt8186_ids);
707
708 /* DT driver definition */
709 static struct platform_driver snd_sof_of_mt8186_driver = {
710         .probe = sof_of_probe,
711         .remove_new = sof_of_remove,
712         .shutdown = sof_of_shutdown,
713         .driver = {
714         .name = "sof-audio-of-mt8186",
715                 .pm = &sof_of_pm,
716                 .of_match_table = sof_of_mt8186_ids,
717         },
718 };
719 module_platform_driver(snd_sof_of_mt8186_driver);
720
721 MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
722 MODULE_IMPORT_NS(SND_SOC_SOF_MTK_COMMON);
723 MODULE_LICENSE("Dual BSD/GPL");