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