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 platform_component[] = { 799 { 800 .name = "acp_asoc_renoir.0", 801 } 802 }; 803 804 static struct snd_soc_dai_link_component platform_rmb_component[] = { 805 { 806 .name = "acp_asoc_rembrandt.0", 807 } 808 }; 809 810 static struct snd_soc_dai_link_component sof_component[] = { 811 { 812 .name = "0000:04:00.5", 813 } 814 }; 815 816 SND_SOC_DAILINK_DEF(i2s_sp, 817 DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-sp"))); 818 SND_SOC_DAILINK_DEF(i2s_hs, 819 DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-hs"))); 820 SND_SOC_DAILINK_DEF(sof_sp, 821 DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp"))); 822 SND_SOC_DAILINK_DEF(sof_sp_virtual, 823 DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp-virtual"))); 824 SND_SOC_DAILINK_DEF(sof_hs, 825 DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs"))); 826 SND_SOC_DAILINK_DEF(sof_hs_virtual, 827 DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs-virtual"))); 828 SND_SOC_DAILINK_DEF(sof_dmic, 829 DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-dmic"))); 830 SND_SOC_DAILINK_DEF(pdm_dmic, 831 DAILINK_COMP_ARRAY(COMP_CPU("acp-pdm-dmic"))); 832 833 static int acp_rtk_set_bias_level(struct snd_soc_card *card, 834 struct snd_soc_dapm_context *dapm, 835 enum snd_soc_bias_level level) 836 { 837 struct snd_soc_component *component = dapm->component; 838 struct acp_card_drvdata *drvdata = card->drvdata; 839 int ret = 0; 840 841 if (!component) 842 return 0; 843 844 if (strncmp(component->name, "i2c-RTL5682", 11) && 845 strncmp(component->name, "i2c-10EC1019", 12)) 846 return 0; 847 848 /* 849 * For Realtek's codec and amplifier components, 850 * the lrck and bclk must be enabled brfore their all dapms be powered on, 851 * and must be disabled after their all dapms be powered down 852 * to avoid any pop. 853 */ 854 switch (level) { 855 case SND_SOC_BIAS_STANDBY: 856 if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { 857 858 /* Increase bclk's enable_count */ 859 ret = clk_prepare_enable(drvdata->bclk); 860 if (ret < 0) 861 dev_err(component->dev, "Failed to enable bclk %d\n", ret); 862 } else { 863 /* 864 * Decrease bclk's enable_count. 865 * While the enable_count is 0, the bclk would be closed. 866 */ 867 clk_disable_unprepare(drvdata->bclk); 868 } 869 break; 870 default: 871 break; 872 } 873 874 return ret; 875 } 876 877 int acp_sofdsp_dai_links_create(struct snd_soc_card *card) 878 { 879 struct snd_soc_dai_link *links; 880 struct device *dev = card->dev; 881 struct acp_card_drvdata *drv_data = card->drvdata; 882 int i = 0, num_links = 0; 883 884 if (drv_data->hs_cpu_id) 885 num_links++; 886 if (drv_data->amp_cpu_id) 887 num_links++; 888 if (drv_data->dmic_cpu_id) 889 num_links++; 890 891 links = devm_kcalloc(dev, num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL); 892 if (!links) 893 return -ENOMEM; 894 895 if (drv_data->hs_cpu_id == I2S_SP) { 896 links[i].name = "acp-headset-codec"; 897 links[i].id = HEADSET_BE_ID; 898 links[i].cpus = sof_sp; 899 links[i].num_cpus = ARRAY_SIZE(sof_sp); 900 links[i].platforms = sof_component; 901 links[i].num_platforms = ARRAY_SIZE(sof_component); 902 links[i].dpcm_playback = 1; 903 links[i].dpcm_capture = 1; 904 links[i].nonatomic = true; 905 links[i].no_pcm = 1; 906 if (!drv_data->hs_codec_id) { 907 /* Use dummy codec if codec id not specified */ 908 links[i].codecs = &asoc_dummy_dlc; 909 links[i].num_codecs = 1; 910 } 911 if (drv_data->hs_codec_id == RT5682) { 912 links[i].codecs = rt5682; 913 links[i].num_codecs = ARRAY_SIZE(rt5682); 914 links[i].init = acp_card_rt5682_init; 915 links[i].ops = &acp_card_rt5682_ops; 916 } 917 if (drv_data->hs_codec_id == RT5682S) { 918 links[i].codecs = rt5682s; 919 links[i].num_codecs = ARRAY_SIZE(rt5682s); 920 links[i].init = acp_card_rt5682s_init; 921 links[i].ops = &acp_card_rt5682s_ops; 922 } 923 i++; 924 } 925 926 if (drv_data->hs_cpu_id == I2S_HS) { 927 links[i].name = "acp-headset-codec"; 928 links[i].id = HEADSET_BE_ID; 929 links[i].cpus = sof_hs; 930 links[i].num_cpus = ARRAY_SIZE(sof_hs); 931 links[i].platforms = sof_component; 932 links[i].num_platforms = ARRAY_SIZE(sof_component); 933 links[i].dpcm_playback = 1; 934 links[i].dpcm_capture = 1; 935 links[i].nonatomic = true; 936 links[i].no_pcm = 1; 937 if (!drv_data->hs_codec_id) { 938 /* Use dummy codec if codec id not specified */ 939 links[i].codecs = &asoc_dummy_dlc; 940 links[i].num_codecs = 1; 941 } 942 if (drv_data->hs_codec_id == NAU8825) { 943 links[i].codecs = nau8825; 944 links[i].num_codecs = ARRAY_SIZE(nau8825); 945 links[i].init = acp_card_nau8825_init; 946 links[i].ops = &acp_card_nau8825_ops; 947 } 948 if (drv_data->hs_codec_id == RT5682S) { 949 links[i].codecs = rt5682s; 950 links[i].num_codecs = ARRAY_SIZE(rt5682s); 951 links[i].init = acp_card_rt5682s_init; 952 links[i].ops = &acp_card_rt5682s_ops; 953 } 954 i++; 955 } 956 957 if (drv_data->amp_cpu_id == I2S_SP) { 958 links[i].name = "acp-amp-codec"; 959 links[i].id = AMP_BE_ID; 960 links[i].cpus = sof_sp_virtual; 961 links[i].num_cpus = ARRAY_SIZE(sof_sp_virtual); 962 links[i].platforms = sof_component; 963 links[i].num_platforms = ARRAY_SIZE(sof_component); 964 links[i].dpcm_playback = 1; 965 links[i].nonatomic = true; 966 links[i].no_pcm = 1; 967 if (!drv_data->amp_codec_id) { 968 /* Use dummy codec if codec id not specified */ 969 links[i].codecs = &asoc_dummy_dlc; 970 links[i].num_codecs = 1; 971 } 972 if (drv_data->amp_codec_id == RT1019) { 973 links[i].codecs = rt1019; 974 links[i].num_codecs = ARRAY_SIZE(rt1019); 975 links[i].ops = &acp_card_rt1019_ops; 976 links[i].init = acp_card_rt1019_init; 977 card->codec_conf = rt1019_conf; 978 card->num_configs = ARRAY_SIZE(rt1019_conf); 979 } 980 if (drv_data->amp_codec_id == MAX98360A) { 981 links[i].codecs = max98360a; 982 links[i].num_codecs = ARRAY_SIZE(max98360a); 983 links[i].ops = &acp_card_maxim_ops; 984 links[i].init = acp_card_maxim_init; 985 } 986 i++; 987 } 988 989 if (drv_data->amp_cpu_id == I2S_HS) { 990 links[i].name = "acp-amp-codec"; 991 links[i].id = AMP_BE_ID; 992 links[i].cpus = sof_hs_virtual; 993 links[i].num_cpus = ARRAY_SIZE(sof_hs_virtual); 994 links[i].platforms = sof_component; 995 links[i].num_platforms = ARRAY_SIZE(sof_component); 996 links[i].dpcm_playback = 1; 997 links[i].nonatomic = true; 998 links[i].no_pcm = 1; 999 if (!drv_data->amp_codec_id) { 1000 /* Use dummy codec if codec id not specified */ 1001 links[i].codecs = &asoc_dummy_dlc; 1002 links[i].num_codecs = 1; 1003 } 1004 if (drv_data->amp_codec_id == MAX98360A) { 1005 links[i].codecs = max98360a; 1006 links[i].num_codecs = ARRAY_SIZE(max98360a); 1007 links[i].ops = &acp_card_maxim_ops; 1008 links[i].init = acp_card_maxim_init; 1009 } 1010 if (drv_data->amp_codec_id == RT1019) { 1011 links[i].codecs = rt1019; 1012 links[i].num_codecs = ARRAY_SIZE(rt1019); 1013 links[i].ops = &acp_card_rt1019_ops; 1014 links[i].init = acp_card_rt1019_init; 1015 card->codec_conf = rt1019_conf; 1016 card->num_configs = ARRAY_SIZE(rt1019_conf); 1017 } 1018 i++; 1019 } 1020 1021 if (drv_data->dmic_cpu_id == DMIC) { 1022 links[i].name = "acp-dmic-codec"; 1023 links[i].id = DMIC_BE_ID; 1024 links[i].codecs = dmic_codec; 1025 links[i].num_codecs = ARRAY_SIZE(dmic_codec); 1026 links[i].cpus = sof_dmic; 1027 links[i].num_cpus = ARRAY_SIZE(sof_dmic); 1028 links[i].platforms = sof_component; 1029 links[i].num_platforms = ARRAY_SIZE(sof_component); 1030 links[i].dpcm_capture = 1; 1031 links[i].nonatomic = true; 1032 links[i].no_pcm = 1; 1033 } 1034 1035 card->dai_link = links; 1036 card->num_links = num_links; 1037 card->set_bias_level = acp_rtk_set_bias_level; 1038 1039 return 0; 1040 } 1041 EXPORT_SYMBOL_NS_GPL(acp_sofdsp_dai_links_create, SND_SOC_AMD_MACH); 1042 1043 int acp_legacy_dai_links_create(struct snd_soc_card *card) 1044 { 1045 struct snd_soc_dai_link *links; 1046 struct device *dev = card->dev; 1047 struct acp_card_drvdata *drv_data = card->drvdata; 1048 int i = 0, num_links = 0; 1049 1050 if (drv_data->hs_cpu_id) 1051 num_links++; 1052 if (drv_data->amp_cpu_id) 1053 num_links++; 1054 if (drv_data->dmic_cpu_id) 1055 num_links++; 1056 1057 links = devm_kcalloc(dev, num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL); 1058 if (!links) 1059 return -ENOMEM; 1060 1061 if (drv_data->hs_cpu_id == I2S_SP) { 1062 links[i].name = "acp-headset-codec"; 1063 links[i].id = HEADSET_BE_ID; 1064 links[i].cpus = i2s_sp; 1065 links[i].num_cpus = ARRAY_SIZE(i2s_sp); 1066 links[i].platforms = platform_component; 1067 links[i].num_platforms = ARRAY_SIZE(platform_component); 1068 links[i].dpcm_playback = 1; 1069 links[i].dpcm_capture = 1; 1070 if (!drv_data->hs_codec_id) { 1071 /* Use dummy codec if codec id not specified */ 1072 links[i].codecs = &asoc_dummy_dlc; 1073 links[i].num_codecs = 1; 1074 } 1075 if (drv_data->hs_codec_id == RT5682) { 1076 links[i].codecs = rt5682; 1077 links[i].num_codecs = ARRAY_SIZE(rt5682); 1078 links[i].init = acp_card_rt5682_init; 1079 links[i].ops = &acp_card_rt5682_ops; 1080 } 1081 if (drv_data->hs_codec_id == RT5682S) { 1082 links[i].codecs = rt5682s; 1083 links[i].num_codecs = ARRAY_SIZE(rt5682s); 1084 links[i].init = acp_card_rt5682s_init; 1085 links[i].ops = &acp_card_rt5682s_ops; 1086 } 1087 i++; 1088 } 1089 1090 if (drv_data->hs_cpu_id == I2S_HS) { 1091 links[i].name = "acp-headset-codec"; 1092 links[i].id = HEADSET_BE_ID; 1093 links[i].cpus = i2s_hs; 1094 links[i].num_cpus = ARRAY_SIZE(i2s_hs); 1095 if (drv_data->platform == REMBRANDT) { 1096 links[i].platforms = platform_rmb_component; 1097 links[i].num_platforms = ARRAY_SIZE(platform_rmb_component); 1098 } else { 1099 links[i].platforms = platform_component; 1100 links[i].num_platforms = ARRAY_SIZE(platform_component); 1101 } 1102 links[i].dpcm_playback = 1; 1103 links[i].dpcm_capture = 1; 1104 if (!drv_data->hs_codec_id) { 1105 /* Use dummy codec if codec id not specified */ 1106 links[i].codecs = &asoc_dummy_dlc; 1107 links[i].num_codecs = 1; 1108 } 1109 if (drv_data->hs_codec_id == NAU8825) { 1110 links[i].codecs = nau8825; 1111 links[i].num_codecs = ARRAY_SIZE(nau8825); 1112 links[i].init = acp_card_nau8825_init; 1113 links[i].ops = &acp_card_nau8825_ops; 1114 } 1115 if (drv_data->hs_codec_id == RT5682S) { 1116 links[i].codecs = rt5682s; 1117 links[i].num_codecs = ARRAY_SIZE(rt5682s); 1118 links[i].init = acp_card_rt5682s_init; 1119 links[i].ops = &acp_card_rt5682s_ops; 1120 } 1121 i++; 1122 } 1123 1124 if (drv_data->amp_cpu_id == I2S_SP) { 1125 links[i].name = "acp-amp-codec"; 1126 links[i].id = AMP_BE_ID; 1127 links[i].cpus = i2s_sp; 1128 links[i].num_cpus = ARRAY_SIZE(i2s_sp); 1129 links[i].platforms = platform_component; 1130 links[i].num_platforms = ARRAY_SIZE(platform_component); 1131 links[i].dpcm_playback = 1; 1132 if (!drv_data->amp_codec_id) { 1133 /* Use dummy codec if codec id not specified */ 1134 links[i].codecs = &asoc_dummy_dlc; 1135 links[i].num_codecs = 1; 1136 } 1137 if (drv_data->amp_codec_id == RT1019) { 1138 links[i].codecs = rt1019; 1139 links[i].num_codecs = ARRAY_SIZE(rt1019); 1140 links[i].ops = &acp_card_rt1019_ops; 1141 links[i].init = acp_card_rt1019_init; 1142 card->codec_conf = rt1019_conf; 1143 card->num_configs = ARRAY_SIZE(rt1019_conf); 1144 } 1145 if (drv_data->amp_codec_id == MAX98360A) { 1146 links[i].codecs = max98360a; 1147 links[i].num_codecs = ARRAY_SIZE(max98360a); 1148 links[i].ops = &acp_card_maxim_ops; 1149 links[i].init = acp_card_maxim_init; 1150 } 1151 i++; 1152 } 1153 1154 if (drv_data->amp_cpu_id == I2S_HS) { 1155 links[i].name = "acp-amp-codec"; 1156 links[i].id = AMP_BE_ID; 1157 links[i].cpus = i2s_hs; 1158 links[i].num_cpus = ARRAY_SIZE(i2s_hs); 1159 if (drv_data->platform == REMBRANDT) { 1160 links[i].platforms = platform_rmb_component; 1161 links[i].num_platforms = ARRAY_SIZE(platform_rmb_component); 1162 } else { 1163 links[i].platforms = platform_component; 1164 links[i].num_platforms = ARRAY_SIZE(platform_component); 1165 } 1166 links[i].dpcm_playback = 1; 1167 if (!drv_data->amp_codec_id) { 1168 /* Use dummy codec if codec id not specified */ 1169 links[i].codecs = &asoc_dummy_dlc; 1170 links[i].num_codecs = 1; 1171 } 1172 if (drv_data->amp_codec_id == MAX98360A) { 1173 links[i].codecs = max98360a; 1174 links[i].num_codecs = ARRAY_SIZE(max98360a); 1175 links[i].ops = &acp_card_maxim_ops; 1176 links[i].init = acp_card_maxim_init; 1177 } 1178 if (drv_data->amp_codec_id == RT1019) { 1179 links[i].codecs = rt1019; 1180 links[i].num_codecs = ARRAY_SIZE(rt1019); 1181 links[i].ops = &acp_card_rt1019_ops; 1182 links[i].init = acp_card_rt1019_init; 1183 card->codec_conf = rt1019_conf; 1184 card->num_configs = ARRAY_SIZE(rt1019_conf); 1185 } 1186 i++; 1187 } 1188 1189 if (drv_data->dmic_cpu_id == DMIC) { 1190 links[i].name = "acp-dmic-codec"; 1191 links[i].id = DMIC_BE_ID; 1192 if (drv_data->dmic_codec_id == DMIC) { 1193 links[i].codecs = dmic_codec; 1194 links[i].num_codecs = ARRAY_SIZE(dmic_codec); 1195 } else { 1196 /* Use dummy codec if codec id not specified */ 1197 links[i].codecs = &asoc_dummy_dlc; 1198 links[i].num_codecs = 1; 1199 } 1200 links[i].cpus = pdm_dmic; 1201 links[i].num_cpus = ARRAY_SIZE(pdm_dmic); 1202 if (drv_data->platform == REMBRANDT) { 1203 links[i].platforms = platform_rmb_component; 1204 links[i].num_platforms = ARRAY_SIZE(platform_rmb_component); 1205 } else { 1206 links[i].platforms = platform_component; 1207 links[i].num_platforms = ARRAY_SIZE(platform_component); 1208 } 1209 links[i].ops = &acp_card_dmic_ops; 1210 links[i].dpcm_capture = 1; 1211 } 1212 1213 card->dai_link = links; 1214 card->num_links = num_links; 1215 card->set_bias_level = acp_rtk_set_bias_level; 1216 1217 return 0; 1218 } 1219 EXPORT_SYMBOL_NS_GPL(acp_legacy_dai_links_create, SND_SOC_AMD_MACH); 1220 1221 MODULE_LICENSE("GPL v2"); 1222