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