1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Copyright(c) 2021-2022 Intel Corporation
4 //
5 // Authors: Cezary Rojewski <cezary.rojewski@intel.com>
6 // Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
7 //
8
9 #include <linux/cleanup.h>
10 #include <linux/debugfs.h>
11 #include <linux/device.h>
12 #include <sound/hda_register.h>
13 #include <sound/hdaudio_ext.h>
14 #include <sound/pcm_params.h>
15 #include <sound/soc-acpi.h>
16 #include <sound/soc-acpi-intel-match.h>
17 #include <sound/soc-component.h>
18 #include "avs.h"
19 #include "path.h"
20 #include "pcm.h"
21 #include "topology.h"
22 #include "utils.h"
23 #include "../../codecs/hda.h"
24
25 struct avs_dma_data {
26 struct avs_tplg_path_template *template;
27 struct avs_path *path;
28 struct avs_dev *adev;
29
30 /* LINK-stream utilized in BE operations while HOST in FE ones. */
31 union {
32 struct hdac_ext_stream *link_stream;
33 struct hdac_ext_stream *host_stream;
34 };
35
36 struct snd_pcm_hw_constraint_list rate_list;
37 struct snd_pcm_hw_constraint_list channels_list;
38 struct snd_pcm_hw_constraint_list sample_bits_list;
39
40 struct work_struct period_elapsed_work;
41 struct hdac_ext_link *link;
42 struct snd_pcm_substream *substream;
43 };
44
45 static struct avs_tplg_path_template *
avs_dai_find_path_template(struct snd_soc_dai * dai,bool is_fe,int direction)46 avs_dai_find_path_template(struct snd_soc_dai *dai, bool is_fe, int direction)
47 {
48 struct snd_soc_dapm_widget *dw = snd_soc_dai_get_widget(dai, direction);
49 struct snd_soc_dapm_path *dp;
50 enum snd_soc_dapm_direction dir;
51
52 if (direction == SNDRV_PCM_STREAM_CAPTURE) {
53 dir = is_fe ? SND_SOC_DAPM_DIR_OUT : SND_SOC_DAPM_DIR_IN;
54 } else {
55 dir = is_fe ? SND_SOC_DAPM_DIR_IN : SND_SOC_DAPM_DIR_OUT;
56 }
57
58 dp = list_first_entry_or_null(&dw->edges[dir], typeof(*dp), list_node[dir]);
59 if (!dp)
60 return NULL;
61
62 /* Get the other widget, with actual path template data */
63 dw = (dp->source == dw) ? dp->sink : dp->source;
64
65 return dw->priv;
66 }
67
avs_period_elapsed_work(struct work_struct * work)68 static void avs_period_elapsed_work(struct work_struct *work)
69 {
70 struct avs_dma_data *data = container_of(work, struct avs_dma_data, period_elapsed_work);
71
72 snd_pcm_period_elapsed(data->substream);
73 }
74
avs_period_elapsed(struct snd_pcm_substream * substream)75 void avs_period_elapsed(struct snd_pcm_substream *substream)
76 {
77 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
78 struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0);
79 struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream);
80
81 schedule_work(&data->period_elapsed_work);
82 }
83
84 static int hw_rule_param_size(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule);
avs_hw_constraints_init(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)85 static int avs_hw_constraints_init(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
86 {
87 struct snd_pcm_runtime *runtime = substream->runtime;
88 struct snd_pcm_hw_constraint_list *r, *c, *s;
89 struct avs_dma_data *data;
90 int ret;
91
92 ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
93 if (ret < 0)
94 return ret;
95
96 data = snd_soc_dai_get_dma_data(dai, substream);
97 r = &(data->rate_list);
98 c = &(data->channels_list);
99 s = &(data->sample_bits_list);
100
101 ret = avs_path_set_constraint(data->adev, data->template, r, c, s);
102 if (ret <= 0)
103 return ret;
104
105 ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, r);
106 if (ret < 0)
107 return ret;
108
109 ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, c);
110 if (ret < 0)
111 return ret;
112
113 ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, s);
114 if (ret < 0)
115 return ret;
116
117 return 0;
118 }
119
avs_dai_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)120 static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
121 {
122 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
123 struct avs_dev *adev = to_avs_dev(dai->component->dev);
124 struct avs_tplg_path_template *template;
125 struct avs_dma_data *data;
126
127 template = avs_dai_find_path_template(dai, !rtd->dai_link->no_pcm, substream->stream);
128 if (!template) {
129 dev_err(dai->dev, "no %s path for dai %s, invalid tplg?\n",
130 snd_pcm_stream_str(substream), dai->name);
131 return -EINVAL;
132 }
133
134 data = kzalloc_obj(*data);
135 if (!data)
136 return -ENOMEM;
137
138 data->substream = substream;
139 data->template = template;
140 data->adev = adev;
141 INIT_WORK(&data->period_elapsed_work, avs_period_elapsed_work);
142 snd_soc_dai_set_dma_data(dai, substream, data);
143
144 if (rtd->dai_link->ignore_suspend)
145 adev->num_lp_paths++;
146
147 return avs_hw_constraints_init(substream, dai);
148 }
149
avs_dai_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)150 static void avs_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
151 {
152 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
153 struct avs_dma_data *data;
154
155 data = snd_soc_dai_get_dma_data(dai, substream);
156
157 if (rtd->dai_link->ignore_suspend)
158 data->adev->num_lp_paths--;
159
160 kfree(data->rate_list.list);
161 kfree(data->channels_list.list);
162 kfree(data->sample_bits_list.list);
163
164 snd_soc_dai_set_dma_data(dai, substream, NULL);
165 kfree(data);
166 }
167
avs_dai_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * fe_hw_params,struct snd_pcm_hw_params * be_hw_params,struct snd_soc_dai * dai,int dma_id)168 static int avs_dai_hw_params(struct snd_pcm_substream *substream,
169 struct snd_pcm_hw_params *fe_hw_params,
170 struct snd_pcm_hw_params *be_hw_params, struct snd_soc_dai *dai,
171 int dma_id)
172 {
173 struct avs_dma_data *data;
174 struct avs_path *path;
175 int ret;
176
177 data = snd_soc_dai_get_dma_data(dai, substream);
178
179 dev_dbg(dai->dev, "%s FE hw_params str %p rtd %p",
180 __func__, substream, substream->runtime);
181 dev_dbg(dai->dev, "rate %d chn %d vbd %d bd %d\n",
182 params_rate(fe_hw_params), params_channels(fe_hw_params),
183 params_width(fe_hw_params), params_physical_width(fe_hw_params));
184
185 dev_dbg(dai->dev, "%s BE hw_params str %p rtd %p",
186 __func__, substream, substream->runtime);
187 dev_dbg(dai->dev, "rate %d chn %d vbd %d bd %d\n",
188 params_rate(be_hw_params), params_channels(be_hw_params),
189 params_width(be_hw_params), params_physical_width(be_hw_params));
190
191 path = avs_path_create(data->adev, dma_id, data->template, fe_hw_params, be_hw_params);
192 if (IS_ERR(path)) {
193 ret = PTR_ERR(path);
194 dev_err(dai->dev, "create path failed: %d\n", ret);
195 return ret;
196 }
197
198 data->path = path;
199 return 0;
200 }
201
avs_dai_be_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * be_hw_params,struct snd_soc_dai * dai,int dma_id)202 static int avs_dai_be_hw_params(struct snd_pcm_substream *substream,
203 struct snd_pcm_hw_params *be_hw_params, struct snd_soc_dai *dai,
204 int dma_id)
205 {
206 struct snd_pcm_hw_params *fe_hw_params = NULL;
207 struct snd_soc_pcm_runtime *fe, *be;
208 struct snd_soc_dpcm *dpcm;
209
210 be = snd_soc_substream_to_rtd(substream);
211 /* dpcm_fe_dai_open() guarantees the list is not empty at this point. */
212 for_each_dpcm_fe(be, substream->stream, dpcm) {
213 fe = dpcm->fe;
214 fe_hw_params = &fe->dpcm[substream->stream].hw_params;
215 }
216
217 return avs_dai_hw_params(substream, fe_hw_params, be_hw_params, dai, dma_id);
218 }
219
avs_dai_prepare(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)220 static int avs_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
221 {
222 struct avs_dma_data *data;
223 int ret;
224
225 data = snd_soc_dai_get_dma_data(dai, substream);
226 if (!data->path)
227 return 0;
228
229 ret = avs_path_reset(data->path);
230 if (ret < 0) {
231 dev_err(dai->dev, "reset path failed: %d\n", ret);
232 return ret;
233 }
234
235 ret = avs_path_pause(data->path);
236 if (ret < 0)
237 dev_err(dai->dev, "pause path failed: %d\n", ret);
238 return ret;
239 }
240
avs_dai_nonhda_be_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params,struct snd_soc_dai * dai)241 static int avs_dai_nonhda_be_hw_params(struct snd_pcm_substream *substream,
242 struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
243 {
244 struct avs_dma_data *data;
245
246 data = snd_soc_dai_get_dma_data(dai, substream);
247 if (data->path)
248 return 0;
249
250 /* Actual port-id comes from topology. */
251 return avs_dai_be_hw_params(substream, hw_params, dai, 0);
252 }
253
avs_dai_nonhda_be_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)254 static int avs_dai_nonhda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
255 {
256 struct avs_dma_data *data;
257
258 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
259
260 data = snd_soc_dai_get_dma_data(dai, substream);
261 if (data->path) {
262 avs_path_free(data->path);
263 data->path = NULL;
264 }
265
266 return 0;
267 }
268
avs_dai_nonhda_be_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)269 static int avs_dai_nonhda_be_trigger(struct snd_pcm_substream *substream, int cmd,
270 struct snd_soc_dai *dai)
271 {
272 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
273 struct avs_dma_data *data;
274 int ret = 0;
275
276 data = snd_soc_dai_get_dma_data(dai, substream);
277
278 switch (cmd) {
279 case SNDRV_PCM_TRIGGER_RESUME:
280 if (rtd->dai_link->ignore_suspend)
281 break;
282 fallthrough;
283 case SNDRV_PCM_TRIGGER_START:
284 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
285 ret = avs_path_pause(data->path);
286 if (ret < 0) {
287 dev_err(dai->dev, "pause BE path failed: %d\n", ret);
288 break;
289 }
290
291 ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
292 if (ret < 0)
293 dev_err(dai->dev, "run BE path failed: %d\n", ret);
294 break;
295
296 case SNDRV_PCM_TRIGGER_SUSPEND:
297 if (rtd->dai_link->ignore_suspend)
298 break;
299 fallthrough;
300 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
301 case SNDRV_PCM_TRIGGER_STOP:
302 ret = avs_path_pause(data->path);
303 if (ret < 0)
304 dev_err(dai->dev, "pause BE path failed: %d\n", ret);
305
306 ret = avs_path_reset(data->path);
307 if (ret < 0)
308 dev_err(dai->dev, "reset BE path failed: %d\n", ret);
309 break;
310
311 default:
312 ret = -EINVAL;
313 break;
314 }
315
316 return ret;
317 }
318
319 static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops = {
320 .startup = avs_dai_startup,
321 .shutdown = avs_dai_shutdown,
322 .hw_params = avs_dai_nonhda_be_hw_params,
323 .hw_free = avs_dai_nonhda_be_hw_free,
324 .prepare = avs_dai_prepare,
325 .trigger = avs_dai_nonhda_be_trigger,
326 };
327
__avs_dai_hda_be_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai,struct hdac_ext_link * link)328 static int __avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai,
329 struct hdac_ext_link *link)
330 {
331 struct hdac_ext_stream *link_stream;
332 struct avs_dma_data *data;
333 int ret;
334
335 ret = avs_dai_startup(substream, dai);
336 if (ret)
337 return ret;
338
339 data = snd_soc_dai_get_dma_data(dai, substream);
340 link_stream = snd_hdac_ext_stream_assign(&data->adev->base.core, substream,
341 HDAC_EXT_STREAM_TYPE_LINK);
342 if (!link_stream) {
343 avs_dai_shutdown(substream, dai);
344 return -EBUSY;
345 }
346
347 data->link_stream = link_stream;
348 data->link = link;
349 return 0;
350 }
351
avs_dai_hda_be_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)352 static int avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
353 {
354 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
355 struct hdac_ext_link *link;
356 struct avs_dma_data *data;
357 struct hda_codec *codec;
358 int ret;
359
360 codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
361
362 link = snd_hdac_ext_bus_get_hlink_by_addr(&codec->bus->core, codec->core.addr);
363 if (!link)
364 return -EINVAL;
365
366 ret = __avs_dai_hda_be_startup(substream, dai, link);
367 if (!ret) {
368 data = snd_soc_dai_get_dma_data(dai, substream);
369 substream->runtime->private_data = data->link_stream;
370 }
371
372 return ret;
373 }
374
avs_dai_i2shda_be_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)375 static int avs_dai_i2shda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
376 {
377 struct avs_dev *adev = to_avs_dev(dai->component->dev);
378 struct hdac_ext_link *link;
379
380 link = snd_hdac_ext_bus_get_hlink_by_id(&adev->base.core, AZX_REG_ML_LEPTR_ID_INTEL_SSP);
381 if (!link)
382 return -EINVAL;
383 return __avs_dai_hda_be_startup(substream, dai, link);
384 }
385
avs_dai_dmichda_be_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)386 static int avs_dai_dmichda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
387 {
388 struct avs_dev *adev = to_avs_dev(dai->component->dev);
389 struct hdac_ext_link *link;
390
391 link = snd_hdac_ext_bus_get_hlink_by_id(&adev->base.core, AZX_REG_ML_LEPTR_ID_INTEL_DMIC);
392 if (!link)
393 return -EINVAL;
394 return __avs_dai_hda_be_startup(substream, dai, link);
395 }
396
avs_dai_hda_be_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)397 static void avs_dai_hda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
398 {
399 struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream);
400
401 snd_hdac_ext_stream_release(data->link_stream, HDAC_EXT_STREAM_TYPE_LINK);
402 substream->runtime->private_data = NULL;
403 avs_dai_shutdown(substream, dai);
404 }
405
avs_dai_althda_be_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)406 static void avs_dai_althda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
407 {
408 struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream);
409
410 snd_hdac_ext_stream_release(data->link_stream, HDAC_EXT_STREAM_TYPE_LINK);
411 avs_dai_shutdown(substream, dai);
412 }
413
avs_dai_hda_be_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params,struct snd_soc_dai * dai)414 static int avs_dai_hda_be_hw_params(struct snd_pcm_substream *substream,
415 struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
416 {
417 struct avs_dma_data *data;
418
419 data = snd_soc_dai_get_dma_data(dai, substream);
420 if (data->path)
421 return 0;
422
423 return avs_dai_be_hw_params(substream, hw_params, dai,
424 hdac_stream(data->link_stream)->stream_tag - 1);
425 }
426
avs_dai_hda_be_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)427 static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
428 {
429 struct hdac_ext_stream *link_stream;
430 struct avs_dma_data *data;
431
432 data = snd_soc_dai_get_dma_data(dai, substream);
433 if (!data->path)
434 return 0;
435
436 link_stream = data->link_stream;
437 link_stream->link_prepared = false;
438 avs_path_free(data->path);
439 data->path = NULL;
440
441 /* clear link <-> stream mapping */
442 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
443 snd_hdac_ext_bus_link_clear_stream_id(data->link,
444 hdac_stream(link_stream)->stream_tag);
445
446 return 0;
447 }
448
avs_dai_hda_be_prepare(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)449 static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
450 {
451 struct snd_soc_pcm_runtime *be = snd_soc_substream_to_rtd(substream);
452 const struct snd_soc_pcm_stream *stream_info;
453 struct hdac_ext_stream *link_stream;
454 const struct snd_pcm_hw_params *p;
455 struct avs_dma_data *data;
456 unsigned int format_val;
457 unsigned int bits;
458 int ret;
459
460 data = snd_soc_dai_get_dma_data(dai, substream);
461 link_stream = data->link_stream;
462 p = &be->dpcm[substream->stream].hw_params;
463
464 if (link_stream->link_prepared)
465 return 0;
466
467 stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
468 bits = snd_hdac_stream_format_bits(params_format(p), params_subformat(p),
469 stream_info->sig_bits);
470 format_val = snd_hdac_stream_format(params_channels(p), bits, params_rate(p));
471
472 snd_hdac_ext_stream_decouple(&data->adev->base.core, link_stream, true);
473 snd_hdac_ext_stream_reset(link_stream);
474 snd_hdac_ext_stream_setup(link_stream, format_val);
475
476 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
477 snd_hdac_ext_bus_link_set_stream_id(data->link,
478 hdac_stream(link_stream)->stream_tag);
479
480 ret = avs_dai_prepare(substream, dai);
481 if (ret)
482 return ret;
483
484 link_stream->link_prepared = true;
485 return 0;
486 }
487
avs_dai_hda_be_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)488 static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
489 struct snd_soc_dai *dai)
490 {
491 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
492 struct avs_dma_data *data;
493 int ret = 0;
494
495 dev_dbg(dai->dev, "entry %s cmd=%d\n", __func__, cmd);
496
497 data = snd_soc_dai_get_dma_data(dai, substream);
498
499 switch (cmd) {
500 case SNDRV_PCM_TRIGGER_RESUME:
501 if (rtd->dai_link->ignore_suspend)
502 break;
503 fallthrough;
504 case SNDRV_PCM_TRIGGER_START:
505 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
506 snd_hdac_ext_stream_start(data->link_stream);
507
508 ret = avs_path_pause(data->path);
509 if (ret < 0) {
510 dev_err(dai->dev, "pause BE path failed: %d\n", ret);
511 break;
512 }
513
514 ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
515 if (ret < 0)
516 dev_err(dai->dev, "run BE path failed: %d\n", ret);
517 break;
518
519 case SNDRV_PCM_TRIGGER_SUSPEND:
520 if (rtd->dai_link->ignore_suspend)
521 break;
522 fallthrough;
523 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
524 case SNDRV_PCM_TRIGGER_STOP:
525 ret = avs_path_pause(data->path);
526 if (ret < 0)
527 dev_err(dai->dev, "pause BE path failed: %d\n", ret);
528
529 snd_hdac_ext_stream_clear(data->link_stream);
530
531 ret = avs_path_reset(data->path);
532 if (ret < 0)
533 dev_err(dai->dev, "reset BE path failed: %d\n", ret);
534 break;
535
536 default:
537 ret = -EINVAL;
538 break;
539 }
540
541 return ret;
542 }
543
544 static const struct snd_soc_dai_ops avs_dai_hda_be_ops = {
545 .startup = avs_dai_hda_be_startup,
546 .shutdown = avs_dai_hda_be_shutdown,
547 .hw_params = avs_dai_hda_be_hw_params,
548 .hw_free = avs_dai_hda_be_hw_free,
549 .prepare = avs_dai_hda_be_prepare,
550 .trigger = avs_dai_hda_be_trigger,
551 };
552
553 static const struct snd_soc_dai_ops avs_dai_i2shda_be_ops = {
554 .startup = avs_dai_i2shda_be_startup,
555 .shutdown = avs_dai_althda_be_shutdown,
556 .hw_params = avs_dai_hda_be_hw_params,
557 .hw_free = avs_dai_hda_be_hw_free,
558 .prepare = avs_dai_hda_be_prepare,
559 .trigger = avs_dai_hda_be_trigger,
560 };
561
562 static const struct snd_soc_dai_ops avs_dai_dmichda_be_ops = {
563 .startup = avs_dai_dmichda_be_startup,
564 .shutdown = avs_dai_althda_be_shutdown,
565 .hw_params = avs_dai_hda_be_hw_params,
566 .hw_free = avs_dai_hda_be_hw_free,
567 .prepare = avs_dai_hda_be_prepare,
568 .trigger = avs_dai_hda_be_trigger,
569 };
570
hw_rule_param_size(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)571 static int hw_rule_param_size(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
572 {
573 struct snd_interval *interval = hw_param_interval(params, rule->var);
574 struct snd_interval to;
575
576 snd_interval_any(&to);
577 to.integer = interval->integer;
578 to.max = interval->max;
579 /*
580 * Commonly 2ms buffer size is used in HDA scenarios whereas 4ms is used
581 * when streaming through GPDMA. Align to the latter to account for both.
582 */
583 to.min = params_rate(params) / 1000 * 4;
584
585 if (rule->var == SNDRV_PCM_HW_PARAM_PERIOD_SIZE)
586 to.min /= params_periods(params);
587
588 return snd_interval_refine(interval, &to);
589 }
590
avs_pcm_hw_constraints_init(struct snd_pcm_substream * substream)591 static int avs_pcm_hw_constraints_init(struct snd_pcm_substream *substream)
592 {
593 struct snd_pcm_runtime *runtime = substream->runtime;
594 int ret;
595
596 ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
597 if (ret < 0)
598 return ret;
599
600 /* Avoid wrap-around with wall-clock. */
601 ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME, 20, 178000000);
602 if (ret < 0)
603 return ret;
604
605 /* Adjust buffer and period size based on the audio format. */
606 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, hw_rule_param_size, NULL,
607 SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_CHANNELS,
608 SNDRV_PCM_HW_PARAM_RATE, -1);
609 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, hw_rule_param_size, NULL,
610 SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_CHANNELS,
611 SNDRV_PCM_HW_PARAM_RATE, -1);
612
613 return 0;
614 }
615
avs_dai_fe_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)616 static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
617 {
618 struct hdac_ext_stream *host_stream;
619 struct avs_dma_data *data;
620 struct hdac_bus *bus;
621 int ret;
622
623 ret = avs_pcm_hw_constraints_init(substream);
624 if (ret)
625 return ret;
626
627 ret = avs_dai_startup(substream, dai);
628 if (ret)
629 return ret;
630
631 data = snd_soc_dai_get_dma_data(dai, substream);
632 bus = &data->adev->base.core;
633
634 host_stream = snd_hdac_ext_stream_assign(bus, substream, HDAC_EXT_STREAM_TYPE_HOST);
635 if (!host_stream) {
636 avs_dai_shutdown(substream, dai);
637 return -EBUSY;
638 }
639
640 data->host_stream = host_stream;
641 snd_pcm_set_sync(substream);
642
643 dev_dbg(dai->dev, "%s fe STARTUP tag %d str %p",
644 __func__, hdac_stream(host_stream)->stream_tag, substream);
645
646 return 0;
647 }
648
avs_dai_fe_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)649 static void avs_dai_fe_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
650 {
651 struct avs_dma_data *data;
652
653 data = snd_soc_dai_get_dma_data(dai, substream);
654
655 disable_work_sync(&data->period_elapsed_work);
656 snd_hdac_ext_stream_release(data->host_stream, HDAC_EXT_STREAM_TYPE_HOST);
657 avs_dai_shutdown(substream, dai);
658 }
659
avs_dai_fe_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params,struct snd_soc_dai * dai)660 static int avs_dai_fe_hw_params(struct snd_pcm_substream *substream,
661 struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
662 {
663 struct snd_pcm_hw_params *be_hw_params = NULL;
664 struct snd_soc_pcm_runtime *fe, *be;
665 struct snd_soc_dpcm *dpcm;
666 struct avs_dma_data *data;
667 struct hdac_ext_stream *host_stream;
668 int ret;
669
670 data = snd_soc_dai_get_dma_data(dai, substream);
671 if (data->path)
672 return 0;
673
674 host_stream = data->host_stream;
675
676 hdac_stream(host_stream)->bufsize = 0;
677 hdac_stream(host_stream)->period_bytes = 0;
678 hdac_stream(host_stream)->format_val = 0;
679
680 fe = snd_soc_substream_to_rtd(substream);
681 /* dpcm_fe_dai_open() guarantees the list is not empty at this point. */
682 for_each_dpcm_be(fe, substream->stream, dpcm) {
683 be = dpcm->be;
684 be_hw_params = &be->dpcm[substream->stream].hw_params;
685 }
686
687 ret = avs_dai_hw_params(substream, hw_params, be_hw_params, dai,
688 hdac_stream(host_stream)->stream_tag - 1);
689 if (ret)
690 goto create_err;
691
692 ret = avs_path_bind(data->path);
693 if (ret < 0) {
694 dev_err(dai->dev, "bind FE <-> BE failed: %d\n", ret);
695 goto bind_err;
696 }
697
698 return 0;
699
700 bind_err:
701 avs_path_free(data->path);
702 data->path = NULL;
703 create_err:
704 snd_pcm_lib_free_pages(substream);
705 return ret;
706 }
707
__avs_dai_fe_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)708 static int __avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
709 {
710 struct avs_dma_data *data;
711 struct hdac_ext_stream *host_stream;
712 int ret;
713
714 dev_dbg(dai->dev, "%s fe HW_FREE str %p rtd %p",
715 __func__, substream, substream->runtime);
716
717 data = snd_soc_dai_get_dma_data(dai, substream);
718 if (!data->path)
719 return 0;
720
721 host_stream = data->host_stream;
722
723 ret = avs_path_unbind(data->path);
724 if (ret < 0)
725 dev_err(dai->dev, "unbind FE <-> BE failed: %d\n", ret);
726
727 avs_path_free(data->path);
728 data->path = NULL;
729 snd_hdac_stream_cleanup(hdac_stream(host_stream));
730 hdac_stream(host_stream)->prepared = false;
731
732 return ret;
733 }
734
avs_dai_fe_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)735 static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
736 {
737 int ret;
738
739 ret = __avs_dai_fe_hw_free(substream, dai);
740 snd_pcm_lib_free_pages(substream);
741
742 return ret;
743 }
744
avs_dai_fe_prepare(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)745 static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
746 {
747 struct snd_pcm_runtime *runtime = substream->runtime;
748 const struct snd_soc_pcm_stream *stream_info;
749 struct avs_dma_data *data;
750 struct hdac_ext_stream *host_stream;
751 unsigned int format_val;
752 struct hdac_bus *bus;
753 unsigned int bits;
754 int ret;
755
756 data = snd_soc_dai_get_dma_data(dai, substream);
757 host_stream = data->host_stream;
758
759 if (runtime->state == SNDRV_PCM_STATE_XRUN)
760 hdac_stream(host_stream)->prepared = false;
761 if (hdac_stream(host_stream)->prepared)
762 return 0;
763
764 bus = hdac_stream(host_stream)->bus;
765 snd_hdac_ext_stream_decouple(bus, data->host_stream, true);
766 snd_hdac_stream_reset(hdac_stream(host_stream));
767
768 stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
769 bits = snd_hdac_stream_format_bits(runtime->format, runtime->subformat,
770 stream_info->sig_bits);
771 format_val = snd_hdac_stream_format(runtime->channels, bits, runtime->rate);
772
773 ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val);
774 if (ret < 0)
775 return ret;
776
777 ret = snd_hdac_ext_host_stream_setup(host_stream, false);
778 if (ret < 0)
779 return ret;
780
781 ret = avs_dai_prepare(substream, dai);
782 if (ret)
783 return ret;
784
785 hdac_stream(host_stream)->prepared = true;
786 return 0;
787 }
788
avs_hda_stream_start(struct hdac_bus * bus,struct hdac_ext_stream * host_stream)789 static void avs_hda_stream_start(struct hdac_bus *bus, struct hdac_ext_stream *host_stream)
790 {
791 struct hdac_stream *first_running = NULL;
792 struct hdac_stream *pos;
793 struct avs_dev *adev = hdac_to_avs(bus);
794
795 list_for_each_entry(pos, &bus->stream_list, list) {
796 if (pos->running) {
797 if (first_running)
798 break; /* more than one running */
799 first_running = pos;
800 }
801 }
802
803 /*
804 * If host_stream is a CAPTURE stream and will be the only one running,
805 * disable L1SEN to avoid sound clipping.
806 */
807 if (!first_running) {
808 if (hdac_stream(host_stream)->direction == SNDRV_PCM_STREAM_CAPTURE)
809 avs_hda_l1sen_enable(adev, false);
810 snd_hdac_stream_start(hdac_stream(host_stream));
811 return;
812 }
813
814 snd_hdac_stream_start(hdac_stream(host_stream));
815 /*
816 * If host_stream is the first stream to break the rule above,
817 * re-enable L1SEN.
818 */
819 if (list_entry_is_head(pos, &bus->stream_list, list) &&
820 first_running->direction == SNDRV_PCM_STREAM_CAPTURE)
821 avs_hda_l1sen_enable(adev, true);
822 }
823
avs_hda_stream_stop(struct hdac_bus * bus,struct hdac_ext_stream * host_stream)824 static void avs_hda_stream_stop(struct hdac_bus *bus, struct hdac_ext_stream *host_stream)
825 {
826 struct hdac_stream *first_running = NULL;
827 struct hdac_stream *pos;
828 struct avs_dev *adev = hdac_to_avs(bus);
829
830 list_for_each_entry(pos, &bus->stream_list, list) {
831 if (pos == hdac_stream(host_stream))
832 continue; /* ignore stream that is about to be stopped */
833 if (pos->running) {
834 if (first_running)
835 break; /* more than one running */
836 first_running = pos;
837 }
838 }
839
840 /*
841 * If host_stream is a CAPTURE stream and is the only one running,
842 * re-enable L1SEN.
843 */
844 if (!first_running) {
845 snd_hdac_stream_stop(hdac_stream(host_stream));
846 if (hdac_stream(host_stream)->direction == SNDRV_PCM_STREAM_CAPTURE)
847 avs_hda_l1sen_enable(adev, true);
848 return;
849 }
850
851 /*
852 * If by stopping host_stream there is only a single, CAPTURE stream running
853 * left, disable L1SEN to avoid sound clipping.
854 */
855 if (list_entry_is_head(pos, &bus->stream_list, list) &&
856 first_running->direction == SNDRV_PCM_STREAM_CAPTURE)
857 avs_hda_l1sen_enable(adev, false);
858
859 snd_hdac_stream_stop(hdac_stream(host_stream));
860 }
861
avs_dai_fe_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)862 static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
863 {
864 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
865 struct avs_dma_data *data;
866 struct hdac_ext_stream *host_stream;
867 struct hdac_bus *bus;
868 unsigned long flags;
869 int ret = 0;
870
871 data = snd_soc_dai_get_dma_data(dai, substream);
872 host_stream = data->host_stream;
873 bus = hdac_stream(host_stream)->bus;
874
875 switch (cmd) {
876 case SNDRV_PCM_TRIGGER_RESUME:
877 if (rtd->dai_link->ignore_suspend)
878 break;
879 fallthrough;
880 case SNDRV_PCM_TRIGGER_START:
881 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
882 spin_lock_irqsave(&bus->reg_lock, flags);
883 avs_hda_stream_start(bus, host_stream);
884 spin_unlock_irqrestore(&bus->reg_lock, flags);
885
886 /* Timeout on DRSM poll shall not stop the resume so ignore the result. */
887 if (cmd == SNDRV_PCM_TRIGGER_RESUME)
888 snd_hdac_stream_wait_drsm(hdac_stream(host_stream));
889
890 ret = avs_path_pause(data->path);
891 if (ret < 0) {
892 dev_err(dai->dev, "pause FE path failed: %d\n", ret);
893 break;
894 }
895
896 ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
897 if (ret < 0)
898 dev_err(dai->dev, "run FE path failed: %d\n", ret);
899
900 break;
901
902 case SNDRV_PCM_TRIGGER_SUSPEND:
903 if (rtd->dai_link->ignore_suspend)
904 break;
905 fallthrough;
906 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
907 case SNDRV_PCM_TRIGGER_STOP:
908 ret = avs_path_pause(data->path);
909 if (ret < 0)
910 dev_err(dai->dev, "pause FE path failed: %d\n", ret);
911
912 spin_lock_irqsave(&bus->reg_lock, flags);
913 avs_hda_stream_stop(bus, host_stream);
914 spin_unlock_irqrestore(&bus->reg_lock, flags);
915
916 ret = avs_path_reset(data->path);
917 if (ret < 0)
918 dev_err(dai->dev, "reset FE path failed: %d\n", ret);
919 break;
920
921 default:
922 ret = -EINVAL;
923 break;
924 }
925
926 return ret;
927 }
928
929 const struct snd_soc_dai_ops avs_dai_fe_ops = {
930 .startup = avs_dai_fe_startup,
931 .shutdown = avs_dai_fe_shutdown,
932 .hw_params = avs_dai_fe_hw_params,
933 .hw_free = avs_dai_fe_hw_free,
934 .prepare = avs_dai_fe_prepare,
935 .trigger = avs_dai_fe_trigger,
936 };
937
topology_name_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)938 static ssize_t topology_name_read(struct file *file, char __user *user_buf, size_t count,
939 loff_t *ppos)
940 {
941 struct snd_soc_component *component = file->private_data;
942 struct snd_soc_card *card = component->card;
943 struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
944 char buf[64];
945 size_t len;
946
947 len = scnprintf(buf, sizeof(buf), "%s/%s\n", component->driver->topology_name_prefix,
948 mach->tplg_filename);
949
950 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
951 }
952
953 static const struct file_operations topology_name_fops = {
954 .open = simple_open,
955 .read = topology_name_read,
956 .llseek = default_llseek,
957 };
958
avs_component_load_libraries(struct avs_soc_component * acomp)959 static int avs_component_load_libraries(struct avs_soc_component *acomp)
960 {
961 struct avs_tplg *tplg = acomp->tplg;
962 struct avs_dev *adev = to_avs_dev(acomp->base->dev);
963 int ret;
964
965 if (!tplg->num_libs)
966 return 0;
967
968 /* Parent device may be asleep and library loading involves IPCs. */
969 ret = pm_runtime_resume_and_get(adev->dev);
970 if (ret < 0)
971 return ret;
972
973 avs_hda_power_gating_enable(adev, false);
974 avs_hda_clock_gating_enable(adev, false);
975 avs_hda_l1sen_enable(adev, false);
976
977 ret = avs_dsp_load_libraries(adev, tplg->libs, tplg->num_libs);
978
979 avs_hda_l1sen_enable(adev, true);
980 avs_hda_clock_gating_enable(adev, true);
981 avs_hda_power_gating_enable(adev, true);
982
983 if (!ret)
984 ret = avs_module_info_init(adev, false);
985
986 pm_runtime_put_autosuspend(adev->dev);
987
988 return ret;
989 }
990
avs_request_topology(struct snd_soc_component * component,const char * name,const struct firmware ** fw)991 static int avs_request_topology(struct snd_soc_component *component, const char *name,
992 const struct firmware **fw)
993 {
994 char *fullname __free(kfree) = NULL;
995
996 fullname = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix, name);
997 if (!fullname)
998 return -ENOMEM;
999
1000 return request_firmware(fw, fullname, component->dev);
1001 }
1002
avs_component_probe(struct snd_soc_component * component)1003 static int avs_component_probe(struct snd_soc_component *component)
1004 {
1005 struct snd_soc_card *card = component->card;
1006 struct snd_soc_acpi_mach *mach;
1007 struct avs_soc_component *acomp;
1008 const struct firmware *fw;
1009 struct avs_dev *adev;
1010 int ret;
1011
1012 dev_dbg(card->dev, "probing %s card %s\n", component->name, card->name);
1013 mach = dev_get_platdata(card->dev);
1014 acomp = to_avs_soc_component(component);
1015 adev = to_avs_dev(component->dev);
1016
1017 acomp->tplg = avs_tplg_new(component);
1018 if (!acomp->tplg)
1019 return -ENOMEM;
1020
1021 if (!mach->tplg_filename)
1022 goto finalize;
1023
1024 /* Load specified topology and create debugfs for it. */
1025 ret = avs_request_topology(component, mach->tplg_filename, &fw);
1026 if (ret == -ENOENT && !strncmp(mach->tplg_filename, "hda-", 4)) {
1027 unsigned int vendor_id;
1028
1029 if (sscanf(mach->tplg_filename, "hda-%08x-tplg.bin", &vendor_id) != 1)
1030 return ret;
1031
1032 if (((vendor_id >> 16) & 0xFFFF) == 0x8086)
1033 mach->tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
1034 "hda-8086-generic-tplg.bin");
1035 else
1036 mach->tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
1037 "hda-generic-tplg.bin");
1038 if (!mach->tplg_filename)
1039 return -ENOMEM;
1040
1041 dev_info(card->dev, "trying to load fallback topology %s\n", mach->tplg_filename);
1042 ret = avs_request_topology(component, mach->tplg_filename, &fw);
1043 }
1044 if (ret < 0)
1045 return ret;
1046
1047 ret = snd_soc_tplg_component_load(component, &avs_tplg_ops, fw);
1048 if (ret)
1049 return ret;
1050
1051 ret = avs_component_load_libraries(acomp);
1052 if (ret < 0) {
1053 dev_err(card->dev, "libraries loading failed: %d\n", ret);
1054 goto err_load_libs;
1055 }
1056
1057 finalize:
1058 debugfs_create_file("topology_name", 0444, component->debugfs_root, component,
1059 &topology_name_fops);
1060
1061 mutex_lock(&adev->comp_list_mutex);
1062 list_add_tail(&acomp->node, &adev->comp_list);
1063 mutex_unlock(&adev->comp_list_mutex);
1064
1065 return 0;
1066
1067 err_load_libs:
1068 avs_remove_topology(component);
1069 return ret;
1070 }
1071
avs_component_remove(struct snd_soc_component * component)1072 static void avs_component_remove(struct snd_soc_component *component)
1073 {
1074 struct avs_soc_component *acomp = to_avs_soc_component(component);
1075 struct snd_soc_acpi_mach *mach;
1076 struct avs_dev *adev = to_avs_dev(component->dev);
1077 int ret;
1078
1079 mach = dev_get_platdata(component->card->dev);
1080
1081 mutex_lock(&adev->comp_list_mutex);
1082 list_del(&acomp->node);
1083 mutex_unlock(&adev->comp_list_mutex);
1084
1085 if (mach->tplg_filename) {
1086 ret = avs_remove_topology(component);
1087 if (ret < 0)
1088 dev_err(component->dev, "unload topology failed: %d\n", ret);
1089 }
1090 }
1091
avs_dai_resume_hw_params(struct snd_soc_dai * dai,struct avs_dma_data * data)1092 static int avs_dai_resume_hw_params(struct snd_soc_dai *dai, struct avs_dma_data *data)
1093 {
1094 struct snd_pcm_substream *substream;
1095 struct snd_soc_pcm_runtime *rtd;
1096 int ret;
1097
1098 substream = data->substream;
1099 rtd = snd_soc_substream_to_rtd(substream);
1100
1101 ret = dai->driver->ops->hw_params(substream, &rtd->dpcm[substream->stream].hw_params, dai);
1102 if (ret)
1103 dev_err(dai->dev, "hw_params on resume failed: %d\n", ret);
1104
1105 return ret;
1106 }
1107
avs_dai_resume_fe_prepare(struct snd_soc_dai * dai,struct avs_dma_data * data)1108 static int avs_dai_resume_fe_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
1109 {
1110 struct hdac_ext_stream *host_stream;
1111 struct hdac_stream *hstream;
1112 struct hdac_bus *bus;
1113 int ret;
1114
1115 host_stream = data->host_stream;
1116 hstream = hdac_stream(host_stream);
1117 bus = hdac_stream(host_stream)->bus;
1118
1119 /* Set DRSM before programming stream and position registers. */
1120 snd_hdac_stream_drsm_enable(bus, true, hstream->index);
1121
1122 ret = dai->driver->ops->prepare(data->substream, dai);
1123 if (ret) {
1124 dev_err(dai->dev, "prepare FE on resume failed: %d\n", ret);
1125 return ret;
1126 }
1127
1128 writel(host_stream->pphcllpl, host_stream->pphc_addr + AZX_REG_PPHCLLPL);
1129 writel(host_stream->pphcllpu, host_stream->pphc_addr + AZX_REG_PPHCLLPU);
1130 writel(host_stream->pphcldpl, host_stream->pphc_addr + AZX_REG_PPHCLDPL);
1131 writel(host_stream->pphcldpu, host_stream->pphc_addr + AZX_REG_PPHCLDPU);
1132
1133 /* As per HW spec recommendation, program LPIB and DPIB to the same value. */
1134 snd_hdac_stream_set_lpib(hstream, hstream->lpib);
1135 snd_hdac_stream_set_dpibr(bus, hstream, hstream->lpib);
1136
1137 return 0;
1138 }
1139
avs_dai_resume_be_prepare(struct snd_soc_dai * dai,struct avs_dma_data * data)1140 static int avs_dai_resume_be_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
1141 {
1142 int ret;
1143
1144 ret = dai->driver->ops->prepare(data->substream, dai);
1145 if (ret)
1146 dev_err(dai->dev, "prepare BE on resume failed: %d\n", ret);
1147
1148 return ret;
1149 }
1150
avs_dai_suspend_fe_hw_free(struct snd_soc_dai * dai,struct avs_dma_data * data)1151 static int avs_dai_suspend_fe_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
1152 {
1153 struct hdac_ext_stream *host_stream;
1154 int ret;
1155
1156 host_stream = data->host_stream;
1157
1158 /* Store position addresses so we can resume from them later on. */
1159 hdac_stream(host_stream)->lpib = snd_hdac_stream_get_pos_lpib(hdac_stream(host_stream));
1160 host_stream->pphcllpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPL);
1161 host_stream->pphcllpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPU);
1162 host_stream->pphcldpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPL);
1163 host_stream->pphcldpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPU);
1164
1165 ret = __avs_dai_fe_hw_free(data->substream, dai);
1166 if (ret < 0)
1167 dev_err(dai->dev, "hw_free FE on suspend failed: %d\n", ret);
1168
1169 return ret;
1170 }
1171
avs_dai_suspend_be_hw_free(struct snd_soc_dai * dai,struct avs_dma_data * data)1172 static int avs_dai_suspend_be_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
1173 {
1174 int ret;
1175
1176 ret = dai->driver->ops->hw_free(data->substream, dai);
1177 if (ret < 0)
1178 dev_err(dai->dev, "hw_free BE on suspend failed: %d\n", ret);
1179
1180 return ret;
1181 }
1182
avs_component_pm_op(struct snd_soc_component * component,bool be,int (* op)(struct snd_soc_dai *,struct avs_dma_data *))1183 static int avs_component_pm_op(struct snd_soc_component *component, bool be,
1184 int (*op)(struct snd_soc_dai *, struct avs_dma_data *))
1185 {
1186 struct snd_soc_pcm_runtime *rtd;
1187 struct avs_dma_data *data;
1188 struct snd_soc_dai *dai;
1189 int ret;
1190
1191 for_each_component_dais(component, dai) {
1192 data = snd_soc_dai_dma_data_get_playback(dai);
1193 if (data) {
1194 rtd = snd_soc_substream_to_rtd(data->substream);
1195 if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
1196 ret = op(dai, data);
1197 if (ret < 0) {
1198 __snd_pcm_set_state(data->substream->runtime,
1199 SNDRV_PCM_STATE_DISCONNECTED);
1200 return ret;
1201 }
1202 }
1203 }
1204
1205 data = snd_soc_dai_dma_data_get_capture(dai);
1206 if (data) {
1207 rtd = snd_soc_substream_to_rtd(data->substream);
1208 if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
1209 ret = op(dai, data);
1210 if (ret < 0) {
1211 __snd_pcm_set_state(data->substream->runtime,
1212 SNDRV_PCM_STATE_DISCONNECTED);
1213 return ret;
1214 }
1215 }
1216 }
1217 }
1218
1219 return 0;
1220 }
1221
avs_component_resume_hw_params(struct snd_soc_component * component,bool be)1222 static int avs_component_resume_hw_params(struct snd_soc_component *component, bool be)
1223 {
1224 return avs_component_pm_op(component, be, &avs_dai_resume_hw_params);
1225 }
1226
avs_component_resume_prepare(struct snd_soc_component * component,bool be)1227 static int avs_component_resume_prepare(struct snd_soc_component *component, bool be)
1228 {
1229 int (*prepare_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
1230
1231 if (be)
1232 prepare_cb = &avs_dai_resume_be_prepare;
1233 else
1234 prepare_cb = &avs_dai_resume_fe_prepare;
1235
1236 return avs_component_pm_op(component, be, prepare_cb);
1237 }
1238
avs_component_suspend_hw_free(struct snd_soc_component * component,bool be)1239 static int avs_component_suspend_hw_free(struct snd_soc_component *component, bool be)
1240 {
1241 int (*hw_free_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
1242
1243 if (be)
1244 hw_free_cb = &avs_dai_suspend_be_hw_free;
1245 else
1246 hw_free_cb = &avs_dai_suspend_fe_hw_free;
1247
1248 return avs_component_pm_op(component, be, hw_free_cb);
1249 }
1250
avs_component_suspend(struct snd_soc_component * component)1251 static int avs_component_suspend(struct snd_soc_component *component)
1252 {
1253 int ret;
1254
1255 /*
1256 * When freeing paths, FEs need to be first as they perform
1257 * path unbinding.
1258 */
1259 ret = avs_component_suspend_hw_free(component, false);
1260 if (ret)
1261 return ret;
1262
1263 return avs_component_suspend_hw_free(component, true);
1264 }
1265
avs_component_resume(struct snd_soc_component * component)1266 static int avs_component_resume(struct snd_soc_component *component)
1267 {
1268 int ret;
1269
1270 /*
1271 * When creating paths, FEs need to be last as they perform
1272 * path binding.
1273 */
1274 ret = avs_component_resume_hw_params(component, true);
1275 if (ret)
1276 return ret;
1277
1278 ret = avs_component_resume_hw_params(component, false);
1279 if (ret)
1280 return ret;
1281
1282 /* It is expected that the LINK stream is prepared first. */
1283 ret = avs_component_resume_prepare(component, true);
1284 if (ret)
1285 return ret;
1286
1287 return avs_component_resume_prepare(component, false);
1288 }
1289
1290 static const struct snd_pcm_hardware avs_pcm_hardware = {
1291 .info = SNDRV_PCM_INFO_MMAP |
1292 SNDRV_PCM_INFO_MMAP_VALID |
1293 SNDRV_PCM_INFO_INTERLEAVED |
1294 SNDRV_PCM_INFO_PAUSE |
1295 SNDRV_PCM_INFO_RESUME |
1296 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
1297 .formats = SNDRV_PCM_FMTBIT_S16_LE |
1298 SNDRV_PCM_FMTBIT_S32_LE,
1299 .subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1300 SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1301 SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1302 .buffer_bytes_max = AZX_MAX_BUF_SIZE,
1303 .period_bytes_min = 128,
1304 .period_bytes_max = AZX_MAX_BUF_SIZE / 2,
1305 .periods_min = 2,
1306 .periods_max = AZX_MAX_FRAG,
1307 .fifo_size = 0,
1308 };
1309
avs_component_open(struct snd_soc_component * component,struct snd_pcm_substream * substream)1310 static int avs_component_open(struct snd_soc_component *component,
1311 struct snd_pcm_substream *substream)
1312 {
1313 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1314
1315 /* only FE DAI links are handled here */
1316 if (rtd->dai_link->no_pcm)
1317 return 0;
1318
1319 return snd_soc_set_runtime_hwparams(substream, &avs_pcm_hardware);
1320 }
1321
avs_hda_stream_dpib_read(struct hdac_ext_stream * stream)1322 static unsigned int avs_hda_stream_dpib_read(struct hdac_ext_stream *stream)
1323 {
1324 return readl(hdac_stream(stream)->bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE +
1325 (AZX_REG_VS_SDXDPIB_XINTERVAL * hdac_stream(stream)->index));
1326 }
1327
1328 static snd_pcm_uframes_t
avs_component_pointer(struct snd_soc_component * component,struct snd_pcm_substream * substream)1329 avs_component_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream)
1330 {
1331 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1332 struct avs_dma_data *data;
1333 struct hdac_ext_stream *host_stream;
1334 unsigned int pos;
1335
1336 data = snd_soc_dai_get_dma_data(snd_soc_rtd_to_cpu(rtd, 0), substream);
1337 if (!data->host_stream)
1338 return 0;
1339
1340 host_stream = data->host_stream;
1341 pos = avs_hda_stream_dpib_read(host_stream);
1342
1343 if (pos >= hdac_stream(host_stream)->bufsize)
1344 pos = 0;
1345
1346 return bytes_to_frames(substream->runtime, pos);
1347 }
1348
avs_component_mmap(struct snd_soc_component * component,struct snd_pcm_substream * substream,struct vm_area_struct * vma)1349 static int avs_component_mmap(struct snd_soc_component *component,
1350 struct snd_pcm_substream *substream,
1351 struct vm_area_struct *vma)
1352 {
1353 return snd_pcm_lib_default_mmap(substream, vma);
1354 }
1355
1356 #define MAX_PREALLOC_SIZE (32 * 1024 * 1024)
1357
avs_component_new(struct snd_soc_component * component,struct snd_soc_pcm_runtime * rtd)1358 static int avs_component_new(struct snd_soc_component *component,
1359 struct snd_soc_pcm_runtime *rtd)
1360 {
1361 struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0);
1362 struct snd_pcm *pcm = rtd->pcm;
1363
1364 if (dai->driver->playback.channels_min)
1365 snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
1366 SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
1367 MAX_PREALLOC_SIZE);
1368
1369 if (dai->driver->capture.channels_min)
1370 snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
1371 SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
1372 MAX_PREALLOC_SIZE);
1373
1374 return 0;
1375 }
1376
1377 static struct snd_soc_component_driver avs_component_driver = {
1378 .name = "avs-pcm",
1379 .probe = avs_component_probe,
1380 .remove = avs_component_remove,
1381 .suspend = avs_component_suspend,
1382 .resume = avs_component_resume,
1383 .open = avs_component_open,
1384 .pointer = avs_component_pointer,
1385 .mmap = avs_component_mmap,
1386 .pcm_new = avs_component_new,
1387 .module_get_upon_open = 1, /* increment refcount when a pcm is opened */
1388 .topology_name_prefix = "intel/avs",
1389 };
1390
avs_register_component(struct device * dev,const char * name,struct snd_soc_component_driver * drv,struct snd_soc_dai_driver * cpu_dais,int num_cpu_dais)1391 int avs_register_component(struct device *dev, const char *name,
1392 struct snd_soc_component_driver *drv,
1393 struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais)
1394 {
1395 struct avs_soc_component *acomp;
1396 const char *comp_name;
1397
1398 acomp = devm_kzalloc(dev, sizeof(*acomp), GFP_KERNEL);
1399 if (!acomp)
1400 return -ENOMEM;
1401
1402 acomp->base = snd_soc_component_alloc(dev);
1403 if (!acomp->base)
1404 return -ENOMEM;
1405
1406 comp_name = devm_kstrdup(dev, name, GFP_KERNEL);
1407 if (!comp_name)
1408 return -ENOMEM;
1409
1410 INIT_LIST_HEAD(&acomp->node);
1411
1412 drv->use_dai_pcm_id = !obsolete_card_names;
1413
1414 snd_soc_component_set_name(acomp->base, comp_name);
1415 snd_soc_component_set_priv(acomp->base, acomp);
1416
1417 return snd_soc_register_component(acomp->base, drv, cpu_dais, num_cpu_dais);
1418 }
1419
1420 static struct snd_soc_dai_driver dmic_cpu_dais[] = {
1421 {
1422 .name = "DMIC Pin",
1423 .capture = {
1424 .stream_name = "DMIC Rx",
1425 .channels_min = 1,
1426 .channels_max = 4,
1427 .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000,
1428 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
1429 },
1430 },
1431 {
1432 .name = "DMIC WoV Pin",
1433 .capture = {
1434 .stream_name = "DMIC WoV Rx",
1435 .channels_min = 1,
1436 .channels_max = 4,
1437 .rates = SNDRV_PCM_RATE_16000,
1438 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1439 },
1440 },
1441 };
1442
avs_register_dmic_component(struct avs_dev * adev,const char * name)1443 int avs_register_dmic_component(struct avs_dev *adev, const char *name)
1444 {
1445 const struct snd_soc_dai_ops *ops;
1446
1447 if (avs_platattr_test(adev, ALTHDA))
1448 ops = &avs_dai_dmichda_be_ops;
1449 else
1450 ops = &avs_dai_nonhda_be_ops;
1451
1452 dmic_cpu_dais[0].ops = ops;
1453 dmic_cpu_dais[1].ops = ops;
1454 return avs_register_component(adev->dev, name, &avs_component_driver, dmic_cpu_dais,
1455 ARRAY_SIZE(dmic_cpu_dais));
1456 }
1457
1458 static const struct snd_soc_dai_driver i2s_dai_template = {
1459 .playback = {
1460 .channels_min = 1,
1461 .channels_max = AVS_CHANNELS_MAX,
1462 .rates = SNDRV_PCM_RATE_8000_192000 |
1463 SNDRV_PCM_RATE_12000 |
1464 SNDRV_PCM_RATE_24000 |
1465 SNDRV_PCM_RATE_128000,
1466 .formats = SNDRV_PCM_FMTBIT_S16_LE |
1467 SNDRV_PCM_FMTBIT_S32_LE,
1468 .subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1469 SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1470 SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1471 },
1472 .capture = {
1473 .channels_min = 1,
1474 .channels_max = AVS_CHANNELS_MAX,
1475 .rates = SNDRV_PCM_RATE_8000_192000 |
1476 SNDRV_PCM_RATE_12000 |
1477 SNDRV_PCM_RATE_24000 |
1478 SNDRV_PCM_RATE_128000,
1479 .formats = SNDRV_PCM_FMTBIT_S16_LE |
1480 SNDRV_PCM_FMTBIT_S32_LE,
1481 .subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1482 SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1483 SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1484 },
1485 };
1486
avs_register_i2s_component(struct avs_dev * adev,const char * name,unsigned long port_mask,unsigned long * tdms)1487 int avs_register_i2s_component(struct avs_dev *adev, const char *name, unsigned long port_mask,
1488 unsigned long *tdms)
1489 {
1490 struct snd_soc_dai_driver *cpus, *dai;
1491 const struct snd_soc_dai_ops *ops;
1492 size_t ssp_count, cpu_count;
1493 int i, j;
1494
1495 ssp_count = adev->hw_cfg.i2s_caps.ctrl_count;
1496 if (avs_platattr_test(adev, ALTHDA))
1497 ops = &avs_dai_i2shda_be_ops;
1498 else
1499 ops = &avs_dai_nonhda_be_ops;
1500
1501 cpu_count = 0;
1502 for_each_set_bit(i, &port_mask, ssp_count)
1503 if (!tdms || test_bit(0, &tdms[i]))
1504 cpu_count++;
1505 if (tdms)
1506 for_each_set_bit(i, &port_mask, ssp_count)
1507 cpu_count += hweight_long(tdms[i]);
1508
1509 cpus = devm_kcalloc(adev->dev, cpu_count, sizeof(*cpus), GFP_KERNEL);
1510 if (!cpus)
1511 return -ENOMEM;
1512
1513 dai = cpus;
1514 for_each_set_bit(i, &port_mask, ssp_count) {
1515 if (!tdms || test_bit(0, &tdms[i])) {
1516 memcpy(dai, &i2s_dai_template, sizeof(*dai));
1517
1518 dai->name =
1519 devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d Pin", i);
1520 dai->playback.stream_name =
1521 devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Tx", i);
1522 dai->capture.stream_name =
1523 devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Rx", i);
1524
1525 if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
1526 return -ENOMEM;
1527 dai->ops = ops;
1528 dai++;
1529 }
1530 }
1531
1532 if (!tdms)
1533 goto plat_register;
1534
1535 for_each_set_bit(i, &port_mask, ssp_count) {
1536 for_each_set_bit(j, &tdms[i], AVS_CHANNELS_MAX) {
1537 memcpy(dai, &i2s_dai_template, sizeof(*dai));
1538
1539 dai->name =
1540 devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d:%d Pin", i, j);
1541 dai->playback.stream_name =
1542 devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Tx", i, j);
1543 dai->capture.stream_name =
1544 devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Rx", i, j);
1545
1546 if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
1547 return -ENOMEM;
1548 dai->ops = ops;
1549 dai++;
1550 }
1551 }
1552
1553 plat_register:
1554 return avs_register_component(adev->dev, name, &avs_component_driver, cpus, cpu_count);
1555 }
1556
1557 /* HD-Audio CPU DAI template */
1558 static const struct snd_soc_dai_driver hda_cpu_dai = {
1559 .ops = &avs_dai_hda_be_ops,
1560 .playback = {
1561 .channels_min = 1,
1562 .channels_max = AVS_CHANNELS_MAX,
1563 .rates = SNDRV_PCM_RATE_8000_192000,
1564 .formats = SNDRV_PCM_FMTBIT_S16_LE |
1565 SNDRV_PCM_FMTBIT_S32_LE,
1566 .subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1567 SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1568 SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1569 },
1570 .capture = {
1571 .channels_min = 1,
1572 .channels_max = AVS_CHANNELS_MAX,
1573 .rates = SNDRV_PCM_RATE_8000_192000,
1574 .formats = SNDRV_PCM_FMTBIT_S16_LE |
1575 SNDRV_PCM_FMTBIT_S32_LE,
1576 .subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1577 SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1578 SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1579 },
1580 };
1581
avs_component_hda_unregister_dais(struct snd_soc_component * component)1582 static void avs_component_hda_unregister_dais(struct snd_soc_component *component)
1583 {
1584 struct snd_soc_acpi_mach *mach;
1585 struct snd_soc_dai *dai, *save;
1586 struct avs_mach_pdata *pdata;
1587 struct hda_codec *codec;
1588 char name[32];
1589
1590 mach = dev_get_platdata(component->card->dev);
1591 pdata = mach->pdata;
1592 codec = pdata->codec;
1593 snprintf(name, sizeof(name), "%s-cpu", dev_name(&codec->core.dev));
1594
1595 for_each_component_dais_safe(component, dai, save) {
1596 int stream;
1597
1598 if (!strstr(dai->driver->name, name))
1599 continue;
1600
1601 for_each_pcm_streams(stream)
1602 snd_soc_dapm_free_widget(snd_soc_dai_get_widget(dai, stream));
1603
1604 snd_soc_unregister_dai(dai);
1605 }
1606 }
1607
avs_component_hda_probe(struct snd_soc_component * component)1608 static int avs_component_hda_probe(struct snd_soc_component *component)
1609 {
1610 struct snd_soc_dapm_context *dapm;
1611 struct snd_soc_dai_driver *dais;
1612 struct snd_soc_acpi_mach *mach;
1613 struct avs_mach_pdata *pdata;
1614 struct hda_codec *codec;
1615 struct hda_pcm *pcm;
1616 const char *cname;
1617 int pcm_count = 0, ret, i;
1618
1619 mach = dev_get_platdata(component->card->dev);
1620 if (!mach)
1621 return -EINVAL;
1622
1623 pdata = mach->pdata;
1624 codec = pdata->codec;
1625 if (list_empty(&codec->pcm_list_head))
1626 return -EINVAL;
1627 list_for_each_entry(pcm, &codec->pcm_list_head, list)
1628 pcm_count++;
1629
1630 dais = devm_kcalloc(component->dev, pcm_count, sizeof(*dais),
1631 GFP_KERNEL);
1632 if (!dais)
1633 return -ENOMEM;
1634
1635 cname = dev_name(&codec->core.dev);
1636 dapm = snd_soc_component_to_dapm(component);
1637 pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list);
1638
1639 for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) {
1640 struct snd_soc_dai *dai;
1641
1642 memcpy(&dais[i], &hda_cpu_dai, sizeof(*dais));
1643 dais[i].id = i;
1644 dais[i].name = devm_kasprintf(component->dev, GFP_KERNEL,
1645 "%s-cpu%d", cname, i);
1646 if (!dais[i].name) {
1647 ret = -ENOMEM;
1648 goto exit;
1649 }
1650
1651 if (pcm->stream[0].substreams) {
1652 dais[i].playback.stream_name =
1653 devm_kasprintf(component->dev, GFP_KERNEL,
1654 "%s-cpu%d Tx", cname, i);
1655 if (!dais[i].playback.stream_name) {
1656 ret = -ENOMEM;
1657 goto exit;
1658 }
1659
1660 if (!hda_codec_is_display(codec)) {
1661 dais[i].playback.formats = pcm->stream[0].formats;
1662 dais[i].playback.subformats = pcm->stream[0].subformats;
1663 dais[i].playback.rates = pcm->stream[0].rates;
1664 dais[i].playback.channels_min = pcm->stream[0].channels_min;
1665 dais[i].playback.channels_max = pcm->stream[0].channels_max;
1666 dais[i].playback.sig_bits = pcm->stream[0].maxbps;
1667 }
1668 }
1669
1670 if (pcm->stream[1].substreams) {
1671 dais[i].capture.stream_name =
1672 devm_kasprintf(component->dev, GFP_KERNEL,
1673 "%s-cpu%d Rx", cname, i);
1674 if (!dais[i].capture.stream_name) {
1675 ret = -ENOMEM;
1676 goto exit;
1677 }
1678
1679 if (!hda_codec_is_display(codec)) {
1680 dais[i].capture.formats = pcm->stream[1].formats;
1681 dais[i].capture.subformats = pcm->stream[1].subformats;
1682 dais[i].capture.rates = pcm->stream[1].rates;
1683 dais[i].capture.channels_min = pcm->stream[1].channels_min;
1684 dais[i].capture.channels_max = pcm->stream[1].channels_max;
1685 dais[i].capture.sig_bits = pcm->stream[1].maxbps;
1686 }
1687 }
1688
1689 dai = snd_soc_register_dai(component, &dais[i], false);
1690 if (!dai) {
1691 dev_err(component->dev, "register dai for %s failed\n",
1692 pcm->name);
1693 ret = -EINVAL;
1694 goto exit;
1695 }
1696
1697 ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
1698 if (ret < 0) {
1699 dev_err(component->dev, "create widgets failed: %d\n",
1700 ret);
1701 snd_soc_unregister_dai(dai);
1702 goto exit;
1703 }
1704 }
1705
1706 ret = avs_component_probe(component);
1707 exit:
1708 if (ret)
1709 avs_component_hda_unregister_dais(component);
1710
1711 return ret;
1712 }
1713
avs_component_hda_remove(struct snd_soc_component * component)1714 static void avs_component_hda_remove(struct snd_soc_component *component)
1715 {
1716 avs_component_remove(component);
1717 avs_component_hda_unregister_dais(component);
1718 }
1719
avs_component_hda_open(struct snd_soc_component * component,struct snd_pcm_substream * substream)1720 static int avs_component_hda_open(struct snd_soc_component *component,
1721 struct snd_pcm_substream *substream)
1722 {
1723 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1724
1725 if (!rtd->dai_link->no_pcm) {
1726 struct snd_pcm_hardware hwparams = avs_pcm_hardware;
1727 struct snd_soc_pcm_runtime *be;
1728 struct snd_soc_dpcm *dpcm;
1729 int dir = substream->stream;
1730
1731 /*
1732 * Support the DPCM reparenting while still fulfilling expectations of HDAudio
1733 * common code - a valid stream pointer at substream->runtime->private_data -
1734 * by having all FEs point to the same private data.
1735 */
1736 for_each_dpcm_be(rtd, dir, dpcm) {
1737 struct snd_pcm_substream *be_substream;
1738
1739 be = dpcm->be;
1740 if (be->dpcm[dir].users == 1)
1741 break;
1742
1743 be_substream = snd_soc_dpcm_get_substream(be, dir);
1744 substream->runtime->private_data = be_substream->runtime->private_data;
1745 break;
1746 }
1747
1748 /* RESUME unsupported for de-coupled HD-Audio capture. */
1749 if (dir == SNDRV_PCM_STREAM_CAPTURE)
1750 hwparams.info &= ~SNDRV_PCM_INFO_RESUME;
1751
1752 return snd_soc_set_runtime_hwparams(substream, &hwparams);
1753 }
1754
1755 return 0;
1756 }
1757
1758 static struct snd_soc_component_driver avs_hda_component_driver = {
1759 .name = "avs-hda-pcm",
1760 .probe = avs_component_hda_probe,
1761 .remove = avs_component_hda_remove,
1762 .suspend = avs_component_suspend,
1763 .resume = avs_component_resume,
1764 .open = avs_component_hda_open,
1765 .pointer = avs_component_pointer,
1766 .mmap = avs_component_mmap,
1767 .pcm_new = avs_component_new,
1768 /*
1769 * hda platform component's probe() is dependent on
1770 * codec->pcm_list_head, it needs to be initialized after codec
1771 * component. remove_order is here for completeness sake
1772 */
1773 .probe_order = SND_SOC_COMP_ORDER_LATE,
1774 .remove_order = SND_SOC_COMP_ORDER_EARLY,
1775 .module_get_upon_open = 1,
1776 .topology_name_prefix = "intel/avs",
1777 };
1778
avs_register_hda_component(struct avs_dev * adev,const char * name)1779 int avs_register_hda_component(struct avs_dev *adev, const char *name)
1780 {
1781 return avs_register_component(adev->dev, name, &avs_hda_component_driver, NULL, 0);
1782 }
1783