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