xref: /linux/sound/soc/intel/boards/sof_rt5682.c (revision 8e07e0e3964ca4e23ce7b68e2096fe660a888942)
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 #include "sof_ssp_common.h"
31 
32 #define SOF_RT5682_SSP_CODEC(quirk)		((quirk) & GENMASK(2, 0))
33 #define SOF_RT5682_SSP_CODEC_MASK			(GENMASK(2, 0))
34 #define SOF_RT5682_MCLK_EN			BIT(3)
35 #define SOF_RT5682_SSP_AMP_SHIFT		6
36 #define SOF_RT5682_SSP_AMP_MASK                 (GENMASK(8, 6))
37 #define SOF_RT5682_SSP_AMP(quirk)	\
38 	(((quirk) << SOF_RT5682_SSP_AMP_SHIFT) & SOF_RT5682_SSP_AMP_MASK)
39 #define SOF_RT5682_MCLK_BYTCHT_EN		BIT(9)
40 #define SOF_RT5682_NUM_HDMIDEV_SHIFT		10
41 #define SOF_RT5682_NUM_HDMIDEV_MASK		(GENMASK(12, 10))
42 #define SOF_RT5682_NUM_HDMIDEV(quirk)	\
43 	((quirk << SOF_RT5682_NUM_HDMIDEV_SHIFT) & SOF_RT5682_NUM_HDMIDEV_MASK)
44 
45 /* BT audio offload: reserve 3 bits for future */
46 #define SOF_BT_OFFLOAD_SSP_SHIFT		19
47 #define SOF_BT_OFFLOAD_SSP_MASK		(GENMASK(21, 19))
48 #define SOF_BT_OFFLOAD_SSP(quirk)	\
49 	(((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK)
50 #define SOF_SSP_BT_OFFLOAD_PRESENT		BIT(22)
51 
52 /* HDMI capture*/
53 #define SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT  27
54 #define SOF_SSP_HDMI_CAPTURE_PRESENT_MASK (GENMASK(30, 27))
55 #define SOF_HDMI_CAPTURE_SSP_MASK(quirk)   \
56 	(((quirk) << SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT) & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK)
57 
58 /* Default: MCLK on, MCLK 19.2M, SSP0  */
59 static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
60 					SOF_RT5682_SSP_CODEC(0);
61 
62 static int sof_rt5682_quirk_cb(const struct dmi_system_id *id)
63 {
64 	sof_rt5682_quirk = (unsigned long)id->driver_data;
65 	return 1;
66 }
67 
68 static const struct dmi_system_id sof_rt5682_quirk_table[] = {
69 	{
70 		.callback = sof_rt5682_quirk_cb,
71 		.matches = {
72 			DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
73 			DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max"),
74 		},
75 		.driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)),
76 	},
77 	{
78 		.callback = sof_rt5682_quirk_cb,
79 		.matches = {
80 			DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
81 			DMI_MATCH(DMI_PRODUCT_NAME, "UP-CHT01"),
82 		},
83 		.driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)),
84 	},
85 	{
86 		.callback = sof_rt5682_quirk_cb,
87 		.matches = {
88 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
89 			DMI_MATCH(DMI_PRODUCT_NAME, "WhiskeyLake Client"),
90 		},
91 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
92 					SOF_RT5682_SSP_CODEC(1)),
93 	},
94 	{
95 		.callback = sof_rt5682_quirk_cb,
96 		.matches = {
97 			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Hatch"),
98 		},
99 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
100 					SOF_RT5682_SSP_CODEC(0) |
101 					SOF_RT5682_SSP_AMP(1)),
102 	},
103 	{
104 		.callback = sof_rt5682_quirk_cb,
105 		.matches = {
106 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
107 			DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"),
108 		},
109 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
110 					SOF_RT5682_SSP_CODEC(0)),
111 	},
112 	{
113 		.callback = sof_rt5682_quirk_cb,
114 		.matches = {
115 			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Volteer"),
116 			DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98373_ALC5682I_I2S_UP4"),
117 		},
118 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
119 					SOF_RT5682_SSP_CODEC(0) |
120 					SOF_RT5682_SSP_AMP(2) |
121 					SOF_RT5682_NUM_HDMIDEV(4)),
122 	},
123 	{
124 		.callback = sof_rt5682_quirk_cb,
125 		.matches = {
126 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
127 			DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"),
128 			DMI_MATCH(DMI_OEM_STRING, "AUDIO-ADL_MAX98373_ALC5682I_I2S"),
129 		},
130 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
131 					SOF_RT5682_SSP_CODEC(0) |
132 					SOF_RT5682_SSP_AMP(2) |
133 					SOF_RT5682_NUM_HDMIDEV(4)),
134 	},
135 	{
136 		.callback = sof_rt5682_quirk_cb,
137 		.matches = {
138 			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Brya"),
139 			DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98390_ALC5682I_I2S"),
140 		},
141 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
142 					SOF_RT5682_SSP_CODEC(0) |
143 					SOF_RT5682_SSP_AMP(2) |
144 					SOF_RT5682_NUM_HDMIDEV(4)),
145 	},
146 	{
147 		.callback = sof_rt5682_quirk_cb,
148 		.matches = {
149 			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Brya"),
150 			DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98360_ALC5682I_I2S_AMP_SSP2"),
151 		},
152 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
153 					SOF_RT5682_SSP_CODEC(0) |
154 					SOF_RT5682_SSP_AMP(2) |
155 					SOF_RT5682_NUM_HDMIDEV(4)),
156 	},
157 	{
158 		.callback = sof_rt5682_quirk_cb,
159 		.matches = {
160 			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"),
161 			DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98360_ALC5682I_I2S"),
162 		},
163 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
164 					SOF_RT5682_SSP_CODEC(2) |
165 					SOF_RT5682_SSP_AMP(0) |
166 					SOF_RT5682_NUM_HDMIDEV(3) |
167 					SOF_BT_OFFLOAD_SSP(1) |
168 					SOF_SSP_BT_OFFLOAD_PRESENT
169 					),
170 	},
171 	{
172 		.callback = sof_rt5682_quirk_cb,
173 		.matches = {
174 			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"),
175 			DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98360_ALC5682I_DISCRETE_I2S_BT"),
176 		},
177 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
178 					SOF_RT5682_SSP_CODEC(2) |
179 					SOF_RT5682_SSP_AMP(0) |
180 					SOF_RT5682_NUM_HDMIDEV(3) |
181 					SOF_BT_OFFLOAD_SSP(1) |
182 					SOF_SSP_BT_OFFLOAD_PRESENT
183 					),
184 	},
185 	{
186 		.callback = sof_rt5682_quirk_cb,
187 		.matches = {
188 			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"),
189 			DMI_MATCH(DMI_OEM_STRING, "AUDIO-ALC1019_ALC5682I_I2S"),
190 		},
191 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
192 					SOF_RT5682_SSP_CODEC(2) |
193 					SOF_RT5682_SSP_AMP(0) |
194 					SOF_RT5682_NUM_HDMIDEV(3)
195 					),
196 	},
197 	{
198 		.callback = sof_rt5682_quirk_cb,
199 		.matches = {
200 			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"),
201 		},
202 		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
203 					SOF_RT5682_SSP_CODEC(2) |
204 					SOF_RT5682_SSP_AMP(0) |
205 					SOF_RT5682_NUM_HDMIDEV(3) |
206 					SOF_BT_OFFLOAD_SSP(1) |
207 					SOF_SSP_BT_OFFLOAD_PRESENT
208 					),
209 	},
210 	{}
211 };
212 
213 static struct snd_soc_jack_pin jack_pins[] = {
214 	{
215 		.pin    = "Headphone Jack",
216 		.mask   = SND_JACK_HEADPHONE,
217 	},
218 	{
219 		.pin    = "Headset Mic",
220 		.mask   = SND_JACK_MICROPHONE,
221 	},
222 };
223 
224 static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
225 {
226 	struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
227 	struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
228 	struct snd_soc_jack *jack = &ctx->headset_jack;
229 	int extra_jack_data;
230 	int ret, mclk_freq;
231 
232 	if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) {
233 		mclk_freq = sof_dai_get_mclk(rtd);
234 		if (mclk_freq <= 0) {
235 			dev_err(rtd->dev, "invalid mclk freq %d\n", mclk_freq);
236 			return -EINVAL;
237 		}
238 
239 		/* need to enable ASRC function for 24MHz mclk rate */
240 		if (mclk_freq == 24000000) {
241 			dev_info(rtd->dev, "enable ASRC\n");
242 
243 			switch (ctx->codec_type) {
244 			case CODEC_RT5650:
245 				rt5645_sel_asrc_clk_src(component,
246 							RT5645_DA_STEREO_FILTER |
247 							RT5645_AD_STEREO_FILTER,
248 							RT5645_CLK_SEL_I2S1_ASRC);
249 				rt5645_sel_asrc_clk_src(component,
250 							RT5645_DA_MONO_L_FILTER |
251 							RT5645_DA_MONO_R_FILTER,
252 							RT5645_CLK_SEL_I2S2_ASRC);
253 				break;
254 			case CODEC_RT5682:
255 				rt5682_sel_asrc_clk_src(component,
256 							RT5682_DA_STEREO1_FILTER |
257 							RT5682_AD_STEREO1_FILTER,
258 							RT5682_CLK_SEL_I2S1_ASRC);
259 				break;
260 			case CODEC_RT5682S:
261 				rt5682s_sel_asrc_clk_src(component,
262 							 RT5682S_DA_STEREO1_FILTER |
263 							 RT5682S_AD_STEREO1_FILTER,
264 							 RT5682S_CLK_SEL_I2S1_ASRC);
265 				break;
266 			default:
267 				dev_err(rtd->dev, "invalid codec type %d\n",
268 					ctx->codec_type);
269 				return -EINVAL;
270 			}
271 		}
272 
273 		if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
274 			/*
275 			 * The firmware might enable the clock at
276 			 * boot (this information may or may not
277 			 * be reflected in the enable clock register).
278 			 * To change the rate we must disable the clock
279 			 * first to cover these cases. Due to common
280 			 * clock framework restrictions that do not allow
281 			 * to disable a clock that has not been enabled,
282 			 * we need to enable the clock first.
283 			 */
284 			ret = clk_prepare_enable(ctx->rt5682.mclk);
285 			if (!ret)
286 				clk_disable_unprepare(ctx->rt5682.mclk);
287 
288 			ret = clk_set_rate(ctx->rt5682.mclk, 19200000);
289 
290 			if (ret)
291 				dev_err(rtd->dev, "unable to set MCLK rate\n");
292 		}
293 	}
294 
295 	/*
296 	 * Headset buttons map to the google Reference headset.
297 	 * These can be configured by userspace.
298 	 */
299 	ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
300 					 SND_JACK_HEADSET | SND_JACK_BTN_0 |
301 					 SND_JACK_BTN_1 | SND_JACK_BTN_2 |
302 					 SND_JACK_BTN_3,
303 					 jack,
304 					 jack_pins,
305 					 ARRAY_SIZE(jack_pins));
306 	if (ret) {
307 		dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
308 		return ret;
309 	}
310 
311 	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
312 	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
313 	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
314 	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
315 
316 	if (ctx->codec_type == CODEC_RT5650) {
317 		extra_jack_data = SND_JACK_MICROPHONE | SND_JACK_BTN_0;
318 		ret = snd_soc_component_set_jack(component, jack, &extra_jack_data);
319 	} else
320 		ret = snd_soc_component_set_jack(component, jack, NULL);
321 
322 	if (ret) {
323 		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
324 		return ret;
325 	}
326 
327 	return ret;
328 };
329 
330 static void sof_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd)
331 {
332 	struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
333 
334 	snd_soc_component_set_jack(component, NULL, NULL);
335 }
336 
337 static int sof_rt5682_hw_params(struct snd_pcm_substream *substream,
338 				struct snd_pcm_hw_params *params)
339 {
340 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
341 	struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
342 	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
343 	int pll_id, pll_source, pll_in, pll_out, clk_id, ret;
344 
345 	if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) {
346 		if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
347 			ret = clk_prepare_enable(ctx->rt5682.mclk);
348 			if (ret < 0) {
349 				dev_err(rtd->dev,
350 					"could not configure MCLK state");
351 				return ret;
352 			}
353 		}
354 
355 		switch (ctx->codec_type) {
356 		case CODEC_RT5650:
357 			pll_source = RT5645_PLL1_S_MCLK;
358 			break;
359 		case CODEC_RT5682:
360 			pll_source = RT5682_PLL1_S_MCLK;
361 			break;
362 		case CODEC_RT5682S:
363 			pll_source = RT5682S_PLL_S_MCLK;
364 			break;
365 		default:
366 			dev_err(rtd->dev, "invalid codec type %d\n",
367 				ctx->codec_type);
368 			return -EINVAL;
369 		}
370 
371 		/* get the tplg configured mclk. */
372 		pll_in = sof_dai_get_mclk(rtd);
373 		if (pll_in <= 0) {
374 			dev_err(rtd->dev, "invalid mclk freq %d\n", pll_in);
375 			return -EINVAL;
376 		}
377 	} else {
378 		switch (ctx->codec_type) {
379 		case CODEC_RT5650:
380 			pll_source = RT5645_PLL1_S_BCLK1;
381 			break;
382 		case CODEC_RT5682:
383 			pll_source = RT5682_PLL1_S_BCLK1;
384 			break;
385 		case CODEC_RT5682S:
386 			pll_source = RT5682S_PLL_S_BCLK1;
387 			break;
388 		default:
389 			dev_err(rtd->dev, "invalid codec type %d\n",
390 				ctx->codec_type);
391 			return -EINVAL;
392 		}
393 
394 		pll_in = params_rate(params) * 50;
395 	}
396 
397 	switch (ctx->codec_type) {
398 	case CODEC_RT5650:
399 		pll_id = 0; /* not used in codec driver */
400 		clk_id = RT5645_SCLK_S_PLL1;
401 		break;
402 	case CODEC_RT5682:
403 		pll_id = RT5682_PLL1;
404 		clk_id = RT5682_SCLK_S_PLL1;
405 		break;
406 	case CODEC_RT5682S:
407 		pll_id = RT5682S_PLL2;
408 		clk_id = RT5682S_SCLK_S_PLL2;
409 		break;
410 	default:
411 		dev_err(rtd->dev, "invalid codec type %d\n", ctx->codec_type);
412 		return -EINVAL;
413 	}
414 
415 	pll_out = params_rate(params) * 512;
416 
417 	/* when MCLK is 512FS, no need to set PLL configuration additionally. */
418 	if (pll_in == pll_out) {
419 		switch (ctx->codec_type) {
420 		case CODEC_RT5650:
421 			clk_id = RT5645_SCLK_S_MCLK;
422 			break;
423 		case CODEC_RT5682:
424 			clk_id = RT5682_SCLK_S_MCLK;
425 			break;
426 		case CODEC_RT5682S:
427 			clk_id = RT5682S_SCLK_S_MCLK;
428 			break;
429 		default:
430 			dev_err(rtd->dev, "invalid codec type %d\n",
431 				ctx->codec_type);
432 			return -EINVAL;
433 		}
434 	} else {
435 		/* Configure pll for codec */
436 		ret = snd_soc_dai_set_pll(codec_dai, pll_id, pll_source, pll_in,
437 					  pll_out);
438 		if (ret < 0)
439 			dev_err(rtd->dev, "snd_soc_dai_set_pll err = %d\n", ret);
440 	}
441 
442 	/* Configure sysclk for codec */
443 	ret = snd_soc_dai_set_sysclk(codec_dai, clk_id,
444 				     pll_out, SND_SOC_CLOCK_IN);
445 	if (ret < 0)
446 		dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
447 
448 	/*
449 	 * slot_width should equal or large than data length, set them
450 	 * be the same
451 	 */
452 	ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0, 0x0, 2,
453 				       params_width(params));
454 	if (ret < 0) {
455 		dev_err(rtd->dev, "set TDM slot err:%d\n", ret);
456 		return ret;
457 	}
458 
459 	return ret;
460 }
461 
462 static struct snd_soc_ops sof_rt5682_ops = {
463 	.hw_params = sof_rt5682_hw_params,
464 };
465 
466 static struct snd_soc_dai_link_component platform_component[] = {
467 	{
468 		/* name might be overridden during probe */
469 		.name = "0000:00:1f.3"
470 	}
471 };
472 
473 static int sof_card_late_probe(struct snd_soc_card *card)
474 {
475 	struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
476 	struct snd_soc_dapm_context *dapm = &card->dapm;
477 	int err;
478 
479 	if (ctx->amp_type == CODEC_MAX98373) {
480 		/* Disable Left and Right Spk pin after boot */
481 		snd_soc_dapm_disable_pin(dapm, "Left Spk");
482 		snd_soc_dapm_disable_pin(dapm, "Right Spk");
483 		err = snd_soc_dapm_sync(dapm);
484 		if (err < 0)
485 			return err;
486 	}
487 
488 	return sof_intel_board_card_late_probe(card);
489 }
490 
491 static const struct snd_kcontrol_new sof_controls[] = {
492 	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
493 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
494 	SOC_DAPM_PIN_SWITCH("Left Spk"),
495 	SOC_DAPM_PIN_SWITCH("Right Spk"),
496 
497 };
498 
499 static const struct snd_soc_dapm_widget sof_widgets[] = {
500 	SND_SOC_DAPM_HP("Headphone Jack", NULL),
501 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
502 	SND_SOC_DAPM_SPK("Left Spk", NULL),
503 	SND_SOC_DAPM_SPK("Right Spk", NULL),
504 };
505 
506 static const struct snd_soc_dapm_route sof_map[] = {
507 	/* HP jack connectors - unknown if we have jack detection */
508 	{ "Headphone Jack", NULL, "HPOL" },
509 	{ "Headphone Jack", NULL, "HPOR" },
510 
511 	/* other jacks */
512 	{ "IN1P", NULL, "Headset Mic" },
513 };
514 
515 static const struct snd_soc_dapm_route rt5650_spk_dapm_routes[] = {
516 	/* speaker */
517 	{ "Left Spk", NULL, "SPOL" },
518 	{ "Right Spk", NULL, "SPOR" },
519 };
520 
521 static int rt5650_spk_init(struct snd_soc_pcm_runtime *rtd)
522 {
523 	struct snd_soc_card *card = rtd->card;
524 	int ret;
525 
526 	ret = snd_soc_dapm_add_routes(&card->dapm, rt5650_spk_dapm_routes,
527 				      ARRAY_SIZE(rt5650_spk_dapm_routes));
528 	if (ret)
529 		dev_err(rtd->dev, "fail to add dapm routes, ret=%d\n", ret);
530 
531 	return ret;
532 }
533 
534 /* sof audio machine driver for rt5682 codec */
535 static struct snd_soc_card sof_audio_card_rt5682 = {
536 	.name = "rt5682", /* the sof- prefix is added by the core */
537 	.owner = THIS_MODULE,
538 	.controls = sof_controls,
539 	.num_controls = ARRAY_SIZE(sof_controls),
540 	.dapm_widgets = sof_widgets,
541 	.num_dapm_widgets = ARRAY_SIZE(sof_widgets),
542 	.dapm_routes = sof_map,
543 	.num_dapm_routes = ARRAY_SIZE(sof_map),
544 	.fully_routed = true,
545 	.late_probe = sof_card_late_probe,
546 };
547 
548 static struct snd_soc_dai_link_component rt5682_component[] = {
549 	{
550 		.name = "i2c-10EC5682:00",
551 		.dai_name = "rt5682-aif1",
552 	}
553 };
554 
555 static struct snd_soc_dai_link_component rt5682s_component[] = {
556 	{
557 		.name = "i2c-RTL5682:00",
558 		.dai_name = "rt5682s-aif1",
559 	}
560 };
561 
562 static struct snd_soc_dai_link_component rt5650_components[] = {
563 	{
564 		.name = "i2c-10EC5650:00",
565 		.dai_name = "rt5645-aif1",
566 	},
567 	{
568 		.name = "i2c-10EC5650:00",
569 		.dai_name = "rt5645-aif2",
570 	}
571 };
572 
573 static struct snd_soc_dai_link *
574 sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec codec_type,
575 			  enum sof_ssp_codec amp_type, int ssp_codec,
576 			  int ssp_amp, int dmic_be_num, int hdmi_num,
577 			  bool idisp_codec, bool is_legacy_cpu)
578 {
579 	struct snd_soc_dai_link_component *cpus;
580 	struct snd_soc_dai_link *links;
581 	int i;
582 	int id = 0;
583 	int ret;
584 	int hdmi_id_offset = 0;
585 
586 	links = devm_kcalloc(dev, sof_audio_card_rt5682.num_links,
587 			    sizeof(struct snd_soc_dai_link), GFP_KERNEL);
588 	cpus = devm_kcalloc(dev, sof_audio_card_rt5682.num_links,
589 			    sizeof(struct snd_soc_dai_link_component), GFP_KERNEL);
590 	if (!links || !cpus)
591 		goto devm_err;
592 
593 	/* codec SSP */
594 	links[id].name = devm_kasprintf(dev, GFP_KERNEL,
595 					"SSP%d-Codec", ssp_codec);
596 	if (!links[id].name)
597 		goto devm_err;
598 
599 	links[id].id = id;
600 
601 	switch (codec_type) {
602 	case CODEC_RT5650:
603 		links[id].codecs = &rt5650_components[0];
604 		links[id].num_codecs = 1;
605 		break;
606 	case CODEC_RT5682:
607 		links[id].codecs = rt5682_component;
608 		links[id].num_codecs = ARRAY_SIZE(rt5682_component);
609 		break;
610 	case CODEC_RT5682S:
611 		links[id].codecs = rt5682s_component;
612 		links[id].num_codecs = ARRAY_SIZE(rt5682s_component);
613 		break;
614 	default:
615 		dev_err(dev, "invalid codec type %d\n", codec_type);
616 		return NULL;
617 	}
618 
619 	links[id].platforms = platform_component;
620 	links[id].num_platforms = ARRAY_SIZE(platform_component);
621 	links[id].init = sof_rt5682_codec_init;
622 	links[id].exit = sof_rt5682_codec_exit;
623 	links[id].ops = &sof_rt5682_ops;
624 	links[id].dpcm_playback = 1;
625 	links[id].dpcm_capture = 1;
626 	links[id].no_pcm = 1;
627 	links[id].cpus = &cpus[id];
628 	links[id].num_cpus = 1;
629 	if (is_legacy_cpu) {
630 		links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
631 							  "ssp%d-port",
632 							  ssp_codec);
633 		if (!links[id].cpus->dai_name)
634 			goto devm_err;
635 	} else {
636 		/*
637 		 * Currently, On SKL+ platforms MCLK will be turned off in sof
638 		 * runtime suspended, and it will go into runtime suspended
639 		 * right after playback is stop. However, rt5682 will output
640 		 * static noise if sysclk turns off during playback. Set
641 		 * ignore_pmdown_time to power down rt5682 immediately and
642 		 * avoid the noise.
643 		 * It can be removed once we can control MCLK by driver.
644 		 */
645 		links[id].ignore_pmdown_time = 1;
646 		links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
647 							  "SSP%d Pin",
648 							  ssp_codec);
649 		if (!links[id].cpus->dai_name)
650 			goto devm_err;
651 	}
652 	id++;
653 
654 	/* dmic */
655 	if (dmic_be_num > 0) {
656 		/* at least we have dmic01 */
657 		ret = sof_intel_board_set_dmic_link(dev, &links[id], id,
658 						    SOF_DMIC_01);
659 		if (ret)
660 			return NULL;
661 
662 		id++;
663 	}
664 
665 	if (dmic_be_num > 1) {
666 		/* set up 2 BE links at most */
667 		ret = sof_intel_board_set_dmic_link(dev, &links[id], id,
668 						    SOF_DMIC_16K);
669 		if (ret)
670 			return NULL;
671 
672 		id++;
673 	}
674 
675 	/* HDMI */
676 	for (i = 1; i <= hdmi_num; i++) {
677 		ret = sof_intel_board_set_intel_hdmi_link(dev, &links[id], id,
678 							  i, idisp_codec);
679 		if (ret)
680 			return NULL;
681 
682 		id++;
683 	}
684 
685 	/* speaker amp */
686 	if (amp_type != CODEC_NONE) {
687 		links[id].name = devm_kasprintf(dev, GFP_KERNEL,
688 						"SSP%d-Codec", ssp_amp);
689 		if (!links[id].name)
690 			goto devm_err;
691 
692 		links[id].id = id;
693 
694 		switch (amp_type) {
695 		case CODEC_MAX98357A:
696 			max_98357a_dai_link(&links[id]);
697 			break;
698 		case CODEC_MAX98360A:
699 			max_98360a_dai_link(&links[id]);
700 			break;
701 		case CODEC_MAX98373:
702 			links[id].codecs = max_98373_components;
703 			links[id].num_codecs = ARRAY_SIZE(max_98373_components);
704 			links[id].init = max_98373_spk_codec_init;
705 			links[id].ops = &max_98373_ops;
706 			break;
707 		case CODEC_MAX98390:
708 			max_98390_dai_link(dev, &links[id]);
709 			break;
710 		case CODEC_RT1011:
711 			sof_rt1011_dai_link(&links[id]);
712 			break;
713 		case CODEC_RT1015:
714 			sof_rt1015_dai_link(&links[id]);
715 			break;
716 		case CODEC_RT1015P:
717 			sof_rt1015p_dai_link(&links[id]);
718 			break;
719 		case CODEC_RT1019P:
720 			sof_rt1019p_dai_link(&links[id]);
721 			break;
722 		case CODEC_RT5650:
723 			/* use AIF2 to support speaker pipeline */
724 			links[id].codecs = &rt5650_components[1];
725 			links[id].num_codecs = 1;
726 			links[id].init = rt5650_spk_init;
727 			links[id].ops = &sof_rt5682_ops;
728 			break;
729 		default:
730 			dev_err(dev, "invalid amp type %d\n", amp_type);
731 			return NULL;
732 		}
733 
734 		links[id].platforms = platform_component;
735 		links[id].num_platforms = ARRAY_SIZE(platform_component);
736 		links[id].dpcm_playback = 1;
737 		/* feedback stream or firmware-generated echo reference */
738 		links[id].dpcm_capture = 1;
739 
740 		links[id].no_pcm = 1;
741 		links[id].cpus = &cpus[id];
742 		links[id].num_cpus = 1;
743 		if (is_legacy_cpu) {
744 			links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
745 								  "ssp%d-port",
746 								  ssp_amp);
747 			if (!links[id].cpus->dai_name)
748 				goto devm_err;
749 
750 		} else {
751 			links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
752 								  "SSP%d Pin",
753 								  ssp_amp);
754 			if (!links[id].cpus->dai_name)
755 				goto devm_err;
756 		}
757 		id++;
758 	}
759 
760 	/* BT audio offload */
761 	if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) {
762 		int port = (sof_rt5682_quirk & SOF_BT_OFFLOAD_SSP_MASK) >>
763 				SOF_BT_OFFLOAD_SSP_SHIFT;
764 
765 		links[id].id = id;
766 		links[id].cpus = &cpus[id];
767 		links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
768 							  "SSP%d Pin", port);
769 		if (!links[id].cpus->dai_name)
770 			goto devm_err;
771 		links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port);
772 		if (!links[id].name)
773 			goto devm_err;
774 		links[id].codecs = &snd_soc_dummy_dlc;
775 		links[id].num_codecs = 1;
776 		links[id].platforms = platform_component;
777 		links[id].num_platforms = ARRAY_SIZE(platform_component);
778 		links[id].dpcm_playback = 1;
779 		links[id].dpcm_capture = 1;
780 		links[id].no_pcm = 1;
781 		links[id].num_cpus = 1;
782 	}
783 
784 	/* HDMI-In SSP */
785 	if (sof_rt5682_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK) {
786 		unsigned long hdmi_in_ssp = (sof_rt5682_quirk &
787 				SOF_SSP_HDMI_CAPTURE_PRESENT_MASK) >>
788 				SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT;
789 		int port = 0;
790 
791 		for_each_set_bit(port, &hdmi_in_ssp, 32) {
792 			links[id].cpus = &cpus[id];
793 			links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
794 								  "SSP%d Pin", port);
795 			if (!links[id].cpus->dai_name)
796 				return NULL;
797 			links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-HDMI", port);
798 			if (!links[id].name)
799 				return NULL;
800 			links[id].id = id + hdmi_id_offset;
801 			links[id].codecs = &snd_soc_dummy_dlc;
802 			links[id].num_codecs = 1;
803 			links[id].platforms = platform_component;
804 			links[id].num_platforms = ARRAY_SIZE(platform_component);
805 			links[id].dpcm_capture = 1;
806 			links[id].no_pcm = 1;
807 			links[id].num_cpus = 1;
808 			id++;
809 		}
810 	}
811 
812 	return links;
813 devm_err:
814 	return NULL;
815 }
816 
817 static int sof_audio_probe(struct platform_device *pdev)
818 {
819 	struct snd_soc_acpi_mach *mach = pdev->dev.platform_data;
820 	struct snd_soc_dai_link *dai_links;
821 	struct sof_card_private *ctx;
822 	int ret, ssp_amp, ssp_codec;
823 
824 	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
825 	if (!ctx)
826 		return -ENOMEM;
827 
828 	if (pdev->id_entry && pdev->id_entry->driver_data)
829 		sof_rt5682_quirk = (unsigned long)pdev->id_entry->driver_data;
830 
831 	dmi_check_system(sof_rt5682_quirk_table);
832 
833 	ctx->codec_type = sof_ssp_detect_codec_type(&pdev->dev);
834 	ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev);
835 
836 	if (ctx->codec_type == CODEC_RT5650) {
837 		sof_audio_card_rt5682.name = devm_kstrdup(&pdev->dev, "rt5650",
838 							  GFP_KERNEL);
839 
840 		/* create speaker dai link also */
841 		if (ctx->amp_type == CODEC_NONE)
842 			ctx->amp_type = CODEC_RT5650;
843 	}
844 
845 	if (soc_intel_is_byt() || soc_intel_is_cht()) {
846 		ctx->rt5682.is_legacy_cpu = true;
847 		ctx->dmic_be_num = 0;
848 		/* HDMI is not supported by SOF on Baytrail/CherryTrail */
849 		ctx->hdmi_num = 0;
850 		/* default quirk for legacy cpu */
851 		sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
852 						SOF_RT5682_MCLK_BYTCHT_EN |
853 						SOF_RT5682_SSP_CODEC(2);
854 	} else {
855 		ctx->dmic_be_num = 2;
856 		ctx->hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >>
857 			 SOF_RT5682_NUM_HDMIDEV_SHIFT;
858 		/* default number of HDMI DAI's */
859 		if (!ctx->hdmi_num)
860 			ctx->hdmi_num = 3;
861 
862 		if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
863 			ctx->hdmi.idisp_codec = true;
864 	}
865 
866 	/* need to get main clock from pmc */
867 	if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
868 		ctx->rt5682.mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
869 		if (IS_ERR(ctx->rt5682.mclk)) {
870 			ret = PTR_ERR(ctx->rt5682.mclk);
871 
872 			dev_err(&pdev->dev,
873 				"Failed to get MCLK from pmc_plt_clk_3: %d\n",
874 				ret);
875 			return ret;
876 		}
877 
878 		ret = clk_prepare_enable(ctx->rt5682.mclk);
879 		if (ret < 0) {
880 			dev_err(&pdev->dev,
881 				"could not configure MCLK state");
882 			return ret;
883 		}
884 	}
885 
886 	dev_dbg(&pdev->dev, "sof_rt5682_quirk = %lx\n", sof_rt5682_quirk);
887 
888 	ssp_amp = (sof_rt5682_quirk & SOF_RT5682_SSP_AMP_MASK) >>
889 			SOF_RT5682_SSP_AMP_SHIFT;
890 
891 	ssp_codec = sof_rt5682_quirk & SOF_RT5682_SSP_CODEC_MASK;
892 
893 	/* compute number of dai links */
894 	sof_audio_card_rt5682.num_links = 1 + ctx->dmic_be_num + ctx->hdmi_num;
895 
896 	if (ctx->amp_type != CODEC_NONE)
897 		sof_audio_card_rt5682.num_links++;
898 
899 	if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
900 		sof_audio_card_rt5682.num_links++;
901 
902 	if (sof_rt5682_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK)
903 		sof_audio_card_rt5682.num_links +=
904 			hweight32((sof_rt5682_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK) >>
905 					SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT);
906 
907 	dai_links = sof_card_dai_links_create(&pdev->dev, ctx->codec_type,
908 					      ctx->amp_type, ssp_codec, ssp_amp,
909 					      ctx->dmic_be_num, ctx->hdmi_num,
910 					      ctx->hdmi.idisp_codec,
911 					      ctx->rt5682.is_legacy_cpu);
912 	if (!dai_links)
913 		return -ENOMEM;
914 
915 	sof_audio_card_rt5682.dai_link = dai_links;
916 
917 	/* update codec_conf */
918 	switch (ctx->amp_type) {
919 	case CODEC_MAX98373:
920 		max_98373_set_codec_conf(&sof_audio_card_rt5682);
921 		break;
922 	case CODEC_MAX98390:
923 		max_98390_set_codec_conf(&pdev->dev, &sof_audio_card_rt5682);
924 		break;
925 	case CODEC_RT1011:
926 		sof_rt1011_codec_conf(&sof_audio_card_rt5682);
927 		break;
928 	case CODEC_RT1015:
929 		sof_rt1015_codec_conf(&sof_audio_card_rt5682);
930 		break;
931 	case CODEC_RT1015P:
932 		sof_rt1015p_codec_conf(&sof_audio_card_rt5682);
933 		break;
934 	case CODEC_NONE:
935 	case CODEC_MAX98357A:
936 	case CODEC_MAX98360A:
937 	case CODEC_RT1019P:
938 	case CODEC_RT5650:
939 		/* no codec conf required */
940 		break;
941 	default:
942 		dev_err(&pdev->dev, "invalid amp type %d\n", ctx->amp_type);
943 		return -EINVAL;
944 	}
945 
946 	sof_audio_card_rt5682.dev = &pdev->dev;
947 
948 	/* set platform name for each dailink */
949 	ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_rt5682,
950 						    mach->mach_params.platform);
951 	if (ret)
952 		return ret;
953 
954 	snd_soc_card_set_drvdata(&sof_audio_card_rt5682, ctx);
955 
956 	return devm_snd_soc_register_card(&pdev->dev,
957 					  &sof_audio_card_rt5682);
958 }
959 
960 static const struct platform_device_id board_ids[] = {
961 	{
962 		.name = "sof_rt5682",
963 	},
964 	{
965 		.name = "cml_rt1015_rt5682",
966 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
967 					SOF_RT5682_SSP_CODEC(0) |
968 					SOF_RT5682_SSP_AMP(1)),
969 	},
970 	{
971 		.name = "jsl_rt5682_rt1015",
972 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
973 					SOF_RT5682_SSP_CODEC(0) |
974 					SOF_RT5682_SSP_AMP(1)),
975 	},
976 	{
977 		.name = "jsl_rt5682_mx98360",
978 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
979 					SOF_RT5682_SSP_CODEC(0) |
980 					SOF_RT5682_SSP_AMP(1)),
981 	},
982 	{
983 		.name = "jsl_rt5682_rt1015p",
984 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
985 					SOF_RT5682_SSP_CODEC(0) |
986 					SOF_RT5682_SSP_AMP(1)),
987 	},
988 	{
989 		.name = "jsl_rt5682",
990 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
991 					SOF_RT5682_SSP_CODEC(0)),
992 	},
993 	{
994 		.name = "jsl_rt5650",
995 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
996 					SOF_RT5682_SSP_CODEC(0) |
997 					SOF_RT5682_SSP_AMP(1)),
998 	},
999 	{
1000 		.name = "tgl_mx98357_rt5682",
1001 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1002 					SOF_RT5682_SSP_CODEC(0) |
1003 					SOF_RT5682_SSP_AMP(1) |
1004 					SOF_RT5682_NUM_HDMIDEV(4) |
1005 					SOF_BT_OFFLOAD_SSP(2) |
1006 					SOF_SSP_BT_OFFLOAD_PRESENT),
1007 	},
1008 	{
1009 		.name = "tgl_rt1011_rt5682",
1010 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1011 					SOF_RT5682_SSP_CODEC(0) |
1012 					SOF_RT5682_SSP_AMP(1) |
1013 					SOF_RT5682_NUM_HDMIDEV(4) |
1014 					SOF_BT_OFFLOAD_SSP(2) |
1015 					SOF_SSP_BT_OFFLOAD_PRESENT),
1016 	},
1017 	{
1018 		.name = "tgl_mx98373_rt5682",
1019 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1020 					SOF_RT5682_SSP_CODEC(0) |
1021 					SOF_RT5682_SSP_AMP(1) |
1022 					SOF_RT5682_NUM_HDMIDEV(4) |
1023 					SOF_BT_OFFLOAD_SSP(2) |
1024 					SOF_SSP_BT_OFFLOAD_PRESENT),
1025 	},
1026 	{
1027 		.name = "adl_mx98373_rt5682",
1028 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1029 					SOF_RT5682_SSP_CODEC(0) |
1030 					SOF_RT5682_SSP_AMP(1) |
1031 					SOF_RT5682_NUM_HDMIDEV(4) |
1032 					SOF_BT_OFFLOAD_SSP(2) |
1033 					SOF_SSP_BT_OFFLOAD_PRESENT),
1034 	},
1035 	{
1036 		.name = "adl_mx98357_rt5682",
1037 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1038 					SOF_RT5682_SSP_CODEC(0) |
1039 					SOF_RT5682_SSP_AMP(2) |
1040 					SOF_RT5682_NUM_HDMIDEV(4)),
1041 	},
1042 	{
1043 		.name = "adl_max98390_rt5682",
1044 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1045 					SOF_RT5682_SSP_CODEC(0) |
1046 					SOF_RT5682_SSP_AMP(1) |
1047 					SOF_RT5682_NUM_HDMIDEV(4) |
1048 					SOF_BT_OFFLOAD_SSP(2) |
1049 					SOF_SSP_BT_OFFLOAD_PRESENT),
1050 	},
1051 	{
1052 		.name = "adl_mx98360_rt5682",
1053 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1054 					SOF_RT5682_SSP_CODEC(0) |
1055 					SOF_RT5682_SSP_AMP(1) |
1056 					SOF_RT5682_NUM_HDMIDEV(4) |
1057 					SOF_BT_OFFLOAD_SSP(2) |
1058 					SOF_SSP_BT_OFFLOAD_PRESENT),
1059 	},
1060 	{
1061 		.name = "adl_rt5682",
1062 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1063 					SOF_RT5682_SSP_CODEC(0) |
1064 					SOF_RT5682_NUM_HDMIDEV(4) |
1065 					SOF_BT_OFFLOAD_SSP(2) |
1066 					SOF_SSP_BT_OFFLOAD_PRESENT),
1067 	},
1068 	{
1069 		.name = "adl_rt1019_rt5682",
1070 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1071 					SOF_RT5682_SSP_CODEC(0) |
1072 					SOF_RT5682_SSP_AMP(1) |
1073 					SOF_RT5682_NUM_HDMIDEV(4) |
1074 					SOF_BT_OFFLOAD_SSP(2) |
1075 					SOF_SSP_BT_OFFLOAD_PRESENT),
1076 	},
1077 	{
1078 		.name = "adl_rt5682_c1_h02",
1079 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1080 					SOF_RT5682_SSP_CODEC(1) |
1081 					SOF_RT5682_NUM_HDMIDEV(3) |
1082 					/* SSP 0 and SSP 2 are used for HDMI IN */
1083 					SOF_HDMI_CAPTURE_SSP_MASK(0x5)),
1084 	},
1085 	{
1086 		.name = "adl_rt5650",
1087 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1088 					SOF_RT5682_SSP_CODEC(0) |
1089 					SOF_RT5682_SSP_AMP(1) |
1090 					SOF_RT5682_NUM_HDMIDEV(4) |
1091 					SOF_BT_OFFLOAD_SSP(2) |
1092 					SOF_SSP_BT_OFFLOAD_PRESENT),
1093 	},
1094 	{
1095 		.name = "rpl_mx98357_rt5682",
1096 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1097 					SOF_RT5682_SSP_CODEC(0) |
1098 					SOF_RT5682_SSP_AMP(2) |
1099 					SOF_RT5682_NUM_HDMIDEV(4)),
1100 	},
1101 	{
1102 		.name = "rpl_mx98360_rt5682",
1103 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1104 					SOF_RT5682_SSP_CODEC(0) |
1105 					SOF_RT5682_SSP_AMP(1) |
1106 					SOF_RT5682_NUM_HDMIDEV(4) |
1107 					SOF_BT_OFFLOAD_SSP(2) |
1108 					SOF_SSP_BT_OFFLOAD_PRESENT),
1109 	},
1110 	{
1111 		.name = "rpl_rt1019_rt5682",
1112 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1113 					SOF_RT5682_SSP_CODEC(0) |
1114 					SOF_RT5682_SSP_AMP(1) |
1115 					SOF_RT5682_NUM_HDMIDEV(4) |
1116 					SOF_BT_OFFLOAD_SSP(2) |
1117 					SOF_SSP_BT_OFFLOAD_PRESENT),
1118 	},
1119 	{
1120 		.name = "rpl_rt5682_c1_h02",
1121 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1122 					SOF_RT5682_SSP_CODEC(1) |
1123 					SOF_RT5682_NUM_HDMIDEV(3) |
1124 					/* SSP 0 and SSP 2 are used for HDMI IN */
1125 					SOF_HDMI_CAPTURE_SSP_MASK(0x5)),
1126 	},
1127 	{
1128 		.name = "mtl_mx98357_rt5682",
1129 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1130 					SOF_RT5682_SSP_CODEC(0) |
1131 					SOF_RT5682_SSP_AMP(1) |
1132 					SOF_RT5682_NUM_HDMIDEV(3) |
1133 					SOF_BT_OFFLOAD_SSP(2) |
1134 					SOF_SSP_BT_OFFLOAD_PRESENT),
1135 	},
1136 	{
1137 		.name = "mtl_mx98360_rt5682",
1138 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1139 					SOF_RT5682_SSP_CODEC(0) |
1140 					SOF_RT5682_SSP_AMP(1) |
1141 					SOF_RT5682_NUM_HDMIDEV(3)),
1142 	},
1143 	{
1144 		.name = "mtl_rt1019_rt5682",
1145 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
1146 					SOF_RT5682_SSP_CODEC(2) |
1147 					SOF_RT5682_SSP_AMP(0) |
1148 					SOF_RT5682_NUM_HDMIDEV(3)),
1149 	},
1150 	{ }
1151 };
1152 MODULE_DEVICE_TABLE(platform, board_ids);
1153 
1154 static struct platform_driver sof_audio = {
1155 	.probe = sof_audio_probe,
1156 	.driver = {
1157 		.name = "sof_rt5682",
1158 		.pm = &snd_soc_pm_ops,
1159 	},
1160 	.id_table = board_ids,
1161 };
1162 module_platform_driver(sof_audio)
1163 
1164 /* Module information */
1165 MODULE_DESCRIPTION("SOF Audio Machine driver");
1166 MODULE_AUTHOR("Bard Liao <bard.liao@intel.com>");
1167 MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
1168 MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
1169 MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
1170 MODULE_LICENSE("GPL v2");
1171 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS);
1172 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);
1173 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON);
1174 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON);
1175