1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Copyright(c) 2021 Intel Corporation
4 //
5 // Authors: Cezary Rojewski <cezary.rojewski@intel.com>
6 // Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
7 //
8
9 #include <linux/cleanup.h>
10 #include <linux/acpi.h>
11 #include <acpi/nhlt.h>
12 #include <sound/pcm_params.h>
13 #include <sound/soc.h>
14 #include "avs.h"
15 #include "control.h"
16 #include "path.h"
17 #include "topology.h"
18
19 /* Must be called with adev->comp_list_mutex held. */
20 static struct avs_tplg *
avs_path_find_tplg(struct avs_dev * adev,const char * name)21 avs_path_find_tplg(struct avs_dev *adev, const char *name)
22 {
23 struct avs_soc_component *acomp;
24
25 list_for_each_entry(acomp, &adev->comp_list, node)
26 if (!strcmp(acomp->tplg->name, name))
27 return acomp->tplg;
28 return NULL;
29 }
30
31 static struct avs_path_module *
avs_path_find_module(struct avs_path_pipeline * ppl,u32 template_id)32 avs_path_find_module(struct avs_path_pipeline *ppl, u32 template_id)
33 {
34 struct avs_path_module *mod;
35
36 list_for_each_entry(mod, &ppl->mod_list, node)
37 if (mod->template->id == template_id)
38 return mod;
39 return NULL;
40 }
41
42 static struct avs_path_pipeline *
avs_path_find_pipeline(struct avs_path * path,u32 template_id)43 avs_path_find_pipeline(struct avs_path *path, u32 template_id)
44 {
45 struct avs_path_pipeline *ppl;
46
47 list_for_each_entry(ppl, &path->ppl_list, node)
48 if (ppl->template->id == template_id)
49 return ppl;
50 return NULL;
51 }
52
53 static struct avs_path *
avs_path_find_path(struct avs_dev * adev,const char * name,u32 template_id)54 avs_path_find_path(struct avs_dev *adev, const char *name, u32 template_id)
55 {
56 struct avs_tplg_path_template *pos, *template = NULL;
57 struct avs_tplg *tplg;
58 struct avs_path *path;
59
60 tplg = avs_path_find_tplg(adev, name);
61 if (!tplg)
62 return NULL;
63
64 list_for_each_entry(pos, &tplg->path_tmpl_list, node) {
65 if (pos->id == template_id) {
66 template = pos;
67 break;
68 }
69 }
70 if (!template)
71 return NULL;
72
73 guard(spinlock)(&adev->path_list_lock);
74 /* Only one variant of given path template may be instantiated at a time. */
75 list_for_each_entry(path, &adev->path_list, node) {
76 if (path->template->owner == template)
77 return path;
78 }
79
80 return NULL;
81 }
82
avs_test_hw_params(struct snd_pcm_hw_params * params,struct avs_audio_format * fmt)83 static bool avs_test_hw_params(struct snd_pcm_hw_params *params,
84 struct avs_audio_format *fmt)
85 {
86 return (params_rate(params) == fmt->sampling_freq &&
87 params_channels(params) == fmt->num_channels &&
88 params_physical_width(params) == fmt->bit_depth &&
89 snd_pcm_hw_params_bits(params) == fmt->valid_bit_depth);
90 }
91
92 static struct avs_tplg_path *
avs_path_find_variant(struct avs_dev * adev,struct avs_tplg_path_template * template,struct snd_pcm_hw_params * fe_params,struct snd_pcm_hw_params * be_params)93 avs_path_find_variant(struct avs_dev *adev,
94 struct avs_tplg_path_template *template,
95 struct snd_pcm_hw_params *fe_params,
96 struct snd_pcm_hw_params *be_params)
97 {
98 struct avs_tplg_path *variant;
99
100 list_for_each_entry(variant, &template->path_list, node) {
101 dev_dbg(adev->dev, "check FE rate %d chn %d vbd %d bd %d\n",
102 variant->fe_fmt->sampling_freq, variant->fe_fmt->num_channels,
103 variant->fe_fmt->valid_bit_depth, variant->fe_fmt->bit_depth);
104 dev_dbg(adev->dev, "check BE rate %d chn %d vbd %d bd %d\n",
105 variant->be_fmt->sampling_freq, variant->be_fmt->num_channels,
106 variant->be_fmt->valid_bit_depth, variant->be_fmt->bit_depth);
107
108 if (variant->fe_fmt && avs_test_hw_params(fe_params, variant->fe_fmt) &&
109 variant->be_fmt && avs_test_hw_params(be_params, variant->be_fmt))
110 return variant;
111 }
112
113 return NULL;
114 }
115
avs_condpath_find_variant(struct avs_dev * adev,struct avs_tplg_path_template * template,struct avs_path * source,struct avs_path * sink)116 static struct avs_tplg_path *avs_condpath_find_variant(struct avs_dev *adev,
117 struct avs_tplg_path_template *template,
118 struct avs_path *source,
119 struct avs_path *sink)
120 {
121 struct avs_tplg_path *variant;
122
123 list_for_each_entry(variant, &template->path_list, node) {
124 if (variant->source_path_id == source->template->id &&
125 variant->sink_path_id == sink->template->id)
126 return variant;
127 }
128
129 return NULL;
130 }
131
avs_tplg_path_template_id_equal(struct avs_tplg_path_template_id * id,struct avs_tplg_path_template_id * id2)132 static bool avs_tplg_path_template_id_equal(struct avs_tplg_path_template_id *id,
133 struct avs_tplg_path_template_id *id2)
134 {
135 return id->id == id2->id && !sysfs_streq(id->tplg_name, id2->tplg_name);
136 }
137
avs_condpath_find_match(struct avs_dev * adev,struct avs_tplg_path_template * template,struct avs_path * path,int dir)138 static struct avs_path *avs_condpath_find_match(struct avs_dev *adev,
139 struct avs_tplg_path_template *template,
140 struct avs_path *path, int dir)
141 {
142 struct avs_tplg_path_template_id *id, *id2;
143
144 if (dir) {
145 id = &template->source;
146 id2 = &template->sink;
147 } else {
148 id = &template->sink;
149 id2 = &template->source;
150 }
151
152 /* Check whether this path is either source or sink of condpath template. */
153 if (id->id != path->template->owner->id ||
154 strcmp(id->tplg_name, path->template->owner->owner->name))
155 return NULL;
156
157 /* Unidirectional condpaths are allowed. */
158 if (avs_tplg_path_template_id_equal(id, id2))
159 return path;
160
161 /* Now find the counterpart. */
162 return avs_path_find_path(adev, id2->tplg_name, id2->id);
163 }
164
165 static struct acpi_nhlt_config *
166 avs_nhlt_config_or_default(struct avs_dev *adev, struct avs_tplg_module *t);
167
avs_path_set_constraint(struct avs_dev * adev,struct avs_tplg_path_template * template,struct snd_pcm_hw_constraint_list * rate_list,struct snd_pcm_hw_constraint_list * channels_list,struct snd_pcm_hw_constraint_list * sample_bits_list)168 int avs_path_set_constraint(struct avs_dev *adev, struct avs_tplg_path_template *template,
169 struct snd_pcm_hw_constraint_list *rate_list,
170 struct snd_pcm_hw_constraint_list *channels_list,
171 struct snd_pcm_hw_constraint_list *sample_bits_list)
172 {
173 struct avs_tplg_path *path_template;
174 unsigned int *rlist, *clist, *slist;
175 size_t i;
176
177 i = 0;
178 list_for_each_entry(path_template, &template->path_list, node)
179 i++;
180
181 rlist = kcalloc(i, sizeof(*rlist), GFP_KERNEL);
182 clist = kcalloc(i, sizeof(*clist), GFP_KERNEL);
183 slist = kcalloc(i, sizeof(*slist), GFP_KERNEL);
184 if (!rlist || !clist || !slist)
185 return -ENOMEM;
186
187 i = 0;
188 list_for_each_entry(path_template, &template->path_list, node) {
189 struct avs_tplg_pipeline *pipeline_template;
190
191 list_for_each_entry(pipeline_template, &path_template->ppl_list, node) {
192 struct avs_tplg_module *module_template;
193
194 list_for_each_entry(module_template, &pipeline_template->mod_list, node) {
195 const guid_t *type = &module_template->cfg_ext->type;
196 struct acpi_nhlt_config *blob;
197
198 if (!guid_equal(type, &AVS_COPIER_MOD_UUID) &&
199 !guid_equal(type, &AVS_WOVHOSTM_MOD_UUID))
200 continue;
201
202 switch (module_template->cfg_ext->copier.dma_type) {
203 case AVS_DMA_DMIC_LINK_INPUT:
204 case AVS_DMA_I2S_LINK_OUTPUT:
205 case AVS_DMA_I2S_LINK_INPUT:
206 break;
207 default:
208 continue;
209 }
210
211 if (!module_template->nhlt_config) {
212 blob = avs_nhlt_config_or_default(adev, module_template);
213 if (IS_ERR(blob))
214 continue;
215 }
216
217 rlist[i] = path_template->fe_fmt->sampling_freq;
218 clist[i] = path_template->fe_fmt->num_channels;
219 slist[i] = path_template->fe_fmt->bit_depth;
220 i++;
221 }
222 }
223 }
224
225 if (i) {
226 rate_list->count = i;
227 rate_list->list = rlist;
228 channels_list->count = i;
229 channels_list->list = clist;
230 sample_bits_list->count = i;
231 sample_bits_list->list = slist;
232 } else {
233 kfree(rlist);
234 kfree(clist);
235 kfree(slist);
236 }
237
238 return i;
239 }
240
avs_init_node_id(union avs_connector_node_id * node_id,struct avs_tplg_modcfg_ext * te,u32 dma_id)241 static void avs_init_node_id(union avs_connector_node_id *node_id,
242 struct avs_tplg_modcfg_ext *te, u32 dma_id)
243 {
244 node_id->val = 0;
245 node_id->dma_type = te->copier.dma_type;
246
247 switch (node_id->dma_type) {
248 case AVS_DMA_DMIC_LINK_INPUT:
249 case AVS_DMA_I2S_LINK_OUTPUT:
250 case AVS_DMA_I2S_LINK_INPUT:
251 /* Gateway's virtual index is statically assigned in the topology. */
252 node_id->vindex = te->copier.vindex.val;
253 break;
254
255 case AVS_DMA_HDA_HOST_OUTPUT:
256 case AVS_DMA_HDA_HOST_INPUT:
257 /* Gateway's virtual index is dynamically assigned with DMA ID */
258 node_id->vindex = dma_id;
259 break;
260
261 case AVS_DMA_HDA_LINK_OUTPUT:
262 case AVS_DMA_HDA_LINK_INPUT:
263 node_id->vindex = te->copier.vindex.val | dma_id;
264 break;
265
266 default:
267 *node_id = INVALID_NODE_ID;
268 break;
269 }
270 }
271
272 /* Every BLOB contains at least gateway attributes. */
273 static struct acpi_nhlt_config *default_blob = (struct acpi_nhlt_config *)&(u32[2]) {4};
274
275 static struct acpi_nhlt_config *
avs_nhlt_config_or_default(struct avs_dev * adev,struct avs_tplg_module * t)276 avs_nhlt_config_or_default(struct avs_dev *adev, struct avs_tplg_module *t)
277 {
278 struct acpi_nhlt_format_config *fmtcfg;
279 struct avs_tplg_modcfg_ext *te;
280 struct avs_audio_format *fmt;
281 int link_type, dev_type;
282 int bus_id, dir;
283
284 te = t->cfg_ext;
285
286 switch (te->copier.dma_type) {
287 case AVS_DMA_I2S_LINK_OUTPUT:
288 link_type = ACPI_NHLT_LINKTYPE_SSP;
289 dev_type = ACPI_NHLT_DEVICETYPE_CODEC;
290 bus_id = te->copier.vindex.i2s.instance;
291 dir = SNDRV_PCM_STREAM_PLAYBACK;
292 fmt = te->copier.out_fmt;
293 break;
294
295 case AVS_DMA_I2S_LINK_INPUT:
296 link_type = ACPI_NHLT_LINKTYPE_SSP;
297 dev_type = ACPI_NHLT_DEVICETYPE_CODEC;
298 bus_id = te->copier.vindex.i2s.instance;
299 dir = SNDRV_PCM_STREAM_CAPTURE;
300 fmt = t->in_fmt;
301 break;
302
303 case AVS_DMA_DMIC_LINK_INPUT:
304 link_type = ACPI_NHLT_LINKTYPE_PDM;
305 dev_type = -1; /* ignored */
306 bus_id = 0;
307 dir = SNDRV_PCM_STREAM_CAPTURE;
308 fmt = t->in_fmt;
309 break;
310
311 default:
312 return default_blob;
313 }
314
315 /* Override format selection if necessary. */
316 if (te->copier.blob_fmt)
317 fmt = te->copier.blob_fmt;
318
319 fmtcfg = acpi_nhlt_find_fmtcfg(link_type, dev_type, dir, bus_id,
320 fmt->num_channels, fmt->sampling_freq, fmt->valid_bit_depth,
321 fmt->bit_depth);
322 if (!fmtcfg) {
323 dev_warn(adev->dev, "Endpoint format configuration not found.\n");
324 return ERR_PTR(-ENOENT);
325 }
326
327 if (fmtcfg->config.capabilities_size < default_blob->capabilities_size)
328 return ERR_PTR(-ETOOSMALL);
329 /* The firmware expects the payload to be DWORD-aligned. */
330 if (fmtcfg->config.capabilities_size % sizeof(u32))
331 return ERR_PTR(-EINVAL);
332
333 return &fmtcfg->config;
334 }
335
avs_append_dma_cfg(struct avs_dev * adev,struct avs_copier_gtw_cfg * gtw,struct avs_tplg_module * t,u32 dma_id,size_t * cfg_size)336 static int avs_append_dma_cfg(struct avs_dev *adev, struct avs_copier_gtw_cfg *gtw,
337 struct avs_tplg_module *t, u32 dma_id, size_t *cfg_size)
338 {
339 u32 dma_type = t->cfg_ext->copier.dma_type;
340 struct avs_dma_cfg *dma;
341 struct avs_tlv *tlv;
342 size_t tlv_size;
343
344 if (!avs_platattr_test(adev, ALTHDA))
345 return 0;
346
347 switch (dma_type) {
348 case AVS_DMA_HDA_HOST_OUTPUT:
349 case AVS_DMA_HDA_HOST_INPUT:
350 case AVS_DMA_HDA_LINK_OUTPUT:
351 case AVS_DMA_HDA_LINK_INPUT:
352 return 0;
353 default:
354 break;
355 }
356
357 tlv_size = sizeof(*tlv) + sizeof(*dma);
358 if (*cfg_size + tlv_size > AVS_MAILBOX_SIZE)
359 return -E2BIG;
360
361 /* DMA config is a TLV tailing the existing payload. */
362 tlv = (struct avs_tlv *)>w->config.blob[gtw->config_length];
363 tlv->type = AVS_GTW_DMA_CONFIG_ID;
364 tlv->length = sizeof(*dma);
365
366 dma = (struct avs_dma_cfg *)tlv->value;
367 memset(dma, 0, sizeof(*dma));
368 dma->dma_method = AVS_DMA_METHOD_HDA;
369 dma->pre_allocated = true;
370 dma->dma_channel_id = dma_id;
371 dma->stream_id = dma_id + 1;
372
373 gtw->config_length += tlv_size / sizeof(u32);
374 *cfg_size += tlv_size;
375
376 return 0;
377 }
378
avs_fill_gtw_config(struct avs_dev * adev,struct avs_copier_gtw_cfg * gtw,struct avs_tplg_module * t,u32 dma_id,size_t * cfg_size)379 static int avs_fill_gtw_config(struct avs_dev *adev, struct avs_copier_gtw_cfg *gtw,
380 struct avs_tplg_module *t, u32 dma_id, size_t *cfg_size)
381 {
382 struct acpi_nhlt_config *blob;
383 size_t gtw_size;
384
385 if (t->nhlt_config)
386 blob = t->nhlt_config->blob;
387 else
388 blob = avs_nhlt_config_or_default(adev, t);
389 if (IS_ERR(blob))
390 return PTR_ERR(blob);
391
392 gtw_size = blob->capabilities_size;
393 if (*cfg_size + gtw_size > AVS_MAILBOX_SIZE)
394 return -E2BIG;
395
396 gtw->config_length = gtw_size / sizeof(u32);
397 memcpy(gtw->config.blob, blob->capabilities, blob->capabilities_size);
398 *cfg_size += gtw_size;
399
400 return avs_append_dma_cfg(adev, gtw, t, dma_id, cfg_size);
401 }
402
avs_copier_create(struct avs_dev * adev,struct avs_path_module * mod)403 static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod)
404 {
405 struct avs_tplg_module *t = mod->template;
406 struct avs_tplg_modcfg_ext *te;
407 struct avs_copier_cfg *cfg;
408 size_t cfg_size;
409 u32 dma_id;
410 int ret;
411
412 te = t->cfg_ext;
413 cfg = adev->modcfg_buf;
414 dma_id = mod->owner->owner->dma_id;
415 cfg_size = offsetof(struct avs_copier_cfg, gtw_cfg.config);
416
417 ret = avs_fill_gtw_config(adev, &cfg->gtw_cfg, t, dma_id, &cfg_size);
418 if (ret)
419 return ret;
420
421 cfg->base.cpc = t->cfg_base->cpc;
422 cfg->base.ibs = t->cfg_base->ibs;
423 cfg->base.obs = t->cfg_base->obs;
424 cfg->base.is_pages = t->cfg_base->is_pages;
425 cfg->base.audio_fmt = *t->in_fmt;
426 cfg->out_fmt = *te->copier.out_fmt;
427 cfg->feature_mask = te->copier.feature_mask;
428 avs_init_node_id(&cfg->gtw_cfg.node_id, te, dma_id);
429 cfg->gtw_cfg.dma_buffer_size = te->copier.dma_buffer_size;
430 mod->gtw_attrs = cfg->gtw_cfg.config.attrs;
431
432 ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id,
433 t->domain, cfg, cfg_size, &mod->instance_id);
434 return ret;
435 }
436
avs_whm_create(struct avs_dev * adev,struct avs_path_module * mod)437 static int avs_whm_create(struct avs_dev *adev, struct avs_path_module *mod)
438 {
439 struct avs_tplg_module *t = mod->template;
440 struct avs_tplg_modcfg_ext *te;
441 struct avs_whm_cfg *cfg;
442 size_t cfg_size;
443 u32 dma_id;
444 int ret;
445
446 te = t->cfg_ext;
447 cfg = adev->modcfg_buf;
448 dma_id = mod->owner->owner->dma_id;
449 cfg_size = offsetof(struct avs_whm_cfg, gtw_cfg.config);
450
451 ret = avs_fill_gtw_config(adev, &cfg->gtw_cfg, t, dma_id, &cfg_size);
452 if (ret)
453 return ret;
454
455 cfg->base.cpc = t->cfg_base->cpc;
456 cfg->base.ibs = t->cfg_base->ibs;
457 cfg->base.obs = t->cfg_base->obs;
458 cfg->base.is_pages = t->cfg_base->is_pages;
459 cfg->base.audio_fmt = *t->in_fmt;
460 cfg->ref_fmt = *te->whm.ref_fmt;
461 cfg->out_fmt = *te->whm.out_fmt;
462 cfg->wake_tick_period = te->whm.wake_tick_period;
463 avs_init_node_id(&cfg->gtw_cfg.node_id, te, dma_id);
464 cfg->gtw_cfg.dma_buffer_size = te->whm.dma_buffer_size;
465 mod->gtw_attrs = cfg->gtw_cfg.config.attrs;
466
467 ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id,
468 t->domain, cfg, cfg_size, &mod->instance_id);
469 return ret;
470 }
471
avs_get_module_control(struct avs_path_module * mod,const char * name)472 static struct soc_mixer_control *avs_get_module_control(struct avs_path_module *mod,
473 const char *name)
474 {
475 struct avs_tplg_module *t = mod->template;
476 struct avs_tplg_path_template *path_tmpl;
477 struct snd_soc_dapm_widget *w;
478 int i;
479
480 path_tmpl = t->owner->owner->owner;
481 w = path_tmpl->w;
482
483 for (i = 0; i < w->num_kcontrols; i++) {
484 struct avs_control_data *ctl_data;
485 struct soc_mixer_control *mc;
486
487 mc = (struct soc_mixer_control *)w->kcontrols[i]->private_value;
488 ctl_data = (struct avs_control_data *)mc->dobj.private;
489 if (ctl_data->id == t->ctl_id && strstr(w->kcontrols[i]->id.name, name))
490 return mc;
491 }
492
493 return NULL;
494 }
495
avs_peakvol_set_volume(struct avs_dev * adev,struct avs_path_module * mod,struct soc_mixer_control * mc,long * input)496 int avs_peakvol_set_volume(struct avs_dev *adev, struct avs_path_module *mod,
497 struct soc_mixer_control *mc, long *input)
498 {
499 struct avs_volume_cfg vols[SND_SOC_TPLG_MAX_CHAN] = {{0}};
500 struct avs_control_data *ctl_data;
501 struct avs_tplg_module *t;
502 int ret, i;
503
504 ctl_data = mc->dobj.private;
505 t = mod->template;
506 if (!input)
507 input = ctl_data->values;
508
509 if (mc->num_channels) {
510 for (i = 0; i < mc->num_channels; i++) {
511 vols[i].channel_id = i;
512 vols[i].target_volume = input[i];
513 vols[i].curve_type = t->cfg_ext->peakvol.curve_type;
514 vols[i].curve_duration = t->cfg_ext->peakvol.curve_duration;
515 }
516
517 ret = avs_ipc_peakvol_set_volumes(adev, mod->module_id, mod->instance_id, vols,
518 mc->num_channels);
519 return AVS_IPC_RET(ret);
520 }
521
522 /* Target all channels if no individual selected. */
523 vols[0].channel_id = AVS_ALL_CHANNELS_MASK;
524 vols[0].target_volume = input[0];
525 vols[0].curve_type = t->cfg_ext->peakvol.curve_type;
526 vols[0].curve_duration = t->cfg_ext->peakvol.curve_duration;
527
528 ret = avs_ipc_peakvol_set_volume(adev, mod->module_id, mod->instance_id, &vols[0]);
529 return AVS_IPC_RET(ret);
530 }
531
avs_peakvol_set_mute(struct avs_dev * adev,struct avs_path_module * mod,struct soc_mixer_control * mc,long * input)532 int avs_peakvol_set_mute(struct avs_dev *adev, struct avs_path_module *mod,
533 struct soc_mixer_control *mc, long *input)
534 {
535 struct avs_mute_cfg mutes[SND_SOC_TPLG_MAX_CHAN] = {{0}};
536 struct avs_control_data *ctl_data;
537 struct avs_tplg_module *t;
538 int ret, i;
539
540 ctl_data = mc->dobj.private;
541 t = mod->template;
542 if (!input)
543 input = ctl_data->values;
544
545 if (mc->num_channels) {
546 for (i = 0; i < mc->num_channels; i++) {
547 mutes[i].channel_id = i;
548 mutes[i].mute = !input[i];
549 mutes[i].curve_type = t->cfg_ext->peakvol.curve_type;
550 mutes[i].curve_duration = t->cfg_ext->peakvol.curve_duration;
551 }
552
553 ret = avs_ipc_peakvol_set_mutes(adev, mod->module_id, mod->instance_id, mutes,
554 mc->num_channels);
555 return AVS_IPC_RET(ret);
556 }
557
558 /* Target all channels if no individual selected. */
559 mutes[0].channel_id = AVS_ALL_CHANNELS_MASK;
560 mutes[0].mute = !input[0];
561 mutes[0].curve_type = t->cfg_ext->peakvol.curve_type;
562 mutes[0].curve_duration = t->cfg_ext->peakvol.curve_duration;
563
564 ret = avs_ipc_peakvol_set_mute(adev, mod->module_id, mod->instance_id, &mutes[0]);
565 return AVS_IPC_RET(ret);
566 }
567
avs_peakvol_create(struct avs_dev * adev,struct avs_path_module * mod)568 static int avs_peakvol_create(struct avs_dev *adev, struct avs_path_module *mod)
569 {
570 struct avs_tplg_module *t = mod->template;
571 struct soc_mixer_control *mc;
572 struct avs_peakvol_cfg *cfg;
573 size_t cfg_size;
574 int ret;
575
576 cfg_size = struct_size(cfg, vols, 1);
577 if (cfg_size > AVS_MAILBOX_SIZE)
578 return -EINVAL;
579
580 cfg = adev->modcfg_buf;
581 memset(cfg, 0, cfg_size);
582 cfg->base.cpc = t->cfg_base->cpc;
583 cfg->base.ibs = t->cfg_base->ibs;
584 cfg->base.obs = t->cfg_base->obs;
585 cfg->base.is_pages = t->cfg_base->is_pages;
586 cfg->base.audio_fmt = *t->in_fmt;
587 cfg->vols[0].channel_id = AVS_ALL_CHANNELS_MASK;
588 cfg->vols[0].target_volume = S32_MAX;
589 cfg->vols[0].curve_type = t->cfg_ext->peakvol.curve_type;
590 cfg->vols[0].curve_duration = t->cfg_ext->peakvol.curve_duration;
591
592 ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id,
593 t->domain, cfg, cfg_size, &mod->instance_id);
594 if (ret)
595 return ret;
596
597 /* Now configure both VOLUME and MUTE parameters. */
598 mc = avs_get_module_control(mod, "Volume");
599 if (mc) {
600 ret = avs_peakvol_set_volume(adev, mod, mc, NULL);
601 if (ret)
602 return ret;
603 }
604
605 mc = avs_get_module_control(mod, "Switch");
606 if (mc)
607 return avs_peakvol_set_mute(adev, mod, mc, NULL);
608 return 0;
609 }
610
avs_updown_mix_create(struct avs_dev * adev,struct avs_path_module * mod)611 static int avs_updown_mix_create(struct avs_dev *adev, struct avs_path_module *mod)
612 {
613 struct avs_tplg_module *t = mod->template;
614 struct avs_updown_mixer_cfg cfg;
615 int i;
616
617 cfg.base.cpc = t->cfg_base->cpc;
618 cfg.base.ibs = t->cfg_base->ibs;
619 cfg.base.obs = t->cfg_base->obs;
620 cfg.base.is_pages = t->cfg_base->is_pages;
621 cfg.base.audio_fmt = *t->in_fmt;
622 cfg.out_channel_config = t->cfg_ext->updown_mix.out_channel_config;
623 cfg.coefficients_select = t->cfg_ext->updown_mix.coefficients_select;
624 for (i = 0; i < AVS_COEFF_CHANNELS_MAX; i++)
625 cfg.coefficients[i] = t->cfg_ext->updown_mix.coefficients[i];
626 cfg.channel_map = t->cfg_ext->updown_mix.channel_map;
627
628 return avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
629 t->core_id, t->domain, &cfg, sizeof(cfg),
630 &mod->instance_id);
631 }
632
avs_src_create(struct avs_dev * adev,struct avs_path_module * mod)633 static int avs_src_create(struct avs_dev *adev, struct avs_path_module *mod)
634 {
635 struct avs_tplg_module *t = mod->template;
636 struct avs_src_cfg cfg;
637
638 cfg.base.cpc = t->cfg_base->cpc;
639 cfg.base.ibs = t->cfg_base->ibs;
640 cfg.base.obs = t->cfg_base->obs;
641 cfg.base.is_pages = t->cfg_base->is_pages;
642 cfg.base.audio_fmt = *t->in_fmt;
643 cfg.out_freq = t->cfg_ext->src.out_freq;
644
645 return avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
646 t->core_id, t->domain, &cfg, sizeof(cfg),
647 &mod->instance_id);
648 }
649
avs_asrc_create(struct avs_dev * adev,struct avs_path_module * mod)650 static int avs_asrc_create(struct avs_dev *adev, struct avs_path_module *mod)
651 {
652 struct avs_tplg_module *t = mod->template;
653 struct avs_asrc_cfg cfg;
654
655 memset(&cfg, 0, sizeof(cfg));
656 cfg.base.cpc = t->cfg_base->cpc;
657 cfg.base.ibs = t->cfg_base->ibs;
658 cfg.base.obs = t->cfg_base->obs;
659 cfg.base.is_pages = t->cfg_base->is_pages;
660 cfg.base.audio_fmt = *t->in_fmt;
661 cfg.out_freq = t->cfg_ext->asrc.out_freq;
662 cfg.mode = t->cfg_ext->asrc.mode;
663 cfg.disable_jitter_buffer = t->cfg_ext->asrc.disable_jitter_buffer;
664
665 return avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
666 t->core_id, t->domain, &cfg, sizeof(cfg),
667 &mod->instance_id);
668 }
669
avs_aec_create(struct avs_dev * adev,struct avs_path_module * mod)670 static int avs_aec_create(struct avs_dev *adev, struct avs_path_module *mod)
671 {
672 struct avs_tplg_module *t = mod->template;
673 struct avs_aec_cfg cfg;
674
675 cfg.base.cpc = t->cfg_base->cpc;
676 cfg.base.ibs = t->cfg_base->ibs;
677 cfg.base.obs = t->cfg_base->obs;
678 cfg.base.is_pages = t->cfg_base->is_pages;
679 cfg.base.audio_fmt = *t->in_fmt;
680 cfg.ref_fmt = *t->cfg_ext->aec.ref_fmt;
681 cfg.out_fmt = *t->cfg_ext->aec.out_fmt;
682 cfg.cpc_lp_mode = t->cfg_ext->aec.cpc_lp_mode;
683
684 return avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
685 t->core_id, t->domain, &cfg, sizeof(cfg),
686 &mod->instance_id);
687 }
688
avs_mux_create(struct avs_dev * adev,struct avs_path_module * mod)689 static int avs_mux_create(struct avs_dev *adev, struct avs_path_module *mod)
690 {
691 struct avs_tplg_module *t = mod->template;
692 struct avs_mux_cfg cfg;
693
694 cfg.base.cpc = t->cfg_base->cpc;
695 cfg.base.ibs = t->cfg_base->ibs;
696 cfg.base.obs = t->cfg_base->obs;
697 cfg.base.is_pages = t->cfg_base->is_pages;
698 cfg.base.audio_fmt = *t->in_fmt;
699 cfg.ref_fmt = *t->cfg_ext->mux.ref_fmt;
700 cfg.out_fmt = *t->cfg_ext->mux.out_fmt;
701
702 return avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
703 t->core_id, t->domain, &cfg, sizeof(cfg),
704 &mod->instance_id);
705 }
706
avs_wov_create(struct avs_dev * adev,struct avs_path_module * mod)707 static int avs_wov_create(struct avs_dev *adev, struct avs_path_module *mod)
708 {
709 struct avs_tplg_module *t = mod->template;
710 struct avs_wov_cfg cfg;
711
712 cfg.base.cpc = t->cfg_base->cpc;
713 cfg.base.ibs = t->cfg_base->ibs;
714 cfg.base.obs = t->cfg_base->obs;
715 cfg.base.is_pages = t->cfg_base->is_pages;
716 cfg.base.audio_fmt = *t->in_fmt;
717 cfg.cpc_lp_mode = t->cfg_ext->wov.cpc_lp_mode;
718
719 return avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
720 t->core_id, t->domain, &cfg, sizeof(cfg),
721 &mod->instance_id);
722 }
723
avs_micsel_create(struct avs_dev * adev,struct avs_path_module * mod)724 static int avs_micsel_create(struct avs_dev *adev, struct avs_path_module *mod)
725 {
726 struct avs_tplg_module *t = mod->template;
727 struct avs_micsel_cfg cfg;
728
729 cfg.base.cpc = t->cfg_base->cpc;
730 cfg.base.ibs = t->cfg_base->ibs;
731 cfg.base.obs = t->cfg_base->obs;
732 cfg.base.is_pages = t->cfg_base->is_pages;
733 cfg.base.audio_fmt = *t->in_fmt;
734 cfg.out_fmt = *t->cfg_ext->micsel.out_fmt;
735
736 return avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
737 t->core_id, t->domain, &cfg, sizeof(cfg),
738 &mod->instance_id);
739 }
740
avs_modbase_create(struct avs_dev * adev,struct avs_path_module * mod)741 static int avs_modbase_create(struct avs_dev *adev, struct avs_path_module *mod)
742 {
743 struct avs_tplg_module *t = mod->template;
744 struct avs_modcfg_base cfg;
745
746 cfg.cpc = t->cfg_base->cpc;
747 cfg.ibs = t->cfg_base->ibs;
748 cfg.obs = t->cfg_base->obs;
749 cfg.is_pages = t->cfg_base->is_pages;
750 cfg.audio_fmt = *t->in_fmt;
751
752 return avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
753 t->core_id, t->domain, &cfg, sizeof(cfg),
754 &mod->instance_id);
755 }
756
avs_modext_create(struct avs_dev * adev,struct avs_path_module * mod)757 static int avs_modext_create(struct avs_dev *adev, struct avs_path_module *mod)
758 {
759 struct avs_tplg_module *t = mod->template;
760 struct avs_tplg_modcfg_ext *tcfg = t->cfg_ext;
761 struct avs_modcfg_ext *cfg;
762 size_t cfg_size, num_pins;
763 int ret, i;
764
765 num_pins = tcfg->generic.num_input_pins + tcfg->generic.num_output_pins;
766 cfg_size = struct_size(cfg, pin_fmts, num_pins);
767
768 if (cfg_size > AVS_MAILBOX_SIZE)
769 return -EINVAL;
770
771 cfg = adev->modcfg_buf;
772 memset(cfg, 0, cfg_size);
773 cfg->base.cpc = t->cfg_base->cpc;
774 cfg->base.ibs = t->cfg_base->ibs;
775 cfg->base.obs = t->cfg_base->obs;
776 cfg->base.is_pages = t->cfg_base->is_pages;
777 cfg->base.audio_fmt = *t->in_fmt;
778 cfg->num_input_pins = tcfg->generic.num_input_pins;
779 cfg->num_output_pins = tcfg->generic.num_output_pins;
780
781 /* configure pin formats */
782 for (i = 0; i < num_pins; i++) {
783 struct avs_tplg_pin_format *tpin = &tcfg->generic.pin_fmts[i];
784 struct avs_pin_format *pin = &cfg->pin_fmts[i];
785
786 pin->pin_index = tpin->pin_index;
787 pin->iobs = tpin->iobs;
788 pin->audio_fmt = *tpin->fmt;
789 }
790
791 ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
792 t->core_id, t->domain, cfg, cfg_size,
793 &mod->instance_id);
794 return ret;
795 }
796
avs_probe_create(struct avs_dev * adev,struct avs_path_module * mod)797 static int avs_probe_create(struct avs_dev *adev, struct avs_path_module *mod)
798 {
799 dev_err(adev->dev, "Probe module can't be instantiated by topology");
800 return -EINVAL;
801 }
802
803 struct avs_module_create {
804 guid_t *guid;
805 int (*create)(struct avs_dev *adev, struct avs_path_module *mod);
806 };
807
808 static struct avs_module_create avs_module_create[] = {
809 { &AVS_MIXIN_MOD_UUID, avs_modbase_create },
810 { &AVS_MIXOUT_MOD_UUID, avs_modbase_create },
811 { &AVS_KPBUFF_MOD_UUID, avs_modbase_create },
812 { &AVS_COPIER_MOD_UUID, avs_copier_create },
813 { &AVS_PEAKVOL_MOD_UUID, avs_peakvol_create },
814 { &AVS_GAIN_MOD_UUID, avs_peakvol_create },
815 { &AVS_MICSEL_MOD_UUID, avs_micsel_create },
816 { &AVS_MUX_MOD_UUID, avs_mux_create },
817 { &AVS_UPDWMIX_MOD_UUID, avs_updown_mix_create },
818 { &AVS_SRCINTC_MOD_UUID, avs_src_create },
819 { &AVS_AEC_MOD_UUID, avs_aec_create },
820 { &AVS_ASRC_MOD_UUID, avs_asrc_create },
821 { &AVS_INTELWOV_MOD_UUID, avs_wov_create },
822 { &AVS_PROBE_MOD_UUID, avs_probe_create },
823 { &AVS_WOVHOSTM_MOD_UUID, avs_whm_create },
824 };
825
avs_path_module_type_create(struct avs_dev * adev,struct avs_path_module * mod)826 static int avs_path_module_type_create(struct avs_dev *adev, struct avs_path_module *mod)
827 {
828 const guid_t *type = &mod->template->cfg_ext->type;
829
830 for (int i = 0; i < ARRAY_SIZE(avs_module_create); i++)
831 if (guid_equal(type, avs_module_create[i].guid))
832 return avs_module_create[i].create(adev, mod);
833
834 return avs_modext_create(adev, mod);
835 }
836
avs_path_module_send_init_configs(struct avs_dev * adev,struct avs_path_module * mod)837 static int avs_path_module_send_init_configs(struct avs_dev *adev, struct avs_path_module *mod)
838 {
839 struct avs_tplg_module *template = mod->template;
840
841 for (int i = 0; i < template->num_init_configs; i++) {
842 struct avs_tplg_init_config *config = template->init_configs[i];
843 size_t len = config->length;
844 void *data = config->data;
845 u32 param = config->param;
846 int ret;
847
848 ret = avs_ipc_set_large_config(adev, mod->module_id, mod->instance_id,
849 param, data, len);
850 if (ret) {
851 dev_err(adev->dev, "send initial module config failed: %d\n", ret);
852 return AVS_IPC_RET(ret);
853 }
854 }
855
856 return 0;
857 }
858
avs_path_module_free(struct avs_dev * adev,struct avs_path_module * mod)859 static void avs_path_module_free(struct avs_dev *adev, struct avs_path_module *mod)
860 {
861 kfree(mod);
862 }
863
864 static struct avs_path_module *
avs_path_module_create(struct avs_dev * adev,struct avs_path_pipeline * owner,struct avs_tplg_module * template)865 avs_path_module_create(struct avs_dev *adev,
866 struct avs_path_pipeline *owner,
867 struct avs_tplg_module *template)
868 {
869 struct avs_path_module *mod;
870 int module_id, ret;
871
872 module_id = avs_get_module_id(adev, &template->cfg_ext->type);
873 if (module_id < 0)
874 return ERR_PTR(module_id);
875
876 mod = kzalloc_obj(*mod);
877 if (!mod)
878 return ERR_PTR(-ENOMEM);
879
880 mod->template = template;
881 mod->module_id = module_id;
882 mod->owner = owner;
883 INIT_LIST_HEAD(&mod->node);
884
885 ret = avs_path_module_type_create(adev, mod);
886 if (ret) {
887 dev_err(adev->dev, "module-type create failed: %d\n", ret);
888 kfree(mod);
889 return ERR_PTR(ret);
890 }
891
892 ret = avs_path_module_send_init_configs(adev, mod);
893 if (ret) {
894 kfree(mod);
895 return ERR_PTR(ret);
896 }
897
898 return mod;
899 }
900
avs_path_binding_arm(struct avs_dev * adev,struct avs_path_binding * binding)901 static int avs_path_binding_arm(struct avs_dev *adev, struct avs_path_binding *binding)
902 {
903 struct avs_path_module *this_mod, *target_mod;
904 struct avs_path_pipeline *target_ppl;
905 struct avs_path *target_path;
906 struct avs_tplg_binding *t;
907
908 t = binding->template;
909 this_mod = avs_path_find_module(binding->owner,
910 t->mod_id);
911 if (!this_mod) {
912 dev_err(adev->dev, "path mod %d not found\n", t->mod_id);
913 return -EINVAL;
914 }
915
916 /* update with target_tplg_name too */
917 target_path = avs_path_find_path(adev, t->target_tplg_name,
918 t->target_path_tmpl_id);
919 if (!target_path) {
920 dev_err(adev->dev, "target path %s:%d not found\n",
921 t->target_tplg_name, t->target_path_tmpl_id);
922 return -EINVAL;
923 }
924
925 target_ppl = avs_path_find_pipeline(target_path,
926 t->target_ppl_id);
927 if (!target_ppl) {
928 dev_err(adev->dev, "target ppl %d not found\n", t->target_ppl_id);
929 return -EINVAL;
930 }
931
932 target_mod = avs_path_find_module(target_ppl, t->target_mod_id);
933 if (!target_mod) {
934 dev_err(adev->dev, "target mod %d not found\n", t->target_mod_id);
935 return -EINVAL;
936 }
937
938 if (t->is_sink) {
939 binding->sink = this_mod;
940 binding->sink_pin = t->mod_pin;
941 binding->source = target_mod;
942 binding->source_pin = t->target_mod_pin;
943 } else {
944 binding->sink = target_mod;
945 binding->sink_pin = t->target_mod_pin;
946 binding->source = this_mod;
947 binding->source_pin = t->mod_pin;
948 }
949
950 return 0;
951 }
952
avs_path_binding_free(struct avs_dev * adev,struct avs_path_binding * binding)953 static void avs_path_binding_free(struct avs_dev *adev, struct avs_path_binding *binding)
954 {
955 kfree(binding);
956 }
957
avs_path_binding_create(struct avs_dev * adev,struct avs_path_pipeline * owner,struct avs_tplg_binding * t)958 static struct avs_path_binding *avs_path_binding_create(struct avs_dev *adev,
959 struct avs_path_pipeline *owner,
960 struct avs_tplg_binding *t)
961 {
962 struct avs_path_binding *binding;
963
964 binding = kzalloc_obj(*binding);
965 if (!binding)
966 return ERR_PTR(-ENOMEM);
967
968 binding->template = t;
969 binding->owner = owner;
970 INIT_LIST_HEAD(&binding->node);
971
972 return binding;
973 }
974
avs_path_pipeline_arm(struct avs_dev * adev,struct avs_path_pipeline * ppl)975 static int avs_path_pipeline_arm(struct avs_dev *adev,
976 struct avs_path_pipeline *ppl)
977 {
978 struct avs_path_module *mod;
979
980 list_for_each_entry(mod, &ppl->mod_list, node) {
981 struct avs_path_module *source, *sink;
982 int ret;
983
984 /*
985 * Only one module (so it's implicitly last) or it is the last
986 * one, either way we don't have next module to bind it to.
987 */
988 if (mod == list_last_entry(&ppl->mod_list,
989 struct avs_path_module, node))
990 break;
991
992 /* bind current module to next module on list */
993 source = mod;
994 sink = list_next_entry(mod, node);
995
996 ret = avs_ipc_bind(adev, source->module_id, source->instance_id,
997 sink->module_id, sink->instance_id, 0, 0);
998 if (ret)
999 return AVS_IPC_RET(ret);
1000 }
1001
1002 return 0;
1003 }
1004
avs_path_pipeline_free(struct avs_dev * adev,struct avs_path_pipeline * ppl)1005 static void avs_path_pipeline_free(struct avs_dev *adev,
1006 struct avs_path_pipeline *ppl)
1007 {
1008 struct avs_path_binding *binding, *bsave;
1009 struct avs_path_module *mod, *save;
1010
1011 list_for_each_entry_safe(binding, bsave, &ppl->binding_list, node) {
1012 list_del(&binding->node);
1013 avs_path_binding_free(adev, binding);
1014 }
1015
1016 avs_dsp_delete_pipeline(adev, ppl->instance_id);
1017
1018 /* Unload resources occupied by owned modules */
1019 list_for_each_entry_safe(mod, save, &ppl->mod_list, node) {
1020 avs_dsp_delete_module(adev, mod->module_id, mod->instance_id,
1021 mod->owner->instance_id,
1022 mod->template->core_id);
1023 avs_path_module_free(adev, mod);
1024 }
1025
1026 list_del(&ppl->node);
1027 kfree(ppl);
1028 }
1029
1030 static struct avs_path_pipeline *
avs_path_pipeline_create(struct avs_dev * adev,struct avs_path * owner,struct avs_tplg_pipeline * template)1031 avs_path_pipeline_create(struct avs_dev *adev, struct avs_path *owner,
1032 struct avs_tplg_pipeline *template)
1033 {
1034 struct avs_path_pipeline *ppl;
1035 struct avs_tplg_pplcfg *cfg = template->cfg;
1036 struct avs_tplg_module *tmod;
1037 int ret, i;
1038
1039 ppl = kzalloc_obj(*ppl);
1040 if (!ppl)
1041 return ERR_PTR(-ENOMEM);
1042
1043 ppl->template = template;
1044 ppl->owner = owner;
1045 INIT_LIST_HEAD(&ppl->binding_list);
1046 INIT_LIST_HEAD(&ppl->mod_list);
1047 INIT_LIST_HEAD(&ppl->node);
1048
1049 ret = avs_dsp_create_pipeline(adev, cfg->req_size, cfg->priority,
1050 cfg->lp, cfg->attributes,
1051 &ppl->instance_id);
1052 if (ret) {
1053 dev_err(adev->dev, "error creating pipeline %d\n", ret);
1054 kfree(ppl);
1055 return ERR_PTR(ret);
1056 }
1057
1058 list_for_each_entry(tmod, &template->mod_list, node) {
1059 struct avs_path_module *mod;
1060
1061 mod = avs_path_module_create(adev, ppl, tmod);
1062 if (IS_ERR(mod)) {
1063 ret = PTR_ERR(mod);
1064 dev_err(adev->dev, "error creating module %d\n", ret);
1065 goto init_err;
1066 }
1067
1068 list_add_tail(&mod->node, &ppl->mod_list);
1069 }
1070
1071 for (i = 0; i < template->num_bindings; i++) {
1072 struct avs_path_binding *binding;
1073
1074 binding = avs_path_binding_create(adev, ppl, template->bindings[i]);
1075 if (IS_ERR(binding)) {
1076 ret = PTR_ERR(binding);
1077 dev_err(adev->dev, "error creating binding %d\n", ret);
1078 goto init_err;
1079 }
1080
1081 list_add_tail(&binding->node, &ppl->binding_list);
1082 }
1083
1084 return ppl;
1085
1086 init_err:
1087 avs_path_pipeline_free(adev, ppl);
1088 return ERR_PTR(ret);
1089 }
1090
avs_path_init(struct avs_dev * adev,struct avs_path * path,struct avs_tplg_path * template,u32 dma_id)1091 static int avs_path_init(struct avs_dev *adev, struct avs_path *path,
1092 struct avs_tplg_path *template, u32 dma_id)
1093 {
1094 struct avs_tplg_pipeline *tppl;
1095
1096 path->owner = adev;
1097 path->template = template;
1098 path->dma_id = dma_id;
1099 INIT_LIST_HEAD(&path->ppl_list);
1100 INIT_LIST_HEAD(&path->node);
1101 INIT_LIST_HEAD(&path->source_list);
1102 INIT_LIST_HEAD(&path->sink_list);
1103 INIT_LIST_HEAD(&path->source_node);
1104 INIT_LIST_HEAD(&path->sink_node);
1105
1106 /* create all the pipelines */
1107 list_for_each_entry(tppl, &template->ppl_list, node) {
1108 struct avs_path_pipeline *ppl;
1109
1110 ppl = avs_path_pipeline_create(adev, path, tppl);
1111 if (IS_ERR(ppl))
1112 return PTR_ERR(ppl);
1113
1114 list_add_tail(&ppl->node, &path->ppl_list);
1115 }
1116
1117 spin_lock(&adev->path_list_lock);
1118 list_add_tail(&path->node, &adev->path_list);
1119 spin_unlock(&adev->path_list_lock);
1120
1121 return 0;
1122 }
1123
avs_path_arm(struct avs_dev * adev,struct avs_path * path)1124 static int avs_path_arm(struct avs_dev *adev, struct avs_path *path)
1125 {
1126 struct avs_path_pipeline *ppl;
1127 struct avs_path_binding *binding;
1128 int ret;
1129
1130 list_for_each_entry(ppl, &path->ppl_list, node) {
1131 /*
1132 * Arm all ppl bindings before binding internal modules
1133 * as it costs no IPCs which isn't true for the latter.
1134 */
1135 list_for_each_entry(binding, &ppl->binding_list, node) {
1136 ret = avs_path_binding_arm(adev, binding);
1137 if (ret < 0)
1138 return ret;
1139 }
1140
1141 ret = avs_path_pipeline_arm(adev, ppl);
1142 if (ret < 0)
1143 return ret;
1144 }
1145
1146 return 0;
1147 }
1148
avs_path_free_unlocked(struct avs_path * path)1149 static void avs_path_free_unlocked(struct avs_path *path)
1150 {
1151 struct avs_path_pipeline *ppl, *save;
1152
1153 spin_lock(&path->owner->path_list_lock);
1154 list_del(&path->node);
1155 spin_unlock(&path->owner->path_list_lock);
1156
1157 list_for_each_entry_safe(ppl, save, &path->ppl_list, node)
1158 avs_path_pipeline_free(path->owner, ppl);
1159
1160 kfree(path);
1161 }
1162
avs_path_create_unlocked(struct avs_dev * adev,u32 dma_id,struct avs_tplg_path * template)1163 static struct avs_path *avs_path_create_unlocked(struct avs_dev *adev, u32 dma_id,
1164 struct avs_tplg_path *template)
1165 {
1166 struct avs_path *path;
1167 int ret;
1168
1169 path = kzalloc_obj(*path);
1170 if (!path)
1171 return ERR_PTR(-ENOMEM);
1172
1173 ret = avs_path_init(adev, path, template, dma_id);
1174 if (ret < 0)
1175 goto err;
1176
1177 ret = avs_path_arm(adev, path);
1178 if (ret < 0)
1179 goto err;
1180
1181 path->state = AVS_PPL_STATE_INVALID;
1182 return path;
1183 err:
1184 avs_path_free_unlocked(path);
1185 return ERR_PTR(ret);
1186 }
1187
avs_condpath_free(struct avs_dev * adev,struct avs_path * path)1188 static void avs_condpath_free(struct avs_dev *adev, struct avs_path *path)
1189 {
1190 int ret;
1191
1192 list_del(&path->source_node);
1193 list_del(&path->sink_node);
1194
1195 ret = avs_path_reset(path);
1196 if (ret < 0)
1197 dev_err(adev->dev, "reset condpath failed: %d\n", ret);
1198
1199 ret = avs_path_unbind(path);
1200 if (ret < 0)
1201 dev_err(adev->dev, "unbind condpath failed: %d\n", ret);
1202
1203 avs_path_free_unlocked(path);
1204 }
1205
avs_condpath_create(struct avs_dev * adev,struct avs_tplg_path * template,struct avs_path * source,struct avs_path * sink)1206 static struct avs_path *avs_condpath_create(struct avs_dev *adev,
1207 struct avs_tplg_path *template,
1208 struct avs_path *source,
1209 struct avs_path *sink)
1210 {
1211 struct avs_path *path;
1212 int ret;
1213
1214 path = avs_path_create_unlocked(adev, 0, template);
1215 if (IS_ERR(path))
1216 return path;
1217
1218 ret = avs_path_bind(path);
1219 if (ret)
1220 goto err_bind;
1221
1222 ret = avs_path_reset(path);
1223 if (ret)
1224 goto err_reset;
1225
1226 path->source = source;
1227 path->sink = sink;
1228 list_add_tail(&path->source_node, &source->source_list);
1229 list_add_tail(&path->sink_node, &sink->sink_list);
1230
1231 return path;
1232
1233 err_reset:
1234 avs_path_unbind(path);
1235 err_bind:
1236 avs_path_free_unlocked(path);
1237 return ERR_PTR(ret);
1238 }
1239
avs_condpaths_walk(struct avs_dev * adev,struct avs_path * path,int dir)1240 static int avs_condpaths_walk(struct avs_dev *adev, struct avs_path *path, int dir)
1241 {
1242 struct avs_soc_component *acomp;
1243 struct avs_path *source, *sink;
1244 struct avs_path **other;
1245
1246 if (dir) {
1247 source = path;
1248 other = &sink;
1249 } else {
1250 sink = path;
1251 other = &source;
1252 }
1253
1254 list_for_each_entry(acomp, &adev->comp_list, node) {
1255 for (int i = 0; i < acomp->tplg->num_condpath_tmpls; i++) {
1256 struct avs_tplg_path_template *template;
1257 struct avs_tplg_path *variant;
1258 struct avs_path *cpath;
1259
1260 template = &acomp->tplg->condpath_tmpls[i];
1261
1262 /* Do not create unidirectional condpaths twice. */
1263 if (avs_tplg_path_template_id_equal(&template->source,
1264 &template->sink) && dir)
1265 continue;
1266
1267 *other = avs_condpath_find_match(adev, template, path, dir);
1268 if (!*other)
1269 continue;
1270
1271 variant = avs_condpath_find_variant(adev, template, source, sink);
1272 if (!variant)
1273 continue;
1274
1275 cpath = avs_condpath_create(adev, variant, source, sink);
1276 if (IS_ERR(cpath))
1277 return PTR_ERR(cpath);
1278 }
1279 }
1280
1281 return 0;
1282 }
1283
1284 /* Caller responsible for holding adev->path_mutex. */
avs_condpaths_walk_all(struct avs_dev * adev,struct avs_path * path)1285 static int avs_condpaths_walk_all(struct avs_dev *adev, struct avs_path *path)
1286 {
1287 int ret;
1288
1289 ret = avs_condpaths_walk(adev, path, SNDRV_PCM_STREAM_CAPTURE);
1290 if (ret)
1291 return ret;
1292
1293 return avs_condpaths_walk(adev, path, SNDRV_PCM_STREAM_PLAYBACK);
1294 }
1295
avs_path_free(struct avs_path * path)1296 void avs_path_free(struct avs_path *path)
1297 {
1298 struct avs_path *cpath, *csave;
1299 struct avs_dev *adev = path->owner;
1300
1301 guard(mutex)(&adev->path_mutex);
1302
1303 /* Free all condpaths this path spawned. */
1304 list_for_each_entry_safe(cpath, csave, &path->source_list, source_node)
1305 avs_condpath_free(path->owner, cpath);
1306 list_for_each_entry_safe(cpath, csave, &path->sink_list, sink_node)
1307 avs_condpath_free(path->owner, cpath);
1308
1309 avs_path_free_unlocked(path);
1310 }
1311
avs_path_create(struct avs_dev * adev,u32 dma_id,struct avs_tplg_path_template * template,struct snd_pcm_hw_params * fe_params,struct snd_pcm_hw_params * be_params)1312 struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id,
1313 struct avs_tplg_path_template *template,
1314 struct snd_pcm_hw_params *fe_params,
1315 struct snd_pcm_hw_params *be_params)
1316 {
1317 struct avs_tplg_path *variant;
1318 struct avs_path *path;
1319 int ret;
1320
1321 variant = avs_path_find_variant(adev, template, fe_params, be_params);
1322 if (!variant) {
1323 dev_err(adev->dev, "no matching variant found\n");
1324 return ERR_PTR(-ENOENT);
1325 }
1326
1327 /* Serialize path and its components creation. */
1328 guard(mutex)(&adev->path_mutex);
1329 /* Satisfy needs of avs_path_find_tplg(). */
1330 guard(mutex)(&adev->comp_list_mutex);
1331
1332 path = avs_path_create_unlocked(adev, dma_id, variant);
1333 if (IS_ERR(path))
1334 return path;
1335
1336 ret = avs_condpaths_walk_all(adev, path);
1337 if (ret) {
1338 avs_path_free_unlocked(path);
1339 path = ERR_PTR(ret);
1340 }
1341
1342 return path;
1343 }
1344
avs_path_bind_prepare(struct avs_dev * adev,struct avs_path_binding * binding)1345 static int avs_path_bind_prepare(struct avs_dev *adev,
1346 struct avs_path_binding *binding)
1347 {
1348 const struct avs_audio_format *src_fmt, *sink_fmt;
1349 struct avs_tplg_module *tsource = binding->source->template;
1350 struct avs_path_module *source = binding->source;
1351 int ret;
1352
1353 /*
1354 * only copier modules about to be bound
1355 * to output pin other than 0 need preparation
1356 */
1357 if (!binding->source_pin)
1358 return 0;
1359 if (!guid_equal(&tsource->cfg_ext->type, &AVS_COPIER_MOD_UUID))
1360 return 0;
1361
1362 src_fmt = tsource->in_fmt;
1363 sink_fmt = binding->sink->template->in_fmt;
1364
1365 ret = avs_ipc_copier_set_sink_format(adev, source->module_id,
1366 source->instance_id, binding->source_pin,
1367 src_fmt, sink_fmt);
1368 if (ret) {
1369 dev_err(adev->dev, "config copier failed: %d\n", ret);
1370 return AVS_IPC_RET(ret);
1371 }
1372
1373 return 0;
1374 }
1375
avs_path_bind(struct avs_path * path)1376 int avs_path_bind(struct avs_path *path)
1377 {
1378 struct avs_path_pipeline *ppl;
1379 struct avs_dev *adev = path->owner;
1380 int ret;
1381
1382 list_for_each_entry(ppl, &path->ppl_list, node) {
1383 struct avs_path_binding *binding;
1384
1385 list_for_each_entry(binding, &ppl->binding_list, node) {
1386 struct avs_path_module *source, *sink;
1387
1388 source = binding->source;
1389 sink = binding->sink;
1390
1391 ret = avs_path_bind_prepare(adev, binding);
1392 if (ret < 0)
1393 return ret;
1394
1395 ret = avs_ipc_bind(adev, source->module_id,
1396 source->instance_id, sink->module_id,
1397 sink->instance_id, binding->sink_pin,
1398 binding->source_pin);
1399 if (ret) {
1400 dev_err(adev->dev, "bind path failed: %d\n", ret);
1401 return AVS_IPC_RET(ret);
1402 }
1403 }
1404 }
1405
1406 return 0;
1407 }
1408
avs_path_unbind(struct avs_path * path)1409 int avs_path_unbind(struct avs_path *path)
1410 {
1411 struct avs_path_pipeline *ppl;
1412 struct avs_dev *adev = path->owner;
1413 int ret;
1414
1415 list_for_each_entry(ppl, &path->ppl_list, node) {
1416 struct avs_path_binding *binding;
1417
1418 list_for_each_entry(binding, &ppl->binding_list, node) {
1419 struct avs_path_module *source, *sink;
1420
1421 source = binding->source;
1422 sink = binding->sink;
1423
1424 ret = avs_ipc_unbind(adev, source->module_id,
1425 source->instance_id, sink->module_id,
1426 sink->instance_id, binding->sink_pin,
1427 binding->source_pin);
1428 if (ret) {
1429 dev_err(adev->dev, "unbind path failed: %d\n", ret);
1430 return AVS_IPC_RET(ret);
1431 }
1432 }
1433 }
1434
1435 return 0;
1436 }
1437
avs_path_reset(struct avs_path * path)1438 int avs_path_reset(struct avs_path *path)
1439 {
1440 struct avs_path_pipeline *ppl;
1441 struct avs_dev *adev = path->owner;
1442 int ret;
1443
1444 if (path->state == AVS_PPL_STATE_RESET)
1445 return 0;
1446
1447 list_for_each_entry(ppl, &path->ppl_list, node) {
1448 ret = avs_ipc_set_pipeline_state(adev, ppl->instance_id,
1449 AVS_PPL_STATE_RESET);
1450 if (ret) {
1451 dev_err(adev->dev, "reset path failed: %d\n", ret);
1452 path->state = AVS_PPL_STATE_INVALID;
1453 return AVS_IPC_RET(ret);
1454 }
1455 }
1456
1457 path->state = AVS_PPL_STATE_RESET;
1458 return 0;
1459 }
1460
avs_condpath_pause(struct avs_dev * adev,struct avs_path * cpath)1461 static int avs_condpath_pause(struct avs_dev *adev, struct avs_path *cpath)
1462 {
1463 struct avs_path_pipeline *ppl;
1464 int ret;
1465
1466 if (cpath->state == AVS_PPL_STATE_PAUSED)
1467 return 0;
1468
1469 list_for_each_entry_reverse(ppl, &cpath->ppl_list, node) {
1470 ret = avs_ipc_set_pipeline_state(adev, ppl->instance_id, AVS_PPL_STATE_PAUSED);
1471 if (ret) {
1472 dev_err(adev->dev, "pause cpath failed: %d\n", ret);
1473 cpath->state = AVS_PPL_STATE_INVALID;
1474 return AVS_IPC_RET(ret);
1475 }
1476 }
1477
1478 cpath->state = AVS_PPL_STATE_PAUSED;
1479 return 0;
1480 }
1481
avs_condpaths_pause(struct avs_dev * adev,struct avs_path * path)1482 static void avs_condpaths_pause(struct avs_dev *adev, struct avs_path *path)
1483 {
1484 struct avs_path *cpath;
1485
1486 guard(mutex)(&adev->path_mutex);
1487
1488 /* If either source or sink stops, so do the attached conditional paths. */
1489 list_for_each_entry(cpath, &path->source_list, source_node)
1490 avs_condpath_pause(adev, cpath);
1491 list_for_each_entry(cpath, &path->sink_list, sink_node)
1492 avs_condpath_pause(adev, cpath);
1493 }
1494
avs_path_pause(struct avs_path * path)1495 int avs_path_pause(struct avs_path *path)
1496 {
1497 struct avs_path_pipeline *ppl;
1498 struct avs_dev *adev = path->owner;
1499 int ret;
1500
1501 if (path->state == AVS_PPL_STATE_PAUSED)
1502 return 0;
1503
1504 avs_condpaths_pause(adev, path);
1505
1506 list_for_each_entry_reverse(ppl, &path->ppl_list, node) {
1507 ret = avs_ipc_set_pipeline_state(adev, ppl->instance_id,
1508 AVS_PPL_STATE_PAUSED);
1509 if (ret) {
1510 dev_err(adev->dev, "pause path failed: %d\n", ret);
1511 path->state = AVS_PPL_STATE_INVALID;
1512 return AVS_IPC_RET(ret);
1513 }
1514 }
1515
1516 path->state = AVS_PPL_STATE_PAUSED;
1517 return 0;
1518 }
1519
avs_condpath_run(struct avs_dev * adev,struct avs_path * cpath,int trigger)1520 static int avs_condpath_run(struct avs_dev *adev, struct avs_path *cpath, int trigger)
1521 {
1522 struct avs_path_pipeline *ppl;
1523 int ret;
1524
1525 if (cpath->state == AVS_PPL_STATE_RUNNING)
1526 return 0;
1527
1528 list_for_each_entry(ppl, &cpath->ppl_list, node) {
1529 if (ppl->template->cfg->trigger != trigger)
1530 continue;
1531
1532 ret = avs_ipc_set_pipeline_state(adev, ppl->instance_id, AVS_PPL_STATE_RUNNING);
1533 if (ret) {
1534 dev_err(adev->dev, "run cpath failed: %d\n", ret);
1535 cpath->state = AVS_PPL_STATE_INVALID;
1536 return AVS_IPC_RET(ret);
1537 }
1538 }
1539
1540 cpath->state = AVS_PPL_STATE_RUNNING;
1541 return 0;
1542 }
1543
avs_condpaths_run(struct avs_dev * adev,struct avs_path * path,int trigger)1544 static void avs_condpaths_run(struct avs_dev *adev, struct avs_path *path, int trigger)
1545 {
1546 struct avs_path *cpath;
1547
1548 guard(mutex)(&adev->path_mutex);
1549
1550 /* Run conditional paths only if source and sink are both running. */
1551 list_for_each_entry(cpath, &path->source_list, source_node)
1552 if (cpath->source->state == AVS_PPL_STATE_RUNNING &&
1553 cpath->sink->state == AVS_PPL_STATE_RUNNING)
1554 avs_condpath_run(adev, cpath, trigger);
1555
1556 list_for_each_entry(cpath, &path->sink_list, sink_node)
1557 if (cpath->source->state == AVS_PPL_STATE_RUNNING &&
1558 cpath->sink->state == AVS_PPL_STATE_RUNNING)
1559 avs_condpath_run(adev, cpath, trigger);
1560 }
1561
avs_path_run(struct avs_path * path,int trigger)1562 int avs_path_run(struct avs_path *path, int trigger)
1563 {
1564 struct avs_path_pipeline *ppl;
1565 struct avs_dev *adev = path->owner;
1566 int ret;
1567
1568 if (path->state == AVS_PPL_STATE_RUNNING && trigger == AVS_TPLG_TRIGGER_AUTO)
1569 return 0;
1570
1571 list_for_each_entry(ppl, &path->ppl_list, node) {
1572 if (ppl->template->cfg->trigger != trigger)
1573 continue;
1574
1575 ret = avs_ipc_set_pipeline_state(adev, ppl->instance_id,
1576 AVS_PPL_STATE_RUNNING);
1577 if (ret) {
1578 dev_err(adev->dev, "run path failed: %d\n", ret);
1579 path->state = AVS_PPL_STATE_INVALID;
1580 return AVS_IPC_RET(ret);
1581 }
1582 }
1583
1584 path->state = AVS_PPL_STATE_RUNNING;
1585
1586 /* Granular pipeline triggering not intended for conditional paths. */
1587 if (trigger == AVS_TPLG_TRIGGER_AUTO)
1588 avs_condpaths_run(adev, path, trigger);
1589
1590 return 0;
1591 }
1592