1 // SPDX-License-Identifier: GPL-2.0-only 2 // 3 // Copyright(c) 2020 Intel Corporation. All rights reserved. 4 5 #include <linux/device.h> 6 #include <linux/kernel.h> 7 #include <sound/pcm.h> 8 #include <sound/pcm_params.h> 9 #include <sound/soc.h> 10 #include <sound/soc-acpi.h> 11 #include <sound/soc-dai.h> 12 #include <sound/soc-dapm.h> 13 #include <sound/sof.h> 14 #include <uapi/sound/asound.h> 15 #include "../../codecs/rt1011.h" 16 #include "../../codecs/rt1015.h" 17 #include "../../codecs/rt1308.h" 18 #include "../common/soc-intel-quirks.h" 19 #include "sof_realtek_common.h" 20 21 /* 22 * Common structures and functions 23 */ 24 static const struct snd_kcontrol_new realtek_4spk_kcontrols[] = { 25 SOC_DAPM_PIN_SWITCH("WL Ext Spk"), 26 SOC_DAPM_PIN_SWITCH("WR Ext Spk"), 27 SOC_DAPM_PIN_SWITCH("TL Ext Spk"), 28 SOC_DAPM_PIN_SWITCH("TR Ext Spk"), 29 }; 30 31 static const struct snd_soc_dapm_widget realtek_4spk_widgets[] = { 32 SND_SOC_DAPM_SPK("WL Ext Spk", NULL), 33 SND_SOC_DAPM_SPK("WR Ext Spk", NULL), 34 SND_SOC_DAPM_SPK("TL Ext Spk", NULL), 35 SND_SOC_DAPM_SPK("TR Ext Spk", NULL), 36 }; 37 38 /* helper function to get the number of specific codec */ 39 static unsigned int get_num_codecs(const char *hid) 40 { 41 struct acpi_device *adev; 42 unsigned int dev_num = 0; 43 44 for_each_acpi_dev_match(adev, hid, NULL, -1) 45 dev_num++; 46 47 return dev_num; 48 } 49 50 /* 51 * Realtek ALC1011 52 */ 53 static const struct snd_soc_dapm_route speaker_map_lr[] = { 54 /* speaker */ 55 { "Left Spk", NULL, "Left SPO" }, 56 { "Right Spk", NULL, "Right SPO" }, 57 }; 58 59 static const struct snd_soc_dapm_route rt1011_4spk_routes[] = { 60 {"WL Ext Spk", NULL, "WL SPO" }, 61 {"WR Ext Spk", NULL, "WR SPO" }, 62 {"TL Ext Spk", NULL, "TL SPO" }, 63 {"TR Ext Spk", NULL, "TR SPO" }, 64 }; 65 66 static struct snd_soc_codec_conf rt1011_2spk_codec_confs[] = { 67 { 68 .dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME), 69 .name_prefix = "Left", 70 }, 71 { 72 .dlc = COMP_CODEC_CONF(RT1011_DEV1_NAME), 73 .name_prefix = "Right", 74 }, 75 }; 76 77 static struct snd_soc_codec_conf rt1011_4spk_codec_confs[] = { 78 { 79 .dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME), 80 .name_prefix = "WL", 81 }, 82 { 83 .dlc = COMP_CODEC_CONF(RT1011_DEV1_NAME), 84 .name_prefix = "WR", 85 }, 86 { 87 .dlc = COMP_CODEC_CONF(RT1011_DEV2_NAME), 88 .name_prefix = "TL", 89 }, 90 { 91 .dlc = COMP_CODEC_CONF(RT1011_DEV3_NAME), 92 .name_prefix = "TR", 93 }, 94 }; 95 96 static struct snd_soc_dai_link_component rt1011_dai_link_components[] = { 97 { 98 .name = RT1011_DEV0_NAME, 99 .dai_name = RT1011_CODEC_DAI, 100 }, 101 { 102 .name = RT1011_DEV1_NAME, 103 .dai_name = RT1011_CODEC_DAI, 104 }, 105 { 106 .name = RT1011_DEV2_NAME, 107 .dai_name = RT1011_CODEC_DAI, 108 }, 109 { 110 .name = RT1011_DEV3_NAME, 111 .dai_name = RT1011_CODEC_DAI, 112 }, 113 }; 114 115 static const struct { 116 unsigned int tx; 117 unsigned int rx; 118 } rt1011_tdm_mask[] = { 119 {.tx = 0x4, .rx = 0x1}, 120 {.tx = 0x8, .rx = 0x2}, 121 {.tx = 0x1, .rx = 0x1}, 122 {.tx = 0x2, .rx = 0x2}, 123 }; 124 125 static int rt1011_hw_params(struct snd_pcm_substream *substream, 126 struct snd_pcm_hw_params *params) 127 { 128 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 129 struct snd_soc_dai *codec_dai; 130 int srate, i, ret = 0; 131 132 srate = params_rate(params); 133 134 for_each_rtd_codec_dais(rtd, i, codec_dai) { 135 /* 100 Fs to drive 24 bit data */ 136 ret = snd_soc_dai_set_pll(codec_dai, 0, RT1011_PLL1_S_BCLK, 137 100 * srate, 256 * srate); 138 if (ret < 0) { 139 dev_err(codec_dai->dev, "fail to set pll, ret %d\n", 140 ret); 141 return ret; 142 } 143 144 ret = snd_soc_dai_set_sysclk(codec_dai, RT1011_FS_SYS_PRE_S_PLL1, 145 256 * srate, SND_SOC_CLOCK_IN); 146 if (ret < 0) { 147 dev_err(codec_dai->dev, "fail to set sysclk, ret %d\n", 148 ret); 149 return ret; 150 } 151 152 if (i >= ARRAY_SIZE(rt1011_tdm_mask)) { 153 dev_err(codec_dai->dev, "invalid codec index %d\n", 154 i); 155 return -ENODEV; 156 } 157 158 ret = snd_soc_dai_set_tdm_slot(codec_dai, rt1011_tdm_mask[i].tx, 159 rt1011_tdm_mask[i].rx, 4, 160 params_width(params)); 161 if (ret < 0) { 162 dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n", 163 ret); 164 return ret; 165 } 166 } 167 168 return 0; 169 } 170 171 static const struct snd_soc_ops rt1011_ops = { 172 .hw_params = rt1011_hw_params, 173 }; 174 175 static int rt1011_init(struct snd_soc_pcm_runtime *rtd) 176 { 177 struct snd_soc_card *card = rtd->card; 178 unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID); 179 int ret; 180 181 switch (num_codecs) { 182 case 2: 183 if (!soc_intel_is_cml()) { 184 ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map_lr, 185 ARRAY_SIZE(speaker_map_lr)); 186 if (ret) { 187 dev_err(rtd->dev, "fail to add rt1011 routes, ret %d\n", 188 ret); 189 return ret; 190 } 191 192 break; 193 } 194 195 /* 196 * register speaker widgets "WL Ext Spk" and "WR Ext Spk" to 197 * keep backward compatible with cml devices 198 */ 199 fallthrough; 200 case 4: 201 ret = snd_soc_dapm_new_controls(&card->dapm, realtek_4spk_widgets, 202 num_codecs); 203 if (ret) { 204 dev_err(rtd->dev, "fail to add rt1011 widgets, ret %d\n", 205 ret); 206 return ret; 207 } 208 209 ret = snd_soc_add_card_controls(card, realtek_4spk_kcontrols, 210 num_codecs); 211 if (ret) { 212 dev_err(rtd->dev, "fail to add rt1011 controls, ret %d\n", 213 ret); 214 return ret; 215 } 216 217 ret = snd_soc_dapm_add_routes(&card->dapm, rt1011_4spk_routes, 218 num_codecs); 219 if (ret) { 220 dev_err(rtd->dev, "fail to add rt1011 routes, ret %d\n", 221 ret); 222 return ret; 223 } 224 break; 225 default: 226 dev_err(rtd->dev, "rt1011: invalid num_codecs %d\n", num_codecs); 227 return -EINVAL; 228 } 229 230 return ret; 231 } 232 233 void sof_rt1011_dai_link(struct device *dev, struct snd_soc_dai_link *link) 234 { 235 unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID); 236 237 link->codecs = rt1011_dai_link_components; 238 239 switch (num_codecs) { 240 case 2: 241 case 4: 242 link->num_codecs = num_codecs; 243 break; 244 default: 245 dev_err(dev, "rt1011: invalid num_codecs %d\n", num_codecs); 246 break; 247 } 248 249 link->init = rt1011_init; 250 link->ops = &rt1011_ops; 251 } 252 EXPORT_SYMBOL_NS(sof_rt1011_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); 253 254 void sof_rt1011_codec_conf(struct device *dev, struct snd_soc_card *card) 255 { 256 unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID); 257 258 switch (num_codecs) { 259 case 2: 260 if (soc_intel_is_cml()) { 261 /* 262 * use name prefix 'WL' and 'WR' for speaker widgets to 263 * keep backward compatible with cml devices 264 */ 265 card->codec_conf = rt1011_4spk_codec_confs; 266 } else { 267 card->codec_conf = rt1011_2spk_codec_confs; 268 } 269 270 card->num_configs = num_codecs; 271 break; 272 case 4: 273 card->codec_conf = rt1011_4spk_codec_confs; 274 card->num_configs = ARRAY_SIZE(rt1011_4spk_codec_confs); 275 break; 276 default: 277 dev_err(dev, "rt1011: invalid num_codecs %d\n", num_codecs); 278 break; 279 } 280 281 } 282 EXPORT_SYMBOL_NS(sof_rt1011_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON); 283 284 /* 285 * rt1015: i2c mode driver for ALC1015 and ALC1015Q 286 * rt1015p: auto-mode driver for ALC1015, ALC1015Q, and ALC1015Q-VB 287 * 288 * For stereo output, there are always two amplifiers on the board. 289 * However, the ACPI implements only one device instance (UID=0) if they 290 * are sharing the same enable pin. The code will detect the number of 291 * device instance and use corresponding DAPM structures for 292 * initialization. 293 */ 294 static const struct snd_soc_dapm_route rt1015p_1dev_dapm_routes[] = { 295 /* speaker */ 296 { "Left Spk", NULL, "Speaker" }, 297 { "Right Spk", NULL, "Speaker" }, 298 }; 299 300 static const struct snd_soc_dapm_route rt1015p_2dev_dapm_routes[] = { 301 /* speaker */ 302 { "Left Spk", NULL, "Left Speaker" }, 303 { "Right Spk", NULL, "Right Speaker" }, 304 }; 305 306 static struct snd_soc_codec_conf rt1015p_codec_confs[] = { 307 { 308 .dlc = COMP_CODEC_CONF(RT1015P_DEV0_NAME), 309 .name_prefix = "Left", 310 }, 311 { 312 .dlc = COMP_CODEC_CONF(RT1015P_DEV1_NAME), 313 .name_prefix = "Right", 314 }, 315 }; 316 317 static struct snd_soc_dai_link_component rt1015p_dai_link_components[] = { 318 { 319 .name = RT1015P_DEV0_NAME, 320 .dai_name = RT1015P_CODEC_DAI, 321 }, 322 { 323 .name = RT1015P_DEV1_NAME, 324 .dai_name = RT1015P_CODEC_DAI, 325 }, 326 }; 327 328 static int rt1015p_get_num_codecs(void) 329 { 330 static int dev_num; 331 332 if (dev_num) 333 return dev_num; 334 335 if (!acpi_dev_present("RTL1015", "1", -1)) 336 dev_num = 1; 337 else 338 dev_num = 2; 339 340 return dev_num; 341 } 342 343 static int rt1015p_hw_params(struct snd_pcm_substream *substream, 344 struct snd_pcm_hw_params *params) 345 { 346 /* reserved for debugging purpose */ 347 348 return 0; 349 } 350 351 static const struct snd_soc_ops rt1015p_ops = { 352 .hw_params = rt1015p_hw_params, 353 }; 354 355 static int rt1015p_init(struct snd_soc_pcm_runtime *rtd) 356 { 357 struct snd_soc_card *card = rtd->card; 358 int ret; 359 360 if (rt1015p_get_num_codecs() == 1) 361 ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_1dev_dapm_routes, 362 ARRAY_SIZE(rt1015p_1dev_dapm_routes)); 363 else 364 ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_2dev_dapm_routes, 365 ARRAY_SIZE(rt1015p_2dev_dapm_routes)); 366 if (ret) 367 dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); 368 return ret; 369 } 370 371 void sof_rt1015p_dai_link(struct snd_soc_dai_link *link) 372 { 373 link->codecs = rt1015p_dai_link_components; 374 link->num_codecs = rt1015p_get_num_codecs(); 375 link->init = rt1015p_init; 376 link->ops = &rt1015p_ops; 377 } 378 EXPORT_SYMBOL_NS(sof_rt1015p_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); 379 380 void sof_rt1015p_codec_conf(struct snd_soc_card *card) 381 { 382 if (rt1015p_get_num_codecs() == 1) 383 return; 384 385 card->codec_conf = rt1015p_codec_confs; 386 card->num_configs = ARRAY_SIZE(rt1015p_codec_confs); 387 } 388 EXPORT_SYMBOL_NS(sof_rt1015p_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON); 389 390 /* 391 * RT1015 audio amplifier 392 */ 393 394 static const struct { 395 unsigned int tx; 396 unsigned int rx; 397 } rt1015_tdm_mask[] = { 398 {.tx = 0x0, .rx = 0x1}, 399 {.tx = 0x0, .rx = 0x2}, 400 }; 401 402 static int rt1015_hw_params(struct snd_pcm_substream *substream, 403 struct snd_pcm_hw_params *params) 404 { 405 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 406 struct snd_soc_dai_link *dai_link = rtd->dai_link; 407 struct snd_soc_dai *codec_dai; 408 int i, clk_freq; 409 int ret = 0; 410 411 clk_freq = sof_dai_get_bclk(rtd); 412 413 if (clk_freq <= 0) { 414 dev_err(rtd->dev, "fail to get bclk freq, ret %d\n", clk_freq); 415 return -EINVAL; 416 } 417 418 for_each_rtd_codec_dais(rtd, i, codec_dai) { 419 ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, 420 clk_freq, 421 params_rate(params) * 256); 422 if (ret) { 423 dev_err(codec_dai->dev, "fail to set pll, ret %d\n", 424 ret); 425 return ret; 426 } 427 428 ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL, 429 params_rate(params) * 256, 430 SND_SOC_CLOCK_IN); 431 if (ret) { 432 dev_err(codec_dai->dev, "fail to set sysclk, ret %d\n", 433 ret); 434 return ret; 435 } 436 437 switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 438 case SND_SOC_DAIFMT_DSP_A: 439 case SND_SOC_DAIFMT_DSP_B: 440 /* 4-slot TDM */ 441 ret = snd_soc_dai_set_tdm_slot(codec_dai, 442 rt1015_tdm_mask[i].tx, 443 rt1015_tdm_mask[i].rx, 444 4, 445 params_width(params)); 446 if (ret < 0) { 447 dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n", 448 ret); 449 return ret; 450 } 451 break; 452 default: 453 dev_dbg(codec_dai->dev, "codec is in I2S mode\n"); 454 break; 455 } 456 } 457 458 return ret; 459 } 460 461 static struct snd_soc_ops rt1015_ops = { 462 .hw_params = rt1015_hw_params, 463 }; 464 465 static struct snd_soc_codec_conf rt1015_amp_conf[] = { 466 { 467 .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME), 468 .name_prefix = "Left", 469 }, 470 { 471 .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME), 472 .name_prefix = "Right", 473 }, 474 }; 475 476 static struct snd_soc_dai_link_component rt1015_components[] = { 477 { 478 .name = RT1015_DEV0_NAME, 479 .dai_name = RT1015_CODEC_DAI, 480 }, 481 { 482 .name = RT1015_DEV1_NAME, 483 .dai_name = RT1015_CODEC_DAI, 484 }, 485 }; 486 487 static int speaker_codec_init_lr(struct snd_soc_pcm_runtime *rtd) 488 { 489 return snd_soc_dapm_add_routes(&rtd->card->dapm, speaker_map_lr, 490 ARRAY_SIZE(speaker_map_lr)); 491 } 492 493 void sof_rt1015_codec_conf(struct snd_soc_card *card) 494 { 495 card->codec_conf = rt1015_amp_conf; 496 card->num_configs = ARRAY_SIZE(rt1015_amp_conf); 497 } 498 EXPORT_SYMBOL_NS(sof_rt1015_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON); 499 500 void sof_rt1015_dai_link(struct snd_soc_dai_link *link) 501 { 502 link->codecs = rt1015_components; 503 link->num_codecs = ARRAY_SIZE(rt1015_components); 504 link->init = speaker_codec_init_lr; 505 link->ops = &rt1015_ops; 506 } 507 EXPORT_SYMBOL_NS(sof_rt1015_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); 508 509 /* 510 * RT1308 audio amplifier 511 */ 512 static const struct snd_kcontrol_new rt1308_kcontrols[] = { 513 SOC_DAPM_PIN_SWITCH("Speakers"), 514 }; 515 516 static const struct snd_soc_dapm_widget rt1308_dapm_widgets[] = { 517 SND_SOC_DAPM_SPK("Speakers", NULL), 518 }; 519 520 static const struct snd_soc_dapm_route rt1308_dapm_routes[] = { 521 /* speaker */ 522 {"Speakers", NULL, "SPOL"}, 523 {"Speakers", NULL, "SPOR"}, 524 }; 525 526 static struct snd_soc_dai_link_component rt1308_components[] = { 527 { 528 .name = RT1308_DEV0_NAME, 529 .dai_name = RT1308_CODEC_DAI, 530 } 531 }; 532 533 static int rt1308_init(struct snd_soc_pcm_runtime *rtd) 534 { 535 struct snd_soc_card *card = rtd->card; 536 int ret; 537 538 ret = snd_soc_dapm_new_controls(&card->dapm, rt1308_dapm_widgets, 539 ARRAY_SIZE(rt1308_dapm_widgets)); 540 if (ret) { 541 dev_err(rtd->dev, "fail to add dapm controls, ret %d\n", ret); 542 return ret; 543 } 544 545 ret = snd_soc_add_card_controls(card, rt1308_kcontrols, 546 ARRAY_SIZE(rt1308_kcontrols)); 547 if (ret) { 548 dev_err(rtd->dev, "fail to add card controls, ret %d\n", ret); 549 return ret; 550 } 551 552 ret = snd_soc_dapm_add_routes(&card->dapm, rt1308_dapm_routes, 553 ARRAY_SIZE(rt1308_dapm_routes)); 554 555 if (ret) 556 dev_err(rtd->dev, "fail to add dapm routes, ret %d\n", ret); 557 558 return ret; 559 } 560 561 static int rt1308_hw_params(struct snd_pcm_substream *substream, 562 struct snd_pcm_hw_params *params) 563 { 564 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 565 struct snd_soc_card *card = rtd->card; 566 struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); 567 int clk_id, clk_freq, pll_out; 568 int ret; 569 570 clk_id = RT1308_PLL_S_MCLK; 571 /* get the tplg configured mclk. */ 572 clk_freq = sof_dai_get_mclk(rtd); 573 574 pll_out = params_rate(params) * 512; 575 576 /* Set rt1308 pll */ 577 ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out); 578 if (ret < 0) { 579 dev_err(card->dev, "Failed to set RT1308 PLL: %d\n", ret); 580 return ret; 581 } 582 583 /* Set rt1308 sysclk */ 584 ret = snd_soc_dai_set_sysclk(codec_dai, RT1308_FS_SYS_S_PLL, pll_out, 585 SND_SOC_CLOCK_IN); 586 if (ret < 0) 587 dev_err(card->dev, "Failed to set RT1308 SYSCLK: %d\n", ret); 588 589 return ret; 590 } 591 592 static const struct snd_soc_ops rt1308_ops = { 593 .hw_params = rt1308_hw_params, 594 }; 595 596 void sof_rt1308_dai_link(struct snd_soc_dai_link *link) 597 { 598 link->codecs = rt1308_components; 599 link->num_codecs = ARRAY_SIZE(rt1308_components); 600 link->init = rt1308_init; 601 link->ops = &rt1308_ops; 602 } 603 EXPORT_SYMBOL_NS(sof_rt1308_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); 604 605 /* 606 * 2-amp Configuration for RT1019 607 */ 608 609 static const struct snd_soc_dapm_route rt1019p_dapm_routes[] = { 610 /* speaker */ 611 { "Left Spk", NULL, "Speaker" }, 612 { "Right Spk", NULL, "Speaker" }, 613 }; 614 615 static struct snd_soc_dai_link_component rt1019p_components[] = { 616 { 617 .name = RT1019P_DEV0_NAME, 618 .dai_name = RT1019P_CODEC_DAI, 619 }, 620 }; 621 622 static int rt1019p_init(struct snd_soc_pcm_runtime *rtd) 623 { 624 struct snd_soc_card *card = rtd->card; 625 int ret; 626 627 ret = snd_soc_dapm_add_routes(&card->dapm, rt1019p_dapm_routes, 628 ARRAY_SIZE(rt1019p_dapm_routes)); 629 if (ret) { 630 dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); 631 return ret; 632 } 633 return ret; 634 } 635 636 void sof_rt1019p_dai_link(struct snd_soc_dai_link *link) 637 { 638 link->codecs = rt1019p_components; 639 link->num_codecs = ARRAY_SIZE(rt1019p_components); 640 link->init = rt1019p_init; 641 } 642 EXPORT_SYMBOL_NS(sof_rt1019p_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); 643 644 MODULE_DESCRIPTION("ASoC Intel SOF Realtek helpers"); 645 MODULE_LICENSE("GPL"); 646