• Home
  • Raw
  • Download

Lines Matching +full:primary +full:- +full:dai +full:- +full:link

1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
13 #include <sound/intel-nhlt.h>
14 #include "sof-priv.h"
15 #include "sof-audio.h"
16 #include "ipc4-priv.h"
17 #include "ipc4-topology.h"
146 [SOF_DAI_TOKENS] = {"DAI tokens", dai_tokens, ARRAY_SIZE(dai_tokens)},
177 pin_fmt[i].pin_index, fmt->sampling_frequency, fmt->bit_depth, fmt->ch_map, in sof_ipc4_dbg_audio_format()
178 fmt->ch_cfg, fmt->interleaving_style, fmt->fmt_cfg, in sof_ipc4_dbg_audio_format()
190 if (swidget->id != snd_soc_dapm_effect) { in sof_ipc4_get_input_pin_audio_fmt()
191 struct sof_ipc4_base_module_cfg *base = swidget->private; in sof_ipc4_get_input_pin_audio_fmt()
193 /* For non-process modules, base module config format is used for all input pins */ in sof_ipc4_get_input_pin_audio_fmt()
194 return &base->audio_fmt; in sof_ipc4_get_input_pin_audio_fmt()
197 process = swidget->private; in sof_ipc4_get_input_pin_audio_fmt()
203 if (process->init_config != SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) in sof_ipc4_get_input_pin_audio_fmt()
204 return &process->base_config.audio_fmt; in sof_ipc4_get_input_pin_audio_fmt()
206 base_cfg_ext = process->base_config_ext; in sof_ipc4_get_input_pin_audio_fmt()
212 for (i = 0; i < base_cfg_ext->num_input_pin_fmts; i++) { in sof_ipc4_get_input_pin_audio_fmt()
213 struct sof_ipc4_pin_format *pin_format = &base_cfg_ext->pin_formats[i]; in sof_ipc4_get_input_pin_audio_fmt()
215 if (pin_format->pin_index == pin_index) in sof_ipc4_get_input_pin_audio_fmt()
216 return &pin_format->audio_fmt; in sof_ipc4_get_input_pin_audio_fmt()
223 * sof_ipc4_get_audio_fmt - get available audio formats from swidget->tuples
241 SOF_AUDIO_FMT_NUM_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
242 swidget->num_tuples, sizeof(*available_fmt), 1); in sof_ipc4_get_audio_fmt()
244 dev_err(scomp->dev, "Failed to parse audio format token count\n"); in sof_ipc4_get_audio_fmt()
248 if (!available_fmt->num_input_formats && !available_fmt->num_output_formats) { in sof_ipc4_get_audio_fmt()
249 dev_err(scomp->dev, "No input/output pin formats set in topology\n"); in sof_ipc4_get_audio_fmt()
250 return -EINVAL; in sof_ipc4_get_audio_fmt()
253 dev_dbg(scomp->dev, in sof_ipc4_get_audio_fmt()
255 available_fmt->num_input_formats, available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
258 ret = sof_update_ipc_object(scomp, module_base_cfg, SOF_COMP_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
259 swidget->num_tuples, sizeof(*module_base_cfg), 1); in sof_ipc4_get_audio_fmt()
261 dev_err(scomp->dev, "parse comp tokens for %s failed, error: %d\n", in sof_ipc4_get_audio_fmt()
262 swidget->widget->name, ret); in sof_ipc4_get_audio_fmt()
266 dev_dbg(scomp->dev, "widget %s: is_pages: %d\n", swidget->widget->name, in sof_ipc4_get_audio_fmt()
267 module_base_cfg->is_pages); in sof_ipc4_get_audio_fmt()
269 if (available_fmt->num_input_formats) { in sof_ipc4_get_audio_fmt()
270 in_format = kcalloc(available_fmt->num_input_formats, in sof_ipc4_get_audio_fmt()
273 return -ENOMEM; in sof_ipc4_get_audio_fmt()
274 available_fmt->input_pin_fmts = in_format; in sof_ipc4_get_audio_fmt()
277 SOF_IN_AUDIO_FORMAT_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
278 swidget->num_tuples, sizeof(*in_format), in sof_ipc4_get_audio_fmt()
279 available_fmt->num_input_formats); in sof_ipc4_get_audio_fmt()
281 dev_err(scomp->dev, "parse input audio fmt tokens failed %d\n", ret); in sof_ipc4_get_audio_fmt()
285 dev_dbg(scomp->dev, "Input audio formats for %s\n", swidget->widget->name); in sof_ipc4_get_audio_fmt()
286 sof_ipc4_dbg_audio_format(scomp->dev, in_format, in sof_ipc4_get_audio_fmt()
287 available_fmt->num_input_formats); in sof_ipc4_get_audio_fmt()
290 if (available_fmt->num_output_formats) { in sof_ipc4_get_audio_fmt()
291 out_format = kcalloc(available_fmt->num_output_formats, sizeof(*out_format), in sof_ipc4_get_audio_fmt()
294 ret = -ENOMEM; in sof_ipc4_get_audio_fmt()
299 SOF_OUT_AUDIO_FORMAT_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
300 swidget->num_tuples, sizeof(*out_format), in sof_ipc4_get_audio_fmt()
301 available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
303 dev_err(scomp->dev, "parse output audio fmt tokens failed\n"); in sof_ipc4_get_audio_fmt()
307 available_fmt->output_pin_fmts = out_format; in sof_ipc4_get_audio_fmt()
308 dev_dbg(scomp->dev, "Output audio formats for %s\n", swidget->widget->name); in sof_ipc4_get_audio_fmt()
309 sof_ipc4_dbg_audio_format(scomp->dev, out_format, in sof_ipc4_get_audio_fmt()
310 available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
319 available_fmt->input_pin_fmts = NULL; in sof_ipc4_get_audio_fmt()
327 kfree(available_fmt->output_pin_fmts); in sof_ipc4_free_audio_fmt()
328 available_fmt->output_pin_fmts = NULL; in sof_ipc4_free_audio_fmt()
329 kfree(available_fmt->input_pin_fmts); in sof_ipc4_free_audio_fmt()
330 available_fmt->input_pin_fmts = NULL; in sof_ipc4_free_audio_fmt()
335 kfree(swidget->private); in sof_ipc4_widget_free_comp_pipeline()
340 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_set_module_info()
343 swidget->module_info = sof_ipc4_find_module_by_uuid(sdev, &swidget->uuid); in sof_ipc4_widget_set_module_info()
345 if (swidget->module_info) in sof_ipc4_widget_set_module_info()
348 dev_err(sdev->dev, "failed to find module info for widget %s with UUID %pUL\n", in sof_ipc4_widget_set_module_info()
349 swidget->widget->name, &swidget->uuid); in sof_ipc4_widget_set_module_info()
350 return -EINVAL; in sof_ipc4_widget_set_module_info()
363 fw_module = swidget->module_info; in sof_ipc4_widget_setup_msg()
365 msg->primary = fw_module->man4_module_entry.id; in sof_ipc4_widget_setup_msg()
366 msg->primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_INIT_INSTANCE); in sof_ipc4_widget_setup_msg()
367 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_widget_setup_msg()
368 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_widget_setup_msg()
370 msg->extension = SOF_IPC4_MOD_EXT_CORE_ID(swidget->core); in sof_ipc4_widget_setup_msg()
372 type = (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_DP) ? 1 : 0; in sof_ipc4_widget_setup_msg()
373 msg->extension |= SOF_IPC4_MOD_EXT_DOMAIN(type); in sof_ipc4_widget_setup_msg()
380 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_update_kcontrol_module_id()
382 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_update_kcontrol_module_id()
386 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { in sof_ipc4_widget_update_kcontrol_module_id()
387 if (scontrol->comp_id == swidget->comp_id) { in sof_ipc4_widget_update_kcontrol_module_id()
388 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; in sof_ipc4_widget_update_kcontrol_module_id()
389 struct sof_ipc4_msg *msg = &cdata->msg; in sof_ipc4_widget_update_kcontrol_module_id()
391 msg->primary |= fw_module->man4_module_entry.id; in sof_ipc4_widget_update_kcontrol_module_id()
399 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_pcm()
406 return -ENOMEM; in sof_ipc4_widget_setup_pcm()
408 swidget->private = ipc4_copier; in sof_ipc4_widget_setup_pcm()
409 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_setup_pcm()
411 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_pcm()
414 &ipc4_copier->data.base_config); in sof_ipc4_widget_setup_pcm()
419 * This callback is used by host copier and module-to-module copier, in sof_ipc4_widget_setup_pcm()
422 if (!WIDGET_IS_AIF(swidget->id)) in sof_ipc4_widget_setup_pcm()
426 SOF_COPIER_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_pcm()
427 swidget->num_tuples, sizeof(node_type), 1); in sof_ipc4_widget_setup_pcm()
430 dev_err(scomp->dev, "parse host copier node type token failed %d\n", in sof_ipc4_widget_setup_pcm()
434 dev_dbg(scomp->dev, "host copier '%s' node_type %u\n", swidget->widget->name, node_type); in sof_ipc4_widget_setup_pcm()
437 ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); in sof_ipc4_widget_setup_pcm()
438 if (!ipc4_copier->gtw_attr) { in sof_ipc4_widget_setup_pcm()
439 ret = -ENOMEM; in sof_ipc4_widget_setup_pcm()
443 ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; in sof_ipc4_widget_setup_pcm()
444 ipc4_copier->data.gtw_cfg.config_length = in sof_ipc4_widget_setup_pcm()
447 switch (swidget->id) { in sof_ipc4_widget_setup_pcm()
450 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); in sof_ipc4_widget_setup_pcm()
453 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID; in sof_ipc4_widget_setup_pcm()
454 ipc4_copier->ipc_config_size = 0; in sof_ipc4_widget_setup_pcm()
457 dev_err(scomp->dev, "invalid widget type %d\n", swidget->id); in sof_ipc4_widget_setup_pcm()
458 ret = -EINVAL; in sof_ipc4_widget_setup_pcm()
463 ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg); in sof_ipc4_widget_setup_pcm()
470 kfree(ipc4_copier->gtw_attr); in sof_ipc4_widget_setup_pcm()
475 swidget->private = NULL; in sof_ipc4_widget_setup_pcm()
481 struct sof_ipc4_copier *ipc4_copier = swidget->private; in sof_ipc4_widget_free_comp_pcm()
487 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_free_comp_pcm()
488 kfree(available_fmt->output_pin_fmts); in sof_ipc4_widget_free_comp_pcm()
489 kfree(ipc4_copier->gtw_attr); in sof_ipc4_widget_free_comp_pcm()
491 swidget->private = NULL; in sof_ipc4_widget_free_comp_pcm()
497 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_dai()
498 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_setup_comp_dai() local
507 return -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
509 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_setup_comp_dai()
511 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_dai()
514 &ipc4_copier->data.base_config); in sof_ipc4_widget_setup_comp_dai()
519 SOF_COPIER_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_dai()
520 swidget->num_tuples, sizeof(node_type), 1); in sof_ipc4_widget_setup_comp_dai()
522 dev_err(scomp->dev, "parse dai node type failed %d\n", ret); in sof_ipc4_widget_setup_comp_dai()
527 SOF_DAI_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_dai()
528 swidget->num_tuples, sizeof(u32), 1); in sof_ipc4_widget_setup_comp_dai()
530 dev_err(scomp->dev, "parse dai copier node token failed %d\n", ret); in sof_ipc4_widget_setup_comp_dai()
534 dev_dbg(scomp->dev, "dai %s node_type %u dai_type %u dai_index %d\n", swidget->widget->name, in sof_ipc4_widget_setup_comp_dai()
535 node_type, ipc4_copier->dai_type, ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
537 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); in sof_ipc4_widget_setup_comp_dai()
539 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_setup_comp_dai()
540 pipeline = pipe_widget->private; in sof_ipc4_widget_setup_comp_dai()
541 if (pipeline->use_chain_dma && ipc4_copier->dai_type != SOF_DAI_INTEL_HDA) { in sof_ipc4_widget_setup_comp_dai()
542 dev_err(scomp->dev, in sof_ipc4_widget_setup_comp_dai()
543 "Bad DAI type '%d', Chained DMA is only supported by HDA DAIs (%d).\n", in sof_ipc4_widget_setup_comp_dai()
544 ipc4_copier->dai_type, SOF_DAI_INTEL_HDA); in sof_ipc4_widget_setup_comp_dai()
545 ret = -ENODEV; in sof_ipc4_widget_setup_comp_dai()
549 switch (ipc4_copier->dai_type) { in sof_ipc4_widget_setup_comp_dai()
558 snd_soc_dapm_widget_for_each_source_path(swidget->widget, p) in sof_ipc4_widget_setup_comp_dai()
561 if (swidget->id == snd_soc_dapm_dai_in && src_num == 0) { in sof_ipc4_widget_setup_comp_dai()
565 * It is fine to call kfree(ipc4_copier->copier_config) since in sof_ipc4_widget_setup_comp_dai()
566 * ipc4_copier->copier_config is null. in sof_ipc4_widget_setup_comp_dai()
574 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
578 list_for_each_entry(w, &sdev->widget_list, list) { in sof_ipc4_widget_setup_comp_dai()
579 if (w->widget->sname && in sof_ipc4_widget_setup_comp_dai()
580 strcmp(w->widget->sname, swidget->widget->sname)) in sof_ipc4_widget_setup_comp_dai()
583 blob->alh_cfg.device_count++; in sof_ipc4_widget_setup_comp_dai()
586 ipc4_copier->copier_config = (uint32_t *)blob; in sof_ipc4_widget_setup_comp_dai()
587 ipc4_copier->data.gtw_cfg.config_length = sizeof(*blob) >> 2; in sof_ipc4_widget_setup_comp_dai()
591 /* set SSP DAI index as the node_id */ in sof_ipc4_widget_setup_comp_dai()
592 ipc4_copier->data.gtw_cfg.node_id |= in sof_ipc4_widget_setup_comp_dai()
593 SOF_IPC4_NODE_INDEX_INTEL_SSP(ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
596 /* set DMIC DAI index as the node_id */ in sof_ipc4_widget_setup_comp_dai()
597 ipc4_copier->data.gtw_cfg.node_id |= in sof_ipc4_widget_setup_comp_dai()
598 SOF_IPC4_NODE_INDEX_INTEL_DMIC(ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
601 ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); in sof_ipc4_widget_setup_comp_dai()
602 if (!ipc4_copier->gtw_attr) { in sof_ipc4_widget_setup_comp_dai()
603 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
607 ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; in sof_ipc4_widget_setup_comp_dai()
608 ipc4_copier->data.gtw_cfg.config_length = in sof_ipc4_widget_setup_comp_dai()
613 dai->scomp = scomp; in sof_ipc4_widget_setup_comp_dai()
614 dai->private = ipc4_copier; in sof_ipc4_widget_setup_comp_dai()
617 ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg); in sof_ipc4_widget_setup_comp_dai()
624 kfree(ipc4_copier->copier_config); in sof_ipc4_widget_setup_comp_dai()
629 dai->private = NULL; in sof_ipc4_widget_setup_comp_dai()
630 dai->scomp = NULL; in sof_ipc4_widget_setup_comp_dai()
637 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_free_comp_dai() local
640 if (!dai) in sof_ipc4_widget_free_comp_dai()
643 if (!dai->private) { in sof_ipc4_widget_free_comp_dai()
644 kfree(dai); in sof_ipc4_widget_free_comp_dai()
645 swidget->private = NULL; in sof_ipc4_widget_free_comp_dai()
649 ipc4_copier = dai->private; in sof_ipc4_widget_free_comp_dai()
650 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_free_comp_dai()
652 kfree(available_fmt->output_pin_fmts); in sof_ipc4_widget_free_comp_dai()
653 if (ipc4_copier->dai_type != SOF_DAI_INTEL_SSP && in sof_ipc4_widget_free_comp_dai()
654 ipc4_copier->dai_type != SOF_DAI_INTEL_DMIC) in sof_ipc4_widget_free_comp_dai()
655 kfree(ipc4_copier->copier_config); in sof_ipc4_widget_free_comp_dai()
656 kfree(dai->private); in sof_ipc4_widget_free_comp_dai()
657 kfree(dai); in sof_ipc4_widget_free_comp_dai()
658 swidget->private = NULL; in sof_ipc4_widget_free_comp_dai()
663 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_pipeline()
665 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_pipeline()
670 return -ENOMEM; in sof_ipc4_widget_setup_comp_pipeline()
672 ret = sof_update_ipc_object(scomp, pipeline, SOF_SCHED_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_pipeline()
673 swidget->num_tuples, sizeof(*pipeline), 1); in sof_ipc4_widget_setup_comp_pipeline()
675 dev_err(scomp->dev, "parsing scheduler tokens failed\n"); in sof_ipc4_widget_setup_comp_pipeline()
679 swidget->core = pipeline->core_id; in sof_ipc4_widget_setup_comp_pipeline()
680 spipe->core_mask |= BIT(pipeline->core_id); in sof_ipc4_widget_setup_comp_pipeline()
682 if (pipeline->use_chain_dma) { in sof_ipc4_widget_setup_comp_pipeline()
683 dev_dbg(scomp->dev, "Set up chain DMA for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_pipeline()
684 swidget->private = pipeline; in sof_ipc4_widget_setup_comp_pipeline()
689 ret = sof_update_ipc_object(scomp, swidget, SOF_PIPELINE_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_pipeline()
690 swidget->num_tuples, sizeof(*swidget), 1); in sof_ipc4_widget_setup_comp_pipeline()
692 dev_err(scomp->dev, "parsing pipeline tokens failed\n"); in sof_ipc4_widget_setup_comp_pipeline()
697 pipeline->priority = 0; in sof_ipc4_widget_setup_comp_pipeline()
699 dev_dbg(scomp->dev, "pipeline '%s': id %d, pri %d, core_id %u, lp mode %d\n", in sof_ipc4_widget_setup_comp_pipeline()
700 swidget->widget->name, swidget->pipeline_id, in sof_ipc4_widget_setup_comp_pipeline()
701 pipeline->priority, pipeline->core_id, pipeline->lp_mode); in sof_ipc4_widget_setup_comp_pipeline()
703 swidget->private = pipeline; in sof_ipc4_widget_setup_comp_pipeline()
705 pipeline->msg.primary = SOF_IPC4_GLB_PIPE_PRIORITY(pipeline->priority); in sof_ipc4_widget_setup_comp_pipeline()
706 pipeline->msg.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_CREATE_PIPELINE); in sof_ipc4_widget_setup_comp_pipeline()
707 pipeline->msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_widget_setup_comp_pipeline()
708 pipeline->msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG); in sof_ipc4_widget_setup_comp_pipeline()
710 pipeline->msg.extension = pipeline->lp_mode; in sof_ipc4_widget_setup_comp_pipeline()
711 pipeline->msg.extension |= SOF_IPC4_GLB_PIPE_EXT_CORE_ID(pipeline->core_id); in sof_ipc4_widget_setup_comp_pipeline()
712 pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED; in sof_ipc4_widget_setup_comp_pipeline()
722 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_pga()
728 return -ENOMEM; in sof_ipc4_widget_setup_comp_pga()
730 swidget->private = gain; in sof_ipc4_widget_setup_comp_pga()
732 gain->data.params.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK; in sof_ipc4_widget_setup_comp_pga()
733 gain->data.params.init_val = SOF_IPC4_VOL_ZERO_DB; in sof_ipc4_widget_setup_comp_pga()
735 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, &gain->data.base_config); in sof_ipc4_widget_setup_comp_pga()
739 ret = sof_update_ipc_object(scomp, &gain->data.params, SOF_GAIN_TOKENS, in sof_ipc4_widget_setup_comp_pga()
740 swidget->tuples, swidget->num_tuples, sizeof(gain->data), 1); in sof_ipc4_widget_setup_comp_pga()
742 dev_err(scomp->dev, "Parsing gain tokens failed\n"); in sof_ipc4_widget_setup_comp_pga()
746 dev_dbg(scomp->dev, in sof_ipc4_widget_setup_comp_pga()
748 swidget->widget->name, gain->data.params.curve_type, in sof_ipc4_widget_setup_comp_pga()
749 gain->data.params.curve_duration_l, gain->data.params.init_val); in sof_ipc4_widget_setup_comp_pga()
751 ret = sof_ipc4_widget_setup_msg(swidget, &gain->msg); in sof_ipc4_widget_setup_comp_pga()
759 sof_ipc4_free_audio_fmt(&gain->available_fmt); in sof_ipc4_widget_setup_comp_pga()
761 swidget->private = NULL; in sof_ipc4_widget_setup_comp_pga()
767 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_widget_free_comp_pga()
772 sof_ipc4_free_audio_fmt(&gain->available_fmt); in sof_ipc4_widget_free_comp_pga()
773 kfree(swidget->private); in sof_ipc4_widget_free_comp_pga()
774 swidget->private = NULL; in sof_ipc4_widget_free_comp_pga()
779 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_mixer()
783 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_mixer()
787 return -ENOMEM; in sof_ipc4_widget_setup_comp_mixer()
789 swidget->private = mixer; in sof_ipc4_widget_setup_comp_mixer()
791 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &mixer->available_fmt, in sof_ipc4_widget_setup_comp_mixer()
792 &mixer->base_config); in sof_ipc4_widget_setup_comp_mixer()
796 ret = sof_ipc4_widget_setup_msg(swidget, &mixer->msg); in sof_ipc4_widget_setup_comp_mixer()
802 sof_ipc4_free_audio_fmt(&mixer->available_fmt); in sof_ipc4_widget_setup_comp_mixer()
804 swidget->private = NULL; in sof_ipc4_widget_setup_comp_mixer()
810 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_src()
811 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_src()
815 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_src()
819 return -ENOMEM; in sof_ipc4_widget_setup_comp_src()
821 swidget->private = src; in sof_ipc4_widget_setup_comp_src()
823 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt, in sof_ipc4_widget_setup_comp_src()
824 &src->data.base_config); in sof_ipc4_widget_setup_comp_src()
828 ret = sof_update_ipc_object(scomp, &src->data, SOF_SRC_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_src()
829 swidget->num_tuples, sizeof(*src), 1); in sof_ipc4_widget_setup_comp_src()
831 dev_err(scomp->dev, "Parsing SRC tokens failed\n"); in sof_ipc4_widget_setup_comp_src()
835 spipe->core_mask |= BIT(swidget->core); in sof_ipc4_widget_setup_comp_src()
837 dev_dbg(scomp->dev, "SRC sink rate %d\n", src->data.sink_rate); in sof_ipc4_widget_setup_comp_src()
839 ret = sof_ipc4_widget_setup_msg(swidget, &src->msg); in sof_ipc4_widget_setup_comp_src()
845 sof_ipc4_free_audio_fmt(&src->available_fmt); in sof_ipc4_widget_setup_comp_src()
847 swidget->private = NULL; in sof_ipc4_widget_setup_comp_src()
853 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_widget_free_comp_src()
858 sof_ipc4_free_audio_fmt(&src->available_fmt); in sof_ipc4_widget_free_comp_src()
859 kfree(swidget->private); in sof_ipc4_widget_free_comp_src()
860 swidget->private = NULL; in sof_ipc4_widget_free_comp_src()
865 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_widget_free_comp_mixer()
870 sof_ipc4_free_audio_fmt(&mixer->available_fmt); in sof_ipc4_widget_free_comp_mixer()
871 kfree(swidget->private); in sof_ipc4_widget_free_comp_mixer()
872 swidget->private = NULL; in sof_ipc4_widget_free_comp_mixer()
880 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_process()
882 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_process()
889 return -ENOMEM; in sof_ipc4_widget_setup_comp_process()
891 swidget->private = process; in sof_ipc4_widget_setup_comp_process()
893 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &process->available_fmt, in sof_ipc4_widget_setup_comp_process()
894 &process->base_config); in sof_ipc4_widget_setup_comp_process()
898 ret = sof_ipc4_widget_setup_msg(swidget, &process->msg); in sof_ipc4_widget_setup_comp_process()
903 fw_module = swidget->module_info; in sof_ipc4_widget_setup_comp_process()
904 process->init_config = FIELD_GET(SOF_IPC4_MODULE_INIT_CONFIG_MASK, in sof_ipc4_widget_setup_comp_process()
905 fw_module->man4_module_entry.type); in sof_ipc4_widget_setup_comp_process()
907 process->ipc_config_size = sizeof(struct sof_ipc4_base_module_cfg); in sof_ipc4_widget_setup_comp_process()
910 if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) { in sof_ipc4_widget_setup_comp_process()
913 size_add(swidget->num_input_pins, in sof_ipc4_widget_setup_comp_process()
914 swidget->num_output_pins)); in sof_ipc4_widget_setup_comp_process()
918 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_process()
922 base_cfg_ext->num_input_pin_fmts = swidget->num_input_pins; in sof_ipc4_widget_setup_comp_process()
923 base_cfg_ext->num_output_pin_fmts = swidget->num_output_pins; in sof_ipc4_widget_setup_comp_process()
924 process->base_config_ext = base_cfg_ext; in sof_ipc4_widget_setup_comp_process()
925 process->base_config_ext_size = ext_size; in sof_ipc4_widget_setup_comp_process()
926 process->ipc_config_size += ext_size; in sof_ipc4_widget_setup_comp_process()
929 cfg = kzalloc(process->ipc_config_size, GFP_KERNEL); in sof_ipc4_widget_setup_comp_process()
931 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_process()
935 process->ipc_config_data = cfg; in sof_ipc4_widget_setup_comp_process()
940 spipe->core_mask |= BIT(swidget->core); in sof_ipc4_widget_setup_comp_process()
944 kfree(process->base_config_ext); in sof_ipc4_widget_setup_comp_process()
945 process->base_config_ext = NULL; in sof_ipc4_widget_setup_comp_process()
947 sof_ipc4_free_audio_fmt(&process->available_fmt); in sof_ipc4_widget_setup_comp_process()
950 swidget->private = NULL; in sof_ipc4_widget_setup_comp_process()
956 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_widget_free_comp_process()
961 kfree(process->ipc_config_data); in sof_ipc4_widget_free_comp_process()
962 kfree(process->base_config_ext); in sof_ipc4_widget_free_comp_process()
963 sof_ipc4_free_audio_fmt(&process->available_fmt); in sof_ipc4_widget_free_comp_process()
964 kfree(swidget->private); in sof_ipc4_widget_free_comp_process()
965 swidget->private = NULL; in sof_ipc4_widget_free_comp_process()
972 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_update_resource_usage()
978 ibs = base_config->ibs; in sof_ipc4_update_resource_usage()
979 bss = base_config->is_pages; in sof_ipc4_update_resource_usage()
984 if (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_LL) { in sof_ipc4_update_resource_usage()
998 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_update_resource_usage()
999 pipeline = pipe_widget->private; in sof_ipc4_update_resource_usage()
1000 pipeline->mem_usage += total; in sof_ipc4_update_resource_usage()
1002 /* Update base_config->cpc from the module manifest */ in sof_ipc4_update_resource_usage()
1006 dev_dbg(sdev->dev, "%s: ibs / obs: %u / %u, forcing cpc to 0 from %u\n", in sof_ipc4_update_resource_usage()
1007 swidget->widget->name, base_config->ibs, base_config->obs, in sof_ipc4_update_resource_usage()
1008 base_config->cpc); in sof_ipc4_update_resource_usage()
1009 base_config->cpc = 0; in sof_ipc4_update_resource_usage()
1011 dev_dbg(sdev->dev, "%s: ibs / obs / cpc: %u / %u / %u\n", in sof_ipc4_update_resource_usage()
1012 swidget->widget->name, base_config->ibs, base_config->obs, in sof_ipc4_update_resource_usage()
1013 base_config->cpc); in sof_ipc4_update_resource_usage()
1020 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_assign_instance_id()
1021 int max_instances = fw_module->man4_module_entry.instance_max_count; in sof_ipc4_widget_assign_instance_id()
1023 swidget->instance_id = ida_alloc_max(&fw_module->m_ida, max_instances, GFP_KERNEL); in sof_ipc4_widget_assign_instance_id()
1024 if (swidget->instance_id < 0) { in sof_ipc4_widget_assign_instance_id()
1025 dev_err(sdev->dev, "failed to assign instance id for widget %s", in sof_ipc4_widget_assign_instance_id()
1026 swidget->widget->name); in sof_ipc4_widget_assign_instance_id()
1027 return swidget->instance_id; in sof_ipc4_widget_assign_instance_id()
1040 int valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_update_hw_params()
1054 dev_err(sdev->dev, "invalid PCM valid_bits %d\n", valid_bits); in sof_ipc4_update_hw_params()
1055 return -EINVAL; in sof_ipc4_update_hw_params()
1062 rate = fmt->sampling_frequency; in sof_ipc4_update_hw_params()
1064 i->min = rate; in sof_ipc4_update_hw_params()
1065 i->max = rate; in sof_ipc4_update_hw_params()
1067 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_update_hw_params()
1069 i->min = channels; in sof_ipc4_update_hw_params()
1070 i->max = channels; in sof_ipc4_update_hw_params()
1083 rate = fmt->sampling_frequency; in sof_ipc4_is_single_format()
1084 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1085 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1092 _rate = fmt->sampling_frequency; in sof_ipc4_is_single_format()
1093 _channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1094 _valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1113 if (!available_fmt->num_output_formats) in sof_ipc4_init_output_audio_fmt()
1114 return -EINVAL; in sof_ipc4_init_output_audio_fmt()
1116 single_format = sof_ipc4_is_single_format(sdev, available_fmt->output_pin_fmts, in sof_ipc4_init_output_audio_fmt()
1117 available_fmt->num_output_formats); in sof_ipc4_init_output_audio_fmt()
1121 base_config->obs = available_fmt->output_pin_fmts[0].buffer_size; in sof_ipc4_init_output_audio_fmt()
1129 for (i = 0; i < available_fmt->num_output_formats; i++) { in sof_ipc4_init_output_audio_fmt()
1132 out_fmt = &available_fmt->output_pin_fmts[i].audio_fmt; in sof_ipc4_init_output_audio_fmt()
1133 _out_rate = out_fmt->sampling_frequency; in sof_ipc4_init_output_audio_fmt()
1134 _out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(out_fmt->fmt_cfg); in sof_ipc4_init_output_audio_fmt()
1135 _out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); in sof_ipc4_init_output_audio_fmt()
1139 base_config->obs = available_fmt->output_pin_fmts[i].buffer_size; in sof_ipc4_init_output_audio_fmt()
1144 return -EINVAL; in sof_ipc4_init_output_audio_fmt()
1157 dev_err(sdev->dev, "invalid pcm frame format %d\n", params_format(params)); in sof_ipc4_get_valid_bits()
1158 return -EINVAL; in sof_ipc4_get_valid_bits()
1168 struct sof_ipc4_pin_format *pin_fmts = available_fmt->input_pin_fmts; in sof_ipc4_init_input_audio_fmt()
1169 u32 pin_fmts_size = available_fmt->num_input_formats; in sof_ipc4_init_input_audio_fmt()
1177 if (!available_fmt->num_input_formats) { in sof_ipc4_init_input_audio_fmt()
1178 dev_err(sdev->dev, "no input formats for %s\n", swidget->widget->name); in sof_ipc4_init_input_audio_fmt()
1179 return -EINVAL; in sof_ipc4_init_input_audio_fmt()
1182 single_format = sof_ipc4_is_single_format(sdev, available_fmt->input_pin_fmts, in sof_ipc4_init_input_audio_fmt()
1183 available_fmt->num_input_formats); in sof_ipc4_init_input_audio_fmt()
1201 rate = fmt->sampling_frequency; in sof_ipc4_init_input_audio_fmt()
1202 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_init_input_audio_fmt()
1203 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_init_input_audio_fmt()
1206 dev_dbg(sdev->dev, "matched audio format index for %uHz, %ubit, %u channels: %d\n", in sof_ipc4_init_input_audio_fmt()
1213 dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n", in sof_ipc4_init_input_audio_fmt()
1215 return -EINVAL; in sof_ipc4_init_input_audio_fmt()
1220 if (available_fmt->num_input_formats && i < available_fmt->num_input_formats) { in sof_ipc4_init_input_audio_fmt()
1221 memcpy(&base_config->audio_fmt, &available_fmt->input_pin_fmts[i].audio_fmt, in sof_ipc4_init_input_audio_fmt()
1225 base_config->ibs = available_fmt->input_pin_fmts[i].buffer_size; in sof_ipc4_init_input_audio_fmt()
1227 dev_dbg(sdev->dev, "Init input audio formats for %s\n", swidget->widget->name); in sof_ipc4_init_input_audio_fmt()
1228 sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->input_pin_fmts[i], 1); in sof_ipc4_init_input_audio_fmt()
1241 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_unprepare_copier_module()
1242 pipeline = pipe_widget->private; in sof_ipc4_unprepare_copier_module()
1243 pipeline->mem_usage = 0; in sof_ipc4_unprepare_copier_module()
1245 if (WIDGET_IS_AIF(swidget->id) || swidget->id == snd_soc_dapm_buffer) { in sof_ipc4_unprepare_copier_module()
1246 if (pipeline->use_chain_dma) { in sof_ipc4_unprepare_copier_module()
1247 pipeline->msg.primary = 0; in sof_ipc4_unprepare_copier_module()
1248 pipeline->msg.extension = 0; in sof_ipc4_unprepare_copier_module()
1250 ipc4_copier = swidget->private; in sof_ipc4_unprepare_copier_module()
1251 } else if (WIDGET_IS_DAI(swidget->id)) { in sof_ipc4_unprepare_copier_module()
1252 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_unprepare_copier_module() local
1254 ipc4_copier = dai->private; in sof_ipc4_unprepare_copier_module()
1256 if (pipeline->use_chain_dma) { in sof_ipc4_unprepare_copier_module()
1258 * Preserve the DMA Link ID and clear other bits since in sof_ipc4_unprepare_copier_module()
1259 * the DMA Link ID is only configured once during in sof_ipc4_unprepare_copier_module()
1261 * re-configuration in sof_ipc4_unprepare_copier_module()
1263 pipeline->msg.primary &= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK; in sof_ipc4_unprepare_copier_module()
1264 pipeline->msg.extension = 0; in sof_ipc4_unprepare_copier_module()
1267 if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { in sof_ipc4_unprepare_copier_module()
1268 struct sof_ipc4_copier_data *copier_data = &ipc4_copier->data; in sof_ipc4_unprepare_copier_module()
1272 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; in sof_ipc4_unprepare_copier_module()
1273 if (blob->alh_cfg.device_count > 1) { in sof_ipc4_unprepare_copier_module()
1274 group_id = SOF_IPC4_NODE_INDEX(ipc4_copier->data.gtw_cfg.node_id) - in sof_ipc4_unprepare_copier_module()
1280 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_unprepare_copier_module()
1285 kfree(ipc4_copier->ipc_config_data); in sof_ipc4_unprepare_copier_module()
1286 ipc4_copier->ipc_config_data = NULL; in sof_ipc4_unprepare_copier_module()
1287 ipc4_copier->ipc_config_size = 0; in sof_ipc4_unprepare_copier_module()
1292 static int snd_sof_get_hw_config_params(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, in snd_sof_get_hw_config_params() argument
1301 /* get current hw_config from link */ in snd_sof_get_hw_config_params()
1302 list_for_each_entry(slink, &sdev->dai_link_list, list) { in snd_sof_get_hw_config_params()
1303 if (!strcmp(slink->link->name, dai->name)) { in snd_sof_get_hw_config_params()
1310 dev_err(sdev->dev, "%s: no DAI link found for DAI %s\n", __func__, dai->name); in snd_sof_get_hw_config_params()
1311 return -EINVAL; in snd_sof_get_hw_config_params()
1314 for (i = 0; i < slink->num_hw_configs; i++) { in snd_sof_get_hw_config_params()
1315 hw_config = &slink->hw_configs[i]; in snd_sof_get_hw_config_params()
1316 if (dai->current_config == le32_to_cpu(hw_config->id)) { in snd_sof_get_hw_config_params()
1323 dev_err(sdev->dev, "%s: no matching hw_config found for DAI %s\n", __func__, in snd_sof_get_hw_config_params()
1324 dai->name); in snd_sof_get_hw_config_params()
1325 return -EINVAL; in snd_sof_get_hw_config_params()
1328 *bit_depth = le32_to_cpu(hw_config->tdm_slot_width); in snd_sof_get_hw_config_params()
1329 *channel_count = le32_to_cpu(hw_config->tdm_slots); in snd_sof_get_hw_config_params()
1330 *sample_rate = le32_to_cpu(hw_config->fsync_rate); in snd_sof_get_hw_config_params()
1332 dev_dbg(sdev->dev, "sample rate: %d sample width: %d channels: %d\n", in snd_sof_get_hw_config_params()
1338 static int snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, in snd_sof_get_nhlt_endpoint_data() argument
1342 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in snd_sof_get_nhlt_endpoint_data()
1358 ret = snd_sof_get_hw_config_params(sdev, dai, &sample_rate, &channel_count, in snd_sof_get_nhlt_endpoint_data()
1367 dev_dbg(sdev->dev, "dai index %d nhlt type %d direction %d\n", in snd_sof_get_nhlt_endpoint_data()
1371 cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, dai_index, nhlt_type, in snd_sof_get_nhlt_endpoint_data()
1376 dev_err(sdev->dev, in snd_sof_get_nhlt_endpoint_data()
1379 return -EINVAL; in snd_sof_get_nhlt_endpoint_data()
1383 *len = cfg->size >> 2; in snd_sof_get_nhlt_endpoint_data()
1384 *dst = (u32 *)cfg->caps; in snd_sof_get_nhlt_endpoint_data()
1389 static int snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, in snd_sof_get_nhlt_endpoint_data() argument
1406 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_copier_is_single_format()
1413 _valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_copier_is_single_format()
1429 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_copier_module()
1434 struct snd_sof_dai *dai; in sof_ipc4_prepare_copier_module() local
1446 dev_dbg(sdev->dev, "copier %s, type %d", swidget->widget->name, swidget->id); in sof_ipc4_prepare_copier_module()
1448 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1458 SOF_COPIER_DEEP_BUFFER_TOKENS, swidget->tuples, in sof_ipc4_prepare_copier_module()
1459 swidget->num_tuples, sizeof(u32), 1); in sof_ipc4_prepare_copier_module()
1461 dev_err(scomp->dev, "Failed to parse deep buffer dma size for %s\n", in sof_ipc4_prepare_copier_module()
1462 swidget->widget->name); in sof_ipc4_prepare_copier_module()
1466 ipc4_copier = (struct sof_ipc4_copier *)swidget->private; in sof_ipc4_prepare_copier_module()
1467 gtw_attr = ipc4_copier->gtw_attr; in sof_ipc4_prepare_copier_module()
1468 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1469 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1471 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_prepare_copier_module()
1472 pipeline = pipe_widget->private; in sof_ipc4_prepare_copier_module()
1474 if (pipeline->use_chain_dma) { in sof_ipc4_prepare_copier_module()
1478 host_dma_id = platform_params->stream_tag - 1; in sof_ipc4_prepare_copier_module()
1479 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_HOST_ID(host_dma_id); in sof_ipc4_prepare_copier_module()
1483 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK; in sof_ipc4_prepare_copier_module()
1493 pipeline->msg.extension |= SOF_IPC4_GLB_EXT_CHAIN_DMA_FIFO_SIZE(fifo_size); in sof_ipc4_prepare_copier_module()
1499 copier_data->gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID; in sof_ipc4_prepare_copier_module()
1513 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_prepare_copier_module()
1514 copier_data->gtw_cfg.node_id |= in sof_ipc4_prepare_copier_module()
1515 SOF_IPC4_NODE_INDEX(platform_params->stream_tag - 1); in sof_ipc4_prepare_copier_module()
1518 gtw_attr->lp_buffer_alloc = pipeline->lp_mode; in sof_ipc4_prepare_copier_module()
1524 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_prepare_copier_module()
1525 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_prepare_copier_module()
1527 if (pipeline->use_chain_dma) in sof_ipc4_prepare_copier_module()
1530 dai = swidget->private; in sof_ipc4_prepare_copier_module()
1532 ipc4_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_prepare_copier_module()
1533 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1534 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1538 * output formats is typically limited to just 1 for the DAI copiers. But when there in sof_ipc4_prepare_copier_module()
1539 * is no format conversion, the DAI copiers input format must match that of the in sof_ipc4_prepare_copier_module()
1547 ret = snd_sof_get_nhlt_endpoint_data(sdev, dai, fe_params, ipc4_copier->dai_index, in sof_ipc4_prepare_copier_module()
1548 ipc4_copier->dai_type, dir, in sof_ipc4_prepare_copier_module()
1549 &ipc4_copier->copier_config, in sof_ipc4_prepare_copier_module()
1550 &copier_data->gtw_cfg.config_length); in sof_ipc4_prepare_copier_module()
1558 ipc4_copier = (struct sof_ipc4_copier *)swidget->private; in sof_ipc4_prepare_copier_module()
1559 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1560 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1566 dev_err(sdev->dev, "unsupported type %d for copier %s", in sof_ipc4_prepare_copier_module()
1567 swidget->id, swidget->widget->name); in sof_ipc4_prepare_copier_module()
1568 return -EINVAL; in sof_ipc4_prepare_copier_module()
1572 ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &copier_data->base_config, ref_params, in sof_ipc4_prepare_copier_module()
1579 available_fmt->output_pin_fmts, in sof_ipc4_prepare_copier_module()
1580 available_fmt->num_output_formats); in sof_ipc4_prepare_copier_module()
1581 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1588 in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; in sof_ipc4_prepare_copier_module()
1589 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_copier_module()
1590 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
1594 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
1612 return -EINVAL; in sof_ipc4_prepare_copier_module()
1622 out_fmt = &available_fmt->output_pin_fmts[0].audio_fmt; in sof_ipc4_prepare_copier_module()
1624 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
1627 dev_dbg(sdev->dev, "copier %s: reference output rate %d, channels %d valid_bits %d\n", in sof_ipc4_prepare_copier_module()
1628 swidget->widget->name, out_ref_rate, out_ref_channels, out_ref_valid_bits); in sof_ipc4_prepare_copier_module()
1630 output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &copier_data->base_config, in sof_ipc4_prepare_copier_module()
1634 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_copier_module()
1635 swidget->widget->name); in sof_ipc4_prepare_copier_module()
1646 memcpy(&copier_data->out_format, in sof_ipc4_prepare_copier_module()
1647 &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt, in sof_ipc4_prepare_copier_module()
1649 dev_dbg(sdev->dev, "Output audio format for %s\n", swidget->widget->name); in sof_ipc4_prepare_copier_module()
1650 sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->output_pin_fmts[output_fmt_index], 1); in sof_ipc4_prepare_copier_module()
1652 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1658 * That's why only ALH dai's blob is set after sof_ipc4_init_input_audio_fmt in sof_ipc4_prepare_copier_module()
1660 if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { in sof_ipc4_prepare_copier_module()
1672 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; in sof_ipc4_prepare_copier_module()
1674 blob->gw_attr.lp_buffer_alloc = 0; in sof_ipc4_prepare_copier_module()
1677 ch_map = copier_data->base_config.audio_fmt.ch_map; in sof_ipc4_prepare_copier_module()
1686 step = ch_count / blob->alh_cfg.device_count; in sof_ipc4_prepare_copier_module()
1687 mask = GENMASK(step - 1, 0); in sof_ipc4_prepare_copier_module()
1689 * Set each gtw_cfg.node_id to blob->alh_cfg.mapping[] in sof_ipc4_prepare_copier_module()
1693 list_for_each_entry(w, &sdev->widget_list, list) { in sof_ipc4_prepare_copier_module()
1694 if (w->widget->sname && in sof_ipc4_prepare_copier_module()
1695 strcmp(w->widget->sname, swidget->widget->sname)) in sof_ipc4_prepare_copier_module()
1698 dai = w->private; in sof_ipc4_prepare_copier_module()
1699 alh_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_prepare_copier_module()
1700 alh_data = &alh_copier->data; in sof_ipc4_prepare_copier_module()
1701 blob->alh_cfg.mapping[i].device = alh_data->gtw_cfg.node_id; in sof_ipc4_prepare_copier_module()
1707 * two DAI's. in sof_ipc4_prepare_copier_module()
1713 if (w->id == snd_soc_dapm_dai_in) in sof_ipc4_prepare_copier_module()
1714 blob->alh_cfg.mapping[i].channel_mask = ch_mask; in sof_ipc4_prepare_copier_module()
1716 blob->alh_cfg.mapping[i].channel_mask = mask << (step * i); in sof_ipc4_prepare_copier_module()
1720 if (blob->alh_cfg.device_count > 1) { in sof_ipc4_prepare_copier_module()
1723 group_id = ida_alloc_max(&alh_group_ida, ALH_MULTI_GTW_COUNT - 1, in sof_ipc4_prepare_copier_module()
1729 /* add multi-gateway base */ in sof_ipc4_prepare_copier_module()
1731 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_prepare_copier_module()
1732 copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(group_id); in sof_ipc4_prepare_copier_module()
1739 ret = sof_ipc4_update_hw_params(sdev, pipeline_params, &copier_data->out_format); in sof_ipc4_prepare_copier_module()
1748 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1750 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
1751 SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.ibs; in sof_ipc4_prepare_copier_module()
1754 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
1756 copier_data->base_config.ibs; in sof_ipc4_prepare_copier_module()
1760 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
1761 SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.obs; in sof_ipc4_prepare_copier_module()
1767 data = &ipc4_copier->copier_config; in sof_ipc4_prepare_copier_module()
1768 ipc_config_size = &ipc4_copier->ipc_config_size; in sof_ipc4_prepare_copier_module()
1769 ipc_config_data = &ipc4_copier->ipc_config_data; in sof_ipc4_prepare_copier_module()
1772 gtw_cfg_config_length = copier_data->gtw_cfg.config_length * 4; in sof_ipc4_prepare_copier_module()
1775 if (ipc4_copier->dma_config_tlv.type == SOF_IPC4_GTW_DMA_CONFIG_ID && in sof_ipc4_prepare_copier_module()
1776 ipc4_copier->dma_config_tlv.length) { in sof_ipc4_prepare_copier_module()
1777 dma_config_tlv_size = sizeof(ipc4_copier->dma_config_tlv) + in sof_ipc4_prepare_copier_module()
1778 ipc4_copier->dma_config_tlv.dma_config.dma_priv_config_size; in sof_ipc4_prepare_copier_module()
1781 if (dma_config_tlv_size != ipc4_copier->dma_config_tlv.length + in sof_ipc4_prepare_copier_module()
1783 dev_err(sdev->dev, "Invalid configuration, TLV size %d length %d\n", in sof_ipc4_prepare_copier_module()
1784 dma_config_tlv_size, ipc4_copier->dma_config_tlv.length); in sof_ipc4_prepare_copier_module()
1785 return -EINVAL; in sof_ipc4_prepare_copier_module()
1791 copier_data->gtw_cfg.config_length += dma_config_tlv_size / 4; in sof_ipc4_prepare_copier_module()
1794 dev_dbg(sdev->dev, "copier %s, IPC size is %d", swidget->widget->name, ipc_size); in sof_ipc4_prepare_copier_module()
1798 return -ENOMEM; in sof_ipc4_prepare_copier_module()
1803 sof_ipc4_update_resource_usage(sdev, swidget, &copier_data->base_config); in sof_ipc4_prepare_copier_module()
1815 &ipc4_copier->dma_config_tlv, dma_config_tlv_size); in sof_ipc4_prepare_copier_module()
1821 copier_data->gtw_cfg.config_length = gtw_cfg_config_length / 4; in sof_ipc4_prepare_copier_module()
1831 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_gain_module()
1833 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_prepare_gain_module()
1834 struct sof_ipc4_available_audio_format *available_fmt = &gain->available_fmt; in sof_ipc4_prepare_gain_module()
1839 ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &gain->data.base_config, in sof_ipc4_prepare_gain_module()
1844 in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; in sof_ipc4_prepare_gain_module()
1845 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_gain_module()
1846 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_gain_module()
1847 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_gain_module()
1849 ret = sof_ipc4_init_output_audio_fmt(sdev, &gain->data.base_config, available_fmt, in sof_ipc4_prepare_gain_module()
1852 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_gain_module()
1853 swidget->widget->name); in sof_ipc4_prepare_gain_module()
1858 sof_ipc4_update_resource_usage(sdev, swidget, &gain->data.base_config); in sof_ipc4_prepare_gain_module()
1868 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_mixer_module()
1870 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_prepare_mixer_module()
1871 struct sof_ipc4_available_audio_format *available_fmt = &mixer->available_fmt; in sof_ipc4_prepare_mixer_module()
1876 ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &mixer->base_config, in sof_ipc4_prepare_mixer_module()
1881 in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; in sof_ipc4_prepare_mixer_module()
1882 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_mixer_module()
1883 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_mixer_module()
1884 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_mixer_module()
1886 ret = sof_ipc4_init_output_audio_fmt(sdev, &mixer->base_config, available_fmt, in sof_ipc4_prepare_mixer_module()
1889 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_mixer_module()
1890 swidget->widget->name); in sof_ipc4_prepare_mixer_module()
1895 sof_ipc4_update_resource_usage(sdev, swidget, &mixer->base_config); in sof_ipc4_prepare_mixer_module()
1905 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_src_module()
1907 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_prepare_src_module()
1908 struct sof_ipc4_available_audio_format *available_fmt = &src->available_fmt; in sof_ipc4_prepare_src_module()
1914 input_format_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, &src->data.base_config, in sof_ipc4_prepare_src_module()
1921 * format, which is restricted to only deal with DAI's with a single format for now. in sof_ipc4_prepare_src_module()
1923 if (dir == SNDRV_PCM_STREAM_PLAYBACK && available_fmt->num_output_formats > 1) { in sof_ipc4_prepare_src_module()
1924 dev_err(sdev->dev, "Invalid number of output formats: %d for SRC %s\n", in sof_ipc4_prepare_src_module()
1925 available_fmt->num_output_formats, swidget->widget->name); in sof_ipc4_prepare_src_module()
1926 return -EINVAL; in sof_ipc4_prepare_src_module()
1933 in_audio_fmt = &available_fmt->input_pin_fmts[input_format_index].audio_fmt; in sof_ipc4_prepare_src_module()
1934 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_audio_fmt->fmt_cfg); in sof_ipc4_prepare_src_module()
1935 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_audio_fmt->fmt_cfg); in sof_ipc4_prepare_src_module()
1944 output_format_index = sof_ipc4_init_output_audio_fmt(sdev, &src->data.base_config, in sof_ipc4_prepare_src_module()
1948 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_src_module()
1949 swidget->widget->name); in sof_ipc4_prepare_src_module()
1954 sof_ipc4_update_resource_usage(sdev, swidget, &src->data.base_config); in sof_ipc4_prepare_src_module()
1956 out_audio_fmt = &available_fmt->output_pin_fmts[output_format_index].audio_fmt; in sof_ipc4_prepare_src_module()
1957 src->data.sink_rate = out_audio_fmt->sampling_frequency; in sof_ipc4_prepare_src_module()
1966 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_process_set_pin_formats()
1967 struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext; in sof_ipc4_process_set_pin_formats()
1968 struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt; in sof_ipc4_process_set_pin_formats()
1970 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_process_set_pin_formats()
1977 num_pins = swidget->num_input_pins; in sof_ipc4_process_set_pin_formats()
1978 format_list_to_search = available_fmt->input_pin_fmts; in sof_ipc4_process_set_pin_formats()
1979 format_list_count = available_fmt->num_input_formats; in sof_ipc4_process_set_pin_formats()
1981 num_pins = swidget->num_output_pins; in sof_ipc4_process_set_pin_formats()
1982 pin_format_offset = swidget->num_input_pins; in sof_ipc4_process_set_pin_formats()
1983 format_list_to_search = available_fmt->output_pin_fmts; in sof_ipc4_process_set_pin_formats()
1984 format_list_count = available_fmt->num_output_formats; in sof_ipc4_process_set_pin_formats()
1988 pin_format = &base_cfg_ext->pin_formats[i]; in sof_ipc4_process_set_pin_formats()
1993 pin_format->buffer_size = process->base_config.ibs; in sof_ipc4_process_set_pin_formats()
1994 pin_format->audio_fmt = process->base_config.audio_fmt; in sof_ipc4_process_set_pin_formats()
1996 pin_format->buffer_size = process->base_config.obs; in sof_ipc4_process_set_pin_formats()
1997 pin_format->audio_fmt = process->output_format; in sof_ipc4_process_set_pin_formats()
2010 if (pin_format_item->pin_index == i - pin_format_offset) { in sof_ipc4_process_set_pin_formats()
2017 dev_err(scomp->dev, "%s pin %d format not found for %s\n", in sof_ipc4_process_set_pin_formats()
2019 i - pin_format_offset, swidget->widget->name); in sof_ipc4_process_set_pin_formats()
2020 return -EINVAL; in sof_ipc4_process_set_pin_formats()
2046 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_process_module()
2048 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_prepare_process_module()
2049 struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt; in sof_ipc4_prepare_process_module()
2052 void *cfg = process->ipc_config_data; in sof_ipc4_prepare_process_module()
2056 ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &process->base_config, in sof_ipc4_prepare_process_module()
2061 in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; in sof_ipc4_prepare_process_module()
2062 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_process_module()
2063 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_process_module()
2064 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_process_module()
2066 output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &process->base_config, in sof_ipc4_prepare_process_module()
2069 if (output_fmt_index < 0 && available_fmt->num_output_formats) { in sof_ipc4_prepare_process_module()
2070 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_process_module()
2071 swidget->widget->name); in sof_ipc4_prepare_process_module()
2076 if (available_fmt->num_output_formats && in sof_ipc4_prepare_process_module()
2077 output_fmt_index < available_fmt->num_output_formats && in sof_ipc4_prepare_process_module()
2078 !available_fmt->output_pin_fmts[output_fmt_index].pin_index) { in sof_ipc4_prepare_process_module()
2079 memcpy(&process->output_format, in sof_ipc4_prepare_process_module()
2080 &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt, in sof_ipc4_prepare_process_module()
2084 ret = sof_ipc4_update_hw_params(sdev, pipeline_params, &process->output_format); in sof_ipc4_prepare_process_module()
2090 sof_ipc4_update_resource_usage(sdev, swidget, &process->base_config); in sof_ipc4_prepare_process_module()
2093 memcpy(cfg, &process->base_config, sizeof(struct sof_ipc4_base_module_cfg)); in sof_ipc4_prepare_process_module()
2096 if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) { in sof_ipc4_prepare_process_module()
2097 struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext; in sof_ipc4_prepare_process_module()
2103 memcpy(cfg, base_cfg_ext, process->base_config_ext_size); in sof_ipc4_prepare_process_module()
2115 scontrol->size = struct_size(control_data, chanv, scontrol->num_channels); in sof_ipc4_control_load_volume()
2117 /* scontrol->ipc_control_data will be freed in sof_control_unload */ in sof_ipc4_control_load_volume()
2118 scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL); in sof_ipc4_control_load_volume()
2119 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_volume()
2120 return -ENOMEM; in sof_ipc4_control_load_volume()
2122 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_volume()
2123 control_data->index = scontrol->index; in sof_ipc4_control_load_volume()
2125 msg = &control_data->msg; in sof_ipc4_control_load_volume()
2126 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_volume()
2127 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_volume()
2128 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_volume()
2130 /* volume controls with range 0-1 (off/on) are switch controls */ in sof_ipc4_control_load_volume()
2131 if (scontrol->max == 1) in sof_ipc4_control_load_volume()
2132 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_SWITCH_CONTROL_PARAM_ID); in sof_ipc4_control_load_volume()
2134 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_GAIN_PARAM_ID); in sof_ipc4_control_load_volume()
2136 for (i = 0; i < scontrol->num_channels; i++) { in sof_ipc4_control_load_volume()
2137 control_data->chanv[i].channel = i; in sof_ipc4_control_load_volume()
2140 * - 0dB for volume controls in sof_ipc4_control_load_volume()
2141 * - off (0) for switch controls - value already zero after in sof_ipc4_control_load_volume()
2144 if (scontrol->max > 1) in sof_ipc4_control_load_volume()
2145 control_data->chanv[i].value = SOF_IPC4_VOL_ZERO_DB; in sof_ipc4_control_load_volume()
2157 scontrol->size = struct_size(control_data, chanv, scontrol->num_channels); in sof_ipc4_control_load_enum()
2159 /* scontrol->ipc_control_data will be freed in sof_control_unload */ in sof_ipc4_control_load_enum()
2160 scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL); in sof_ipc4_control_load_enum()
2161 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_enum()
2162 return -ENOMEM; in sof_ipc4_control_load_enum()
2164 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_enum()
2165 control_data->index = scontrol->index; in sof_ipc4_control_load_enum()
2167 msg = &control_data->msg; in sof_ipc4_control_load_enum()
2168 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_enum()
2169 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_enum()
2170 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_enum()
2172 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_ENUM_CONTROL_PARAM_ID); in sof_ipc4_control_load_enum()
2175 for (i = 0; i < scontrol->num_channels; i++) in sof_ipc4_control_load_enum()
2176 control_data->chanv[i].channel = i; in sof_ipc4_control_load_enum()
2187 if (scontrol->max_size < (sizeof(*control_data) + sizeof(struct sof_abi_hdr))) { in sof_ipc4_control_load_bytes()
2188 dev_err(sdev->dev, "insufficient size for a bytes control %s: %zu.\n", in sof_ipc4_control_load_bytes()
2189 scontrol->name, scontrol->max_size); in sof_ipc4_control_load_bytes()
2190 return -EINVAL; in sof_ipc4_control_load_bytes()
2193 if (scontrol->priv_size > scontrol->max_size - sizeof(*control_data)) { in sof_ipc4_control_load_bytes()
2194 dev_err(sdev->dev, "scontrol %s bytes data size %zu exceeds max %zu.\n", in sof_ipc4_control_load_bytes()
2195 scontrol->name, scontrol->priv_size, in sof_ipc4_control_load_bytes()
2196 scontrol->max_size - sizeof(*control_data)); in sof_ipc4_control_load_bytes()
2197 return -EINVAL; in sof_ipc4_control_load_bytes()
2200 scontrol->size = sizeof(struct sof_ipc4_control_data) + scontrol->priv_size; in sof_ipc4_control_load_bytes()
2202 scontrol->ipc_control_data = kzalloc(scontrol->max_size, GFP_KERNEL); in sof_ipc4_control_load_bytes()
2203 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_bytes()
2204 return -ENOMEM; in sof_ipc4_control_load_bytes()
2206 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_bytes()
2207 control_data->index = scontrol->index; in sof_ipc4_control_load_bytes()
2208 if (scontrol->priv_size > 0) { in sof_ipc4_control_load_bytes()
2209 memcpy(control_data->data, scontrol->priv, scontrol->priv_size); in sof_ipc4_control_load_bytes()
2210 kfree(scontrol->priv); in sof_ipc4_control_load_bytes()
2211 scontrol->priv = NULL; in sof_ipc4_control_load_bytes()
2213 if (control_data->data->magic != SOF_IPC4_ABI_MAGIC) { in sof_ipc4_control_load_bytes()
2214 dev_err(sdev->dev, "Wrong ABI magic (%#x) for control: %s\n", in sof_ipc4_control_load_bytes()
2215 control_data->data->magic, scontrol->name); in sof_ipc4_control_load_bytes()
2216 ret = -EINVAL; in sof_ipc4_control_load_bytes()
2222 if (control_data->data->size + sizeof(struct sof_abi_hdr) != in sof_ipc4_control_load_bytes()
2223 scontrol->priv_size) { in sof_ipc4_control_load_bytes()
2224 dev_err(sdev->dev, "Control %s conflict in bytes %zu vs. priv size %zu.\n", in sof_ipc4_control_load_bytes()
2225 scontrol->name, in sof_ipc4_control_load_bytes()
2226 control_data->data->size + sizeof(struct sof_abi_hdr), in sof_ipc4_control_load_bytes()
2227 scontrol->priv_size); in sof_ipc4_control_load_bytes()
2228 ret = -EINVAL; in sof_ipc4_control_load_bytes()
2233 msg = &control_data->msg; in sof_ipc4_control_load_bytes()
2234 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_bytes()
2235 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_bytes()
2236 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_bytes()
2241 kfree(scontrol->ipc_control_data); in sof_ipc4_control_load_bytes()
2242 scontrol->ipc_control_data = NULL; in sof_ipc4_control_load_bytes()
2248 switch (scontrol->info_type) { in sof_ipc4_control_setup()
2267 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_setup()
2268 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_widget_setup()
2275 switch (swidget->id) { in sof_ipc4_widget_setup()
2277 pipeline = swidget->private; in sof_ipc4_widget_setup()
2279 if (pipeline->use_chain_dma) { in sof_ipc4_widget_setup()
2280 dev_warn(sdev->dev, "use_chain_dma set for scheduler %s", in sof_ipc4_widget_setup()
2281 swidget->widget->name); in sof_ipc4_widget_setup()
2285 dev_dbg(sdev->dev, "pipeline: %d memory pages: %d\n", swidget->pipeline_id, in sof_ipc4_widget_setup()
2286 pipeline->mem_usage); in sof_ipc4_widget_setup()
2288 msg = &pipeline->msg; in sof_ipc4_widget_setup()
2289 msg->primary |= pipeline->mem_usage; in sof_ipc4_widget_setup()
2291 swidget->instance_id = ida_alloc_max(&pipeline_ida, ipc4_data->max_num_pipelines, in sof_ipc4_widget_setup()
2293 if (swidget->instance_id < 0) { in sof_ipc4_widget_setup()
2294 dev_err(sdev->dev, "failed to assign pipeline id for %s: %d\n", in sof_ipc4_widget_setup()
2295 swidget->widget->name, swidget->instance_id); in sof_ipc4_widget_setup()
2296 return swidget->instance_id; in sof_ipc4_widget_setup()
2298 msg->primary &= ~SOF_IPC4_GLB_PIPE_INSTANCE_MASK; in sof_ipc4_widget_setup()
2299 msg->primary |= SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id); in sof_ipc4_widget_setup()
2305 struct sof_ipc4_copier *ipc4_copier = swidget->private; in sof_ipc4_widget_setup()
2307 pipeline = pipe_widget->private; in sof_ipc4_widget_setup()
2308 if (pipeline->use_chain_dma) in sof_ipc4_widget_setup()
2311 ipc_size = ipc4_copier->ipc_config_size; in sof_ipc4_widget_setup()
2312 ipc_data = ipc4_copier->ipc_config_data; in sof_ipc4_widget_setup()
2314 msg = &ipc4_copier->msg; in sof_ipc4_widget_setup()
2320 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_setup() local
2321 struct sof_ipc4_copier *ipc4_copier = dai->private; in sof_ipc4_widget_setup()
2323 pipeline = pipe_widget->private; in sof_ipc4_widget_setup()
2324 if (pipeline->use_chain_dma) in sof_ipc4_widget_setup()
2327 ipc_size = ipc4_copier->ipc_config_size; in sof_ipc4_widget_setup()
2328 ipc_data = ipc4_copier->ipc_config_data; in sof_ipc4_widget_setup()
2330 msg = &ipc4_copier->msg; in sof_ipc4_widget_setup()
2335 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_widget_setup()
2337 ipc_size = sizeof(gain->data); in sof_ipc4_widget_setup()
2338 ipc_data = &gain->data; in sof_ipc4_widget_setup()
2340 msg = &gain->msg; in sof_ipc4_widget_setup()
2345 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_widget_setup()
2347 ipc_size = sizeof(mixer->base_config); in sof_ipc4_widget_setup()
2348 ipc_data = &mixer->base_config; in sof_ipc4_widget_setup()
2350 msg = &mixer->msg; in sof_ipc4_widget_setup()
2355 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_widget_setup()
2357 ipc_size = sizeof(src->data); in sof_ipc4_widget_setup()
2358 ipc_data = &src->data; in sof_ipc4_widget_setup()
2360 msg = &src->msg; in sof_ipc4_widget_setup()
2365 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_widget_setup()
2367 if (!process->ipc_config_size) { in sof_ipc4_widget_setup()
2368 dev_err(sdev->dev, "module %s has no config data!\n", in sof_ipc4_widget_setup()
2369 swidget->widget->name); in sof_ipc4_widget_setup()
2370 return -EINVAL; in sof_ipc4_widget_setup()
2373 ipc_size = process->ipc_config_size; in sof_ipc4_widget_setup()
2374 ipc_data = process->ipc_config_data; in sof_ipc4_widget_setup()
2376 msg = &process->msg; in sof_ipc4_widget_setup()
2380 dev_err(sdev->dev, "widget type %d not supported", swidget->id); in sof_ipc4_widget_setup()
2381 return -EINVAL; in sof_ipc4_widget_setup()
2384 if (swidget->id != snd_soc_dapm_scheduler) { in sof_ipc4_widget_setup()
2387 dev_err(sdev->dev, "failed to assign instance id for %s\n", in sof_ipc4_widget_setup()
2388 swidget->widget->name); in sof_ipc4_widget_setup()
2392 msg->primary &= ~SOF_IPC4_MOD_INSTANCE_MASK; in sof_ipc4_widget_setup()
2393 msg->primary |= SOF_IPC4_MOD_INSTANCE(swidget->instance_id); in sof_ipc4_widget_setup()
2395 msg->extension &= ~SOF_IPC4_MOD_EXT_PARAM_SIZE_MASK; in sof_ipc4_widget_setup()
2396 msg->extension |= ipc_size >> 2; in sof_ipc4_widget_setup()
2398 msg->extension &= ~SOF_IPC4_MOD_EXT_PPL_ID_MASK; in sof_ipc4_widget_setup()
2399 msg->extension |= SOF_IPC4_MOD_EXT_PPL_ID(pipe_widget->instance_id); in sof_ipc4_widget_setup()
2401 dev_dbg(sdev->dev, "Create widget %s instance %d - pipe %d - core %d\n", in sof_ipc4_widget_setup()
2402 swidget->widget->name, swidget->instance_id, swidget->pipeline_id, swidget->core); in sof_ipc4_widget_setup()
2404 msg->data_size = ipc_size; in sof_ipc4_widget_setup()
2405 msg->data_ptr = ipc_data; in sof_ipc4_widget_setup()
2407 ret = sof_ipc_tx_message_no_reply(sdev->ipc, msg, ipc_size); in sof_ipc4_widget_setup()
2409 dev_err(sdev->dev, "failed to create module %s\n", swidget->widget->name); in sof_ipc4_widget_setup()
2411 if (swidget->id != snd_soc_dapm_scheduler) { in sof_ipc4_widget_setup()
2412 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_setup()
2414 ida_free(&fw_module->m_ida, swidget->instance_id); in sof_ipc4_widget_setup()
2416 ida_free(&pipeline_ida, swidget->instance_id); in sof_ipc4_widget_setup()
2425 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_free()
2426 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_widget_free()
2429 mutex_lock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2432 if (swidget->id == snd_soc_dapm_scheduler) { in sof_ipc4_widget_free()
2433 struct sof_ipc4_pipeline *pipeline = swidget->private; in sof_ipc4_widget_free()
2437 if (pipeline->use_chain_dma) { in sof_ipc4_widget_free()
2438 dev_warn(sdev->dev, "use_chain_dma set for scheduler %s", in sof_ipc4_widget_free()
2439 swidget->widget->name); in sof_ipc4_widget_free()
2440 mutex_unlock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2444 header = SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id); in sof_ipc4_widget_free()
2449 msg.primary = header; in sof_ipc4_widget_free()
2451 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_widget_free()
2453 dev_err(sdev->dev, "failed to free pipeline widget %s\n", in sof_ipc4_widget_free()
2454 swidget->widget->name); in sof_ipc4_widget_free()
2456 pipeline->mem_usage = 0; in sof_ipc4_widget_free()
2457 pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED; in sof_ipc4_widget_free()
2458 ida_free(&pipeline_ida, swidget->instance_id); in sof_ipc4_widget_free()
2459 swidget->instance_id = -EINVAL; in sof_ipc4_widget_free()
2461 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_free()
2462 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_widget_free()
2464 if (!pipeline->use_chain_dma) in sof_ipc4_widget_free()
2465 ida_free(&fw_module->m_ida, swidget->instance_id); in sof_ipc4_widget_free()
2468 mutex_unlock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2486 pin_binding = src_widget->output_pin_binding; in sof_ipc4_get_queue_id()
2487 queue_ida = &src_widget->output_queue_ida; in sof_ipc4_get_queue_id()
2488 num_pins = src_widget->num_output_pins; in sof_ipc4_get_queue_id()
2489 buddy_name = sink_widget->widget->name; in sof_ipc4_get_queue_id()
2492 pin_binding = sink_widget->input_pin_binding; in sof_ipc4_get_queue_id()
2493 queue_ida = &sink_widget->input_queue_ida; in sof_ipc4_get_queue_id()
2494 num_pins = sink_widget->num_input_pins; in sof_ipc4_get_queue_id()
2495 buddy_name = src_widget->widget->name; in sof_ipc4_get_queue_id()
2498 scomp = current_swidget->scomp; in sof_ipc4_get_queue_id()
2501 dev_err(scomp->dev, "invalid %s num_pins: %d for queue allocation for %s\n", in sof_ipc4_get_queue_id()
2503 num_pins, current_swidget->widget->name); in sof_ipc4_get_queue_id()
2504 return -EINVAL; in sof_ipc4_get_queue_id()
2521 dev_err(scomp->dev, "no %s queue id found from pin binding array for %s\n", in sof_ipc4_get_queue_id()
2523 current_swidget->widget->name); in sof_ipc4_get_queue_id()
2524 return -EINVAL; in sof_ipc4_get_queue_id()
2539 pin_binding = swidget->output_pin_binding; in sof_ipc4_put_queue_id()
2540 queue_ida = &swidget->output_queue_ida; in sof_ipc4_put_queue_id()
2541 num_pins = swidget->num_output_pins; in sof_ipc4_put_queue_id()
2543 pin_binding = swidget->input_pin_binding; in sof_ipc4_put_queue_id()
2544 queue_ida = &swidget->input_queue_ida; in sof_ipc4_put_queue_id()
2545 num_pins = swidget->num_input_pins; in sof_ipc4_put_queue_id()
2561 const struct sof_ipc_ops *iops = sdev->ipc->ops; in sof_ipc4_set_copier_sink_format()
2567 dev_dbg(sdev->dev, "%s set copier sink %d format\n", in sof_ipc4_set_copier_sink_format()
2568 src_widget->widget->name, sink_id); in sof_ipc4_set_copier_sink_format()
2570 if (WIDGET_IS_DAI(src_widget->id)) { in sof_ipc4_set_copier_sink_format()
2571 struct snd_sof_dai *dai = src_widget->private; in sof_ipc4_set_copier_sink_format() local
2573 src_config = dai->private; in sof_ipc4_set_copier_sink_format()
2575 src_config = src_widget->private; in sof_ipc4_set_copier_sink_format()
2578 fw_module = src_widget->module_info; in sof_ipc4_set_copier_sink_format()
2581 memcpy(&format.source_fmt, &src_config->audio_fmt, sizeof(format.source_fmt)); in sof_ipc4_set_copier_sink_format()
2585 dev_err(sdev->dev, "Unable to get pin %d format for %s", in sof_ipc4_set_copier_sink_format()
2586 sink_id, sink_widget->widget->name); in sof_ipc4_set_copier_sink_format()
2587 return -EINVAL; in sof_ipc4_set_copier_sink_format()
2595 msg.primary = fw_module->man4_module_entry.id; in sof_ipc4_set_copier_sink_format()
2596 msg.primary |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_set_copier_sink_format()
2597 msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_set_copier_sink_format()
2598 msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_set_copier_sink_format()
2603 return iops->set_get_data(sdev, &msg, msg.data_size, true); in sof_ipc4_set_copier_sink_format()
2608 struct snd_sof_widget *src_widget = sroute->src_widget; in sof_ipc4_route_setup()
2609 struct snd_sof_widget *sink_widget = sroute->sink_widget; in sof_ipc4_route_setup()
2610 struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget; in sof_ipc4_route_setup()
2611 struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget; in sof_ipc4_route_setup()
2612 struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info; in sof_ipc4_route_setup()
2613 struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; in sof_ipc4_route_setup()
2614 struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private; in sof_ipc4_route_setup()
2615 struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private; in sof_ipc4_route_setup()
2621 if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma) { in sof_ipc4_route_setup()
2622 if (!src_pipeline->use_chain_dma || !sink_pipeline->use_chain_dma) { in sof_ipc4_route_setup()
2623 dev_err(sdev->dev, in sof_ipc4_route_setup()
2625 src_widget->widget->name, sink_widget->widget->name); in sof_ipc4_route_setup()
2626 return -EINVAL; in sof_ipc4_route_setup()
2632 dev_err(sdev->dev, in sof_ipc4_route_setup()
2633 "cannot bind %s -> %s, no firmware module for: %s%s\n", in sof_ipc4_route_setup()
2634 src_widget->widget->name, sink_widget->widget->name, in sof_ipc4_route_setup()
2638 return -ENODEV; in sof_ipc4_route_setup()
2641 sroute->src_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, in sof_ipc4_route_setup()
2643 if (sroute->src_queue_id < 0) { in sof_ipc4_route_setup()
2644 dev_err(sdev->dev, "failed to get queue ID for source widget: %s\n", in sof_ipc4_route_setup()
2645 src_widget->widget->name); in sof_ipc4_route_setup()
2646 return sroute->src_queue_id; in sof_ipc4_route_setup()
2649 sroute->dst_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, in sof_ipc4_route_setup()
2651 if (sroute->dst_queue_id < 0) { in sof_ipc4_route_setup()
2652 dev_err(sdev->dev, "failed to get queue ID for sink widget: %s\n", in sof_ipc4_route_setup()
2653 sink_widget->widget->name); in sof_ipc4_route_setup()
2654 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, in sof_ipc4_route_setup()
2656 return sroute->dst_queue_id; in sof_ipc4_route_setup()
2660 if (sroute->src_queue_id > 0 && WIDGET_IS_COPIER(src_widget->id)) { in sof_ipc4_route_setup()
2662 sroute->src_queue_id); in sof_ipc4_route_setup()
2664 dev_err(sdev->dev, "failed to set sink format for %s source queue ID %d\n", in sof_ipc4_route_setup()
2665 src_widget->widget->name, sroute->src_queue_id); in sof_ipc4_route_setup()
2670 dev_dbg(sdev->dev, "bind %s:%d -> %s:%d\n", in sof_ipc4_route_setup()
2671 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_setup()
2672 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_setup()
2674 header = src_fw_module->man4_module_entry.id; in sof_ipc4_route_setup()
2675 header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_route_setup()
2680 extension = sink_fw_module->man4_module_entry.id; in sof_ipc4_route_setup()
2681 extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id); in sof_ipc4_route_setup()
2682 extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id); in sof_ipc4_route_setup()
2683 extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id); in sof_ipc4_route_setup()
2685 msg.primary = header; in sof_ipc4_route_setup()
2688 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_route_setup()
2690 dev_err(sdev->dev, "failed to bind modules %s:%d -> %s:%d\n", in sof_ipc4_route_setup()
2691 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_setup()
2692 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_setup()
2699 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT); in sof_ipc4_route_setup()
2700 sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT); in sof_ipc4_route_setup()
2706 struct snd_sof_widget *src_widget = sroute->src_widget; in sof_ipc4_route_free()
2707 struct snd_sof_widget *sink_widget = sroute->sink_widget; in sof_ipc4_route_free()
2708 struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info; in sof_ipc4_route_free()
2709 struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; in sof_ipc4_route_free()
2711 struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget; in sof_ipc4_route_free()
2712 struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget; in sof_ipc4_route_free()
2713 struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private; in sof_ipc4_route_free()
2714 struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private; in sof_ipc4_route_free()
2719 if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma) in sof_ipc4_route_free()
2722 dev_dbg(sdev->dev, "unbind modules %s:%d -> %s:%d\n", in sof_ipc4_route_free()
2723 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_free()
2724 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_free()
2730 if (src_widget->spipe->pipe_widget == sink_widget->spipe->pipe_widget) in sof_ipc4_route_free()
2733 header = src_fw_module->man4_module_entry.id; in sof_ipc4_route_free()
2734 header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_route_free()
2739 extension = sink_fw_module->man4_module_entry.id; in sof_ipc4_route_free()
2740 extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id); in sof_ipc4_route_free()
2741 extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id); in sof_ipc4_route_free()
2742 extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id); in sof_ipc4_route_free()
2744 msg.primary = header; in sof_ipc4_route_free()
2747 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_route_free()
2749 dev_err(sdev->dev, "failed to unbind modules %s:%d -> %s:%d\n", in sof_ipc4_route_free()
2750 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_free()
2751 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_free()
2753 sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT); in sof_ipc4_route_free()
2754 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT); in sof_ipc4_route_free()
2762 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_dai_config()
2763 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_dai_config()
2764 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_dai_config() local
2769 if (!dai || !dai->private) { in sof_ipc4_dai_config()
2770 dev_err(sdev->dev, "Invalid DAI or DAI private data for %s\n", in sof_ipc4_dai_config()
2771 swidget->widget->name); in sof_ipc4_dai_config()
2772 return -EINVAL; in sof_ipc4_dai_config()
2775 ipc4_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_dai_config()
2776 copier_data = &ipc4_copier->data; in sof_ipc4_dai_config()
2781 switch (ipc4_copier->dai_type) { in sof_ipc4_dai_config()
2783 if (pipeline->use_chain_dma) { in sof_ipc4_dai_config()
2784 pipeline->msg.primary &= ~SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK; in sof_ipc4_dai_config()
2785 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID(data->dai_data); in sof_ipc4_dai_config()
2788 gtw_attr = ipc4_copier->gtw_attr; in sof_ipc4_dai_config()
2789 gtw_attr->lp_buffer_alloc = pipeline->lp_mode; in sof_ipc4_dai_config()
2798 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_dai_config()
2799 copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_data); in sof_ipc4_dai_config()
2807 dev_err(sdev->dev, "%s: unsupported dai type %d\n", __func__, in sof_ipc4_dai_config()
2808 ipc4_copier->dai_type); in sof_ipc4_dai_config()
2809 return -EINVAL; in sof_ipc4_dai_config()
2819 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_parse_manifest()
2822 u32 size = le32_to_cpu(man->priv.size); in sof_ipc4_parse_manifest()
2823 u8 *man_ptr = man->priv.data; in sof_ipc4_parse_manifest()
2828 dev_err(scomp->dev, "%s: Invalid topology ABI size: %u\n", in sof_ipc4_parse_manifest()
2830 return -EINVAL; in sof_ipc4_parse_manifest()
2835 dev_info(scomp->dev, in sof_ipc4_parse_manifest()
2837 le16_to_cpu(manifest->abi_major), le16_to_cpu(manifest->abi_minor), in sof_ipc4_parse_manifest()
2838 le16_to_cpu(manifest->abi_patch), in sof_ipc4_parse_manifest()
2847 manifest_tlv = manifest->items; in sof_ipc4_parse_manifest()
2849 for (i = 0; i < le16_to_cpu(manifest->count); i++) { in sof_ipc4_parse_manifest()
2850 len_check += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size); in sof_ipc4_parse_manifest()
2852 return -EINVAL; in sof_ipc4_parse_manifest()
2854 switch (le32_to_cpu(manifest_tlv->type)) { in sof_ipc4_parse_manifest()
2857 if (ipc4_data->nhlt) in sof_ipc4_parse_manifest()
2859 ipc4_data->nhlt = devm_kmemdup(sdev->dev, manifest_tlv->data, in sof_ipc4_parse_manifest()
2860 le32_to_cpu(manifest_tlv->size), GFP_KERNEL); in sof_ipc4_parse_manifest()
2861 if (!ipc4_data->nhlt) in sof_ipc4_parse_manifest()
2862 return -ENOMEM; in sof_ipc4_parse_manifest()
2865 dev_warn(scomp->dev, "Skipping unknown manifest data type %d\n", in sof_ipc4_parse_manifest()
2866 manifest_tlv->type); in sof_ipc4_parse_manifest()
2869 man_ptr += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size); in sof_ipc4_parse_manifest()
2876 static int sof_ipc4_dai_get_clk(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, int clk_type) in sof_ipc4_dai_get_clk() argument
2878 struct sof_ipc4_copier *ipc4_copier = dai->private; in sof_ipc4_dai_get_clk()
2888 list_for_each_entry(slink, &sdev->dai_link_list, list) { in sof_ipc4_dai_get_clk()
2889 if (!strcmp(slink->link->name, dai->name)) { in sof_ipc4_dai_get_clk()
2896 dev_err(sdev->dev, "no DAI link found for DAI %s\n", dai->name); in sof_ipc4_dai_get_clk()
2897 return -EINVAL; in sof_ipc4_dai_get_clk()
2900 for (i = 0; i < slink->num_hw_configs; i++) { in sof_ipc4_dai_get_clk()
2901 hw_config = &slink->hw_configs[i]; in sof_ipc4_dai_get_clk()
2902 if (dai->current_config == le32_to_cpu(hw_config->id)) { in sof_ipc4_dai_get_clk()
2909 dev_err(sdev->dev, "no matching hw_config found for DAI %s\n", dai->name); in sof_ipc4_dai_get_clk()
2910 return -EINVAL; in sof_ipc4_dai_get_clk()
2913 switch (ipc4_copier->dai_type) { in sof_ipc4_dai_get_clk()
2917 return le32_to_cpu(hw_config->mclk_rate); in sof_ipc4_dai_get_clk()
2919 return le32_to_cpu(hw_config->bclk_rate); in sof_ipc4_dai_get_clk()
2921 dev_err(sdev->dev, "Invalid clk type for SSP %d\n", clk_type); in sof_ipc4_dai_get_clk()
2926 dev_err(sdev->dev, "DAI type %d not supported yet!\n", ipc4_copier->dai_type); in sof_ipc4_dai_get_clk()
2930 return -EINVAL; in sof_ipc4_dai_get_clk()
2949 list_for_each_entry(spcm, &sdev->pcm_list, list) { in sof_ipc4_tear_down_all_pipelines()
2951 struct snd_pcm_substream *substream = spcm->stream[dir].substream; in sof_ipc4_tear_down_all_pipelines()
2953 if (!substream || !substream->runtime || spcm->stream[dir].suspend_ignored) in sof_ipc4_tear_down_all_pipelines()
2956 if (spcm->stream[dir].list) { in sof_ipc4_tear_down_all_pipelines()
2966 static int sof_ipc4_link_setup(struct snd_sof_dev *sdev, struct snd_soc_dai_link *link) in sof_ipc4_link_setup() argument
2968 if (link->no_pcm) in sof_ipc4_link_setup()
2978 link->trigger[SNDRV_PCM_STREAM_PLAYBACK] = SND_SOC_DPCM_TRIGGER_POST; in sof_ipc4_link_setup()
2979 link->trigger[SNDRV_PCM_STREAM_CAPTURE] = SND_SOC_DPCM_TRIGGER_PRE; in sof_ipc4_link_setup()