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