xref: /linux/sound/soc/intel/boards/sof_rt5682.c (revision f728c17fc97aea7a33151d9ba64106291c62bb02)
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 int sof_card_late_probe(struct snd_soc_card *card)
467 {
468 	struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
469 	struct snd_soc_dapm_context *dapm = &card->dapm;
470 	int err;
471 
472 	if (ctx->amp_type == CODEC_MAX98373) {
473 		/* Disable Left and Right Spk pin after boot */
474 		snd_soc_dapm_disable_pin(dapm, "Left Spk");
475 		snd_soc_dapm_disable_pin(dapm, "Right Spk");
476 		err = snd_soc_dapm_sync(dapm);
477 		if (err < 0)
478 			return err;
479 	}
480 
481 	return sof_intel_board_card_late_probe(card);
482 }
483 
484 static const struct snd_kcontrol_new sof_controls[] = {
485 	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
486 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
487 	SOC_DAPM_PIN_SWITCH("Left Spk"),
488 	SOC_DAPM_PIN_SWITCH("Right Spk"),
489 
490 };
491 
492 static const struct snd_soc_dapm_widget sof_widgets[] = {
493 	SND_SOC_DAPM_HP("Headphone Jack", NULL),
494 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
495 	SND_SOC_DAPM_SPK("Left Spk", NULL),
496 	SND_SOC_DAPM_SPK("Right Spk", NULL),
497 };
498 
499 static const struct snd_soc_dapm_route sof_map[] = {
500 	/* HP jack connectors - unknown if we have jack detection */
501 	{ "Headphone Jack", NULL, "HPOL" },
502 	{ "Headphone Jack", NULL, "HPOR" },
503 
504 	/* other jacks */
505 	{ "IN1P", NULL, "Headset Mic" },
506 };
507 
508 static const struct snd_soc_dapm_route rt5650_spk_dapm_routes[] = {
509 	/* speaker */
510 	{ "Left Spk", NULL, "SPOL" },
511 	{ "Right Spk", NULL, "SPOR" },
512 };
513 
514 static int rt5650_spk_init(struct snd_soc_pcm_runtime *rtd)
515 {
516 	struct snd_soc_card *card = rtd->card;
517 	int ret;
518 
519 	ret = snd_soc_dapm_add_routes(&card->dapm, rt5650_spk_dapm_routes,
520 				      ARRAY_SIZE(rt5650_spk_dapm_routes));
521 	if (ret)
522 		dev_err(rtd->dev, "fail to add dapm routes, ret=%d\n", ret);
523 
524 	return ret;
525 }
526 
527 /* sof audio machine driver for rt5682 codec */
528 static struct snd_soc_card sof_audio_card_rt5682 = {
529 	.name = "rt5682", /* the sof- prefix is added by the core */
530 	.owner = THIS_MODULE,
531 	.controls = sof_controls,
532 	.num_controls = ARRAY_SIZE(sof_controls),
533 	.dapm_widgets = sof_widgets,
534 	.num_dapm_widgets = ARRAY_SIZE(sof_widgets),
535 	.dapm_routes = sof_map,
536 	.num_dapm_routes = ARRAY_SIZE(sof_map),
537 	.fully_routed = true,
538 	.late_probe = sof_card_late_probe,
539 };
540 
541 static struct snd_soc_dai_link_component rt5682_component[] = {
542 	{
543 		.name = "i2c-10EC5682:00",
544 		.dai_name = "rt5682-aif1",
545 	}
546 };
547 
548 static struct snd_soc_dai_link_component rt5682s_component[] = {
549 	{
550 		.name = "i2c-RTL5682:00",
551 		.dai_name = "rt5682s-aif1",
552 	}
553 };
554 
555 static struct snd_soc_dai_link_component rt5650_components[] = {
556 	{
557 		.name = "i2c-10EC5650:00",
558 		.dai_name = "rt5645-aif1",
559 	},
560 	{
561 		.name = "i2c-10EC5650:00",
562 		.dai_name = "rt5645-aif2",
563 	}
564 };
565 
566 static int
567 sof_card_dai_links_create(struct device *dev, struct snd_soc_card *card,
568 			  struct sof_card_private *ctx)
569 {
570 	int ret;
571 
572 	ret = sof_intel_board_set_dai_link(dev, card, ctx);
573 	if (ret)
574 		return ret;
575 
576 	if (!ctx->codec_link) {
577 		dev_err(dev, "codec link not available");
578 		return -EINVAL;
579 	}
580 
581 	/* codec-specific fields for headphone codec */
582 	switch (ctx->codec_type) {
583 	case CODEC_RT5650:
584 		ctx->codec_link->codecs = &rt5650_components[0];
585 		ctx->codec_link->num_codecs = 1;
586 		break;
587 	case CODEC_RT5682:
588 		ctx->codec_link->codecs = rt5682_component;
589 		ctx->codec_link->num_codecs = ARRAY_SIZE(rt5682_component);
590 		break;
591 	case CODEC_RT5682S:
592 		ctx->codec_link->codecs = rt5682s_component;
593 		ctx->codec_link->num_codecs = ARRAY_SIZE(rt5682s_component);
594 		break;
595 	default:
596 		dev_err(dev, "invalid codec type %d\n", ctx->codec_type);
597 		return -EINVAL;
598 	}
599 
600 	ctx->codec_link->init = sof_rt5682_codec_init;
601 	ctx->codec_link->exit = sof_rt5682_codec_exit;
602 	ctx->codec_link->ops = &sof_rt5682_ops;
603 
604 	if (!ctx->rt5682.is_legacy_cpu) {
605 		/*
606 		 * Currently, On SKL+ platforms MCLK will be turned off in sof
607 		 * runtime suspended, and it will go into runtime suspended
608 		 * right after playback is stop. However, rt5682 will output
609 		 * static noise if sysclk turns off during playback. Set
610 		 * ignore_pmdown_time to power down rt5682 immediately and
611 		 * avoid the noise.
612 		 * It can be removed once we can control MCLK by driver.
613 		 */
614 		ctx->codec_link->ignore_pmdown_time = 1;
615 	}
616 
617 	if (ctx->amp_type == CODEC_NONE)
618 		return 0;
619 
620 	if (!ctx->amp_link) {
621 		dev_err(dev, "amp link not available");
622 		return -EINVAL;
623 	}
624 
625 	/* codec-specific fields for speaker amplifier */
626 	switch (ctx->amp_type) {
627 	case CODEC_MAX98357A:
628 		max_98357a_dai_link(ctx->amp_link);
629 		break;
630 	case CODEC_MAX98360A:
631 		max_98360a_dai_link(ctx->amp_link);
632 		break;
633 	case CODEC_MAX98373:
634 		ctx->amp_link->codecs = max_98373_components;
635 		ctx->amp_link->num_codecs = ARRAY_SIZE(max_98373_components);
636 		ctx->amp_link->init = max_98373_spk_codec_init;
637 		ctx->amp_link->ops = &max_98373_ops;
638 		break;
639 	case CODEC_MAX98390:
640 		max_98390_dai_link(dev, ctx->amp_link);
641 		break;
642 	case CODEC_RT1011:
643 		sof_rt1011_dai_link(ctx->amp_link);
644 		break;
645 	case CODEC_RT1015:
646 		sof_rt1015_dai_link(ctx->amp_link);
647 		break;
648 	case CODEC_RT1015P:
649 		sof_rt1015p_dai_link(ctx->amp_link);
650 		break;
651 	case CODEC_RT1019P:
652 		sof_rt1019p_dai_link(ctx->amp_link);
653 		break;
654 	case CODEC_RT5650:
655 		/* use AIF2 to support speaker pipeline */
656 		ctx->amp_link->codecs = &rt5650_components[1];
657 		ctx->amp_link->num_codecs = 1;
658 		ctx->amp_link->init = rt5650_spk_init;
659 		ctx->amp_link->ops = &sof_rt5682_ops;
660 		break;
661 	default:
662 		dev_err(dev, "invalid amp type %d\n", ctx->amp_type);
663 		return -EINVAL;
664 	}
665 
666 	return 0;
667 }
668 
669 static int sof_audio_probe(struct platform_device *pdev)
670 {
671 	struct snd_soc_acpi_mach *mach = pdev->dev.platform_data;
672 	struct sof_card_private *ctx;
673 	int ret;
674 
675 	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
676 	if (!ctx)
677 		return -ENOMEM;
678 
679 	if (pdev->id_entry && pdev->id_entry->driver_data)
680 		sof_rt5682_quirk = (unsigned long)pdev->id_entry->driver_data;
681 
682 	dmi_check_system(sof_rt5682_quirk_table);
683 
684 	ctx->codec_type = sof_ssp_detect_codec_type(&pdev->dev);
685 	ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev);
686 
687 	if (ctx->codec_type == CODEC_RT5650) {
688 		sof_audio_card_rt5682.name = devm_kstrdup(&pdev->dev, "rt5650",
689 							  GFP_KERNEL);
690 
691 		/* create speaker dai link also */
692 		if (ctx->amp_type == CODEC_NONE)
693 			ctx->amp_type = CODEC_RT5650;
694 	}
695 
696 	if (soc_intel_is_byt() || soc_intel_is_cht()) {
697 		ctx->rt5682.is_legacy_cpu = true;
698 		ctx->dmic_be_num = 0;
699 		/* HDMI is not supported by SOF on Baytrail/CherryTrail */
700 		ctx->hdmi_num = 0;
701 		/* default quirk for legacy cpu */
702 		sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
703 						SOF_RT5682_MCLK_BYTCHT_EN |
704 						SOF_RT5682_SSP_CODEC(2);
705 	} else {
706 		ctx->dmic_be_num = 2;
707 		ctx->hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >>
708 			 SOF_RT5682_NUM_HDMIDEV_SHIFT;
709 		/* default number of HDMI DAI's */
710 		if (!ctx->hdmi_num)
711 			ctx->hdmi_num = 3;
712 
713 		if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
714 			ctx->hdmi.idisp_codec = true;
715 	}
716 
717 	/* need to get main clock from pmc */
718 	if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
719 		ctx->rt5682.mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
720 		if (IS_ERR(ctx->rt5682.mclk)) {
721 			ret = PTR_ERR(ctx->rt5682.mclk);
722 
723 			dev_err(&pdev->dev,
724 				"Failed to get MCLK from pmc_plt_clk_3: %d\n",
725 				ret);
726 			return ret;
727 		}
728 
729 		ret = clk_prepare_enable(ctx->rt5682.mclk);
730 		if (ret < 0) {
731 			dev_err(&pdev->dev,
732 				"could not configure MCLK state");
733 			return ret;
734 		}
735 	}
736 
737 	dev_dbg(&pdev->dev, "sof_rt5682_quirk = %lx\n", sof_rt5682_quirk);
738 
739 	/* port number/mask of peripherals attached to ssp interface */
740 	ctx->ssp_mask_hdmi_in = (sof_rt5682_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK) >>
741 			SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT;
742 
743 	ctx->ssp_bt = (sof_rt5682_quirk & SOF_BT_OFFLOAD_SSP_MASK) >>
744 			SOF_BT_OFFLOAD_SSP_SHIFT;
745 
746 	ctx->ssp_amp = (sof_rt5682_quirk & SOF_RT5682_SSP_AMP_MASK) >>
747 			SOF_RT5682_SSP_AMP_SHIFT;
748 
749 	ctx->ssp_codec = sof_rt5682_quirk & SOF_RT5682_SSP_CODEC_MASK;
750 
751 	if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
752 		ctx->bt_offload_present = true;
753 
754 	/* update dai_link */
755 	ret = sof_card_dai_links_create(&pdev->dev, &sof_audio_card_rt5682, ctx);
756 	if (ret)
757 		return ret;
758 
759 	/* update codec_conf */
760 	switch (ctx->amp_type) {
761 	case CODEC_MAX98373:
762 		max_98373_set_codec_conf(&sof_audio_card_rt5682);
763 		break;
764 	case CODEC_MAX98390:
765 		max_98390_set_codec_conf(&pdev->dev, &sof_audio_card_rt5682);
766 		break;
767 	case CODEC_RT1011:
768 		sof_rt1011_codec_conf(&sof_audio_card_rt5682);
769 		break;
770 	case CODEC_RT1015:
771 		sof_rt1015_codec_conf(&sof_audio_card_rt5682);
772 		break;
773 	case CODEC_RT1015P:
774 		sof_rt1015p_codec_conf(&sof_audio_card_rt5682);
775 		break;
776 	case CODEC_NONE:
777 	case CODEC_MAX98357A:
778 	case CODEC_MAX98360A:
779 	case CODEC_RT1019P:
780 	case CODEC_RT5650:
781 		/* no codec conf required */
782 		break;
783 	default:
784 		dev_err(&pdev->dev, "invalid amp type %d\n", ctx->amp_type);
785 		return -EINVAL;
786 	}
787 
788 	sof_audio_card_rt5682.dev = &pdev->dev;
789 
790 	/* set platform name for each dailink */
791 	ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_rt5682,
792 						    mach->mach_params.platform);
793 	if (ret)
794 		return ret;
795 
796 	snd_soc_card_set_drvdata(&sof_audio_card_rt5682, ctx);
797 
798 	return devm_snd_soc_register_card(&pdev->dev,
799 					  &sof_audio_card_rt5682);
800 }
801 
802 static const struct platform_device_id board_ids[] = {
803 	{
804 		.name = "sof_rt5682",
805 	},
806 	{
807 		.name = "cml_rt1015_rt5682",
808 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
809 					SOF_RT5682_SSP_CODEC(0) |
810 					SOF_RT5682_SSP_AMP(1)),
811 	},
812 	{
813 		.name = "jsl_rt5682_rt1015",
814 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
815 					SOF_RT5682_SSP_CODEC(0) |
816 					SOF_RT5682_SSP_AMP(1)),
817 	},
818 	{
819 		.name = "jsl_rt5682_mx98360",
820 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
821 					SOF_RT5682_SSP_CODEC(0) |
822 					SOF_RT5682_SSP_AMP(1)),
823 	},
824 	{
825 		.name = "jsl_rt5682_rt1015p",
826 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
827 					SOF_RT5682_SSP_CODEC(0) |
828 					SOF_RT5682_SSP_AMP(1)),
829 	},
830 	{
831 		.name = "jsl_rt5682",
832 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
833 					SOF_RT5682_SSP_CODEC(0)),
834 	},
835 	{
836 		.name = "jsl_rt5650",
837 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
838 					SOF_RT5682_SSP_CODEC(0) |
839 					SOF_RT5682_SSP_AMP(1)),
840 	},
841 	{
842 		.name = "tgl_mx98357_rt5682",
843 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
844 					SOF_RT5682_SSP_CODEC(0) |
845 					SOF_RT5682_SSP_AMP(1) |
846 					SOF_RT5682_NUM_HDMIDEV(4) |
847 					SOF_BT_OFFLOAD_SSP(2) |
848 					SOF_SSP_BT_OFFLOAD_PRESENT),
849 	},
850 	{
851 		.name = "tgl_rt1011_rt5682",
852 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
853 					SOF_RT5682_SSP_CODEC(0) |
854 					SOF_RT5682_SSP_AMP(1) |
855 					SOF_RT5682_NUM_HDMIDEV(4) |
856 					SOF_BT_OFFLOAD_SSP(2) |
857 					SOF_SSP_BT_OFFLOAD_PRESENT),
858 	},
859 	{
860 		.name = "tgl_mx98373_rt5682",
861 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
862 					SOF_RT5682_SSP_CODEC(0) |
863 					SOF_RT5682_SSP_AMP(1) |
864 					SOF_RT5682_NUM_HDMIDEV(4) |
865 					SOF_BT_OFFLOAD_SSP(2) |
866 					SOF_SSP_BT_OFFLOAD_PRESENT),
867 	},
868 	{
869 		.name = "adl_mx98373_rt5682",
870 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
871 					SOF_RT5682_SSP_CODEC(0) |
872 					SOF_RT5682_SSP_AMP(1) |
873 					SOF_RT5682_NUM_HDMIDEV(4) |
874 					SOF_BT_OFFLOAD_SSP(2) |
875 					SOF_SSP_BT_OFFLOAD_PRESENT),
876 	},
877 	{
878 		.name = "adl_mx98357_rt5682",
879 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
880 					SOF_RT5682_SSP_CODEC(0) |
881 					SOF_RT5682_SSP_AMP(2) |
882 					SOF_RT5682_NUM_HDMIDEV(4)),
883 	},
884 	{
885 		.name = "adl_max98390_rt5682",
886 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
887 					SOF_RT5682_SSP_CODEC(0) |
888 					SOF_RT5682_SSP_AMP(1) |
889 					SOF_RT5682_NUM_HDMIDEV(4) |
890 					SOF_BT_OFFLOAD_SSP(2) |
891 					SOF_SSP_BT_OFFLOAD_PRESENT),
892 	},
893 	{
894 		.name = "adl_mx98360_rt5682",
895 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
896 					SOF_RT5682_SSP_CODEC(0) |
897 					SOF_RT5682_SSP_AMP(1) |
898 					SOF_RT5682_NUM_HDMIDEV(4) |
899 					SOF_BT_OFFLOAD_SSP(2) |
900 					SOF_SSP_BT_OFFLOAD_PRESENT),
901 	},
902 	{
903 		.name = "adl_rt5682",
904 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
905 					SOF_RT5682_SSP_CODEC(0) |
906 					SOF_RT5682_NUM_HDMIDEV(4) |
907 					SOF_BT_OFFLOAD_SSP(2) |
908 					SOF_SSP_BT_OFFLOAD_PRESENT),
909 	},
910 	{
911 		.name = "adl_rt1019_rt5682",
912 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
913 					SOF_RT5682_SSP_CODEC(0) |
914 					SOF_RT5682_SSP_AMP(1) |
915 					SOF_RT5682_NUM_HDMIDEV(4) |
916 					SOF_BT_OFFLOAD_SSP(2) |
917 					SOF_SSP_BT_OFFLOAD_PRESENT),
918 	},
919 	{
920 		.name = "adl_rt5682_c1_h02",
921 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
922 					SOF_RT5682_SSP_CODEC(1) |
923 					SOF_RT5682_NUM_HDMIDEV(3) |
924 					/* SSP 0 and SSP 2 are used for HDMI IN */
925 					SOF_HDMI_CAPTURE_SSP_MASK(0x5)),
926 	},
927 	{
928 		.name = "adl_rt5650",
929 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
930 					SOF_RT5682_SSP_CODEC(0) |
931 					SOF_RT5682_SSP_AMP(1) |
932 					SOF_RT5682_NUM_HDMIDEV(4) |
933 					SOF_BT_OFFLOAD_SSP(2) |
934 					SOF_SSP_BT_OFFLOAD_PRESENT),
935 	},
936 	{
937 		.name = "rpl_mx98357_rt5682",
938 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
939 					SOF_RT5682_SSP_CODEC(0) |
940 					SOF_RT5682_SSP_AMP(2) |
941 					SOF_RT5682_NUM_HDMIDEV(4)),
942 	},
943 	{
944 		.name = "rpl_mx98360_rt5682",
945 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
946 					SOF_RT5682_SSP_CODEC(0) |
947 					SOF_RT5682_SSP_AMP(1) |
948 					SOF_RT5682_NUM_HDMIDEV(4) |
949 					SOF_BT_OFFLOAD_SSP(2) |
950 					SOF_SSP_BT_OFFLOAD_PRESENT),
951 	},
952 	{
953 		.name = "rpl_rt1019_rt5682",
954 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
955 					SOF_RT5682_SSP_CODEC(0) |
956 					SOF_RT5682_SSP_AMP(1) |
957 					SOF_RT5682_NUM_HDMIDEV(4) |
958 					SOF_BT_OFFLOAD_SSP(2) |
959 					SOF_SSP_BT_OFFLOAD_PRESENT),
960 	},
961 	{
962 		.name = "rpl_rt5682_c1_h02",
963 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
964 					SOF_RT5682_SSP_CODEC(1) |
965 					SOF_RT5682_NUM_HDMIDEV(3) |
966 					/* SSP 0 and SSP 2 are used for HDMI IN */
967 					SOF_HDMI_CAPTURE_SSP_MASK(0x5)),
968 	},
969 	{
970 		.name = "mtl_mx98357_rt5682",
971 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
972 					SOF_RT5682_SSP_CODEC(0) |
973 					SOF_RT5682_SSP_AMP(1) |
974 					SOF_RT5682_NUM_HDMIDEV(3) |
975 					SOF_BT_OFFLOAD_SSP(2) |
976 					SOF_SSP_BT_OFFLOAD_PRESENT),
977 	},
978 	{
979 		.name = "mtl_mx98360_rt5682",
980 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
981 					SOF_RT5682_SSP_CODEC(0) |
982 					SOF_RT5682_SSP_AMP(1) |
983 					SOF_RT5682_NUM_HDMIDEV(3)),
984 	},
985 	{
986 		.name = "mtl_rt1019_rt5682",
987 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
988 					SOF_RT5682_SSP_CODEC(2) |
989 					SOF_RT5682_SSP_AMP(0) |
990 					SOF_RT5682_NUM_HDMIDEV(3)),
991 	},
992 	{
993 		.name = "mtl_rt5650",
994 		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
995 					SOF_RT5682_SSP_CODEC(2) |
996 					SOF_RT5682_SSP_AMP(0) |
997 					SOF_RT5682_NUM_HDMIDEV(3) |
998 					SOF_BT_OFFLOAD_SSP(1) |
999 					SOF_SSP_BT_OFFLOAD_PRESENT),
1000 	},
1001 	{ }
1002 };
1003 MODULE_DEVICE_TABLE(platform, board_ids);
1004 
1005 static struct platform_driver sof_audio = {
1006 	.probe = sof_audio_probe,
1007 	.driver = {
1008 		.name = "sof_rt5682",
1009 		.pm = &snd_soc_pm_ops,
1010 	},
1011 	.id_table = board_ids,
1012 };
1013 module_platform_driver(sof_audio)
1014 
1015 /* Module information */
1016 MODULE_DESCRIPTION("SOF Audio Machine driver");
1017 MODULE_AUTHOR("Bard Liao <bard.liao@intel.com>");
1018 MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
1019 MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
1020 MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
1021 MODULE_LICENSE("GPL v2");
1022 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS);
1023 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);
1024 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON);
1025 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON);
1026