Commit | Line | Data |
---|---|---|
ec040dd5 N |
1 | /* |
2 | * Intel Kabylake I2S Machine Driver with MAXIM98927 | |
3 | * and RT5663 Codecs | |
4 | * | |
5 | * Copyright (C) 2017, Intel Corporation. All rights reserved. | |
6 | * | |
7 | * Modified from: | |
8 | * Intel Skylake I2S Machine driver | |
9 | * | |
10 | * This program is free software; you can redistribute it and/or | |
11 | * modify it under the terms of the GNU General Public License version | |
12 | * 2 as published by the Free Software Foundation. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
18 | */ | |
19 | ||
ae09a478 | 20 | #include <linux/input.h> |
ec040dd5 N |
21 | #include <linux/module.h> |
22 | #include <linux/platform_device.h> | |
23 | #include <sound/core.h> | |
24 | #include <sound/jack.h> | |
25 | #include <sound/pcm.h> | |
26 | #include <sound/pcm_params.h> | |
27 | #include <sound/soc.h> | |
28 | #include "../../codecs/rt5663.h" | |
29 | #include "../../codecs/hdac_hdmi.h" | |
30 | #include "../skylake/skl.h" | |
f7f61e08 HP |
31 | #include <linux/clk.h> |
32 | #include <linux/clk-provider.h> | |
33 | #include <linux/clkdev.h> | |
ec040dd5 N |
34 | |
35 | #define KBL_REALTEK_CODEC_DAI "rt5663-aif" | |
36 | #define KBL_MAXIM_CODEC_DAI "max98927-aif1" | |
37 | #define DMIC_CH(p) p->list[p->count-1] | |
38 | #define MAXIM_DEV0_NAME "i2c-MX98927:00" | |
39 | #define MAXIM_DEV1_NAME "i2c-MX98927:01" | |
40 | ||
c0642570 | 41 | static struct snd_soc_card *kabylake_audio_card; |
ec040dd5 N |
42 | static const struct snd_pcm_hw_constraint_list *dmic_constraints; |
43 | static struct snd_soc_jack skylake_hdmi[3]; | |
44 | ||
45 | struct kbl_hdmi_pcm { | |
46 | struct list_head head; | |
47 | struct snd_soc_dai *codec_dai; | |
48 | int device; | |
49 | }; | |
50 | ||
51 | struct kbl_rt5663_private { | |
52 | struct snd_soc_jack kabylake_headset; | |
53 | struct list_head hdmi_pcm_list; | |
f7f61e08 HP |
54 | struct clk *mclk; |
55 | struct clk *sclk; | |
ec040dd5 N |
56 | }; |
57 | ||
58 | enum { | |
59 | KBL_DPCM_AUDIO_PB = 0, | |
60 | KBL_DPCM_AUDIO_CP, | |
b32ee384 NM |
61 | KBL_DPCM_AUDIO_HS_PB, |
62 | KBL_DPCM_AUDIO_ECHO_REF_CP, | |
ec040dd5 N |
63 | KBL_DPCM_AUDIO_REF_CP, |
64 | KBL_DPCM_AUDIO_DMIC_CP, | |
65 | KBL_DPCM_AUDIO_HDMI1_PB, | |
66 | KBL_DPCM_AUDIO_HDMI2_PB, | |
67 | KBL_DPCM_AUDIO_HDMI3_PB, | |
68 | }; | |
69 | ||
70 | static const struct snd_kcontrol_new kabylake_controls[] = { | |
71 | SOC_DAPM_PIN_SWITCH("Headphone Jack"), | |
72 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | |
73 | SOC_DAPM_PIN_SWITCH("Left Spk"), | |
74 | SOC_DAPM_PIN_SWITCH("Right Spk"), | |
75 | }; | |
76 | ||
f7f61e08 HP |
77 | static int platform_clock_control(struct snd_soc_dapm_widget *w, |
78 | struct snd_kcontrol *k, int event) | |
79 | { | |
80 | struct snd_soc_dapm_context *dapm = w->dapm; | |
81 | struct snd_soc_card *card = dapm->card; | |
82 | struct kbl_rt5663_private *priv = snd_soc_card_get_drvdata(card); | |
83 | int ret = 0; | |
84 | ||
85 | /* | |
86 | * MCLK/SCLK need to be ON early for a successful synchronization of | |
87 | * codec internal clock. And the clocks are turned off during | |
88 | * POST_PMD after the stream is stopped. | |
89 | */ | |
90 | switch (event) { | |
91 | case SND_SOC_DAPM_PRE_PMU: | |
92 | /* Enable MCLK */ | |
93 | ret = clk_set_rate(priv->mclk, 24000000); | |
94 | if (ret < 0) { | |
95 | dev_err(card->dev, "Can't set rate for mclk, err: %d\n", | |
96 | ret); | |
97 | return ret; | |
98 | } | |
99 | ||
100 | ret = clk_prepare_enable(priv->mclk); | |
101 | if (ret < 0) { | |
102 | dev_err(card->dev, "Can't enable mclk, err: %d\n", ret); | |
103 | return ret; | |
104 | } | |
105 | ||
106 | /* Enable SCLK */ | |
107 | ret = clk_set_rate(priv->sclk, 3072000); | |
108 | if (ret < 0) { | |
109 | dev_err(card->dev, "Can't set rate for sclk, err: %d\n", | |
110 | ret); | |
111 | clk_disable_unprepare(priv->mclk); | |
112 | return ret; | |
113 | } | |
114 | ||
115 | ret = clk_prepare_enable(priv->sclk); | |
116 | if (ret < 0) { | |
117 | dev_err(card->dev, "Can't enable sclk, err: %d\n", ret); | |
118 | clk_disable_unprepare(priv->mclk); | |
119 | } | |
120 | break; | |
121 | case SND_SOC_DAPM_POST_PMD: | |
122 | clk_disable_unprepare(priv->mclk); | |
123 | clk_disable_unprepare(priv->sclk); | |
124 | break; | |
125 | default: | |
126 | return 0; | |
127 | } | |
128 | ||
129 | return 0; | |
130 | } | |
131 | ||
ec040dd5 N |
132 | static const struct snd_soc_dapm_widget kabylake_widgets[] = { |
133 | SND_SOC_DAPM_HP("Headphone Jack", NULL), | |
134 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | |
135 | SND_SOC_DAPM_SPK("Left Spk", NULL), | |
136 | SND_SOC_DAPM_SPK("Right Spk", NULL), | |
137 | SND_SOC_DAPM_MIC("SoC DMIC", NULL), | |
c20252cf N |
138 | SND_SOC_DAPM_SPK("HDMI1", NULL), |
139 | SND_SOC_DAPM_SPK("HDMI2", NULL), | |
140 | SND_SOC_DAPM_SPK("HDMI3", NULL), | |
f7f61e08 HP |
141 | SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, |
142 | platform_clock_control, SND_SOC_DAPM_PRE_PMU | | |
143 | SND_SOC_DAPM_POST_PMD), | |
ec040dd5 N |
144 | }; |
145 | ||
146 | static const struct snd_soc_dapm_route kabylake_map[] = { | |
147 | /* HP jack connectors - unknown if we have jack detection */ | |
f7f61e08 | 148 | { "Headphone Jack", NULL, "Platform Clock" }, |
ec040dd5 N |
149 | { "Headphone Jack", NULL, "HPOL" }, |
150 | { "Headphone Jack", NULL, "HPOR" }, | |
151 | ||
152 | /* speaker */ | |
153 | { "Left Spk", NULL, "Left BE_OUT" }, | |
154 | { "Right Spk", NULL, "Right BE_OUT" }, | |
155 | ||
156 | /* other jacks */ | |
f7f61e08 | 157 | { "Headset Mic", NULL, "Platform Clock" }, |
ec040dd5 N |
158 | { "IN1P", NULL, "Headset Mic" }, |
159 | { "IN1N", NULL, "Headset Mic" }, | |
160 | { "DMic", NULL, "SoC DMIC" }, | |
161 | ||
ec040dd5 N |
162 | /* CODEC BE connections */ |
163 | { "Left HiFi Playback", NULL, "ssp0 Tx" }, | |
164 | { "Right HiFi Playback", NULL, "ssp0 Tx" }, | |
0b06122f | 165 | { "ssp0 Tx", NULL, "spk_out" }, |
ec040dd5 N |
166 | |
167 | { "AIF Playback", NULL, "ssp1 Tx" }, | |
4c761ebf | 168 | { "ssp1 Tx", NULL, "codec1_out" }, |
ec040dd5 | 169 | |
0b06122f | 170 | { "hs_in", NULL, "ssp1 Rx" }, |
ec040dd5 N |
171 | { "ssp1 Rx", NULL, "AIF Capture" }, |
172 | ||
64220b9d NM |
173 | /* IV feedback path */ |
174 | { "codec0_fb_in", NULL, "ssp0 Rx"}, | |
175 | { "ssp0 Rx", NULL, "Left HiFi Capture" }, | |
176 | { "ssp0 Rx", NULL, "Right HiFi Capture" }, | |
177 | ||
ec040dd5 N |
178 | /* DMIC */ |
179 | { "dmic01_hifi", NULL, "DMIC01 Rx" }, | |
180 | { "DMIC01 Rx", NULL, "DMIC AIF" }, | |
181 | ||
182 | { "hifi3", NULL, "iDisp3 Tx"}, | |
183 | { "iDisp3 Tx", NULL, "iDisp3_out"}, | |
184 | { "hifi2", NULL, "iDisp2 Tx"}, | |
185 | { "iDisp2 Tx", NULL, "iDisp2_out"}, | |
186 | { "hifi1", NULL, "iDisp1 Tx"}, | |
187 | { "iDisp1 Tx", NULL, "iDisp1_out"}, | |
188 | }; | |
189 | ||
c0642570 KC |
190 | enum { |
191 | KBL_DPCM_AUDIO_5663_PB = 0, | |
192 | KBL_DPCM_AUDIO_5663_CP, | |
193 | KBL_DPCM_AUDIO_5663_HDMI1_PB, | |
194 | KBL_DPCM_AUDIO_5663_HDMI2_PB, | |
195 | }; | |
196 | ||
197 | static const struct snd_kcontrol_new kabylake_5663_controls[] = { | |
198 | SOC_DAPM_PIN_SWITCH("Headphone Jack"), | |
199 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | |
200 | }; | |
201 | ||
202 | static const struct snd_soc_dapm_widget kabylake_5663_widgets[] = { | |
203 | SND_SOC_DAPM_HP("Headphone Jack", NULL), | |
204 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | |
205 | SND_SOC_DAPM_SPK("DP", NULL), | |
206 | SND_SOC_DAPM_SPK("HDMI", NULL), | |
256ac58a NM |
207 | SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, |
208 | platform_clock_control, SND_SOC_DAPM_PRE_PMU | | |
209 | SND_SOC_DAPM_POST_PMD), | |
c0642570 KC |
210 | }; |
211 | ||
212 | static const struct snd_soc_dapm_route kabylake_5663_map[] = { | |
256ac58a | 213 | { "Headphone Jack", NULL, "Platform Clock" }, |
c0642570 KC |
214 | { "Headphone Jack", NULL, "HPOL" }, |
215 | { "Headphone Jack", NULL, "HPOR" }, | |
216 | ||
217 | /* other jacks */ | |
256ac58a | 218 | { "Headset Mic", NULL, "Platform Clock" }, |
c0642570 KC |
219 | { "IN1P", NULL, "Headset Mic" }, |
220 | { "IN1N", NULL, "Headset Mic" }, | |
221 | ||
222 | { "HDMI", NULL, "hif5 Output" }, | |
223 | { "DP", NULL, "hif6 Output" }, | |
224 | ||
225 | /* CODEC BE connections */ | |
226 | { "AIF Playback", NULL, "ssp1 Tx" }, | |
227 | { "ssp1 Tx", NULL, "codec1_out" }, | |
228 | ||
229 | { "codec0_in", NULL, "ssp1 Rx" }, | |
230 | { "ssp1 Rx", NULL, "AIF Capture" }, | |
231 | ||
232 | { "hifi2", NULL, "iDisp2 Tx"}, | |
233 | { "iDisp2 Tx", NULL, "iDisp2_out"}, | |
234 | { "hifi1", NULL, "iDisp1 Tx"}, | |
235 | { "iDisp1 Tx", NULL, "iDisp1_out"}, | |
236 | }; | |
237 | ||
ec040dd5 N |
238 | static struct snd_soc_codec_conf max98927_codec_conf[] = { |
239 | { | |
240 | .dev_name = MAXIM_DEV0_NAME, | |
241 | .name_prefix = "Right", | |
242 | }, | |
243 | { | |
244 | .dev_name = MAXIM_DEV1_NAME, | |
245 | .name_prefix = "Left", | |
246 | }, | |
247 | }; | |
248 | ||
249 | static struct snd_soc_dai_link_component max98927_codec_components[] = { | |
250 | { /* Left */ | |
251 | .name = MAXIM_DEV0_NAME, | |
252 | .dai_name = KBL_MAXIM_CODEC_DAI, | |
253 | }, | |
254 | { /* Right */ | |
255 | .name = MAXIM_DEV1_NAME, | |
256 | .dai_name = KBL_MAXIM_CODEC_DAI, | |
257 | }, | |
258 | }; | |
259 | ||
260 | static int kabylake_rt5663_fe_init(struct snd_soc_pcm_runtime *rtd) | |
261 | { | |
262 | int ret; | |
263 | struct snd_soc_dapm_context *dapm; | |
264 | struct snd_soc_component *component = rtd->cpu_dai->component; | |
265 | ||
266 | dapm = snd_soc_component_get_dapm(component); | |
267 | ret = snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); | |
268 | if (ret) { | |
269 | dev_err(rtd->dev, "Ref Cap ignore suspend failed %d\n", ret); | |
270 | return ret; | |
271 | } | |
272 | ||
273 | return ret; | |
274 | } | |
275 | ||
276 | static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) | |
277 | { | |
278 | int ret; | |
279 | struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); | |
45101122 | 280 | struct snd_soc_component *component = rtd->codec_dai->component; |
ae09a478 | 281 | struct snd_soc_jack *jack; |
ec040dd5 N |
282 | |
283 | /* | |
284 | * Headset buttons map to the google Reference headset. | |
285 | * These can be configured by userspace. | |
286 | */ | |
c0642570 | 287 | ret = snd_soc_card_jack_new(kabylake_audio_card, "Headset Jack", |
ec040dd5 N |
288 | SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | |
289 | SND_JACK_BTN_2 | SND_JACK_BTN_3, &ctx->kabylake_headset, | |
290 | NULL, 0); | |
291 | if (ret) { | |
292 | dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); | |
293 | return ret; | |
294 | } | |
ae09a478 N |
295 | |
296 | jack = &ctx->kabylake_headset; | |
38a5882e | 297 | snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); |
ae09a478 N |
298 | snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); |
299 | snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); | |
300 | snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); | |
301 | ||
37a04911 OC |
302 | snd_soc_component_set_jack(component, &ctx->kabylake_headset, NULL); |
303 | ||
c0642570 KC |
304 | return ret; |
305 | } | |
306 | ||
307 | static int kabylake_rt5663_max98927_codec_init(struct snd_soc_pcm_runtime *rtd) | |
308 | { | |
309 | int ret; | |
310 | ||
311 | ret = kabylake_rt5663_codec_init(rtd); | |
312 | if (ret) | |
313 | return ret; | |
314 | ||
ec040dd5 N |
315 | ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); |
316 | if (ret) { | |
317 | dev_err(rtd->dev, "SoC DMIC ignore suspend failed %d\n", ret); | |
318 | return ret; | |
319 | } | |
320 | ||
321 | return ret; | |
322 | } | |
323 | ||
c0642570 | 324 | static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) |
ec040dd5 N |
325 | { |
326 | struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); | |
327 | struct snd_soc_dai *dai = rtd->codec_dai; | |
328 | struct kbl_hdmi_pcm *pcm; | |
329 | ||
330 | pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); | |
331 | if (!pcm) | |
332 | return -ENOMEM; | |
333 | ||
c0642570 | 334 | pcm->device = device; |
ec040dd5 N |
335 | pcm->codec_dai = dai; |
336 | ||
337 | list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); | |
338 | ||
339 | return 0; | |
340 | } | |
341 | ||
c0642570 | 342 | static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) |
ec040dd5 | 343 | { |
c0642570 KC |
344 | return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI1_PB); |
345 | } | |
ec040dd5 | 346 | |
c0642570 KC |
347 | static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) |
348 | { | |
349 | return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI2_PB); | |
ec040dd5 N |
350 | } |
351 | ||
352 | static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) | |
353 | { | |
c0642570 KC |
354 | return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI3_PB); |
355 | } | |
ec040dd5 | 356 | |
c0642570 KC |
357 | static int kabylake_5663_hdmi1_init(struct snd_soc_pcm_runtime *rtd) |
358 | { | |
359 | return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_5663_HDMI1_PB); | |
360 | } | |
ec040dd5 | 361 | |
c0642570 KC |
362 | static int kabylake_5663_hdmi2_init(struct snd_soc_pcm_runtime *rtd) |
363 | { | |
364 | return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_5663_HDMI2_PB); | |
ec040dd5 N |
365 | } |
366 | ||
367 | static unsigned int rates[] = { | |
368 | 48000, | |
369 | }; | |
370 | ||
2d5f8487 | 371 | static const struct snd_pcm_hw_constraint_list constraints_rates = { |
ec040dd5 N |
372 | .count = ARRAY_SIZE(rates), |
373 | .list = rates, | |
374 | .mask = 0, | |
375 | }; | |
376 | ||
377 | static unsigned int channels[] = { | |
378 | 2, | |
379 | }; | |
380 | ||
2d5f8487 | 381 | static const struct snd_pcm_hw_constraint_list constraints_channels = { |
ec040dd5 N |
382 | .count = ARRAY_SIZE(channels), |
383 | .list = channels, | |
384 | .mask = 0, | |
385 | }; | |
386 | ||
387 | static int kbl_fe_startup(struct snd_pcm_substream *substream) | |
388 | { | |
389 | struct snd_pcm_runtime *runtime = substream->runtime; | |
390 | ||
391 | /* | |
392 | * On this platform for PCM device we support, | |
393 | * 48Khz | |
394 | * stereo | |
395 | * 16 bit audio | |
396 | */ | |
397 | ||
398 | runtime->hw.channels_max = 2; | |
399 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | |
400 | &constraints_channels); | |
401 | ||
402 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; | |
403 | snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); | |
404 | ||
405 | snd_pcm_hw_constraint_list(runtime, 0, | |
406 | SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); | |
407 | ||
408 | return 0; | |
409 | } | |
410 | ||
411 | static const struct snd_soc_ops kabylake_rt5663_fe_ops = { | |
412 | .startup = kbl_fe_startup, | |
413 | }; | |
414 | ||
415 | static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, | |
416 | struct snd_pcm_hw_params *params) | |
417 | { | |
418 | struct snd_interval *rate = hw_param_interval(params, | |
419 | SNDRV_PCM_HW_PARAM_RATE); | |
420 | struct snd_interval *channels = hw_param_interval(params, | |
421 | SNDRV_PCM_HW_PARAM_CHANNELS); | |
422 | struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | |
e78407fb HP |
423 | struct snd_soc_dpcm *dpcm = container_of( |
424 | params, struct snd_soc_dpcm, hw_params); | |
425 | struct snd_soc_dai_link *fe_dai_link = dpcm->fe->dai_link; | |
426 | struct snd_soc_dai_link *be_dai_link = dpcm->be->dai_link; | |
ec040dd5 | 427 | |
e78407fb HP |
428 | /* |
429 | * The ADSP will convert the FE rate to 48k, stereo, 24 bit | |
430 | */ | |
431 | if (!strcmp(fe_dai_link->name, "Kbl Audio Port") || | |
432 | !strcmp(fe_dai_link->name, "Kbl Audio Headset Playback") || | |
433 | !strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) { | |
434 | rate->min = rate->max = 48000; | |
435 | channels->min = channels->max = 2; | |
436 | snd_mask_none(fmt); | |
b5453e8c | 437 | snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); |
e78407fb HP |
438 | } |
439 | /* | |
440 | * The speaker on the SSP0 supports S16_LE and not S24_LE. | |
441 | * thus changing the mask here | |
442 | */ | |
443 | if (!strcmp(be_dai_link->name, "SSP0-Codec")) | |
b5453e8c | 444 | snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); |
ec040dd5 N |
445 | |
446 | return 0; | |
447 | } | |
448 | ||
449 | static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream, | |
450 | struct snd_pcm_hw_params *params) | |
451 | { | |
452 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
453 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | |
454 | int ret; | |
455 | ||
ec040dd5 | 456 | /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */ |
45101122 | 457 | rt5663_sel_asrc_clk_src(codec_dai->component, |
d46b1828 HP |
458 | RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER, |
459 | RT5663_CLK_SEL_I2S1_ASRC); | |
ec040dd5 | 460 | |
d46b1828 HP |
461 | ret = snd_soc_dai_set_sysclk(codec_dai, |
462 | RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN); | |
ec040dd5 N |
463 | if (ret < 0) |
464 | dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); | |
465 | ||
466 | return ret; | |
467 | } | |
468 | ||
469 | static struct snd_soc_ops kabylake_rt5663_ops = { | |
470 | .hw_params = kabylake_rt5663_hw_params, | |
471 | }; | |
472 | ||
473 | static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, | |
474 | struct snd_pcm_hw_params *params) | |
475 | { | |
476 | struct snd_interval *channels = hw_param_interval(params, | |
477 | SNDRV_PCM_HW_PARAM_CHANNELS); | |
478 | ||
479 | if (params_channels(params) == 2 || DMIC_CH(dmic_constraints) == 2) | |
480 | channels->min = channels->max = 2; | |
481 | else | |
482 | channels->min = channels->max = 4; | |
483 | ||
484 | return 0; | |
485 | } | |
486 | ||
7a679ea7 HP |
487 | static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, |
488 | struct snd_pcm_hw_params *params) | |
489 | { | |
490 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
0b7990e3 | 491 | struct snd_soc_dai *codec_dai; |
7a679ea7 HP |
492 | int ret = 0, j; |
493 | ||
0b7990e3 | 494 | for_each_rtd_codec_dai(rtd, j, codec_dai) { |
7a679ea7 HP |
495 | if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME)) { |
496 | /* | |
497 | * Use channel 4 and 5 for the first amp | |
498 | */ | |
499 | ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16); | |
500 | if (ret < 0) { | |
501 | dev_err(rtd->dev, "set TDM slot err:%d\n", ret); | |
502 | return ret; | |
503 | } | |
504 | } | |
505 | if (!strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) { | |
506 | /* | |
507 | * Use channel 6 and 7 for the second amp | |
508 | */ | |
509 | ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 3, 8, 16); | |
510 | if (ret < 0) { | |
511 | dev_err(rtd->dev, "set TDM slot err:%d\n", ret); | |
512 | return ret; | |
513 | } | |
514 | } | |
515 | } | |
516 | return ret; | |
517 | } | |
518 | ||
519 | static struct snd_soc_ops kabylake_ssp0_ops = { | |
520 | .hw_params = kabylake_ssp0_hw_params, | |
521 | }; | |
522 | ||
ec040dd5 N |
523 | static unsigned int channels_dmic[] = { |
524 | 2, 4, | |
525 | }; | |
526 | ||
527 | static struct snd_pcm_hw_constraint_list constraints_dmic_channels = { | |
528 | .count = ARRAY_SIZE(channels_dmic), | |
529 | .list = channels_dmic, | |
530 | .mask = 0, | |
531 | }; | |
532 | ||
533 | static const unsigned int dmic_2ch[] = { | |
534 | 2, | |
535 | }; | |
536 | ||
537 | static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = { | |
538 | .count = ARRAY_SIZE(dmic_2ch), | |
539 | .list = dmic_2ch, | |
540 | .mask = 0, | |
541 | }; | |
542 | ||
543 | static int kabylake_dmic_startup(struct snd_pcm_substream *substream) | |
544 | { | |
545 | struct snd_pcm_runtime *runtime = substream->runtime; | |
546 | ||
547 | runtime->hw.channels_max = DMIC_CH(dmic_constraints); | |
548 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | |
549 | dmic_constraints); | |
550 | ||
551 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | |
552 | SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); | |
553 | } | |
554 | ||
555 | static struct snd_soc_ops kabylake_dmic_ops = { | |
556 | .startup = kabylake_dmic_startup, | |
557 | }; | |
558 | ||
559 | static unsigned int rates_16000[] = { | |
560 | 16000, | |
561 | }; | |
562 | ||
2d5f8487 | 563 | static const struct snd_pcm_hw_constraint_list constraints_16000 = { |
ec040dd5 N |
564 | .count = ARRAY_SIZE(rates_16000), |
565 | .list = rates_16000, | |
566 | }; | |
567 | ||
568 | static const unsigned int ch_mono[] = { | |
569 | 1, | |
570 | }; | |
571 | ||
572 | static const struct snd_pcm_hw_constraint_list constraints_refcap = { | |
573 | .count = ARRAY_SIZE(ch_mono), | |
574 | .list = ch_mono, | |
575 | }; | |
576 | ||
577 | static int kabylake_refcap_startup(struct snd_pcm_substream *substream) | |
578 | { | |
579 | substream->runtime->hw.channels_max = 1; | |
580 | snd_pcm_hw_constraint_list(substream->runtime, 0, | |
581 | SNDRV_PCM_HW_PARAM_CHANNELS, | |
582 | &constraints_refcap); | |
583 | ||
584 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | |
585 | SNDRV_PCM_HW_PARAM_RATE, | |
586 | &constraints_16000); | |
587 | } | |
588 | ||
589 | static struct snd_soc_ops skylaye_refcap_ops = { | |
590 | .startup = kabylake_refcap_startup, | |
591 | }; | |
592 | ||
593 | /* kabylake digital audio interface glue - connects codec <--> CPU */ | |
594 | static struct snd_soc_dai_link kabylake_dais[] = { | |
595 | /* Front End DAI links */ | |
596 | [KBL_DPCM_AUDIO_PB] = { | |
597 | .name = "Kbl Audio Port", | |
598 | .stream_name = "Audio", | |
599 | .cpu_dai_name = "System Pin", | |
600 | .platform_name = "0000:00:1f.3", | |
601 | .dynamic = 1, | |
602 | .codec_name = "snd-soc-dummy", | |
603 | .codec_dai_name = "snd-soc-dummy-dai", | |
604 | .nonatomic = 1, | |
605 | .init = kabylake_rt5663_fe_init, | |
606 | .trigger = { | |
607 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
608 | .dpcm_playback = 1, | |
609 | .ops = &kabylake_rt5663_fe_ops, | |
610 | }, | |
611 | [KBL_DPCM_AUDIO_CP] = { | |
612 | .name = "Kbl Audio Capture Port", | |
613 | .stream_name = "Audio Record", | |
614 | .cpu_dai_name = "System Pin", | |
615 | .platform_name = "0000:00:1f.3", | |
616 | .dynamic = 1, | |
617 | .codec_name = "snd-soc-dummy", | |
618 | .codec_dai_name = "snd-soc-dummy-dai", | |
619 | .nonatomic = 1, | |
620 | .trigger = { | |
621 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
622 | .dpcm_capture = 1, | |
623 | .ops = &kabylake_rt5663_fe_ops, | |
624 | }, | |
b32ee384 NM |
625 | [KBL_DPCM_AUDIO_HS_PB] = { |
626 | .name = "Kbl Audio Headset Playback", | |
627 | .stream_name = "Headset Audio", | |
628 | .cpu_dai_name = "System Pin2", | |
629 | .codec_name = "snd-soc-dummy", | |
630 | .codec_dai_name = "snd-soc-dummy-dai", | |
631 | .platform_name = "0000:00:1f.3", | |
632 | .dpcm_playback = 1, | |
633 | .nonatomic = 1, | |
634 | .dynamic = 1, | |
635 | }, | |
636 | [KBL_DPCM_AUDIO_ECHO_REF_CP] = { | |
637 | .name = "Kbl Audio Echo Reference cap", | |
638 | .stream_name = "Echoreference Capture", | |
639 | .cpu_dai_name = "Echoref Pin", | |
640 | .codec_name = "snd-soc-dummy", | |
641 | .codec_dai_name = "snd-soc-dummy-dai", | |
642 | .platform_name = "0000:00:1f.3", | |
643 | .init = NULL, | |
644 | .capture_only = 1, | |
645 | .nonatomic = 1, | |
646 | }, | |
ec040dd5 N |
647 | [KBL_DPCM_AUDIO_REF_CP] = { |
648 | .name = "Kbl Audio Reference cap", | |
649 | .stream_name = "Wake on Voice", | |
650 | .cpu_dai_name = "Reference Pin", | |
651 | .codec_name = "snd-soc-dummy", | |
652 | .codec_dai_name = "snd-soc-dummy-dai", | |
653 | .platform_name = "0000:00:1f.3", | |
654 | .init = NULL, | |
655 | .dpcm_capture = 1, | |
656 | .nonatomic = 1, | |
657 | .dynamic = 1, | |
658 | .ops = &skylaye_refcap_ops, | |
659 | }, | |
660 | [KBL_DPCM_AUDIO_DMIC_CP] = { | |
661 | .name = "Kbl Audio DMIC cap", | |
662 | .stream_name = "dmiccap", | |
663 | .cpu_dai_name = "DMIC Pin", | |
664 | .codec_name = "snd-soc-dummy", | |
665 | .codec_dai_name = "snd-soc-dummy-dai", | |
666 | .platform_name = "0000:00:1f.3", | |
667 | .init = NULL, | |
668 | .dpcm_capture = 1, | |
669 | .nonatomic = 1, | |
670 | .dynamic = 1, | |
671 | .ops = &kabylake_dmic_ops, | |
672 | }, | |
673 | [KBL_DPCM_AUDIO_HDMI1_PB] = { | |
674 | .name = "Kbl HDMI Port1", | |
675 | .stream_name = "Hdmi1", | |
676 | .cpu_dai_name = "HDMI1 Pin", | |
677 | .codec_name = "snd-soc-dummy", | |
678 | .codec_dai_name = "snd-soc-dummy-dai", | |
679 | .platform_name = "0000:00:1f.3", | |
680 | .dpcm_playback = 1, | |
681 | .init = NULL, | |
682 | .trigger = { | |
683 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
684 | .nonatomic = 1, | |
685 | .dynamic = 1, | |
686 | }, | |
687 | [KBL_DPCM_AUDIO_HDMI2_PB] = { | |
688 | .name = "Kbl HDMI Port2", | |
689 | .stream_name = "Hdmi2", | |
690 | .cpu_dai_name = "HDMI2 Pin", | |
691 | .codec_name = "snd-soc-dummy", | |
692 | .codec_dai_name = "snd-soc-dummy-dai", | |
693 | .platform_name = "0000:00:1f.3", | |
694 | .dpcm_playback = 1, | |
695 | .init = NULL, | |
696 | .trigger = { | |
697 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
698 | .nonatomic = 1, | |
699 | .dynamic = 1, | |
700 | }, | |
701 | [KBL_DPCM_AUDIO_HDMI3_PB] = { | |
702 | .name = "Kbl HDMI Port3", | |
703 | .stream_name = "Hdmi3", | |
704 | .cpu_dai_name = "HDMI3 Pin", | |
705 | .codec_name = "snd-soc-dummy", | |
706 | .codec_dai_name = "snd-soc-dummy-dai", | |
707 | .platform_name = "0000:00:1f.3", | |
708 | .trigger = { | |
709 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
710 | .dpcm_playback = 1, | |
711 | .init = NULL, | |
712 | .nonatomic = 1, | |
713 | .dynamic = 1, | |
714 | }, | |
715 | ||
716 | /* Back End DAI links */ | |
717 | { | |
718 | /* SSP0 - Codec */ | |
719 | .name = "SSP0-Codec", | |
720 | .id = 0, | |
721 | .cpu_dai_name = "SSP0 Pin", | |
722 | .platform_name = "0000:00:1f.3", | |
723 | .no_pcm = 1, | |
724 | .codecs = max98927_codec_components, | |
725 | .num_codecs = ARRAY_SIZE(max98927_codec_components), | |
7a679ea7 | 726 | .dai_fmt = SND_SOC_DAIFMT_DSP_B | |
ec040dd5 N |
727 | SND_SOC_DAIFMT_NB_NF | |
728 | SND_SOC_DAIFMT_CBS_CFS, | |
729 | .ignore_pmdown_time = 1, | |
730 | .be_hw_params_fixup = kabylake_ssp_fixup, | |
731 | .dpcm_playback = 1, | |
7a679ea7 | 732 | .ops = &kabylake_ssp0_ops, |
ec040dd5 N |
733 | }, |
734 | { | |
735 | /* SSP1 - Codec */ | |
736 | .name = "SSP1-Codec", | |
737 | .id = 1, | |
738 | .cpu_dai_name = "SSP1 Pin", | |
739 | .platform_name = "0000:00:1f.3", | |
740 | .no_pcm = 1, | |
741 | .codec_name = "i2c-10EC5663:00", | |
742 | .codec_dai_name = KBL_REALTEK_CODEC_DAI, | |
c0642570 | 743 | .init = kabylake_rt5663_max98927_codec_init, |
ec040dd5 N |
744 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
745 | SND_SOC_DAIFMT_CBS_CFS, | |
746 | .ignore_pmdown_time = 1, | |
747 | .be_hw_params_fixup = kabylake_ssp_fixup, | |
748 | .ops = &kabylake_rt5663_ops, | |
749 | .dpcm_playback = 1, | |
750 | .dpcm_capture = 1, | |
751 | }, | |
752 | { | |
753 | .name = "dmic01", | |
754 | .id = 2, | |
755 | .cpu_dai_name = "DMIC01 Pin", | |
756 | .codec_name = "dmic-codec", | |
757 | .codec_dai_name = "dmic-hifi", | |
758 | .platform_name = "0000:00:1f.3", | |
759 | .be_hw_params_fixup = kabylake_dmic_fixup, | |
760 | .ignore_suspend = 1, | |
761 | .dpcm_capture = 1, | |
762 | .no_pcm = 1, | |
763 | }, | |
764 | { | |
765 | .name = "iDisp1", | |
766 | .id = 3, | |
767 | .cpu_dai_name = "iDisp1 Pin", | |
768 | .codec_name = "ehdaudio0D2", | |
769 | .codec_dai_name = "intel-hdmi-hifi1", | |
770 | .platform_name = "0000:00:1f.3", | |
771 | .dpcm_playback = 1, | |
772 | .init = kabylake_hdmi1_init, | |
773 | .no_pcm = 1, | |
774 | }, | |
775 | { | |
776 | .name = "iDisp2", | |
777 | .id = 4, | |
778 | .cpu_dai_name = "iDisp2 Pin", | |
779 | .codec_name = "ehdaudio0D2", | |
780 | .codec_dai_name = "intel-hdmi-hifi2", | |
781 | .platform_name = "0000:00:1f.3", | |
782 | .init = kabylake_hdmi2_init, | |
783 | .dpcm_playback = 1, | |
784 | .no_pcm = 1, | |
785 | }, | |
786 | { | |
787 | .name = "iDisp3", | |
788 | .id = 5, | |
789 | .cpu_dai_name = "iDisp3 Pin", | |
790 | .codec_name = "ehdaudio0D2", | |
791 | .codec_dai_name = "intel-hdmi-hifi3", | |
792 | .platform_name = "0000:00:1f.3", | |
793 | .init = kabylake_hdmi3_init, | |
794 | .dpcm_playback = 1, | |
795 | .no_pcm = 1, | |
796 | }, | |
797 | }; | |
798 | ||
c0642570 KC |
799 | static struct snd_soc_dai_link kabylake_5663_dais[] = { |
800 | /* Front End DAI links */ | |
801 | [KBL_DPCM_AUDIO_5663_PB] = { | |
802 | .name = "Kbl Audio Port", | |
803 | .stream_name = "Audio", | |
804 | .cpu_dai_name = "System Pin", | |
805 | .platform_name = "0000:00:1f.3", | |
806 | .dynamic = 1, | |
807 | .codec_name = "snd-soc-dummy", | |
808 | .codec_dai_name = "snd-soc-dummy-dai", | |
809 | .nonatomic = 1, | |
810 | .trigger = { | |
811 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
812 | .dpcm_playback = 1, | |
813 | .ops = &kabylake_rt5663_fe_ops, | |
814 | }, | |
815 | [KBL_DPCM_AUDIO_5663_CP] = { | |
816 | .name = "Kbl Audio Capture Port", | |
817 | .stream_name = "Audio Record", | |
818 | .cpu_dai_name = "System Pin", | |
819 | .platform_name = "0000:00:1f.3", | |
820 | .dynamic = 1, | |
821 | .codec_name = "snd-soc-dummy", | |
822 | .codec_dai_name = "snd-soc-dummy-dai", | |
823 | .nonatomic = 1, | |
824 | .trigger = { | |
825 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
826 | .dpcm_capture = 1, | |
827 | .ops = &kabylake_rt5663_fe_ops, | |
828 | }, | |
829 | [KBL_DPCM_AUDIO_5663_HDMI1_PB] = { | |
830 | .name = "Kbl HDMI Port1", | |
831 | .stream_name = "Hdmi1", | |
832 | .cpu_dai_name = "HDMI1 Pin", | |
833 | .codec_name = "snd-soc-dummy", | |
834 | .codec_dai_name = "snd-soc-dummy-dai", | |
835 | .platform_name = "0000:00:1f.3", | |
836 | .dpcm_playback = 1, | |
837 | .init = NULL, | |
838 | .trigger = { | |
839 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
840 | .nonatomic = 1, | |
841 | .dynamic = 1, | |
842 | }, | |
843 | [KBL_DPCM_AUDIO_5663_HDMI2_PB] = { | |
844 | .name = "Kbl HDMI Port2", | |
845 | .stream_name = "Hdmi2", | |
846 | .cpu_dai_name = "HDMI2 Pin", | |
847 | .codec_name = "snd-soc-dummy", | |
848 | .codec_dai_name = "snd-soc-dummy-dai", | |
849 | .platform_name = "0000:00:1f.3", | |
850 | .dpcm_playback = 1, | |
851 | .init = NULL, | |
852 | .trigger = { | |
853 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
854 | .nonatomic = 1, | |
855 | .dynamic = 1, | |
856 | }, | |
857 | ||
858 | /* Back End DAI links */ | |
859 | { | |
860 | /* SSP1 - Codec */ | |
861 | .name = "SSP1-Codec", | |
862 | .id = 0, | |
863 | .cpu_dai_name = "SSP1 Pin", | |
864 | .platform_name = "0000:00:1f.3", | |
865 | .no_pcm = 1, | |
866 | .codec_name = "i2c-10EC5663:00", | |
867 | .codec_dai_name = KBL_REALTEK_CODEC_DAI, | |
868 | .init = kabylake_rt5663_codec_init, | |
869 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | |
870 | SND_SOC_DAIFMT_CBS_CFS, | |
871 | .ignore_pmdown_time = 1, | |
872 | .be_hw_params_fixup = kabylake_ssp_fixup, | |
873 | .ops = &kabylake_rt5663_ops, | |
874 | .dpcm_playback = 1, | |
875 | .dpcm_capture = 1, | |
876 | }, | |
877 | { | |
878 | .name = "iDisp1", | |
879 | .id = 1, | |
880 | .cpu_dai_name = "iDisp1 Pin", | |
881 | .codec_name = "ehdaudio0D2", | |
882 | .codec_dai_name = "intel-hdmi-hifi1", | |
883 | .platform_name = "0000:00:1f.3", | |
884 | .dpcm_playback = 1, | |
885 | .init = kabylake_5663_hdmi1_init, | |
886 | .no_pcm = 1, | |
887 | }, | |
888 | { | |
889 | .name = "iDisp2", | |
890 | .id = 2, | |
891 | .cpu_dai_name = "iDisp2 Pin", | |
892 | .codec_name = "ehdaudio0D2", | |
893 | .codec_dai_name = "intel-hdmi-hifi2", | |
894 | .platform_name = "0000:00:1f.3", | |
895 | .init = kabylake_5663_hdmi2_init, | |
896 | .dpcm_playback = 1, | |
897 | .no_pcm = 1, | |
898 | }, | |
899 | }; | |
900 | ||
ec040dd5 N |
901 | #define NAME_SIZE 32 |
902 | static int kabylake_card_late_probe(struct snd_soc_card *card) | |
903 | { | |
904 | struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card); | |
905 | struct kbl_hdmi_pcm *pcm; | |
45101122 | 906 | struct snd_soc_component *component = NULL; |
ec040dd5 N |
907 | int err, i = 0; |
908 | char jack_name[NAME_SIZE]; | |
909 | ||
910 | list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { | |
45101122 | 911 | component = pcm->codec_dai->component; |
ec040dd5 N |
912 | snprintf(jack_name, sizeof(jack_name), |
913 | "HDMI/DP, pcm=%d Jack", pcm->device); | |
914 | err = snd_soc_card_jack_new(card, jack_name, | |
915 | SND_JACK_AVOUT, &skylake_hdmi[i], | |
916 | NULL, 0); | |
917 | ||
918 | if (err) | |
919 | return err; | |
920 | ||
921 | err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, | |
922 | &skylake_hdmi[i]); | |
923 | if (err < 0) | |
924 | return err; | |
925 | ||
926 | i++; | |
927 | } | |
928 | ||
45101122 | 929 | if (!component) |
3a13347f N |
930 | return -EINVAL; |
931 | ||
45101122 | 932 | return hdac_hdmi_jack_port_init(component, &card->dapm); |
ec040dd5 N |
933 | } |
934 | ||
935 | /* kabylake audio machine driver for SPT + RT5663 */ | |
c0642570 | 936 | static struct snd_soc_card kabylake_audio_card_rt5663_m98927 = { |
ec040dd5 N |
937 | .name = "kblrt5663max", |
938 | .owner = THIS_MODULE, | |
939 | .dai_link = kabylake_dais, | |
940 | .num_links = ARRAY_SIZE(kabylake_dais), | |
941 | .controls = kabylake_controls, | |
942 | .num_controls = ARRAY_SIZE(kabylake_controls), | |
943 | .dapm_widgets = kabylake_widgets, | |
944 | .num_dapm_widgets = ARRAY_SIZE(kabylake_widgets), | |
945 | .dapm_routes = kabylake_map, | |
946 | .num_dapm_routes = ARRAY_SIZE(kabylake_map), | |
947 | .codec_conf = max98927_codec_conf, | |
948 | .num_configs = ARRAY_SIZE(max98927_codec_conf), | |
949 | .fully_routed = true, | |
950 | .late_probe = kabylake_card_late_probe, | |
951 | }; | |
952 | ||
c0642570 KC |
953 | /* kabylake audio machine driver for RT5663 */ |
954 | static struct snd_soc_card kabylake_audio_card_rt5663 = { | |
955 | .name = "kblrt5663", | |
956 | .owner = THIS_MODULE, | |
957 | .dai_link = kabylake_5663_dais, | |
958 | .num_links = ARRAY_SIZE(kabylake_5663_dais), | |
959 | .controls = kabylake_5663_controls, | |
960 | .num_controls = ARRAY_SIZE(kabylake_5663_controls), | |
961 | .dapm_widgets = kabylake_5663_widgets, | |
962 | .num_dapm_widgets = ARRAY_SIZE(kabylake_5663_widgets), | |
963 | .dapm_routes = kabylake_5663_map, | |
964 | .num_dapm_routes = ARRAY_SIZE(kabylake_5663_map), | |
965 | .fully_routed = true, | |
966 | .late_probe = kabylake_card_late_probe, | |
967 | }; | |
968 | ||
ec040dd5 N |
969 | static int kabylake_audio_probe(struct platform_device *pdev) |
970 | { | |
971 | struct kbl_rt5663_private *ctx; | |
972 | struct skl_machine_pdata *pdata; | |
f7f61e08 | 973 | int ret; |
ec040dd5 | 974 | |
52726816 | 975 | ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); |
ec040dd5 N |
976 | if (!ctx) |
977 | return -ENOMEM; | |
978 | ||
979 | INIT_LIST_HEAD(&ctx->hdmi_pcm_list); | |
980 | ||
c0642570 KC |
981 | kabylake_audio_card = |
982 | (struct snd_soc_card *)pdev->id_entry->driver_data; | |
983 | ||
984 | kabylake_audio_card->dev = &pdev->dev; | |
985 | snd_soc_card_set_drvdata(kabylake_audio_card, ctx); | |
ec040dd5 N |
986 | |
987 | pdata = dev_get_drvdata(&pdev->dev); | |
988 | if (pdata) | |
989 | dmic_constraints = pdata->dmic_num == 2 ? | |
990 | &constraints_dmic_2ch : &constraints_dmic_channels; | |
991 | ||
f7f61e08 HP |
992 | ctx->mclk = devm_clk_get(&pdev->dev, "ssp1_mclk"); |
993 | if (IS_ERR(ctx->mclk)) { | |
994 | ret = PTR_ERR(ctx->mclk); | |
995 | if (ret == -ENOENT) { | |
996 | dev_info(&pdev->dev, | |
997 | "Failed to get ssp1_sclk, defer probe\n"); | |
998 | return -EPROBE_DEFER; | |
999 | } | |
1000 | ||
1001 | dev_err(&pdev->dev, "Failed to get ssp1_mclk with err:%d\n", | |
1002 | ret); | |
1003 | return ret; | |
1004 | } | |
1005 | ||
1006 | ctx->sclk = devm_clk_get(&pdev->dev, "ssp1_sclk"); | |
1007 | if (IS_ERR(ctx->sclk)) { | |
1008 | ret = PTR_ERR(ctx->sclk); | |
1009 | if (ret == -ENOENT) { | |
1010 | dev_info(&pdev->dev, | |
1011 | "Failed to get ssp1_sclk, defer probe\n"); | |
1012 | return -EPROBE_DEFER; | |
1013 | } | |
1014 | ||
1015 | dev_err(&pdev->dev, "Failed to get ssp1_sclk with err:%d\n", | |
1016 | ret); | |
1017 | return ret; | |
1018 | } | |
1019 | ||
c0642570 | 1020 | return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card); |
ec040dd5 N |
1021 | } |
1022 | ||
1023 | static const struct platform_device_id kbl_board_ids[] = { | |
c0642570 KC |
1024 | { |
1025 | .name = "kbl_rt5663", | |
1026 | .driver_data = (kernel_ulong_t)&kabylake_audio_card_rt5663, | |
1027 | }, | |
1028 | { | |
1029 | .name = "kbl_rt5663_m98927", | |
1030 | .driver_data = | |
1031 | (kernel_ulong_t)&kabylake_audio_card_rt5663_m98927, | |
1032 | }, | |
ec040dd5 N |
1033 | { } |
1034 | }; | |
1035 | ||
1036 | static struct platform_driver kabylake_audio = { | |
1037 | .probe = kabylake_audio_probe, | |
1038 | .driver = { | |
1039 | .name = "kbl_rt5663_m98927", | |
1040 | .pm = &snd_soc_pm_ops, | |
1041 | }, | |
1042 | .id_table = kbl_board_ids, | |
1043 | }; | |
1044 | ||
1045 | module_platform_driver(kabylake_audio) | |
1046 | ||
1047 | /* Module information */ | |
1048 | MODULE_DESCRIPTION("Audio Machine driver-RT5663 & MAX98927 in I2S mode"); | |
1049 | MODULE_AUTHOR("Naveen M <naveen.m@intel.com>"); | |
1050 | MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); | |
1051 | MODULE_LICENSE("GPL v2"); | |
c0642570 | 1052 | MODULE_ALIAS("platform:kbl_rt5663"); |
ec040dd5 | 1053 | MODULE_ALIAS("platform:kbl_rt5663_m98927"); |