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