1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Intel Skylake I2S Machine Driver for NAU88L25+SSM4567 4 * 5 * Copyright (C) 2015, Intel Corporation. All rights reserved. 6 * 7 * Modified from: 8 * Intel Skylake I2S Machine Driver for NAU88L25 and SSM4567 9 * 10 * Copyright (C) 2015, Intel Corporation. All rights reserved. 11 */ 12 13 #include <linux/module.h> 14 #include <linux/platform_device.h> 15 #include <sound/core.h> 16 #include <sound/pcm.h> 17 #include <sound/soc.h> 18 #include <sound/soc-acpi.h> 19 #include <sound/jack.h> 20 #include <sound/pcm_params.h> 21 #include "../../codecs/nau8825.h" 22 #include "../../codecs/hdac_hdmi.h" 23 24 #define SKL_NUVOTON_CODEC_DAI "nau8825-hifi" 25 #define SKL_SSM_CODEC_DAI "ssm4567-hifi" 26 #define DMIC_CH(p) p->list[p->count-1] 27 28 static struct snd_soc_jack skylake_headset; 29 static struct snd_soc_card skylake_audio_card; 30 static const struct snd_pcm_hw_constraint_list *dmic_constraints; 31 static struct snd_soc_jack skylake_hdmi[3]; 32 33 struct skl_hdmi_pcm { 34 struct list_head head; 35 struct snd_soc_dai *codec_dai; 36 int device; 37 }; 38 39 struct skl_nau88125_private { 40 struct list_head hdmi_pcm_list; 41 }; 42 enum { 43 SKL_DPCM_AUDIO_PB = 0, 44 SKL_DPCM_AUDIO_CP, 45 SKL_DPCM_AUDIO_REF_CP, 46 SKL_DPCM_AUDIO_DMIC_CP, 47 SKL_DPCM_AUDIO_HDMI1_PB, 48 SKL_DPCM_AUDIO_HDMI2_PB, 49 SKL_DPCM_AUDIO_HDMI3_PB, 50 }; 51 52 static const struct snd_kcontrol_new skylake_controls[] = { 53 SOC_DAPM_PIN_SWITCH("Headphone Jack"), 54 SOC_DAPM_PIN_SWITCH("Headset Mic"), 55 SOC_DAPM_PIN_SWITCH("Left Speaker"), 56 SOC_DAPM_PIN_SWITCH("Right Speaker"), 57 }; 58 59 static int platform_clock_control(struct snd_soc_dapm_widget *w, 60 struct snd_kcontrol *k, int event) 61 { 62 struct snd_soc_dapm_context *dapm = w->dapm; 63 struct snd_soc_card *card = dapm->card; 64 struct snd_soc_dai *codec_dai; 65 int ret; 66 67 codec_dai = snd_soc_card_get_codec_dai(card, SKL_NUVOTON_CODEC_DAI); 68 if (!codec_dai) { 69 dev_err(card->dev, "Codec dai not found\n"); 70 return -EIO; 71 } 72 73 if (SND_SOC_DAPM_EVENT_ON(event)) { 74 ret = snd_soc_dai_set_sysclk(codec_dai, 75 NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN); 76 if (ret < 0) { 77 dev_err(card->dev, "set sysclk err = %d\n", ret); 78 return -EIO; 79 } 80 } else { 81 ret = snd_soc_dai_set_sysclk(codec_dai, 82 NAU8825_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN); 83 if (ret < 0) { 84 dev_err(card->dev, "set sysclk err = %d\n", ret); 85 return -EIO; 86 } 87 } 88 return ret; 89 } 90 91 static const struct snd_soc_dapm_widget skylake_widgets[] = { 92 SND_SOC_DAPM_HP("Headphone Jack", NULL), 93 SND_SOC_DAPM_MIC("Headset Mic", NULL), 94 SND_SOC_DAPM_SPK("Left Speaker", NULL), 95 SND_SOC_DAPM_SPK("Right Speaker", NULL), 96 SND_SOC_DAPM_MIC("SoC DMIC", NULL), 97 SND_SOC_DAPM_SPK("DP1", NULL), 98 SND_SOC_DAPM_SPK("DP2", NULL), 99 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, 100 platform_clock_control, SND_SOC_DAPM_PRE_PMU | 101 SND_SOC_DAPM_POST_PMD), 102 }; 103 104 static const struct snd_soc_dapm_route skylake_map[] = { 105 /* HP jack connectors - unknown if we have jack detection */ 106 {"Headphone Jack", NULL, "HPOL"}, 107 {"Headphone Jack", NULL, "HPOR"}, 108 109 /* speaker */ 110 {"Left Speaker", NULL, "Left OUT"}, 111 {"Right Speaker", NULL, "Right OUT"}, 112 113 /* other jacks */ 114 {"MIC", NULL, "Headset Mic"}, 115 {"DMic", NULL, "SoC DMIC"}, 116 117 /* CODEC BE connections */ 118 { "Left Playback", NULL, "ssp0 Tx"}, 119 { "Right Playback", NULL, "ssp0 Tx"}, 120 { "ssp0 Tx", NULL, "codec0_out"}, 121 122 /* IV feedback path */ 123 { "codec0_lp_in", NULL, "ssp0 Rx"}, 124 { "ssp0 Rx", NULL, "Left Capture Sense" }, 125 { "ssp0 Rx", NULL, "Right Capture Sense" }, 126 127 { "Playback", NULL, "ssp1 Tx"}, 128 { "ssp1 Tx", NULL, "codec1_out"}, 129 130 { "codec0_in", NULL, "ssp1 Rx" }, 131 { "ssp1 Rx", NULL, "Capture" }, 132 133 /* DMIC */ 134 { "dmic01_hifi", NULL, "DMIC01 Rx" }, 135 { "DMIC01 Rx", NULL, "DMIC AIF" }, 136 137 { "hifi3", NULL, "iDisp3 Tx"}, 138 { "iDisp3 Tx", NULL, "iDisp3_out"}, 139 { "hifi2", NULL, "iDisp2 Tx"}, 140 { "iDisp2 Tx", NULL, "iDisp2_out"}, 141 { "hifi1", NULL, "iDisp1 Tx"}, 142 { "iDisp1 Tx", NULL, "iDisp1_out"}, 143 144 { "Headphone Jack", NULL, "Platform Clock" }, 145 { "Headset Mic", NULL, "Platform Clock" }, 146 }; 147 148 static struct snd_soc_codec_conf ssm4567_codec_conf[] = { 149 { 150 .dlc = COMP_CODEC_CONF("i2c-INT343B:00"), 151 .name_prefix = "Left", 152 }, 153 { 154 .dlc = COMP_CODEC_CONF("i2c-INT343B:01"), 155 .name_prefix = "Right", 156 }, 157 }; 158 159 static int skylake_ssm4567_codec_init(struct snd_soc_pcm_runtime *rtd) 160 { 161 int ret; 162 163 /* Slot 1 for left */ 164 ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 0x01, 0x01, 2, 48); 165 if (ret < 0) 166 return ret; 167 168 /* Slot 2 for right */ 169 ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 1), 0x02, 0x02, 2, 48); 170 if (ret < 0) 171 return ret; 172 173 return ret; 174 } 175 176 static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) 177 { 178 int ret; 179 struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 180 181 /* 182 * 4 buttons here map to the google Reference headset 183 * The use of these buttons can be decided by the user space. 184 */ 185 ret = snd_soc_card_jack_new(&skylake_audio_card, "Headset Jack", 186 SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | 187 SND_JACK_BTN_2 | SND_JACK_BTN_3, &skylake_headset, 188 NULL, 0); 189 if (ret) { 190 dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); 191 return ret; 192 } 193 194 nau8825_enable_jack_detect(component, &skylake_headset); 195 196 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); 197 198 return ret; 199 } 200 201 static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) 202 { 203 struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); 204 struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 205 struct skl_hdmi_pcm *pcm; 206 207 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); 208 if (!pcm) 209 return -ENOMEM; 210 211 pcm->device = SKL_DPCM_AUDIO_HDMI1_PB; 212 pcm->codec_dai = dai; 213 214 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); 215 216 return 0; 217 } 218 219 static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) 220 { 221 struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); 222 struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 223 struct skl_hdmi_pcm *pcm; 224 225 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); 226 if (!pcm) 227 return -ENOMEM; 228 229 pcm->device = SKL_DPCM_AUDIO_HDMI2_PB; 230 pcm->codec_dai = dai; 231 232 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); 233 234 return 0; 235 } 236 237 238 static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) 239 { 240 struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); 241 struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 242 struct skl_hdmi_pcm *pcm; 243 244 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); 245 if (!pcm) 246 return -ENOMEM; 247 248 pcm->device = SKL_DPCM_AUDIO_HDMI3_PB; 249 pcm->codec_dai = dai; 250 251 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); 252 253 return 0; 254 } 255 256 static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd) 257 { 258 struct snd_soc_dapm_context *dapm; 259 struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; 260 261 dapm = snd_soc_component_get_dapm(component); 262 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); 263 264 return 0; 265 } 266 267 static const unsigned int rates[] = { 268 48000, 269 }; 270 271 static const struct snd_pcm_hw_constraint_list constraints_rates = { 272 .count = ARRAY_SIZE(rates), 273 .list = rates, 274 .mask = 0, 275 }; 276 277 static const unsigned int channels[] = { 278 2, 279 }; 280 281 static const struct snd_pcm_hw_constraint_list constraints_channels = { 282 .count = ARRAY_SIZE(channels), 283 .list = channels, 284 .mask = 0, 285 }; 286 287 static int skl_fe_startup(struct snd_pcm_substream *substream) 288 { 289 struct snd_pcm_runtime *runtime = substream->runtime; 290 291 /* 292 * on this platform for PCM device we support, 293 * 48Khz 294 * stereo 295 * 16 bit audio 296 */ 297 298 runtime->hw.channels_max = 2; 299 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 300 &constraints_channels); 301 302 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; 303 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); 304 305 snd_pcm_hw_constraint_list(runtime, 0, 306 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 307 308 return 0; 309 } 310 311 static const struct snd_soc_ops skylake_nau8825_fe_ops = { 312 .startup = skl_fe_startup, 313 }; 314 315 static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, 316 struct snd_pcm_hw_params *params) 317 { 318 struct snd_interval *rate = hw_param_interval(params, 319 SNDRV_PCM_HW_PARAM_RATE); 320 struct snd_interval *chan = hw_param_interval(params, 321 SNDRV_PCM_HW_PARAM_CHANNELS); 322 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 323 324 /* The ADSP will covert the FE rate to 48k, stereo */ 325 rate->min = rate->max = 48000; 326 chan->min = chan->max = 2; 327 328 /* set SSP0 to 24 bit */ 329 snd_mask_none(fmt); 330 snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); 331 return 0; 332 } 333 334 static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, 335 struct snd_pcm_hw_params *params) 336 { 337 struct snd_interval *chan = hw_param_interval(params, 338 SNDRV_PCM_HW_PARAM_CHANNELS); 339 if (params_channels(params) == 2 || DMIC_CH(dmic_constraints) == 2) 340 chan->min = chan->max = 2; 341 else 342 chan->min = chan->max = 4; 343 344 return 0; 345 } 346 347 static int skylake_nau8825_hw_params(struct snd_pcm_substream *substream, 348 struct snd_pcm_hw_params *params) 349 { 350 struct snd_soc_pcm_runtime *rtd = substream->private_data; 351 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 352 int ret; 353 354 ret = snd_soc_dai_set_sysclk(codec_dai, 355 NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN); 356 357 if (ret < 0) 358 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); 359 360 return ret; 361 } 362 363 static const struct snd_soc_ops skylake_nau8825_ops = { 364 .hw_params = skylake_nau8825_hw_params, 365 }; 366 367 static const unsigned int channels_dmic[] = { 368 2, 4, 369 }; 370 371 static const struct snd_pcm_hw_constraint_list constraints_dmic_channels = { 372 .count = ARRAY_SIZE(channels_dmic), 373 .list = channels_dmic, 374 .mask = 0, 375 }; 376 377 static const unsigned int dmic_2ch[] = { 378 2, 379 }; 380 381 static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = { 382 .count = ARRAY_SIZE(dmic_2ch), 383 .list = dmic_2ch, 384 .mask = 0, 385 }; 386 387 static int skylake_dmic_startup(struct snd_pcm_substream *substream) 388 { 389 struct snd_pcm_runtime *runtime = substream->runtime; 390 391 runtime->hw.channels_max = DMIC_CH(dmic_constraints); 392 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 393 dmic_constraints); 394 395 return snd_pcm_hw_constraint_list(substream->runtime, 0, 396 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 397 } 398 399 static const struct snd_soc_ops skylake_dmic_ops = { 400 .startup = skylake_dmic_startup, 401 }; 402 403 static const unsigned int rates_16000[] = { 404 16000, 405 }; 406 407 static const struct snd_pcm_hw_constraint_list constraints_16000 = { 408 .count = ARRAY_SIZE(rates_16000), 409 .list = rates_16000, 410 }; 411 412 static const unsigned int ch_mono[] = { 413 1, 414 }; 415 416 static const struct snd_pcm_hw_constraint_list constraints_refcap = { 417 .count = ARRAY_SIZE(ch_mono), 418 .list = ch_mono, 419 }; 420 421 static int skylake_refcap_startup(struct snd_pcm_substream *substream) 422 { 423 substream->runtime->hw.channels_max = 1; 424 snd_pcm_hw_constraint_list(substream->runtime, 0, 425 SNDRV_PCM_HW_PARAM_CHANNELS, 426 &constraints_refcap); 427 428 return snd_pcm_hw_constraint_list(substream->runtime, 0, 429 SNDRV_PCM_HW_PARAM_RATE, 430 &constraints_16000); 431 } 432 433 static const struct snd_soc_ops skylake_refcap_ops = { 434 .startup = skylake_refcap_startup, 435 }; 436 437 SND_SOC_DAILINK_DEF(dummy, 438 DAILINK_COMP_ARRAY(COMP_DUMMY())); 439 440 SND_SOC_DAILINK_DEF(system, 441 DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); 442 443 SND_SOC_DAILINK_DEF(reference, 444 DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin"))); 445 446 SND_SOC_DAILINK_DEF(dmic, 447 DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); 448 449 SND_SOC_DAILINK_DEF(hdmi1, 450 DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin"))); 451 452 SND_SOC_DAILINK_DEF(hdmi2, 453 DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin"))); 454 455 SND_SOC_DAILINK_DEF(hdmi3, 456 DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin"))); 457 458 SND_SOC_DAILINK_DEF(ssp0_pin, 459 DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin"))); 460 SND_SOC_DAILINK_DEF(ssp0_codec, 461 DAILINK_COMP_ARRAY( 462 /* Left */ COMP_CODEC("i2c-INT343B:00", SKL_SSM_CODEC_DAI), 463 /* Right */ COMP_CODEC("i2c-INT343B:01", SKL_SSM_CODEC_DAI))); 464 465 SND_SOC_DAILINK_DEF(ssp1_pin, 466 DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin"))); 467 SND_SOC_DAILINK_DEF(ssp1_codec, 468 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10508825:00", SKL_NUVOTON_CODEC_DAI))); 469 470 SND_SOC_DAILINK_DEF(dmic01_pin, 471 DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); 472 SND_SOC_DAILINK_DEF(dmic_codec, 473 DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); 474 475 SND_SOC_DAILINK_DEF(idisp1_pin, 476 DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); 477 SND_SOC_DAILINK_DEF(idisp1_codec, 478 DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); 479 480 SND_SOC_DAILINK_DEF(idisp2_pin, 481 DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); 482 SND_SOC_DAILINK_DEF(idisp2_codec, 483 DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2"))); 484 485 SND_SOC_DAILINK_DEF(idisp3_pin, 486 DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); 487 SND_SOC_DAILINK_DEF(idisp3_codec, 488 DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3"))); 489 490 SND_SOC_DAILINK_DEF(platform, 491 DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3"))); 492 493 /* skylake digital audio interface glue - connects codec <--> CPU */ 494 static struct snd_soc_dai_link skylake_dais[] = { 495 /* Front End DAI links */ 496 [SKL_DPCM_AUDIO_PB] = { 497 .name = "Skl Audio Port", 498 .stream_name = "Audio", 499 .dynamic = 1, 500 .nonatomic = 1, 501 .init = skylake_nau8825_fe_init, 502 .trigger = { 503 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 504 .dpcm_playback = 1, 505 .ops = &skylake_nau8825_fe_ops, 506 SND_SOC_DAILINK_REG(system, dummy, platform), 507 }, 508 [SKL_DPCM_AUDIO_CP] = { 509 .name = "Skl Audio Capture Port", 510 .stream_name = "Audio Record", 511 .dynamic = 1, 512 .nonatomic = 1, 513 .trigger = { 514 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 515 .dpcm_capture = 1, 516 .ops = &skylake_nau8825_fe_ops, 517 SND_SOC_DAILINK_REG(system, dummy, platform), 518 }, 519 [SKL_DPCM_AUDIO_REF_CP] = { 520 .name = "Skl Audio Reference cap", 521 .stream_name = "Wake on Voice", 522 .init = NULL, 523 .dpcm_capture = 1, 524 .nonatomic = 1, 525 .dynamic = 1, 526 .ops = &skylake_refcap_ops, 527 SND_SOC_DAILINK_REG(reference, dummy, platform), 528 }, 529 [SKL_DPCM_AUDIO_DMIC_CP] = { 530 .name = "Skl Audio DMIC cap", 531 .stream_name = "dmiccap", 532 .init = NULL, 533 .dpcm_capture = 1, 534 .nonatomic = 1, 535 .dynamic = 1, 536 .ops = &skylake_dmic_ops, 537 SND_SOC_DAILINK_REG(dmic, dummy, platform), 538 }, 539 [SKL_DPCM_AUDIO_HDMI1_PB] = { 540 .name = "Skl HDMI Port1", 541 .stream_name = "Hdmi1", 542 .dpcm_playback = 1, 543 .init = NULL, 544 .trigger = { 545 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 546 .nonatomic = 1, 547 .dynamic = 1, 548 SND_SOC_DAILINK_REG(hdmi1, dummy, platform), 549 }, 550 [SKL_DPCM_AUDIO_HDMI2_PB] = { 551 .name = "Skl HDMI Port2", 552 .stream_name = "Hdmi2", 553 .dpcm_playback = 1, 554 .init = NULL, 555 .trigger = { 556 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 557 .nonatomic = 1, 558 .dynamic = 1, 559 SND_SOC_DAILINK_REG(hdmi2, dummy, platform), 560 }, 561 [SKL_DPCM_AUDIO_HDMI3_PB] = { 562 .name = "Skl HDMI Port3", 563 .stream_name = "Hdmi3", 564 .trigger = { 565 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 566 .dpcm_playback = 1, 567 .init = NULL, 568 .nonatomic = 1, 569 .dynamic = 1, 570 SND_SOC_DAILINK_REG(hdmi3, dummy, platform), 571 }, 572 573 /* Back End DAI links */ 574 { 575 /* SSP0 - Codec */ 576 .name = "SSP0-Codec", 577 .id = 0, 578 .no_pcm = 1, 579 .dai_fmt = SND_SOC_DAIFMT_DSP_A | 580 SND_SOC_DAIFMT_IB_NF | 581 SND_SOC_DAIFMT_CBS_CFS, 582 .init = skylake_ssm4567_codec_init, 583 .ignore_pmdown_time = 1, 584 .be_hw_params_fixup = skylake_ssp_fixup, 585 .dpcm_playback = 1, 586 .dpcm_capture = 1, 587 SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec, platform), 588 }, 589 { 590 /* SSP1 - Codec */ 591 .name = "SSP1-Codec", 592 .id = 1, 593 .no_pcm = 1, 594 .init = skylake_nau8825_codec_init, 595 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 596 SND_SOC_DAIFMT_CBS_CFS, 597 .ignore_pmdown_time = 1, 598 .be_hw_params_fixup = skylake_ssp_fixup, 599 .ops = &skylake_nau8825_ops, 600 .dpcm_playback = 1, 601 .dpcm_capture = 1, 602 SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform), 603 }, 604 { 605 .name = "dmic01", 606 .id = 2, 607 .ignore_suspend = 1, 608 .be_hw_params_fixup = skylake_dmic_fixup, 609 .dpcm_capture = 1, 610 .no_pcm = 1, 611 SND_SOC_DAILINK_REG(dmic01_pin, dmic_codec, platform), 612 }, 613 { 614 .name = "iDisp1", 615 .id = 3, 616 .dpcm_playback = 1, 617 .init = skylake_hdmi1_init, 618 .no_pcm = 1, 619 SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), 620 }, 621 { 622 .name = "iDisp2", 623 .id = 4, 624 .init = skylake_hdmi2_init, 625 .dpcm_playback = 1, 626 .no_pcm = 1, 627 SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), 628 }, 629 { 630 .name = "iDisp3", 631 .id = 5, 632 .init = skylake_hdmi3_init, 633 .dpcm_playback = 1, 634 .no_pcm = 1, 635 SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), 636 }, 637 }; 638 639 #define NAME_SIZE 32 640 static int skylake_card_late_probe(struct snd_soc_card *card) 641 { 642 struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(card); 643 struct skl_hdmi_pcm *pcm; 644 struct snd_soc_component *component = NULL; 645 int err, i = 0; 646 char jack_name[NAME_SIZE]; 647 648 list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { 649 component = pcm->codec_dai->component; 650 snprintf(jack_name, sizeof(jack_name), 651 "HDMI/DP, pcm=%d Jack", pcm->device); 652 err = snd_soc_card_jack_new(card, jack_name, 653 SND_JACK_AVOUT, 654 &skylake_hdmi[i], 655 NULL, 0); 656 657 if (err) 658 return err; 659 660 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, 661 &skylake_hdmi[i]); 662 if (err < 0) 663 return err; 664 665 i++; 666 } 667 668 if (!component) 669 return -EINVAL; 670 671 return hdac_hdmi_jack_port_init(component, &card->dapm); 672 } 673 674 /* skylake audio machine driver for SPT + NAU88L25 */ 675 static struct snd_soc_card skylake_audio_card = { 676 .name = "sklnau8825adi", 677 .owner = THIS_MODULE, 678 .dai_link = skylake_dais, 679 .num_links = ARRAY_SIZE(skylake_dais), 680 .controls = skylake_controls, 681 .num_controls = ARRAY_SIZE(skylake_controls), 682 .dapm_widgets = skylake_widgets, 683 .num_dapm_widgets = ARRAY_SIZE(skylake_widgets), 684 .dapm_routes = skylake_map, 685 .num_dapm_routes = ARRAY_SIZE(skylake_map), 686 .codec_conf = ssm4567_codec_conf, 687 .num_configs = ARRAY_SIZE(ssm4567_codec_conf), 688 .fully_routed = true, 689 .disable_route_checks = true, 690 .late_probe = skylake_card_late_probe, 691 }; 692 693 static int skylake_audio_probe(struct platform_device *pdev) 694 { 695 struct skl_nau88125_private *ctx; 696 struct snd_soc_acpi_mach *mach; 697 698 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 699 if (!ctx) 700 return -ENOMEM; 701 702 INIT_LIST_HEAD(&ctx->hdmi_pcm_list); 703 704 skylake_audio_card.dev = &pdev->dev; 705 snd_soc_card_set_drvdata(&skylake_audio_card, ctx); 706 707 mach = pdev->dev.platform_data; 708 if (mach) 709 dmic_constraints = mach->mach_params.dmic_num == 2 ? 710 &constraints_dmic_2ch : &constraints_dmic_channels; 711 712 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card); 713 } 714 715 static const struct platform_device_id skl_board_ids[] = { 716 { .name = "skl_n88l25_s4567" }, 717 { .name = "kbl_n88l25_s4567" }, 718 { } 719 }; 720 721 static struct platform_driver skylake_audio = { 722 .probe = skylake_audio_probe, 723 .driver = { 724 .name = "skl_n88l25_s4567", 725 .pm = &snd_soc_pm_ops, 726 }, 727 .id_table = skl_board_ids, 728 }; 729 730 module_platform_driver(skylake_audio) 731 732 /* Module information */ 733 MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>"); 734 MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); 735 MODULE_AUTHOR("Naveen M <naveen.m@intel.com>"); 736 MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>"); 737 MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>"); 738 MODULE_DESCRIPTION("Intel Audio Machine driver for SKL with NAU88L25 and SSM4567 in I2S Mode"); 739 MODULE_LICENSE("GPL v2"); 740 MODULE_ALIAS("platform:skl_n88l25_s4567"); 741 MODULE_ALIAS("platform:kbl_n88l25_s4567"); 742