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