1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright(c) 2019 Intel Corporation.
3 
4 /*
5  * Intel SOF Machine Driver with Realtek rt5682 Codec
6  * and speaker codec MAX98357A
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/rt5682.h>
20 #include <sound/soc-acpi.h>
21 #include "../../codecs/rt5682.h"
22 #include "../../codecs/hdac_hdmi.h"
23 #include "../common/soc-intel-quirks.h"
24 #include "hda_dsp_common.h"
25 
26 #define NAME_SIZE 32
27 
28 #define SOF_RT5682_SSP_CODEC(quirk)		((quirk) & GENMASK(2, 0))
29 #define SOF_RT5682_SSP_CODEC_MASK			(GENMASK(2, 0))
30 #define SOF_RT5682_MCLK_EN			BIT(3)
31 #define SOF_RT5682_MCLK_24MHZ			BIT(4)
32 #define SOF_SPEAKER_AMP_PRESENT		BIT(5)
33 #define SOF_RT5682_SSP_AMP_SHIFT		6
34 #define SOF_RT5682_SSP_AMP_MASK                 (GENMASK(8, 6))
35 #define SOF_RT5682_SSP_AMP(quirk)	\
36 	(((quirk) << SOF_RT5682_SSP_AMP_SHIFT) & SOF_RT5682_SSP_AMP_MASK)
37 #define SOF_RT5682_MCLK_BYTCHT_EN		BIT(9)
38 
39 /* Default: MCLK on, MCLK 19.2M, SSP0  */
40 static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
41 					SOF_RT5682_SSP_CODEC(0);
42 
43 static int is_legacy_cpu;
44 
45 static struct snd_soc_jack sof_hdmi[3];
46 
47 struct sof_hdmi_pcm {
48 	struct list_head head;
49 	struct snd_soc_dai *codec_dai;
50 	int device;
51 };
52 
53 struct sof_card_private {
54 	struct clk *mclk;
55 	struct snd_soc_jack sof_headset;
56 	struct list_head hdmi_pcm_list;
57 	bool common_hdmi_codec_drv;
58 };
59 
60 static int sof_rt5682_quirk_cb(const struct dmi_system_id *id)
61 {
62 	sof_rt5682_quirk = (unsigned long)id->driver_data;
63 	return 1;
64 }
65 
66 static const struct dmi_system_id sof_rt5682_quirk_table[] = {
67 	{
68 		.callback = sof_rt5682_quirk_cb,
69 		.matches = {
70 			DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
71 			DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max"),
72 		},
73 		.driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)),
74 	},
75 	{
76 		.callback = sof_rt5682_quirk_cb,
77 		.matches = {
78 			DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
79 			DMI_MATCH(DMI_PRODUCT_NAME, "UP-CHT01"),
80 		},
81 		.driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)),
82 	},
83 	{
84 		.callback = sof_rt5682_quirk_cb,
85 		.matches = {
86 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
87 			DMI_MATCH(DMI_PRODUCT_NAME, "WhiskeyLake Client"),
88 		},
89 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
90 					SOF_RT5682_MCLK_24MHZ |
91 					SOF_RT5682_SSP_CODEC(1)),
92 	},
93 	{
94 		.callback = sof_rt5682_quirk_cb,
95 		.matches = {
96 			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Hatch"),
97 		},
98 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
99 					SOF_RT5682_MCLK_24MHZ |
100 					SOF_RT5682_SSP_CODEC(0) |
101 					SOF_SPEAKER_AMP_PRESENT |
102 					SOF_RT5682_SSP_AMP(1)),
103 	},
104 	{
105 		.callback = sof_rt5682_quirk_cb,
106 		.matches = {
107 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
108 			DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"),
109 		},
110 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
111 					SOF_RT5682_SSP_CODEC(0)),
112 	},
113 	{}
114 };
115 
116 static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd)
117 {
118 	struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
119 	struct snd_soc_dai *dai = rtd->codec_dai;
120 	struct sof_hdmi_pcm *pcm;
121 
122 	pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
123 	if (!pcm)
124 		return -ENOMEM;
125 
126 	/* dai_link id is 1:1 mapped to the PCM device */
127 	pcm->device = rtd->dai_link->id;
128 	pcm->codec_dai = dai;
129 
130 	list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
131 
132 	return 0;
133 }
134 
135 static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
136 {
137 	struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
138 	struct snd_soc_component *component = rtd->codec_dai->component;
139 	struct snd_soc_jack *jack;
140 	int ret;
141 
142 	/* need to enable ASRC function for 24MHz mclk rate */
143 	if ((sof_rt5682_quirk & SOF_RT5682_MCLK_EN) &&
144 	    (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ)) {
145 		rt5682_sel_asrc_clk_src(component, RT5682_DA_STEREO1_FILTER |
146 					RT5682_AD_STEREO1_FILTER,
147 					RT5682_CLK_SEL_I2S1_ASRC);
148 	}
149 
150 	if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
151 		/*
152 		 * The firmware might enable the clock at
153 		 * boot (this information may or may not
154 		 * be reflected in the enable clock register).
155 		 * To change the rate we must disable the clock
156 		 * first to cover these cases. Due to common
157 		 * clock framework restrictions that do not allow
158 		 * to disable a clock that has not been enabled,
159 		 * we need to enable the clock first.
160 		 */
161 		ret = clk_prepare_enable(ctx->mclk);
162 		if (!ret)
163 			clk_disable_unprepare(ctx->mclk);
164 
165 		ret = clk_set_rate(ctx->mclk, 19200000);
166 
167 		if (ret)
168 			dev_err(rtd->dev, "unable to set MCLK rate\n");
169 	}
170 
171 	/*
172 	 * Headset buttons map to the google Reference headset.
173 	 * These can be configured by userspace.
174 	 */
175 	ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
176 				    SND_JACK_HEADSET | SND_JACK_BTN_0 |
177 				    SND_JACK_BTN_1 | SND_JACK_BTN_2 |
178 				    SND_JACK_BTN_3,
179 				    &ctx->sof_headset, NULL, 0);
180 	if (ret) {
181 		dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
182 		return ret;
183 	}
184 
185 	jack = &ctx->sof_headset;
186 
187 	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
188 	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
189 	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
190 	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
191 	ret = snd_soc_component_set_jack(component, jack, NULL);
192 
193 	if (ret) {
194 		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
195 		return ret;
196 	}
197 
198 	return ret;
199 };
200 
201 static int sof_rt5682_hw_params(struct snd_pcm_substream *substream,
202 				struct snd_pcm_hw_params *params)
203 {
204 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
205 	struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
206 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
207 	int clk_id, clk_freq, pll_out, ret;
208 
209 	if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) {
210 		if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
211 			ret = clk_prepare_enable(ctx->mclk);
212 			if (ret < 0) {
213 				dev_err(rtd->dev,
214 					"could not configure MCLK state");
215 				return ret;
216 			}
217 		}
218 
219 		clk_id = RT5682_PLL1_S_MCLK;
220 		if (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ)
221 			clk_freq = 24000000;
222 		else
223 			clk_freq = 19200000;
224 	} else {
225 		clk_id = RT5682_PLL1_S_BCLK1;
226 		clk_freq = params_rate(params) * 50;
227 	}
228 
229 	pll_out = params_rate(params) * 512;
230 
231 	ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out);
232 	if (ret < 0)
233 		dev_err(rtd->dev, "snd_soc_dai_set_pll err = %d\n", ret);
234 
235 	/* Configure sysclk for codec */
236 	ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1,
237 				     pll_out, SND_SOC_CLOCK_IN);
238 	if (ret < 0)
239 		dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
240 
241 	/*
242 	 * slot_width should equal or large than data length, set them
243 	 * be the same
244 	 */
245 	ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0, 0x0, 2,
246 				       params_width(params));
247 	if (ret < 0) {
248 		dev_err(rtd->dev, "set TDM slot err:%d\n", ret);
249 		return ret;
250 	}
251 
252 	return ret;
253 }
254 
255 static struct snd_soc_ops sof_rt5682_ops = {
256 	.hw_params = sof_rt5682_hw_params,
257 };
258 
259 static struct snd_soc_dai_link_component platform_component[] = {
260 	{
261 		/* name might be overridden during probe */
262 		.name = "0000:00:1f.3"
263 	}
264 };
265 
266 static int sof_card_late_probe(struct snd_soc_card *card)
267 {
268 	struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
269 	struct snd_soc_component *component = NULL;
270 	char jack_name[NAME_SIZE];
271 	struct sof_hdmi_pcm *pcm;
272 	int err = 0;
273 	int i = 0;
274 
275 	/* HDMI is not supported by SOF on Baytrail/CherryTrail */
276 	if (is_legacy_cpu)
277 		return 0;
278 
279 	pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm,
280 			       head);
281 	component = pcm->codec_dai->component;
282 
283 	if (ctx->common_hdmi_codec_drv)
284 		return hda_dsp_hdmi_build_controls(card, component);
285 
286 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
287 		component = pcm->codec_dai->component;
288 		snprintf(jack_name, sizeof(jack_name),
289 			 "HDMI/DP, pcm=%d Jack", pcm->device);
290 		err = snd_soc_card_jack_new(card, jack_name,
291 					    SND_JACK_AVOUT, &sof_hdmi[i],
292 					    NULL, 0);
293 
294 		if (err)
295 			return err;
296 
297 		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
298 					  &sof_hdmi[i]);
299 		if (err < 0)
300 			return err;
301 
302 		i++;
303 	}
304 	if (!component)
305 		return -EINVAL;
306 
307 	return hdac_hdmi_jack_port_init(component, &card->dapm);
308 }
309 
310 static const struct snd_kcontrol_new sof_controls[] = {
311 	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
312 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
313 	SOC_DAPM_PIN_SWITCH("Spk"),
314 };
315 
316 static const struct snd_soc_dapm_widget sof_widgets[] = {
317 	SND_SOC_DAPM_HP("Headphone Jack", NULL),
318 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
319 	SND_SOC_DAPM_SPK("Spk", NULL),
320 };
321 
322 static const struct snd_soc_dapm_widget dmic_widgets[] = {
323 	SND_SOC_DAPM_MIC("SoC DMIC", NULL),
324 };
325 
326 static const struct snd_soc_dapm_route sof_map[] = {
327 	/* HP jack connectors - unknown if we have jack detection */
328 	{ "Headphone Jack", NULL, "HPOL" },
329 	{ "Headphone Jack", NULL, "HPOR" },
330 
331 	/* other jacks */
332 	{ "IN1P", NULL, "Headset Mic" },
333 };
334 
335 static const struct snd_soc_dapm_route speaker_map[] = {
336 	/* speaker */
337 	{ "Spk", NULL, "Speaker" },
338 };
339 
340 static const struct snd_soc_dapm_route dmic_map[] = {
341 	/* digital mics */
342 	{"DMic", NULL, "SoC DMIC"},
343 };
344 
345 static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd)
346 {
347 	struct snd_soc_card *card = rtd->card;
348 	int ret;
349 
350 	ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map,
351 				      ARRAY_SIZE(speaker_map));
352 
353 	if (ret)
354 		dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret);
355 	return ret;
356 }
357 
358 static int dmic_init(struct snd_soc_pcm_runtime *rtd)
359 {
360 	struct snd_soc_card *card = rtd->card;
361 	int ret;
362 
363 	ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets,
364 					ARRAY_SIZE(dmic_widgets));
365 	if (ret) {
366 		dev_err(card->dev, "DMic widget addition failed: %d\n", ret);
367 		/* Don't need to add routes if widget addition failed */
368 		return ret;
369 	}
370 
371 	ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map,
372 				      ARRAY_SIZE(dmic_map));
373 
374 	if (ret)
375 		dev_err(card->dev, "DMic map addition failed: %d\n", ret);
376 
377 	return ret;
378 }
379 
380 /* sof audio machine driver for rt5682 codec */
381 static struct snd_soc_card sof_audio_card_rt5682 = {
382 	.name = "rt5682", /* the sof- prefix is added by the core */
383 	.owner = THIS_MODULE,
384 	.controls = sof_controls,
385 	.num_controls = ARRAY_SIZE(sof_controls),
386 	.dapm_widgets = sof_widgets,
387 	.num_dapm_widgets = ARRAY_SIZE(sof_widgets),
388 	.dapm_routes = sof_map,
389 	.num_dapm_routes = ARRAY_SIZE(sof_map),
390 	.fully_routed = true,
391 	.late_probe = sof_card_late_probe,
392 };
393 
394 static struct snd_soc_dai_link_component rt5682_component[] = {
395 	{
396 		.name = "i2c-10EC5682:00",
397 		.dai_name = "rt5682-aif1",
398 	}
399 };
400 
401 static struct snd_soc_dai_link_component dmic_component[] = {
402 	{
403 		.name = "dmic-codec",
404 		.dai_name = "dmic-hifi",
405 	}
406 };
407 
408 static struct snd_soc_dai_link_component max98357a_component[] = {
409 	{
410 		.name = "MX98357A:00",
411 		.dai_name = "HiFi",
412 	}
413 };
414 
415 static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
416 							  int ssp_codec,
417 							  int ssp_amp,
418 							  int dmic_be_num,
419 							  int hdmi_num)
420 {
421 	struct snd_soc_dai_link_component *idisp_components;
422 	struct snd_soc_dai_link_component *cpus;
423 	struct snd_soc_dai_link *links;
424 	int i, id = 0;
425 
426 	links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) *
427 			     sof_audio_card_rt5682.num_links, GFP_KERNEL);
428 	cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component) *
429 			     sof_audio_card_rt5682.num_links, GFP_KERNEL);
430 	if (!links || !cpus)
431 		goto devm_err;
432 
433 	/* codec SSP */
434 	links[id].name = devm_kasprintf(dev, GFP_KERNEL,
435 					"SSP%d-Codec", ssp_codec);
436 	if (!links[id].name)
437 		goto devm_err;
438 
439 	links[id].id = id;
440 	links[id].codecs = rt5682_component;
441 	links[id].num_codecs = ARRAY_SIZE(rt5682_component);
442 	links[id].platforms = platform_component;
443 	links[id].num_platforms = ARRAY_SIZE(platform_component);
444 	links[id].init = sof_rt5682_codec_init;
445 	links[id].ops = &sof_rt5682_ops;
446 	links[id].nonatomic = true;
447 	links[id].dpcm_playback = 1;
448 	links[id].dpcm_capture = 1;
449 	links[id].no_pcm = 1;
450 	links[id].cpus = &cpus[id];
451 	links[id].num_cpus = 1;
452 	if (is_legacy_cpu) {
453 		links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
454 							  "ssp%d-port",
455 							  ssp_codec);
456 		if (!links[id].cpus->dai_name)
457 			goto devm_err;
458 	} else {
459 		/*
460 		 * Currently, On SKL+ platforms MCLK will be turned off in sof
461 		 * runtime suspended, and it will go into runtime suspended
462 		 * right after playback is stop. However, rt5682 will output
463 		 * static noise if sysclk turns off during playback. Set
464 		 * ignore_pmdown_time to power down rt5682 immediately and
465 		 * avoid the noise.
466 		 * It can be removed once we can control MCLK by driver.
467 		 */
468 		links[id].ignore_pmdown_time = 1;
469 		links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
470 							  "SSP%d Pin",
471 							  ssp_codec);
472 		if (!links[id].cpus->dai_name)
473 			goto devm_err;
474 	}
475 	id++;
476 
477 	/* dmic */
478 	if (dmic_be_num > 0) {
479 		/* at least we have dmic01 */
480 		links[id].name = "dmic01";
481 		links[id].cpus = &cpus[id];
482 		links[id].cpus->dai_name = "DMIC01 Pin";
483 		links[id].init = dmic_init;
484 		if (dmic_be_num > 1) {
485 			/* set up 2 BE links at most */
486 			links[id + 1].name = "dmic16k";
487 			links[id + 1].cpus = &cpus[id + 1];
488 			links[id + 1].cpus->dai_name = "DMIC16k Pin";
489 			dmic_be_num = 2;
490 		}
491 	}
492 
493 	for (i = 0; i < dmic_be_num; i++) {
494 		links[id].id = id;
495 		links[id].num_cpus = 1;
496 		links[id].codecs = dmic_component;
497 		links[id].num_codecs = ARRAY_SIZE(dmic_component);
498 		links[id].platforms = platform_component;
499 		links[id].num_platforms = ARRAY_SIZE(platform_component);
500 		links[id].ignore_suspend = 1;
501 		links[id].dpcm_capture = 1;
502 		links[id].no_pcm = 1;
503 		id++;
504 	}
505 
506 	/* HDMI */
507 	if (hdmi_num > 0) {
508 		idisp_components = devm_kzalloc(dev,
509 				   sizeof(struct snd_soc_dai_link_component) *
510 				   hdmi_num, GFP_KERNEL);
511 		if (!idisp_components)
512 			goto devm_err;
513 	}
514 	for (i = 1; i <= hdmi_num; i++) {
515 		links[id].name = devm_kasprintf(dev, GFP_KERNEL,
516 						"iDisp%d", i);
517 		if (!links[id].name)
518 			goto devm_err;
519 
520 		links[id].id = id;
521 		links[id].cpus = &cpus[id];
522 		links[id].num_cpus = 1;
523 		links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
524 							  "iDisp%d Pin", i);
525 		if (!links[id].cpus->dai_name)
526 			goto devm_err;
527 
528 		idisp_components[i - 1].name = "ehdaudio0D2";
529 		idisp_components[i - 1].dai_name = devm_kasprintf(dev,
530 								  GFP_KERNEL,
531 								  "intel-hdmi-hifi%d",
532 								  i);
533 		if (!idisp_components[i - 1].dai_name)
534 			goto devm_err;
535 
536 		links[id].codecs = &idisp_components[i - 1];
537 		links[id].num_codecs = 1;
538 		links[id].platforms = platform_component;
539 		links[id].num_platforms = ARRAY_SIZE(platform_component);
540 		links[id].init = sof_hdmi_init;
541 		links[id].dpcm_playback = 1;
542 		links[id].no_pcm = 1;
543 		id++;
544 	}
545 
546 	/* speaker amp */
547 	if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) {
548 		links[id].name = devm_kasprintf(dev, GFP_KERNEL,
549 						"SSP%d-Codec", ssp_amp);
550 		if (!links[id].name)
551 			goto devm_err;
552 
553 		links[id].id = id;
554 		links[id].codecs = max98357a_component;
555 		links[id].num_codecs = ARRAY_SIZE(max98357a_component);
556 		links[id].platforms = platform_component;
557 		links[id].num_platforms = ARRAY_SIZE(platform_component);
558 		links[id].init = speaker_codec_init,
559 		links[id].nonatomic = true;
560 		links[id].dpcm_playback = 1;
561 		links[id].no_pcm = 1;
562 		links[id].cpus = &cpus[id];
563 		links[id].num_cpus = 1;
564 		if (is_legacy_cpu) {
565 			links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
566 								  "ssp%d-port",
567 								  ssp_amp);
568 			if (!links[id].cpus->dai_name)
569 				goto devm_err;
570 
571 		} else {
572 			links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
573 								  "SSP%d Pin",
574 								  ssp_amp);
575 			if (!links[id].cpus->dai_name)
576 				goto devm_err;
577 		}
578 	}
579 
580 	return links;
581 devm_err:
582 	return NULL;
583 }
584 
585 static int sof_audio_probe(struct platform_device *pdev)
586 {
587 	struct snd_soc_dai_link *dai_links;
588 	struct snd_soc_acpi_mach *mach;
589 	struct sof_card_private *ctx;
590 	int dmic_be_num, hdmi_num;
591 	int ret, ssp_amp, ssp_codec;
592 
593 	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
594 	if (!ctx)
595 		return -ENOMEM;
596 
597 	if (soc_intel_is_byt() || soc_intel_is_cht()) {
598 		is_legacy_cpu = 1;
599 		dmic_be_num = 0;
600 		hdmi_num = 0;
601 		/* default quirk for legacy cpu */
602 		sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
603 						SOF_RT5682_MCLK_BYTCHT_EN |
604 						SOF_RT5682_SSP_CODEC(2);
605 	} else {
606 		dmic_be_num = 2;
607 		hdmi_num = 3;
608 	}
609 
610 	dmi_check_system(sof_rt5682_quirk_table);
611 
612 	/* need to get main clock from pmc */
613 	if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
614 		ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
615 		if (IS_ERR(ctx->mclk)) {
616 			ret = PTR_ERR(ctx->mclk);
617 
618 			dev_err(&pdev->dev,
619 				"Failed to get MCLK from pmc_plt_clk_3: %d\n",
620 				ret);
621 			return ret;
622 		}
623 
624 		ret = clk_prepare_enable(ctx->mclk);
625 		if (ret < 0) {
626 			dev_err(&pdev->dev,
627 				"could not configure MCLK state");
628 			return ret;
629 		}
630 	}
631 
632 	dev_dbg(&pdev->dev, "sof_rt5682_quirk = %lx\n", sof_rt5682_quirk);
633 
634 	ssp_amp = (sof_rt5682_quirk & SOF_RT5682_SSP_AMP_MASK) >>
635 			SOF_RT5682_SSP_AMP_SHIFT;
636 
637 	ssp_codec = sof_rt5682_quirk & SOF_RT5682_SSP_CODEC_MASK;
638 
639 	/* compute number of dai links */
640 	sof_audio_card_rt5682.num_links = 1 + dmic_be_num + hdmi_num;
641 
642 	if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT)
643 		sof_audio_card_rt5682.num_links++;
644 
645 	dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp,
646 					      dmic_be_num, hdmi_num);
647 	if (!dai_links)
648 		return -ENOMEM;
649 
650 	sof_audio_card_rt5682.dai_link = dai_links;
651 
652 	INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
653 
654 	sof_audio_card_rt5682.dev = &pdev->dev;
655 	mach = (&pdev->dev)->platform_data;
656 
657 	/* set platform name for each dailink */
658 	ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_rt5682,
659 						    mach->mach_params.platform);
660 	if (ret)
661 		return ret;
662 
663 	ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
664 
665 	snd_soc_card_set_drvdata(&sof_audio_card_rt5682, ctx);
666 
667 	return devm_snd_soc_register_card(&pdev->dev,
668 					  &sof_audio_card_rt5682);
669 }
670 
671 static int sof_rt5682_remove(struct platform_device *pdev)
672 {
673 	struct snd_soc_card *card = platform_get_drvdata(pdev);
674 	struct snd_soc_component *component = NULL;
675 
676 	for_each_card_components(card, component) {
677 		if (!strcmp(component->name, rt5682_component[0].name)) {
678 			snd_soc_component_set_jack(component, NULL, NULL);
679 			break;
680 		}
681 	}
682 
683 	return 0;
684 }
685 
686 static struct platform_driver sof_audio = {
687 	.probe = sof_audio_probe,
688 	.remove = sof_rt5682_remove,
689 	.driver = {
690 		.name = "sof_rt5682",
691 		.pm = &snd_soc_pm_ops,
692 	},
693 };
694 module_platform_driver(sof_audio)
695 
696 /* Module information */
697 MODULE_DESCRIPTION("SOF Audio Machine driver");
698 MODULE_AUTHOR("Bard Liao <bard.liao@intel.com>");
699 MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
700 MODULE_LICENSE("GPL v2");
701 MODULE_ALIAS("platform:sof_rt5682");
702