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