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 "../../codecs/nau8821.h" 29 #include "acp-mach.h" 30 31 static struct snd_soc_jack vg_headset; 32 #define PCO_PLAT_CLK 48000000 33 #define RT5682_PLL_FREQ (48000 * 512) 34 #define DUAL_CHANNEL 2 35 #define FOUR_CHANNEL 4 36 #define NAU8821_CODEC_DAI "nau8821-hifi" 37 #define NAU8821_BCLK 1536000 38 #define NAU8821_FREQ_OUT 12288000 39 #define MAX98388_CODEC_DAI "max98388-aif1" 40 41 #define TDM_MODE_ENABLE 1 42 43 const struct dmi_system_id acp_quirk_table[] = { 44 { 45 /* Google skyrim proto-0 */ 46 .matches = { 47 DMI_EXACT_MATCH(DMI_PRODUCT_FAMILY, "Google_Skyrim"), 48 }, 49 .driver_data = (void *)TDM_MODE_ENABLE, 50 }, 51 {} 52 }; 53 EXPORT_SYMBOL_GPL(acp_quirk_table); 54 55 static struct snd_soc_jack pco_jack; 56 57 static const unsigned int channels[] = { 58 DUAL_CHANNEL, 59 }; 60 61 static const unsigned int rates[] = { 62 48000, 63 }; 64 65 static const struct snd_pcm_hw_constraint_list constraints_rates = { 66 .count = ARRAY_SIZE(rates), 67 .list = rates, 68 .mask = 0, 69 }; 70 71 static const struct snd_pcm_hw_constraint_list constraints_channels = { 72 .count = ARRAY_SIZE(channels), 73 .list = channels, 74 .mask = 0, 75 }; 76 77 static int acp_clk_enable(struct acp_card_drvdata *drvdata, 78 unsigned int srate, unsigned int bclk_ratio) 79 { 80 clk_set_rate(drvdata->wclk, srate); 81 clk_set_rate(drvdata->bclk, srate * bclk_ratio); 82 83 return clk_prepare_enable(drvdata->wclk); 84 } 85 86 /* Declare RT5682 codec components */ 87 SND_SOC_DAILINK_DEF(rt5682, 88 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1"))); 89 90 static const struct snd_soc_dapm_route rt5682_map[] = { 91 { "Headphone Jack", NULL, "HPOL" }, 92 { "Headphone Jack", NULL, "HPOR" }, 93 { "IN1P", NULL, "Headset Mic" }, 94 }; 95 96 /* Define card ops for RT5682 CODEC */ 97 static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd) 98 { 99 struct snd_soc_card *card = rtd->card; 100 struct acp_card_drvdata *drvdata = card->drvdata; 101 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 102 struct snd_soc_component *component = codec_dai->component; 103 int ret; 104 105 dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name); 106 107 if (drvdata->hs_codec_id != RT5682) 108 return -EINVAL; 109 110 drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk"); 111 drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk"); 112 113 ret = snd_soc_card_jack_new(card, "Headset Jack", 114 SND_JACK_HEADSET | SND_JACK_LINEOUT | 115 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 116 SND_JACK_BTN_2 | SND_JACK_BTN_3, 117 &pco_jack); 118 if (ret) { 119 dev_err(card->dev, "HP jack creation failed %d\n", ret); 120 return ret; 121 } 122 123 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 124 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); 125 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP); 126 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); 127 128 ret = snd_soc_component_set_jack(component, &pco_jack, NULL); 129 if (ret) { 130 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); 131 return ret; 132 } 133 134 return snd_soc_dapm_add_routes(&rtd->card->dapm, rt5682_map, ARRAY_SIZE(rt5682_map)); 135 } 136 137 static int acp_card_hs_startup(struct snd_pcm_substream *substream) 138 { 139 struct snd_pcm_runtime *runtime = substream->runtime; 140 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 141 struct snd_soc_card *card = rtd->card; 142 struct acp_card_drvdata *drvdata = card->drvdata; 143 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 144 int ret; 145 unsigned int fmt; 146 147 if (drvdata->tdm_mode) 148 fmt = SND_SOC_DAIFMT_DSP_A; 149 else 150 fmt = SND_SOC_DAIFMT_I2S; 151 152 if (drvdata->soc_mclk) 153 fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; 154 else 155 fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP; 156 157 ret = snd_soc_dai_set_fmt(codec_dai, fmt); 158 if (ret < 0) { 159 dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret); 160 return ret; 161 } 162 163 runtime->hw.channels_max = DUAL_CHANNEL; 164 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 165 &constraints_channels); 166 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 167 &constraints_rates); 168 169 return ret; 170 } 171 172 static void acp_card_shutdown(struct snd_pcm_substream *substream) 173 { 174 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 175 struct snd_soc_card *card = rtd->card; 176 struct acp_card_drvdata *drvdata = card->drvdata; 177 178 if (!drvdata->soc_mclk) 179 clk_disable_unprepare(drvdata->wclk); 180 } 181 182 static int acp_card_rt5682_hw_params(struct snd_pcm_substream *substream, 183 struct snd_pcm_hw_params *params) 184 { 185 struct snd_soc_pcm_runtime *rtd = substream->private_data; 186 struct snd_soc_card *card = rtd->card; 187 struct acp_card_drvdata *drvdata = card->drvdata; 188 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 189 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 190 int ret; 191 unsigned int fmt, srate, ch, format; 192 193 srate = params_rate(params); 194 ch = params_channels(params); 195 format = params_physical_width(params); 196 197 if (drvdata->tdm_mode) 198 fmt = SND_SOC_DAIFMT_DSP_A; 199 else 200 fmt = SND_SOC_DAIFMT_I2S; 201 202 if (drvdata->soc_mclk) 203 fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; 204 else 205 fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP; 206 207 ret = snd_soc_dai_set_fmt(cpu_dai, fmt); 208 if (ret && ret != -ENOTSUPP) { 209 dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret); 210 return ret; 211 } 212 213 ret = snd_soc_dai_set_fmt(codec_dai, fmt); 214 if (ret < 0) { 215 dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret); 216 return ret; 217 } 218 219 if (drvdata->tdm_mode) { 220 /** 221 * As codec supports slot 0 and slot 1 for playback and capture. 222 */ 223 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 8, 16); 224 if (ret && ret != -ENOTSUPP) { 225 dev_err(rtd->dev, "set TDM slot err: %d\n", ret); 226 return ret; 227 } 228 229 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 8, 16); 230 if (ret < 0) { 231 dev_warn(rtd->dev, "set TDM slot err:%d\n", ret); 232 return ret; 233 } 234 } 235 236 ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL2, RT5682_PLL2_S_MCLK, 237 PCO_PLAT_CLK, RT5682_PLL_FREQ); 238 if (ret < 0) { 239 dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret); 240 return ret; 241 } 242 243 ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL2, 244 RT5682_PLL_FREQ, SND_SOC_CLOCK_IN); 245 if (ret < 0) { 246 dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret); 247 return ret; 248 } 249 250 /* Set tdm/i2s1 master bclk ratio */ 251 ret = snd_soc_dai_set_bclk_ratio(codec_dai, ch * format); 252 if (ret < 0) { 253 dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret); 254 return ret; 255 } 256 257 if (!drvdata->soc_mclk) { 258 ret = acp_clk_enable(drvdata, srate, ch * format); 259 if (ret < 0) { 260 dev_err(rtd->card->dev, "Failed to enable HS clk: %d\n", ret); 261 return ret; 262 } 263 } 264 265 return 0; 266 } 267 268 static const struct snd_soc_ops acp_card_rt5682_ops = { 269 .startup = acp_card_hs_startup, 270 .shutdown = acp_card_shutdown, 271 .hw_params = acp_card_rt5682_hw_params, 272 }; 273 274 /* Define RT5682S CODEC component*/ 275 SND_SOC_DAILINK_DEF(rt5682s, 276 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RTL5682:00", "rt5682s-aif1"))); 277 278 static const struct snd_soc_dapm_route rt5682s_map[] = { 279 { "Headphone Jack", NULL, "HPOL" }, 280 { "Headphone Jack", NULL, "HPOR" }, 281 { "IN1P", NULL, "Headset Mic" }, 282 }; 283 284 static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd) 285 { 286 struct snd_soc_card *card = rtd->card; 287 struct acp_card_drvdata *drvdata = card->drvdata; 288 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 289 struct snd_soc_component *component = codec_dai->component; 290 int ret; 291 292 dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name); 293 294 if (drvdata->hs_codec_id != RT5682S) 295 return -EINVAL; 296 297 if (!drvdata->soc_mclk) { 298 drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk"); 299 drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk"); 300 } 301 302 ret = snd_soc_card_jack_new(card, "Headset Jack", 303 SND_JACK_HEADSET | SND_JACK_LINEOUT | 304 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 305 SND_JACK_BTN_2 | SND_JACK_BTN_3, 306 &pco_jack); 307 if (ret) { 308 dev_err(card->dev, "HP jack creation failed %d\n", ret); 309 return ret; 310 } 311 312 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 313 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); 314 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP); 315 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); 316 317 ret = snd_soc_component_set_jack(component, &pco_jack, NULL); 318 if (ret) { 319 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); 320 return ret; 321 } 322 323 return snd_soc_dapm_add_routes(&rtd->card->dapm, rt5682s_map, ARRAY_SIZE(rt5682s_map)); 324 } 325 326 static int acp_card_rt5682s_hw_params(struct snd_pcm_substream *substream, 327 struct snd_pcm_hw_params *params) 328 { 329 struct snd_soc_pcm_runtime *rtd = substream->private_data; 330 struct snd_soc_card *card = rtd->card; 331 struct acp_card_drvdata *drvdata = card->drvdata; 332 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 333 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 334 int ret; 335 unsigned int fmt, srate, ch, format; 336 337 srate = params_rate(params); 338 ch = params_channels(params); 339 format = params_physical_width(params); 340 341 if (drvdata->tdm_mode) 342 fmt = SND_SOC_DAIFMT_DSP_A; 343 else 344 fmt = SND_SOC_DAIFMT_I2S; 345 346 if (drvdata->soc_mclk) 347 fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; 348 else 349 fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP; 350 351 ret = snd_soc_dai_set_fmt(cpu_dai, fmt); 352 if (ret && ret != -ENOTSUPP) { 353 dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret); 354 return ret; 355 } 356 357 ret = snd_soc_dai_set_fmt(codec_dai, fmt); 358 if (ret < 0) { 359 dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret); 360 return ret; 361 } 362 363 if (drvdata->tdm_mode) { 364 /** 365 * As codec supports slot 0 and slot 1 for playback and capture. 366 */ 367 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 8, 16); 368 if (ret && ret != -ENOTSUPP) { 369 dev_err(rtd->dev, "set TDM slot err: %d\n", ret); 370 return ret; 371 } 372 373 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 8, 16); 374 if (ret < 0) { 375 dev_warn(rtd->dev, "set TDM slot err:%d\n", ret); 376 return ret; 377 } 378 } 379 380 ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL2, RT5682S_PLL_S_MCLK, 381 PCO_PLAT_CLK, RT5682_PLL_FREQ); 382 if (ret < 0) { 383 dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret); 384 return ret; 385 } 386 387 ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL2, 388 RT5682_PLL_FREQ, SND_SOC_CLOCK_IN); 389 if (ret < 0) { 390 dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret); 391 return ret; 392 } 393 394 /* Set tdm/i2s1 master bclk ratio */ 395 ret = snd_soc_dai_set_bclk_ratio(codec_dai, ch * format); 396 if (ret < 0) { 397 dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret); 398 return ret; 399 } 400 401 clk_set_rate(drvdata->wclk, srate); 402 clk_set_rate(drvdata->bclk, srate * ch * format); 403 404 return 0; 405 } 406 407 static const struct snd_soc_ops acp_card_rt5682s_ops = { 408 .startup = acp_card_hs_startup, 409 .hw_params = acp_card_rt5682s_hw_params, 410 }; 411 412 static const unsigned int dmic_channels[] = { 413 DUAL_CHANNEL, FOUR_CHANNEL, 414 }; 415 416 static const struct snd_pcm_hw_constraint_list dmic_constraints_channels = { 417 .count = ARRAY_SIZE(dmic_channels), 418 .list = dmic_channels, 419 .mask = 0, 420 }; 421 422 static int acp_card_dmic_startup(struct snd_pcm_substream *substream) 423 { 424 struct snd_pcm_runtime *runtime = substream->runtime; 425 426 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 427 &dmic_constraints_channels); 428 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 429 &constraints_rates); 430 431 return 0; 432 } 433 434 static const struct snd_soc_ops acp_card_dmic_ops = { 435 .startup = acp_card_dmic_startup, 436 }; 437 438 /* Declare RT1019 codec components */ 439 SND_SOC_DAILINK_DEF(rt1019, 440 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"), 441 COMP_CODEC("i2c-10EC1019:01", "rt1019-aif"))); 442 443 static const struct snd_soc_dapm_route rt1019_map_lr[] = { 444 { "Left Spk", NULL, "Left SPO" }, 445 { "Right Spk", NULL, "Right SPO" }, 446 }; 447 448 static struct snd_soc_codec_conf rt1019_conf[] = { 449 { 450 .dlc = COMP_CODEC_CONF("i2c-10EC1019:01"), 451 .name_prefix = "Left", 452 }, 453 { 454 .dlc = COMP_CODEC_CONF("i2c-10EC1019:00"), 455 .name_prefix = "Right", 456 }, 457 }; 458 459 static int acp_card_rt1019_init(struct snd_soc_pcm_runtime *rtd) 460 { 461 struct snd_soc_card *card = rtd->card; 462 struct acp_card_drvdata *drvdata = card->drvdata; 463 464 if (drvdata->amp_codec_id != RT1019) 465 return -EINVAL; 466 467 return snd_soc_dapm_add_routes(&rtd->card->dapm, rt1019_map_lr, 468 ARRAY_SIZE(rt1019_map_lr)); 469 } 470 471 static int acp_card_rt1019_hw_params(struct snd_pcm_substream *substream, 472 struct snd_pcm_hw_params *params) 473 { 474 struct snd_soc_pcm_runtime *rtd = substream->private_data; 475 struct snd_soc_card *card = rtd->card; 476 struct acp_card_drvdata *drvdata = card->drvdata; 477 struct snd_soc_dai *codec_dai; 478 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 479 int i, ret = 0; 480 unsigned int fmt, srate, ch, format; 481 482 srate = params_rate(params); 483 ch = params_channels(params); 484 format = params_physical_width(params); 485 486 if (drvdata->amp_codec_id != RT1019) 487 return -EINVAL; 488 489 if (drvdata->tdm_mode) 490 fmt = SND_SOC_DAIFMT_DSP_A; 491 else 492 fmt = SND_SOC_DAIFMT_I2S; 493 494 if (drvdata->soc_mclk) 495 fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; 496 else 497 fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP; 498 499 ret = snd_soc_dai_set_fmt(cpu_dai, fmt); 500 if (ret && ret != -ENOTSUPP) { 501 dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret); 502 return ret; 503 } 504 505 if (drvdata->tdm_mode) { 506 /** 507 * As codec supports slot 2 and slot 3 for playback. 508 */ 509 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xC, 0, 8, 16); 510 if (ret && ret != -ENOTSUPP) { 511 dev_err(rtd->dev, "set TDM slot err: %d\n", ret); 512 return ret; 513 } 514 } 515 516 for_each_rtd_codec_dais(rtd, i, codec_dai) { 517 if (strcmp(codec_dai->name, "rt1019-aif")) 518 continue; 519 520 if (drvdata->tdm_mode) 521 ret = snd_soc_dai_set_pll(codec_dai, 0, RT1019_PLL_S_BCLK, 522 TDM_CHANNELS * format * srate, 256 * srate); 523 else 524 ret = snd_soc_dai_set_pll(codec_dai, 0, RT1019_PLL_S_BCLK, 525 ch * format * srate, 256 * srate); 526 527 if (ret < 0) 528 return ret; 529 530 ret = snd_soc_dai_set_sysclk(codec_dai, RT1019_SCLK_S_PLL, 531 256 * srate, SND_SOC_CLOCK_IN); 532 if (ret < 0) 533 return ret; 534 535 if (drvdata->tdm_mode) { 536 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A 537 | SND_SOC_DAIFMT_NB_NF); 538 if (ret < 0) { 539 dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret); 540 return ret; 541 } 542 543 /** 544 * As codec supports slot 2 for left channel playback. 545 */ 546 if (!strcmp(codec_dai->component->name, "i2c-10EC1019:00")) { 547 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x4, 0x4, 8, 16); 548 if (ret < 0) 549 break; 550 } 551 552 /** 553 * As codec supports slot 3 for right channel playback. 554 */ 555 if (!strcmp(codec_dai->component->name, "i2c-10EC1019:01")) { 556 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x8, 0x8, 8, 16); 557 if (ret < 0) 558 break; 559 } 560 } 561 } 562 563 if (!drvdata->soc_mclk) { 564 ret = acp_clk_enable(drvdata, srate, ch * format); 565 if (ret < 0) { 566 dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret); 567 return ret; 568 } 569 } 570 571 return 0; 572 } 573 574 static int acp_card_amp_startup(struct snd_pcm_substream *substream) 575 { 576 struct snd_pcm_runtime *runtime = substream->runtime; 577 578 runtime->hw.channels_max = DUAL_CHANNEL; 579 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 580 &constraints_channels); 581 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 582 &constraints_rates); 583 584 return 0; 585 } 586 587 static const struct snd_soc_ops acp_card_rt1019_ops = { 588 .startup = acp_card_amp_startup, 589 .shutdown = acp_card_shutdown, 590 .hw_params = acp_card_rt1019_hw_params, 591 }; 592 593 /* Declare Maxim codec components */ 594 SND_SOC_DAILINK_DEF(max98360a, 595 DAILINK_COMP_ARRAY(COMP_CODEC("MX98360A:00", "HiFi"))); 596 597 static const struct snd_soc_dapm_route max98360a_map[] = { 598 {"Spk", NULL, "Speaker"}, 599 }; 600 601 static int acp_card_maxim_init(struct snd_soc_pcm_runtime *rtd) 602 { 603 struct snd_soc_card *card = rtd->card; 604 struct acp_card_drvdata *drvdata = card->drvdata; 605 606 if (drvdata->amp_codec_id != MAX98360A) 607 return -EINVAL; 608 609 return snd_soc_dapm_add_routes(&rtd->card->dapm, max98360a_map, 610 ARRAY_SIZE(max98360a_map)); 611 } 612 613 static int acp_card_maxim_hw_params(struct snd_pcm_substream *substream, 614 struct snd_pcm_hw_params *params) 615 { 616 struct snd_soc_pcm_runtime *rtd = substream->private_data; 617 struct snd_soc_card *card = rtd->card; 618 struct acp_card_drvdata *drvdata = card->drvdata; 619 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 620 unsigned int fmt, srate, ch, format; 621 int ret; 622 623 srate = params_rate(params); 624 ch = params_channels(params); 625 format = params_physical_width(params); 626 627 if (drvdata->tdm_mode) 628 fmt = SND_SOC_DAIFMT_DSP_A; 629 else 630 fmt = SND_SOC_DAIFMT_I2S; 631 632 if (drvdata->soc_mclk) 633 fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; 634 else 635 fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP; 636 637 ret = snd_soc_dai_set_fmt(cpu_dai, fmt); 638 if (ret && ret != -ENOTSUPP) { 639 dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret); 640 return ret; 641 } 642 643 if (drvdata->tdm_mode) { 644 /** 645 * As codec supports slot 2 and slot 3 for playback. 646 */ 647 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xC, 0, 8, 16); 648 if (ret && ret != -ENOTSUPP) { 649 dev_err(rtd->dev, "set TDM slot err: %d\n", ret); 650 return ret; 651 } 652 } 653 654 if (!drvdata->soc_mclk) { 655 ret = acp_clk_enable(drvdata, srate, ch * format); 656 if (ret < 0) { 657 dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret); 658 return ret; 659 } 660 } 661 return 0; 662 } 663 664 static const struct snd_soc_ops acp_card_maxim_ops = { 665 .startup = acp_card_amp_startup, 666 .shutdown = acp_card_shutdown, 667 .hw_params = acp_card_maxim_hw_params, 668 }; 669 670 SND_SOC_DAILINK_DEF(max98388, 671 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ADS8388:00", "max98388-aif1"), 672 COMP_CODEC("i2c-ADS8388:01", "max98388-aif1"))); 673 674 static const struct snd_soc_dapm_widget max98388_widgets[] = { 675 SND_SOC_DAPM_SPK("SPK", NULL), 676 }; 677 678 static const struct snd_soc_dapm_route max98388_map[] = { 679 { "SPK", NULL, "Left BE_OUT" }, 680 { "SPK", NULL, "Right BE_OUT" }, 681 }; 682 683 static struct snd_soc_codec_conf max98388_conf[] = { 684 { 685 .dlc = COMP_CODEC_CONF("i2c-ADS8388:00"), 686 .name_prefix = "Left", 687 }, 688 { 689 .dlc = COMP_CODEC_CONF("i2c-ADS8388:01"), 690 .name_prefix = "Right", 691 }, 692 }; 693 694 static const unsigned int max98388_format[] = {16}; 695 696 static struct snd_pcm_hw_constraint_list constraints_sample_bits_max = { 697 .list = max98388_format, 698 .count = ARRAY_SIZE(max98388_format), 699 }; 700 701 static int acp_card_max98388_startup(struct snd_pcm_substream *substream) 702 { 703 struct snd_pcm_runtime *runtime = substream->runtime; 704 705 runtime->hw.channels_max = DUAL_CHANNEL; 706 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 707 &constraints_channels); 708 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 709 &constraints_rates); 710 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 711 &constraints_sample_bits_max); 712 713 return 0; 714 } 715 716 static int acp_card_max98388_init(struct snd_soc_pcm_runtime *rtd) 717 { 718 struct snd_soc_card *card = rtd->card; 719 struct acp_card_drvdata *drvdata = card->drvdata; 720 int ret; 721 722 if (drvdata->amp_codec_id != MAX98388) 723 return -EINVAL; 724 725 ret = snd_soc_dapm_new_controls(&card->dapm, max98388_widgets, 726 ARRAY_SIZE(max98388_widgets)); 727 728 if (ret) { 729 dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret); 730 /* Don't need to add routes if widget addition failed */ 731 return ret; 732 } 733 return snd_soc_dapm_add_routes(&rtd->card->dapm, max98388_map, 734 ARRAY_SIZE(max98388_map)); 735 } 736 737 static int acp_max98388_hw_params(struct snd_pcm_substream *substream, 738 struct snd_pcm_hw_params *params) 739 { 740 struct snd_soc_pcm_runtime *rtd = substream->private_data; 741 struct snd_soc_card *card = rtd->card; 742 struct snd_soc_dai *codec_dai = 743 snd_soc_card_get_codec_dai(card, 744 MAX98388_CODEC_DAI); 745 int ret; 746 747 ret = snd_soc_dai_set_fmt(codec_dai, 748 SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_I2S | 749 SND_SOC_DAIFMT_NB_NF); 750 if (ret < 0) 751 return ret; 752 753 return ret; 754 } 755 756 static const struct snd_soc_ops acp_max98388_ops = { 757 .startup = acp_card_max98388_startup, 758 .hw_params = acp_max98388_hw_params, 759 }; 760 761 /* Declare nau8825 codec components */ 762 SND_SOC_DAILINK_DEF(nau8825, 763 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10508825:00", "nau8825-hifi"))); 764 765 static const struct snd_soc_dapm_route nau8825_map[] = { 766 { "Headphone Jack", NULL, "HPOL" }, 767 { "Headphone Jack", NULL, "HPOR" }, 768 }; 769 770 static int acp_card_nau8825_init(struct snd_soc_pcm_runtime *rtd) 771 { 772 struct snd_soc_card *card = rtd->card; 773 struct acp_card_drvdata *drvdata = card->drvdata; 774 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 775 struct snd_soc_component *component = codec_dai->component; 776 int ret; 777 778 dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name); 779 780 if (drvdata->hs_codec_id != NAU8825) 781 return -EINVAL; 782 783 ret = snd_soc_card_jack_new(card, "Headset Jack", 784 SND_JACK_HEADSET | SND_JACK_LINEOUT | 785 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 786 SND_JACK_BTN_2 | SND_JACK_BTN_3, 787 &pco_jack); 788 if (ret) { 789 dev_err(card->dev, "HP jack creation failed %d\n", ret); 790 return ret; 791 } 792 793 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 794 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); 795 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP); 796 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); 797 798 ret = snd_soc_component_set_jack(component, &pco_jack, NULL); 799 if (ret) { 800 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); 801 return ret; 802 } 803 804 return snd_soc_dapm_add_routes(&rtd->card->dapm, nau8825_map, ARRAY_SIZE(nau8825_map)); 805 } 806 807 static int acp_nau8825_hw_params(struct snd_pcm_substream *substream, 808 struct snd_pcm_hw_params *params) 809 { 810 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 811 struct snd_soc_card *card = rtd->card; 812 struct acp_card_drvdata *drvdata = card->drvdata; 813 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 814 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 815 int ret; 816 unsigned int fmt; 817 818 ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_FS, 819 (48000 * 256), SND_SOC_CLOCK_IN); 820 if (ret < 0) 821 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); 822 823 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, params_rate(params), 824 params_rate(params) * 256); 825 if (ret < 0) { 826 dev_err(rtd->dev, "can't set FLL: %d\n", ret); 827 return ret; 828 } 829 830 if (drvdata->tdm_mode) 831 fmt = SND_SOC_DAIFMT_DSP_A; 832 else 833 fmt = SND_SOC_DAIFMT_I2S; 834 835 if (drvdata->soc_mclk) 836 fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; 837 else 838 fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP; 839 840 ret = snd_soc_dai_set_fmt(cpu_dai, fmt); 841 if (ret && ret != -ENOTSUPP) { 842 dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret); 843 return ret; 844 } 845 846 ret = snd_soc_dai_set_fmt(codec_dai, fmt); 847 if (ret < 0) { 848 dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret); 849 return ret; 850 } 851 852 if (drvdata->tdm_mode) { 853 /** 854 * As codec supports slot 4 and slot 5 for playback and slot 6 for capture. 855 */ 856 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x30, 0xC0, 8, 16); 857 if (ret && ret != -ENOTSUPP) { 858 dev_err(rtd->dev, "set TDM slot err: %d\n", ret); 859 return ret; 860 } 861 862 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x40, 0x30, 8, 16); 863 if (ret < 0) { 864 dev_warn(rtd->dev, "set TDM slot err:%d\n", ret); 865 return ret; 866 } 867 } 868 return ret; 869 } 870 871 static int acp_nau8825_startup(struct snd_pcm_substream *substream) 872 { 873 struct snd_pcm_runtime *runtime = substream->runtime; 874 875 runtime->hw.channels_max = 2; 876 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 877 &constraints_channels); 878 879 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; 880 snd_pcm_hw_constraint_list(runtime, 0, 881 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 882 return 0; 883 } 884 885 static const struct snd_soc_ops acp_card_nau8825_ops = { 886 .startup = acp_nau8825_startup, 887 .hw_params = acp_nau8825_hw_params, 888 }; 889 890 static int platform_clock_control(struct snd_soc_dapm_widget *w, 891 struct snd_kcontrol *k, int event) 892 { 893 struct snd_soc_dapm_context *dapm = w->dapm; 894 struct snd_soc_card *card = dapm->card; 895 struct snd_soc_dai *codec_dai; 896 int ret = 0; 897 898 codec_dai = snd_soc_card_get_codec_dai(card, NAU8821_CODEC_DAI); 899 if (!codec_dai) { 900 dev_err(card->dev, "Codec dai not found\n"); 901 return -EIO; 902 } 903 904 if (SND_SOC_DAPM_EVENT_OFF(event)) { 905 ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_INTERNAL, 906 0, SND_SOC_CLOCK_IN); 907 if (ret < 0) { 908 dev_err(card->dev, "set sysclk err = %d\n", ret); 909 return -EIO; 910 } 911 } else { 912 ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0, 913 SND_SOC_CLOCK_IN); 914 if (ret < 0) 915 dev_err(codec_dai->dev, "can't set FS clock %d\n", ret); 916 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, NAU8821_BCLK, 917 NAU8821_FREQ_OUT); 918 if (ret < 0) 919 dev_err(codec_dai->dev, "can't set FLL: %d\n", ret); 920 } 921 return ret; 922 } 923 924 static const struct snd_soc_dapm_widget nau8821_widgets[] = { 925 SND_SOC_DAPM_HP("Headphone jack", NULL), 926 SND_SOC_DAPM_MIC("Headset Mic", NULL), 927 SND_SOC_DAPM_MIC("Int Mic", NULL), 928 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, 929 platform_clock_control, SND_SOC_DAPM_PRE_PMU | 930 SND_SOC_DAPM_POST_PMD), 931 }; 932 933 static const struct snd_soc_dapm_route nau8821_audio_route[] = { 934 /* HP jack connectors - unknown if we have jack detection */ 935 { "Headphone jack", NULL, "HPOL" }, 936 { "Headphone jack", NULL, "HPOR" }, 937 { "MICL", NULL, "Headset Mic" }, 938 { "MICR", NULL, "Headset Mic" }, 939 { "DMIC", NULL, "Int Mic" }, 940 { "Headphone jack", NULL, "Platform Clock" }, 941 { "Headset Mic", NULL, "Platform Clock" }, 942 { "Int Mic", NULL, "Platform Clock" }, 943 }; 944 945 static const unsigned int nau8821_format[] = {16}; 946 947 static struct snd_pcm_hw_constraint_list constraints_sample_bits = { 948 .list = nau8821_format, 949 .count = ARRAY_SIZE(nau8821_format), 950 }; 951 952 static int acp_8821_init(struct snd_soc_pcm_runtime *rtd) 953 { 954 struct snd_soc_card *card = rtd->card; 955 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 956 struct snd_soc_component *component = codec_dai->component; 957 int ret; 958 959 dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name); 960 961 ret = snd_soc_dapm_new_controls(&card->dapm, nau8821_widgets, 962 ARRAY_SIZE(nau8821_widgets)); 963 if (ret) { 964 dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret); 965 // Don't need to add routes if widget addition failed 966 return ret; 967 } 968 969 ret = snd_soc_card_jack_new(card, "Headset Jack", 970 SND_JACK_HEADSET | SND_JACK_LINEOUT | 971 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 972 SND_JACK_BTN_2 | SND_JACK_BTN_3, 973 &vg_headset); 974 if (ret) { 975 dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); 976 return ret; 977 } 978 snd_jack_set_key(vg_headset.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 979 snd_jack_set_key(vg_headset.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); 980 snd_jack_set_key(vg_headset.jack, SND_JACK_BTN_2, KEY_VOLUMEUP); 981 snd_jack_set_key(vg_headset.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); 982 983 nau8821_enable_jack_detect(component, &vg_headset); 984 985 return snd_soc_dapm_add_routes(&rtd->card->dapm, nau8821_audio_route, 986 ARRAY_SIZE(nau8821_audio_route)); 987 } 988 989 static int acp_8821_startup(struct snd_pcm_substream *substream) 990 { 991 struct snd_pcm_runtime *runtime = substream->runtime; 992 993 runtime->hw.channels_max = DUAL_CHANNEL; 994 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 995 &constraints_channels); 996 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 997 &constraints_rates); 998 snd_pcm_hw_constraint_list(substream->runtime, 0, 999 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 1000 &constraints_sample_bits); 1001 return 0; 1002 } 1003 1004 static int acp_nau8821_hw_params(struct snd_pcm_substream *substream, 1005 struct snd_pcm_hw_params *params) 1006 { 1007 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 1008 struct snd_soc_card *card = rtd->card; 1009 struct acp_card_drvdata *drvdata = card->drvdata; 1010 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 1011 int ret; 1012 unsigned int fmt; 1013 1014 if (drvdata->soc_mclk) 1015 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; 1016 else 1017 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP; 1018 1019 ret = snd_soc_dai_set_fmt(codec_dai, fmt); 1020 if (ret < 0) { 1021 dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret); 1022 return ret; 1023 } 1024 1025 ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0, 1026 SND_SOC_CLOCK_IN); 1027 if (ret < 0) 1028 dev_err(card->dev, "can't set FS clock %d\n", ret); 1029 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, snd_soc_params_to_bclk(params), 1030 params_rate(params) * 256); 1031 if (ret < 0) 1032 dev_err(card->dev, "can't set FLL: %d\n", ret); 1033 1034 return ret; 1035 } 1036 1037 static const struct snd_soc_ops acp_8821_ops = { 1038 .startup = acp_8821_startup, 1039 .hw_params = acp_nau8821_hw_params, 1040 }; 1041 1042 SND_SOC_DAILINK_DEF(nau8821, 1043 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-NVTN2020:00", 1044 "nau8821-hifi"))); 1045 1046 /* Declare DMIC codec components */ 1047 SND_SOC_DAILINK_DEF(dmic_codec, 1048 DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); 1049 1050 /* Declare ACP CPU components */ 1051 static struct snd_soc_dai_link_component platform_component[] = { 1052 { 1053 .name = "acp_asoc_renoir.0", 1054 } 1055 }; 1056 1057 static struct snd_soc_dai_link_component platform_rmb_component[] = { 1058 { 1059 .name = "acp_asoc_rembrandt.0", 1060 } 1061 }; 1062 1063 static struct snd_soc_dai_link_component sof_component[] = { 1064 { 1065 .name = "0000:04:00.5", 1066 } 1067 }; 1068 1069 SND_SOC_DAILINK_DEF(i2s_sp, 1070 DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-sp"))); 1071 SND_SOC_DAILINK_DEF(i2s_hs, 1072 DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-hs"))); 1073 SND_SOC_DAILINK_DEF(sof_sp, 1074 DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp"))); 1075 SND_SOC_DAILINK_DEF(sof_sp_virtual, 1076 DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp-virtual"))); 1077 SND_SOC_DAILINK_DEF(sof_hs, 1078 DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs"))); 1079 SND_SOC_DAILINK_DEF(sof_hs_virtual, 1080 DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs-virtual"))); 1081 SND_SOC_DAILINK_DEF(sof_dmic, 1082 DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-dmic"))); 1083 SND_SOC_DAILINK_DEF(pdm_dmic, 1084 DAILINK_COMP_ARRAY(COMP_CPU("acp-pdm-dmic"))); 1085 1086 static int acp_rtk_set_bias_level(struct snd_soc_card *card, 1087 struct snd_soc_dapm_context *dapm, 1088 enum snd_soc_bias_level level) 1089 { 1090 struct snd_soc_component *component = dapm->component; 1091 struct acp_card_drvdata *drvdata = card->drvdata; 1092 int ret = 0; 1093 1094 if (!component) 1095 return 0; 1096 1097 if (strncmp(component->name, "i2c-RTL5682", 11) && 1098 strncmp(component->name, "i2c-10EC1019", 12)) 1099 return 0; 1100 1101 /* 1102 * For Realtek's codec and amplifier components, 1103 * the lrck and bclk must be enabled brfore their all dapms be powered on, 1104 * and must be disabled after their all dapms be powered down 1105 * to avoid any pop. 1106 */ 1107 switch (level) { 1108 case SND_SOC_BIAS_STANDBY: 1109 if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { 1110 1111 /* Increase bclk's enable_count */ 1112 ret = clk_prepare_enable(drvdata->bclk); 1113 if (ret < 0) 1114 dev_err(component->dev, "Failed to enable bclk %d\n", ret); 1115 } else { 1116 /* 1117 * Decrease bclk's enable_count. 1118 * While the enable_count is 0, the bclk would be closed. 1119 */ 1120 clk_disable_unprepare(drvdata->bclk); 1121 } 1122 break; 1123 default: 1124 break; 1125 } 1126 1127 return ret; 1128 } 1129 1130 int acp_sofdsp_dai_links_create(struct snd_soc_card *card) 1131 { 1132 struct snd_soc_dai_link *links; 1133 struct device *dev = card->dev; 1134 struct acp_card_drvdata *drv_data = card->drvdata; 1135 int i = 0, num_links = 0; 1136 1137 if (drv_data->hs_cpu_id) 1138 num_links++; 1139 if (drv_data->amp_cpu_id) 1140 num_links++; 1141 if (drv_data->dmic_cpu_id) 1142 num_links++; 1143 1144 links = devm_kcalloc(dev, num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL); 1145 if (!links) 1146 return -ENOMEM; 1147 1148 if (drv_data->hs_cpu_id == I2S_SP) { 1149 links[i].name = "acp-headset-codec"; 1150 links[i].id = HEADSET_BE_ID; 1151 links[i].cpus = sof_sp; 1152 links[i].num_cpus = ARRAY_SIZE(sof_sp); 1153 links[i].platforms = sof_component; 1154 links[i].num_platforms = ARRAY_SIZE(sof_component); 1155 links[i].dpcm_playback = 1; 1156 links[i].dpcm_capture = 1; 1157 links[i].nonatomic = true; 1158 links[i].no_pcm = 1; 1159 if (!drv_data->hs_codec_id) { 1160 /* Use dummy codec if codec id not specified */ 1161 links[i].codecs = &asoc_dummy_dlc; 1162 links[i].num_codecs = 1; 1163 } 1164 if (drv_data->hs_codec_id == RT5682) { 1165 links[i].codecs = rt5682; 1166 links[i].num_codecs = ARRAY_SIZE(rt5682); 1167 links[i].init = acp_card_rt5682_init; 1168 links[i].ops = &acp_card_rt5682_ops; 1169 } 1170 if (drv_data->hs_codec_id == RT5682S) { 1171 links[i].codecs = rt5682s; 1172 links[i].num_codecs = ARRAY_SIZE(rt5682s); 1173 links[i].init = acp_card_rt5682s_init; 1174 links[i].ops = &acp_card_rt5682s_ops; 1175 } 1176 if (drv_data->hs_codec_id == NAU8821) { 1177 links[i].codecs = nau8821; 1178 links[i].num_codecs = ARRAY_SIZE(nau8821); 1179 links[i].init = acp_8821_init; 1180 links[i].ops = &acp_8821_ops; 1181 } 1182 i++; 1183 } 1184 1185 if (drv_data->hs_cpu_id == I2S_HS) { 1186 links[i].name = "acp-headset-codec"; 1187 links[i].id = HEADSET_BE_ID; 1188 links[i].cpus = sof_hs; 1189 links[i].num_cpus = ARRAY_SIZE(sof_hs); 1190 links[i].platforms = sof_component; 1191 links[i].num_platforms = ARRAY_SIZE(sof_component); 1192 links[i].dpcm_playback = 1; 1193 links[i].dpcm_capture = 1; 1194 links[i].nonatomic = true; 1195 links[i].no_pcm = 1; 1196 if (!drv_data->hs_codec_id) { 1197 /* Use dummy codec if codec id not specified */ 1198 links[i].codecs = &asoc_dummy_dlc; 1199 links[i].num_codecs = 1; 1200 } 1201 if (drv_data->hs_codec_id == NAU8825) { 1202 links[i].codecs = nau8825; 1203 links[i].num_codecs = ARRAY_SIZE(nau8825); 1204 links[i].init = acp_card_nau8825_init; 1205 links[i].ops = &acp_card_nau8825_ops; 1206 } 1207 if (drv_data->hs_codec_id == RT5682S) { 1208 links[i].codecs = rt5682s; 1209 links[i].num_codecs = ARRAY_SIZE(rt5682s); 1210 links[i].init = acp_card_rt5682s_init; 1211 links[i].ops = &acp_card_rt5682s_ops; 1212 } 1213 i++; 1214 } 1215 1216 if (drv_data->amp_cpu_id == I2S_SP) { 1217 links[i].name = "acp-amp-codec"; 1218 links[i].id = AMP_BE_ID; 1219 links[i].cpus = sof_sp_virtual; 1220 links[i].num_cpus = ARRAY_SIZE(sof_sp_virtual); 1221 links[i].platforms = sof_component; 1222 links[i].num_platforms = ARRAY_SIZE(sof_component); 1223 links[i].dpcm_playback = 1; 1224 links[i].nonatomic = true; 1225 links[i].no_pcm = 1; 1226 if (!drv_data->amp_codec_id) { 1227 /* Use dummy codec if codec id not specified */ 1228 links[i].codecs = &asoc_dummy_dlc; 1229 links[i].num_codecs = 1; 1230 } 1231 if (drv_data->amp_codec_id == RT1019) { 1232 links[i].codecs = rt1019; 1233 links[i].num_codecs = ARRAY_SIZE(rt1019); 1234 links[i].ops = &acp_card_rt1019_ops; 1235 links[i].init = acp_card_rt1019_init; 1236 card->codec_conf = rt1019_conf; 1237 card->num_configs = ARRAY_SIZE(rt1019_conf); 1238 } 1239 if (drv_data->amp_codec_id == MAX98360A) { 1240 links[i].codecs = max98360a; 1241 links[i].num_codecs = ARRAY_SIZE(max98360a); 1242 links[i].ops = &acp_card_maxim_ops; 1243 links[i].init = acp_card_maxim_init; 1244 } 1245 i++; 1246 } 1247 1248 if (drv_data->amp_cpu_id == I2S_HS) { 1249 links[i].name = "acp-amp-codec"; 1250 links[i].id = AMP_BE_ID; 1251 links[i].cpus = sof_hs_virtual; 1252 links[i].num_cpus = ARRAY_SIZE(sof_hs_virtual); 1253 links[i].platforms = sof_component; 1254 links[i].num_platforms = ARRAY_SIZE(sof_component); 1255 links[i].dpcm_playback = 1; 1256 links[i].nonatomic = true; 1257 links[i].no_pcm = 1; 1258 if (!drv_data->amp_codec_id) { 1259 /* Use dummy codec if codec id not specified */ 1260 links[i].codecs = &asoc_dummy_dlc; 1261 links[i].num_codecs = 1; 1262 } 1263 if (drv_data->amp_codec_id == MAX98360A) { 1264 links[i].codecs = max98360a; 1265 links[i].num_codecs = ARRAY_SIZE(max98360a); 1266 links[i].ops = &acp_card_maxim_ops; 1267 links[i].init = acp_card_maxim_init; 1268 } 1269 if (drv_data->amp_codec_id == MAX98388) { 1270 links[i].codecs = max98388; 1271 links[i].num_codecs = ARRAY_SIZE(max98388); 1272 links[i].ops = &acp_max98388_ops; 1273 links[i].init = acp_card_max98388_init; 1274 card->codec_conf = max98388_conf; 1275 card->num_configs = ARRAY_SIZE(max98388_conf); 1276 } 1277 if (drv_data->amp_codec_id == RT1019) { 1278 links[i].codecs = rt1019; 1279 links[i].num_codecs = ARRAY_SIZE(rt1019); 1280 links[i].ops = &acp_card_rt1019_ops; 1281 links[i].init = acp_card_rt1019_init; 1282 card->codec_conf = rt1019_conf; 1283 card->num_configs = ARRAY_SIZE(rt1019_conf); 1284 } 1285 i++; 1286 } 1287 1288 if (drv_data->dmic_cpu_id == DMIC) { 1289 links[i].name = "acp-dmic-codec"; 1290 links[i].id = DMIC_BE_ID; 1291 links[i].codecs = dmic_codec; 1292 links[i].num_codecs = ARRAY_SIZE(dmic_codec); 1293 links[i].cpus = sof_dmic; 1294 links[i].num_cpus = ARRAY_SIZE(sof_dmic); 1295 links[i].platforms = sof_component; 1296 links[i].num_platforms = ARRAY_SIZE(sof_component); 1297 links[i].dpcm_capture = 1; 1298 links[i].nonatomic = true; 1299 links[i].no_pcm = 1; 1300 } 1301 1302 card->dai_link = links; 1303 card->num_links = num_links; 1304 card->set_bias_level = acp_rtk_set_bias_level; 1305 1306 return 0; 1307 } 1308 EXPORT_SYMBOL_NS_GPL(acp_sofdsp_dai_links_create, SND_SOC_AMD_MACH); 1309 1310 int acp_legacy_dai_links_create(struct snd_soc_card *card) 1311 { 1312 struct snd_soc_dai_link *links; 1313 struct device *dev = card->dev; 1314 struct acp_card_drvdata *drv_data = card->drvdata; 1315 int i = 0, num_links = 0; 1316 1317 if (drv_data->hs_cpu_id) 1318 num_links++; 1319 if (drv_data->amp_cpu_id) 1320 num_links++; 1321 if (drv_data->dmic_cpu_id) 1322 num_links++; 1323 1324 links = devm_kcalloc(dev, num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL); 1325 if (!links) 1326 return -ENOMEM; 1327 1328 if (drv_data->hs_cpu_id == I2S_SP) { 1329 links[i].name = "acp-headset-codec"; 1330 links[i].id = HEADSET_BE_ID; 1331 links[i].cpus = i2s_sp; 1332 links[i].num_cpus = ARRAY_SIZE(i2s_sp); 1333 links[i].platforms = platform_component; 1334 links[i].num_platforms = ARRAY_SIZE(platform_component); 1335 links[i].dpcm_playback = 1; 1336 links[i].dpcm_capture = 1; 1337 if (!drv_data->hs_codec_id) { 1338 /* Use dummy codec if codec id not specified */ 1339 links[i].codecs = &asoc_dummy_dlc; 1340 links[i].num_codecs = 1; 1341 } 1342 if (drv_data->hs_codec_id == RT5682) { 1343 links[i].codecs = rt5682; 1344 links[i].num_codecs = ARRAY_SIZE(rt5682); 1345 links[i].init = acp_card_rt5682_init; 1346 links[i].ops = &acp_card_rt5682_ops; 1347 } 1348 if (drv_data->hs_codec_id == RT5682S) { 1349 links[i].codecs = rt5682s; 1350 links[i].num_codecs = ARRAY_SIZE(rt5682s); 1351 links[i].init = acp_card_rt5682s_init; 1352 links[i].ops = &acp_card_rt5682s_ops; 1353 } 1354 i++; 1355 } 1356 1357 if (drv_data->hs_cpu_id == I2S_HS) { 1358 links[i].name = "acp-headset-codec"; 1359 links[i].id = HEADSET_BE_ID; 1360 links[i].cpus = i2s_hs; 1361 links[i].num_cpus = ARRAY_SIZE(i2s_hs); 1362 if (drv_data->platform == REMBRANDT) { 1363 links[i].platforms = platform_rmb_component; 1364 links[i].num_platforms = ARRAY_SIZE(platform_rmb_component); 1365 } else { 1366 links[i].platforms = platform_component; 1367 links[i].num_platforms = ARRAY_SIZE(platform_component); 1368 } 1369 links[i].dpcm_playback = 1; 1370 links[i].dpcm_capture = 1; 1371 if (!drv_data->hs_codec_id) { 1372 /* Use dummy codec if codec id not specified */ 1373 links[i].codecs = &asoc_dummy_dlc; 1374 links[i].num_codecs = 1; 1375 } 1376 if (drv_data->hs_codec_id == NAU8825) { 1377 links[i].codecs = nau8825; 1378 links[i].num_codecs = ARRAY_SIZE(nau8825); 1379 links[i].init = acp_card_nau8825_init; 1380 links[i].ops = &acp_card_nau8825_ops; 1381 } 1382 if (drv_data->hs_codec_id == RT5682S) { 1383 links[i].codecs = rt5682s; 1384 links[i].num_codecs = ARRAY_SIZE(rt5682s); 1385 links[i].init = acp_card_rt5682s_init; 1386 links[i].ops = &acp_card_rt5682s_ops; 1387 } 1388 i++; 1389 } 1390 1391 if (drv_data->amp_cpu_id == I2S_SP) { 1392 links[i].name = "acp-amp-codec"; 1393 links[i].id = AMP_BE_ID; 1394 links[i].cpus = i2s_sp; 1395 links[i].num_cpus = ARRAY_SIZE(i2s_sp); 1396 links[i].platforms = platform_component; 1397 links[i].num_platforms = ARRAY_SIZE(platform_component); 1398 links[i].dpcm_playback = 1; 1399 if (!drv_data->amp_codec_id) { 1400 /* Use dummy codec if codec id not specified */ 1401 links[i].codecs = &asoc_dummy_dlc; 1402 links[i].num_codecs = 1; 1403 } 1404 if (drv_data->amp_codec_id == RT1019) { 1405 links[i].codecs = rt1019; 1406 links[i].num_codecs = ARRAY_SIZE(rt1019); 1407 links[i].ops = &acp_card_rt1019_ops; 1408 links[i].init = acp_card_rt1019_init; 1409 card->codec_conf = rt1019_conf; 1410 card->num_configs = ARRAY_SIZE(rt1019_conf); 1411 } 1412 if (drv_data->amp_codec_id == MAX98360A) { 1413 links[i].codecs = max98360a; 1414 links[i].num_codecs = ARRAY_SIZE(max98360a); 1415 links[i].ops = &acp_card_maxim_ops; 1416 links[i].init = acp_card_maxim_init; 1417 } 1418 i++; 1419 } 1420 1421 if (drv_data->amp_cpu_id == I2S_HS) { 1422 links[i].name = "acp-amp-codec"; 1423 links[i].id = AMP_BE_ID; 1424 links[i].cpus = i2s_hs; 1425 links[i].num_cpus = ARRAY_SIZE(i2s_hs); 1426 if (drv_data->platform == REMBRANDT) { 1427 links[i].platforms = platform_rmb_component; 1428 links[i].num_platforms = ARRAY_SIZE(platform_rmb_component); 1429 } else { 1430 links[i].platforms = platform_component; 1431 links[i].num_platforms = ARRAY_SIZE(platform_component); 1432 } 1433 links[i].dpcm_playback = 1; 1434 if (!drv_data->amp_codec_id) { 1435 /* Use dummy codec if codec id not specified */ 1436 links[i].codecs = &asoc_dummy_dlc; 1437 links[i].num_codecs = 1; 1438 } 1439 if (drv_data->amp_codec_id == MAX98360A) { 1440 links[i].codecs = max98360a; 1441 links[i].num_codecs = ARRAY_SIZE(max98360a); 1442 links[i].ops = &acp_card_maxim_ops; 1443 links[i].init = acp_card_maxim_init; 1444 } 1445 if (drv_data->amp_codec_id == RT1019) { 1446 links[i].codecs = rt1019; 1447 links[i].num_codecs = ARRAY_SIZE(rt1019); 1448 links[i].ops = &acp_card_rt1019_ops; 1449 links[i].init = acp_card_rt1019_init; 1450 card->codec_conf = rt1019_conf; 1451 card->num_configs = ARRAY_SIZE(rt1019_conf); 1452 } 1453 i++; 1454 } 1455 1456 if (drv_data->dmic_cpu_id == DMIC) { 1457 links[i].name = "acp-dmic-codec"; 1458 links[i].id = DMIC_BE_ID; 1459 if (drv_data->dmic_codec_id == DMIC) { 1460 links[i].codecs = dmic_codec; 1461 links[i].num_codecs = ARRAY_SIZE(dmic_codec); 1462 } else { 1463 /* Use dummy codec if codec id not specified */ 1464 links[i].codecs = &asoc_dummy_dlc; 1465 links[i].num_codecs = 1; 1466 } 1467 links[i].cpus = pdm_dmic; 1468 links[i].num_cpus = ARRAY_SIZE(pdm_dmic); 1469 if (drv_data->platform == REMBRANDT) { 1470 links[i].platforms = platform_rmb_component; 1471 links[i].num_platforms = ARRAY_SIZE(platform_rmb_component); 1472 } else { 1473 links[i].platforms = platform_component; 1474 links[i].num_platforms = ARRAY_SIZE(platform_component); 1475 } 1476 links[i].ops = &acp_card_dmic_ops; 1477 links[i].dpcm_capture = 1; 1478 } 1479 1480 card->dai_link = links; 1481 card->num_links = num_links; 1482 card->set_bias_level = acp_rtk_set_bias_level; 1483 1484 return 0; 1485 } 1486 EXPORT_SYMBOL_NS_GPL(acp_legacy_dai_links_create, SND_SOC_AMD_MACH); 1487 1488 MODULE_LICENSE("GPL v2"); 1489