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