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