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