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