1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * mt8188-mt6359.c  --  MT8188-MT6359 ALSA SoC machine driver
4  *
5  * Copyright (c) 2022 MediaTek Inc.
6  * Author: Trevor Wu <trevor.wu@mediatek.com>
7  */
8 
9 #include <linux/bitfield.h>
10 #include <linux/input.h>
11 #include <linux/module.h>
12 #include <linux/of_device.h>
13 #include <linux/pm_runtime.h>
14 #include <sound/jack.h>
15 #include <sound/pcm_params.h>
16 #include <sound/soc.h>
17 #include "mt8188-afe-common.h"
18 #include "../../codecs/nau8825.h"
19 #include "../../codecs/mt6359.h"
20 #include "../common/mtk-afe-platform-driver.h"
21 #include "../common/mtk-soundcard-driver.h"
22 
23 #define CKSYS_AUD_TOP_CFG	0x032c
24  #define RG_TEST_ON		BIT(0)
25  #define RG_TEST_TYPE		BIT(2)
26 #define CKSYS_AUD_TOP_MON	0x0330
27  #define TEST_MISO_COUNT_1	GENMASK(3, 0)
28  #define TEST_MISO_COUNT_2	GENMASK(7, 4)
29  #define TEST_MISO_DONE_1	BIT(28)
30  #define TEST_MISO_DONE_2	BIT(29)
31 
32 #define NAU8825_HS_PRESENT	BIT(0)
33 
34 /*
35  * Maxim MAX98390
36  */
37 #define MAX98390_CODEC_DAI     "max98390-aif1"
38 #define MAX98390_DEV0_NAME     "max98390.0-0038" /* rear right */
39 #define MAX98390_DEV1_NAME     "max98390.0-0039" /* rear left */
40 #define MAX98390_DEV2_NAME     "max98390.0-003a" /* front right */
41 #define MAX98390_DEV3_NAME     "max98390.0-003b" /* front left */
42 
43 /*
44  * Nau88l25
45  */
46 #define NAU8825_CODEC_DAI  "nau8825-hifi"
47 
48 /* FE */
49 SND_SOC_DAILINK_DEFS(playback2,
50 		     DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
51 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
52 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
53 
54 SND_SOC_DAILINK_DEFS(playback3,
55 		     DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
56 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
57 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
58 
59 SND_SOC_DAILINK_DEFS(playback6,
60 		     DAILINK_COMP_ARRAY(COMP_CPU("DL6")),
61 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
62 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
63 
64 SND_SOC_DAILINK_DEFS(playback7,
65 		     DAILINK_COMP_ARRAY(COMP_CPU("DL7")),
66 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
67 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
68 
69 SND_SOC_DAILINK_DEFS(playback8,
70 		     DAILINK_COMP_ARRAY(COMP_CPU("DL8")),
71 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
72 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
73 
74 SND_SOC_DAILINK_DEFS(playback10,
75 		     DAILINK_COMP_ARRAY(COMP_CPU("DL10")),
76 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
77 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
78 
79 SND_SOC_DAILINK_DEFS(playback11,
80 		     DAILINK_COMP_ARRAY(COMP_CPU("DL11")),
81 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
82 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
83 
84 SND_SOC_DAILINK_DEFS(capture1,
85 		     DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
86 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
87 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
88 
89 SND_SOC_DAILINK_DEFS(capture2,
90 		     DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
91 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
92 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
93 
94 SND_SOC_DAILINK_DEFS(capture3,
95 		     DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
96 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
97 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
98 
99 SND_SOC_DAILINK_DEFS(capture4,
100 		     DAILINK_COMP_ARRAY(COMP_CPU("UL4")),
101 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
102 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
103 
104 SND_SOC_DAILINK_DEFS(capture5,
105 		     DAILINK_COMP_ARRAY(COMP_CPU("UL5")),
106 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
107 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
108 
109 SND_SOC_DAILINK_DEFS(capture6,
110 		     DAILINK_COMP_ARRAY(COMP_CPU("UL6")),
111 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
112 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
113 
114 SND_SOC_DAILINK_DEFS(capture8,
115 		     DAILINK_COMP_ARRAY(COMP_CPU("UL8")),
116 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
117 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
118 
119 SND_SOC_DAILINK_DEFS(capture9,
120 		     DAILINK_COMP_ARRAY(COMP_CPU("UL9")),
121 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
122 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
123 
124 SND_SOC_DAILINK_DEFS(capture10,
125 		     DAILINK_COMP_ARRAY(COMP_CPU("UL10")),
126 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
127 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
128 
129 /* BE */
130 SND_SOC_DAILINK_DEFS(dl_src,
131 		     DAILINK_COMP_ARRAY(COMP_CPU("DL_SRC")),
132 		     DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
133 						   "mt6359-snd-codec-aif1")),
134 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
135 
136 SND_SOC_DAILINK_DEFS(dptx,
137 		     DAILINK_COMP_ARRAY(COMP_CPU("DPTX")),
138 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
139 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
140 
141 SND_SOC_DAILINK_DEFS(etdm1_in,
142 		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_IN")),
143 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
144 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
145 
146 SND_SOC_DAILINK_DEFS(etdm2_in,
147 		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_IN")),
148 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
149 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
150 
151 SND_SOC_DAILINK_DEFS(etdm1_out,
152 		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_OUT")),
153 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
154 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
155 
156 SND_SOC_DAILINK_DEFS(etdm2_out,
157 		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_OUT")),
158 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
159 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
160 
161 SND_SOC_DAILINK_DEFS(etdm3_out,
162 		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM3_OUT")),
163 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
164 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
165 
166 SND_SOC_DAILINK_DEFS(pcm1,
167 		     DAILINK_COMP_ARRAY(COMP_CPU("PCM1")),
168 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
169 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
170 
171 SND_SOC_DAILINK_DEFS(ul_src,
172 		     DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC")),
173 		     DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
174 						   "mt6359-snd-codec-aif1"),
175 					COMP_CODEC("dmic-codec",
176 						   "dmic-hifi")),
177 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
178 
179 struct mt8188_mt6359_priv {
180 	struct snd_soc_jack dp_jack;
181 	struct snd_soc_jack hdmi_jack;
182 	struct snd_soc_jack headset_jack;
183 	void *private_data;
184 };
185 
186 static struct snd_soc_jack_pin mt8188_hdmi_jack_pins[] = {
187 	{
188 		.pin = "HDMI",
189 		.mask = SND_JACK_LINEOUT,
190 	},
191 };
192 
193 static struct snd_soc_jack_pin mt8188_dp_jack_pins[] = {
194 	{
195 		.pin = "DP",
196 		.mask = SND_JACK_LINEOUT,
197 	},
198 };
199 
200 static struct snd_soc_jack_pin nau8825_jack_pins[] = {
201 	{
202 		.pin    = "Headphone Jack",
203 		.mask   = SND_JACK_HEADPHONE,
204 	},
205 	{
206 		.pin    = "Headset Mic",
207 		.mask   = SND_JACK_MICROPHONE,
208 	},
209 };
210 
211 struct mt8188_card_data {
212 	const char *name;
213 	unsigned long quirk;
214 };
215 
216 static const struct snd_kcontrol_new mt8188_dumb_spk_controls[] = {
217 	SOC_DAPM_PIN_SWITCH("Ext Spk"),
218 };
219 
220 static const struct snd_soc_dapm_widget mt8188_dumb_spk_widgets[] = {
221 	SND_SOC_DAPM_SPK("Ext Spk", NULL),
222 };
223 
224 static const struct snd_kcontrol_new mt8188_dual_spk_controls[] = {
225 	SOC_DAPM_PIN_SWITCH("Left Spk"),
226 	SOC_DAPM_PIN_SWITCH("Right Spk"),
227 };
228 
229 static const struct snd_soc_dapm_widget mt8188_dual_spk_widgets[] = {
230 	SND_SOC_DAPM_SPK("Left Spk", NULL),
231 	SND_SOC_DAPM_SPK("Right Spk", NULL),
232 };
233 
234 static const struct snd_kcontrol_new mt8188_rear_spk_controls[] = {
235 	SOC_DAPM_PIN_SWITCH("Rear Left Spk"),
236 	SOC_DAPM_PIN_SWITCH("Rear Right Spk"),
237 };
238 
239 static const struct snd_soc_dapm_widget mt8188_rear_spk_widgets[] = {
240 	SND_SOC_DAPM_SPK("Rear Left Spk", NULL),
241 	SND_SOC_DAPM_SPK("Rear Right Spk", NULL),
242 };
243 
244 static const struct snd_soc_dapm_widget mt8188_mt6359_widgets[] = {
245 	SND_SOC_DAPM_HP("Headphone", NULL),
246 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
247 	SND_SOC_DAPM_SINK("HDMI"),
248 	SND_SOC_DAPM_SINK("DP"),
249 };
250 
251 static const struct snd_kcontrol_new mt8188_mt6359_controls[] = {
252 	SOC_DAPM_PIN_SWITCH("Headphone"),
253 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
254 };
255 
256 static const struct snd_soc_dapm_widget mt8188_nau8825_widgets[] = {
257 	SND_SOC_DAPM_HP("Headphone Jack", NULL),
258 };
259 
260 static const struct snd_kcontrol_new mt8188_nau8825_controls[] = {
261 	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
262 };
263 
264 static int mt8188_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd)
265 {
266 	struct snd_soc_component *cmpnt_afe =
267 		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
268 	struct snd_soc_component *cmpnt_codec =
269 		asoc_rtd_to_codec(rtd, 0)->component;
270 	struct mtk_base_afe *afe;
271 	struct mt8188_afe_private *afe_priv;
272 	struct mtkaif_param *param;
273 	int chosen_phase_1, chosen_phase_2;
274 	int prev_cycle_1, prev_cycle_2;
275 	u8 test_done_1, test_done_2;
276 	int cycle_1, cycle_2;
277 	int mtkaif_chosen_phase[MT8188_MTKAIF_MISO_NUM];
278 	int mtkaif_phase_cycle[MT8188_MTKAIF_MISO_NUM];
279 	int mtkaif_calibration_num_phase;
280 	bool mtkaif_calibration_ok;
281 	u32 monitor = 0;
282 	int counter;
283 	int phase;
284 	int i;
285 
286 	if (!cmpnt_afe)
287 		return -EINVAL;
288 
289 	afe = snd_soc_component_get_drvdata(cmpnt_afe);
290 	afe_priv = afe->platform_priv;
291 	param = &afe_priv->mtkaif_params;
292 
293 	dev_dbg(afe->dev, "%s(), start\n", __func__);
294 
295 	param->mtkaif_calibration_ok = false;
296 	for (i = 0; i < MT8188_MTKAIF_MISO_NUM; i++) {
297 		param->mtkaif_chosen_phase[i] = -1;
298 		param->mtkaif_phase_cycle[i] = 0;
299 		mtkaif_chosen_phase[i] = -1;
300 		mtkaif_phase_cycle[i] = 0;
301 	}
302 
303 	if (IS_ERR(afe_priv->topckgen)) {
304 		dev_info(afe->dev, "%s() Cannot find topckgen controller\n",
305 			 __func__);
306 		return 0;
307 	}
308 
309 	pm_runtime_get_sync(afe->dev);
310 	mt6359_mtkaif_calibration_enable(cmpnt_codec);
311 
312 	/* set test type to synchronizer pulse */
313 	regmap_write(afe_priv->topckgen, CKSYS_AUD_TOP_CFG, RG_TEST_TYPE);
314 	mtkaif_calibration_num_phase = 42;	/* mt6359: 0 ~ 42 */
315 	mtkaif_calibration_ok = true;
316 
317 	for (phase = 0;
318 	     phase <= mtkaif_calibration_num_phase && mtkaif_calibration_ok;
319 	     phase++) {
320 		mt6359_set_mtkaif_calibration_phase(cmpnt_codec,
321 						    phase, phase, phase);
322 
323 		regmap_set_bits(afe_priv->topckgen, CKSYS_AUD_TOP_CFG, RG_TEST_ON);
324 
325 		test_done_1 = 0;
326 		test_done_2 = 0;
327 
328 		cycle_1 = -1;
329 		cycle_2 = -1;
330 
331 		counter = 0;
332 		while (!(test_done_1 & test_done_2)) {
333 			regmap_read(afe_priv->topckgen,
334 				    CKSYS_AUD_TOP_MON, &monitor);
335 			test_done_1 = FIELD_GET(TEST_MISO_DONE_1, monitor);
336 			test_done_2 = FIELD_GET(TEST_MISO_DONE_2, monitor);
337 
338 			if (test_done_1 == 1)
339 				cycle_1 = FIELD_GET(TEST_MISO_COUNT_1, monitor);
340 
341 			if (test_done_2 == 1)
342 				cycle_2 = FIELD_GET(TEST_MISO_COUNT_2, monitor);
343 
344 			/* handle if never test done */
345 			if (++counter > 10000) {
346 				dev_err(afe->dev, "%s(), test fail, cycle_1 %d, cycle_2 %d, monitor 0x%x\n",
347 					__func__, cycle_1, cycle_2, monitor);
348 				mtkaif_calibration_ok = false;
349 				break;
350 			}
351 		}
352 
353 		if (phase == 0) {
354 			prev_cycle_1 = cycle_1;
355 			prev_cycle_2 = cycle_2;
356 		}
357 
358 		if (cycle_1 != prev_cycle_1 &&
359 		    mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] < 0) {
360 			mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] = phase - 1;
361 			mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0] = prev_cycle_1;
362 		}
363 
364 		if (cycle_2 != prev_cycle_2 &&
365 		    mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] < 0) {
366 			mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] = phase - 1;
367 			mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1] = prev_cycle_2;
368 		}
369 
370 		regmap_clear_bits(afe_priv->topckgen, CKSYS_AUD_TOP_CFG, RG_TEST_ON);
371 
372 		if (mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] >= 0 &&
373 		    mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] >= 0)
374 			break;
375 	}
376 
377 	if (mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] < 0) {
378 		mtkaif_calibration_ok = false;
379 		chosen_phase_1 = 0;
380 	} else {
381 		chosen_phase_1 = mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0];
382 	}
383 
384 	if (mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] < 0) {
385 		mtkaif_calibration_ok = false;
386 		chosen_phase_2 = 0;
387 	} else {
388 		chosen_phase_2 = mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1];
389 	}
390 
391 	mt6359_set_mtkaif_calibration_phase(cmpnt_codec,
392 					    chosen_phase_1,
393 					    chosen_phase_2,
394 					    0);
395 
396 	mt6359_mtkaif_calibration_disable(cmpnt_codec);
397 	pm_runtime_put(afe->dev);
398 
399 	param->mtkaif_calibration_ok = mtkaif_calibration_ok;
400 	param->mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] = chosen_phase_1;
401 	param->mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] = chosen_phase_2;
402 
403 	for (i = 0; i < MT8188_MTKAIF_MISO_NUM; i++)
404 		param->mtkaif_phase_cycle[i] = mtkaif_phase_cycle[i];
405 
406 	dev_dbg(afe->dev, "%s(), end, calibration ok %d\n",
407 		__func__, param->mtkaif_calibration_ok);
408 
409 	return 0;
410 }
411 
412 static int mt8188_mt6359_init(struct snd_soc_pcm_runtime *rtd)
413 {
414 	struct snd_soc_component *cmpnt_codec =
415 		asoc_rtd_to_codec(rtd, 0)->component;
416 
417 	/* set mtkaif protocol */
418 	mt6359_set_mtkaif_protocol(cmpnt_codec,
419 				   MT6359_MTKAIF_PROTOCOL_2_CLK_P2);
420 
421 	/* mtkaif calibration */
422 	mt8188_mt6359_mtkaif_calibration(rtd);
423 
424 	return 0;
425 }
426 
427 enum {
428 	DAI_LINK_DL2_FE,
429 	DAI_LINK_DL3_FE,
430 	DAI_LINK_DL6_FE,
431 	DAI_LINK_DL7_FE,
432 	DAI_LINK_DL8_FE,
433 	DAI_LINK_DL10_FE,
434 	DAI_LINK_DL11_FE,
435 	DAI_LINK_UL1_FE,
436 	DAI_LINK_UL2_FE,
437 	DAI_LINK_UL3_FE,
438 	DAI_LINK_UL4_FE,
439 	DAI_LINK_UL5_FE,
440 	DAI_LINK_UL6_FE,
441 	DAI_LINK_UL8_FE,
442 	DAI_LINK_UL9_FE,
443 	DAI_LINK_UL10_FE,
444 	DAI_LINK_DL_SRC_BE,
445 	DAI_LINK_DPTX_BE,
446 	DAI_LINK_ETDM1_IN_BE,
447 	DAI_LINK_ETDM2_IN_BE,
448 	DAI_LINK_ETDM1_OUT_BE,
449 	DAI_LINK_ETDM2_OUT_BE,
450 	DAI_LINK_ETDM3_OUT_BE,
451 	DAI_LINK_PCM1_BE,
452 	DAI_LINK_UL_SRC_BE,
453 };
454 
455 static int mt8188_dptx_hw_params(struct snd_pcm_substream *substream,
456 				 struct snd_pcm_hw_params *params)
457 {
458 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
459 	unsigned int rate = params_rate(params);
460 	unsigned int mclk_fs_ratio = 256;
461 	unsigned int mclk_fs = rate * mclk_fs_ratio;
462 	struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0);
463 
464 	return snd_soc_dai_set_sysclk(dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);
465 }
466 
467 static const struct snd_soc_ops mt8188_dptx_ops = {
468 	.hw_params = mt8188_dptx_hw_params,
469 };
470 
471 static int mt8188_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
472 				       struct snd_pcm_hw_params *params)
473 {
474 	/* fix BE i2s format to 32bit, clean param mask first */
475 	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
476 			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
477 
478 	params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
479 
480 	return 0;
481 }
482 
483 static int mt8188_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)
484 {
485 	struct mt8188_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card);
486 	struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
487 	int ret = 0;
488 
489 	ret = snd_soc_card_jack_new_pins(rtd->card, "HDMI Jack",
490 					 SND_JACK_LINEOUT, &priv->hdmi_jack,
491 					 mt8188_hdmi_jack_pins,
492 					 ARRAY_SIZE(mt8188_hdmi_jack_pins));
493 	if (ret) {
494 		dev_err(rtd->dev, "%s, new jack failed: %d\n", __func__, ret);
495 		return ret;
496 	}
497 
498 	ret = snd_soc_component_set_jack(component, &priv->hdmi_jack, NULL);
499 	if (ret) {
500 		dev_err(rtd->dev, "%s, set jack failed on %s (ret=%d)\n",
501 			__func__, component->name, ret);
502 		return ret;
503 	}
504 
505 	return 0;
506 }
507 
508 static int mt8188_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)
509 {
510 	struct mt8188_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card);
511 	struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
512 	int ret = 0;
513 
514 	ret = snd_soc_card_jack_new_pins(rtd->card, "DP Jack", SND_JACK_LINEOUT,
515 					 &priv->dp_jack, mt8188_dp_jack_pins,
516 					 ARRAY_SIZE(mt8188_dp_jack_pins));
517 	if (ret) {
518 		dev_err(rtd->dev, "%s, new jack failed: %d\n", __func__, ret);
519 		return ret;
520 	}
521 
522 	ret = snd_soc_component_set_jack(component, &priv->dp_jack, NULL);
523 	if (ret) {
524 		dev_err(rtd->dev, "%s, set jack failed on %s (ret=%d)\n",
525 			__func__, component->name, ret);
526 		return ret;
527 	}
528 
529 	return 0;
530 }
531 
532 static int mt8188_dumb_amp_init(struct snd_soc_pcm_runtime *rtd)
533 {
534 	struct snd_soc_card *card = rtd->card;
535 	int ret = 0;
536 
537 	ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_dumb_spk_widgets,
538 					ARRAY_SIZE(mt8188_dumb_spk_widgets));
539 	if (ret) {
540 		dev_err(rtd->dev, "unable to add Dumb Speaker dapm, ret %d\n", ret);
541 		return ret;
542 	}
543 
544 	ret = snd_soc_add_card_controls(card, mt8188_dumb_spk_controls,
545 					ARRAY_SIZE(mt8188_dumb_spk_controls));
546 	if (ret) {
547 		dev_err(rtd->dev, "unable to add Dumb card controls, ret %d\n", ret);
548 		return ret;
549 	}
550 
551 	return 0;
552 }
553 
554 static int mt8188_max98390_hw_params(struct snd_pcm_substream *substream,
555 				     struct snd_pcm_hw_params *params)
556 {
557 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
558 	unsigned int bit_width = params_width(params);
559 	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
560 	struct snd_soc_dai *codec_dai;
561 	int i;
562 
563 	snd_soc_dai_set_tdm_slot(cpu_dai, 0xf, 0xf, 4, bit_width);
564 
565 	for_each_rtd_codec_dais(rtd, i, codec_dai) {
566 		if (!strcmp(codec_dai->component->name, MAX98390_DEV0_NAME))
567 			snd_soc_dai_set_tdm_slot(codec_dai, 0x8, 0x3, 4, bit_width);
568 
569 		if (!strcmp(codec_dai->component->name, MAX98390_DEV1_NAME))
570 			snd_soc_dai_set_tdm_slot(codec_dai, 0x4, 0x3, 4, bit_width);
571 
572 		if (!strcmp(codec_dai->component->name, MAX98390_DEV2_NAME))
573 			snd_soc_dai_set_tdm_slot(codec_dai, 0x2, 0x3, 4, bit_width);
574 
575 		if (!strcmp(codec_dai->component->name, MAX98390_DEV3_NAME))
576 			snd_soc_dai_set_tdm_slot(codec_dai, 0x1, 0x3, 4, bit_width);
577 	}
578 	return 0;
579 }
580 
581 static const struct snd_soc_ops mt8188_max98390_ops = {
582 	.hw_params = mt8188_max98390_hw_params,
583 };
584 
585 static int mt8188_max98390_codec_init(struct snd_soc_pcm_runtime *rtd)
586 {
587 	struct snd_soc_card *card = rtd->card;
588 	int ret;
589 
590 	/* add regular speakers dapm route */
591 	ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_dual_spk_widgets,
592 					ARRAY_SIZE(mt8188_dual_spk_widgets));
593 	if (ret) {
594 		dev_err(rtd->dev, "unable to add Left/Right Speaker widget, ret %d\n", ret);
595 		return ret;
596 	}
597 
598 	ret = snd_soc_add_card_controls(card, mt8188_dual_spk_controls,
599 					ARRAY_SIZE(mt8188_dual_spk_controls));
600 	if (ret) {
601 		dev_err(rtd->dev, "unable to add Left/Right card controls, ret %d\n", ret);
602 		return ret;
603 	}
604 
605 	if (rtd->dai_link->num_codecs <= 2)
606 		return 0;
607 
608 	/* add widgets/controls/dapm for rear speakers */
609 	ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_rear_spk_widgets,
610 					ARRAY_SIZE(mt8188_rear_spk_widgets));
611 	if (ret) {
612 		dev_err(rtd->dev, "unable to add Rear Speaker widget, ret %d\n", ret);
613 		/* Don't need to add routes if widget addition failed */
614 		return ret;
615 	}
616 
617 	ret = snd_soc_add_card_controls(card, mt8188_rear_spk_controls,
618 					ARRAY_SIZE(mt8188_rear_spk_controls));
619 	if (ret) {
620 		dev_err(rtd->dev, "unable to add Rear card controls, ret %d\n", ret);
621 		return ret;
622 	}
623 
624 	return 0;
625 }
626 
627 static int mt8188_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
628 {
629 	struct snd_soc_card *card = rtd->card;
630 	struct mt8188_mt6359_priv *priv = snd_soc_card_get_drvdata(card);
631 	struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
632 	struct snd_soc_jack *jack = &priv->headset_jack;
633 	int ret;
634 
635 	ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_nau8825_widgets,
636 					ARRAY_SIZE(mt8188_nau8825_widgets));
637 	if (ret) {
638 		dev_err(rtd->dev, "unable to add nau8825 card widget, ret %d\n", ret);
639 		return ret;
640 	}
641 
642 	ret = snd_soc_add_card_controls(card, mt8188_nau8825_controls,
643 					ARRAY_SIZE(mt8188_nau8825_controls));
644 	if (ret) {
645 		dev_err(rtd->dev, "unable to add nau8825 card controls, ret %d\n", ret);
646 		return ret;
647 	}
648 
649 	ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
650 					 SND_JACK_HEADSET | SND_JACK_BTN_0 |
651 					 SND_JACK_BTN_1 | SND_JACK_BTN_2 |
652 					 SND_JACK_BTN_3,
653 					 jack,
654 					 nau8825_jack_pins,
655 					 ARRAY_SIZE(nau8825_jack_pins));
656 	if (ret) {
657 		dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
658 		return ret;
659 	}
660 
661 	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
662 	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
663 	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
664 	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
665 	ret = snd_soc_component_set_jack(component, jack, NULL);
666 
667 	if (ret) {
668 		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
669 		return ret;
670 	}
671 
672 	return 0;
673 };
674 
675 static void mt8188_nau8825_codec_exit(struct snd_soc_pcm_runtime *rtd)
676 {
677 	struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
678 
679 	snd_soc_component_set_jack(component, NULL, NULL);
680 }
681 
682 static int mt8188_nau8825_hw_params(struct snd_pcm_substream *substream,
683 				    struct snd_pcm_hw_params *params)
684 {
685 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
686 	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
687 	unsigned int rate = params_rate(params);
688 	unsigned int bit_width = params_width(params);
689 	int clk_freq, ret;
690 
691 	clk_freq = rate * 2 * bit_width;
692 
693 	/* Configure clock for codec */
694 	ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_BLK, 0,
695 				     SND_SOC_CLOCK_IN);
696 	if (ret < 0) {
697 		dev_err(codec_dai->dev, "can't set BCLK clock %d\n", ret);
698 		return ret;
699 	}
700 
701 	/* Configure pll for codec */
702 	ret = snd_soc_dai_set_pll(codec_dai, 0, 0, clk_freq,
703 				  params_rate(params) * 256);
704 	if (ret < 0) {
705 		dev_err(codec_dai->dev, "can't set BCLK: %d\n", ret);
706 		return ret;
707 	}
708 
709 	return 0;
710 }
711 
712 static const struct snd_soc_ops mt8188_nau8825_ops = {
713 	.hw_params = mt8188_nau8825_hw_params,
714 };
715 static struct snd_soc_dai_link mt8188_mt6359_dai_links[] = {
716 	/* FE */
717 	[DAI_LINK_DL2_FE] = {
718 		.name = "DL2_FE",
719 		.stream_name = "DL2 Playback",
720 		.trigger = {
721 			SND_SOC_DPCM_TRIGGER_POST,
722 			SND_SOC_DPCM_TRIGGER_POST,
723 		},
724 		.dynamic = 1,
725 		.dpcm_playback = 1,
726 		.dpcm_merged_chan = 1,
727 		.dpcm_merged_rate = 1,
728 		.dpcm_merged_format = 1,
729 		SND_SOC_DAILINK_REG(playback2),
730 	},
731 	[DAI_LINK_DL3_FE] = {
732 		.name = "DL3_FE",
733 		.stream_name = "DL3 Playback",
734 		.trigger = {
735 			SND_SOC_DPCM_TRIGGER_POST,
736 			SND_SOC_DPCM_TRIGGER_POST,
737 		},
738 		.dynamic = 1,
739 		.dpcm_playback = 1,
740 		.dpcm_merged_chan = 1,
741 		.dpcm_merged_rate = 1,
742 		.dpcm_merged_format = 1,
743 		SND_SOC_DAILINK_REG(playback3),
744 	},
745 	[DAI_LINK_DL6_FE] = {
746 		.name = "DL6_FE",
747 		.stream_name = "DL6 Playback",
748 		.trigger = {
749 			SND_SOC_DPCM_TRIGGER_POST,
750 			SND_SOC_DPCM_TRIGGER_POST,
751 		},
752 		.dynamic = 1,
753 		.dpcm_playback = 1,
754 		.dpcm_merged_chan = 1,
755 		.dpcm_merged_rate = 1,
756 		.dpcm_merged_format = 1,
757 		SND_SOC_DAILINK_REG(playback6),
758 	},
759 	[DAI_LINK_DL7_FE] = {
760 		.name = "DL7_FE",
761 		.stream_name = "DL7 Playback",
762 		.trigger = {
763 			SND_SOC_DPCM_TRIGGER_PRE,
764 			SND_SOC_DPCM_TRIGGER_PRE,
765 		},
766 		.dynamic = 1,
767 		.dpcm_playback = 1,
768 		SND_SOC_DAILINK_REG(playback7),
769 	},
770 	[DAI_LINK_DL8_FE] = {
771 		.name = "DL8_FE",
772 		.stream_name = "DL8 Playback",
773 		.trigger = {
774 			SND_SOC_DPCM_TRIGGER_POST,
775 			SND_SOC_DPCM_TRIGGER_POST,
776 		},
777 		.dynamic = 1,
778 		.dpcm_playback = 1,
779 		SND_SOC_DAILINK_REG(playback8),
780 	},
781 	[DAI_LINK_DL10_FE] = {
782 		.name = "DL10_FE",
783 		.stream_name = "DL10 Playback",
784 		.trigger = {
785 			SND_SOC_DPCM_TRIGGER_POST,
786 			SND_SOC_DPCM_TRIGGER_POST,
787 		},
788 		.dynamic = 1,
789 		.dpcm_playback = 1,
790 		SND_SOC_DAILINK_REG(playback10),
791 	},
792 	[DAI_LINK_DL11_FE] = {
793 		.name = "DL11_FE",
794 		.stream_name = "DL11 Playback",
795 		.trigger = {
796 			SND_SOC_DPCM_TRIGGER_POST,
797 			SND_SOC_DPCM_TRIGGER_POST,
798 		},
799 		.dynamic = 1,
800 		.dpcm_playback = 1,
801 		SND_SOC_DAILINK_REG(playback11),
802 	},
803 	[DAI_LINK_UL1_FE] = {
804 		.name = "UL1_FE",
805 		.stream_name = "UL1 Capture",
806 		.trigger = {
807 			SND_SOC_DPCM_TRIGGER_PRE,
808 			SND_SOC_DPCM_TRIGGER_PRE,
809 		},
810 		.dynamic = 1,
811 		.dpcm_capture = 1,
812 		SND_SOC_DAILINK_REG(capture1),
813 	},
814 	[DAI_LINK_UL2_FE] = {
815 		.name = "UL2_FE",
816 		.stream_name = "UL2 Capture",
817 		.trigger = {
818 			SND_SOC_DPCM_TRIGGER_POST,
819 			SND_SOC_DPCM_TRIGGER_POST,
820 		},
821 		.dynamic = 1,
822 		.dpcm_capture = 1,
823 		SND_SOC_DAILINK_REG(capture2),
824 	},
825 	[DAI_LINK_UL3_FE] = {
826 		.name = "UL3_FE",
827 		.stream_name = "UL3 Capture",
828 		.trigger = {
829 			SND_SOC_DPCM_TRIGGER_POST,
830 			SND_SOC_DPCM_TRIGGER_POST,
831 		},
832 		.dynamic = 1,
833 		.dpcm_capture = 1,
834 		SND_SOC_DAILINK_REG(capture3),
835 	},
836 	[DAI_LINK_UL4_FE] = {
837 		.name = "UL4_FE",
838 		.stream_name = "UL4 Capture",
839 		.trigger = {
840 			SND_SOC_DPCM_TRIGGER_POST,
841 			SND_SOC_DPCM_TRIGGER_POST,
842 		},
843 		.dynamic = 1,
844 		.dpcm_capture = 1,
845 		.dpcm_merged_chan = 1,
846 		.dpcm_merged_rate = 1,
847 		.dpcm_merged_format = 1,
848 		SND_SOC_DAILINK_REG(capture4),
849 	},
850 	[DAI_LINK_UL5_FE] = {
851 		.name = "UL5_FE",
852 		.stream_name = "UL5 Capture",
853 		.trigger = {
854 			SND_SOC_DPCM_TRIGGER_POST,
855 			SND_SOC_DPCM_TRIGGER_POST,
856 		},
857 		.dynamic = 1,
858 		.dpcm_capture = 1,
859 		.dpcm_merged_chan = 1,
860 		.dpcm_merged_rate = 1,
861 		.dpcm_merged_format = 1,
862 		SND_SOC_DAILINK_REG(capture5),
863 	},
864 	[DAI_LINK_UL6_FE] = {
865 		.name = "UL6_FE",
866 		.stream_name = "UL6 Capture",
867 		.trigger = {
868 			SND_SOC_DPCM_TRIGGER_PRE,
869 			SND_SOC_DPCM_TRIGGER_PRE,
870 		},
871 		.dynamic = 1,
872 		.dpcm_capture = 1,
873 		SND_SOC_DAILINK_REG(capture6),
874 	},
875 	[DAI_LINK_UL8_FE] = {
876 		.name = "UL8_FE",
877 		.stream_name = "UL8 Capture",
878 		.trigger = {
879 			SND_SOC_DPCM_TRIGGER_POST,
880 			SND_SOC_DPCM_TRIGGER_POST,
881 		},
882 		.dynamic = 1,
883 		.dpcm_capture = 1,
884 		SND_SOC_DAILINK_REG(capture8),
885 	},
886 	[DAI_LINK_UL9_FE] = {
887 		.name = "UL9_FE",
888 		.stream_name = "UL9 Capture",
889 		.trigger = {
890 			SND_SOC_DPCM_TRIGGER_POST,
891 			SND_SOC_DPCM_TRIGGER_POST,
892 		},
893 		.dynamic = 1,
894 		.dpcm_capture = 1,
895 		SND_SOC_DAILINK_REG(capture9),
896 	},
897 	[DAI_LINK_UL10_FE] = {
898 		.name = "UL10_FE",
899 		.stream_name = "UL10 Capture",
900 		.trigger = {
901 			SND_SOC_DPCM_TRIGGER_POST,
902 			SND_SOC_DPCM_TRIGGER_POST,
903 		},
904 		.dynamic = 1,
905 		.dpcm_capture = 1,
906 		SND_SOC_DAILINK_REG(capture10),
907 	},
908 	/* BE */
909 	[DAI_LINK_DL_SRC_BE] = {
910 		.name = "DL_SRC_BE",
911 		.no_pcm = 1,
912 		.dpcm_playback = 1,
913 		SND_SOC_DAILINK_REG(dl_src),
914 	},
915 	[DAI_LINK_DPTX_BE] = {
916 		.name = "DPTX_BE",
917 		.ops = &mt8188_dptx_ops,
918 		.be_hw_params_fixup = mt8188_dptx_hw_params_fixup,
919 		.no_pcm = 1,
920 		.dpcm_playback = 1,
921 		SND_SOC_DAILINK_REG(dptx),
922 	},
923 	[DAI_LINK_ETDM1_IN_BE] = {
924 		.name = "ETDM1_IN_BE",
925 		.no_pcm = 1,
926 		.dai_fmt = SND_SOC_DAIFMT_I2S |
927 			SND_SOC_DAIFMT_NB_NF |
928 			SND_SOC_DAIFMT_CBP_CFP,
929 		.dpcm_capture = 1,
930 		.ignore_suspend = 1,
931 		SND_SOC_DAILINK_REG(etdm1_in),
932 	},
933 	[DAI_LINK_ETDM2_IN_BE] = {
934 		.name = "ETDM2_IN_BE",
935 		.no_pcm = 1,
936 		.dai_fmt = SND_SOC_DAIFMT_I2S |
937 			SND_SOC_DAIFMT_NB_NF |
938 			SND_SOC_DAIFMT_CBP_CFP,
939 		.dpcm_capture = 1,
940 		SND_SOC_DAILINK_REG(etdm2_in),
941 	},
942 	[DAI_LINK_ETDM1_OUT_BE] = {
943 		.name = "ETDM1_OUT_BE",
944 		.no_pcm = 1,
945 		.dai_fmt = SND_SOC_DAIFMT_I2S |
946 			SND_SOC_DAIFMT_NB_NF |
947 			SND_SOC_DAIFMT_CBC_CFC,
948 		.dpcm_playback = 1,
949 		SND_SOC_DAILINK_REG(etdm1_out),
950 	},
951 	[DAI_LINK_ETDM2_OUT_BE] = {
952 		.name = "ETDM2_OUT_BE",
953 		.no_pcm = 1,
954 		.dai_fmt = SND_SOC_DAIFMT_I2S |
955 			SND_SOC_DAIFMT_NB_NF |
956 			SND_SOC_DAIFMT_CBC_CFC,
957 		.dpcm_playback = 1,
958 		SND_SOC_DAILINK_REG(etdm2_out),
959 	},
960 	[DAI_LINK_ETDM3_OUT_BE] = {
961 		.name = "ETDM3_OUT_BE",
962 		.no_pcm = 1,
963 		.dai_fmt = SND_SOC_DAIFMT_I2S |
964 			SND_SOC_DAIFMT_NB_NF |
965 			SND_SOC_DAIFMT_CBC_CFC,
966 		.dpcm_playback = 1,
967 		SND_SOC_DAILINK_REG(etdm3_out),
968 	},
969 	[DAI_LINK_PCM1_BE] = {
970 		.name = "PCM1_BE",
971 		.no_pcm = 1,
972 		.dai_fmt = SND_SOC_DAIFMT_I2S |
973 			SND_SOC_DAIFMT_NB_NF |
974 			SND_SOC_DAIFMT_CBC_CFC,
975 		.dpcm_playback = 1,
976 		.dpcm_capture = 1,
977 		SND_SOC_DAILINK_REG(pcm1),
978 	},
979 	[DAI_LINK_UL_SRC_BE] = {
980 		.name = "UL_SRC_BE",
981 		.no_pcm = 1,
982 		.dpcm_capture = 1,
983 		SND_SOC_DAILINK_REG(ul_src),
984 	},
985 };
986 
987 static void mt8188_fixup_controls(struct snd_soc_card *card)
988 {
989 	struct mt8188_mt6359_priv *priv = snd_soc_card_get_drvdata(card);
990 	struct mt8188_card_data *card_data = (struct mt8188_card_data *)priv->private_data;
991 	struct snd_kcontrol *kctl;
992 
993 	if (card_data->quirk & NAU8825_HS_PRESENT) {
994 		struct snd_soc_dapm_widget *w, *next_w;
995 
996 		for_each_card_widgets_safe(card, w, next_w) {
997 			if (strcmp(w->name, "Headphone"))
998 				continue;
999 
1000 			snd_soc_dapm_free_widget(w);
1001 		}
1002 
1003 		kctl = snd_ctl_find_id_mixer(card->snd_card, "Headphone Switch");
1004 		if (kctl)
1005 			snd_ctl_remove(card->snd_card, kctl);
1006 		else
1007 			dev_warn(card->dev, "Cannot find ctl : Headphone Switch\n");
1008 	}
1009 }
1010 
1011 static struct snd_soc_card mt8188_mt6359_soc_card = {
1012 	.owner = THIS_MODULE,
1013 	.dai_link = mt8188_mt6359_dai_links,
1014 	.num_links = ARRAY_SIZE(mt8188_mt6359_dai_links),
1015 	.dapm_widgets = mt8188_mt6359_widgets,
1016 	.num_dapm_widgets = ARRAY_SIZE(mt8188_mt6359_widgets),
1017 	.controls = mt8188_mt6359_controls,
1018 	.num_controls = ARRAY_SIZE(mt8188_mt6359_controls),
1019 	.fixup_controls = mt8188_fixup_controls,
1020 };
1021 
1022 static int mt8188_mt6359_dev_probe(struct platform_device *pdev)
1023 {
1024 	struct snd_soc_card *card = &mt8188_mt6359_soc_card;
1025 	struct device_node *platform_node;
1026 	struct mt8188_mt6359_priv *priv;
1027 	struct mt8188_card_data *card_data;
1028 	struct snd_soc_dai_link *dai_link;
1029 	bool init_mt6359 = false;
1030 	bool init_nau8825 = false;
1031 	bool init_max98390 = false;
1032 	bool init_dumb = false;
1033 	int ret, i;
1034 
1035 	card_data = (struct mt8188_card_data *)of_device_get_match_data(&pdev->dev);
1036 	card->dev = &pdev->dev;
1037 
1038 	ret = snd_soc_of_parse_card_name(card, "model");
1039 	if (ret)
1040 		return dev_err_probe(&pdev->dev, ret, "%s new card name parsing error\n",
1041 				     __func__);
1042 
1043 	if (!card->name)
1044 		card->name = card_data->name;
1045 
1046 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
1047 	if (!priv)
1048 		return  -ENOMEM;
1049 
1050 	if (of_property_read_bool(pdev->dev.of_node, "audio-routing")) {
1051 		ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
1052 		if (ret)
1053 			return ret;
1054 	}
1055 
1056 	platform_node = of_parse_phandle(pdev->dev.of_node,
1057 					 "mediatek,platform", 0);
1058 	if (!platform_node) {
1059 		ret = -EINVAL;
1060 		return dev_err_probe(&pdev->dev, ret, "Property 'platform' missing or invalid\n");
1061 	}
1062 
1063 	ret = parse_dai_link_info(card);
1064 	if (ret)
1065 		goto err;
1066 
1067 	for_each_card_prelinks(card, i, dai_link) {
1068 		if (!dai_link->platforms->name)
1069 			dai_link->platforms->of_node = platform_node;
1070 
1071 		if (strcmp(dai_link->name, "DPTX_BE") == 0) {
1072 			if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))
1073 				dai_link->init = mt8188_dptx_codec_init;
1074 		} else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) {
1075 			if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))
1076 				dai_link->init = mt8188_hdmi_codec_init;
1077 		} else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 ||
1078 			   strcmp(dai_link->name, "UL_SRC_BE") == 0) {
1079 			if (!init_mt6359) {
1080 				dai_link->init = mt8188_mt6359_init;
1081 				init_mt6359 = true;
1082 			}
1083 		} else if (strcmp(dai_link->name, "ETDM1_OUT_BE") == 0 ||
1084 			   strcmp(dai_link->name, "ETDM2_OUT_BE") == 0 ||
1085 			   strcmp(dai_link->name, "ETDM1_IN_BE") == 0 ||
1086 			   strcmp(dai_link->name, "ETDM2_IN_BE") == 0) {
1087 			if (!strcmp(dai_link->codecs->dai_name, MAX98390_CODEC_DAI)) {
1088 				dai_link->ops = &mt8188_max98390_ops;
1089 				if (!init_max98390) {
1090 					dai_link->init = mt8188_max98390_codec_init;
1091 					init_max98390 = true;
1092 				}
1093 			} else if (!strcmp(dai_link->codecs->dai_name, NAU8825_CODEC_DAI)) {
1094 				dai_link->ops = &mt8188_nau8825_ops;
1095 				if (!init_nau8825) {
1096 					dai_link->init = mt8188_nau8825_codec_init;
1097 					dai_link->exit = mt8188_nau8825_codec_exit;
1098 					init_nau8825 = true;
1099 				}
1100 			} else {
1101 				if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) {
1102 					if (!init_dumb) {
1103 						dai_link->init = mt8188_dumb_amp_init;
1104 						init_dumb = true;
1105 					}
1106 				}
1107 			}
1108 		}
1109 	}
1110 
1111 	priv->private_data = card_data;
1112 	snd_soc_card_set_drvdata(card, priv);
1113 
1114 	ret = devm_snd_soc_register_card(&pdev->dev, card);
1115 	if (ret)
1116 		dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n",
1117 			      __func__);
1118 err:
1119 	of_node_put(platform_node);
1120 	clean_card_reference(card);
1121 	return ret;
1122 }
1123 
1124 static struct mt8188_card_data mt8188_evb_card = {
1125 	.name = "mt8188_mt6359",
1126 };
1127 
1128 static struct mt8188_card_data mt8188_nau8825_card = {
1129 	.name = "mt8188_nau8825",
1130 	.quirk = NAU8825_HS_PRESENT,
1131 };
1132 
1133 static const struct of_device_id mt8188_mt6359_dt_match[] = {
1134 	{ .compatible = "mediatek,mt8188-mt6359-evb", .data = &mt8188_evb_card, },
1135 	{ .compatible = "mediatek,mt8188-nau8825", .data = &mt8188_nau8825_card, },
1136 	{ /* sentinel */ },
1137 };
1138 MODULE_DEVICE_TABLE(of, mt8188_mt6359_dt_match);
1139 
1140 static struct platform_driver mt8188_mt6359_driver = {
1141 	.driver = {
1142 		.name = "mt8188_mt6359",
1143 		.of_match_table = mt8188_mt6359_dt_match,
1144 		.pm = &snd_soc_pm_ops,
1145 	},
1146 	.probe = mt8188_mt6359_dev_probe,
1147 };
1148 
1149 module_platform_driver(mt8188_mt6359_driver);
1150 
1151 /* Module information */
1152 MODULE_DESCRIPTION("MT8188-MT6359 ALSA SoC machine driver");
1153 MODULE_AUTHOR("Trevor Wu <trevor.wu@mediatek.com>");
1154 MODULE_LICENSE("GPL");
1155 MODULE_ALIAS("mt8188 mt6359 soc card");
1156