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