]>
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), | |
207 | }; | |
208 | ||
209 | static const struct snd_soc_dapm_route kabylake_5663_map[] = { | |
210 | { "Headphone Jack", NULL, "HPOL" }, | |
211 | { "Headphone Jack", NULL, "HPOR" }, | |
212 | ||
213 | /* other jacks */ | |
214 | { "IN1P", NULL, "Headset Mic" }, | |
215 | { "IN1N", NULL, "Headset Mic" }, | |
216 | ||
217 | { "HDMI", NULL, "hif5 Output" }, | |
218 | { "DP", NULL, "hif6 Output" }, | |
219 | ||
220 | /* CODEC BE connections */ | |
221 | { "AIF Playback", NULL, "ssp1 Tx" }, | |
222 | { "ssp1 Tx", NULL, "codec1_out" }, | |
223 | ||
224 | { "codec0_in", NULL, "ssp1 Rx" }, | |
225 | { "ssp1 Rx", NULL, "AIF Capture" }, | |
226 | ||
227 | { "hifi2", NULL, "iDisp2 Tx"}, | |
228 | { "iDisp2 Tx", NULL, "iDisp2_out"}, | |
229 | { "hifi1", NULL, "iDisp1 Tx"}, | |
230 | { "iDisp1 Tx", NULL, "iDisp1_out"}, | |
231 | }; | |
232 | ||
ec040dd5 N |
233 | static struct snd_soc_codec_conf max98927_codec_conf[] = { |
234 | { | |
235 | .dev_name = MAXIM_DEV0_NAME, | |
236 | .name_prefix = "Right", | |
237 | }, | |
238 | { | |
239 | .dev_name = MAXIM_DEV1_NAME, | |
240 | .name_prefix = "Left", | |
241 | }, | |
242 | }; | |
243 | ||
244 | static struct snd_soc_dai_link_component max98927_codec_components[] = { | |
245 | { /* Left */ | |
246 | .name = MAXIM_DEV0_NAME, | |
247 | .dai_name = KBL_MAXIM_CODEC_DAI, | |
248 | }, | |
249 | { /* Right */ | |
250 | .name = MAXIM_DEV1_NAME, | |
251 | .dai_name = KBL_MAXIM_CODEC_DAI, | |
252 | }, | |
253 | }; | |
254 | ||
255 | static int kabylake_rt5663_fe_init(struct snd_soc_pcm_runtime *rtd) | |
256 | { | |
257 | int ret; | |
258 | struct snd_soc_dapm_context *dapm; | |
259 | struct snd_soc_component *component = rtd->cpu_dai->component; | |
260 | ||
261 | dapm = snd_soc_component_get_dapm(component); | |
262 | ret = snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); | |
263 | if (ret) { | |
264 | dev_err(rtd->dev, "Ref Cap ignore suspend failed %d\n", ret); | |
265 | return ret; | |
266 | } | |
267 | ||
268 | return ret; | |
269 | } | |
270 | ||
271 | static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) | |
272 | { | |
273 | int ret; | |
274 | struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); | |
275 | struct snd_soc_codec *codec = rtd->codec; | |
ae09a478 | 276 | struct snd_soc_jack *jack; |
ec040dd5 N |
277 | |
278 | /* | |
279 | * Headset buttons map to the google Reference headset. | |
280 | * These can be configured by userspace. | |
281 | */ | |
c0642570 | 282 | ret = snd_soc_card_jack_new(kabylake_audio_card, "Headset Jack", |
ec040dd5 N |
283 | SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | |
284 | SND_JACK_BTN_2 | SND_JACK_BTN_3, &ctx->kabylake_headset, | |
285 | NULL, 0); | |
286 | if (ret) { | |
287 | dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); | |
288 | return ret; | |
289 | } | |
ae09a478 N |
290 | |
291 | jack = &ctx->kabylake_headset; | |
38a5882e | 292 | snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); |
ae09a478 N |
293 | snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); |
294 | snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); | |
295 | snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); | |
296 | ||
ec040dd5 | 297 | rt5663_set_jack_detect(codec, &ctx->kabylake_headset); |
c0642570 KC |
298 | return ret; |
299 | } | |
300 | ||
301 | static int kabylake_rt5663_max98927_codec_init(struct snd_soc_pcm_runtime *rtd) | |
302 | { | |
303 | int ret; | |
304 | ||
305 | ret = kabylake_rt5663_codec_init(rtd); | |
306 | if (ret) | |
307 | return ret; | |
308 | ||
ec040dd5 N |
309 | ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); |
310 | if (ret) { | |
311 | dev_err(rtd->dev, "SoC DMIC ignore suspend failed %d\n", ret); | |
312 | return ret; | |
313 | } | |
314 | ||
315 | return ret; | |
316 | } | |
317 | ||
c0642570 | 318 | static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) |
ec040dd5 N |
319 | { |
320 | struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); | |
321 | struct snd_soc_dai *dai = rtd->codec_dai; | |
322 | struct kbl_hdmi_pcm *pcm; | |
323 | ||
324 | pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); | |
325 | if (!pcm) | |
326 | return -ENOMEM; | |
327 | ||
c0642570 | 328 | pcm->device = device; |
ec040dd5 N |
329 | pcm->codec_dai = dai; |
330 | ||
331 | list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); | |
332 | ||
333 | return 0; | |
334 | } | |
335 | ||
c0642570 | 336 | static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) |
ec040dd5 | 337 | { |
c0642570 KC |
338 | return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI1_PB); |
339 | } | |
ec040dd5 | 340 | |
c0642570 KC |
341 | static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) |
342 | { | |
343 | return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI2_PB); | |
ec040dd5 N |
344 | } |
345 | ||
346 | static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) | |
347 | { | |
c0642570 KC |
348 | return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI3_PB); |
349 | } | |
ec040dd5 | 350 | |
c0642570 KC |
351 | static int kabylake_5663_hdmi1_init(struct snd_soc_pcm_runtime *rtd) |
352 | { | |
353 | return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_5663_HDMI1_PB); | |
354 | } | |
ec040dd5 | 355 | |
c0642570 KC |
356 | static int kabylake_5663_hdmi2_init(struct snd_soc_pcm_runtime *rtd) |
357 | { | |
358 | return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_5663_HDMI2_PB); | |
ec040dd5 N |
359 | } |
360 | ||
361 | static unsigned int rates[] = { | |
362 | 48000, | |
363 | }; | |
364 | ||
2d5f8487 | 365 | static const struct snd_pcm_hw_constraint_list constraints_rates = { |
ec040dd5 N |
366 | .count = ARRAY_SIZE(rates), |
367 | .list = rates, | |
368 | .mask = 0, | |
369 | }; | |
370 | ||
371 | static unsigned int channels[] = { | |
372 | 2, | |
373 | }; | |
374 | ||
2d5f8487 | 375 | static const struct snd_pcm_hw_constraint_list constraints_channels = { |
ec040dd5 N |
376 | .count = ARRAY_SIZE(channels), |
377 | .list = channels, | |
378 | .mask = 0, | |
379 | }; | |
380 | ||
381 | static int kbl_fe_startup(struct snd_pcm_substream *substream) | |
382 | { | |
383 | struct snd_pcm_runtime *runtime = substream->runtime; | |
384 | ||
385 | /* | |
386 | * On this platform for PCM device we support, | |
387 | * 48Khz | |
388 | * stereo | |
389 | * 16 bit audio | |
390 | */ | |
391 | ||
392 | runtime->hw.channels_max = 2; | |
393 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | |
394 | &constraints_channels); | |
395 | ||
396 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; | |
397 | snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); | |
398 | ||
399 | snd_pcm_hw_constraint_list(runtime, 0, | |
400 | SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); | |
401 | ||
402 | return 0; | |
403 | } | |
404 | ||
405 | static const struct snd_soc_ops kabylake_rt5663_fe_ops = { | |
406 | .startup = kbl_fe_startup, | |
407 | }; | |
408 | ||
409 | static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, | |
410 | struct snd_pcm_hw_params *params) | |
411 | { | |
412 | struct snd_interval *rate = hw_param_interval(params, | |
413 | SNDRV_PCM_HW_PARAM_RATE); | |
414 | struct snd_interval *channels = hw_param_interval(params, | |
415 | SNDRV_PCM_HW_PARAM_CHANNELS); | |
416 | struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | |
e78407fb HP |
417 | struct snd_soc_dpcm *dpcm = container_of( |
418 | params, struct snd_soc_dpcm, hw_params); | |
419 | struct snd_soc_dai_link *fe_dai_link = dpcm->fe->dai_link; | |
420 | struct snd_soc_dai_link *be_dai_link = dpcm->be->dai_link; | |
ec040dd5 | 421 | |
e78407fb HP |
422 | /* |
423 | * The ADSP will convert the FE rate to 48k, stereo, 24 bit | |
424 | */ | |
425 | if (!strcmp(fe_dai_link->name, "Kbl Audio Port") || | |
426 | !strcmp(fe_dai_link->name, "Kbl Audio Headset Playback") || | |
427 | !strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) { | |
428 | rate->min = rate->max = 48000; | |
429 | channels->min = channels->max = 2; | |
430 | snd_mask_none(fmt); | |
431 | snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE); | |
432 | } | |
433 | /* | |
434 | * The speaker on the SSP0 supports S16_LE and not S24_LE. | |
435 | * thus changing the mask here | |
436 | */ | |
437 | if (!strcmp(be_dai_link->name, "SSP0-Codec")) | |
438 | snd_mask_set(fmt, SNDRV_PCM_FORMAT_S16_LE); | |
ec040dd5 N |
439 | |
440 | return 0; | |
441 | } | |
442 | ||
443 | static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream, | |
444 | struct snd_pcm_hw_params *params) | |
445 | { | |
446 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
447 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | |
448 | int ret; | |
449 | ||
ec040dd5 | 450 | /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */ |
d46b1828 HP |
451 | rt5663_sel_asrc_clk_src(codec_dai->codec, |
452 | RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER, | |
453 | RT5663_CLK_SEL_I2S1_ASRC); | |
ec040dd5 | 454 | |
d46b1828 HP |
455 | ret = snd_soc_dai_set_sysclk(codec_dai, |
456 | RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN); | |
ec040dd5 N |
457 | if (ret < 0) |
458 | dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); | |
459 | ||
460 | return ret; | |
461 | } | |
462 | ||
463 | static struct snd_soc_ops kabylake_rt5663_ops = { | |
464 | .hw_params = kabylake_rt5663_hw_params, | |
465 | }; | |
466 | ||
467 | static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, | |
468 | struct snd_pcm_hw_params *params) | |
469 | { | |
470 | struct snd_interval *channels = hw_param_interval(params, | |
471 | SNDRV_PCM_HW_PARAM_CHANNELS); | |
472 | ||
473 | if (params_channels(params) == 2 || DMIC_CH(dmic_constraints) == 2) | |
474 | channels->min = channels->max = 2; | |
475 | else | |
476 | channels->min = channels->max = 4; | |
477 | ||
478 | return 0; | |
479 | } | |
480 | ||
7a679ea7 HP |
481 | static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, |
482 | struct snd_pcm_hw_params *params) | |
483 | { | |
484 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
485 | int ret = 0, j; | |
486 | ||
487 | for (j = 0; j < rtd->num_codecs; j++) { | |
488 | struct snd_soc_dai *codec_dai = rtd->codec_dais[j]; | |
489 | ||
490 | if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME)) { | |
491 | /* | |
492 | * Use channel 4 and 5 for the first amp | |
493 | */ | |
494 | ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16); | |
495 | if (ret < 0) { | |
496 | dev_err(rtd->dev, "set TDM slot err:%d\n", ret); | |
497 | return ret; | |
498 | } | |
499 | } | |
500 | if (!strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) { | |
501 | /* | |
502 | * Use channel 6 and 7 for the second amp | |
503 | */ | |
504 | ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 3, 8, 16); | |
505 | if (ret < 0) { | |
506 | dev_err(rtd->dev, "set TDM slot err:%d\n", ret); | |
507 | return ret; | |
508 | } | |
509 | } | |
510 | } | |
511 | return ret; | |
512 | } | |
513 | ||
514 | static struct snd_soc_ops kabylake_ssp0_ops = { | |
515 | .hw_params = kabylake_ssp0_hw_params, | |
516 | }; | |
517 | ||
ec040dd5 N |
518 | static unsigned int channels_dmic[] = { |
519 | 2, 4, | |
520 | }; | |
521 | ||
522 | static struct snd_pcm_hw_constraint_list constraints_dmic_channels = { | |
523 | .count = ARRAY_SIZE(channels_dmic), | |
524 | .list = channels_dmic, | |
525 | .mask = 0, | |
526 | }; | |
527 | ||
528 | static const unsigned int dmic_2ch[] = { | |
529 | 2, | |
530 | }; | |
531 | ||
532 | static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = { | |
533 | .count = ARRAY_SIZE(dmic_2ch), | |
534 | .list = dmic_2ch, | |
535 | .mask = 0, | |
536 | }; | |
537 | ||
538 | static int kabylake_dmic_startup(struct snd_pcm_substream *substream) | |
539 | { | |
540 | struct snd_pcm_runtime *runtime = substream->runtime; | |
541 | ||
542 | runtime->hw.channels_max = DMIC_CH(dmic_constraints); | |
543 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | |
544 | dmic_constraints); | |
545 | ||
546 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | |
547 | SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); | |
548 | } | |
549 | ||
550 | static struct snd_soc_ops kabylake_dmic_ops = { | |
551 | .startup = kabylake_dmic_startup, | |
552 | }; | |
553 | ||
554 | static unsigned int rates_16000[] = { | |
555 | 16000, | |
556 | }; | |
557 | ||
2d5f8487 | 558 | static const struct snd_pcm_hw_constraint_list constraints_16000 = { |
ec040dd5 N |
559 | .count = ARRAY_SIZE(rates_16000), |
560 | .list = rates_16000, | |
561 | }; | |
562 | ||
563 | static const unsigned int ch_mono[] = { | |
564 | 1, | |
565 | }; | |
566 | ||
567 | static const struct snd_pcm_hw_constraint_list constraints_refcap = { | |
568 | .count = ARRAY_SIZE(ch_mono), | |
569 | .list = ch_mono, | |
570 | }; | |
571 | ||
572 | static int kabylake_refcap_startup(struct snd_pcm_substream *substream) | |
573 | { | |
574 | substream->runtime->hw.channels_max = 1; | |
575 | snd_pcm_hw_constraint_list(substream->runtime, 0, | |
576 | SNDRV_PCM_HW_PARAM_CHANNELS, | |
577 | &constraints_refcap); | |
578 | ||
579 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | |
580 | SNDRV_PCM_HW_PARAM_RATE, | |
581 | &constraints_16000); | |
582 | } | |
583 | ||
584 | static struct snd_soc_ops skylaye_refcap_ops = { | |
585 | .startup = kabylake_refcap_startup, | |
586 | }; | |
587 | ||
588 | /* kabylake digital audio interface glue - connects codec <--> CPU */ | |
589 | static struct snd_soc_dai_link kabylake_dais[] = { | |
590 | /* Front End DAI links */ | |
591 | [KBL_DPCM_AUDIO_PB] = { | |
592 | .name = "Kbl Audio Port", | |
593 | .stream_name = "Audio", | |
594 | .cpu_dai_name = "System Pin", | |
595 | .platform_name = "0000:00:1f.3", | |
596 | .dynamic = 1, | |
597 | .codec_name = "snd-soc-dummy", | |
598 | .codec_dai_name = "snd-soc-dummy-dai", | |
599 | .nonatomic = 1, | |
600 | .init = kabylake_rt5663_fe_init, | |
601 | .trigger = { | |
602 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
603 | .dpcm_playback = 1, | |
604 | .ops = &kabylake_rt5663_fe_ops, | |
605 | }, | |
606 | [KBL_DPCM_AUDIO_CP] = { | |
607 | .name = "Kbl Audio Capture Port", | |
608 | .stream_name = "Audio Record", | |
609 | .cpu_dai_name = "System Pin", | |
610 | .platform_name = "0000:00:1f.3", | |
611 | .dynamic = 1, | |
612 | .codec_name = "snd-soc-dummy", | |
613 | .codec_dai_name = "snd-soc-dummy-dai", | |
614 | .nonatomic = 1, | |
615 | .trigger = { | |
616 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
617 | .dpcm_capture = 1, | |
618 | .ops = &kabylake_rt5663_fe_ops, | |
619 | }, | |
b32ee384 NM |
620 | [KBL_DPCM_AUDIO_HS_PB] = { |
621 | .name = "Kbl Audio Headset Playback", | |
622 | .stream_name = "Headset Audio", | |
623 | .cpu_dai_name = "System Pin2", | |
624 | .codec_name = "snd-soc-dummy", | |
625 | .codec_dai_name = "snd-soc-dummy-dai", | |
626 | .platform_name = "0000:00:1f.3", | |
627 | .dpcm_playback = 1, | |
628 | .nonatomic = 1, | |
629 | .dynamic = 1, | |
630 | }, | |
631 | [KBL_DPCM_AUDIO_ECHO_REF_CP] = { | |
632 | .name = "Kbl Audio Echo Reference cap", | |
633 | .stream_name = "Echoreference Capture", | |
634 | .cpu_dai_name = "Echoref Pin", | |
635 | .codec_name = "snd-soc-dummy", | |
636 | .codec_dai_name = "snd-soc-dummy-dai", | |
637 | .platform_name = "0000:00:1f.3", | |
638 | .init = NULL, | |
639 | .capture_only = 1, | |
640 | .nonatomic = 1, | |
641 | }, | |
ec040dd5 N |
642 | [KBL_DPCM_AUDIO_REF_CP] = { |
643 | .name = "Kbl Audio Reference cap", | |
644 | .stream_name = "Wake on Voice", | |
645 | .cpu_dai_name = "Reference Pin", | |
646 | .codec_name = "snd-soc-dummy", | |
647 | .codec_dai_name = "snd-soc-dummy-dai", | |
648 | .platform_name = "0000:00:1f.3", | |
649 | .init = NULL, | |
650 | .dpcm_capture = 1, | |
651 | .nonatomic = 1, | |
652 | .dynamic = 1, | |
653 | .ops = &skylaye_refcap_ops, | |
654 | }, | |
655 | [KBL_DPCM_AUDIO_DMIC_CP] = { | |
656 | .name = "Kbl Audio DMIC cap", | |
657 | .stream_name = "dmiccap", | |
658 | .cpu_dai_name = "DMIC Pin", | |
659 | .codec_name = "snd-soc-dummy", | |
660 | .codec_dai_name = "snd-soc-dummy-dai", | |
661 | .platform_name = "0000:00:1f.3", | |
662 | .init = NULL, | |
663 | .dpcm_capture = 1, | |
664 | .nonatomic = 1, | |
665 | .dynamic = 1, | |
666 | .ops = &kabylake_dmic_ops, | |
667 | }, | |
668 | [KBL_DPCM_AUDIO_HDMI1_PB] = { | |
669 | .name = "Kbl HDMI Port1", | |
670 | .stream_name = "Hdmi1", | |
671 | .cpu_dai_name = "HDMI1 Pin", | |
672 | .codec_name = "snd-soc-dummy", | |
673 | .codec_dai_name = "snd-soc-dummy-dai", | |
674 | .platform_name = "0000:00:1f.3", | |
675 | .dpcm_playback = 1, | |
676 | .init = NULL, | |
677 | .trigger = { | |
678 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
679 | .nonatomic = 1, | |
680 | .dynamic = 1, | |
681 | }, | |
682 | [KBL_DPCM_AUDIO_HDMI2_PB] = { | |
683 | .name = "Kbl HDMI Port2", | |
684 | .stream_name = "Hdmi2", | |
685 | .cpu_dai_name = "HDMI2 Pin", | |
686 | .codec_name = "snd-soc-dummy", | |
687 | .codec_dai_name = "snd-soc-dummy-dai", | |
688 | .platform_name = "0000:00:1f.3", | |
689 | .dpcm_playback = 1, | |
690 | .init = NULL, | |
691 | .trigger = { | |
692 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
693 | .nonatomic = 1, | |
694 | .dynamic = 1, | |
695 | }, | |
696 | [KBL_DPCM_AUDIO_HDMI3_PB] = { | |
697 | .name = "Kbl HDMI Port3", | |
698 | .stream_name = "Hdmi3", | |
699 | .cpu_dai_name = "HDMI3 Pin", | |
700 | .codec_name = "snd-soc-dummy", | |
701 | .codec_dai_name = "snd-soc-dummy-dai", | |
702 | .platform_name = "0000:00:1f.3", | |
703 | .trigger = { | |
704 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
705 | .dpcm_playback = 1, | |
706 | .init = NULL, | |
707 | .nonatomic = 1, | |
708 | .dynamic = 1, | |
709 | }, | |
710 | ||
711 | /* Back End DAI links */ | |
712 | { | |
713 | /* SSP0 - Codec */ | |
714 | .name = "SSP0-Codec", | |
715 | .id = 0, | |
716 | .cpu_dai_name = "SSP0 Pin", | |
717 | .platform_name = "0000:00:1f.3", | |
718 | .no_pcm = 1, | |
719 | .codecs = max98927_codec_components, | |
720 | .num_codecs = ARRAY_SIZE(max98927_codec_components), | |
7a679ea7 | 721 | .dai_fmt = SND_SOC_DAIFMT_DSP_B | |
ec040dd5 N |
722 | SND_SOC_DAIFMT_NB_NF | |
723 | SND_SOC_DAIFMT_CBS_CFS, | |
724 | .ignore_pmdown_time = 1, | |
725 | .be_hw_params_fixup = kabylake_ssp_fixup, | |
726 | .dpcm_playback = 1, | |
7a679ea7 | 727 | .ops = &kabylake_ssp0_ops, |
ec040dd5 N |
728 | }, |
729 | { | |
730 | /* SSP1 - Codec */ | |
731 | .name = "SSP1-Codec", | |
732 | .id = 1, | |
733 | .cpu_dai_name = "SSP1 Pin", | |
734 | .platform_name = "0000:00:1f.3", | |
735 | .no_pcm = 1, | |
736 | .codec_name = "i2c-10EC5663:00", | |
737 | .codec_dai_name = KBL_REALTEK_CODEC_DAI, | |
c0642570 | 738 | .init = kabylake_rt5663_max98927_codec_init, |
ec040dd5 N |
739 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
740 | SND_SOC_DAIFMT_CBS_CFS, | |
741 | .ignore_pmdown_time = 1, | |
742 | .be_hw_params_fixup = kabylake_ssp_fixup, | |
743 | .ops = &kabylake_rt5663_ops, | |
744 | .dpcm_playback = 1, | |
745 | .dpcm_capture = 1, | |
746 | }, | |
747 | { | |
748 | .name = "dmic01", | |
749 | .id = 2, | |
750 | .cpu_dai_name = "DMIC01 Pin", | |
751 | .codec_name = "dmic-codec", | |
752 | .codec_dai_name = "dmic-hifi", | |
753 | .platform_name = "0000:00:1f.3", | |
754 | .be_hw_params_fixup = kabylake_dmic_fixup, | |
755 | .ignore_suspend = 1, | |
756 | .dpcm_capture = 1, | |
757 | .no_pcm = 1, | |
758 | }, | |
759 | { | |
760 | .name = "iDisp1", | |
761 | .id = 3, | |
762 | .cpu_dai_name = "iDisp1 Pin", | |
763 | .codec_name = "ehdaudio0D2", | |
764 | .codec_dai_name = "intel-hdmi-hifi1", | |
765 | .platform_name = "0000:00:1f.3", | |
766 | .dpcm_playback = 1, | |
767 | .init = kabylake_hdmi1_init, | |
768 | .no_pcm = 1, | |
769 | }, | |
770 | { | |
771 | .name = "iDisp2", | |
772 | .id = 4, | |
773 | .cpu_dai_name = "iDisp2 Pin", | |
774 | .codec_name = "ehdaudio0D2", | |
775 | .codec_dai_name = "intel-hdmi-hifi2", | |
776 | .platform_name = "0000:00:1f.3", | |
777 | .init = kabylake_hdmi2_init, | |
778 | .dpcm_playback = 1, | |
779 | .no_pcm = 1, | |
780 | }, | |
781 | { | |
782 | .name = "iDisp3", | |
783 | .id = 5, | |
784 | .cpu_dai_name = "iDisp3 Pin", | |
785 | .codec_name = "ehdaudio0D2", | |
786 | .codec_dai_name = "intel-hdmi-hifi3", | |
787 | .platform_name = "0000:00:1f.3", | |
788 | .init = kabylake_hdmi3_init, | |
789 | .dpcm_playback = 1, | |
790 | .no_pcm = 1, | |
791 | }, | |
792 | }; | |
793 | ||
c0642570 KC |
794 | static struct snd_soc_dai_link kabylake_5663_dais[] = { |
795 | /* Front End DAI links */ | |
796 | [KBL_DPCM_AUDIO_5663_PB] = { | |
797 | .name = "Kbl Audio Port", | |
798 | .stream_name = "Audio", | |
799 | .cpu_dai_name = "System Pin", | |
800 | .platform_name = "0000:00:1f.3", | |
801 | .dynamic = 1, | |
802 | .codec_name = "snd-soc-dummy", | |
803 | .codec_dai_name = "snd-soc-dummy-dai", | |
804 | .nonatomic = 1, | |
805 | .trigger = { | |
806 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
807 | .dpcm_playback = 1, | |
808 | .ops = &kabylake_rt5663_fe_ops, | |
809 | }, | |
810 | [KBL_DPCM_AUDIO_5663_CP] = { | |
811 | .name = "Kbl Audio Capture Port", | |
812 | .stream_name = "Audio Record", | |
813 | .cpu_dai_name = "System Pin", | |
814 | .platform_name = "0000:00:1f.3", | |
815 | .dynamic = 1, | |
816 | .codec_name = "snd-soc-dummy", | |
817 | .codec_dai_name = "snd-soc-dummy-dai", | |
818 | .nonatomic = 1, | |
819 | .trigger = { | |
820 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
821 | .dpcm_capture = 1, | |
822 | .ops = &kabylake_rt5663_fe_ops, | |
823 | }, | |
824 | [KBL_DPCM_AUDIO_5663_HDMI1_PB] = { | |
825 | .name = "Kbl HDMI Port1", | |
826 | .stream_name = "Hdmi1", | |
827 | .cpu_dai_name = "HDMI1 Pin", | |
828 | .codec_name = "snd-soc-dummy", | |
829 | .codec_dai_name = "snd-soc-dummy-dai", | |
830 | .platform_name = "0000:00:1f.3", | |
831 | .dpcm_playback = 1, | |
832 | .init = NULL, | |
833 | .trigger = { | |
834 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
835 | .nonatomic = 1, | |
836 | .dynamic = 1, | |
837 | }, | |
838 | [KBL_DPCM_AUDIO_5663_HDMI2_PB] = { | |
839 | .name = "Kbl HDMI Port2", | |
840 | .stream_name = "Hdmi2", | |
841 | .cpu_dai_name = "HDMI2 Pin", | |
842 | .codec_name = "snd-soc-dummy", | |
843 | .codec_dai_name = "snd-soc-dummy-dai", | |
844 | .platform_name = "0000:00:1f.3", | |
845 | .dpcm_playback = 1, | |
846 | .init = NULL, | |
847 | .trigger = { | |
848 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, | |
849 | .nonatomic = 1, | |
850 | .dynamic = 1, | |
851 | }, | |
852 | ||
853 | /* Back End DAI links */ | |
854 | { | |
855 | /* SSP1 - Codec */ | |
856 | .name = "SSP1-Codec", | |
857 | .id = 0, | |
858 | .cpu_dai_name = "SSP1 Pin", | |
859 | .platform_name = "0000:00:1f.3", | |
860 | .no_pcm = 1, | |
861 | .codec_name = "i2c-10EC5663:00", | |
862 | .codec_dai_name = KBL_REALTEK_CODEC_DAI, | |
863 | .init = kabylake_rt5663_codec_init, | |
864 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | |
865 | SND_SOC_DAIFMT_CBS_CFS, | |
866 | .ignore_pmdown_time = 1, | |
867 | .be_hw_params_fixup = kabylake_ssp_fixup, | |
868 | .ops = &kabylake_rt5663_ops, | |
869 | .dpcm_playback = 1, | |
870 | .dpcm_capture = 1, | |
871 | }, | |
872 | { | |
873 | .name = "iDisp1", | |
874 | .id = 1, | |
875 | .cpu_dai_name = "iDisp1 Pin", | |
876 | .codec_name = "ehdaudio0D2", | |
877 | .codec_dai_name = "intel-hdmi-hifi1", | |
878 | .platform_name = "0000:00:1f.3", | |
879 | .dpcm_playback = 1, | |
880 | .init = kabylake_5663_hdmi1_init, | |
881 | .no_pcm = 1, | |
882 | }, | |
883 | { | |
884 | .name = "iDisp2", | |
885 | .id = 2, | |
886 | .cpu_dai_name = "iDisp2 Pin", | |
887 | .codec_name = "ehdaudio0D2", | |
888 | .codec_dai_name = "intel-hdmi-hifi2", | |
889 | .platform_name = "0000:00:1f.3", | |
890 | .init = kabylake_5663_hdmi2_init, | |
891 | .dpcm_playback = 1, | |
892 | .no_pcm = 1, | |
893 | }, | |
894 | }; | |
895 | ||
ec040dd5 N |
896 | #define NAME_SIZE 32 |
897 | static int kabylake_card_late_probe(struct snd_soc_card *card) | |
898 | { | |
899 | struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card); | |
900 | struct kbl_hdmi_pcm *pcm; | |
3a13347f | 901 | struct snd_soc_codec *codec = NULL; |
ec040dd5 N |
902 | int err, i = 0; |
903 | char jack_name[NAME_SIZE]; | |
904 | ||
905 | list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { | |
3a13347f | 906 | codec = pcm->codec_dai->codec; |
ec040dd5 N |
907 | snprintf(jack_name, sizeof(jack_name), |
908 | "HDMI/DP, pcm=%d Jack", pcm->device); | |
909 | err = snd_soc_card_jack_new(card, jack_name, | |
910 | SND_JACK_AVOUT, &skylake_hdmi[i], | |
911 | NULL, 0); | |
912 | ||
913 | if (err) | |
914 | return err; | |
915 | ||
916 | err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, | |
917 | &skylake_hdmi[i]); | |
918 | if (err < 0) | |
919 | return err; | |
920 | ||
921 | i++; | |
922 | } | |
923 | ||
3a13347f N |
924 | if (!codec) |
925 | return -EINVAL; | |
926 | ||
927 | return hdac_hdmi_jack_port_init(codec, &card->dapm); | |
ec040dd5 N |
928 | } |
929 | ||
930 | /* kabylake audio machine driver for SPT + RT5663 */ | |
c0642570 | 931 | static struct snd_soc_card kabylake_audio_card_rt5663_m98927 = { |
ec040dd5 N |
932 | .name = "kblrt5663max", |
933 | .owner = THIS_MODULE, | |
934 | .dai_link = kabylake_dais, | |
935 | .num_links = ARRAY_SIZE(kabylake_dais), | |
936 | .controls = kabylake_controls, | |
937 | .num_controls = ARRAY_SIZE(kabylake_controls), | |
938 | .dapm_widgets = kabylake_widgets, | |
939 | .num_dapm_widgets = ARRAY_SIZE(kabylake_widgets), | |
940 | .dapm_routes = kabylake_map, | |
941 | .num_dapm_routes = ARRAY_SIZE(kabylake_map), | |
942 | .codec_conf = max98927_codec_conf, | |
943 | .num_configs = ARRAY_SIZE(max98927_codec_conf), | |
944 | .fully_routed = true, | |
945 | .late_probe = kabylake_card_late_probe, | |
946 | }; | |
947 | ||
c0642570 KC |
948 | /* kabylake audio machine driver for RT5663 */ |
949 | static struct snd_soc_card kabylake_audio_card_rt5663 = { | |
950 | .name = "kblrt5663", | |
951 | .owner = THIS_MODULE, | |
952 | .dai_link = kabylake_5663_dais, | |
953 | .num_links = ARRAY_SIZE(kabylake_5663_dais), | |
954 | .controls = kabylake_5663_controls, | |
955 | .num_controls = ARRAY_SIZE(kabylake_5663_controls), | |
956 | .dapm_widgets = kabylake_5663_widgets, | |
957 | .num_dapm_widgets = ARRAY_SIZE(kabylake_5663_widgets), | |
958 | .dapm_routes = kabylake_5663_map, | |
959 | .num_dapm_routes = ARRAY_SIZE(kabylake_5663_map), | |
960 | .fully_routed = true, | |
961 | .late_probe = kabylake_card_late_probe, | |
962 | }; | |
963 | ||
ec040dd5 N |
964 | static int kabylake_audio_probe(struct platform_device *pdev) |
965 | { | |
966 | struct kbl_rt5663_private *ctx; | |
967 | struct skl_machine_pdata *pdata; | |
f7f61e08 | 968 | int ret; |
ec040dd5 N |
969 | |
970 | ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); | |
971 | if (!ctx) | |
972 | return -ENOMEM; | |
973 | ||
974 | INIT_LIST_HEAD(&ctx->hdmi_pcm_list); | |
975 | ||
c0642570 KC |
976 | kabylake_audio_card = |
977 | (struct snd_soc_card *)pdev->id_entry->driver_data; | |
978 | ||
979 | kabylake_audio_card->dev = &pdev->dev; | |
980 | snd_soc_card_set_drvdata(kabylake_audio_card, ctx); | |
ec040dd5 N |
981 | |
982 | pdata = dev_get_drvdata(&pdev->dev); | |
983 | if (pdata) | |
984 | dmic_constraints = pdata->dmic_num == 2 ? | |
985 | &constraints_dmic_2ch : &constraints_dmic_channels; | |
986 | ||
f7f61e08 HP |
987 | ctx->mclk = devm_clk_get(&pdev->dev, "ssp1_mclk"); |
988 | if (IS_ERR(ctx->mclk)) { | |
989 | ret = PTR_ERR(ctx->mclk); | |
990 | if (ret == -ENOENT) { | |
991 | dev_info(&pdev->dev, | |
992 | "Failed to get ssp1_sclk, defer probe\n"); | |
993 | return -EPROBE_DEFER; | |
994 | } | |
995 | ||
996 | dev_err(&pdev->dev, "Failed to get ssp1_mclk with err:%d\n", | |
997 | ret); | |
998 | return ret; | |
999 | } | |
1000 | ||
1001 | ctx->sclk = devm_clk_get(&pdev->dev, "ssp1_sclk"); | |
1002 | if (IS_ERR(ctx->sclk)) { | |
1003 | ret = PTR_ERR(ctx->sclk); | |
1004 | if (ret == -ENOENT) { | |
1005 | dev_info(&pdev->dev, | |
1006 | "Failed to get ssp1_sclk, defer probe\n"); | |
1007 | return -EPROBE_DEFER; | |
1008 | } | |
1009 | ||
1010 | dev_err(&pdev->dev, "Failed to get ssp1_sclk with err:%d\n", | |
1011 | ret); | |
1012 | return ret; | |
1013 | } | |
1014 | ||
c0642570 | 1015 | return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card); |
ec040dd5 N |
1016 | } |
1017 | ||
1018 | static const struct platform_device_id kbl_board_ids[] = { | |
c0642570 KC |
1019 | { |
1020 | .name = "kbl_rt5663", | |
1021 | .driver_data = (kernel_ulong_t)&kabylake_audio_card_rt5663, | |
1022 | }, | |
1023 | { | |
1024 | .name = "kbl_rt5663_m98927", | |
1025 | .driver_data = | |
1026 | (kernel_ulong_t)&kabylake_audio_card_rt5663_m98927, | |
1027 | }, | |
ec040dd5 N |
1028 | { } |
1029 | }; | |
1030 | ||
1031 | static struct platform_driver kabylake_audio = { | |
1032 | .probe = kabylake_audio_probe, | |
1033 | .driver = { | |
1034 | .name = "kbl_rt5663_m98927", | |
1035 | .pm = &snd_soc_pm_ops, | |
1036 | }, | |
1037 | .id_table = kbl_board_ids, | |
1038 | }; | |
1039 | ||
1040 | module_platform_driver(kabylake_audio) | |
1041 | ||
1042 | /* Module information */ | |
1043 | MODULE_DESCRIPTION("Audio Machine driver-RT5663 & MAX98927 in I2S mode"); | |
1044 | MODULE_AUTHOR("Naveen M <naveen.m@intel.com>"); | |
1045 | MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); | |
1046 | MODULE_LICENSE("GPL v2"); | |
c0642570 | 1047 | MODULE_ALIAS("platform:kbl_rt5663"); |
ec040dd5 | 1048 | MODULE_ALIAS("platform:kbl_rt5663_m98927"); |