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