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 #define SDW_MAX_LINKS 4 26 27 /* To store SDW Pin index for each SoundWire link */ 28 static unsigned int sdw_pin_index[SDW_MAX_LINKS]; 29 30 static void log_quirks(struct device *dev) 31 { 32 if (SOF_JACK_JDSRC(sof_sdw_quirk)) 33 dev_dbg(dev, "quirk realtek,jack-detect-source %ld\n", 34 SOF_JACK_JDSRC(sof_sdw_quirk)); 35 if (sof_sdw_quirk & SOF_SDW_FOUR_SPK) 36 dev_dbg(dev, "quirk SOF_SDW_FOUR_SPK enabled\n"); 37 if (sof_sdw_quirk & SOF_SDW_TGL_HDMI) 38 dev_dbg(dev, "quirk SOF_SDW_TGL_HDMI enabled\n"); 39 if (sof_sdw_quirk & SOF_SDW_PCH_DMIC) 40 dev_dbg(dev, "quirk SOF_SDW_PCH_DMIC enabled\n"); 41 if (SOF_SSP_GET_PORT(sof_sdw_quirk)) 42 dev_dbg(dev, "SSP port %ld\n", 43 SOF_SSP_GET_PORT(sof_sdw_quirk)); 44 if (sof_sdw_quirk & SOF_SDW_NO_AGGREGATION) 45 dev_dbg(dev, "quirk SOF_SDW_NO_AGGREGATION enabled\n"); 46 } 47 48 static int sof_sdw_quirk_cb(const struct dmi_system_id *id) 49 { 50 sof_sdw_quirk = (unsigned long)id->driver_data; 51 return 1; 52 } 53 54 static const struct dmi_system_id sof_sdw_quirk_table[] = { 55 /* CometLake devices */ 56 { 57 .callback = sof_sdw_quirk_cb, 58 .matches = { 59 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 60 DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"), 61 }, 62 .driver_data = (void *)SOF_SDW_PCH_DMIC, 63 }, 64 { 65 .callback = sof_sdw_quirk_cb, 66 .matches = { 67 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 68 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6") 69 }, 70 .driver_data = (void *)RT711_JD2, 71 }, 72 { 73 /* early version of SKU 09C6 */ 74 .callback = sof_sdw_quirk_cb, 75 .matches = { 76 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 77 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983") 78 }, 79 .driver_data = (void *)RT711_JD2, 80 }, 81 { 82 .callback = sof_sdw_quirk_cb, 83 .matches = { 84 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 85 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"), 86 }, 87 .driver_data = (void *)(RT711_JD2 | 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_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 RT711_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 RT711_JD2), 129 }, 130 { 131 /* another SKU of Dell Latitude 9520 */ 132 .callback = sof_sdw_quirk_cb, 133 .matches = { 134 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 135 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3F") 136 }, 137 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 138 RT711_JD2), 139 }, 140 { 141 /* Dell XPS 9710 */ 142 .callback = sof_sdw_quirk_cb, 143 .matches = { 144 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 145 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5D") 146 }, 147 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 148 RT711_JD2 | 149 SOF_SDW_FOUR_SPK), 150 }, 151 { 152 .callback = sof_sdw_quirk_cb, 153 .matches = { 154 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 155 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") 156 }, 157 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 158 RT711_JD2 | 159 SOF_SDW_FOUR_SPK), 160 }, 161 { 162 .callback = sof_sdw_quirk_cb, 163 .matches = { 164 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 165 DMI_MATCH(DMI_PRODUCT_NAME, "Volteer"), 166 }, 167 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 168 SOF_SDW_PCH_DMIC | 169 SOF_SDW_FOUR_SPK | 170 SOF_BT_OFFLOAD_SSP(2) | 171 SOF_SSP_BT_OFFLOAD_PRESENT), 172 }, 173 { 174 .callback = sof_sdw_quirk_cb, 175 .matches = { 176 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 177 DMI_MATCH(DMI_PRODUCT_NAME, "Ripto"), 178 }, 179 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 180 SOF_SDW_PCH_DMIC | 181 SOF_SDW_FOUR_SPK), 182 }, 183 { 184 /* 185 * this entry covers multiple HP SKUs. The family name 186 * does not seem robust enough, so we use a partial 187 * match that ignores the product name suffix 188 * (e.g. 15-eb1xxx, 14t-ea000 or 13-aw2xxx) 189 */ 190 .callback = sof_sdw_quirk_cb, 191 .matches = { 192 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 193 DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Conv"), 194 }, 195 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 196 SOF_SDW_PCH_DMIC | 197 RT711_JD1), 198 }, 199 { 200 /* 201 * this entry covers HP Spectre x360 where the DMI information 202 * changed somehow 203 */ 204 .callback = sof_sdw_quirk_cb, 205 .matches = { 206 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 207 DMI_MATCH(DMI_BOARD_NAME, "8709"), 208 }, 209 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 210 SOF_SDW_PCH_DMIC | 211 RT711_JD1), 212 }, 213 { 214 /* NUC15 'Bishop County' LAPBC510 and LAPBC710 skews */ 215 .callback = sof_sdw_quirk_cb, 216 .matches = { 217 DMI_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"), 218 DMI_MATCH(DMI_PRODUCT_NAME, "LAPBC"), 219 }, 220 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 221 SOF_SDW_PCH_DMIC | 222 RT711_JD1), 223 }, 224 { 225 /* NUC15 LAPBC710 skews */ 226 .callback = sof_sdw_quirk_cb, 227 .matches = { 228 DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), 229 DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"), 230 }, 231 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 232 SOF_SDW_PCH_DMIC | 233 RT711_JD1), 234 }, 235 { 236 /* NUC15 'Rooks County' LAPRC510 and LAPRC710 skews */ 237 .callback = sof_sdw_quirk_cb, 238 .matches = { 239 DMI_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"), 240 DMI_MATCH(DMI_PRODUCT_NAME, "LAPRC"), 241 }, 242 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 243 SOF_SDW_PCH_DMIC | 244 RT711_JD2_100K), 245 }, 246 { 247 /* NUC15 LAPRC710 skews */ 248 .callback = sof_sdw_quirk_cb, 249 .matches = { 250 DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), 251 DMI_MATCH(DMI_BOARD_NAME, "LAPRC710"), 252 }, 253 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 254 SOF_SDW_PCH_DMIC | 255 RT711_JD2_100K), 256 }, 257 /* TigerLake-SDCA devices */ 258 { 259 .callback = sof_sdw_quirk_cb, 260 .matches = { 261 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 262 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32") 263 }, 264 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 265 RT711_JD2 | 266 SOF_SDW_FOUR_SPK), 267 }, 268 { 269 .callback = sof_sdw_quirk_cb, 270 .matches = { 271 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 272 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A45") 273 }, 274 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 275 RT711_JD2), 276 }, 277 /* AlderLake devices */ 278 { 279 .callback = sof_sdw_quirk_cb, 280 .matches = { 281 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 282 DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"), 283 }, 284 .driver_data = (void *)(RT711_JD2_100K | 285 SOF_SDW_TGL_HDMI | 286 SOF_BT_OFFLOAD_SSP(2) | 287 SOF_SSP_BT_OFFLOAD_PRESENT), 288 }, 289 { 290 .callback = sof_sdw_quirk_cb, 291 .matches = { 292 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 293 DMI_MATCH(DMI_PRODUCT_NAME, "Brya"), 294 }, 295 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 296 SOF_SDW_PCH_DMIC | 297 SOF_SDW_FOUR_SPK | 298 SOF_BT_OFFLOAD_SSP(2) | 299 SOF_SSP_BT_OFFLOAD_PRESENT), 300 }, 301 { 302 .callback = sof_sdw_quirk_cb, 303 .matches = { 304 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 305 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AF0") 306 }, 307 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 308 RT711_JD2 | 309 SOF_SDW_FOUR_SPK), 310 }, 311 { 312 .callback = sof_sdw_quirk_cb, 313 .matches = { 314 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 315 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AF3"), 316 }, 317 /* No Jack */ 318 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 319 SOF_SDW_FOUR_SPK), 320 }, 321 { 322 .callback = sof_sdw_quirk_cb, 323 .matches = { 324 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 325 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFE") 326 }, 327 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 328 RT711_JD2 | 329 SOF_SDW_FOUR_SPK), 330 }, 331 { 332 .callback = sof_sdw_quirk_cb, 333 .matches = { 334 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 335 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFF") 336 }, 337 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 338 RT711_JD2 | 339 SOF_SDW_FOUR_SPK), 340 }, 341 { 342 .callback = sof_sdw_quirk_cb, 343 .matches = { 344 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 345 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B00") 346 }, 347 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 348 RT711_JD2 | 349 SOF_SDW_FOUR_SPK), 350 }, 351 { 352 .callback = sof_sdw_quirk_cb, 353 .matches = { 354 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 355 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B01") 356 }, 357 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 358 RT711_JD2 | 359 SOF_SDW_FOUR_SPK), 360 }, 361 { 362 .callback = sof_sdw_quirk_cb, 363 .matches = { 364 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 365 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B11") 366 }, 367 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 368 RT711_JD2 | 369 SOF_SDW_FOUR_SPK), 370 }, 371 { 372 .callback = sof_sdw_quirk_cb, 373 .matches = { 374 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 375 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B12") 376 }, 377 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 378 RT711_JD2 | 379 SOF_SDW_FOUR_SPK), 380 }, 381 { 382 .callback = sof_sdw_quirk_cb, 383 .matches = { 384 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 385 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B13"), 386 }, 387 /* No Jack */ 388 .driver_data = (void *)SOF_SDW_TGL_HDMI, 389 }, 390 { 391 .callback = sof_sdw_quirk_cb, 392 .matches = { 393 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 394 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B14"), 395 }, 396 /* No Jack */ 397 .driver_data = (void *)SOF_SDW_TGL_HDMI, 398 }, 399 400 { 401 .callback = sof_sdw_quirk_cb, 402 .matches = { 403 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 404 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B29"), 405 }, 406 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 407 RT711_JD2 | 408 SOF_SDW_FOUR_SPK), 409 }, 410 { 411 .callback = sof_sdw_quirk_cb, 412 .matches = { 413 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 414 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B34"), 415 }, 416 /* No Jack */ 417 .driver_data = (void *)SOF_SDW_TGL_HDMI, 418 }, 419 { 420 .callback = sof_sdw_quirk_cb, 421 .matches = { 422 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 423 DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16-k0xxx"), 424 }, 425 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 426 RT711_JD2), 427 }, 428 /* RaptorLake devices */ 429 { 430 .callback = sof_sdw_quirk_cb, 431 .matches = { 432 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 433 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0BDA") 434 }, 435 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 436 RT711_JD2 | 437 SOF_SDW_FOUR_SPK), 438 }, 439 { 440 .callback = sof_sdw_quirk_cb, 441 .matches = { 442 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 443 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C0F") 444 }, 445 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 446 RT711_JD2), 447 }, 448 { 449 .callback = sof_sdw_quirk_cb, 450 .matches = { 451 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 452 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C10"), 453 }, 454 /* No Jack */ 455 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 456 SOF_SDW_FOUR_SPK), 457 }, 458 { 459 .callback = sof_sdw_quirk_cb, 460 .matches = { 461 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 462 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C11") 463 }, 464 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 465 RT711_JD2 | 466 SOF_SDW_FOUR_SPK), 467 }, 468 { 469 .callback = sof_sdw_quirk_cb, 470 .matches = { 471 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 472 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C40") 473 }, 474 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 475 RT711_JD2 | 476 SOF_SDW_FOUR_SPK), 477 }, 478 { 479 .callback = sof_sdw_quirk_cb, 480 .matches = { 481 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 482 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C4F") 483 }, 484 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 485 RT711_JD2 | 486 SOF_SDW_FOUR_SPK), 487 }, 488 /* MeteorLake devices */ 489 { 490 .callback = sof_sdw_quirk_cb, 491 .matches = { 492 DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_mtlrvp"), 493 }, 494 .driver_data = (void *)(RT711_JD1), 495 }, 496 { 497 .callback = sof_sdw_quirk_cb, 498 .matches = { 499 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 500 DMI_MATCH(DMI_PRODUCT_NAME, "Meteor Lake Client Platform"), 501 }, 502 .driver_data = (void *)(RT711_JD2_100K), 503 }, 504 { 505 .callback = sof_sdw_quirk_cb, 506 .matches = { 507 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 508 DMI_MATCH(DMI_PRODUCT_NAME, "Rex"), 509 }, 510 .driver_data = (void *)(SOF_SDW_PCH_DMIC | 511 SOF_BT_OFFLOAD_SSP(1) | 512 SOF_SSP_BT_OFFLOAD_PRESENT), 513 }, 514 { 515 .callback = sof_sdw_quirk_cb, 516 .matches = { 517 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 518 DMI_MATCH(DMI_PRODUCT_NAME, "OMEN Transcend Gaming Laptop"), 519 }, 520 .driver_data = (void *)(RT711_JD2), 521 }, 522 523 /* LunarLake devices */ 524 { 525 .callback = sof_sdw_quirk_cb, 526 .matches = { 527 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 528 DMI_MATCH(DMI_PRODUCT_NAME, "Lunar Lake Client Platform"), 529 }, 530 .driver_data = (void *)(RT711_JD2), 531 }, 532 {} 533 }; 534 535 static struct snd_soc_dai_link_component dmic_component[] = { 536 { 537 .name = "dmic-codec", 538 .dai_name = "dmic-hifi", 539 } 540 }; 541 542 static struct snd_soc_dai_link_component platform_component[] = { 543 { 544 /* name might be overridden during probe */ 545 .name = "0000:00:1f.3" 546 } 547 }; 548 549 /* these wrappers are only needed to avoid typecast compilation errors */ 550 int sdw_startup(struct snd_pcm_substream *substream) 551 { 552 return sdw_startup_stream(substream); 553 } 554 555 int sdw_prepare(struct snd_pcm_substream *substream) 556 { 557 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 558 struct sdw_stream_runtime *sdw_stream; 559 struct snd_soc_dai *dai; 560 561 /* Find stream from first CPU DAI */ 562 dai = asoc_rtd_to_cpu(rtd, 0); 563 564 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); 565 if (IS_ERR(sdw_stream)) { 566 dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); 567 return PTR_ERR(sdw_stream); 568 } 569 570 return sdw_prepare_stream(sdw_stream); 571 } 572 573 int sdw_trigger(struct snd_pcm_substream *substream, int cmd) 574 { 575 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 576 struct sdw_stream_runtime *sdw_stream; 577 struct snd_soc_dai *dai; 578 int ret; 579 580 /* Find stream from first CPU DAI */ 581 dai = asoc_rtd_to_cpu(rtd, 0); 582 583 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); 584 if (IS_ERR(sdw_stream)) { 585 dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); 586 return PTR_ERR(sdw_stream); 587 } 588 589 switch (cmd) { 590 case SNDRV_PCM_TRIGGER_START: 591 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 592 case SNDRV_PCM_TRIGGER_RESUME: 593 ret = sdw_enable_stream(sdw_stream); 594 break; 595 596 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 597 case SNDRV_PCM_TRIGGER_SUSPEND: 598 case SNDRV_PCM_TRIGGER_STOP: 599 ret = sdw_disable_stream(sdw_stream); 600 break; 601 default: 602 ret = -EINVAL; 603 break; 604 } 605 606 if (ret) 607 dev_err(rtd->dev, "%s trigger %d failed: %d\n", __func__, cmd, ret); 608 609 return ret; 610 } 611 612 int sdw_hw_params(struct snd_pcm_substream *substream, 613 struct snd_pcm_hw_params *params) 614 { 615 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 616 int ch = params_channels(params); 617 struct snd_soc_dai *codec_dai; 618 struct snd_soc_dai *cpu_dai; 619 unsigned int ch_mask; 620 int num_codecs; 621 int step; 622 int i; 623 int j; 624 625 if (!rtd->dai_link->codec_ch_maps) 626 return 0; 627 628 /* Identical data will be sent to all codecs in playback */ 629 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 630 ch_mask = GENMASK(ch - 1, 0); 631 step = 0; 632 } else { 633 num_codecs = rtd->dai_link->num_codecs; 634 635 if (ch < num_codecs || ch % num_codecs != 0) { 636 dev_err(rtd->dev, "Channels number %d is invalid when codec number = %d\n", 637 ch, num_codecs); 638 return -EINVAL; 639 } 640 641 ch_mask = GENMASK(ch / num_codecs - 1, 0); 642 step = hweight_long(ch_mask); 643 644 } 645 646 /* 647 * The captured data will be combined from each cpu DAI if the dai 648 * link has more than one codec DAIs. Set codec channel mask and 649 * ASoC will set the corresponding channel numbers for each cpu dai. 650 */ 651 for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 652 for_each_rtd_codec_dais(rtd, j, codec_dai) { 653 if (rtd->dai_link->codec_ch_maps[j].connected_cpu_id != i) 654 continue; 655 rtd->dai_link->codec_ch_maps[j].ch_mask = ch_mask << (j * step); 656 } 657 } 658 return 0; 659 } 660 661 int sdw_hw_free(struct snd_pcm_substream *substream) 662 { 663 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 664 struct sdw_stream_runtime *sdw_stream; 665 struct snd_soc_dai *dai; 666 667 /* Find stream from first CPU DAI */ 668 dai = asoc_rtd_to_cpu(rtd, 0); 669 670 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); 671 if (IS_ERR(sdw_stream)) { 672 dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); 673 return PTR_ERR(sdw_stream); 674 } 675 676 return sdw_deprepare_stream(sdw_stream); 677 } 678 679 void sdw_shutdown(struct snd_pcm_substream *substream) 680 { 681 sdw_shutdown_stream(substream); 682 } 683 684 static const struct snd_soc_ops sdw_ops = { 685 .startup = sdw_startup, 686 .prepare = sdw_prepare, 687 .trigger = sdw_trigger, 688 .hw_params = sdw_hw_params, 689 .hw_free = sdw_hw_free, 690 .shutdown = sdw_shutdown, 691 }; 692 693 static struct sof_sdw_codec_info codec_info_list[] = { 694 { 695 .part_id = 0x700, 696 .dais = { 697 { 698 .direction = {true, true}, 699 .dai_name = "rt700-aif1", 700 .dai_type = SOF_SDW_DAI_TYPE_JACK, 701 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 702 .init = sof_sdw_rt700_init, 703 }, 704 }, 705 .dai_num = 1, 706 }, 707 { 708 .part_id = 0x711, 709 .version_id = 3, 710 .dais = { 711 { 712 .direction = {true, true}, 713 .dai_name = "rt711-sdca-aif1", 714 .dai_type = SOF_SDW_DAI_TYPE_JACK, 715 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 716 .init = sof_sdw_rt_sdca_jack_init, 717 .exit = sof_sdw_rt_sdca_jack_exit, 718 }, 719 }, 720 .dai_num = 1, 721 }, 722 { 723 .part_id = 0x711, 724 .version_id = 2, 725 .dais = { 726 { 727 .direction = {true, true}, 728 .dai_name = "rt711-aif1", 729 .dai_type = SOF_SDW_DAI_TYPE_JACK, 730 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 731 .init = sof_sdw_rt711_init, 732 .exit = sof_sdw_rt711_exit, 733 }, 734 }, 735 .dai_num = 1, 736 }, 737 { 738 .part_id = 0x712, 739 .version_id = 3, 740 .dais = { 741 { 742 .direction = {true, true}, 743 .dai_name = "rt712-sdca-aif1", 744 .dai_type = SOF_SDW_DAI_TYPE_JACK, 745 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 746 .init = sof_sdw_rt_sdca_jack_init, 747 .exit = sof_sdw_rt_sdca_jack_exit, 748 }, 749 { 750 .direction = {true, false}, 751 .dai_name = "rt712-sdca-aif2", 752 .dai_type = SOF_SDW_DAI_TYPE_AMP, 753 .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, 754 .init = sof_sdw_rt712_spk_init, 755 }, 756 }, 757 .dai_num = 2, 758 }, 759 { 760 .part_id = 0x1712, 761 .version_id = 3, 762 .dais = { 763 { 764 .direction = {false, true}, 765 .dai_name = "rt712-sdca-dmic-aif1", 766 .dai_type = SOF_SDW_DAI_TYPE_MIC, 767 .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, 768 .init = sof_sdw_rt712_sdca_dmic_init, 769 }, 770 }, 771 .dai_num = 1, 772 }, 773 { 774 .part_id = 0x713, 775 .version_id = 3, 776 .dais = { 777 { 778 .direction = {true, true}, 779 .dai_name = "rt712-sdca-aif1", 780 .dai_type = SOF_SDW_DAI_TYPE_JACK, 781 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 782 .init = sof_sdw_rt_sdca_jack_init, 783 .exit = sof_sdw_rt_sdca_jack_exit, 784 }, 785 }, 786 .dai_num = 1, 787 }, 788 { 789 .part_id = 0x1713, 790 .version_id = 3, 791 .dais = { 792 { 793 .direction = {false, true}, 794 .dai_name = "rt712-sdca-dmic-aif1", 795 .dai_type = SOF_SDW_DAI_TYPE_MIC, 796 .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, 797 .init = sof_sdw_rt712_sdca_dmic_init, 798 }, 799 }, 800 .dai_num = 1, 801 }, 802 { 803 .part_id = 0x1308, 804 .acpi_id = "10EC1308", 805 .dais = { 806 { 807 .direction = {true, false}, 808 .dai_name = "rt1308-aif", 809 .dai_type = SOF_SDW_DAI_TYPE_AMP, 810 .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, 811 .init = sof_sdw_rt_amp_init, 812 .exit = sof_sdw_rt_amp_exit, 813 }, 814 }, 815 .dai_num = 1, 816 .ops = &sof_sdw_rt1308_i2s_ops, 817 }, 818 { 819 .part_id = 0x1316, 820 .dais = { 821 { 822 .direction = {true, true}, 823 .dai_name = "rt1316-aif", 824 .dai_type = SOF_SDW_DAI_TYPE_AMP, 825 .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, 826 .init = sof_sdw_rt_amp_init, 827 .exit = sof_sdw_rt_amp_exit, 828 }, 829 }, 830 .dai_num = 1, 831 }, 832 { 833 .part_id = 0x1318, 834 .dais = { 835 { 836 .direction = {true, true}, 837 .dai_name = "rt1318-aif", 838 .dai_type = SOF_SDW_DAI_TYPE_AMP, 839 .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, 840 .init = sof_sdw_rt_amp_init, 841 .exit = sof_sdw_rt_amp_exit, 842 }, 843 }, 844 .dai_num = 1, 845 }, 846 { 847 .part_id = 0x714, 848 .version_id = 3, 849 .ignore_pch_dmic = true, 850 .dais = { 851 { 852 .direction = {false, true}, 853 .dai_name = "rt715-aif2", 854 .dai_type = SOF_SDW_DAI_TYPE_MIC, 855 .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, 856 .init = sof_sdw_rt715_sdca_init, 857 }, 858 }, 859 .dai_num = 1, 860 }, 861 { 862 .part_id = 0x715, 863 .version_id = 3, 864 .ignore_pch_dmic = true, 865 .dais = { 866 { 867 .direction = {false, true}, 868 .dai_name = "rt715-aif2", 869 .dai_type = SOF_SDW_DAI_TYPE_MIC, 870 .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, 871 .init = sof_sdw_rt715_sdca_init, 872 }, 873 }, 874 .dai_num = 1, 875 }, 876 { 877 .part_id = 0x714, 878 .version_id = 2, 879 .ignore_pch_dmic = true, 880 .dais = { 881 { 882 .direction = {false, true}, 883 .dai_name = "rt715-aif2", 884 .dai_type = SOF_SDW_DAI_TYPE_MIC, 885 .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, 886 .init = sof_sdw_rt715_init, 887 }, 888 }, 889 .dai_num = 1, 890 }, 891 { 892 .part_id = 0x715, 893 .version_id = 2, 894 .ignore_pch_dmic = true, 895 .dais = { 896 { 897 .direction = {false, true}, 898 .dai_name = "rt715-aif2", 899 .dai_type = SOF_SDW_DAI_TYPE_MIC, 900 .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, 901 .init = sof_sdw_rt715_init, 902 }, 903 }, 904 .dai_num = 1, 905 }, 906 { 907 .part_id = 0x8373, 908 .dais = { 909 { 910 .direction = {true, true}, 911 .dai_name = "max98373-aif1", 912 .dai_type = SOF_SDW_DAI_TYPE_AMP, 913 .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, 914 .init = sof_sdw_maxim_init, 915 }, 916 }, 917 .dai_num = 1, 918 }, 919 { 920 .part_id = 0x8363, 921 .dais = { 922 { 923 .direction = {true, false}, 924 .dai_name = "max98363-aif1", 925 .dai_type = SOF_SDW_DAI_TYPE_AMP, 926 .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, 927 .init = sof_sdw_maxim_init, 928 }, 929 }, 930 .dai_num = 1, 931 }, 932 { 933 .part_id = 0x5682, 934 .dais = { 935 { 936 .direction = {true, true}, 937 .dai_name = "rt5682-sdw", 938 .dai_type = SOF_SDW_DAI_TYPE_JACK, 939 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 940 .init = sof_sdw_rt5682_init, 941 }, 942 }, 943 .dai_num = 1, 944 }, 945 { 946 .part_id = 0x3556, 947 .dais = { 948 { 949 .direction = {true, true}, 950 .dai_name = "cs35l56-sdw1", 951 .dai_type = SOF_SDW_DAI_TYPE_AMP, 952 .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, 953 .init = sof_sdw_cs_amp_init, 954 }, 955 }, 956 .dai_num = 1, 957 }, 958 { 959 .part_id = 0x4242, 960 .dais = { 961 { 962 .direction = {true, true}, 963 .dai_name = "cs42l42-sdw", 964 .dai_type = SOF_SDW_DAI_TYPE_JACK, 965 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 966 .init = sof_sdw_cs42l42_init, 967 }, 968 }, 969 .dai_num = 1, 970 }, 971 { 972 .part_id = 0xaaaa, /* generic codec mockup */ 973 .version_id = 0, 974 .dais = { 975 { 976 .direction = {true, true}, 977 .dai_name = "sdw-mockup-aif1", 978 .dai_type = SOF_SDW_DAI_TYPE_JACK, 979 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 980 .init = NULL, 981 }, 982 }, 983 .dai_num = 1, 984 }, 985 { 986 .part_id = 0xaa55, /* headset codec mockup */ 987 .version_id = 0, 988 .dais = { 989 { 990 .direction = {true, true}, 991 .dai_name = "sdw-mockup-aif1", 992 .dai_type = SOF_SDW_DAI_TYPE_JACK, 993 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 994 .init = NULL, 995 }, 996 }, 997 .dai_num = 1, 998 }, 999 { 1000 .part_id = 0x55aa, /* amplifier mockup */ 1001 .version_id = 0, 1002 .dais = { 1003 { 1004 .direction = {true, true}, 1005 .dai_name = "sdw-mockup-aif1", 1006 .dai_type = SOF_SDW_DAI_TYPE_AMP, 1007 .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, 1008 .init = NULL, 1009 }, 1010 }, 1011 .dai_num = 1, 1012 }, 1013 { 1014 .part_id = 0x5555, 1015 .version_id = 0, 1016 .dais = { 1017 { 1018 .dai_name = "sdw-mockup-aif1", 1019 .direction = {false, true}, 1020 .dai_type = SOF_SDW_DAI_TYPE_MIC, 1021 .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, 1022 .init = NULL, 1023 }, 1024 }, 1025 .dai_num = 1, 1026 }, 1027 }; 1028 1029 static inline int find_codec_info_part(const u64 adr) 1030 { 1031 unsigned int part_id, sdw_version; 1032 int i; 1033 1034 part_id = SDW_PART_ID(adr); 1035 sdw_version = SDW_VERSION(adr); 1036 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) 1037 /* 1038 * A codec info is for all sdw version with the part id if 1039 * version_id is not specified in the codec info. 1040 */ 1041 if (part_id == codec_info_list[i].part_id && 1042 (!codec_info_list[i].version_id || 1043 sdw_version == codec_info_list[i].version_id)) 1044 return i; 1045 1046 return -EINVAL; 1047 1048 } 1049 1050 static inline int find_codec_info_acpi(const u8 *acpi_id) 1051 { 1052 int i; 1053 1054 if (!acpi_id[0]) 1055 return -EINVAL; 1056 1057 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) 1058 if (!memcmp(codec_info_list[i].acpi_id, acpi_id, ACPI_ID_LEN)) 1059 return i; 1060 1061 return -EINVAL; 1062 } 1063 1064 /* 1065 * get BE dailink number and CPU DAI number based on sdw link adr. 1066 * Since some sdw slaves may be aggregated, the CPU DAI number 1067 * may be larger than the number of BE dailinks. 1068 */ 1069 static int get_dailink_info(struct device *dev, 1070 const struct snd_soc_acpi_link_adr *adr_link, 1071 int *sdw_be_num, int *sdw_cpu_dai_num, int *codecs_num) 1072 { 1073 bool group_visited[SDW_MAX_GROUPS]; 1074 bool no_aggregation; 1075 int i; 1076 int j; 1077 1078 no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION; 1079 *sdw_cpu_dai_num = 0; 1080 *sdw_be_num = 0; 1081 1082 if (!adr_link) 1083 return -EINVAL; 1084 1085 for (i = 0; i < SDW_MAX_GROUPS; i++) 1086 group_visited[i] = false; 1087 1088 for (; adr_link->num_adr; adr_link++) { 1089 const struct snd_soc_acpi_endpoint *endpoint; 1090 struct sof_sdw_codec_info *codec_info; 1091 int codec_index; 1092 int stream; 1093 u64 adr; 1094 1095 /* make sure the link mask has a single bit set */ 1096 if (!is_power_of_2(adr_link->mask)) 1097 return -EINVAL; 1098 1099 for (i = 0; i < adr_link->num_adr; i++) { 1100 adr = adr_link->adr_d[i].adr; 1101 codec_index = find_codec_info_part(adr); 1102 if (codec_index < 0) 1103 return codec_index; 1104 1105 codec_info = &codec_info_list[codec_index]; 1106 1107 *codecs_num += codec_info->dai_num; 1108 1109 if (!adr_link->adr_d[i].name_prefix) { 1110 dev_err(dev, "codec 0x%llx does not have a name prefix\n", 1111 adr_link->adr_d[i].adr); 1112 return -EINVAL; 1113 } 1114 1115 endpoint = adr_link->adr_d[i].endpoints; 1116 if (endpoint->aggregated && !endpoint->group_id) { 1117 dev_err(dev, "invalid group id on link %x\n", 1118 adr_link->mask); 1119 return -EINVAL; 1120 } 1121 1122 for (j = 0; j < codec_info->dai_num; j++) { 1123 /* count DAI number for playback and capture */ 1124 for_each_pcm_streams(stream) { 1125 if (!codec_info->dais[j].direction[stream]) 1126 continue; 1127 1128 (*sdw_cpu_dai_num)++; 1129 1130 /* count BE for each non-aggregated slave or group */ 1131 if (!endpoint->aggregated || no_aggregation || 1132 !group_visited[endpoint->group_id]) 1133 (*sdw_be_num)++; 1134 } 1135 } 1136 1137 if (endpoint->aggregated) 1138 group_visited[endpoint->group_id] = true; 1139 } 1140 } 1141 1142 return 0; 1143 } 1144 1145 static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, 1146 int be_id, char *name, int playback, int capture, 1147 struct snd_soc_dai_link_component *cpus, int cpus_num, 1148 struct snd_soc_dai_link_component *codecs, int codecs_num, 1149 int (*init)(struct snd_soc_pcm_runtime *rtd), 1150 const struct snd_soc_ops *ops) 1151 { 1152 dev_dbg(dev, "create dai link %s, id %d\n", name, be_id); 1153 dai_links->id = be_id; 1154 dai_links->name = name; 1155 dai_links->platforms = platform_component; 1156 dai_links->num_platforms = ARRAY_SIZE(platform_component); 1157 dai_links->no_pcm = 1; 1158 dai_links->cpus = cpus; 1159 dai_links->num_cpus = cpus_num; 1160 dai_links->codecs = codecs; 1161 dai_links->num_codecs = codecs_num; 1162 dai_links->dpcm_playback = playback; 1163 dai_links->dpcm_capture = capture; 1164 dai_links->init = init; 1165 dai_links->ops = ops; 1166 } 1167 1168 static bool is_unique_device(const struct snd_soc_acpi_link_adr *adr_link, 1169 unsigned int sdw_version, 1170 unsigned int mfg_id, 1171 unsigned int part_id, 1172 unsigned int class_id, 1173 int index_in_link) 1174 { 1175 int i; 1176 1177 for (i = 0; i < adr_link->num_adr; i++) { 1178 unsigned int sdw1_version, mfg1_id, part1_id, class1_id; 1179 u64 adr; 1180 1181 /* skip itself */ 1182 if (i == index_in_link) 1183 continue; 1184 1185 adr = adr_link->adr_d[i].adr; 1186 1187 sdw1_version = SDW_VERSION(adr); 1188 mfg1_id = SDW_MFG_ID(adr); 1189 part1_id = SDW_PART_ID(adr); 1190 class1_id = SDW_CLASS_ID(adr); 1191 1192 if (sdw_version == sdw1_version && 1193 mfg_id == mfg1_id && 1194 part_id == part1_id && 1195 class_id == class1_id) 1196 return false; 1197 } 1198 1199 return true; 1200 } 1201 1202 static int fill_sdw_codec_dlc(struct device *dev, 1203 const struct snd_soc_acpi_link_adr *adr_link, 1204 struct snd_soc_dai_link_component *codec, 1205 int adr_index, int dai_index) 1206 { 1207 unsigned int sdw_version, unique_id, mfg_id, link_id, part_id, class_id; 1208 u64 adr = adr_link->adr_d[adr_index].adr; 1209 int codec_index; 1210 1211 codec_index = find_codec_info_part(adr); 1212 if (codec_index < 0) 1213 return codec_index; 1214 1215 sdw_version = SDW_VERSION(adr); 1216 link_id = SDW_DISCO_LINK_ID(adr); 1217 unique_id = SDW_UNIQUE_ID(adr); 1218 mfg_id = SDW_MFG_ID(adr); 1219 part_id = SDW_PART_ID(adr); 1220 class_id = SDW_CLASS_ID(adr); 1221 1222 if (codec_info_list[codec_index].codec_name) 1223 codec->name = devm_kstrdup(dev, 1224 codec_info_list[codec_index].codec_name, 1225 GFP_KERNEL); 1226 else if (is_unique_device(adr_link, sdw_version, mfg_id, part_id, 1227 class_id, adr_index)) 1228 codec->name = devm_kasprintf(dev, GFP_KERNEL, 1229 "sdw:0:%01x:%04x:%04x:%02x", link_id, 1230 mfg_id, part_id, class_id); 1231 else 1232 codec->name = devm_kasprintf(dev, GFP_KERNEL, 1233 "sdw:0:%01x:%04x:%04x:%02x:%01x", link_id, 1234 mfg_id, part_id, class_id, unique_id); 1235 1236 if (!codec->name) 1237 return -ENOMEM; 1238 1239 codec->dai_name = codec_info_list[codec_index].dais[dai_index].dai_name; 1240 1241 return 0; 1242 } 1243 1244 static int set_codec_init_func(struct snd_soc_card *card, 1245 const struct snd_soc_acpi_link_adr *adr_link, 1246 struct snd_soc_dai_link *dai_links, 1247 bool playback, int group_id, int adr_index, int dai_index) 1248 { 1249 int i = adr_index; 1250 1251 do { 1252 /* 1253 * Initialize the codec. If codec is part of an aggregated 1254 * group (group_id>0), initialize all codecs belonging to 1255 * same group. 1256 * The first link should start with adr_link->adr_d[adr_index] 1257 * because that is the device that we want to initialize and 1258 * we should end immediately if it is not aggregated (group_id=0) 1259 */ 1260 for ( ; i < adr_link->num_adr; i++) { 1261 int codec_index; 1262 1263 codec_index = find_codec_info_part(adr_link->adr_d[i].adr); 1264 if (codec_index < 0) 1265 return codec_index; 1266 1267 /* The group_id is > 0 iff the codec is aggregated */ 1268 if (adr_link->adr_d[i].endpoints->group_id != group_id) 1269 continue; 1270 1271 if (codec_info_list[codec_index].dais[dai_index].init) 1272 codec_info_list[codec_index].dais[dai_index].init(card, 1273 adr_link, 1274 dai_links, 1275 &codec_info_list[codec_index], 1276 playback); 1277 if (!group_id) 1278 return 0; 1279 } 1280 1281 i = 0; 1282 adr_link++; 1283 } while (adr_link->mask); 1284 1285 return 0; 1286 } 1287 1288 /* 1289 * check endpoint status in slaves and gather link ID for all slaves in 1290 * the same group to generate different CPU DAI. Now only support 1291 * one sdw link with all slaves set with only single group id. 1292 * 1293 * one slave on one sdw link with aggregated = 0 1294 * one sdw BE DAI <---> one-cpu DAI <---> one-codec DAI 1295 * 1296 * two or more slaves on one sdw link with aggregated = 0 1297 * one sdw BE DAI <---> one-cpu DAI <---> multi-codec DAIs 1298 * 1299 * multiple links with multiple slaves with aggregated = 1 1300 * one sdw BE DAI <---> 1 .. N CPU DAIs <----> 1 .. N codec DAIs 1301 */ 1302 static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link, 1303 struct device *dev, int *cpu_dai_id, int *cpu_dai_num, 1304 int *codec_num, unsigned int *group_id, 1305 int adr_index) 1306 { 1307 bool no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION; 1308 int i; 1309 1310 if (!adr_link->adr_d[adr_index].endpoints->aggregated || no_aggregation) { 1311 cpu_dai_id[0] = ffs(adr_link->mask) - 1; 1312 *cpu_dai_num = 1; 1313 *codec_num = 1; 1314 *group_id = 0; 1315 return 0; 1316 } 1317 1318 *codec_num = 0; 1319 *cpu_dai_num = 0; 1320 *group_id = adr_link->adr_d[adr_index].endpoints->group_id; 1321 1322 /* Count endpoints with the same group_id in the adr_link */ 1323 for (; adr_link && adr_link->num_adr; adr_link++) { 1324 unsigned int link_codecs = 0; 1325 1326 for (i = 0; i < adr_link->num_adr; i++) { 1327 if (adr_link->adr_d[i].endpoints->aggregated && 1328 adr_link->adr_d[i].endpoints->group_id == *group_id) 1329 link_codecs++; 1330 } 1331 1332 if (link_codecs) { 1333 *codec_num += link_codecs; 1334 1335 if (*cpu_dai_num >= SDW_MAX_CPU_DAIS) { 1336 dev_err(dev, "cpu_dai_id array overflowed\n"); 1337 return -EINVAL; 1338 } 1339 1340 cpu_dai_id[(*cpu_dai_num)++] = ffs(adr_link->mask) - 1; 1341 } 1342 } 1343 1344 return 0; 1345 } 1346 1347 static void set_dailink_map(struct snd_soc_dai_link_codec_ch_map *sdw_codec_ch_maps, 1348 int codec_num, int cpu_num) 1349 { 1350 int step; 1351 int i; 1352 1353 step = codec_num / cpu_num; 1354 for (i = 0; i < codec_num; i++) 1355 sdw_codec_ch_maps[i].connected_cpu_id = i / step; 1356 } 1357 1358 static const char * const type_strings[] = {"SimpleJack", "SmartAmp", "SmartMic"}; 1359 1360 static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, 1361 struct snd_soc_dai_link *dai_links, 1362 int sdw_be_num, int sdw_cpu_dai_num, 1363 struct snd_soc_dai_link_component *cpus, 1364 const struct snd_soc_acpi_link_adr *adr_link, 1365 int *cpu_id, struct snd_soc_codec_conf *codec_conf, 1366 int codec_count, int *be_id, 1367 int *codec_conf_index, 1368 bool *ignore_pch_dmic, 1369 bool append_dai_type, 1370 int adr_index, 1371 int dai_index) 1372 { 1373 struct device *dev = card->dev; 1374 const struct snd_soc_acpi_link_adr *adr_link_next; 1375 struct snd_soc_dai_link_component *codecs; 1376 struct sof_sdw_codec_info *codec_info; 1377 int cpu_dai_id[SDW_MAX_CPU_DAIS]; 1378 int cpu_dai_num, cpu_dai_index; 1379 unsigned int group_id; 1380 int codec_dlc_index = 0; 1381 int codec_index; 1382 int codec_num; 1383 int stream; 1384 int i = 0; 1385 int j, k; 1386 int ret; 1387 1388 ret = get_slave_info(adr_link, dev, cpu_dai_id, &cpu_dai_num, &codec_num, 1389 &group_id, adr_index); 1390 if (ret) 1391 return ret; 1392 1393 codecs = devm_kcalloc(dev, codec_num, sizeof(*codecs), GFP_KERNEL); 1394 if (!codecs) 1395 return -ENOMEM; 1396 1397 /* generate codec name on different links in the same group */ 1398 j = adr_index; 1399 for (adr_link_next = adr_link; adr_link_next && adr_link_next->num_adr && 1400 i < cpu_dai_num; adr_link_next++) { 1401 /* skip the link excluded by this processed group */ 1402 if (cpu_dai_id[i] != ffs(adr_link_next->mask) - 1) 1403 continue; 1404 1405 /* j reset after loop, adr_index only applies to first link */ 1406 for (; j < adr_link_next->num_adr && codec_dlc_index < codec_num; j++) { 1407 const struct snd_soc_acpi_endpoint *endpoints; 1408 1409 endpoints = adr_link_next->adr_d[j].endpoints; 1410 1411 if (group_id && (!endpoints->aggregated || 1412 endpoints->group_id != group_id)) 1413 continue; 1414 1415 /* sanity check */ 1416 if (*codec_conf_index >= codec_count) { 1417 dev_err(dev, "codec_conf array overflowed\n"); 1418 return -EINVAL; 1419 } 1420 1421 ret = fill_sdw_codec_dlc(dev, adr_link_next, 1422 &codecs[codec_dlc_index], 1423 j, dai_index); 1424 if (ret) 1425 return ret; 1426 1427 codec_conf[*codec_conf_index].dlc = codecs[codec_dlc_index]; 1428 codec_conf[*codec_conf_index].name_prefix = 1429 adr_link_next->adr_d[j].name_prefix; 1430 1431 codec_dlc_index++; 1432 (*codec_conf_index)++; 1433 } 1434 j = 0; 1435 1436 /* check next link to create codec dai in the processed group */ 1437 i++; 1438 } 1439 1440 /* find codec info to create BE DAI */ 1441 codec_index = find_codec_info_part(adr_link->adr_d[adr_index].adr); 1442 if (codec_index < 0) 1443 return codec_index; 1444 codec_info = &codec_info_list[codec_index]; 1445 1446 if (codec_info->ignore_pch_dmic) 1447 *ignore_pch_dmic = true; 1448 1449 cpu_dai_index = *cpu_id; 1450 for_each_pcm_streams(stream) { 1451 struct snd_soc_dai_link_codec_ch_map *sdw_codec_ch_maps; 1452 char *name, *cpu_name; 1453 int playback, capture; 1454 static const char * const sdw_stream_name[] = { 1455 "SDW%d-Playback", 1456 "SDW%d-Capture", 1457 "SDW%d-Playback-%s", 1458 "SDW%d-Capture-%s", 1459 }; 1460 1461 if (!codec_info->dais[dai_index].direction[stream]) 1462 continue; 1463 1464 *be_id = codec_info->dais[dai_index].dailink[stream]; 1465 if (*be_id < 0) { 1466 dev_err(dev, "Invalid dailink id %d\n", *be_id); 1467 return -EINVAL; 1468 } 1469 1470 sdw_codec_ch_maps = devm_kcalloc(dev, codec_num, 1471 sizeof(*sdw_codec_ch_maps), GFP_KERNEL); 1472 if (!sdw_codec_ch_maps) 1473 return -ENOMEM; 1474 1475 /* create stream name according to first link id */ 1476 if (append_dai_type) { 1477 name = devm_kasprintf(dev, GFP_KERNEL, 1478 sdw_stream_name[stream + 2], cpu_dai_id[0], 1479 type_strings[codec_info->dais[dai_index].dai_type]); 1480 } else { 1481 name = devm_kasprintf(dev, GFP_KERNEL, 1482 sdw_stream_name[stream], cpu_dai_id[0]); 1483 } 1484 if (!name) 1485 return -ENOMEM; 1486 1487 /* 1488 * generate CPU DAI name base on the sdw link ID and 1489 * PIN ID with offset of 2 according to sdw dai driver. 1490 */ 1491 for (k = 0; k < cpu_dai_num; k++) { 1492 cpu_name = devm_kasprintf(dev, GFP_KERNEL, 1493 "SDW%d Pin%d", cpu_dai_id[k], 1494 sdw_pin_index[cpu_dai_id[k]]++); 1495 if (!cpu_name) 1496 return -ENOMEM; 1497 1498 if (cpu_dai_index >= sdw_cpu_dai_num) { 1499 dev_err(dev, "invalid cpu dai index %d\n", 1500 cpu_dai_index); 1501 return -EINVAL; 1502 } 1503 1504 cpus[cpu_dai_index++].dai_name = cpu_name; 1505 } 1506 1507 /* 1508 * We create sdw dai links at first stage, so link index should 1509 * not be larger than sdw_be_num 1510 */ 1511 if (*link_index >= sdw_be_num) { 1512 dev_err(dev, "invalid dai link index %d\n", *link_index); 1513 return -EINVAL; 1514 } 1515 1516 if (*cpu_id >= sdw_cpu_dai_num) { 1517 dev_err(dev, "invalid cpu dai index %d\n", *cpu_id); 1518 return -EINVAL; 1519 } 1520 1521 playback = (stream == SNDRV_PCM_STREAM_PLAYBACK); 1522 capture = (stream == SNDRV_PCM_STREAM_CAPTURE); 1523 init_dai_link(dev, dai_links + *link_index, (*be_id)++, name, 1524 playback, capture, 1525 cpus + *cpu_id, cpu_dai_num, 1526 codecs, codec_num, 1527 NULL, &sdw_ops); 1528 1529 /* 1530 * SoundWire DAILINKs use 'stream' functions and Bank Switch operations 1531 * based on wait_for_completion(), tag them as 'nonatomic'. 1532 */ 1533 dai_links[*link_index].nonatomic = true; 1534 1535 set_dailink_map(sdw_codec_ch_maps, codec_num, cpu_dai_num); 1536 dai_links[*link_index].codec_ch_maps = sdw_codec_ch_maps; 1537 ret = set_codec_init_func(card, adr_link, dai_links + (*link_index)++, 1538 playback, group_id, adr_index, dai_index); 1539 if (ret < 0) { 1540 dev_err(dev, "failed to init codec %d\n", codec_index); 1541 return ret; 1542 } 1543 1544 *cpu_id += cpu_dai_num; 1545 } 1546 1547 return 0; 1548 } 1549 1550 #define IDISP_CODEC_MASK 0x4 1551 1552 static int sof_card_dai_links_create(struct snd_soc_card *card) 1553 { 1554 struct device *dev = card->dev; 1555 struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev); 1556 int sdw_be_num = 0, ssp_num = 0, dmic_num = 0, hdmi_num = 0, bt_num = 0; 1557 struct mc_private *ctx = snd_soc_card_get_drvdata(card); 1558 struct snd_soc_dai_link_component *idisp_components; 1559 struct snd_soc_dai_link_component *ssp_components; 1560 struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params; 1561 const struct snd_soc_acpi_link_adr *adr_link = mach_params->links; 1562 bool aggregation = !(sof_sdw_quirk & SOF_SDW_NO_AGGREGATION); 1563 struct snd_soc_dai_link_component *cpus; 1564 struct snd_soc_codec_conf *codec_conf; 1565 bool append_dai_type = false; 1566 bool ignore_pch_dmic = false; 1567 int codec_conf_num = 0; 1568 int codec_conf_index = 0; 1569 bool group_generated[SDW_MAX_GROUPS] = { }; 1570 int ssp_codec_index, ssp_mask; 1571 struct snd_soc_dai_link *dai_links; 1572 int num_links, link_index = 0; 1573 char *name, *cpu_name; 1574 int total_cpu_dai_num; 1575 int sdw_cpu_dai_num; 1576 int i, j, be_id = 0; 1577 int codec_index; 1578 int cpu_id = 0; 1579 int ret; 1580 1581 ret = get_dailink_info(dev, adr_link, &sdw_be_num, &sdw_cpu_dai_num, 1582 &codec_conf_num); 1583 if (ret < 0) { 1584 dev_err(dev, "failed to get sdw link info %d\n", ret); 1585 return ret; 1586 } 1587 1588 /* 1589 * on generic tgl platform, I2S or sdw mode is supported 1590 * based on board rework. A ACPI device is registered in 1591 * system only when I2S mode is supported, not sdw mode. 1592 * Here check ACPI ID to confirm I2S is supported. 1593 */ 1594 ssp_codec_index = find_codec_info_acpi(mach->id); 1595 if (ssp_codec_index >= 0) { 1596 ssp_mask = SOF_SSP_GET_PORT(sof_sdw_quirk); 1597 ssp_num = hweight_long(ssp_mask); 1598 } 1599 1600 if (mach_params->codec_mask & IDISP_CODEC_MASK) { 1601 ctx->idisp_codec = true; 1602 1603 if (sof_sdw_quirk & SOF_SDW_TGL_HDMI) 1604 hdmi_num = SOF_TGL_HDMI_COUNT; 1605 else 1606 hdmi_num = SOF_PRE_TGL_HDMI_COUNT; 1607 } 1608 1609 /* enable dmic01 & dmic16k */ 1610 if (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num) 1611 dmic_num = 2; 1612 1613 if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) 1614 bt_num = 1; 1615 1616 dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d, bt: %d\n", 1617 sdw_be_num, ssp_num, dmic_num, hdmi_num, bt_num); 1618 1619 /* allocate BE dailinks */ 1620 num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num; 1621 dai_links = devm_kcalloc(dev, num_links, sizeof(*dai_links), GFP_KERNEL); 1622 if (!dai_links) 1623 return -ENOMEM; 1624 1625 /* allocated CPU DAIs */ 1626 total_cpu_dai_num = sdw_cpu_dai_num + ssp_num + dmic_num + hdmi_num + bt_num; 1627 cpus = devm_kcalloc(dev, total_cpu_dai_num, sizeof(*cpus), GFP_KERNEL); 1628 if (!cpus) 1629 return -ENOMEM; 1630 1631 /* allocate codec conf, will be populated when dailinks are created */ 1632 codec_conf = devm_kcalloc(dev, codec_conf_num, sizeof(*codec_conf), 1633 GFP_KERNEL); 1634 if (!codec_conf) 1635 return -ENOMEM; 1636 1637 /* SDW */ 1638 if (!sdw_be_num) 1639 goto SSP; 1640 1641 for (i = 0; i < SDW_MAX_LINKS; i++) 1642 sdw_pin_index[i] = SDW_INTEL_BIDIR_PDI_BASE; 1643 1644 for (; adr_link->num_adr; adr_link++) { 1645 /* 1646 * If there are two or more different devices on the same sdw link, we have to 1647 * append the codec type to the dai link name to prevent duplicated dai link name. 1648 * The same type devices on the same sdw link will be in the same 1649 * snd_soc_acpi_adr_device array. They won't be described in different adr_links. 1650 */ 1651 for (i = 0; i < adr_link->num_adr; i++) { 1652 /* find codec info to get dai_num */ 1653 codec_index = find_codec_info_part(adr_link->adr_d[i].adr); 1654 if (codec_index < 0) 1655 return codec_index; 1656 if (codec_info_list[codec_index].dai_num > 1) { 1657 append_dai_type = true; 1658 goto out; 1659 } 1660 for (j = 0; j < i; j++) { 1661 if ((SDW_PART_ID(adr_link->adr_d[i].adr) != 1662 SDW_PART_ID(adr_link->adr_d[j].adr)) || 1663 (SDW_MFG_ID(adr_link->adr_d[i].adr) != 1664 SDW_MFG_ID(adr_link->adr_d[j].adr))) { 1665 append_dai_type = true; 1666 goto out; 1667 } 1668 } 1669 } 1670 } 1671 out: 1672 1673 /* generate DAI links by each sdw link */ 1674 for (adr_link = mach_params->links ; adr_link->num_adr; adr_link++) { 1675 for (i = 0; i < adr_link->num_adr; i++) { 1676 const struct snd_soc_acpi_endpoint *endpoint; 1677 1678 endpoint = adr_link->adr_d[i].endpoints; 1679 1680 /* this group has been generated */ 1681 if (endpoint->aggregated && 1682 group_generated[endpoint->group_id]) 1683 continue; 1684 1685 /* find codec info to get dai_num */ 1686 codec_index = find_codec_info_part(adr_link->adr_d[i].adr); 1687 if (codec_index < 0) 1688 return codec_index; 1689 1690 for (j = 0; j < codec_info_list[codec_index].dai_num ; j++) { 1691 ret = create_sdw_dailink(card, &link_index, dai_links, 1692 sdw_be_num, sdw_cpu_dai_num, cpus, 1693 adr_link, &cpu_id, 1694 codec_conf, codec_conf_num, 1695 &be_id, &codec_conf_index, 1696 &ignore_pch_dmic, append_dai_type, i, j); 1697 if (ret < 0) { 1698 dev_err(dev, "failed to create dai link %d\n", link_index); 1699 return ret; 1700 } 1701 } 1702 1703 if (aggregation && endpoint->aggregated) 1704 group_generated[endpoint->group_id] = true; 1705 } 1706 } 1707 1708 SSP: 1709 /* SSP */ 1710 if (!ssp_num) 1711 goto DMIC; 1712 1713 for (i = 0, j = 0; ssp_mask; i++, ssp_mask >>= 1) { 1714 struct sof_sdw_codec_info *info; 1715 int playback, capture; 1716 char *codec_name; 1717 1718 if (!(ssp_mask & 0x1)) 1719 continue; 1720 1721 name = devm_kasprintf(dev, GFP_KERNEL, 1722 "SSP%d-Codec", i); 1723 if (!name) 1724 return -ENOMEM; 1725 1726 cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i); 1727 if (!cpu_name) 1728 return -ENOMEM; 1729 1730 ssp_components = devm_kzalloc(dev, sizeof(*ssp_components), 1731 GFP_KERNEL); 1732 if (!ssp_components) 1733 return -ENOMEM; 1734 1735 info = &codec_info_list[ssp_codec_index]; 1736 codec_name = devm_kasprintf(dev, GFP_KERNEL, "i2c-%s:0%d", 1737 info->acpi_id, j++); 1738 if (!codec_name) 1739 return -ENOMEM; 1740 1741 ssp_components->name = codec_name; 1742 /* TODO: support multi codec dai on SSP when it is needed */ 1743 ssp_components->dai_name = info->dais[0].dai_name; 1744 cpus[cpu_id].dai_name = cpu_name; 1745 1746 playback = info->dais[0].direction[SNDRV_PCM_STREAM_PLAYBACK]; 1747 capture = info->dais[0].direction[SNDRV_PCM_STREAM_CAPTURE]; 1748 init_dai_link(dev, dai_links + link_index, be_id, name, 1749 playback, capture, 1750 cpus + cpu_id, 1, 1751 ssp_components, 1, 1752 NULL, info->ops); 1753 1754 ret = info->dais[0].init(card, NULL, dai_links + link_index, info, 0); 1755 if (ret < 0) 1756 return ret; 1757 1758 INC_ID(be_id, cpu_id, link_index); 1759 } 1760 1761 DMIC: 1762 /* dmic */ 1763 if (dmic_num > 0) { 1764 if (ignore_pch_dmic) { 1765 dev_warn(dev, "Ignoring PCH DMIC\n"); 1766 goto HDMI; 1767 } 1768 cpus[cpu_id].dai_name = "DMIC01 Pin"; 1769 init_dai_link(dev, dai_links + link_index, be_id, "dmic01", 1770 0, 1, // DMIC only supports capture 1771 cpus + cpu_id, 1, 1772 dmic_component, 1, 1773 sof_sdw_dmic_init, NULL); 1774 INC_ID(be_id, cpu_id, link_index); 1775 1776 cpus[cpu_id].dai_name = "DMIC16k Pin"; 1777 init_dai_link(dev, dai_links + link_index, be_id, "dmic16k", 1778 0, 1, // DMIC only supports capture 1779 cpus + cpu_id, 1, 1780 dmic_component, 1, 1781 /* don't call sof_sdw_dmic_init() twice */ 1782 NULL, NULL); 1783 INC_ID(be_id, cpu_id, link_index); 1784 } 1785 1786 HDMI: 1787 /* HDMI */ 1788 if (hdmi_num > 0) { 1789 idisp_components = devm_kcalloc(dev, hdmi_num, 1790 sizeof(*idisp_components), 1791 GFP_KERNEL); 1792 if (!idisp_components) 1793 return -ENOMEM; 1794 } 1795 1796 for (i = 0; i < hdmi_num; i++) { 1797 name = devm_kasprintf(dev, GFP_KERNEL, 1798 "iDisp%d", i + 1); 1799 if (!name) 1800 return -ENOMEM; 1801 1802 if (ctx->idisp_codec) { 1803 idisp_components[i].name = "ehdaudio0D2"; 1804 idisp_components[i].dai_name = devm_kasprintf(dev, 1805 GFP_KERNEL, 1806 "intel-hdmi-hifi%d", 1807 i + 1); 1808 if (!idisp_components[i].dai_name) 1809 return -ENOMEM; 1810 } else { 1811 idisp_components[i] = asoc_dummy_dlc; 1812 } 1813 1814 cpu_name = devm_kasprintf(dev, GFP_KERNEL, 1815 "iDisp%d Pin", i + 1); 1816 if (!cpu_name) 1817 return -ENOMEM; 1818 1819 cpus[cpu_id].dai_name = cpu_name; 1820 init_dai_link(dev, dai_links + link_index, be_id, name, 1821 1, 0, // HDMI only supports playback 1822 cpus + cpu_id, 1, 1823 idisp_components + i, 1, 1824 sof_sdw_hdmi_init, NULL); 1825 INC_ID(be_id, cpu_id, link_index); 1826 } 1827 1828 if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) { 1829 int port = (sof_sdw_quirk & SOF_BT_OFFLOAD_SSP_MASK) >> 1830 SOF_BT_OFFLOAD_SSP_SHIFT; 1831 1832 name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); 1833 if (!name) 1834 return -ENOMEM; 1835 1836 cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port); 1837 if (!cpu_name) 1838 return -ENOMEM; 1839 1840 cpus[cpu_id].dai_name = cpu_name; 1841 init_dai_link(dev, dai_links + link_index, be_id, name, 1, 1, 1842 cpus + cpu_id, 1, &asoc_dummy_dlc, 1, NULL, NULL); 1843 } 1844 1845 card->dai_link = dai_links; 1846 card->num_links = num_links; 1847 1848 card->codec_conf = codec_conf; 1849 card->num_configs = codec_conf_num; 1850 1851 return 0; 1852 } 1853 1854 static int sof_sdw_card_late_probe(struct snd_soc_card *card) 1855 { 1856 struct mc_private *ctx = snd_soc_card_get_drvdata(card); 1857 int ret = 0; 1858 int i; 1859 1860 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { 1861 if (codec_info_list[i].codec_card_late_probe) { 1862 ret = codec_info_list[i].codec_card_late_probe(card); 1863 1864 if (ret < 0) 1865 return ret; 1866 } 1867 } 1868 1869 if (ctx->idisp_codec) 1870 ret = sof_sdw_hdmi_card_late_probe(card); 1871 1872 return ret; 1873 } 1874 1875 /* SoC card */ 1876 static const char sdw_card_long_name[] = "Intel Soundwire SOF"; 1877 1878 static struct snd_soc_card card_sof_sdw = { 1879 .name = "soundwire", 1880 .owner = THIS_MODULE, 1881 .late_probe = sof_sdw_card_late_probe, 1882 }; 1883 1884 /* helper to get the link that the codec DAI is used */ 1885 static struct snd_soc_dai_link *mc_find_codec_dai_used(struct snd_soc_card *card, 1886 const char *dai_name) 1887 { 1888 struct snd_soc_dai_link *dai_link; 1889 int i; 1890 int j; 1891 1892 for_each_card_prelinks(card, i, dai_link) { 1893 for (j = 0; j < dai_link->num_codecs; j++) { 1894 /* Check each codec in a link */ 1895 if (!strcmp(dai_link->codecs[j].dai_name, dai_name)) 1896 return dai_link; 1897 } 1898 } 1899 return NULL; 1900 } 1901 1902 static void mc_dailink_exit_loop(struct snd_soc_card *card) 1903 { 1904 struct snd_soc_dai_link *dai_link; 1905 int ret; 1906 int i, j; 1907 1908 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { 1909 for (j = 0; j < codec_info_list[i].dai_num; j++) { 1910 /* Check each dai in codec_info_lis to see if it is used in the link */ 1911 if (!codec_info_list[i].dais[j].exit) 1912 continue; 1913 /* 1914 * We don't need to call .exit function if there is no matched 1915 * dai link found. 1916 */ 1917 dai_link = mc_find_codec_dai_used(card, 1918 codec_info_list[i].dais[j].dai_name); 1919 if (dai_link) { 1920 /* Do the .exit function if the codec dai is used in the link */ 1921 ret = codec_info_list[i].dais[j].exit(card, dai_link); 1922 if (ret) 1923 dev_warn(card->dev, 1924 "codec exit failed %d\n", 1925 ret); 1926 break; 1927 } 1928 } 1929 } 1930 } 1931 1932 static int mc_probe(struct platform_device *pdev) 1933 { 1934 struct snd_soc_card *card = &card_sof_sdw; 1935 struct snd_soc_acpi_mach *mach = dev_get_platdata(&pdev->dev); 1936 struct mc_private *ctx; 1937 int amp_num = 0, i; 1938 int ret; 1939 1940 card->dev = &pdev->dev; 1941 1942 dev_dbg(card->dev, "Entry\n"); 1943 1944 ctx = devm_kzalloc(card->dev, sizeof(*ctx), GFP_KERNEL); 1945 if (!ctx) 1946 return -ENOMEM; 1947 1948 INIT_LIST_HEAD(&ctx->hdmi_pcm_list); 1949 1950 snd_soc_card_set_drvdata(card, ctx); 1951 1952 dmi_check_system(sof_sdw_quirk_table); 1953 1954 if (quirk_override != -1) { 1955 dev_info(card->dev, "Overriding quirk 0x%lx => 0x%x\n", 1956 sof_sdw_quirk, quirk_override); 1957 sof_sdw_quirk = quirk_override; 1958 } 1959 1960 log_quirks(card->dev); 1961 1962 /* reset amp_num to ensure amp_num++ starts from 0 in each probe */ 1963 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) 1964 codec_info_list[i].amp_num = 0; 1965 1966 if (mach->mach_params.subsystem_id_set) { 1967 snd_soc_card_set_pci_ssid(card, 1968 mach->mach_params.subsystem_vendor, 1969 mach->mach_params.subsystem_device); 1970 } 1971 1972 ret = sof_card_dai_links_create(card); 1973 if (ret < 0) 1974 return ret; 1975 1976 /* 1977 * the default amp_num is zero for each codec and 1978 * amp_num will only be increased for active amp 1979 * codecs on used platform 1980 */ 1981 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) 1982 amp_num += codec_info_list[i].amp_num; 1983 1984 card->components = devm_kasprintf(card->dev, GFP_KERNEL, 1985 "cfg-spk:%d cfg-amp:%d", 1986 (sof_sdw_quirk & SOF_SDW_FOUR_SPK) 1987 ? 4 : 2, amp_num); 1988 if (!card->components) 1989 return -ENOMEM; 1990 1991 if (mach->mach_params.dmic_num) { 1992 card->components = devm_kasprintf(card->dev, GFP_KERNEL, 1993 "%s mic:dmic cfg-mics:%d", 1994 card->components, 1995 mach->mach_params.dmic_num); 1996 if (!card->components) 1997 return -ENOMEM; 1998 } 1999 2000 card->long_name = sdw_card_long_name; 2001 2002 /* Register the card */ 2003 ret = devm_snd_soc_register_card(card->dev, card); 2004 if (ret) { 2005 dev_err(card->dev, "snd_soc_register_card failed %d\n", ret); 2006 mc_dailink_exit_loop(card); 2007 return ret; 2008 } 2009 2010 platform_set_drvdata(pdev, card); 2011 2012 return ret; 2013 } 2014 2015 static void mc_remove(struct platform_device *pdev) 2016 { 2017 struct snd_soc_card *card = platform_get_drvdata(pdev); 2018 2019 mc_dailink_exit_loop(card); 2020 } 2021 2022 static const struct platform_device_id mc_id_table[] = { 2023 { "sof_sdw", }, 2024 {} 2025 }; 2026 MODULE_DEVICE_TABLE(platform, mc_id_table); 2027 2028 static struct platform_driver sof_sdw_driver = { 2029 .driver = { 2030 .name = "sof_sdw", 2031 .pm = &snd_soc_pm_ops, 2032 }, 2033 .probe = mc_probe, 2034 .remove_new = mc_remove, 2035 .id_table = mc_id_table, 2036 }; 2037 2038 module_platform_driver(sof_sdw_driver); 2039 2040 MODULE_DESCRIPTION("ASoC SoundWire Generic Machine driver"); 2041 MODULE_AUTHOR("Bard Liao <yung-chuan.liao@linux.intel.com>"); 2042 MODULE_AUTHOR("Rander Wang <rander.wang@linux.intel.com>"); 2043 MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>"); 2044 MODULE_LICENSE("GPL v2"); 2045 MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); 2046 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); 2047