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