linux/sound/soc/intel/boards/skl_nau88l25_max98357a.c
<<
>>
Prefs
   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
  32static struct snd_soc_jack skylake_headset;
  33static struct snd_soc_card skylake_audio_card;
  34static const struct snd_pcm_hw_constraint_list *dmic_constraints;
  35static struct snd_soc_jack skylake_hdmi[3];
  36
  37struct skl_hdmi_pcm {
  38        struct list_head head;
  39        struct snd_soc_dai *codec_dai;
  40        int device;
  41};
  42
  43struct skl_nau8825_private {
  44        struct list_head hdmi_pcm_list;
  45};
  46
  47enum {
  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
  57static 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
  90static 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
  96static 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
 108static 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
 145static 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(fmt, SNDRV_PCM_FORMAT_S24_LE);
 161
 162        return 0;
 163}
 164
 165static 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
 190static 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
 208static 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
 226static 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
 244static 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
 255static const unsigned int rates[] = {
 256        48000,
 257};
 258
 259static const struct snd_pcm_hw_constraint_list constraints_rates = {
 260        .count = ARRAY_SIZE(rates),
 261        .list  = rates,
 262        .mask = 0,
 263};
 264
 265static const unsigned int channels[] = {
 266        2,
 267};
 268
 269static const struct snd_pcm_hw_constraint_list constraints_channels = {
 270        .count = ARRAY_SIZE(channels),
 271        .list = channels,
 272        .mask = 0,
 273};
 274
 275static 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
 299static const struct snd_soc_ops skylake_nau8825_fe_ops = {
 300        .startup = skl_fe_startup,
 301};
 302
 303static 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
 319static const struct snd_soc_ops skylake_nau8825_ops = {
 320        .hw_params = skylake_nau8825_hw_params,
 321};
 322
 323static 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
 337static const unsigned int channels_dmic[] = {
 338        2, 4,
 339};
 340
 341static 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
 347static const unsigned int dmic_2ch[] = {
 348        2,
 349};
 350
 351static 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
 357static 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
 369static const struct snd_soc_ops skylake_dmic_ops = {
 370        .startup = skylake_dmic_startup,
 371};
 372
 373static const unsigned int rates_16000[] = {
 374        16000,
 375};
 376
 377static const struct snd_pcm_hw_constraint_list constraints_16000 = {
 378        .count = ARRAY_SIZE(rates_16000),
 379        .list  = rates_16000,
 380};
 381
 382static const unsigned int ch_mono[] = {
 383        1,
 384};
 385
 386static const struct snd_pcm_hw_constraint_list constraints_refcap = {
 387        .count = ARRAY_SIZE(ch_mono),
 388        .list  = ch_mono,
 389};
 390
 391static 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
 403static const struct snd_soc_ops skylaye_refcap_ops = {
 404        .startup = skylake_refcap_startup,
 405};
 406
 407/* skylake digital audio interface glue - connects codec <--> CPU */
 408static 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
 591static 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 */
 626static 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
 641static 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_ATOMIC);
 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
 663static const struct platform_device_id skl_board_ids[] = {
 664        { .name = "skl_n88l25_m98357a" },
 665        { .name = "kbl_n88l25_m98357a" },
 666        { }
 667};
 668
 669static 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
 678module_platform_driver(skylake_audio)
 679
 680/* Module information */
 681MODULE_DESCRIPTION("Audio Machine driver-NAU88L25 & MAX98357A in I2S mode");
 682MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com");
 683MODULE_LICENSE("GPL v2");
 684MODULE_ALIAS("platform:skl_n88l25_m98357a");
 685MODULE_ALIAS("platform:kbl_n88l25_m98357a");
 686