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