1 /* 2 * Intel Skylake I2S Machine Driver 3 * 4 * Copyright (C) 2014-2015, Intel Corporation. All rights reserved. 5 * 6 * Modified from: 7 * Intel Broadwell Wildcatpoint SST Audio 8 * 9 * Copyright (C) 2013, Intel Corporation. All rights reserved. 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License version 13 * 2 as published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 */ 20 21 #include <linux/module.h> 22 #include <linux/platform_device.h> 23 #include <sound/core.h> 24 #include <sound/pcm.h> 25 #include <sound/soc.h> 26 #include <sound/jack.h> 27 #include <sound/pcm_params.h> 28 #include "../../codecs/rt286.h" 29 #include "../../codecs/hdac_hdmi.h" 30 31 static struct snd_soc_jack skylake_headset; 32 static struct snd_soc_jack skylake_hdmi[3]; 33 34 struct skl_hdmi_pcm { 35 struct list_head head; 36 struct snd_soc_dai *codec_dai; 37 int device; 38 }; 39 40 struct skl_rt286_private { 41 struct list_head hdmi_pcm_list; 42 }; 43 44 enum { 45 SKL_DPCM_AUDIO_PB = 0, 46 SKL_DPCM_AUDIO_DB_PB, 47 SKL_DPCM_AUDIO_CP, 48 SKL_DPCM_AUDIO_REF_CP, 49 SKL_DPCM_AUDIO_DMIC_CP, 50 SKL_DPCM_AUDIO_HDMI1_PB, 51 SKL_DPCM_AUDIO_HDMI2_PB, 52 SKL_DPCM_AUDIO_HDMI3_PB, 53 }; 54 55 /* Headset jack detection DAPM pins */ 56 static struct snd_soc_jack_pin skylake_headset_pins[] = { 57 { 58 .pin = "Mic Jack", 59 .mask = SND_JACK_MICROPHONE, 60 }, 61 { 62 .pin = "Headphone Jack", 63 .mask = SND_JACK_HEADPHONE, 64 }, 65 }; 66 67 static const struct snd_kcontrol_new skylake_controls[] = { 68 SOC_DAPM_PIN_SWITCH("Speaker"), 69 SOC_DAPM_PIN_SWITCH("Headphone Jack"), 70 SOC_DAPM_PIN_SWITCH("Mic Jack"), 71 }; 72 73 static const struct snd_soc_dapm_widget skylake_widgets[] = { 74 SND_SOC_DAPM_HP("Headphone Jack", NULL), 75 SND_SOC_DAPM_SPK("Speaker", NULL), 76 SND_SOC_DAPM_MIC("Mic Jack", NULL), 77 SND_SOC_DAPM_MIC("DMIC2", NULL), 78 SND_SOC_DAPM_MIC("SoC DMIC", NULL), 79 SND_SOC_DAPM_SPK("HDMI1", NULL), 80 SND_SOC_DAPM_SPK("HDMI2", NULL), 81 SND_SOC_DAPM_SPK("HDMI3", NULL), 82 }; 83 84 static const struct snd_soc_dapm_route skylake_rt286_map[] = { 85 /* speaker */ 86 {"Speaker", NULL, "SPOR"}, 87 {"Speaker", NULL, "SPOL"}, 88 89 /* HP jack connectors - unknown if we have jack deteck */ 90 {"Headphone Jack", NULL, "HPO Pin"}, 91 92 /* other jacks */ 93 {"MIC1", NULL, "Mic Jack"}, 94 95 /* digital mics */ 96 {"DMIC1 Pin", NULL, "DMIC2"}, 97 {"DMic", NULL, "SoC DMIC"}, 98 99 /* CODEC BE connections */ 100 { "AIF1 Playback", NULL, "ssp0 Tx"}, 101 { "ssp0 Tx", NULL, "codec0_out"}, 102 { "ssp0 Tx", NULL, "codec1_out"}, 103 104 { "codec0_in", NULL, "ssp0 Rx" }, 105 { "codec1_in", NULL, "ssp0 Rx" }, 106 { "ssp0 Rx", NULL, "AIF1 Capture" }, 107 108 { "dmic01_hifi", NULL, "DMIC01 Rx" }, 109 { "DMIC01 Rx", NULL, "DMIC AIF" }, 110 111 { "hifi3", NULL, "iDisp3 Tx"}, 112 { "iDisp3 Tx", NULL, "iDisp3_out"}, 113 { "hifi2", NULL, "iDisp2 Tx"}, 114 { "iDisp2 Tx", NULL, "iDisp2_out"}, 115 { "hifi1", NULL, "iDisp1 Tx"}, 116 { "iDisp1 Tx", NULL, "iDisp1_out"}, 117 118 }; 119 120 static int skylake_rt286_fe_init(struct snd_soc_pcm_runtime *rtd) 121 { 122 struct snd_soc_dapm_context *dapm; 123 struct snd_soc_component *component = rtd->cpu_dai->component; 124 125 dapm = snd_soc_component_get_dapm(component); 126 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); 127 128 return 0; 129 } 130 131 static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) 132 { 133 struct snd_soc_codec *codec = rtd->codec; 134 int ret; 135 136 ret = snd_soc_card_jack_new(rtd->card, "Headset", 137 SND_JACK_HEADSET | SND_JACK_BTN_0, 138 &skylake_headset, 139 skylake_headset_pins, ARRAY_SIZE(skylake_headset_pins)); 140 141 if (ret) 142 return ret; 143 144 rt286_mic_detect(codec, &skylake_headset); 145 146 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); 147 148 return 0; 149 } 150 151 static int skylake_hdmi_init(struct snd_soc_pcm_runtime *rtd) 152 { 153 struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(rtd->card); 154 struct snd_soc_dai *dai = rtd->codec_dai; 155 struct skl_hdmi_pcm *pcm; 156 157 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); 158 if (!pcm) 159 return -ENOMEM; 160 161 pcm->device = SKL_DPCM_AUDIO_HDMI1_PB + dai->id; 162 pcm->codec_dai = dai; 163 164 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); 165 166 return 0; 167 } 168 169 static const unsigned int rates[] = { 170 48000, 171 }; 172 173 static const struct snd_pcm_hw_constraint_list constraints_rates = { 174 .count = ARRAY_SIZE(rates), 175 .list = rates, 176 .mask = 0, 177 }; 178 179 static const unsigned int channels[] = { 180 2, 181 }; 182 183 static const struct snd_pcm_hw_constraint_list constraints_channels = { 184 .count = ARRAY_SIZE(channels), 185 .list = channels, 186 .mask = 0, 187 }; 188 189 static int skl_fe_startup(struct snd_pcm_substream *substream) 190 { 191 struct snd_pcm_runtime *runtime = substream->runtime; 192 193 /* 194 * on this platform for PCM device we support, 195 * 48Khz 196 * stereo 197 * 16 bit audio 198 */ 199 200 runtime->hw.channels_max = 2; 201 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 202 &constraints_channels); 203 204 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; 205 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); 206 207 snd_pcm_hw_constraint_list(runtime, 0, 208 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 209 210 return 0; 211 } 212 213 static const struct snd_soc_ops skylake_rt286_fe_ops = { 214 .startup = skl_fe_startup, 215 }; 216 217 static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, 218 struct snd_pcm_hw_params *params) 219 { 220 struct snd_interval *rate = hw_param_interval(params, 221 SNDRV_PCM_HW_PARAM_RATE); 222 struct snd_interval *channels = hw_param_interval(params, 223 SNDRV_PCM_HW_PARAM_CHANNELS); 224 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 225 226 /* The output is 48KHz, stereo, 16bits */ 227 rate->min = rate->max = 48000; 228 channels->min = channels->max = 2; 229 230 /* set SSP0 to 24 bit */ 231 snd_mask_none(fmt); 232 snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE); 233 return 0; 234 } 235 236 static int skylake_rt286_hw_params(struct snd_pcm_substream *substream, 237 struct snd_pcm_hw_params *params) 238 { 239 struct snd_soc_pcm_runtime *rtd = substream->private_data; 240 struct snd_soc_dai *codec_dai = rtd->codec_dai; 241 int ret; 242 243 ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000, 244 SND_SOC_CLOCK_IN); 245 if (ret < 0) 246 dev_err(rtd->dev, "set codec sysclk failed: %d\n", ret); 247 248 return ret; 249 } 250 251 static const struct snd_soc_ops skylake_rt286_ops = { 252 .hw_params = skylake_rt286_hw_params, 253 }; 254 255 static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, 256 struct snd_pcm_hw_params *params) 257 { 258 struct snd_interval *channels = hw_param_interval(params, 259 SNDRV_PCM_HW_PARAM_CHANNELS); 260 if (params_channels(params) == 2) 261 channels->min = channels->max = 2; 262 else 263 channels->min = channels->max = 4; 264 265 return 0; 266 } 267 268 static const unsigned int channels_dmic[] = { 269 2, 4, 270 }; 271 272 static const struct snd_pcm_hw_constraint_list constraints_dmic_channels = { 273 .count = ARRAY_SIZE(channels_dmic), 274 .list = channels_dmic, 275 .mask = 0, 276 }; 277 278 static int skylake_dmic_startup(struct snd_pcm_substream *substream) 279 { 280 struct snd_pcm_runtime *runtime = substream->runtime; 281 282 runtime->hw.channels_max = 4; 283 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 284 &constraints_dmic_channels); 285 286 return snd_pcm_hw_constraint_list(substream->runtime, 0, 287 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 288 } 289 290 static const struct snd_soc_ops skylake_dmic_ops = { 291 .startup = skylake_dmic_startup, 292 }; 293 294 /* skylake digital audio interface glue - connects codec <--> CPU */ 295 static struct snd_soc_dai_link skylake_rt286_dais[] = { 296 /* Front End DAI links */ 297 [SKL_DPCM_AUDIO_PB] = { 298 .name = "Skl Audio Port", 299 .stream_name = "Audio", 300 .cpu_dai_name = "System Pin", 301 .platform_name = "0000:00:1f.3", 302 .nonatomic = 1, 303 .dynamic = 1, 304 .codec_name = "snd-soc-dummy", 305 .codec_dai_name = "snd-soc-dummy-dai", 306 .init = skylake_rt286_fe_init, 307 .trigger = { 308 SND_SOC_DPCM_TRIGGER_POST, 309 SND_SOC_DPCM_TRIGGER_POST 310 }, 311 .dpcm_playback = 1, 312 .ops = &skylake_rt286_fe_ops, 313 }, 314 [SKL_DPCM_AUDIO_DB_PB] = { 315 .name = "Skl Deepbuffer Port", 316 .stream_name = "Deep Buffer Audio", 317 .cpu_dai_name = "Deepbuffer Pin", 318 .platform_name = "0000:00:1f.3", 319 .nonatomic = 1, 320 .dynamic = 1, 321 .codec_name = "snd-soc-dummy", 322 .codec_dai_name = "snd-soc-dummy-dai", 323 .trigger = { 324 SND_SOC_DPCM_TRIGGER_POST, 325 SND_SOC_DPCM_TRIGGER_POST 326 }, 327 .dpcm_playback = 1, 328 .ops = &skylake_rt286_fe_ops, 329 330 }, 331 [SKL_DPCM_AUDIO_CP] = { 332 .name = "Skl Audio Capture Port", 333 .stream_name = "Audio Record", 334 .cpu_dai_name = "System Pin", 335 .platform_name = "0000:00:1f.3", 336 .nonatomic = 1, 337 .dynamic = 1, 338 .codec_name = "snd-soc-dummy", 339 .codec_dai_name = "snd-soc-dummy-dai", 340 .trigger = { 341 SND_SOC_DPCM_TRIGGER_POST, 342 SND_SOC_DPCM_TRIGGER_POST 343 }, 344 .dpcm_capture = 1, 345 .ops = &skylake_rt286_fe_ops, 346 }, 347 [SKL_DPCM_AUDIO_REF_CP] = { 348 .name = "Skl Audio Reference cap", 349 .stream_name = "refcap", 350 .cpu_dai_name = "Reference Pin", 351 .codec_name = "snd-soc-dummy", 352 .codec_dai_name = "snd-soc-dummy-dai", 353 .platform_name = "0000:00:1f.3", 354 .init = NULL, 355 .dpcm_capture = 1, 356 .nonatomic = 1, 357 .dynamic = 1, 358 }, 359 [SKL_DPCM_AUDIO_DMIC_CP] = { 360 .name = "Skl Audio DMIC cap", 361 .stream_name = "dmiccap", 362 .cpu_dai_name = "DMIC Pin", 363 .codec_name = "snd-soc-dummy", 364 .codec_dai_name = "snd-soc-dummy-dai", 365 .platform_name = "0000:00:1f.3", 366 .init = NULL, 367 .dpcm_capture = 1, 368 .nonatomic = 1, 369 .dynamic = 1, 370 .ops = &skylake_dmic_ops, 371 }, 372 [SKL_DPCM_AUDIO_HDMI1_PB] = { 373 .name = "Skl HDMI Port1", 374 .stream_name = "Hdmi1", 375 .cpu_dai_name = "HDMI1 Pin", 376 .codec_name = "snd-soc-dummy", 377 .codec_dai_name = "snd-soc-dummy-dai", 378 .platform_name = "0000:00:1f.3", 379 .dpcm_playback = 1, 380 .init = NULL, 381 .nonatomic = 1, 382 .dynamic = 1, 383 }, 384 [SKL_DPCM_AUDIO_HDMI2_PB] = { 385 .name = "Skl HDMI Port2", 386 .stream_name = "Hdmi2", 387 .cpu_dai_name = "HDMI2 Pin", 388 .codec_name = "snd-soc-dummy", 389 .codec_dai_name = "snd-soc-dummy-dai", 390 .platform_name = "0000:00:1f.3", 391 .dpcm_playback = 1, 392 .init = NULL, 393 .nonatomic = 1, 394 .dynamic = 1, 395 }, 396 [SKL_DPCM_AUDIO_HDMI3_PB] = { 397 .name = "Skl HDMI Port3", 398 .stream_name = "Hdmi3", 399 .cpu_dai_name = "HDMI3 Pin", 400 .codec_name = "snd-soc-dummy", 401 .codec_dai_name = "snd-soc-dummy-dai", 402 .platform_name = "0000:00:1f.3", 403 .dpcm_playback = 1, 404 .init = NULL, 405 .nonatomic = 1, 406 .dynamic = 1, 407 }, 408 409 /* Back End DAI links */ 410 { 411 /* SSP0 - Codec */ 412 .name = "SSP0-Codec", 413 .id = 0, 414 .cpu_dai_name = "SSP0 Pin", 415 .platform_name = "0000:00:1f.3", 416 .no_pcm = 1, 417 .codec_name = "i2c-INT343A:00", 418 .codec_dai_name = "rt286-aif1", 419 .init = skylake_rt286_codec_init, 420 .dai_fmt = SND_SOC_DAIFMT_I2S | 421 SND_SOC_DAIFMT_NB_NF | 422 SND_SOC_DAIFMT_CBS_CFS, 423 .ignore_pmdown_time = 1, 424 .be_hw_params_fixup = skylake_ssp0_fixup, 425 .ops = &skylake_rt286_ops, 426 .dpcm_playback = 1, 427 .dpcm_capture = 1, 428 }, 429 { 430 .name = "dmic01", 431 .id = 1, 432 .cpu_dai_name = "DMIC01 Pin", 433 .codec_name = "dmic-codec", 434 .codec_dai_name = "dmic-hifi", 435 .platform_name = "0000:00:1f.3", 436 .be_hw_params_fixup = skylake_dmic_fixup, 437 .ignore_suspend = 1, 438 .dpcm_capture = 1, 439 .no_pcm = 1, 440 }, 441 { 442 .name = "iDisp1", 443 .id = 2, 444 .cpu_dai_name = "iDisp1 Pin", 445 .codec_name = "ehdaudio0D2", 446 .codec_dai_name = "intel-hdmi-hifi1", 447 .platform_name = "0000:00:1f.3", 448 .init = skylake_hdmi_init, 449 .dpcm_playback = 1, 450 .no_pcm = 1, 451 }, 452 { 453 .name = "iDisp2", 454 .id = 3, 455 .cpu_dai_name = "iDisp2 Pin", 456 .codec_name = "ehdaudio0D2", 457 .codec_dai_name = "intel-hdmi-hifi2", 458 .platform_name = "0000:00:1f.3", 459 .init = skylake_hdmi_init, 460 .dpcm_playback = 1, 461 .no_pcm = 1, 462 }, 463 { 464 .name = "iDisp3", 465 .id = 4, 466 .cpu_dai_name = "iDisp3 Pin", 467 .codec_name = "ehdaudio0D2", 468 .codec_dai_name = "intel-hdmi-hifi3", 469 .platform_name = "0000:00:1f.3", 470 .init = skylake_hdmi_init, 471 .dpcm_playback = 1, 472 .no_pcm = 1, 473 }, 474 }; 475 476 #define NAME_SIZE 32 477 static int skylake_card_late_probe(struct snd_soc_card *card) 478 { 479 struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(card); 480 struct skl_hdmi_pcm *pcm; 481 struct snd_soc_codec *codec = NULL; 482 int err, i = 0; 483 char jack_name[NAME_SIZE]; 484 485 list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { 486 codec = pcm->codec_dai->codec; 487 snprintf(jack_name, sizeof(jack_name), 488 "HDMI/DP, pcm=%d Jack", pcm->device); 489 err = snd_soc_card_jack_new(card, jack_name, 490 SND_JACK_AVOUT, &skylake_hdmi[i], 491 NULL, 0); 492 493 if (err) 494 return err; 495 496 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, 497 &skylake_hdmi[i]); 498 if (err < 0) 499 return err; 500 501 i++; 502 } 503 504 if (!codec) 505 return -EINVAL; 506 507 return hdac_hdmi_jack_port_init(codec, &card->dapm); 508 } 509 510 /* skylake audio machine driver for SPT + RT286S */ 511 static struct snd_soc_card skylake_rt286 = { 512 .name = "skylake-rt286", 513 .owner = THIS_MODULE, 514 .dai_link = skylake_rt286_dais, 515 .num_links = ARRAY_SIZE(skylake_rt286_dais), 516 .controls = skylake_controls, 517 .num_controls = ARRAY_SIZE(skylake_controls), 518 .dapm_widgets = skylake_widgets, 519 .num_dapm_widgets = ARRAY_SIZE(skylake_widgets), 520 .dapm_routes = skylake_rt286_map, 521 .num_dapm_routes = ARRAY_SIZE(skylake_rt286_map), 522 .fully_routed = true, 523 .late_probe = skylake_card_late_probe, 524 }; 525 526 static int skylake_audio_probe(struct platform_device *pdev) 527 { 528 struct skl_rt286_private *ctx; 529 530 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 531 if (!ctx) 532 return -ENOMEM; 533 534 INIT_LIST_HEAD(&ctx->hdmi_pcm_list); 535 536 skylake_rt286.dev = &pdev->dev; 537 snd_soc_card_set_drvdata(&skylake_rt286, ctx); 538 539 return devm_snd_soc_register_card(&pdev->dev, &skylake_rt286); 540 } 541 542 static const struct platform_device_id skl_board_ids[] = { 543 { .name = "skl_alc286s_i2s" }, 544 { .name = "kbl_alc286s_i2s" }, 545 { } 546 }; 547 548 static struct platform_driver skylake_audio = { 549 .probe = skylake_audio_probe, 550 .driver = { 551 .name = "skl_alc286s_i2s", 552 .pm = &snd_soc_pm_ops, 553 }, 554 .id_table = skl_board_ids, 555 556 }; 557 558 module_platform_driver(skylake_audio) 559 560 /* Module information */ 561 MODULE_AUTHOR("Omair Mohammed Abdullah <omair.m.abdullah@intel.com>"); 562 MODULE_DESCRIPTION("Intel SST Audio for Skylake"); 563 MODULE_LICENSE("GPL v2"); 564 MODULE_ALIAS("platform:skl_alc286s_i2s"); 565 MODULE_ALIAS("platform:kbl_alc286s_i2s"); 566