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/rt5682s.h> 22 #include <sound/soc-acpi.h> 23 #include "../../codecs/rt5682.h" 24 #include "../../codecs/rt5682s.h" 25 #include "../../codecs/rt5645.h" 26 #include "../common/soc-intel-quirks.h" 27 #include "sof_board_helpers.h" 28 #include "sof_maxim_common.h" 29 #include "sof_realtek_common.h" 30 31 /* Driver-specific board quirks: from bit 0 to 7 */ 32 #define SOF_RT5682_MCLK_EN BIT(0) 33 #define SOF_RT5682_MCLK_BYTCHT_EN BIT(1) 34 35 /* Default: MCLK on, MCLK 19.2M, SSP0 */ 36 static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN | 37 SOF_SSP_PORT_CODEC(0); 38 39 static int sof_rt5682_quirk_cb(const struct dmi_system_id *id) 40 { 41 sof_rt5682_quirk = (unsigned long)id->driver_data; 42 return 1; 43 } 44 45 static const struct dmi_system_id sof_rt5682_quirk_table[] = { 46 { 47 .callback = sof_rt5682_quirk_cb, 48 .matches = { 49 DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"), 50 DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max"), 51 }, 52 .driver_data = (void *)(SOF_SSP_PORT_CODEC(2)), 53 }, 54 { 55 .callback = sof_rt5682_quirk_cb, 56 .matches = { 57 DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), 58 DMI_MATCH(DMI_PRODUCT_NAME, "UP-CHT01"), 59 }, 60 .driver_data = (void *)(SOF_SSP_PORT_CODEC(2)), 61 }, 62 { 63 .callback = sof_rt5682_quirk_cb, 64 .matches = { 65 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 66 DMI_MATCH(DMI_PRODUCT_NAME, "WhiskeyLake Client"), 67 }, 68 .driver_data = (void *)(SOF_RT5682_MCLK_EN | 69 SOF_SSP_PORT_CODEC(1)), 70 }, 71 { 72 .callback = sof_rt5682_quirk_cb, 73 .matches = { 74 DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Hatch"), 75 }, 76 .driver_data = (void *)(SOF_RT5682_MCLK_EN | 77 SOF_SSP_PORT_CODEC(0) | 78 SOF_SSP_PORT_AMP(1)), 79 }, 80 { 81 .callback = sof_rt5682_quirk_cb, 82 .matches = { 83 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 84 DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"), 85 }, 86 .driver_data = (void *)(SOF_RT5682_MCLK_EN | 87 SOF_SSP_PORT_CODEC(0)), 88 }, 89 { 90 .callback = sof_rt5682_quirk_cb, 91 .matches = { 92 DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Volteer"), 93 DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98373_ALC5682I_I2S_UP4"), 94 }, 95 .driver_data = (void *)(SOF_RT5682_MCLK_EN | 96 SOF_SSP_PORT_CODEC(0) | 97 SOF_SSP_PORT_AMP(2) | 98 SOF_NUM_IDISP_HDMI(4)), 99 }, 100 { 101 .callback = sof_rt5682_quirk_cb, 102 .matches = { 103 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 104 DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"), 105 DMI_MATCH(DMI_OEM_STRING, "AUDIO-ADL_MAX98373_ALC5682I_I2S"), 106 }, 107 .driver_data = (void *)(SOF_RT5682_MCLK_EN | 108 SOF_SSP_PORT_CODEC(0) | 109 SOF_SSP_PORT_AMP(2) | 110 SOF_NUM_IDISP_HDMI(4)), 111 }, 112 { 113 .callback = sof_rt5682_quirk_cb, 114 .matches = { 115 DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Brya"), 116 DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98390_ALC5682I_I2S"), 117 }, 118 .driver_data = (void *)(SOF_RT5682_MCLK_EN | 119 SOF_SSP_PORT_CODEC(0) | 120 SOF_SSP_PORT_AMP(2) | 121 SOF_NUM_IDISP_HDMI(4)), 122 }, 123 { 124 .callback = sof_rt5682_quirk_cb, 125 .matches = { 126 DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Brya"), 127 DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98360_ALC5682I_I2S_AMP_SSP2"), 128 }, 129 .driver_data = (void *)(SOF_RT5682_MCLK_EN | 130 SOF_SSP_PORT_CODEC(0) | 131 SOF_SSP_PORT_AMP(2) | 132 SOF_NUM_IDISP_HDMI(4)), 133 }, 134 { 135 .callback = sof_rt5682_quirk_cb, 136 .matches = { 137 DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"), 138 }, 139 .driver_data = (void *)(SOF_RT5682_MCLK_EN | 140 SOF_SSP_PORT_CODEC(2) | 141 SOF_SSP_PORT_AMP(0) | 142 SOF_SSP_PORT_BT_OFFLOAD(1) | 143 SOF_BT_OFFLOAD_PRESENT 144 ), 145 }, 146 {} 147 }; 148 149 static struct snd_soc_jack_pin jack_pins[] = { 150 { 151 .pin = "Headphone Jack", 152 .mask = SND_JACK_HEADPHONE, 153 }, 154 { 155 .pin = "Headset Mic", 156 .mask = SND_JACK_MICROPHONE, 157 }, 158 }; 159 160 static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) 161 { 162 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 163 struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; 164 struct snd_soc_jack *jack = &ctx->headset_jack; 165 int extra_jack_data; 166 int ret, mclk_freq; 167 168 if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) { 169 mclk_freq = sof_dai_get_mclk(rtd); 170 if (mclk_freq <= 0) { 171 dev_err(rtd->dev, "invalid mclk freq %d\n", mclk_freq); 172 return -EINVAL; 173 } 174 175 /* need to enable ASRC function for 24MHz mclk rate */ 176 if (mclk_freq == 24000000) { 177 dev_info(rtd->dev, "enable ASRC\n"); 178 179 switch (ctx->codec_type) { 180 case CODEC_RT5650: 181 rt5645_sel_asrc_clk_src(component, 182 RT5645_DA_STEREO_FILTER | 183 RT5645_AD_STEREO_FILTER, 184 RT5645_CLK_SEL_I2S1_ASRC); 185 rt5645_sel_asrc_clk_src(component, 186 RT5645_DA_MONO_L_FILTER | 187 RT5645_DA_MONO_R_FILTER, 188 RT5645_CLK_SEL_I2S2_ASRC); 189 break; 190 case CODEC_RT5682: 191 rt5682_sel_asrc_clk_src(component, 192 RT5682_DA_STEREO1_FILTER | 193 RT5682_AD_STEREO1_FILTER, 194 RT5682_CLK_SEL_I2S1_ASRC); 195 break; 196 case CODEC_RT5682S: 197 rt5682s_sel_asrc_clk_src(component, 198 RT5682S_DA_STEREO1_FILTER | 199 RT5682S_AD_STEREO1_FILTER, 200 RT5682S_CLK_SEL_I2S1_ASRC); 201 break; 202 default: 203 dev_err(rtd->dev, "invalid codec type %d\n", 204 ctx->codec_type); 205 return -EINVAL; 206 } 207 } 208 209 if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { 210 /* 211 * The firmware might enable the clock at 212 * boot (this information may or may not 213 * be reflected in the enable clock register). 214 * To change the rate we must disable the clock 215 * first to cover these cases. Due to common 216 * clock framework restrictions that do not allow 217 * to disable a clock that has not been enabled, 218 * we need to enable the clock first. 219 */ 220 ret = clk_prepare_enable(ctx->rt5682.mclk); 221 if (!ret) 222 clk_disable_unprepare(ctx->rt5682.mclk); 223 224 ret = clk_set_rate(ctx->rt5682.mclk, 19200000); 225 226 if (ret) 227 dev_err(rtd->dev, "unable to set MCLK rate\n"); 228 } 229 } 230 231 /* 232 * Headset buttons map to the google Reference headset. 233 * These can be configured by userspace. 234 */ 235 ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", 236 SND_JACK_HEADSET | SND_JACK_BTN_0 | 237 SND_JACK_BTN_1 | SND_JACK_BTN_2 | 238 SND_JACK_BTN_3, 239 jack, 240 jack_pins, 241 ARRAY_SIZE(jack_pins)); 242 if (ret) { 243 dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); 244 return ret; 245 } 246 247 snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 248 snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); 249 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); 250 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); 251 252 if (ctx->codec_type == CODEC_RT5650) { 253 extra_jack_data = SND_JACK_MICROPHONE | SND_JACK_BTN_0; 254 ret = snd_soc_component_set_jack(component, jack, &extra_jack_data); 255 } else 256 ret = snd_soc_component_set_jack(component, jack, NULL); 257 258 if (ret) { 259 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); 260 return ret; 261 } 262 263 return ret; 264 }; 265 266 static void sof_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd) 267 { 268 struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; 269 270 snd_soc_component_set_jack(component, NULL, NULL); 271 } 272 273 static int sof_rt5682_hw_params(struct snd_pcm_substream *substream, 274 struct snd_pcm_hw_params *params) 275 { 276 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 277 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 278 struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); 279 int pll_id, pll_source, pll_in, pll_out, clk_id, ret; 280 281 if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) { 282 if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { 283 ret = clk_prepare_enable(ctx->rt5682.mclk); 284 if (ret < 0) { 285 dev_err(rtd->dev, 286 "could not configure MCLK state"); 287 return ret; 288 } 289 } 290 291 switch (ctx->codec_type) { 292 case CODEC_RT5650: 293 pll_source = RT5645_PLL1_S_MCLK; 294 break; 295 case CODEC_RT5682: 296 pll_source = RT5682_PLL1_S_MCLK; 297 break; 298 case CODEC_RT5682S: 299 pll_source = RT5682S_PLL_S_MCLK; 300 break; 301 default: 302 dev_err(rtd->dev, "invalid codec type %d\n", 303 ctx->codec_type); 304 return -EINVAL; 305 } 306 307 /* get the tplg configured mclk. */ 308 pll_in = sof_dai_get_mclk(rtd); 309 if (pll_in <= 0) { 310 dev_err(rtd->dev, "invalid mclk freq %d\n", pll_in); 311 return -EINVAL; 312 } 313 } else { 314 switch (ctx->codec_type) { 315 case CODEC_RT5650: 316 pll_source = RT5645_PLL1_S_BCLK1; 317 break; 318 case CODEC_RT5682: 319 pll_source = RT5682_PLL1_S_BCLK1; 320 break; 321 case CODEC_RT5682S: 322 pll_source = RT5682S_PLL_S_BCLK1; 323 break; 324 default: 325 dev_err(rtd->dev, "invalid codec type %d\n", 326 ctx->codec_type); 327 return -EINVAL; 328 } 329 330 pll_in = params_rate(params) * 50; 331 } 332 333 switch (ctx->codec_type) { 334 case CODEC_RT5650: 335 pll_id = 0; /* not used in codec driver */ 336 clk_id = RT5645_SCLK_S_PLL1; 337 break; 338 case CODEC_RT5682: 339 pll_id = RT5682_PLL1; 340 clk_id = RT5682_SCLK_S_PLL1; 341 break; 342 case CODEC_RT5682S: 343 /* 344 * For MCLK = 24.576MHz and sample rate = 96KHz case, use PLL1 We don't test 345 * pll_out or params_rate() here since rt5682s PLL2 doesn't support 24.576MHz 346 * input, so we have no choice but to use PLL1. Besides, we will not use PLL at 347 * all if pll_in == pll_out. ex, MCLK = 24.576Mhz and sample rate = 48KHz 348 */ 349 if (pll_in == 24576000) { 350 pll_id = RT5682S_PLL1; 351 clk_id = RT5682S_SCLK_S_PLL1; 352 } else { 353 pll_id = RT5682S_PLL2; 354 clk_id = RT5682S_SCLK_S_PLL2; 355 } 356 break; 357 default: 358 dev_err(rtd->dev, "invalid codec type %d\n", ctx->codec_type); 359 return -EINVAL; 360 } 361 362 pll_out = params_rate(params) * 512; 363 364 /* when MCLK is 512FS, no need to set PLL configuration additionally. */ 365 if (pll_in == pll_out) { 366 switch (ctx->codec_type) { 367 case CODEC_RT5650: 368 clk_id = RT5645_SCLK_S_MCLK; 369 break; 370 case CODEC_RT5682: 371 clk_id = RT5682_SCLK_S_MCLK; 372 break; 373 case CODEC_RT5682S: 374 clk_id = RT5682S_SCLK_S_MCLK; 375 break; 376 default: 377 dev_err(rtd->dev, "invalid codec type %d\n", 378 ctx->codec_type); 379 return -EINVAL; 380 } 381 } else { 382 /* Configure pll for codec */ 383 ret = snd_soc_dai_set_pll(codec_dai, pll_id, pll_source, pll_in, 384 pll_out); 385 if (ret < 0) 386 dev_err(rtd->dev, "snd_soc_dai_set_pll err = %d\n", ret); 387 } 388 389 /* Configure sysclk for codec */ 390 ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, 391 pll_out, SND_SOC_CLOCK_IN); 392 if (ret < 0) 393 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); 394 395 /* 396 * slot_width should equal or large than data length, set them 397 * be the same 398 */ 399 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0, 0x0, 2, 400 params_width(params)); 401 if (ret < 0) { 402 dev_err(rtd->dev, "set TDM slot err:%d\n", ret); 403 return ret; 404 } 405 406 return ret; 407 } 408 409 static struct snd_soc_ops sof_rt5682_ops = { 410 .hw_params = sof_rt5682_hw_params, 411 }; 412 413 static int sof_card_late_probe(struct snd_soc_card *card) 414 { 415 struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); 416 struct snd_soc_dapm_context *dapm = &card->dapm; 417 int err; 418 419 if (ctx->amp_type == CODEC_MAX98373) { 420 /* Disable Left and Right Spk pin after boot */ 421 snd_soc_dapm_disable_pin(dapm, "Left Spk"); 422 snd_soc_dapm_disable_pin(dapm, "Right Spk"); 423 err = snd_soc_dapm_sync(dapm); 424 if (err < 0) 425 return err; 426 } 427 428 return sof_intel_board_card_late_probe(card); 429 } 430 431 static const struct snd_kcontrol_new sof_controls[] = { 432 SOC_DAPM_PIN_SWITCH("Headphone Jack"), 433 SOC_DAPM_PIN_SWITCH("Headset Mic"), 434 SOC_DAPM_PIN_SWITCH("Left Spk"), 435 SOC_DAPM_PIN_SWITCH("Right Spk"), 436 437 }; 438 439 static const struct snd_soc_dapm_widget sof_widgets[] = { 440 SND_SOC_DAPM_HP("Headphone Jack", NULL), 441 SND_SOC_DAPM_MIC("Headset Mic", NULL), 442 SND_SOC_DAPM_SPK("Left Spk", NULL), 443 SND_SOC_DAPM_SPK("Right Spk", NULL), 444 }; 445 446 static const struct snd_soc_dapm_route sof_map[] = { 447 /* HP jack connectors - unknown if we have jack detection */ 448 { "Headphone Jack", NULL, "HPOL" }, 449 { "Headphone Jack", NULL, "HPOR" }, 450 451 /* other jacks */ 452 { "IN1P", NULL, "Headset Mic" }, 453 }; 454 455 static const struct snd_soc_dapm_route rt5650_spk_dapm_routes[] = { 456 /* speaker */ 457 { "Left Spk", NULL, "SPOL" }, 458 { "Right Spk", NULL, "SPOR" }, 459 }; 460 461 static int rt5650_spk_init(struct snd_soc_pcm_runtime *rtd) 462 { 463 struct snd_soc_card *card = rtd->card; 464 int ret; 465 466 ret = snd_soc_dapm_add_routes(&card->dapm, rt5650_spk_dapm_routes, 467 ARRAY_SIZE(rt5650_spk_dapm_routes)); 468 if (ret) 469 dev_err(rtd->dev, "fail to add dapm routes, ret=%d\n", ret); 470 471 return ret; 472 } 473 474 /* sof audio machine driver for rt5682 codec */ 475 static struct snd_soc_card sof_audio_card_rt5682 = { 476 .name = "rt5682", /* the sof- prefix is added by the core */ 477 .owner = THIS_MODULE, 478 .controls = sof_controls, 479 .num_controls = ARRAY_SIZE(sof_controls), 480 .dapm_widgets = sof_widgets, 481 .num_dapm_widgets = ARRAY_SIZE(sof_widgets), 482 .dapm_routes = sof_map, 483 .num_dapm_routes = ARRAY_SIZE(sof_map), 484 .fully_routed = true, 485 .late_probe = sof_card_late_probe, 486 }; 487 488 static struct snd_soc_dai_link_component rt5682_component[] = { 489 { 490 .name = "i2c-10EC5682:00", 491 .dai_name = "rt5682-aif1", 492 } 493 }; 494 495 static struct snd_soc_dai_link_component rt5682s_component[] = { 496 { 497 .name = "i2c-RTL5682:00", 498 .dai_name = "rt5682s-aif1", 499 } 500 }; 501 502 static struct snd_soc_dai_link_component rt5650_components[] = { 503 { 504 .name = "i2c-10EC5650:00", 505 .dai_name = "rt5645-aif1", 506 }, 507 { 508 .name = "i2c-10EC5650:00", 509 .dai_name = "rt5645-aif2", 510 } 511 }; 512 513 static int 514 sof_card_dai_links_create(struct device *dev, struct snd_soc_card *card, 515 struct sof_card_private *ctx) 516 { 517 int ret; 518 519 ret = sof_intel_board_set_dai_link(dev, card, ctx); 520 if (ret) 521 return ret; 522 523 if (!ctx->codec_link) { 524 dev_err(dev, "codec link not available"); 525 return -EINVAL; 526 } 527 528 /* codec-specific fields for headphone codec */ 529 switch (ctx->codec_type) { 530 case CODEC_RT5650: 531 ctx->codec_link->codecs = &rt5650_components[0]; 532 ctx->codec_link->num_codecs = 1; 533 break; 534 case CODEC_RT5682: 535 ctx->codec_link->codecs = rt5682_component; 536 ctx->codec_link->num_codecs = ARRAY_SIZE(rt5682_component); 537 break; 538 case CODEC_RT5682S: 539 ctx->codec_link->codecs = rt5682s_component; 540 ctx->codec_link->num_codecs = ARRAY_SIZE(rt5682s_component); 541 break; 542 default: 543 dev_err(dev, "invalid codec type %d\n", ctx->codec_type); 544 return -EINVAL; 545 } 546 547 ctx->codec_link->init = sof_rt5682_codec_init; 548 ctx->codec_link->exit = sof_rt5682_codec_exit; 549 ctx->codec_link->ops = &sof_rt5682_ops; 550 551 if (!ctx->rt5682.is_legacy_cpu) { 552 /* 553 * Currently, On SKL+ platforms MCLK will be turned off in sof 554 * runtime suspended, and it will go into runtime suspended 555 * right after playback is stop. However, rt5682 will output 556 * static noise if sysclk turns off during playback. Set 557 * ignore_pmdown_time to power down rt5682 immediately and 558 * avoid the noise. 559 * It can be removed once we can control MCLK by driver. 560 */ 561 ctx->codec_link->ignore_pmdown_time = 1; 562 } 563 564 if (ctx->amp_type == CODEC_NONE) 565 return 0; 566 567 if (!ctx->amp_link) { 568 dev_err(dev, "amp link not available"); 569 return -EINVAL; 570 } 571 572 /* codec-specific fields for speaker amplifier */ 573 switch (ctx->amp_type) { 574 case CODEC_MAX98357A: 575 max_98357a_dai_link(ctx->amp_link); 576 break; 577 case CODEC_MAX98360A: 578 max_98360a_dai_link(ctx->amp_link); 579 break; 580 case CODEC_MAX98373: 581 ctx->amp_link->codecs = max_98373_components; 582 ctx->amp_link->num_codecs = ARRAY_SIZE(max_98373_components); 583 ctx->amp_link->init = max_98373_spk_codec_init; 584 ctx->amp_link->ops = &max_98373_ops; 585 break; 586 case CODEC_MAX98390: 587 max_98390_dai_link(dev, ctx->amp_link); 588 break; 589 case CODEC_RT1011: 590 sof_rt1011_dai_link(dev, ctx->amp_link); 591 break; 592 case CODEC_RT1015: 593 sof_rt1015_dai_link(ctx->amp_link); 594 break; 595 case CODEC_RT1015P: 596 sof_rt1015p_dai_link(ctx->amp_link); 597 break; 598 case CODEC_RT1019P: 599 sof_rt1019p_dai_link(ctx->amp_link); 600 break; 601 case CODEC_RT5650: 602 /* use AIF2 to support speaker pipeline */ 603 ctx->amp_link->codecs = &rt5650_components[1]; 604 ctx->amp_link->num_codecs = 1; 605 ctx->amp_link->init = rt5650_spk_init; 606 ctx->amp_link->ops = &sof_rt5682_ops; 607 break; 608 default: 609 dev_err(dev, "invalid amp type %d\n", ctx->amp_type); 610 return -EINVAL; 611 } 612 613 return 0; 614 } 615 616 static int sof_audio_probe(struct platform_device *pdev) 617 { 618 struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; 619 struct sof_card_private *ctx; 620 char *card_name; 621 bool is_legacy_cpu = false; 622 int ret; 623 624 if (pdev->id_entry && pdev->id_entry->driver_data) 625 sof_rt5682_quirk = (unsigned long)pdev->id_entry->driver_data; 626 627 dmi_check_system(sof_rt5682_quirk_table); 628 629 if (soc_intel_is_byt() || soc_intel_is_cht()) { 630 is_legacy_cpu = true; 631 632 /* default quirk for legacy cpu */ 633 sof_rt5682_quirk = SOF_RT5682_MCLK_EN | 634 SOF_RT5682_MCLK_BYTCHT_EN | 635 SOF_SSP_PORT_CODEC(2); 636 } 637 638 dev_dbg(&pdev->dev, "sof_rt5682_quirk = %lx\n", sof_rt5682_quirk); 639 640 /* initialize ctx with board quirk */ 641 ctx = sof_intel_board_get_ctx(&pdev->dev, sof_rt5682_quirk); 642 if (!ctx) 643 return -ENOMEM; 644 645 if (ctx->codec_type == CODEC_RT5650) { 646 card_name = devm_kstrdup(&pdev->dev, "rt5650", GFP_KERNEL); 647 if (!card_name) 648 return -ENOMEM; 649 650 sof_audio_card_rt5682.name = card_name; 651 652 /* create speaker dai link also */ 653 if (ctx->amp_type == CODEC_NONE) 654 ctx->amp_type = CODEC_RT5650; 655 } 656 657 if (ctx->amp_type == CODEC_RT1011 && soc_intel_is_cml()) { 658 /* backward-compatible with existing cml devices */ 659 card_name = devm_kstrdup(&pdev->dev, "cml_rt1011_rt5682", 660 GFP_KERNEL); 661 if (!card_name) 662 return -ENOMEM; 663 664 sof_audio_card_rt5682.name = card_name; 665 } 666 667 if (is_legacy_cpu) { 668 ctx->rt5682.is_legacy_cpu = true; 669 ctx->dmic_be_num = 0; 670 /* HDMI is not supported by SOF on Baytrail/CherryTrail */ 671 ctx->hdmi_num = 0; 672 } else { 673 if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) 674 ctx->hdmi.idisp_codec = true; 675 } 676 677 /* need to get main clock from pmc */ 678 if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { 679 ctx->rt5682.mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); 680 if (IS_ERR(ctx->rt5682.mclk)) { 681 ret = PTR_ERR(ctx->rt5682.mclk); 682 683 dev_err(&pdev->dev, 684 "Failed to get MCLK from pmc_plt_clk_3: %d\n", 685 ret); 686 return ret; 687 } 688 689 ret = clk_prepare_enable(ctx->rt5682.mclk); 690 if (ret < 0) { 691 dev_err(&pdev->dev, 692 "could not configure MCLK state"); 693 return ret; 694 } 695 } 696 697 /* update dai_link */ 698 ret = sof_card_dai_links_create(&pdev->dev, &sof_audio_card_rt5682, ctx); 699 if (ret) 700 return ret; 701 702 /* update codec_conf */ 703 switch (ctx->amp_type) { 704 case CODEC_MAX98373: 705 max_98373_set_codec_conf(&sof_audio_card_rt5682); 706 break; 707 case CODEC_MAX98390: 708 max_98390_set_codec_conf(&pdev->dev, &sof_audio_card_rt5682); 709 break; 710 case CODEC_RT1011: 711 sof_rt1011_codec_conf(&pdev->dev, &sof_audio_card_rt5682); 712 break; 713 case CODEC_RT1015: 714 sof_rt1015_codec_conf(&sof_audio_card_rt5682); 715 break; 716 case CODEC_RT1015P: 717 sof_rt1015p_codec_conf(&sof_audio_card_rt5682); 718 break; 719 case CODEC_MAX98357A: 720 case CODEC_MAX98360A: 721 case CODEC_RT1019P: 722 case CODEC_RT5650: 723 case CODEC_NONE: 724 /* no codec conf required */ 725 break; 726 default: 727 dev_err(&pdev->dev, "invalid amp type %d\n", ctx->amp_type); 728 return -EINVAL; 729 } 730 731 sof_audio_card_rt5682.dev = &pdev->dev; 732 733 /* set platform name for each dailink */ 734 ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_rt5682, 735 mach->mach_params.platform); 736 if (ret) 737 return ret; 738 739 snd_soc_card_set_drvdata(&sof_audio_card_rt5682, ctx); 740 741 return devm_snd_soc_register_card(&pdev->dev, 742 &sof_audio_card_rt5682); 743 } 744 745 static const struct platform_device_id board_ids[] = { 746 { 747 .name = "sof_rt5682", 748 }, 749 { 750 .name = "cml_rt5682_def", 751 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 752 SOF_SSP_PORT_CODEC(0) | 753 SOF_SSP_PORT_AMP(1)), 754 }, 755 { 756 .name = "jsl_rt5682_def", 757 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 758 SOF_SSP_PORT_CODEC(0) | 759 SOF_SSP_PORT_AMP(1)), 760 }, 761 { 762 .name = "tgl_rt5682_def", 763 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 764 SOF_SSP_PORT_CODEC(0) | 765 SOF_SSP_PORT_AMP(1) | 766 SOF_NUM_IDISP_HDMI(4) | 767 SOF_SSP_PORT_BT_OFFLOAD(2) | 768 SOF_BT_OFFLOAD_PRESENT), 769 }, 770 { 771 .name = "adl_rt5682_def", 772 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 773 SOF_SSP_PORT_CODEC(0) | 774 SOF_SSP_PORT_AMP(1) | 775 SOF_NUM_IDISP_HDMI(4) | 776 SOF_SSP_PORT_BT_OFFLOAD(2) | 777 SOF_BT_OFFLOAD_PRESENT), 778 }, 779 { 780 .name = "adl_mx98357_rt5682", 781 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 782 SOF_SSP_PORT_CODEC(0) | 783 SOF_SSP_PORT_AMP(2) | 784 SOF_NUM_IDISP_HDMI(4)), 785 }, 786 { 787 .name = "adl_rt5682_c1_h02", 788 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 789 SOF_SSP_PORT_CODEC(1) | 790 /* SSP 0 and SSP 2 are used for HDMI IN */ 791 SOF_SSP_MASK_HDMI_CAPTURE(0x5)), 792 }, 793 { 794 .name = "rpl_mx98357_rt5682", 795 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 796 SOF_SSP_PORT_CODEC(0) | 797 SOF_SSP_PORT_AMP(2) | 798 SOF_NUM_IDISP_HDMI(4)), 799 }, 800 { 801 .name = "rpl_rt5682_def", 802 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 803 SOF_SSP_PORT_CODEC(0) | 804 SOF_SSP_PORT_AMP(1) | 805 SOF_NUM_IDISP_HDMI(4) | 806 SOF_SSP_PORT_BT_OFFLOAD(2) | 807 SOF_BT_OFFLOAD_PRESENT), 808 }, 809 { 810 .name = "rpl_rt5682_c1_h02", 811 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 812 SOF_SSP_PORT_CODEC(1) | 813 /* SSP 0 and SSP 2 are used for HDMI IN */ 814 SOF_SSP_MASK_HDMI_CAPTURE(0x5)), 815 }, 816 { 817 .name = "mtl_mx98357_rt5682", 818 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 819 SOF_SSP_PORT_CODEC(0) | 820 SOF_SSP_PORT_AMP(1) | 821 SOF_SSP_PORT_BT_OFFLOAD(2) | 822 SOF_BT_OFFLOAD_PRESENT), 823 }, 824 { 825 .name = "mtl_mx98360_rt5682", 826 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 827 SOF_SSP_PORT_CODEC(0) | 828 SOF_SSP_PORT_AMP(1)), 829 }, 830 { 831 .name = "mtl_rt5682_def", 832 .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 833 SOF_SSP_PORT_CODEC(2) | 834 SOF_SSP_PORT_AMP(0) | 835 SOF_SSP_PORT_BT_OFFLOAD(1) | 836 SOF_BT_OFFLOAD_PRESENT), 837 }, 838 { } 839 }; 840 MODULE_DEVICE_TABLE(platform, board_ids); 841 842 static struct platform_driver sof_audio = { 843 .probe = sof_audio_probe, 844 .driver = { 845 .name = "sof_rt5682", 846 .pm = &snd_soc_pm_ops, 847 }, 848 .id_table = board_ids, 849 }; 850 module_platform_driver(sof_audio) 851 852 /* Module information */ 853 MODULE_DESCRIPTION("SOF Audio Machine driver"); 854 MODULE_AUTHOR("Bard Liao <bard.liao@intel.com>"); 855 MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>"); 856 MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); 857 MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>"); 858 MODULE_LICENSE("GPL v2"); 859 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); 860 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); 861 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON); 862