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