1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // mt8186-mt6366-da7219-max98357.c
4 //	--  MT8186-MT6366-DA7219-MAX98357 ALSA SoC machine driver
5 //
6 // Copyright (c) 2022 MediaTek Inc.
7 // Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
8 //
9 
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 
18 #include "../../codecs/da7219.h"
19 #include "../../codecs/mt6358.h"
20 #include "../common/mtk-afe-platform-driver.h"
21 #include "../common/mtk-dsp-sof-common.h"
22 #include "../common/mtk-soc-card.h"
23 #include "mt8186-afe-common.h"
24 #include "mt8186-afe-clk.h"
25 #include "mt8186-afe-gpio.h"
26 #include "mt8186-mt6366-common.h"
27 
28 #define DA7219_CODEC_DAI "da7219-hifi"
29 #define DA7219_DEV_NAME "da7219.5-001a"
30 
31 #define SOF_DMA_DL1 "SOF_DMA_DL1"
32 #define SOF_DMA_DL2 "SOF_DMA_DL2"
33 #define SOF_DMA_UL1 "SOF_DMA_UL1"
34 #define SOF_DMA_UL2 "SOF_DMA_UL2"
35 
36 struct mt8186_mt6366_da7219_max98357_priv {
37 	struct snd_soc_jack headset_jack, hdmi_jack;
38 };
39 
40 /* Headset jack detection DAPM pins */
41 static struct snd_soc_jack_pin mt8186_jack_pins[] = {
42 	{
43 		.pin = "Headphones",
44 		.mask = SND_JACK_HEADPHONE,
45 	},
46 	{
47 		.pin = "Headset Mic",
48 		.mask = SND_JACK_MICROPHONE,
49 	},
50 };
51 
52 static struct snd_soc_codec_conf mt8186_mt6366_da7219_max98357_codec_conf[] = {
53 	{
54 		.dlc = COMP_CODEC_CONF("mt6358-sound"),
55 		.name_prefix = "Mt6366",
56 	},
57 	{
58 		.dlc = COMP_CODEC_CONF("bt-sco"),
59 		.name_prefix = "Mt8186 bt",
60 	},
61 	{
62 		.dlc = COMP_CODEC_CONF("hdmi-audio-codec"),
63 		.name_prefix = "Mt8186 hdmi",
64 	},
65 };
66 
67 static int mt8186_da7219_init(struct snd_soc_pcm_runtime *rtd)
68 {
69 	struct snd_soc_component *cmpnt_afe =
70 		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
71 	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
72 	struct mtk_soc_card_data *soc_card_data =
73 		snd_soc_card_get_drvdata(rtd->card);
74 	struct mt8186_mt6366_da7219_max98357_priv *priv = soc_card_data->mach_priv;
75 	struct snd_soc_jack *jack = &priv->headset_jack;
76 	struct snd_soc_component *cmpnt_codec =
77 		asoc_rtd_to_codec(rtd, 0)->component;
78 	int ret;
79 
80 	ret = mt8186_dai_i2s_set_share(afe, "I2S1", "I2S0");
81 	if (ret) {
82 		dev_err(rtd->dev, "Failed to set up shared clocks\n");
83 		return ret;
84 	}
85 
86 	/* Enable Headset and 4 Buttons Jack detection */
87 	ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
88 				    SND_JACK_HEADSET | SND_JACK_BTN_0 |
89 				    SND_JACK_BTN_1 | SND_JACK_BTN_2 |
90 				    SND_JACK_BTN_3 | SND_JACK_LINEOUT,
91 				    jack, mt8186_jack_pins,
92 				    ARRAY_SIZE(mt8186_jack_pins));
93 	if (ret) {
94 		dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
95 		return ret;
96 	}
97 
98 	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
99 	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
100 	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
101 	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
102 
103 	snd_soc_component_set_jack(cmpnt_codec, &priv->headset_jack, NULL);
104 
105 	return 0;
106 }
107 
108 static int mt8186_da7219_i2s_hw_params(struct snd_pcm_substream *substream,
109 				       struct snd_pcm_hw_params *params)
110 {
111 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
112 	struct snd_soc_dai *codec_dai;
113 	unsigned int rate = params_rate(params);
114 	unsigned int mclk_fs_ratio = 256;
115 	unsigned int mclk_fs = rate * mclk_fs_ratio;
116 	unsigned int freq;
117 	int ret, j;
118 
119 	ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0,
120 				     mclk_fs, SND_SOC_CLOCK_OUT);
121 	if (ret < 0) {
122 		dev_err(rtd->dev, "failed to set cpu dai sysclk: %d\n", ret);
123 		return ret;
124 	}
125 
126 	for_each_rtd_codec_dais(rtd, j, codec_dai) {
127 		if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
128 			ret = snd_soc_dai_set_sysclk(codec_dai,
129 						     DA7219_CLKSRC_MCLK,
130 						     mclk_fs,
131 						     SND_SOC_CLOCK_IN);
132 			if (ret < 0) {
133 				dev_err(rtd->dev, "failed to set sysclk: %d\n",
134 					ret);
135 				return ret;
136 			}
137 
138 			if ((rate % 8000) == 0)
139 				freq = DA7219_PLL_FREQ_OUT_98304;
140 			else
141 				freq = DA7219_PLL_FREQ_OUT_90316;
142 
143 			ret = snd_soc_dai_set_pll(codec_dai, 0,
144 						  DA7219_SYSCLK_PLL_SRM,
145 						  0, freq);
146 			if (ret) {
147 				dev_err(rtd->dev, "failed to start PLL: %d\n",
148 					ret);
149 				return ret;
150 			}
151 		}
152 	}
153 
154 	return 0;
155 }
156 
157 static int mt8186_da7219_i2s_hw_free(struct snd_pcm_substream *substream)
158 {
159 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
160 	struct snd_soc_dai *codec_dai;
161 	int ret = 0, j;
162 
163 	for_each_rtd_codec_dais(rtd, j, codec_dai) {
164 		if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
165 			ret = snd_soc_dai_set_pll(codec_dai,
166 						  0, DA7219_SYSCLK_MCLK, 0, 0);
167 			if (ret < 0) {
168 				dev_err(rtd->dev, "failed to stop PLL: %d\n",
169 					ret);
170 				return ret;
171 			}
172 		}
173 	}
174 
175 	return 0;
176 }
177 
178 static const struct snd_soc_ops mt8186_da7219_i2s_ops = {
179 	.hw_params = mt8186_da7219_i2s_hw_params,
180 	.hw_free = mt8186_da7219_i2s_hw_free,
181 };
182 
183 static int mt8186_mt6366_da7219_max98357_hdmi_init(struct snd_soc_pcm_runtime *rtd)
184 {
185 	struct snd_soc_component *cmpnt_afe =
186 		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
187 	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
188 	struct snd_soc_component *cmpnt_codec =
189 		asoc_rtd_to_codec(rtd, 0)->component;
190 	struct mtk_soc_card_data *soc_card_data =
191 		snd_soc_card_get_drvdata(rtd->card);
192 	struct mt8186_mt6366_da7219_max98357_priv *priv = soc_card_data->mach_priv;
193 	int ret;
194 
195 	ret = mt8186_dai_i2s_set_share(afe, "I2S2", "I2S3");
196 	if (ret) {
197 		dev_err(rtd->dev, "Failed to set up shared clocks\n");
198 		return ret;
199 	}
200 
201 	ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, &priv->hdmi_jack);
202 	if (ret) {
203 		dev_err(rtd->dev, "HDMI Jack creation failed: %d\n", ret);
204 		return ret;
205 	}
206 
207 	return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL);
208 }
209 
210 static int mt8186_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
211 				  struct snd_pcm_hw_params *params,
212 				  snd_pcm_format_t fmt)
213 {
214 	struct snd_interval *channels = hw_param_interval(params,
215 		SNDRV_PCM_HW_PARAM_CHANNELS);
216 
217 	dev_dbg(rtd->dev, "%s(), fix format to %d\n", __func__, fmt);
218 
219 	/* fix BE i2s channel to 2 channel */
220 	channels->min = 2;
221 	channels->max = 2;
222 
223 	/* clean param mask first */
224 	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
225 			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
226 
227 	params_set_format(params, fmt);
228 
229 	return 0;
230 }
231 
232 static int mt8186_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
233 				      struct snd_pcm_hw_params *params)
234 {
235 	return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S32_LE);
236 }
237 
238 static int mt8186_anx7625_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
239 					      struct snd_pcm_hw_params *params)
240 {
241 	return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S24_LE);
242 }
243 
244 /* fixup the BE DAI link to match any values from topology */
245 static int mt8186_sof_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
246 				     struct snd_pcm_hw_params *params)
247 {
248 	int ret;
249 
250 	ret = mtk_sof_dai_link_fixup(rtd, params);
251 
252 	if (!strcmp(rtd->dai_link->name, "I2S0") ||
253 	    !strcmp(rtd->dai_link->name, "I2S1") ||
254 	    !strcmp(rtd->dai_link->name, "I2S2"))
255 		mt8186_i2s_hw_params_fixup(rtd, params);
256 	else if (!strcmp(rtd->dai_link->name, "I2S3"))
257 		mt8186_anx7625_i2s_hw_params_fixup(rtd, params);
258 
259 	return ret;
260 }
261 
262 static int mt8186_mt6366_da7219_max98357_playback_startup(struct snd_pcm_substream *substream)
263 {
264 	static const unsigned int rates[] = {
265 		48000
266 	};
267 	static const unsigned int channels[] = {
268 		2
269 	};
270 	static const struct snd_pcm_hw_constraint_list constraints_rates = {
271 		.count = ARRAY_SIZE(rates),
272 		.list  = rates,
273 		.mask = 0,
274 	};
275 	static const struct snd_pcm_hw_constraint_list constraints_channels = {
276 		.count = ARRAY_SIZE(channels),
277 		.list  = channels,
278 		.mask = 0,
279 	};
280 
281 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
282 	struct snd_pcm_runtime *runtime = substream->runtime;
283 	int ret;
284 
285 	ret = snd_pcm_hw_constraint_list(runtime, 0,
286 					 SNDRV_PCM_HW_PARAM_RATE,
287 					 &constraints_rates);
288 	if (ret < 0) {
289 		dev_err(rtd->dev, "hw_constraint_list rate failed\n");
290 		return ret;
291 	}
292 
293 	ret = snd_pcm_hw_constraint_list(runtime, 0,
294 					 SNDRV_PCM_HW_PARAM_CHANNELS,
295 					 &constraints_channels);
296 	if (ret < 0) {
297 		dev_err(rtd->dev, "hw_constraint_list channel failed\n");
298 		return ret;
299 	}
300 
301 	return 0;
302 }
303 
304 static const struct snd_soc_ops mt8186_mt6366_da7219_max98357_playback_ops = {
305 	.startup = mt8186_mt6366_da7219_max98357_playback_startup,
306 };
307 
308 static int mt8186_mt6366_da7219_max98357_capture_startup(struct snd_pcm_substream *substream)
309 {
310 	static const unsigned int rates[] = {
311 		48000
312 	};
313 	static const unsigned int channels[] = {
314 		1, 2
315 	};
316 	static const struct snd_pcm_hw_constraint_list constraints_rates = {
317 		.count = ARRAY_SIZE(rates),
318 		.list  = rates,
319 		.mask = 0,
320 	};
321 	static const struct snd_pcm_hw_constraint_list constraints_channels = {
322 		.count = ARRAY_SIZE(channels),
323 		.list  = channels,
324 		.mask = 0,
325 	};
326 
327 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
328 	struct snd_pcm_runtime *runtime = substream->runtime;
329 	int ret;
330 
331 	ret = snd_pcm_hw_constraint_list(runtime, 0,
332 					 SNDRV_PCM_HW_PARAM_RATE,
333 					 &constraints_rates);
334 	if (ret < 0) {
335 		dev_err(rtd->dev, "hw_constraint_list rate failed\n");
336 		return ret;
337 	}
338 
339 	ret = snd_pcm_hw_constraint_list(runtime, 0,
340 					 SNDRV_PCM_HW_PARAM_CHANNELS,
341 					 &constraints_channels);
342 	if (ret < 0) {
343 		dev_err(rtd->dev, "hw_constraint_list channel failed\n");
344 		return ret;
345 	}
346 
347 	return 0;
348 }
349 
350 static const struct snd_soc_ops mt8186_mt6366_da7219_max98357_capture_ops = {
351 	.startup = mt8186_mt6366_da7219_max98357_capture_startup,
352 };
353 
354 /* FE */
355 SND_SOC_DAILINK_DEFS(playback1,
356 		     DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
357 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
358 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
359 
360 SND_SOC_DAILINK_DEFS(playback12,
361 		     DAILINK_COMP_ARRAY(COMP_CPU("DL12")),
362 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
363 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
364 
365 SND_SOC_DAILINK_DEFS(playback2,
366 		     DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
367 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
368 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
369 
370 SND_SOC_DAILINK_DEFS(playback3,
371 		     DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
372 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
373 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
374 
375 SND_SOC_DAILINK_DEFS(playback4,
376 		     DAILINK_COMP_ARRAY(COMP_CPU("DL4")),
377 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
378 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
379 
380 SND_SOC_DAILINK_DEFS(playback5,
381 		     DAILINK_COMP_ARRAY(COMP_CPU("DL5")),
382 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
383 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
384 
385 SND_SOC_DAILINK_DEFS(playback6,
386 		     DAILINK_COMP_ARRAY(COMP_CPU("DL6")),
387 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
388 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
389 
390 SND_SOC_DAILINK_DEFS(playback7,
391 		     DAILINK_COMP_ARRAY(COMP_CPU("DL7")),
392 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
393 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
394 
395 SND_SOC_DAILINK_DEFS(playback8,
396 		     DAILINK_COMP_ARRAY(COMP_CPU("DL8")),
397 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
398 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
399 
400 SND_SOC_DAILINK_DEFS(capture1,
401 		     DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
402 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
403 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
404 
405 SND_SOC_DAILINK_DEFS(capture2,
406 		     DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
407 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
408 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
409 
410 SND_SOC_DAILINK_DEFS(capture3,
411 		     DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
412 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
413 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
414 
415 SND_SOC_DAILINK_DEFS(capture4,
416 		     DAILINK_COMP_ARRAY(COMP_CPU("UL4")),
417 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
418 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
419 
420 SND_SOC_DAILINK_DEFS(capture5,
421 		     DAILINK_COMP_ARRAY(COMP_CPU("UL5")),
422 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
423 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
424 
425 SND_SOC_DAILINK_DEFS(capture6,
426 		     DAILINK_COMP_ARRAY(COMP_CPU("UL6")),
427 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
428 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
429 
430 SND_SOC_DAILINK_DEFS(capture7,
431 		     DAILINK_COMP_ARRAY(COMP_CPU("UL7")),
432 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
433 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
434 
435 /* hostless */
436 SND_SOC_DAILINK_DEFS(hostless_lpbk,
437 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless LPBK DAI")),
438 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
439 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
440 SND_SOC_DAILINK_DEFS(hostless_fm,
441 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless FM DAI")),
442 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
443 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
444 SND_SOC_DAILINK_DEFS(hostless_src1,
445 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_SRC_1_DAI")),
446 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
447 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
448 SND_SOC_DAILINK_DEFS(hostless_src_bargein,
449 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_SRC_Bargein_DAI")),
450 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
451 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
452 
453 /* BE */
454 SND_SOC_DAILINK_DEFS(adda,
455 		     DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
456 		     DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound",
457 						   "mt6358-snd-codec-aif1"),
458 					COMP_CODEC("dmic-codec",
459 						   "dmic-hifi")),
460 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
461 SND_SOC_DAILINK_DEFS(i2s0,
462 		     DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
463 		     DAILINK_COMP_ARRAY(COMP_EMPTY()),
464 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
465 SND_SOC_DAILINK_DEFS(i2s1,
466 		     DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
467 		     DAILINK_COMP_ARRAY(COMP_EMPTY()),
468 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
469 SND_SOC_DAILINK_DEFS(i2s2,
470 		     DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
471 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
472 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
473 SND_SOC_DAILINK_DEFS(i2s3,
474 		     DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
475 		     DAILINK_COMP_ARRAY(COMP_EMPTY()),
476 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
477 SND_SOC_DAILINK_DEFS(hw_gain1,
478 		     DAILINK_COMP_ARRAY(COMP_CPU("HW Gain 1")),
479 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
480 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
481 SND_SOC_DAILINK_DEFS(hw_gain2,
482 		     DAILINK_COMP_ARRAY(COMP_CPU("HW Gain 2")),
483 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
484 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
485 SND_SOC_DAILINK_DEFS(hw_src1,
486 		     DAILINK_COMP_ARRAY(COMP_CPU("HW_SRC_1")),
487 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
488 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
489 SND_SOC_DAILINK_DEFS(hw_src2,
490 		     DAILINK_COMP_ARRAY(COMP_CPU("HW_SRC_2")),
491 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
492 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
493 SND_SOC_DAILINK_DEFS(connsys_i2s,
494 		     DAILINK_COMP_ARRAY(COMP_CPU("CONNSYS_I2S")),
495 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
496 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
497 SND_SOC_DAILINK_DEFS(pcm1,
498 		     DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
499 		     DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm-wb")),
500 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
501 SND_SOC_DAILINK_DEFS(tdm_in,
502 		     DAILINK_COMP_ARRAY(COMP_CPU("TDM IN")),
503 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
504 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
505 
506 /* hostless */
507 SND_SOC_DAILINK_DEFS(hostless_ul1,
508 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL1 DAI")),
509 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
510 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
511 SND_SOC_DAILINK_DEFS(hostless_ul2,
512 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL2 DAI")),
513 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
514 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
515 SND_SOC_DAILINK_DEFS(hostless_ul3,
516 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL3 DAI")),
517 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
518 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
519 SND_SOC_DAILINK_DEFS(hostless_ul5,
520 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL5 DAI")),
521 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
522 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
523 SND_SOC_DAILINK_DEFS(hostless_ul6,
524 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL6 DAI")),
525 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
526 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
527 SND_SOC_DAILINK_DEFS(hostless_hw_gain_aaudio,
528 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless HW Gain AAudio DAI")),
529 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
530 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
531 SND_SOC_DAILINK_DEFS(hostless_src_aaudio,
532 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless SRC AAudio DAI")),
533 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
534 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
535 SND_SOC_DAILINK_DEFS(AFE_SOF_DL1,
536 		     DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL1")),
537 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
538 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
539 
540 SND_SOC_DAILINK_DEFS(AFE_SOF_DL2,
541 		     DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL2")),
542 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
543 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
544 
545 SND_SOC_DAILINK_DEFS(AFE_SOF_UL1,
546 		     DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL1")),
547 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
548 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
549 
550 SND_SOC_DAILINK_DEFS(AFE_SOF_UL2,
551 		     DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL2")),
552 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
553 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
554 
555 static const struct sof_conn_stream g_sof_conn_streams[] = {
556 	{ "I2S1", "AFE_SOF_DL1", SOF_DMA_DL1, SNDRV_PCM_STREAM_PLAYBACK},
557 	{ "I2S3", "AFE_SOF_DL2", SOF_DMA_DL2, SNDRV_PCM_STREAM_PLAYBACK},
558 	{ "Primary Codec", "AFE_SOF_UL1", SOF_DMA_UL1, SNDRV_PCM_STREAM_CAPTURE},
559 	{ "I2S0", "AFE_SOF_UL2", SOF_DMA_UL2, SNDRV_PCM_STREAM_CAPTURE},
560 };
561 
562 static struct snd_soc_dai_link mt8186_mt6366_da7219_max98357_dai_links[] = {
563 	/* Front End DAI links */
564 	{
565 		.name = "Playback_1",
566 		.stream_name = "Playback_1",
567 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
568 			    SND_SOC_DPCM_TRIGGER_PRE},
569 		.dynamic = 1,
570 		.dpcm_playback = 1,
571 		.dpcm_merged_format = 1,
572 		.dpcm_merged_chan = 1,
573 		.dpcm_merged_rate = 1,
574 		.ops = &mt8186_mt6366_da7219_max98357_playback_ops,
575 		SND_SOC_DAILINK_REG(playback1),
576 	},
577 	{
578 		.name = "Playback_12",
579 		.stream_name = "Playback_12",
580 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
581 			    SND_SOC_DPCM_TRIGGER_PRE},
582 		.dynamic = 1,
583 		.dpcm_playback = 1,
584 		SND_SOC_DAILINK_REG(playback12),
585 	},
586 	{
587 		.name = "Playback_2",
588 		.stream_name = "Playback_2",
589 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
590 			    SND_SOC_DPCM_TRIGGER_PRE},
591 		.dynamic = 1,
592 		.dpcm_playback = 1,
593 		.dpcm_merged_format = 1,
594 		.dpcm_merged_chan = 1,
595 		.dpcm_merged_rate = 1,
596 		SND_SOC_DAILINK_REG(playback2),
597 	},
598 	{
599 		.name = "Playback_3",
600 		.stream_name = "Playback_3",
601 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
602 			    SND_SOC_DPCM_TRIGGER_PRE},
603 		.dynamic = 1,
604 		.dpcm_playback = 1,
605 		.dpcm_merged_format = 1,
606 		.dpcm_merged_chan = 1,
607 		.dpcm_merged_rate = 1,
608 		.ops = &mt8186_mt6366_da7219_max98357_playback_ops,
609 		SND_SOC_DAILINK_REG(playback3),
610 	},
611 	{
612 		.name = "Playback_4",
613 		.stream_name = "Playback_4",
614 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
615 			    SND_SOC_DPCM_TRIGGER_PRE},
616 		.dynamic = 1,
617 		.dpcm_playback = 1,
618 		SND_SOC_DAILINK_REG(playback4),
619 	},
620 	{
621 		.name = "Playback_5",
622 		.stream_name = "Playback_5",
623 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
624 			    SND_SOC_DPCM_TRIGGER_PRE},
625 		.dynamic = 1,
626 		.dpcm_playback = 1,
627 		SND_SOC_DAILINK_REG(playback5),
628 	},
629 	{
630 		.name = "Playback_6",
631 		.stream_name = "Playback_6",
632 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
633 			    SND_SOC_DPCM_TRIGGER_PRE},
634 		.dynamic = 1,
635 		.dpcm_playback = 1,
636 		SND_SOC_DAILINK_REG(playback6),
637 	},
638 	{
639 		.name = "Playback_7",
640 		.stream_name = "Playback_7",
641 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
642 			    SND_SOC_DPCM_TRIGGER_PRE},
643 		.dynamic = 1,
644 		.dpcm_playback = 1,
645 		SND_SOC_DAILINK_REG(playback7),
646 	},
647 	{
648 		.name = "Playback_8",
649 		.stream_name = "Playback_8",
650 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
651 			    SND_SOC_DPCM_TRIGGER_PRE},
652 		.dynamic = 1,
653 		.dpcm_playback = 1,
654 		SND_SOC_DAILINK_REG(playback8),
655 	},
656 	{
657 		.name = "Capture_1",
658 		.stream_name = "Capture_1",
659 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
660 			    SND_SOC_DPCM_TRIGGER_PRE},
661 		.dynamic = 1,
662 		.dpcm_capture = 1,
663 		SND_SOC_DAILINK_REG(capture1),
664 	},
665 	{
666 		.name = "Capture_2",
667 		.stream_name = "Capture_2",
668 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
669 			    SND_SOC_DPCM_TRIGGER_PRE},
670 		.dynamic = 1,
671 		.dpcm_capture = 1,
672 		.dpcm_merged_format = 1,
673 		.dpcm_merged_chan = 1,
674 		.dpcm_merged_rate = 1,
675 		.ops = &mt8186_mt6366_da7219_max98357_capture_ops,
676 		SND_SOC_DAILINK_REG(capture2),
677 	},
678 	{
679 		.name = "Capture_3",
680 		.stream_name = "Capture_3",
681 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
682 			    SND_SOC_DPCM_TRIGGER_PRE},
683 		.dynamic = 1,
684 		.dpcm_capture = 1,
685 		SND_SOC_DAILINK_REG(capture3),
686 	},
687 	{
688 		.name = "Capture_4",
689 		.stream_name = "Capture_4",
690 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
691 			    SND_SOC_DPCM_TRIGGER_PRE},
692 		.dynamic = 1,
693 		.dpcm_capture = 1,
694 		.dpcm_merged_format = 1,
695 		.dpcm_merged_chan = 1,
696 		.dpcm_merged_rate = 1,
697 		.ops = &mt8186_mt6366_da7219_max98357_capture_ops,
698 		SND_SOC_DAILINK_REG(capture4),
699 	},
700 	{
701 		.name = "Capture_5",
702 		.stream_name = "Capture_5",
703 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
704 			    SND_SOC_DPCM_TRIGGER_PRE},
705 		.dynamic = 1,
706 		.dpcm_capture = 1,
707 		SND_SOC_DAILINK_REG(capture5),
708 	},
709 	{
710 		.name = "Capture_6",
711 		.stream_name = "Capture_6",
712 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
713 			    SND_SOC_DPCM_TRIGGER_PRE},
714 		.dynamic = 1,
715 		.dpcm_capture = 1,
716 		.dpcm_merged_format = 1,
717 		.dpcm_merged_chan = 1,
718 		.dpcm_merged_rate = 1,
719 		SND_SOC_DAILINK_REG(capture6),
720 	},
721 	{
722 		.name = "Capture_7",
723 		.stream_name = "Capture_7",
724 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
725 			    SND_SOC_DPCM_TRIGGER_PRE},
726 		.dynamic = 1,
727 		.dpcm_capture = 1,
728 		SND_SOC_DAILINK_REG(capture7),
729 	},
730 	{
731 		.name = "Hostless_LPBK",
732 		.stream_name = "Hostless_LPBK",
733 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
734 			    SND_SOC_DPCM_TRIGGER_PRE},
735 		.dynamic = 1,
736 		.dpcm_playback = 1,
737 		.dpcm_capture = 1,
738 		.ignore_suspend = 1,
739 		SND_SOC_DAILINK_REG(hostless_lpbk),
740 	},
741 	{
742 		.name = "Hostless_FM",
743 		.stream_name = "Hostless_FM",
744 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
745 			    SND_SOC_DPCM_TRIGGER_PRE},
746 		.dynamic = 1,
747 		.dpcm_playback = 1,
748 		.dpcm_capture = 1,
749 		.ignore_suspend = 1,
750 		SND_SOC_DAILINK_REG(hostless_fm),
751 	},
752 	{
753 		.name = "Hostless_SRC_1",
754 		.stream_name = "Hostless_SRC_1",
755 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
756 			    SND_SOC_DPCM_TRIGGER_PRE},
757 		.dynamic = 1,
758 		.dpcm_playback = 1,
759 		.dpcm_capture = 1,
760 		.ignore_suspend = 1,
761 		SND_SOC_DAILINK_REG(hostless_src1),
762 	},
763 	{
764 		.name = "Hostless_SRC_Bargein",
765 		.stream_name = "Hostless_SRC_Bargein",
766 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
767 			    SND_SOC_DPCM_TRIGGER_PRE},
768 		.dynamic = 1,
769 		.dpcm_playback = 1,
770 		.dpcm_capture = 1,
771 		.ignore_suspend = 1,
772 		SND_SOC_DAILINK_REG(hostless_src_bargein),
773 	},
774 	{
775 		.name = "Hostless_HW_Gain_AAudio",
776 		.stream_name = "Hostless_HW_Gain_AAudio",
777 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
778 			    SND_SOC_DPCM_TRIGGER_PRE},
779 		.dynamic = 1,
780 		.dpcm_capture = 1,
781 		.ignore_suspend = 1,
782 		SND_SOC_DAILINK_REG(hostless_hw_gain_aaudio),
783 	},
784 	{
785 		.name = "Hostless_SRC_AAudio",
786 		.stream_name = "Hostless_SRC_AAudio",
787 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
788 			    SND_SOC_DPCM_TRIGGER_PRE},
789 		.dynamic = 1,
790 		.dpcm_playback = 1,
791 		.dpcm_capture = 1,
792 		.ignore_suspend = 1,
793 		SND_SOC_DAILINK_REG(hostless_src_aaudio),
794 	},
795 	/* Back End DAI links */
796 	{
797 		.name = "Primary Codec",
798 		.no_pcm = 1,
799 		.dpcm_playback = 1,
800 		.dpcm_capture = 1,
801 		.ignore_suspend = 1,
802 		.init = mt8186_mt6366_init,
803 		SND_SOC_DAILINK_REG(adda),
804 	},
805 	{
806 		.name = "I2S3",
807 		.no_pcm = 1,
808 		.dai_fmt = SND_SOC_DAIFMT_I2S |
809 			   SND_SOC_DAIFMT_IB_IF |
810 			   SND_SOC_DAIFMT_CBM_CFM,
811 		.dpcm_playback = 1,
812 		.ignore_suspend = 1,
813 		.init = mt8186_mt6366_da7219_max98357_hdmi_init,
814 		.be_hw_params_fixup = mt8186_anx7625_i2s_hw_params_fixup,
815 		SND_SOC_DAILINK_REG(i2s3),
816 	},
817 	{
818 		.name = "I2S0",
819 		.no_pcm = 1,
820 		.dpcm_capture = 1,
821 		.ignore_suspend = 1,
822 		.be_hw_params_fixup = mt8186_i2s_hw_params_fixup,
823 		.ops = &mt8186_da7219_i2s_ops,
824 		SND_SOC_DAILINK_REG(i2s0),
825 	},
826 	{
827 		.name = "I2S1",
828 		.no_pcm = 1,
829 		.dpcm_playback = 1,
830 		.ignore_suspend = 1,
831 		.be_hw_params_fixup = mt8186_i2s_hw_params_fixup,
832 		.init = mt8186_da7219_init,
833 		.ops = &mt8186_da7219_i2s_ops,
834 		SND_SOC_DAILINK_REG(i2s1),
835 	},
836 	{
837 		.name = "I2S2",
838 		.no_pcm = 1,
839 		.dpcm_capture = 1,
840 		.ignore_suspend = 1,
841 		.be_hw_params_fixup = mt8186_i2s_hw_params_fixup,
842 		SND_SOC_DAILINK_REG(i2s2),
843 	},
844 	{
845 		.name = "HW Gain 1",
846 		.no_pcm = 1,
847 		.dpcm_playback = 1,
848 		.dpcm_capture = 1,
849 		.ignore_suspend = 1,
850 		SND_SOC_DAILINK_REG(hw_gain1),
851 	},
852 	{
853 		.name = "HW Gain 2",
854 		.no_pcm = 1,
855 		.dpcm_playback = 1,
856 		.dpcm_capture = 1,
857 		.ignore_suspend = 1,
858 		SND_SOC_DAILINK_REG(hw_gain2),
859 	},
860 	{
861 		.name = "HW_SRC_1",
862 		.no_pcm = 1,
863 		.dpcm_playback = 1,
864 		.dpcm_capture = 1,
865 		.ignore_suspend = 1,
866 		SND_SOC_DAILINK_REG(hw_src1),
867 	},
868 	{
869 		.name = "HW_SRC_2",
870 		.no_pcm = 1,
871 		.dpcm_playback = 1,
872 		.dpcm_capture = 1,
873 		.ignore_suspend = 1,
874 		SND_SOC_DAILINK_REG(hw_src2),
875 	},
876 	{
877 		.name = "CONNSYS_I2S",
878 		.no_pcm = 1,
879 		.dpcm_capture = 1,
880 		.ignore_suspend = 1,
881 		SND_SOC_DAILINK_REG(connsys_i2s),
882 	},
883 	{
884 		.name = "PCM 1",
885 		.dai_fmt = SND_SOC_DAIFMT_I2S |
886 			   SND_SOC_DAIFMT_NB_IF,
887 		.no_pcm = 1,
888 		.dpcm_playback = 1,
889 		.dpcm_capture = 1,
890 		.ignore_suspend = 1,
891 		SND_SOC_DAILINK_REG(pcm1),
892 	},
893 	{
894 		.name = "TDM IN",
895 		.no_pcm = 1,
896 		.dpcm_capture = 1,
897 		.ignore_suspend = 1,
898 		SND_SOC_DAILINK_REG(tdm_in),
899 	},
900 	/* dummy BE for ul memif to record from dl memif */
901 	{
902 		.name = "Hostless_UL1",
903 		.no_pcm = 1,
904 		.dpcm_capture = 1,
905 		.ignore_suspend = 1,
906 		SND_SOC_DAILINK_REG(hostless_ul1),
907 	},
908 	{
909 		.name = "Hostless_UL2",
910 		.no_pcm = 1,
911 		.dpcm_capture = 1,
912 		.ignore_suspend = 1,
913 		SND_SOC_DAILINK_REG(hostless_ul2),
914 	},
915 	{
916 		.name = "Hostless_UL3",
917 		.no_pcm = 1,
918 		.dpcm_capture = 1,
919 		.ignore_suspend = 1,
920 		SND_SOC_DAILINK_REG(hostless_ul3),
921 	},
922 	{
923 		.name = "Hostless_UL5",
924 		.no_pcm = 1,
925 		.dpcm_capture = 1,
926 		.ignore_suspend = 1,
927 		SND_SOC_DAILINK_REG(hostless_ul5),
928 	},
929 	{
930 		.name = "Hostless_UL6",
931 		.no_pcm = 1,
932 		.dpcm_capture = 1,
933 		.ignore_suspend = 1,
934 		SND_SOC_DAILINK_REG(hostless_ul6),
935 	},
936 	/* SOF BE */
937 	{
938 		.name = "AFE_SOF_DL1",
939 		.no_pcm = 1,
940 		.dpcm_playback = 1,
941 		SND_SOC_DAILINK_REG(AFE_SOF_DL1),
942 	},
943 	{
944 		.name = "AFE_SOF_DL2",
945 		.no_pcm = 1,
946 		.dpcm_playback = 1,
947 		SND_SOC_DAILINK_REG(AFE_SOF_DL2),
948 	},
949 	{
950 		.name = "AFE_SOF_UL1",
951 		.no_pcm = 1,
952 		.dpcm_capture = 1,
953 		SND_SOC_DAILINK_REG(AFE_SOF_UL1),
954 	},
955 	{
956 		.name = "AFE_SOF_UL2",
957 		.no_pcm = 1,
958 		.dpcm_capture = 1,
959 		SND_SOC_DAILINK_REG(AFE_SOF_UL2),
960 	},
961 };
962 
963 static const struct snd_soc_dapm_widget
964 mt8186_mt6366_da7219_max98357_widgets[] = {
965 	SND_SOC_DAPM_SPK("Speakers", NULL),
966 	SND_SOC_DAPM_HP("Headphones", NULL),
967 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
968 	SND_SOC_DAPM_OUTPUT("HDMI1"),
969 	SND_SOC_DAPM_MIXER(SOF_DMA_DL1, SND_SOC_NOPM, 0, 0, NULL, 0),
970 	SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0),
971 	SND_SOC_DAPM_MIXER(SOF_DMA_UL1, SND_SOC_NOPM, 0, 0, NULL, 0),
972 	SND_SOC_DAPM_MIXER(SOF_DMA_UL2, SND_SOC_NOPM, 0, 0, NULL, 0),
973 };
974 
975 static const struct snd_soc_dapm_route
976 mt8186_mt6366_da7219_max98357_routes[] = {
977 	/* SPK */
978 	{ "Speakers", NULL, "Speaker"},
979 	/* Headset */
980 	{ "Headphones", NULL, "HPL" },
981 	{ "Headphones", NULL, "HPR" },
982 	{ "MIC", NULL, "Headset Mic" },
983 	/* HDMI */
984 	{ "HDMI1", NULL, "TX"},
985 	/* SOF Uplink */
986 	{SOF_DMA_UL1, NULL, "UL1_CH1"},
987 	{SOF_DMA_UL1, NULL, "UL1_CH2"},
988 	{SOF_DMA_UL2, NULL, "UL2_CH1"},
989 	{SOF_DMA_UL2, NULL, "UL2_CH2"},
990 	/* SOF Downlink */
991 	{"DSP_DL1_VIRT", NULL, SOF_DMA_DL1},
992 	{"DSP_DL2_VIRT", NULL, SOF_DMA_DL2},
993 };
994 
995 static const struct snd_kcontrol_new
996 mt8186_mt6366_da7219_max98357_controls[] = {
997 	SOC_DAPM_PIN_SWITCH("Speakers"),
998 	SOC_DAPM_PIN_SWITCH("Headphones"),
999 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
1000 	SOC_DAPM_PIN_SWITCH("HDMI1"),
1001 };
1002 
1003 static struct snd_soc_card mt8186_mt6366_da7219_max98357_soc_card = {
1004 	.name = "mt8186_da7219_max98357",
1005 	.owner = THIS_MODULE,
1006 	.dai_link = mt8186_mt6366_da7219_max98357_dai_links,
1007 	.num_links = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_dai_links),
1008 	.controls = mt8186_mt6366_da7219_max98357_controls,
1009 	.num_controls = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_controls),
1010 	.dapm_widgets = mt8186_mt6366_da7219_max98357_widgets,
1011 	.num_dapm_widgets = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_widgets),
1012 	.dapm_routes = mt8186_mt6366_da7219_max98357_routes,
1013 	.num_dapm_routes = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_routes),
1014 	.codec_conf = mt8186_mt6366_da7219_max98357_codec_conf,
1015 	.num_configs = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_codec_conf),
1016 };
1017 
1018 static int mt8186_mt6366_da7219_max98357_dev_probe(struct platform_device *pdev)
1019 {
1020 	struct snd_soc_card *card;
1021 	struct snd_soc_dai_link *dai_link;
1022 	struct mtk_soc_card_data *soc_card_data;
1023 	struct mt8186_mt6366_da7219_max98357_priv *mach_priv;
1024 	struct device_node *platform_node, *headset_codec, *playback_codec, *adsp_node;
1025 	int sof_on = 0;
1026 	int ret, i;
1027 
1028 	card = (struct snd_soc_card *)device_get_match_data(&pdev->dev);
1029 	if (!card)
1030 		return -EINVAL;
1031 	card->dev = &pdev->dev;
1032 
1033 	soc_card_data = devm_kzalloc(&pdev->dev, sizeof(*soc_card_data), GFP_KERNEL);
1034 	if (!soc_card_data)
1035 		return -ENOMEM;
1036 	mach_priv = devm_kzalloc(&pdev->dev, sizeof(*mach_priv), GFP_KERNEL);
1037 	if (!mach_priv)
1038 		return -ENOMEM;
1039 
1040 	soc_card_data->mach_priv = mach_priv;
1041 
1042 	adsp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,adsp", 0);
1043 	if (adsp_node) {
1044 		struct mtk_sof_priv *sof_priv;
1045 
1046 		sof_priv = devm_kzalloc(&pdev->dev, sizeof(*sof_priv), GFP_KERNEL);
1047 		if (!sof_priv) {
1048 			ret = -ENOMEM;
1049 			goto err_adsp_node;
1050 		}
1051 		sof_priv->conn_streams = g_sof_conn_streams;
1052 		sof_priv->num_streams = ARRAY_SIZE(g_sof_conn_streams);
1053 		sof_priv->sof_dai_link_fixup = mt8186_sof_dai_link_fixup;
1054 		soc_card_data->sof_priv = sof_priv;
1055 		card->probe = mtk_sof_card_probe;
1056 		card->late_probe = mtk_sof_card_late_probe;
1057 		if (!card->topology_shortname_created) {
1058 			snprintf(card->topology_shortname, 32, "sof-%s", card->name);
1059 			card->topology_shortname_created = true;
1060 		}
1061 		card->name = card->topology_shortname;
1062 		sof_on = 1;
1063 	} else {
1064 		dev_info(&pdev->dev, "Probe without adsp\n");
1065 	}
1066 
1067 	if (of_property_read_bool(pdev->dev.of_node, "mediatek,dai-link")) {
1068 		ret = mtk_sof_dailink_parse_of(card, pdev->dev.of_node,
1069 					       "mediatek,dai-link",
1070 					       mt8186_mt6366_da7219_max98357_dai_links,
1071 					       ARRAY_SIZE(mt8186_mt6366_da7219_max98357_dai_links));
1072 		if (ret) {
1073 			dev_dbg(&pdev->dev, "Parse dai-link fail\n");
1074 			goto err_adsp_node;
1075 		}
1076 	} else {
1077 		if (!sof_on)
1078 			card->num_links = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_dai_links)
1079 					- ARRAY_SIZE(g_sof_conn_streams);
1080 	}
1081 
1082 	platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0);
1083 	if (!platform_node) {
1084 		ret = -EINVAL;
1085 		dev_err_probe(&pdev->dev, ret, "Property 'platform' missing or invalid\n");
1086 		goto err_platform_node;
1087 	}
1088 
1089 	playback_codec = of_get_child_by_name(pdev->dev.of_node, "playback-codecs");
1090 	if (!playback_codec) {
1091 		ret = -EINVAL;
1092 		dev_err_probe(&pdev->dev, ret, "Property 'speaker-codecs' missing or invalid\n");
1093 		goto err_playback_codec;
1094 	}
1095 
1096 	headset_codec = of_get_child_by_name(pdev->dev.of_node, "headset-codec");
1097 	if (!headset_codec) {
1098 		ret = -EINVAL;
1099 		dev_err_probe(&pdev->dev, ret, "Property 'headset-codec' missing or invalid\n");
1100 		goto err_headset_codec;
1101 	}
1102 
1103 	for_each_card_prelinks(card, i, dai_link) {
1104 		ret = mt8186_mt6366_card_set_be_link(card, dai_link, playback_codec, "I2S3");
1105 		if (ret) {
1106 			dev_err_probe(&pdev->dev, ret, "%s set speaker_codec fail\n",
1107 				      dai_link->name);
1108 			goto err_probe;
1109 		}
1110 
1111 		ret = mt8186_mt6366_card_set_be_link(card, dai_link, headset_codec, "I2S0");
1112 		if (ret) {
1113 			dev_err_probe(&pdev->dev, ret, "%s set headset_codec fail\n",
1114 				      dai_link->name);
1115 			goto err_probe;
1116 		}
1117 
1118 		ret = mt8186_mt6366_card_set_be_link(card, dai_link, headset_codec, "I2S1");
1119 		if (ret) {
1120 			dev_err_probe(&pdev->dev, ret, "%s set headset_codec fail\n",
1121 				      dai_link->name);
1122 			goto err_probe;
1123 		}
1124 
1125 		if (!strncmp(dai_link->name, "AFE_SOF", strlen("AFE_SOF")) && sof_on)
1126 			dai_link->platforms->of_node = adsp_node;
1127 
1128 		if (!dai_link->platforms->name && !dai_link->platforms->of_node)
1129 			dai_link->platforms->of_node = platform_node;
1130 	}
1131 
1132 	snd_soc_card_set_drvdata(card, soc_card_data);
1133 
1134 	ret = mt8186_afe_gpio_init(&pdev->dev);
1135 	if (ret) {
1136 		dev_err_probe(&pdev->dev, ret, "%s init gpio error\n", __func__);
1137 		goto err_probe;
1138 	}
1139 
1140 	ret = devm_snd_soc_register_card(&pdev->dev, card);
1141 	if (ret)
1142 		dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n", __func__);
1143 
1144 err_probe:
1145 	of_node_put(headset_codec);
1146 err_headset_codec:
1147 	of_node_put(playback_codec);
1148 err_playback_codec:
1149 	of_node_put(platform_node);
1150 err_platform_node:
1151 err_adsp_node:
1152 	of_node_put(adsp_node);
1153 
1154 	return ret;
1155 }
1156 
1157 #if IS_ENABLED(CONFIG_OF)
1158 static const struct of_device_id mt8186_mt6366_da7219_max98357_dt_match[] = {
1159 	{	.compatible = "mediatek,mt8186-mt6366-da7219-max98357-sound",
1160 		.data = &mt8186_mt6366_da7219_max98357_soc_card,
1161 	},
1162 	{}
1163 };
1164 MODULE_DEVICE_TABLE(of, mt8186_mt6366_da7219_max98357_dt_match);
1165 #endif
1166 
1167 static struct platform_driver mt8186_mt6366_da7219_max98357_driver = {
1168 	.driver = {
1169 		.name = "mt8186_mt6366_da7219_max98357",
1170 #if IS_ENABLED(CONFIG_OF)
1171 		.of_match_table = mt8186_mt6366_da7219_max98357_dt_match,
1172 #endif
1173 		.pm = &snd_soc_pm_ops,
1174 	},
1175 	.probe = mt8186_mt6366_da7219_max98357_dev_probe,
1176 };
1177 
1178 module_platform_driver(mt8186_mt6366_da7219_max98357_driver);
1179 
1180 /* Module information */
1181 MODULE_DESCRIPTION("MT8186-MT6366-DA7219-MAX98357 ALSA SoC machine driver");
1182 MODULE_AUTHOR("Jiaxin Yu <jiaxin.yu@mediatek.com>");
1183 MODULE_LICENSE("GPL v2");
1184 MODULE_ALIAS("mt8186_mt6366_da7219_max98357 soc card");
1185