1 // SPDX-License-Identifier: GPL-2.0-only 2 // Copyright(c) 2019-2020 Intel Corporation. 3 4 /* 5 * Intel SOF Machine Driver with Realtek rt5682 Codec 6 * and speaker codec MAX98357A or RT1015. 7 */ 8 #include <linux/i2c.h> 9 #include <linux/input.h> 10 #include <linux/module.h> 11 #include <linux/platform_device.h> 12 #include <linux/clk.h> 13 #include <linux/dmi.h> 14 #include <sound/core.h> 15 #include <sound/jack.h> 16 #include <sound/pcm.h> 17 #include <sound/pcm_params.h> 18 #include <sound/soc.h> 19 #include <sound/sof.h> 20 #include <sound/rt5682.h> 21 #include <sound/soc-acpi.h> 22 #include "../../codecs/rt1015.h" 23 #include "../../codecs/rt5682.h" 24 #include "../../codecs/hdac_hdmi.h" 25 #include "../common/soc-intel-quirks.h" 26 #include "hda_dsp_common.h" 27 #include "sof_maxim_common.h" 28 #include "sof_realtek_common.h" 29 30 #define NAME_SIZE 32 31 32 #define SOF_RT5682_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0)) 33 #define SOF_RT5682_SSP_CODEC_MASK (GENMASK(2, 0)) 34 #define SOF_RT5682_MCLK_EN BIT(3) 35 #define SOF_RT5682_MCLK_24MHZ BIT(4) 36 #define SOF_SPEAKER_AMP_PRESENT BIT(5) 37 #define SOF_RT5682_SSP_AMP_SHIFT 6 38 #define SOF_RT5682_SSP_AMP_MASK (GENMASK(8, 6)) 39 #define SOF_RT5682_SSP_AMP(quirk) \ 40 (((quirk) << SOF_RT5682_SSP_AMP_SHIFT) & SOF_RT5682_SSP_AMP_MASK) 41 #define SOF_RT5682_MCLK_BYTCHT_EN BIT(9) 42 #define SOF_RT5682_NUM_HDMIDEV_SHIFT 10 43 #define SOF_RT5682_NUM_HDMIDEV_MASK (GENMASK(12, 10)) 44 #define SOF_RT5682_NUM_HDMIDEV(quirk) \ 45 ((quirk << SOF_RT5682_NUM_HDMIDEV_SHIFT) & SOF_RT5682_NUM_HDMIDEV_MASK) 46 #define SOF_RT1011_SPEAKER_AMP_PRESENT BIT(13) 47 #define SOF_RT1015_SPEAKER_AMP_PRESENT BIT(14) 48 #define SOF_RT1015_SPEAKER_AMP_100FS BIT(15) 49 #define SOF_RT1015P_SPEAKER_AMP_PRESENT BIT(16) 50 #define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(17) 51 #define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(18) 52 53 /* BT audio offload: reserve 3 bits for future */ 54 #define SOF_BT_OFFLOAD_SSP_SHIFT 19 55 #define SOF_BT_OFFLOAD_SSP_MASK (GENMASK(21, 19)) 56 #define SOF_BT_OFFLOAD_SSP(quirk) \ 57 (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK) 58 #define SOF_SSP_BT_OFFLOAD_PRESENT BIT(22) 59 60 /* Default: MCLK on, MCLK 19.2M, SSP0 */ 61 static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN | 62 SOF_RT5682_SSP_CODEC(0); 63 64 static int is_legacy_cpu; 65 66 static struct snd_soc_jack sof_hdmi[3]; 67 68 struct sof_hdmi_pcm { 69 struct list_head head; 70 struct snd_soc_dai *codec_dai; 71 int device; 72 }; 73 74 struct sof_card_private { 75 struct clk *mclk; 76 struct snd_soc_jack sof_headset; 77 struct list_head hdmi_pcm_list; 78 bool common_hdmi_codec_drv; 79 }; 80 81 static int sof_rt5682_quirk_cb(const struct dmi_system_id *id) 82 { 83 sof_rt5682_quirk = (unsigned long)id->driver_data; 84 return 1; 85 } 86 87 static const struct dmi_system_id sof_rt5682_quirk_table[] = { 88 { 89 .callback = sof_rt5682_quirk_cb, 90 .matches = { 91 DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"), 92 DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max"), 93 }, 94 .driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)), 95 }, 96 { 97 .callback = sof_rt5682_quirk_cb, 98 .matches = { 99 DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), 100 DMI_MATCH(DMI_PRODUCT_NAME, "UP-CHT01"), 101 }, 102 .driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)), 103 }, 104 { 105 .callback = sof_rt5682_quirk_cb, 106 .matches = { 107 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 108 DMI_MATCH(DMI_PRODUCT_NAME, "WhiskeyLake Client"), 109 }, 110 .driver_data = (void *)(SOF_RT5682_MCLK_EN | 111 SOF_RT5682_MCLK_24MHZ | 112 SOF_RT5682_SSP_CODEC(1)), 113 }, 114 { 115 /* 116 * Dooly is hatch family but using rt1015 amp so it 117 * requires a quirk before "Google_Hatch". 118 */ 119 .callback = sof_rt5682_quirk_cb, 120 .matches = { 121 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 122 DMI_MATCH(DMI_PRODUCT_NAME, "Dooly"), 123 }, 124 .driver_data = (void *)(SOF_RT5682_MCLK_EN | 125 SOF_RT5682_MCLK_24MHZ | 126 SOF_RT5682_SSP_CODEC(0) | 127 SOF_SPEAKER_AMP_PRESENT | 128 SOF_RT1015_SPEAKER_AMP_PRESENT | 129 SOF_RT1015_SPEAKER_AMP_100FS | 130 SOF_RT5682_SSP_AMP(1)), 131 }, 132 { 133 .callback = sof_rt5682_quirk_cb, 134 .matches = { 135 DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Hatch"), 136 }, 137 .driver_data = (void *)(SOF_RT5682_MCLK_EN | 138 SOF_RT5682_MCLK_24MHZ | 139 SOF_RT5682_SSP_CODEC(0) | 140 SOF_SPEAKER_AMP_PRESENT | 141 SOF_RT5682_SSP_AMP(1)), 142 }, 143 { 144 .callback = sof_rt5682_quirk_cb, 145 .matches = { 146 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 147 DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"), 148 }, 149 .driver_data = (void *)(SOF_RT5682_MCLK_EN | 150 SOF_RT5682_SSP_CODEC(0)), 151 }, 152 { 153 .callback = sof_rt5682_quirk_cb, 154 .matches = { 155 DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Volteer"), 156 DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98373_ALC5682I_I2S_UP4"), 157 }, 158 .driver_data = (void *)(SOF_RT5682_MCLK_EN | 159 SOF_RT5682_SSP_CODEC(0) | 160 SOF_SPEAKER_AMP_PRESENT | 161 SOF_MAX98373_SPEAKER_AMP_PRESENT | 162 SOF_RT5682_SSP_AMP(2) | 163 SOF_RT5682_NUM_HDMIDEV(4)), 164 }, 165 { 166 .callback = sof_rt5682_quirk_cb, 167 .matches = { 168 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 169 DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"), 170 DMI_MATCH(DMI_OEM_STRING, "AUDIO-ADL_MAX98373_ALC5682I_I2S"), 171 }, 172 .driver_data = (void *)(SOF_RT5682_MCLK_EN | 173 SOF_RT5682_SSP_CODEC(0) | 174 SOF_SPEAKER_AMP_PRESENT | 175 SOF_MAX98373_SPEAKER_AMP_PRESENT | 176 SOF_RT5682_SSP_AMP(2) | 177 SOF_RT5682_NUM_HDMIDEV(4)), 178 }, 179 {} 180 }; 181 182 static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) 183 { 184 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 185 struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 186 struct sof_hdmi_pcm *pcm; 187 188 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); 189 if (!pcm) 190 return -ENOMEM; 191 192 /* dai_link id is 1:1 mapped to the PCM device */ 193 pcm->device = rtd->dai_link->id; 194 pcm->codec_dai = dai; 195 196 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); 197 198 return 0; 199 } 200 201 static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) 202 { 203 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 204 struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 205 struct snd_soc_jack *jack; 206 int ret; 207 208 /* need to enable ASRC function for 24MHz mclk rate */ 209 if ((sof_rt5682_quirk & SOF_RT5682_MCLK_EN) && 210 (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ)) { 211 rt5682_sel_asrc_clk_src(component, RT5682_DA_STEREO1_FILTER | 212 RT5682_AD_STEREO1_FILTER, 213 RT5682_CLK_SEL_I2S1_ASRC); 214 } 215 216 if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { 217 /* 218 * The firmware might enable the clock at 219 * boot (this information may or may not 220 * be reflected in the enable clock register). 221 * To change the rate we must disable the clock 222 * first to cover these cases. Due to common 223 * clock framework restrictions that do not allow 224 * to disable a clock that has not been enabled, 225 * we need to enable the clock first. 226 */ 227 ret = clk_prepare_enable(ctx->mclk); 228 if (!ret) 229 clk_disable_unprepare(ctx->mclk); 230 231 ret = clk_set_rate(ctx->mclk, 19200000); 232 233 if (ret) 234 dev_err(rtd->dev, "unable to set MCLK rate\n"); 235 } 236 237 /* 238 * Headset buttons map to the google Reference headset. 239 * These can be configured by userspace. 240 */ 241 ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", 242 SND_JACK_HEADSET | SND_JACK_BTN_0 | 243 SND_JACK_BTN_1 | SND_JACK_BTN_2 | 244 SND_JACK_BTN_3, 245 &ctx->sof_headset, NULL, 0); 246 if (ret) { 247 dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); 248 return ret; 249 } 250 251 jack = &ctx->sof_headset; 252 253 snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 254 snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); 255 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); 256 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); 257 ret = snd_soc_component_set_jack(component, jack, NULL); 258 259 if (ret) { 260 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); 261 return ret; 262 } 263 264 return ret; 265 }; 266 267 static void sof_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd) 268 { 269 struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 270 271 snd_soc_component_set_jack(component, NULL, NULL); 272 } 273 274 static int sof_rt5682_hw_params(struct snd_pcm_substream *substream, 275 struct snd_pcm_hw_params *params) 276 { 277 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 278 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 279 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 280 int clk_id, clk_freq, pll_out, ret; 281 282 if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) { 283 if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { 284 ret = clk_prepare_enable(ctx->mclk); 285 if (ret < 0) { 286 dev_err(rtd->dev, 287 "could not configure MCLK state"); 288 return ret; 289 } 290 } 291 292 clk_id = RT5682_PLL1_S_MCLK; 293 294 /* get the tplg configured mclk. */ 295 clk_freq = sof_dai_get_mclk(rtd); 296 297 /* mclk from the quirk is the first choice */ 298 if (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ) { 299 if (clk_freq != 24000000) 300 dev_warn(rtd->dev, "configure wrong mclk in tplg, please use 24MHz.\n"); 301 clk_freq = 24000000; 302 } else if (clk_freq == 0) { 303 /* use default mclk if not specified correct in topology */ 304 clk_freq = 19200000; 305 } else if (clk_freq < 0) { 306 return clk_freq; 307 } 308 } else { 309 clk_id = RT5682_PLL1_S_BCLK1; 310 clk_freq = params_rate(params) * 50; 311 } 312 313 pll_out = params_rate(params) * 512; 314 315 ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out); 316 if (ret < 0) 317 dev_err(rtd->dev, "snd_soc_dai_set_pll err = %d\n", ret); 318 319 /* Configure sysclk for codec */ 320 ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1, 321 pll_out, SND_SOC_CLOCK_IN); 322 if (ret < 0) 323 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); 324 325 /* 326 * slot_width should equal or large than data length, set them 327 * be the same 328 */ 329 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0, 0x0, 2, 330 params_width(params)); 331 if (ret < 0) { 332 dev_err(rtd->dev, "set TDM slot err:%d\n", ret); 333 return ret; 334 } 335 336 return ret; 337 } 338 339 static struct snd_soc_ops sof_rt5682_ops = { 340 .hw_params = sof_rt5682_hw_params, 341 }; 342 343 static int sof_rt1015_hw_params(struct snd_pcm_substream *substream, 344 struct snd_pcm_hw_params *params) 345 { 346 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 347 struct snd_soc_card *card = rtd->card; 348 struct snd_soc_dai *codec_dai; 349 int i, fs, ret; 350 351 if (!snd_soc_card_get_codec_dai(card, "rt1015-aif")) 352 return 0; 353 354 if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_100FS) 355 fs = 100; 356 else 357 fs = 64; 358 359 for_each_rtd_codec_dais(rtd, i, codec_dai) { 360 ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, 361 params_rate(params) * fs, 362 params_rate(params) * 256); 363 if (ret < 0) { 364 dev_err(card->dev, "failed to set pll\n"); 365 return ret; 366 } 367 /* Configure sysclk for codec */ 368 ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL, 369 params_rate(params) * 256, 370 SND_SOC_CLOCK_IN); 371 if (ret < 0) { 372 dev_err(card->dev, "failed to set sysclk\n"); 373 return ret; 374 } 375 376 if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_100FS) { 377 if (!strcmp(codec_dai->component->name, "i2c-10EC1015:00")) { 378 ret = snd_soc_dai_set_tdm_slot(codec_dai, 379 0x0, 0x1, 4, 24); 380 if (ret < 0) { 381 dev_err(card->dev, "failed to set tdm slot\n"); 382 return ret; 383 } 384 } 385 386 if (!strcmp(codec_dai->component->name, "i2c-10EC1015:01")) { 387 ret = snd_soc_dai_set_tdm_slot(codec_dai, 388 0x0, 0x2, 4, 24); 389 if (ret < 0) { 390 dev_err(card->dev, "failed to set tdm slot\n"); 391 return ret; 392 } 393 } 394 } 395 } 396 397 return 0; 398 } 399 400 static struct snd_soc_ops sof_rt1015_ops = { 401 .hw_params = sof_rt1015_hw_params, 402 }; 403 404 static struct snd_soc_dai_link_component platform_component[] = { 405 { 406 /* name might be overridden during probe */ 407 .name = "0000:00:1f.3" 408 } 409 }; 410 411 static int sof_card_late_probe(struct snd_soc_card *card) 412 { 413 struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); 414 struct snd_soc_component *component = NULL; 415 struct snd_soc_dapm_context *dapm = &card->dapm; 416 char jack_name[NAME_SIZE]; 417 struct sof_hdmi_pcm *pcm; 418 int err; 419 int i = 0; 420 421 /* HDMI is not supported by SOF on Baytrail/CherryTrail */ 422 if (is_legacy_cpu) 423 return 0; 424 425 if (list_empty(&ctx->hdmi_pcm_list)) 426 return -EINVAL; 427 428 if (ctx->common_hdmi_codec_drv) { 429 pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm, 430 head); 431 component = pcm->codec_dai->component; 432 return hda_dsp_hdmi_build_controls(card, component); 433 } 434 435 list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { 436 component = pcm->codec_dai->component; 437 snprintf(jack_name, sizeof(jack_name), 438 "HDMI/DP, pcm=%d Jack", pcm->device); 439 err = snd_soc_card_jack_new(card, jack_name, 440 SND_JACK_AVOUT, &sof_hdmi[i], 441 NULL, 0); 442 443 if (err) 444 return err; 445 446 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, 447 &sof_hdmi[i]); 448 if (err < 0) 449 return err; 450 451 i++; 452 } 453 454 if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) { 455 /* Disable Left and Right Spk pin after boot */ 456 snd_soc_dapm_disable_pin(dapm, "Left Spk"); 457 snd_soc_dapm_disable_pin(dapm, "Right Spk"); 458 err = snd_soc_dapm_sync(dapm); 459 if (err < 0) 460 return err; 461 } 462 return hdac_hdmi_jack_port_init(component, &card->dapm); 463 } 464 465 static const struct snd_kcontrol_new sof_controls[] = { 466 SOC_DAPM_PIN_SWITCH("Headphone Jack"), 467 SOC_DAPM_PIN_SWITCH("Headset Mic"), 468 SOC_DAPM_PIN_SWITCH("Left Spk"), 469 SOC_DAPM_PIN_SWITCH("Right Spk"), 470 471 }; 472 473 static const struct snd_soc_dapm_widget sof_widgets[] = { 474 SND_SOC_DAPM_HP("Headphone Jack", NULL), 475 SND_SOC_DAPM_MIC("Headset Mic", NULL), 476 SND_SOC_DAPM_SPK("Left Spk", NULL), 477 SND_SOC_DAPM_SPK("Right Spk", NULL), 478 }; 479 480 static const struct snd_soc_dapm_widget dmic_widgets[] = { 481 SND_SOC_DAPM_MIC("SoC DMIC", NULL), 482 }; 483 484 static const struct snd_soc_dapm_route sof_map[] = { 485 /* HP jack connectors - unknown if we have jack detection */ 486 { "Headphone Jack", NULL, "HPOL" }, 487 { "Headphone Jack", NULL, "HPOR" }, 488 489 /* other jacks */ 490 { "IN1P", NULL, "Headset Mic" }, 491 }; 492 493 static const struct snd_soc_dapm_route speaker_map_lr[] = { 494 { "Left Spk", NULL, "Left SPO" }, 495 { "Right Spk", NULL, "Right SPO" }, 496 }; 497 498 static const struct snd_soc_dapm_route dmic_map[] = { 499 /* digital mics */ 500 {"DMic", NULL, "SoC DMIC"}, 501 }; 502 503 static int speaker_codec_init_lr(struct snd_soc_pcm_runtime *rtd) 504 { 505 return snd_soc_dapm_add_routes(&rtd->card->dapm, speaker_map_lr, 506 ARRAY_SIZE(speaker_map_lr)); 507 } 508 509 static int dmic_init(struct snd_soc_pcm_runtime *rtd) 510 { 511 struct snd_soc_card *card = rtd->card; 512 int ret; 513 514 ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, 515 ARRAY_SIZE(dmic_widgets)); 516 if (ret) { 517 dev_err(card->dev, "DMic widget addition failed: %d\n", ret); 518 /* Don't need to add routes if widget addition failed */ 519 return ret; 520 } 521 522 ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, 523 ARRAY_SIZE(dmic_map)); 524 525 if (ret) 526 dev_err(card->dev, "DMic map addition failed: %d\n", ret); 527 528 return ret; 529 } 530 531 static struct snd_soc_codec_conf rt1015_amp_conf[] = { 532 { 533 .dlc = COMP_CODEC_CONF("i2c-10EC1015:00"), 534 .name_prefix = "Left", 535 }, 536 { 537 .dlc = COMP_CODEC_CONF("i2c-10EC1015:01"), 538 .name_prefix = "Right", 539 }, 540 }; 541 542 /* sof audio machine driver for rt5682 codec */ 543 static struct snd_soc_card sof_audio_card_rt5682 = { 544 .name = "rt5682", /* the sof- prefix is added by the core */ 545 .owner = THIS_MODULE, 546 .controls = sof_controls, 547 .num_controls = ARRAY_SIZE(sof_controls), 548 .dapm_widgets = sof_widgets, 549 .num_dapm_widgets = ARRAY_SIZE(sof_widgets), 550 .dapm_routes = sof_map, 551 .num_dapm_routes = ARRAY_SIZE(sof_map), 552 .fully_routed = true, 553 .late_probe = sof_card_late_probe, 554 }; 555 556 static struct snd_soc_dai_link_component rt5682_component[] = { 557 { 558 .name = "i2c-10EC5682:00", 559 .dai_name = "rt5682-aif1", 560 } 561 }; 562 563 static struct snd_soc_dai_link_component dmic_component[] = { 564 { 565 .name = "dmic-codec", 566 .dai_name = "dmic-hifi", 567 } 568 }; 569 570 static struct snd_soc_dai_link_component rt1015_components[] = { 571 { 572 .name = "i2c-10EC1015:00", 573 .dai_name = "rt1015-aif", 574 }, 575 { 576 .name = "i2c-10EC1015:01", 577 .dai_name = "rt1015-aif", 578 }, 579 }; 580 581 static struct snd_soc_dai_link_component dummy_component[] = { 582 { 583 .name = "snd-soc-dummy", 584 .dai_name = "snd-soc-dummy-dai", 585 } 586 }; 587 588 static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, 589 int ssp_codec, 590 int ssp_amp, 591 int dmic_be_num, 592 int hdmi_num) 593 { 594 struct snd_soc_dai_link_component *idisp_components; 595 struct snd_soc_dai_link_component *cpus; 596 struct snd_soc_dai_link *links; 597 int i, id = 0; 598 599 links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) * 600 sof_audio_card_rt5682.num_links, GFP_KERNEL); 601 cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component) * 602 sof_audio_card_rt5682.num_links, GFP_KERNEL); 603 if (!links || !cpus) 604 goto devm_err; 605 606 /* codec SSP */ 607 links[id].name = devm_kasprintf(dev, GFP_KERNEL, 608 "SSP%d-Codec", ssp_codec); 609 if (!links[id].name) 610 goto devm_err; 611 612 links[id].id = id; 613 links[id].codecs = rt5682_component; 614 links[id].num_codecs = ARRAY_SIZE(rt5682_component); 615 links[id].platforms = platform_component; 616 links[id].num_platforms = ARRAY_SIZE(platform_component); 617 links[id].init = sof_rt5682_codec_init; 618 links[id].exit = sof_rt5682_codec_exit; 619 links[id].ops = &sof_rt5682_ops; 620 links[id].dpcm_playback = 1; 621 links[id].dpcm_capture = 1; 622 links[id].no_pcm = 1; 623 links[id].cpus = &cpus[id]; 624 links[id].num_cpus = 1; 625 if (is_legacy_cpu) { 626 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, 627 "ssp%d-port", 628 ssp_codec); 629 if (!links[id].cpus->dai_name) 630 goto devm_err; 631 } else { 632 /* 633 * Currently, On SKL+ platforms MCLK will be turned off in sof 634 * runtime suspended, and it will go into runtime suspended 635 * right after playback is stop. However, rt5682 will output 636 * static noise if sysclk turns off during playback. Set 637 * ignore_pmdown_time to power down rt5682 immediately and 638 * avoid the noise. 639 * It can be removed once we can control MCLK by driver. 640 */ 641 links[id].ignore_pmdown_time = 1; 642 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, 643 "SSP%d Pin", 644 ssp_codec); 645 if (!links[id].cpus->dai_name) 646 goto devm_err; 647 } 648 id++; 649 650 /* dmic */ 651 if (dmic_be_num > 0) { 652 /* at least we have dmic01 */ 653 links[id].name = "dmic01"; 654 links[id].cpus = &cpus[id]; 655 links[id].cpus->dai_name = "DMIC01 Pin"; 656 links[id].init = dmic_init; 657 if (dmic_be_num > 1) { 658 /* set up 2 BE links at most */ 659 links[id + 1].name = "dmic16k"; 660 links[id + 1].cpus = &cpus[id + 1]; 661 links[id + 1].cpus->dai_name = "DMIC16k Pin"; 662 dmic_be_num = 2; 663 } 664 } 665 666 for (i = 0; i < dmic_be_num; i++) { 667 links[id].id = id; 668 links[id].num_cpus = 1; 669 links[id].codecs = dmic_component; 670 links[id].num_codecs = ARRAY_SIZE(dmic_component); 671 links[id].platforms = platform_component; 672 links[id].num_platforms = ARRAY_SIZE(platform_component); 673 links[id].ignore_suspend = 1; 674 links[id].dpcm_capture = 1; 675 links[id].no_pcm = 1; 676 id++; 677 } 678 679 /* HDMI */ 680 if (hdmi_num > 0) { 681 idisp_components = devm_kzalloc(dev, 682 sizeof(struct snd_soc_dai_link_component) * 683 hdmi_num, GFP_KERNEL); 684 if (!idisp_components) 685 goto devm_err; 686 } 687 for (i = 1; i <= hdmi_num; i++) { 688 links[id].name = devm_kasprintf(dev, GFP_KERNEL, 689 "iDisp%d", i); 690 if (!links[id].name) 691 goto devm_err; 692 693 links[id].id = id; 694 links[id].cpus = &cpus[id]; 695 links[id].num_cpus = 1; 696 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, 697 "iDisp%d Pin", i); 698 if (!links[id].cpus->dai_name) 699 goto devm_err; 700 701 idisp_components[i - 1].name = "ehdaudio0D2"; 702 idisp_components[i - 1].dai_name = devm_kasprintf(dev, 703 GFP_KERNEL, 704 "intel-hdmi-hifi%d", 705 i); 706 if (!idisp_components[i - 1].dai_name) 707 goto devm_err; 708 709 links[id].codecs = &idisp_components[i - 1]; 710 links[id].num_codecs = 1; 711 links[id].platforms = platform_component; 712 links[id].num_platforms = ARRAY_SIZE(platform_component); 713 links[id].init = sof_hdmi_init; 714 links[id].dpcm_playback = 1; 715 links[id].no_pcm = 1; 716 id++; 717 } 718 719 /* speaker amp */ 720 if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) { 721 links[id].name = devm_kasprintf(dev, GFP_KERNEL, 722 "SSP%d-Codec", ssp_amp); 723 if (!links[id].name) 724 goto devm_err; 725 726 links[id].id = id; 727 if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_PRESENT) { 728 links[id].codecs = rt1015_components; 729 links[id].num_codecs = ARRAY_SIZE(rt1015_components); 730 links[id].init = speaker_codec_init_lr; 731 links[id].ops = &sof_rt1015_ops; 732 } else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) { 733 sof_rt1015p_dai_link(&links[id]); 734 } else if (sof_rt5682_quirk & 735 SOF_MAX98373_SPEAKER_AMP_PRESENT) { 736 links[id].codecs = max_98373_components; 737 links[id].num_codecs = ARRAY_SIZE(max_98373_components); 738 links[id].init = max_98373_spk_codec_init; 739 links[id].ops = &max_98373_ops; 740 /* feedback stream */ 741 links[id].dpcm_capture = 1; 742 } else if (sof_rt5682_quirk & 743 SOF_MAX98360A_SPEAKER_AMP_PRESENT) { 744 max_98360a_dai_link(&links[id]); 745 } else if (sof_rt5682_quirk & 746 SOF_RT1011_SPEAKER_AMP_PRESENT) { 747 sof_rt1011_dai_link(&links[id]); 748 } else { 749 max_98357a_dai_link(&links[id]); 750 } 751 links[id].platforms = platform_component; 752 links[id].num_platforms = ARRAY_SIZE(platform_component); 753 links[id].dpcm_playback = 1; 754 links[id].no_pcm = 1; 755 links[id].cpus = &cpus[id]; 756 links[id].num_cpus = 1; 757 if (is_legacy_cpu) { 758 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, 759 "ssp%d-port", 760 ssp_amp); 761 if (!links[id].cpus->dai_name) 762 goto devm_err; 763 764 } else { 765 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, 766 "SSP%d Pin", 767 ssp_amp); 768 if (!links[id].cpus->dai_name) 769 goto devm_err; 770 } 771 id++; 772 } 773 774 /* BT audio offload */ 775 if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) { 776 int port = (sof_rt5682_quirk & SOF_BT_OFFLOAD_SSP_MASK) >> 777 SOF_BT_OFFLOAD_SSP_SHIFT; 778 779 links[id].id = id; 780 links[id].cpus = &cpus[id]; 781 links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, 782 "SSP%d Pin", port); 783 if (!links[id].cpus->dai_name) 784 goto devm_err; 785 links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); 786 if (!links[id].name) 787 goto devm_err; 788 links[id].codecs = dummy_component; 789 links[id].num_codecs = ARRAY_SIZE(dummy_component); 790 links[id].platforms = platform_component; 791 links[id].num_platforms = ARRAY_SIZE(platform_component); 792 links[id].dpcm_playback = 1; 793 links[id].dpcm_capture = 1; 794 links[id].no_pcm = 1; 795 links[id].num_cpus = 1; 796 } 797 798 return links; 799 devm_err: 800 return NULL; 801 } 802 803 static int sof_audio_probe(struct platform_device *pdev) 804 { 805 struct snd_soc_dai_link *dai_links; 806 struct snd_soc_acpi_mach *mach; 807 struct sof_card_private *ctx; 808 int dmic_be_num, hdmi_num; 809 int ret, ssp_amp, ssp_codec; 810 811 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 812 if (!ctx) 813 return -ENOMEM; 814 815 if (pdev->id_entry && pdev->id_entry->driver_data) 816 sof_rt5682_quirk = (unsigned long)pdev->id_entry->driver_data; 817 818 dmi_check_system(sof_rt5682_quirk_table); 819 820 mach = pdev->dev.platform_data; 821 822 /* A speaker amp might not be present when the quirk claims one is. 823 * Detect this via whether the machine driver match includes quirk_data. 824 */ 825 if ((sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) && !mach->quirk_data) 826 sof_rt5682_quirk &= ~SOF_SPEAKER_AMP_PRESENT; 827 828 if (soc_intel_is_byt() || soc_intel_is_cht()) { 829 is_legacy_cpu = 1; 830 dmic_be_num = 0; 831 hdmi_num = 0; 832 /* default quirk for legacy cpu */ 833 sof_rt5682_quirk = SOF_RT5682_MCLK_EN | 834 SOF_RT5682_MCLK_BYTCHT_EN | 835 SOF_RT5682_SSP_CODEC(2); 836 } else { 837 dmic_be_num = 2; 838 hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >> 839 SOF_RT5682_NUM_HDMIDEV_SHIFT; 840 /* default number of HDMI DAI's */ 841 if (!hdmi_num) 842 hdmi_num = 3; 843 } 844 845 /* need to get main clock from pmc */ 846 if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { 847 ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); 848 if (IS_ERR(ctx->mclk)) { 849 ret = PTR_ERR(ctx->mclk); 850 851 dev_err(&pdev->dev, 852 "Failed to get MCLK from pmc_plt_clk_3: %d\n", 853 ret); 854 return ret; 855 } 856 857 ret = clk_prepare_enable(ctx->mclk); 858 if (ret < 0) { 859 dev_err(&pdev->dev, 860 "could not configure MCLK state"); 861 return ret; 862 } 863 } 864 865 dev_dbg(&pdev->dev, "sof_rt5682_quirk = %lx\n", sof_rt5682_quirk); 866 867 ssp_amp = (sof_rt5682_quirk & SOF_RT5682_SSP_AMP_MASK) >> 868 SOF_RT5682_SSP_AMP_SHIFT; 869 870 ssp_codec = sof_rt5682_quirk & SOF_RT5682_SSP_CODEC_MASK; 871 872 /* compute number of dai links */ 873 sof_audio_card_rt5682.num_links = 1 + dmic_be_num + hdmi_num; 874 875 if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) 876 sof_audio_card_rt5682.num_links++; 877 878 if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) 879 max_98373_set_codec_conf(&sof_audio_card_rt5682); 880 else if (sof_rt5682_quirk & SOF_RT1011_SPEAKER_AMP_PRESENT) 881 sof_rt1011_codec_conf(&sof_audio_card_rt5682); 882 else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) 883 sof_rt1015p_codec_conf(&sof_audio_card_rt5682); 884 885 if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) 886 sof_audio_card_rt5682.num_links++; 887 888 dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp, 889 dmic_be_num, hdmi_num); 890 if (!dai_links) 891 return -ENOMEM; 892 893 sof_audio_card_rt5682.dai_link = dai_links; 894 895 if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_PRESENT) { 896 sof_audio_card_rt5682.codec_conf = rt1015_amp_conf; 897 sof_audio_card_rt5682.num_configs = ARRAY_SIZE(rt1015_amp_conf); 898 } 899 900 INIT_LIST_HEAD(&ctx->hdmi_pcm_list); 901 902 sof_audio_card_rt5682.dev = &pdev->dev; 903 904 /* set platform name for each dailink */ 905 ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_rt5682, 906 mach->mach_params.platform); 907 if (ret) 908 return ret; 909 910 ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv; 911 912 snd_soc_card_set_drvdata(&sof_audio_card_rt5682, ctx); 913 914 return devm_snd_soc_register_card(&pdev->dev, 915 &sof_audio_card_rt5682); 916 } 917 918 static const struct platform_device_id board_ids[] = { 919 { 920 .name = "sof_rt5682", 921 }, 922 { 923 .name = "tgl_mx98357a_rt5682", 924 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 925 SOF_RT5682_SSP_CODEC(0) | 926 SOF_SPEAKER_AMP_PRESENT | 927 SOF_RT5682_SSP_AMP(1) | 928 SOF_RT5682_NUM_HDMIDEV(4) | 929 SOF_BT_OFFLOAD_SSP(2) | 930 SOF_SSP_BT_OFFLOAD_PRESENT), 931 }, 932 { 933 .name = "jsl_rt5682_rt1015", 934 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 935 SOF_RT5682_MCLK_24MHZ | 936 SOF_RT5682_SSP_CODEC(0) | 937 SOF_SPEAKER_AMP_PRESENT | 938 SOF_RT1015_SPEAKER_AMP_PRESENT | 939 SOF_RT5682_SSP_AMP(1)), 940 }, 941 { 942 .name = "tgl_mx98373_rt5682", 943 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 944 SOF_RT5682_SSP_CODEC(0) | 945 SOF_SPEAKER_AMP_PRESENT | 946 SOF_MAX98373_SPEAKER_AMP_PRESENT | 947 SOF_RT5682_SSP_AMP(1) | 948 SOF_RT5682_NUM_HDMIDEV(4) | 949 SOF_BT_OFFLOAD_SSP(2) | 950 SOF_SSP_BT_OFFLOAD_PRESENT), 951 }, 952 { 953 .name = "jsl_rt5682_mx98360a", 954 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 955 SOF_RT5682_MCLK_24MHZ | 956 SOF_RT5682_SSP_CODEC(0) | 957 SOF_SPEAKER_AMP_PRESENT | 958 SOF_MAX98360A_SPEAKER_AMP_PRESENT | 959 SOF_RT5682_SSP_AMP(1)), 960 }, 961 { 962 .name = "cml_rt1015_rt5682", 963 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 964 SOF_RT5682_MCLK_24MHZ | 965 SOF_RT5682_SSP_CODEC(0) | 966 SOF_SPEAKER_AMP_PRESENT | 967 SOF_RT1015_SPEAKER_AMP_PRESENT | 968 SOF_RT1015_SPEAKER_AMP_100FS | 969 SOF_RT5682_SSP_AMP(1)), 970 }, 971 { 972 .name = "tgl_rt1011_rt5682", 973 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 974 SOF_RT5682_SSP_CODEC(0) | 975 SOF_SPEAKER_AMP_PRESENT | 976 SOF_RT1011_SPEAKER_AMP_PRESENT | 977 SOF_RT5682_SSP_AMP(1) | 978 SOF_RT5682_NUM_HDMIDEV(4) | 979 SOF_BT_OFFLOAD_SSP(2) | 980 SOF_SSP_BT_OFFLOAD_PRESENT), 981 }, 982 { 983 .name = "jsl_rt5682_rt1015p", 984 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 985 SOF_RT5682_MCLK_24MHZ | 986 SOF_RT5682_SSP_CODEC(0) | 987 SOF_SPEAKER_AMP_PRESENT | 988 SOF_RT1015P_SPEAKER_AMP_PRESENT | 989 SOF_RT5682_SSP_AMP(1)), 990 }, 991 { 992 .name = "adl_mx98373_rt5682", 993 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 994 SOF_RT5682_SSP_CODEC(0) | 995 SOF_SPEAKER_AMP_PRESENT | 996 SOF_MAX98373_SPEAKER_AMP_PRESENT | 997 SOF_RT5682_SSP_AMP(1) | 998 SOF_RT5682_NUM_HDMIDEV(4) | 999 SOF_BT_OFFLOAD_SSP(2) | 1000 SOF_SSP_BT_OFFLOAD_PRESENT), 1001 }, 1002 { 1003 .name = "adl_mx98357a_rt5682", 1004 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 1005 SOF_RT5682_SSP_CODEC(0) | 1006 SOF_SPEAKER_AMP_PRESENT | 1007 SOF_RT5682_SSP_AMP(2) | 1008 SOF_RT5682_NUM_HDMIDEV(4)), 1009 }, 1010 { } 1011 }; 1012 MODULE_DEVICE_TABLE(platform, board_ids); 1013 1014 static struct platform_driver sof_audio = { 1015 .probe = sof_audio_probe, 1016 .driver = { 1017 .name = "sof_rt5682", 1018 .pm = &snd_soc_pm_ops, 1019 }, 1020 .id_table = board_ids, 1021 }; 1022 module_platform_driver(sof_audio) 1023 1024 /* Module information */ 1025 MODULE_DESCRIPTION("SOF Audio Machine driver"); 1026 MODULE_AUTHOR("Bard Liao <bard.liao@intel.com>"); 1027 MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>"); 1028 MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); 1029 MODULE_LICENSE("GPL v2"); 1030 MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); 1031 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); 1032