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