Lines Matching +full:pri +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()
198 base_cfg_ext = process->base_config_ext; in sof_ipc4_get_input_pin_audio_fmt()
204 for (i = 0; i < base_cfg_ext->num_input_pin_fmts; i++) { in sof_ipc4_get_input_pin_audio_fmt()
205 struct sof_ipc4_pin_format *pin_format = &base_cfg_ext->pin_formats[i]; in sof_ipc4_get_input_pin_audio_fmt()
207 if (pin_format->pin_index == pin_index) in sof_ipc4_get_input_pin_audio_fmt()
208 return &pin_format->audio_fmt; in sof_ipc4_get_input_pin_audio_fmt()
215 * sof_ipc4_get_audio_fmt - get available audio formats from swidget->tuples
233 SOF_AUDIO_FMT_NUM_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
234 swidget->num_tuples, sizeof(*available_fmt), 1); in sof_ipc4_get_audio_fmt()
236 dev_err(scomp->dev, "Failed to parse audio format token count\n"); in sof_ipc4_get_audio_fmt()
240 if (!available_fmt->num_input_formats && !available_fmt->num_output_formats) { in sof_ipc4_get_audio_fmt()
241 dev_err(scomp->dev, "No input/output pin formats set in topology\n"); in sof_ipc4_get_audio_fmt()
242 return -EINVAL; in sof_ipc4_get_audio_fmt()
245 dev_dbg(scomp->dev, in sof_ipc4_get_audio_fmt()
247 available_fmt->num_input_formats, available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
250 ret = sof_update_ipc_object(scomp, module_base_cfg, SOF_COMP_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
251 swidget->num_tuples, sizeof(*module_base_cfg), 1); in sof_ipc4_get_audio_fmt()
253 dev_err(scomp->dev, "parse comp tokens for %s failed, error: %d\n", in sof_ipc4_get_audio_fmt()
254 swidget->widget->name, ret); in sof_ipc4_get_audio_fmt()
258 dev_dbg(scomp->dev, "widget %s: is_pages: %d\n", swidget->widget->name, in sof_ipc4_get_audio_fmt()
259 module_base_cfg->is_pages); in sof_ipc4_get_audio_fmt()
261 if (available_fmt->num_input_formats) { in sof_ipc4_get_audio_fmt()
262 in_format = kcalloc(available_fmt->num_input_formats, in sof_ipc4_get_audio_fmt()
265 return -ENOMEM; in sof_ipc4_get_audio_fmt()
266 available_fmt->input_pin_fmts = in_format; in sof_ipc4_get_audio_fmt()
269 SOF_IN_AUDIO_FORMAT_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
270 swidget->num_tuples, sizeof(*in_format), in sof_ipc4_get_audio_fmt()
271 available_fmt->num_input_formats); in sof_ipc4_get_audio_fmt()
273 dev_err(scomp->dev, "parse input audio fmt tokens failed %d\n", ret); in sof_ipc4_get_audio_fmt()
277 dev_dbg(scomp->dev, "Input audio formats for %s\n", swidget->widget->name); in sof_ipc4_get_audio_fmt()
278 sof_ipc4_dbg_audio_format(scomp->dev, in_format, in sof_ipc4_get_audio_fmt()
279 available_fmt->num_input_formats); in sof_ipc4_get_audio_fmt()
282 if (available_fmt->num_output_formats) { in sof_ipc4_get_audio_fmt()
283 out_format = kcalloc(available_fmt->num_output_formats, sizeof(*out_format), in sof_ipc4_get_audio_fmt()
286 ret = -ENOMEM; in sof_ipc4_get_audio_fmt()
291 SOF_OUT_AUDIO_FORMAT_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
292 swidget->num_tuples, sizeof(*out_format), in sof_ipc4_get_audio_fmt()
293 available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
295 dev_err(scomp->dev, "parse output audio fmt tokens failed\n"); in sof_ipc4_get_audio_fmt()
299 available_fmt->output_pin_fmts = out_format; in sof_ipc4_get_audio_fmt()
300 dev_dbg(scomp->dev, "Output audio formats for %s\n", swidget->widget->name); in sof_ipc4_get_audio_fmt()
301 sof_ipc4_dbg_audio_format(scomp->dev, out_format, in sof_ipc4_get_audio_fmt()
302 available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
311 available_fmt->input_pin_fmts = NULL; in sof_ipc4_get_audio_fmt()
319 kfree(available_fmt->output_pin_fmts); in sof_ipc4_free_audio_fmt()
320 available_fmt->output_pin_fmts = NULL; in sof_ipc4_free_audio_fmt()
321 kfree(available_fmt->input_pin_fmts); in sof_ipc4_free_audio_fmt()
322 available_fmt->input_pin_fmts = NULL; in sof_ipc4_free_audio_fmt()
327 kfree(swidget->private); in sof_ipc4_widget_free_comp_pipeline()
332 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_set_module_info()
335 swidget->module_info = sof_ipc4_find_module_by_uuid(sdev, &swidget->uuid); in sof_ipc4_widget_set_module_info()
337 if (swidget->module_info) in sof_ipc4_widget_set_module_info()
340 dev_err(sdev->dev, "failed to find module info for widget %s with UUID %pUL\n", in sof_ipc4_widget_set_module_info()
341 swidget->widget->name, &swidget->uuid); in sof_ipc4_widget_set_module_info()
342 return -EINVAL; in sof_ipc4_widget_set_module_info()
355 fw_module = swidget->module_info; in sof_ipc4_widget_setup_msg()
357 msg->primary = fw_module->man4_module_entry.id; in sof_ipc4_widget_setup_msg()
358 msg->primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_INIT_INSTANCE); in sof_ipc4_widget_setup_msg()
359 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_widget_setup_msg()
360 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_widget_setup_msg()
362 msg->extension = SOF_IPC4_MOD_EXT_CORE_ID(swidget->core); in sof_ipc4_widget_setup_msg()
364 type = (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_DP) ? 1 : 0; in sof_ipc4_widget_setup_msg()
365 msg->extension |= SOF_IPC4_MOD_EXT_DOMAIN(type); in sof_ipc4_widget_setup_msg()
372 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_update_kcontrol_module_id()
374 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_update_kcontrol_module_id()
378 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { in sof_ipc4_widget_update_kcontrol_module_id()
379 if (scontrol->comp_id == swidget->comp_id) { in sof_ipc4_widget_update_kcontrol_module_id()
380 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; in sof_ipc4_widget_update_kcontrol_module_id()
381 struct sof_ipc4_msg *msg = &cdata->msg; in sof_ipc4_widget_update_kcontrol_module_id()
383 msg->primary |= fw_module->man4_module_entry.id; in sof_ipc4_widget_update_kcontrol_module_id()
391 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_pcm()
398 return -ENOMEM; in sof_ipc4_widget_setup_pcm()
400 swidget->private = ipc4_copier; in sof_ipc4_widget_setup_pcm()
401 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_setup_pcm()
403 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_pcm()
406 &ipc4_copier->data.base_config); in sof_ipc4_widget_setup_pcm()
411 * This callback is used by host copier and module-to-module copier, in sof_ipc4_widget_setup_pcm()
414 if (!WIDGET_IS_AIF(swidget->id)) in sof_ipc4_widget_setup_pcm()
418 SOF_COPIER_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_pcm()
419 swidget->num_tuples, sizeof(node_type), 1); in sof_ipc4_widget_setup_pcm()
422 dev_err(scomp->dev, "parse host copier node type token failed %d\n", in sof_ipc4_widget_setup_pcm()
426 dev_dbg(scomp->dev, "host copier '%s' node_type %u\n", swidget->widget->name, node_type); in sof_ipc4_widget_setup_pcm()
429 ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); in sof_ipc4_widget_setup_pcm()
430 if (!ipc4_copier->gtw_attr) { in sof_ipc4_widget_setup_pcm()
431 ret = -ENOMEM; in sof_ipc4_widget_setup_pcm()
435 ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; in sof_ipc4_widget_setup_pcm()
436 ipc4_copier->data.gtw_cfg.config_length = in sof_ipc4_widget_setup_pcm()
439 switch (swidget->id) { in sof_ipc4_widget_setup_pcm()
442 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); in sof_ipc4_widget_setup_pcm()
445 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID; in sof_ipc4_widget_setup_pcm()
446 ipc4_copier->ipc_config_size = 0; in sof_ipc4_widget_setup_pcm()
449 dev_err(scomp->dev, "invalid widget type %d\n", swidget->id); in sof_ipc4_widget_setup_pcm()
450 ret = -EINVAL; in sof_ipc4_widget_setup_pcm()
455 ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg); in sof_ipc4_widget_setup_pcm()
462 kfree(ipc4_copier->gtw_attr); in sof_ipc4_widget_setup_pcm()
467 swidget->private = NULL; in sof_ipc4_widget_setup_pcm()
473 struct sof_ipc4_copier *ipc4_copier = swidget->private; in sof_ipc4_widget_free_comp_pcm()
479 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_free_comp_pcm()
480 kfree(available_fmt->output_pin_fmts); in sof_ipc4_widget_free_comp_pcm()
481 kfree(ipc4_copier->gtw_attr); in sof_ipc4_widget_free_comp_pcm()
483 swidget->private = NULL; in sof_ipc4_widget_free_comp_pcm()
489 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_dai()
490 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_setup_comp_dai() local
499 return -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
501 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_setup_comp_dai()
503 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_dai()
506 &ipc4_copier->data.base_config); in sof_ipc4_widget_setup_comp_dai()
511 SOF_COPIER_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_dai()
512 swidget->num_tuples, sizeof(node_type), 1); in sof_ipc4_widget_setup_comp_dai()
514 dev_err(scomp->dev, "parse dai node type failed %d\n", ret); in sof_ipc4_widget_setup_comp_dai()
519 SOF_DAI_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_dai()
520 swidget->num_tuples, sizeof(u32), 1); in sof_ipc4_widget_setup_comp_dai()
522 dev_err(scomp->dev, "parse dai copier node token failed %d\n", ret); in sof_ipc4_widget_setup_comp_dai()
526 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()
527 node_type, ipc4_copier->dai_type, ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
529 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); in sof_ipc4_widget_setup_comp_dai()
531 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_setup_comp_dai()
532 pipeline = pipe_widget->private; in sof_ipc4_widget_setup_comp_dai()
533 if (pipeline->use_chain_dma && ipc4_copier->dai_type != SOF_DAI_INTEL_HDA) { in sof_ipc4_widget_setup_comp_dai()
534 dev_err(scomp->dev, in sof_ipc4_widget_setup_comp_dai()
535 "Bad DAI type '%d', Chained DMA is only supported by HDA DAIs (%d).\n", in sof_ipc4_widget_setup_comp_dai()
536 ipc4_copier->dai_type, SOF_DAI_INTEL_HDA); in sof_ipc4_widget_setup_comp_dai()
537 ret = -ENODEV; in sof_ipc4_widget_setup_comp_dai()
541 switch (ipc4_copier->dai_type) { in sof_ipc4_widget_setup_comp_dai()
550 snd_soc_dapm_widget_for_each_source_path(swidget->widget, p) in sof_ipc4_widget_setup_comp_dai()
553 if (swidget->id == snd_soc_dapm_dai_in && src_num == 0) { in sof_ipc4_widget_setup_comp_dai()
557 * It is fine to call kfree(ipc4_copier->copier_config) since in sof_ipc4_widget_setup_comp_dai()
558 * ipc4_copier->copier_config is null. in sof_ipc4_widget_setup_comp_dai()
566 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
570 list_for_each_entry(w, &sdev->widget_list, list) { in sof_ipc4_widget_setup_comp_dai()
571 if (w->widget->sname && in sof_ipc4_widget_setup_comp_dai()
572 strcmp(w->widget->sname, swidget->widget->sname)) in sof_ipc4_widget_setup_comp_dai()
575 blob->alh_cfg.device_count++; in sof_ipc4_widget_setup_comp_dai()
578 ipc4_copier->copier_config = (uint32_t *)blob; in sof_ipc4_widget_setup_comp_dai()
579 ipc4_copier->data.gtw_cfg.config_length = sizeof(*blob) >> 2; in sof_ipc4_widget_setup_comp_dai()
583 /* set SSP DAI index as the node_id */ in sof_ipc4_widget_setup_comp_dai()
584 ipc4_copier->data.gtw_cfg.node_id |= in sof_ipc4_widget_setup_comp_dai()
585 SOF_IPC4_NODE_INDEX_INTEL_SSP(ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
588 /* set DMIC DAI index as the node_id */ in sof_ipc4_widget_setup_comp_dai()
589 ipc4_copier->data.gtw_cfg.node_id |= in sof_ipc4_widget_setup_comp_dai()
590 SOF_IPC4_NODE_INDEX_INTEL_DMIC(ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
593 ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); in sof_ipc4_widget_setup_comp_dai()
594 if (!ipc4_copier->gtw_attr) { in sof_ipc4_widget_setup_comp_dai()
595 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
599 ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; in sof_ipc4_widget_setup_comp_dai()
600 ipc4_copier->data.gtw_cfg.config_length = in sof_ipc4_widget_setup_comp_dai()
605 dai->scomp = scomp; in sof_ipc4_widget_setup_comp_dai()
606 dai->private = ipc4_copier; in sof_ipc4_widget_setup_comp_dai()
609 ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg); in sof_ipc4_widget_setup_comp_dai()
616 kfree(ipc4_copier->copier_config); in sof_ipc4_widget_setup_comp_dai()
621 dai->private = NULL; in sof_ipc4_widget_setup_comp_dai()
622 dai->scomp = NULL; in sof_ipc4_widget_setup_comp_dai()
629 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_free_comp_dai() local
632 if (!dai) in sof_ipc4_widget_free_comp_dai()
635 if (!dai->private) { in sof_ipc4_widget_free_comp_dai()
636 kfree(dai); in sof_ipc4_widget_free_comp_dai()
637 swidget->private = NULL; in sof_ipc4_widget_free_comp_dai()
641 ipc4_copier = dai->private; in sof_ipc4_widget_free_comp_dai()
642 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_free_comp_dai()
644 kfree(available_fmt->output_pin_fmts); in sof_ipc4_widget_free_comp_dai()
645 if (ipc4_copier->dai_type != SOF_DAI_INTEL_SSP && in sof_ipc4_widget_free_comp_dai()
646 ipc4_copier->dai_type != SOF_DAI_INTEL_DMIC) in sof_ipc4_widget_free_comp_dai()
647 kfree(ipc4_copier->copier_config); in sof_ipc4_widget_free_comp_dai()
648 kfree(dai->private); in sof_ipc4_widget_free_comp_dai()
649 kfree(dai); in sof_ipc4_widget_free_comp_dai()
650 swidget->private = NULL; in sof_ipc4_widget_free_comp_dai()
655 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_pipeline()
657 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_pipeline()
662 return -ENOMEM; in sof_ipc4_widget_setup_comp_pipeline()
664 ret = sof_update_ipc_object(scomp, pipeline, SOF_SCHED_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_pipeline()
665 swidget->num_tuples, sizeof(*pipeline), 1); in sof_ipc4_widget_setup_comp_pipeline()
667 dev_err(scomp->dev, "parsing scheduler tokens failed\n"); in sof_ipc4_widget_setup_comp_pipeline()
671 swidget->core = pipeline->core_id; in sof_ipc4_widget_setup_comp_pipeline()
672 spipe->core_mask |= BIT(pipeline->core_id); in sof_ipc4_widget_setup_comp_pipeline()
674 if (pipeline->use_chain_dma) { in sof_ipc4_widget_setup_comp_pipeline()
675 dev_dbg(scomp->dev, "Set up chain DMA for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_pipeline()
676 swidget->private = pipeline; in sof_ipc4_widget_setup_comp_pipeline()
681 ret = sof_update_ipc_object(scomp, swidget, SOF_PIPELINE_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_pipeline()
682 swidget->num_tuples, sizeof(*swidget), 1); in sof_ipc4_widget_setup_comp_pipeline()
684 dev_err(scomp->dev, "parsing pipeline tokens failed\n"); in sof_ipc4_widget_setup_comp_pipeline()
689 pipeline->priority = 0; in sof_ipc4_widget_setup_comp_pipeline()
691 dev_dbg(scomp->dev, "pipeline '%s': id %d, pri %d, core_id %u, lp mode %d\n", in sof_ipc4_widget_setup_comp_pipeline()
692 swidget->widget->name, swidget->pipeline_id, in sof_ipc4_widget_setup_comp_pipeline()
693 pipeline->priority, pipeline->core_id, pipeline->lp_mode); in sof_ipc4_widget_setup_comp_pipeline()
695 swidget->private = pipeline; in sof_ipc4_widget_setup_comp_pipeline()
697 pipeline->msg.primary = SOF_IPC4_GLB_PIPE_PRIORITY(pipeline->priority); in sof_ipc4_widget_setup_comp_pipeline()
698 pipeline->msg.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_CREATE_PIPELINE); in sof_ipc4_widget_setup_comp_pipeline()
699 pipeline->msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_widget_setup_comp_pipeline()
700 pipeline->msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG); in sof_ipc4_widget_setup_comp_pipeline()
702 pipeline->msg.extension = pipeline->lp_mode; in sof_ipc4_widget_setup_comp_pipeline()
703 pipeline->msg.extension |= SOF_IPC4_GLB_PIPE_EXT_CORE_ID(pipeline->core_id); in sof_ipc4_widget_setup_comp_pipeline()
704 pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED; in sof_ipc4_widget_setup_comp_pipeline()
714 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_pga()
720 return -ENOMEM; in sof_ipc4_widget_setup_comp_pga()
722 swidget->private = gain; in sof_ipc4_widget_setup_comp_pga()
724 gain->data.params.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK; in sof_ipc4_widget_setup_comp_pga()
725 gain->data.params.init_val = SOF_IPC4_VOL_ZERO_DB; in sof_ipc4_widget_setup_comp_pga()
727 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, &gain->data.base_config); in sof_ipc4_widget_setup_comp_pga()
731 ret = sof_update_ipc_object(scomp, &gain->data.params, SOF_GAIN_TOKENS, in sof_ipc4_widget_setup_comp_pga()
732 swidget->tuples, swidget->num_tuples, sizeof(gain->data), 1); in sof_ipc4_widget_setup_comp_pga()
734 dev_err(scomp->dev, "Parsing gain tokens failed\n"); in sof_ipc4_widget_setup_comp_pga()
738 dev_dbg(scomp->dev, in sof_ipc4_widget_setup_comp_pga()
740 swidget->widget->name, gain->data.params.curve_type, in sof_ipc4_widget_setup_comp_pga()
741 gain->data.params.curve_duration_l, gain->data.params.init_val); in sof_ipc4_widget_setup_comp_pga()
743 ret = sof_ipc4_widget_setup_msg(swidget, &gain->msg); in sof_ipc4_widget_setup_comp_pga()
751 sof_ipc4_free_audio_fmt(&gain->available_fmt); in sof_ipc4_widget_setup_comp_pga()
753 swidget->private = NULL; in sof_ipc4_widget_setup_comp_pga()
759 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_widget_free_comp_pga()
764 sof_ipc4_free_audio_fmt(&gain->available_fmt); in sof_ipc4_widget_free_comp_pga()
765 kfree(swidget->private); in sof_ipc4_widget_free_comp_pga()
766 swidget->private = NULL; in sof_ipc4_widget_free_comp_pga()
771 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_mixer()
775 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_mixer()
779 return -ENOMEM; in sof_ipc4_widget_setup_comp_mixer()
781 swidget->private = mixer; in sof_ipc4_widget_setup_comp_mixer()
783 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &mixer->available_fmt, in sof_ipc4_widget_setup_comp_mixer()
784 &mixer->base_config); in sof_ipc4_widget_setup_comp_mixer()
788 ret = sof_ipc4_widget_setup_msg(swidget, &mixer->msg); in sof_ipc4_widget_setup_comp_mixer()
794 sof_ipc4_free_audio_fmt(&mixer->available_fmt); in sof_ipc4_widget_setup_comp_mixer()
796 swidget->private = NULL; in sof_ipc4_widget_setup_comp_mixer()
802 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_src()
803 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_src()
807 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_src()
811 return -ENOMEM; in sof_ipc4_widget_setup_comp_src()
813 swidget->private = src; in sof_ipc4_widget_setup_comp_src()
815 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt, in sof_ipc4_widget_setup_comp_src()
816 &src->data.base_config); in sof_ipc4_widget_setup_comp_src()
820 ret = sof_update_ipc_object(scomp, &src->data, SOF_SRC_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_src()
821 swidget->num_tuples, sizeof(*src), 1); in sof_ipc4_widget_setup_comp_src()
823 dev_err(scomp->dev, "Parsing SRC tokens failed\n"); in sof_ipc4_widget_setup_comp_src()
827 spipe->core_mask |= BIT(swidget->core); in sof_ipc4_widget_setup_comp_src()
829 dev_dbg(scomp->dev, "SRC sink rate %d\n", src->data.sink_rate); in sof_ipc4_widget_setup_comp_src()
831 ret = sof_ipc4_widget_setup_msg(swidget, &src->msg); in sof_ipc4_widget_setup_comp_src()
837 sof_ipc4_free_audio_fmt(&src->available_fmt); in sof_ipc4_widget_setup_comp_src()
839 swidget->private = NULL; in sof_ipc4_widget_setup_comp_src()
845 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_widget_free_comp_src()
850 sof_ipc4_free_audio_fmt(&src->available_fmt); in sof_ipc4_widget_free_comp_src()
851 kfree(swidget->private); in sof_ipc4_widget_free_comp_src()
852 swidget->private = NULL; in sof_ipc4_widget_free_comp_src()
857 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_widget_free_comp_mixer()
862 sof_ipc4_free_audio_fmt(&mixer->available_fmt); in sof_ipc4_widget_free_comp_mixer()
863 kfree(swidget->private); in sof_ipc4_widget_free_comp_mixer()
864 swidget->private = NULL; in sof_ipc4_widget_free_comp_mixer()
872 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_process()
874 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_process()
881 return -ENOMEM; in sof_ipc4_widget_setup_comp_process()
883 swidget->private = process; in sof_ipc4_widget_setup_comp_process()
885 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &process->available_fmt, in sof_ipc4_widget_setup_comp_process()
886 &process->base_config); in sof_ipc4_widget_setup_comp_process()
890 ret = sof_ipc4_widget_setup_msg(swidget, &process->msg); in sof_ipc4_widget_setup_comp_process()
895 fw_module = swidget->module_info; in sof_ipc4_widget_setup_comp_process()
896 process->init_config = FIELD_GET(SOF_IPC4_MODULE_INIT_CONFIG_MASK, in sof_ipc4_widget_setup_comp_process()
897 fw_module->man4_module_entry.type); in sof_ipc4_widget_setup_comp_process()
899 process->ipc_config_size = sizeof(struct sof_ipc4_base_module_cfg); in sof_ipc4_widget_setup_comp_process()
902 if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) { in sof_ipc4_widget_setup_comp_process()
905 size_add(swidget->num_input_pins, in sof_ipc4_widget_setup_comp_process()
906 swidget->num_output_pins)); in sof_ipc4_widget_setup_comp_process()
910 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_process()
914 base_cfg_ext->num_input_pin_fmts = swidget->num_input_pins; in sof_ipc4_widget_setup_comp_process()
915 base_cfg_ext->num_output_pin_fmts = swidget->num_output_pins; in sof_ipc4_widget_setup_comp_process()
916 process->base_config_ext = base_cfg_ext; in sof_ipc4_widget_setup_comp_process()
917 process->base_config_ext_size = ext_size; in sof_ipc4_widget_setup_comp_process()
918 process->ipc_config_size += ext_size; in sof_ipc4_widget_setup_comp_process()
921 cfg = kzalloc(process->ipc_config_size, GFP_KERNEL); in sof_ipc4_widget_setup_comp_process()
923 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_process()
927 process->ipc_config_data = cfg; in sof_ipc4_widget_setup_comp_process()
932 spipe->core_mask |= BIT(swidget->core); in sof_ipc4_widget_setup_comp_process()
936 kfree(process->base_config_ext); in sof_ipc4_widget_setup_comp_process()
937 process->base_config_ext = NULL; in sof_ipc4_widget_setup_comp_process()
939 sof_ipc4_free_audio_fmt(&process->available_fmt); in sof_ipc4_widget_setup_comp_process()
942 swidget->private = NULL; in sof_ipc4_widget_setup_comp_process()
948 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_widget_free_comp_process()
953 kfree(process->ipc_config_data); in sof_ipc4_widget_free_comp_process()
954 kfree(process->base_config_ext); in sof_ipc4_widget_free_comp_process()
955 sof_ipc4_free_audio_fmt(&process->available_fmt); in sof_ipc4_widget_free_comp_process()
956 kfree(swidget->private); in sof_ipc4_widget_free_comp_process()
957 swidget->private = NULL; in sof_ipc4_widget_free_comp_process()
964 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_update_resource_usage()
970 ibs = base_config->ibs; in sof_ipc4_update_resource_usage()
971 bss = base_config->is_pages; in sof_ipc4_update_resource_usage()
976 if (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_LL) { in sof_ipc4_update_resource_usage()
990 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_update_resource_usage()
991 pipeline = pipe_widget->private; in sof_ipc4_update_resource_usage()
992 pipeline->mem_usage += total; in sof_ipc4_update_resource_usage()
994 /* Update base_config->cpc from the module manifest */ in sof_ipc4_update_resource_usage()
998 dev_dbg(sdev->dev, "%s: ibs / obs: %u / %u, forcing cpc to 0 from %u\n", in sof_ipc4_update_resource_usage()
999 swidget->widget->name, base_config->ibs, base_config->obs, in sof_ipc4_update_resource_usage()
1000 base_config->cpc); in sof_ipc4_update_resource_usage()
1001 base_config->cpc = 0; in sof_ipc4_update_resource_usage()
1003 dev_dbg(sdev->dev, "%s: ibs / obs / cpc: %u / %u / %u\n", in sof_ipc4_update_resource_usage()
1004 swidget->widget->name, base_config->ibs, base_config->obs, in sof_ipc4_update_resource_usage()
1005 base_config->cpc); in sof_ipc4_update_resource_usage()
1012 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_assign_instance_id()
1013 int max_instances = fw_module->man4_module_entry.instance_max_count; in sof_ipc4_widget_assign_instance_id()
1015 swidget->instance_id = ida_alloc_max(&fw_module->m_ida, max_instances, GFP_KERNEL); in sof_ipc4_widget_assign_instance_id()
1016 if (swidget->instance_id < 0) { in sof_ipc4_widget_assign_instance_id()
1017 dev_err(sdev->dev, "failed to assign instance id for widget %s", in sof_ipc4_widget_assign_instance_id()
1018 swidget->widget->name); in sof_ipc4_widget_assign_instance_id()
1019 return swidget->instance_id; in sof_ipc4_widget_assign_instance_id()
1032 int valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_update_hw_params()
1046 dev_err(sdev->dev, "invalid PCM valid_bits %d\n", valid_bits); in sof_ipc4_update_hw_params()
1047 return -EINVAL; in sof_ipc4_update_hw_params()
1054 rate = fmt->sampling_frequency; in sof_ipc4_update_hw_params()
1056 i->min = rate; in sof_ipc4_update_hw_params()
1057 i->max = rate; in sof_ipc4_update_hw_params()
1059 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_update_hw_params()
1061 i->min = channels; in sof_ipc4_update_hw_params()
1062 i->max = channels; in sof_ipc4_update_hw_params()
1075 rate = fmt->sampling_frequency; in sof_ipc4_is_single_format()
1076 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1077 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1084 _rate = fmt->sampling_frequency; in sof_ipc4_is_single_format()
1085 _channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1086 _valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1105 if (!available_fmt->num_output_formats) in sof_ipc4_init_output_audio_fmt()
1106 return -EINVAL; in sof_ipc4_init_output_audio_fmt()
1108 single_format = sof_ipc4_is_single_format(sdev, available_fmt->output_pin_fmts, in sof_ipc4_init_output_audio_fmt()
1109 available_fmt->num_output_formats); in sof_ipc4_init_output_audio_fmt()
1113 base_config->obs = available_fmt->output_pin_fmts[0].buffer_size; in sof_ipc4_init_output_audio_fmt()
1121 for (i = 0; i < available_fmt->num_output_formats; i++) { in sof_ipc4_init_output_audio_fmt()
1124 out_fmt = &available_fmt->output_pin_fmts[i].audio_fmt; in sof_ipc4_init_output_audio_fmt()
1125 _out_rate = out_fmt->sampling_frequency; in sof_ipc4_init_output_audio_fmt()
1126 _out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(out_fmt->fmt_cfg); in sof_ipc4_init_output_audio_fmt()
1127 _out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); in sof_ipc4_init_output_audio_fmt()
1131 base_config->obs = available_fmt->output_pin_fmts[i].buffer_size; in sof_ipc4_init_output_audio_fmt()
1136 return -EINVAL; in sof_ipc4_init_output_audio_fmt()
1149 dev_err(sdev->dev, "invalid pcm frame format %d\n", params_format(params)); in sof_ipc4_get_valid_bits()
1150 return -EINVAL; in sof_ipc4_get_valid_bits()
1160 struct sof_ipc4_pin_format *pin_fmts = available_fmt->input_pin_fmts; in sof_ipc4_init_input_audio_fmt()
1161 u32 pin_fmts_size = available_fmt->num_input_formats; in sof_ipc4_init_input_audio_fmt()
1169 if (!available_fmt->num_input_formats) { in sof_ipc4_init_input_audio_fmt()
1170 dev_err(sdev->dev, "no input formats for %s\n", swidget->widget->name); in sof_ipc4_init_input_audio_fmt()
1171 return -EINVAL; in sof_ipc4_init_input_audio_fmt()
1174 single_format = sof_ipc4_is_single_format(sdev, available_fmt->input_pin_fmts, in sof_ipc4_init_input_audio_fmt()
1175 available_fmt->num_input_formats); in sof_ipc4_init_input_audio_fmt()
1193 rate = fmt->sampling_frequency; in sof_ipc4_init_input_audio_fmt()
1194 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_init_input_audio_fmt()
1195 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_init_input_audio_fmt()
1198 dev_dbg(sdev->dev, "matched audio format index for %uHz, %ubit, %u channels: %d\n", in sof_ipc4_init_input_audio_fmt()
1205 dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n", in sof_ipc4_init_input_audio_fmt()
1207 return -EINVAL; in sof_ipc4_init_input_audio_fmt()
1212 if (available_fmt->num_input_formats && i < available_fmt->num_input_formats) { in sof_ipc4_init_input_audio_fmt()
1213 memcpy(&base_config->audio_fmt, &available_fmt->input_pin_fmts[i].audio_fmt, in sof_ipc4_init_input_audio_fmt()
1217 base_config->ibs = available_fmt->input_pin_fmts[i].buffer_size; in sof_ipc4_init_input_audio_fmt()
1219 dev_dbg(sdev->dev, "Init input audio formats for %s\n", swidget->widget->name); in sof_ipc4_init_input_audio_fmt()
1220 sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->input_pin_fmts[i], 1); in sof_ipc4_init_input_audio_fmt()
1233 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_unprepare_copier_module()
1234 pipeline = pipe_widget->private; in sof_ipc4_unprepare_copier_module()
1235 pipeline->mem_usage = 0; in sof_ipc4_unprepare_copier_module()
1237 if (WIDGET_IS_AIF(swidget->id) || swidget->id == snd_soc_dapm_buffer) { in sof_ipc4_unprepare_copier_module()
1238 if (pipeline->use_chain_dma) { in sof_ipc4_unprepare_copier_module()
1239 pipeline->msg.primary = 0; in sof_ipc4_unprepare_copier_module()
1240 pipeline->msg.extension = 0; in sof_ipc4_unprepare_copier_module()
1242 ipc4_copier = swidget->private; in sof_ipc4_unprepare_copier_module()
1243 } else if (WIDGET_IS_DAI(swidget->id)) { in sof_ipc4_unprepare_copier_module()
1244 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_unprepare_copier_module() local
1246 ipc4_copier = dai->private; in sof_ipc4_unprepare_copier_module()
1248 if (pipeline->use_chain_dma) { in sof_ipc4_unprepare_copier_module()
1249 pipeline->msg.primary = 0; in sof_ipc4_unprepare_copier_module()
1250 pipeline->msg.extension = 0; in sof_ipc4_unprepare_copier_module()
1253 if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { in sof_ipc4_unprepare_copier_module()
1254 struct sof_ipc4_copier_data *copier_data = &ipc4_copier->data; in sof_ipc4_unprepare_copier_module()
1258 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; in sof_ipc4_unprepare_copier_module()
1259 if (blob->alh_cfg.device_count > 1) { in sof_ipc4_unprepare_copier_module()
1260 group_id = SOF_IPC4_NODE_INDEX(ipc4_copier->data.gtw_cfg.node_id) - in sof_ipc4_unprepare_copier_module()
1266 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_unprepare_copier_module()
1271 kfree(ipc4_copier->ipc_config_data); in sof_ipc4_unprepare_copier_module()
1272 ipc4_copier->ipc_config_data = NULL; in sof_ipc4_unprepare_copier_module()
1273 ipc4_copier->ipc_config_size = 0; in sof_ipc4_unprepare_copier_module()
1278 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
1287 /* get current hw_config from link */ in snd_sof_get_hw_config_params()
1288 list_for_each_entry(slink, &sdev->dai_link_list, list) { in snd_sof_get_hw_config_params()
1289 if (!strcmp(slink->link->name, dai->name)) { in snd_sof_get_hw_config_params()
1296 dev_err(sdev->dev, "%s: no DAI link found for DAI %s\n", __func__, dai->name); in snd_sof_get_hw_config_params()
1297 return -EINVAL; in snd_sof_get_hw_config_params()
1300 for (i = 0; i < slink->num_hw_configs; i++) { in snd_sof_get_hw_config_params()
1301 hw_config = &slink->hw_configs[i]; in snd_sof_get_hw_config_params()
1302 if (dai->current_config == le32_to_cpu(hw_config->id)) { in snd_sof_get_hw_config_params()
1309 dev_err(sdev->dev, "%s: no matching hw_config found for DAI %s\n", __func__, in snd_sof_get_hw_config_params()
1310 dai->name); in snd_sof_get_hw_config_params()
1311 return -EINVAL; in snd_sof_get_hw_config_params()
1314 *bit_depth = le32_to_cpu(hw_config->tdm_slot_width); in snd_sof_get_hw_config_params()
1315 *channel_count = le32_to_cpu(hw_config->tdm_slots); in snd_sof_get_hw_config_params()
1316 *sample_rate = le32_to_cpu(hw_config->fsync_rate); in snd_sof_get_hw_config_params()
1318 dev_dbg(sdev->dev, "sample rate: %d sample width: %d channels: %d\n", in snd_sof_get_hw_config_params()
1324 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
1328 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in snd_sof_get_nhlt_endpoint_data()
1344 ret = snd_sof_get_hw_config_params(sdev, dai, &sample_rate, &channel_count, in snd_sof_get_nhlt_endpoint_data()
1353 dev_dbg(sdev->dev, "dai index %d nhlt type %d direction %d\n", in snd_sof_get_nhlt_endpoint_data()
1357 cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, dai_index, nhlt_type, in snd_sof_get_nhlt_endpoint_data()
1362 dev_err(sdev->dev, in snd_sof_get_nhlt_endpoint_data()
1365 return -EINVAL; in snd_sof_get_nhlt_endpoint_data()
1369 *len = cfg->size >> 2; in snd_sof_get_nhlt_endpoint_data()
1370 *dst = (u32 *)cfg->caps; in snd_sof_get_nhlt_endpoint_data()
1375 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
1392 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_copier_is_single_format()
1399 _valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_copier_is_single_format()
1415 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_copier_module()
1420 struct snd_sof_dai *dai; in sof_ipc4_prepare_copier_module() local
1432 dev_dbg(sdev->dev, "copier %s, type %d", swidget->widget->name, swidget->id); in sof_ipc4_prepare_copier_module()
1434 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1444 SOF_COPIER_DEEP_BUFFER_TOKENS, swidget->tuples, in sof_ipc4_prepare_copier_module()
1445 swidget->num_tuples, sizeof(u32), 1); in sof_ipc4_prepare_copier_module()
1447 dev_err(scomp->dev, "Failed to parse deep buffer dma size for %s\n", in sof_ipc4_prepare_copier_module()
1448 swidget->widget->name); in sof_ipc4_prepare_copier_module()
1452 ipc4_copier = (struct sof_ipc4_copier *)swidget->private; in sof_ipc4_prepare_copier_module()
1453 gtw_attr = ipc4_copier->gtw_attr; in sof_ipc4_prepare_copier_module()
1454 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1455 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1457 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_prepare_copier_module()
1458 pipeline = pipe_widget->private; in sof_ipc4_prepare_copier_module()
1460 if (pipeline->use_chain_dma) { in sof_ipc4_prepare_copier_module()
1464 host_dma_id = platform_params->stream_tag - 1; in sof_ipc4_prepare_copier_module()
1465 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_HOST_ID(host_dma_id); in sof_ipc4_prepare_copier_module()
1469 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK; in sof_ipc4_prepare_copier_module()
1479 pipeline->msg.extension |= SOF_IPC4_GLB_EXT_CHAIN_DMA_FIFO_SIZE(fifo_size); in sof_ipc4_prepare_copier_module()
1485 copier_data->gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID; in sof_ipc4_prepare_copier_module()
1499 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_prepare_copier_module()
1500 copier_data->gtw_cfg.node_id |= in sof_ipc4_prepare_copier_module()
1501 SOF_IPC4_NODE_INDEX(platform_params->stream_tag - 1); in sof_ipc4_prepare_copier_module()
1504 gtw_attr->lp_buffer_alloc = pipeline->lp_mode; in sof_ipc4_prepare_copier_module()
1510 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_prepare_copier_module()
1511 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_prepare_copier_module()
1513 if (pipeline->use_chain_dma) in sof_ipc4_prepare_copier_module()
1516 dai = swidget->private; in sof_ipc4_prepare_copier_module()
1518 ipc4_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_prepare_copier_module()
1519 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1520 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1524 * output formats is typically limited to just 1 for the DAI copiers. But when there in sof_ipc4_prepare_copier_module()
1525 * is no format conversion, the DAI copiers input format must match that of the in sof_ipc4_prepare_copier_module()
1533 ret = snd_sof_get_nhlt_endpoint_data(sdev, dai, fe_params, ipc4_copier->dai_index, in sof_ipc4_prepare_copier_module()
1534 ipc4_copier->dai_type, dir, in sof_ipc4_prepare_copier_module()
1535 &ipc4_copier->copier_config, in sof_ipc4_prepare_copier_module()
1536 &copier_data->gtw_cfg.config_length); in sof_ipc4_prepare_copier_module()
1544 ipc4_copier = (struct sof_ipc4_copier *)swidget->private; in sof_ipc4_prepare_copier_module()
1545 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1546 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1552 dev_err(sdev->dev, "unsupported type %d for copier %s", in sof_ipc4_prepare_copier_module()
1553 swidget->id, swidget->widget->name); in sof_ipc4_prepare_copier_module()
1554 return -EINVAL; in sof_ipc4_prepare_copier_module()
1558 ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &copier_data->base_config, ref_params, in sof_ipc4_prepare_copier_module()
1565 available_fmt->output_pin_fmts, in sof_ipc4_prepare_copier_module()
1566 available_fmt->num_output_formats); in sof_ipc4_prepare_copier_module()
1567 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1574 in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; in sof_ipc4_prepare_copier_module()
1575 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_copier_module()
1576 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
1580 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
1598 return -EINVAL; in sof_ipc4_prepare_copier_module()
1608 out_fmt = &available_fmt->output_pin_fmts[0].audio_fmt; in sof_ipc4_prepare_copier_module()
1610 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
1613 dev_dbg(sdev->dev, "copier %s: reference output rate %d, channels %d valid_bits %d\n", in sof_ipc4_prepare_copier_module()
1614 swidget->widget->name, out_ref_rate, out_ref_channels, out_ref_valid_bits); in sof_ipc4_prepare_copier_module()
1616 output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &copier_data->base_config, in sof_ipc4_prepare_copier_module()
1620 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_copier_module()
1621 swidget->widget->name); in sof_ipc4_prepare_copier_module()
1632 memcpy(&copier_data->out_format, in sof_ipc4_prepare_copier_module()
1633 &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt, in sof_ipc4_prepare_copier_module()
1635 dev_dbg(sdev->dev, "Output audio format for %s\n", swidget->widget->name); in sof_ipc4_prepare_copier_module()
1636 sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->output_pin_fmts[output_fmt_index], 1); in sof_ipc4_prepare_copier_module()
1638 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1644 * That's why only ALH dai's blob is set after sof_ipc4_init_input_audio_fmt in sof_ipc4_prepare_copier_module()
1646 if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { in sof_ipc4_prepare_copier_module()
1658 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; in sof_ipc4_prepare_copier_module()
1660 blob->gw_attr.lp_buffer_alloc = 0; in sof_ipc4_prepare_copier_module()
1663 ch_map = copier_data->base_config.audio_fmt.ch_map; in sof_ipc4_prepare_copier_module()
1672 step = ch_count / blob->alh_cfg.device_count; in sof_ipc4_prepare_copier_module()
1673 mask = GENMASK(step - 1, 0); in sof_ipc4_prepare_copier_module()
1675 * Set each gtw_cfg.node_id to blob->alh_cfg.mapping[] in sof_ipc4_prepare_copier_module()
1679 list_for_each_entry(w, &sdev->widget_list, list) { in sof_ipc4_prepare_copier_module()
1680 if (w->widget->sname && in sof_ipc4_prepare_copier_module()
1681 strcmp(w->widget->sname, swidget->widget->sname)) in sof_ipc4_prepare_copier_module()
1684 dai = w->private; in sof_ipc4_prepare_copier_module()
1685 alh_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_prepare_copier_module()
1686 alh_data = &alh_copier->data; in sof_ipc4_prepare_copier_module()
1687 blob->alh_cfg.mapping[i].device = alh_data->gtw_cfg.node_id; in sof_ipc4_prepare_copier_module()
1693 * two DAI's. in sof_ipc4_prepare_copier_module()
1699 if (w->id == snd_soc_dapm_dai_in) in sof_ipc4_prepare_copier_module()
1700 blob->alh_cfg.mapping[i].channel_mask = ch_mask; in sof_ipc4_prepare_copier_module()
1702 blob->alh_cfg.mapping[i].channel_mask = mask << (step * i); in sof_ipc4_prepare_copier_module()
1706 if (blob->alh_cfg.device_count > 1) { in sof_ipc4_prepare_copier_module()
1709 group_id = ida_alloc_max(&alh_group_ida, ALH_MULTI_GTW_COUNT - 1, in sof_ipc4_prepare_copier_module()
1715 /* add multi-gateway base */ in sof_ipc4_prepare_copier_module()
1717 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_prepare_copier_module()
1718 copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(group_id); in sof_ipc4_prepare_copier_module()
1725 ret = sof_ipc4_update_hw_params(sdev, pipeline_params, &copier_data->out_format); in sof_ipc4_prepare_copier_module()
1734 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1736 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
1737 SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.ibs; in sof_ipc4_prepare_copier_module()
1740 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
1742 copier_data->base_config.ibs; in sof_ipc4_prepare_copier_module()
1746 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
1747 SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.obs; in sof_ipc4_prepare_copier_module()
1753 data = &ipc4_copier->copier_config; in sof_ipc4_prepare_copier_module()
1754 ipc_config_size = &ipc4_copier->ipc_config_size; in sof_ipc4_prepare_copier_module()
1755 ipc_config_data = &ipc4_copier->ipc_config_data; in sof_ipc4_prepare_copier_module()
1758 gtw_cfg_config_length = copier_data->gtw_cfg.config_length * 4; in sof_ipc4_prepare_copier_module()
1761 if (ipc4_copier->dma_config_tlv.type == SOF_IPC4_GTW_DMA_CONFIG_ID && in sof_ipc4_prepare_copier_module()
1762 ipc4_copier->dma_config_tlv.length) { in sof_ipc4_prepare_copier_module()
1763 dma_config_tlv_size = sizeof(ipc4_copier->dma_config_tlv) + in sof_ipc4_prepare_copier_module()
1764 ipc4_copier->dma_config_tlv.dma_config.dma_priv_config_size; in sof_ipc4_prepare_copier_module()
1767 if (dma_config_tlv_size != ipc4_copier->dma_config_tlv.length + in sof_ipc4_prepare_copier_module()
1769 dev_err(sdev->dev, "Invalid configuration, TLV size %d length %d\n", in sof_ipc4_prepare_copier_module()
1770 dma_config_tlv_size, ipc4_copier->dma_config_tlv.length); in sof_ipc4_prepare_copier_module()
1771 return -EINVAL; in sof_ipc4_prepare_copier_module()
1777 copier_data->gtw_cfg.config_length += dma_config_tlv_size / 4; in sof_ipc4_prepare_copier_module()
1780 dev_dbg(sdev->dev, "copier %s, IPC size is %d", swidget->widget->name, ipc_size); in sof_ipc4_prepare_copier_module()
1784 return -ENOMEM; in sof_ipc4_prepare_copier_module()
1789 sof_ipc4_update_resource_usage(sdev, swidget, &copier_data->base_config); in sof_ipc4_prepare_copier_module()
1801 &ipc4_copier->dma_config_tlv, dma_config_tlv_size); in sof_ipc4_prepare_copier_module()
1807 copier_data->gtw_cfg.config_length = gtw_cfg_config_length / 4; in sof_ipc4_prepare_copier_module()
1817 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_gain_module()
1819 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_prepare_gain_module()
1820 struct sof_ipc4_available_audio_format *available_fmt = &gain->available_fmt; in sof_ipc4_prepare_gain_module()
1825 ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &gain->data.base_config, in sof_ipc4_prepare_gain_module()
1830 in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; in sof_ipc4_prepare_gain_module()
1831 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_gain_module()
1832 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_gain_module()
1833 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_gain_module()
1835 ret = sof_ipc4_init_output_audio_fmt(sdev, &gain->data.base_config, available_fmt, in sof_ipc4_prepare_gain_module()
1838 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_gain_module()
1839 swidget->widget->name); in sof_ipc4_prepare_gain_module()
1844 sof_ipc4_update_resource_usage(sdev, swidget, &gain->data.base_config); in sof_ipc4_prepare_gain_module()
1854 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_mixer_module()
1856 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_prepare_mixer_module()
1857 struct sof_ipc4_available_audio_format *available_fmt = &mixer->available_fmt; in sof_ipc4_prepare_mixer_module()
1862 ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &mixer->base_config, in sof_ipc4_prepare_mixer_module()
1867 in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; in sof_ipc4_prepare_mixer_module()
1868 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_mixer_module()
1869 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_mixer_module()
1870 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_mixer_module()
1872 ret = sof_ipc4_init_output_audio_fmt(sdev, &mixer->base_config, available_fmt, in sof_ipc4_prepare_mixer_module()
1875 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_mixer_module()
1876 swidget->widget->name); in sof_ipc4_prepare_mixer_module()
1881 sof_ipc4_update_resource_usage(sdev, swidget, &mixer->base_config); in sof_ipc4_prepare_mixer_module()
1891 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_src_module()
1893 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_prepare_src_module()
1894 struct sof_ipc4_available_audio_format *available_fmt = &src->available_fmt; in sof_ipc4_prepare_src_module()
1900 input_format_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, &src->data.base_config, in sof_ipc4_prepare_src_module()
1907 * format, which is restricted to only deal with DAI's with a single format for now. in sof_ipc4_prepare_src_module()
1909 if (dir == SNDRV_PCM_STREAM_PLAYBACK && available_fmt->num_output_formats > 1) { in sof_ipc4_prepare_src_module()
1910 dev_err(sdev->dev, "Invalid number of output formats: %d for SRC %s\n", in sof_ipc4_prepare_src_module()
1911 available_fmt->num_output_formats, swidget->widget->name); in sof_ipc4_prepare_src_module()
1912 return -EINVAL; in sof_ipc4_prepare_src_module()
1919 in_audio_fmt = &available_fmt->input_pin_fmts[input_format_index].audio_fmt; in sof_ipc4_prepare_src_module()
1920 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_audio_fmt->fmt_cfg); in sof_ipc4_prepare_src_module()
1921 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_audio_fmt->fmt_cfg); in sof_ipc4_prepare_src_module()
1930 output_format_index = sof_ipc4_init_output_audio_fmt(sdev, &src->data.base_config, in sof_ipc4_prepare_src_module()
1934 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_src_module()
1935 swidget->widget->name); in sof_ipc4_prepare_src_module()
1940 sof_ipc4_update_resource_usage(sdev, swidget, &src->data.base_config); in sof_ipc4_prepare_src_module()
1942 out_audio_fmt = &available_fmt->output_pin_fmts[output_format_index].audio_fmt; in sof_ipc4_prepare_src_module()
1943 src->data.sink_rate = out_audio_fmt->sampling_frequency; in sof_ipc4_prepare_src_module()
1952 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_process_set_pin_formats()
1953 struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext; in sof_ipc4_process_set_pin_formats()
1954 struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt; in sof_ipc4_process_set_pin_formats()
1956 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_process_set_pin_formats()
1963 num_pins = swidget->num_input_pins; in sof_ipc4_process_set_pin_formats()
1964 format_list_to_search = available_fmt->input_pin_fmts; in sof_ipc4_process_set_pin_formats()
1965 format_list_count = available_fmt->num_input_formats; in sof_ipc4_process_set_pin_formats()
1967 num_pins = swidget->num_output_pins; in sof_ipc4_process_set_pin_formats()
1968 pin_format_offset = swidget->num_input_pins; in sof_ipc4_process_set_pin_formats()
1969 format_list_to_search = available_fmt->output_pin_fmts; in sof_ipc4_process_set_pin_formats()
1970 format_list_count = available_fmt->num_output_formats; in sof_ipc4_process_set_pin_formats()
1974 pin_format = &base_cfg_ext->pin_formats[i]; in sof_ipc4_process_set_pin_formats()
1979 pin_format->buffer_size = process->base_config.ibs; in sof_ipc4_process_set_pin_formats()
1980 pin_format->audio_fmt = process->base_config.audio_fmt; in sof_ipc4_process_set_pin_formats()
1982 pin_format->buffer_size = process->base_config.obs; in sof_ipc4_process_set_pin_formats()
1983 pin_format->audio_fmt = process->output_format; in sof_ipc4_process_set_pin_formats()
1996 if (pin_format_item->pin_index == i - pin_format_offset) { in sof_ipc4_process_set_pin_formats()
2003 dev_err(scomp->dev, "%s pin %d format not found for %s\n", in sof_ipc4_process_set_pin_formats()
2005 i - pin_format_offset, swidget->widget->name); in sof_ipc4_process_set_pin_formats()
2006 return -EINVAL; in sof_ipc4_process_set_pin_formats()
2032 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_process_module()
2034 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_prepare_process_module()
2035 struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt; in sof_ipc4_prepare_process_module()
2038 void *cfg = process->ipc_config_data; in sof_ipc4_prepare_process_module()
2042 ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &process->base_config, in sof_ipc4_prepare_process_module()
2047 in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; in sof_ipc4_prepare_process_module()
2048 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_process_module()
2049 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_process_module()
2050 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_process_module()
2052 output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &process->base_config, in sof_ipc4_prepare_process_module()
2055 if (output_fmt_index < 0 && available_fmt->num_output_formats) { in sof_ipc4_prepare_process_module()
2056 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_process_module()
2057 swidget->widget->name); in sof_ipc4_prepare_process_module()
2062 if (available_fmt->num_output_formats && in sof_ipc4_prepare_process_module()
2063 output_fmt_index < available_fmt->num_output_formats && in sof_ipc4_prepare_process_module()
2064 !available_fmt->output_pin_fmts[output_fmt_index].pin_index) { in sof_ipc4_prepare_process_module()
2065 memcpy(&process->output_format, in sof_ipc4_prepare_process_module()
2066 &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt, in sof_ipc4_prepare_process_module()
2070 ret = sof_ipc4_update_hw_params(sdev, pipeline_params, &process->output_format); in sof_ipc4_prepare_process_module()
2076 sof_ipc4_update_resource_usage(sdev, swidget, &process->base_config); in sof_ipc4_prepare_process_module()
2079 memcpy(cfg, &process->base_config, sizeof(struct sof_ipc4_base_module_cfg)); in sof_ipc4_prepare_process_module()
2082 if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) { in sof_ipc4_prepare_process_module()
2083 struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext; in sof_ipc4_prepare_process_module()
2089 memcpy(cfg, base_cfg_ext, process->base_config_ext_size); in sof_ipc4_prepare_process_module()
2101 scontrol->size = struct_size(control_data, chanv, scontrol->num_channels); in sof_ipc4_control_load_volume()
2103 /* scontrol->ipc_control_data will be freed in sof_control_unload */ in sof_ipc4_control_load_volume()
2104 scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL); in sof_ipc4_control_load_volume()
2105 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_volume()
2106 return -ENOMEM; in sof_ipc4_control_load_volume()
2108 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_volume()
2109 control_data->index = scontrol->index; in sof_ipc4_control_load_volume()
2111 msg = &control_data->msg; in sof_ipc4_control_load_volume()
2112 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_volume()
2113 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_volume()
2114 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_volume()
2116 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_GAIN_PARAM_ID); in sof_ipc4_control_load_volume()
2119 for (i = 0; i < scontrol->num_channels; i++) { in sof_ipc4_control_load_volume()
2120 control_data->chanv[i].channel = i; in sof_ipc4_control_load_volume()
2121 control_data->chanv[i].value = SOF_IPC4_VOL_ZERO_DB; in sof_ipc4_control_load_volume()
2133 if (scontrol->max_size < (sizeof(*control_data) + sizeof(struct sof_abi_hdr))) { in sof_ipc4_control_load_bytes()
2134 dev_err(sdev->dev, "insufficient size for a bytes control %s: %zu.\n", in sof_ipc4_control_load_bytes()
2135 scontrol->name, scontrol->max_size); in sof_ipc4_control_load_bytes()
2136 return -EINVAL; in sof_ipc4_control_load_bytes()
2139 if (scontrol->priv_size > scontrol->max_size - sizeof(*control_data)) { in sof_ipc4_control_load_bytes()
2140 dev_err(sdev->dev, "scontrol %s bytes data size %zu exceeds max %zu.\n", in sof_ipc4_control_load_bytes()
2141 scontrol->name, scontrol->priv_size, in sof_ipc4_control_load_bytes()
2142 scontrol->max_size - sizeof(*control_data)); in sof_ipc4_control_load_bytes()
2143 return -EINVAL; in sof_ipc4_control_load_bytes()
2146 scontrol->size = sizeof(struct sof_ipc4_control_data) + scontrol->priv_size; in sof_ipc4_control_load_bytes()
2148 scontrol->ipc_control_data = kzalloc(scontrol->max_size, GFP_KERNEL); in sof_ipc4_control_load_bytes()
2149 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_bytes()
2150 return -ENOMEM; in sof_ipc4_control_load_bytes()
2152 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_bytes()
2153 control_data->index = scontrol->index; in sof_ipc4_control_load_bytes()
2154 if (scontrol->priv_size > 0) { in sof_ipc4_control_load_bytes()
2155 memcpy(control_data->data, scontrol->priv, scontrol->priv_size); in sof_ipc4_control_load_bytes()
2156 kfree(scontrol->priv); in sof_ipc4_control_load_bytes()
2157 scontrol->priv = NULL; in sof_ipc4_control_load_bytes()
2159 if (control_data->data->magic != SOF_IPC4_ABI_MAGIC) { in sof_ipc4_control_load_bytes()
2160 dev_err(sdev->dev, "Wrong ABI magic (%#x) for control: %s\n", in sof_ipc4_control_load_bytes()
2161 control_data->data->magic, scontrol->name); in sof_ipc4_control_load_bytes()
2162 ret = -EINVAL; in sof_ipc4_control_load_bytes()
2168 if (control_data->data->size + sizeof(struct sof_abi_hdr) != in sof_ipc4_control_load_bytes()
2169 scontrol->priv_size) { in sof_ipc4_control_load_bytes()
2170 dev_err(sdev->dev, "Control %s conflict in bytes %zu vs. priv size %zu.\n", in sof_ipc4_control_load_bytes()
2171 scontrol->name, in sof_ipc4_control_load_bytes()
2172 control_data->data->size + sizeof(struct sof_abi_hdr), in sof_ipc4_control_load_bytes()
2173 scontrol->priv_size); in sof_ipc4_control_load_bytes()
2174 ret = -EINVAL; in sof_ipc4_control_load_bytes()
2179 msg = &control_data->msg; in sof_ipc4_control_load_bytes()
2180 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_bytes()
2181 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_bytes()
2182 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_bytes()
2187 kfree(scontrol->ipc_control_data); in sof_ipc4_control_load_bytes()
2188 scontrol->ipc_control_data = NULL; in sof_ipc4_control_load_bytes()
2194 switch (scontrol->info_type) { in sof_ipc4_control_setup()
2210 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_setup()
2211 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_widget_setup()
2218 switch (swidget->id) { in sof_ipc4_widget_setup()
2220 pipeline = swidget->private; in sof_ipc4_widget_setup()
2222 if (pipeline->use_chain_dma) { in sof_ipc4_widget_setup()
2223 dev_warn(sdev->dev, "use_chain_dma set for scheduler %s", in sof_ipc4_widget_setup()
2224 swidget->widget->name); in sof_ipc4_widget_setup()
2228 dev_dbg(sdev->dev, "pipeline: %d memory pages: %d\n", swidget->pipeline_id, in sof_ipc4_widget_setup()
2229 pipeline->mem_usage); in sof_ipc4_widget_setup()
2231 msg = &pipeline->msg; in sof_ipc4_widget_setup()
2232 msg->primary |= pipeline->mem_usage; in sof_ipc4_widget_setup()
2234 swidget->instance_id = ida_alloc_max(&pipeline_ida, ipc4_data->max_num_pipelines, in sof_ipc4_widget_setup()
2236 if (swidget->instance_id < 0) { in sof_ipc4_widget_setup()
2237 dev_err(sdev->dev, "failed to assign pipeline id for %s: %d\n", in sof_ipc4_widget_setup()
2238 swidget->widget->name, swidget->instance_id); in sof_ipc4_widget_setup()
2239 return swidget->instance_id; in sof_ipc4_widget_setup()
2241 msg->primary &= ~SOF_IPC4_GLB_PIPE_INSTANCE_MASK; in sof_ipc4_widget_setup()
2242 msg->primary |= SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id); in sof_ipc4_widget_setup()
2248 struct sof_ipc4_copier *ipc4_copier = swidget->private; in sof_ipc4_widget_setup()
2250 pipeline = pipe_widget->private; in sof_ipc4_widget_setup()
2251 if (pipeline->use_chain_dma) in sof_ipc4_widget_setup()
2254 ipc_size = ipc4_copier->ipc_config_size; in sof_ipc4_widget_setup()
2255 ipc_data = ipc4_copier->ipc_config_data; in sof_ipc4_widget_setup()
2257 msg = &ipc4_copier->msg; in sof_ipc4_widget_setup()
2263 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_setup() local
2264 struct sof_ipc4_copier *ipc4_copier = dai->private; in sof_ipc4_widget_setup()
2266 pipeline = pipe_widget->private; in sof_ipc4_widget_setup()
2267 if (pipeline->use_chain_dma) in sof_ipc4_widget_setup()
2270 ipc_size = ipc4_copier->ipc_config_size; in sof_ipc4_widget_setup()
2271 ipc_data = ipc4_copier->ipc_config_data; in sof_ipc4_widget_setup()
2273 msg = &ipc4_copier->msg; in sof_ipc4_widget_setup()
2278 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_widget_setup()
2280 ipc_size = sizeof(gain->data); in sof_ipc4_widget_setup()
2281 ipc_data = &gain->data; in sof_ipc4_widget_setup()
2283 msg = &gain->msg; in sof_ipc4_widget_setup()
2288 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_widget_setup()
2290 ipc_size = sizeof(mixer->base_config); in sof_ipc4_widget_setup()
2291 ipc_data = &mixer->base_config; in sof_ipc4_widget_setup()
2293 msg = &mixer->msg; in sof_ipc4_widget_setup()
2298 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_widget_setup()
2300 ipc_size = sizeof(src->data); in sof_ipc4_widget_setup()
2301 ipc_data = &src->data; in sof_ipc4_widget_setup()
2303 msg = &src->msg; in sof_ipc4_widget_setup()
2308 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_widget_setup()
2310 if (!process->ipc_config_size) { in sof_ipc4_widget_setup()
2311 dev_err(sdev->dev, "module %s has no config data!\n", in sof_ipc4_widget_setup()
2312 swidget->widget->name); in sof_ipc4_widget_setup()
2313 return -EINVAL; in sof_ipc4_widget_setup()
2316 ipc_size = process->ipc_config_size; in sof_ipc4_widget_setup()
2317 ipc_data = process->ipc_config_data; in sof_ipc4_widget_setup()
2319 msg = &process->msg; in sof_ipc4_widget_setup()
2323 dev_err(sdev->dev, "widget type %d not supported", swidget->id); in sof_ipc4_widget_setup()
2324 return -EINVAL; in sof_ipc4_widget_setup()
2327 if (swidget->id != snd_soc_dapm_scheduler) { in sof_ipc4_widget_setup()
2330 dev_err(sdev->dev, "failed to assign instance id for %s\n", in sof_ipc4_widget_setup()
2331 swidget->widget->name); in sof_ipc4_widget_setup()
2335 msg->primary &= ~SOF_IPC4_MOD_INSTANCE_MASK; in sof_ipc4_widget_setup()
2336 msg->primary |= SOF_IPC4_MOD_INSTANCE(swidget->instance_id); in sof_ipc4_widget_setup()
2338 msg->extension &= ~SOF_IPC4_MOD_EXT_PARAM_SIZE_MASK; in sof_ipc4_widget_setup()
2339 msg->extension |= ipc_size >> 2; in sof_ipc4_widget_setup()
2341 msg->extension &= ~SOF_IPC4_MOD_EXT_PPL_ID_MASK; in sof_ipc4_widget_setup()
2342 msg->extension |= SOF_IPC4_MOD_EXT_PPL_ID(pipe_widget->instance_id); in sof_ipc4_widget_setup()
2344 dev_dbg(sdev->dev, "Create widget %s instance %d - pipe %d - core %d\n", in sof_ipc4_widget_setup()
2345 swidget->widget->name, swidget->instance_id, swidget->pipeline_id, swidget->core); in sof_ipc4_widget_setup()
2347 msg->data_size = ipc_size; in sof_ipc4_widget_setup()
2348 msg->data_ptr = ipc_data; in sof_ipc4_widget_setup()
2350 ret = sof_ipc_tx_message_no_reply(sdev->ipc, msg, ipc_size); in sof_ipc4_widget_setup()
2352 dev_err(sdev->dev, "failed to create module %s\n", swidget->widget->name); in sof_ipc4_widget_setup()
2354 if (swidget->id != snd_soc_dapm_scheduler) { in sof_ipc4_widget_setup()
2355 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_setup()
2357 ida_free(&fw_module->m_ida, swidget->instance_id); in sof_ipc4_widget_setup()
2359 ida_free(&pipeline_ida, swidget->instance_id); in sof_ipc4_widget_setup()
2368 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_free()
2369 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_widget_free()
2372 mutex_lock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2375 if (swidget->id == snd_soc_dapm_scheduler) { in sof_ipc4_widget_free()
2376 struct sof_ipc4_pipeline *pipeline = swidget->private; in sof_ipc4_widget_free()
2380 if (pipeline->use_chain_dma) { in sof_ipc4_widget_free()
2381 dev_warn(sdev->dev, "use_chain_dma set for scheduler %s", in sof_ipc4_widget_free()
2382 swidget->widget->name); in sof_ipc4_widget_free()
2383 mutex_unlock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2387 header = SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id); in sof_ipc4_widget_free()
2394 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_widget_free()
2396 dev_err(sdev->dev, "failed to free pipeline widget %s\n", in sof_ipc4_widget_free()
2397 swidget->widget->name); in sof_ipc4_widget_free()
2399 pipeline->mem_usage = 0; in sof_ipc4_widget_free()
2400 pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED; in sof_ipc4_widget_free()
2401 ida_free(&pipeline_ida, swidget->instance_id); in sof_ipc4_widget_free()
2402 swidget->instance_id = -EINVAL; in sof_ipc4_widget_free()
2404 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_free()
2405 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_widget_free()
2407 if (!pipeline->use_chain_dma) in sof_ipc4_widget_free()
2408 ida_free(&fw_module->m_ida, swidget->instance_id); in sof_ipc4_widget_free()
2411 mutex_unlock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2429 pin_binding = src_widget->output_pin_binding; in sof_ipc4_get_queue_id()
2430 queue_ida = &src_widget->output_queue_ida; in sof_ipc4_get_queue_id()
2431 num_pins = src_widget->num_output_pins; in sof_ipc4_get_queue_id()
2432 buddy_name = sink_widget->widget->name; in sof_ipc4_get_queue_id()
2435 pin_binding = sink_widget->input_pin_binding; in sof_ipc4_get_queue_id()
2436 queue_ida = &sink_widget->input_queue_ida; in sof_ipc4_get_queue_id()
2437 num_pins = sink_widget->num_input_pins; in sof_ipc4_get_queue_id()
2438 buddy_name = src_widget->widget->name; in sof_ipc4_get_queue_id()
2441 scomp = current_swidget->scomp; in sof_ipc4_get_queue_id()
2444 dev_err(scomp->dev, "invalid %s num_pins: %d for queue allocation for %s\n", in sof_ipc4_get_queue_id()
2446 num_pins, current_swidget->widget->name); in sof_ipc4_get_queue_id()
2447 return -EINVAL; in sof_ipc4_get_queue_id()
2464 dev_err(scomp->dev, "no %s queue id found from pin binding array for %s\n", in sof_ipc4_get_queue_id()
2466 current_swidget->widget->name); in sof_ipc4_get_queue_id()
2467 return -EINVAL; in sof_ipc4_get_queue_id()
2482 pin_binding = swidget->output_pin_binding; in sof_ipc4_put_queue_id()
2483 queue_ida = &swidget->output_queue_ida; in sof_ipc4_put_queue_id()
2484 num_pins = swidget->num_output_pins; in sof_ipc4_put_queue_id()
2486 pin_binding = swidget->input_pin_binding; in sof_ipc4_put_queue_id()
2487 queue_ida = &swidget->input_queue_ida; in sof_ipc4_put_queue_id()
2488 num_pins = swidget->num_input_pins; in sof_ipc4_put_queue_id()
2504 const struct sof_ipc_ops *iops = sdev->ipc->ops; in sof_ipc4_set_copier_sink_format()
2510 dev_dbg(sdev->dev, "%s set copier sink %d format\n", in sof_ipc4_set_copier_sink_format()
2511 src_widget->widget->name, sink_id); in sof_ipc4_set_copier_sink_format()
2513 if (WIDGET_IS_DAI(src_widget->id)) { in sof_ipc4_set_copier_sink_format()
2514 struct snd_sof_dai *dai = src_widget->private; in sof_ipc4_set_copier_sink_format() local
2516 src_config = dai->private; in sof_ipc4_set_copier_sink_format()
2518 src_config = src_widget->private; in sof_ipc4_set_copier_sink_format()
2521 fw_module = src_widget->module_info; in sof_ipc4_set_copier_sink_format()
2524 memcpy(&format.source_fmt, &src_config->audio_fmt, sizeof(format.source_fmt)); in sof_ipc4_set_copier_sink_format()
2528 dev_err(sdev->dev, "Unable to get pin %d format for %s", in sof_ipc4_set_copier_sink_format()
2529 sink_id, sink_widget->widget->name); in sof_ipc4_set_copier_sink_format()
2530 return -EINVAL; in sof_ipc4_set_copier_sink_format()
2538 msg.primary = fw_module->man4_module_entry.id; in sof_ipc4_set_copier_sink_format()
2539 msg.primary |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_set_copier_sink_format()
2546 return iops->set_get_data(sdev, &msg, msg.data_size, true); in sof_ipc4_set_copier_sink_format()
2551 struct snd_sof_widget *src_widget = sroute->src_widget; in sof_ipc4_route_setup()
2552 struct snd_sof_widget *sink_widget = sroute->sink_widget; in sof_ipc4_route_setup()
2553 struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget; in sof_ipc4_route_setup()
2554 struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget; in sof_ipc4_route_setup()
2555 struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info; in sof_ipc4_route_setup()
2556 struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; in sof_ipc4_route_setup()
2557 struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private; in sof_ipc4_route_setup()
2558 struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private; in sof_ipc4_route_setup()
2564 if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma) { in sof_ipc4_route_setup()
2565 if (!src_pipeline->use_chain_dma || !sink_pipeline->use_chain_dma) { in sof_ipc4_route_setup()
2566 dev_err(sdev->dev, in sof_ipc4_route_setup()
2568 src_widget->widget->name, sink_widget->widget->name); in sof_ipc4_route_setup()
2569 return -EINVAL; in sof_ipc4_route_setup()
2575 dev_err(sdev->dev, in sof_ipc4_route_setup()
2576 "cannot bind %s -> %s, no firmware module for: %s%s\n", in sof_ipc4_route_setup()
2577 src_widget->widget->name, sink_widget->widget->name, in sof_ipc4_route_setup()
2581 return -ENODEV; in sof_ipc4_route_setup()
2584 sroute->src_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, in sof_ipc4_route_setup()
2586 if (sroute->src_queue_id < 0) { in sof_ipc4_route_setup()
2587 dev_err(sdev->dev, "failed to get queue ID for source widget: %s\n", in sof_ipc4_route_setup()
2588 src_widget->widget->name); in sof_ipc4_route_setup()
2589 return sroute->src_queue_id; in sof_ipc4_route_setup()
2592 sroute->dst_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, in sof_ipc4_route_setup()
2594 if (sroute->dst_queue_id < 0) { in sof_ipc4_route_setup()
2595 dev_err(sdev->dev, "failed to get queue ID for sink widget: %s\n", in sof_ipc4_route_setup()
2596 sink_widget->widget->name); in sof_ipc4_route_setup()
2597 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, in sof_ipc4_route_setup()
2599 return sroute->dst_queue_id; in sof_ipc4_route_setup()
2603 if (sroute->src_queue_id > 0 && WIDGET_IS_COPIER(src_widget->id)) { in sof_ipc4_route_setup()
2605 sroute->src_queue_id); in sof_ipc4_route_setup()
2607 dev_err(sdev->dev, "failed to set sink format for %s source queue ID %d\n", in sof_ipc4_route_setup()
2608 src_widget->widget->name, sroute->src_queue_id); in sof_ipc4_route_setup()
2613 dev_dbg(sdev->dev, "bind %s:%d -> %s:%d\n", in sof_ipc4_route_setup()
2614 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_setup()
2615 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_setup()
2617 header = src_fw_module->man4_module_entry.id; in sof_ipc4_route_setup()
2618 header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_route_setup()
2623 extension = sink_fw_module->man4_module_entry.id; in sof_ipc4_route_setup()
2624 extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id); in sof_ipc4_route_setup()
2625 extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id); in sof_ipc4_route_setup()
2626 extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id); in sof_ipc4_route_setup()
2631 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_route_setup()
2633 dev_err(sdev->dev, "failed to bind modules %s:%d -> %s:%d\n", in sof_ipc4_route_setup()
2634 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_setup()
2635 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_setup()
2642 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT); in sof_ipc4_route_setup()
2643 sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT); in sof_ipc4_route_setup()
2649 struct snd_sof_widget *src_widget = sroute->src_widget; in sof_ipc4_route_free()
2650 struct snd_sof_widget *sink_widget = sroute->sink_widget; in sof_ipc4_route_free()
2651 struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info; in sof_ipc4_route_free()
2652 struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; in sof_ipc4_route_free()
2654 struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget; in sof_ipc4_route_free()
2655 struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget; in sof_ipc4_route_free()
2656 struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private; in sof_ipc4_route_free()
2657 struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private; in sof_ipc4_route_free()
2662 if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma) in sof_ipc4_route_free()
2665 dev_dbg(sdev->dev, "unbind modules %s:%d -> %s:%d\n", in sof_ipc4_route_free()
2666 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_free()
2667 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_free()
2673 if (src_widget->spipe->pipe_widget == sink_widget->spipe->pipe_widget) in sof_ipc4_route_free()
2676 header = src_fw_module->man4_module_entry.id; in sof_ipc4_route_free()
2677 header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_route_free()
2682 extension = sink_fw_module->man4_module_entry.id; in sof_ipc4_route_free()
2683 extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id); in sof_ipc4_route_free()
2684 extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id); in sof_ipc4_route_free()
2685 extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id); in sof_ipc4_route_free()
2690 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_route_free()
2692 dev_err(sdev->dev, "failed to unbind modules %s:%d -> %s:%d\n", in sof_ipc4_route_free()
2693 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_free()
2694 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_free()
2696 sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT); in sof_ipc4_route_free()
2697 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT); in sof_ipc4_route_free()
2705 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_dai_config()
2706 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_dai_config()
2707 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_dai_config() local
2712 if (!dai || !dai->private) { in sof_ipc4_dai_config()
2713 dev_err(sdev->dev, "Invalid DAI or DAI private data for %s\n", in sof_ipc4_dai_config()
2714 swidget->widget->name); in sof_ipc4_dai_config()
2715 return -EINVAL; in sof_ipc4_dai_config()
2718 ipc4_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_dai_config()
2719 copier_data = &ipc4_copier->data; in sof_ipc4_dai_config()
2724 switch (ipc4_copier->dai_type) { in sof_ipc4_dai_config()
2726 if (pipeline->use_chain_dma) { in sof_ipc4_dai_config()
2727 pipeline->msg.primary &= ~SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK; in sof_ipc4_dai_config()
2728 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID(data->dai_data); in sof_ipc4_dai_config()
2731 gtw_attr = ipc4_copier->gtw_attr; in sof_ipc4_dai_config()
2732 gtw_attr->lp_buffer_alloc = pipeline->lp_mode; in sof_ipc4_dai_config()
2741 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_dai_config()
2742 copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_data); in sof_ipc4_dai_config()
2750 dev_err(sdev->dev, "%s: unsupported dai type %d\n", __func__, in sof_ipc4_dai_config()
2751 ipc4_copier->dai_type); in sof_ipc4_dai_config()
2752 return -EINVAL; in sof_ipc4_dai_config()
2762 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_parse_manifest()
2765 u32 size = le32_to_cpu(man->priv.size); in sof_ipc4_parse_manifest()
2766 u8 *man_ptr = man->priv.data; in sof_ipc4_parse_manifest()
2771 dev_err(scomp->dev, "%s: Invalid topology ABI size: %u\n", in sof_ipc4_parse_manifest()
2773 return -EINVAL; in sof_ipc4_parse_manifest()
2778 dev_info(scomp->dev, in sof_ipc4_parse_manifest()
2780 le16_to_cpu(manifest->abi_major), le16_to_cpu(manifest->abi_minor), in sof_ipc4_parse_manifest()
2781 le16_to_cpu(manifest->abi_patch), in sof_ipc4_parse_manifest()
2790 manifest_tlv = manifest->items; in sof_ipc4_parse_manifest()
2792 for (i = 0; i < le16_to_cpu(manifest->count); i++) { in sof_ipc4_parse_manifest()
2793 len_check += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size); in sof_ipc4_parse_manifest()
2795 return -EINVAL; in sof_ipc4_parse_manifest()
2797 switch (le32_to_cpu(manifest_tlv->type)) { in sof_ipc4_parse_manifest()
2800 if (ipc4_data->nhlt) in sof_ipc4_parse_manifest()
2802 ipc4_data->nhlt = devm_kmemdup(sdev->dev, manifest_tlv->data, in sof_ipc4_parse_manifest()
2803 le32_to_cpu(manifest_tlv->size), GFP_KERNEL); in sof_ipc4_parse_manifest()
2804 if (!ipc4_data->nhlt) in sof_ipc4_parse_manifest()
2805 return -ENOMEM; in sof_ipc4_parse_manifest()
2808 dev_warn(scomp->dev, "Skipping unknown manifest data type %d\n", in sof_ipc4_parse_manifest()
2809 manifest_tlv->type); in sof_ipc4_parse_manifest()
2812 man_ptr += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size); in sof_ipc4_parse_manifest()
2819 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
2821 struct sof_ipc4_copier *ipc4_copier = dai->private; in sof_ipc4_dai_get_clk()
2831 list_for_each_entry(slink, &sdev->dai_link_list, list) { in sof_ipc4_dai_get_clk()
2832 if (!strcmp(slink->link->name, dai->name)) { in sof_ipc4_dai_get_clk()
2839 dev_err(sdev->dev, "no DAI link found for DAI %s\n", dai->name); in sof_ipc4_dai_get_clk()
2840 return -EINVAL; in sof_ipc4_dai_get_clk()
2843 for (i = 0; i < slink->num_hw_configs; i++) { in sof_ipc4_dai_get_clk()
2844 hw_config = &slink->hw_configs[i]; in sof_ipc4_dai_get_clk()
2845 if (dai->current_config == le32_to_cpu(hw_config->id)) { in sof_ipc4_dai_get_clk()
2852 dev_err(sdev->dev, "no matching hw_config found for DAI %s\n", dai->name); in sof_ipc4_dai_get_clk()
2853 return -EINVAL; in sof_ipc4_dai_get_clk()
2856 switch (ipc4_copier->dai_type) { in sof_ipc4_dai_get_clk()
2860 return le32_to_cpu(hw_config->mclk_rate); in sof_ipc4_dai_get_clk()
2862 return le32_to_cpu(hw_config->bclk_rate); in sof_ipc4_dai_get_clk()
2864 dev_err(sdev->dev, "Invalid clk type for SSP %d\n", clk_type); in sof_ipc4_dai_get_clk()
2869 dev_err(sdev->dev, "DAI type %d not supported yet!\n", ipc4_copier->dai_type); in sof_ipc4_dai_get_clk()
2873 return -EINVAL; in sof_ipc4_dai_get_clk()
2892 list_for_each_entry(spcm, &sdev->pcm_list, list) { in sof_ipc4_tear_down_all_pipelines()
2894 struct snd_pcm_substream *substream = spcm->stream[dir].substream; in sof_ipc4_tear_down_all_pipelines()
2896 if (!substream || !substream->runtime || spcm->stream[dir].suspend_ignored) in sof_ipc4_tear_down_all_pipelines()
2899 if (spcm->stream[dir].list) { in sof_ipc4_tear_down_all_pipelines()
2909 static int sof_ipc4_link_setup(struct snd_sof_dev *sdev, struct snd_soc_dai_link *link) in sof_ipc4_link_setup() argument
2911 if (link->no_pcm) in sof_ipc4_link_setup()
2921 link->trigger[SNDRV_PCM_STREAM_PLAYBACK] = SND_SOC_DPCM_TRIGGER_POST; in sof_ipc4_link_setup()
2922 link->trigger[SNDRV_PCM_STREAM_CAPTURE] = SND_SOC_DPCM_TRIGGER_PRE; in sof_ipc4_link_setup()