cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

skl_nau88l25_max98357a.c (17684B)


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