xref: /linux/sound/soc/amd/acp/acp-mach-common.c (revision a266ef69b890f099069cf51bb40572611c435a54)
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2 //
3 // This file is provided under a dual BSD/GPLv2 license. When using or
4 // redistributing this file, you may do so under either license.
5 //
6 // Copyright(c) 2021 Advanced Micro Devices, Inc.
7 //
8 // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
9 //	    Vijendar Mukunda <Vijendar.Mukunda@amd.com>
10 //
11 
12 /*
13  * Machine Driver Interface for ACP HW block
14  */
15 
16 #include <sound/core.h>
17 #include <sound/jack.h>
18 #include <sound/pcm_params.h>
19 #include <sound/soc-dapm.h>
20 #include <sound/soc.h>
21 #include <linux/input.h>
22 #include <linux/module.h>
23 
24 #include "../../codecs/rt5682.h"
25 #include "../../codecs/rt1019.h"
26 #include "../../codecs/rt5682s.h"
27 #include "../../codecs/nau8825.h"
28 #include "acp-mach.h"
29 
30 #define PCO_PLAT_CLK 48000000
31 #define RT5682_PLL_FREQ (48000 * 512)
32 #define DUAL_CHANNEL	2
33 #define FOUR_CHANNEL	4
34 
35 static struct snd_soc_jack pco_jack;
36 
37 static const unsigned int channels[] = {
38 	DUAL_CHANNEL,
39 };
40 
41 static const unsigned int rates[] = {
42 	48000,
43 };
44 
45 static const struct snd_pcm_hw_constraint_list constraints_rates = {
46 	.count = ARRAY_SIZE(rates),
47 	.list  = rates,
48 	.mask = 0,
49 };
50 
51 static const struct snd_pcm_hw_constraint_list constraints_channels = {
52 	.count = ARRAY_SIZE(channels),
53 	.list = channels,
54 	.mask = 0,
55 };
56 
57 static int acp_clk_enable(struct acp_card_drvdata *drvdata)
58 {
59 	clk_set_rate(drvdata->wclk, 48000);
60 	clk_set_rate(drvdata->bclk, 48000 * 64);
61 
62 	return clk_prepare_enable(drvdata->wclk);
63 }
64 
65 /* Declare RT5682 codec components */
66 SND_SOC_DAILINK_DEF(rt5682,
67 	DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1")));
68 
69 static const struct snd_soc_dapm_route rt5682_map[] = {
70 	{ "Headphone Jack", NULL, "HPOL" },
71 	{ "Headphone Jack", NULL, "HPOR" },
72 	{ "IN1P", NULL, "Headset Mic" },
73 };
74 
75 /* Define card ops for RT5682 CODEC */
76 static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd)
77 {
78 	struct snd_soc_card *card = rtd->card;
79 	struct acp_card_drvdata *drvdata = card->drvdata;
80 	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
81 	struct snd_soc_component *component = codec_dai->component;
82 	int ret;
83 
84 	dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
85 
86 	if (drvdata->hs_codec_id != RT5682)
87 		return -EINVAL;
88 
89 	ret =  snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
90 				   | SND_SOC_DAIFMT_CBP_CFP);
91 	if (ret < 0) {
92 		dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
93 		return ret;
94 	}
95 
96 	ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL2, RT5682_PLL2_S_MCLK,
97 				  PCO_PLAT_CLK, RT5682_PLL_FREQ);
98 	if (ret < 0) {
99 		dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
100 		return ret;
101 	}
102 
103 	ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL2,
104 				     RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
105 	if (ret < 0) {
106 		dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
107 		return ret;
108 	}
109 
110 	/* Set tdm/i2s1 master bclk ratio */
111 	ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64);
112 	if (ret < 0) {
113 		dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret);
114 		return ret;
115 	}
116 
117 	drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
118 	drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
119 
120 	ret = snd_soc_card_jack_new(card, "Headset Jack",
121 				    SND_JACK_HEADSET | SND_JACK_LINEOUT |
122 				    SND_JACK_BTN_0 | SND_JACK_BTN_1 |
123 				    SND_JACK_BTN_2 | SND_JACK_BTN_3,
124 				    &pco_jack);
125 	if (ret) {
126 		dev_err(card->dev, "HP jack creation failed %d\n", ret);
127 		return ret;
128 	}
129 
130 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
131 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
132 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
133 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
134 
135 	ret = snd_soc_component_set_jack(component, &pco_jack, NULL);
136 	if (ret) {
137 		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
138 		return ret;
139 	}
140 
141 	return snd_soc_dapm_add_routes(&rtd->card->dapm, rt5682_map, ARRAY_SIZE(rt5682_map));
142 }
143 
144 static int acp_card_hs_startup(struct snd_pcm_substream *substream)
145 {
146 	struct snd_pcm_runtime *runtime = substream->runtime;
147 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
148 	struct snd_soc_card *card = rtd->card;
149 	struct acp_card_drvdata *drvdata = card->drvdata;
150 	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
151 	int ret;
152 	unsigned int fmt;
153 
154 	if (drvdata->soc_mclk)
155 		fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
156 	else
157 		fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
158 
159 	ret =  snd_soc_dai_set_fmt(codec_dai, fmt);
160 	if (ret < 0) {
161 		dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
162 		return ret;
163 	}
164 
165 	runtime->hw.channels_max = DUAL_CHANNEL;
166 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
167 				      &constraints_channels);
168 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
169 				      &constraints_rates);
170 
171 	if (strcmp(codec_dai->name, "rt5682s-aif1") && strcmp(codec_dai->name, "rt5682s-aif2")) {
172 		if (!drvdata->soc_mclk) {
173 			ret = acp_clk_enable(drvdata);
174 			if (ret < 0) {
175 				dev_err(rtd->card->dev, "Failed to enable HS clk: %d\n", ret);
176 				return ret;
177 			}
178 		}
179 	}
180 
181 	return ret;
182 }
183 
184 static void acp_card_shutdown(struct snd_pcm_substream *substream)
185 {
186 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
187 	struct snd_soc_card *card = rtd->card;
188 	struct acp_card_drvdata *drvdata = card->drvdata;
189 
190 	if (!drvdata->soc_mclk)
191 		clk_disable_unprepare(drvdata->wclk);
192 }
193 
194 static const struct snd_soc_ops acp_card_rt5682_ops = {
195 	.startup = acp_card_hs_startup,
196 	.shutdown = acp_card_shutdown,
197 };
198 
199 /* Define RT5682S CODEC component*/
200 SND_SOC_DAILINK_DEF(rt5682s,
201 		    DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RTL5682:00", "rt5682s-aif1")));
202 
203 static const struct snd_soc_dapm_route rt5682s_map[] = {
204 	{ "Headphone Jack", NULL, "HPOL" },
205 	{ "Headphone Jack", NULL, "HPOR" },
206 	{ "IN1P", NULL, "Headset Mic" },
207 };
208 
209 static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd)
210 {
211 	struct snd_soc_card *card = rtd->card;
212 	struct acp_card_drvdata *drvdata = card->drvdata;
213 	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
214 	struct snd_soc_component *component = codec_dai->component;
215 	unsigned int fmt;
216 	int ret;
217 
218 	dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
219 
220 	if (drvdata->hs_codec_id != RT5682S)
221 		return -EINVAL;
222 
223 	if (drvdata->soc_mclk)
224 		fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
225 	else
226 		fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
227 
228 	ret =  snd_soc_dai_set_fmt(codec_dai, fmt);
229 	if (ret < 0) {
230 		dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
231 		return ret;
232 	}
233 
234 	ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL2, RT5682S_PLL_S_MCLK,
235 				  PCO_PLAT_CLK, RT5682_PLL_FREQ);
236 	if (ret < 0) {
237 		dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
238 		return ret;
239 	}
240 
241 	ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL2,
242 				     RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
243 	if (ret < 0) {
244 		dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
245 		return ret;
246 	}
247 
248 	/* Set tdm/i2s1 master bclk ratio */
249 	ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64);
250 	if (ret < 0) {
251 		dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret);
252 		return ret;
253 	}
254 
255 	if (!drvdata->soc_mclk) {
256 		drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
257 		drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
258 	}
259 
260 	ret = snd_soc_card_jack_new(card, "Headset Jack",
261 				    SND_JACK_HEADSET | SND_JACK_LINEOUT |
262 				    SND_JACK_BTN_0 | SND_JACK_BTN_1 |
263 				    SND_JACK_BTN_2 | SND_JACK_BTN_3,
264 				    &pco_jack);
265 	if (ret) {
266 		dev_err(card->dev, "HP jack creation failed %d\n", ret);
267 		return ret;
268 	}
269 
270 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
271 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
272 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
273 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
274 
275 	ret = snd_soc_component_set_jack(component, &pco_jack, NULL);
276 	if (ret) {
277 		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
278 		return ret;
279 	}
280 
281 	return snd_soc_dapm_add_routes(&rtd->card->dapm, rt5682s_map, ARRAY_SIZE(rt5682s_map));
282 }
283 
284 static const struct snd_soc_ops acp_card_rt5682s_ops = {
285 	.startup = acp_card_hs_startup,
286 };
287 
288 static const unsigned int dmic_channels[] = {
289 	DUAL_CHANNEL, FOUR_CHANNEL,
290 };
291 
292 static const struct snd_pcm_hw_constraint_list dmic_constraints_channels = {
293 	.count = ARRAY_SIZE(dmic_channels),
294 	.list = dmic_channels,
295 	.mask = 0,
296 };
297 
298 static int acp_card_dmic_startup(struct snd_pcm_substream *substream)
299 {
300 	struct snd_pcm_runtime *runtime = substream->runtime;
301 
302 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
303 				   &dmic_constraints_channels);
304 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
305 				   &constraints_rates);
306 
307 	return 0;
308 }
309 
310 static const struct snd_soc_ops acp_card_dmic_ops = {
311 	.startup = acp_card_dmic_startup,
312 };
313 
314 /* Declare RT1019 codec components */
315 SND_SOC_DAILINK_DEF(rt1019,
316 	DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"),
317 			  COMP_CODEC("i2c-10EC1019:01", "rt1019-aif")));
318 
319 static const struct snd_soc_dapm_route rt1019_map_lr[] = {
320 	{ "Left Spk", NULL, "Left SPO" },
321 	{ "Right Spk", NULL, "Right SPO" },
322 };
323 
324 static struct snd_soc_codec_conf rt1019_conf[] = {
325 	{
326 		 .dlc = COMP_CODEC_CONF("i2c-10EC1019:01"),
327 		 .name_prefix = "Left",
328 	},
329 	{
330 		 .dlc = COMP_CODEC_CONF("i2c-10EC1019:00"),
331 		 .name_prefix = "Right",
332 	},
333 };
334 
335 static int acp_card_rt1019_init(struct snd_soc_pcm_runtime *rtd)
336 {
337 	struct snd_soc_card *card = rtd->card;
338 	struct acp_card_drvdata *drvdata = card->drvdata;
339 
340 	if (drvdata->amp_codec_id != RT1019)
341 		return -EINVAL;
342 
343 	return snd_soc_dapm_add_routes(&rtd->card->dapm, rt1019_map_lr,
344 				       ARRAY_SIZE(rt1019_map_lr));
345 }
346 
347 static int acp_card_rt1019_hw_params(struct snd_pcm_substream *substream,
348 				     struct snd_pcm_hw_params *params)
349 {
350 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
351 	struct snd_soc_card *card = rtd->card;
352 	struct acp_card_drvdata *drvdata = card->drvdata;
353 	struct snd_soc_dai *codec_dai;
354 	int srate, i, ret = 0;
355 
356 	srate = params_rate(params);
357 
358 	if (drvdata->amp_codec_id != RT1019)
359 		return -EINVAL;
360 
361 	for_each_rtd_codec_dais(rtd, i, codec_dai) {
362 		if (strcmp(codec_dai->name, "rt1019-aif"))
363 			continue;
364 
365 		ret = snd_soc_dai_set_pll(codec_dai, 0, RT1019_PLL_S_BCLK,
366 					  64 * srate, 256 * srate);
367 		if (ret < 0)
368 			return ret;
369 
370 		ret = snd_soc_dai_set_sysclk(codec_dai, RT1019_SCLK_S_PLL,
371 					     256 * srate, SND_SOC_CLOCK_IN);
372 		if (ret < 0)
373 			return ret;
374 	}
375 
376 	return 0;
377 }
378 
379 static int acp_card_amp_startup(struct snd_pcm_substream *substream)
380 {
381 	struct snd_pcm_runtime *runtime = substream->runtime;
382 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
383 	struct snd_soc_card *card = rtd->card;
384 	struct acp_card_drvdata *drvdata = card->drvdata;
385 	int ret = 0;
386 
387 	runtime->hw.channels_max = DUAL_CHANNEL;
388 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
389 				      &constraints_channels);
390 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
391 				      &constraints_rates);
392 
393 	if (!drvdata->soc_mclk) {
394 		ret = acp_clk_enable(drvdata);
395 		if (ret < 0) {
396 			dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret);
397 			return ret;
398 		}
399 	}
400 	return ret;
401 }
402 
403 static const struct snd_soc_ops acp_card_rt1019_ops = {
404 	.startup = acp_card_amp_startup,
405 	.shutdown = acp_card_shutdown,
406 	.hw_params = acp_card_rt1019_hw_params,
407 };
408 
409 /* Declare Maxim codec components */
410 SND_SOC_DAILINK_DEF(max98360a,
411 	DAILINK_COMP_ARRAY(COMP_CODEC("MX98360A:00", "HiFi")));
412 
413 static const struct snd_soc_dapm_route max98360a_map[] = {
414 	{"Spk", NULL, "Speaker"},
415 };
416 
417 static int acp_card_maxim_init(struct snd_soc_pcm_runtime *rtd)
418 {
419 	struct snd_soc_card *card = rtd->card;
420 	struct acp_card_drvdata *drvdata = card->drvdata;
421 
422 	if (drvdata->amp_codec_id != MAX98360A)
423 		return -EINVAL;
424 
425 	return snd_soc_dapm_add_routes(&rtd->card->dapm, max98360a_map,
426 				       ARRAY_SIZE(max98360a_map));
427 }
428 
429 static const struct snd_soc_ops acp_card_maxim_ops = {
430 	.startup = acp_card_amp_startup,
431 	.shutdown = acp_card_shutdown,
432 };
433 
434 /* Declare nau8825 codec components */
435 SND_SOC_DAILINK_DEF(nau8825,
436 		    DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10508825:00", "nau8825-hifi")));
437 
438 static const struct snd_soc_dapm_route nau8825_map[] = {
439 	{ "Headphone Jack", NULL, "HPOL" },
440 	{ "Headphone Jack", NULL, "HPOR" },
441 };
442 
443 static int acp_card_nau8825_init(struct snd_soc_pcm_runtime *rtd)
444 {
445 	struct snd_soc_card *card = rtd->card;
446 	struct acp_card_drvdata *drvdata = card->drvdata;
447 	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
448 	struct snd_soc_component *component = codec_dai->component;
449 	unsigned int fmt;
450 	int ret;
451 
452 	dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
453 
454 	if (drvdata->hs_codec_id != NAU8825)
455 		return -EINVAL;
456 
457 	if (drvdata->soc_mclk)
458 		fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
459 	else
460 		fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
461 
462 	ret =  snd_soc_dai_set_fmt(codec_dai, fmt);
463 	if (ret < 0) {
464 		dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
465 		return ret;
466 	}
467 	ret = snd_soc_card_jack_new(card, "Headset Jack",
468 					 SND_JACK_HEADSET | SND_JACK_LINEOUT |
469 					 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
470 					 SND_JACK_BTN_2 | SND_JACK_BTN_3,
471 					 &pco_jack);
472 	if (ret) {
473 		dev_err(card->dev, "HP jack creation failed %d\n", ret);
474 		return ret;
475 	}
476 
477 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
478 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
479 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
480 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
481 
482 	ret = snd_soc_component_set_jack(component, &pco_jack, NULL);
483 	if (ret) {
484 		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
485 		return ret;
486 	}
487 
488 	return snd_soc_dapm_add_routes(&rtd->card->dapm, nau8825_map, ARRAY_SIZE(nau8825_map));
489 }
490 
491 static int acp_nau8825_hw_params(struct snd_pcm_substream *substream,
492 				 struct snd_pcm_hw_params *params)
493 {
494 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
495 	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
496 	int ret;
497 
498 	ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_FS,
499 				     (48000 * 256), SND_SOC_CLOCK_IN);
500 	if (ret < 0)
501 		dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
502 
503 	ret = snd_soc_dai_set_pll(codec_dai, 0, 0, params_rate(params),
504 				  params_rate(params) * 256);
505 	if (ret < 0) {
506 		dev_err(rtd->dev, "can't set FLL: %d\n", ret);
507 		return ret;
508 	}
509 
510 	return ret;
511 }
512 
513 static int acp_nau8825_startup(struct snd_pcm_substream *substream)
514 {
515 	struct snd_pcm_runtime *runtime = substream->runtime;
516 
517 	runtime->hw.channels_max = 2;
518 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
519 				   &constraints_channels);
520 
521 	runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
522 	snd_pcm_hw_constraint_list(runtime, 0,
523 				   SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
524 	return 0;
525 }
526 
527 static const struct snd_soc_ops acp_card_nau8825_ops = {
528 	.startup =  acp_nau8825_startup,
529 	.hw_params = acp_nau8825_hw_params,
530 };
531 
532 /* Declare DMIC codec components */
533 SND_SOC_DAILINK_DEF(dmic_codec,
534 		DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
535 
536 /* Declare ACP CPU components */
537 static struct snd_soc_dai_link_component dummy_codec[] = {
538 	{
539 		.name = "snd-soc-dummy",
540 		.dai_name = "snd-soc-dummy-dai",
541 	}
542 };
543 
544 static struct snd_soc_dai_link_component platform_component[] = {
545 	{
546 		 .name = "acp_asoc_renoir.0",
547 	}
548 };
549 
550 static struct snd_soc_dai_link_component platform_rmb_component[] = {
551 	{
552 		.name = "acp_asoc_rembrandt.0",
553 	}
554 };
555 
556 static struct snd_soc_dai_link_component sof_component[] = {
557 	{
558 		 .name = "0000:04:00.5",
559 	}
560 };
561 
562 SND_SOC_DAILINK_DEF(i2s_sp,
563 	DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-sp")));
564 SND_SOC_DAILINK_DEF(i2s_hs,
565 		    DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-hs")));
566 SND_SOC_DAILINK_DEF(sof_sp,
567 	DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp")));
568 SND_SOC_DAILINK_DEF(sof_hs,
569 		    DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs")));
570 SND_SOC_DAILINK_DEF(sof_dmic,
571 	DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-dmic")));
572 SND_SOC_DAILINK_DEF(pdm_dmic,
573 	DAILINK_COMP_ARRAY(COMP_CPU("acp-pdm-dmic")));
574 
575 static int acp_rtk_set_bias_level(struct snd_soc_card *card,
576 				  struct snd_soc_dapm_context *dapm,
577 				  enum snd_soc_bias_level level)
578 {
579 	struct snd_soc_component *component = dapm->component;
580 	struct acp_card_drvdata *drvdata = card->drvdata;
581 	int ret = 0;
582 
583 	if (!component)
584 		return 0;
585 
586 	if (strncmp(component->name, "i2c-RTL5682", 11) &&
587 	    strncmp(component->name, "i2c-10EC1019", 12))
588 		return 0;
589 
590 	/*
591 	 * For Realtek's codec and amplifier components,
592 	 * the lrck and bclk must be enabled brfore their all dapms be powered on,
593 	 * and must be disabled after their all dapms be powered down
594 	 * to avoid any pop.
595 	 */
596 	switch (level) {
597 	case SND_SOC_BIAS_STANDBY:
598 		if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) {
599 			clk_set_rate(drvdata->wclk, 48000);
600 			clk_set_rate(drvdata->bclk, 48000 * 64);
601 
602 			/* Increase bclk's enable_count */
603 			ret = clk_prepare_enable(drvdata->bclk);
604 			if (ret < 0)
605 				dev_err(component->dev, "Failed to enable bclk %d\n", ret);
606 		} else {
607 			/*
608 			 * Decrease bclk's enable_count.
609 			 * While the enable_count is 0, the bclk would be closed.
610 			 */
611 			clk_disable_unprepare(drvdata->bclk);
612 		}
613 		break;
614 	default:
615 		break;
616 	}
617 
618 	return ret;
619 }
620 
621 int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
622 {
623 	struct snd_soc_dai_link *links;
624 	struct device *dev = card->dev;
625 	struct acp_card_drvdata *drv_data = card->drvdata;
626 	int i = 0, num_links = 0;
627 
628 	if (drv_data->hs_cpu_id)
629 		num_links++;
630 	if (drv_data->amp_cpu_id)
631 		num_links++;
632 	if (drv_data->dmic_cpu_id)
633 		num_links++;
634 
635 	links = devm_kcalloc(dev, num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL);
636 	if (!links)
637 		return -ENOMEM;
638 
639 	if (drv_data->hs_cpu_id == I2S_SP) {
640 		links[i].name = "acp-headset-codec";
641 		links[i].id = HEADSET_BE_ID;
642 		links[i].cpus = sof_sp;
643 		links[i].num_cpus = ARRAY_SIZE(sof_sp);
644 		links[i].platforms = sof_component;
645 		links[i].num_platforms = ARRAY_SIZE(sof_component);
646 		links[i].dpcm_playback = 1;
647 		links[i].dpcm_capture = 1;
648 		links[i].nonatomic = true;
649 		links[i].no_pcm = 1;
650 		if (!drv_data->hs_codec_id) {
651 			/* Use dummy codec if codec id not specified */
652 			links[i].codecs = dummy_codec;
653 			links[i].num_codecs = ARRAY_SIZE(dummy_codec);
654 		}
655 		if (drv_data->hs_codec_id == RT5682) {
656 			links[i].codecs = rt5682;
657 			links[i].num_codecs = ARRAY_SIZE(rt5682);
658 			links[i].init = acp_card_rt5682_init;
659 			links[i].ops = &acp_card_rt5682_ops;
660 		}
661 		if (drv_data->hs_codec_id == RT5682S) {
662 			links[i].codecs = rt5682s;
663 			links[i].num_codecs = ARRAY_SIZE(rt5682s);
664 			links[i].init = acp_card_rt5682s_init;
665 			links[i].ops = &acp_card_rt5682s_ops;
666 		}
667 		i++;
668 	}
669 
670 	if (drv_data->hs_cpu_id == I2S_HS) {
671 		links[i].name = "acp-headset-codec";
672 		links[i].id = HEADSET_BE_ID;
673 		links[i].cpus = sof_hs;
674 		links[i].num_cpus = ARRAY_SIZE(sof_hs);
675 		links[i].platforms = sof_component;
676 		links[i].num_platforms = ARRAY_SIZE(sof_component);
677 		links[i].dpcm_playback = 1;
678 		links[i].dpcm_capture = 1;
679 		links[i].nonatomic = true;
680 		links[i].no_pcm = 1;
681 		if (!drv_data->hs_codec_id) {
682 			/* Use dummy codec if codec id not specified */
683 			links[i].codecs = dummy_codec;
684 			links[i].num_codecs = ARRAY_SIZE(dummy_codec);
685 		}
686 		if (drv_data->hs_codec_id == NAU8825) {
687 			links[i].codecs = nau8825;
688 			links[i].num_codecs = ARRAY_SIZE(nau8825);
689 			links[i].init = acp_card_nau8825_init;
690 			links[i].ops = &acp_card_nau8825_ops;
691 		}
692 		if (drv_data->hs_codec_id == RT5682S) {
693 			links[i].codecs = rt5682s;
694 			links[i].num_codecs = ARRAY_SIZE(rt5682s);
695 			links[i].init = acp_card_rt5682s_init;
696 			links[i].ops = &acp_card_rt5682s_ops;
697 		}
698 		i++;
699 	}
700 
701 	if (drv_data->amp_cpu_id == I2S_SP) {
702 		links[i].name = "acp-amp-codec";
703 		links[i].id = AMP_BE_ID;
704 		links[i].cpus = sof_sp;
705 		links[i].num_cpus = ARRAY_SIZE(sof_sp);
706 		links[i].platforms = sof_component;
707 		links[i].num_platforms = ARRAY_SIZE(sof_component);
708 		links[i].dpcm_playback = 1;
709 		links[i].nonatomic = true;
710 		links[i].no_pcm = 1;
711 		if (!drv_data->amp_codec_id) {
712 			/* Use dummy codec if codec id not specified */
713 			links[i].codecs = dummy_codec;
714 			links[i].num_codecs = ARRAY_SIZE(dummy_codec);
715 		}
716 		if (drv_data->amp_codec_id == RT1019) {
717 			links[i].codecs = rt1019;
718 			links[i].num_codecs = ARRAY_SIZE(rt1019);
719 			links[i].ops = &acp_card_rt1019_ops;
720 			links[i].init = acp_card_rt1019_init;
721 			card->codec_conf = rt1019_conf;
722 			card->num_configs = ARRAY_SIZE(rt1019_conf);
723 		}
724 		if (drv_data->amp_codec_id == MAX98360A) {
725 			links[i].codecs = max98360a;
726 			links[i].num_codecs = ARRAY_SIZE(max98360a);
727 			links[i].ops = &acp_card_maxim_ops;
728 			links[i].init = acp_card_maxim_init;
729 		}
730 		i++;
731 	}
732 
733 	if (drv_data->amp_cpu_id == I2S_HS) {
734 		links[i].name = "acp-amp-codec";
735 		links[i].id = AMP_BE_ID;
736 		links[i].cpus = sof_hs;
737 		links[i].num_cpus = ARRAY_SIZE(sof_hs);
738 		links[i].platforms = sof_component;
739 		links[i].num_platforms = ARRAY_SIZE(sof_component);
740 		links[i].dpcm_playback = 1;
741 		links[i].nonatomic = true;
742 		links[i].no_pcm = 1;
743 		if (!drv_data->amp_codec_id) {
744 			/* Use dummy codec if codec id not specified */
745 			links[i].codecs = dummy_codec;
746 			links[i].num_codecs = ARRAY_SIZE(dummy_codec);
747 		}
748 		if (drv_data->amp_codec_id == MAX98360A) {
749 			links[i].codecs = max98360a;
750 			links[i].num_codecs = ARRAY_SIZE(max98360a);
751 			links[i].ops = &acp_card_maxim_ops;
752 			links[i].init = acp_card_maxim_init;
753 		}
754 		if (drv_data->amp_codec_id == RT1019) {
755 			links[i].codecs = rt1019;
756 			links[i].num_codecs = ARRAY_SIZE(rt1019);
757 			links[i].ops = &acp_card_rt1019_ops;
758 			links[i].init = acp_card_rt1019_init;
759 			card->codec_conf = rt1019_conf;
760 			card->num_configs = ARRAY_SIZE(rt1019_conf);
761 		}
762 		i++;
763 	}
764 
765 	if (drv_data->dmic_cpu_id == DMIC) {
766 		links[i].name = "acp-dmic-codec";
767 		links[i].id = DMIC_BE_ID;
768 		links[i].codecs = dmic_codec;
769 		links[i].num_codecs = ARRAY_SIZE(dmic_codec);
770 		links[i].cpus = sof_dmic;
771 		links[i].num_cpus = ARRAY_SIZE(sof_dmic);
772 		links[i].platforms = sof_component;
773 		links[i].num_platforms = ARRAY_SIZE(sof_component);
774 		links[i].dpcm_capture = 1;
775 		links[i].nonatomic = true;
776 		links[i].no_pcm = 1;
777 	}
778 
779 	card->dai_link = links;
780 	card->num_links = num_links;
781 	card->set_bias_level = acp_rtk_set_bias_level;
782 
783 	return 0;
784 }
785 EXPORT_SYMBOL_NS_GPL(acp_sofdsp_dai_links_create, SND_SOC_AMD_MACH);
786 
787 int acp_legacy_dai_links_create(struct snd_soc_card *card)
788 {
789 	struct snd_soc_dai_link *links;
790 	struct device *dev = card->dev;
791 	struct acp_card_drvdata *drv_data = card->drvdata;
792 	int i = 0, num_links = 0;
793 
794 	if (drv_data->hs_cpu_id)
795 		num_links++;
796 	if (drv_data->amp_cpu_id)
797 		num_links++;
798 	if (drv_data->dmic_cpu_id)
799 		num_links++;
800 
801 	links = devm_kcalloc(dev, num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL);
802 	if (!links)
803 		return -ENOMEM;
804 
805 	if (drv_data->hs_cpu_id == I2S_SP) {
806 		links[i].name = "acp-headset-codec";
807 		links[i].id = HEADSET_BE_ID;
808 		links[i].cpus = i2s_sp;
809 		links[i].num_cpus = ARRAY_SIZE(i2s_sp);
810 		links[i].platforms = platform_component;
811 		links[i].num_platforms = ARRAY_SIZE(platform_component);
812 		links[i].dpcm_playback = 1;
813 		links[i].dpcm_capture = 1;
814 		if (!drv_data->hs_codec_id) {
815 			/* Use dummy codec if codec id not specified */
816 			links[i].codecs = dummy_codec;
817 			links[i].num_codecs = ARRAY_SIZE(dummy_codec);
818 		}
819 		if (drv_data->hs_codec_id == RT5682) {
820 			links[i].codecs = rt5682;
821 			links[i].num_codecs = ARRAY_SIZE(rt5682);
822 			links[i].init = acp_card_rt5682_init;
823 			links[i].ops = &acp_card_rt5682_ops;
824 		}
825 		if (drv_data->hs_codec_id == RT5682S) {
826 			links[i].codecs = rt5682s;
827 			links[i].num_codecs = ARRAY_SIZE(rt5682s);
828 			links[i].init = acp_card_rt5682s_init;
829 			links[i].ops = &acp_card_rt5682s_ops;
830 		}
831 		i++;
832 	}
833 
834 	if (drv_data->hs_cpu_id == I2S_HS) {
835 		links[i].name = "acp-headset-codec";
836 		links[i].id = HEADSET_BE_ID;
837 		links[i].cpus = i2s_hs;
838 		links[i].num_cpus = ARRAY_SIZE(i2s_hs);
839 		if (drv_data->platform == REMBRANDT) {
840 			links[i].platforms = platform_rmb_component;
841 			links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
842 		} else {
843 			links[i].platforms = platform_component;
844 			links[i].num_platforms = ARRAY_SIZE(platform_component);
845 		}
846 		links[i].dpcm_playback = 1;
847 		links[i].dpcm_capture = 1;
848 		if (!drv_data->hs_codec_id) {
849 			/* Use dummy codec if codec id not specified */
850 			links[i].codecs = dummy_codec;
851 			links[i].num_codecs = ARRAY_SIZE(dummy_codec);
852 		}
853 		if (drv_data->hs_codec_id == NAU8825) {
854 			links[i].codecs = nau8825;
855 			links[i].num_codecs = ARRAY_SIZE(nau8825);
856 			links[i].init = acp_card_nau8825_init;
857 			links[i].ops = &acp_card_nau8825_ops;
858 		}
859 		if (drv_data->hs_codec_id == RT5682S) {
860 			links[i].codecs = rt5682s;
861 			links[i].num_codecs = ARRAY_SIZE(rt5682s);
862 			links[i].init = acp_card_rt5682s_init;
863 			links[i].ops = &acp_card_rt5682s_ops;
864 		}
865 		i++;
866 	}
867 
868 	if (drv_data->amp_cpu_id == I2S_SP) {
869 		links[i].name = "acp-amp-codec";
870 		links[i].id = AMP_BE_ID;
871 		links[i].cpus = i2s_sp;
872 		links[i].num_cpus = ARRAY_SIZE(i2s_sp);
873 		links[i].platforms = platform_component;
874 		links[i].num_platforms = ARRAY_SIZE(platform_component);
875 		links[i].dpcm_playback = 1;
876 		if (!drv_data->amp_codec_id) {
877 			/* Use dummy codec if codec id not specified */
878 			links[i].codecs = dummy_codec;
879 			links[i].num_codecs = ARRAY_SIZE(dummy_codec);
880 		}
881 		if (drv_data->amp_codec_id == RT1019) {
882 			links[i].codecs = rt1019;
883 			links[i].num_codecs = ARRAY_SIZE(rt1019);
884 			links[i].ops = &acp_card_rt1019_ops;
885 			links[i].init = acp_card_rt1019_init;
886 			card->codec_conf = rt1019_conf;
887 			card->num_configs = ARRAY_SIZE(rt1019_conf);
888 		}
889 		if (drv_data->amp_codec_id == MAX98360A) {
890 			links[i].codecs = max98360a;
891 			links[i].num_codecs = ARRAY_SIZE(max98360a);
892 			links[i].ops = &acp_card_maxim_ops;
893 			links[i].init = acp_card_maxim_init;
894 		}
895 		i++;
896 	}
897 
898 	if (drv_data->amp_cpu_id == I2S_HS) {
899 		links[i].name = "acp-amp-codec";
900 		links[i].id = AMP_BE_ID;
901 		links[i].cpus = i2s_hs;
902 		links[i].num_cpus = ARRAY_SIZE(i2s_hs);
903 		if (drv_data->platform == REMBRANDT) {
904 			links[i].platforms = platform_rmb_component;
905 			links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
906 		} else {
907 			links[i].platforms = platform_component;
908 			links[i].num_platforms = ARRAY_SIZE(platform_component);
909 		}
910 		links[i].dpcm_playback = 1;
911 		if (!drv_data->amp_codec_id) {
912 			/* Use dummy codec if codec id not specified */
913 			links[i].codecs = dummy_codec;
914 			links[i].num_codecs = ARRAY_SIZE(dummy_codec);
915 		}
916 		if (drv_data->amp_codec_id == MAX98360A) {
917 			links[i].codecs = max98360a;
918 			links[i].num_codecs = ARRAY_SIZE(max98360a);
919 			links[i].ops = &acp_card_maxim_ops;
920 			links[i].init = acp_card_maxim_init;
921 		}
922 		if (drv_data->amp_codec_id == RT1019) {
923 			links[i].codecs = rt1019;
924 			links[i].num_codecs = ARRAY_SIZE(rt1019);
925 			links[i].ops = &acp_card_rt1019_ops;
926 			links[i].init = acp_card_rt1019_init;
927 			card->codec_conf = rt1019_conf;
928 			card->num_configs = ARRAY_SIZE(rt1019_conf);
929 		}
930 		i++;
931 	}
932 
933 	if (drv_data->dmic_cpu_id == DMIC) {
934 		links[i].name = "acp-dmic-codec";
935 		links[i].id = DMIC_BE_ID;
936 		if (drv_data->dmic_codec_id == DMIC) {
937 			links[i].codecs = dmic_codec;
938 			links[i].num_codecs = ARRAY_SIZE(dmic_codec);
939 		} else {
940 			/* Use dummy codec if codec id not specified */
941 			links[i].codecs = dummy_codec;
942 			links[i].num_codecs = ARRAY_SIZE(dummy_codec);
943 		}
944 		links[i].cpus = pdm_dmic;
945 		links[i].num_cpus = ARRAY_SIZE(pdm_dmic);
946 		if (drv_data->platform == REMBRANDT) {
947 			links[i].platforms = platform_rmb_component;
948 			links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
949 		} else {
950 			links[i].platforms = platform_component;
951 			links[i].num_platforms = ARRAY_SIZE(platform_component);
952 		}
953 		links[i].ops = &acp_card_dmic_ops;
954 		links[i].dpcm_capture = 1;
955 	}
956 
957 	card->dai_link = links;
958 	card->num_links = num_links;
959 	card->set_bias_level = acp_rtk_set_bias_level;
960 
961 	return 0;
962 }
963 EXPORT_SYMBOL_NS_GPL(acp_legacy_dai_links_create, SND_SOC_AMD_MACH);
964 
965 MODULE_LICENSE("GPL v2");
966