blob: e45b6feca076d77be5bd9d9e3277ed145daca424 [file] [log] [blame]
Naveen Mec040dd2017-05-15 13:42:16 +05301/*
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
Naveen Mae09a472017-09-15 13:43:21 +053020#include <linux/input.h>
Naveen Mec040dd2017-05-15 13:42:16 +053021#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"
31
32#define KBL_REALTEK_CODEC_DAI "rt5663-aif"
33#define KBL_MAXIM_CODEC_DAI "max98927-aif1"
34#define DMIC_CH(p) p->list[p->count-1]
35#define MAXIM_DEV0_NAME "i2c-MX98927:00"
36#define MAXIM_DEV1_NAME "i2c-MX98927:01"
37
Kevin Chengc0642572017-07-27 16:38:36 +080038static struct snd_soc_card *kabylake_audio_card;
Naveen Mec040dd2017-05-15 13:42:16 +053039static const struct snd_pcm_hw_constraint_list *dmic_constraints;
40static struct snd_soc_jack skylake_hdmi[3];
41
42struct kbl_hdmi_pcm {
43 struct list_head head;
44 struct snd_soc_dai *codec_dai;
45 int device;
46};
47
48struct kbl_rt5663_private {
49 struct snd_soc_jack kabylake_headset;
50 struct list_head hdmi_pcm_list;
51};
52
53enum {
54 KBL_DPCM_AUDIO_PB = 0,
55 KBL_DPCM_AUDIO_CP,
Naveen Manoharb32ee382017-08-02 11:43:34 +053056 KBL_DPCM_AUDIO_HS_PB,
57 KBL_DPCM_AUDIO_ECHO_REF_CP,
Naveen Mec040dd2017-05-15 13:42:16 +053058 KBL_DPCM_AUDIO_REF_CP,
59 KBL_DPCM_AUDIO_DMIC_CP,
60 KBL_DPCM_AUDIO_HDMI1_PB,
61 KBL_DPCM_AUDIO_HDMI2_PB,
62 KBL_DPCM_AUDIO_HDMI3_PB,
63};
64
65static const struct snd_kcontrol_new kabylake_controls[] = {
66 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
67 SOC_DAPM_PIN_SWITCH("Headset Mic"),
68 SOC_DAPM_PIN_SWITCH("Left Spk"),
69 SOC_DAPM_PIN_SWITCH("Right Spk"),
70};
71
72static const struct snd_soc_dapm_widget kabylake_widgets[] = {
73 SND_SOC_DAPM_HP("Headphone Jack", NULL),
74 SND_SOC_DAPM_MIC("Headset Mic", NULL),
75 SND_SOC_DAPM_SPK("Left Spk", NULL),
76 SND_SOC_DAPM_SPK("Right Spk", NULL),
77 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
Naveen Mc20252c2017-08-26 04:04:09 +053078 SND_SOC_DAPM_SPK("HDMI1", NULL),
79 SND_SOC_DAPM_SPK("HDMI2", NULL),
80 SND_SOC_DAPM_SPK("HDMI3", NULL),
Naveen Mec040dd2017-05-15 13:42:16 +053081
82};
83
84static const struct snd_soc_dapm_route kabylake_map[] = {
85 /* HP jack connectors - unknown if we have jack detection */
86 { "Headphone Jack", NULL, "HPOL" },
87 { "Headphone Jack", NULL, "HPOR" },
88
89 /* speaker */
90 { "Left Spk", NULL, "Left BE_OUT" },
91 { "Right Spk", NULL, "Right BE_OUT" },
92
93 /* other jacks */
94 { "IN1P", NULL, "Headset Mic" },
95 { "IN1N", NULL, "Headset Mic" },
96 { "DMic", NULL, "SoC DMIC" },
97
Naveen Mec040dd2017-05-15 13:42:16 +053098 /* CODEC BE connections */
99 { "Left HiFi Playback", NULL, "ssp0 Tx" },
100 { "Right HiFi Playback", NULL, "ssp0 Tx" },
Naveen Manohar0b061222017-08-02 11:43:35 +0530101 { "ssp0 Tx", NULL, "spk_out" },
Naveen Mec040dd2017-05-15 13:42:16 +0530102
103 { "AIF Playback", NULL, "ssp1 Tx" },
Naveen Manohar0b061222017-08-02 11:43:35 +0530104 { "ssp1 Tx", NULL, "hs_out" },
Naveen Mec040dd2017-05-15 13:42:16 +0530105
Naveen Manohar0b061222017-08-02 11:43:35 +0530106 { "hs_in", NULL, "ssp1 Rx" },
Naveen Mec040dd2017-05-15 13:42:16 +0530107 { "ssp1 Rx", NULL, "AIF Capture" },
108
Naveen Manohar64220b92017-08-26 03:21:39 +0530109 /* IV feedback path */
110 { "codec0_fb_in", NULL, "ssp0 Rx"},
111 { "ssp0 Rx", NULL, "Left HiFi Capture" },
112 { "ssp0 Rx", NULL, "Right HiFi Capture" },
113
Naveen Mec040dd2017-05-15 13:42:16 +0530114 /* DMIC */
115 { "dmic01_hifi", NULL, "DMIC01 Rx" },
116 { "DMIC01 Rx", NULL, "DMIC AIF" },
117
118 { "hifi3", NULL, "iDisp3 Tx"},
119 { "iDisp3 Tx", NULL, "iDisp3_out"},
120 { "hifi2", NULL, "iDisp2 Tx"},
121 { "iDisp2 Tx", NULL, "iDisp2_out"},
122 { "hifi1", NULL, "iDisp1 Tx"},
123 { "iDisp1 Tx", NULL, "iDisp1_out"},
124};
125
Kevin Chengc0642572017-07-27 16:38:36 +0800126enum {
127 KBL_DPCM_AUDIO_5663_PB = 0,
128 KBL_DPCM_AUDIO_5663_CP,
129 KBL_DPCM_AUDIO_5663_HDMI1_PB,
130 KBL_DPCM_AUDIO_5663_HDMI2_PB,
131};
132
133static const struct snd_kcontrol_new kabylake_5663_controls[] = {
134 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
135 SOC_DAPM_PIN_SWITCH("Headset Mic"),
136};
137
138static const struct snd_soc_dapm_widget kabylake_5663_widgets[] = {
139 SND_SOC_DAPM_HP("Headphone Jack", NULL),
140 SND_SOC_DAPM_MIC("Headset Mic", NULL),
141 SND_SOC_DAPM_SPK("DP", NULL),
142 SND_SOC_DAPM_SPK("HDMI", NULL),
143};
144
145static const struct snd_soc_dapm_route kabylake_5663_map[] = {
146 { "Headphone Jack", NULL, "HPOL" },
147 { "Headphone Jack", NULL, "HPOR" },
148
149 /* other jacks */
150 { "IN1P", NULL, "Headset Mic" },
151 { "IN1N", NULL, "Headset Mic" },
152
153 { "HDMI", NULL, "hif5 Output" },
154 { "DP", NULL, "hif6 Output" },
155
156 /* CODEC BE connections */
157 { "AIF Playback", NULL, "ssp1 Tx" },
158 { "ssp1 Tx", NULL, "codec1_out" },
159
160 { "codec0_in", NULL, "ssp1 Rx" },
161 { "ssp1 Rx", NULL, "AIF Capture" },
162
163 { "hifi2", NULL, "iDisp2 Tx"},
164 { "iDisp2 Tx", NULL, "iDisp2_out"},
165 { "hifi1", NULL, "iDisp1 Tx"},
166 { "iDisp1 Tx", NULL, "iDisp1_out"},
167};
168
Naveen Mec040dd2017-05-15 13:42:16 +0530169static struct snd_soc_codec_conf max98927_codec_conf[] = {
170 {
171 .dev_name = MAXIM_DEV0_NAME,
172 .name_prefix = "Right",
173 },
174 {
175 .dev_name = MAXIM_DEV1_NAME,
176 .name_prefix = "Left",
177 },
178};
179
180static struct snd_soc_dai_link_component max98927_codec_components[] = {
181 { /* Left */
182 .name = MAXIM_DEV0_NAME,
183 .dai_name = KBL_MAXIM_CODEC_DAI,
184 },
185 { /* Right */
186 .name = MAXIM_DEV1_NAME,
187 .dai_name = KBL_MAXIM_CODEC_DAI,
188 },
189};
190
191static int kabylake_rt5663_fe_init(struct snd_soc_pcm_runtime *rtd)
192{
193 int ret;
194 struct snd_soc_dapm_context *dapm;
195 struct snd_soc_component *component = rtd->cpu_dai->component;
196
197 dapm = snd_soc_component_get_dapm(component);
198 ret = snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
199 if (ret) {
200 dev_err(rtd->dev, "Ref Cap ignore suspend failed %d\n", ret);
201 return ret;
202 }
203
204 return ret;
205}
206
207static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
208{
209 int ret;
210 struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card);
211 struct snd_soc_codec *codec = rtd->codec;
Naveen Mae09a472017-09-15 13:43:21 +0530212 struct snd_soc_jack *jack;
Naveen Mec040dd2017-05-15 13:42:16 +0530213
214 /*
215 * Headset buttons map to the google Reference headset.
216 * These can be configured by userspace.
217 */
Kevin Chengc0642572017-07-27 16:38:36 +0800218 ret = snd_soc_card_jack_new(kabylake_audio_card, "Headset Jack",
Naveen Mec040dd2017-05-15 13:42:16 +0530219 SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
220 SND_JACK_BTN_2 | SND_JACK_BTN_3, &ctx->kabylake_headset,
221 NULL, 0);
222 if (ret) {
223 dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret);
224 return ret;
225 }
Naveen Mae09a472017-09-15 13:43:21 +0530226
227 jack = &ctx->kabylake_headset;
228 snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA);
229 snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
230 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
231 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
232
Naveen Mec040dd2017-05-15 13:42:16 +0530233 rt5663_set_jack_detect(codec, &ctx->kabylake_headset);
Kevin Chengc0642572017-07-27 16:38:36 +0800234 return ret;
235}
236
237static int kabylake_rt5663_max98927_codec_init(struct snd_soc_pcm_runtime *rtd)
238{
239 int ret;
240
241 ret = kabylake_rt5663_codec_init(rtd);
242 if (ret)
243 return ret;
244
Naveen Mec040dd2017-05-15 13:42:16 +0530245 ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
246 if (ret) {
247 dev_err(rtd->dev, "SoC DMIC ignore suspend failed %d\n", ret);
248 return ret;
249 }
250
251 return ret;
252}
253
Kevin Chengc0642572017-07-27 16:38:36 +0800254static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device)
Naveen Mec040dd2017-05-15 13:42:16 +0530255{
256 struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card);
257 struct snd_soc_dai *dai = rtd->codec_dai;
258 struct kbl_hdmi_pcm *pcm;
259
260 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
261 if (!pcm)
262 return -ENOMEM;
263
Kevin Chengc0642572017-07-27 16:38:36 +0800264 pcm->device = device;
Naveen Mec040dd2017-05-15 13:42:16 +0530265 pcm->codec_dai = dai;
266
267 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
268
269 return 0;
270}
271
Kevin Chengc0642572017-07-27 16:38:36 +0800272static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
273{
274 return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI1_PB);
275}
276
Naveen Mec040dd2017-05-15 13:42:16 +0530277static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd)
278{
Kevin Chengc0642572017-07-27 16:38:36 +0800279 return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI2_PB);
Naveen Mec040dd2017-05-15 13:42:16 +0530280}
281
282static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd)
283{
Kevin Chengc0642572017-07-27 16:38:36 +0800284 return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI3_PB);
285}
Naveen Mec040dd2017-05-15 13:42:16 +0530286
Kevin Chengc0642572017-07-27 16:38:36 +0800287static int kabylake_5663_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
288{
289 return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_5663_HDMI1_PB);
290}
Naveen Mec040dd2017-05-15 13:42:16 +0530291
Kevin Chengc0642572017-07-27 16:38:36 +0800292static int kabylake_5663_hdmi2_init(struct snd_soc_pcm_runtime *rtd)
293{
294 return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_5663_HDMI2_PB);
Naveen Mec040dd2017-05-15 13:42:16 +0530295}
296
297static unsigned int rates[] = {
298 48000,
299};
300
Bhumika Goyal2d5f8482017-08-11 21:26:49 +0530301static const struct snd_pcm_hw_constraint_list constraints_rates = {
Naveen Mec040dd2017-05-15 13:42:16 +0530302 .count = ARRAY_SIZE(rates),
303 .list = rates,
304 .mask = 0,
305};
306
307static unsigned int channels[] = {
308 2,
309};
310
Bhumika Goyal2d5f8482017-08-11 21:26:49 +0530311static const struct snd_pcm_hw_constraint_list constraints_channels = {
Naveen Mec040dd2017-05-15 13:42:16 +0530312 .count = ARRAY_SIZE(channels),
313 .list = channels,
314 .mask = 0,
315};
316
317static int kbl_fe_startup(struct snd_pcm_substream *substream)
318{
319 struct snd_pcm_runtime *runtime = substream->runtime;
320
321 /*
322 * On this platform for PCM device we support,
323 * 48Khz
324 * stereo
325 * 16 bit audio
326 */
327
328 runtime->hw.channels_max = 2;
329 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
330 &constraints_channels);
331
332 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
333 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
334
335 snd_pcm_hw_constraint_list(runtime, 0,
336 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
337
338 return 0;
339}
340
341static const struct snd_soc_ops kabylake_rt5663_fe_ops = {
342 .startup = kbl_fe_startup,
343};
344
345static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
346 struct snd_pcm_hw_params *params)
347{
348 struct snd_interval *rate = hw_param_interval(params,
349 SNDRV_PCM_HW_PARAM_RATE);
350 struct snd_interval *channels = hw_param_interval(params,
351 SNDRV_PCM_HW_PARAM_CHANNELS);
352 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
353
354 /* The ADSP will convert the FE rate to 48k, stereo */
355 rate->min = rate->max = 48000;
356 channels->min = channels->max = 2;
357 /* set SSP1 to 24 bit */
358 snd_mask_none(fmt);
359 snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
360
361 return 0;
362}
363
364static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream,
365 struct snd_pcm_hw_params *params)
366{
367 struct snd_soc_pcm_runtime *rtd = substream->private_data;
368 struct snd_soc_dai *codec_dai = rtd->codec_dai;
369 int ret;
370
Harsha Priya Nd46b1822017-08-16 16:19:55 +0530371 /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */
372 rt5663_sel_asrc_clk_src(codec_dai->codec,
373 RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
374 RT5663_CLK_SEL_I2S1_ASRC);
375
Naveen Mec040dd2017-05-15 13:42:16 +0530376 ret = snd_soc_dai_set_sysclk(codec_dai,
377 RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN);
Naveen Mec040dd2017-05-15 13:42:16 +0530378 if (ret < 0)
379 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
380
381 return ret;
382}
383
384static struct snd_soc_ops kabylake_rt5663_ops = {
385 .hw_params = kabylake_rt5663_hw_params,
386};
387
388static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
389 struct snd_pcm_hw_params *params)
390{
391 struct snd_interval *channels = hw_param_interval(params,
392 SNDRV_PCM_HW_PARAM_CHANNELS);
393
394 if (params_channels(params) == 2 || DMIC_CH(dmic_constraints) == 2)
395 channels->min = channels->max = 2;
396 else
397 channels->min = channels->max = 4;
398
399 return 0;
400}
401
402static unsigned int channels_dmic[] = {
403 2, 4,
404};
405
406static struct snd_pcm_hw_constraint_list constraints_dmic_channels = {
407 .count = ARRAY_SIZE(channels_dmic),
408 .list = channels_dmic,
409 .mask = 0,
410};
411
412static const unsigned int dmic_2ch[] = {
413 2,
414};
415
416static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = {
417 .count = ARRAY_SIZE(dmic_2ch),
418 .list = dmic_2ch,
419 .mask = 0,
420};
421
422static int kabylake_dmic_startup(struct snd_pcm_substream *substream)
423{
424 struct snd_pcm_runtime *runtime = substream->runtime;
425
426 runtime->hw.channels_max = DMIC_CH(dmic_constraints);
427 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
428 dmic_constraints);
429
430 return snd_pcm_hw_constraint_list(substream->runtime, 0,
431 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
432}
433
434static struct snd_soc_ops kabylake_dmic_ops = {
435 .startup = kabylake_dmic_startup,
436};
437
438static unsigned int rates_16000[] = {
439 16000,
440};
441
Bhumika Goyal2d5f8482017-08-11 21:26:49 +0530442static const struct snd_pcm_hw_constraint_list constraints_16000 = {
Naveen Mec040dd2017-05-15 13:42:16 +0530443 .count = ARRAY_SIZE(rates_16000),
444 .list = rates_16000,
445};
446
447static const unsigned int ch_mono[] = {
448 1,
449};
450
451static const struct snd_pcm_hw_constraint_list constraints_refcap = {
452 .count = ARRAY_SIZE(ch_mono),
453 .list = ch_mono,
454};
455
456static int kabylake_refcap_startup(struct snd_pcm_substream *substream)
457{
458 substream->runtime->hw.channels_max = 1;
459 snd_pcm_hw_constraint_list(substream->runtime, 0,
460 SNDRV_PCM_HW_PARAM_CHANNELS,
461 &constraints_refcap);
462
463 return snd_pcm_hw_constraint_list(substream->runtime, 0,
464 SNDRV_PCM_HW_PARAM_RATE,
465 &constraints_16000);
466}
467
468static struct snd_soc_ops skylaye_refcap_ops = {
469 .startup = kabylake_refcap_startup,
470};
471
472/* kabylake digital audio interface glue - connects codec <--> CPU */
473static struct snd_soc_dai_link kabylake_dais[] = {
474 /* Front End DAI links */
475 [KBL_DPCM_AUDIO_PB] = {
476 .name = "Kbl Audio Port",
477 .stream_name = "Audio",
478 .cpu_dai_name = "System Pin",
479 .platform_name = "0000:00:1f.3",
480 .dynamic = 1,
481 .codec_name = "snd-soc-dummy",
482 .codec_dai_name = "snd-soc-dummy-dai",
483 .nonatomic = 1,
484 .init = kabylake_rt5663_fe_init,
485 .trigger = {
486 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
487 .dpcm_playback = 1,
488 .ops = &kabylake_rt5663_fe_ops,
489 },
490 [KBL_DPCM_AUDIO_CP] = {
491 .name = "Kbl Audio Capture Port",
492 .stream_name = "Audio Record",
493 .cpu_dai_name = "System Pin",
494 .platform_name = "0000:00:1f.3",
495 .dynamic = 1,
496 .codec_name = "snd-soc-dummy",
497 .codec_dai_name = "snd-soc-dummy-dai",
498 .nonatomic = 1,
499 .trigger = {
500 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
501 .dpcm_capture = 1,
502 .ops = &kabylake_rt5663_fe_ops,
503 },
Naveen Manoharb32ee382017-08-02 11:43:34 +0530504 [KBL_DPCM_AUDIO_HS_PB] = {
505 .name = "Kbl Audio Headset Playback",
506 .stream_name = "Headset Audio",
507 .cpu_dai_name = "System Pin2",
508 .codec_name = "snd-soc-dummy",
509 .codec_dai_name = "snd-soc-dummy-dai",
510 .platform_name = "0000:00:1f.3",
511 .dpcm_playback = 1,
512 .nonatomic = 1,
513 .dynamic = 1,
514 },
515 [KBL_DPCM_AUDIO_ECHO_REF_CP] = {
516 .name = "Kbl Audio Echo Reference cap",
517 .stream_name = "Echoreference Capture",
518 .cpu_dai_name = "Echoref Pin",
519 .codec_name = "snd-soc-dummy",
520 .codec_dai_name = "snd-soc-dummy-dai",
521 .platform_name = "0000:00:1f.3",
522 .init = NULL,
523 .capture_only = 1,
524 .nonatomic = 1,
525 },
Naveen Mec040dd2017-05-15 13:42:16 +0530526 [KBL_DPCM_AUDIO_REF_CP] = {
527 .name = "Kbl Audio Reference cap",
528 .stream_name = "Wake on Voice",
529 .cpu_dai_name = "Reference Pin",
530 .codec_name = "snd-soc-dummy",
531 .codec_dai_name = "snd-soc-dummy-dai",
532 .platform_name = "0000:00:1f.3",
533 .init = NULL,
534 .dpcm_capture = 1,
535 .nonatomic = 1,
536 .dynamic = 1,
537 .ops = &skylaye_refcap_ops,
538 },
539 [KBL_DPCM_AUDIO_DMIC_CP] = {
540 .name = "Kbl Audio DMIC cap",
541 .stream_name = "dmiccap",
542 .cpu_dai_name = "DMIC Pin",
543 .codec_name = "snd-soc-dummy",
544 .codec_dai_name = "snd-soc-dummy-dai",
545 .platform_name = "0000:00:1f.3",
546 .init = NULL,
547 .dpcm_capture = 1,
548 .nonatomic = 1,
549 .dynamic = 1,
550 .ops = &kabylake_dmic_ops,
551 },
552 [KBL_DPCM_AUDIO_HDMI1_PB] = {
553 .name = "Kbl HDMI Port1",
554 .stream_name = "Hdmi1",
555 .cpu_dai_name = "HDMI1 Pin",
556 .codec_name = "snd-soc-dummy",
557 .codec_dai_name = "snd-soc-dummy-dai",
558 .platform_name = "0000:00:1f.3",
559 .dpcm_playback = 1,
560 .init = NULL,
561 .trigger = {
562 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
563 .nonatomic = 1,
564 .dynamic = 1,
565 },
566 [KBL_DPCM_AUDIO_HDMI2_PB] = {
567 .name = "Kbl HDMI Port2",
568 .stream_name = "Hdmi2",
569 .cpu_dai_name = "HDMI2 Pin",
570 .codec_name = "snd-soc-dummy",
571 .codec_dai_name = "snd-soc-dummy-dai",
572 .platform_name = "0000:00:1f.3",
573 .dpcm_playback = 1,
574 .init = NULL,
575 .trigger = {
576 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
577 .nonatomic = 1,
578 .dynamic = 1,
579 },
580 [KBL_DPCM_AUDIO_HDMI3_PB] = {
581 .name = "Kbl HDMI Port3",
582 .stream_name = "Hdmi3",
583 .cpu_dai_name = "HDMI3 Pin",
584 .codec_name = "snd-soc-dummy",
585 .codec_dai_name = "snd-soc-dummy-dai",
586 .platform_name = "0000:00:1f.3",
587 .trigger = {
588 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
589 .dpcm_playback = 1,
590 .init = NULL,
591 .nonatomic = 1,
592 .dynamic = 1,
593 },
594
595 /* Back End DAI links */
596 {
597 /* SSP0 - Codec */
598 .name = "SSP0-Codec",
599 .id = 0,
600 .cpu_dai_name = "SSP0 Pin",
601 .platform_name = "0000:00:1f.3",
602 .no_pcm = 1,
603 .codecs = max98927_codec_components,
604 .num_codecs = ARRAY_SIZE(max98927_codec_components),
605 .dai_fmt = SND_SOC_DAIFMT_I2S |
606 SND_SOC_DAIFMT_NB_NF |
607 SND_SOC_DAIFMT_CBS_CFS,
608 .ignore_pmdown_time = 1,
609 .be_hw_params_fixup = kabylake_ssp_fixup,
610 .dpcm_playback = 1,
611 },
612 {
613 /* SSP1 - Codec */
614 .name = "SSP1-Codec",
615 .id = 1,
616 .cpu_dai_name = "SSP1 Pin",
617 .platform_name = "0000:00:1f.3",
618 .no_pcm = 1,
619 .codec_name = "i2c-10EC5663:00",
620 .codec_dai_name = KBL_REALTEK_CODEC_DAI,
Kevin Chengc0642572017-07-27 16:38:36 +0800621 .init = kabylake_rt5663_max98927_codec_init,
Naveen Mec040dd2017-05-15 13:42:16 +0530622 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
623 SND_SOC_DAIFMT_CBS_CFS,
624 .ignore_pmdown_time = 1,
625 .be_hw_params_fixup = kabylake_ssp_fixup,
626 .ops = &kabylake_rt5663_ops,
627 .dpcm_playback = 1,
628 .dpcm_capture = 1,
629 },
630 {
631 .name = "dmic01",
632 .id = 2,
633 .cpu_dai_name = "DMIC01 Pin",
634 .codec_name = "dmic-codec",
635 .codec_dai_name = "dmic-hifi",
636 .platform_name = "0000:00:1f.3",
637 .be_hw_params_fixup = kabylake_dmic_fixup,
638 .ignore_suspend = 1,
639 .dpcm_capture = 1,
640 .no_pcm = 1,
641 },
642 {
643 .name = "iDisp1",
644 .id = 3,
645 .cpu_dai_name = "iDisp1 Pin",
646 .codec_name = "ehdaudio0D2",
647 .codec_dai_name = "intel-hdmi-hifi1",
648 .platform_name = "0000:00:1f.3",
649 .dpcm_playback = 1,
650 .init = kabylake_hdmi1_init,
651 .no_pcm = 1,
652 },
653 {
654 .name = "iDisp2",
655 .id = 4,
656 .cpu_dai_name = "iDisp2 Pin",
657 .codec_name = "ehdaudio0D2",
658 .codec_dai_name = "intel-hdmi-hifi2",
659 .platform_name = "0000:00:1f.3",
660 .init = kabylake_hdmi2_init,
661 .dpcm_playback = 1,
662 .no_pcm = 1,
663 },
664 {
665 .name = "iDisp3",
666 .id = 5,
667 .cpu_dai_name = "iDisp3 Pin",
668 .codec_name = "ehdaudio0D2",
669 .codec_dai_name = "intel-hdmi-hifi3",
670 .platform_name = "0000:00:1f.3",
671 .init = kabylake_hdmi3_init,
672 .dpcm_playback = 1,
673 .no_pcm = 1,
674 },
675};
676
Kevin Chengc0642572017-07-27 16:38:36 +0800677static struct snd_soc_dai_link kabylake_5663_dais[] = {
678 /* Front End DAI links */
679 [KBL_DPCM_AUDIO_5663_PB] = {
680 .name = "Kbl Audio Port",
681 .stream_name = "Audio",
682 .cpu_dai_name = "System Pin",
683 .platform_name = "0000:00:1f.3",
684 .dynamic = 1,
685 .codec_name = "snd-soc-dummy",
686 .codec_dai_name = "snd-soc-dummy-dai",
687 .nonatomic = 1,
688 .trigger = {
689 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
690 .dpcm_playback = 1,
691 .ops = &kabylake_rt5663_fe_ops,
692 },
693 [KBL_DPCM_AUDIO_5663_CP] = {
694 .name = "Kbl Audio Capture Port",
695 .stream_name = "Audio Record",
696 .cpu_dai_name = "System Pin",
697 .platform_name = "0000:00:1f.3",
698 .dynamic = 1,
699 .codec_name = "snd-soc-dummy",
700 .codec_dai_name = "snd-soc-dummy-dai",
701 .nonatomic = 1,
702 .trigger = {
703 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
704 .dpcm_capture = 1,
705 .ops = &kabylake_rt5663_fe_ops,
706 },
707 [KBL_DPCM_AUDIO_5663_HDMI1_PB] = {
708 .name = "Kbl HDMI Port1",
709 .stream_name = "Hdmi1",
710 .cpu_dai_name = "HDMI1 Pin",
711 .codec_name = "snd-soc-dummy",
712 .codec_dai_name = "snd-soc-dummy-dai",
713 .platform_name = "0000:00:1f.3",
714 .dpcm_playback = 1,
715 .init = NULL,
716 .trigger = {
717 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
718 .nonatomic = 1,
719 .dynamic = 1,
720 },
721 [KBL_DPCM_AUDIO_5663_HDMI2_PB] = {
722 .name = "Kbl HDMI Port2",
723 .stream_name = "Hdmi2",
724 .cpu_dai_name = "HDMI2 Pin",
725 .codec_name = "snd-soc-dummy",
726 .codec_dai_name = "snd-soc-dummy-dai",
727 .platform_name = "0000:00:1f.3",
728 .dpcm_playback = 1,
729 .init = NULL,
730 .trigger = {
731 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
732 .nonatomic = 1,
733 .dynamic = 1,
734 },
735
736 /* Back End DAI links */
737 {
738 /* SSP1 - Codec */
739 .name = "SSP1-Codec",
740 .id = 0,
741 .cpu_dai_name = "SSP1 Pin",
742 .platform_name = "0000:00:1f.3",
743 .no_pcm = 1,
744 .codec_name = "i2c-10EC5663:00",
745 .codec_dai_name = KBL_REALTEK_CODEC_DAI,
746 .init = kabylake_rt5663_codec_init,
747 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
748 SND_SOC_DAIFMT_CBS_CFS,
749 .ignore_pmdown_time = 1,
750 .be_hw_params_fixup = kabylake_ssp_fixup,
751 .ops = &kabylake_rt5663_ops,
752 .dpcm_playback = 1,
753 .dpcm_capture = 1,
754 },
755 {
756 .name = "iDisp1",
757 .id = 1,
758 .cpu_dai_name = "iDisp1 Pin",
759 .codec_name = "ehdaudio0D2",
760 .codec_dai_name = "intel-hdmi-hifi1",
761 .platform_name = "0000:00:1f.3",
762 .dpcm_playback = 1,
763 .init = kabylake_5663_hdmi1_init,
764 .no_pcm = 1,
765 },
766 {
767 .name = "iDisp2",
768 .id = 2,
769 .cpu_dai_name = "iDisp2 Pin",
770 .codec_name = "ehdaudio0D2",
771 .codec_dai_name = "intel-hdmi-hifi2",
772 .platform_name = "0000:00:1f.3",
773 .init = kabylake_5663_hdmi2_init,
774 .dpcm_playback = 1,
775 .no_pcm = 1,
776 },
777};
778
Naveen Mec040dd2017-05-15 13:42:16 +0530779#define NAME_SIZE 32
780static int kabylake_card_late_probe(struct snd_soc_card *card)
781{
782 struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card);
783 struct kbl_hdmi_pcm *pcm;
Naveen M3a133472017-08-26 04:04:10 +0530784 struct snd_soc_codec *codec = NULL;
Naveen Mec040dd2017-05-15 13:42:16 +0530785 int err, i = 0;
786 char jack_name[NAME_SIZE];
787
788 list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
Naveen M3a133472017-08-26 04:04:10 +0530789 codec = pcm->codec_dai->codec;
Naveen Mec040dd2017-05-15 13:42:16 +0530790 snprintf(jack_name, sizeof(jack_name),
791 "HDMI/DP, pcm=%d Jack", pcm->device);
792 err = snd_soc_card_jack_new(card, jack_name,
793 SND_JACK_AVOUT, &skylake_hdmi[i],
794 NULL, 0);
795
796 if (err)
797 return err;
798
799 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
800 &skylake_hdmi[i]);
801 if (err < 0)
802 return err;
803
804 i++;
805 }
806
Naveen M3a133472017-08-26 04:04:10 +0530807 if (!codec)
808 return -EINVAL;
809
810 return hdac_hdmi_jack_port_init(codec, &card->dapm);
Naveen Mec040dd2017-05-15 13:42:16 +0530811}
812
813/* kabylake audio machine driver for SPT + RT5663 */
Kevin Chengc0642572017-07-27 16:38:36 +0800814static struct snd_soc_card kabylake_audio_card_rt5663_m98927 = {
Naveen Mec040dd2017-05-15 13:42:16 +0530815 .name = "kblrt5663max",
816 .owner = THIS_MODULE,
817 .dai_link = kabylake_dais,
818 .num_links = ARRAY_SIZE(kabylake_dais),
819 .controls = kabylake_controls,
820 .num_controls = ARRAY_SIZE(kabylake_controls),
821 .dapm_widgets = kabylake_widgets,
822 .num_dapm_widgets = ARRAY_SIZE(kabylake_widgets),
823 .dapm_routes = kabylake_map,
824 .num_dapm_routes = ARRAY_SIZE(kabylake_map),
825 .codec_conf = max98927_codec_conf,
826 .num_configs = ARRAY_SIZE(max98927_codec_conf),
827 .fully_routed = true,
828 .late_probe = kabylake_card_late_probe,
829};
830
Kevin Chengc0642572017-07-27 16:38:36 +0800831/* kabylake audio machine driver for RT5663 */
832static struct snd_soc_card kabylake_audio_card_rt5663 = {
833 .name = "kblrt5663",
834 .owner = THIS_MODULE,
835 .dai_link = kabylake_5663_dais,
836 .num_links = ARRAY_SIZE(kabylake_5663_dais),
837 .controls = kabylake_5663_controls,
838 .num_controls = ARRAY_SIZE(kabylake_5663_controls),
839 .dapm_widgets = kabylake_5663_widgets,
840 .num_dapm_widgets = ARRAY_SIZE(kabylake_5663_widgets),
841 .dapm_routes = kabylake_5663_map,
842 .num_dapm_routes = ARRAY_SIZE(kabylake_5663_map),
843 .fully_routed = true,
844 .late_probe = kabylake_card_late_probe,
845};
846
Naveen Mec040dd2017-05-15 13:42:16 +0530847static int kabylake_audio_probe(struct platform_device *pdev)
848{
849 struct kbl_rt5663_private *ctx;
850 struct skl_machine_pdata *pdata;
851
852 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC);
853 if (!ctx)
854 return -ENOMEM;
855
856 INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
857
Kevin Chengc0642572017-07-27 16:38:36 +0800858 kabylake_audio_card =
859 (struct snd_soc_card *)pdev->id_entry->driver_data;
860
861 kabylake_audio_card->dev = &pdev->dev;
862 snd_soc_card_set_drvdata(kabylake_audio_card, ctx);
Naveen Mec040dd2017-05-15 13:42:16 +0530863
864 pdata = dev_get_drvdata(&pdev->dev);
865 if (pdata)
866 dmic_constraints = pdata->dmic_num == 2 ?
867 &constraints_dmic_2ch : &constraints_dmic_channels;
868
Kevin Chengc0642572017-07-27 16:38:36 +0800869 return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card);
Naveen Mec040dd2017-05-15 13:42:16 +0530870}
871
872static const struct platform_device_id kbl_board_ids[] = {
Kevin Chengc0642572017-07-27 16:38:36 +0800873 {
874 .name = "kbl_rt5663",
875 .driver_data = (kernel_ulong_t)&kabylake_audio_card_rt5663,
876 },
877 {
878 .name = "kbl_rt5663_m98927",
879 .driver_data =
880 (kernel_ulong_t)&kabylake_audio_card_rt5663_m98927,
881 },
Naveen Mec040dd2017-05-15 13:42:16 +0530882 { }
883};
884
885static struct platform_driver kabylake_audio = {
886 .probe = kabylake_audio_probe,
887 .driver = {
888 .name = "kbl_rt5663_m98927",
889 .pm = &snd_soc_pm_ops,
890 },
891 .id_table = kbl_board_ids,
892};
893
894module_platform_driver(kabylake_audio)
895
896/* Module information */
897MODULE_DESCRIPTION("Audio Machine driver-RT5663 & MAX98927 in I2S mode");
898MODULE_AUTHOR("Naveen M <naveen.m@intel.com>");
899MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>");
900MODULE_LICENSE("GPL v2");
Kevin Chengc0642572017-07-27 16:38:36 +0800901MODULE_ALIAS("platform:kbl_rt5663");
Naveen Mec040dd2017-05-15 13:42:16 +0530902MODULE_ALIAS("platform:kbl_rt5663_m98927");