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