xref: /linux/sound/soc/intel/boards/sof_rt5682.c (revision 36ec807b627b4c0a0a382f0ae48eac7187d14b2b)
1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright(c) 2019-2020 Intel Corporation.
3 
4 /*
5  * Intel SOF Machine Driver with Realtek rt5682 Codec
6  * and speaker codec MAX98357A or RT1015.
7  */
8 #include <linux/i2c.h>
9 #include <linux/input.h>
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
12 #include <linux/clk.h>
13 #include <linux/dmi.h>
14 #include <sound/core.h>
15 #include <sound/jack.h>
16 #include <sound/pcm.h>
17 #include <sound/pcm_params.h>
18 #include <sound/soc.h>
19 #include <sound/sof.h>
20 #include <sound/rt5682.h>
21 #include <sound/rt5682s.h>
22 #include <sound/soc-acpi.h>
23 #include "../../codecs/rt5682.h"
24 #include "../../codecs/rt5682s.h"
25 #include "../../codecs/rt5645.h"
26 #include "../common/soc-intel-quirks.h"
27 #include "sof_board_helpers.h"
28 #include "sof_maxim_common.h"
29 #include "sof_realtek_common.h"
30 
31 /* Driver-specific board quirks: from bit 0 to 7 */
32 #define SOF_RT5682_MCLK_EN			BIT(0)
33 
34 /* Default: MCLK on, MCLK 19.2M, SSP0  */
35 static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
36 					SOF_SSP_PORT_CODEC(0);
37 
38 static int sof_rt5682_quirk_cb(const struct dmi_system_id *id)
39 {
40 	sof_rt5682_quirk = (unsigned long)id->driver_data;
41 	return 1;
42 }
43 
44 static const struct dmi_system_id sof_rt5682_quirk_table[] = {
45 	{
46 		.callback = sof_rt5682_quirk_cb,
47 		.matches = {
48 			DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
49 			DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max"),
50 		},
51 		.driver_data = (void *)(SOF_SSP_PORT_CODEC(2)),
52 	},
53 	{
54 		.callback = sof_rt5682_quirk_cb,
55 		.matches = {
56 			DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
57 			DMI_MATCH(DMI_PRODUCT_NAME, "UP-CHT01"),
58 		},
59 		.driver_data = (void *)(SOF_SSP_PORT_CODEC(2)),
60 	},
61 	{
62 		.callback = sof_rt5682_quirk_cb,
63 		.matches = {
64 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
65 			DMI_MATCH(DMI_PRODUCT_NAME, "WhiskeyLake Client"),
66 		},
67 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
68 					SOF_SSP_PORT_CODEC(1)),
69 	},
70 	{
71 		.callback = sof_rt5682_quirk_cb,
72 		.matches = {
73 			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Volteer"),
74 			DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98373_ALC5682I_I2S_UP4"),
75 		},
76 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
77 					SOF_SSP_PORT_CODEC(0) |
78 					SOF_SSP_PORT_AMP(2) |
79 					SOF_NUM_IDISP_HDMI(4)),
80 	},
81 	{
82 		.callback = sof_rt5682_quirk_cb,
83 		.matches = {
84 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
85 			DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"),
86 			DMI_MATCH(DMI_OEM_STRING, "AUDIO-ADL_MAX98373_ALC5682I_I2S"),
87 		},
88 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
89 					SOF_SSP_PORT_CODEC(0) |
90 					SOF_SSP_PORT_AMP(2) |
91 					SOF_NUM_IDISP_HDMI(4)),
92 	},
93 	{
94 		.callback = sof_rt5682_quirk_cb,
95 		.matches = {
96 			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Brya"),
97 			DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98390_ALC5682I_I2S"),
98 		},
99 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
100 					SOF_SSP_PORT_CODEC(0) |
101 					SOF_SSP_PORT_AMP(2) |
102 					SOF_NUM_IDISP_HDMI(4)),
103 	},
104 	{
105 		.callback = sof_rt5682_quirk_cb,
106 		.matches = {
107 			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Brya"),
108 			DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98360_ALC5682I_I2S_AMP_SSP2"),
109 		},
110 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
111 					SOF_SSP_PORT_CODEC(0) |
112 					SOF_SSP_PORT_AMP(2) |
113 					SOF_NUM_IDISP_HDMI(4)),
114 	},
115 	{
116 		.callback = sof_rt5682_quirk_cb,
117 		.matches = {
118 			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"),
119 		},
120 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
121 					SOF_SSP_PORT_CODEC(2) |
122 					SOF_SSP_PORT_AMP(0) |
123 					SOF_SSP_PORT_BT_OFFLOAD(1) |
124 					SOF_BT_OFFLOAD_PRESENT
125 					),
126 	},
127 	{}
128 };
129 
130 static struct snd_soc_jack_pin jack_pins[] = {
131 	{
132 		.pin    = "Headphone Jack",
133 		.mask   = SND_JACK_HEADPHONE,
134 	},
135 	{
136 		.pin    = "Headset Mic",
137 		.mask   = SND_JACK_MICROPHONE,
138 	},
139 };
140 
141 static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
142 {
143 	struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
144 	struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
145 	struct snd_soc_jack *jack = &ctx->headset_jack;
146 	int extra_jack_data;
147 	int ret, mclk_freq;
148 
149 	if (ctx->rt5682.mclk_en) {
150 		mclk_freq = sof_dai_get_mclk(rtd);
151 		if (mclk_freq <= 0) {
152 			dev_err(rtd->dev, "invalid mclk freq %d\n", mclk_freq);
153 			return -EINVAL;
154 		}
155 
156 		/* need to enable ASRC function for 24MHz mclk rate */
157 		if (mclk_freq == 24000000) {
158 			dev_info(rtd->dev, "enable ASRC\n");
159 
160 			switch (ctx->codec_type) {
161 			case CODEC_RT5650:
162 				rt5645_sel_asrc_clk_src(component,
163 							RT5645_DA_STEREO_FILTER |
164 							RT5645_AD_STEREO_FILTER,
165 							RT5645_CLK_SEL_I2S1_ASRC);
166 				rt5645_sel_asrc_clk_src(component,
167 							RT5645_DA_MONO_L_FILTER |
168 							RT5645_DA_MONO_R_FILTER,
169 							RT5645_CLK_SEL_I2S2_ASRC);
170 				break;
171 			case CODEC_RT5682:
172 				rt5682_sel_asrc_clk_src(component,
173 							RT5682_DA_STEREO1_FILTER |
174 							RT5682_AD_STEREO1_FILTER,
175 							RT5682_CLK_SEL_I2S1_ASRC);
176 				break;
177 			case CODEC_RT5682S:
178 				rt5682s_sel_asrc_clk_src(component,
179 							 RT5682S_DA_STEREO1_FILTER |
180 							 RT5682S_AD_STEREO1_FILTER,
181 							 RT5682S_CLK_SEL_I2S1_ASRC);
182 				break;
183 			default:
184 				dev_err(rtd->dev, "invalid codec type %d\n",
185 					ctx->codec_type);
186 				return -EINVAL;
187 			}
188 		}
189 
190 		if (ctx->rt5682.is_legacy_cpu) {
191 			/*
192 			 * The firmware might enable the clock at
193 			 * boot (this information may or may not
194 			 * be reflected in the enable clock register).
195 			 * To change the rate we must disable the clock
196 			 * first to cover these cases. Due to common
197 			 * clock framework restrictions that do not allow
198 			 * to disable a clock that has not been enabled,
199 			 * we need to enable the clock first.
200 			 */
201 			ret = clk_prepare_enable(ctx->rt5682.mclk);
202 			if (!ret)
203 				clk_disable_unprepare(ctx->rt5682.mclk);
204 
205 			ret = clk_set_rate(ctx->rt5682.mclk, 19200000);
206 
207 			if (ret)
208 				dev_err(rtd->dev, "unable to set MCLK rate\n");
209 		}
210 	}
211 
212 	/*
213 	 * Headset buttons map to the google Reference headset.
214 	 * These can be configured by userspace.
215 	 */
216 	ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
217 					 SND_JACK_HEADSET | SND_JACK_BTN_0 |
218 					 SND_JACK_BTN_1 | SND_JACK_BTN_2 |
219 					 SND_JACK_BTN_3,
220 					 jack,
221 					 jack_pins,
222 					 ARRAY_SIZE(jack_pins));
223 	if (ret) {
224 		dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
225 		return ret;
226 	}
227 
228 	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
229 	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
230 	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
231 	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
232 
233 	if (ctx->codec_type == CODEC_RT5650) {
234 		extra_jack_data = SND_JACK_MICROPHONE | SND_JACK_BTN_0;
235 		ret = snd_soc_component_set_jack(component, jack, &extra_jack_data);
236 	} else
237 		ret = snd_soc_component_set_jack(component, jack, NULL);
238 
239 	if (ret) {
240 		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
241 		return ret;
242 	}
243 
244 	return ret;
245 };
246 
247 static void sof_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd)
248 {
249 	struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
250 
251 	snd_soc_component_set_jack(component, NULL, NULL);
252 }
253 
254 static int sof_rt5682_hw_params(struct snd_pcm_substream *substream,
255 				struct snd_pcm_hw_params *params)
256 {
257 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
258 	struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
259 	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
260 	int pll_id, pll_source, pll_in, pll_out, clk_id, ret;
261 
262 	if (ctx->rt5682.mclk_en) {
263 		if (ctx->rt5682.is_legacy_cpu) {
264 			ret = clk_prepare_enable(ctx->rt5682.mclk);
265 			if (ret < 0) {
266 				dev_err(rtd->dev,
267 					"could not configure MCLK state");
268 				return ret;
269 			}
270 		}
271 
272 		switch (ctx->codec_type) {
273 		case CODEC_RT5650:
274 			pll_source = RT5645_PLL1_S_MCLK;
275 			break;
276 		case CODEC_RT5682:
277 			pll_source = RT5682_PLL1_S_MCLK;
278 			break;
279 		case CODEC_RT5682S:
280 			pll_source = RT5682S_PLL_S_MCLK;
281 			break;
282 		default:
283 			dev_err(rtd->dev, "invalid codec type %d\n",
284 				ctx->codec_type);
285 			return -EINVAL;
286 		}
287 
288 		/* get the tplg configured mclk. */
289 		pll_in = sof_dai_get_mclk(rtd);
290 		if (pll_in <= 0) {
291 			dev_err(rtd->dev, "invalid mclk freq %d\n", pll_in);
292 			return -EINVAL;
293 		}
294 	} else {
295 		switch (ctx->codec_type) {
296 		case CODEC_RT5650:
297 			pll_source = RT5645_PLL1_S_BCLK1;
298 			break;
299 		case CODEC_RT5682:
300 			pll_source = RT5682_PLL1_S_BCLK1;
301 			break;
302 		case CODEC_RT5682S:
303 			pll_source = RT5682S_PLL_S_BCLK1;
304 			break;
305 		default:
306 			dev_err(rtd->dev, "invalid codec type %d\n",
307 				ctx->codec_type);
308 			return -EINVAL;
309 		}
310 
311 		/* get the tplg configured bclk. */
312 		pll_in = sof_dai_get_bclk(rtd);
313 		if (pll_in <= 0) {
314 			dev_err(rtd->dev, "invalid bclk freq %d\n", pll_in);
315 			return -EINVAL;
316 		}
317 	}
318 
319 	pll_out = params_rate(params) * 512;
320 
321 	/* when MCLK is 512FS, no need to set PLL configuration additionally. */
322 	if (pll_in == pll_out) {
323 		switch (ctx->codec_type) {
324 		case CODEC_RT5650:
325 			clk_id = RT5645_SCLK_S_MCLK;
326 			break;
327 		case CODEC_RT5682:
328 			clk_id = RT5682_SCLK_S_MCLK;
329 			break;
330 		case CODEC_RT5682S:
331 			clk_id = RT5682S_SCLK_S_MCLK;
332 			break;
333 		default:
334 			dev_err(rtd->dev, "invalid codec type %d\n",
335 				ctx->codec_type);
336 			return -EINVAL;
337 		}
338 	} else {
339 		switch (ctx->codec_type) {
340 		case CODEC_RT5650:
341 			pll_id = 0; /* not used in codec driver */
342 			clk_id = RT5645_SCLK_S_PLL1;
343 			break;
344 		case CODEC_RT5682:
345 			pll_id = RT5682_PLL1;
346 			clk_id = RT5682_SCLK_S_PLL1;
347 			break;
348 		case CODEC_RT5682S:
349 			/* check plla_table and pllb_table in rt5682s.c */
350 			switch (pll_in) {
351 			case 3072000:
352 			case 24576000:
353 				/*
354 				 * For MCLK = 24.576MHz and sample rate = 96KHz case, use PLL1  We don't test
355 				 * pll_out or params_rate() here since rt5682s PLL2 doesn't support 24.576MHz
356 				 * input, so we have no choice but to use PLL1. Besides, we will not use PLL at
357 				 * all if pll_in == pll_out. ex, MCLK = 24.576Mhz and sample rate = 48KHz
358 				 */
359 				pll_id = RT5682S_PLL1;
360 				clk_id = RT5682S_SCLK_S_PLL1;
361 				break;
362 			default:
363 				pll_id = RT5682S_PLL2;
364 				clk_id = RT5682S_SCLK_S_PLL2;
365 				break;
366 			}
367 			break;
368 		default:
369 			dev_err(rtd->dev, "invalid codec type %d\n", ctx->codec_type);
370 			return -EINVAL;
371 		}
372 
373 		/* Configure pll for codec */
374 		ret = snd_soc_dai_set_pll(codec_dai, pll_id, pll_source, pll_in,
375 					  pll_out);
376 		if (ret < 0)
377 			dev_err(rtd->dev, "snd_soc_dai_set_pll err = %d\n", ret);
378 	}
379 
380 	/* Configure sysclk for codec */
381 	ret = snd_soc_dai_set_sysclk(codec_dai, clk_id,
382 				     pll_out, SND_SOC_CLOCK_IN);
383 	if (ret < 0)
384 		dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
385 
386 	/*
387 	 * slot_width should equal or large than data length, set them
388 	 * be the same
389 	 */
390 	ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0, 0x0, 2,
391 				       params_width(params));
392 	if (ret < 0) {
393 		dev_err(rtd->dev, "set TDM slot err:%d\n", ret);
394 		return ret;
395 	}
396 
397 	return ret;
398 }
399 
400 static const struct snd_soc_ops sof_rt5682_ops = {
401 	.hw_params = sof_rt5682_hw_params,
402 };
403 
404 static int sof_card_late_probe(struct snd_soc_card *card)
405 {
406 	struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
407 	struct snd_soc_dapm_context *dapm = &card->dapm;
408 	int err;
409 
410 	if (ctx->amp_type == CODEC_MAX98373) {
411 		/* Disable Left and Right Spk pin after boot */
412 		snd_soc_dapm_disable_pin(dapm, "Left Spk");
413 		snd_soc_dapm_disable_pin(dapm, "Right Spk");
414 		err = snd_soc_dapm_sync(dapm);
415 		if (err < 0)
416 			return err;
417 	}
418 
419 	return sof_intel_board_card_late_probe(card);
420 }
421 
422 static const struct snd_kcontrol_new sof_controls[] = {
423 	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
424 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
425 };
426 
427 static const struct snd_soc_dapm_widget sof_widgets[] = {
428 	SND_SOC_DAPM_HP("Headphone Jack", NULL),
429 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
430 };
431 
432 static const struct snd_soc_dapm_route sof_map[] = {
433 	/* HP jack connectors - unknown if we have jack detection */
434 	{ "Headphone Jack", NULL, "HPOL" },
435 	{ "Headphone Jack", NULL, "HPOR" },
436 
437 	/* other jacks */
438 	{ "IN1P", NULL, "Headset Mic" },
439 };
440 
441 static const struct snd_kcontrol_new rt5650_spk_kcontrols[] = {
442 	SOC_DAPM_PIN_SWITCH("Left Spk"),
443 	SOC_DAPM_PIN_SWITCH("Right Spk"),
444 
445 };
446 
447 static const struct snd_soc_dapm_widget rt5650_spk_widgets[] = {
448 	SND_SOC_DAPM_SPK("Left Spk", NULL),
449 	SND_SOC_DAPM_SPK("Right Spk", NULL),
450 };
451 
452 static const struct snd_soc_dapm_route rt5650_spk_dapm_routes[] = {
453 	/* speaker */
454 	{ "Left Spk", NULL, "SPOL" },
455 	{ "Right Spk", NULL, "SPOR" },
456 };
457 
458 static int rt5650_spk_init(struct snd_soc_pcm_runtime *rtd)
459 {
460 	struct snd_soc_card *card = rtd->card;
461 	int ret;
462 
463 	ret = snd_soc_dapm_new_controls(&card->dapm, rt5650_spk_widgets,
464 					ARRAY_SIZE(rt5650_spk_widgets));
465 	if (ret) {
466 		dev_err(rtd->dev, "fail to add rt5650 spk widgets, ret %d\n",
467 			ret);
468 		return ret;
469 	}
470 
471 	ret = snd_soc_add_card_controls(card, rt5650_spk_kcontrols,
472 					ARRAY_SIZE(rt5650_spk_kcontrols));
473 	if (ret) {
474 		dev_err(rtd->dev, "fail to add rt5650 spk kcontrols, ret %d\n",
475 			ret);
476 		return ret;
477 	}
478 
479 	ret = snd_soc_dapm_add_routes(&card->dapm, rt5650_spk_dapm_routes,
480 				      ARRAY_SIZE(rt5650_spk_dapm_routes));
481 	if (ret)
482 		dev_err(rtd->dev, "fail to add dapm routes, ret=%d\n", ret);
483 
484 	return ret;
485 }
486 
487 /* sof audio machine driver for rt5682 codec */
488 static struct snd_soc_card sof_audio_card_rt5682 = {
489 	.name = "rt5682", /* the sof- prefix is added by the core */
490 	.owner = THIS_MODULE,
491 	.controls = sof_controls,
492 	.num_controls = ARRAY_SIZE(sof_controls),
493 	.dapm_widgets = sof_widgets,
494 	.num_dapm_widgets = ARRAY_SIZE(sof_widgets),
495 	.dapm_routes = sof_map,
496 	.num_dapm_routes = ARRAY_SIZE(sof_map),
497 	.fully_routed = true,
498 	.late_probe = sof_card_late_probe,
499 };
500 
501 static struct snd_soc_dai_link_component rt5682_component[] = {
502 	{
503 		.name = "i2c-10EC5682:00",
504 		.dai_name = "rt5682-aif1",
505 	}
506 };
507 
508 static struct snd_soc_dai_link_component rt5682s_component[] = {
509 	{
510 		.name = "i2c-RTL5682:00",
511 		.dai_name = "rt5682s-aif1",
512 	}
513 };
514 
515 static struct snd_soc_dai_link_component rt5650_components[] = {
516 	{
517 		.name = "i2c-10EC5650:00",
518 		.dai_name = "rt5645-aif1",
519 	},
520 	{
521 		.name = "i2c-10EC5650:00",
522 		.dai_name = "rt5645-aif2",
523 	}
524 };
525 
526 static int
527 sof_card_dai_links_create(struct device *dev, struct snd_soc_card *card,
528 			  struct sof_card_private *ctx)
529 {
530 	int ret;
531 
532 	ret = sof_intel_board_set_dai_link(dev, card, ctx);
533 	if (ret)
534 		return ret;
535 
536 	if (!ctx->codec_link) {
537 		dev_err(dev, "codec link not available");
538 		return -EINVAL;
539 	}
540 
541 	/* codec-specific fields for headphone codec */
542 	switch (ctx->codec_type) {
543 	case CODEC_RT5650:
544 		ctx->codec_link->codecs = &rt5650_components[0];
545 		ctx->codec_link->num_codecs = 1;
546 		break;
547 	case CODEC_RT5682:
548 		ctx->codec_link->codecs = rt5682_component;
549 		ctx->codec_link->num_codecs = ARRAY_SIZE(rt5682_component);
550 		break;
551 	case CODEC_RT5682S:
552 		ctx->codec_link->codecs = rt5682s_component;
553 		ctx->codec_link->num_codecs = ARRAY_SIZE(rt5682s_component);
554 		break;
555 	default:
556 		dev_err(dev, "invalid codec type %d\n", ctx->codec_type);
557 		return -EINVAL;
558 	}
559 
560 	ctx->codec_link->init = sof_rt5682_codec_init;
561 	ctx->codec_link->exit = sof_rt5682_codec_exit;
562 	ctx->codec_link->ops = &sof_rt5682_ops;
563 
564 	if (!ctx->rt5682.is_legacy_cpu) {
565 		/*
566 		 * Currently, On SKL+ platforms MCLK will be turned off in sof
567 		 * runtime suspended, and it will go into runtime suspended
568 		 * right after playback is stop. However, rt5682 will output
569 		 * static noise if sysclk turns off during playback. Set
570 		 * ignore_pmdown_time to power down rt5682 immediately and
571 		 * avoid the noise.
572 		 * It can be removed once we can control MCLK by driver.
573 		 */
574 		ctx->codec_link->ignore_pmdown_time = 1;
575 	}
576 
577 	if (ctx->amp_type == CODEC_NONE)
578 		return 0;
579 
580 	if (!ctx->amp_link) {
581 		dev_err(dev, "amp link not available");
582 		return -EINVAL;
583 	}
584 
585 	/* codec-specific fields for speaker amplifier */
586 	switch (ctx->amp_type) {
587 	case CODEC_MAX98357A:
588 		max_98357a_dai_link(ctx->amp_link);
589 		break;
590 	case CODEC_MAX98360A:
591 		max_98360a_dai_link(ctx->amp_link);
592 		break;
593 	case CODEC_MAX98373:
594 		max_98373_dai_link(dev, ctx->amp_link);
595 		break;
596 	case CODEC_MAX98390:
597 		max_98390_dai_link(dev, ctx->amp_link);
598 		break;
599 	case CODEC_RT1011:
600 		sof_rt1011_dai_link(dev, ctx->amp_link);
601 		break;
602 	case CODEC_RT1015:
603 		sof_rt1015_dai_link(ctx->amp_link);
604 		break;
605 	case CODEC_RT1015P:
606 		sof_rt1015p_dai_link(ctx->amp_link);
607 		break;
608 	case CODEC_RT1019P:
609 		sof_rt1019p_dai_link(ctx->amp_link);
610 		break;
611 	case CODEC_RT5650:
612 		/* use AIF2 to support speaker pipeline */
613 		ctx->amp_link->codecs = &rt5650_components[1];
614 		ctx->amp_link->num_codecs = 1;
615 		ctx->amp_link->init = rt5650_spk_init;
616 		ctx->amp_link->ops = &sof_rt5682_ops;
617 		break;
618 	default:
619 		dev_err(dev, "invalid amp type %d\n", ctx->amp_type);
620 		return -EINVAL;
621 	}
622 
623 	return 0;
624 }
625 
626 #define GLK_LINK_ORDER	SOF_LINK_ORDER(SOF_LINK_AMP,         \
627 					SOF_LINK_CODEC,      \
628 					SOF_LINK_DMIC01,     \
629 					SOF_LINK_IDISP_HDMI, \
630 					SOF_LINK_NONE,       \
631 					SOF_LINK_NONE,       \
632 					SOF_LINK_NONE)
633 
634 static int sof_audio_probe(struct platform_device *pdev)
635 {
636 	struct snd_soc_acpi_mach *mach = pdev->dev.platform_data;
637 	struct sof_card_private *ctx;
638 	char *card_name;
639 	int ret;
640 
641 	if (pdev->id_entry && pdev->id_entry->driver_data)
642 		sof_rt5682_quirk = (unsigned long)pdev->id_entry->driver_data;
643 
644 	dmi_check_system(sof_rt5682_quirk_table);
645 
646 	dev_dbg(&pdev->dev, "sof_rt5682_quirk = %lx\n", sof_rt5682_quirk);
647 
648 	/* initialize ctx with board quirk */
649 	ctx = sof_intel_board_get_ctx(&pdev->dev, sof_rt5682_quirk);
650 	if (!ctx)
651 		return -ENOMEM;
652 
653 	if (ctx->codec_type == CODEC_RT5650) {
654 		card_name = devm_kstrdup(&pdev->dev, "rt5650", GFP_KERNEL);
655 		if (!card_name)
656 			return -ENOMEM;
657 
658 		sof_audio_card_rt5682.name = card_name;
659 
660 		/* create speaker dai link also */
661 		if (ctx->amp_type == CODEC_NONE)
662 			ctx->amp_type = CODEC_RT5650;
663 	}
664 
665 	if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
666 		ctx->hdmi.idisp_codec = true;
667 
668 	if (soc_intel_is_byt() || soc_intel_is_cht()) {
669 		ctx->rt5682.is_legacy_cpu = true;
670 		ctx->dmic_be_num = 0;
671 		/* HDMI is not supported by SOF on Baytrail/CherryTrail */
672 		ctx->hdmi_num = 0;
673 	} else if (soc_intel_is_glk()) {
674 		/* dmic16k not support */
675 		ctx->dmic_be_num = 1;
676 
677 		/* overwrite the DAI link order for GLK boards */
678 		ctx->link_order_overwrite = GLK_LINK_ORDER;
679 
680 		/* backward-compatible with existing devices */
681 		switch (ctx->amp_type) {
682 		case CODEC_MAX98357A:
683 			card_name = devm_kstrdup(&pdev->dev, "glkrt5682max",
684 						 GFP_KERNEL);
685 			if (!card_name)
686 				return -ENOMEM;
687 
688 			sof_audio_card_rt5682.name = card_name;
689 			break;
690 		default:
691 			break;
692 		}
693 	} else if (soc_intel_is_cml()) {
694 		/* backward-compatible with existing devices */
695 		switch (ctx->amp_type) {
696 		case CODEC_RT1011:
697 			card_name = devm_kstrdup(&pdev->dev, "cml_rt1011_rt5682",
698 						 GFP_KERNEL);
699 			if (!card_name)
700 				return -ENOMEM;
701 
702 			sof_audio_card_rt5682.name = card_name;
703 			break;
704 		default:
705 			break;
706 		}
707 	}
708 
709 	if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) {
710 		ctx->rt5682.mclk_en = true;
711 
712 		/* need to get main clock from pmc */
713 		if (ctx->rt5682.is_legacy_cpu) {
714 			ctx->rt5682.mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
715 			if (IS_ERR(ctx->rt5682.mclk)) {
716 				ret = PTR_ERR(ctx->rt5682.mclk);
717 
718 				dev_err(&pdev->dev,
719 					"Failed to get MCLK from pmc_plt_clk_3: %d\n",
720 					ret);
721 				return ret;
722 			}
723 
724 			ret = clk_prepare_enable(ctx->rt5682.mclk);
725 			if (ret < 0) {
726 				dev_err(&pdev->dev,
727 					"could not configure MCLK state");
728 				return ret;
729 			}
730 		}
731 	}
732 
733 	/* update dai_link */
734 	ret = sof_card_dai_links_create(&pdev->dev, &sof_audio_card_rt5682, ctx);
735 	if (ret)
736 		return ret;
737 
738 	/* update codec_conf */
739 	switch (ctx->amp_type) {
740 	case CODEC_MAX98373:
741 		max_98373_set_codec_conf(&sof_audio_card_rt5682);
742 		break;
743 	case CODEC_MAX98390:
744 		max_98390_set_codec_conf(&pdev->dev, &sof_audio_card_rt5682);
745 		break;
746 	case CODEC_RT1011:
747 		sof_rt1011_codec_conf(&pdev->dev, &sof_audio_card_rt5682);
748 		break;
749 	case CODEC_RT1015:
750 		sof_rt1015_codec_conf(&sof_audio_card_rt5682);
751 		break;
752 	case CODEC_RT1015P:
753 		sof_rt1015p_codec_conf(&sof_audio_card_rt5682);
754 		break;
755 	case CODEC_MAX98357A:
756 	case CODEC_MAX98360A:
757 	case CODEC_RT1019P:
758 	case CODEC_RT5650:
759 	case CODEC_NONE:
760 		/* no codec conf required */
761 		break;
762 	default:
763 		dev_err(&pdev->dev, "invalid amp type %d\n", ctx->amp_type);
764 		return -EINVAL;
765 	}
766 
767 	sof_audio_card_rt5682.dev = &pdev->dev;
768 
769 	/* set platform name for each dailink */
770 	ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_rt5682,
771 						    mach->mach_params.platform);
772 	if (ret)
773 		return ret;
774 
775 	snd_soc_card_set_drvdata(&sof_audio_card_rt5682, ctx);
776 
777 	return devm_snd_soc_register_card(&pdev->dev,
778 					  &sof_audio_card_rt5682);
779 }
780 
781 static const struct platform_device_id board_ids[] = {
782 	{
783 		.name = "sof_rt5682",
784 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
785 					SOF_SSP_PORT_CODEC(2)),
786 	},
787 	{
788 		.name = "glk_rt5682_def",
789 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
790 					SOF_SSP_PORT_CODEC(2) |
791 					SOF_SSP_PORT_AMP(1)),
792 	},
793 	{
794 		.name = "icl_rt5682_def",
795 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
796 					SOF_SSP_PORT_CODEC(0)),
797 	},
798 	{
799 		.name = "cml_rt5682_def",
800 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
801 					SOF_SSP_PORT_CODEC(0) |
802 					SOF_SSP_PORT_AMP(1)),
803 	},
804 	{
805 		.name = "jsl_rt5682_def",
806 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
807 					SOF_SSP_PORT_CODEC(0) |
808 					SOF_SSP_PORT_AMP(1)),
809 	},
810 	{
811 		.name = "tgl_rt5682_def",
812 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
813 					SOF_SSP_PORT_CODEC(0) |
814 					SOF_SSP_PORT_AMP(1) |
815 					SOF_NUM_IDISP_HDMI(4) |
816 					SOF_SSP_PORT_BT_OFFLOAD(2) |
817 					SOF_BT_OFFLOAD_PRESENT),
818 	},
819 	{
820 		.name = "adl_rt5682_def",
821 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
822 					SOF_SSP_PORT_CODEC(0) |
823 					SOF_SSP_PORT_AMP(1) |
824 					SOF_NUM_IDISP_HDMI(4) |
825 					SOF_SSP_PORT_BT_OFFLOAD(2) |
826 					SOF_BT_OFFLOAD_PRESENT),
827 	},
828 	{
829 		.name = "adl_mx98357_rt5682",
830 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
831 					SOF_SSP_PORT_CODEC(0) |
832 					SOF_SSP_PORT_AMP(2) |
833 					SOF_NUM_IDISP_HDMI(4)),
834 	},
835 	{
836 		.name = "adl_rt5682_c1_h02",
837 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
838 					SOF_SSP_PORT_CODEC(1) |
839 					/* SSP 0 and SSP 2 are used for HDMI IN */
840 					SOF_SSP_MASK_HDMI_CAPTURE(0x5)),
841 	},
842 	{
843 		.name = "rpl_mx98357_rt5682",
844 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
845 					SOF_SSP_PORT_CODEC(0) |
846 					SOF_SSP_PORT_AMP(2) |
847 					SOF_NUM_IDISP_HDMI(4)),
848 	},
849 	{
850 		.name = "rpl_rt5682_def",
851 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
852 					SOF_SSP_PORT_CODEC(0) |
853 					SOF_SSP_PORT_AMP(1) |
854 					SOF_NUM_IDISP_HDMI(4) |
855 					SOF_SSP_PORT_BT_OFFLOAD(2) |
856 					SOF_BT_OFFLOAD_PRESENT),
857 	},
858 	{
859 		.name = "rpl_rt5682_c1_h02",
860 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
861 					SOF_SSP_PORT_CODEC(1) |
862 					/* SSP 0 and SSP 2 are used for HDMI IN */
863 					SOF_SSP_MASK_HDMI_CAPTURE(0x5)),
864 	},
865 	{
866 		.name = "mtl_rt5682_def",
867 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
868 					SOF_SSP_PORT_CODEC(0) |
869 					SOF_SSP_PORT_AMP(1) |
870 					SOF_SSP_PORT_BT_OFFLOAD(2) |
871 					SOF_BT_OFFLOAD_PRESENT),
872 	},
873 	{ }
874 };
875 MODULE_DEVICE_TABLE(platform, board_ids);
876 
877 static struct platform_driver sof_audio = {
878 	.probe = sof_audio_probe,
879 	.driver = {
880 		.name = "sof_rt5682",
881 		.pm = &snd_soc_pm_ops,
882 	},
883 	.id_table = board_ids,
884 };
885 module_platform_driver(sof_audio)
886 
887 /* Module information */
888 MODULE_DESCRIPTION("SOF Audio Machine driver");
889 MODULE_AUTHOR("Bard Liao <bard.liao@intel.com>");
890 MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
891 MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
892 MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
893 MODULE_LICENSE("GPL v2");
894 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS);
895 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);
896 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON);
897