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