ASoC: Intel: avs: Handle SUSPEND and RESUME triggers
[platform/kernel/linux-starfive.git] / sound / soc / intel / avs / pcm.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
4 //
5 // Authors: Cezary Rojewski <cezary.rojewski@intel.com>
6 //          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
7 //
8
9 #include <linux/debugfs.h>
10 #include <linux/device.h>
11 #include <sound/hda_register.h>
12 #include <sound/hdaudio_ext.h>
13 #include <sound/pcm_params.h>
14 #include <sound/soc-acpi.h>
15 #include <sound/soc-acpi-intel-match.h>
16 #include <sound/soc-component.h>
17 #include "avs.h"
18 #include "path.h"
19 #include "topology.h"
20
21 struct avs_dma_data {
22         struct avs_tplg_path_template *template;
23         struct avs_path *path;
24         /*
25          * link stream is stored within substream's runtime
26          * private_data to fulfill the needs of codec BE path
27          *
28          * host stream assigned
29          */
30         struct hdac_ext_stream *host_stream;
31
32         struct snd_pcm_substream *substream;
33 };
34
35 static struct avs_tplg_path_template *
36 avs_dai_find_path_template(struct snd_soc_dai *dai, bool is_fe, int direction)
37 {
38         struct snd_soc_dapm_widget *dw;
39         struct snd_soc_dapm_path *dp;
40         enum snd_soc_dapm_direction dir;
41
42         if (direction == SNDRV_PCM_STREAM_CAPTURE) {
43                 dw = dai->capture_widget;
44                 dir = is_fe ? SND_SOC_DAPM_DIR_OUT : SND_SOC_DAPM_DIR_IN;
45         } else {
46                 dw = dai->playback_widget;
47                 dir = is_fe ? SND_SOC_DAPM_DIR_IN : SND_SOC_DAPM_DIR_OUT;
48         }
49
50         dp = list_first_entry_or_null(&dw->edges[dir], typeof(*dp), list_node[dir]);
51         if (!dp)
52                 return NULL;
53
54         /* Get the other widget, with actual path template data */
55         dw = (dp->source == dw) ? dp->sink : dp->source;
56
57         return dw->priv;
58 }
59
60 static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, bool is_fe,
61                            const struct snd_soc_dai_ops *ops)
62 {
63         struct avs_tplg_path_template *template;
64         struct avs_dma_data *data;
65
66         template = avs_dai_find_path_template(dai, is_fe, substream->stream);
67         if (!template) {
68                 dev_err(dai->dev, "no %s path for dai %s, invalid tplg?\n",
69                         snd_pcm_stream_str(substream), dai->name);
70                 return -EINVAL;
71         }
72
73         data = kzalloc(sizeof(*data), GFP_KERNEL);
74         if (!data)
75                 return -ENOMEM;
76
77         data->substream = substream;
78         data->template = template;
79         snd_soc_dai_set_dma_data(dai, substream, data);
80
81         return 0;
82 }
83
84 static int avs_dai_hw_params(struct snd_pcm_substream *substream,
85                              struct snd_pcm_hw_params *fe_hw_params,
86                              struct snd_pcm_hw_params *be_hw_params, struct snd_soc_dai *dai,
87                              int dma_id)
88 {
89         struct avs_dma_data *data;
90         struct avs_path *path;
91         struct avs_dev *adev = to_avs_dev(dai->dev);
92         int ret;
93
94         data = snd_soc_dai_get_dma_data(dai, substream);
95
96         dev_dbg(dai->dev, "%s FE hw_params str %p rtd %p",
97                 __func__, substream, substream->runtime);
98         dev_dbg(dai->dev, "rate %d chn %d vbd %d bd %d\n",
99                 params_rate(fe_hw_params), params_channels(fe_hw_params),
100                 params_width(fe_hw_params), params_physical_width(fe_hw_params));
101
102         dev_dbg(dai->dev, "%s BE hw_params str %p rtd %p",
103                 __func__, substream, substream->runtime);
104         dev_dbg(dai->dev, "rate %d chn %d vbd %d bd %d\n",
105                 params_rate(be_hw_params), params_channels(be_hw_params),
106                 params_width(be_hw_params), params_physical_width(be_hw_params));
107
108         path = avs_path_create(adev, dma_id, data->template, fe_hw_params, be_hw_params);
109         if (IS_ERR(path)) {
110                 ret = PTR_ERR(path);
111                 dev_err(dai->dev, "create path failed: %d\n", ret);
112                 return ret;
113         }
114
115         data->path = path;
116         return 0;
117 }
118
119 static int avs_dai_be_hw_params(struct snd_pcm_substream *substream,
120                                 struct snd_pcm_hw_params *be_hw_params, struct snd_soc_dai *dai,
121                                 int dma_id)
122 {
123         struct snd_pcm_hw_params *fe_hw_params = NULL;
124         struct snd_soc_pcm_runtime *fe, *be;
125         struct snd_soc_dpcm *dpcm;
126
127         be = asoc_substream_to_rtd(substream);
128         for_each_dpcm_fe(be, substream->stream, dpcm) {
129                 fe = dpcm->fe;
130                 fe_hw_params = &fe->dpcm[substream->stream].hw_params;
131         }
132
133         return avs_dai_hw_params(substream, fe_hw_params, be_hw_params, dai, dma_id);
134 }
135
136 static int avs_dai_prepare(struct avs_dev *adev, struct snd_pcm_substream *substream,
137                            struct snd_soc_dai *dai)
138 {
139         struct avs_dma_data *data;
140         int ret;
141
142         data = snd_soc_dai_get_dma_data(dai, substream);
143         if (!data->path)
144                 return 0;
145
146         ret = avs_path_reset(data->path);
147         if (ret < 0) {
148                 dev_err(dai->dev, "reset path failed: %d\n", ret);
149                 return ret;
150         }
151
152         ret = avs_path_pause(data->path);
153         if (ret < 0)
154                 dev_err(dai->dev, "pause path failed: %d\n", ret);
155         return ret;
156 }
157
158 static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops;
159
160 static int avs_dai_nonhda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
161 {
162         return avs_dai_startup(substream, dai, false, &avs_dai_nonhda_be_ops);
163 }
164
165 static void avs_dai_nonhda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
166 {
167         struct avs_dma_data *data;
168
169         data = snd_soc_dai_get_dma_data(dai, substream);
170
171         snd_soc_dai_set_dma_data(dai, substream, NULL);
172         kfree(data);
173 }
174
175 static int avs_dai_nonhda_be_hw_params(struct snd_pcm_substream *substream,
176                                        struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
177 {
178         struct avs_dma_data *data;
179
180         data = snd_soc_dai_get_dma_data(dai, substream);
181         if (data->path)
182                 return 0;
183
184         /* Actual port-id comes from topology. */
185         return avs_dai_be_hw_params(substream, hw_params, dai, 0);
186 }
187
188 static int avs_dai_nonhda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
189 {
190         struct avs_dma_data *data;
191
192         dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
193
194         data = snd_soc_dai_get_dma_data(dai, substream);
195         if (data->path) {
196                 avs_path_free(data->path);
197                 data->path = NULL;
198         }
199
200         return 0;
201 }
202
203 static int avs_dai_nonhda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
204 {
205         return avs_dai_prepare(to_avs_dev(dai->dev), substream, dai);
206 }
207
208 static int avs_dai_nonhda_be_trigger(struct snd_pcm_substream *substream, int cmd,
209                                      struct snd_soc_dai *dai)
210 {
211         struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
212         struct avs_dma_data *data;
213         int ret = 0;
214
215         data = snd_soc_dai_get_dma_data(dai, substream);
216
217         switch (cmd) {
218         case SNDRV_PCM_TRIGGER_RESUME:
219                 if (rtd->dai_link->ignore_suspend)
220                         break;
221                 fallthrough;
222         case SNDRV_PCM_TRIGGER_START:
223         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
224                 ret = avs_path_pause(data->path);
225                 if (ret < 0) {
226                         dev_err(dai->dev, "pause BE path failed: %d\n", ret);
227                         break;
228                 }
229
230                 ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
231                 if (ret < 0)
232                         dev_err(dai->dev, "run BE path failed: %d\n", ret);
233                 break;
234
235         case SNDRV_PCM_TRIGGER_SUSPEND:
236                 if (rtd->dai_link->ignore_suspend)
237                         break;
238                 fallthrough;
239         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
240         case SNDRV_PCM_TRIGGER_STOP:
241                 ret = avs_path_pause(data->path);
242                 if (ret < 0)
243                         dev_err(dai->dev, "pause BE path failed: %d\n", ret);
244
245                 ret = avs_path_reset(data->path);
246                 if (ret < 0)
247                         dev_err(dai->dev, "reset BE path failed: %d\n", ret);
248                 break;
249
250         default:
251                 ret = -EINVAL;
252                 break;
253         }
254
255         return ret;
256 }
257
258 static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops = {
259         .startup = avs_dai_nonhda_be_startup,
260         .shutdown = avs_dai_nonhda_be_shutdown,
261         .hw_params = avs_dai_nonhda_be_hw_params,
262         .hw_free = avs_dai_nonhda_be_hw_free,
263         .prepare = avs_dai_nonhda_be_prepare,
264         .trigger = avs_dai_nonhda_be_trigger,
265 };
266
267 static const struct snd_soc_dai_ops avs_dai_hda_be_ops;
268
269 static int avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
270 {
271         return avs_dai_startup(substream, dai, false, &avs_dai_hda_be_ops);
272 }
273
274 static void avs_dai_hda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
275 {
276         return avs_dai_nonhda_be_shutdown(substream, dai);
277 }
278
279 static int avs_dai_hda_be_hw_params(struct snd_pcm_substream *substream,
280                                     struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
281 {
282         struct avs_dma_data *data;
283         struct hdac_ext_stream *link_stream;
284
285         data = snd_soc_dai_get_dma_data(dai, substream);
286         if (data->path)
287                 return 0;
288
289         link_stream = substream->runtime->private_data;
290
291         return avs_dai_be_hw_params(substream, hw_params, dai,
292                                     hdac_stream(link_stream)->stream_tag - 1);
293 }
294
295 static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
296 {
297         struct avs_dma_data *data;
298         struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
299         struct hdac_ext_stream *link_stream;
300         struct hdac_ext_link *link;
301         struct hda_codec *codec;
302
303         dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
304
305         data = snd_soc_dai_get_dma_data(dai, substream);
306         if (!data->path)
307                 return 0;
308
309         link_stream = substream->runtime->private_data;
310         link_stream->link_prepared = false;
311         avs_path_free(data->path);
312         data->path = NULL;
313
314         /* clear link <-> stream mapping */
315         codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev);
316         link = snd_hdac_ext_bus_get_hlink_by_addr(&codec->bus->core, codec->core.addr);
317         if (!link)
318                 return -EINVAL;
319
320         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
321                 snd_hdac_ext_bus_link_clear_stream_id(link, hdac_stream(link_stream)->stream_tag);
322
323         return 0;
324 }
325
326 static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
327 {
328         struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
329         struct snd_pcm_runtime *runtime = substream->runtime;
330         struct hdac_ext_stream *link_stream = runtime->private_data;
331         struct hdac_ext_link *link;
332         struct hda_codec *codec;
333         struct hdac_bus *bus;
334         unsigned int format_val;
335         int ret;
336
337         if (link_stream->link_prepared)
338                 return 0;
339
340         codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev);
341         bus = &codec->bus->core;
342         format_val = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format,
343                                                  runtime->sample_bits, 0);
344
345         snd_hdac_ext_stream_decouple(bus, link_stream, true);
346         snd_hdac_ext_stream_reset(link_stream);
347         snd_hdac_ext_stream_setup(link_stream, format_val);
348
349         link = snd_hdac_ext_bus_get_hlink_by_addr(bus, codec->core.addr);
350         if (!link)
351                 return -EINVAL;
352
353         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
354                 snd_hdac_ext_bus_link_set_stream_id(link, hdac_stream(link_stream)->stream_tag);
355
356         ret = avs_dai_prepare(to_avs_dev(dai->dev), substream, dai);
357         if (ret)
358                 return ret;
359
360         link_stream->link_prepared = true;
361         return 0;
362 }
363
364 static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
365                                   struct snd_soc_dai *dai)
366 {
367         struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
368         struct hdac_ext_stream *link_stream;
369         struct avs_dma_data *data;
370         int ret = 0;
371
372         dev_dbg(dai->dev, "entry %s cmd=%d\n", __func__, cmd);
373
374         data = snd_soc_dai_get_dma_data(dai, substream);
375         link_stream = substream->runtime->private_data;
376
377         switch (cmd) {
378         case SNDRV_PCM_TRIGGER_RESUME:
379                 if (rtd->dai_link->ignore_suspend)
380                         break;
381                 fallthrough;
382         case SNDRV_PCM_TRIGGER_START:
383         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
384                 snd_hdac_ext_stream_start(link_stream);
385
386                 ret = avs_path_pause(data->path);
387                 if (ret < 0) {
388                         dev_err(dai->dev, "pause BE path failed: %d\n", ret);
389                         break;
390                 }
391
392                 ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
393                 if (ret < 0)
394                         dev_err(dai->dev, "run BE path failed: %d\n", ret);
395                 break;
396
397         case SNDRV_PCM_TRIGGER_SUSPEND:
398                 if (rtd->dai_link->ignore_suspend)
399                         break;
400                 fallthrough;
401         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
402         case SNDRV_PCM_TRIGGER_STOP:
403                 ret = avs_path_pause(data->path);
404                 if (ret < 0)
405                         dev_err(dai->dev, "pause BE path failed: %d\n", ret);
406
407                 snd_hdac_ext_stream_clear(link_stream);
408
409                 ret = avs_path_reset(data->path);
410                 if (ret < 0)
411                         dev_err(dai->dev, "reset BE path failed: %d\n", ret);
412                 break;
413
414         default:
415                 ret = -EINVAL;
416                 break;
417         }
418
419         return ret;
420 }
421
422 static const struct snd_soc_dai_ops avs_dai_hda_be_ops = {
423         .startup = avs_dai_hda_be_startup,
424         .shutdown = avs_dai_hda_be_shutdown,
425         .hw_params = avs_dai_hda_be_hw_params,
426         .hw_free = avs_dai_hda_be_hw_free,
427         .prepare = avs_dai_hda_be_prepare,
428         .trigger = avs_dai_hda_be_trigger,
429 };
430
431 static const unsigned int rates[] = {
432         8000, 11025, 12000, 16000,
433         22050, 24000, 32000, 44100,
434         48000, 64000, 88200, 96000,
435         128000, 176400, 192000,
436 };
437
438 static const struct snd_pcm_hw_constraint_list hw_rates = {
439         .count = ARRAY_SIZE(rates),
440         .list = rates,
441         .mask = 0,
442 };
443
444 const struct snd_soc_dai_ops avs_dai_fe_ops;
445
446 static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
447 {
448         struct snd_pcm_runtime *runtime = substream->runtime;
449         struct avs_dma_data *data;
450         struct avs_dev *adev = to_avs_dev(dai->dev);
451         struct hdac_bus *bus = &adev->base.core;
452         struct hdac_ext_stream *host_stream;
453         int ret;
454
455         ret = avs_dai_startup(substream, dai, true, &avs_dai_fe_ops);
456         if (ret)
457                 return ret;
458
459         data = snd_soc_dai_get_dma_data(dai, substream);
460
461         host_stream = snd_hdac_ext_stream_assign(bus, substream, HDAC_EXT_STREAM_TYPE_HOST);
462         if (!host_stream) {
463                 kfree(data);
464                 return -EBUSY;
465         }
466
467         data->host_stream = host_stream;
468         snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
469         /* avoid wrap-around with wall-clock */
470         snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME, 20, 178000000);
471         snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_rates);
472         snd_pcm_set_sync(substream);
473
474         dev_dbg(dai->dev, "%s fe STARTUP tag %d str %p",
475                 __func__, hdac_stream(host_stream)->stream_tag, substream);
476
477         return 0;
478 }
479
480 static void avs_dai_fe_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
481 {
482         struct avs_dma_data *data;
483
484         data = snd_soc_dai_get_dma_data(dai, substream);
485
486         snd_soc_dai_set_dma_data(dai, substream, NULL);
487         snd_hdac_ext_stream_release(data->host_stream, HDAC_EXT_STREAM_TYPE_HOST);
488         kfree(data);
489 }
490
491 static int avs_dai_fe_hw_params(struct snd_pcm_substream *substream,
492                                 struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
493 {
494         struct snd_pcm_hw_params *be_hw_params = NULL;
495         struct snd_soc_pcm_runtime *fe, *be;
496         struct snd_soc_dpcm *dpcm;
497         struct avs_dma_data *data;
498         struct hdac_ext_stream *host_stream;
499         int ret;
500
501         data = snd_soc_dai_get_dma_data(dai, substream);
502         if (data->path)
503                 return 0;
504
505         host_stream = data->host_stream;
506
507         hdac_stream(host_stream)->bufsize = 0;
508         hdac_stream(host_stream)->period_bytes = 0;
509         hdac_stream(host_stream)->format_val = 0;
510
511         fe = asoc_substream_to_rtd(substream);
512         for_each_dpcm_be(fe, substream->stream, dpcm) {
513                 be = dpcm->be;
514                 be_hw_params = &be->dpcm[substream->stream].hw_params;
515         }
516
517         ret = avs_dai_hw_params(substream, hw_params, be_hw_params, dai,
518                                 hdac_stream(host_stream)->stream_tag - 1);
519         if (ret)
520                 goto create_err;
521
522         ret = avs_path_bind(data->path);
523         if (ret < 0) {
524                 dev_err(dai->dev, "bind FE <-> BE failed: %d\n", ret);
525                 goto bind_err;
526         }
527
528         return 0;
529
530 bind_err:
531         avs_path_free(data->path);
532         data->path = NULL;
533 create_err:
534         snd_pcm_lib_free_pages(substream);
535         return ret;
536 }
537
538 static int __avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
539 {
540         struct avs_dma_data *data;
541         struct hdac_ext_stream *host_stream;
542         int ret;
543
544         dev_dbg(dai->dev, "%s fe HW_FREE str %p rtd %p",
545                 __func__, substream, substream->runtime);
546
547         data = snd_soc_dai_get_dma_data(dai, substream);
548         if (!data->path)
549                 return 0;
550
551         host_stream = data->host_stream;
552
553         ret = avs_path_unbind(data->path);
554         if (ret < 0)
555                 dev_err(dai->dev, "unbind FE <-> BE failed: %d\n", ret);
556
557         avs_path_free(data->path);
558         data->path = NULL;
559         snd_hdac_stream_cleanup(hdac_stream(host_stream));
560         hdac_stream(host_stream)->prepared = false;
561
562         return ret;
563 }
564
565 static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
566 {
567         int ret;
568
569         ret = __avs_dai_fe_hw_free(substream, dai);
570         snd_pcm_lib_free_pages(substream);
571
572         return ret;
573 }
574
575 static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
576 {
577         struct snd_pcm_runtime *runtime = substream->runtime;
578         struct avs_dma_data *data;
579         struct avs_dev *adev = to_avs_dev(dai->dev);
580         struct hdac_ext_stream *host_stream;
581         struct hdac_bus *bus;
582         unsigned int format_val;
583         int ret;
584
585         data = snd_soc_dai_get_dma_data(dai, substream);
586         host_stream = data->host_stream;
587
588         if (hdac_stream(host_stream)->prepared)
589                 return 0;
590
591         bus = hdac_stream(host_stream)->bus;
592         snd_hdac_ext_stream_decouple(bus, data->host_stream, true);
593         snd_hdac_stream_reset(hdac_stream(host_stream));
594
595         format_val = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format,
596                                                  runtime->sample_bits, 0);
597
598         ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val);
599         if (ret < 0)
600                 return ret;
601
602         ret = snd_hdac_stream_setup(hdac_stream(host_stream));
603         if (ret < 0)
604                 return ret;
605
606         ret = avs_dai_prepare(adev, substream, dai);
607         if (ret)
608                 return ret;
609
610         hdac_stream(host_stream)->prepared = true;
611         return 0;
612 }
613
614 static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
615 {
616         struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
617         struct avs_dma_data *data;
618         struct hdac_ext_stream *host_stream;
619         struct hdac_bus *bus;
620         unsigned long flags;
621         int ret = 0;
622
623         data = snd_soc_dai_get_dma_data(dai, substream);
624         host_stream = data->host_stream;
625         bus = hdac_stream(host_stream)->bus;
626
627         switch (cmd) {
628         case SNDRV_PCM_TRIGGER_RESUME:
629                 if (rtd->dai_link->ignore_suspend)
630                         break;
631                 fallthrough;
632         case SNDRV_PCM_TRIGGER_START:
633         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
634                 spin_lock_irqsave(&bus->reg_lock, flags);
635                 snd_hdac_stream_start(hdac_stream(host_stream), true);
636                 spin_unlock_irqrestore(&bus->reg_lock, flags);
637
638                 /* Timeout on DRSM poll shall not stop the resume so ignore the result. */
639                 if (cmd == SNDRV_PCM_TRIGGER_RESUME)
640                         snd_hdac_stream_wait_drsm(hdac_stream(host_stream));
641
642                 ret = avs_path_pause(data->path);
643                 if (ret < 0) {
644                         dev_err(dai->dev, "pause FE path failed: %d\n", ret);
645                         break;
646                 }
647
648                 ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
649                 if (ret < 0)
650                         dev_err(dai->dev, "run FE path failed: %d\n", ret);
651
652                 break;
653
654         case SNDRV_PCM_TRIGGER_SUSPEND:
655                 if (rtd->dai_link->ignore_suspend)
656                         break;
657                 fallthrough;
658         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
659         case SNDRV_PCM_TRIGGER_STOP:
660                 ret = avs_path_pause(data->path);
661                 if (ret < 0)
662                         dev_err(dai->dev, "pause FE path failed: %d\n", ret);
663
664                 spin_lock_irqsave(&bus->reg_lock, flags);
665                 snd_hdac_stream_stop(hdac_stream(host_stream));
666                 spin_unlock_irqrestore(&bus->reg_lock, flags);
667
668                 ret = avs_path_reset(data->path);
669                 if (ret < 0)
670                         dev_err(dai->dev, "reset FE path failed: %d\n", ret);
671                 break;
672
673         default:
674                 ret = -EINVAL;
675                 break;
676         }
677
678         return ret;
679 }
680
681 const struct snd_soc_dai_ops avs_dai_fe_ops = {
682         .startup = avs_dai_fe_startup,
683         .shutdown = avs_dai_fe_shutdown,
684         .hw_params = avs_dai_fe_hw_params,
685         .hw_free = avs_dai_fe_hw_free,
686         .prepare = avs_dai_fe_prepare,
687         .trigger = avs_dai_fe_trigger,
688 };
689
690 static ssize_t topology_name_read(struct file *file, char __user *user_buf, size_t count,
691                                   loff_t *ppos)
692 {
693         struct snd_soc_component *component = file->private_data;
694         struct snd_soc_card *card = component->card;
695         struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
696         char buf[64];
697         size_t len;
698
699         len = scnprintf(buf, sizeof(buf), "%s/%s\n", component->driver->topology_name_prefix,
700                         mach->tplg_filename);
701
702         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
703 }
704
705 static const struct file_operations topology_name_fops = {
706         .open = simple_open,
707         .read = topology_name_read,
708         .llseek = default_llseek,
709 };
710
711 static int avs_component_load_libraries(struct avs_soc_component *acomp)
712 {
713         struct avs_tplg *tplg = acomp->tplg;
714         struct avs_dev *adev = to_avs_dev(acomp->base.dev);
715         int ret;
716
717         if (!tplg->num_libs)
718                 return 0;
719
720         /* Parent device may be asleep and library loading involves IPCs. */
721         ret = pm_runtime_resume_and_get(adev->dev);
722         if (ret < 0)
723                 return ret;
724
725         avs_hda_clock_gating_enable(adev, false);
726         avs_hda_l1sen_enable(adev, false);
727
728         ret = avs_dsp_load_libraries(adev, tplg->libs, tplg->num_libs);
729
730         avs_hda_l1sen_enable(adev, true);
731         avs_hda_clock_gating_enable(adev, true);
732
733         if (!ret)
734                 ret = avs_module_info_init(adev, false);
735
736         pm_runtime_mark_last_busy(adev->dev);
737         pm_runtime_put_autosuspend(adev->dev);
738
739         return ret;
740 }
741
742 static int avs_component_probe(struct snd_soc_component *component)
743 {
744         struct snd_soc_card *card = component->card;
745         struct snd_soc_acpi_mach *mach;
746         struct avs_soc_component *acomp;
747         struct avs_dev *adev;
748         char *filename;
749         int ret;
750
751         dev_dbg(card->dev, "probing %s card %s\n", component->name, card->name);
752         mach = dev_get_platdata(card->dev);
753         acomp = to_avs_soc_component(component);
754         adev = to_avs_dev(component->dev);
755
756         acomp->tplg = avs_tplg_new(component);
757         if (!acomp->tplg)
758                 return -ENOMEM;
759
760         if (!mach->tplg_filename)
761                 goto finalize;
762
763         /* Load specified topology and create debugfs for it. */
764         filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
765                              mach->tplg_filename);
766         if (!filename)
767                 return -ENOMEM;
768
769         ret = avs_load_topology(component, filename);
770         kfree(filename);
771         if (ret < 0)
772                 return ret;
773
774         ret = avs_component_load_libraries(acomp);
775         if (ret < 0) {
776                 dev_err(card->dev, "libraries loading failed: %d\n", ret);
777                 goto err_load_libs;
778         }
779
780 finalize:
781         debugfs_create_file("topology_name", 0444, component->debugfs_root, component,
782                             &topology_name_fops);
783
784         mutex_lock(&adev->comp_list_mutex);
785         list_add_tail(&acomp->node, &adev->comp_list);
786         mutex_unlock(&adev->comp_list_mutex);
787
788         return 0;
789
790 err_load_libs:
791         avs_remove_topology(component);
792         return ret;
793 }
794
795 static void avs_component_remove(struct snd_soc_component *component)
796 {
797         struct avs_soc_component *acomp = to_avs_soc_component(component);
798         struct snd_soc_acpi_mach *mach;
799         struct avs_dev *adev = to_avs_dev(component->dev);
800         int ret;
801
802         mach = dev_get_platdata(component->card->dev);
803
804         mutex_lock(&adev->comp_list_mutex);
805         list_del(&acomp->node);
806         mutex_unlock(&adev->comp_list_mutex);
807
808         if (mach->tplg_filename) {
809                 ret = avs_remove_topology(component);
810                 if (ret < 0)
811                         dev_err(component->dev, "unload topology failed: %d\n", ret);
812         }
813 }
814
815 static int avs_dai_resume_hw_params(struct snd_soc_dai *dai, struct avs_dma_data *data)
816 {
817         struct snd_pcm_substream *substream;
818         struct snd_soc_pcm_runtime *rtd;
819         int ret;
820
821         substream = data->substream;
822         rtd = snd_pcm_substream_chip(substream);
823
824         ret = dai->driver->ops->hw_params(substream, &rtd->dpcm[substream->stream].hw_params, dai);
825         if (ret)
826                 dev_err(dai->dev, "hw_params on resume failed: %d\n", ret);
827
828         return ret;
829 }
830
831 static int avs_dai_resume_fe_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
832 {
833         struct hdac_ext_stream *host_stream;
834         struct hdac_stream *hstream;
835         struct hdac_bus *bus;
836         int ret;
837
838         host_stream = data->host_stream;
839         hstream = hdac_stream(host_stream);
840         bus = hdac_stream(host_stream)->bus;
841
842         /* Set DRSM before programming stream and position registers. */
843         snd_hdac_stream_drsm_enable(bus, true, hstream->index);
844
845         ret = dai->driver->ops->prepare(data->substream, dai);
846         if (ret) {
847                 dev_err(dai->dev, "prepare FE on resume failed: %d\n", ret);
848                 return ret;
849         }
850
851         writel(host_stream->pphcllpl, host_stream->pphc_addr + AZX_REG_PPHCLLPL);
852         writel(host_stream->pphcllpu, host_stream->pphc_addr + AZX_REG_PPHCLLPU);
853         writel(host_stream->pphcldpl, host_stream->pphc_addr + AZX_REG_PPHCLDPL);
854         writel(host_stream->pphcldpu, host_stream->pphc_addr + AZX_REG_PPHCLDPU);
855
856         /* As per HW spec recommendation, program LPIB and DPIB to the same value. */
857         snd_hdac_stream_set_lpib(hstream, hstream->lpib);
858         snd_hdac_stream_set_dpibr(bus, hstream, hstream->lpib);
859
860         return 0;
861 }
862
863 static int avs_dai_resume_be_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
864 {
865         int ret;
866
867         ret = dai->driver->ops->prepare(data->substream, dai);
868         if (ret)
869                 dev_err(dai->dev, "prepare BE on resume failed: %d\n", ret);
870
871         return ret;
872 }
873
874 static int avs_dai_suspend_fe_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
875 {
876         struct hdac_ext_stream *host_stream;
877         int ret;
878
879         host_stream = data->host_stream;
880
881         /* Store position addresses so we can resume from them later on. */
882         hdac_stream(host_stream)->lpib = snd_hdac_stream_get_pos_lpib(hdac_stream(host_stream));
883         host_stream->pphcllpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPL);
884         host_stream->pphcllpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPU);
885         host_stream->pphcldpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPL);
886         host_stream->pphcldpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPU);
887
888         ret = __avs_dai_fe_hw_free(data->substream, dai);
889         if (ret < 0)
890                 dev_err(dai->dev, "hw_free FE on suspend failed: %d\n", ret);
891
892         return ret;
893 }
894
895 static int avs_dai_suspend_be_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
896 {
897         int ret;
898
899         ret = dai->driver->ops->hw_free(data->substream, dai);
900         if (ret < 0)
901                 dev_err(dai->dev, "hw_free BE on suspend failed: %d\n", ret);
902
903         return ret;
904 }
905
906 static int avs_component_pm_op(struct snd_soc_component *component, bool be,
907                                int (*op)(struct snd_soc_dai *, struct avs_dma_data *))
908 {
909         struct snd_soc_pcm_runtime *rtd;
910         struct avs_dma_data *data;
911         struct snd_soc_dai *dai;
912         int ret;
913
914         for_each_component_dais(component, dai) {
915                 data = dai->playback_dma_data;
916                 if (data) {
917                         rtd = snd_pcm_substream_chip(data->substream);
918                         if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
919                                 ret = op(dai, data);
920                                 if (ret < 0)
921                                         return ret;
922                         }
923                 }
924
925                 data = dai->capture_dma_data;
926                 if (data) {
927                         rtd = snd_pcm_substream_chip(data->substream);
928                         if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
929                                 ret = op(dai, data);
930                                 if (ret < 0)
931                                         return ret;
932                         }
933                 }
934         }
935
936         return 0;
937 }
938
939 static int avs_component_resume_hw_params(struct snd_soc_component *component, bool be)
940 {
941         return avs_component_pm_op(component, be, &avs_dai_resume_hw_params);
942 }
943
944 static int avs_component_resume_prepare(struct snd_soc_component *component, bool be)
945 {
946         int (*prepare_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
947
948         if (be)
949                 prepare_cb = &avs_dai_resume_be_prepare;
950         else
951                 prepare_cb = &avs_dai_resume_fe_prepare;
952
953         return avs_component_pm_op(component, be, prepare_cb);
954 }
955
956 static int avs_component_suspend_hw_free(struct snd_soc_component *component, bool be)
957 {
958         int (*hw_free_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
959
960         if (be)
961                 hw_free_cb = &avs_dai_suspend_be_hw_free;
962         else
963                 hw_free_cb = &avs_dai_suspend_fe_hw_free;
964
965         return avs_component_pm_op(component, be, hw_free_cb);
966 }
967
968 static int avs_component_suspend(struct snd_soc_component *component)
969 {
970         int ret;
971
972         /*
973          * When freeing paths, FEs need to be first as they perform
974          * path unbinding.
975          */
976         ret = avs_component_suspend_hw_free(component, false);
977         if (ret)
978                 return ret;
979
980         return avs_component_suspend_hw_free(component, true);
981 }
982
983 static int avs_component_resume(struct snd_soc_component *component)
984 {
985         int ret;
986
987         /*
988          * When creating paths, FEs need to be last as they perform
989          * path binding.
990          */
991         ret = avs_component_resume_hw_params(component, true);
992         if (ret)
993                 return ret;
994
995         ret = avs_component_resume_hw_params(component, false);
996         if (ret)
997                 return ret;
998
999         /* It is expected that the LINK stream is prepared first. */
1000         ret = avs_component_resume_prepare(component, true);
1001         if (ret)
1002                 return ret;
1003
1004         return avs_component_resume_prepare(component, false);
1005 }
1006
1007 static int avs_component_open(struct snd_soc_component *component,
1008                               struct snd_pcm_substream *substream)
1009 {
1010         struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
1011         struct snd_pcm_hardware hwparams;
1012
1013         /* only FE DAI links are handled here */
1014         if (rtd->dai_link->no_pcm)
1015                 return 0;
1016
1017         hwparams.info = SNDRV_PCM_INFO_MMAP |
1018                         SNDRV_PCM_INFO_MMAP_VALID |
1019                         SNDRV_PCM_INFO_INTERLEAVED |
1020                         SNDRV_PCM_INFO_PAUSE |
1021                         SNDRV_PCM_INFO_RESUME |
1022                         SNDRV_PCM_INFO_NO_PERIOD_WAKEUP;
1023
1024         hwparams.formats = SNDRV_PCM_FMTBIT_S16_LE |
1025                            SNDRV_PCM_FMTBIT_S24_LE |
1026                            SNDRV_PCM_FMTBIT_S32_LE;
1027         hwparams.period_bytes_min = 128;
1028         hwparams.period_bytes_max = AZX_MAX_BUF_SIZE / 2;
1029         hwparams.periods_min = 2;
1030         hwparams.periods_max = AZX_MAX_FRAG;
1031         hwparams.buffer_bytes_max = AZX_MAX_BUF_SIZE;
1032         hwparams.fifo_size = 0;
1033
1034         return snd_soc_set_runtime_hwparams(substream, &hwparams);
1035 }
1036
1037 static unsigned int avs_hda_stream_dpib_read(struct hdac_ext_stream *stream)
1038 {
1039         return readl(hdac_stream(stream)->bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE +
1040                      (AZX_REG_VS_SDXDPIB_XINTERVAL * hdac_stream(stream)->index));
1041 }
1042
1043 static snd_pcm_uframes_t
1044 avs_component_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream)
1045 {
1046         struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
1047         struct avs_dma_data *data;
1048         struct hdac_ext_stream *host_stream;
1049         unsigned int pos;
1050
1051         data = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream);
1052         if (!data->host_stream)
1053                 return 0;
1054
1055         host_stream = data->host_stream;
1056         pos = avs_hda_stream_dpib_read(host_stream);
1057
1058         if (pos >= hdac_stream(host_stream)->bufsize)
1059                 pos = 0;
1060
1061         return bytes_to_frames(substream->runtime, pos);
1062 }
1063
1064 static int avs_component_mmap(struct snd_soc_component *component,
1065                               struct snd_pcm_substream *substream,
1066                               struct vm_area_struct *vma)
1067 {
1068         return snd_pcm_lib_default_mmap(substream, vma);
1069 }
1070
1071 #define MAX_PREALLOC_SIZE       (32 * 1024 * 1024)
1072
1073 static int avs_component_construct(struct snd_soc_component *component,
1074                                    struct snd_soc_pcm_runtime *rtd)
1075 {
1076         struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0);
1077         struct snd_pcm *pcm = rtd->pcm;
1078
1079         if (dai->driver->playback.channels_min)
1080                 snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
1081                                            SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
1082                                            MAX_PREALLOC_SIZE);
1083
1084         if (dai->driver->capture.channels_min)
1085                 snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
1086                                            SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
1087                                            MAX_PREALLOC_SIZE);
1088
1089         return 0;
1090 }
1091
1092 static const struct snd_soc_component_driver avs_component_driver = {
1093         .name                   = "avs-pcm",
1094         .probe                  = avs_component_probe,
1095         .remove                 = avs_component_remove,
1096         .suspend                = avs_component_suspend,
1097         .resume                 = avs_component_resume,
1098         .open                   = avs_component_open,
1099         .pointer                = avs_component_pointer,
1100         .mmap                   = avs_component_mmap,
1101         .pcm_construct          = avs_component_construct,
1102         .module_get_upon_open   = 1, /* increment refcount when a pcm is opened */
1103         .topology_name_prefix   = "intel/avs",
1104 };
1105
1106 static int avs_soc_component_register(struct device *dev, const char *name,
1107                                       const struct snd_soc_component_driver *drv,
1108                                       struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais)
1109 {
1110         struct avs_soc_component *acomp;
1111         int ret;
1112
1113         acomp = devm_kzalloc(dev, sizeof(*acomp), GFP_KERNEL);
1114         if (!acomp)
1115                 return -ENOMEM;
1116
1117         ret = snd_soc_component_initialize(&acomp->base, drv, dev);
1118         if (ret < 0)
1119                 return ret;
1120
1121         /* force name change after ASoC is done with its init */
1122         acomp->base.name = name;
1123         INIT_LIST_HEAD(&acomp->node);
1124
1125         return snd_soc_add_component(&acomp->base, cpu_dais, num_cpu_dais);
1126 }
1127
1128 static struct snd_soc_dai_driver dmic_cpu_dais[] = {
1129 {
1130         .name = "DMIC Pin",
1131         .ops = &avs_dai_nonhda_be_ops,
1132         .capture = {
1133                 .stream_name    = "DMIC Rx",
1134                 .channels_min   = 1,
1135                 .channels_max   = 4,
1136                 .rates          = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000,
1137                 .formats        = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
1138         },
1139 },
1140 {
1141         .name = "DMIC WoV Pin",
1142         .ops = &avs_dai_nonhda_be_ops,
1143         .capture = {
1144                 .stream_name    = "DMIC WoV Rx",
1145                 .channels_min   = 1,
1146                 .channels_max   = 4,
1147                 .rates          = SNDRV_PCM_RATE_16000,
1148                 .formats        = SNDRV_PCM_FMTBIT_S16_LE,
1149         },
1150 },
1151 };
1152
1153 int avs_dmic_platform_register(struct avs_dev *adev, const char *name)
1154 {
1155         return avs_soc_component_register(adev->dev, name, &avs_component_driver, dmic_cpu_dais,
1156                                           ARRAY_SIZE(dmic_cpu_dais));
1157 }
1158
1159 static const struct snd_soc_dai_driver i2s_dai_template = {
1160         .ops = &avs_dai_nonhda_be_ops,
1161         .playback = {
1162                 .channels_min   = 1,
1163                 .channels_max   = 8,
1164                 .rates          = SNDRV_PCM_RATE_8000_192000 |
1165                                   SNDRV_PCM_RATE_KNOT,
1166                 .formats        = SNDRV_PCM_FMTBIT_S16_LE |
1167                                   SNDRV_PCM_FMTBIT_S24_LE |
1168                                   SNDRV_PCM_FMTBIT_S32_LE,
1169         },
1170         .capture = {
1171                 .channels_min   = 1,
1172                 .channels_max   = 8,
1173                 .rates          = SNDRV_PCM_RATE_8000_192000 |
1174                                   SNDRV_PCM_RATE_KNOT,
1175                 .formats        = SNDRV_PCM_FMTBIT_S16_LE |
1176                                   SNDRV_PCM_FMTBIT_S24_LE |
1177                                   SNDRV_PCM_FMTBIT_S32_LE,
1178         },
1179 };
1180
1181 int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned long port_mask,
1182                               unsigned long *tdms)
1183 {
1184         struct snd_soc_dai_driver *cpus, *dai;
1185         size_t ssp_count, cpu_count;
1186         int i, j;
1187
1188         ssp_count = adev->hw_cfg.i2s_caps.ctrl_count;
1189         cpu_count = hweight_long(port_mask);
1190         if (tdms)
1191                 for_each_set_bit(i, &port_mask, ssp_count)
1192                         cpu_count += hweight_long(tdms[i]);
1193
1194         cpus = devm_kzalloc(adev->dev, sizeof(*cpus) * cpu_count, GFP_KERNEL);
1195         if (!cpus)
1196                 return -ENOMEM;
1197
1198         dai = cpus;
1199         for_each_set_bit(i, &port_mask, ssp_count) {
1200                 memcpy(dai, &i2s_dai_template, sizeof(*dai));
1201
1202                 dai->name =
1203                         devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d Pin", i);
1204                 dai->playback.stream_name =
1205                         devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Tx", i);
1206                 dai->capture.stream_name =
1207                         devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Rx", i);
1208
1209                 if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
1210                         return -ENOMEM;
1211                 dai++;
1212         }
1213
1214         if (!tdms)
1215                 goto plat_register;
1216
1217         for_each_set_bit(i, &port_mask, ssp_count) {
1218                 for_each_set_bit(j, &tdms[i], ssp_count) {
1219                         memcpy(dai, &i2s_dai_template, sizeof(*dai));
1220
1221                         dai->name =
1222                                 devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d:%d Pin", i, j);
1223                         dai->playback.stream_name =
1224                                 devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Tx", i, j);
1225                         dai->capture.stream_name =
1226                                 devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Rx", i, j);
1227
1228                         if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
1229                                 return -ENOMEM;
1230                         dai++;
1231                 }
1232         }
1233
1234 plat_register:
1235         return avs_soc_component_register(adev->dev, name, &avs_component_driver, cpus, cpu_count);
1236 }
1237
1238 /* HD-Audio CPU DAI template */
1239 static const struct snd_soc_dai_driver hda_cpu_dai = {
1240         .ops = &avs_dai_hda_be_ops,
1241         .playback = {
1242                 .channels_min   = 1,
1243                 .channels_max   = 8,
1244                 .rates          = SNDRV_PCM_RATE_8000_192000,
1245                 .formats        = SNDRV_PCM_FMTBIT_S16_LE |
1246                                   SNDRV_PCM_FMTBIT_S24_LE |
1247                                   SNDRV_PCM_FMTBIT_S32_LE,
1248         },
1249         .capture = {
1250                 .channels_min   = 1,
1251                 .channels_max   = 8,
1252                 .rates          = SNDRV_PCM_RATE_8000_192000,
1253                 .formats        = SNDRV_PCM_FMTBIT_S16_LE |
1254                                   SNDRV_PCM_FMTBIT_S24_LE |
1255                                   SNDRV_PCM_FMTBIT_S32_LE,
1256         },
1257 };
1258
1259 static void avs_component_hda_unregister_dais(struct snd_soc_component *component)
1260 {
1261         struct snd_soc_acpi_mach *mach;
1262         struct snd_soc_dai *dai, *save;
1263         struct hda_codec *codec;
1264         char name[32];
1265
1266         mach = dev_get_platdata(component->card->dev);
1267         codec = mach->pdata;
1268         sprintf(name, "%s-cpu", dev_name(&codec->core.dev));
1269
1270         for_each_component_dais_safe(component, dai, save) {
1271                 if (!strstr(dai->driver->name, name))
1272                         continue;
1273
1274                 snd_soc_dapm_free_widget(dai->playback_widget);
1275                 snd_soc_dapm_free_widget(dai->capture_widget);
1276                 snd_soc_unregister_dai(dai);
1277         }
1278 }
1279
1280 static int avs_component_hda_probe(struct snd_soc_component *component)
1281 {
1282         struct snd_soc_dapm_context *dapm;
1283         struct snd_soc_dai_driver *dais;
1284         struct snd_soc_acpi_mach *mach;
1285         struct hda_codec *codec;
1286         struct hda_pcm *pcm;
1287         const char *cname;
1288         int pcm_count = 0, ret, i;
1289
1290         mach = dev_get_platdata(component->card->dev);
1291         if (!mach)
1292                 return -EINVAL;
1293
1294         codec = mach->pdata;
1295         if (list_empty(&codec->pcm_list_head))
1296                 return -EINVAL;
1297         list_for_each_entry(pcm, &codec->pcm_list_head, list)
1298                 pcm_count++;
1299
1300         dais = devm_kcalloc(component->dev, pcm_count, sizeof(*dais),
1301                             GFP_KERNEL);
1302         if (!dais)
1303                 return -ENOMEM;
1304
1305         cname = dev_name(&codec->core.dev);
1306         dapm = snd_soc_component_get_dapm(component);
1307         pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list);
1308
1309         for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) {
1310                 struct snd_soc_dai *dai;
1311
1312                 memcpy(&dais[i], &hda_cpu_dai, sizeof(*dais));
1313                 dais[i].id = i;
1314                 dais[i].name = devm_kasprintf(component->dev, GFP_KERNEL,
1315                                               "%s-cpu%d", cname, i);
1316                 if (!dais[i].name) {
1317                         ret = -ENOMEM;
1318                         goto exit;
1319                 }
1320
1321                 if (pcm->stream[0].substreams) {
1322                         dais[i].playback.stream_name =
1323                                 devm_kasprintf(component->dev, GFP_KERNEL,
1324                                                "%s-cpu%d Tx", cname, i);
1325                         if (!dais[i].playback.stream_name) {
1326                                 ret = -ENOMEM;
1327                                 goto exit;
1328                         }
1329                 }
1330
1331                 if (pcm->stream[1].substreams) {
1332                         dais[i].capture.stream_name =
1333                                 devm_kasprintf(component->dev, GFP_KERNEL,
1334                                                "%s-cpu%d Rx", cname, i);
1335                         if (!dais[i].capture.stream_name) {
1336                                 ret = -ENOMEM;
1337                                 goto exit;
1338                         }
1339                 }
1340
1341                 dai = snd_soc_register_dai(component, &dais[i], false);
1342                 if (!dai) {
1343                         dev_err(component->dev, "register dai for %s failed\n",
1344                                 pcm->name);
1345                         ret = -EINVAL;
1346                         goto exit;
1347                 }
1348
1349                 ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
1350                 if (ret < 0) {
1351                         dev_err(component->dev, "create widgets failed: %d\n",
1352                                 ret);
1353                         goto exit;
1354                 }
1355         }
1356
1357         ret = avs_component_probe(component);
1358 exit:
1359         if (ret)
1360                 avs_component_hda_unregister_dais(component);
1361
1362         return ret;
1363 }
1364
1365 static void avs_component_hda_remove(struct snd_soc_component *component)
1366 {
1367         avs_component_hda_unregister_dais(component);
1368         avs_component_remove(component);
1369 }
1370
1371 static int avs_component_hda_open(struct snd_soc_component *component,
1372                                   struct snd_pcm_substream *substream)
1373 {
1374         struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
1375         struct hdac_ext_stream *link_stream;
1376         struct hda_codec *codec;
1377
1378         /* only BE DAI links are handled here */
1379         if (!rtd->dai_link->no_pcm)
1380                 return avs_component_open(component, substream);
1381
1382         codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev);
1383         link_stream = snd_hdac_ext_stream_assign(&codec->bus->core, substream,
1384                                              HDAC_EXT_STREAM_TYPE_LINK);
1385         if (!link_stream)
1386                 return -EBUSY;
1387
1388         substream->runtime->private_data = link_stream;
1389         return 0;
1390 }
1391
1392 static int avs_component_hda_close(struct snd_soc_component *component,
1393                                    struct snd_pcm_substream *substream)
1394 {
1395         struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
1396         struct hdac_ext_stream *link_stream;
1397
1398         /* only BE DAI links are handled here */
1399         if (!rtd->dai_link->no_pcm)
1400                 return 0;
1401
1402         link_stream = substream->runtime->private_data;
1403         snd_hdac_ext_stream_release(link_stream, HDAC_EXT_STREAM_TYPE_LINK);
1404         substream->runtime->private_data = NULL;
1405
1406         return 0;
1407 }
1408
1409 static const struct snd_soc_component_driver avs_hda_component_driver = {
1410         .name                   = "avs-hda-pcm",
1411         .probe                  = avs_component_hda_probe,
1412         .remove                 = avs_component_hda_remove,
1413         .suspend                = avs_component_suspend,
1414         .resume                 = avs_component_resume,
1415         .open                   = avs_component_hda_open,
1416         .close                  = avs_component_hda_close,
1417         .pointer                = avs_component_pointer,
1418         .mmap                   = avs_component_mmap,
1419         .pcm_construct          = avs_component_construct,
1420         /*
1421          * hda platform component's probe() is dependent on
1422          * codec->pcm_list_head, it needs to be initialized after codec
1423          * component. remove_order is here for completeness sake
1424          */
1425         .probe_order            = SND_SOC_COMP_ORDER_LATE,
1426         .remove_order           = SND_SOC_COMP_ORDER_EARLY,
1427         .module_get_upon_open   = 1,
1428         .topology_name_prefix   = "intel/avs",
1429 };
1430
1431 int avs_hda_platform_register(struct avs_dev *adev, const char *name)
1432 {
1433         return avs_soc_component_register(adev->dev, name,
1434                                           &avs_hda_component_driver, NULL, 0);
1435 }