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