xref: /linux/sound/soc/intel/boards/sof_realtek_common.c (revision 9c2f5b6eb8b7da05e13cde60c32e0a8b1f5873b0)
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Copyright(c) 2020 Intel Corporation
4 
5 #include <linux/device.h>
6 #include <linux/kernel.h>
7 #include <sound/pcm.h>
8 #include <sound/pcm_params.h>
9 #include <sound/soc.h>
10 #include <sound/soc-acpi.h>
11 #include <sound/soc-dai.h>
12 #include <sound/soc-dapm.h>
13 #include <sound/sof.h>
14 #include <uapi/sound/asound.h>
15 #include "../../codecs/rt1011.h"
16 #include "../../codecs/rt1015.h"
17 #include "../../codecs/rt1308.h"
18 #include "../common/soc-intel-quirks.h"
19 #include "sof_realtek_common.h"
20 
21 /*
22  * Common structures and functions
23  */
24 static const struct snd_kcontrol_new realtek_2spk_kcontrols[] = {
25 	SOC_DAPM_PIN_SWITCH("Left Spk"),
26 	SOC_DAPM_PIN_SWITCH("Right Spk"),
27 
28 };
29 
30 static const struct snd_soc_dapm_widget realtek_2spk_widgets[] = {
31 	SND_SOC_DAPM_SPK("Left Spk", NULL),
32 	SND_SOC_DAPM_SPK("Right Spk", NULL),
33 };
34 
35 static const struct snd_kcontrol_new realtek_4spk_kcontrols[] = {
36 	SOC_DAPM_PIN_SWITCH("WL Ext Spk"),
37 	SOC_DAPM_PIN_SWITCH("WR Ext Spk"),
38 	SOC_DAPM_PIN_SWITCH("TL Ext Spk"),
39 	SOC_DAPM_PIN_SWITCH("TR Ext Spk"),
40 };
41 
42 static const struct snd_soc_dapm_widget realtek_4spk_widgets[] = {
43 	SND_SOC_DAPM_SPK("WL Ext Spk", NULL),
44 	SND_SOC_DAPM_SPK("WR Ext Spk", NULL),
45 	SND_SOC_DAPM_SPK("TL Ext Spk", NULL),
46 	SND_SOC_DAPM_SPK("TR Ext Spk", NULL),
47 };
48 
49 /* helper function to get the number of specific codec */
50 static unsigned int get_num_codecs(const char *hid)
51 {
52 	struct acpi_device *adev;
53 	unsigned int dev_num = 0;
54 
55 	for_each_acpi_dev_match(adev, hid, NULL, -1)
56 		dev_num++;
57 
58 	return dev_num;
59 }
60 
61 /*
62  * Realtek ALC1011
63  */
64 static const struct snd_soc_dapm_route speaker_map_lr[] = {
65 	/* speaker */
66 	{ "Left Spk", NULL, "Left SPO" },
67 	{ "Right Spk", NULL, "Right SPO" },
68 };
69 
70 static const struct snd_soc_dapm_route rt1011_4spk_routes[] = {
71 	{"WL Ext Spk", NULL, "WL SPO" },
72 	{"WR Ext Spk", NULL, "WR SPO" },
73 	{"TL Ext Spk", NULL, "TL SPO" },
74 	{"TR Ext Spk", NULL, "TR SPO" },
75 };
76 
77 static struct snd_soc_codec_conf rt1011_2spk_codec_confs[] = {
78 	{
79 		.dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME),
80 		.name_prefix = "Left",
81 	},
82 	{
83 		.dlc = COMP_CODEC_CONF(RT1011_DEV1_NAME),
84 		.name_prefix = "Right",
85 	},
86 };
87 
88 static struct snd_soc_codec_conf rt1011_4spk_codec_confs[] = {
89 	{
90 		.dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME),
91 		.name_prefix = "WL",
92 	},
93 	{
94 		.dlc = COMP_CODEC_CONF(RT1011_DEV1_NAME),
95 		.name_prefix = "WR",
96 	},
97 	{
98 		.dlc = COMP_CODEC_CONF(RT1011_DEV2_NAME),
99 		.name_prefix = "TL",
100 	},
101 	{
102 		.dlc = COMP_CODEC_CONF(RT1011_DEV3_NAME),
103 		.name_prefix = "TR",
104 	},
105 };
106 
107 static struct snd_soc_dai_link_component rt1011_dai_link_components[] = {
108 	{
109 		.name = RT1011_DEV0_NAME,
110 		.dai_name = RT1011_CODEC_DAI,
111 	},
112 	{
113 		.name = RT1011_DEV1_NAME,
114 		.dai_name = RT1011_CODEC_DAI,
115 	},
116 	{
117 		.name = RT1011_DEV2_NAME,
118 		.dai_name = RT1011_CODEC_DAI,
119 	},
120 	{
121 		.name = RT1011_DEV3_NAME,
122 		.dai_name = RT1011_CODEC_DAI,
123 	},
124 };
125 
126 static const struct {
127 	unsigned int tx;
128 	unsigned int rx;
129 } rt1011_tdm_mask[] = {
130 	{.tx = 0x4, .rx = 0x1},
131 	{.tx = 0x8, .rx = 0x2},
132 	{.tx = 0x1, .rx = 0x1},
133 	{.tx = 0x2, .rx = 0x2},
134 };
135 
136 static int rt1011_hw_params(struct snd_pcm_substream *substream,
137 			    struct snd_pcm_hw_params *params)
138 {
139 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
140 	struct snd_soc_dai *codec_dai;
141 	int srate, i, ret = 0;
142 
143 	srate = params_rate(params);
144 
145 	for_each_rtd_codec_dais(rtd, i, codec_dai) {
146 		/* 100 Fs to drive 24 bit data */
147 		ret = snd_soc_dai_set_pll(codec_dai, 0, RT1011_PLL1_S_BCLK,
148 					  100 * srate, 256 * srate);
149 		if (ret < 0) {
150 			dev_err(codec_dai->dev, "fail to set pll, ret %d\n",
151 				ret);
152 			return ret;
153 		}
154 
155 		ret = snd_soc_dai_set_sysclk(codec_dai, RT1011_FS_SYS_PRE_S_PLL1,
156 					     256 * srate, SND_SOC_CLOCK_IN);
157 		if (ret < 0) {
158 			dev_err(codec_dai->dev, "fail to set sysclk, ret %d\n",
159 				ret);
160 			return ret;
161 		}
162 
163 		if (i >= ARRAY_SIZE(rt1011_tdm_mask)) {
164 			dev_err(codec_dai->dev, "invalid codec index %d\n",
165 				i);
166 			return -ENODEV;
167 		}
168 
169 		ret = snd_soc_dai_set_tdm_slot(codec_dai, rt1011_tdm_mask[i].tx,
170 					       rt1011_tdm_mask[i].rx, 4,
171 					       params_width(params));
172 		if (ret < 0) {
173 			dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n",
174 				ret);
175 			return ret;
176 		}
177 	}
178 
179 	return 0;
180 }
181 
182 static const struct snd_soc_ops rt1011_ops = {
183 	.hw_params = rt1011_hw_params,
184 };
185 
186 static int rt1011_init(struct snd_soc_pcm_runtime *rtd)
187 {
188 	struct snd_soc_card *card = rtd->card;
189 	unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID);
190 	int ret;
191 
192 	switch (num_codecs) {
193 	case 2:
194 		if (!soc_intel_is_cml()) {
195 			ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets,
196 							ARRAY_SIZE(realtek_2spk_widgets));
197 			if (ret) {
198 				dev_err(rtd->dev, "fail to add rt1011 widgets, ret %d\n",
199 					ret);
200 				return ret;
201 			}
202 
203 			ret = snd_soc_add_card_controls(card, realtek_2spk_kcontrols,
204 							ARRAY_SIZE(realtek_2spk_kcontrols));
205 			if (ret) {
206 				dev_err(rtd->dev, "fail to add rt1011 kcontrols, ret %d\n",
207 					ret);
208 				return ret;
209 			}
210 
211 			ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map_lr,
212 						      ARRAY_SIZE(speaker_map_lr));
213 			if (ret) {
214 				dev_err(rtd->dev, "fail to add rt1011 routes, ret %d\n",
215 					ret);
216 				return ret;
217 			}
218 
219 			break;
220 		}
221 
222 		/*
223 		 * register speaker widgets "WL Ext Spk" and "WR Ext Spk" to
224 		 * keep backward compatible with cml devices
225 		 */
226 		fallthrough;
227 	case 4:
228 		ret = snd_soc_dapm_new_controls(&card->dapm, realtek_4spk_widgets,
229 						num_codecs);
230 		if (ret) {
231 			dev_err(rtd->dev, "fail to add rt1011 widgets, ret %d\n",
232 				ret);
233 			return ret;
234 		}
235 
236 		ret = snd_soc_add_card_controls(card, realtek_4spk_kcontrols,
237 						num_codecs);
238 		if (ret) {
239 			dev_err(rtd->dev, "fail to add rt1011 controls, ret %d\n",
240 				ret);
241 			return ret;
242 		}
243 
244 		ret = snd_soc_dapm_add_routes(&card->dapm, rt1011_4spk_routes,
245 					      num_codecs);
246 		if (ret) {
247 			dev_err(rtd->dev, "fail to add rt1011 routes, ret %d\n",
248 				ret);
249 			return ret;
250 		}
251 		break;
252 	default:
253 		dev_err(rtd->dev, "rt1011: invalid num_codecs %d\n", num_codecs);
254 		return -EINVAL;
255 	}
256 
257 	return ret;
258 }
259 
260 void sof_rt1011_dai_link(struct device *dev, struct snd_soc_dai_link *link)
261 {
262 	unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID);
263 
264 	link->codecs = rt1011_dai_link_components;
265 
266 	switch (num_codecs) {
267 	case 2:
268 	case 4:
269 		link->num_codecs = num_codecs;
270 		break;
271 	default:
272 		dev_err(dev, "rt1011: invalid num_codecs %d\n", num_codecs);
273 		break;
274 	}
275 
276 	link->init = rt1011_init;
277 	link->ops = &rt1011_ops;
278 }
279 EXPORT_SYMBOL_NS(sof_rt1011_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON);
280 
281 void sof_rt1011_codec_conf(struct device *dev, struct snd_soc_card *card)
282 {
283 	unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID);
284 
285 	switch (num_codecs) {
286 	case 2:
287 		if (soc_intel_is_cml()) {
288 			/*
289 			 * use name prefix 'WL' and 'WR' for speaker widgets to
290 			 * keep backward compatible with cml devices
291 			 */
292 			card->codec_conf = rt1011_4spk_codec_confs;
293 		} else {
294 			card->codec_conf = rt1011_2spk_codec_confs;
295 		}
296 
297 		card->num_configs = num_codecs;
298 		break;
299 	case 4:
300 		card->codec_conf = rt1011_4spk_codec_confs;
301 		card->num_configs = ARRAY_SIZE(rt1011_4spk_codec_confs);
302 		break;
303 	default:
304 		dev_err(dev, "rt1011: invalid num_codecs %d\n", num_codecs);
305 		break;
306 	}
307 
308 }
309 EXPORT_SYMBOL_NS(sof_rt1011_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON);
310 
311 /*
312  * rt1015:  i2c mode driver for ALC1015 and ALC1015Q
313  * rt1015p: auto-mode driver for ALC1015, ALC1015Q, and ALC1015Q-VB
314  *
315  * For stereo output, there are always two amplifiers on the board.
316  * However, the ACPI implements only one device instance (UID=0) if they
317  * are sharing the same enable pin. The code will detect the number of
318  * device instance and use corresponding DAPM structures for
319  * initialization.
320  */
321 static const struct snd_soc_dapm_route rt1015p_1dev_dapm_routes[] = {
322 	/* speaker */
323 	{ "Left Spk", NULL, "Speaker" },
324 	{ "Right Spk", NULL, "Speaker" },
325 };
326 
327 static const struct snd_soc_dapm_route rt1015p_2dev_dapm_routes[] = {
328 	/* speaker */
329 	{ "Left Spk", NULL, "Left Speaker" },
330 	{ "Right Spk", NULL, "Right Speaker" },
331 };
332 
333 static struct snd_soc_codec_conf rt1015p_codec_confs[] = {
334 	{
335 		.dlc = COMP_CODEC_CONF(RT1015P_DEV0_NAME),
336 		.name_prefix = "Left",
337 	},
338 	{
339 		.dlc = COMP_CODEC_CONF(RT1015P_DEV1_NAME),
340 		.name_prefix = "Right",
341 	},
342 };
343 
344 static struct snd_soc_dai_link_component rt1015p_dai_link_components[] = {
345 	{
346 		.name = RT1015P_DEV0_NAME,
347 		.dai_name = RT1015P_CODEC_DAI,
348 	},
349 	{
350 		.name = RT1015P_DEV1_NAME,
351 		.dai_name = RT1015P_CODEC_DAI,
352 	},
353 };
354 
355 static int rt1015p_get_num_codecs(void)
356 {
357 	static int dev_num;
358 
359 	if (dev_num)
360 		return dev_num;
361 
362 	if (!acpi_dev_present("RTL1015", "1", -1))
363 		dev_num = 1;
364 	else
365 		dev_num = 2;
366 
367 	return dev_num;
368 }
369 
370 static int rt1015p_hw_params(struct snd_pcm_substream *substream,
371 			     struct snd_pcm_hw_params *params)
372 {
373 	/* reserved for debugging purpose */
374 
375 	return 0;
376 }
377 
378 static const struct snd_soc_ops rt1015p_ops = {
379 	.hw_params = rt1015p_hw_params,
380 };
381 
382 static int rt1015p_init(struct snd_soc_pcm_runtime *rtd)
383 {
384 	struct snd_soc_card *card = rtd->card;
385 	int ret;
386 
387 	ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets,
388 					ARRAY_SIZE(realtek_2spk_widgets));
389 	if (ret) {
390 		dev_err(rtd->dev, "fail to add rt1015p widgets, ret %d\n", ret);
391 		return ret;
392 	}
393 
394 	ret = snd_soc_add_card_controls(card, realtek_2spk_kcontrols,
395 					ARRAY_SIZE(realtek_2spk_kcontrols));
396 	if (ret) {
397 		dev_err(rtd->dev, "fail to add rt1015p kcontrols, ret %d\n", ret);
398 		return ret;
399 	}
400 
401 	if (rt1015p_get_num_codecs() == 1)
402 		ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_1dev_dapm_routes,
403 					      ARRAY_SIZE(rt1015p_1dev_dapm_routes));
404 	else
405 		ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_2dev_dapm_routes,
406 					      ARRAY_SIZE(rt1015p_2dev_dapm_routes));
407 	if (ret)
408 		dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret);
409 	return ret;
410 }
411 
412 void sof_rt1015p_dai_link(struct snd_soc_dai_link *link)
413 {
414 	link->codecs = rt1015p_dai_link_components;
415 	link->num_codecs = rt1015p_get_num_codecs();
416 	link->init = rt1015p_init;
417 	link->ops = &rt1015p_ops;
418 }
419 EXPORT_SYMBOL_NS(sof_rt1015p_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON);
420 
421 void sof_rt1015p_codec_conf(struct snd_soc_card *card)
422 {
423 	if (rt1015p_get_num_codecs() == 1)
424 		return;
425 
426 	card->codec_conf = rt1015p_codec_confs;
427 	card->num_configs = ARRAY_SIZE(rt1015p_codec_confs);
428 }
429 EXPORT_SYMBOL_NS(sof_rt1015p_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON);
430 
431 /*
432  * RT1015 audio amplifier
433  */
434 
435 static const struct {
436 	unsigned int tx;
437 	unsigned int rx;
438 } rt1015_tdm_mask[] = {
439 	{.tx = 0x0, .rx = 0x1},
440 	{.tx = 0x0, .rx = 0x2},
441 };
442 
443 static int rt1015_hw_params(struct snd_pcm_substream *substream,
444 			    struct snd_pcm_hw_params *params)
445 {
446 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
447 	struct snd_soc_dai_link *dai_link = rtd->dai_link;
448 	struct snd_soc_dai *codec_dai;
449 	int i, clk_freq;
450 	int ret = 0;
451 
452 	clk_freq = sof_dai_get_bclk(rtd);
453 
454 	if (clk_freq <= 0) {
455 		dev_err(rtd->dev, "fail to get bclk freq, ret %d\n", clk_freq);
456 		return -EINVAL;
457 	}
458 
459 	for_each_rtd_codec_dais(rtd, i, codec_dai) {
460 		ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK,
461 					  clk_freq,
462 					  params_rate(params) * 256);
463 		if (ret) {
464 			dev_err(codec_dai->dev, "fail to set pll, ret %d\n",
465 				ret);
466 			return ret;
467 		}
468 
469 		ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL,
470 					     params_rate(params) * 256,
471 					     SND_SOC_CLOCK_IN);
472 		if (ret) {
473 			dev_err(codec_dai->dev, "fail to set sysclk, ret %d\n",
474 				ret);
475 			return ret;
476 		}
477 
478 		switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
479 		case SND_SOC_DAIFMT_DSP_A:
480 		case SND_SOC_DAIFMT_DSP_B:
481 			/* 4-slot TDM */
482 			ret = snd_soc_dai_set_tdm_slot(codec_dai,
483 						       rt1015_tdm_mask[i].tx,
484 						       rt1015_tdm_mask[i].rx,
485 						       4,
486 						       params_width(params));
487 			if (ret < 0) {
488 				dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n",
489 					ret);
490 				return ret;
491 			}
492 			break;
493 		default:
494 			dev_dbg(codec_dai->dev, "codec is in I2S mode\n");
495 			break;
496 		}
497 	}
498 
499 	return ret;
500 }
501 
502 static struct snd_soc_ops rt1015_ops = {
503 	.hw_params = rt1015_hw_params,
504 };
505 
506 static struct snd_soc_codec_conf rt1015_amp_conf[] = {
507 	{
508 		.dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME),
509 		.name_prefix = "Left",
510 	},
511 	{
512 		.dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME),
513 		.name_prefix = "Right",
514 	},
515 };
516 
517 static struct snd_soc_dai_link_component rt1015_components[] = {
518 	{
519 		.name = RT1015_DEV0_NAME,
520 		.dai_name = RT1015_CODEC_DAI,
521 	},
522 	{
523 		.name = RT1015_DEV1_NAME,
524 		.dai_name = RT1015_CODEC_DAI,
525 	},
526 };
527 
528 static int speaker_codec_init_lr(struct snd_soc_pcm_runtime *rtd)
529 {
530 	struct snd_soc_card *card = rtd->card;
531 	unsigned int num_codecs = get_num_codecs(RT1015_ACPI_HID);
532 	int ret;
533 
534 	switch (num_codecs) {
535 	case 2:
536 		ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets,
537 						ARRAY_SIZE(realtek_2spk_widgets));
538 		if (ret) {
539 			dev_err(rtd->dev, "fail to add rt1015 widgets, ret %d\n",
540 				ret);
541 			return ret;
542 		}
543 
544 		ret = snd_soc_add_card_controls(card, realtek_2spk_kcontrols,
545 						ARRAY_SIZE(realtek_2spk_kcontrols));
546 		if (ret) {
547 			dev_err(rtd->dev, "fail to add rt1015 kcontrols, ret %d\n",
548 				ret);
549 			return ret;
550 		}
551 
552 		ret = snd_soc_dapm_add_routes(&rtd->card->dapm, speaker_map_lr,
553 					      ARRAY_SIZE(speaker_map_lr));
554 		if (ret) {
555 			dev_err(rtd->dev, "fail to add rt1015 routes, ret %d\n",
556 				ret);
557 			return ret;
558 		}
559 		break;
560 	default:
561 		dev_err(rtd->dev, "rt1015: invalid num_codecs %d\n", num_codecs);
562 		return -EINVAL;
563 	}
564 
565 	return ret;
566 }
567 
568 void sof_rt1015_codec_conf(struct snd_soc_card *card)
569 {
570 	card->codec_conf = rt1015_amp_conf;
571 	card->num_configs = ARRAY_SIZE(rt1015_amp_conf);
572 }
573 EXPORT_SYMBOL_NS(sof_rt1015_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON);
574 
575 void sof_rt1015_dai_link(struct snd_soc_dai_link *link)
576 {
577 	link->codecs = rt1015_components;
578 	link->num_codecs = ARRAY_SIZE(rt1015_components);
579 	link->init = speaker_codec_init_lr;
580 	link->ops = &rt1015_ops;
581 }
582 EXPORT_SYMBOL_NS(sof_rt1015_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON);
583 
584 /*
585  * RT1308 audio amplifier
586  */
587 static const struct snd_kcontrol_new rt1308_kcontrols[] = {
588 	SOC_DAPM_PIN_SWITCH("Speakers"),
589 };
590 
591 static const struct snd_soc_dapm_widget rt1308_dapm_widgets[] = {
592 	SND_SOC_DAPM_SPK("Speakers", NULL),
593 };
594 
595 static const struct snd_soc_dapm_route rt1308_dapm_routes[] = {
596 	/* speaker */
597 	{"Speakers", NULL, "SPOL"},
598 	{"Speakers", NULL, "SPOR"},
599 };
600 
601 static struct snd_soc_dai_link_component rt1308_components[] = {
602 	{
603 		.name = RT1308_DEV0_NAME,
604 		.dai_name = RT1308_CODEC_DAI,
605 	}
606 };
607 
608 static int rt1308_init(struct snd_soc_pcm_runtime *rtd)
609 {
610 	struct snd_soc_card *card = rtd->card;
611 	int ret;
612 
613 	ret = snd_soc_dapm_new_controls(&card->dapm, rt1308_dapm_widgets,
614 					ARRAY_SIZE(rt1308_dapm_widgets));
615 	if (ret) {
616 		dev_err(rtd->dev, "fail to add dapm controls, ret %d\n", ret);
617 		return ret;
618 	}
619 
620 	ret = snd_soc_add_card_controls(card, rt1308_kcontrols,
621 					ARRAY_SIZE(rt1308_kcontrols));
622 	if (ret) {
623 		dev_err(rtd->dev, "fail to add card controls, ret %d\n", ret);
624 		return ret;
625 	}
626 
627 	ret = snd_soc_dapm_add_routes(&card->dapm, rt1308_dapm_routes,
628 				      ARRAY_SIZE(rt1308_dapm_routes));
629 
630 	if (ret)
631 		dev_err(rtd->dev, "fail to add dapm routes, ret %d\n", ret);
632 
633 	return ret;
634 }
635 
636 static int rt1308_hw_params(struct snd_pcm_substream *substream,
637 			    struct snd_pcm_hw_params *params)
638 {
639 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
640 	struct snd_soc_card *card = rtd->card;
641 	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
642 	int clk_id, clk_freq, pll_out;
643 	int ret;
644 
645 	clk_id = RT1308_PLL_S_MCLK;
646 	/* get the tplg configured mclk. */
647 	clk_freq = sof_dai_get_mclk(rtd);
648 
649 	pll_out = params_rate(params) * 512;
650 
651 	/* Set rt1308 pll */
652 	ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out);
653 	if (ret < 0) {
654 		dev_err(card->dev, "Failed to set RT1308 PLL: %d\n", ret);
655 		return ret;
656 	}
657 
658 	/* Set rt1308 sysclk */
659 	ret = snd_soc_dai_set_sysclk(codec_dai, RT1308_FS_SYS_S_PLL, pll_out,
660 				     SND_SOC_CLOCK_IN);
661 	if (ret < 0)
662 		dev_err(card->dev, "Failed to set RT1308 SYSCLK: %d\n", ret);
663 
664 	return ret;
665 }
666 
667 static const struct snd_soc_ops rt1308_ops = {
668 	.hw_params = rt1308_hw_params,
669 };
670 
671 void sof_rt1308_dai_link(struct snd_soc_dai_link *link)
672 {
673 	link->codecs = rt1308_components;
674 	link->num_codecs = ARRAY_SIZE(rt1308_components);
675 	link->init = rt1308_init;
676 	link->ops = &rt1308_ops;
677 }
678 EXPORT_SYMBOL_NS(sof_rt1308_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON);
679 
680 /*
681  * 2-amp Configuration for RT1019
682  */
683 
684 static const struct snd_soc_dapm_route rt1019p_dapm_routes[] = {
685 	/* speaker */
686 	{ "Left Spk", NULL, "Speaker" },
687 	{ "Right Spk", NULL, "Speaker" },
688 };
689 
690 static struct snd_soc_dai_link_component rt1019p_components[] = {
691 	{
692 		.name = RT1019P_DEV0_NAME,
693 		.dai_name = RT1019P_CODEC_DAI,
694 	},
695 };
696 
697 static int rt1019p_init(struct snd_soc_pcm_runtime *rtd)
698 {
699 	struct snd_soc_card *card = rtd->card;
700 	int ret;
701 
702 	ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets,
703 					ARRAY_SIZE(realtek_2spk_widgets));
704 	if (ret) {
705 		dev_err(rtd->dev, "fail to add rt1019p widgets, ret %d\n", ret);
706 		return ret;
707 	}
708 
709 	ret = snd_soc_add_card_controls(card, realtek_2spk_kcontrols,
710 					ARRAY_SIZE(realtek_2spk_kcontrols));
711 	if (ret) {
712 		dev_err(rtd->dev, "fail to add rt1019p kcontrols, ret %d\n", ret);
713 		return ret;
714 	}
715 
716 	ret = snd_soc_dapm_add_routes(&card->dapm, rt1019p_dapm_routes,
717 				      ARRAY_SIZE(rt1019p_dapm_routes));
718 	if (ret) {
719 		dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret);
720 		return ret;
721 	}
722 	return ret;
723 }
724 
725 void sof_rt1019p_dai_link(struct snd_soc_dai_link *link)
726 {
727 	link->codecs = rt1019p_components;
728 	link->num_codecs = ARRAY_SIZE(rt1019p_components);
729 	link->init = rt1019p_init;
730 }
731 EXPORT_SYMBOL_NS(sof_rt1019p_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON);
732 
733 MODULE_DESCRIPTION("ASoC Intel SOF Realtek helpers");
734 MODULE_LICENSE("GPL");
735