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