0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <sound/intel-nhlt.h>
0010 #include <sound/pcm_params.h>
0011 #include <sound/soc.h>
0012 #include "avs.h"
0013 #include "path.h"
0014 #include "topology.h"
0015
0016
0017 static struct avs_tplg *
0018 avs_path_find_tplg(struct avs_dev *adev, const char *name)
0019 {
0020 struct avs_soc_component *acomp;
0021
0022 list_for_each_entry(acomp, &adev->comp_list, node)
0023 if (!strcmp(acomp->tplg->name, name))
0024 return acomp->tplg;
0025 return NULL;
0026 }
0027
0028 static struct avs_path_module *
0029 avs_path_find_module(struct avs_path_pipeline *ppl, u32 template_id)
0030 {
0031 struct avs_path_module *mod;
0032
0033 list_for_each_entry(mod, &ppl->mod_list, node)
0034 if (mod->template->id == template_id)
0035 return mod;
0036 return NULL;
0037 }
0038
0039 static struct avs_path_pipeline *
0040 avs_path_find_pipeline(struct avs_path *path, u32 template_id)
0041 {
0042 struct avs_path_pipeline *ppl;
0043
0044 list_for_each_entry(ppl, &path->ppl_list, node)
0045 if (ppl->template->id == template_id)
0046 return ppl;
0047 return NULL;
0048 }
0049
0050 static struct avs_path *
0051 avs_path_find_path(struct avs_dev *adev, const char *name, u32 template_id)
0052 {
0053 struct avs_tplg_path_template *pos, *template = NULL;
0054 struct avs_tplg *tplg;
0055 struct avs_path *path;
0056
0057 tplg = avs_path_find_tplg(adev, name);
0058 if (!tplg)
0059 return NULL;
0060
0061 list_for_each_entry(pos, &tplg->path_tmpl_list, node) {
0062 if (pos->id == template_id) {
0063 template = pos;
0064 break;
0065 }
0066 }
0067 if (!template)
0068 return NULL;
0069
0070 spin_lock(&adev->path_list_lock);
0071
0072 list_for_each_entry(path, &adev->path_list, node) {
0073 if (path->template->owner == template) {
0074 spin_unlock(&adev->path_list_lock);
0075 return path;
0076 }
0077 }
0078
0079 spin_unlock(&adev->path_list_lock);
0080 return NULL;
0081 }
0082
0083 static bool avs_test_hw_params(struct snd_pcm_hw_params *params,
0084 struct avs_audio_format *fmt)
0085 {
0086 return (params_rate(params) == fmt->sampling_freq &&
0087 params_channels(params) == fmt->num_channels &&
0088 params_physical_width(params) == fmt->bit_depth &&
0089 params_width(params) == fmt->valid_bit_depth);
0090 }
0091
0092 static struct avs_tplg_path *
0093 avs_path_find_variant(struct avs_dev *adev,
0094 struct avs_tplg_path_template *template,
0095 struct snd_pcm_hw_params *fe_params,
0096 struct snd_pcm_hw_params *be_params)
0097 {
0098 struct avs_tplg_path *variant;
0099
0100 list_for_each_entry(variant, &template->path_list, node) {
0101 dev_dbg(adev->dev, "check FE rate %d chn %d vbd %d bd %d\n",
0102 variant->fe_fmt->sampling_freq, variant->fe_fmt->num_channels,
0103 variant->fe_fmt->valid_bit_depth, variant->fe_fmt->bit_depth);
0104 dev_dbg(adev->dev, "check BE rate %d chn %d vbd %d bd %d\n",
0105 variant->be_fmt->sampling_freq, variant->be_fmt->num_channels,
0106 variant->be_fmt->valid_bit_depth, variant->be_fmt->bit_depth);
0107
0108 if (variant->fe_fmt && avs_test_hw_params(fe_params, variant->fe_fmt) &&
0109 variant->be_fmt && avs_test_hw_params(be_params, variant->be_fmt))
0110 return variant;
0111 }
0112
0113 return NULL;
0114 }
0115
0116 __maybe_unused
0117 static bool avs_dma_type_is_host(u32 dma_type)
0118 {
0119 return dma_type == AVS_DMA_HDA_HOST_OUTPUT ||
0120 dma_type == AVS_DMA_HDA_HOST_INPUT;
0121 }
0122
0123 __maybe_unused
0124 static bool avs_dma_type_is_link(u32 dma_type)
0125 {
0126 return !avs_dma_type_is_host(dma_type);
0127 }
0128
0129 __maybe_unused
0130 static bool avs_dma_type_is_output(u32 dma_type)
0131 {
0132 return dma_type == AVS_DMA_HDA_HOST_OUTPUT ||
0133 dma_type == AVS_DMA_HDA_LINK_OUTPUT ||
0134 dma_type == AVS_DMA_I2S_LINK_OUTPUT;
0135 }
0136
0137 __maybe_unused
0138 static bool avs_dma_type_is_input(u32 dma_type)
0139 {
0140 return !avs_dma_type_is_output(dma_type);
0141 }
0142
0143 static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod)
0144 {
0145 struct nhlt_acpi_table *nhlt = adev->nhlt;
0146 struct avs_tplg_module *t = mod->template;
0147 struct avs_copier_cfg *cfg;
0148 struct nhlt_specific_cfg *ep_blob;
0149 union avs_connector_node_id node_id = {0};
0150 size_t cfg_size, data_size = 0;
0151 void *data = NULL;
0152 u32 dma_type;
0153 int ret;
0154
0155 dma_type = t->cfg_ext->copier.dma_type;
0156 node_id.dma_type = dma_type;
0157
0158 switch (dma_type) {
0159 struct avs_audio_format *fmt;
0160 int direction;
0161
0162 case AVS_DMA_I2S_LINK_OUTPUT:
0163 case AVS_DMA_I2S_LINK_INPUT:
0164 if (avs_dma_type_is_input(dma_type))
0165 direction = SNDRV_PCM_STREAM_CAPTURE;
0166 else
0167 direction = SNDRV_PCM_STREAM_PLAYBACK;
0168
0169 if (t->cfg_ext->copier.blob_fmt)
0170 fmt = t->cfg_ext->copier.blob_fmt;
0171 else if (direction == SNDRV_PCM_STREAM_CAPTURE)
0172 fmt = t->in_fmt;
0173 else
0174 fmt = t->cfg_ext->copier.out_fmt;
0175
0176 ep_blob = intel_nhlt_get_endpoint_blob(adev->dev,
0177 nhlt, t->cfg_ext->copier.vindex.i2s.instance,
0178 NHLT_LINK_SSP, fmt->valid_bit_depth, fmt->bit_depth,
0179 fmt->num_channels, fmt->sampling_freq, direction,
0180 NHLT_DEVICE_I2S);
0181 if (!ep_blob) {
0182 dev_err(adev->dev, "no I2S ep_blob found\n");
0183 return -ENOENT;
0184 }
0185
0186 data = ep_blob->caps;
0187 data_size = ep_blob->size;
0188
0189 node_id.vindex = t->cfg_ext->copier.vindex.val;
0190
0191 break;
0192
0193 case AVS_DMA_DMIC_LINK_INPUT:
0194 direction = SNDRV_PCM_STREAM_CAPTURE;
0195
0196 if (t->cfg_ext->copier.blob_fmt)
0197 fmt = t->cfg_ext->copier.blob_fmt;
0198 else
0199 fmt = t->in_fmt;
0200
0201 ep_blob = intel_nhlt_get_endpoint_blob(adev->dev, nhlt, 0,
0202 NHLT_LINK_DMIC, fmt->valid_bit_depth,
0203 fmt->bit_depth, fmt->num_channels,
0204 fmt->sampling_freq, direction, NHLT_DEVICE_DMIC);
0205 if (!ep_blob) {
0206 dev_err(adev->dev, "no DMIC ep_blob found\n");
0207 return -ENOENT;
0208 }
0209
0210 data = ep_blob->caps;
0211 data_size = ep_blob->size;
0212
0213 node_id.vindex = t->cfg_ext->copier.vindex.val;
0214
0215 break;
0216
0217 case AVS_DMA_HDA_HOST_OUTPUT:
0218 case AVS_DMA_HDA_HOST_INPUT:
0219
0220 node_id.vindex = mod->owner->owner->dma_id;
0221 break;
0222
0223 case AVS_DMA_HDA_LINK_OUTPUT:
0224 case AVS_DMA_HDA_LINK_INPUT:
0225 node_id.vindex = t->cfg_ext->copier.vindex.val |
0226 mod->owner->owner->dma_id;
0227 break;
0228
0229 case INVALID_OBJECT_ID:
0230 default:
0231 node_id = INVALID_NODE_ID;
0232 break;
0233 }
0234
0235 cfg_size = sizeof(*cfg) + data_size;
0236
0237 if (data_size)
0238 cfg_size -= sizeof(cfg->gtw_cfg.config.attrs);
0239
0240 cfg = kzalloc(cfg_size, GFP_KERNEL);
0241 if (!cfg)
0242 return -ENOMEM;
0243
0244 cfg->base.cpc = t->cfg_base->cpc;
0245 cfg->base.ibs = t->cfg_base->ibs;
0246 cfg->base.obs = t->cfg_base->obs;
0247 cfg->base.is_pages = t->cfg_base->is_pages;
0248 cfg->base.audio_fmt = *t->in_fmt;
0249 cfg->out_fmt = *t->cfg_ext->copier.out_fmt;
0250 cfg->feature_mask = t->cfg_ext->copier.feature_mask;
0251 cfg->gtw_cfg.node_id = node_id;
0252 cfg->gtw_cfg.dma_buffer_size = t->cfg_ext->copier.dma_buffer_size;
0253
0254 cfg->gtw_cfg.config_length = DIV_ROUND_UP(data_size, 4);
0255 if (data)
0256 memcpy(&cfg->gtw_cfg.config, data, data_size);
0257
0258 mod->gtw_attrs = cfg->gtw_cfg.config.attrs;
0259
0260 ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
0261 t->core_id, t->domain, cfg, cfg_size,
0262 &mod->instance_id);
0263 kfree(cfg);
0264 return ret;
0265 }
0266
0267 static int avs_updown_mix_create(struct avs_dev *adev, struct avs_path_module *mod)
0268 {
0269 struct avs_tplg_module *t = mod->template;
0270 struct avs_updown_mixer_cfg cfg;
0271 int i;
0272
0273 cfg.base.cpc = t->cfg_base->cpc;
0274 cfg.base.ibs = t->cfg_base->ibs;
0275 cfg.base.obs = t->cfg_base->obs;
0276 cfg.base.is_pages = t->cfg_base->is_pages;
0277 cfg.base.audio_fmt = *t->in_fmt;
0278 cfg.out_channel_config = t->cfg_ext->updown_mix.out_channel_config;
0279 cfg.coefficients_select = t->cfg_ext->updown_mix.coefficients_select;
0280 for (i = 0; i < AVS_CHANNELS_MAX; i++)
0281 cfg.coefficients[i] = t->cfg_ext->updown_mix.coefficients[i];
0282 cfg.channel_map = t->cfg_ext->updown_mix.channel_map;
0283
0284 return avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
0285 t->core_id, t->domain, &cfg, sizeof(cfg),
0286 &mod->instance_id);
0287 }
0288
0289 static int avs_src_create(struct avs_dev *adev, struct avs_path_module *mod)
0290 {
0291 struct avs_tplg_module *t = mod->template;
0292 struct avs_src_cfg cfg;
0293
0294 cfg.base.cpc = t->cfg_base->cpc;
0295 cfg.base.ibs = t->cfg_base->ibs;
0296 cfg.base.obs = t->cfg_base->obs;
0297 cfg.base.is_pages = t->cfg_base->is_pages;
0298 cfg.base.audio_fmt = *t->in_fmt;
0299 cfg.out_freq = t->cfg_ext->src.out_freq;
0300
0301 return avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
0302 t->core_id, t->domain, &cfg, sizeof(cfg),
0303 &mod->instance_id);
0304 }
0305
0306 static int avs_asrc_create(struct avs_dev *adev, struct avs_path_module *mod)
0307 {
0308 struct avs_tplg_module *t = mod->template;
0309 struct avs_asrc_cfg cfg;
0310
0311 cfg.base.cpc = t->cfg_base->cpc;
0312 cfg.base.ibs = t->cfg_base->ibs;
0313 cfg.base.obs = t->cfg_base->obs;
0314 cfg.base.is_pages = t->cfg_base->is_pages;
0315 cfg.base.audio_fmt = *t->in_fmt;
0316 cfg.out_freq = t->cfg_ext->asrc.out_freq;
0317 cfg.mode = t->cfg_ext->asrc.mode;
0318 cfg.disable_jitter_buffer = t->cfg_ext->asrc.disable_jitter_buffer;
0319
0320 return avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
0321 t->core_id, t->domain, &cfg, sizeof(cfg),
0322 &mod->instance_id);
0323 }
0324
0325 static int avs_aec_create(struct avs_dev *adev, struct avs_path_module *mod)
0326 {
0327 struct avs_tplg_module *t = mod->template;
0328 struct avs_aec_cfg cfg;
0329
0330 cfg.base.cpc = t->cfg_base->cpc;
0331 cfg.base.ibs = t->cfg_base->ibs;
0332 cfg.base.obs = t->cfg_base->obs;
0333 cfg.base.is_pages = t->cfg_base->is_pages;
0334 cfg.base.audio_fmt = *t->in_fmt;
0335 cfg.ref_fmt = *t->cfg_ext->aec.ref_fmt;
0336 cfg.out_fmt = *t->cfg_ext->aec.out_fmt;
0337 cfg.cpc_lp_mode = t->cfg_ext->aec.cpc_lp_mode;
0338
0339 return avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
0340 t->core_id, t->domain, &cfg, sizeof(cfg),
0341 &mod->instance_id);
0342 }
0343
0344 static int avs_mux_create(struct avs_dev *adev, struct avs_path_module *mod)
0345 {
0346 struct avs_tplg_module *t = mod->template;
0347 struct avs_mux_cfg cfg;
0348
0349 cfg.base.cpc = t->cfg_base->cpc;
0350 cfg.base.ibs = t->cfg_base->ibs;
0351 cfg.base.obs = t->cfg_base->obs;
0352 cfg.base.is_pages = t->cfg_base->is_pages;
0353 cfg.base.audio_fmt = *t->in_fmt;
0354 cfg.ref_fmt = *t->cfg_ext->mux.ref_fmt;
0355 cfg.out_fmt = *t->cfg_ext->mux.out_fmt;
0356
0357 return avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
0358 t->core_id, t->domain, &cfg, sizeof(cfg),
0359 &mod->instance_id);
0360 }
0361
0362 static int avs_wov_create(struct avs_dev *adev, struct avs_path_module *mod)
0363 {
0364 struct avs_tplg_module *t = mod->template;
0365 struct avs_wov_cfg cfg;
0366
0367 cfg.base.cpc = t->cfg_base->cpc;
0368 cfg.base.ibs = t->cfg_base->ibs;
0369 cfg.base.obs = t->cfg_base->obs;
0370 cfg.base.is_pages = t->cfg_base->is_pages;
0371 cfg.base.audio_fmt = *t->in_fmt;
0372 cfg.cpc_lp_mode = t->cfg_ext->wov.cpc_lp_mode;
0373
0374 return avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
0375 t->core_id, t->domain, &cfg, sizeof(cfg),
0376 &mod->instance_id);
0377 }
0378
0379 static int avs_micsel_create(struct avs_dev *adev, struct avs_path_module *mod)
0380 {
0381 struct avs_tplg_module *t = mod->template;
0382 struct avs_micsel_cfg cfg;
0383
0384 cfg.base.cpc = t->cfg_base->cpc;
0385 cfg.base.ibs = t->cfg_base->ibs;
0386 cfg.base.obs = t->cfg_base->obs;
0387 cfg.base.is_pages = t->cfg_base->is_pages;
0388 cfg.base.audio_fmt = *t->in_fmt;
0389 cfg.out_fmt = *t->cfg_ext->micsel.out_fmt;
0390
0391 return avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
0392 t->core_id, t->domain, &cfg, sizeof(cfg),
0393 &mod->instance_id);
0394 }
0395
0396 static int avs_modbase_create(struct avs_dev *adev, struct avs_path_module *mod)
0397 {
0398 struct avs_tplg_module *t = mod->template;
0399 struct avs_modcfg_base cfg;
0400
0401 cfg.cpc = t->cfg_base->cpc;
0402 cfg.ibs = t->cfg_base->ibs;
0403 cfg.obs = t->cfg_base->obs;
0404 cfg.is_pages = t->cfg_base->is_pages;
0405 cfg.audio_fmt = *t->in_fmt;
0406
0407 return avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
0408 t->core_id, t->domain, &cfg, sizeof(cfg),
0409 &mod->instance_id);
0410 }
0411
0412 static int avs_modext_create(struct avs_dev *adev, struct avs_path_module *mod)
0413 {
0414 struct avs_tplg_module *t = mod->template;
0415 struct avs_tplg_modcfg_ext *tcfg = t->cfg_ext;
0416 struct avs_modcfg_ext *cfg;
0417 size_t cfg_size, num_pins;
0418 int ret, i;
0419
0420 num_pins = tcfg->generic.num_input_pins + tcfg->generic.num_output_pins;
0421 cfg_size = sizeof(*cfg) + sizeof(*cfg->pin_fmts) * num_pins;
0422
0423 cfg = kzalloc(cfg_size, GFP_KERNEL);
0424 if (!cfg)
0425 return -ENOMEM;
0426
0427 cfg->base.cpc = t->cfg_base->cpc;
0428 cfg->base.ibs = t->cfg_base->ibs;
0429 cfg->base.obs = t->cfg_base->obs;
0430 cfg->base.is_pages = t->cfg_base->is_pages;
0431 cfg->base.audio_fmt = *t->in_fmt;
0432 cfg->num_input_pins = tcfg->generic.num_input_pins;
0433 cfg->num_output_pins = tcfg->generic.num_output_pins;
0434
0435
0436 for (i = 0; i < num_pins; i++) {
0437 struct avs_tplg_pin_format *tpin = &tcfg->generic.pin_fmts[i];
0438 struct avs_pin_format *pin = &cfg->pin_fmts[i];
0439
0440 pin->pin_index = tpin->pin_index;
0441 pin->iobs = tpin->iobs;
0442 pin->audio_fmt = *tpin->fmt;
0443 }
0444
0445 ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
0446 t->core_id, t->domain, cfg, cfg_size,
0447 &mod->instance_id);
0448 kfree(cfg);
0449 return ret;
0450 }
0451
0452 static int avs_probe_create(struct avs_dev *adev, struct avs_path_module *mod)
0453 {
0454 dev_err(adev->dev, "Probe module can't be instantiated by topology");
0455 return -EINVAL;
0456 }
0457
0458 struct avs_module_create {
0459 guid_t *guid;
0460 int (*create)(struct avs_dev *adev, struct avs_path_module *mod);
0461 };
0462
0463 static struct avs_module_create avs_module_create[] = {
0464 { &AVS_MIXIN_MOD_UUID, avs_modbase_create },
0465 { &AVS_MIXOUT_MOD_UUID, avs_modbase_create },
0466 { &AVS_KPBUFF_MOD_UUID, avs_modbase_create },
0467 { &AVS_COPIER_MOD_UUID, avs_copier_create },
0468 { &AVS_MICSEL_MOD_UUID, avs_micsel_create },
0469 { &AVS_MUX_MOD_UUID, avs_mux_create },
0470 { &AVS_UPDWMIX_MOD_UUID, avs_updown_mix_create },
0471 { &AVS_SRCINTC_MOD_UUID, avs_src_create },
0472 { &AVS_AEC_MOD_UUID, avs_aec_create },
0473 { &AVS_ASRC_MOD_UUID, avs_asrc_create },
0474 { &AVS_INTELWOV_MOD_UUID, avs_wov_create },
0475 { &AVS_PROBE_MOD_UUID, avs_probe_create },
0476 };
0477
0478 static int avs_path_module_type_create(struct avs_dev *adev, struct avs_path_module *mod)
0479 {
0480 const guid_t *type = &mod->template->cfg_ext->type;
0481
0482 for (int i = 0; i < ARRAY_SIZE(avs_module_create); i++)
0483 if (guid_equal(type, avs_module_create[i].guid))
0484 return avs_module_create[i].create(adev, mod);
0485
0486 return avs_modext_create(adev, mod);
0487 }
0488
0489 static void avs_path_module_free(struct avs_dev *adev, struct avs_path_module *mod)
0490 {
0491 kfree(mod);
0492 }
0493
0494 static struct avs_path_module *
0495 avs_path_module_create(struct avs_dev *adev,
0496 struct avs_path_pipeline *owner,
0497 struct avs_tplg_module *template)
0498 {
0499 struct avs_path_module *mod;
0500 int module_id, ret;
0501
0502 module_id = avs_get_module_id(adev, &template->cfg_ext->type);
0503 if (module_id < 0)
0504 return ERR_PTR(module_id);
0505
0506 mod = kzalloc(sizeof(*mod), GFP_KERNEL);
0507 if (!mod)
0508 return ERR_PTR(-ENOMEM);
0509
0510 mod->template = template;
0511 mod->module_id = module_id;
0512 mod->owner = owner;
0513 INIT_LIST_HEAD(&mod->node);
0514
0515 ret = avs_path_module_type_create(adev, mod);
0516 if (ret) {
0517 dev_err(adev->dev, "module-type create failed: %d\n", ret);
0518 kfree(mod);
0519 return ERR_PTR(ret);
0520 }
0521
0522 return mod;
0523 }
0524
0525 static int avs_path_binding_arm(struct avs_dev *adev, struct avs_path_binding *binding)
0526 {
0527 struct avs_path_module *this_mod, *target_mod;
0528 struct avs_path_pipeline *target_ppl;
0529 struct avs_path *target_path;
0530 struct avs_tplg_binding *t;
0531
0532 t = binding->template;
0533 this_mod = avs_path_find_module(binding->owner,
0534 t->mod_id);
0535 if (!this_mod) {
0536 dev_err(adev->dev, "path mod %d not found\n", t->mod_id);
0537 return -EINVAL;
0538 }
0539
0540
0541 target_path = avs_path_find_path(adev, t->target_tplg_name,
0542 t->target_path_tmpl_id);
0543 if (!target_path) {
0544 dev_err(adev->dev, "target path %s:%d not found\n",
0545 t->target_tplg_name, t->target_path_tmpl_id);
0546 return -EINVAL;
0547 }
0548
0549 target_ppl = avs_path_find_pipeline(target_path,
0550 t->target_ppl_id);
0551 if (!target_ppl) {
0552 dev_err(adev->dev, "target ppl %d not found\n", t->target_ppl_id);
0553 return -EINVAL;
0554 }
0555
0556 target_mod = avs_path_find_module(target_ppl, t->target_mod_id);
0557 if (!target_mod) {
0558 dev_err(adev->dev, "target mod %d not found\n", t->target_mod_id);
0559 return -EINVAL;
0560 }
0561
0562 if (t->is_sink) {
0563 binding->sink = this_mod;
0564 binding->sink_pin = t->mod_pin;
0565 binding->source = target_mod;
0566 binding->source_pin = t->target_mod_pin;
0567 } else {
0568 binding->sink = target_mod;
0569 binding->sink_pin = t->target_mod_pin;
0570 binding->source = this_mod;
0571 binding->source_pin = t->mod_pin;
0572 }
0573
0574 return 0;
0575 }
0576
0577 static void avs_path_binding_free(struct avs_dev *adev, struct avs_path_binding *binding)
0578 {
0579 kfree(binding);
0580 }
0581
0582 static struct avs_path_binding *avs_path_binding_create(struct avs_dev *adev,
0583 struct avs_path_pipeline *owner,
0584 struct avs_tplg_binding *t)
0585 {
0586 struct avs_path_binding *binding;
0587
0588 binding = kzalloc(sizeof(*binding), GFP_KERNEL);
0589 if (!binding)
0590 return ERR_PTR(-ENOMEM);
0591
0592 binding->template = t;
0593 binding->owner = owner;
0594 INIT_LIST_HEAD(&binding->node);
0595
0596 return binding;
0597 }
0598
0599 static int avs_path_pipeline_arm(struct avs_dev *adev,
0600 struct avs_path_pipeline *ppl)
0601 {
0602 struct avs_path_module *mod;
0603
0604 list_for_each_entry(mod, &ppl->mod_list, node) {
0605 struct avs_path_module *source, *sink;
0606 int ret;
0607
0608
0609
0610
0611
0612 if (mod == list_last_entry(&ppl->mod_list,
0613 struct avs_path_module, node))
0614 break;
0615
0616
0617 source = mod;
0618 sink = list_next_entry(mod, node);
0619 if (!source || !sink)
0620 return -EINVAL;
0621
0622 ret = avs_ipc_bind(adev, source->module_id, source->instance_id,
0623 sink->module_id, sink->instance_id, 0, 0);
0624 if (ret)
0625 return AVS_IPC_RET(ret);
0626 }
0627
0628 return 0;
0629 }
0630
0631 static void avs_path_pipeline_free(struct avs_dev *adev,
0632 struct avs_path_pipeline *ppl)
0633 {
0634 struct avs_path_binding *binding, *bsave;
0635 struct avs_path_module *mod, *save;
0636
0637 list_for_each_entry_safe(binding, bsave, &ppl->binding_list, node) {
0638 list_del(&binding->node);
0639 avs_path_binding_free(adev, binding);
0640 }
0641
0642 avs_dsp_delete_pipeline(adev, ppl->instance_id);
0643
0644
0645 list_for_each_entry_safe(mod, save, &ppl->mod_list, node) {
0646 avs_dsp_delete_module(adev, mod->module_id, mod->instance_id,
0647 mod->owner->instance_id,
0648 mod->template->core_id);
0649 avs_path_module_free(adev, mod);
0650 }
0651
0652 list_del(&ppl->node);
0653 kfree(ppl);
0654 }
0655
0656 static struct avs_path_pipeline *
0657 avs_path_pipeline_create(struct avs_dev *adev, struct avs_path *owner,
0658 struct avs_tplg_pipeline *template)
0659 {
0660 struct avs_path_pipeline *ppl;
0661 struct avs_tplg_pplcfg *cfg = template->cfg;
0662 struct avs_tplg_module *tmod;
0663 int ret, i;
0664
0665 ppl = kzalloc(sizeof(*ppl), GFP_KERNEL);
0666 if (!ppl)
0667 return ERR_PTR(-ENOMEM);
0668
0669 ppl->template = template;
0670 ppl->owner = owner;
0671 INIT_LIST_HEAD(&ppl->binding_list);
0672 INIT_LIST_HEAD(&ppl->mod_list);
0673 INIT_LIST_HEAD(&ppl->node);
0674
0675 ret = avs_dsp_create_pipeline(adev, cfg->req_size, cfg->priority,
0676 cfg->lp, cfg->attributes,
0677 &ppl->instance_id);
0678 if (ret) {
0679 dev_err(adev->dev, "error creating pipeline %d\n", ret);
0680 kfree(ppl);
0681 return ERR_PTR(ret);
0682 }
0683
0684 list_for_each_entry(tmod, &template->mod_list, node) {
0685 struct avs_path_module *mod;
0686
0687 mod = avs_path_module_create(adev, ppl, tmod);
0688 if (IS_ERR(mod)) {
0689 ret = PTR_ERR(mod);
0690 dev_err(adev->dev, "error creating module %d\n", ret);
0691 goto init_err;
0692 }
0693
0694 list_add_tail(&mod->node, &ppl->mod_list);
0695 }
0696
0697 for (i = 0; i < template->num_bindings; i++) {
0698 struct avs_path_binding *binding;
0699
0700 binding = avs_path_binding_create(adev, ppl, template->bindings[i]);
0701 if (IS_ERR(binding)) {
0702 ret = PTR_ERR(binding);
0703 dev_err(adev->dev, "error creating binding %d\n", ret);
0704 goto init_err;
0705 }
0706
0707 list_add_tail(&binding->node, &ppl->binding_list);
0708 }
0709
0710 return ppl;
0711
0712 init_err:
0713 avs_path_pipeline_free(adev, ppl);
0714 return ERR_PTR(ret);
0715 }
0716
0717 static int avs_path_init(struct avs_dev *adev, struct avs_path *path,
0718 struct avs_tplg_path *template, u32 dma_id)
0719 {
0720 struct avs_tplg_pipeline *tppl;
0721
0722 path->owner = adev;
0723 path->template = template;
0724 path->dma_id = dma_id;
0725 INIT_LIST_HEAD(&path->ppl_list);
0726 INIT_LIST_HEAD(&path->node);
0727
0728
0729 list_for_each_entry(tppl, &template->ppl_list, node) {
0730 struct avs_path_pipeline *ppl;
0731
0732 ppl = avs_path_pipeline_create(adev, path, tppl);
0733 if (IS_ERR(ppl))
0734 return PTR_ERR(ppl);
0735
0736 list_add_tail(&ppl->node, &path->ppl_list);
0737 }
0738
0739 spin_lock(&adev->path_list_lock);
0740 list_add_tail(&path->node, &adev->path_list);
0741 spin_unlock(&adev->path_list_lock);
0742
0743 return 0;
0744 }
0745
0746 static int avs_path_arm(struct avs_dev *adev, struct avs_path *path)
0747 {
0748 struct avs_path_pipeline *ppl;
0749 struct avs_path_binding *binding;
0750 int ret;
0751
0752 list_for_each_entry(ppl, &path->ppl_list, node) {
0753
0754
0755
0756
0757 list_for_each_entry(binding, &ppl->binding_list, node) {
0758 ret = avs_path_binding_arm(adev, binding);
0759 if (ret < 0)
0760 return ret;
0761 }
0762
0763 ret = avs_path_pipeline_arm(adev, ppl);
0764 if (ret < 0)
0765 return ret;
0766 }
0767
0768 return 0;
0769 }
0770
0771 static void avs_path_free_unlocked(struct avs_path *path)
0772 {
0773 struct avs_path_pipeline *ppl, *save;
0774
0775 spin_lock(&path->owner->path_list_lock);
0776 list_del(&path->node);
0777 spin_unlock(&path->owner->path_list_lock);
0778
0779 list_for_each_entry_safe(ppl, save, &path->ppl_list, node)
0780 avs_path_pipeline_free(path->owner, ppl);
0781
0782 kfree(path);
0783 }
0784
0785 static struct avs_path *avs_path_create_unlocked(struct avs_dev *adev, u32 dma_id,
0786 struct avs_tplg_path *template)
0787 {
0788 struct avs_path *path;
0789 int ret;
0790
0791 path = kzalloc(sizeof(*path), GFP_KERNEL);
0792 if (!path)
0793 return ERR_PTR(-ENOMEM);
0794
0795 ret = avs_path_init(adev, path, template, dma_id);
0796 if (ret < 0)
0797 goto err;
0798
0799 ret = avs_path_arm(adev, path);
0800 if (ret < 0)
0801 goto err;
0802
0803 path->state = AVS_PPL_STATE_INVALID;
0804 return path;
0805 err:
0806 avs_path_free_unlocked(path);
0807 return ERR_PTR(ret);
0808 }
0809
0810 void avs_path_free(struct avs_path *path)
0811 {
0812 struct avs_dev *adev = path->owner;
0813
0814 mutex_lock(&adev->path_mutex);
0815 avs_path_free_unlocked(path);
0816 mutex_unlock(&adev->path_mutex);
0817 }
0818
0819 struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id,
0820 struct avs_tplg_path_template *template,
0821 struct snd_pcm_hw_params *fe_params,
0822 struct snd_pcm_hw_params *be_params)
0823 {
0824 struct avs_tplg_path *variant;
0825 struct avs_path *path;
0826
0827 variant = avs_path_find_variant(adev, template, fe_params, be_params);
0828 if (!variant) {
0829 dev_err(adev->dev, "no matching variant found\n");
0830 return ERR_PTR(-ENOENT);
0831 }
0832
0833
0834 mutex_lock(&adev->path_mutex);
0835
0836 mutex_lock(&adev->comp_list_mutex);
0837
0838 path = avs_path_create_unlocked(adev, dma_id, variant);
0839
0840 mutex_unlock(&adev->comp_list_mutex);
0841 mutex_unlock(&adev->path_mutex);
0842
0843 return path;
0844 }
0845
0846 static int avs_path_bind_prepare(struct avs_dev *adev,
0847 struct avs_path_binding *binding)
0848 {
0849 const struct avs_audio_format *src_fmt, *sink_fmt;
0850 struct avs_tplg_module *tsource = binding->source->template;
0851 struct avs_path_module *source = binding->source;
0852 int ret;
0853
0854
0855
0856
0857
0858 if (!binding->source_pin)
0859 return 0;
0860 if (!guid_equal(&tsource->cfg_ext->type, &AVS_COPIER_MOD_UUID))
0861 return 0;
0862
0863 src_fmt = tsource->in_fmt;
0864 sink_fmt = binding->sink->template->in_fmt;
0865
0866 ret = avs_ipc_copier_set_sink_format(adev, source->module_id,
0867 source->instance_id, binding->source_pin,
0868 src_fmt, sink_fmt);
0869 if (ret) {
0870 dev_err(adev->dev, "config copier failed: %d\n", ret);
0871 return AVS_IPC_RET(ret);
0872 }
0873
0874 return 0;
0875 }
0876
0877 int avs_path_bind(struct avs_path *path)
0878 {
0879 struct avs_path_pipeline *ppl;
0880 struct avs_dev *adev = path->owner;
0881 int ret;
0882
0883 list_for_each_entry(ppl, &path->ppl_list, node) {
0884 struct avs_path_binding *binding;
0885
0886 list_for_each_entry(binding, &ppl->binding_list, node) {
0887 struct avs_path_module *source, *sink;
0888
0889 source = binding->source;
0890 sink = binding->sink;
0891
0892 ret = avs_path_bind_prepare(adev, binding);
0893 if (ret < 0)
0894 return ret;
0895
0896 ret = avs_ipc_bind(adev, source->module_id,
0897 source->instance_id, sink->module_id,
0898 sink->instance_id, binding->sink_pin,
0899 binding->source_pin);
0900 if (ret) {
0901 dev_err(adev->dev, "bind path failed: %d\n", ret);
0902 return AVS_IPC_RET(ret);
0903 }
0904 }
0905 }
0906
0907 return 0;
0908 }
0909
0910 int avs_path_unbind(struct avs_path *path)
0911 {
0912 struct avs_path_pipeline *ppl;
0913 struct avs_dev *adev = path->owner;
0914 int ret;
0915
0916 list_for_each_entry(ppl, &path->ppl_list, node) {
0917 struct avs_path_binding *binding;
0918
0919 list_for_each_entry(binding, &ppl->binding_list, node) {
0920 struct avs_path_module *source, *sink;
0921
0922 source = binding->source;
0923 sink = binding->sink;
0924
0925 ret = avs_ipc_unbind(adev, source->module_id,
0926 source->instance_id, sink->module_id,
0927 sink->instance_id, binding->sink_pin,
0928 binding->source_pin);
0929 if (ret) {
0930 dev_err(adev->dev, "unbind path failed: %d\n", ret);
0931 return AVS_IPC_RET(ret);
0932 }
0933 }
0934 }
0935
0936 return 0;
0937 }
0938
0939 int avs_path_reset(struct avs_path *path)
0940 {
0941 struct avs_path_pipeline *ppl;
0942 struct avs_dev *adev = path->owner;
0943 int ret;
0944
0945 if (path->state == AVS_PPL_STATE_RESET)
0946 return 0;
0947
0948 list_for_each_entry(ppl, &path->ppl_list, node) {
0949 ret = avs_ipc_set_pipeline_state(adev, ppl->instance_id,
0950 AVS_PPL_STATE_RESET);
0951 if (ret) {
0952 dev_err(adev->dev, "reset path failed: %d\n", ret);
0953 path->state = AVS_PPL_STATE_INVALID;
0954 return AVS_IPC_RET(ret);
0955 }
0956 }
0957
0958 path->state = AVS_PPL_STATE_RESET;
0959 return 0;
0960 }
0961
0962 int avs_path_pause(struct avs_path *path)
0963 {
0964 struct avs_path_pipeline *ppl;
0965 struct avs_dev *adev = path->owner;
0966 int ret;
0967
0968 if (path->state == AVS_PPL_STATE_PAUSED)
0969 return 0;
0970
0971 list_for_each_entry_reverse(ppl, &path->ppl_list, node) {
0972 ret = avs_ipc_set_pipeline_state(adev, ppl->instance_id,
0973 AVS_PPL_STATE_PAUSED);
0974 if (ret) {
0975 dev_err(adev->dev, "pause path failed: %d\n", ret);
0976 path->state = AVS_PPL_STATE_INVALID;
0977 return AVS_IPC_RET(ret);
0978 }
0979 }
0980
0981 path->state = AVS_PPL_STATE_PAUSED;
0982 return 0;
0983 }
0984
0985 int avs_path_run(struct avs_path *path, int trigger)
0986 {
0987 struct avs_path_pipeline *ppl;
0988 struct avs_dev *adev = path->owner;
0989 int ret;
0990
0991 if (path->state == AVS_PPL_STATE_RUNNING && trigger == AVS_TPLG_TRIGGER_AUTO)
0992 return 0;
0993
0994 list_for_each_entry(ppl, &path->ppl_list, node) {
0995 if (ppl->template->cfg->trigger != trigger)
0996 continue;
0997
0998 ret = avs_ipc_set_pipeline_state(adev, ppl->instance_id,
0999 AVS_PPL_STATE_RUNNING);
1000 if (ret) {
1001 dev_err(adev->dev, "run path failed: %d\n", ret);
1002 path->state = AVS_PPL_STATE_INVALID;
1003 return AVS_IPC_RET(ret);
1004 }
1005 }
1006
1007 path->state = AVS_PPL_STATE_RUNNING;
1008 return 0;
1009 }