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