1 // SPDX-License-Identifier: GPL-2.0-only 2 // Copyright (c) 2020 Intel Corporation 3 4 /* 5 * sof_sdw - ASOC Machine driver for Intel SoundWire platforms 6 */ 7 8 #include <linux/device.h> 9 #include <linux/dmi.h> 10 #include <linux/module.h> 11 #include <linux/soundwire/sdw.h> 12 #include <linux/soundwire/sdw_type.h> 13 #include <sound/soc.h> 14 #include <sound/soc-acpi.h> 15 #include "sof_sdw_common.h" 16 #include "../../codecs/rt711.h" 17 18 unsigned long sof_sdw_quirk = RT711_JD1; 19 static int quirk_override = -1; 20 module_param_named(quirk, quirk_override, int, 0444); 21 MODULE_PARM_DESC(quirk, "Board-specific quirk override"); 22 23 #define INC_ID(BE, CPU, LINK) do { (BE)++; (CPU)++; (LINK)++; } while (0) 24 25 static void log_quirks(struct device *dev) 26 { 27 if (SOF_RT711_JDSRC(sof_sdw_quirk)) 28 dev_dbg(dev, "quirk realtek,jack-detect-source %ld\n", 29 SOF_RT711_JDSRC(sof_sdw_quirk)); 30 if (sof_sdw_quirk & SOF_SDW_FOUR_SPK) 31 dev_dbg(dev, "quirk SOF_SDW_FOUR_SPK enabled\n"); 32 if (sof_sdw_quirk & SOF_SDW_TGL_HDMI) 33 dev_dbg(dev, "quirk SOF_SDW_TGL_HDMI enabled\n"); 34 if (sof_sdw_quirk & SOF_SDW_PCH_DMIC) 35 dev_dbg(dev, "quirk SOF_SDW_PCH_DMIC enabled\n"); 36 if (SOF_SSP_GET_PORT(sof_sdw_quirk)) 37 dev_dbg(dev, "SSP port %ld\n", 38 SOF_SSP_GET_PORT(sof_sdw_quirk)); 39 if (sof_sdw_quirk & SOF_SDW_NO_AGGREGATION) 40 dev_dbg(dev, "quirk SOF_SDW_NO_AGGREGATION enabled\n"); 41 } 42 43 static int sof_sdw_quirk_cb(const struct dmi_system_id *id) 44 { 45 sof_sdw_quirk = (unsigned long)id->driver_data; 46 return 1; 47 } 48 49 static const struct dmi_system_id sof_sdw_quirk_table[] = { 50 /* CometLake devices */ 51 { 52 .callback = sof_sdw_quirk_cb, 53 .matches = { 54 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 55 DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"), 56 }, 57 .driver_data = (void *)SOF_SDW_PCH_DMIC, 58 }, 59 { 60 .callback = sof_sdw_quirk_cb, 61 .matches = { 62 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 63 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6") 64 }, 65 .driver_data = (void *)RT711_JD2, 66 }, 67 { 68 /* early version of SKU 09C6 */ 69 .callback = sof_sdw_quirk_cb, 70 .matches = { 71 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 72 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983") 73 }, 74 .driver_data = (void *)RT711_JD2, 75 }, 76 { 77 .callback = sof_sdw_quirk_cb, 78 .matches = { 79 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 80 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"), 81 }, 82 .driver_data = (void *)(RT711_JD2 | 83 SOF_SDW_FOUR_SPK), 84 }, 85 { 86 .callback = sof_sdw_quirk_cb, 87 .matches = { 88 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 89 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"), 90 }, 91 .driver_data = (void *)(RT711_JD2 | 92 SOF_SDW_FOUR_SPK), 93 }, 94 /* IceLake devices */ 95 { 96 .callback = sof_sdw_quirk_cb, 97 .matches = { 98 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 99 DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"), 100 }, 101 .driver_data = (void *)SOF_SDW_PCH_DMIC, 102 }, 103 /* TigerLake devices */ 104 { 105 .callback = sof_sdw_quirk_cb, 106 .matches = { 107 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 108 DMI_MATCH(DMI_PRODUCT_NAME, 109 "Tiger Lake Client Platform"), 110 }, 111 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 112 RT711_JD1 | 113 SOF_SDW_PCH_DMIC | 114 SOF_SSP_PORT(SOF_I2S_SSP2)), 115 }, 116 { 117 .callback = sof_sdw_quirk_cb, 118 .matches = { 119 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 120 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E") 121 }, 122 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 123 RT711_JD2), 124 }, 125 { 126 /* another SKU of Dell Latitude 9520 */ 127 .callback = sof_sdw_quirk_cb, 128 .matches = { 129 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 130 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3F") 131 }, 132 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 133 RT711_JD2), 134 }, 135 { 136 /* Dell XPS 9710 */ 137 .callback = sof_sdw_quirk_cb, 138 .matches = { 139 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 140 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5D") 141 }, 142 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 143 RT711_JD2 | 144 SOF_SDW_FOUR_SPK), 145 }, 146 { 147 .callback = sof_sdw_quirk_cb, 148 .matches = { 149 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 150 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") 151 }, 152 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 153 RT711_JD2 | 154 SOF_SDW_FOUR_SPK), 155 }, 156 { 157 .callback = sof_sdw_quirk_cb, 158 .matches = { 159 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 160 DMI_MATCH(DMI_PRODUCT_NAME, "Volteer"), 161 }, 162 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 163 SOF_SDW_PCH_DMIC | 164 SOF_SDW_FOUR_SPK | 165 SOF_BT_OFFLOAD_SSP(2) | 166 SOF_SSP_BT_OFFLOAD_PRESENT), 167 }, 168 { 169 .callback = sof_sdw_quirk_cb, 170 .matches = { 171 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 172 DMI_MATCH(DMI_PRODUCT_NAME, "Ripto"), 173 }, 174 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 175 SOF_SDW_PCH_DMIC | 176 SOF_SDW_FOUR_SPK), 177 }, 178 { 179 /* 180 * this entry covers multiple HP SKUs. The family name 181 * does not seem robust enough, so we use a partial 182 * match that ignores the product name suffix 183 * (e.g. 15-eb1xxx, 14t-ea000 or 13-aw2xxx) 184 */ 185 .callback = sof_sdw_quirk_cb, 186 .matches = { 187 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 188 DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Conv"), 189 }, 190 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 191 SOF_SDW_PCH_DMIC | 192 RT711_JD1), 193 }, 194 { 195 /* 196 * this entry covers HP Spectre x360 where the DMI information 197 * changed somehow 198 */ 199 .callback = sof_sdw_quirk_cb, 200 .matches = { 201 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 202 DMI_MATCH(DMI_BOARD_NAME, "8709"), 203 }, 204 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 205 SOF_SDW_PCH_DMIC | 206 RT711_JD1), 207 }, 208 { 209 /* NUC15 'Bishop County' LAPBC510 and LAPBC710 skews */ 210 .callback = sof_sdw_quirk_cb, 211 .matches = { 212 DMI_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"), 213 DMI_MATCH(DMI_PRODUCT_NAME, "LAPBC"), 214 }, 215 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 216 SOF_SDW_PCH_DMIC | 217 RT711_JD1), 218 }, 219 { 220 /* NUC15 LAPBC710 skews */ 221 .callback = sof_sdw_quirk_cb, 222 .matches = { 223 DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), 224 DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"), 225 }, 226 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 227 SOF_SDW_PCH_DMIC | 228 RT711_JD1), 229 }, 230 { 231 /* NUC15 'Rooks County' LAPRC510 and LAPRC710 skews */ 232 .callback = sof_sdw_quirk_cb, 233 .matches = { 234 DMI_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"), 235 DMI_MATCH(DMI_PRODUCT_NAME, "LAPRC"), 236 }, 237 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 238 SOF_SDW_PCH_DMIC | 239 RT711_JD2_100K), 240 }, 241 /* TigerLake-SDCA devices */ 242 { 243 .callback = sof_sdw_quirk_cb, 244 .matches = { 245 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 246 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32") 247 }, 248 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 249 RT711_JD2 | 250 SOF_SDW_FOUR_SPK), 251 }, 252 { 253 .callback = sof_sdw_quirk_cb, 254 .matches = { 255 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 256 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A45") 257 }, 258 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 259 RT711_JD2), 260 }, 261 /* AlderLake devices */ 262 { 263 .callback = sof_sdw_quirk_cb, 264 .matches = { 265 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 266 DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"), 267 }, 268 .driver_data = (void *)(RT711_JD2_100K | 269 SOF_SDW_TGL_HDMI | 270 SOF_BT_OFFLOAD_SSP(2) | 271 SOF_SSP_BT_OFFLOAD_PRESENT), 272 }, 273 { 274 .callback = sof_sdw_quirk_cb, 275 .matches = { 276 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 277 DMI_MATCH(DMI_PRODUCT_NAME, "Brya"), 278 }, 279 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 280 SOF_SDW_PCH_DMIC | 281 SOF_SDW_FOUR_SPK | 282 SOF_BT_OFFLOAD_SSP(2) | 283 SOF_SSP_BT_OFFLOAD_PRESENT), 284 }, 285 { 286 .callback = sof_sdw_quirk_cb, 287 .matches = { 288 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 289 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AF0") 290 }, 291 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 292 RT711_JD2 | 293 SOF_SDW_FOUR_SPK), 294 }, 295 { 296 .callback = sof_sdw_quirk_cb, 297 .matches = { 298 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 299 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AF3"), 300 }, 301 /* No Jack */ 302 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 303 SOF_SDW_FOUR_SPK), 304 }, 305 { 306 .callback = sof_sdw_quirk_cb, 307 .matches = { 308 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 309 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFF") 310 }, 311 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 312 RT711_JD2 | 313 SOF_SDW_FOUR_SPK), 314 }, 315 { 316 .callback = sof_sdw_quirk_cb, 317 .matches = { 318 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 319 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B00") 320 }, 321 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 322 RT711_JD2 | 323 SOF_SDW_FOUR_SPK), 324 }, 325 { 326 .callback = sof_sdw_quirk_cb, 327 .matches = { 328 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 329 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B01") 330 }, 331 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 332 RT711_JD2 | 333 SOF_SDW_FOUR_SPK), 334 }, 335 { 336 .callback = sof_sdw_quirk_cb, 337 .matches = { 338 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 339 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B11") 340 }, 341 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 342 RT711_JD2 | 343 SOF_SDW_FOUR_SPK), 344 }, 345 { 346 .callback = sof_sdw_quirk_cb, 347 .matches = { 348 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 349 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B12") 350 }, 351 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 352 RT711_JD2 | 353 SOF_SDW_FOUR_SPK), 354 }, 355 { 356 .callback = sof_sdw_quirk_cb, 357 .matches = { 358 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 359 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B13"), 360 }, 361 /* No Jack */ 362 .driver_data = (void *)SOF_SDW_TGL_HDMI, 363 }, 364 { 365 .callback = sof_sdw_quirk_cb, 366 .matches = { 367 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 368 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B29"), 369 }, 370 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 371 RT711_JD2 | 372 SOF_SDW_FOUR_SPK), 373 }, 374 { 375 .callback = sof_sdw_quirk_cb, 376 .matches = { 377 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 378 DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16-k0xxx"), 379 }, 380 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 381 RT711_JD2), 382 }, 383 /* RaptorLake devices */ 384 { 385 .callback = sof_sdw_quirk_cb, 386 .matches = { 387 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 388 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C10"), 389 }, 390 /* No Jack */ 391 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 392 SOF_SDW_FOUR_SPK), 393 }, 394 { 395 .callback = sof_sdw_quirk_cb, 396 .matches = { 397 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 398 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C11") 399 }, 400 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 401 RT711_JD2 | 402 SOF_SDW_FOUR_SPK), 403 }, 404 { 405 .callback = sof_sdw_quirk_cb, 406 .matches = { 407 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 408 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C40") 409 }, 410 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 411 RT711_JD2 | 412 SOF_SDW_FOUR_SPK), 413 }, 414 { 415 .callback = sof_sdw_quirk_cb, 416 .matches = { 417 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 418 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C4F") 419 }, 420 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 421 RT711_JD2 | 422 SOF_SDW_FOUR_SPK), 423 }, 424 /* MeteorLake devices */ 425 { 426 .callback = sof_sdw_quirk_cb, 427 .matches = { 428 DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_mtlrvp"), 429 }, 430 .driver_data = (void *)(RT711_JD1), 431 }, 432 { 433 .callback = sof_sdw_quirk_cb, 434 .matches = { 435 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 436 DMI_MATCH(DMI_PRODUCT_NAME, "Meteor Lake Client Platform"), 437 }, 438 .driver_data = (void *)(RT711_JD2_100K), 439 }, 440 /* LunarLake devices */ 441 { 442 .callback = sof_sdw_quirk_cb, 443 .matches = { 444 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 445 DMI_MATCH(DMI_PRODUCT_NAME, "Lunar Lake Client Platform"), 446 }, 447 .driver_data = (void *)(RT711_JD2_100K), 448 }, 449 {} 450 }; 451 452 static struct snd_soc_dai_link_component dmic_component[] = { 453 { 454 .name = "dmic-codec", 455 .dai_name = "dmic-hifi", 456 } 457 }; 458 459 static struct snd_soc_dai_link_component platform_component[] = { 460 { 461 /* name might be overridden during probe */ 462 .name = "0000:00:1f.3" 463 } 464 }; 465 466 /* these wrappers are only needed to avoid typecast compilation errors */ 467 int sdw_startup(struct snd_pcm_substream *substream) 468 { 469 return sdw_startup_stream(substream); 470 } 471 472 int sdw_prepare(struct snd_pcm_substream *substream) 473 { 474 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 475 struct sdw_stream_runtime *sdw_stream; 476 struct snd_soc_dai *dai; 477 478 /* Find stream from first CPU DAI */ 479 dai = asoc_rtd_to_cpu(rtd, 0); 480 481 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); 482 483 if (IS_ERR(sdw_stream)) { 484 dev_err(rtd->dev, "no stream found for DAI %s", dai->name); 485 return PTR_ERR(sdw_stream); 486 } 487 488 return sdw_prepare_stream(sdw_stream); 489 } 490 491 int sdw_trigger(struct snd_pcm_substream *substream, int cmd) 492 { 493 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 494 struct sdw_stream_runtime *sdw_stream; 495 struct snd_soc_dai *dai; 496 int ret; 497 498 /* Find stream from first CPU DAI */ 499 dai = asoc_rtd_to_cpu(rtd, 0); 500 501 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); 502 503 if (IS_ERR(sdw_stream)) { 504 dev_err(rtd->dev, "no stream found for DAI %s", dai->name); 505 return PTR_ERR(sdw_stream); 506 } 507 508 switch (cmd) { 509 case SNDRV_PCM_TRIGGER_START: 510 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 511 case SNDRV_PCM_TRIGGER_RESUME: 512 ret = sdw_enable_stream(sdw_stream); 513 break; 514 515 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 516 case SNDRV_PCM_TRIGGER_SUSPEND: 517 case SNDRV_PCM_TRIGGER_STOP: 518 ret = sdw_disable_stream(sdw_stream); 519 break; 520 default: 521 ret = -EINVAL; 522 break; 523 } 524 525 if (ret) 526 dev_err(rtd->dev, "%s trigger %d failed: %d", __func__, cmd, ret); 527 528 return ret; 529 } 530 531 int sdw_hw_free(struct snd_pcm_substream *substream) 532 { 533 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 534 struct sdw_stream_runtime *sdw_stream; 535 struct snd_soc_dai *dai; 536 537 /* Find stream from first CPU DAI */ 538 dai = asoc_rtd_to_cpu(rtd, 0); 539 540 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); 541 542 if (IS_ERR(sdw_stream)) { 543 dev_err(rtd->dev, "no stream found for DAI %s", dai->name); 544 return PTR_ERR(sdw_stream); 545 } 546 547 return sdw_deprepare_stream(sdw_stream); 548 } 549 550 void sdw_shutdown(struct snd_pcm_substream *substream) 551 { 552 sdw_shutdown_stream(substream); 553 } 554 555 static const struct snd_soc_ops sdw_ops = { 556 .startup = sdw_startup, 557 .prepare = sdw_prepare, 558 .trigger = sdw_trigger, 559 .hw_free = sdw_hw_free, 560 .shutdown = sdw_shutdown, 561 }; 562 563 static struct sof_sdw_codec_info codec_info_list[] = { 564 { 565 .part_id = 0x700, 566 .direction = {true, true}, 567 .dai_name = "rt700-aif1", 568 .init = sof_sdw_rt700_init, 569 .codec_type = SOF_SDW_CODEC_TYPE_JACK, 570 }, 571 { 572 .part_id = 0x711, 573 .version_id = 3, 574 .direction = {true, true}, 575 .dai_name = "rt711-sdca-aif1", 576 .init = sof_sdw_rt711_sdca_init, 577 .exit = sof_sdw_rt711_sdca_exit, 578 .codec_type = SOF_SDW_CODEC_TYPE_JACK, 579 }, 580 { 581 .part_id = 0x711, 582 .version_id = 2, 583 .direction = {true, true}, 584 .dai_name = "rt711-aif1", 585 .init = sof_sdw_rt711_init, 586 .exit = sof_sdw_rt711_exit, 587 .codec_type = SOF_SDW_CODEC_TYPE_JACK, 588 }, 589 { 590 .part_id = 0x1308, 591 .acpi_id = "10EC1308", 592 .direction = {true, false}, 593 .dai_name = "rt1308-aif", 594 .ops = &sof_sdw_rt1308_i2s_ops, 595 .init = sof_sdw_rt_amp_init, 596 .exit = sof_sdw_rt_amp_exit, 597 .codec_type = SOF_SDW_CODEC_TYPE_AMP, 598 }, 599 { 600 .part_id = 0x1316, 601 .direction = {true, true}, 602 .dai_name = "rt1316-aif", 603 .init = sof_sdw_rt_amp_init, 604 .exit = sof_sdw_rt_amp_exit, 605 .codec_type = SOF_SDW_CODEC_TYPE_AMP, 606 }, 607 { 608 .part_id = 0x1318, 609 .direction = {true, true}, 610 .dai_name = "rt1318-aif", 611 .init = sof_sdw_rt_amp_init, 612 .codec_type = SOF_SDW_CODEC_TYPE_AMP, 613 }, 614 { 615 .part_id = 0x714, 616 .version_id = 3, 617 .direction = {false, true}, 618 .ignore_pch_dmic = true, 619 .dai_name = "rt715-aif2", 620 .init = sof_sdw_rt715_sdca_init, 621 .codec_type = SOF_SDW_CODEC_TYPE_MIC, 622 }, 623 { 624 .part_id = 0x715, 625 .version_id = 3, 626 .direction = {false, true}, 627 .ignore_pch_dmic = true, 628 .dai_name = "rt715-aif2", 629 .init = sof_sdw_rt715_sdca_init, 630 .codec_type = SOF_SDW_CODEC_TYPE_MIC, 631 }, 632 { 633 .part_id = 0x714, 634 .version_id = 2, 635 .direction = {false, true}, 636 .ignore_pch_dmic = true, 637 .dai_name = "rt715-aif2", 638 .init = sof_sdw_rt715_init, 639 .codec_type = SOF_SDW_CODEC_TYPE_MIC, 640 }, 641 { 642 .part_id = 0x715, 643 .version_id = 2, 644 .direction = {false, true}, 645 .ignore_pch_dmic = true, 646 .dai_name = "rt715-aif2", 647 .init = sof_sdw_rt715_init, 648 .codec_type = SOF_SDW_CODEC_TYPE_MIC, 649 }, 650 { 651 .part_id = 0x8373, 652 .direction = {true, true}, 653 .dai_name = "max98373-aif1", 654 .init = sof_sdw_mx8373_init, 655 .codec_type = SOF_SDW_CODEC_TYPE_AMP, 656 }, 657 { 658 .part_id = 0x5682, 659 .direction = {true, true}, 660 .dai_name = "rt5682-sdw", 661 .init = sof_sdw_rt5682_init, 662 .codec_type = SOF_SDW_CODEC_TYPE_JACK, 663 }, 664 { 665 .part_id = 0xaaaa, /* generic codec mockup */ 666 .version_id = 0, 667 .direction = {true, true}, 668 .dai_name = "sdw-mockup-aif1", 669 .init = NULL, 670 .codec_type = SOF_SDW_CODEC_TYPE_JACK, 671 }, 672 { 673 .part_id = 0xaa55, /* headset codec mockup */ 674 .version_id = 0, 675 .direction = {true, true}, 676 .dai_name = "sdw-mockup-aif1", 677 .init = NULL, 678 .codec_type = SOF_SDW_CODEC_TYPE_JACK, 679 }, 680 { 681 .part_id = 0x55aa, /* amplifier mockup */ 682 .version_id = 0, 683 .direction = {true, false}, 684 .dai_name = "sdw-mockup-aif1", 685 .init = NULL, 686 .codec_type = SOF_SDW_CODEC_TYPE_AMP, 687 }, 688 { 689 .part_id = 0x5555, 690 .version_id = 0, 691 .direction = {false, true}, 692 .dai_name = "sdw-mockup-aif1", 693 .codec_type = SOF_SDW_CODEC_TYPE_MIC, 694 }, 695 }; 696 697 static inline int find_codec_info_part(u64 adr) 698 { 699 unsigned int part_id, sdw_version; 700 int i; 701 702 part_id = SDW_PART_ID(adr); 703 sdw_version = SDW_VERSION(adr); 704 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) 705 /* 706 * A codec info is for all sdw version with the part id if 707 * version_id is not specified in the codec info. 708 */ 709 if (part_id == codec_info_list[i].part_id && 710 (!codec_info_list[i].version_id || 711 sdw_version == codec_info_list[i].version_id)) 712 return i; 713 714 return -EINVAL; 715 716 } 717 718 static inline int find_codec_info_acpi(const u8 *acpi_id) 719 { 720 int i; 721 722 if (!acpi_id[0]) 723 return -EINVAL; 724 725 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) 726 if (!memcmp(codec_info_list[i].acpi_id, acpi_id, 727 ACPI_ID_LEN)) 728 break; 729 730 if (i == ARRAY_SIZE(codec_info_list)) 731 return -EINVAL; 732 733 return i; 734 } 735 736 /* 737 * get BE dailink number and CPU DAI number based on sdw link adr. 738 * Since some sdw slaves may be aggregated, the CPU DAI number 739 * may be larger than the number of BE dailinks. 740 */ 741 static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_link_adr *links, 742 int *sdw_be_num, int *sdw_cpu_dai_num) 743 { 744 const struct snd_soc_acpi_link_adr *link; 745 int _codec_type = SOF_SDW_CODEC_TYPE_JACK; 746 bool group_visited[SDW_MAX_GROUPS]; 747 bool no_aggregation; 748 int i; 749 750 no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION; 751 *sdw_cpu_dai_num = 0; 752 *sdw_be_num = 0; 753 754 if (!links) 755 return -EINVAL; 756 757 for (i = 0; i < SDW_MAX_GROUPS; i++) 758 group_visited[i] = false; 759 760 for (link = links; link->num_adr; link++) { 761 const struct snd_soc_acpi_endpoint *endpoint; 762 int codec_index; 763 int stream; 764 u64 adr; 765 766 for (i = 0; i < link->num_adr; i++) { 767 adr = link->adr_d[i].adr; 768 codec_index = find_codec_info_part(adr); 769 if (codec_index < 0) 770 return codec_index; 771 772 if (codec_info_list[codec_index].codec_type < _codec_type) 773 dev_warn(dev, 774 "Unexpected address table ordering. Expected order: jack -> amp -> mic\n"); 775 776 _codec_type = codec_info_list[codec_index].codec_type; 777 778 endpoint = link->adr_d[i].endpoints; 779 780 /* count DAI number for playback and capture */ 781 for_each_pcm_streams(stream) { 782 if (!codec_info_list[codec_index].direction[stream]) 783 continue; 784 785 (*sdw_cpu_dai_num)++; 786 787 /* count BE for each non-aggregated slave or group */ 788 if (!endpoint->aggregated || no_aggregation || 789 !group_visited[endpoint->group_id]) 790 (*sdw_be_num)++; 791 } 792 793 if (endpoint->aggregated) 794 group_visited[endpoint->group_id] = true; 795 } 796 } 797 798 return 0; 799 } 800 801 static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, 802 int be_id, char *name, int playback, int capture, 803 struct snd_soc_dai_link_component *cpus, int cpus_num, 804 struct snd_soc_dai_link_component *codecs, int codecs_num, 805 int (*init)(struct snd_soc_pcm_runtime *rtd), 806 const struct snd_soc_ops *ops) 807 { 808 dev_dbg(dev, "create dai link %s, id %d\n", name, be_id); 809 dai_links->id = be_id; 810 dai_links->name = name; 811 dai_links->platforms = platform_component; 812 dai_links->num_platforms = ARRAY_SIZE(platform_component); 813 dai_links->no_pcm = 1; 814 dai_links->cpus = cpus; 815 dai_links->num_cpus = cpus_num; 816 dai_links->codecs = codecs; 817 dai_links->num_codecs = codecs_num; 818 dai_links->dpcm_playback = playback; 819 dai_links->dpcm_capture = capture; 820 dai_links->init = init; 821 dai_links->ops = ops; 822 } 823 824 static bool is_unique_device(const struct snd_soc_acpi_link_adr *link, 825 unsigned int sdw_version, 826 unsigned int mfg_id, 827 unsigned int part_id, 828 unsigned int class_id, 829 int index_in_link 830 ) 831 { 832 int i; 833 834 for (i = 0; i < link->num_adr; i++) { 835 unsigned int sdw1_version, mfg1_id, part1_id, class1_id; 836 u64 adr; 837 838 /* skip itself */ 839 if (i == index_in_link) 840 continue; 841 842 adr = link->adr_d[i].adr; 843 844 sdw1_version = SDW_VERSION(adr); 845 mfg1_id = SDW_MFG_ID(adr); 846 part1_id = SDW_PART_ID(adr); 847 class1_id = SDW_CLASS_ID(adr); 848 849 if (sdw_version == sdw1_version && 850 mfg_id == mfg1_id && 851 part_id == part1_id && 852 class_id == class1_id) 853 return false; 854 } 855 856 return true; 857 } 858 859 static int create_codec_dai_name(struct device *dev, 860 const struct snd_soc_acpi_link_adr *link, 861 struct snd_soc_dai_link_component *codec, 862 int offset, 863 struct snd_soc_codec_conf *codec_conf, 864 int codec_count, 865 int *codec_conf_index, 866 int adr_index) 867 { 868 int _codec_index = -1; 869 int i; 870 871 /* sanity check */ 872 if (*codec_conf_index + link->num_adr - adr_index > codec_count) { 873 dev_err(dev, "codec_conf: out-of-bounds access requested\n"); 874 return -EINVAL; 875 } 876 877 for (i = adr_index; i < link->num_adr; i++) { 878 unsigned int sdw_version, unique_id, mfg_id; 879 unsigned int link_id, part_id, class_id; 880 int codec_index, comp_index; 881 char *codec_str; 882 u64 adr; 883 884 adr = link->adr_d[i].adr; 885 886 sdw_version = SDW_VERSION(adr); 887 link_id = SDW_DISCO_LINK_ID(adr); 888 unique_id = SDW_UNIQUE_ID(adr); 889 mfg_id = SDW_MFG_ID(adr); 890 part_id = SDW_PART_ID(adr); 891 class_id = SDW_CLASS_ID(adr); 892 893 comp_index = i - adr_index + offset; 894 if (is_unique_device(link, sdw_version, mfg_id, part_id, 895 class_id, i)) { 896 codec_str = "sdw:%01x:%04x:%04x:%02x"; 897 codec[comp_index].name = 898 devm_kasprintf(dev, GFP_KERNEL, codec_str, 899 link_id, mfg_id, part_id, 900 class_id); 901 } else { 902 codec_str = "sdw:%01x:%04x:%04x:%02x:%01x"; 903 codec[comp_index].name = 904 devm_kasprintf(dev, GFP_KERNEL, codec_str, 905 link_id, mfg_id, part_id, 906 class_id, unique_id); 907 } 908 909 if (!codec[comp_index].name) 910 return -ENOMEM; 911 912 codec_index = find_codec_info_part(adr); 913 if (codec_index < 0) 914 return codec_index; 915 if (_codec_index != -1 && codec_index != _codec_index) { 916 dev_dbg(dev, "Different devices on the same sdw link\n"); 917 break; 918 } 919 _codec_index = codec_index; 920 921 codec[comp_index].dai_name = 922 codec_info_list[codec_index].dai_name; 923 924 codec_conf[*codec_conf_index].dlc = codec[comp_index]; 925 codec_conf[*codec_conf_index].name_prefix = link->adr_d[i].name_prefix; 926 927 ++*codec_conf_index; 928 } 929 930 return 0; 931 } 932 933 static int set_codec_init_func(struct snd_soc_card *card, 934 const struct snd_soc_acpi_link_adr *link, 935 struct snd_soc_dai_link *dai_links, 936 bool playback, int group_id, int adr_index) 937 { 938 int i = adr_index; 939 940 do { 941 /* 942 * Initialize the codec. If codec is part of an aggregated 943 * group (group_id>0), initialize all codecs belonging to 944 * same group. 945 * The first link should start with link->adr_d[adr_index] 946 * because that is the device that we want to initialize and 947 * we should end immediately if it is not aggregated (group_id=0) 948 */ 949 for ( ; i < link->num_adr; i++) { 950 int codec_index; 951 952 codec_index = find_codec_info_part(link->adr_d[i].adr); 953 954 if (codec_index < 0) 955 return codec_index; 956 /* The group_id is > 0 iff the codec is aggregated */ 957 if (link->adr_d[i].endpoints->group_id != group_id) 958 continue; 959 if (codec_info_list[codec_index].init) 960 codec_info_list[codec_index].init(card, 961 link, 962 dai_links, 963 &codec_info_list[codec_index], 964 playback); 965 if (!group_id) 966 return 0; 967 } 968 i = 0; 969 link++; 970 } while (link->mask); 971 972 return 0; 973 } 974 975 /* 976 * check endpoint status in slaves and gather link ID for all slaves in 977 * the same group to generate different CPU DAI. Now only support 978 * one sdw link with all slaves set with only single group id. 979 * 980 * one slave on one sdw link with aggregated = 0 981 * one sdw BE DAI <---> one-cpu DAI <---> one-codec DAI 982 * 983 * two or more slaves on one sdw link with aggregated = 0 984 * one sdw BE DAI <---> one-cpu DAI <---> multi-codec DAIs 985 * 986 * multiple links with multiple slaves with aggregated = 1 987 * one sdw BE DAI <---> 1 .. N CPU DAIs <----> 1 .. N codec DAIs 988 */ 989 static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link, 990 struct device *dev, int *cpu_dai_id, int *cpu_dai_num, 991 int *codec_num, unsigned int *group_id, 992 bool *group_generated, int adr_index) 993 { 994 const struct snd_soc_acpi_adr_device *adr_d; 995 const struct snd_soc_acpi_link_adr *adr_next; 996 bool no_aggregation; 997 int index = 0; 998 int i; 999 1000 no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION; 1001 adr_d = &adr_link->adr_d[adr_index]; 1002 1003 /* make sure the link mask has a single bit set */ 1004 if (!is_power_of_2(adr_link->mask)) 1005 return -EINVAL; 1006 1007 cpu_dai_id[index++] = ffs(adr_link->mask) - 1; 1008 if (!adr_d->endpoints->aggregated || no_aggregation) { 1009 *cpu_dai_num = 1; 1010 *codec_num = 1; 1011 *group_id = 0; 1012 return 0; 1013 } 1014 1015 *group_id = adr_d->endpoints->group_id; 1016 1017 /* Count endpoints with the same group_id in the adr_link */ 1018 *codec_num = 0; 1019 for (i = 0; i < adr_link->num_adr; i++) { 1020 if (adr_link->adr_d[i].endpoints->aggregated && 1021 adr_link->adr_d[i].endpoints->group_id == *group_id) 1022 (*codec_num)++; 1023 } 1024 1025 /* gather other link ID of slaves in the same group */ 1026 for (adr_next = adr_link + 1; adr_next && adr_next->num_adr; 1027 adr_next++) { 1028 const struct snd_soc_acpi_endpoint *endpoint; 1029 1030 endpoint = adr_next->adr_d->endpoints; 1031 if (!endpoint->aggregated || 1032 endpoint->group_id != *group_id) 1033 continue; 1034 1035 /* make sure the link mask has a single bit set */ 1036 if (!is_power_of_2(adr_next->mask)) 1037 return -EINVAL; 1038 1039 if (index >= SDW_MAX_CPU_DAIS) { 1040 dev_err(dev, " cpu_dai_id array overflows"); 1041 return -EINVAL; 1042 } 1043 1044 cpu_dai_id[index++] = ffs(adr_next->mask) - 1; 1045 for (i = 0; i < adr_next->num_adr; i++) { 1046 if (adr_next->adr_d[i].endpoints->aggregated && 1047 adr_next->adr_d[i].endpoints->group_id == *group_id) 1048 (*codec_num)++; 1049 } 1050 } 1051 1052 /* 1053 * indicate CPU DAIs for this group have been generated 1054 * to avoid generating CPU DAIs for this group again. 1055 */ 1056 group_generated[*group_id] = true; 1057 *cpu_dai_num = index; 1058 1059 return 0; 1060 } 1061 1062 static const char * const type_strings[] = {"SimpleJack", "SmartAmp", "SmartMic"}; 1063 1064 static int create_sdw_dailink(struct snd_soc_card *card, 1065 struct device *dev, int *link_index, 1066 struct snd_soc_dai_link *dai_links, 1067 int sdw_be_num, int sdw_cpu_dai_num, 1068 struct snd_soc_dai_link_component *cpus, 1069 const struct snd_soc_acpi_link_adr *link, 1070 int *cpu_id, bool *group_generated, 1071 struct snd_soc_codec_conf *codec_conf, 1072 int codec_count, int *link_id, 1073 int *codec_conf_index, 1074 bool *ignore_pch_dmic, 1075 bool append_codec_type, 1076 int adr_index) 1077 { 1078 const struct snd_soc_acpi_link_adr *link_next; 1079 struct snd_soc_dai_link_component *codecs; 1080 int cpu_dai_id[SDW_MAX_CPU_DAIS]; 1081 int cpu_dai_num, cpu_dai_index; 1082 unsigned int group_id; 1083 int codec_idx = 0; 1084 int i = 0, j = 0; 1085 int codec_index; 1086 int codec_num; 1087 int stream; 1088 int ret; 1089 int k; 1090 1091 ret = get_slave_info(link, dev, cpu_dai_id, &cpu_dai_num, &codec_num, 1092 &group_id, group_generated, adr_index); 1093 if (ret) 1094 return ret; 1095 1096 codecs = devm_kcalloc(dev, codec_num, sizeof(*codecs), GFP_KERNEL); 1097 if (!codecs) 1098 return -ENOMEM; 1099 1100 /* generate codec name on different links in the same group */ 1101 for (link_next = link; link_next && link_next->num_adr && 1102 i < cpu_dai_num; link_next++) { 1103 const struct snd_soc_acpi_endpoint *endpoints; 1104 1105 endpoints = link_next->adr_d->endpoints; 1106 if (group_id && (!endpoints->aggregated || 1107 endpoints->group_id != group_id)) 1108 continue; 1109 1110 /* skip the link excluded by this processed group */ 1111 if (cpu_dai_id[i] != ffs(link_next->mask) - 1) 1112 continue; 1113 1114 ret = create_codec_dai_name(dev, link_next, codecs, codec_idx, 1115 codec_conf, codec_count, codec_conf_index, adr_index); 1116 if (ret < 0) 1117 return ret; 1118 1119 /* check next link to create codec dai in the processed group */ 1120 i++; 1121 codec_idx += link_next->num_adr; 1122 } 1123 1124 /* find codec info to create BE DAI */ 1125 codec_index = find_codec_info_part(link->adr_d[adr_index].adr); 1126 if (codec_index < 0) 1127 return codec_index; 1128 1129 if (codec_info_list[codec_index].ignore_pch_dmic) 1130 *ignore_pch_dmic = true; 1131 1132 /* Shift the first amplifier's *link_id to SDW_AMP_DAI_ID */ 1133 if (codec_info_list[codec_index].codec_type == SOF_SDW_CODEC_TYPE_AMP && 1134 *link_id < SDW_AMP_DAI_ID) 1135 *link_id = SDW_AMP_DAI_ID; 1136 1137 /* 1138 * DAI ID is fixed at SDW_DMIC_DAI_ID for MICs to 1139 * keep sdw DMIC and HDMI setting static in UCM 1140 */ 1141 if (codec_info_list[codec_index].codec_type == SOF_SDW_CODEC_TYPE_MIC && 1142 *link_id < SDW_DMIC_DAI_ID) 1143 *link_id = SDW_DMIC_DAI_ID; 1144 1145 cpu_dai_index = *cpu_id; 1146 for_each_pcm_streams(stream) { 1147 char *name, *cpu_name; 1148 int playback, capture; 1149 static const char * const sdw_stream_name[] = { 1150 "SDW%d-Playback", 1151 "SDW%d-Capture", 1152 "SDW%d-Playback-%s", 1153 "SDW%d-Capture-%s", 1154 }; 1155 1156 if (!codec_info_list[codec_index].direction[stream]) 1157 continue; 1158 1159 /* create stream name according to first link id */ 1160 if (append_codec_type) { 1161 name = devm_kasprintf(dev, GFP_KERNEL, 1162 sdw_stream_name[stream + 2], cpu_dai_id[0], 1163 type_strings[codec_info_list[codec_index].codec_type]); 1164 } else { 1165 name = devm_kasprintf(dev, GFP_KERNEL, 1166 sdw_stream_name[stream], cpu_dai_id[0]); 1167 } 1168 if (!name) 1169 return -ENOMEM; 1170 1171 /* 1172 * generate CPU DAI name base on the sdw link ID and 1173 * PIN ID with offset of 2 according to sdw dai driver. 1174 */ 1175 for (k = 0; k < cpu_dai_num; k++) { 1176 cpu_name = devm_kasprintf(dev, GFP_KERNEL, 1177 "SDW%d Pin%d", cpu_dai_id[k], 1178 j + SDW_INTEL_BIDIR_PDI_BASE); 1179 if (!cpu_name) 1180 return -ENOMEM; 1181 1182 if (cpu_dai_index >= sdw_cpu_dai_num) { 1183 dev_err(dev, "invalid cpu dai index %d", 1184 cpu_dai_index); 1185 return -EINVAL; 1186 } 1187 1188 cpus[cpu_dai_index++].dai_name = cpu_name; 1189 } 1190 1191 /* 1192 * We create sdw dai links at first stage, so link index should 1193 * not be larger than sdw_be_num 1194 */ 1195 if (*link_index >= sdw_be_num) { 1196 dev_err(dev, "invalid dai link index %d", *link_index); 1197 return -EINVAL; 1198 } 1199 1200 if (*cpu_id >= sdw_cpu_dai_num) { 1201 dev_err(dev, " invalid cpu dai index %d", *cpu_id); 1202 return -EINVAL; 1203 } 1204 1205 playback = (stream == SNDRV_PCM_STREAM_PLAYBACK); 1206 capture = (stream == SNDRV_PCM_STREAM_CAPTURE); 1207 init_dai_link(dev, dai_links + *link_index, (*link_id)++, name, 1208 playback, capture, 1209 cpus + *cpu_id, cpu_dai_num, 1210 codecs, codec_num, 1211 NULL, &sdw_ops); 1212 1213 /* 1214 * SoundWire DAILINKs use 'stream' functions and Bank Switch operations 1215 * based on wait_for_completion(), tag them as 'nonatomic'. 1216 */ 1217 dai_links[*link_index].nonatomic = true; 1218 1219 ret = set_codec_init_func(card, link, dai_links + (*link_index)++, 1220 playback, group_id, adr_index); 1221 if (ret < 0) { 1222 dev_err(dev, "failed to init codec %d", codec_index); 1223 return ret; 1224 } 1225 1226 *cpu_id += cpu_dai_num; 1227 j++; 1228 } 1229 1230 return 0; 1231 } 1232 1233 #define IDISP_CODEC_MASK 0x4 1234 1235 static int sof_card_codec_conf_alloc(struct device *dev, 1236 struct snd_soc_acpi_mach_params *mach_params, 1237 struct snd_soc_codec_conf **codec_conf, 1238 int *codec_conf_count) 1239 { 1240 const struct snd_soc_acpi_link_adr *adr_link; 1241 struct snd_soc_codec_conf *c_conf; 1242 int num_codecs = 0; 1243 int i; 1244 1245 adr_link = mach_params->links; 1246 if (!adr_link) 1247 return -EINVAL; 1248 1249 /* generate DAI links by each sdw link */ 1250 for (; adr_link->num_adr; adr_link++) { 1251 for (i = 0; i < adr_link->num_adr; i++) { 1252 if (!adr_link->adr_d[i].name_prefix) { 1253 dev_err(dev, "codec 0x%llx does not have a name prefix\n", 1254 adr_link->adr_d[i].adr); 1255 return -EINVAL; 1256 } 1257 } 1258 num_codecs += adr_link->num_adr; 1259 } 1260 1261 c_conf = devm_kzalloc(dev, num_codecs * sizeof(*c_conf), GFP_KERNEL); 1262 if (!c_conf) 1263 return -ENOMEM; 1264 1265 *codec_conf = c_conf; 1266 *codec_conf_count = num_codecs; 1267 1268 return 0; 1269 } 1270 1271 static int sof_card_dai_links_create(struct device *dev, 1272 struct snd_soc_acpi_mach *mach, 1273 struct snd_soc_card *card) 1274 { 1275 int ssp_num, sdw_be_num = 0, hdmi_num = 0, dmic_num; 1276 struct mc_private *ctx = snd_soc_card_get_drvdata(card); 1277 struct snd_soc_dai_link_component *idisp_components; 1278 struct snd_soc_dai_link_component *ssp_components; 1279 struct snd_soc_acpi_mach_params *mach_params; 1280 const struct snd_soc_acpi_link_adr *adr_link; 1281 struct snd_soc_dai_link_component *cpus; 1282 struct snd_soc_codec_conf *codec_conf; 1283 bool append_codec_type = false; 1284 bool ignore_pch_dmic = false; 1285 int codec_conf_count; 1286 int codec_conf_index = 0; 1287 bool group_generated[SDW_MAX_GROUPS]; 1288 int ssp_codec_index, ssp_mask; 1289 struct snd_soc_dai_link *links; 1290 int num_links, link_index = 0; 1291 char *name, *cpu_name; 1292 int total_cpu_dai_num; 1293 int sdw_cpu_dai_num; 1294 int i, j, be_id = 0; 1295 int cpu_id = 0; 1296 int comp_num; 1297 int ret; 1298 1299 mach_params = &mach->mach_params; 1300 1301 /* allocate codec conf, will be populated when dailinks are created */ 1302 ret = sof_card_codec_conf_alloc(dev, mach_params, &codec_conf, &codec_conf_count); 1303 if (ret < 0) 1304 return ret; 1305 1306 /* reset amp_num to ensure amp_num++ starts from 0 in each probe */ 1307 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) 1308 codec_info_list[i].amp_num = 0; 1309 1310 if (mach_params->codec_mask & IDISP_CODEC_MASK) { 1311 ctx->idisp_codec = true; 1312 1313 if (sof_sdw_quirk & SOF_SDW_TGL_HDMI) 1314 hdmi_num = SOF_TGL_HDMI_COUNT; 1315 else 1316 hdmi_num = SOF_PRE_TGL_HDMI_COUNT; 1317 } 1318 1319 ssp_mask = SOF_SSP_GET_PORT(sof_sdw_quirk); 1320 /* 1321 * on generic tgl platform, I2S or sdw mode is supported 1322 * based on board rework. A ACPI device is registered in 1323 * system only when I2S mode is supported, not sdw mode. 1324 * Here check ACPI ID to confirm I2S is supported. 1325 */ 1326 ssp_codec_index = find_codec_info_acpi(mach->id); 1327 ssp_num = ssp_codec_index >= 0 ? hweight_long(ssp_mask) : 0; 1328 comp_num = hdmi_num + ssp_num; 1329 1330 ret = get_sdw_dailink_info(dev, mach_params->links, 1331 &sdw_be_num, &sdw_cpu_dai_num); 1332 if (ret < 0) { 1333 dev_err(dev, "failed to get sdw link info %d", ret); 1334 return ret; 1335 } 1336 1337 /* enable dmic01 & dmic16k */ 1338 dmic_num = (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num) ? 2 : 0; 1339 comp_num += dmic_num; 1340 1341 if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) 1342 comp_num++; 1343 1344 dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d", sdw_be_num, ssp_num, 1345 dmic_num, ctx->idisp_codec ? hdmi_num : 0); 1346 1347 /* allocate BE dailinks */ 1348 num_links = comp_num + sdw_be_num; 1349 links = devm_kcalloc(dev, num_links, sizeof(*links), GFP_KERNEL); 1350 1351 /* allocated CPU DAIs */ 1352 total_cpu_dai_num = comp_num + sdw_cpu_dai_num; 1353 cpus = devm_kcalloc(dev, total_cpu_dai_num, sizeof(*cpus), 1354 GFP_KERNEL); 1355 1356 if (!links || !cpus) 1357 return -ENOMEM; 1358 1359 /* SDW */ 1360 if (!sdw_be_num) 1361 goto SSP; 1362 1363 adr_link = mach_params->links; 1364 if (!adr_link) 1365 return -EINVAL; 1366 1367 /* 1368 * SoundWire Slaves aggregated in the same group may be 1369 * located on different hardware links. Clear array to indicate 1370 * CPU DAIs for this group have not been generated. 1371 */ 1372 for (i = 0; i < SDW_MAX_GROUPS; i++) 1373 group_generated[i] = false; 1374 1375 for (; adr_link->num_adr; adr_link++) { 1376 /* 1377 * If there are two or more different devices on the same sdw link, we have to 1378 * append the codec type to the dai link name to prevent duplicated dai link name. 1379 * The same type devices on the same sdw link will be in the same 1380 * snd_soc_acpi_adr_device array. They won't be described in different adr_links. 1381 */ 1382 for (i = 0; i < adr_link->num_adr; i++) { 1383 for (j = 0; j < i; j++) { 1384 if ((SDW_PART_ID(adr_link->adr_d[i].adr) != 1385 SDW_PART_ID(adr_link->adr_d[j].adr)) || 1386 (SDW_MFG_ID(adr_link->adr_d[i].adr) != 1387 SDW_MFG_ID(adr_link->adr_d[i].adr))) { 1388 append_codec_type = true; 1389 goto out; 1390 } 1391 } 1392 } 1393 } 1394 out: 1395 1396 /* generate DAI links by each sdw link */ 1397 for (adr_link = mach_params->links ; adr_link->num_adr; adr_link++) { 1398 for (i = 0; i < adr_link->num_adr; i++) { 1399 const struct snd_soc_acpi_endpoint *endpoint; 1400 1401 endpoint = adr_link->adr_d[i].endpoints; 1402 if (endpoint->aggregated && !endpoint->group_id) { 1403 dev_err(dev, "invalid group id on link %x", 1404 adr_link->mask); 1405 continue; 1406 } 1407 1408 /* this group has been generated */ 1409 if (endpoint->aggregated && 1410 group_generated[endpoint->group_id]) 1411 continue; 1412 1413 ret = create_sdw_dailink(card, dev, &link_index, links, sdw_be_num, 1414 sdw_cpu_dai_num, cpus, adr_link, 1415 &cpu_id, group_generated, 1416 codec_conf, codec_conf_count, 1417 &be_id, &codec_conf_index, 1418 &ignore_pch_dmic, append_codec_type, i); 1419 if (ret < 0) { 1420 dev_err(dev, "failed to create dai link %d", link_index); 1421 return ret; 1422 } 1423 } 1424 } 1425 1426 SSP: 1427 /* SSP */ 1428 if (!ssp_num) 1429 goto DMIC; 1430 1431 for (i = 0, j = 0; ssp_mask; i++, ssp_mask >>= 1) { 1432 struct sof_sdw_codec_info *info; 1433 int playback, capture; 1434 char *codec_name; 1435 1436 if (!(ssp_mask & 0x1)) 1437 continue; 1438 1439 name = devm_kasprintf(dev, GFP_KERNEL, 1440 "SSP%d-Codec", i); 1441 if (!name) 1442 return -ENOMEM; 1443 1444 cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i); 1445 if (!cpu_name) 1446 return -ENOMEM; 1447 1448 ssp_components = devm_kzalloc(dev, sizeof(*ssp_components), 1449 GFP_KERNEL); 1450 if (!ssp_components) 1451 return -ENOMEM; 1452 1453 info = &codec_info_list[ssp_codec_index]; 1454 codec_name = devm_kasprintf(dev, GFP_KERNEL, "i2c-%s:0%d", 1455 info->acpi_id, j++); 1456 if (!codec_name) 1457 return -ENOMEM; 1458 1459 ssp_components->name = codec_name; 1460 ssp_components->dai_name = info->dai_name; 1461 cpus[cpu_id].dai_name = cpu_name; 1462 1463 playback = info->direction[SNDRV_PCM_STREAM_PLAYBACK]; 1464 capture = info->direction[SNDRV_PCM_STREAM_CAPTURE]; 1465 init_dai_link(dev, links + link_index, be_id, name, 1466 playback, capture, 1467 cpus + cpu_id, 1, 1468 ssp_components, 1, 1469 NULL, info->ops); 1470 1471 ret = info->init(card, NULL, links + link_index, info, 0); 1472 if (ret < 0) 1473 return ret; 1474 1475 INC_ID(be_id, cpu_id, link_index); 1476 } 1477 1478 DMIC: 1479 /* dmic */ 1480 if (dmic_num > 0) { 1481 if (ignore_pch_dmic) { 1482 dev_warn(dev, "Ignoring PCH DMIC\n"); 1483 goto HDMI; 1484 } 1485 cpus[cpu_id].dai_name = "DMIC01 Pin"; 1486 init_dai_link(dev, links + link_index, be_id, "dmic01", 1487 0, 1, // DMIC only supports capture 1488 cpus + cpu_id, 1, 1489 dmic_component, 1, 1490 sof_sdw_dmic_init, NULL); 1491 INC_ID(be_id, cpu_id, link_index); 1492 1493 cpus[cpu_id].dai_name = "DMIC16k Pin"; 1494 init_dai_link(dev, links + link_index, be_id, "dmic16k", 1495 0, 1, // DMIC only supports capture 1496 cpus + cpu_id, 1, 1497 dmic_component, 1, 1498 /* don't call sof_sdw_dmic_init() twice */ 1499 NULL, NULL); 1500 INC_ID(be_id, cpu_id, link_index); 1501 } 1502 1503 HDMI: 1504 /* HDMI */ 1505 if (hdmi_num > 0) { 1506 idisp_components = devm_kcalloc(dev, hdmi_num, 1507 sizeof(*idisp_components), 1508 GFP_KERNEL); 1509 if (!idisp_components) 1510 return -ENOMEM; 1511 } 1512 1513 for (i = 0; i < hdmi_num; i++) { 1514 name = devm_kasprintf(dev, GFP_KERNEL, 1515 "iDisp%d", i + 1); 1516 if (!name) 1517 return -ENOMEM; 1518 1519 if (ctx->idisp_codec) { 1520 idisp_components[i].name = "ehdaudio0D2"; 1521 idisp_components[i].dai_name = devm_kasprintf(dev, 1522 GFP_KERNEL, 1523 "intel-hdmi-hifi%d", 1524 i + 1); 1525 if (!idisp_components[i].dai_name) 1526 return -ENOMEM; 1527 } else { 1528 idisp_components[i] = asoc_dummy_dlc; 1529 } 1530 1531 cpu_name = devm_kasprintf(dev, GFP_KERNEL, 1532 "iDisp%d Pin", i + 1); 1533 if (!cpu_name) 1534 return -ENOMEM; 1535 1536 cpus[cpu_id].dai_name = cpu_name; 1537 init_dai_link(dev, links + link_index, be_id, name, 1538 1, 0, // HDMI only supports playback 1539 cpus + cpu_id, 1, 1540 idisp_components + i, 1, 1541 sof_sdw_hdmi_init, NULL); 1542 INC_ID(be_id, cpu_id, link_index); 1543 } 1544 1545 if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) { 1546 int port = (sof_sdw_quirk & SOF_BT_OFFLOAD_SSP_MASK) >> 1547 SOF_BT_OFFLOAD_SSP_SHIFT; 1548 1549 name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); 1550 if (!name) 1551 return -ENOMEM; 1552 1553 cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port); 1554 if (!cpu_name) 1555 return -ENOMEM; 1556 1557 cpus[cpu_id].dai_name = cpu_name; 1558 init_dai_link(dev, links + link_index, be_id, name, 1, 1, 1559 cpus + cpu_id, 1, &asoc_dummy_dlc, 1, NULL, NULL); 1560 } 1561 1562 card->dai_link = links; 1563 card->num_links = num_links; 1564 1565 card->codec_conf = codec_conf; 1566 card->num_configs = codec_conf_count; 1567 1568 return 0; 1569 } 1570 1571 static int sof_sdw_card_late_probe(struct snd_soc_card *card) 1572 { 1573 struct mc_private *ctx = snd_soc_card_get_drvdata(card); 1574 int ret = 0; 1575 int i; 1576 1577 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { 1578 if (codec_info_list[i].codec_card_late_probe) { 1579 ret = codec_info_list[i].codec_card_late_probe(card); 1580 1581 if (ret < 0) 1582 return ret; 1583 } 1584 } 1585 1586 if (ctx->idisp_codec) 1587 ret = sof_sdw_hdmi_card_late_probe(card); 1588 1589 return ret; 1590 } 1591 1592 /* SoC card */ 1593 static const char sdw_card_long_name[] = "Intel Soundwire SOF"; 1594 1595 static struct snd_soc_card card_sof_sdw = { 1596 .name = "soundwire", 1597 .owner = THIS_MODULE, 1598 .late_probe = sof_sdw_card_late_probe, 1599 }; 1600 1601 static void mc_dailink_exit_loop(struct snd_soc_card *card) 1602 { 1603 struct snd_soc_dai_link *link; 1604 int ret; 1605 int i, j; 1606 1607 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { 1608 if (!codec_info_list[i].exit) 1609 continue; 1610 /* 1611 * We don't need to call .exit function if there is no matched 1612 * dai link found. 1613 */ 1614 for_each_card_prelinks(card, j, link) { 1615 if (!strcmp(link->codecs[0].dai_name, 1616 codec_info_list[i].dai_name)) { 1617 ret = codec_info_list[i].exit(card, link); 1618 if (ret) 1619 dev_warn(card->dev, 1620 "codec exit failed %d\n", 1621 ret); 1622 break; 1623 } 1624 } 1625 } 1626 } 1627 1628 static int mc_probe(struct platform_device *pdev) 1629 { 1630 struct snd_soc_card *card = &card_sof_sdw; 1631 struct snd_soc_acpi_mach *mach; 1632 struct mc_private *ctx; 1633 int amp_num = 0, i; 1634 int ret; 1635 1636 dev_dbg(&pdev->dev, "Entry\n"); 1637 1638 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 1639 if (!ctx) 1640 return -ENOMEM; 1641 1642 dmi_check_system(sof_sdw_quirk_table); 1643 1644 if (quirk_override != -1) { 1645 dev_info(&pdev->dev, "Overriding quirk 0x%lx => 0x%x\n", 1646 sof_sdw_quirk, quirk_override); 1647 sof_sdw_quirk = quirk_override; 1648 } 1649 log_quirks(&pdev->dev); 1650 1651 INIT_LIST_HEAD(&ctx->hdmi_pcm_list); 1652 1653 card->dev = &pdev->dev; 1654 snd_soc_card_set_drvdata(card, ctx); 1655 1656 mach = pdev->dev.platform_data; 1657 ret = sof_card_dai_links_create(&pdev->dev, mach, 1658 card); 1659 if (ret < 0) 1660 return ret; 1661 1662 /* 1663 * the default amp_num is zero for each codec and 1664 * amp_num will only be increased for active amp 1665 * codecs on used platform 1666 */ 1667 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) 1668 amp_num += codec_info_list[i].amp_num; 1669 1670 card->components = devm_kasprintf(card->dev, GFP_KERNEL, 1671 "cfg-spk:%d cfg-amp:%d", 1672 (sof_sdw_quirk & SOF_SDW_FOUR_SPK) 1673 ? 4 : 2, amp_num); 1674 if (!card->components) 1675 return -ENOMEM; 1676 1677 if (mach->mach_params.dmic_num) { 1678 card->components = devm_kasprintf(card->dev, GFP_KERNEL, 1679 "%s mic:dmic cfg-mics:%d", 1680 card->components, 1681 mach->mach_params.dmic_num); 1682 if (!card->components) 1683 return -ENOMEM; 1684 } 1685 1686 card->long_name = sdw_card_long_name; 1687 1688 /* Register the card */ 1689 ret = devm_snd_soc_register_card(&pdev->dev, card); 1690 if (ret) { 1691 dev_err(card->dev, "snd_soc_register_card failed %d\n", ret); 1692 mc_dailink_exit_loop(card); 1693 return ret; 1694 } 1695 1696 platform_set_drvdata(pdev, card); 1697 1698 return ret; 1699 } 1700 1701 static void mc_remove(struct platform_device *pdev) 1702 { 1703 struct snd_soc_card *card = platform_get_drvdata(pdev); 1704 1705 mc_dailink_exit_loop(card); 1706 } 1707 1708 static struct platform_driver sof_sdw_driver = { 1709 .driver = { 1710 .name = "sof_sdw", 1711 .pm = &snd_soc_pm_ops, 1712 }, 1713 .probe = mc_probe, 1714 .remove_new = mc_remove, 1715 }; 1716 1717 module_platform_driver(sof_sdw_driver); 1718 1719 MODULE_DESCRIPTION("ASoC SoundWire Generic Machine driver"); 1720 MODULE_AUTHOR("Bard Liao <yung-chuan.liao@linux.intel.com>"); 1721 MODULE_AUTHOR("Rander Wang <rander.wang@linux.intel.com>"); 1722 MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>"); 1723 MODULE_LICENSE("GPL v2"); 1724 MODULE_ALIAS("platform:sof_sdw"); 1725 MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); 1726 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); 1727