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