xref: /openbmc/linux/sound/soc/intel/boards/skl_rt286.c (revision b181f7029bd71238ac2754ce7052dffd69432085)
11802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2624729fdSOmair M Abdullah /*
3624729fdSOmair M Abdullah  * Intel Skylake I2S Machine Driver
4624729fdSOmair M Abdullah  *
5624729fdSOmair M Abdullah  * Copyright (C) 2014-2015, Intel Corporation. All rights reserved.
6624729fdSOmair M Abdullah  *
7624729fdSOmair M Abdullah  * Modified from:
8624729fdSOmair M Abdullah  *   Intel Broadwell Wildcatpoint SST Audio
9624729fdSOmair M Abdullah  *
10624729fdSOmair M Abdullah  *   Copyright (C) 2013, Intel Corporation. All rights reserved.
11624729fdSOmair M Abdullah  */
12624729fdSOmair M Abdullah 
13624729fdSOmair M Abdullah #include <linux/module.h>
14624729fdSOmair M Abdullah #include <linux/platform_device.h>
15624729fdSOmair M Abdullah #include <sound/core.h>
16624729fdSOmair M Abdullah #include <sound/pcm.h>
17624729fdSOmair M Abdullah #include <sound/soc.h>
18624729fdSOmair M Abdullah #include <sound/jack.h>
19624729fdSOmair M Abdullah #include <sound/pcm_params.h>
20624729fdSOmair M Abdullah #include "../../codecs/rt286.h"
2123905cd1SJeeja KP #include "../../codecs/hdac_hdmi.h"
22624729fdSOmair M Abdullah 
23624729fdSOmair M Abdullah static struct snd_soc_jack skylake_headset;
24f3af3592SJeeja KP static struct snd_soc_jack skylake_hdmi[3];
2523905cd1SJeeja KP 
261a10612fSSubhransu S. Prusty struct skl_hdmi_pcm {
271a10612fSSubhransu S. Prusty 	struct list_head head;
281a10612fSSubhransu S. Prusty 	struct snd_soc_dai *codec_dai;
291a10612fSSubhransu S. Prusty 	int device;
301a10612fSSubhransu S. Prusty };
311a10612fSSubhransu S. Prusty 
321a10612fSSubhransu S. Prusty struct skl_rt286_private {
331a10612fSSubhransu S. Prusty 	struct list_head hdmi_pcm_list;
341a10612fSSubhransu S. Prusty };
351a10612fSSubhransu S. Prusty 
3623905cd1SJeeja KP enum {
3723905cd1SJeeja KP 	SKL_DPCM_AUDIO_PB = 0,
381f0f8bdeSSubhransu S. Prusty 	SKL_DPCM_AUDIO_DB_PB,
3923905cd1SJeeja KP 	SKL_DPCM_AUDIO_CP,
4023905cd1SJeeja KP 	SKL_DPCM_AUDIO_REF_CP,
4123905cd1SJeeja KP 	SKL_DPCM_AUDIO_DMIC_CP,
4223905cd1SJeeja KP 	SKL_DPCM_AUDIO_HDMI1_PB,
4323905cd1SJeeja KP 	SKL_DPCM_AUDIO_HDMI2_PB,
4423905cd1SJeeja KP 	SKL_DPCM_AUDIO_HDMI3_PB,
4523905cd1SJeeja KP };
4623905cd1SJeeja KP 
47624729fdSOmair M Abdullah /* Headset jack detection DAPM pins */
48624729fdSOmair M Abdullah static struct snd_soc_jack_pin skylake_headset_pins[] = {
49624729fdSOmair M Abdullah 	{
50624729fdSOmair M Abdullah 		.pin = "Mic Jack",
51624729fdSOmair M Abdullah 		.mask = SND_JACK_MICROPHONE,
52624729fdSOmair M Abdullah 	},
53624729fdSOmair M Abdullah 	{
54624729fdSOmair M Abdullah 		.pin = "Headphone Jack",
55624729fdSOmair M Abdullah 		.mask = SND_JACK_HEADPHONE,
56624729fdSOmair M Abdullah 	},
57624729fdSOmair M Abdullah };
58624729fdSOmair M Abdullah 
59624729fdSOmair M Abdullah static const struct snd_kcontrol_new skylake_controls[] = {
60624729fdSOmair M Abdullah 	SOC_DAPM_PIN_SWITCH("Speaker"),
61624729fdSOmair M Abdullah 	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
62624729fdSOmair M Abdullah 	SOC_DAPM_PIN_SWITCH("Mic Jack"),
63624729fdSOmair M Abdullah };
64624729fdSOmair M Abdullah 
65624729fdSOmair M Abdullah static const struct snd_soc_dapm_widget skylake_widgets[] = {
66624729fdSOmair M Abdullah 	SND_SOC_DAPM_HP("Headphone Jack", NULL),
67624729fdSOmair M Abdullah 	SND_SOC_DAPM_SPK("Speaker", NULL),
68624729fdSOmair M Abdullah 	SND_SOC_DAPM_MIC("Mic Jack", NULL),
69624729fdSOmair M Abdullah 	SND_SOC_DAPM_MIC("DMIC2", NULL),
70624729fdSOmair M Abdullah 	SND_SOC_DAPM_MIC("SoC DMIC", NULL),
7123905cd1SJeeja KP 	SND_SOC_DAPM_SPK("HDMI1", NULL),
7223905cd1SJeeja KP 	SND_SOC_DAPM_SPK("HDMI2", NULL),
7323905cd1SJeeja KP 	SND_SOC_DAPM_SPK("HDMI3", NULL),
74624729fdSOmair M Abdullah };
75624729fdSOmair M Abdullah 
76624729fdSOmair M Abdullah static const struct snd_soc_dapm_route skylake_rt286_map[] = {
77624729fdSOmair M Abdullah 	/* speaker */
78624729fdSOmair M Abdullah 	{"Speaker", NULL, "SPOR"},
79624729fdSOmair M Abdullah 	{"Speaker", NULL, "SPOL"},
80624729fdSOmair M Abdullah 
81624729fdSOmair M Abdullah 	/* HP jack connectors - unknown if we have jack deteck */
82624729fdSOmair M Abdullah 	{"Headphone Jack", NULL, "HPO Pin"},
83624729fdSOmair M Abdullah 
84624729fdSOmair M Abdullah 	/* other jacks */
85624729fdSOmair M Abdullah 	{"MIC1", NULL, "Mic Jack"},
86624729fdSOmair M Abdullah 
87624729fdSOmair M Abdullah 	/* digital mics */
88624729fdSOmair M Abdullah 	{"DMIC1 Pin", NULL, "DMIC2"},
89820f339fSVinod Koul 	{"DMic", NULL, "SoC DMIC"},
90624729fdSOmair M Abdullah 
91624729fdSOmair M Abdullah 	/* CODEC BE connections */
92624729fdSOmair M Abdullah 	{ "AIF1 Playback", NULL, "ssp0 Tx"},
93624729fdSOmair M Abdullah 	{ "ssp0 Tx", NULL, "codec0_out"},
94624729fdSOmair M Abdullah 	{ "ssp0 Tx", NULL, "codec1_out"},
95624729fdSOmair M Abdullah 
96624729fdSOmair M Abdullah 	{ "codec0_in", NULL, "ssp0 Rx" },
97624729fdSOmair M Abdullah 	{ "codec1_in", NULL, "ssp0 Rx" },
98624729fdSOmair M Abdullah 	{ "ssp0 Rx", NULL, "AIF1 Capture" },
99624729fdSOmair M Abdullah 
100624729fdSOmair M Abdullah 	{ "dmic01_hifi", NULL, "DMIC01 Rx" },
101820f339fSVinod Koul 	{ "DMIC01 Rx", NULL, "DMIC AIF" },
102624729fdSOmair M Abdullah 
10323905cd1SJeeja KP 	{ "hifi3", NULL, "iDisp3 Tx"},
10423905cd1SJeeja KP 	{ "iDisp3 Tx", NULL, "iDisp3_out"},
10523905cd1SJeeja KP 	{ "hifi2", NULL, "iDisp2 Tx"},
10623905cd1SJeeja KP 	{ "iDisp2 Tx", NULL, "iDisp2_out"},
10723905cd1SJeeja KP 	{ "hifi1", NULL, "iDisp1 Tx"},
10823905cd1SJeeja KP 	{ "iDisp1 Tx", NULL, "iDisp1_out"},
109624729fdSOmair M Abdullah 
110624729fdSOmair M Abdullah };
111624729fdSOmair M Abdullah 
skylake_rt286_fe_init(struct snd_soc_pcm_runtime * rtd)1129ec2053bSPraveen Diwakar static int skylake_rt286_fe_init(struct snd_soc_pcm_runtime *rtd)
1139ec2053bSPraveen Diwakar {
1149ec2053bSPraveen Diwakar 	struct snd_soc_dapm_context *dapm;
1150d1571c1SKuninori Morimoto 	struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component;
1169ec2053bSPraveen Diwakar 
1179ec2053bSPraveen Diwakar 	dapm = snd_soc_component_get_dapm(component);
1189ec2053bSPraveen Diwakar 	snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
1199ec2053bSPraveen Diwakar 
1209ec2053bSPraveen Diwakar 	return 0;
1219ec2053bSPraveen Diwakar }
1229ec2053bSPraveen Diwakar 
skylake_rt286_codec_init(struct snd_soc_pcm_runtime * rtd)123624729fdSOmair M Abdullah static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
124624729fdSOmair M Abdullah {
1250d1571c1SKuninori Morimoto 	struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
126624729fdSOmair M Abdullah 	int ret;
127624729fdSOmair M Abdullah 
12819aed2d6SAkihiko Odaki 	ret = snd_soc_card_jack_new_pins(rtd->card, "Headset",
129624729fdSOmair M Abdullah 		SND_JACK_HEADSET | SND_JACK_BTN_0,
130624729fdSOmair M Abdullah 		&skylake_headset,
131624729fdSOmair M Abdullah 		skylake_headset_pins, ARRAY_SIZE(skylake_headset_pins));
132624729fdSOmair M Abdullah 
133624729fdSOmair M Abdullah 	if (ret)
134624729fdSOmair M Abdullah 		return ret;
135624729fdSOmair M Abdullah 
1363082afe0SCezary Rojewski 	snd_soc_component_set_jack(component, &skylake_headset, NULL);
137624729fdSOmair M Abdullah 
1389ec2053bSPraveen Diwakar 	snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
1399ec2053bSPraveen Diwakar 
140624729fdSOmair M Abdullah 	return 0;
141624729fdSOmair M Abdullah }
142624729fdSOmair M Abdullah 
skylake_hdmi_init(struct snd_soc_pcm_runtime * rtd)14323905cd1SJeeja KP static int skylake_hdmi_init(struct snd_soc_pcm_runtime *rtd)
14423905cd1SJeeja KP {
1451a10612fSSubhransu S. Prusty 	struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(rtd->card);
1460d1571c1SKuninori Morimoto 	struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0);
1471a10612fSSubhransu S. Prusty 	struct skl_hdmi_pcm *pcm;
14823905cd1SJeeja KP 
1491a10612fSSubhransu S. Prusty 	pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
1501a10612fSSubhransu S. Prusty 	if (!pcm)
1511a10612fSSubhransu S. Prusty 		return -ENOMEM;
1521a10612fSSubhransu S. Prusty 
1531a10612fSSubhransu S. Prusty 	pcm->device = SKL_DPCM_AUDIO_HDMI1_PB + dai->id;
1541a10612fSSubhransu S. Prusty 	pcm->codec_dai = dai;
1551a10612fSSubhransu S. Prusty 
1561a10612fSSubhransu S. Prusty 	list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
1571a10612fSSubhransu S. Prusty 
1581a10612fSSubhransu S. Prusty 	return 0;
15923905cd1SJeeja KP }
16023905cd1SJeeja KP 
161617647aeSTakashi Iwai static const unsigned int rates[] = {
1625eab6ab9SVinod Koul 	48000,
1635eab6ab9SVinod Koul };
1645eab6ab9SVinod Koul 
165617647aeSTakashi Iwai static const struct snd_pcm_hw_constraint_list constraints_rates = {
1665eab6ab9SVinod Koul 	.count = ARRAY_SIZE(rates),
1675eab6ab9SVinod Koul 	.list  = rates,
1685eab6ab9SVinod Koul 	.mask = 0,
1695eab6ab9SVinod Koul };
1705eab6ab9SVinod Koul 
171617647aeSTakashi Iwai static const unsigned int channels[] = {
1725eab6ab9SVinod Koul 	2,
1735eab6ab9SVinod Koul };
1745eab6ab9SVinod Koul 
175617647aeSTakashi Iwai static const struct snd_pcm_hw_constraint_list constraints_channels = {
1765eab6ab9SVinod Koul 	.count = ARRAY_SIZE(channels),
1775eab6ab9SVinod Koul 	.list = channels,
1785eab6ab9SVinod Koul 	.mask = 0,
1795eab6ab9SVinod Koul };
1805eab6ab9SVinod Koul 
skl_fe_startup(struct snd_pcm_substream * substream)1815eab6ab9SVinod Koul static int skl_fe_startup(struct snd_pcm_substream *substream)
1825eab6ab9SVinod Koul {
1835eab6ab9SVinod Koul 	struct snd_pcm_runtime *runtime = substream->runtime;
1845eab6ab9SVinod Koul 
1855eab6ab9SVinod Koul 	/*
1865eab6ab9SVinod Koul 	 * on this platform for PCM device we support,
1875eab6ab9SVinod Koul 	 *	48Khz
1885eab6ab9SVinod Koul 	 *	stereo
1895eab6ab9SVinod Koul 	 *	16 bit audio
1905eab6ab9SVinod Koul 	 */
1915eab6ab9SVinod Koul 
1925eab6ab9SVinod Koul 	runtime->hw.channels_max = 2;
1935eab6ab9SVinod Koul 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1945eab6ab9SVinod Koul 					   &constraints_channels);
1955eab6ab9SVinod Koul 
1965eab6ab9SVinod Koul 	runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
1975eab6ab9SVinod Koul 	snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
1985eab6ab9SVinod Koul 
1995eab6ab9SVinod Koul 	snd_pcm_hw_constraint_list(runtime, 0,
2005eab6ab9SVinod Koul 				SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
2015eab6ab9SVinod Koul 
2025eab6ab9SVinod Koul 	return 0;
2035eab6ab9SVinod Koul }
2045eab6ab9SVinod Koul 
2055eab6ab9SVinod Koul static const struct snd_soc_ops skylake_rt286_fe_ops = {
2065eab6ab9SVinod Koul 	.startup = skl_fe_startup,
2075eab6ab9SVinod Koul };
208624729fdSOmair M Abdullah 
skylake_ssp0_fixup(struct snd_soc_pcm_runtime * rtd,struct snd_pcm_hw_params * params)209624729fdSOmair M Abdullah static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
210624729fdSOmair M Abdullah 			struct snd_pcm_hw_params *params)
211624729fdSOmair M Abdullah {
212624729fdSOmair M Abdullah 	struct snd_interval *rate = hw_param_interval(params,
213624729fdSOmair M Abdullah 			SNDRV_PCM_HW_PARAM_RATE);
2140c7288f4SPierre-Louis Bossart 	struct snd_interval *chan = hw_param_interval(params,
215624729fdSOmair M Abdullah 						SNDRV_PCM_HW_PARAM_CHANNELS);
216677165f7SJeeja KP 	struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
217624729fdSOmair M Abdullah 
218624729fdSOmair M Abdullah 	/* The output is 48KHz, stereo, 16bits */
219624729fdSOmair M Abdullah 	rate->min = rate->max = 48000;
2200c7288f4SPierre-Louis Bossart 	chan->min = chan->max = 2;
221624729fdSOmair M Abdullah 
222677165f7SJeeja KP 	/* set SSP0 to 24 bit */
223677165f7SJeeja KP 	snd_mask_none(fmt);
224b5453e8cSTakashi Iwai 	snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
225624729fdSOmair M Abdullah 	return 0;
226624729fdSOmair M Abdullah }
227624729fdSOmair M Abdullah 
skylake_rt286_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)228624729fdSOmair M Abdullah static int skylake_rt286_hw_params(struct snd_pcm_substream *substream,
229624729fdSOmair M Abdullah 	struct snd_pcm_hw_params *params)
230624729fdSOmair M Abdullah {
2312207b93bSKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
2320d1571c1SKuninori Morimoto 	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
233624729fdSOmair M Abdullah 	int ret;
234624729fdSOmair M Abdullah 
235624729fdSOmair M Abdullah 	ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000,
236624729fdSOmair M Abdullah 		SND_SOC_CLOCK_IN);
237624729fdSOmair M Abdullah 	if (ret < 0)
238624729fdSOmair M Abdullah 		dev_err(rtd->dev, "set codec sysclk failed: %d\n", ret);
239624729fdSOmair M Abdullah 
240624729fdSOmair M Abdullah 	return ret;
241624729fdSOmair M Abdullah }
242624729fdSOmair M Abdullah 
2439b6fdef6SJulia Lawall static const struct snd_soc_ops skylake_rt286_ops = {
244624729fdSOmair M Abdullah 	.hw_params = skylake_rt286_hw_params,
245624729fdSOmair M Abdullah };
246624729fdSOmair M Abdullah 
skylake_dmic_fixup(struct snd_soc_pcm_runtime * rtd,struct snd_pcm_hw_params * params)2474386b767SJeeja KP static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
2484386b767SJeeja KP 				struct snd_pcm_hw_params *params)
2494386b767SJeeja KP {
2500c7288f4SPierre-Louis Bossart 	struct snd_interval *chan = hw_param_interval(params,
2514386b767SJeeja KP 						SNDRV_PCM_HW_PARAM_CHANNELS);
2526e3ffa00SJeeja KP 	if (params_channels(params) == 2)
2530c7288f4SPierre-Louis Bossart 		chan->min = chan->max = 2;
2546e3ffa00SJeeja KP 	else
2550c7288f4SPierre-Louis Bossart 		chan->min = chan->max = 4;
2564386b767SJeeja KP 
2574386b767SJeeja KP 	return 0;
2584386b767SJeeja KP }
2594386b767SJeeja KP 
260617647aeSTakashi Iwai static const unsigned int channels_dmic[] = {
2614386b767SJeeja KP 	2, 4,
2624386b767SJeeja KP };
2634386b767SJeeja KP 
264617647aeSTakashi Iwai static const struct snd_pcm_hw_constraint_list constraints_dmic_channels = {
2654386b767SJeeja KP 	.count = ARRAY_SIZE(channels_dmic),
2664386b767SJeeja KP 	.list = channels_dmic,
2674386b767SJeeja KP 	.mask = 0,
2684386b767SJeeja KP };
2694386b767SJeeja KP 
skylake_dmic_startup(struct snd_pcm_substream * substream)2704386b767SJeeja KP static int skylake_dmic_startup(struct snd_pcm_substream *substream)
2714386b767SJeeja KP {
2724386b767SJeeja KP 	struct snd_pcm_runtime *runtime = substream->runtime;
2734386b767SJeeja KP 
2744386b767SJeeja KP 	runtime->hw.channels_max = 4;
2754386b767SJeeja KP 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
2764386b767SJeeja KP 					   &constraints_dmic_channels);
2774386b767SJeeja KP 
2784386b767SJeeja KP 	return snd_pcm_hw_constraint_list(substream->runtime, 0,
2794386b767SJeeja KP 			SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
2804386b767SJeeja KP }
2814386b767SJeeja KP 
2829b6fdef6SJulia Lawall static const struct snd_soc_ops skylake_dmic_ops = {
2834386b767SJeeja KP 	.startup = skylake_dmic_startup,
2844386b767SJeeja KP };
2854386b767SJeeja KP 
2869cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(dummy,
2879cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_DUMMY()));
2889cb56a5cSKuninori Morimoto 
2899cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(system,
2909cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("System Pin")));
2919cb56a5cSKuninori Morimoto 
2929cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(deepbuffer,
2939cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("Deepbuffer Pin")));
2949cb56a5cSKuninori Morimoto 
2959cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(reference,
2969cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin")));
2979cb56a5cSKuninori Morimoto 
2989cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(dmic,
2999cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin")));
3009cb56a5cSKuninori Morimoto 
3019cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(hdmi1,
3029cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin")));
3039cb56a5cSKuninori Morimoto 
3049cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(hdmi2,
3059cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin")));
3069cb56a5cSKuninori Morimoto 
3079cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(hdmi3,
3089cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin")));
3099cb56a5cSKuninori Morimoto 
3109cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(ssp0_pin,
3119cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin")));
3129cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(ssp0_codec,
3139cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CODEC("i2c-INT343A:00", "rt286-aif1")));
3149cb56a5cSKuninori Morimoto 
3159cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(dmic01_pin,
3169cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin")));
3179cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(dmic_codec,
3189cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
3199cb56a5cSKuninori Morimoto 
3209cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(idisp1_pin,
3219cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin")));
3229cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(idisp1_codec,
3239cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1")));
3249cb56a5cSKuninori Morimoto 
3259cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(idisp2_pin,
3269cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin")));
3279cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(idisp2_codec,
3289cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2")));
3299cb56a5cSKuninori Morimoto 
3309cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(idisp3_pin,
3319cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin")));
3329cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(idisp3_codec,
3339cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3")));
3349cb56a5cSKuninori Morimoto 
3359cb56a5cSKuninori Morimoto SND_SOC_DAILINK_DEF(platform,
3369cb56a5cSKuninori Morimoto 	DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3")));
3379cb56a5cSKuninori Morimoto 
338624729fdSOmair M Abdullah /* skylake digital audio interface glue - connects codec <--> CPU */
339624729fdSOmair M Abdullah static struct snd_soc_dai_link skylake_rt286_dais[] = {
340624729fdSOmair M Abdullah 	/* Front End DAI links */
34123905cd1SJeeja KP 	[SKL_DPCM_AUDIO_PB] = {
342624729fdSOmair M Abdullah 		.name = "Skl Audio Port",
343624729fdSOmair M Abdullah 		.stream_name = "Audio",
344624729fdSOmair M Abdullah 		.nonatomic = 1,
345624729fdSOmair M Abdullah 		.dynamic = 1,
3469ec2053bSPraveen Diwakar 		.init = skylake_rt286_fe_init,
347624729fdSOmair M Abdullah 		.trigger = {
348624729fdSOmair M Abdullah 			SND_SOC_DPCM_TRIGGER_POST,
349624729fdSOmair M Abdullah 			SND_SOC_DPCM_TRIGGER_POST
350624729fdSOmair M Abdullah 		},
351624729fdSOmair M Abdullah 		.dpcm_playback = 1,
3525eab6ab9SVinod Koul 		.ops = &skylake_rt286_fe_ops,
3539cb56a5cSKuninori Morimoto 		SND_SOC_DAILINK_REG(system, dummy, platform),
354624729fdSOmair M Abdullah 	},
3551f0f8bdeSSubhransu S. Prusty 	[SKL_DPCM_AUDIO_DB_PB] = {
3561f0f8bdeSSubhransu S. Prusty 		.name = "Skl Deepbuffer Port",
3571f0f8bdeSSubhransu S. Prusty 		.stream_name = "Deep Buffer Audio",
3581f0f8bdeSSubhransu S. Prusty 		.nonatomic = 1,
3591f0f8bdeSSubhransu S. Prusty 		.dynamic = 1,
3601f0f8bdeSSubhransu S. Prusty 		.trigger = {
3611f0f8bdeSSubhransu S. Prusty 			SND_SOC_DPCM_TRIGGER_POST,
3621f0f8bdeSSubhransu S. Prusty 			SND_SOC_DPCM_TRIGGER_POST
3631f0f8bdeSSubhransu S. Prusty 		},
3641f0f8bdeSSubhransu S. Prusty 		.dpcm_playback = 1,
3651f0f8bdeSSubhransu S. Prusty 		.ops = &skylake_rt286_fe_ops,
3669cb56a5cSKuninori Morimoto 		SND_SOC_DAILINK_REG(deepbuffer, dummy, platform),
3671f0f8bdeSSubhransu S. Prusty 	},
36823905cd1SJeeja KP 	[SKL_DPCM_AUDIO_CP] = {
369624729fdSOmair M Abdullah 		.name = "Skl Audio Capture Port",
370624729fdSOmair M Abdullah 		.stream_name = "Audio Record",
371624729fdSOmair M Abdullah 		.nonatomic = 1,
372624729fdSOmair M Abdullah 		.dynamic = 1,
373624729fdSOmair M Abdullah 		.trigger = {
374624729fdSOmair M Abdullah 			SND_SOC_DPCM_TRIGGER_POST,
375624729fdSOmair M Abdullah 			SND_SOC_DPCM_TRIGGER_POST
376624729fdSOmair M Abdullah 		},
377624729fdSOmair M Abdullah 		.dpcm_capture = 1,
3785eab6ab9SVinod Koul 		.ops = &skylake_rt286_fe_ops,
3799cb56a5cSKuninori Morimoto 		SND_SOC_DAILINK_REG(system, dummy, platform),
380624729fdSOmair M Abdullah 	},
38123905cd1SJeeja KP 	[SKL_DPCM_AUDIO_REF_CP] = {
382624729fdSOmair M Abdullah 		.name = "Skl Audio Reference cap",
383624729fdSOmair M Abdullah 		.stream_name = "refcap",
384624729fdSOmair M Abdullah 		.init = NULL,
385624729fdSOmair M Abdullah 		.dpcm_capture = 1,
386624729fdSOmair M Abdullah 		.nonatomic = 1,
387624729fdSOmair M Abdullah 		.dynamic = 1,
3889cb56a5cSKuninori Morimoto 		SND_SOC_DAILINK_REG(reference, dummy, platform),
389624729fdSOmair M Abdullah 	},
39023905cd1SJeeja KP 	[SKL_DPCM_AUDIO_DMIC_CP] = {
3914386b767SJeeja KP 		.name = "Skl Audio DMIC cap",
3924386b767SJeeja KP 		.stream_name = "dmiccap",
3934386b767SJeeja KP 		.init = NULL,
3944386b767SJeeja KP 		.dpcm_capture = 1,
3954386b767SJeeja KP 		.nonatomic = 1,
3964386b767SJeeja KP 		.dynamic = 1,
3974386b767SJeeja KP 		.ops = &skylake_dmic_ops,
3989cb56a5cSKuninori Morimoto 		SND_SOC_DAILINK_REG(dmic, dummy, platform),
3994386b767SJeeja KP 	},
40023905cd1SJeeja KP 	[SKL_DPCM_AUDIO_HDMI1_PB] = {
40123905cd1SJeeja KP 		.name = "Skl HDMI Port1",
40223905cd1SJeeja KP 		.stream_name = "Hdmi1",
40323905cd1SJeeja KP 		.dpcm_playback = 1,
40423905cd1SJeeja KP 		.init = NULL,
40523905cd1SJeeja KP 		.nonatomic = 1,
40623905cd1SJeeja KP 		.dynamic = 1,
4079cb56a5cSKuninori Morimoto 		SND_SOC_DAILINK_REG(hdmi1, dummy, platform),
40823905cd1SJeeja KP 	},
40923905cd1SJeeja KP 	[SKL_DPCM_AUDIO_HDMI2_PB] = {
41023905cd1SJeeja KP 		.name = "Skl HDMI Port2",
41123905cd1SJeeja KP 		.stream_name = "Hdmi2",
41223905cd1SJeeja KP 		.dpcm_playback = 1,
41323905cd1SJeeja KP 		.init = NULL,
41423905cd1SJeeja KP 		.nonatomic = 1,
41523905cd1SJeeja KP 		.dynamic = 1,
4169cb56a5cSKuninori Morimoto 		SND_SOC_DAILINK_REG(hdmi2, dummy, platform),
41723905cd1SJeeja KP 	},
41823905cd1SJeeja KP 	[SKL_DPCM_AUDIO_HDMI3_PB] = {
41923905cd1SJeeja KP 		.name = "Skl HDMI Port3",
42023905cd1SJeeja KP 		.stream_name = "Hdmi3",
42123905cd1SJeeja KP 		.dpcm_playback = 1,
42223905cd1SJeeja KP 		.init = NULL,
42323905cd1SJeeja KP 		.nonatomic = 1,
42423905cd1SJeeja KP 		.dynamic = 1,
4259cb56a5cSKuninori Morimoto 		SND_SOC_DAILINK_REG(hdmi3, dummy, platform),
42623905cd1SJeeja KP 	},
427624729fdSOmair M Abdullah 
428624729fdSOmair M Abdullah 	/* Back End DAI links */
429624729fdSOmair M Abdullah 	{
430624729fdSOmair M Abdullah 		/* SSP0 - Codec */
431624729fdSOmair M Abdullah 		.name = "SSP0-Codec",
4322f0ad491SMengdong Lin 		.id = 0,
433624729fdSOmair M Abdullah 		.no_pcm = 1,
434624729fdSOmair M Abdullah 		.init = skylake_rt286_codec_init,
435624729fdSOmair M Abdullah 		.dai_fmt = SND_SOC_DAIFMT_I2S |
436624729fdSOmair M Abdullah 			SND_SOC_DAIFMT_NB_NF |
4375374b921SPeter Ujfalusi 			SND_SOC_DAIFMT_CBC_CFC,
438624729fdSOmair M Abdullah 		.ignore_pmdown_time = 1,
439624729fdSOmair M Abdullah 		.be_hw_params_fixup = skylake_ssp0_fixup,
440624729fdSOmair M Abdullah 		.ops = &skylake_rt286_ops,
441624729fdSOmair M Abdullah 		.dpcm_playback = 1,
442624729fdSOmair M Abdullah 		.dpcm_capture = 1,
4439cb56a5cSKuninori Morimoto 		SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec, platform),
444624729fdSOmair M Abdullah 	},
445624729fdSOmair M Abdullah 	{
446624729fdSOmair M Abdullah 		.name = "dmic01",
4472f0ad491SMengdong Lin 		.id = 1,
4484386b767SJeeja KP 		.be_hw_params_fixup = skylake_dmic_fixup,
449624729fdSOmair M Abdullah 		.ignore_suspend = 1,
450624729fdSOmair M Abdullah 		.dpcm_capture = 1,
451624729fdSOmair M Abdullah 		.no_pcm = 1,
4529cb56a5cSKuninori Morimoto 		SND_SOC_DAILINK_REG(dmic01_pin, dmic_codec, platform),
453624729fdSOmair M Abdullah 	},
45423905cd1SJeeja KP 	{
45523905cd1SJeeja KP 		.name = "iDisp1",
4562f0ad491SMengdong Lin 		.id = 2,
45723905cd1SJeeja KP 		.init = skylake_hdmi_init,
45823905cd1SJeeja KP 		.dpcm_playback = 1,
45923905cd1SJeeja KP 		.no_pcm = 1,
4609cb56a5cSKuninori Morimoto 		SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform),
46123905cd1SJeeja KP 	},
46223905cd1SJeeja KP 	{
46323905cd1SJeeja KP 		.name = "iDisp2",
4642f0ad491SMengdong Lin 		.id = 3,
46523905cd1SJeeja KP 		.init = skylake_hdmi_init,
46623905cd1SJeeja KP 		.dpcm_playback = 1,
46723905cd1SJeeja KP 		.no_pcm = 1,
4689cb56a5cSKuninori Morimoto 		SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform),
46923905cd1SJeeja KP 	},
47023905cd1SJeeja KP 	{
47123905cd1SJeeja KP 		.name = "iDisp3",
4722f0ad491SMengdong Lin 		.id = 4,
47323905cd1SJeeja KP 		.init = skylake_hdmi_init,
47423905cd1SJeeja KP 		.dpcm_playback = 1,
47523905cd1SJeeja KP 		.no_pcm = 1,
4769cb56a5cSKuninori Morimoto 		SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform),
47723905cd1SJeeja KP 	},
478624729fdSOmair M Abdullah };
479624729fdSOmair M Abdullah 
480f3af3592SJeeja KP #define NAME_SIZE	32
skylake_card_late_probe(struct snd_soc_card * card)4811a10612fSSubhransu S. Prusty static int skylake_card_late_probe(struct snd_soc_card *card)
4821a10612fSSubhransu S. Prusty {
4831a10612fSSubhransu S. Prusty 	struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(card);
4841a10612fSSubhransu S. Prusty 	struct skl_hdmi_pcm *pcm;
48545101122SKuninori Morimoto 	struct snd_soc_component *component = NULL;
486f3af3592SJeeja KP 	int err, i = 0;
487f3af3592SJeeja KP 	char jack_name[NAME_SIZE];
4881a10612fSSubhransu S. Prusty 
4891a10612fSSubhransu S. Prusty 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
49045101122SKuninori Morimoto 		component = pcm->codec_dai->component;
491f3af3592SJeeja KP 		snprintf(jack_name, sizeof(jack_name),
492f3af3592SJeeja KP 			"HDMI/DP, pcm=%d Jack", pcm->device);
493f3af3592SJeeja KP 		err = snd_soc_card_jack_new(card, jack_name,
49419aed2d6SAkihiko Odaki 					SND_JACK_AVOUT, &skylake_hdmi[i]);
495f3af3592SJeeja KP 
496f3af3592SJeeja KP 		if (err)
497f3af3592SJeeja KP 			return err;
498f3af3592SJeeja KP 
499f3af3592SJeeja KP 		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
500f3af3592SJeeja KP 						&skylake_hdmi[i]);
5011a10612fSSubhransu S. Prusty 		if (err < 0)
5021a10612fSSubhransu S. Prusty 			return err;
503f3af3592SJeeja KP 
504f3af3592SJeeja KP 		i++;
5051a10612fSSubhransu S. Prusty 	}
5061a10612fSSubhransu S. Prusty 
50745101122SKuninori Morimoto 	if (!component)
50864f8620dSJeeja KP 		return -EINVAL;
50964f8620dSJeeja KP 
51045101122SKuninori Morimoto 	return hdac_hdmi_jack_port_init(component, &card->dapm);
5111a10612fSSubhransu S. Prusty }
5121a10612fSSubhransu S. Prusty 
513624729fdSOmair M Abdullah /* skylake audio machine driver for SPT + RT286S */
514624729fdSOmair M Abdullah static struct snd_soc_card skylake_rt286 = {
515624729fdSOmair M Abdullah 	.name = "skylake-rt286",
516624729fdSOmair M Abdullah 	.owner = THIS_MODULE,
517624729fdSOmair M Abdullah 	.dai_link = skylake_rt286_dais,
518624729fdSOmair M Abdullah 	.num_links = ARRAY_SIZE(skylake_rt286_dais),
519624729fdSOmair M Abdullah 	.controls = skylake_controls,
520624729fdSOmair M Abdullah 	.num_controls = ARRAY_SIZE(skylake_controls),
521624729fdSOmair M Abdullah 	.dapm_widgets = skylake_widgets,
522624729fdSOmair M Abdullah 	.num_dapm_widgets = ARRAY_SIZE(skylake_widgets),
523624729fdSOmair M Abdullah 	.dapm_routes = skylake_rt286_map,
524624729fdSOmair M Abdullah 	.num_dapm_routes = ARRAY_SIZE(skylake_rt286_map),
525624729fdSOmair M Abdullah 	.fully_routed = true,
526*48f3fe13SCezary Rojewski 	.disable_route_checks = true,
5271a10612fSSubhransu S. Prusty 	.late_probe = skylake_card_late_probe,
528624729fdSOmair M Abdullah };
529624729fdSOmair M Abdullah 
skylake_audio_probe(struct platform_device * pdev)530624729fdSOmair M Abdullah static int skylake_audio_probe(struct platform_device *pdev)
531624729fdSOmair M Abdullah {
5321a10612fSSubhransu S. Prusty 	struct skl_rt286_private *ctx;
5331a10612fSSubhransu S. Prusty 
534a6b09837SJia-Ju Bai 	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
5351a10612fSSubhransu S. Prusty 	if (!ctx)
5361a10612fSSubhransu S. Prusty 		return -ENOMEM;
5371a10612fSSubhransu S. Prusty 
5381a10612fSSubhransu S. Prusty 	INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
5391a10612fSSubhransu S. Prusty 
540624729fdSOmair M Abdullah 	skylake_rt286.dev = &pdev->dev;
5411a10612fSSubhransu S. Prusty 	snd_soc_card_set_drvdata(&skylake_rt286, ctx);
542624729fdSOmair M Abdullah 
5434901aa06SAxel Lin 	return devm_snd_soc_register_card(&pdev->dev, &skylake_rt286);
544624729fdSOmair M Abdullah }
545624729fdSOmair M Abdullah 
546894a16dbSVinod Koul static const struct platform_device_id skl_board_ids[] = {
547894a16dbSVinod Koul 	{ .name = "skl_alc286s_i2s" },
548894a16dbSVinod Koul 	{ .name = "kbl_alc286s_i2s" },
549894a16dbSVinod Koul 	{ }
550894a16dbSVinod Koul };
55153b98536SPierre-Louis Bossart MODULE_DEVICE_TABLE(platform, skl_board_ids);
552894a16dbSVinod Koul 
553624729fdSOmair M Abdullah static struct platform_driver skylake_audio = {
554624729fdSOmair M Abdullah 	.probe = skylake_audio_probe,
555624729fdSOmair M Abdullah 	.driver = {
556624729fdSOmair M Abdullah 		.name = "skl_alc286s_i2s",
557314038e4SJeeja KP 		.pm = &snd_soc_pm_ops,
558624729fdSOmair M Abdullah 	},
559894a16dbSVinod Koul 	.id_table = skl_board_ids,
560894a16dbSVinod Koul 
561624729fdSOmair M Abdullah };
562624729fdSOmair M Abdullah 
563624729fdSOmair M Abdullah module_platform_driver(skylake_audio)
564624729fdSOmair M Abdullah 
565624729fdSOmair M Abdullah /* Module information */
566624729fdSOmair M Abdullah MODULE_AUTHOR("Omair Mohammed Abdullah <omair.m.abdullah@intel.com>");
567624729fdSOmair M Abdullah MODULE_DESCRIPTION("Intel SST Audio for Skylake");
568624729fdSOmair M Abdullah MODULE_LICENSE("GPL v2");
569