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