aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/intel/boards/skl_rt286.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/intel/boards/skl_rt286.c')
-rw-r--r--sound/soc/intel/boards/skl_rt286.c128
1 files changed, 124 insertions, 4 deletions
diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c
index a73a431bd8b7..7396ddb427d8 100644
--- a/sound/soc/intel/boards/skl_rt286.c
+++ b/sound/soc/intel/boards/skl_rt286.c
@@ -52,6 +52,7 @@ static const struct snd_soc_dapm_widget skylake_widgets[] = {
52 SND_SOC_DAPM_MIC("Mic Jack", NULL), 52 SND_SOC_DAPM_MIC("Mic Jack", NULL),
53 SND_SOC_DAPM_MIC("DMIC2", NULL), 53 SND_SOC_DAPM_MIC("DMIC2", NULL),
54 SND_SOC_DAPM_MIC("SoC DMIC", NULL), 54 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
55 SND_SOC_DAPM_SINK("WoV Sink"),
55}; 56};
56 57
57static const struct snd_soc_dapm_route skylake_rt286_map[] = { 58static const struct snd_soc_dapm_route skylake_rt286_map[] = {
@@ -67,7 +68,9 @@ static const struct snd_soc_dapm_route skylake_rt286_map[] = {
67 68
68 /* digital mics */ 69 /* digital mics */
69 {"DMIC1 Pin", NULL, "DMIC2"}, 70 {"DMIC1 Pin", NULL, "DMIC2"},
70 {"DMIC AIF", NULL, "SoC DMIC"}, 71 {"DMic", NULL, "SoC DMIC"},
72
73 {"WoV Sink", NULL, "hwd_in sink"},
71 74
72 /* CODEC BE connections */ 75 /* CODEC BE connections */
73 { "AIF1 Playback", NULL, "ssp0 Tx"}, 76 { "AIF1 Playback", NULL, "ssp0 Tx"},
@@ -79,13 +82,24 @@ static const struct snd_soc_dapm_route skylake_rt286_map[] = {
79 { "ssp0 Rx", NULL, "AIF1 Capture" }, 82 { "ssp0 Rx", NULL, "AIF1 Capture" },
80 83
81 { "dmic01_hifi", NULL, "DMIC01 Rx" }, 84 { "dmic01_hifi", NULL, "DMIC01 Rx" },
82 { "DMIC01 Rx", NULL, "Capture" }, 85 { "DMIC01 Rx", NULL, "DMIC AIF" },
83 86
84 { "hif1", NULL, "iDisp Tx"}, 87 { "hif1", NULL, "iDisp Tx"},
85 { "iDisp Tx", NULL, "iDisp_out"}, 88 { "iDisp Tx", NULL, "iDisp_out"},
86 89
87}; 90};
88 91
92static int skylake_rt286_fe_init(struct snd_soc_pcm_runtime *rtd)
93{
94 struct snd_soc_dapm_context *dapm;
95 struct snd_soc_component *component = rtd->cpu_dai->component;
96
97 dapm = snd_soc_component_get_dapm(component);
98 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
99
100 return 0;
101}
102
89static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) 103static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
90{ 104{
91 struct snd_soc_codec *codec = rtd->codec; 105 struct snd_soc_codec *codec = rtd->codec;
@@ -101,9 +115,59 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
101 115
102 rt286_mic_detect(codec, &skylake_headset); 116 rt286_mic_detect(codec, &skylake_headset);
103 117
118 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
119 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "WoV Sink");
120
104 return 0; 121 return 0;
105} 122}
106 123
124static unsigned int rates[] = {
125 48000,
126};
127
128static struct snd_pcm_hw_constraint_list constraints_rates = {
129 .count = ARRAY_SIZE(rates),
130 .list = rates,
131 .mask = 0,
132};
133
134static unsigned int channels[] = {
135 2,
136};
137
138static struct snd_pcm_hw_constraint_list constraints_channels = {
139 .count = ARRAY_SIZE(channels),
140 .list = channels,
141 .mask = 0,
142};
143
144static int skl_fe_startup(struct snd_pcm_substream *substream)
145{
146 struct snd_pcm_runtime *runtime = substream->runtime;
147
148 /*
149 * on this platform for PCM device we support,
150 * 48Khz
151 * stereo
152 * 16 bit audio
153 */
154
155 runtime->hw.channels_max = 2;
156 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
157 &constraints_channels);
158
159 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
160 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
161
162 snd_pcm_hw_constraint_list(runtime, 0,
163 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
164
165 return 0;
166}
167
168static const struct snd_soc_ops skylake_rt286_fe_ops = {
169 .startup = skl_fe_startup,
170};
107 171
108static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, 172static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
109 struct snd_pcm_hw_params *params) 173 struct snd_pcm_hw_params *params)
@@ -112,12 +176,15 @@ static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
112 SNDRV_PCM_HW_PARAM_RATE); 176 SNDRV_PCM_HW_PARAM_RATE);
113 struct snd_interval *channels = hw_param_interval(params, 177 struct snd_interval *channels = hw_param_interval(params,
114 SNDRV_PCM_HW_PARAM_CHANNELS); 178 SNDRV_PCM_HW_PARAM_CHANNELS);
179 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
115 180
116 /* The output is 48KHz, stereo, 16bits */ 181 /* The output is 48KHz, stereo, 16bits */
117 rate->min = rate->max = 48000; 182 rate->min = rate->max = 48000;
118 channels->min = channels->max = 2; 183 channels->min = channels->max = 2;
119 params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
120 184
185 /* set SSP0 to 24 bit */
186 snd_mask_none(fmt);
187 snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
121 return 0; 188 return 0;
122} 189}
123 190
@@ -140,6 +207,42 @@ static struct snd_soc_ops skylake_rt286_ops = {
140 .hw_params = skylake_rt286_hw_params, 207 .hw_params = skylake_rt286_hw_params,
141}; 208};
142 209
210static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
211 struct snd_pcm_hw_params *params)
212{
213 struct snd_interval *channels = hw_param_interval(params,
214 SNDRV_PCM_HW_PARAM_CHANNELS);
215 channels->min = channels->max = 4;
216
217 return 0;
218}
219
220static unsigned int channels_dmic[] = {
221 2, 4,
222};
223
224static struct snd_pcm_hw_constraint_list constraints_dmic_channels = {
225 .count = ARRAY_SIZE(channels_dmic),
226 .list = channels_dmic,
227 .mask = 0,
228};
229
230static int skylake_dmic_startup(struct snd_pcm_substream *substream)
231{
232 struct snd_pcm_runtime *runtime = substream->runtime;
233
234 runtime->hw.channels_max = 4;
235 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
236 &constraints_dmic_channels);
237
238 return snd_pcm_hw_constraint_list(substream->runtime, 0,
239 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
240}
241
242static struct snd_soc_ops skylake_dmic_ops = {
243 .startup = skylake_dmic_startup,
244};
245
143/* skylake digital audio interface glue - connects codec <--> CPU */ 246/* skylake digital audio interface glue - connects codec <--> CPU */
144static struct snd_soc_dai_link skylake_rt286_dais[] = { 247static struct snd_soc_dai_link skylake_rt286_dais[] = {
145 /* Front End DAI links */ 248 /* Front End DAI links */
@@ -152,11 +255,13 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
152 .dynamic = 1, 255 .dynamic = 1,
153 .codec_name = "snd-soc-dummy", 256 .codec_name = "snd-soc-dummy",
154 .codec_dai_name = "snd-soc-dummy-dai", 257 .codec_dai_name = "snd-soc-dummy-dai",
258 .init = skylake_rt286_fe_init,
155 .trigger = { 259 .trigger = {
156 SND_SOC_DPCM_TRIGGER_POST, 260 SND_SOC_DPCM_TRIGGER_POST,
157 SND_SOC_DPCM_TRIGGER_POST 261 SND_SOC_DPCM_TRIGGER_POST
158 }, 262 },
159 .dpcm_playback = 1, 263 .dpcm_playback = 1,
264 .ops = &skylake_rt286_fe_ops,
160 }, 265 },
161 { 266 {
162 .name = "Skl Audio Capture Port", 267 .name = "Skl Audio Capture Port",
@@ -172,6 +277,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
172 SND_SOC_DPCM_TRIGGER_POST 277 SND_SOC_DPCM_TRIGGER_POST
173 }, 278 },
174 .dpcm_capture = 1, 279 .dpcm_capture = 1,
280 .ops = &skylake_rt286_fe_ops,
175 }, 281 },
176 { 282 {
177 .name = "Skl Audio Reference cap", 283 .name = "Skl Audio Reference cap",
@@ -186,6 +292,19 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
186 .nonatomic = 1, 292 .nonatomic = 1,
187 .dynamic = 1, 293 .dynamic = 1,
188 }, 294 },
295 {
296 .name = "Skl Audio DMIC cap",
297 .stream_name = "dmiccap",
298 .cpu_dai_name = "DMIC Pin",
299 .codec_name = "snd-soc-dummy",
300 .codec_dai_name = "snd-soc-dummy-dai",
301 .platform_name = "0000:00:1f.3",
302 .init = NULL,
303 .dpcm_capture = 1,
304 .nonatomic = 1,
305 .dynamic = 1,
306 .ops = &skylake_dmic_ops,
307 },
189 308
190 /* Back End DAI links */ 309 /* Back End DAI links */
191 { 310 {
@@ -201,7 +320,6 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
201 .dai_fmt = SND_SOC_DAIFMT_I2S | 320 .dai_fmt = SND_SOC_DAIFMT_I2S |
202 SND_SOC_DAIFMT_NB_NF | 321 SND_SOC_DAIFMT_NB_NF |
203 SND_SOC_DAIFMT_CBS_CFS, 322 SND_SOC_DAIFMT_CBS_CFS,
204 .ignore_suspend = 1,
205 .ignore_pmdown_time = 1, 323 .ignore_pmdown_time = 1,
206 .be_hw_params_fixup = skylake_ssp0_fixup, 324 .be_hw_params_fixup = skylake_ssp0_fixup,
207 .ops = &skylake_rt286_ops, 325 .ops = &skylake_rt286_ops,
@@ -215,6 +333,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
215 .codec_name = "dmic-codec", 333 .codec_name = "dmic-codec",
216 .codec_dai_name = "dmic-hifi", 334 .codec_dai_name = "dmic-hifi",
217 .platform_name = "0000:00:1f.3", 335 .platform_name = "0000:00:1f.3",
336 .be_hw_params_fixup = skylake_dmic_fixup,
218 .ignore_suspend = 1, 337 .ignore_suspend = 1,
219 .dpcm_capture = 1, 338 .dpcm_capture = 1,
220 .no_pcm = 1, 339 .no_pcm = 1,
@@ -247,6 +366,7 @@ static struct platform_driver skylake_audio = {
247 .probe = skylake_audio_probe, 366 .probe = skylake_audio_probe,
248 .driver = { 367 .driver = {
249 .name = "skl_alc286s_i2s", 368 .name = "skl_alc286s_i2s",
369 .pm = &snd_soc_pm_ops,
250 }, 370 },
251}; 371};
252 372