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 */
49 SND_SOC_DAILINK_DEFS(playback2,
50 DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
51 DAILINK_COMP_ARRAY(COMP_DUMMY()),
52 DAILINK_COMP_ARRAY(COMP_EMPTY()));
53
54 SND_SOC_DAILINK_DEFS(playback3,
55 DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
56 DAILINK_COMP_ARRAY(COMP_DUMMY()),
57 DAILINK_COMP_ARRAY(COMP_EMPTY()));
58
59 SND_SOC_DAILINK_DEFS(playback6,
60 DAILINK_COMP_ARRAY(COMP_CPU("DL6")),
61 DAILINK_COMP_ARRAY(COMP_DUMMY()),
62 DAILINK_COMP_ARRAY(COMP_EMPTY()));
63
64 SND_SOC_DAILINK_DEFS(playback7,
65 DAILINK_COMP_ARRAY(COMP_CPU("DL7")),
66 DAILINK_COMP_ARRAY(COMP_DUMMY()),
67 DAILINK_COMP_ARRAY(COMP_EMPTY()));
68
69 SND_SOC_DAILINK_DEFS(playback8,
70 DAILINK_COMP_ARRAY(COMP_CPU("DL8")),
71 DAILINK_COMP_ARRAY(COMP_DUMMY()),
72 DAILINK_COMP_ARRAY(COMP_EMPTY()));
73
74 SND_SOC_DAILINK_DEFS(playback10,
75 DAILINK_COMP_ARRAY(COMP_CPU("DL10")),
76 DAILINK_COMP_ARRAY(COMP_DUMMY()),
77 DAILINK_COMP_ARRAY(COMP_EMPTY()));
78
79 SND_SOC_DAILINK_DEFS(playback11,
80 DAILINK_COMP_ARRAY(COMP_CPU("DL11")),
81 DAILINK_COMP_ARRAY(COMP_DUMMY()),
82 DAILINK_COMP_ARRAY(COMP_EMPTY()));
83
84 SND_SOC_DAILINK_DEFS(capture1,
85 DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
86 DAILINK_COMP_ARRAY(COMP_DUMMY()),
87 DAILINK_COMP_ARRAY(COMP_EMPTY()));
88
89 SND_SOC_DAILINK_DEFS(capture2,
90 DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
91 DAILINK_COMP_ARRAY(COMP_DUMMY()),
92 DAILINK_COMP_ARRAY(COMP_EMPTY()));
93
94 SND_SOC_DAILINK_DEFS(capture3,
95 DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
96 DAILINK_COMP_ARRAY(COMP_DUMMY()),
97 DAILINK_COMP_ARRAY(COMP_EMPTY()));
98
99 SND_SOC_DAILINK_DEFS(capture4,
100 DAILINK_COMP_ARRAY(COMP_CPU("UL4")),
101 DAILINK_COMP_ARRAY(COMP_DUMMY()),
102 DAILINK_COMP_ARRAY(COMP_EMPTY()));
103
104 SND_SOC_DAILINK_DEFS(capture5,
105 DAILINK_COMP_ARRAY(COMP_CPU("UL5")),
106 DAILINK_COMP_ARRAY(COMP_DUMMY()),
107 DAILINK_COMP_ARRAY(COMP_EMPTY()));
108
109 SND_SOC_DAILINK_DEFS(capture6,
110 DAILINK_COMP_ARRAY(COMP_CPU("UL6")),
111 DAILINK_COMP_ARRAY(COMP_DUMMY()),
112 DAILINK_COMP_ARRAY(COMP_EMPTY()));
113
114 SND_SOC_DAILINK_DEFS(capture8,
115 DAILINK_COMP_ARRAY(COMP_CPU("UL8")),
116 DAILINK_COMP_ARRAY(COMP_DUMMY()),
117 DAILINK_COMP_ARRAY(COMP_EMPTY()));
118
119 SND_SOC_DAILINK_DEFS(capture9,
120 DAILINK_COMP_ARRAY(COMP_CPU("UL9")),
121 DAILINK_COMP_ARRAY(COMP_DUMMY()),
122 DAILINK_COMP_ARRAY(COMP_EMPTY()));
123
124 SND_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 */
130 SND_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
136 SND_SOC_DAILINK_DEFS(dptx,
137 DAILINK_COMP_ARRAY(COMP_CPU("DPTX")),
138 DAILINK_COMP_ARRAY(COMP_DUMMY()),
139 DAILINK_COMP_ARRAY(COMP_EMPTY()));
140
141 SND_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
146 SND_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
151 SND_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
156 SND_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
161 SND_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
166 SND_SOC_DAILINK_DEFS(pcm1,
167 DAILINK_COMP_ARRAY(COMP_CPU("PCM1")),
168 DAILINK_COMP_ARRAY(COMP_DUMMY()),
169 DAILINK_COMP_ARRAY(COMP_EMPTY()));
170
171 SND_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
179 struct 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
186 static struct snd_soc_jack_pin mt8188_hdmi_jack_pins[] = {
187 {
188 .pin = "HDMI",
189 .mask = SND_JACK_LINEOUT,
190 },
191 };
192
193 static struct snd_soc_jack_pin mt8188_dp_jack_pins[] = {
194 {
195 .pin = "DP",
196 .mask = SND_JACK_LINEOUT,
197 },
198 };
199
200 static 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
211 struct mt8188_card_data {
212 const char *name;
213 unsigned long quirk;
214 };
215
216 static const struct snd_kcontrol_new mt8188_dumb_spk_controls[] = {
217 SOC_DAPM_PIN_SWITCH("Ext Spk"),
218 };
219
220 static const struct snd_soc_dapm_widget mt8188_dumb_spk_widgets[] = {
221 SND_SOC_DAPM_SPK("Ext Spk", NULL),
222 };
223
224 static 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
229 static 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
234 static 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
239 static 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
244 static 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
256 static const struct snd_kcontrol_new mt8188_mt6359_controls[] = {
257 SOC_DAPM_PIN_SWITCH("Headphone"),
258 SOC_DAPM_PIN_SWITCH("Headset Mic"),
259 };
260
261 static const struct snd_soc_dapm_widget mt8188_nau8825_widgets[] = {
262 SND_SOC_DAPM_HP("Headphone Jack", NULL),
263 };
264
265 static const struct snd_kcontrol_new mt8188_nau8825_controls[] = {
266 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
267 };
268
mt8188_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime * rtd)269 static 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
mt8188_mt6359_init(struct snd_soc_pcm_runtime * rtd)433 static 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
448 enum {
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
mt8188_dptx_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)476 static 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
488 static const struct snd_soc_ops mt8188_dptx_ops = {
489 .hw_params = mt8188_dptx_hw_params,
490 };
491
mt8188_dptx_hw_params_fixup(struct snd_soc_pcm_runtime * rtd,struct snd_pcm_hw_params * params)492 static 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
mt8188_hdmi_codec_init(struct snd_soc_pcm_runtime * rtd)504 static 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
mt8188_dptx_codec_init(struct snd_soc_pcm_runtime * rtd)529 static 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
mt8188_dumb_amp_init(struct snd_soc_pcm_runtime * rtd)553 static 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
mt8188_max98390_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)575 static 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
602 static const struct snd_soc_ops mt8188_max98390_ops = {
603 .hw_params = mt8188_max98390_hw_params,
604 };
605
mt8188_max98390_codec_init(struct snd_soc_pcm_runtime * rtd)606 static 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
mt8188_nau8825_codec_init(struct snd_soc_pcm_runtime * rtd)648 static 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
mt8188_nau8825_codec_exit(struct snd_soc_pcm_runtime * rtd)696 static 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
mt8188_nau8825_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)703 static 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
733 static const struct snd_soc_ops mt8188_nau8825_ops = {
734 .hw_params = mt8188_nau8825_hw_params,
735 };
736 static 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
mt8188_fixup_controls(struct snd_soc_card * card)1008 static 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
1032 static 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
mt8188_mt6359_dev_probe(struct platform_device * pdev)1043 static 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__);
1139 err:
1140 of_node_put(platform_node);
1141 clean_card_reference(card);
1142 return ret;
1143 }
1144
1145 static struct mt8188_card_data mt8188_evb_card = {
1146 .name = "mt8188_mt6359",
1147 };
1148
1149 static struct mt8188_card_data mt8188_nau8825_card = {
1150 .name = "mt8188_nau8825",
1151 .quirk = NAU8825_HS_PRESENT,
1152 };
1153
1154 static 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 };
1159 MODULE_DEVICE_TABLE(of, mt8188_mt6359_dt_match);
1160
1161 static 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
1170 module_platform_driver(mt8188_mt6359_driver);
1171
1172 /* Module information */
1173 MODULE_DESCRIPTION("MT8188-MT6359 ALSA SoC machine driver");
1174 MODULE_AUTHOR("Trevor Wu <trevor.wu@mediatek.com>");
1175 MODULE_LICENSE("GPL");
1176 MODULE_ALIAS("mt8188 mt6359 soc card");
1177