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