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, "0AFE") 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, "0AFF") 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, "0B00") 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, "0B01") 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, "0B11") 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, "0B12") 365 }, 366 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 367 RT711_JD2 | 368 SOF_SDW_FOUR_SPK), 369 }, 370 { 371 .callback = sof_sdw_quirk_cb, 372 .matches = { 373 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 374 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B13"), 375 }, 376 /* No Jack */ 377 .driver_data = (void *)SOF_SDW_TGL_HDMI, 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, "0B29"), 384 }, 385 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 386 RT711_JD2 | 387 SOF_SDW_FOUR_SPK), 388 }, 389 { 390 .callback = sof_sdw_quirk_cb, 391 .matches = { 392 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 393 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B34"), 394 }, 395 /* No Jack */ 396 .driver_data = (void *)SOF_SDW_TGL_HDMI, 397 }, 398 { 399 .callback = sof_sdw_quirk_cb, 400 .matches = { 401 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 402 DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16-k0xxx"), 403 }, 404 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 405 RT711_JD2), 406 }, 407 /* RaptorLake devices */ 408 { 409 .callback = sof_sdw_quirk_cb, 410 .matches = { 411 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 412 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0BDA") 413 }, 414 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 415 RT711_JD2 | 416 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, "0C10"), 423 }, 424 /* No Jack */ 425 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 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, "0C11") 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, "0C40") 443 }, 444 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 445 RT711_JD2 | 446 SOF_SDW_FOUR_SPK), 447 }, 448 { 449 .callback = sof_sdw_quirk_cb, 450 .matches = { 451 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 452 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C4F") 453 }, 454 .driver_data = (void *)(SOF_SDW_TGL_HDMI | 455 RT711_JD2 | 456 SOF_SDW_FOUR_SPK), 457 }, 458 /* MeteorLake devices */ 459 { 460 .callback = sof_sdw_quirk_cb, 461 .matches = { 462 DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_mtlrvp"), 463 }, 464 .driver_data = (void *)(RT711_JD1), 465 }, 466 { 467 .callback = sof_sdw_quirk_cb, 468 .matches = { 469 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 470 DMI_MATCH(DMI_PRODUCT_NAME, "Meteor Lake Client Platform"), 471 }, 472 .driver_data = (void *)(RT711_JD2_100K), 473 }, 474 { 475 .callback = sof_sdw_quirk_cb, 476 .matches = { 477 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 478 DMI_MATCH(DMI_PRODUCT_NAME, "Rex"), 479 }, 480 .driver_data = (void *)(SOF_SDW_PCH_DMIC | 481 SOF_BT_OFFLOAD_SSP(1) | 482 SOF_SSP_BT_OFFLOAD_PRESENT), 483 }, 484 /* LunarLake devices */ 485 { 486 .callback = sof_sdw_quirk_cb, 487 .matches = { 488 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 489 DMI_MATCH(DMI_PRODUCT_NAME, "Lunar Lake Client Platform"), 490 }, 491 .driver_data = (void *)(RT711_JD2), 492 }, 493 {} 494 }; 495 496 static struct snd_soc_dai_link_component dmic_component[] = { 497 { 498 .name = "dmic-codec", 499 .dai_name = "dmic-hifi", 500 } 501 }; 502 503 static struct snd_soc_dai_link_component platform_component[] = { 504 { 505 /* name might be overridden during probe */ 506 .name = "0000:00:1f.3" 507 } 508 }; 509 510 /* these wrappers are only needed to avoid typecast compilation errors */ 511 int sdw_startup(struct snd_pcm_substream *substream) 512 { 513 return sdw_startup_stream(substream); 514 } 515 516 int sdw_prepare(struct snd_pcm_substream *substream) 517 { 518 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 519 struct sdw_stream_runtime *sdw_stream; 520 struct snd_soc_dai *dai; 521 522 /* Find stream from first CPU DAI */ 523 dai = asoc_rtd_to_cpu(rtd, 0); 524 525 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); 526 if (IS_ERR(sdw_stream)) { 527 dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); 528 return PTR_ERR(sdw_stream); 529 } 530 531 return sdw_prepare_stream(sdw_stream); 532 } 533 534 int sdw_trigger(struct snd_pcm_substream *substream, int cmd) 535 { 536 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 537 struct sdw_stream_runtime *sdw_stream; 538 struct snd_soc_dai *dai; 539 int ret; 540 541 /* Find stream from first CPU DAI */ 542 dai = asoc_rtd_to_cpu(rtd, 0); 543 544 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); 545 if (IS_ERR(sdw_stream)) { 546 dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); 547 return PTR_ERR(sdw_stream); 548 } 549 550 switch (cmd) { 551 case SNDRV_PCM_TRIGGER_START: 552 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 553 case SNDRV_PCM_TRIGGER_RESUME: 554 ret = sdw_enable_stream(sdw_stream); 555 break; 556 557 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 558 case SNDRV_PCM_TRIGGER_SUSPEND: 559 case SNDRV_PCM_TRIGGER_STOP: 560 ret = sdw_disable_stream(sdw_stream); 561 break; 562 default: 563 ret = -EINVAL; 564 break; 565 } 566 567 if (ret) 568 dev_err(rtd->dev, "%s trigger %d failed: %d\n", __func__, cmd, ret); 569 570 return ret; 571 } 572 573 int sdw_hw_params(struct snd_pcm_substream *substream, 574 struct snd_pcm_hw_params *params) 575 { 576 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 577 int ch = params_channels(params); 578 struct snd_soc_dai *codec_dai; 579 struct snd_soc_dai *cpu_dai; 580 unsigned int ch_mask; 581 int num_codecs; 582 int step; 583 int i; 584 int j; 585 586 if (!rtd->dai_link->codec_ch_maps) 587 return 0; 588 589 /* Identical data will be sent to all codecs in playback */ 590 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 591 ch_mask = GENMASK(ch - 1, 0); 592 step = 0; 593 } else { 594 num_codecs = rtd->dai_link->num_codecs; 595 596 if (ch < num_codecs || ch % num_codecs != 0) { 597 dev_err(rtd->dev, "Channels number %d is invalid when codec number = %d\n", 598 ch, num_codecs); 599 return -EINVAL; 600 } 601 602 ch_mask = GENMASK(ch / num_codecs - 1, 0); 603 step = hweight_long(ch_mask); 604 605 } 606 607 /* 608 * The captured data will be combined from each cpu DAI if the dai 609 * link has more than one codec DAIs. Set codec channel mask and 610 * ASoC will set the corresponding channel numbers for each cpu dai. 611 */ 612 for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 613 for_each_rtd_codec_dais(rtd, j, codec_dai) { 614 if (rtd->dai_link->codec_ch_maps[j].connected_cpu_id != i) 615 continue; 616 rtd->dai_link->codec_ch_maps[j].ch_mask = ch_mask << (j * step); 617 } 618 } 619 return 0; 620 } 621 622 int sdw_hw_free(struct snd_pcm_substream *substream) 623 { 624 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 625 struct sdw_stream_runtime *sdw_stream; 626 struct snd_soc_dai *dai; 627 628 /* Find stream from first CPU DAI */ 629 dai = asoc_rtd_to_cpu(rtd, 0); 630 631 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); 632 if (IS_ERR(sdw_stream)) { 633 dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); 634 return PTR_ERR(sdw_stream); 635 } 636 637 return sdw_deprepare_stream(sdw_stream); 638 } 639 640 void sdw_shutdown(struct snd_pcm_substream *substream) 641 { 642 sdw_shutdown_stream(substream); 643 } 644 645 static const struct snd_soc_ops sdw_ops = { 646 .startup = sdw_startup, 647 .prepare = sdw_prepare, 648 .trigger = sdw_trigger, 649 .hw_params = sdw_hw_params, 650 .hw_free = sdw_hw_free, 651 .shutdown = sdw_shutdown, 652 }; 653 654 static struct sof_sdw_codec_info codec_info_list[] = { 655 { 656 .part_id = 0x700, 657 .dais = { 658 { 659 .direction = {true, true}, 660 .dai_name = "rt700-aif1", 661 .dai_type = SOF_SDW_DAI_TYPE_JACK, 662 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 663 .init = sof_sdw_rt700_init, 664 }, 665 }, 666 .dai_num = 1, 667 }, 668 { 669 .part_id = 0x711, 670 .version_id = 3, 671 .dais = { 672 { 673 .direction = {true, true}, 674 .dai_name = "rt711-sdca-aif1", 675 .dai_type = SOF_SDW_DAI_TYPE_JACK, 676 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 677 .init = sof_sdw_rt_sdca_jack_init, 678 .exit = sof_sdw_rt_sdca_jack_exit, 679 }, 680 }, 681 .dai_num = 1, 682 }, 683 { 684 .part_id = 0x711, 685 .version_id = 2, 686 .dais = { 687 { 688 .direction = {true, true}, 689 .dai_name = "rt711-aif1", 690 .dai_type = SOF_SDW_DAI_TYPE_JACK, 691 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 692 .init = sof_sdw_rt711_init, 693 .exit = sof_sdw_rt711_exit, 694 }, 695 }, 696 .dai_num = 1, 697 }, 698 { 699 .part_id = 0x712, 700 .version_id = 3, 701 .dais = { 702 { 703 .direction = {true, true}, 704 .dai_name = "rt712-sdca-aif1", 705 .dai_type = SOF_SDW_DAI_TYPE_JACK, 706 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 707 .init = sof_sdw_rt_sdca_jack_init, 708 .exit = sof_sdw_rt_sdca_jack_exit, 709 }, 710 { 711 .direction = {true, false}, 712 .dai_name = "rt712-sdca-aif2", 713 .dai_type = SOF_SDW_DAI_TYPE_AMP, 714 .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, 715 .init = sof_sdw_rt712_spk_init, 716 }, 717 }, 718 .dai_num = 2, 719 }, 720 { 721 .part_id = 0x1712, 722 .version_id = 3, 723 .dais = { 724 { 725 .direction = {false, true}, 726 .dai_name = "rt712-sdca-dmic-aif1", 727 .dai_type = SOF_SDW_DAI_TYPE_MIC, 728 .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, 729 .init = sof_sdw_rt712_sdca_dmic_init, 730 }, 731 }, 732 .dai_num = 1, 733 }, 734 { 735 .part_id = 0x713, 736 .version_id = 3, 737 .dais = { 738 { 739 .direction = {true, true}, 740 .dai_name = "rt712-sdca-aif1", 741 .dai_type = SOF_SDW_DAI_TYPE_JACK, 742 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 743 .init = sof_sdw_rt_sdca_jack_init, 744 .exit = sof_sdw_rt_sdca_jack_exit, 745 }, 746 }, 747 .dai_num = 1, 748 }, 749 { 750 .part_id = 0x1713, 751 .version_id = 3, 752 .dais = { 753 { 754 .direction = {false, true}, 755 .dai_name = "rt712-sdca-dmic-aif1", 756 .dai_type = SOF_SDW_DAI_TYPE_MIC, 757 .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, 758 .init = sof_sdw_rt712_sdca_dmic_init, 759 }, 760 }, 761 .dai_num = 1, 762 }, 763 { 764 .part_id = 0x1308, 765 .acpi_id = "10EC1308", 766 .dais = { 767 { 768 .direction = {true, false}, 769 .dai_name = "rt1308-aif", 770 .dai_type = SOF_SDW_DAI_TYPE_AMP, 771 .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, 772 .init = sof_sdw_rt_amp_init, 773 .exit = sof_sdw_rt_amp_exit, 774 }, 775 }, 776 .dai_num = 1, 777 .ops = &sof_sdw_rt1308_i2s_ops, 778 }, 779 { 780 .part_id = 0x1316, 781 .dais = { 782 { 783 .direction = {true, true}, 784 .dai_name = "rt1316-aif", 785 .dai_type = SOF_SDW_DAI_TYPE_AMP, 786 .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, 787 .init = sof_sdw_rt_amp_init, 788 .exit = sof_sdw_rt_amp_exit, 789 }, 790 }, 791 .dai_num = 1, 792 }, 793 { 794 .part_id = 0x1318, 795 .dais = { 796 { 797 .direction = {true, true}, 798 .dai_name = "rt1318-aif", 799 .dai_type = SOF_SDW_DAI_TYPE_AMP, 800 .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, 801 .init = sof_sdw_rt_amp_init, 802 .exit = sof_sdw_rt_amp_exit, 803 }, 804 }, 805 .dai_num = 1, 806 }, 807 { 808 .part_id = 0x714, 809 .version_id = 3, 810 .ignore_pch_dmic = true, 811 .dais = { 812 { 813 .direction = {false, true}, 814 .dai_name = "rt715-aif2", 815 .dai_type = SOF_SDW_DAI_TYPE_MIC, 816 .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, 817 .init = sof_sdw_rt715_sdca_init, 818 }, 819 }, 820 .dai_num = 1, 821 }, 822 { 823 .part_id = 0x715, 824 .version_id = 3, 825 .ignore_pch_dmic = true, 826 .dais = { 827 { 828 .direction = {false, true}, 829 .dai_name = "rt715-aif2", 830 .dai_type = SOF_SDW_DAI_TYPE_MIC, 831 .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, 832 .init = sof_sdw_rt715_sdca_init, 833 }, 834 }, 835 .dai_num = 1, 836 }, 837 { 838 .part_id = 0x714, 839 .version_id = 2, 840 .ignore_pch_dmic = true, 841 .dais = { 842 { 843 .direction = {false, true}, 844 .dai_name = "rt715-aif2", 845 .dai_type = SOF_SDW_DAI_TYPE_MIC, 846 .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, 847 .init = sof_sdw_rt715_init, 848 }, 849 }, 850 .dai_num = 1, 851 }, 852 { 853 .part_id = 0x715, 854 .version_id = 2, 855 .ignore_pch_dmic = true, 856 .dais = { 857 { 858 .direction = {false, true}, 859 .dai_name = "rt715-aif2", 860 .dai_type = SOF_SDW_DAI_TYPE_MIC, 861 .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, 862 .init = sof_sdw_rt715_init, 863 }, 864 }, 865 .dai_num = 1, 866 }, 867 { 868 .part_id = 0x8373, 869 .dais = { 870 { 871 .direction = {true, true}, 872 .dai_name = "max98373-aif1", 873 .dai_type = SOF_SDW_DAI_TYPE_AMP, 874 .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, 875 .init = sof_sdw_maxim_init, 876 }, 877 }, 878 .dai_num = 1, 879 }, 880 { 881 .part_id = 0x8363, 882 .dais = { 883 { 884 .direction = {true, false}, 885 .dai_name = "max98363-aif1", 886 .dai_type = SOF_SDW_DAI_TYPE_AMP, 887 .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, 888 .init = sof_sdw_maxim_init, 889 }, 890 }, 891 .dai_num = 1, 892 }, 893 { 894 .part_id = 0x5682, 895 .dais = { 896 { 897 .direction = {true, true}, 898 .dai_name = "rt5682-sdw", 899 .dai_type = SOF_SDW_DAI_TYPE_JACK, 900 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 901 .init = sof_sdw_rt5682_init, 902 }, 903 }, 904 .dai_num = 1, 905 }, 906 { 907 .part_id = 0x3556, 908 .dais = { 909 { 910 .direction = {true, true}, 911 .dai_name = "cs35l56-sdw1", 912 .dai_type = SOF_SDW_DAI_TYPE_AMP, 913 .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, 914 .init = sof_sdw_cs_amp_init, 915 }, 916 }, 917 .dai_num = 1, 918 }, 919 { 920 .part_id = 0x4242, 921 .dais = { 922 { 923 .direction = {true, true}, 924 .dai_name = "cs42l42-sdw", 925 .dai_type = SOF_SDW_DAI_TYPE_JACK, 926 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 927 .init = sof_sdw_cs42l42_init, 928 }, 929 }, 930 .dai_num = 1, 931 }, 932 { 933 .part_id = 0xaaaa, /* generic codec mockup */ 934 .version_id = 0, 935 .dais = { 936 { 937 .direction = {true, true}, 938 .dai_name = "sdw-mockup-aif1", 939 .dai_type = SOF_SDW_DAI_TYPE_JACK, 940 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 941 .init = NULL, 942 }, 943 }, 944 .dai_num = 1, 945 }, 946 { 947 .part_id = 0xaa55, /* headset codec mockup */ 948 .version_id = 0, 949 .dais = { 950 { 951 .direction = {true, true}, 952 .dai_name = "sdw-mockup-aif1", 953 .dai_type = SOF_SDW_DAI_TYPE_JACK, 954 .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, 955 .init = NULL, 956 }, 957 }, 958 .dai_num = 1, 959 }, 960 { 961 .part_id = 0x55aa, /* amplifier mockup */ 962 .version_id = 0, 963 .dais = { 964 { 965 .direction = {true, true}, 966 .dai_name = "sdw-mockup-aif1", 967 .dai_type = SOF_SDW_DAI_TYPE_AMP, 968 .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, 969 .init = NULL, 970 }, 971 }, 972 .dai_num = 1, 973 }, 974 { 975 .part_id = 0x5555, 976 .version_id = 0, 977 .dais = { 978 { 979 .dai_name = "sdw-mockup-aif1", 980 .direction = {false, true}, 981 .dai_type = SOF_SDW_DAI_TYPE_MIC, 982 .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, 983 .init = NULL, 984 }, 985 }, 986 .dai_num = 1, 987 }, 988 }; 989 990 static inline int find_codec_info_part(const u64 adr) 991 { 992 unsigned int part_id, sdw_version; 993 int i; 994 995 part_id = SDW_PART_ID(adr); 996 sdw_version = SDW_VERSION(adr); 997 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) 998 /* 999 * A codec info is for all sdw version with the part id if 1000 * version_id is not specified in the codec info. 1001 */ 1002 if (part_id == codec_info_list[i].part_id && 1003 (!codec_info_list[i].version_id || 1004 sdw_version == codec_info_list[i].version_id)) 1005 return i; 1006 1007 return -EINVAL; 1008 1009 } 1010 1011 static inline int find_codec_info_acpi(const u8 *acpi_id) 1012 { 1013 int i; 1014 1015 if (!acpi_id[0]) 1016 return -EINVAL; 1017 1018 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) 1019 if (!memcmp(codec_info_list[i].acpi_id, acpi_id, ACPI_ID_LEN)) 1020 return i; 1021 1022 return -EINVAL; 1023 } 1024 1025 /* 1026 * get BE dailink number and CPU DAI number based on sdw link adr. 1027 * Since some sdw slaves may be aggregated, the CPU DAI number 1028 * may be larger than the number of BE dailinks. 1029 */ 1030 static int get_dailink_info(struct device *dev, 1031 const struct snd_soc_acpi_link_adr *adr_link, 1032 int *sdw_be_num, int *sdw_cpu_dai_num, int *codecs_num) 1033 { 1034 bool group_visited[SDW_MAX_GROUPS]; 1035 bool no_aggregation; 1036 int i; 1037 int j; 1038 1039 no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION; 1040 *sdw_cpu_dai_num = 0; 1041 *sdw_be_num = 0; 1042 1043 if (!adr_link) 1044 return -EINVAL; 1045 1046 for (i = 0; i < SDW_MAX_GROUPS; i++) 1047 group_visited[i] = false; 1048 1049 for (; adr_link->num_adr; adr_link++) { 1050 const struct snd_soc_acpi_endpoint *endpoint; 1051 struct sof_sdw_codec_info *codec_info; 1052 int codec_index; 1053 int stream; 1054 u64 adr; 1055 1056 /* make sure the link mask has a single bit set */ 1057 if (!is_power_of_2(adr_link->mask)) 1058 return -EINVAL; 1059 1060 for (i = 0; i < adr_link->num_adr; i++) { 1061 adr = adr_link->adr_d[i].adr; 1062 codec_index = find_codec_info_part(adr); 1063 if (codec_index < 0) 1064 return codec_index; 1065 1066 codec_info = &codec_info_list[codec_index]; 1067 1068 *codecs_num += codec_info->dai_num; 1069 1070 if (!adr_link->adr_d[i].name_prefix) { 1071 dev_err(dev, "codec 0x%llx does not have a name prefix\n", 1072 adr_link->adr_d[i].adr); 1073 return -EINVAL; 1074 } 1075 1076 endpoint = adr_link->adr_d[i].endpoints; 1077 if (endpoint->aggregated && !endpoint->group_id) { 1078 dev_err(dev, "invalid group id on link %x\n", 1079 adr_link->mask); 1080 return -EINVAL; 1081 } 1082 1083 for (j = 0; j < codec_info->dai_num; j++) { 1084 /* count DAI number for playback and capture */ 1085 for_each_pcm_streams(stream) { 1086 if (!codec_info->dais[j].direction[stream]) 1087 continue; 1088 1089 (*sdw_cpu_dai_num)++; 1090 1091 /* count BE for each non-aggregated slave or group */ 1092 if (!endpoint->aggregated || no_aggregation || 1093 !group_visited[endpoint->group_id]) 1094 (*sdw_be_num)++; 1095 } 1096 } 1097 1098 if (endpoint->aggregated) 1099 group_visited[endpoint->group_id] = true; 1100 } 1101 } 1102 1103 return 0; 1104 } 1105 1106 static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, 1107 int be_id, char *name, int playback, int capture, 1108 struct snd_soc_dai_link_component *cpus, int cpus_num, 1109 struct snd_soc_dai_link_component *codecs, int codecs_num, 1110 int (*init)(struct snd_soc_pcm_runtime *rtd), 1111 const struct snd_soc_ops *ops) 1112 { 1113 dev_dbg(dev, "create dai link %s, id %d\n", name, be_id); 1114 dai_links->id = be_id; 1115 dai_links->name = name; 1116 dai_links->platforms = platform_component; 1117 dai_links->num_platforms = ARRAY_SIZE(platform_component); 1118 dai_links->no_pcm = 1; 1119 dai_links->cpus = cpus; 1120 dai_links->num_cpus = cpus_num; 1121 dai_links->codecs = codecs; 1122 dai_links->num_codecs = codecs_num; 1123 dai_links->dpcm_playback = playback; 1124 dai_links->dpcm_capture = capture; 1125 dai_links->init = init; 1126 dai_links->ops = ops; 1127 } 1128 1129 static bool is_unique_device(const struct snd_soc_acpi_link_adr *adr_link, 1130 unsigned int sdw_version, 1131 unsigned int mfg_id, 1132 unsigned int part_id, 1133 unsigned int class_id, 1134 int index_in_link) 1135 { 1136 int i; 1137 1138 for (i = 0; i < adr_link->num_adr; i++) { 1139 unsigned int sdw1_version, mfg1_id, part1_id, class1_id; 1140 u64 adr; 1141 1142 /* skip itself */ 1143 if (i == index_in_link) 1144 continue; 1145 1146 adr = adr_link->adr_d[i].adr; 1147 1148 sdw1_version = SDW_VERSION(adr); 1149 mfg1_id = SDW_MFG_ID(adr); 1150 part1_id = SDW_PART_ID(adr); 1151 class1_id = SDW_CLASS_ID(adr); 1152 1153 if (sdw_version == sdw1_version && 1154 mfg_id == mfg1_id && 1155 part_id == part1_id && 1156 class_id == class1_id) 1157 return false; 1158 } 1159 1160 return true; 1161 } 1162 1163 static int fill_sdw_codec_dlc(struct device *dev, 1164 const struct snd_soc_acpi_link_adr *adr_link, 1165 struct snd_soc_dai_link_component *codec, 1166 int adr_index, int dai_index) 1167 { 1168 unsigned int sdw_version, unique_id, mfg_id, link_id, part_id, class_id; 1169 u64 adr = adr_link->adr_d[adr_index].adr; 1170 int codec_index; 1171 1172 codec_index = find_codec_info_part(adr); 1173 if (codec_index < 0) 1174 return codec_index; 1175 1176 sdw_version = SDW_VERSION(adr); 1177 link_id = SDW_DISCO_LINK_ID(adr); 1178 unique_id = SDW_UNIQUE_ID(adr); 1179 mfg_id = SDW_MFG_ID(adr); 1180 part_id = SDW_PART_ID(adr); 1181 class_id = SDW_CLASS_ID(adr); 1182 1183 if (codec_info_list[codec_index].codec_name) 1184 codec->name = devm_kstrdup(dev, 1185 codec_info_list[codec_index].codec_name, 1186 GFP_KERNEL); 1187 else if (is_unique_device(adr_link, sdw_version, mfg_id, part_id, 1188 class_id, adr_index)) 1189 codec->name = devm_kasprintf(dev, GFP_KERNEL, 1190 "sdw:%01x:%04x:%04x:%02x", link_id, 1191 mfg_id, part_id, class_id); 1192 else 1193 codec->name = devm_kasprintf(dev, GFP_KERNEL, 1194 "sdw:%01x:%04x:%04x:%02x:%01x", link_id, 1195 mfg_id, part_id, class_id, unique_id); 1196 1197 if (!codec->name) 1198 return -ENOMEM; 1199 1200 codec->dai_name = codec_info_list[codec_index].dais[dai_index].dai_name; 1201 1202 return 0; 1203 } 1204 1205 static int set_codec_init_func(struct snd_soc_card *card, 1206 const struct snd_soc_acpi_link_adr *adr_link, 1207 struct snd_soc_dai_link *dai_links, 1208 bool playback, int group_id, int adr_index, int dai_index) 1209 { 1210 int i = adr_index; 1211 1212 do { 1213 /* 1214 * Initialize the codec. If codec is part of an aggregated 1215 * group (group_id>0), initialize all codecs belonging to 1216 * same group. 1217 * The first link should start with adr_link->adr_d[adr_index] 1218 * because that is the device that we want to initialize and 1219 * we should end immediately if it is not aggregated (group_id=0) 1220 */ 1221 for ( ; i < adr_link->num_adr; i++) { 1222 int codec_index; 1223 1224 codec_index = find_codec_info_part(adr_link->adr_d[i].adr); 1225 if (codec_index < 0) 1226 return codec_index; 1227 1228 /* The group_id is > 0 iff the codec is aggregated */ 1229 if (adr_link->adr_d[i].endpoints->group_id != group_id) 1230 continue; 1231 1232 if (codec_info_list[codec_index].dais[dai_index].init) 1233 codec_info_list[codec_index].dais[dai_index].init(card, 1234 adr_link, 1235 dai_links, 1236 &codec_info_list[codec_index], 1237 playback); 1238 if (!group_id) 1239 return 0; 1240 } 1241 1242 i = 0; 1243 adr_link++; 1244 } while (adr_link->mask); 1245 1246 return 0; 1247 } 1248 1249 /* 1250 * check endpoint status in slaves and gather link ID for all slaves in 1251 * the same group to generate different CPU DAI. Now only support 1252 * one sdw link with all slaves set with only single group id. 1253 * 1254 * one slave on one sdw link with aggregated = 0 1255 * one sdw BE DAI <---> one-cpu DAI <---> one-codec DAI 1256 * 1257 * two or more slaves on one sdw link with aggregated = 0 1258 * one sdw BE DAI <---> one-cpu DAI <---> multi-codec DAIs 1259 * 1260 * multiple links with multiple slaves with aggregated = 1 1261 * one sdw BE DAI <---> 1 .. N CPU DAIs <----> 1 .. N codec DAIs 1262 */ 1263 static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link, 1264 struct device *dev, int *cpu_dai_id, int *cpu_dai_num, 1265 int *codec_num, unsigned int *group_id, 1266 int adr_index) 1267 { 1268 bool no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION; 1269 int i; 1270 1271 if (!adr_link->adr_d[adr_index].endpoints->aggregated || no_aggregation) { 1272 cpu_dai_id[0] = ffs(adr_link->mask) - 1; 1273 *cpu_dai_num = 1; 1274 *codec_num = 1; 1275 *group_id = 0; 1276 return 0; 1277 } 1278 1279 *codec_num = 0; 1280 *cpu_dai_num = 0; 1281 *group_id = adr_link->adr_d[adr_index].endpoints->group_id; 1282 1283 /* Count endpoints with the same group_id in the adr_link */ 1284 for (; adr_link && adr_link->num_adr; adr_link++) { 1285 unsigned int link_codecs = 0; 1286 1287 for (i = 0; i < adr_link->num_adr; i++) { 1288 if (adr_link->adr_d[i].endpoints->aggregated && 1289 adr_link->adr_d[i].endpoints->group_id == *group_id) 1290 link_codecs++; 1291 } 1292 1293 if (link_codecs) { 1294 *codec_num += link_codecs; 1295 1296 if (*cpu_dai_num >= SDW_MAX_CPU_DAIS) { 1297 dev_err(dev, "cpu_dai_id array overflowed\n"); 1298 return -EINVAL; 1299 } 1300 1301 cpu_dai_id[(*cpu_dai_num)++] = ffs(adr_link->mask) - 1; 1302 } 1303 } 1304 1305 return 0; 1306 } 1307 1308 static void set_dailink_map(struct snd_soc_dai_link_codec_ch_map *sdw_codec_ch_maps, 1309 int codec_num, int cpu_num) 1310 { 1311 int step; 1312 int i; 1313 1314 step = codec_num / cpu_num; 1315 for (i = 0; i < codec_num; i++) 1316 sdw_codec_ch_maps[i].connected_cpu_id = i / step; 1317 } 1318 1319 static const char * const type_strings[] = {"SimpleJack", "SmartAmp", "SmartMic"}; 1320 1321 static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, 1322 struct snd_soc_dai_link *dai_links, 1323 int sdw_be_num, int sdw_cpu_dai_num, 1324 struct snd_soc_dai_link_component *cpus, 1325 const struct snd_soc_acpi_link_adr *adr_link, 1326 int *cpu_id, struct snd_soc_codec_conf *codec_conf, 1327 int codec_count, int *be_id, 1328 int *codec_conf_index, 1329 bool *ignore_pch_dmic, 1330 bool append_dai_type, 1331 int adr_index, 1332 int dai_index) 1333 { 1334 struct device *dev = card->dev; 1335 const struct snd_soc_acpi_link_adr *adr_link_next; 1336 struct snd_soc_dai_link_component *codecs; 1337 struct sof_sdw_codec_info *codec_info; 1338 int cpu_dai_id[SDW_MAX_CPU_DAIS]; 1339 int cpu_dai_num, cpu_dai_index; 1340 unsigned int group_id; 1341 int codec_dlc_index = 0; 1342 int codec_index; 1343 int codec_num; 1344 int stream; 1345 int i = 0; 1346 int j, k; 1347 int ret; 1348 1349 ret = get_slave_info(adr_link, dev, cpu_dai_id, &cpu_dai_num, &codec_num, 1350 &group_id, adr_index); 1351 if (ret) 1352 return ret; 1353 1354 codecs = devm_kcalloc(dev, codec_num, sizeof(*codecs), GFP_KERNEL); 1355 if (!codecs) 1356 return -ENOMEM; 1357 1358 /* generate codec name on different links in the same group */ 1359 j = adr_index; 1360 for (adr_link_next = adr_link; adr_link_next && adr_link_next->num_adr && 1361 i < cpu_dai_num; adr_link_next++) { 1362 /* skip the link excluded by this processed group */ 1363 if (cpu_dai_id[i] != ffs(adr_link_next->mask) - 1) 1364 continue; 1365 1366 /* j reset after loop, adr_index only applies to first link */ 1367 for (; j < adr_link_next->num_adr; j++) { 1368 const struct snd_soc_acpi_endpoint *endpoints; 1369 1370 endpoints = adr_link_next->adr_d[j].endpoints; 1371 1372 if (group_id && (!endpoints->aggregated || 1373 endpoints->group_id != group_id)) 1374 continue; 1375 1376 /* sanity check */ 1377 if (*codec_conf_index >= codec_count) { 1378 dev_err(dev, "codec_conf array overflowed\n"); 1379 return -EINVAL; 1380 } 1381 1382 ret = fill_sdw_codec_dlc(dev, adr_link_next, 1383 &codecs[codec_dlc_index], 1384 j, dai_index); 1385 if (ret) 1386 return ret; 1387 1388 codec_conf[*codec_conf_index].dlc = codecs[codec_dlc_index]; 1389 codec_conf[*codec_conf_index].name_prefix = 1390 adr_link_next->adr_d[j].name_prefix; 1391 1392 codec_dlc_index++; 1393 (*codec_conf_index)++; 1394 } 1395 j = 0; 1396 1397 /* check next link to create codec dai in the processed group */ 1398 i++; 1399 } 1400 1401 /* find codec info to create BE DAI */ 1402 codec_index = find_codec_info_part(adr_link->adr_d[adr_index].adr); 1403 if (codec_index < 0) 1404 return codec_index; 1405 codec_info = &codec_info_list[codec_index]; 1406 1407 if (codec_info->ignore_pch_dmic) 1408 *ignore_pch_dmic = true; 1409 1410 cpu_dai_index = *cpu_id; 1411 for_each_pcm_streams(stream) { 1412 struct snd_soc_dai_link_codec_ch_map *sdw_codec_ch_maps; 1413 char *name, *cpu_name; 1414 int playback, capture; 1415 static const char * const sdw_stream_name[] = { 1416 "SDW%d-Playback", 1417 "SDW%d-Capture", 1418 "SDW%d-Playback-%s", 1419 "SDW%d-Capture-%s", 1420 }; 1421 1422 if (!codec_info->dais[dai_index].direction[stream]) 1423 continue; 1424 1425 *be_id = codec_info->dais[dai_index].dailink[stream]; 1426 if (*be_id < 0) { 1427 dev_err(dev, "Invalid dailink id %d\n", *be_id); 1428 return -EINVAL; 1429 } 1430 1431 sdw_codec_ch_maps = devm_kcalloc(dev, codec_num, 1432 sizeof(*sdw_codec_ch_maps), GFP_KERNEL); 1433 if (!sdw_codec_ch_maps) 1434 return -ENOMEM; 1435 1436 /* create stream name according to first link id */ 1437 if (append_dai_type) { 1438 name = devm_kasprintf(dev, GFP_KERNEL, 1439 sdw_stream_name[stream + 2], cpu_dai_id[0], 1440 type_strings[codec_info->dais[dai_index].dai_type]); 1441 } else { 1442 name = devm_kasprintf(dev, GFP_KERNEL, 1443 sdw_stream_name[stream], cpu_dai_id[0]); 1444 } 1445 if (!name) 1446 return -ENOMEM; 1447 1448 /* 1449 * generate CPU DAI name base on the sdw link ID and 1450 * PIN ID with offset of 2 according to sdw dai driver. 1451 */ 1452 for (k = 0; k < cpu_dai_num; k++) { 1453 cpu_name = devm_kasprintf(dev, GFP_KERNEL, 1454 "SDW%d Pin%d", cpu_dai_id[k], 1455 sdw_pin_index[cpu_dai_id[k]]++); 1456 if (!cpu_name) 1457 return -ENOMEM; 1458 1459 if (cpu_dai_index >= sdw_cpu_dai_num) { 1460 dev_err(dev, "invalid cpu dai index %d\n", 1461 cpu_dai_index); 1462 return -EINVAL; 1463 } 1464 1465 cpus[cpu_dai_index++].dai_name = cpu_name; 1466 } 1467 1468 /* 1469 * We create sdw dai links at first stage, so link index should 1470 * not be larger than sdw_be_num 1471 */ 1472 if (*link_index >= sdw_be_num) { 1473 dev_err(dev, "invalid dai link index %d\n", *link_index); 1474 return -EINVAL; 1475 } 1476 1477 if (*cpu_id >= sdw_cpu_dai_num) { 1478 dev_err(dev, "invalid cpu dai index %d\n", *cpu_id); 1479 return -EINVAL; 1480 } 1481 1482 playback = (stream == SNDRV_PCM_STREAM_PLAYBACK); 1483 capture = (stream == SNDRV_PCM_STREAM_CAPTURE); 1484 init_dai_link(dev, dai_links + *link_index, (*be_id)++, name, 1485 playback, capture, 1486 cpus + *cpu_id, cpu_dai_num, 1487 codecs, codec_num, 1488 NULL, &sdw_ops); 1489 1490 /* 1491 * SoundWire DAILINKs use 'stream' functions and Bank Switch operations 1492 * based on wait_for_completion(), tag them as 'nonatomic'. 1493 */ 1494 dai_links[*link_index].nonatomic = true; 1495 1496 set_dailink_map(sdw_codec_ch_maps, codec_num, cpu_dai_num); 1497 dai_links[*link_index].codec_ch_maps = sdw_codec_ch_maps; 1498 ret = set_codec_init_func(card, adr_link, dai_links + (*link_index)++, 1499 playback, group_id, adr_index, dai_index); 1500 if (ret < 0) { 1501 dev_err(dev, "failed to init codec %d\n", codec_index); 1502 return ret; 1503 } 1504 1505 *cpu_id += cpu_dai_num; 1506 } 1507 1508 return 0; 1509 } 1510 1511 #define IDISP_CODEC_MASK 0x4 1512 1513 static int sof_card_dai_links_create(struct snd_soc_card *card) 1514 { 1515 struct device *dev = card->dev; 1516 struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev); 1517 int sdw_be_num = 0, ssp_num = 0, dmic_num = 0, hdmi_num = 0, bt_num = 0; 1518 struct mc_private *ctx = snd_soc_card_get_drvdata(card); 1519 struct snd_soc_dai_link_component *idisp_components; 1520 struct snd_soc_dai_link_component *ssp_components; 1521 struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params; 1522 const struct snd_soc_acpi_link_adr *adr_link = mach_params->links; 1523 bool aggregation = !(sof_sdw_quirk & SOF_SDW_NO_AGGREGATION); 1524 struct snd_soc_dai_link_component *cpus; 1525 struct snd_soc_codec_conf *codec_conf; 1526 bool append_dai_type = false; 1527 bool ignore_pch_dmic = false; 1528 int codec_conf_num = 0; 1529 int codec_conf_index = 0; 1530 bool group_generated[SDW_MAX_GROUPS] = { }; 1531 int ssp_codec_index, ssp_mask; 1532 struct snd_soc_dai_link *dai_links; 1533 int num_links, link_index = 0; 1534 char *name, *cpu_name; 1535 int total_cpu_dai_num; 1536 int sdw_cpu_dai_num; 1537 int i, j, be_id = 0; 1538 int codec_index; 1539 int cpu_id = 0; 1540 int ret; 1541 1542 ret = get_dailink_info(dev, adr_link, &sdw_be_num, &sdw_cpu_dai_num, 1543 &codec_conf_num); 1544 if (ret < 0) { 1545 dev_err(dev, "failed to get sdw link info %d\n", ret); 1546 return ret; 1547 } 1548 1549 /* 1550 * on generic tgl platform, I2S or sdw mode is supported 1551 * based on board rework. A ACPI device is registered in 1552 * system only when I2S mode is supported, not sdw mode. 1553 * Here check ACPI ID to confirm I2S is supported. 1554 */ 1555 ssp_codec_index = find_codec_info_acpi(mach->id); 1556 if (ssp_codec_index >= 0) { 1557 ssp_mask = SOF_SSP_GET_PORT(sof_sdw_quirk); 1558 ssp_num = hweight_long(ssp_mask); 1559 } 1560 1561 if (mach_params->codec_mask & IDISP_CODEC_MASK) { 1562 ctx->idisp_codec = true; 1563 1564 if (sof_sdw_quirk & SOF_SDW_TGL_HDMI) 1565 hdmi_num = SOF_TGL_HDMI_COUNT; 1566 else 1567 hdmi_num = SOF_PRE_TGL_HDMI_COUNT; 1568 } 1569 1570 /* enable dmic01 & dmic16k */ 1571 if (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num) 1572 dmic_num = 2; 1573 1574 if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) 1575 bt_num = 1; 1576 1577 dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d, bt: %d\n", 1578 sdw_be_num, ssp_num, dmic_num, hdmi_num, bt_num); 1579 1580 /* allocate BE dailinks */ 1581 num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num; 1582 dai_links = devm_kcalloc(dev, num_links, sizeof(*dai_links), GFP_KERNEL); 1583 if (!dai_links) 1584 return -ENOMEM; 1585 1586 /* allocated CPU DAIs */ 1587 total_cpu_dai_num = sdw_cpu_dai_num + ssp_num + dmic_num + hdmi_num + bt_num; 1588 cpus = devm_kcalloc(dev, total_cpu_dai_num, sizeof(*cpus), GFP_KERNEL); 1589 if (!cpus) 1590 return -ENOMEM; 1591 1592 /* allocate codec conf, will be populated when dailinks are created */ 1593 codec_conf = devm_kcalloc(dev, codec_conf_num, sizeof(*codec_conf), 1594 GFP_KERNEL); 1595 if (!codec_conf) 1596 return -ENOMEM; 1597 1598 /* SDW */ 1599 if (!sdw_be_num) 1600 goto SSP; 1601 1602 for (i = 0; i < SDW_MAX_LINKS; i++) 1603 sdw_pin_index[i] = SDW_INTEL_BIDIR_PDI_BASE; 1604 1605 for (; adr_link->num_adr; adr_link++) { 1606 /* 1607 * If there are two or more different devices on the same sdw link, we have to 1608 * append the codec type to the dai link name to prevent duplicated dai link name. 1609 * The same type devices on the same sdw link will be in the same 1610 * snd_soc_acpi_adr_device array. They won't be described in different adr_links. 1611 */ 1612 for (i = 0; i < adr_link->num_adr; i++) { 1613 /* find codec info to get dai_num */ 1614 codec_index = find_codec_info_part(adr_link->adr_d[i].adr); 1615 if (codec_index < 0) 1616 return codec_index; 1617 if (codec_info_list[codec_index].dai_num > 1) { 1618 append_dai_type = true; 1619 goto out; 1620 } 1621 for (j = 0; j < i; j++) { 1622 if ((SDW_PART_ID(adr_link->adr_d[i].adr) != 1623 SDW_PART_ID(adr_link->adr_d[j].adr)) || 1624 (SDW_MFG_ID(adr_link->adr_d[i].adr) != 1625 SDW_MFG_ID(adr_link->adr_d[j].adr))) { 1626 append_dai_type = true; 1627 goto out; 1628 } 1629 } 1630 } 1631 } 1632 out: 1633 1634 /* generate DAI links by each sdw link */ 1635 for (adr_link = mach_params->links ; adr_link->num_adr; adr_link++) { 1636 for (i = 0; i < adr_link->num_adr; i++) { 1637 const struct snd_soc_acpi_endpoint *endpoint; 1638 1639 endpoint = adr_link->adr_d[i].endpoints; 1640 1641 /* this group has been generated */ 1642 if (endpoint->aggregated && 1643 group_generated[endpoint->group_id]) 1644 continue; 1645 1646 /* find codec info to get dai_num */ 1647 codec_index = find_codec_info_part(adr_link->adr_d[i].adr); 1648 if (codec_index < 0) 1649 return codec_index; 1650 1651 for (j = 0; j < codec_info_list[codec_index].dai_num ; j++) { 1652 ret = create_sdw_dailink(card, &link_index, dai_links, 1653 sdw_be_num, sdw_cpu_dai_num, cpus, 1654 adr_link, &cpu_id, 1655 codec_conf, codec_conf_num, 1656 &be_id, &codec_conf_index, 1657 &ignore_pch_dmic, append_dai_type, i, j); 1658 if (ret < 0) { 1659 dev_err(dev, "failed to create dai link %d\n", link_index); 1660 return ret; 1661 } 1662 } 1663 1664 if (aggregation && endpoint->aggregated) 1665 group_generated[endpoint->group_id] = true; 1666 } 1667 } 1668 1669 SSP: 1670 /* SSP */ 1671 if (!ssp_num) 1672 goto DMIC; 1673 1674 for (i = 0, j = 0; ssp_mask; i++, ssp_mask >>= 1) { 1675 struct sof_sdw_codec_info *info; 1676 int playback, capture; 1677 char *codec_name; 1678 1679 if (!(ssp_mask & 0x1)) 1680 continue; 1681 1682 name = devm_kasprintf(dev, GFP_KERNEL, 1683 "SSP%d-Codec", i); 1684 if (!name) 1685 return -ENOMEM; 1686 1687 cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i); 1688 if (!cpu_name) 1689 return -ENOMEM; 1690 1691 ssp_components = devm_kzalloc(dev, sizeof(*ssp_components), 1692 GFP_KERNEL); 1693 if (!ssp_components) 1694 return -ENOMEM; 1695 1696 info = &codec_info_list[ssp_codec_index]; 1697 codec_name = devm_kasprintf(dev, GFP_KERNEL, "i2c-%s:0%d", 1698 info->acpi_id, j++); 1699 if (!codec_name) 1700 return -ENOMEM; 1701 1702 ssp_components->name = codec_name; 1703 /* TODO: support multi codec dai on SSP when it is needed */ 1704 ssp_components->dai_name = info->dais[0].dai_name; 1705 cpus[cpu_id].dai_name = cpu_name; 1706 1707 playback = info->dais[0].direction[SNDRV_PCM_STREAM_PLAYBACK]; 1708 capture = info->dais[0].direction[SNDRV_PCM_STREAM_CAPTURE]; 1709 init_dai_link(dev, dai_links + link_index, be_id, name, 1710 playback, capture, 1711 cpus + cpu_id, 1, 1712 ssp_components, 1, 1713 NULL, info->ops); 1714 1715 ret = info->dais[0].init(card, NULL, dai_links + link_index, info, 0); 1716 if (ret < 0) 1717 return ret; 1718 1719 INC_ID(be_id, cpu_id, link_index); 1720 } 1721 1722 DMIC: 1723 /* dmic */ 1724 if (dmic_num > 0) { 1725 if (ignore_pch_dmic) { 1726 dev_warn(dev, "Ignoring PCH DMIC\n"); 1727 goto HDMI; 1728 } 1729 cpus[cpu_id].dai_name = "DMIC01 Pin"; 1730 init_dai_link(dev, dai_links + link_index, be_id, "dmic01", 1731 0, 1, // DMIC only supports capture 1732 cpus + cpu_id, 1, 1733 dmic_component, 1, 1734 sof_sdw_dmic_init, NULL); 1735 INC_ID(be_id, cpu_id, link_index); 1736 1737 cpus[cpu_id].dai_name = "DMIC16k Pin"; 1738 init_dai_link(dev, dai_links + link_index, be_id, "dmic16k", 1739 0, 1, // DMIC only supports capture 1740 cpus + cpu_id, 1, 1741 dmic_component, 1, 1742 /* don't call sof_sdw_dmic_init() twice */ 1743 NULL, NULL); 1744 INC_ID(be_id, cpu_id, link_index); 1745 } 1746 1747 HDMI: 1748 /* HDMI */ 1749 if (hdmi_num > 0) { 1750 idisp_components = devm_kcalloc(dev, hdmi_num, 1751 sizeof(*idisp_components), 1752 GFP_KERNEL); 1753 if (!idisp_components) 1754 return -ENOMEM; 1755 } 1756 1757 for (i = 0; i < hdmi_num; i++) { 1758 name = devm_kasprintf(dev, GFP_KERNEL, 1759 "iDisp%d", i + 1); 1760 if (!name) 1761 return -ENOMEM; 1762 1763 if (ctx->idisp_codec) { 1764 idisp_components[i].name = "ehdaudio0D2"; 1765 idisp_components[i].dai_name = devm_kasprintf(dev, 1766 GFP_KERNEL, 1767 "intel-hdmi-hifi%d", 1768 i + 1); 1769 if (!idisp_components[i].dai_name) 1770 return -ENOMEM; 1771 } else { 1772 idisp_components[i] = asoc_dummy_dlc; 1773 } 1774 1775 cpu_name = devm_kasprintf(dev, GFP_KERNEL, 1776 "iDisp%d Pin", i + 1); 1777 if (!cpu_name) 1778 return -ENOMEM; 1779 1780 cpus[cpu_id].dai_name = cpu_name; 1781 init_dai_link(dev, dai_links + link_index, be_id, name, 1782 1, 0, // HDMI only supports playback 1783 cpus + cpu_id, 1, 1784 idisp_components + i, 1, 1785 sof_sdw_hdmi_init, NULL); 1786 INC_ID(be_id, cpu_id, link_index); 1787 } 1788 1789 if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) { 1790 int port = (sof_sdw_quirk & SOF_BT_OFFLOAD_SSP_MASK) >> 1791 SOF_BT_OFFLOAD_SSP_SHIFT; 1792 1793 name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); 1794 if (!name) 1795 return -ENOMEM; 1796 1797 cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port); 1798 if (!cpu_name) 1799 return -ENOMEM; 1800 1801 cpus[cpu_id].dai_name = cpu_name; 1802 init_dai_link(dev, dai_links + link_index, be_id, name, 1, 1, 1803 cpus + cpu_id, 1, &asoc_dummy_dlc, 1, NULL, NULL); 1804 } 1805 1806 card->dai_link = dai_links; 1807 card->num_links = num_links; 1808 1809 card->codec_conf = codec_conf; 1810 card->num_configs = codec_conf_num; 1811 1812 return 0; 1813 } 1814 1815 static int sof_sdw_card_late_probe(struct snd_soc_card *card) 1816 { 1817 struct mc_private *ctx = snd_soc_card_get_drvdata(card); 1818 int ret = 0; 1819 int i; 1820 1821 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { 1822 if (codec_info_list[i].codec_card_late_probe) { 1823 ret = codec_info_list[i].codec_card_late_probe(card); 1824 1825 if (ret < 0) 1826 return ret; 1827 } 1828 } 1829 1830 if (ctx->idisp_codec) 1831 ret = sof_sdw_hdmi_card_late_probe(card); 1832 1833 return ret; 1834 } 1835 1836 /* SoC card */ 1837 static const char sdw_card_long_name[] = "Intel Soundwire SOF"; 1838 1839 static struct snd_soc_card card_sof_sdw = { 1840 .name = "soundwire", 1841 .owner = THIS_MODULE, 1842 .late_probe = sof_sdw_card_late_probe, 1843 }; 1844 1845 /* helper to get the link that the codec DAI is used */ 1846 static struct snd_soc_dai_link *mc_find_codec_dai_used(struct snd_soc_card *card, 1847 const char *dai_name) 1848 { 1849 struct snd_soc_dai_link *dai_link; 1850 int i; 1851 int j; 1852 1853 for_each_card_prelinks(card, i, dai_link) { 1854 for (j = 0; j < dai_link->num_codecs; j++) { 1855 /* Check each codec in a link */ 1856 if (!strcmp(dai_link->codecs[j].dai_name, dai_name)) 1857 return dai_link; 1858 } 1859 } 1860 return NULL; 1861 } 1862 1863 static void mc_dailink_exit_loop(struct snd_soc_card *card) 1864 { 1865 struct snd_soc_dai_link *dai_link; 1866 int ret; 1867 int i, j; 1868 1869 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { 1870 for (j = 0; j < codec_info_list[i].dai_num; j++) { 1871 /* Check each dai in codec_info_lis to see if it is used in the link */ 1872 if (!codec_info_list[i].dais[j].exit) 1873 continue; 1874 /* 1875 * We don't need to call .exit function if there is no matched 1876 * dai link found. 1877 */ 1878 dai_link = mc_find_codec_dai_used(card, 1879 codec_info_list[i].dais[j].dai_name); 1880 if (dai_link) { 1881 /* Do the .exit function if the codec dai is used in the link */ 1882 ret = codec_info_list[i].dais[j].exit(card, dai_link); 1883 if (ret) 1884 dev_warn(card->dev, 1885 "codec exit failed %d\n", 1886 ret); 1887 break; 1888 } 1889 } 1890 } 1891 } 1892 1893 static int mc_probe(struct platform_device *pdev) 1894 { 1895 struct snd_soc_card *card = &card_sof_sdw; 1896 struct snd_soc_acpi_mach *mach = dev_get_platdata(&pdev->dev); 1897 struct mc_private *ctx; 1898 int amp_num = 0, i; 1899 int ret; 1900 1901 card->dev = &pdev->dev; 1902 1903 dev_dbg(card->dev, "Entry\n"); 1904 1905 ctx = devm_kzalloc(card->dev, sizeof(*ctx), GFP_KERNEL); 1906 if (!ctx) 1907 return -ENOMEM; 1908 1909 INIT_LIST_HEAD(&ctx->hdmi_pcm_list); 1910 1911 snd_soc_card_set_drvdata(card, ctx); 1912 1913 dmi_check_system(sof_sdw_quirk_table); 1914 1915 if (quirk_override != -1) { 1916 dev_info(card->dev, "Overriding quirk 0x%lx => 0x%x\n", 1917 sof_sdw_quirk, quirk_override); 1918 sof_sdw_quirk = quirk_override; 1919 } 1920 1921 log_quirks(card->dev); 1922 1923 /* reset amp_num to ensure amp_num++ starts from 0 in each probe */ 1924 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) 1925 codec_info_list[i].amp_num = 0; 1926 1927 ret = sof_card_dai_links_create(card); 1928 if (ret < 0) 1929 return ret; 1930 1931 /* 1932 * the default amp_num is zero for each codec and 1933 * amp_num will only be increased for active amp 1934 * codecs on used platform 1935 */ 1936 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) 1937 amp_num += codec_info_list[i].amp_num; 1938 1939 card->components = devm_kasprintf(card->dev, GFP_KERNEL, 1940 "cfg-spk:%d cfg-amp:%d", 1941 (sof_sdw_quirk & SOF_SDW_FOUR_SPK) 1942 ? 4 : 2, amp_num); 1943 if (!card->components) 1944 return -ENOMEM; 1945 1946 if (mach->mach_params.dmic_num) { 1947 card->components = devm_kasprintf(card->dev, GFP_KERNEL, 1948 "%s mic:dmic cfg-mics:%d", 1949 card->components, 1950 mach->mach_params.dmic_num); 1951 if (!card->components) 1952 return -ENOMEM; 1953 } 1954 1955 card->long_name = sdw_card_long_name; 1956 1957 /* Register the card */ 1958 ret = devm_snd_soc_register_card(card->dev, card); 1959 if (ret) { 1960 dev_err(card->dev, "snd_soc_register_card failed %d\n", ret); 1961 mc_dailink_exit_loop(card); 1962 return ret; 1963 } 1964 1965 platform_set_drvdata(pdev, card); 1966 1967 return ret; 1968 } 1969 1970 static void mc_remove(struct platform_device *pdev) 1971 { 1972 struct snd_soc_card *card = platform_get_drvdata(pdev); 1973 1974 mc_dailink_exit_loop(card); 1975 } 1976 1977 static const struct platform_device_id mc_id_table[] = { 1978 { "sof_sdw", }, 1979 {} 1980 }; 1981 MODULE_DEVICE_TABLE(platform, mc_id_table); 1982 1983 static struct platform_driver sof_sdw_driver = { 1984 .driver = { 1985 .name = "sof_sdw", 1986 .pm = &snd_soc_pm_ops, 1987 }, 1988 .probe = mc_probe, 1989 .remove_new = mc_remove, 1990 .id_table = mc_id_table, 1991 }; 1992 1993 module_platform_driver(sof_sdw_driver); 1994 1995 MODULE_DESCRIPTION("ASoC SoundWire Generic Machine driver"); 1996 MODULE_AUTHOR("Bard Liao <yung-chuan.liao@linux.intel.com>"); 1997 MODULE_AUTHOR("Rander Wang <rander.wang@linux.intel.com>"); 1998 MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>"); 1999 MODULE_LICENSE("GPL v2"); 2000 MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); 2001 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); 2002