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