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/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/rt5682.h>
17 #include <sound/soc.h>
18 
19 #include "../../codecs/mt6358.h"
20 #include "../../codecs/rt5682.h"
21 #include "../common/mtk-afe-platform-driver.h"
22 #include "mt8186-afe-common.h"
23 #include "mt8186-afe-clk.h"
24 #include "mt8186-afe-gpio.h"
25 #include "mt8186-mt6366-common.h"
26 
27 #define RT1019_CODEC_DAI	"HiFi"
28 #define RT1019_DEV0_NAME	"rt1019p"
29 
30 #define RT5682S_CODEC_DAI	"rt5682s-aif1"
31 #define RT5682S_DEV0_NAME	"rt5682s.5-001a"
32 
33 struct mt8186_mt6366_rt1019_rt5682s_priv {
34 	struct snd_soc_jack headset_jack, hdmi_jack;
35 };
36 
37 static struct snd_soc_codec_conf mt8186_mt6366_rt1019_rt5682s_codec_conf[] = {
38 	{
39 		.dlc = COMP_CODEC_CONF("mt6358-sound"),
40 		.name_prefix = "Mt6366",
41 	},
42 	{
43 		.dlc = COMP_CODEC_CONF("bt-sco"),
44 		.name_prefix = "Mt8186 bt",
45 	},
46 	{
47 		.dlc = COMP_CODEC_CONF("hdmi-audio-codec"),
48 		.name_prefix = "Mt8186 hdmi",
49 	},
50 };
51 
52 static int mt8186_rt5682s_init(struct snd_soc_pcm_runtime *rtd)
53 {
54 	struct mt8186_mt6366_rt1019_rt5682s_priv *priv =
55 		snd_soc_card_get_drvdata(rtd->card);
56 	struct snd_soc_jack *jack = &priv->headset_jack;
57 	struct snd_soc_component *cmpnt_codec =
58 		asoc_rtd_to_codec(rtd, 0)->component;
59 	int ret;
60 
61 	ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
62 				    SND_JACK_HEADSET | SND_JACK_BTN_0 |
63 				    SND_JACK_BTN_1 | SND_JACK_BTN_2 |
64 				    SND_JACK_BTN_3,
65 				    jack);
66 	if (ret) {
67 		dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
68 		return ret;
69 	}
70 
71 	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
72 	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
73 	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
74 	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
75 
76 	return snd_soc_component_set_jack(cmpnt_codec, jack, NULL);
77 }
78 
79 static int mt8186_rt5682s_i2s_hw_params(struct snd_pcm_substream *substream,
80 					struct snd_pcm_hw_params *params)
81 {
82 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
83 	struct snd_soc_card *card = rtd->card;
84 	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
85 	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
86 	unsigned int rate = params_rate(params);
87 	unsigned int mclk_fs_ratio = 128;
88 	unsigned int mclk_fs = rate * mclk_fs_ratio;
89 	int bitwidth;
90 	int ret;
91 
92 	bitwidth = snd_pcm_format_width(params_format(params));
93 	if (bitwidth < 0) {
94 		dev_err(card->dev, "invalid bit width: %d\n", bitwidth);
95 		return bitwidth;
96 	}
97 
98 	ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth);
99 	if (ret) {
100 		dev_err(card->dev, "failed to set tdm slot\n");
101 		return ret;
102 	}
103 
104 	ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1,
105 				  RT5682_PLL1_S_BCLK1,
106 				  params_rate(params) * 64,
107 				  params_rate(params) * 512);
108 	if (ret) {
109 		dev_err(card->dev, "failed to set pll\n");
110 		return ret;
111 	}
112 
113 	ret = snd_soc_dai_set_sysclk(codec_dai,
114 				     RT5682_SCLK_S_PLL1,
115 				     params_rate(params) * 512,
116 				     SND_SOC_CLOCK_IN);
117 	if (ret) {
118 		dev_err(card->dev, "failed to set sysclk\n");
119 		return ret;
120 	}
121 
122 	return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);
123 }
124 
125 static const struct snd_soc_ops mt8186_rt5682s_i2s_ops = {
126 	.hw_params = mt8186_rt5682s_i2s_hw_params,
127 };
128 
129 static int mt8186_mt6366_rt1019_rt5682s_hdmi_init(struct snd_soc_pcm_runtime *rtd)
130 {
131 	struct snd_soc_component *cmpnt_codec =
132 		asoc_rtd_to_codec(rtd, 0)->component;
133 	struct mt8186_mt6366_rt1019_rt5682s_priv *priv =
134 		snd_soc_card_get_drvdata(rtd->card);
135 	int ret;
136 
137 	ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, &priv->hdmi_jack);
138 	if (ret) {
139 		dev_err(rtd->dev, "HDMI Jack creation failed: %d\n", ret);
140 		return ret;
141 	}
142 
143 	return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL);
144 }
145 
146 static int mt8186_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
147 				  struct snd_pcm_hw_params *params,
148 				  snd_pcm_format_t fmt)
149 {
150 	struct snd_interval *channels = hw_param_interval(params,
151 		SNDRV_PCM_HW_PARAM_CHANNELS);
152 
153 	dev_dbg(rtd->dev, "%s(), fix format to %d\n", __func__, fmt);
154 
155 	/* fix BE i2s channel to 2 channel */
156 	channels->min = 2;
157 	channels->max = 2;
158 
159 	/* clean param mask first */
160 	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
161 			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
162 
163 	params_set_format(params, fmt);
164 
165 	return 0;
166 }
167 
168 static int mt8186_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
169 				      struct snd_pcm_hw_params *params)
170 {
171 	return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S24_LE);
172 }
173 
174 static int mt8186_it6505_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
175 					     struct snd_pcm_hw_params *params)
176 {
177 	return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S32_LE);
178 }
179 
180 static int mt8186_mt6366_rt1019_rt5682s_playback_startup(struct snd_pcm_substream *substream)
181 {
182 	static const unsigned int rates[] = {
183 		48000
184 	};
185 	static const unsigned int channels[] = {
186 		2
187 	};
188 	static const struct snd_pcm_hw_constraint_list constraints_rates = {
189 		.count = ARRAY_SIZE(rates),
190 		.list  = rates,
191 		.mask = 0,
192 	};
193 	static const struct snd_pcm_hw_constraint_list constraints_channels = {
194 		.count = ARRAY_SIZE(channels),
195 		.list  = channels,
196 		.mask = 0,
197 	};
198 
199 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
200 	struct snd_pcm_runtime *runtime = substream->runtime;
201 	int ret;
202 
203 	ret = snd_pcm_hw_constraint_list(runtime, 0,
204 					 SNDRV_PCM_HW_PARAM_RATE,
205 					 &constraints_rates);
206 	if (ret < 0) {
207 		dev_err(rtd->dev, "hw_constraint_list rate failed\n");
208 		return ret;
209 	}
210 
211 	ret = snd_pcm_hw_constraint_list(runtime, 0,
212 					 SNDRV_PCM_HW_PARAM_CHANNELS,
213 					 &constraints_channels);
214 	if (ret < 0) {
215 		dev_err(rtd->dev, "hw_constraint_list channel failed\n");
216 		return ret;
217 	}
218 
219 	return 0;
220 }
221 
222 static const struct snd_soc_ops mt8186_mt6366_rt1019_rt5682s_playback_ops = {
223 	.startup = mt8186_mt6366_rt1019_rt5682s_playback_startup,
224 };
225 
226 static int mt8186_mt6366_rt1019_rt5682s_capture_startup(struct snd_pcm_substream *substream)
227 {
228 	static const unsigned int rates[] = {
229 		48000
230 	};
231 	static const unsigned int channels[] = {
232 		1, 2
233 	};
234 	static const struct snd_pcm_hw_constraint_list constraints_rates = {
235 		.count = ARRAY_SIZE(rates),
236 		.list  = rates,
237 		.mask = 0,
238 	};
239 	static const struct snd_pcm_hw_constraint_list constraints_channels = {
240 		.count = ARRAY_SIZE(channels),
241 		.list  = channels,
242 		.mask = 0,
243 	};
244 
245 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
246 	struct snd_pcm_runtime *runtime = substream->runtime;
247 	int ret;
248 
249 	ret = snd_pcm_hw_constraint_list(runtime, 0,
250 					 SNDRV_PCM_HW_PARAM_RATE,
251 					 &constraints_rates);
252 	if (ret < 0) {
253 		dev_err(rtd->dev, "hw_constraint_list rate failed\n");
254 		return ret;
255 	}
256 
257 	ret = snd_pcm_hw_constraint_list(runtime, 0,
258 					 SNDRV_PCM_HW_PARAM_CHANNELS,
259 					 &constraints_channels);
260 	if (ret < 0) {
261 		dev_err(rtd->dev, "hw_constraint_list channel failed\n");
262 		return ret;
263 	}
264 
265 	return 0;
266 }
267 
268 static const struct snd_soc_ops mt8186_mt6366_rt1019_rt5682s_capture_ops = {
269 	.startup = mt8186_mt6366_rt1019_rt5682s_capture_startup,
270 };
271 
272 /* FE */
273 SND_SOC_DAILINK_DEFS(playback1,
274 		     DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
275 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
276 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
277 
278 SND_SOC_DAILINK_DEFS(playback12,
279 		     DAILINK_COMP_ARRAY(COMP_CPU("DL12")),
280 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
281 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
282 
283 SND_SOC_DAILINK_DEFS(playback2,
284 		     DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
285 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
286 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
287 
288 SND_SOC_DAILINK_DEFS(playback3,
289 		     DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
290 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
291 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
292 
293 SND_SOC_DAILINK_DEFS(playback4,
294 		     DAILINK_COMP_ARRAY(COMP_CPU("DL4")),
295 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
296 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
297 
298 SND_SOC_DAILINK_DEFS(playback5,
299 		     DAILINK_COMP_ARRAY(COMP_CPU("DL5")),
300 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
301 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
302 
303 SND_SOC_DAILINK_DEFS(playback6,
304 		     DAILINK_COMP_ARRAY(COMP_CPU("DL6")),
305 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
306 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
307 
308 SND_SOC_DAILINK_DEFS(playback7,
309 		     DAILINK_COMP_ARRAY(COMP_CPU("DL7")),
310 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
311 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
312 
313 SND_SOC_DAILINK_DEFS(playback8,
314 		     DAILINK_COMP_ARRAY(COMP_CPU("DL8")),
315 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
316 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
317 
318 SND_SOC_DAILINK_DEFS(capture1,
319 		     DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
320 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
321 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
322 
323 SND_SOC_DAILINK_DEFS(capture2,
324 		     DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
325 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
326 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
327 
328 SND_SOC_DAILINK_DEFS(capture3,
329 		     DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
330 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
331 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
332 
333 SND_SOC_DAILINK_DEFS(capture4,
334 		     DAILINK_COMP_ARRAY(COMP_CPU("UL4")),
335 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
336 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
337 
338 SND_SOC_DAILINK_DEFS(capture5,
339 		     DAILINK_COMP_ARRAY(COMP_CPU("UL5")),
340 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
341 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
342 
343 SND_SOC_DAILINK_DEFS(capture6,
344 		     DAILINK_COMP_ARRAY(COMP_CPU("UL6")),
345 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
346 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
347 
348 SND_SOC_DAILINK_DEFS(capture7,
349 		     DAILINK_COMP_ARRAY(COMP_CPU("UL7")),
350 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
351 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
352 
353 /* hostless */
354 SND_SOC_DAILINK_DEFS(hostless_lpbk,
355 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless LPBK DAI")),
356 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
357 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
358 SND_SOC_DAILINK_DEFS(hostless_fm,
359 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless FM DAI")),
360 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
361 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
362 SND_SOC_DAILINK_DEFS(hostless_src1,
363 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_SRC_1_DAI")),
364 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
365 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
366 SND_SOC_DAILINK_DEFS(hostless_src_bargein,
367 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_SRC_Bargein_DAI")),
368 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
369 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
370 
371 /* BE */
372 SND_SOC_DAILINK_DEFS(adda,
373 		     DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
374 		     DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound",
375 						   "mt6358-snd-codec-aif1"),
376 					COMP_CODEC("dmic-codec",
377 						   "dmic-hifi")),
378 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
379 SND_SOC_DAILINK_DEFS(i2s0,
380 		     DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
381 		     DAILINK_COMP_ARRAY(COMP_EMPTY()),
382 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
383 SND_SOC_DAILINK_DEFS(i2s1,
384 		     DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
385 		     DAILINK_COMP_ARRAY(COMP_EMPTY()),
386 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
387 SND_SOC_DAILINK_DEFS(i2s2,
388 		     DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
389 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
390 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
391 SND_SOC_DAILINK_DEFS(i2s3,
392 		     DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
393 		     DAILINK_COMP_ARRAY(COMP_EMPTY()),
394 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
395 SND_SOC_DAILINK_DEFS(hw_gain1,
396 		     DAILINK_COMP_ARRAY(COMP_CPU("HW Gain 1")),
397 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
398 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
399 SND_SOC_DAILINK_DEFS(hw_gain2,
400 		     DAILINK_COMP_ARRAY(COMP_CPU("HW Gain 2")),
401 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
402 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
403 SND_SOC_DAILINK_DEFS(hw_src1,
404 		     DAILINK_COMP_ARRAY(COMP_CPU("HW_SRC_1")),
405 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
406 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
407 SND_SOC_DAILINK_DEFS(hw_src2,
408 		     DAILINK_COMP_ARRAY(COMP_CPU("HW_SRC_2")),
409 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
410 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
411 SND_SOC_DAILINK_DEFS(connsys_i2s,
412 		     DAILINK_COMP_ARRAY(COMP_CPU("CONNSYS_I2S")),
413 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
414 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
415 SND_SOC_DAILINK_DEFS(pcm1,
416 		     DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
417 		     DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm-wb")),
418 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
419 SND_SOC_DAILINK_DEFS(tdm_in,
420 		     DAILINK_COMP_ARRAY(COMP_CPU("TDM IN")),
421 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
422 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
423 
424 /* hostless */
425 SND_SOC_DAILINK_DEFS(hostless_ul1,
426 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL1 DAI")),
427 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
428 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
429 SND_SOC_DAILINK_DEFS(hostless_ul2,
430 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL2 DAI")),
431 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
432 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
433 SND_SOC_DAILINK_DEFS(hostless_ul3,
434 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL3 DAI")),
435 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
436 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
437 SND_SOC_DAILINK_DEFS(hostless_ul5,
438 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL5 DAI")),
439 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
440 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
441 SND_SOC_DAILINK_DEFS(hostless_ul6,
442 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless_UL6 DAI")),
443 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
444 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
445 SND_SOC_DAILINK_DEFS(hostless_hw_gain_aaudio,
446 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless HW Gain AAudio DAI")),
447 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
448 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
449 SND_SOC_DAILINK_DEFS(hostless_src_aaudio,
450 		     DAILINK_COMP_ARRAY(COMP_CPU("Hostless SRC AAudio DAI")),
451 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
452 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
453 static struct snd_soc_dai_link mt8186_mt6366_rt1019_rt5682s_dai_links[] = {
454 	/* Front End DAI links */
455 	{
456 		.name = "Playback_1",
457 		.stream_name = "Playback_1",
458 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
459 			    SND_SOC_DPCM_TRIGGER_PRE},
460 		.dynamic = 1,
461 		.dpcm_playback = 1,
462 		.dpcm_merged_format = 1,
463 		.dpcm_merged_chan = 1,
464 		.dpcm_merged_rate = 1,
465 		.ops = &mt8186_mt6366_rt1019_rt5682s_playback_ops,
466 		SND_SOC_DAILINK_REG(playback1),
467 	},
468 	{
469 		.name = "Playback_12",
470 		.stream_name = "Playback_12",
471 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
472 			    SND_SOC_DPCM_TRIGGER_PRE},
473 		.dynamic = 1,
474 		.dpcm_playback = 1,
475 		SND_SOC_DAILINK_REG(playback12),
476 	},
477 	{
478 		.name = "Playback_2",
479 		.stream_name = "Playback_2",
480 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
481 			    SND_SOC_DPCM_TRIGGER_PRE},
482 		.dynamic = 1,
483 		.dpcm_playback = 1,
484 		.dpcm_merged_format = 1,
485 		.dpcm_merged_chan = 1,
486 		.dpcm_merged_rate = 1,
487 		SND_SOC_DAILINK_REG(playback2),
488 	},
489 	{
490 		.name = "Playback_3",
491 		.stream_name = "Playback_3",
492 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
493 			    SND_SOC_DPCM_TRIGGER_PRE},
494 		.dynamic = 1,
495 		.dpcm_playback = 1,
496 		.dpcm_merged_format = 1,
497 		.dpcm_merged_chan = 1,
498 		.dpcm_merged_rate = 1,
499 		.ops = &mt8186_mt6366_rt1019_rt5682s_playback_ops,
500 		SND_SOC_DAILINK_REG(playback3),
501 	},
502 	{
503 		.name = "Playback_4",
504 		.stream_name = "Playback_4",
505 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
506 			    SND_SOC_DPCM_TRIGGER_PRE},
507 		.dynamic = 1,
508 		.dpcm_playback = 1,
509 		SND_SOC_DAILINK_REG(playback4),
510 	},
511 	{
512 		.name = "Playback_5",
513 		.stream_name = "Playback_5",
514 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
515 			    SND_SOC_DPCM_TRIGGER_PRE},
516 		.dynamic = 1,
517 		.dpcm_playback = 1,
518 		SND_SOC_DAILINK_REG(playback5),
519 	},
520 	{
521 		.name = "Playback_6",
522 		.stream_name = "Playback_6",
523 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
524 			    SND_SOC_DPCM_TRIGGER_PRE},
525 		.dynamic = 1,
526 		.dpcm_playback = 1,
527 		SND_SOC_DAILINK_REG(playback6),
528 	},
529 	{
530 		.name = "Playback_7",
531 		.stream_name = "Playback_7",
532 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
533 			    SND_SOC_DPCM_TRIGGER_PRE},
534 		.dynamic = 1,
535 		.dpcm_playback = 1,
536 		SND_SOC_DAILINK_REG(playback7),
537 	},
538 	{
539 		.name = "Playback_8",
540 		.stream_name = "Playback_8",
541 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
542 			    SND_SOC_DPCM_TRIGGER_PRE},
543 		.dynamic = 1,
544 		.dpcm_playback = 1,
545 		SND_SOC_DAILINK_REG(playback8),
546 	},
547 	{
548 		.name = "Capture_1",
549 		.stream_name = "Capture_1",
550 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
551 			    SND_SOC_DPCM_TRIGGER_PRE},
552 		.dynamic = 1,
553 		.dpcm_capture = 1,
554 		SND_SOC_DAILINK_REG(capture1),
555 	},
556 	{
557 		.name = "Capture_2",
558 		.stream_name = "Capture_2",
559 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
560 			    SND_SOC_DPCM_TRIGGER_PRE},
561 		.dynamic = 1,
562 		.dpcm_capture = 1,
563 		.dpcm_merged_format = 1,
564 		.dpcm_merged_chan = 1,
565 		.dpcm_merged_rate = 1,
566 		.ops = &mt8186_mt6366_rt1019_rt5682s_capture_ops,
567 		SND_SOC_DAILINK_REG(capture2),
568 	},
569 	{
570 		.name = "Capture_3",
571 		.stream_name = "Capture_3",
572 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
573 			    SND_SOC_DPCM_TRIGGER_PRE},
574 		.dynamic = 1,
575 		.dpcm_capture = 1,
576 		SND_SOC_DAILINK_REG(capture3),
577 	},
578 	{
579 		.name = "Capture_4",
580 		.stream_name = "Capture_4",
581 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
582 			    SND_SOC_DPCM_TRIGGER_PRE},
583 		.dynamic = 1,
584 		.dpcm_capture = 1,
585 		.dpcm_merged_format = 1,
586 		.dpcm_merged_chan = 1,
587 		.dpcm_merged_rate = 1,
588 		.ops = &mt8186_mt6366_rt1019_rt5682s_capture_ops,
589 		SND_SOC_DAILINK_REG(capture4),
590 	},
591 	{
592 		.name = "Capture_5",
593 		.stream_name = "Capture_5",
594 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
595 			    SND_SOC_DPCM_TRIGGER_PRE},
596 		.dynamic = 1,
597 		.dpcm_capture = 1,
598 		SND_SOC_DAILINK_REG(capture5),
599 	},
600 	{
601 		.name = "Capture_6",
602 		.stream_name = "Capture_6",
603 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
604 			    SND_SOC_DPCM_TRIGGER_PRE},
605 		.dynamic = 1,
606 		.dpcm_capture = 1,
607 		.dpcm_merged_format = 1,
608 		.dpcm_merged_chan = 1,
609 		.dpcm_merged_rate = 1,
610 		SND_SOC_DAILINK_REG(capture6),
611 	},
612 	{
613 		.name = "Capture_7",
614 		.stream_name = "Capture_7",
615 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
616 			    SND_SOC_DPCM_TRIGGER_PRE},
617 		.dynamic = 1,
618 		.dpcm_capture = 1,
619 		SND_SOC_DAILINK_REG(capture7),
620 	},
621 	{
622 		.name = "Hostless_LPBK",
623 		.stream_name = "Hostless_LPBK",
624 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
625 			    SND_SOC_DPCM_TRIGGER_PRE},
626 		.dynamic = 1,
627 		.dpcm_playback = 1,
628 		.dpcm_capture = 1,
629 		.ignore_suspend = 1,
630 		SND_SOC_DAILINK_REG(hostless_lpbk),
631 	},
632 	{
633 		.name = "Hostless_FM",
634 		.stream_name = "Hostless_FM",
635 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
636 			    SND_SOC_DPCM_TRIGGER_PRE},
637 		.dynamic = 1,
638 		.dpcm_playback = 1,
639 		.dpcm_capture = 1,
640 		.ignore_suspend = 1,
641 		SND_SOC_DAILINK_REG(hostless_fm),
642 	},
643 	{
644 		.name = "Hostless_SRC_1",
645 		.stream_name = "Hostless_SRC_1",
646 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
647 			    SND_SOC_DPCM_TRIGGER_PRE},
648 		.dynamic = 1,
649 		.dpcm_playback = 1,
650 		.dpcm_capture = 1,
651 		.ignore_suspend = 1,
652 		SND_SOC_DAILINK_REG(hostless_src1),
653 	},
654 	{
655 		.name = "Hostless_SRC_Bargein",
656 		.stream_name = "Hostless_SRC_Bargein",
657 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
658 			    SND_SOC_DPCM_TRIGGER_PRE},
659 		.dynamic = 1,
660 		.dpcm_playback = 1,
661 		.dpcm_capture = 1,
662 		.ignore_suspend = 1,
663 		SND_SOC_DAILINK_REG(hostless_src_bargein),
664 	},
665 	{
666 		.name = "Hostless_HW_Gain_AAudio",
667 		.stream_name = "Hostless_HW_Gain_AAudio",
668 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
669 			    SND_SOC_DPCM_TRIGGER_PRE},
670 		.dynamic = 1,
671 		.dpcm_capture = 1,
672 		.ignore_suspend = 1,
673 		SND_SOC_DAILINK_REG(hostless_hw_gain_aaudio),
674 	},
675 	{
676 		.name = "Hostless_SRC_AAudio",
677 		.stream_name = "Hostless_SRC_AAudio",
678 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
679 			    SND_SOC_DPCM_TRIGGER_PRE},
680 		.dynamic = 1,
681 		.dpcm_playback = 1,
682 		.dpcm_capture = 1,
683 		.ignore_suspend = 1,
684 		SND_SOC_DAILINK_REG(hostless_src_aaudio),
685 	},
686 	/* Back End DAI links */
687 	{
688 		.name = "Primary Codec",
689 		.no_pcm = 1,
690 		.dpcm_playback = 1,
691 		.dpcm_capture = 1,
692 		.ignore_suspend = 1,
693 		.init = mt8186_mt6366_init,
694 		SND_SOC_DAILINK_REG(adda),
695 	},
696 	{
697 		.name = "I2S3",
698 		.no_pcm = 1,
699 		.dai_fmt = SND_SOC_DAIFMT_I2S |
700 			   SND_SOC_DAIFMT_IB_IF |
701 			   SND_SOC_DAIFMT_CBM_CFM,
702 		.dpcm_playback = 1,
703 		.ignore_suspend = 1,
704 		.init = mt8186_mt6366_rt1019_rt5682s_hdmi_init,
705 		.be_hw_params_fixup = mt8186_it6505_i2s_hw_params_fixup,
706 		SND_SOC_DAILINK_REG(i2s3),
707 	},
708 	{
709 		.name = "I2S0",
710 		.no_pcm = 1,
711 		.dpcm_capture = 1,
712 		.ignore_suspend = 1,
713 		.be_hw_params_fixup = mt8186_i2s_hw_params_fixup,
714 		.ops = &mt8186_rt5682s_i2s_ops,
715 		SND_SOC_DAILINK_REG(i2s0),
716 	},
717 	{
718 		.name = "I2S1",
719 		.no_pcm = 1,
720 		.dpcm_playback = 1,
721 		.ignore_suspend = 1,
722 		.be_hw_params_fixup = mt8186_i2s_hw_params_fixup,
723 		.init = mt8186_rt5682s_init,
724 		.ops = &mt8186_rt5682s_i2s_ops,
725 		SND_SOC_DAILINK_REG(i2s1),
726 	},
727 	{
728 		.name = "I2S2",
729 		.no_pcm = 1,
730 		.dpcm_capture = 1,
731 		.ignore_suspend = 1,
732 		.be_hw_params_fixup = mt8186_i2s_hw_params_fixup,
733 		SND_SOC_DAILINK_REG(i2s2),
734 	},
735 	{
736 		.name = "HW Gain 1",
737 		.no_pcm = 1,
738 		.dpcm_playback = 1,
739 		.dpcm_capture = 1,
740 		.ignore_suspend = 1,
741 		SND_SOC_DAILINK_REG(hw_gain1),
742 	},
743 	{
744 		.name = "HW Gain 2",
745 		.no_pcm = 1,
746 		.dpcm_playback = 1,
747 		.dpcm_capture = 1,
748 		.ignore_suspend = 1,
749 		SND_SOC_DAILINK_REG(hw_gain2),
750 	},
751 	{
752 		.name = "HW_SRC_1",
753 		.no_pcm = 1,
754 		.dpcm_playback = 1,
755 		.dpcm_capture = 1,
756 		.ignore_suspend = 1,
757 		SND_SOC_DAILINK_REG(hw_src1),
758 	},
759 	{
760 		.name = "HW_SRC_2",
761 		.no_pcm = 1,
762 		.dpcm_playback = 1,
763 		.dpcm_capture = 1,
764 		.ignore_suspend = 1,
765 		SND_SOC_DAILINK_REG(hw_src2),
766 	},
767 	{
768 		.name = "CONNSYS_I2S",
769 		.no_pcm = 1,
770 		.dpcm_capture = 1,
771 		.ignore_suspend = 1,
772 		SND_SOC_DAILINK_REG(connsys_i2s),
773 	},
774 	{
775 		.name = "PCM 1",
776 		.dai_fmt = SND_SOC_DAIFMT_I2S |
777 			   SND_SOC_DAIFMT_NB_IF,
778 		.no_pcm = 1,
779 		.dpcm_playback = 1,
780 		.dpcm_capture = 1,
781 		.ignore_suspend = 1,
782 		SND_SOC_DAILINK_REG(pcm1),
783 	},
784 	{
785 		.name = "TDM IN",
786 		.no_pcm = 1,
787 		.dpcm_capture = 1,
788 		.ignore_suspend = 1,
789 		SND_SOC_DAILINK_REG(tdm_in),
790 	},
791 	/* dummy BE for ul memif to record from dl memif */
792 	{
793 		.name = "Hostless_UL1",
794 		.no_pcm = 1,
795 		.dpcm_capture = 1,
796 		.ignore_suspend = 1,
797 		SND_SOC_DAILINK_REG(hostless_ul1),
798 	},
799 	{
800 		.name = "Hostless_UL2",
801 		.no_pcm = 1,
802 		.dpcm_capture = 1,
803 		.ignore_suspend = 1,
804 		SND_SOC_DAILINK_REG(hostless_ul2),
805 	},
806 	{
807 		.name = "Hostless_UL3",
808 		.no_pcm = 1,
809 		.dpcm_capture = 1,
810 		.ignore_suspend = 1,
811 		SND_SOC_DAILINK_REG(hostless_ul3),
812 	},
813 	{
814 		.name = "Hostless_UL5",
815 		.no_pcm = 1,
816 		.dpcm_capture = 1,
817 		.ignore_suspend = 1,
818 		SND_SOC_DAILINK_REG(hostless_ul5),
819 	},
820 	{
821 		.name = "Hostless_UL6",
822 		.no_pcm = 1,
823 		.dpcm_capture = 1,
824 		.ignore_suspend = 1,
825 		SND_SOC_DAILINK_REG(hostless_ul6),
826 	},
827 };
828 
829 static const struct snd_soc_dapm_widget
830 mt8186_mt6366_rt1019_rt5682s_widgets[] = {
831 	SND_SOC_DAPM_SPK("Speakers", NULL),
832 	SND_SOC_DAPM_OUTPUT("HDMI1"),
833 };
834 
835 static const struct snd_soc_dapm_route
836 mt8186_mt6366_rt1019_rt5682s_routes[] = {
837 	/* SPK */
838 	{ "Speakers", NULL, "Speaker" },
839 	/* HDMI */
840 	{ "HDMI1", NULL, "TX" },
841 };
842 
843 static const struct snd_kcontrol_new
844 mt8186_mt6366_rt1019_rt5682s_controls[] = {
845 	SOC_DAPM_PIN_SWITCH("Speakers"),
846 	SOC_DAPM_PIN_SWITCH("HDMI1"),
847 };
848 
849 static struct snd_soc_card mt8186_mt6366_rt1019_rt5682s_soc_card = {
850 	.name = "mt8186_mt6366_rt1019_rt5682s",
851 	.owner = THIS_MODULE,
852 	.dai_link = mt8186_mt6366_rt1019_rt5682s_dai_links,
853 	.num_links = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_dai_links),
854 	.controls = mt8186_mt6366_rt1019_rt5682s_controls,
855 	.num_controls = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_controls),
856 	.dapm_widgets = mt8186_mt6366_rt1019_rt5682s_widgets,
857 	.num_dapm_widgets = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_widgets),
858 	.dapm_routes = mt8186_mt6366_rt1019_rt5682s_routes,
859 	.num_dapm_routes = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_routes),
860 	.codec_conf = mt8186_mt6366_rt1019_rt5682s_codec_conf,
861 	.num_configs = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_codec_conf),
862 };
863 
864 static int mt8186_mt6366_rt1019_rt5682s_dev_probe(struct platform_device *pdev)
865 {
866 	struct snd_soc_card *card;
867 	struct snd_soc_dai_link *dai_link;
868 	struct mt8186_mt6366_rt1019_rt5682s_priv *priv;
869 	struct device_node *platform_node, *headset_codec, *playback_codec;
870 	int ret, i;
871 
872 	card = (struct snd_soc_card *)device_get_match_data(&pdev->dev);
873 	if (!card)
874 		return -EINVAL;
875 	card->dev = &pdev->dev;
876 
877 	platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0);
878 	if (!platform_node) {
879 		ret = -EINVAL;
880 		dev_err_probe(&pdev->dev, ret, "Property 'platform' missing or invalid\n");
881 		return ret;
882 	}
883 
884 	playback_codec = of_get_child_by_name(pdev->dev.of_node, "playback-codecs");
885 	if (!playback_codec) {
886 		ret = -EINVAL;
887 		dev_err_probe(&pdev->dev, ret, "Property 'speaker-codecs' missing or invalid\n");
888 		goto err_playback_codec;
889 	}
890 
891 	headset_codec = of_get_child_by_name(pdev->dev.of_node, "headset-codec");
892 	if (!headset_codec) {
893 		ret = -EINVAL;
894 		dev_err_probe(&pdev->dev, ret, "Property 'headset-codec' missing or invalid\n");
895 		goto err_headset_codec;
896 	}
897 
898 	for_each_card_prelinks(card, i, dai_link) {
899 		ret = mt8186_mt6366_card_set_be_link(card, dai_link, playback_codec, "I2S3");
900 		if (ret) {
901 			dev_err_probe(&pdev->dev, ret, "%s set speaker_codec fail\n",
902 				      dai_link->name);
903 			goto err_probe;
904 		}
905 
906 		ret = mt8186_mt6366_card_set_be_link(card, dai_link, headset_codec, "I2S0");
907 		if (ret) {
908 			dev_err_probe(&pdev->dev, ret, "%s set headset_codec fail\n",
909 				      dai_link->name);
910 			goto err_probe;
911 		}
912 
913 		ret = mt8186_mt6366_card_set_be_link(card, dai_link, headset_codec, "I2S1");
914 		if (ret) {
915 			dev_err_probe(&pdev->dev, ret, "%s set headset_codec fail\n",
916 				      dai_link->name);
917 			goto err_probe;
918 		}
919 
920 		if (!dai_link->platforms->name)
921 			dai_link->platforms->of_node = platform_node;
922 	}
923 
924 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
925 	if (!priv) {
926 		ret = -ENOMEM;
927 		goto err_probe;
928 	}
929 
930 	snd_soc_card_set_drvdata(card, priv);
931 
932 	ret = mt8186_afe_gpio_init(&pdev->dev);
933 	if (ret) {
934 		dev_err_probe(&pdev->dev, ret, "%s init gpio error\n", __func__);
935 		goto err_probe;
936 	}
937 
938 	ret = devm_snd_soc_register_card(&pdev->dev, card);
939 	if (ret)
940 		dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n", __func__);
941 
942 err_probe:
943 	of_node_put(headset_codec);
944 err_headset_codec:
945 	of_node_put(playback_codec);
946 err_playback_codec:
947 	of_node_put(platform_node);
948 
949 	return ret;
950 }
951 
952 #if IS_ENABLED(CONFIG_OF)
953 static const struct of_device_id mt8186_mt6366_rt1019_rt5682s_dt_match[] = {
954 	{	.compatible = "mediatek,mt8186-mt6366-rt1019-rt5682s-sound",
955 		.data = &mt8186_mt6366_rt1019_rt5682s_soc_card,
956 	},
957 	{}
958 };
959 #endif
960 
961 static struct platform_driver mt8186_mt6366_rt1019_rt5682s_driver = {
962 	.driver = {
963 		.name = "mt8186_mt6366_rt1019_rt5682s",
964 #if IS_ENABLED(CONFIG_OF)
965 		.of_match_table = mt8186_mt6366_rt1019_rt5682s_dt_match,
966 #endif
967 		.pm = &snd_soc_pm_ops,
968 	},
969 	.probe = mt8186_mt6366_rt1019_rt5682s_dev_probe,
970 };
971 
972 module_platform_driver(mt8186_mt6366_rt1019_rt5682s_driver);
973 
974 /* Module information */
975 MODULE_DESCRIPTION("MT8186-MT6366-RT1019-RT5682S ALSA SoC machine driver");
976 MODULE_AUTHOR("Jiaxin Yu <jiaxin.yu@mediatek.com>");
977 MODULE_LICENSE("GPL v2");
978 MODULE_ALIAS("mt8186_mt6366_rt1019_rt5682s soc card");
979