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