skl_nau88l25_ssm4567.c (19204B)
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 28static struct snd_soc_jack skylake_headset; 29static struct snd_soc_card skylake_audio_card; 30static const struct snd_pcm_hw_constraint_list *dmic_constraints; 31static struct snd_soc_jack skylake_hdmi[3]; 32 33struct skl_hdmi_pcm { 34 struct list_head head; 35 struct snd_soc_dai *codec_dai; 36 int device; 37}; 38 39struct skl_nau88125_private { 40 struct list_head hdmi_pcm_list; 41}; 42enum { 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 52static 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 59static 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 91static 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 104static 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 148static 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 159static 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 176static 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 if (ret) { 189 dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); 190 return ret; 191 } 192 193 nau8825_enable_jack_detect(component, &skylake_headset); 194 195 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); 196 197 return ret; 198} 199 200static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) 201{ 202 struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); 203 struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 204 struct skl_hdmi_pcm *pcm; 205 206 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); 207 if (!pcm) 208 return -ENOMEM; 209 210 pcm->device = SKL_DPCM_AUDIO_HDMI1_PB; 211 pcm->codec_dai = dai; 212 213 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); 214 215 return 0; 216} 217 218static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) 219{ 220 struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); 221 struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 222 struct skl_hdmi_pcm *pcm; 223 224 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); 225 if (!pcm) 226 return -ENOMEM; 227 228 pcm->device = SKL_DPCM_AUDIO_HDMI2_PB; 229 pcm->codec_dai = dai; 230 231 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); 232 233 return 0; 234} 235 236 237static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) 238{ 239 struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); 240 struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 241 struct skl_hdmi_pcm *pcm; 242 243 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); 244 if (!pcm) 245 return -ENOMEM; 246 247 pcm->device = SKL_DPCM_AUDIO_HDMI3_PB; 248 pcm->codec_dai = dai; 249 250 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); 251 252 return 0; 253} 254 255static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd) 256{ 257 struct snd_soc_dapm_context *dapm; 258 struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; 259 260 dapm = snd_soc_component_get_dapm(component); 261 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); 262 263 return 0; 264} 265 266static const unsigned int rates[] = { 267 48000, 268}; 269 270static const struct snd_pcm_hw_constraint_list constraints_rates = { 271 .count = ARRAY_SIZE(rates), 272 .list = rates, 273 .mask = 0, 274}; 275 276static const unsigned int channels[] = { 277 2, 278}; 279 280static const struct snd_pcm_hw_constraint_list constraints_channels = { 281 .count = ARRAY_SIZE(channels), 282 .list = channels, 283 .mask = 0, 284}; 285 286static int skl_fe_startup(struct snd_pcm_substream *substream) 287{ 288 struct snd_pcm_runtime *runtime = substream->runtime; 289 290 /* 291 * on this platform for PCM device we support, 292 * 48Khz 293 * stereo 294 * 16 bit audio 295 */ 296 297 runtime->hw.channels_max = 2; 298 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 299 &constraints_channels); 300 301 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; 302 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); 303 304 snd_pcm_hw_constraint_list(runtime, 0, 305 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 306 307 return 0; 308} 309 310static const struct snd_soc_ops skylake_nau8825_fe_ops = { 311 .startup = skl_fe_startup, 312}; 313 314static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, 315 struct snd_pcm_hw_params *params) 316{ 317 struct snd_interval *rate = hw_param_interval(params, 318 SNDRV_PCM_HW_PARAM_RATE); 319 struct snd_interval *chan = hw_param_interval(params, 320 SNDRV_PCM_HW_PARAM_CHANNELS); 321 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 322 323 /* The ADSP will covert the FE rate to 48k, stereo */ 324 rate->min = rate->max = 48000; 325 chan->min = chan->max = 2; 326 327 /* set SSP0 to 24 bit */ 328 snd_mask_none(fmt); 329 snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); 330 return 0; 331} 332 333static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, 334 struct snd_pcm_hw_params *params) 335{ 336 struct snd_interval *chan = hw_param_interval(params, 337 SNDRV_PCM_HW_PARAM_CHANNELS); 338 if (params_channels(params) == 2 || DMIC_CH(dmic_constraints) == 2) 339 chan->min = chan->max = 2; 340 else 341 chan->min = chan->max = 4; 342 343 return 0; 344} 345 346static int skylake_nau8825_hw_params(struct snd_pcm_substream *substream, 347 struct snd_pcm_hw_params *params) 348{ 349 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 350 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 351 int ret; 352 353 ret = snd_soc_dai_set_sysclk(codec_dai, 354 NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN); 355 356 if (ret < 0) 357 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); 358 359 return ret; 360} 361 362static const struct snd_soc_ops skylake_nau8825_ops = { 363 .hw_params = skylake_nau8825_hw_params, 364}; 365 366static const unsigned int channels_dmic[] = { 367 2, 4, 368}; 369 370static const struct snd_pcm_hw_constraint_list constraints_dmic_channels = { 371 .count = ARRAY_SIZE(channels_dmic), 372 .list = channels_dmic, 373 .mask = 0, 374}; 375 376static const unsigned int dmic_2ch[] = { 377 2, 378}; 379 380static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = { 381 .count = ARRAY_SIZE(dmic_2ch), 382 .list = dmic_2ch, 383 .mask = 0, 384}; 385 386static int skylake_dmic_startup(struct snd_pcm_substream *substream) 387{ 388 struct snd_pcm_runtime *runtime = substream->runtime; 389 390 runtime->hw.channels_max = DMIC_CH(dmic_constraints); 391 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 392 dmic_constraints); 393 394 return snd_pcm_hw_constraint_list(substream->runtime, 0, 395 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 396} 397 398static const struct snd_soc_ops skylake_dmic_ops = { 399 .startup = skylake_dmic_startup, 400}; 401 402static const unsigned int rates_16000[] = { 403 16000, 404}; 405 406static const struct snd_pcm_hw_constraint_list constraints_16000 = { 407 .count = ARRAY_SIZE(rates_16000), 408 .list = rates_16000, 409}; 410 411static const unsigned int ch_mono[] = { 412 1, 413}; 414 415static const struct snd_pcm_hw_constraint_list constraints_refcap = { 416 .count = ARRAY_SIZE(ch_mono), 417 .list = ch_mono, 418}; 419 420static int skylake_refcap_startup(struct snd_pcm_substream *substream) 421{ 422 substream->runtime->hw.channels_max = 1; 423 snd_pcm_hw_constraint_list(substream->runtime, 0, 424 SNDRV_PCM_HW_PARAM_CHANNELS, 425 &constraints_refcap); 426 427 return snd_pcm_hw_constraint_list(substream->runtime, 0, 428 SNDRV_PCM_HW_PARAM_RATE, 429 &constraints_16000); 430} 431 432static const struct snd_soc_ops skylake_refcap_ops = { 433 .startup = skylake_refcap_startup, 434}; 435 436SND_SOC_DAILINK_DEF(dummy, 437 DAILINK_COMP_ARRAY(COMP_DUMMY())); 438 439SND_SOC_DAILINK_DEF(system, 440 DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); 441 442SND_SOC_DAILINK_DEF(reference, 443 DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin"))); 444 445SND_SOC_DAILINK_DEF(dmic, 446 DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); 447 448SND_SOC_DAILINK_DEF(hdmi1, 449 DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin"))); 450 451SND_SOC_DAILINK_DEF(hdmi2, 452 DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin"))); 453 454SND_SOC_DAILINK_DEF(hdmi3, 455 DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin"))); 456 457SND_SOC_DAILINK_DEF(ssp0_pin, 458 DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin"))); 459SND_SOC_DAILINK_DEF(ssp0_codec, 460 DAILINK_COMP_ARRAY( 461 /* Left */ COMP_CODEC("i2c-INT343B:00", SKL_SSM_CODEC_DAI), 462 /* Right */ COMP_CODEC("i2c-INT343B:01", SKL_SSM_CODEC_DAI))); 463 464SND_SOC_DAILINK_DEF(ssp1_pin, 465 DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin"))); 466SND_SOC_DAILINK_DEF(ssp1_codec, 467 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10508825:00", SKL_NUVOTON_CODEC_DAI))); 468 469SND_SOC_DAILINK_DEF(dmic01_pin, 470 DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); 471SND_SOC_DAILINK_DEF(dmic_codec, 472 DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); 473 474SND_SOC_DAILINK_DEF(idisp1_pin, 475 DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); 476SND_SOC_DAILINK_DEF(idisp1_codec, 477 DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); 478 479SND_SOC_DAILINK_DEF(idisp2_pin, 480 DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); 481SND_SOC_DAILINK_DEF(idisp2_codec, 482 DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2"))); 483 484SND_SOC_DAILINK_DEF(idisp3_pin, 485 DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); 486SND_SOC_DAILINK_DEF(idisp3_codec, 487 DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3"))); 488 489SND_SOC_DAILINK_DEF(platform, 490 DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3"))); 491 492/* skylake digital audio interface glue - connects codec <--> CPU */ 493static struct snd_soc_dai_link skylake_dais[] = { 494 /* Front End DAI links */ 495 [SKL_DPCM_AUDIO_PB] = { 496 .name = "Skl Audio Port", 497 .stream_name = "Audio", 498 .dynamic = 1, 499 .nonatomic = 1, 500 .init = skylake_nau8825_fe_init, 501 .trigger = { 502 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 503 .dpcm_playback = 1, 504 .ops = &skylake_nau8825_fe_ops, 505 SND_SOC_DAILINK_REG(system, dummy, platform), 506 }, 507 [SKL_DPCM_AUDIO_CP] = { 508 .name = "Skl Audio Capture Port", 509 .stream_name = "Audio Record", 510 .dynamic = 1, 511 .nonatomic = 1, 512 .trigger = { 513 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 514 .dpcm_capture = 1, 515 .ops = &skylake_nau8825_fe_ops, 516 SND_SOC_DAILINK_REG(system, dummy, platform), 517 }, 518 [SKL_DPCM_AUDIO_REF_CP] = { 519 .name = "Skl Audio Reference cap", 520 .stream_name = "Wake on Voice", 521 .init = NULL, 522 .dpcm_capture = 1, 523 .nonatomic = 1, 524 .dynamic = 1, 525 .ops = &skylake_refcap_ops, 526 SND_SOC_DAILINK_REG(reference, dummy, platform), 527 }, 528 [SKL_DPCM_AUDIO_DMIC_CP] = { 529 .name = "Skl Audio DMIC cap", 530 .stream_name = "dmiccap", 531 .init = NULL, 532 .dpcm_capture = 1, 533 .nonatomic = 1, 534 .dynamic = 1, 535 .ops = &skylake_dmic_ops, 536 SND_SOC_DAILINK_REG(dmic, dummy, platform), 537 }, 538 [SKL_DPCM_AUDIO_HDMI1_PB] = { 539 .name = "Skl HDMI Port1", 540 .stream_name = "Hdmi1", 541 .dpcm_playback = 1, 542 .init = NULL, 543 .trigger = { 544 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 545 .nonatomic = 1, 546 .dynamic = 1, 547 SND_SOC_DAILINK_REG(hdmi1, dummy, platform), 548 }, 549 [SKL_DPCM_AUDIO_HDMI2_PB] = { 550 .name = "Skl HDMI Port2", 551 .stream_name = "Hdmi2", 552 .dpcm_playback = 1, 553 .init = NULL, 554 .trigger = { 555 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 556 .nonatomic = 1, 557 .dynamic = 1, 558 SND_SOC_DAILINK_REG(hdmi2, dummy, platform), 559 }, 560 [SKL_DPCM_AUDIO_HDMI3_PB] = { 561 .name = "Skl HDMI Port3", 562 .stream_name = "Hdmi3", 563 .trigger = { 564 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 565 .dpcm_playback = 1, 566 .init = NULL, 567 .nonatomic = 1, 568 .dynamic = 1, 569 SND_SOC_DAILINK_REG(hdmi3, dummy, platform), 570 }, 571 572 /* Back End DAI links */ 573 { 574 /* SSP0 - Codec */ 575 .name = "SSP0-Codec", 576 .id = 0, 577 .no_pcm = 1, 578 .dai_fmt = SND_SOC_DAIFMT_DSP_A | 579 SND_SOC_DAIFMT_IB_NF | 580 SND_SOC_DAIFMT_CBC_CFC, 581 .init = skylake_ssm4567_codec_init, 582 .ignore_pmdown_time = 1, 583 .be_hw_params_fixup = skylake_ssp_fixup, 584 .dpcm_playback = 1, 585 .dpcm_capture = 1, 586 SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec, platform), 587 }, 588 { 589 /* SSP1 - Codec */ 590 .name = "SSP1-Codec", 591 .id = 1, 592 .no_pcm = 1, 593 .init = skylake_nau8825_codec_init, 594 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 595 SND_SOC_DAIFMT_CBC_CFC, 596 .ignore_pmdown_time = 1, 597 .be_hw_params_fixup = skylake_ssp_fixup, 598 .ops = &skylake_nau8825_ops, 599 .dpcm_playback = 1, 600 .dpcm_capture = 1, 601 SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform), 602 }, 603 { 604 .name = "dmic01", 605 .id = 2, 606 .ignore_suspend = 1, 607 .be_hw_params_fixup = skylake_dmic_fixup, 608 .dpcm_capture = 1, 609 .no_pcm = 1, 610 SND_SOC_DAILINK_REG(dmic01_pin, dmic_codec, platform), 611 }, 612 { 613 .name = "iDisp1", 614 .id = 3, 615 .dpcm_playback = 1, 616 .init = skylake_hdmi1_init, 617 .no_pcm = 1, 618 SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), 619 }, 620 { 621 .name = "iDisp2", 622 .id = 4, 623 .init = skylake_hdmi2_init, 624 .dpcm_playback = 1, 625 .no_pcm = 1, 626 SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), 627 }, 628 { 629 .name = "iDisp3", 630 .id = 5, 631 .init = skylake_hdmi3_init, 632 .dpcm_playback = 1, 633 .no_pcm = 1, 634 SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), 635 }, 636}; 637 638#define NAME_SIZE 32 639static int skylake_card_late_probe(struct snd_soc_card *card) 640{ 641 struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(card); 642 struct skl_hdmi_pcm *pcm; 643 struct snd_soc_component *component = NULL; 644 int err, i = 0; 645 char jack_name[NAME_SIZE]; 646 647 list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { 648 component = pcm->codec_dai->component; 649 snprintf(jack_name, sizeof(jack_name), 650 "HDMI/DP, pcm=%d Jack", pcm->device); 651 err = snd_soc_card_jack_new(card, jack_name, 652 SND_JACK_AVOUT, 653 &skylake_hdmi[i]); 654 655 if (err) 656 return err; 657 658 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, 659 &skylake_hdmi[i]); 660 if (err < 0) 661 return err; 662 663 i++; 664 } 665 666 if (!component) 667 return -EINVAL; 668 669 return hdac_hdmi_jack_port_init(component, &card->dapm); 670} 671 672/* skylake audio machine driver for SPT + NAU88L25 */ 673static struct snd_soc_card skylake_audio_card = { 674 .name = "sklnau8825adi", 675 .owner = THIS_MODULE, 676 .dai_link = skylake_dais, 677 .num_links = ARRAY_SIZE(skylake_dais), 678 .controls = skylake_controls, 679 .num_controls = ARRAY_SIZE(skylake_controls), 680 .dapm_widgets = skylake_widgets, 681 .num_dapm_widgets = ARRAY_SIZE(skylake_widgets), 682 .dapm_routes = skylake_map, 683 .num_dapm_routes = ARRAY_SIZE(skylake_map), 684 .codec_conf = ssm4567_codec_conf, 685 .num_configs = ARRAY_SIZE(ssm4567_codec_conf), 686 .fully_routed = true, 687 .disable_route_checks = true, 688 .late_probe = skylake_card_late_probe, 689}; 690 691static int skylake_audio_probe(struct platform_device *pdev) 692{ 693 struct skl_nau88125_private *ctx; 694 struct snd_soc_acpi_mach *mach; 695 696 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 697 if (!ctx) 698 return -ENOMEM; 699 700 INIT_LIST_HEAD(&ctx->hdmi_pcm_list); 701 702 skylake_audio_card.dev = &pdev->dev; 703 snd_soc_card_set_drvdata(&skylake_audio_card, ctx); 704 705 mach = pdev->dev.platform_data; 706 if (mach) 707 dmic_constraints = mach->mach_params.dmic_num == 2 ? 708 &constraints_dmic_2ch : &constraints_dmic_channels; 709 710 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card); 711} 712 713static const struct platform_device_id skl_board_ids[] = { 714 { .name = "skl_n88l25_s4567" }, 715 { .name = "kbl_n88l25_s4567" }, 716 { } 717}; 718MODULE_DEVICE_TABLE(platform, skl_board_ids); 719 720static struct platform_driver skylake_audio = { 721 .probe = skylake_audio_probe, 722 .driver = { 723 .name = "skl_n88l25_s4567", 724 .pm = &snd_soc_pm_ops, 725 }, 726 .id_table = skl_board_ids, 727}; 728 729module_platform_driver(skylake_audio) 730 731/* Module information */ 732MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>"); 733MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); 734MODULE_AUTHOR("Naveen M <naveen.m@intel.com>"); 735MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>"); 736MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>"); 737MODULE_DESCRIPTION("Intel Audio Machine driver for SKL with NAU88L25 and SSM4567 in I2S Mode"); 738MODULE_LICENSE("GPL v2");