diff options
Diffstat (limited to 'sound/soc/intel/boards/skl_rt286.c')
-rw-r--r-- | sound/soc/intel/boards/skl_rt286.c | 128 |
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 | ||
57 | static const struct snd_soc_dapm_route skylake_rt286_map[] = { | 58 | static 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 | ||
92 | static 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 | |||
89 | static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) | 103 | static 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 | ||
124 | static unsigned int rates[] = { | ||
125 | 48000, | ||
126 | }; | ||
127 | |||
128 | static struct snd_pcm_hw_constraint_list constraints_rates = { | ||
129 | .count = ARRAY_SIZE(rates), | ||
130 | .list = rates, | ||
131 | .mask = 0, | ||
132 | }; | ||
133 | |||
134 | static unsigned int channels[] = { | ||
135 | 2, | ||
136 | }; | ||
137 | |||
138 | static struct snd_pcm_hw_constraint_list constraints_channels = { | ||
139 | .count = ARRAY_SIZE(channels), | ||
140 | .list = channels, | ||
141 | .mask = 0, | ||
142 | }; | ||
143 | |||
144 | static 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 | |||
168 | static const struct snd_soc_ops skylake_rt286_fe_ops = { | ||
169 | .startup = skl_fe_startup, | ||
170 | }; | ||
107 | 171 | ||
108 | static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, | 172 | static 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 | ||
210 | static 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 | |||
220 | static unsigned int channels_dmic[] = { | ||
221 | 2, 4, | ||
222 | }; | ||
223 | |||
224 | static struct snd_pcm_hw_constraint_list constraints_dmic_channels = { | ||
225 | .count = ARRAY_SIZE(channels_dmic), | ||
226 | .list = channels_dmic, | ||
227 | .mask = 0, | ||
228 | }; | ||
229 | |||
230 | static 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 | |||
242 | static 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 */ |
144 | static struct snd_soc_dai_link skylake_rt286_dais[] = { | 247 | static 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 | ||