xref: /linux/sound/soc/mediatek/mt8196/mt8196-nau8825.c (revision efe86f088f48f18c27b648e5724048947f3b7fb4)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  mt8196-nau8825.c  --  mt8196 nau8825 ALSA SoC machine driver
4  *
5  *  Copyright (c) 2025 MediaTek Inc.
6  *  Author: Darren Ye <darren.ye@mediatek.com>
7  */
8 
9 #include <linux/input.h>
10 #include <linux/module.h>
11 #include <linux/of_device.h>
12 #include <linux/pm_runtime.h>
13 
14 #include <sound/soc.h>
15 #include <sound/jack.h>
16 #include <sound/pcm_params.h>
17 
18 #include "mt8196-afe-common.h"
19 
20 #include "../../codecs/nau8825.h"
21 #include "../../codecs/rt5682s.h"
22 
23 #include "../common/mtk-soc-card.h"
24 #include "../common/mtk-dsp-sof-common.h"
25 #include "../common/mtk-soundcard-driver.h"
26 #include "../common/mtk-afe-platform-driver.h"
27 
28 #define NAU8825_HS_PRESENT	BIT(0)
29 #define RT5682S_HS_PRESENT	BIT(1)
30 #define RT5650_HS_PRESENT	BIT(2)
31 
32 /*
33  * Nau88l25
34  */
35 #define NAU8825_CODEC_DAI  "nau8825-hifi"
36 
37 /*
38  * Rt5682s
39  */
40 #define RT5682S_CODEC_DAI     "rt5682s-aif1"
41 
42 /*
43  * Rt5650
44  */
45 #define RT5650_CODEC_DAI     "rt5645-aif1"
46 
47 #define SOF_DMA_DL1 "SOF_DMA_DL1"
48 #define SOF_DMA_DL_24CH "SOF_DMA_DL_24CH"
49 #define SOF_DMA_UL0 "SOF_DMA_UL0"
50 #define SOF_DMA_UL1 "SOF_DMA_UL1"
51 #define SOF_DMA_UL2 "SOF_DMA_UL2"
52 
53 enum mt8196_jacks {
54 	MT8196_JACK_HEADSET,
55 	MT8196_JACK_DP,
56 	MT8196_JACK_HDMI,
57 	MT8196_JACK_MAX,
58 };
59 
60 static struct snd_soc_jack_pin mt8196_dp_jack_pins[] = {
61 	{
62 		.pin = "DP",
63 		.mask = SND_JACK_AVOUT,
64 	},
65 };
66 
67 static struct snd_soc_jack_pin mt8196_hdmi_jack_pins[] = {
68 	{
69 		.pin = "HDMI",
70 		.mask = SND_JACK_AVOUT,
71 	},
72 };
73 
74 static struct snd_soc_jack_pin nau8825_jack_pins[] = {
75 	{
76 		.pin    = "Headphone Jack",
77 		.mask   = SND_JACK_HEADPHONE,
78 	},
79 	{
80 		.pin    = "Headset Mic",
81 		.mask   = SND_JACK_MICROPHONE,
82 	},
83 };
84 
85 static const struct snd_kcontrol_new mt8196_dumb_spk_controls[] = {
86 	SOC_DAPM_PIN_SWITCH("Ext Spk"),
87 };
88 
89 static const struct snd_soc_dapm_widget mt8196_dumb_spk_widgets[] = {
90 	SND_SOC_DAPM_SPK("Ext Spk", NULL),
91 };
92 
93 static const struct snd_soc_dapm_widget mt8196_nau8825_widgets[] = {
94 	SND_SOC_DAPM_HP("Headphone Jack", NULL),
95 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
96 	SND_SOC_DAPM_SPK("Ext Spk", NULL),
97 	SND_SOC_DAPM_SINK("DP"),
98 };
99 
100 static const struct snd_kcontrol_new mt8196_nau8825_controls[] = {
101 	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
102 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
103 };
104 
105 #define EXT_SPK_AMP_W_NAME "Ext_Speaker_Amp"
106 
107 static struct snd_soc_card mt8196_nau8825_soc_card;
108 
109 static const struct snd_soc_dapm_widget mt8196_nau8825_card_widgets[] = {
110 	/* SOF Uplink */
111 	SND_SOC_DAPM_MIXER("SOF_DMA_UL0", SND_SOC_NOPM, 0, 0, NULL, 0),
112 	SND_SOC_DAPM_MIXER("SOF_DMA_UL1", SND_SOC_NOPM, 0, 0, NULL, 0),
113 	SND_SOC_DAPM_MIXER("SOF_DMA_UL2", SND_SOC_NOPM, 0, 0, NULL, 0),
114 
115 	/*
116 	 * SOF Downlink
117 	 * the widgets on the machine driver cannot use the parameter with kcontrol
118 	 * because the widget domain is its platform driver. so sof downlink route
119 	 * is written in the i2s dai driver.
120 	 */
121 };
122 
123 static const struct snd_soc_dapm_route mt8196_nau8825_card_routes[] = {
124 	/* SOF Uplink */
125 	{"SOF_DMA_UL0", NULL, "UL0_CH1"},
126 	{"SOF_DMA_UL0", NULL, "UL0_CH2"},
127 	/* SOF Uplink */
128 	{"SOF_DMA_UL1", NULL, "UL1_CH1"},
129 	{"SOF_DMA_UL1", NULL, "UL1_CH2"},
130 	/* SOF Uplink */
131 	{"SOF_DMA_UL2", NULL, "UL2_CH1"},
132 	{"SOF_DMA_UL2", NULL, "UL2_CH2"},
133 };
134 
135 static const struct snd_kcontrol_new mt8196_nau8825_card_controls[] = {
136 	SOC_DAPM_PIN_SWITCH(EXT_SPK_AMP_W_NAME),
137 };
138 
139 /*
140  * define mtk_spk_i2s_mck node in dts when need mclk,
141  * BE i2s need assign snd_soc_ops = mt8196_nau8825_i2s_ops
142  */
143 static int mt8196_nau8825_i2s_hw_params(struct snd_pcm_substream *substream,
144 					struct snd_pcm_hw_params *params)
145 {
146 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
147 	unsigned int rate = params_rate(params);
148 	unsigned int mclk_fs_ratio = 128;
149 	unsigned int mclk_fs = rate * mclk_fs_ratio;
150 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
151 
152 	return snd_soc_dai_set_sysclk(cpu_dai,
153 				      0, mclk_fs, SND_SOC_CLOCK_OUT);
154 }
155 
156 static const struct snd_soc_ops mt8196_nau8825_i2s_ops = {
157 	.hw_params = mt8196_nau8825_i2s_hw_params,
158 };
159 
160 static int mt8196_dptx_hw_params(struct snd_pcm_substream *substream,
161 				 struct snd_pcm_hw_params *params)
162 {
163 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
164 	unsigned int rate = params_rate(params);
165 	unsigned int mclk_fs_ratio = 256;
166 	unsigned int mclk_fs = rate * mclk_fs_ratio;
167 	struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0);
168 
169 	return snd_soc_dai_set_sysclk(dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);
170 }
171 
172 static const struct snd_soc_ops mt8196_dptx_ops = {
173 	.hw_params = mt8196_dptx_hw_params,
174 };
175 
176 static int mt8196_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
177 				  struct snd_pcm_hw_params *params)
178 {
179 	dev_info(rtd->dev, "fix format to 32bit\n");
180 
181 	/* fix BE i2s format to 32bit, clean param mask first */
182 	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
183 			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
184 
185 	params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
186 	return 0;
187 }
188 
189 static int mt8196_sof_be_hw_params(struct snd_pcm_substream *substream,
190 				   struct snd_pcm_hw_params *params)
191 {
192 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
193 	struct snd_soc_component *cmpnt_afe = NULL;
194 	struct snd_soc_pcm_runtime *runtime;
195 
196 	/* find afe component */
197 	for_each_card_rtds(rtd->card, runtime) {
198 		cmpnt_afe = snd_soc_rtdcom_lookup(runtime, AFE_PCM_NAME);
199 		if (cmpnt_afe) {
200 			dev_info(rtd->dev, "component->name: %s\n", cmpnt_afe->name);
201 			break;
202 		}
203 	}
204 
205 	if (cmpnt_afe && !pm_runtime_active(cmpnt_afe->dev)) {
206 		dev_err(rtd->dev, "afe pm runtime is not active!!\n");
207 		return -EINVAL;
208 	}
209 
210 	return 0;
211 }
212 
213 static const struct snd_soc_ops mt8196_sof_be_ops = {
214 	.hw_params = mt8196_sof_be_hw_params,
215 };
216 
217 static const struct sof_conn_stream g_sof_conn_streams[] = {
218 	{
219 		.sof_link = "AFE_SOF_DL1",
220 		.sof_dma = SOF_DMA_DL1,
221 		.stream_dir = SNDRV_PCM_STREAM_PLAYBACK
222 	},
223 	{
224 		.sof_link = "AFE_SOF_DL_24CH",
225 		.sof_dma = SOF_DMA_DL_24CH,
226 		.stream_dir = SNDRV_PCM_STREAM_PLAYBACK
227 	},
228 	{
229 		.sof_link = "AFE_SOF_UL0",
230 		.sof_dma = SOF_DMA_UL0,
231 		.stream_dir = SNDRV_PCM_STREAM_CAPTURE
232 	},
233 	{
234 		.sof_link = "AFE_SOF_UL1",
235 		.sof_dma = SOF_DMA_UL1,
236 		.stream_dir = SNDRV_PCM_STREAM_CAPTURE
237 	},
238 	{
239 		.sof_link = "AFE_SOF_UL2",
240 		.sof_dma = SOF_DMA_UL2,
241 		.stream_dir = SNDRV_PCM_STREAM_CAPTURE
242 	},
243 };
244 
245 /* FE */
246 SND_SOC_DAILINK_DEFS(playback1,
247 		     DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
248 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
249 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
250 SND_SOC_DAILINK_DEFS(playback_24ch,
251 		     DAILINK_COMP_ARRAY(COMP_CPU("DL_24CH")),
252 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
253 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
254 SND_SOC_DAILINK_DEFS(capture0,
255 		     DAILINK_COMP_ARRAY(COMP_CPU("UL0")),
256 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
257 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
258 SND_SOC_DAILINK_DEFS(capture1,
259 		     DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
260 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
261 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
262 SND_SOC_DAILINK_DEFS(capture2,
263 		     DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
264 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
265 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
266 SND_SOC_DAILINK_DEFS(playback_hdmi,
267 		     DAILINK_COMP_ARRAY(COMP_CPU("HDMI")),
268 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
269 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
270 SND_SOC_DAILINK_DEFS(playback2,
271 		     DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
272 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
273 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
274 SND_SOC_DAILINK_DEFS(capture_cm0,
275 		     DAILINK_COMP_ARRAY(COMP_CPU("UL_CM0")),
276 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
277 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
278 /* BE */
279 SND_SOC_DAILINK_DEFS(ap_dmic,
280 		     DAILINK_COMP_ARRAY(COMP_CPU("AP_DMIC")),
281 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
282 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
283 SND_SOC_DAILINK_DEFS(ap_dmic_ch34,
284 		     DAILINK_COMP_ARRAY(COMP_CPU("AP_DMIC_CH34")),
285 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
286 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
287 SND_SOC_DAILINK_DEFS(ap_dmic_multich,
288 		     DAILINK_COMP_ARRAY(COMP_CPU("AP_DMIC_MULTICH")),
289 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
290 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
291 SND_SOC_DAILINK_DEFS(i2sin6,
292 		     DAILINK_COMP_ARRAY(COMP_CPU("I2SIN6")),
293 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
294 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
295 SND_SOC_DAILINK_DEFS(i2sout3,
296 		     DAILINK_COMP_ARRAY(COMP_CPU("I2SOUT3")),
297 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
298 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
299 SND_SOC_DAILINK_DEFS(i2sout4,
300 		     DAILINK_COMP_ARRAY(COMP_CPU("I2SOUT4")),
301 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
302 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
303 SND_SOC_DAILINK_DEFS(i2sout6,
304 		     DAILINK_COMP_ARRAY(COMP_CPU("I2SOUT6")),
305 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
306 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
307 SND_SOC_DAILINK_DEFS(tdm_dptx,
308 		     DAILINK_COMP_ARRAY(COMP_CPU("TDM_DPTX")),
309 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
310 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
311 SND_SOC_DAILINK_DEFS(AFE_SOF_DL_24CH,
312 		     DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL_24CH")),
313 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
314 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
315 SND_SOC_DAILINK_DEFS(AFE_SOF_DL1,
316 		     DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL1")),
317 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
318 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
319 SND_SOC_DAILINK_DEFS(AFE_SOF_UL0,
320 		     DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL0")),
321 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
322 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
323 SND_SOC_DAILINK_DEFS(AFE_SOF_UL1,
324 		     DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL1")),
325 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
326 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
327 SND_SOC_DAILINK_DEFS(AFE_SOF_UL2,
328 		     DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL2")),
329 		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
330 		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
331 
332 static struct snd_soc_dai_link mt8196_nau8825_dai_links[] = {
333 	/*
334 	 * The SOF topology expects PCM streams 0~4 to be available
335 	 * for the SOF PCM streams. Put the SOF BE definitions here
336 	 * so that the PCM device numbers are skipped over.
337 	 * (BE dailinks do not have PCM devices created.)
338 	 */
339 	{
340 		.name = "AFE_SOF_DL_24CH",
341 		.no_pcm = 1,
342 		.playback_only = 1,
343 		.ops = &mt8196_sof_be_ops,
344 		SND_SOC_DAILINK_REG(AFE_SOF_DL_24CH),
345 	},
346 	{
347 		.name = "AFE_SOF_DL1",
348 		.no_pcm = 1,
349 		.playback_only = 1,
350 		.ops = &mt8196_sof_be_ops,
351 		SND_SOC_DAILINK_REG(AFE_SOF_DL1),
352 	},
353 	{
354 		.name = "AFE_SOF_UL0",
355 		.no_pcm = 1,
356 		.capture_only = 1,
357 		.ops = &mt8196_sof_be_ops,
358 		SND_SOC_DAILINK_REG(AFE_SOF_UL0),
359 	},
360 	{
361 		.name = "AFE_SOF_UL1",
362 		.no_pcm = 1,
363 		.capture_only = 1,
364 		.ops = &mt8196_sof_be_ops,
365 		SND_SOC_DAILINK_REG(AFE_SOF_UL1),
366 	},
367 	{
368 		.name = "AFE_SOF_UL2",
369 		.no_pcm = 1,
370 		.capture_only = 1,
371 		.ops = &mt8196_sof_be_ops,
372 		SND_SOC_DAILINK_REG(AFE_SOF_UL2),
373 	},
374 	/* Front End DAI links */
375 	{
376 		.name = "HDMI_FE",
377 		.stream_name = "HDMI Playback",
378 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
379 			    SND_SOC_DPCM_TRIGGER_PRE},
380 		.dynamic = 1,
381 		.playback_only = 1,
382 		SND_SOC_DAILINK_REG(playback_hdmi),
383 	},
384 	{
385 		.name = "DL2_FE",
386 		.stream_name = "DL2 Playback",
387 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
388 			    SND_SOC_DPCM_TRIGGER_PRE},
389 		.dynamic = 1,
390 		.playback_only = 1,
391 		SND_SOC_DAILINK_REG(playback2),
392 	},
393 	{
394 		.name = "UL_CM0_FE",
395 		.stream_name = "UL_CM0 Capture",
396 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
397 			    SND_SOC_DPCM_TRIGGER_PRE},
398 		.dynamic = 1,
399 		.capture_only = 1,
400 		SND_SOC_DAILINK_REG(capture_cm0),
401 	},
402 	{
403 		.name = "DL_24CH_FE",
404 		.stream_name = "DL_24CH Playback",
405 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
406 				SND_SOC_DPCM_TRIGGER_PRE},
407 		.dynamic = 1,
408 		.playback_only = 1,
409 		SND_SOC_DAILINK_REG(playback_24ch),
410 	},
411 	{
412 		.name = "DL1_FE",
413 		.stream_name = "DL1 Playback",
414 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
415 				SND_SOC_DPCM_TRIGGER_PRE},
416 		.dynamic = 1,
417 		.playback_only = 1,
418 		SND_SOC_DAILINK_REG(playback1),
419 	},
420 	{
421 		.name = "UL0_FE",
422 		.stream_name = "UL0 Capture",
423 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
424 				SND_SOC_DPCM_TRIGGER_PRE},
425 		.dynamic = 1,
426 		.capture_only = 1,
427 		SND_SOC_DAILINK_REG(capture0),
428 	},
429 	{
430 		.name = "UL1_FE",
431 		.stream_name = "UL1 Capture",
432 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
433 				SND_SOC_DPCM_TRIGGER_PRE},
434 		.dynamic = 1,
435 		.capture_only = 1,
436 		SND_SOC_DAILINK_REG(capture1),
437 	},
438 	{
439 		.name = "UL2_FE",
440 		.stream_name = "UL2 Capture",
441 		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
442 				SND_SOC_DPCM_TRIGGER_PRE},
443 		.dynamic = 1,
444 		.capture_only = 1,
445 		SND_SOC_DAILINK_REG(capture2),
446 	},
447 	/* Back End DAI links */
448 	{
449 		.name = "I2SIN6_BE",
450 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC
451 			| SND_SOC_DAIFMT_GATED,
452 		.ops = &mt8196_nau8825_i2s_ops,
453 		.no_pcm = 1,
454 		.capture_only = 1,
455 		.ignore_suspend = 1,
456 		.be_hw_params_fixup = mt8196_hw_params_fixup,
457 		SND_SOC_DAILINK_REG(i2sin6),
458 	},
459 	{
460 		.name = "I2SOUT4_BE",
461 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC
462 			| SND_SOC_DAIFMT_GATED,
463 		.ops = &mt8196_nau8825_i2s_ops,
464 		.no_pcm = 1,
465 		.playback_only = 1,
466 		.ignore_suspend = 1,
467 		.ignore_pmdown_time = 1,
468 		.be_hw_params_fixup = mt8196_hw_params_fixup,
469 		SND_SOC_DAILINK_REG(i2sout4),
470 	},
471 	{
472 		.name = "I2SOUT6_BE",
473 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC
474 			| SND_SOC_DAIFMT_GATED,
475 		.ops = &mt8196_nau8825_i2s_ops,
476 		.no_pcm = 1,
477 		.playback_only = 1,
478 		.ignore_suspend = 1,
479 		.be_hw_params_fixup = mt8196_hw_params_fixup,
480 		SND_SOC_DAILINK_REG(i2sout6),
481 	},
482 	{
483 		.name = "AP_DMIC_BE",
484 		.no_pcm = 1,
485 		.capture_only = 1,
486 		.ignore_suspend = 1,
487 		SND_SOC_DAILINK_REG(ap_dmic),
488 	},
489 	{
490 		.name = "AP_DMIC_CH34_BE",
491 		.no_pcm = 1,
492 		.capture_only = 1,
493 		.ignore_suspend = 1,
494 		SND_SOC_DAILINK_REG(ap_dmic_ch34),
495 	},
496 	{
497 		.name = "AP_DMIC_MULTICH_BE",
498 		.no_pcm = 1,
499 		.capture_only = 1,
500 		.ignore_suspend = 1,
501 		SND_SOC_DAILINK_REG(ap_dmic_multich),
502 	},
503 	{
504 		.name = "TDM_DPTX_BE",
505 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC
506 			| SND_SOC_DAIFMT_GATED,
507 		.ops = &mt8196_dptx_ops,
508 		.be_hw_params_fixup = mt8196_hw_params_fixup,
509 		.no_pcm = 1,
510 		.playback_only = 1,
511 		.ignore_suspend = 1,
512 		SND_SOC_DAILINK_REG(tdm_dptx),
513 	},
514 	{
515 		.name = "I2SOUT3_BE",
516 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC
517 			| SND_SOC_DAIFMT_GATED,
518 		.ops = &mt8196_nau8825_i2s_ops,
519 		.no_pcm = 1,
520 		.playback_only = 1,
521 		.ignore_suspend = 1,
522 		SND_SOC_DAILINK_REG(i2sout3),
523 	},
524 };
525 
526 static int mt8196_dumb_amp_init(struct snd_soc_pcm_runtime *rtd)
527 {
528 	struct snd_soc_card *card = rtd->card;
529 	struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
530 	int ret = 0;
531 
532 	ret = snd_soc_dapm_new_controls(dapm, mt8196_dumb_spk_widgets,
533 					ARRAY_SIZE(mt8196_dumb_spk_widgets));
534 	if (ret) {
535 		dev_err(rtd->dev, "unable to add Dumb Speaker dapm, ret %d\n", ret);
536 		return ret;
537 	}
538 
539 	ret = snd_soc_add_card_controls(card, mt8196_dumb_spk_controls,
540 					ARRAY_SIZE(mt8196_dumb_spk_controls));
541 	if (ret) {
542 		dev_err(rtd->dev, "unable to add Dumb card controls, ret %d\n", ret);
543 		return ret;
544 	}
545 
546 	return 0;
547 }
548 
549 static int mt8196_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)
550 {
551 	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);
552 	struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8196_JACK_DP];
553 	struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
554 	int ret = 0;
555 
556 	ret = snd_soc_card_jack_new_pins(rtd->card, "DP Jack", SND_JACK_AVOUT,
557 					 jack, mt8196_dp_jack_pins,
558 					 ARRAY_SIZE(mt8196_dp_jack_pins));
559 	if (ret) {
560 		dev_err(rtd->dev, "new jack failed: %d\n", ret);
561 		return ret;
562 	}
563 
564 	ret = snd_soc_component_set_jack(component, jack, NULL);
565 	if (ret) {
566 		dev_err(rtd->dev, "set jack failed on %s (ret=%d)\n",
567 			component->name, ret);
568 		return ret;
569 	}
570 
571 	return 0;
572 }
573 
574 static int mt8196_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)
575 {
576 	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);
577 	struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8196_JACK_HDMI];
578 	struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
579 	int ret = 0;
580 
581 	ret = snd_soc_card_jack_new_pins(rtd->card, "HDMI Jack", SND_JACK_AVOUT,
582 					 jack, mt8196_hdmi_jack_pins,
583 					 ARRAY_SIZE(mt8196_hdmi_jack_pins));
584 	if (ret) {
585 		dev_err(rtd->dev, "new jack failed: %d\n", ret);
586 		return ret;
587 	}
588 
589 	ret = snd_soc_component_set_jack(component, jack, NULL);
590 	if (ret) {
591 		dev_err(rtd->dev, "set jack failed on %s (ret=%d)\n",
592 			component->name, ret);
593 		return ret;
594 	}
595 
596 	return 0;
597 }
598 
599 static int mt8196_headset_codec_init(struct snd_soc_pcm_runtime *rtd)
600 {
601 	struct snd_soc_card *card = rtd->card;
602 	struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
603 	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);
604 	struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8196_JACK_HEADSET];
605 	struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
606 	int ret;
607 	int type;
608 
609 	ret = snd_soc_dapm_new_controls(dapm, mt8196_nau8825_widgets,
610 					ARRAY_SIZE(mt8196_nau8825_widgets));
611 	if (ret) {
612 		dev_err(rtd->dev, "unable to add nau8825 card widget, ret %d\n", ret);
613 		return ret;
614 	}
615 
616 	ret = snd_soc_add_card_controls(card, mt8196_nau8825_controls,
617 					ARRAY_SIZE(mt8196_nau8825_controls));
618 	if (ret) {
619 		dev_err(rtd->dev, "unable to add nau8825 card controls, ret %d\n", ret);
620 		return ret;
621 	}
622 
623 	ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
624 					 SND_JACK_HEADSET | SND_JACK_BTN_0 |
625 					 SND_JACK_BTN_1 | SND_JACK_BTN_2 |
626 					 SND_JACK_BTN_3,
627 					 jack,
628 					 nau8825_jack_pins,
629 					 ARRAY_SIZE(nau8825_jack_pins));
630 	if (ret) {
631 		dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
632 		return ret;
633 	}
634 
635 	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
636 	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
637 	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
638 	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
639 
640 	type = SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3;
641 	ret = snd_soc_component_set_jack(component, jack, (void *)&type);
642 
643 	if (ret) {
644 		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
645 		return ret;
646 	}
647 
648 	return 0;
649 };
650 
651 static void mt8196_headset_codec_exit(struct snd_soc_pcm_runtime *rtd)
652 {
653 	struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
654 
655 	snd_soc_component_set_jack(component, NULL, NULL);
656 }
657 
658 static int mt8196_nau8825_hw_params(struct snd_pcm_substream *substream,
659 				    struct snd_pcm_hw_params *params)
660 {
661 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
662 	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
663 	unsigned int rate = params_rate(params);
664 	unsigned int bit_width = params_width(params);
665 	int clk_freq, ret;
666 
667 	clk_freq = rate * 2 * bit_width;
668 
669 	/* Configure clock for codec */
670 	ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_BLK, 0,
671 				     SND_SOC_CLOCK_IN);
672 	if (ret < 0) {
673 		dev_err(codec_dai->dev, "can't set BCLK clock %d\n", ret);
674 		return ret;
675 	}
676 
677 	/* Configure pll for codec */
678 	ret = snd_soc_dai_set_pll(codec_dai, 0, 0, clk_freq,
679 				  params_rate(params) * 256);
680 	if (ret < 0) {
681 		dev_err(codec_dai->dev, "can't set BCLK: %d\n", ret);
682 		return ret;
683 	}
684 
685 	return 0;
686 }
687 
688 static const struct snd_soc_ops mt8196_nau8825_ops = {
689 	.hw_params = mt8196_nau8825_hw_params,
690 };
691 
692 static int mt8196_rt5682s_i2s_hw_params(struct snd_pcm_substream *substream,
693 					struct snd_pcm_hw_params *params)
694 {
695 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
696 	struct snd_soc_card *card = rtd->card;
697 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
698 	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
699 	unsigned int rate = params_rate(params);
700 	int bitwidth;
701 	int ret;
702 
703 	bitwidth = snd_pcm_format_width(params_format(params));
704 	if (bitwidth < 0) {
705 		dev_err(card->dev, "invalid bit width: %d\n", bitwidth);
706 		return bitwidth;
707 	}
708 
709 	ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth);
710 	if (ret) {
711 		dev_err(card->dev, "failed to set tdm slot\n");
712 		return ret;
713 	}
714 
715 	ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL1, RT5682S_PLL_S_BCLK1,
716 				  rate * 32, rate * 512);
717 	if (ret) {
718 		dev_err(card->dev, "failed to set pll\n");
719 		return ret;
720 	}
721 
722 	dev_info(card->dev, "%s set mclk rate: %d\n", __func__, rate * 512);
723 
724 	ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_MCLK,
725 				     rate * 512, SND_SOC_CLOCK_IN);
726 	if (ret) {
727 		dev_err(card->dev, "failed to set sysclk\n");
728 		return ret;
729 	}
730 
731 	return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 512,
732 				      SND_SOC_CLOCK_OUT);
733 }
734 
735 static const struct snd_soc_ops mt8196_rt5682s_i2s_ops = {
736 	.hw_params = mt8196_rt5682s_i2s_hw_params,
737 };
738 
739 static int mt8196_nau8825_soc_card_probe(struct mtk_soc_card_data *soc_card_data, bool legacy)
740 {
741 	struct snd_soc_card *card = soc_card_data->card_data->card;
742 	struct snd_soc_dai_link *dai_link;
743 	bool init_nau8825 = false;
744 	bool init_rt5682s = false;
745 	bool init_rt5650 = false;
746 	bool init_dumb = false;
747 	int i;
748 
749 	dev_info(card->dev, "legacy: %d\n", legacy);
750 
751 	for_each_card_prelinks(card, i, dai_link) {
752 		if (strcmp(dai_link->name, "TDM_DPTX_BE") == 0) {
753 			if (dai_link->num_codecs &&
754 			    strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))
755 				dai_link->init = mt8196_dptx_codec_init;
756 		} else if (strcmp(dai_link->name, "I2SOUT3_BE") == 0) {
757 			if (dai_link->num_codecs &&
758 			    strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))
759 				dai_link->init = mt8196_hdmi_codec_init;
760 		} else if (strcmp(dai_link->name, "I2SOUT6_BE") == 0 ||
761 			   strcmp(dai_link->name, "I2SIN6_BE") == 0) {
762 			if (!strcmp(dai_link->codecs->dai_name, NAU8825_CODEC_DAI)) {
763 				dai_link->ops = &mt8196_nau8825_ops;
764 				if (!init_nau8825) {
765 					dai_link->init = mt8196_headset_codec_init;
766 					dai_link->exit = mt8196_headset_codec_exit;
767 					init_nau8825 = true;
768 				}
769 			} else if (!strcmp(dai_link->codecs->dai_name, RT5682S_CODEC_DAI)) {
770 				dai_link->ops = &mt8196_rt5682s_i2s_ops;
771 				if (!init_rt5682s) {
772 					dai_link->init = mt8196_headset_codec_init;
773 					dai_link->exit = mt8196_headset_codec_exit;
774 					init_rt5682s = true;
775 				}
776 			} else if (!strcmp(dai_link->codecs->dai_name, RT5650_CODEC_DAI)) {
777 				dai_link->ops = &mt8196_rt5682s_i2s_ops;
778 				if (!init_rt5650) {
779 					dai_link->init = mt8196_headset_codec_init;
780 					dai_link->exit = mt8196_headset_codec_exit;
781 					init_rt5650 = true;
782 				}
783 			} else {
784 				if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) {
785 					if (!init_dumb) {
786 						dai_link->init = mt8196_dumb_amp_init;
787 						init_dumb = true;
788 					}
789 				}
790 			}
791 		}
792 	}
793 
794 	return 0;
795 }
796 
797 static const struct mtk_sof_priv mt8196_sof_priv = {
798 	.conn_streams = g_sof_conn_streams,
799 	.num_streams = ARRAY_SIZE(g_sof_conn_streams),
800 };
801 
802 static struct snd_soc_card mt8196_nau8825_soc_card = {
803 	.owner = THIS_MODULE,
804 	.dai_link = mt8196_nau8825_dai_links,
805 	.num_links = ARRAY_SIZE(mt8196_nau8825_dai_links),
806 	.dapm_widgets = mt8196_nau8825_card_widgets,
807 	.num_dapm_widgets = ARRAY_SIZE(mt8196_nau8825_card_widgets),
808 	.dapm_routes = mt8196_nau8825_card_routes,
809 	.num_dapm_routes = ARRAY_SIZE(mt8196_nau8825_card_routes),
810 	.controls = mt8196_nau8825_card_controls,
811 	.num_controls = ARRAY_SIZE(mt8196_nau8825_card_controls),
812 };
813 
814 static const struct mtk_soundcard_pdata mt8196_nau8825_card = {
815 	.card_name = "mt8196_nau8825",
816 	.card_data = &(struct mtk_platform_card_data) {
817 		.card = &mt8196_nau8825_soc_card,
818 		.num_jacks = MT8196_JACK_MAX,
819 		.flags = NAU8825_HS_PRESENT
820 	},
821 	.sof_priv = &mt8196_sof_priv,
822 	.soc_probe = mt8196_nau8825_soc_card_probe,
823 };
824 
825 static const struct mtk_soundcard_pdata mt8196_rt5682s_card = {
826 	.card_name = "mt8196_rt5682s",
827 	.card_data = &(struct mtk_platform_card_data) {
828 		.card = &mt8196_nau8825_soc_card,
829 		.num_jacks = MT8196_JACK_MAX,
830 		.flags = RT5682S_HS_PRESENT
831 	},
832 	.sof_priv = &mt8196_sof_priv,
833 	.soc_probe = mt8196_nau8825_soc_card_probe,
834 };
835 
836 static const struct mtk_soundcard_pdata mt8196_rt5650_card = {
837 	.card_name = "mt8196_rt5650",
838 	.card_data = &(struct mtk_platform_card_data) {
839 		.card = &mt8196_nau8825_soc_card,
840 		.num_jacks = MT8196_JACK_MAX,
841 		.flags = RT5650_HS_PRESENT
842 	},
843 	.sof_priv = &mt8196_sof_priv,
844 	.soc_probe = mt8196_nau8825_soc_card_probe,
845 };
846 
847 static const struct of_device_id mt8196_nau8825_dt_match[] = {
848 	{.compatible = "mediatek,mt8196-nau8825-sound", .data = &mt8196_nau8825_card,},
849 	{.compatible = "mediatek,mt8196-rt5682s-sound", .data = &mt8196_rt5682s_card,},
850 	{.compatible = "mediatek,mt8196-rt5650-sound", .data = &mt8196_rt5650_card,},
851 	{}
852 };
853 MODULE_DEVICE_TABLE(of, mt8196_nau8825_dt_match);
854 
855 static struct platform_driver mt8196_nau8825_driver = {
856 	.driver = {
857 		.name = "mt8196-nau8825",
858 		.of_match_table = mt8196_nau8825_dt_match,
859 		.pm = &snd_soc_pm_ops,
860 	},
861 	.probe = mtk_soundcard_common_probe,
862 };
863 module_platform_driver(mt8196_nau8825_driver);
864 
865 /* Module information */
866 MODULE_DESCRIPTION("MT8196 nau8825 ALSA SoC machine driver");
867 MODULE_AUTHOR("Darren Ye <darren.ye@mediatek.com>");
868 MODULE_LICENSE("GPL");
869 MODULE_ALIAS("mt8196 nau8825 soc card");
870 
871