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