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