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