1e149ca29SPierre-Louis Bossart // SPDX-License-Identifier: GPL-2.0-only
2b3ea70eeSNaveen Manohar // Copyright(c) 2017-18 Intel Corporation.
3b3ea70eeSNaveen Manohar
4b3ea70eeSNaveen Manohar /*
5b3ea70eeSNaveen Manohar * Intel Kabylake I2S Machine Driver with MAX98357A & DA7219 Codecs
6b3ea70eeSNaveen Manohar *
7b3ea70eeSNaveen Manohar * Modified from:
8b3ea70eeSNaveen Manohar * Intel Kabylake I2S Machine driver supporting MAXIM98927 and
9b3ea70eeSNaveen Manohar * RT5663 codecs
10b3ea70eeSNaveen Manohar */
11b3ea70eeSNaveen Manohar
12b3ea70eeSNaveen Manohar #include <linux/input.h>
13b3ea70eeSNaveen Manohar #include <linux/module.h>
14b3ea70eeSNaveen Manohar #include <linux/platform_device.h>
15b3ea70eeSNaveen Manohar #include <sound/core.h>
16b3ea70eeSNaveen Manohar #include <sound/jack.h>
17b3ea70eeSNaveen Manohar #include <sound/pcm.h>
18b3ea70eeSNaveen Manohar #include <sound/pcm_params.h>
19b3ea70eeSNaveen Manohar #include <sound/soc.h>
20b3ea70eeSNaveen Manohar #include "../../codecs/da7219.h"
21b3ea70eeSNaveen Manohar #include "../../codecs/hdac_hdmi.h"
22b3ea70eeSNaveen Manohar
23b3ea70eeSNaveen Manohar #define KBL_DIALOG_CODEC_DAI "da7219-hifi"
24b3ea70eeSNaveen Manohar #define KBL_MAXIM_CODEC_DAI "HiFi"
25b3ea70eeSNaveen Manohar #define MAXIM_DEV0_NAME "MX98357A:00"
26b3ea70eeSNaveen Manohar #define DUAL_CHANNEL 2
27b3ea70eeSNaveen Manohar #define QUAD_CHANNEL 4
28b3ea70eeSNaveen Manohar
29b3ea70eeSNaveen Manohar static struct snd_soc_card *kabylake_audio_card;
30b3ea70eeSNaveen Manohar static struct snd_soc_jack skylake_hdmi[3];
31b3ea70eeSNaveen Manohar
32b3ea70eeSNaveen Manohar struct kbl_hdmi_pcm {
33b3ea70eeSNaveen Manohar struct list_head head;
34b3ea70eeSNaveen Manohar struct snd_soc_dai *codec_dai;
35b3ea70eeSNaveen Manohar int device;
36b3ea70eeSNaveen Manohar };
37b3ea70eeSNaveen Manohar
38b3ea70eeSNaveen Manohar struct kbl_codec_private {
39b3ea70eeSNaveen Manohar struct snd_soc_jack kabylake_headset;
40b3ea70eeSNaveen Manohar struct list_head hdmi_pcm_list;
41b3ea70eeSNaveen Manohar };
42b3ea70eeSNaveen Manohar
43b3ea70eeSNaveen Manohar enum {
44b3ea70eeSNaveen Manohar KBL_DPCM_AUDIO_PB = 0,
45b3ea70eeSNaveen Manohar KBL_DPCM_AUDIO_CP,
4674ed9e9bSMac Chiang KBL_DPCM_AUDIO_REF_CP,
47b3ea70eeSNaveen Manohar KBL_DPCM_AUDIO_DMIC_CP,
48b3ea70eeSNaveen Manohar KBL_DPCM_AUDIO_HDMI1_PB,
49b3ea70eeSNaveen Manohar KBL_DPCM_AUDIO_HDMI2_PB,
50b3ea70eeSNaveen Manohar KBL_DPCM_AUDIO_HDMI3_PB,
51b3ea70eeSNaveen Manohar };
52b3ea70eeSNaveen Manohar
platform_clock_control(struct snd_soc_dapm_widget * w,struct snd_kcontrol * k,int event)53b3ea70eeSNaveen Manohar static int platform_clock_control(struct snd_soc_dapm_widget *w,
54b3ea70eeSNaveen Manohar struct snd_kcontrol *k, int event)
55b3ea70eeSNaveen Manohar {
56b3ea70eeSNaveen Manohar struct snd_soc_dapm_context *dapm = w->dapm;
57b3ea70eeSNaveen Manohar struct snd_soc_card *card = dapm->card;
58b3ea70eeSNaveen Manohar struct snd_soc_dai *codec_dai;
59b3ea70eeSNaveen Manohar int ret = 0;
60b3ea70eeSNaveen Manohar
61b3ea70eeSNaveen Manohar codec_dai = snd_soc_card_get_codec_dai(card, KBL_DIALOG_CODEC_DAI);
62b3ea70eeSNaveen Manohar if (!codec_dai) {
63b3ea70eeSNaveen Manohar dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n");
64b3ea70eeSNaveen Manohar return -EIO;
65b3ea70eeSNaveen Manohar }
66b3ea70eeSNaveen Manohar
67b3ea70eeSNaveen Manohar if (SND_SOC_DAPM_EVENT_OFF(event)) {
68b3ea70eeSNaveen Manohar ret = snd_soc_dai_set_pll(codec_dai, 0,
69b3ea70eeSNaveen Manohar DA7219_SYSCLK_MCLK, 0, 0);
70b3ea70eeSNaveen Manohar if (ret)
71b3ea70eeSNaveen Manohar dev_err(card->dev, "failed to stop PLL: %d\n", ret);
72b3ea70eeSNaveen Manohar } else if (SND_SOC_DAPM_EVENT_ON(event)) {
73b3ea70eeSNaveen Manohar ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL_SRM,
74b3ea70eeSNaveen Manohar 0, DA7219_PLL_FREQ_OUT_98304);
75b3ea70eeSNaveen Manohar if (ret)
76b3ea70eeSNaveen Manohar dev_err(card->dev, "failed to start PLL: %d\n", ret);
77b3ea70eeSNaveen Manohar }
78b3ea70eeSNaveen Manohar
79b3ea70eeSNaveen Manohar return ret;
80b3ea70eeSNaveen Manohar }
81b3ea70eeSNaveen Manohar
82b3ea70eeSNaveen Manohar static const struct snd_kcontrol_new kabylake_controls[] = {
83b3ea70eeSNaveen Manohar SOC_DAPM_PIN_SWITCH("Headphone Jack"),
84b3ea70eeSNaveen Manohar SOC_DAPM_PIN_SWITCH("Headset Mic"),
85b3ea70eeSNaveen Manohar SOC_DAPM_PIN_SWITCH("Spk"),
86da09176fSAlper Nebi Yasak SOC_DAPM_PIN_SWITCH("Line Out"),
87b3ea70eeSNaveen Manohar };
88b3ea70eeSNaveen Manohar
89b3ea70eeSNaveen Manohar static const struct snd_soc_dapm_widget kabylake_widgets[] = {
90b3ea70eeSNaveen Manohar SND_SOC_DAPM_HP("Headphone Jack", NULL),
91b3ea70eeSNaveen Manohar SND_SOC_DAPM_MIC("Headset Mic", NULL),
92b3ea70eeSNaveen Manohar SND_SOC_DAPM_SPK("Spk", NULL),
93da09176fSAlper Nebi Yasak SND_SOC_DAPM_LINE("Line Out", NULL),
94b3ea70eeSNaveen Manohar SND_SOC_DAPM_MIC("SoC DMIC", NULL),
95c7c19ec0SVamshi Krishna Gopal SND_SOC_DAPM_SPK("HDMI1", NULL),
96c7c19ec0SVamshi Krishna Gopal SND_SOC_DAPM_SPK("HDMI2", NULL),
97c7c19ec0SVamshi Krishna Gopal SND_SOC_DAPM_SPK("HDMI3", NULL),
98b3ea70eeSNaveen Manohar SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
99b3ea70eeSNaveen Manohar platform_clock_control, SND_SOC_DAPM_PRE_PMU |
100b3ea70eeSNaveen Manohar SND_SOC_DAPM_POST_PMD),
101b3ea70eeSNaveen Manohar };
102b3ea70eeSNaveen Manohar
103c2065d43SPierre-Louis Bossart static struct snd_soc_jack_pin jack_pins[] = {
104c2065d43SPierre-Louis Bossart {
105c2065d43SPierre-Louis Bossart .pin = "Headphone Jack",
106c2065d43SPierre-Louis Bossart .mask = SND_JACK_HEADPHONE,
107c2065d43SPierre-Louis Bossart },
108c2065d43SPierre-Louis Bossart {
109c2065d43SPierre-Louis Bossart .pin = "Headset Mic",
110c2065d43SPierre-Louis Bossart .mask = SND_JACK_MICROPHONE,
111c2065d43SPierre-Louis Bossart },
112da09176fSAlper Nebi Yasak {
113da09176fSAlper Nebi Yasak .pin = "Line Out",
114da09176fSAlper Nebi Yasak .mask = SND_JACK_LINEOUT,
115da09176fSAlper Nebi Yasak },
116c2065d43SPierre-Louis Bossart };
117c2065d43SPierre-Louis Bossart
118b3ea70eeSNaveen Manohar static const struct snd_soc_dapm_route kabylake_map[] = {
119b3ea70eeSNaveen Manohar { "Headphone Jack", NULL, "HPL" },
120b3ea70eeSNaveen Manohar { "Headphone Jack", NULL, "HPR" },
121b3ea70eeSNaveen Manohar
122b3ea70eeSNaveen Manohar /* speaker */
123b3ea70eeSNaveen Manohar { "Spk", NULL, "Speaker" },
124b3ea70eeSNaveen Manohar
125b3ea70eeSNaveen Manohar /* other jacks */
126b3ea70eeSNaveen Manohar { "MIC", NULL, "Headset Mic" },
127b3ea70eeSNaveen Manohar { "DMic", NULL, "SoC DMIC" },
128b3ea70eeSNaveen Manohar
129c7c19ec0SVamshi Krishna Gopal {"HDMI1", NULL, "hif5-0 Output"},
130c7c19ec0SVamshi Krishna Gopal {"HDMI2", NULL, "hif6-0 Output"},
131c7c19ec0SVamshi Krishna Gopal {"HDMI3", NULL, "hif7-0 Output"},
132b3ea70eeSNaveen Manohar
133b3ea70eeSNaveen Manohar /* CODEC BE connections */
134b3ea70eeSNaveen Manohar { "HiFi Playback", NULL, "ssp0 Tx" },
135b3ea70eeSNaveen Manohar { "ssp0 Tx", NULL, "codec0_out" },
136b3ea70eeSNaveen Manohar
137b3ea70eeSNaveen Manohar { "Playback", NULL, "ssp1 Tx" },
138b3ea70eeSNaveen Manohar { "ssp1 Tx", NULL, "codec1_out" },
139b3ea70eeSNaveen Manohar
140b3ea70eeSNaveen Manohar { "codec0_in", NULL, "ssp1 Rx" },
141b3ea70eeSNaveen Manohar { "ssp1 Rx", NULL, "Capture" },
142b3ea70eeSNaveen Manohar
143b3ea70eeSNaveen Manohar /* DMIC */
144b3ea70eeSNaveen Manohar { "dmic01_hifi", NULL, "DMIC01 Rx" },
145b3ea70eeSNaveen Manohar { "DMIC01 Rx", NULL, "DMIC AIF" },
146b3ea70eeSNaveen Manohar
147b3ea70eeSNaveen Manohar { "hifi1", NULL, "iDisp1 Tx" },
148b3ea70eeSNaveen Manohar { "iDisp1 Tx", NULL, "iDisp1_out" },
149b3ea70eeSNaveen Manohar { "hifi2", NULL, "iDisp2 Tx" },
150b3ea70eeSNaveen Manohar { "iDisp2 Tx", NULL, "iDisp2_out" },
151b3ea70eeSNaveen Manohar { "hifi3", NULL, "iDisp3 Tx"},
152b3ea70eeSNaveen Manohar { "iDisp3 Tx", NULL, "iDisp3_out"},
153b3ea70eeSNaveen Manohar
154b3ea70eeSNaveen Manohar { "Headphone Jack", NULL, "Platform Clock" },
155b3ea70eeSNaveen Manohar { "Headset Mic", NULL, "Platform Clock" },
156da09176fSAlper Nebi Yasak { "Line Out", NULL, "Platform Clock" },
157b3ea70eeSNaveen Manohar };
158b3ea70eeSNaveen Manohar
kabylake_ssp_fixup(struct snd_soc_pcm_runtime * rtd,struct snd_pcm_hw_params * params)159b3ea70eeSNaveen Manohar static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
160b3ea70eeSNaveen Manohar struct snd_pcm_hw_params *params)
161b3ea70eeSNaveen Manohar {
162b3ea70eeSNaveen Manohar struct snd_interval *rate = hw_param_interval(params,
163b3ea70eeSNaveen Manohar SNDRV_PCM_HW_PARAM_RATE);
1642e539cf7SPierre-Louis Bossart struct snd_interval *chan = hw_param_interval(params,
165b3ea70eeSNaveen Manohar SNDRV_PCM_HW_PARAM_CHANNELS);
166b3ea70eeSNaveen Manohar struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
167b3ea70eeSNaveen Manohar
168b3ea70eeSNaveen Manohar /* The ADSP will convert the FE rate to 48k, stereo */
169b3ea70eeSNaveen Manohar rate->min = rate->max = 48000;
1702e539cf7SPierre-Louis Bossart chan->min = chan->max = DUAL_CHANNEL;
171b3ea70eeSNaveen Manohar
172b3ea70eeSNaveen Manohar /* set SSP to 24 bit */
173b3ea70eeSNaveen Manohar snd_mask_none(fmt);
174b5453e8cSTakashi Iwai snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
175b3ea70eeSNaveen Manohar
176b3ea70eeSNaveen Manohar return 0;
177b3ea70eeSNaveen Manohar }
178b3ea70eeSNaveen Manohar
kabylake_da7219_codec_init(struct snd_soc_pcm_runtime * rtd)179b3ea70eeSNaveen Manohar static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
180b3ea70eeSNaveen Manohar {
181b3ea70eeSNaveen Manohar struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
1820d1571c1SKuninori Morimoto struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
1830d1571c1SKuninori Morimoto struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
184b3ea70eeSNaveen Manohar struct snd_soc_jack *jack;
185b3ea70eeSNaveen Manohar int ret;
186b3ea70eeSNaveen Manohar
18756c3a953SMac Chiang /* Configure sysclk for codec */
18856c3a953SMac Chiang ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 24576000,
18956c3a953SMac Chiang SND_SOC_CLOCK_IN);
19056c3a953SMac Chiang if (ret) {
19156c3a953SMac Chiang dev_err(rtd->dev, "can't set codec sysclk configuration\n");
19256c3a953SMac Chiang return ret;
19356c3a953SMac Chiang }
19456c3a953SMac Chiang
195b3ea70eeSNaveen Manohar /*
196b3ea70eeSNaveen Manohar * Headset buttons map to the google Reference headset.
197b3ea70eeSNaveen Manohar * These can be configured by userspace.
198b3ea70eeSNaveen Manohar */
199c2065d43SPierre-Louis Bossart ret = snd_soc_card_jack_new_pins(kabylake_audio_card, "Headset Jack",
200b3ea70eeSNaveen Manohar SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
201b3ea70eeSNaveen Manohar SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT,
202c2065d43SPierre-Louis Bossart &ctx->kabylake_headset,
203c2065d43SPierre-Louis Bossart jack_pins,
204c2065d43SPierre-Louis Bossart ARRAY_SIZE(jack_pins));
205b3ea70eeSNaveen Manohar if (ret) {
206b3ea70eeSNaveen Manohar dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
207b3ea70eeSNaveen Manohar return ret;
208b3ea70eeSNaveen Manohar }
209b3ea70eeSNaveen Manohar
210b3ea70eeSNaveen Manohar jack = &ctx->kabylake_headset;
211b3ea70eeSNaveen Manohar
21216ec5dfeSMac Chiang snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
213b3ea70eeSNaveen Manohar snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
214b3ea70eeSNaveen Manohar snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
215b3ea70eeSNaveen Manohar snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
2169a1fe79dSCezary Rojewski snd_soc_component_set_jack(component, &ctx->kabylake_headset, NULL);
217b3ea70eeSNaveen Manohar
218b3ea70eeSNaveen Manohar ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
219b3ea70eeSNaveen Manohar if (ret)
220b3ea70eeSNaveen Manohar dev_err(rtd->dev, "SoC DMIC - Ignore suspend failed %d\n", ret);
221b3ea70eeSNaveen Manohar
222b3ea70eeSNaveen Manohar return ret;
223b3ea70eeSNaveen Manohar }
224b3ea70eeSNaveen Manohar
kabylake_hdmi_init(struct snd_soc_pcm_runtime * rtd,int device)225b3ea70eeSNaveen Manohar static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device)
226b3ea70eeSNaveen Manohar {
227b3ea70eeSNaveen Manohar struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
2280d1571c1SKuninori Morimoto struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0);
229b3ea70eeSNaveen Manohar struct kbl_hdmi_pcm *pcm;
230b3ea70eeSNaveen Manohar
231b3ea70eeSNaveen Manohar pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
232b3ea70eeSNaveen Manohar if (!pcm)
233b3ea70eeSNaveen Manohar return -ENOMEM;
234b3ea70eeSNaveen Manohar
235b3ea70eeSNaveen Manohar pcm->device = device;
236b3ea70eeSNaveen Manohar pcm->codec_dai = dai;
237b3ea70eeSNaveen Manohar
238b3ea70eeSNaveen Manohar list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
239b3ea70eeSNaveen Manohar
240b3ea70eeSNaveen Manohar return 0;
241b3ea70eeSNaveen Manohar }
242b3ea70eeSNaveen Manohar
kabylake_hdmi1_init(struct snd_soc_pcm_runtime * rtd)243b3ea70eeSNaveen Manohar static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
244b3ea70eeSNaveen Manohar {
245b3ea70eeSNaveen Manohar return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI1_PB);
246b3ea70eeSNaveen Manohar }
247b3ea70eeSNaveen Manohar
kabylake_hdmi2_init(struct snd_soc_pcm_runtime * rtd)248b3ea70eeSNaveen Manohar static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd)
249b3ea70eeSNaveen Manohar {
250b3ea70eeSNaveen Manohar return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI2_PB);
251b3ea70eeSNaveen Manohar }
252b3ea70eeSNaveen Manohar
kabylake_hdmi3_init(struct snd_soc_pcm_runtime * rtd)253b3ea70eeSNaveen Manohar static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd)
254b3ea70eeSNaveen Manohar {
255b3ea70eeSNaveen Manohar return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI3_PB);
256b3ea70eeSNaveen Manohar }
257b3ea70eeSNaveen Manohar
kabylake_da7219_fe_init(struct snd_soc_pcm_runtime * rtd)258b3ea70eeSNaveen Manohar static int kabylake_da7219_fe_init(struct snd_soc_pcm_runtime *rtd)
259b3ea70eeSNaveen Manohar {
260b3ea70eeSNaveen Manohar struct snd_soc_dapm_context *dapm;
2610d1571c1SKuninori Morimoto struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component;
262b3ea70eeSNaveen Manohar
263b3ea70eeSNaveen Manohar dapm = snd_soc_component_get_dapm(component);
264b3ea70eeSNaveen Manohar snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
265b3ea70eeSNaveen Manohar
266b3ea70eeSNaveen Manohar return 0;
267b3ea70eeSNaveen Manohar }
268b3ea70eeSNaveen Manohar
269b3ea70eeSNaveen Manohar static const unsigned int rates[] = {
270b3ea70eeSNaveen Manohar 48000,
271b3ea70eeSNaveen Manohar };
272b3ea70eeSNaveen Manohar
273b3ea70eeSNaveen Manohar static const struct snd_pcm_hw_constraint_list constraints_rates = {
274b3ea70eeSNaveen Manohar .count = ARRAY_SIZE(rates),
275b3ea70eeSNaveen Manohar .list = rates,
276b3ea70eeSNaveen Manohar .mask = 0,
277b3ea70eeSNaveen Manohar };
278b3ea70eeSNaveen Manohar
279b3ea70eeSNaveen Manohar static const unsigned int channels[] = {
280b3ea70eeSNaveen Manohar DUAL_CHANNEL,
281b3ea70eeSNaveen Manohar };
282b3ea70eeSNaveen Manohar
283b3ea70eeSNaveen Manohar static const struct snd_pcm_hw_constraint_list constraints_channels = {
284b3ea70eeSNaveen Manohar .count = ARRAY_SIZE(channels),
285b3ea70eeSNaveen Manohar .list = channels,
286b3ea70eeSNaveen Manohar .mask = 0,
287b3ea70eeSNaveen Manohar };
288b3ea70eeSNaveen Manohar
289b3ea70eeSNaveen Manohar static unsigned int channels_quad[] = {
290b3ea70eeSNaveen Manohar QUAD_CHANNEL,
291b3ea70eeSNaveen Manohar };
292b3ea70eeSNaveen Manohar
293b3ea70eeSNaveen Manohar static struct snd_pcm_hw_constraint_list constraints_channels_quad = {
294b3ea70eeSNaveen Manohar .count = ARRAY_SIZE(channels_quad),
295b3ea70eeSNaveen Manohar .list = channels_quad,
296b3ea70eeSNaveen Manohar .mask = 0,
297b3ea70eeSNaveen Manohar };
298b3ea70eeSNaveen Manohar
kbl_fe_startup(struct snd_pcm_substream * substream)299b3ea70eeSNaveen Manohar static int kbl_fe_startup(struct snd_pcm_substream *substream)
300b3ea70eeSNaveen Manohar {
301b3ea70eeSNaveen Manohar struct snd_pcm_runtime *runtime = substream->runtime;
302b3ea70eeSNaveen Manohar
303b3ea70eeSNaveen Manohar /*
304b3ea70eeSNaveen Manohar * On this platform for PCM device we support,
305b3ea70eeSNaveen Manohar * 48Khz
306b3ea70eeSNaveen Manohar * stereo
307b3ea70eeSNaveen Manohar * 16 bit audio
308b3ea70eeSNaveen Manohar */
309b3ea70eeSNaveen Manohar
310b3ea70eeSNaveen Manohar runtime->hw.channels_max = DUAL_CHANNEL;
311b3ea70eeSNaveen Manohar snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
312b3ea70eeSNaveen Manohar &constraints_channels);
313b3ea70eeSNaveen Manohar
314b3ea70eeSNaveen Manohar runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
315b3ea70eeSNaveen Manohar snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
316b3ea70eeSNaveen Manohar
317b3ea70eeSNaveen Manohar snd_pcm_hw_constraint_list(runtime, 0,
318b3ea70eeSNaveen Manohar SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
319b3ea70eeSNaveen Manohar
320b3ea70eeSNaveen Manohar return 0;
321b3ea70eeSNaveen Manohar }
322b3ea70eeSNaveen Manohar
323b3ea70eeSNaveen Manohar static const struct snd_soc_ops kabylake_da7219_fe_ops = {
324b3ea70eeSNaveen Manohar .startup = kbl_fe_startup,
325b3ea70eeSNaveen Manohar };
326b3ea70eeSNaveen Manohar
kabylake_dmic_fixup(struct snd_soc_pcm_runtime * rtd,struct snd_pcm_hw_params * params)327b3ea70eeSNaveen Manohar static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
328b3ea70eeSNaveen Manohar struct snd_pcm_hw_params *params)
329b3ea70eeSNaveen Manohar {
3302e539cf7SPierre-Louis Bossart struct snd_interval *chan = hw_param_interval(params,
331b3ea70eeSNaveen Manohar SNDRV_PCM_HW_PARAM_CHANNELS);
332b3ea70eeSNaveen Manohar
333b3ea70eeSNaveen Manohar /*
334b3ea70eeSNaveen Manohar * set BE channel constraint as user FE channels
335b3ea70eeSNaveen Manohar */
336b3ea70eeSNaveen Manohar
337b3ea70eeSNaveen Manohar if (params_channels(params) == 2)
3382e539cf7SPierre-Louis Bossart chan->min = chan->max = 2;
339b3ea70eeSNaveen Manohar else
3402e539cf7SPierre-Louis Bossart chan->min = chan->max = 4;
341b3ea70eeSNaveen Manohar
342b3ea70eeSNaveen Manohar return 0;
343b3ea70eeSNaveen Manohar }
344b3ea70eeSNaveen Manohar
kabylake_dmic_startup(struct snd_pcm_substream * substream)345b3ea70eeSNaveen Manohar static int kabylake_dmic_startup(struct snd_pcm_substream *substream)
346b3ea70eeSNaveen Manohar {
347b3ea70eeSNaveen Manohar struct snd_pcm_runtime *runtime = substream->runtime;
348b3ea70eeSNaveen Manohar
349b3ea70eeSNaveen Manohar runtime->hw.channels_min = runtime->hw.channels_max = QUAD_CHANNEL;
350b3ea70eeSNaveen Manohar snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
351b3ea70eeSNaveen Manohar &constraints_channels_quad);
352b3ea70eeSNaveen Manohar
353b3ea70eeSNaveen Manohar return snd_pcm_hw_constraint_list(substream->runtime, 0,
354b3ea70eeSNaveen Manohar SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
355b3ea70eeSNaveen Manohar }
356b3ea70eeSNaveen Manohar
357b3ea70eeSNaveen Manohar static struct snd_soc_ops kabylake_dmic_ops = {
358b3ea70eeSNaveen Manohar .startup = kabylake_dmic_startup,
359b3ea70eeSNaveen Manohar };
360b3ea70eeSNaveen Manohar
36174ed9e9bSMac Chiang static unsigned int rates_16000[] = {
36274ed9e9bSMac Chiang 16000,
36374ed9e9bSMac Chiang };
36474ed9e9bSMac Chiang
36574ed9e9bSMac Chiang static const struct snd_pcm_hw_constraint_list constraints_16000 = {
36674ed9e9bSMac Chiang .count = ARRAY_SIZE(rates_16000),
36774ed9e9bSMac Chiang .list = rates_16000,
36874ed9e9bSMac Chiang };
36974ed9e9bSMac Chiang
37074ed9e9bSMac Chiang static const unsigned int ch_mono[] = {
37174ed9e9bSMac Chiang 1,
37274ed9e9bSMac Chiang };
37374ed9e9bSMac Chiang
37474ed9e9bSMac Chiang static const struct snd_pcm_hw_constraint_list constraints_refcap = {
37574ed9e9bSMac Chiang .count = ARRAY_SIZE(ch_mono),
37674ed9e9bSMac Chiang .list = ch_mono,
37774ed9e9bSMac Chiang };
37874ed9e9bSMac Chiang
kabylake_refcap_startup(struct snd_pcm_substream * substream)37974ed9e9bSMac Chiang static int kabylake_refcap_startup(struct snd_pcm_substream *substream)
38074ed9e9bSMac Chiang {
38174ed9e9bSMac Chiang substream->runtime->hw.channels_max = 1;
38274ed9e9bSMac Chiang snd_pcm_hw_constraint_list(substream->runtime, 0,
38374ed9e9bSMac Chiang SNDRV_PCM_HW_PARAM_CHANNELS,
38474ed9e9bSMac Chiang &constraints_refcap);
38574ed9e9bSMac Chiang
38674ed9e9bSMac Chiang return snd_pcm_hw_constraint_list(substream->runtime, 0,
38774ed9e9bSMac Chiang SNDRV_PCM_HW_PARAM_RATE,
38874ed9e9bSMac Chiang &constraints_16000);
38974ed9e9bSMac Chiang }
39074ed9e9bSMac Chiang
39174ed9e9bSMac Chiang static struct snd_soc_ops skylake_refcap_ops = {
39274ed9e9bSMac Chiang .startup = kabylake_refcap_startup,
39374ed9e9bSMac Chiang };
39474ed9e9bSMac Chiang
39527eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(dummy,
39627eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_DUMMY()));
39727eb6c7cSKuninori Morimoto
39827eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(system,
39927eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("System Pin")));
40027eb6c7cSKuninori Morimoto
40174ed9e9bSMac Chiang SND_SOC_DAILINK_DEF(reference,
40274ed9e9bSMac Chiang DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin")));
40374ed9e9bSMac Chiang
40427eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(dmic,
40527eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin")));
40627eb6c7cSKuninori Morimoto
40727eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(hdmi1,
40827eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin")));
40927eb6c7cSKuninori Morimoto
41027eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(hdmi2,
41127eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin")));
41227eb6c7cSKuninori Morimoto
41327eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(hdmi3,
41427eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin")));
41527eb6c7cSKuninori Morimoto
41627eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(ssp0_pin,
41727eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin")));
41827eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(ssp0_codec,
41927eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CODEC(MAXIM_DEV0_NAME,
42027eb6c7cSKuninori Morimoto KBL_MAXIM_CODEC_DAI)));
42127eb6c7cSKuninori Morimoto
42227eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(ssp1_pin,
42327eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin")));
42427eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(ssp1_codec,
42527eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00",
42627eb6c7cSKuninori Morimoto KBL_DIALOG_CODEC_DAI)));
42727eb6c7cSKuninori Morimoto
42827eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(dmic_pin,
42927eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin")));
43027eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(dmic_codec,
43127eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
43227eb6c7cSKuninori Morimoto
43327eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(idisp1_pin,
43427eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin")));
43527eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(idisp1_codec,
43627eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2",
43727eb6c7cSKuninori Morimoto "intel-hdmi-hifi1")));
43827eb6c7cSKuninori Morimoto
43927eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(idisp2_pin,
44027eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin")));
44127eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(idisp2_codec,
44227eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2")));
44327eb6c7cSKuninori Morimoto
44427eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(idisp3_pin,
44527eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin")));
44627eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(idisp3_codec,
44727eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3")));
44827eb6c7cSKuninori Morimoto
44927eb6c7cSKuninori Morimoto SND_SOC_DAILINK_DEF(platform,
45027eb6c7cSKuninori Morimoto DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3")));
45127eb6c7cSKuninori Morimoto
452b3ea70eeSNaveen Manohar /* kabylake digital audio interface glue - connects codec <--> CPU */
453b3ea70eeSNaveen Manohar static struct snd_soc_dai_link kabylake_dais[] = {
454b3ea70eeSNaveen Manohar /* Front End DAI links */
455b3ea70eeSNaveen Manohar [KBL_DPCM_AUDIO_PB] = {
456b3ea70eeSNaveen Manohar .name = "Kbl Audio Port",
457b3ea70eeSNaveen Manohar .stream_name = "Audio",
458b3ea70eeSNaveen Manohar .dynamic = 1,
459b3ea70eeSNaveen Manohar .nonatomic = 1,
460b3ea70eeSNaveen Manohar .init = kabylake_da7219_fe_init,
461b3ea70eeSNaveen Manohar .trigger = {
462b3ea70eeSNaveen Manohar SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
463b3ea70eeSNaveen Manohar .dpcm_playback = 1,
464b3ea70eeSNaveen Manohar .ops = &kabylake_da7219_fe_ops,
46527eb6c7cSKuninori Morimoto SND_SOC_DAILINK_REG(system, dummy, platform),
466b3ea70eeSNaveen Manohar },
467b3ea70eeSNaveen Manohar [KBL_DPCM_AUDIO_CP] = {
468b3ea70eeSNaveen Manohar .name = "Kbl Audio Capture Port",
469b3ea70eeSNaveen Manohar .stream_name = "Audio Record",
470b3ea70eeSNaveen Manohar .dynamic = 1,
471b3ea70eeSNaveen Manohar .nonatomic = 1,
472b3ea70eeSNaveen Manohar .trigger = {
473b3ea70eeSNaveen Manohar SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
474b3ea70eeSNaveen Manohar .dpcm_capture = 1,
4755fd46e64SMac Chiang .ops = &kabylake_da7219_fe_ops,
47627eb6c7cSKuninori Morimoto SND_SOC_DAILINK_REG(system, dummy, platform),
477b3ea70eeSNaveen Manohar },
47874ed9e9bSMac Chiang [KBL_DPCM_AUDIO_REF_CP] = {
47974ed9e9bSMac Chiang .name = "Kbl Audio Reference cap",
48074ed9e9bSMac Chiang .stream_name = "Wake on Voice",
48174ed9e9bSMac Chiang .init = NULL,
48274ed9e9bSMac Chiang .dpcm_capture = 1,
48374ed9e9bSMac Chiang .nonatomic = 1,
48474ed9e9bSMac Chiang .dynamic = 1,
48574ed9e9bSMac Chiang .ops = &skylake_refcap_ops,
48674ed9e9bSMac Chiang SND_SOC_DAILINK_REG(reference, dummy, platform),
48774ed9e9bSMac Chiang },
488b3ea70eeSNaveen Manohar [KBL_DPCM_AUDIO_DMIC_CP] = {
489b3ea70eeSNaveen Manohar .name = "Kbl Audio DMIC cap",
490b3ea70eeSNaveen Manohar .stream_name = "dmiccap",
491b3ea70eeSNaveen Manohar .init = NULL,
492b3ea70eeSNaveen Manohar .dpcm_capture = 1,
493b3ea70eeSNaveen Manohar .nonatomic = 1,
494b3ea70eeSNaveen Manohar .dynamic = 1,
495b3ea70eeSNaveen Manohar .ops = &kabylake_dmic_ops,
49627eb6c7cSKuninori Morimoto SND_SOC_DAILINK_REG(dmic, dummy, platform),
497b3ea70eeSNaveen Manohar },
498b3ea70eeSNaveen Manohar [KBL_DPCM_AUDIO_HDMI1_PB] = {
499b3ea70eeSNaveen Manohar .name = "Kbl HDMI Port1",
500b3ea70eeSNaveen Manohar .stream_name = "Hdmi1",
501b3ea70eeSNaveen Manohar .dpcm_playback = 1,
502b3ea70eeSNaveen Manohar .init = NULL,
503b3ea70eeSNaveen Manohar .trigger = {
504b3ea70eeSNaveen Manohar SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
505b3ea70eeSNaveen Manohar .nonatomic = 1,
506b3ea70eeSNaveen Manohar .dynamic = 1,
50727eb6c7cSKuninori Morimoto SND_SOC_DAILINK_REG(hdmi1, dummy, platform),
508b3ea70eeSNaveen Manohar },
509b3ea70eeSNaveen Manohar [KBL_DPCM_AUDIO_HDMI2_PB] = {
510b3ea70eeSNaveen Manohar .name = "Kbl HDMI Port2",
511b3ea70eeSNaveen Manohar .stream_name = "Hdmi2",
512b3ea70eeSNaveen Manohar .dpcm_playback = 1,
513b3ea70eeSNaveen Manohar .init = NULL,
514b3ea70eeSNaveen Manohar .trigger = {
515b3ea70eeSNaveen Manohar SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
516b3ea70eeSNaveen Manohar .nonatomic = 1,
517b3ea70eeSNaveen Manohar .dynamic = 1,
51827eb6c7cSKuninori Morimoto SND_SOC_DAILINK_REG(hdmi2, dummy, platform),
519b3ea70eeSNaveen Manohar },
520b3ea70eeSNaveen Manohar [KBL_DPCM_AUDIO_HDMI3_PB] = {
521b3ea70eeSNaveen Manohar .name = "Kbl HDMI Port3",
522b3ea70eeSNaveen Manohar .stream_name = "Hdmi3",
523b3ea70eeSNaveen Manohar .trigger = {
524b3ea70eeSNaveen Manohar SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
525b3ea70eeSNaveen Manohar .dpcm_playback = 1,
526b3ea70eeSNaveen Manohar .init = NULL,
527b3ea70eeSNaveen Manohar .nonatomic = 1,
528b3ea70eeSNaveen Manohar .dynamic = 1,
52927eb6c7cSKuninori Morimoto SND_SOC_DAILINK_REG(hdmi3, dummy, platform),
530b3ea70eeSNaveen Manohar },
531b3ea70eeSNaveen Manohar
532b3ea70eeSNaveen Manohar /* Back End DAI links */
533b3ea70eeSNaveen Manohar {
534b3ea70eeSNaveen Manohar /* SSP0 - Codec */
535b3ea70eeSNaveen Manohar .name = "SSP0-Codec",
536b3ea70eeSNaveen Manohar .id = 0,
537b3ea70eeSNaveen Manohar .no_pcm = 1,
538b3ea70eeSNaveen Manohar .dai_fmt = SND_SOC_DAIFMT_I2S |
539b3ea70eeSNaveen Manohar SND_SOC_DAIFMT_NB_NF |
5405374b921SPeter Ujfalusi SND_SOC_DAIFMT_CBC_CFC,
541b3ea70eeSNaveen Manohar .ignore_pmdown_time = 1,
542b3ea70eeSNaveen Manohar .be_hw_params_fixup = kabylake_ssp_fixup,
543b3ea70eeSNaveen Manohar .dpcm_playback = 1,
54427eb6c7cSKuninori Morimoto SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec, platform),
545b3ea70eeSNaveen Manohar },
546b3ea70eeSNaveen Manohar {
547b3ea70eeSNaveen Manohar /* SSP1 - Codec */
548b3ea70eeSNaveen Manohar .name = "SSP1-Codec",
549b3ea70eeSNaveen Manohar .id = 1,
550b3ea70eeSNaveen Manohar .no_pcm = 1,
551b3ea70eeSNaveen Manohar .init = kabylake_da7219_codec_init,
552b3ea70eeSNaveen Manohar .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
5535374b921SPeter Ujfalusi SND_SOC_DAIFMT_CBC_CFC,
554b3ea70eeSNaveen Manohar .ignore_pmdown_time = 1,
555b3ea70eeSNaveen Manohar .be_hw_params_fixup = kabylake_ssp_fixup,
556b3ea70eeSNaveen Manohar .dpcm_playback = 1,
557b3ea70eeSNaveen Manohar .dpcm_capture = 1,
55827eb6c7cSKuninori Morimoto SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform),
559b3ea70eeSNaveen Manohar },
560b3ea70eeSNaveen Manohar {
561b3ea70eeSNaveen Manohar .name = "dmic01",
562b3ea70eeSNaveen Manohar .id = 2,
563b3ea70eeSNaveen Manohar .be_hw_params_fixup = kabylake_dmic_fixup,
564b3ea70eeSNaveen Manohar .ignore_suspend = 1,
565b3ea70eeSNaveen Manohar .dpcm_capture = 1,
566b3ea70eeSNaveen Manohar .no_pcm = 1,
56727eb6c7cSKuninori Morimoto SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform),
568b3ea70eeSNaveen Manohar },
569b3ea70eeSNaveen Manohar {
570b3ea70eeSNaveen Manohar .name = "iDisp1",
571b3ea70eeSNaveen Manohar .id = 3,
572b3ea70eeSNaveen Manohar .dpcm_playback = 1,
573b3ea70eeSNaveen Manohar .init = kabylake_hdmi1_init,
574b3ea70eeSNaveen Manohar .no_pcm = 1,
57527eb6c7cSKuninori Morimoto SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform),
576b3ea70eeSNaveen Manohar },
577b3ea70eeSNaveen Manohar {
578b3ea70eeSNaveen Manohar .name = "iDisp2",
579b3ea70eeSNaveen Manohar .id = 4,
580b3ea70eeSNaveen Manohar .init = kabylake_hdmi2_init,
581b3ea70eeSNaveen Manohar .dpcm_playback = 1,
582b3ea70eeSNaveen Manohar .no_pcm = 1,
58327eb6c7cSKuninori Morimoto SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform),
584b3ea70eeSNaveen Manohar },
585b3ea70eeSNaveen Manohar {
586b3ea70eeSNaveen Manohar .name = "iDisp3",
587b3ea70eeSNaveen Manohar .id = 5,
588b3ea70eeSNaveen Manohar .init = kabylake_hdmi3_init,
589b3ea70eeSNaveen Manohar .dpcm_playback = 1,
590b3ea70eeSNaveen Manohar .no_pcm = 1,
59127eb6c7cSKuninori Morimoto SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform),
592b3ea70eeSNaveen Manohar },
593b3ea70eeSNaveen Manohar };
594b3ea70eeSNaveen Manohar
595b3ea70eeSNaveen Manohar #define NAME_SIZE 32
kabylake_card_late_probe(struct snd_soc_card * card)596b3ea70eeSNaveen Manohar static int kabylake_card_late_probe(struct snd_soc_card *card)
597b3ea70eeSNaveen Manohar {
598b3ea70eeSNaveen Manohar struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
599b3ea70eeSNaveen Manohar struct kbl_hdmi_pcm *pcm;
600257aacebSKuninori Morimoto struct snd_soc_component *component = NULL;
601b3ea70eeSNaveen Manohar int err, i = 0;
602b3ea70eeSNaveen Manohar char jack_name[NAME_SIZE];
603b3ea70eeSNaveen Manohar
604b3ea70eeSNaveen Manohar list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
605257aacebSKuninori Morimoto component = pcm->codec_dai->component;
606b3ea70eeSNaveen Manohar snprintf(jack_name, sizeof(jack_name),
607b3ea70eeSNaveen Manohar "HDMI/DP, pcm=%d Jack", pcm->device);
608b3ea70eeSNaveen Manohar err = snd_soc_card_jack_new(card, jack_name,
60919aed2d6SAkihiko Odaki SND_JACK_AVOUT, &skylake_hdmi[i]);
610b3ea70eeSNaveen Manohar
611b3ea70eeSNaveen Manohar if (err)
612b3ea70eeSNaveen Manohar return err;
613b3ea70eeSNaveen Manohar
614b3ea70eeSNaveen Manohar err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
615b3ea70eeSNaveen Manohar &skylake_hdmi[i]);
616b3ea70eeSNaveen Manohar if (err < 0)
617b3ea70eeSNaveen Manohar return err;
618b3ea70eeSNaveen Manohar
619b3ea70eeSNaveen Manohar i++;
620b3ea70eeSNaveen Manohar
621b3ea70eeSNaveen Manohar }
622b3ea70eeSNaveen Manohar
623257aacebSKuninori Morimoto if (!component)
624b3ea70eeSNaveen Manohar return -EINVAL;
625b3ea70eeSNaveen Manohar
626257aacebSKuninori Morimoto return hdac_hdmi_jack_port_init(component, &card->dapm);
627b3ea70eeSNaveen Manohar }
628b3ea70eeSNaveen Manohar
629b3ea70eeSNaveen Manohar /* kabylake audio machine driver for SPT + DA7219 */
630b3ea70eeSNaveen Manohar static struct snd_soc_card kabylake_audio_card_da7219_m98357a = {
631b3ea70eeSNaveen Manohar .name = "kblda7219max",
632b3ea70eeSNaveen Manohar .owner = THIS_MODULE,
633b3ea70eeSNaveen Manohar .dai_link = kabylake_dais,
634b3ea70eeSNaveen Manohar .num_links = ARRAY_SIZE(kabylake_dais),
635b3ea70eeSNaveen Manohar .controls = kabylake_controls,
636b3ea70eeSNaveen Manohar .num_controls = ARRAY_SIZE(kabylake_controls),
637b3ea70eeSNaveen Manohar .dapm_widgets = kabylake_widgets,
638b3ea70eeSNaveen Manohar .num_dapm_widgets = ARRAY_SIZE(kabylake_widgets),
639b3ea70eeSNaveen Manohar .dapm_routes = kabylake_map,
640b3ea70eeSNaveen Manohar .num_dapm_routes = ARRAY_SIZE(kabylake_map),
641b3ea70eeSNaveen Manohar .fully_routed = true,
642*48f3fe13SCezary Rojewski .disable_route_checks = true,
643b3ea70eeSNaveen Manohar .late_probe = kabylake_card_late_probe,
644b3ea70eeSNaveen Manohar };
645b3ea70eeSNaveen Manohar
kabylake_audio_probe(struct platform_device * pdev)646b3ea70eeSNaveen Manohar static int kabylake_audio_probe(struct platform_device *pdev)
647b3ea70eeSNaveen Manohar {
648b3ea70eeSNaveen Manohar struct kbl_codec_private *ctx;
649b3ea70eeSNaveen Manohar
6503069db24SVinod Koul ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
651b3ea70eeSNaveen Manohar if (!ctx)
652b3ea70eeSNaveen Manohar return -ENOMEM;
653b3ea70eeSNaveen Manohar
654b3ea70eeSNaveen Manohar INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
655b3ea70eeSNaveen Manohar
656b3ea70eeSNaveen Manohar kabylake_audio_card =
657b3ea70eeSNaveen Manohar (struct snd_soc_card *)pdev->id_entry->driver_data;
658b3ea70eeSNaveen Manohar
659b3ea70eeSNaveen Manohar kabylake_audio_card->dev = &pdev->dev;
660b3ea70eeSNaveen Manohar snd_soc_card_set_drvdata(kabylake_audio_card, ctx);
661b3ea70eeSNaveen Manohar return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card);
662b3ea70eeSNaveen Manohar }
663b3ea70eeSNaveen Manohar
664b3ea70eeSNaveen Manohar static const struct platform_device_id kbl_board_ids[] = {
665b3ea70eeSNaveen Manohar {
66694efd726SPierre-Louis Bossart .name = "kbl_da7219_mx98357a",
667b3ea70eeSNaveen Manohar .driver_data =
668b3ea70eeSNaveen Manohar (kernel_ulong_t)&kabylake_audio_card_da7219_m98357a,
669b3ea70eeSNaveen Manohar },
670b3ea70eeSNaveen Manohar { }
671b3ea70eeSNaveen Manohar };
67253b98536SPierre-Louis Bossart MODULE_DEVICE_TABLE(platform, kbl_board_ids);
673b3ea70eeSNaveen Manohar
674b3ea70eeSNaveen Manohar static struct platform_driver kabylake_audio = {
675b3ea70eeSNaveen Manohar .probe = kabylake_audio_probe,
676b3ea70eeSNaveen Manohar .driver = {
677b3ea70eeSNaveen Manohar .name = "kbl_da7219_max98357a",
678b3ea70eeSNaveen Manohar .pm = &snd_soc_pm_ops,
679b3ea70eeSNaveen Manohar },
680b3ea70eeSNaveen Manohar .id_table = kbl_board_ids,
681b3ea70eeSNaveen Manohar };
682b3ea70eeSNaveen Manohar
683b3ea70eeSNaveen Manohar module_platform_driver(kabylake_audio)
684b3ea70eeSNaveen Manohar
685b3ea70eeSNaveen Manohar /* Module information */
686b3ea70eeSNaveen Manohar MODULE_DESCRIPTION("Audio Machine driver-DA7219 & MAX98357A in I2S mode");
687b3ea70eeSNaveen Manohar MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>");
688b3ea70eeSNaveen Manohar MODULE_LICENSE("GPL v2");
689