Commit | Line | Data |
---|---|---|
1802d0be | 1 | // SPDX-License-Identifier: GPL-2.0-only |
624729fd OA |
2 | /* |
3 | * Intel Skylake I2S Machine Driver | |
4 | * | |
5 | * Copyright (C) 2014-2015, Intel Corporation. All rights reserved. | |
6 | * | |
7 | * Modified from: | |
8 | * Intel Broadwell Wildcatpoint SST Audio | |
9 | * | |
10 | * Copyright (C) 2013, Intel Corporation. All rights reserved. | |
624729fd OA |
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/jack.h> | |
19 | #include <sound/pcm_params.h> | |
20 | #include "../../codecs/rt286.h" | |
23905cd1 | 21 | #include "../../codecs/hdac_hdmi.h" |
624729fd OA |
22 | |
23 | static struct snd_soc_jack skylake_headset; | |
f3af3592 | 24 | static struct snd_soc_jack skylake_hdmi[3]; |
23905cd1 | 25 | |
1a10612f SP |
26 | struct skl_hdmi_pcm { |
27 | struct list_head head; | |
28 | struct snd_soc_dai *codec_dai; | |
29 | int device; | |
30 | }; | |
31 | ||
32 | struct skl_rt286_private { | |
33 | struct list_head hdmi_pcm_list; | |
34 | }; | |
35 | ||
23905cd1 JK |
36 | enum { |
37 | SKL_DPCM_AUDIO_PB = 0, | |
1f0f8bde | 38 | SKL_DPCM_AUDIO_DB_PB, |
23905cd1 JK |
39 | SKL_DPCM_AUDIO_CP, |
40 | SKL_DPCM_AUDIO_REF_CP, | |
41 | SKL_DPCM_AUDIO_DMIC_CP, | |
42 | SKL_DPCM_AUDIO_HDMI1_PB, | |
43 | SKL_DPCM_AUDIO_HDMI2_PB, | |
44 | SKL_DPCM_AUDIO_HDMI3_PB, | |
45 | }; | |
46 | ||
624729fd OA |
47 | /* Headset jack detection DAPM pins */ |
48 | static struct snd_soc_jack_pin skylake_headset_pins[] = { | |
49 | { | |
50 | .pin = "Mic Jack", | |
51 | .mask = SND_JACK_MICROPHONE, | |
52 | }, | |
53 | { | |
54 | .pin = "Headphone Jack", | |
55 | .mask = SND_JACK_HEADPHONE, | |
56 | }, | |
57 | }; | |
58 | ||
59 | static const struct snd_kcontrol_new skylake_controls[] = { | |
60 | SOC_DAPM_PIN_SWITCH("Speaker"), | |
61 | SOC_DAPM_PIN_SWITCH("Headphone Jack"), | |
62 | SOC_DAPM_PIN_SWITCH("Mic Jack"), | |
63 | }; | |
64 | ||
65 | static const struct snd_soc_dapm_widget skylake_widgets[] = { | |
66 | SND_SOC_DAPM_HP("Headphone Jack", NULL), | |
67 | SND_SOC_DAPM_SPK("Speaker", NULL), | |
68 | SND_SOC_DAPM_MIC("Mic Jack", NULL), | |
69 | SND_SOC_DAPM_MIC("DMIC2", NULL), | |
70 | SND_SOC_DAPM_MIC("SoC DMIC", NULL), | |
23905cd1 JK |
71 | SND_SOC_DAPM_SPK("HDMI1", NULL), |
72 | SND_SOC_DAPM_SPK("HDMI2", NULL), | |
73 | SND_SOC_DAPM_SPK("HDMI3", NULL), | |
624729fd OA |
74 | }; |
75 | ||
76 | static const struct snd_soc_dapm_route skylake_rt286_map[] = { | |
77 | /* speaker */ | |
78 | {"Speaker", NULL, "SPOR"}, | |
79 | {"Speaker", NULL, "SPOL"}, | |
80 | ||
81 | /* HP jack connectors - unknown if we have jack deteck */ | |
82 | {"Headphone Jack", NULL, "HPO Pin"}, | |
83 | ||
84 | /* other jacks */ | |
85 | {"MIC1", NULL, "Mic Jack"}, | |
86 | ||
87 | /* digital mics */ | |
88 | {"DMIC1 Pin", NULL, "DMIC2"}, | |
820f339f | 89 | {"DMic", NULL, "SoC DMIC"}, |
624729fd OA |
90 | |
91 | /* CODEC BE connections */ | |
92 | { "AIF1 Playback", NULL, "ssp0 Tx"}, | |
93 | { "ssp0 Tx", NULL, "codec0_out"}, | |
94 | { "ssp0 Tx", NULL, "codec1_out"}, | |
95 | ||
96 | { "codec0_in", NULL, "ssp0 Rx" }, | |
97 | { "codec1_in", NULL, "ssp0 Rx" }, | |
98 | { "ssp0 Rx", NULL, "AIF1 Capture" }, | |
99 | ||
100 | { "dmic01_hifi", NULL, "DMIC01 Rx" }, | |
820f339f | 101 | { "DMIC01 Rx", NULL, "DMIC AIF" }, |
624729fd | 102 | |
23905cd1 JK |
103 | { "hifi3", NULL, "iDisp3 Tx"}, |
104 | { "iDisp3 Tx", NULL, "iDisp3_out"}, | |
105 | { "hifi2", NULL, "iDisp2 Tx"}, | |
106 | { "iDisp2 Tx", NULL, "iDisp2_out"}, | |
107 | { "hifi1", NULL, "iDisp1 Tx"}, | |
108 | { "iDisp1 Tx", NULL, "iDisp1_out"}, | |
624729fd OA |
109 | |
110 | }; | |
111 | ||
9ec2053b PD |
112 | static int skylake_rt286_fe_init(struct snd_soc_pcm_runtime *rtd) |
113 | { | |
114 | struct snd_soc_dapm_context *dapm; | |
115 | struct snd_soc_component *component = rtd->cpu_dai->component; | |
116 | ||
117 | dapm = snd_soc_component_get_dapm(component); | |
118 | snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); | |
119 | ||
120 | return 0; | |
121 | } | |
122 | ||
624729fd OA |
123 | static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) |
124 | { | |
45101122 | 125 | struct snd_soc_component *component = rtd->codec_dai->component; |
624729fd OA |
126 | int ret; |
127 | ||
128 | ret = snd_soc_card_jack_new(rtd->card, "Headset", | |
129 | SND_JACK_HEADSET | SND_JACK_BTN_0, | |
130 | &skylake_headset, | |
131 | skylake_headset_pins, ARRAY_SIZE(skylake_headset_pins)); | |
132 | ||
133 | if (ret) | |
134 | return ret; | |
135 | ||
45101122 | 136 | rt286_mic_detect(component, &skylake_headset); |
624729fd | 137 | |
9ec2053b | 138 | snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); |
9ec2053b | 139 | |
624729fd OA |
140 | return 0; |
141 | } | |
142 | ||
23905cd1 JK |
143 | static int skylake_hdmi_init(struct snd_soc_pcm_runtime *rtd) |
144 | { | |
1a10612f | 145 | struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(rtd->card); |
23905cd1 | 146 | struct snd_soc_dai *dai = rtd->codec_dai; |
1a10612f SP |
147 | struct skl_hdmi_pcm *pcm; |
148 | ||
149 | pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); | |
150 | if (!pcm) | |
151 | return -ENOMEM; | |
23905cd1 | 152 | |
1a10612f SP |
153 | pcm->device = SKL_DPCM_AUDIO_HDMI1_PB + dai->id; |
154 | pcm->codec_dai = dai; | |
155 | ||
156 | list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); | |
157 | ||
158 | return 0; | |
23905cd1 JK |
159 | } |
160 | ||
617647ae | 161 | static const unsigned int rates[] = { |
5eab6ab9 VK |
162 | 48000, |
163 | }; | |
164 | ||
617647ae | 165 | static const struct snd_pcm_hw_constraint_list constraints_rates = { |
5eab6ab9 VK |
166 | .count = ARRAY_SIZE(rates), |
167 | .list = rates, | |
168 | .mask = 0, | |
169 | }; | |
170 | ||
617647ae | 171 | static const unsigned int channels[] = { |
5eab6ab9 VK |
172 | 2, |
173 | }; | |
174 | ||
617647ae | 175 | static const struct snd_pcm_hw_constraint_list constraints_channels = { |
5eab6ab9 VK |
176 | .count = ARRAY_SIZE(channels), |
177 | .list = channels, | |
178 | .mask = 0, | |
179 | }; | |
180 | ||
181 | static int skl_fe_startup(struct snd_pcm_substream *substream) | |
182 | { | |
183 | struct snd_pcm_runtime *runtime = substream->runtime; | |
184 | ||
185 | /* | |
186 | * on this platform for PCM device we support, | |
187 | * 48Khz | |
188 | * stereo | |
189 | * 16 bit audio | |
190 | */ | |
191 | ||
192 | runtime->hw.channels_max = 2; | |
193 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | |
194 | &constraints_channels); | |
195 | ||
196 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; | |
197 | snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); | |
198 | ||
199 | snd_pcm_hw_constraint_list(runtime, 0, | |
200 | SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); | |
201 | ||
202 | return 0; | |
203 | } | |
204 | ||
205 | static const struct snd_soc_ops skylake_rt286_fe_ops = { | |
206 | .startup = skl_fe_startup, | |
207 | }; | |
624729fd OA |
208 | |
209 | static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, | |
210 | struct snd_pcm_hw_params *params) | |
211 | { | |
212 | struct snd_interval *rate = hw_param_interval(params, | |
213 | SNDRV_PCM_HW_PARAM_RATE); | |
214 | struct snd_interval *channels = hw_param_interval(params, | |
215 | SNDRV_PCM_HW_PARAM_CHANNELS); | |
677165f7 | 216 | struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); |
624729fd OA |
217 | |
218 | /* The output is 48KHz, stereo, 16bits */ | |
219 | rate->min = rate->max = 48000; | |
220 | channels->min = channels->max = 2; | |
624729fd | 221 | |
677165f7 JK |
222 | /* set SSP0 to 24 bit */ |
223 | snd_mask_none(fmt); | |
b5453e8c | 224 | snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); |
624729fd OA |
225 | return 0; |
226 | } | |
227 | ||
228 | static int skylake_rt286_hw_params(struct snd_pcm_substream *substream, | |
229 | struct snd_pcm_hw_params *params) | |
230 | { | |
231 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
232 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | |
233 | int ret; | |
234 | ||
235 | ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000, | |
236 | SND_SOC_CLOCK_IN); | |
237 | if (ret < 0) | |
238 | dev_err(rtd->dev, "set codec sysclk failed: %d\n", ret); | |
239 | ||
240 | return ret; | |
241 | } | |
242 | ||
9b6fdef6 | 243 | static const struct snd_soc_ops skylake_rt286_ops = { |
624729fd OA |
244 | .hw_params = skylake_rt286_hw_params, |
245 | }; | |
246 | ||
4386b767 JK |
247 | static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, |
248 | struct snd_pcm_hw_params *params) | |
249 | { | |
250 | struct snd_interval *channels = hw_param_interval(params, | |
251 | SNDRV_PCM_HW_PARAM_CHANNELS); | |
6e3ffa00 JK |
252 | if (params_channels(params) == 2) |
253 | channels->min = channels->max = 2; | |
254 | else | |
255 | channels->min = channels->max = 4; | |
4386b767 JK |
256 | |
257 | return 0; | |
258 | } | |
259 | ||
617647ae | 260 | static const unsigned int channels_dmic[] = { |
4386b767 JK |
261 | 2, 4, |
262 | }; | |
263 | ||
617647ae | 264 | static const struct snd_pcm_hw_constraint_list constraints_dmic_channels = { |
4386b767 JK |
265 | .count = ARRAY_SIZE(channels_dmic), |
266 | .list = channels_dmic, | |
267 | .mask = 0, | |
268 | }; | |
269 | ||
270 | static int skylake_dmic_startup(struct snd_pcm_substream *substream) | |
271 | { | |
272 | struct snd_pcm_runtime *runtime = substream->runtime; | |
273 | ||
274 | runtime->hw.channels_max = 4; | |
275 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | |
276 | &constraints_dmic_channels); | |
277 | ||
278 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | |
279 | SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); | |
280 | } | |
281 | ||
9b6fdef6 | 282 | static const struct snd_soc_ops skylake_dmic_ops = { |
4386b767 JK |
283 | .startup = skylake_dmic_startup, |
284 | }; | |
285 | ||
624729fd OA |
286 | /* skylake digital audio interface glue - connects codec <--> CPU */ |
287 | static struct snd_soc_dai_link skylake_rt286_dais[] = { | |
288 | /* Front End DAI links */ | |
23905cd1 | 289 | [SKL_DPCM_AUDIO_PB] = { |
624729fd OA |
290 | .name = "Skl Audio Port", |
291 | .stream_name = "Audio", | |
292 | .cpu_dai_name = "System Pin", | |
293 | .platform_name = "0000:00:1f.3", | |
294 | .nonatomic = 1, | |
295 | .dynamic = 1, | |
296 | .codec_name = "snd-soc-dummy", | |
297 | .codec_dai_name = "snd-soc-dummy-dai", | |
9ec2053b | 298 | .init = skylake_rt286_fe_init, |
624729fd OA |
299 | .trigger = { |
300 | SND_SOC_DPCM_TRIGGER_POST, | |
301 | SND_SOC_DPCM_TRIGGER_POST | |
302 | }, | |
303 | .dpcm_playback = 1, | |
5eab6ab9 | 304 | .ops = &skylake_rt286_fe_ops, |
624729fd | 305 | }, |
1f0f8bde SP |
306 | [SKL_DPCM_AUDIO_DB_PB] = { |
307 | .name = "Skl Deepbuffer Port", | |
308 | .stream_name = "Deep Buffer Audio", | |
309 | .cpu_dai_name = "Deepbuffer Pin", | |
310 | .platform_name = "0000:00:1f.3", | |
311 | .nonatomic = 1, | |
312 | .dynamic = 1, | |
313 | .codec_name = "snd-soc-dummy", | |
314 | .codec_dai_name = "snd-soc-dummy-dai", | |
315 | .trigger = { | |
316 | SND_SOC_DPCM_TRIGGER_POST, | |
317 | SND_SOC_DPCM_TRIGGER_POST | |
318 | }, | |
319 | .dpcm_playback = 1, | |
320 | .ops = &skylake_rt286_fe_ops, | |
321 | ||
322 | }, | |
23905cd1 | 323 | [SKL_DPCM_AUDIO_CP] = { |
624729fd OA |
324 | .name = "Skl Audio Capture Port", |
325 | .stream_name = "Audio Record", | |
326 | .cpu_dai_name = "System Pin", | |
327 | .platform_name = "0000:00:1f.3", | |
328 | .nonatomic = 1, | |
329 | .dynamic = 1, | |
330 | .codec_name = "snd-soc-dummy", | |
331 | .codec_dai_name = "snd-soc-dummy-dai", | |
332 | .trigger = { | |
333 | SND_SOC_DPCM_TRIGGER_POST, | |
334 | SND_SOC_DPCM_TRIGGER_POST | |
335 | }, | |
336 | .dpcm_capture = 1, | |
5eab6ab9 | 337 | .ops = &skylake_rt286_fe_ops, |
624729fd | 338 | }, |
23905cd1 | 339 | [SKL_DPCM_AUDIO_REF_CP] = { |
624729fd OA |
340 | .name = "Skl Audio Reference cap", |
341 | .stream_name = "refcap", | |
342 | .cpu_dai_name = "Reference Pin", | |
343 | .codec_name = "snd-soc-dummy", | |
344 | .codec_dai_name = "snd-soc-dummy-dai", | |
345 | .platform_name = "0000:00:1f.3", | |
346 | .init = NULL, | |
347 | .dpcm_capture = 1, | |
624729fd OA |
348 | .nonatomic = 1, |
349 | .dynamic = 1, | |
350 | }, | |
23905cd1 | 351 | [SKL_DPCM_AUDIO_DMIC_CP] = { |
4386b767 JK |
352 | .name = "Skl Audio DMIC cap", |
353 | .stream_name = "dmiccap", | |
354 | .cpu_dai_name = "DMIC Pin", | |
355 | .codec_name = "snd-soc-dummy", | |
356 | .codec_dai_name = "snd-soc-dummy-dai", | |
357 | .platform_name = "0000:00:1f.3", | |
358 | .init = NULL, | |
359 | .dpcm_capture = 1, | |
4386b767 JK |
360 | .nonatomic = 1, |
361 | .dynamic = 1, | |
362 | .ops = &skylake_dmic_ops, | |
363 | }, | |
23905cd1 JK |
364 | [SKL_DPCM_AUDIO_HDMI1_PB] = { |
365 | .name = "Skl HDMI Port1", | |
366 | .stream_name = "Hdmi1", | |
367 | .cpu_dai_name = "HDMI1 Pin", | |
368 | .codec_name = "snd-soc-dummy", | |
369 | .codec_dai_name = "snd-soc-dummy-dai", | |
370 | .platform_name = "0000:00:1f.3", | |
371 | .dpcm_playback = 1, | |
372 | .init = NULL, | |
373 | .nonatomic = 1, | |
374 | .dynamic = 1, | |
375 | }, | |
376 | [SKL_DPCM_AUDIO_HDMI2_PB] = { | |
377 | .name = "Skl HDMI Port2", | |
378 | .stream_name = "Hdmi2", | |
379 | .cpu_dai_name = "HDMI2 Pin", | |
380 | .codec_name = "snd-soc-dummy", | |
381 | .codec_dai_name = "snd-soc-dummy-dai", | |
382 | .platform_name = "0000:00:1f.3", | |
383 | .dpcm_playback = 1, | |
384 | .init = NULL, | |
385 | .nonatomic = 1, | |
386 | .dynamic = 1, | |
387 | }, | |
388 | [SKL_DPCM_AUDIO_HDMI3_PB] = { | |
389 | .name = "Skl HDMI Port3", | |
390 | .stream_name = "Hdmi3", | |
391 | .cpu_dai_name = "HDMI3 Pin", | |
392 | .codec_name = "snd-soc-dummy", | |
393 | .codec_dai_name = "snd-soc-dummy-dai", | |
394 | .platform_name = "0000:00:1f.3", | |
395 | .dpcm_playback = 1, | |
396 | .init = NULL, | |
397 | .nonatomic = 1, | |
398 | .dynamic = 1, | |
399 | }, | |
624729fd OA |
400 | |
401 | /* Back End DAI links */ | |
402 | { | |
403 | /* SSP0 - Codec */ | |
404 | .name = "SSP0-Codec", | |
2f0ad491 | 405 | .id = 0, |
624729fd OA |
406 | .cpu_dai_name = "SSP0 Pin", |
407 | .platform_name = "0000:00:1f.3", | |
408 | .no_pcm = 1, | |
409 | .codec_name = "i2c-INT343A:00", | |
410 | .codec_dai_name = "rt286-aif1", | |
411 | .init = skylake_rt286_codec_init, | |
412 | .dai_fmt = SND_SOC_DAIFMT_I2S | | |
413 | SND_SOC_DAIFMT_NB_NF | | |
414 | SND_SOC_DAIFMT_CBS_CFS, | |
624729fd OA |
415 | .ignore_pmdown_time = 1, |
416 | .be_hw_params_fixup = skylake_ssp0_fixup, | |
417 | .ops = &skylake_rt286_ops, | |
418 | .dpcm_playback = 1, | |
419 | .dpcm_capture = 1, | |
420 | }, | |
421 | { | |
422 | .name = "dmic01", | |
2f0ad491 | 423 | .id = 1, |
624729fd OA |
424 | .cpu_dai_name = "DMIC01 Pin", |
425 | .codec_name = "dmic-codec", | |
426 | .codec_dai_name = "dmic-hifi", | |
427 | .platform_name = "0000:00:1f.3", | |
4386b767 | 428 | .be_hw_params_fixup = skylake_dmic_fixup, |
624729fd OA |
429 | .ignore_suspend = 1, |
430 | .dpcm_capture = 1, | |
431 | .no_pcm = 1, | |
432 | }, | |
23905cd1 JK |
433 | { |
434 | .name = "iDisp1", | |
2f0ad491 | 435 | .id = 2, |
23905cd1 JK |
436 | .cpu_dai_name = "iDisp1 Pin", |
437 | .codec_name = "ehdaudio0D2", | |
438 | .codec_dai_name = "intel-hdmi-hifi1", | |
439 | .platform_name = "0000:00:1f.3", | |
440 | .init = skylake_hdmi_init, | |
441 | .dpcm_playback = 1, | |
442 | .no_pcm = 1, | |
443 | }, | |
444 | { | |
445 | .name = "iDisp2", | |
2f0ad491 | 446 | .id = 3, |
23905cd1 JK |
447 | .cpu_dai_name = "iDisp2 Pin", |
448 | .codec_name = "ehdaudio0D2", | |
449 | .codec_dai_name = "intel-hdmi-hifi2", | |
450 | .platform_name = "0000:00:1f.3", | |
451 | .init = skylake_hdmi_init, | |
452 | .dpcm_playback = 1, | |
453 | .no_pcm = 1, | |
454 | }, | |
455 | { | |
456 | .name = "iDisp3", | |
2f0ad491 | 457 | .id = 4, |
23905cd1 JK |
458 | .cpu_dai_name = "iDisp3 Pin", |
459 | .codec_name = "ehdaudio0D2", | |
460 | .codec_dai_name = "intel-hdmi-hifi3", | |
461 | .platform_name = "0000:00:1f.3", | |
462 | .init = skylake_hdmi_init, | |
463 | .dpcm_playback = 1, | |
464 | .no_pcm = 1, | |
465 | }, | |
624729fd OA |
466 | }; |
467 | ||
f3af3592 | 468 | #define NAME_SIZE 32 |
1a10612f SP |
469 | static int skylake_card_late_probe(struct snd_soc_card *card) |
470 | { | |
471 | struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(card); | |
472 | struct skl_hdmi_pcm *pcm; | |
45101122 | 473 | struct snd_soc_component *component = NULL; |
f3af3592 JK |
474 | int err, i = 0; |
475 | char jack_name[NAME_SIZE]; | |
1a10612f SP |
476 | |
477 | list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { | |
45101122 | 478 | component = pcm->codec_dai->component; |
f3af3592 JK |
479 | snprintf(jack_name, sizeof(jack_name), |
480 | "HDMI/DP, pcm=%d Jack", pcm->device); | |
481 | err = snd_soc_card_jack_new(card, jack_name, | |
482 | SND_JACK_AVOUT, &skylake_hdmi[i], | |
483 | NULL, 0); | |
484 | ||
485 | if (err) | |
486 | return err; | |
487 | ||
488 | err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, | |
489 | &skylake_hdmi[i]); | |
1a10612f SP |
490 | if (err < 0) |
491 | return err; | |
f3af3592 JK |
492 | |
493 | i++; | |
1a10612f SP |
494 | } |
495 | ||
45101122 | 496 | if (!component) |
64f8620d JK |
497 | return -EINVAL; |
498 | ||
45101122 | 499 | return hdac_hdmi_jack_port_init(component, &card->dapm); |
1a10612f SP |
500 | } |
501 | ||
624729fd OA |
502 | /* skylake audio machine driver for SPT + RT286S */ |
503 | static struct snd_soc_card skylake_rt286 = { | |
504 | .name = "skylake-rt286", | |
505 | .owner = THIS_MODULE, | |
506 | .dai_link = skylake_rt286_dais, | |
507 | .num_links = ARRAY_SIZE(skylake_rt286_dais), | |
508 | .controls = skylake_controls, | |
509 | .num_controls = ARRAY_SIZE(skylake_controls), | |
510 | .dapm_widgets = skylake_widgets, | |
511 | .num_dapm_widgets = ARRAY_SIZE(skylake_widgets), | |
512 | .dapm_routes = skylake_rt286_map, | |
513 | .num_dapm_routes = ARRAY_SIZE(skylake_rt286_map), | |
514 | .fully_routed = true, | |
1a10612f | 515 | .late_probe = skylake_card_late_probe, |
624729fd OA |
516 | }; |
517 | ||
518 | static int skylake_audio_probe(struct platform_device *pdev) | |
519 | { | |
1a10612f SP |
520 | struct skl_rt286_private *ctx; |
521 | ||
a6b09837 | 522 | ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); |
1a10612f SP |
523 | if (!ctx) |
524 | return -ENOMEM; | |
525 | ||
526 | INIT_LIST_HEAD(&ctx->hdmi_pcm_list); | |
527 | ||
624729fd | 528 | skylake_rt286.dev = &pdev->dev; |
1a10612f | 529 | snd_soc_card_set_drvdata(&skylake_rt286, ctx); |
624729fd | 530 | |
4901aa06 | 531 | return devm_snd_soc_register_card(&pdev->dev, &skylake_rt286); |
624729fd OA |
532 | } |
533 | ||
894a16db VK |
534 | static const struct platform_device_id skl_board_ids[] = { |
535 | { .name = "skl_alc286s_i2s" }, | |
536 | { .name = "kbl_alc286s_i2s" }, | |
537 | { } | |
538 | }; | |
539 | ||
624729fd OA |
540 | static struct platform_driver skylake_audio = { |
541 | .probe = skylake_audio_probe, | |
624729fd OA |
542 | .driver = { |
543 | .name = "skl_alc286s_i2s", | |
314038e4 | 544 | .pm = &snd_soc_pm_ops, |
624729fd | 545 | }, |
894a16db VK |
546 | .id_table = skl_board_ids, |
547 | ||
624729fd OA |
548 | }; |
549 | ||
550 | module_platform_driver(skylake_audio) | |
551 | ||
552 | /* Module information */ | |
553 | MODULE_AUTHOR("Omair Mohammed Abdullah <omair.m.abdullah@intel.com>"); | |
554 | MODULE_DESCRIPTION("Intel SST Audio for Skylake"); | |
555 | MODULE_LICENSE("GPL v2"); | |
556 | MODULE_ALIAS("platform:skl_alc286s_i2s"); | |
894a16db | 557 | MODULE_ALIAS("platform:kbl_alc286s_i2s"); |