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"
148 [SOF_DAI_TOKENS] = {"DAI tokens", dai_tokens, ARRAY_SIZE(dai_tokens)},
175 list_for_each_entry(swidget, &sdev->widget_list, list) { in sof_ipc4_find_swidget_by_ids()
176 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_find_swidget_by_ids()
179 if (!swidget->use_count) in sof_ipc4_find_swidget_by_ids()
182 if (fw_module && fw_module->man4_module_entry.id == module_id && in sof_ipc4_find_swidget_by_ids()
183 swidget->instance_id == instance_id) in sof_ipc4_find_swidget_by_ids()
199 pin_fmt[i].pin_index, fmt->sampling_frequency, fmt->bit_depth, fmt->ch_map, in sof_ipc4_dbg_audio_format()
200 fmt->ch_cfg, fmt->interleaving_style, fmt->fmt_cfg, in sof_ipc4_dbg_audio_format()
212 if (swidget->id != snd_soc_dapm_effect) { in sof_ipc4_get_input_pin_audio_fmt()
213 struct sof_ipc4_base_module_cfg *base = swidget->private; in sof_ipc4_get_input_pin_audio_fmt()
215 /* For non-process modules, base module config format is used for all input pins */ in sof_ipc4_get_input_pin_audio_fmt()
216 return &base->audio_fmt; in sof_ipc4_get_input_pin_audio_fmt()
219 process = swidget->private; in sof_ipc4_get_input_pin_audio_fmt()
220 base_cfg_ext = process->base_config_ext; in sof_ipc4_get_input_pin_audio_fmt()
226 for (i = 0; i < base_cfg_ext->num_input_pin_fmts; i++) { in sof_ipc4_get_input_pin_audio_fmt()
227 struct sof_ipc4_pin_format *pin_format = &base_cfg_ext->pin_formats[i]; in sof_ipc4_get_input_pin_audio_fmt()
229 if (pin_format->pin_index == pin_index) in sof_ipc4_get_input_pin_audio_fmt()
230 return &pin_format->audio_fmt; in sof_ipc4_get_input_pin_audio_fmt()
237 * sof_ipc4_get_audio_fmt - get available audio formats from swidget->tuples
255 SOF_AUDIO_FMT_NUM_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
256 swidget->num_tuples, sizeof(*available_fmt), 1); in sof_ipc4_get_audio_fmt()
258 dev_err(scomp->dev, "Failed to parse audio format token count\n"); in sof_ipc4_get_audio_fmt()
262 if (!available_fmt->num_input_formats && !available_fmt->num_output_formats) { in sof_ipc4_get_audio_fmt()
263 dev_err(scomp->dev, "No input/output pin formats set in topology\n"); in sof_ipc4_get_audio_fmt()
264 return -EINVAL; in sof_ipc4_get_audio_fmt()
267 dev_dbg(scomp->dev, in sof_ipc4_get_audio_fmt()
269 available_fmt->num_input_formats, available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
272 ret = sof_update_ipc_object(scomp, module_base_cfg, SOF_COMP_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
273 swidget->num_tuples, sizeof(*module_base_cfg), 1); in sof_ipc4_get_audio_fmt()
275 dev_err(scomp->dev, "parse comp tokens for %s failed, error: %d\n", in sof_ipc4_get_audio_fmt()
276 swidget->widget->name, ret); in sof_ipc4_get_audio_fmt()
280 dev_dbg(scomp->dev, "widget %s: is_pages: %d\n", swidget->widget->name, in sof_ipc4_get_audio_fmt()
281 module_base_cfg->is_pages); in sof_ipc4_get_audio_fmt()
283 if (available_fmt->num_input_formats) { in sof_ipc4_get_audio_fmt()
284 in_format = kcalloc(available_fmt->num_input_formats, in sof_ipc4_get_audio_fmt()
287 return -ENOMEM; in sof_ipc4_get_audio_fmt()
288 available_fmt->input_pin_fmts = in_format; in sof_ipc4_get_audio_fmt()
291 SOF_IN_AUDIO_FORMAT_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
292 swidget->num_tuples, sizeof(*in_format), in sof_ipc4_get_audio_fmt()
293 available_fmt->num_input_formats); in sof_ipc4_get_audio_fmt()
295 dev_err(scomp->dev, "parse input audio fmt tokens failed %d\n", ret); in sof_ipc4_get_audio_fmt()
299 dev_dbg(scomp->dev, "Input audio formats for %s\n", swidget->widget->name); in sof_ipc4_get_audio_fmt()
300 sof_ipc4_dbg_audio_format(scomp->dev, in_format, in sof_ipc4_get_audio_fmt()
301 available_fmt->num_input_formats); in sof_ipc4_get_audio_fmt()
304 if (available_fmt->num_output_formats) { in sof_ipc4_get_audio_fmt()
305 out_format = kcalloc(available_fmt->num_output_formats, sizeof(*out_format), in sof_ipc4_get_audio_fmt()
308 ret = -ENOMEM; in sof_ipc4_get_audio_fmt()
313 SOF_OUT_AUDIO_FORMAT_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
314 swidget->num_tuples, sizeof(*out_format), in sof_ipc4_get_audio_fmt()
315 available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
317 dev_err(scomp->dev, "parse output audio fmt tokens failed\n"); in sof_ipc4_get_audio_fmt()
321 available_fmt->output_pin_fmts = out_format; in sof_ipc4_get_audio_fmt()
322 dev_dbg(scomp->dev, "Output audio formats for %s\n", swidget->widget->name); in sof_ipc4_get_audio_fmt()
323 sof_ipc4_dbg_audio_format(scomp->dev, out_format, in sof_ipc4_get_audio_fmt()
324 available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
333 available_fmt->input_pin_fmts = NULL; in sof_ipc4_get_audio_fmt()
341 kfree(available_fmt->output_pin_fmts); in sof_ipc4_free_audio_fmt()
342 available_fmt->output_pin_fmts = NULL; in sof_ipc4_free_audio_fmt()
343 kfree(available_fmt->input_pin_fmts); in sof_ipc4_free_audio_fmt()
344 available_fmt->input_pin_fmts = NULL; in sof_ipc4_free_audio_fmt()
349 kfree(swidget->private); in sof_ipc4_widget_free_comp_pipeline()
354 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_set_module_info()
357 swidget->module_info = sof_ipc4_find_module_by_uuid(sdev, &swidget->uuid); in sof_ipc4_widget_set_module_info()
359 if (swidget->module_info) in sof_ipc4_widget_set_module_info()
362 dev_err(sdev->dev, "failed to find module info for widget %s with UUID %pUL\n", in sof_ipc4_widget_set_module_info()
363 swidget->widget->name, &swidget->uuid); in sof_ipc4_widget_set_module_info()
364 return -EINVAL; in sof_ipc4_widget_set_module_info()
377 fw_module = swidget->module_info; in sof_ipc4_widget_setup_msg()
379 msg->primary = fw_module->man4_module_entry.id; in sof_ipc4_widget_setup_msg()
380 msg->primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_INIT_INSTANCE); in sof_ipc4_widget_setup_msg()
381 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_widget_setup_msg()
382 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_widget_setup_msg()
384 msg->extension = SOF_IPC4_MOD_EXT_CORE_ID(swidget->core); in sof_ipc4_widget_setup_msg()
386 type = (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_DP) ? 1 : 0; in sof_ipc4_widget_setup_msg()
387 msg->extension |= SOF_IPC4_MOD_EXT_DOMAIN(type); in sof_ipc4_widget_setup_msg()
394 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_update_kcontrol_module_id()
396 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_update_kcontrol_module_id()
400 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { in sof_ipc4_widget_update_kcontrol_module_id()
401 if (scontrol->comp_id == swidget->comp_id) { in sof_ipc4_widget_update_kcontrol_module_id()
402 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; in sof_ipc4_widget_update_kcontrol_module_id()
403 struct sof_ipc4_msg *msg = &cdata->msg; in sof_ipc4_widget_update_kcontrol_module_id()
405 msg->primary |= fw_module->man4_module_entry.id; in sof_ipc4_widget_update_kcontrol_module_id()
413 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_pcm()
420 return -ENOMEM; in sof_ipc4_widget_setup_pcm()
422 swidget->private = ipc4_copier; in sof_ipc4_widget_setup_pcm()
423 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_setup_pcm()
425 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_pcm()
428 &ipc4_copier->data.base_config); in sof_ipc4_widget_setup_pcm()
433 * This callback is used by host copier and module-to-module copier, in sof_ipc4_widget_setup_pcm()
436 if (!WIDGET_IS_AIF(swidget->id)) in sof_ipc4_widget_setup_pcm()
440 SOF_COPIER_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_pcm()
441 swidget->num_tuples, sizeof(node_type), 1); in sof_ipc4_widget_setup_pcm()
444 dev_err(scomp->dev, "parse host copier node type token failed %d\n", in sof_ipc4_widget_setup_pcm()
448 dev_dbg(scomp->dev, "host copier '%s' node_type %u\n", swidget->widget->name, node_type); in sof_ipc4_widget_setup_pcm()
451 ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); in sof_ipc4_widget_setup_pcm()
452 if (!ipc4_copier->gtw_attr) { in sof_ipc4_widget_setup_pcm()
453 ret = -ENOMEM; in sof_ipc4_widget_setup_pcm()
457 ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; in sof_ipc4_widget_setup_pcm()
458 ipc4_copier->data.gtw_cfg.config_length = in sof_ipc4_widget_setup_pcm()
461 switch (swidget->id) { in sof_ipc4_widget_setup_pcm()
464 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); in sof_ipc4_widget_setup_pcm()
467 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID; in sof_ipc4_widget_setup_pcm()
468 ipc4_copier->ipc_config_size = 0; in sof_ipc4_widget_setup_pcm()
471 dev_err(scomp->dev, "invalid widget type %d\n", swidget->id); in sof_ipc4_widget_setup_pcm()
472 ret = -EINVAL; in sof_ipc4_widget_setup_pcm()
477 ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg); in sof_ipc4_widget_setup_pcm()
484 kfree(ipc4_copier->gtw_attr); in sof_ipc4_widget_setup_pcm()
489 swidget->private = NULL; in sof_ipc4_widget_setup_pcm()
495 struct sof_ipc4_copier *ipc4_copier = swidget->private; in sof_ipc4_widget_free_comp_pcm()
501 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_free_comp_pcm()
502 kfree(available_fmt->output_pin_fmts); in sof_ipc4_widget_free_comp_pcm()
503 kfree(ipc4_copier->gtw_attr); in sof_ipc4_widget_free_comp_pcm()
505 swidget->private = NULL; in sof_ipc4_widget_free_comp_pcm()
511 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_dai()
512 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_setup_comp_dai() local
521 return -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
523 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_setup_comp_dai()
525 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_dai()
528 &ipc4_copier->data.base_config); in sof_ipc4_widget_setup_comp_dai()
533 SOF_COPIER_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_dai()
534 swidget->num_tuples, sizeof(node_type), 1); in sof_ipc4_widget_setup_comp_dai()
536 dev_err(scomp->dev, "parse dai node type failed %d\n", ret); in sof_ipc4_widget_setup_comp_dai()
541 SOF_DAI_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_dai()
542 swidget->num_tuples, sizeof(u32), 1); in sof_ipc4_widget_setup_comp_dai()
544 dev_err(scomp->dev, "parse dai copier node token failed %d\n", ret); in sof_ipc4_widget_setup_comp_dai()
548 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()
549 node_type, ipc4_copier->dai_type, ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
551 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); in sof_ipc4_widget_setup_comp_dai()
553 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_setup_comp_dai()
554 pipeline = pipe_widget->private; in sof_ipc4_widget_setup_comp_dai()
555 if (pipeline->use_chain_dma && ipc4_copier->dai_type != SOF_DAI_INTEL_HDA) { in sof_ipc4_widget_setup_comp_dai()
556 dev_err(scomp->dev, in sof_ipc4_widget_setup_comp_dai()
557 "Bad DAI type '%d', Chained DMA is only supported by HDA DAIs (%d).\n", in sof_ipc4_widget_setup_comp_dai()
558 ipc4_copier->dai_type, SOF_DAI_INTEL_HDA); in sof_ipc4_widget_setup_comp_dai()
559 ret = -ENODEV; in sof_ipc4_widget_setup_comp_dai()
563 switch (ipc4_copier->dai_type) { in sof_ipc4_widget_setup_comp_dai()
572 snd_soc_dapm_widget_for_each_source_path(swidget->widget, p) in sof_ipc4_widget_setup_comp_dai()
575 if (swidget->id == snd_soc_dapm_dai_in && src_num == 0) { in sof_ipc4_widget_setup_comp_dai()
579 * It is fine to call kfree(ipc4_copier->copier_config) since in sof_ipc4_widget_setup_comp_dai()
580 * ipc4_copier->copier_config is null. in sof_ipc4_widget_setup_comp_dai()
588 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
592 list_for_each_entry(w, &sdev->widget_list, list) { in sof_ipc4_widget_setup_comp_dai()
593 if (w->widget->sname && in sof_ipc4_widget_setup_comp_dai()
594 strcmp(w->widget->sname, swidget->widget->sname)) in sof_ipc4_widget_setup_comp_dai()
597 blob->alh_cfg.device_count++; in sof_ipc4_widget_setup_comp_dai()
600 ipc4_copier->copier_config = (uint32_t *)blob; in sof_ipc4_widget_setup_comp_dai()
601 ipc4_copier->data.gtw_cfg.config_length = sizeof(*blob) >> 2; in sof_ipc4_widget_setup_comp_dai()
605 /* set SSP DAI index as the node_id */ in sof_ipc4_widget_setup_comp_dai()
606 ipc4_copier->data.gtw_cfg.node_id |= in sof_ipc4_widget_setup_comp_dai()
607 SOF_IPC4_NODE_INDEX_INTEL_SSP(ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
610 /* set DMIC DAI index as the node_id */ in sof_ipc4_widget_setup_comp_dai()
611 ipc4_copier->data.gtw_cfg.node_id |= in sof_ipc4_widget_setup_comp_dai()
612 SOF_IPC4_NODE_INDEX_INTEL_DMIC(ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
615 ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); in sof_ipc4_widget_setup_comp_dai()
616 if (!ipc4_copier->gtw_attr) { in sof_ipc4_widget_setup_comp_dai()
617 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
621 ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; in sof_ipc4_widget_setup_comp_dai()
622 ipc4_copier->data.gtw_cfg.config_length = in sof_ipc4_widget_setup_comp_dai()
627 dai->scomp = scomp; in sof_ipc4_widget_setup_comp_dai()
628 dai->private = ipc4_copier; in sof_ipc4_widget_setup_comp_dai()
631 ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg); in sof_ipc4_widget_setup_comp_dai()
638 kfree(ipc4_copier->copier_config); in sof_ipc4_widget_setup_comp_dai()
643 dai->private = NULL; in sof_ipc4_widget_setup_comp_dai()
644 dai->scomp = NULL; in sof_ipc4_widget_setup_comp_dai()
651 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_free_comp_dai() local
654 if (!dai) in sof_ipc4_widget_free_comp_dai()
657 if (!dai->private) { in sof_ipc4_widget_free_comp_dai()
658 kfree(dai); in sof_ipc4_widget_free_comp_dai()
659 swidget->private = NULL; in sof_ipc4_widget_free_comp_dai()
663 ipc4_copier = dai->private; in sof_ipc4_widget_free_comp_dai()
664 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_free_comp_dai()
666 kfree(available_fmt->output_pin_fmts); in sof_ipc4_widget_free_comp_dai()
667 if (ipc4_copier->dai_type != SOF_DAI_INTEL_SSP && in sof_ipc4_widget_free_comp_dai()
668 ipc4_copier->dai_type != SOF_DAI_INTEL_DMIC) in sof_ipc4_widget_free_comp_dai()
669 kfree(ipc4_copier->copier_config); in sof_ipc4_widget_free_comp_dai()
670 kfree(dai->private); in sof_ipc4_widget_free_comp_dai()
671 kfree(dai); in sof_ipc4_widget_free_comp_dai()
672 swidget->private = NULL; in sof_ipc4_widget_free_comp_dai()
677 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_pipeline()
679 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_pipeline()
684 return -ENOMEM; in sof_ipc4_widget_setup_comp_pipeline()
686 ret = sof_update_ipc_object(scomp, pipeline, SOF_SCHED_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_pipeline()
687 swidget->num_tuples, sizeof(*pipeline), 1); in sof_ipc4_widget_setup_comp_pipeline()
689 dev_err(scomp->dev, "parsing scheduler tokens failed\n"); in sof_ipc4_widget_setup_comp_pipeline()
693 swidget->core = pipeline->core_id; in sof_ipc4_widget_setup_comp_pipeline()
694 spipe->core_mask |= BIT(pipeline->core_id); in sof_ipc4_widget_setup_comp_pipeline()
696 if (pipeline->use_chain_dma) { in sof_ipc4_widget_setup_comp_pipeline()
697 dev_dbg(scomp->dev, "Set up chain DMA for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_pipeline()
698 swidget->private = pipeline; in sof_ipc4_widget_setup_comp_pipeline()
703 ret = sof_update_ipc_object(scomp, swidget, SOF_PIPELINE_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_pipeline()
704 swidget->num_tuples, sizeof(*swidget), 1); in sof_ipc4_widget_setup_comp_pipeline()
706 dev_err(scomp->dev, "parsing pipeline tokens failed\n"); in sof_ipc4_widget_setup_comp_pipeline()
710 dev_dbg(scomp->dev, "pipeline '%s': id %d, pri %d, core_id %u, lp mode %d\n", in sof_ipc4_widget_setup_comp_pipeline()
711 swidget->widget->name, swidget->pipeline_id, in sof_ipc4_widget_setup_comp_pipeline()
712 pipeline->priority, pipeline->core_id, pipeline->lp_mode); in sof_ipc4_widget_setup_comp_pipeline()
714 swidget->private = pipeline; in sof_ipc4_widget_setup_comp_pipeline()
716 pipeline->msg.primary = SOF_IPC4_GLB_PIPE_PRIORITY(pipeline->priority); in sof_ipc4_widget_setup_comp_pipeline()
717 pipeline->msg.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_CREATE_PIPELINE); in sof_ipc4_widget_setup_comp_pipeline()
718 pipeline->msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_widget_setup_comp_pipeline()
719 pipeline->msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG); in sof_ipc4_widget_setup_comp_pipeline()
721 pipeline->msg.extension = pipeline->lp_mode; in sof_ipc4_widget_setup_comp_pipeline()
722 pipeline->msg.extension |= SOF_IPC4_GLB_PIPE_EXT_CORE_ID(pipeline->core_id); in sof_ipc4_widget_setup_comp_pipeline()
723 pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED; in sof_ipc4_widget_setup_comp_pipeline()
733 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_pga()
739 return -ENOMEM; in sof_ipc4_widget_setup_comp_pga()
741 swidget->private = gain; in sof_ipc4_widget_setup_comp_pga()
743 gain->data.params.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK; in sof_ipc4_widget_setup_comp_pga()
744 gain->data.params.init_val = SOF_IPC4_VOL_ZERO_DB; in sof_ipc4_widget_setup_comp_pga()
746 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, &gain->data.base_config); in sof_ipc4_widget_setup_comp_pga()
750 ret = sof_update_ipc_object(scomp, &gain->data.params, SOF_GAIN_TOKENS, in sof_ipc4_widget_setup_comp_pga()
751 swidget->tuples, swidget->num_tuples, sizeof(gain->data), 1); in sof_ipc4_widget_setup_comp_pga()
753 dev_err(scomp->dev, "Parsing gain tokens failed\n"); in sof_ipc4_widget_setup_comp_pga()
757 dev_dbg(scomp->dev, in sof_ipc4_widget_setup_comp_pga()
759 swidget->widget->name, gain->data.params.curve_type, in sof_ipc4_widget_setup_comp_pga()
760 gain->data.params.curve_duration_l, gain->data.params.init_val); in sof_ipc4_widget_setup_comp_pga()
762 ret = sof_ipc4_widget_setup_msg(swidget, &gain->msg); in sof_ipc4_widget_setup_comp_pga()
770 sof_ipc4_free_audio_fmt(&gain->available_fmt); in sof_ipc4_widget_setup_comp_pga()
772 swidget->private = NULL; in sof_ipc4_widget_setup_comp_pga()
778 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_widget_free_comp_pga()
783 sof_ipc4_free_audio_fmt(&gain->available_fmt); in sof_ipc4_widget_free_comp_pga()
784 kfree(swidget->private); in sof_ipc4_widget_free_comp_pga()
785 swidget->private = NULL; in sof_ipc4_widget_free_comp_pga()
790 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_mixer()
794 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_mixer()
798 return -ENOMEM; in sof_ipc4_widget_setup_comp_mixer()
800 swidget->private = mixer; in sof_ipc4_widget_setup_comp_mixer()
802 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &mixer->available_fmt, in sof_ipc4_widget_setup_comp_mixer()
803 &mixer->base_config); in sof_ipc4_widget_setup_comp_mixer()
807 ret = sof_ipc4_widget_setup_msg(swidget, &mixer->msg); in sof_ipc4_widget_setup_comp_mixer()
813 sof_ipc4_free_audio_fmt(&mixer->available_fmt); in sof_ipc4_widget_setup_comp_mixer()
815 swidget->private = NULL; in sof_ipc4_widget_setup_comp_mixer()
821 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_src()
822 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_src()
826 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_src()
830 return -ENOMEM; in sof_ipc4_widget_setup_comp_src()
832 swidget->private = src; in sof_ipc4_widget_setup_comp_src()
834 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt, in sof_ipc4_widget_setup_comp_src()
835 &src->data.base_config); in sof_ipc4_widget_setup_comp_src()
839 ret = sof_update_ipc_object(scomp, &src->data, SOF_SRC_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_src()
840 swidget->num_tuples, sizeof(*src), 1); in sof_ipc4_widget_setup_comp_src()
842 dev_err(scomp->dev, "Parsing SRC tokens failed\n"); in sof_ipc4_widget_setup_comp_src()
846 spipe->core_mask |= BIT(swidget->core); in sof_ipc4_widget_setup_comp_src()
848 dev_dbg(scomp->dev, "SRC sink rate %d\n", src->data.sink_rate); in sof_ipc4_widget_setup_comp_src()
850 ret = sof_ipc4_widget_setup_msg(swidget, &src->msg); in sof_ipc4_widget_setup_comp_src()
856 sof_ipc4_free_audio_fmt(&src->available_fmt); in sof_ipc4_widget_setup_comp_src()
858 swidget->private = NULL; in sof_ipc4_widget_setup_comp_src()
864 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_widget_free_comp_src()
869 sof_ipc4_free_audio_fmt(&src->available_fmt); in sof_ipc4_widget_free_comp_src()
870 kfree(swidget->private); in sof_ipc4_widget_free_comp_src()
871 swidget->private = NULL; in sof_ipc4_widget_free_comp_src()
876 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_widget_free_comp_mixer()
881 sof_ipc4_free_audio_fmt(&mixer->available_fmt); in sof_ipc4_widget_free_comp_mixer()
882 kfree(swidget->private); in sof_ipc4_widget_free_comp_mixer()
883 swidget->private = NULL; in sof_ipc4_widget_free_comp_mixer()
891 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_process()
893 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_process()
900 return -ENOMEM; in sof_ipc4_widget_setup_comp_process()
902 swidget->private = process; in sof_ipc4_widget_setup_comp_process()
904 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &process->available_fmt, in sof_ipc4_widget_setup_comp_process()
905 &process->base_config); in sof_ipc4_widget_setup_comp_process()
909 ret = sof_ipc4_widget_setup_msg(swidget, &process->msg); in sof_ipc4_widget_setup_comp_process()
914 fw_module = swidget->module_info; in sof_ipc4_widget_setup_comp_process()
915 process->init_config = FIELD_GET(SOF_IPC4_MODULE_INIT_CONFIG_MASK, in sof_ipc4_widget_setup_comp_process()
916 fw_module->man4_module_entry.type); in sof_ipc4_widget_setup_comp_process()
918 process->ipc_config_size = sizeof(struct sof_ipc4_base_module_cfg); in sof_ipc4_widget_setup_comp_process()
921 if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) { in sof_ipc4_widget_setup_comp_process()
924 size_add(swidget->num_input_pins, in sof_ipc4_widget_setup_comp_process()
925 swidget->num_output_pins)); in sof_ipc4_widget_setup_comp_process()
929 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_process()
933 base_cfg_ext->num_input_pin_fmts = swidget->num_input_pins; in sof_ipc4_widget_setup_comp_process()
934 base_cfg_ext->num_output_pin_fmts = swidget->num_output_pins; in sof_ipc4_widget_setup_comp_process()
935 process->base_config_ext = base_cfg_ext; in sof_ipc4_widget_setup_comp_process()
936 process->base_config_ext_size = ext_size; in sof_ipc4_widget_setup_comp_process()
937 process->ipc_config_size += ext_size; in sof_ipc4_widget_setup_comp_process()
940 cfg = kzalloc(process->ipc_config_size, GFP_KERNEL); in sof_ipc4_widget_setup_comp_process()
942 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_process()
946 process->ipc_config_data = cfg; in sof_ipc4_widget_setup_comp_process()
951 spipe->core_mask |= BIT(swidget->core); in sof_ipc4_widget_setup_comp_process()
955 kfree(process->base_config_ext); in sof_ipc4_widget_setup_comp_process()
956 process->base_config_ext = NULL; in sof_ipc4_widget_setup_comp_process()
958 sof_ipc4_free_audio_fmt(&process->available_fmt); in sof_ipc4_widget_setup_comp_process()
961 swidget->private = NULL; in sof_ipc4_widget_setup_comp_process()
967 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_widget_free_comp_process()
972 kfree(process->ipc_config_data); in sof_ipc4_widget_free_comp_process()
973 kfree(process->base_config_ext); in sof_ipc4_widget_free_comp_process()
974 sof_ipc4_free_audio_fmt(&process->available_fmt); in sof_ipc4_widget_free_comp_process()
975 kfree(swidget->private); in sof_ipc4_widget_free_comp_process()
976 swidget->private = NULL; in sof_ipc4_widget_free_comp_process()
983 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_update_resource_usage()
989 ibs = base_config->ibs; in sof_ipc4_update_resource_usage()
990 bss = base_config->is_pages; in sof_ipc4_update_resource_usage()
995 if (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_LL) { in sof_ipc4_update_resource_usage()
1009 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_update_resource_usage()
1010 pipeline = pipe_widget->private; in sof_ipc4_update_resource_usage()
1011 pipeline->mem_usage += total; in sof_ipc4_update_resource_usage()
1013 /* Update base_config->cpc from the module manifest */ in sof_ipc4_update_resource_usage()
1017 dev_dbg(sdev->dev, "%s: ibs / obs: %u / %u, forcing cpc to 0 from %u\n", in sof_ipc4_update_resource_usage()
1018 swidget->widget->name, base_config->ibs, base_config->obs, in sof_ipc4_update_resource_usage()
1019 base_config->cpc); in sof_ipc4_update_resource_usage()
1020 base_config->cpc = 0; in sof_ipc4_update_resource_usage()
1022 dev_dbg(sdev->dev, "%s: ibs / obs / cpc: %u / %u / %u\n", in sof_ipc4_update_resource_usage()
1023 swidget->widget->name, base_config->ibs, base_config->obs, in sof_ipc4_update_resource_usage()
1024 base_config->cpc); in sof_ipc4_update_resource_usage()
1031 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_assign_instance_id()
1032 int max_instances = fw_module->man4_module_entry.instance_max_count; in sof_ipc4_widget_assign_instance_id()
1034 swidget->instance_id = ida_alloc_max(&fw_module->m_ida, max_instances, GFP_KERNEL); in sof_ipc4_widget_assign_instance_id()
1035 if (swidget->instance_id < 0) { in sof_ipc4_widget_assign_instance_id()
1036 dev_err(sdev->dev, "failed to assign instance id for widget %s", in sof_ipc4_widget_assign_instance_id()
1037 swidget->widget->name); in sof_ipc4_widget_assign_instance_id()
1038 return swidget->instance_id; in sof_ipc4_widget_assign_instance_id()
1051 int valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_update_hw_params()
1065 dev_err(sdev->dev, "invalid PCM valid_bits %d\n", valid_bits); in sof_ipc4_update_hw_params()
1066 return -EINVAL; in sof_ipc4_update_hw_params()
1073 rate = fmt->sampling_frequency; in sof_ipc4_update_hw_params()
1075 i->min = rate; in sof_ipc4_update_hw_params()
1076 i->max = rate; in sof_ipc4_update_hw_params()
1078 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_update_hw_params()
1080 i->min = channels; in sof_ipc4_update_hw_params()
1081 i->max = channels; in sof_ipc4_update_hw_params()
1094 rate = fmt->sampling_frequency; in sof_ipc4_is_single_format()
1095 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1096 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1103 _rate = fmt->sampling_frequency; in sof_ipc4_is_single_format()
1104 _channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1105 _valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1124 if (!available_fmt->num_output_formats) in sof_ipc4_init_output_audio_fmt()
1125 return -EINVAL; in sof_ipc4_init_output_audio_fmt()
1127 single_format = sof_ipc4_is_single_format(sdev, available_fmt->output_pin_fmts, in sof_ipc4_init_output_audio_fmt()
1128 available_fmt->num_output_formats); in sof_ipc4_init_output_audio_fmt()
1132 base_config->obs = available_fmt->output_pin_fmts[0].buffer_size; in sof_ipc4_init_output_audio_fmt()
1140 for (i = 0; i < available_fmt->num_output_formats; i++) { in sof_ipc4_init_output_audio_fmt()
1143 out_fmt = &available_fmt->output_pin_fmts[i].audio_fmt; in sof_ipc4_init_output_audio_fmt()
1144 _out_rate = out_fmt->sampling_frequency; in sof_ipc4_init_output_audio_fmt()
1145 _out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(out_fmt->fmt_cfg); in sof_ipc4_init_output_audio_fmt()
1146 _out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); in sof_ipc4_init_output_audio_fmt()
1150 base_config->obs = available_fmt->output_pin_fmts[i].buffer_size; in sof_ipc4_init_output_audio_fmt()
1155 return -EINVAL; in sof_ipc4_init_output_audio_fmt()
1168 dev_err(sdev->dev, "invalid pcm frame format %d\n", params_format(params)); in sof_ipc4_get_valid_bits()
1169 return -EINVAL; in sof_ipc4_get_valid_bits()
1179 struct sof_ipc4_pin_format *pin_fmts = available_fmt->input_pin_fmts; in sof_ipc4_init_input_audio_fmt()
1180 u32 pin_fmts_size = available_fmt->num_input_formats; in sof_ipc4_init_input_audio_fmt()
1188 if (!available_fmt->num_input_formats) { in sof_ipc4_init_input_audio_fmt()
1189 dev_err(sdev->dev, "no input formats for %s\n", swidget->widget->name); in sof_ipc4_init_input_audio_fmt()
1190 return -EINVAL; in sof_ipc4_init_input_audio_fmt()
1193 single_format = sof_ipc4_is_single_format(sdev, available_fmt->input_pin_fmts, in sof_ipc4_init_input_audio_fmt()
1194 available_fmt->num_input_formats); in sof_ipc4_init_input_audio_fmt()
1212 rate = fmt->sampling_frequency; in sof_ipc4_init_input_audio_fmt()
1213 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_init_input_audio_fmt()
1214 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_init_input_audio_fmt()
1217 dev_dbg(sdev->dev, "matched audio format index for %uHz, %ubit, %u channels: %d\n", in sof_ipc4_init_input_audio_fmt()
1224 dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n", in sof_ipc4_init_input_audio_fmt()
1226 return -EINVAL; in sof_ipc4_init_input_audio_fmt()
1231 if (available_fmt->num_input_formats && i < available_fmt->num_input_formats) { in sof_ipc4_init_input_audio_fmt()
1232 memcpy(&base_config->audio_fmt, &available_fmt->input_pin_fmts[i].audio_fmt, in sof_ipc4_init_input_audio_fmt()
1236 base_config->ibs = available_fmt->input_pin_fmts[i].buffer_size; in sof_ipc4_init_input_audio_fmt()
1238 dev_dbg(sdev->dev, "Init input audio formats for %s\n", swidget->widget->name); in sof_ipc4_init_input_audio_fmt()
1239 sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->input_pin_fmts[i], 1); in sof_ipc4_init_input_audio_fmt()
1252 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_unprepare_copier_module()
1253 pipeline = pipe_widget->private; in sof_ipc4_unprepare_copier_module()
1254 pipeline->mem_usage = 0; in sof_ipc4_unprepare_copier_module()
1256 if (WIDGET_IS_AIF(swidget->id) || swidget->id == snd_soc_dapm_buffer) { in sof_ipc4_unprepare_copier_module()
1257 if (pipeline->use_chain_dma) { in sof_ipc4_unprepare_copier_module()
1258 pipeline->msg.primary = 0; in sof_ipc4_unprepare_copier_module()
1259 pipeline->msg.extension = 0; in sof_ipc4_unprepare_copier_module()
1261 ipc4_copier = swidget->private; in sof_ipc4_unprepare_copier_module()
1262 } else if (WIDGET_IS_DAI(swidget->id)) { in sof_ipc4_unprepare_copier_module()
1263 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_unprepare_copier_module() local
1265 ipc4_copier = dai->private; in sof_ipc4_unprepare_copier_module()
1267 if (pipeline->use_chain_dma) { in sof_ipc4_unprepare_copier_module()
1268 pipeline->msg.primary = 0; in sof_ipc4_unprepare_copier_module()
1269 pipeline->msg.extension = 0; in sof_ipc4_unprepare_copier_module()
1272 if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { in sof_ipc4_unprepare_copier_module()
1273 struct sof_ipc4_copier_data *copier_data = &ipc4_copier->data; in sof_ipc4_unprepare_copier_module()
1277 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; in sof_ipc4_unprepare_copier_module()
1278 if (blob->alh_cfg.device_count > 1) { in sof_ipc4_unprepare_copier_module()
1279 group_id = SOF_IPC4_NODE_INDEX(ipc4_copier->data.gtw_cfg.node_id) - in sof_ipc4_unprepare_copier_module()
1285 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_unprepare_copier_module()
1290 kfree(ipc4_copier->ipc_config_data); in sof_ipc4_unprepare_copier_module()
1291 ipc4_copier->ipc_config_data = NULL; in sof_ipc4_unprepare_copier_module()
1292 ipc4_copier->ipc_config_size = 0; in sof_ipc4_unprepare_copier_module()
1297 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
1306 /* get current hw_config from link */ in snd_sof_get_hw_config_params()
1307 list_for_each_entry(slink, &sdev->dai_link_list, list) { in snd_sof_get_hw_config_params()
1308 if (!strcmp(slink->link->name, dai->name)) { in snd_sof_get_hw_config_params()
1315 dev_err(sdev->dev, "%s: no DAI link found for DAI %s\n", __func__, dai->name); in snd_sof_get_hw_config_params()
1316 return -EINVAL; in snd_sof_get_hw_config_params()
1319 for (i = 0; i < slink->num_hw_configs; i++) { in snd_sof_get_hw_config_params()
1320 hw_config = &slink->hw_configs[i]; in snd_sof_get_hw_config_params()
1321 if (dai->current_config == le32_to_cpu(hw_config->id)) { in snd_sof_get_hw_config_params()
1328 dev_err(sdev->dev, "%s: no matching hw_config found for DAI %s\n", __func__, in snd_sof_get_hw_config_params()
1329 dai->name); in snd_sof_get_hw_config_params()
1330 return -EINVAL; in snd_sof_get_hw_config_params()
1333 *bit_depth = le32_to_cpu(hw_config->tdm_slot_width); in snd_sof_get_hw_config_params()
1334 *channel_count = le32_to_cpu(hw_config->tdm_slots); in snd_sof_get_hw_config_params()
1335 *sample_rate = le32_to_cpu(hw_config->fsync_rate); in snd_sof_get_hw_config_params()
1337 dev_dbg(sdev->dev, "sample rate: %d sample width: %d channels: %d\n", in snd_sof_get_hw_config_params()
1343 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
1347 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in snd_sof_get_nhlt_endpoint_data()
1363 ret = snd_sof_get_hw_config_params(sdev, dai, &sample_rate, &channel_count, in snd_sof_get_nhlt_endpoint_data()
1372 dev_dbg(sdev->dev, "dai index %d nhlt type %d direction %d\n", in snd_sof_get_nhlt_endpoint_data()
1376 cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, dai_index, nhlt_type, in snd_sof_get_nhlt_endpoint_data()
1381 dev_err(sdev->dev, in snd_sof_get_nhlt_endpoint_data()
1384 return -EINVAL; in snd_sof_get_nhlt_endpoint_data()
1388 *len = cfg->size >> 2; in snd_sof_get_nhlt_endpoint_data()
1389 *dst = (u32 *)cfg->caps; in snd_sof_get_nhlt_endpoint_data()
1394 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
1411 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_copier_is_single_format()
1418 _valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_copier_is_single_format()
1434 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_copier_module()
1439 struct snd_sof_dai *dai; in sof_ipc4_prepare_copier_module() local
1451 dev_dbg(sdev->dev, "copier %s, type %d", swidget->widget->name, swidget->id); in sof_ipc4_prepare_copier_module()
1453 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1463 SOF_COPIER_DEEP_BUFFER_TOKENS, swidget->tuples, in sof_ipc4_prepare_copier_module()
1464 swidget->num_tuples, sizeof(u32), 1); in sof_ipc4_prepare_copier_module()
1466 dev_err(scomp->dev, "Failed to parse deep buffer dma size for %s\n", in sof_ipc4_prepare_copier_module()
1467 swidget->widget->name); in sof_ipc4_prepare_copier_module()
1471 ipc4_copier = (struct sof_ipc4_copier *)swidget->private; in sof_ipc4_prepare_copier_module()
1472 gtw_attr = ipc4_copier->gtw_attr; in sof_ipc4_prepare_copier_module()
1473 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1474 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1476 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_prepare_copier_module()
1477 pipeline = pipe_widget->private; in sof_ipc4_prepare_copier_module()
1479 if (pipeline->use_chain_dma) { in sof_ipc4_prepare_copier_module()
1483 host_dma_id = platform_params->stream_tag - 1; in sof_ipc4_prepare_copier_module()
1484 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_HOST_ID(host_dma_id); in sof_ipc4_prepare_copier_module()
1488 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK; in sof_ipc4_prepare_copier_module()
1498 pipeline->msg.extension |= SOF_IPC4_GLB_EXT_CHAIN_DMA_FIFO_SIZE(fifo_size); in sof_ipc4_prepare_copier_module()
1504 copier_data->gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID; in sof_ipc4_prepare_copier_module()
1518 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_prepare_copier_module()
1519 copier_data->gtw_cfg.node_id |= in sof_ipc4_prepare_copier_module()
1520 SOF_IPC4_NODE_INDEX(platform_params->stream_tag - 1); in sof_ipc4_prepare_copier_module()
1523 gtw_attr->lp_buffer_alloc = pipeline->lp_mode; in sof_ipc4_prepare_copier_module()
1529 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_prepare_copier_module()
1530 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_prepare_copier_module()
1532 if (pipeline->use_chain_dma) in sof_ipc4_prepare_copier_module()
1535 dai = swidget->private; in sof_ipc4_prepare_copier_module()
1537 ipc4_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_prepare_copier_module()
1538 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1539 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1543 * output formats is typically limited to just 1 for the DAI copiers. But when there in sof_ipc4_prepare_copier_module()
1544 * is no format conversion, the DAI copiers input format must match that of the in sof_ipc4_prepare_copier_module()
1552 ret = snd_sof_get_nhlt_endpoint_data(sdev, dai, fe_params, ipc4_copier->dai_index, in sof_ipc4_prepare_copier_module()
1553 ipc4_copier->dai_type, dir, in sof_ipc4_prepare_copier_module()
1554 &ipc4_copier->copier_config, in sof_ipc4_prepare_copier_module()
1555 &copier_data->gtw_cfg.config_length); in sof_ipc4_prepare_copier_module()
1563 ipc4_copier = (struct sof_ipc4_copier *)swidget->private; in sof_ipc4_prepare_copier_module()
1564 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1565 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1571 dev_err(sdev->dev, "unsupported type %d for copier %s", in sof_ipc4_prepare_copier_module()
1572 swidget->id, swidget->widget->name); in sof_ipc4_prepare_copier_module()
1573 return -EINVAL; in sof_ipc4_prepare_copier_module()
1577 ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &copier_data->base_config, ref_params, in sof_ipc4_prepare_copier_module()
1584 available_fmt->output_pin_fmts, in sof_ipc4_prepare_copier_module()
1585 available_fmt->num_output_formats); in sof_ipc4_prepare_copier_module()
1586 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1593 in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; in sof_ipc4_prepare_copier_module()
1594 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_copier_module()
1595 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
1599 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
1617 return -EINVAL; in sof_ipc4_prepare_copier_module()
1627 out_fmt = &available_fmt->output_pin_fmts[0].audio_fmt; in sof_ipc4_prepare_copier_module()
1629 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
1632 dev_dbg(sdev->dev, "copier %s: reference output rate %d, channels %d valid_bits %d\n", in sof_ipc4_prepare_copier_module()
1633 swidget->widget->name, out_ref_rate, out_ref_channels, out_ref_valid_bits); in sof_ipc4_prepare_copier_module()
1635 output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &copier_data->base_config, in sof_ipc4_prepare_copier_module()
1639 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_copier_module()
1640 swidget->widget->name); in sof_ipc4_prepare_copier_module()
1651 memcpy(&copier_data->out_format, in sof_ipc4_prepare_copier_module()
1652 &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt, in sof_ipc4_prepare_copier_module()
1654 dev_dbg(sdev->dev, "Output audio format for %s\n", swidget->widget->name); in sof_ipc4_prepare_copier_module()
1655 sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->output_pin_fmts[output_fmt_index], 1); in sof_ipc4_prepare_copier_module()
1657 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1663 * That's why only ALH dai's blob is set after sof_ipc4_init_input_audio_fmt in sof_ipc4_prepare_copier_module()
1665 if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { in sof_ipc4_prepare_copier_module()
1677 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; in sof_ipc4_prepare_copier_module()
1679 blob->gw_attr.lp_buffer_alloc = 0; in sof_ipc4_prepare_copier_module()
1682 ch_map = copier_data->base_config.audio_fmt.ch_map; in sof_ipc4_prepare_copier_module()
1691 step = ch_count / blob->alh_cfg.device_count; in sof_ipc4_prepare_copier_module()
1692 mask = GENMASK(step - 1, 0); in sof_ipc4_prepare_copier_module()
1694 * Set each gtw_cfg.node_id to blob->alh_cfg.mapping[] in sof_ipc4_prepare_copier_module()
1698 list_for_each_entry(w, &sdev->widget_list, list) { in sof_ipc4_prepare_copier_module()
1699 if (w->widget->sname && in sof_ipc4_prepare_copier_module()
1700 strcmp(w->widget->sname, swidget->widget->sname)) in sof_ipc4_prepare_copier_module()
1703 dai = w->private; in sof_ipc4_prepare_copier_module()
1704 alh_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_prepare_copier_module()
1705 alh_data = &alh_copier->data; in sof_ipc4_prepare_copier_module()
1706 blob->alh_cfg.mapping[i].device = alh_data->gtw_cfg.node_id; in sof_ipc4_prepare_copier_module()
1712 * two DAI's. in sof_ipc4_prepare_copier_module()
1718 if (w->id == snd_soc_dapm_dai_in) in sof_ipc4_prepare_copier_module()
1719 blob->alh_cfg.mapping[i].channel_mask = ch_mask; in sof_ipc4_prepare_copier_module()
1721 blob->alh_cfg.mapping[i].channel_mask = mask << (step * i); in sof_ipc4_prepare_copier_module()
1725 if (blob->alh_cfg.device_count > 1) { in sof_ipc4_prepare_copier_module()
1728 group_id = ida_alloc_max(&alh_group_ida, ALH_MULTI_GTW_COUNT - 1, in sof_ipc4_prepare_copier_module()
1734 /* add multi-gateway base */ in sof_ipc4_prepare_copier_module()
1736 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_prepare_copier_module()
1737 copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(group_id); in sof_ipc4_prepare_copier_module()
1744 ret = sof_ipc4_update_hw_params(sdev, pipeline_params, &copier_data->out_format); in sof_ipc4_prepare_copier_module()
1753 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1755 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
1756 SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.ibs; in sof_ipc4_prepare_copier_module()
1759 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
1761 copier_data->base_config.ibs; in sof_ipc4_prepare_copier_module()
1762 dev_dbg(sdev->dev, "copier %s, dma buffer%s: %u ms (%u bytes)", in sof_ipc4_prepare_copier_module()
1763 swidget->widget->name, in sof_ipc4_prepare_copier_module()
1766 copier_data->gtw_cfg.dma_buffer_size); in sof_ipc4_prepare_copier_module()
1770 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
1771 SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.obs; in sof_ipc4_prepare_copier_module()
1777 data = &ipc4_copier->copier_config; in sof_ipc4_prepare_copier_module()
1778 ipc_config_size = &ipc4_copier->ipc_config_size; in sof_ipc4_prepare_copier_module()
1779 ipc_config_data = &ipc4_copier->ipc_config_data; in sof_ipc4_prepare_copier_module()
1782 gtw_cfg_config_length = copier_data->gtw_cfg.config_length * 4; in sof_ipc4_prepare_copier_module()
1785 if (ipc4_copier->dma_config_tlv.type == SOF_IPC4_GTW_DMA_CONFIG_ID && in sof_ipc4_prepare_copier_module()
1786 ipc4_copier->dma_config_tlv.length) { in sof_ipc4_prepare_copier_module()
1787 dma_config_tlv_size = sizeof(ipc4_copier->dma_config_tlv) + in sof_ipc4_prepare_copier_module()
1788 ipc4_copier->dma_config_tlv.dma_config.dma_priv_config_size; in sof_ipc4_prepare_copier_module()
1791 if (dma_config_tlv_size != ipc4_copier->dma_config_tlv.length + in sof_ipc4_prepare_copier_module()
1793 dev_err(sdev->dev, "Invalid configuration, TLV size %d length %d\n", in sof_ipc4_prepare_copier_module()
1794 dma_config_tlv_size, ipc4_copier->dma_config_tlv.length); in sof_ipc4_prepare_copier_module()
1795 return -EINVAL; in sof_ipc4_prepare_copier_module()
1801 copier_data->gtw_cfg.config_length += dma_config_tlv_size / 4; in sof_ipc4_prepare_copier_module()
1804 dev_dbg(sdev->dev, "copier %s, IPC size is %d", swidget->widget->name, ipc_size); in sof_ipc4_prepare_copier_module()
1808 return -ENOMEM; in sof_ipc4_prepare_copier_module()
1813 sof_ipc4_update_resource_usage(sdev, swidget, &copier_data->base_config); in sof_ipc4_prepare_copier_module()
1825 &ipc4_copier->dma_config_tlv, dma_config_tlv_size); in sof_ipc4_prepare_copier_module()
1831 copier_data->gtw_cfg.config_length = gtw_cfg_config_length / 4; in sof_ipc4_prepare_copier_module()
1841 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_gain_module()
1843 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_prepare_gain_module()
1844 struct sof_ipc4_available_audio_format *available_fmt = &gain->available_fmt; in sof_ipc4_prepare_gain_module()
1849 ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &gain->data.base_config, in sof_ipc4_prepare_gain_module()
1854 in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; in sof_ipc4_prepare_gain_module()
1855 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_gain_module()
1856 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_gain_module()
1857 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_gain_module()
1859 ret = sof_ipc4_init_output_audio_fmt(sdev, &gain->data.base_config, available_fmt, in sof_ipc4_prepare_gain_module()
1862 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_gain_module()
1863 swidget->widget->name); in sof_ipc4_prepare_gain_module()
1868 sof_ipc4_update_resource_usage(sdev, swidget, &gain->data.base_config); in sof_ipc4_prepare_gain_module()
1878 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_mixer_module()
1880 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_prepare_mixer_module()
1881 struct sof_ipc4_available_audio_format *available_fmt = &mixer->available_fmt; in sof_ipc4_prepare_mixer_module()
1886 ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &mixer->base_config, in sof_ipc4_prepare_mixer_module()
1891 in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; in sof_ipc4_prepare_mixer_module()
1892 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_mixer_module()
1893 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_mixer_module()
1894 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_mixer_module()
1896 ret = sof_ipc4_init_output_audio_fmt(sdev, &mixer->base_config, available_fmt, in sof_ipc4_prepare_mixer_module()
1899 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_mixer_module()
1900 swidget->widget->name); in sof_ipc4_prepare_mixer_module()
1905 sof_ipc4_update_resource_usage(sdev, swidget, &mixer->base_config); in sof_ipc4_prepare_mixer_module()
1915 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_src_module()
1917 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_prepare_src_module()
1918 struct sof_ipc4_available_audio_format *available_fmt = &src->available_fmt; in sof_ipc4_prepare_src_module()
1924 input_format_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, &src->data.base_config, in sof_ipc4_prepare_src_module()
1931 * format, which is restricted to only deal with DAI's with a single format for now. in sof_ipc4_prepare_src_module()
1933 if (dir == SNDRV_PCM_STREAM_PLAYBACK && available_fmt->num_output_formats > 1) { in sof_ipc4_prepare_src_module()
1934 dev_err(sdev->dev, "Invalid number of output formats: %d for SRC %s\n", in sof_ipc4_prepare_src_module()
1935 available_fmt->num_output_formats, swidget->widget->name); in sof_ipc4_prepare_src_module()
1936 return -EINVAL; in sof_ipc4_prepare_src_module()
1943 in_audio_fmt = &available_fmt->input_pin_fmts[input_format_index].audio_fmt; in sof_ipc4_prepare_src_module()
1944 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_audio_fmt->fmt_cfg); in sof_ipc4_prepare_src_module()
1945 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_audio_fmt->fmt_cfg); in sof_ipc4_prepare_src_module()
1954 output_format_index = sof_ipc4_init_output_audio_fmt(sdev, &src->data.base_config, in sof_ipc4_prepare_src_module()
1958 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_src_module()
1959 swidget->widget->name); in sof_ipc4_prepare_src_module()
1964 sof_ipc4_update_resource_usage(sdev, swidget, &src->data.base_config); in sof_ipc4_prepare_src_module()
1966 out_audio_fmt = &available_fmt->output_pin_fmts[output_format_index].audio_fmt; in sof_ipc4_prepare_src_module()
1967 src->data.sink_rate = out_audio_fmt->sampling_frequency; in sof_ipc4_prepare_src_module()
1976 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_process_set_pin_formats()
1977 struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext; in sof_ipc4_process_set_pin_formats()
1978 struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt; in sof_ipc4_process_set_pin_formats()
1980 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_process_set_pin_formats()
1987 num_pins = swidget->num_input_pins; in sof_ipc4_process_set_pin_formats()
1988 format_list_to_search = available_fmt->input_pin_fmts; in sof_ipc4_process_set_pin_formats()
1989 format_list_count = available_fmt->num_input_formats; in sof_ipc4_process_set_pin_formats()
1991 num_pins = swidget->num_output_pins; in sof_ipc4_process_set_pin_formats()
1992 pin_format_offset = swidget->num_input_pins; in sof_ipc4_process_set_pin_formats()
1993 format_list_to_search = available_fmt->output_pin_fmts; in sof_ipc4_process_set_pin_formats()
1994 format_list_count = available_fmt->num_output_formats; in sof_ipc4_process_set_pin_formats()
1998 pin_format = &base_cfg_ext->pin_formats[i]; in sof_ipc4_process_set_pin_formats()
2003 pin_format->buffer_size = process->base_config.ibs; in sof_ipc4_process_set_pin_formats()
2004 pin_format->audio_fmt = process->base_config.audio_fmt; in sof_ipc4_process_set_pin_formats()
2006 pin_format->buffer_size = process->base_config.obs; in sof_ipc4_process_set_pin_formats()
2007 pin_format->audio_fmt = process->output_format; in sof_ipc4_process_set_pin_formats()
2020 if (pin_format_item->pin_index == i - pin_format_offset) { in sof_ipc4_process_set_pin_formats()
2027 dev_err(scomp->dev, "%s pin %d format not found for %s\n", in sof_ipc4_process_set_pin_formats()
2029 i - pin_format_offset, swidget->widget->name); in sof_ipc4_process_set_pin_formats()
2030 return -EINVAL; in sof_ipc4_process_set_pin_formats()
2056 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_process_module()
2058 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_prepare_process_module()
2059 struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt; in sof_ipc4_prepare_process_module()
2062 void *cfg = process->ipc_config_data; in sof_ipc4_prepare_process_module()
2066 ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &process->base_config, in sof_ipc4_prepare_process_module()
2071 in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; in sof_ipc4_prepare_process_module()
2072 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_process_module()
2073 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_process_module()
2074 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_process_module()
2076 output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &process->base_config, in sof_ipc4_prepare_process_module()
2079 if (output_fmt_index < 0 && available_fmt->num_output_formats) { in sof_ipc4_prepare_process_module()
2080 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_process_module()
2081 swidget->widget->name); in sof_ipc4_prepare_process_module()
2086 if (available_fmt->num_output_formats && in sof_ipc4_prepare_process_module()
2087 output_fmt_index < available_fmt->num_output_formats && in sof_ipc4_prepare_process_module()
2088 !available_fmt->output_pin_fmts[output_fmt_index].pin_index) { in sof_ipc4_prepare_process_module()
2089 memcpy(&process->output_format, in sof_ipc4_prepare_process_module()
2090 &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt, in sof_ipc4_prepare_process_module()
2094 ret = sof_ipc4_update_hw_params(sdev, pipeline_params, &process->output_format); in sof_ipc4_prepare_process_module()
2100 sof_ipc4_update_resource_usage(sdev, swidget, &process->base_config); in sof_ipc4_prepare_process_module()
2103 memcpy(cfg, &process->base_config, sizeof(struct sof_ipc4_base_module_cfg)); in sof_ipc4_prepare_process_module()
2106 if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) { in sof_ipc4_prepare_process_module()
2107 struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext; in sof_ipc4_prepare_process_module()
2113 memcpy(cfg, base_cfg_ext, process->base_config_ext_size); in sof_ipc4_prepare_process_module()
2125 scontrol->size = struct_size(control_data, chanv, scontrol->num_channels); in sof_ipc4_control_load_volume()
2127 /* scontrol->ipc_control_data will be freed in sof_control_unload */ in sof_ipc4_control_load_volume()
2128 scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL); in sof_ipc4_control_load_volume()
2129 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_volume()
2130 return -ENOMEM; in sof_ipc4_control_load_volume()
2132 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_volume()
2133 control_data->index = scontrol->index; in sof_ipc4_control_load_volume()
2135 msg = &control_data->msg; in sof_ipc4_control_load_volume()
2136 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_volume()
2137 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_volume()
2138 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_volume()
2140 /* volume controls with range 0-1 (off/on) are switch controls */ in sof_ipc4_control_load_volume()
2141 if (scontrol->max == 1) in sof_ipc4_control_load_volume()
2142 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_SWITCH_CONTROL_PARAM_ID); in sof_ipc4_control_load_volume()
2144 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_GAIN_PARAM_ID); in sof_ipc4_control_load_volume()
2146 for (i = 0; i < scontrol->num_channels; i++) { in sof_ipc4_control_load_volume()
2147 control_data->chanv[i].channel = i; in sof_ipc4_control_load_volume()
2150 * - 0dB for volume controls in sof_ipc4_control_load_volume()
2151 * - off (0) for switch controls - value already zero after in sof_ipc4_control_load_volume()
2154 if (scontrol->max > 1) in sof_ipc4_control_load_volume()
2155 control_data->chanv[i].value = SOF_IPC4_VOL_ZERO_DB; in sof_ipc4_control_load_volume()
2167 scontrol->size = struct_size(control_data, chanv, scontrol->num_channels); in sof_ipc4_control_load_enum()
2169 /* scontrol->ipc_control_data will be freed in sof_control_unload */ in sof_ipc4_control_load_enum()
2170 scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL); in sof_ipc4_control_load_enum()
2171 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_enum()
2172 return -ENOMEM; in sof_ipc4_control_load_enum()
2174 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_enum()
2175 control_data->index = scontrol->index; in sof_ipc4_control_load_enum()
2177 msg = &control_data->msg; in sof_ipc4_control_load_enum()
2178 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_enum()
2179 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_enum()
2180 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_enum()
2182 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_ENUM_CONTROL_PARAM_ID); in sof_ipc4_control_load_enum()
2185 for (i = 0; i < scontrol->num_channels; i++) in sof_ipc4_control_load_enum()
2186 control_data->chanv[i].channel = i; in sof_ipc4_control_load_enum()
2197 if (scontrol->max_size < (sizeof(*control_data) + sizeof(struct sof_abi_hdr))) { in sof_ipc4_control_load_bytes()
2198 dev_err(sdev->dev, "insufficient size for a bytes control %s: %zu.\n", in sof_ipc4_control_load_bytes()
2199 scontrol->name, scontrol->max_size); in sof_ipc4_control_load_bytes()
2200 return -EINVAL; in sof_ipc4_control_load_bytes()
2203 if (scontrol->priv_size > scontrol->max_size - sizeof(*control_data)) { in sof_ipc4_control_load_bytes()
2204 dev_err(sdev->dev, "scontrol %s bytes data size %zu exceeds max %zu.\n", in sof_ipc4_control_load_bytes()
2205 scontrol->name, scontrol->priv_size, in sof_ipc4_control_load_bytes()
2206 scontrol->max_size - sizeof(*control_data)); in sof_ipc4_control_load_bytes()
2207 return -EINVAL; in sof_ipc4_control_load_bytes()
2210 scontrol->size = sizeof(struct sof_ipc4_control_data) + scontrol->priv_size; in sof_ipc4_control_load_bytes()
2212 scontrol->ipc_control_data = kzalloc(scontrol->max_size, GFP_KERNEL); in sof_ipc4_control_load_bytes()
2213 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_bytes()
2214 return -ENOMEM; in sof_ipc4_control_load_bytes()
2216 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_bytes()
2217 control_data->index = scontrol->index; in sof_ipc4_control_load_bytes()
2218 if (scontrol->priv_size > 0) { in sof_ipc4_control_load_bytes()
2219 memcpy(control_data->data, scontrol->priv, scontrol->priv_size); in sof_ipc4_control_load_bytes()
2220 kfree(scontrol->priv); in sof_ipc4_control_load_bytes()
2221 scontrol->priv = NULL; in sof_ipc4_control_load_bytes()
2223 if (control_data->data->magic != SOF_IPC4_ABI_MAGIC) { in sof_ipc4_control_load_bytes()
2224 dev_err(sdev->dev, "Wrong ABI magic (%#x) for control: %s\n", in sof_ipc4_control_load_bytes()
2225 control_data->data->magic, scontrol->name); in sof_ipc4_control_load_bytes()
2226 ret = -EINVAL; in sof_ipc4_control_load_bytes()
2232 if (control_data->data->size + sizeof(struct sof_abi_hdr) != in sof_ipc4_control_load_bytes()
2233 scontrol->priv_size) { in sof_ipc4_control_load_bytes()
2234 dev_err(sdev->dev, "Control %s conflict in bytes %zu vs. priv size %zu.\n", in sof_ipc4_control_load_bytes()
2235 scontrol->name, in sof_ipc4_control_load_bytes()
2236 control_data->data->size + sizeof(struct sof_abi_hdr), in sof_ipc4_control_load_bytes()
2237 scontrol->priv_size); in sof_ipc4_control_load_bytes()
2238 ret = -EINVAL; in sof_ipc4_control_load_bytes()
2243 msg = &control_data->msg; in sof_ipc4_control_load_bytes()
2244 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_bytes()
2245 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_bytes()
2246 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_bytes()
2251 kfree(scontrol->ipc_control_data); in sof_ipc4_control_load_bytes()
2252 scontrol->ipc_control_data = NULL; in sof_ipc4_control_load_bytes()
2258 switch (scontrol->info_type) { in sof_ipc4_control_setup()
2277 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_setup()
2278 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_widget_setup()
2285 switch (swidget->id) { in sof_ipc4_widget_setup()
2287 pipeline = swidget->private; in sof_ipc4_widget_setup()
2289 if (pipeline->use_chain_dma) { in sof_ipc4_widget_setup()
2290 dev_warn(sdev->dev, "use_chain_dma set for scheduler %s", in sof_ipc4_widget_setup()
2291 swidget->widget->name); in sof_ipc4_widget_setup()
2295 dev_dbg(sdev->dev, "pipeline: %d memory pages: %d\n", swidget->pipeline_id, in sof_ipc4_widget_setup()
2296 pipeline->mem_usage); in sof_ipc4_widget_setup()
2298 msg = &pipeline->msg; in sof_ipc4_widget_setup()
2299 msg->primary |= pipeline->mem_usage; in sof_ipc4_widget_setup()
2301 swidget->instance_id = ida_alloc_max(&pipeline_ida, ipc4_data->max_num_pipelines, in sof_ipc4_widget_setup()
2303 if (swidget->instance_id < 0) { in sof_ipc4_widget_setup()
2304 dev_err(sdev->dev, "failed to assign pipeline id for %s: %d\n", in sof_ipc4_widget_setup()
2305 swidget->widget->name, swidget->instance_id); in sof_ipc4_widget_setup()
2306 return swidget->instance_id; in sof_ipc4_widget_setup()
2308 msg->primary &= ~SOF_IPC4_GLB_PIPE_INSTANCE_MASK; in sof_ipc4_widget_setup()
2309 msg->primary |= SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id); in sof_ipc4_widget_setup()
2315 struct sof_ipc4_copier *ipc4_copier = swidget->private; in sof_ipc4_widget_setup()
2317 pipeline = pipe_widget->private; in sof_ipc4_widget_setup()
2318 if (pipeline->use_chain_dma) in sof_ipc4_widget_setup()
2321 ipc_size = ipc4_copier->ipc_config_size; in sof_ipc4_widget_setup()
2322 ipc_data = ipc4_copier->ipc_config_data; in sof_ipc4_widget_setup()
2324 msg = &ipc4_copier->msg; in sof_ipc4_widget_setup()
2330 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_setup() local
2331 struct sof_ipc4_copier *ipc4_copier = dai->private; in sof_ipc4_widget_setup()
2333 pipeline = pipe_widget->private; in sof_ipc4_widget_setup()
2334 if (pipeline->use_chain_dma) in sof_ipc4_widget_setup()
2337 ipc_size = ipc4_copier->ipc_config_size; in sof_ipc4_widget_setup()
2338 ipc_data = ipc4_copier->ipc_config_data; in sof_ipc4_widget_setup()
2340 msg = &ipc4_copier->msg; in sof_ipc4_widget_setup()
2345 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_widget_setup()
2347 ipc_size = sizeof(gain->data); in sof_ipc4_widget_setup()
2348 ipc_data = &gain->data; in sof_ipc4_widget_setup()
2350 msg = &gain->msg; in sof_ipc4_widget_setup()
2355 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_widget_setup()
2357 ipc_size = sizeof(mixer->base_config); in sof_ipc4_widget_setup()
2358 ipc_data = &mixer->base_config; in sof_ipc4_widget_setup()
2360 msg = &mixer->msg; in sof_ipc4_widget_setup()
2365 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_widget_setup()
2367 ipc_size = sizeof(src->data); in sof_ipc4_widget_setup()
2368 ipc_data = &src->data; in sof_ipc4_widget_setup()
2370 msg = &src->msg; in sof_ipc4_widget_setup()
2375 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_widget_setup()
2377 if (!process->ipc_config_size) { in sof_ipc4_widget_setup()
2378 dev_err(sdev->dev, "module %s has no config data!\n", in sof_ipc4_widget_setup()
2379 swidget->widget->name); in sof_ipc4_widget_setup()
2380 return -EINVAL; in sof_ipc4_widget_setup()
2383 ipc_size = process->ipc_config_size; in sof_ipc4_widget_setup()
2384 ipc_data = process->ipc_config_data; in sof_ipc4_widget_setup()
2386 msg = &process->msg; in sof_ipc4_widget_setup()
2390 dev_err(sdev->dev, "widget type %d not supported", swidget->id); in sof_ipc4_widget_setup()
2391 return -EINVAL; in sof_ipc4_widget_setup()
2394 if (swidget->id != snd_soc_dapm_scheduler) { in sof_ipc4_widget_setup()
2395 int module_id = msg->primary & SOF_IPC4_MOD_ID_MASK; in sof_ipc4_widget_setup()
2399 dev_err(sdev->dev, "failed to assign instance id for %s\n", in sof_ipc4_widget_setup()
2400 swidget->widget->name); in sof_ipc4_widget_setup()
2404 msg->primary &= ~SOF_IPC4_MOD_INSTANCE_MASK; in sof_ipc4_widget_setup()
2405 msg->primary |= SOF_IPC4_MOD_INSTANCE(swidget->instance_id); in sof_ipc4_widget_setup()
2407 msg->extension &= ~SOF_IPC4_MOD_EXT_PARAM_SIZE_MASK; in sof_ipc4_widget_setup()
2408 msg->extension |= ipc_size >> 2; in sof_ipc4_widget_setup()
2410 msg->extension &= ~SOF_IPC4_MOD_EXT_PPL_ID_MASK; in sof_ipc4_widget_setup()
2411 msg->extension |= SOF_IPC4_MOD_EXT_PPL_ID(pipe_widget->instance_id); in sof_ipc4_widget_setup()
2413 dev_dbg(sdev->dev, "Create widget %s (pipe %d) - ID %d, instance %d, core %d\n", in sof_ipc4_widget_setup()
2414 swidget->widget->name, swidget->pipeline_id, module_id, in sof_ipc4_widget_setup()
2415 swidget->instance_id, swidget->core); in sof_ipc4_widget_setup()
2417 dev_dbg(sdev->dev, "Create pipeline %s (pipe %d) - instance %d, core %d\n", in sof_ipc4_widget_setup()
2418 swidget->widget->name, swidget->pipeline_id, in sof_ipc4_widget_setup()
2419 swidget->instance_id, swidget->core); in sof_ipc4_widget_setup()
2422 msg->data_size = ipc_size; in sof_ipc4_widget_setup()
2423 msg->data_ptr = ipc_data; in sof_ipc4_widget_setup()
2425 ret = sof_ipc_tx_message_no_reply(sdev->ipc, msg, ipc_size); in sof_ipc4_widget_setup()
2427 dev_err(sdev->dev, "failed to create module %s\n", swidget->widget->name); in sof_ipc4_widget_setup()
2429 if (swidget->id != snd_soc_dapm_scheduler) { in sof_ipc4_widget_setup()
2430 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_setup()
2432 ida_free(&fw_module->m_ida, swidget->instance_id); in sof_ipc4_widget_setup()
2434 ida_free(&pipeline_ida, swidget->instance_id); in sof_ipc4_widget_setup()
2443 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_free()
2444 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_widget_free()
2447 mutex_lock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2450 if (swidget->id == snd_soc_dapm_scheduler) { in sof_ipc4_widget_free()
2451 struct sof_ipc4_pipeline *pipeline = swidget->private; in sof_ipc4_widget_free()
2455 if (pipeline->use_chain_dma) { in sof_ipc4_widget_free()
2456 dev_warn(sdev->dev, "use_chain_dma set for scheduler %s", in sof_ipc4_widget_free()
2457 swidget->widget->name); in sof_ipc4_widget_free()
2458 mutex_unlock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2462 header = SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id); in sof_ipc4_widget_free()
2467 msg.primary = header; in sof_ipc4_widget_free()
2469 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_widget_free()
2471 dev_err(sdev->dev, "failed to free pipeline widget %s\n", in sof_ipc4_widget_free()
2472 swidget->widget->name); in sof_ipc4_widget_free()
2474 pipeline->mem_usage = 0; in sof_ipc4_widget_free()
2475 pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED; in sof_ipc4_widget_free()
2476 ida_free(&pipeline_ida, swidget->instance_id); in sof_ipc4_widget_free()
2477 swidget->instance_id = -EINVAL; in sof_ipc4_widget_free()
2479 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_free()
2480 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_widget_free()
2482 if (!pipeline->use_chain_dma) in sof_ipc4_widget_free()
2483 ida_free(&fw_module->m_ida, swidget->instance_id); in sof_ipc4_widget_free()
2486 mutex_unlock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2504 pin_binding = src_widget->output_pin_binding; in sof_ipc4_get_queue_id()
2505 queue_ida = &src_widget->output_queue_ida; in sof_ipc4_get_queue_id()
2506 num_pins = src_widget->num_output_pins; in sof_ipc4_get_queue_id()
2507 buddy_name = sink_widget->widget->name; in sof_ipc4_get_queue_id()
2510 pin_binding = sink_widget->input_pin_binding; in sof_ipc4_get_queue_id()
2511 queue_ida = &sink_widget->input_queue_ida; in sof_ipc4_get_queue_id()
2512 num_pins = sink_widget->num_input_pins; in sof_ipc4_get_queue_id()
2513 buddy_name = src_widget->widget->name; in sof_ipc4_get_queue_id()
2516 scomp = current_swidget->scomp; in sof_ipc4_get_queue_id()
2519 dev_err(scomp->dev, "invalid %s num_pins: %d for queue allocation for %s\n", in sof_ipc4_get_queue_id()
2521 num_pins, current_swidget->widget->name); in sof_ipc4_get_queue_id()
2522 return -EINVAL; in sof_ipc4_get_queue_id()
2539 dev_err(scomp->dev, "no %s queue id found from pin binding array for %s\n", in sof_ipc4_get_queue_id()
2541 current_swidget->widget->name); in sof_ipc4_get_queue_id()
2542 return -EINVAL; in sof_ipc4_get_queue_id()
2557 pin_binding = swidget->output_pin_binding; in sof_ipc4_put_queue_id()
2558 queue_ida = &swidget->output_queue_ida; in sof_ipc4_put_queue_id()
2559 num_pins = swidget->num_output_pins; in sof_ipc4_put_queue_id()
2561 pin_binding = swidget->input_pin_binding; in sof_ipc4_put_queue_id()
2562 queue_ida = &swidget->input_queue_ida; in sof_ipc4_put_queue_id()
2563 num_pins = swidget->num_input_pins; in sof_ipc4_put_queue_id()
2579 const struct sof_ipc_ops *iops = sdev->ipc->ops; in sof_ipc4_set_copier_sink_format()
2585 dev_dbg(sdev->dev, "%s set copier sink %d format\n", in sof_ipc4_set_copier_sink_format()
2586 src_widget->widget->name, sink_id); in sof_ipc4_set_copier_sink_format()
2588 if (WIDGET_IS_DAI(src_widget->id)) { in sof_ipc4_set_copier_sink_format()
2589 struct snd_sof_dai *dai = src_widget->private; in sof_ipc4_set_copier_sink_format() local
2591 src_config = dai->private; in sof_ipc4_set_copier_sink_format()
2593 src_config = src_widget->private; in sof_ipc4_set_copier_sink_format()
2596 fw_module = src_widget->module_info; in sof_ipc4_set_copier_sink_format()
2599 memcpy(&format.source_fmt, &src_config->audio_fmt, sizeof(format.source_fmt)); in sof_ipc4_set_copier_sink_format()
2603 dev_err(sdev->dev, "Unable to get pin %d format for %s", in sof_ipc4_set_copier_sink_format()
2604 sink_id, sink_widget->widget->name); in sof_ipc4_set_copier_sink_format()
2605 return -EINVAL; in sof_ipc4_set_copier_sink_format()
2613 msg.primary = fw_module->man4_module_entry.id; in sof_ipc4_set_copier_sink_format()
2614 msg.primary |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_set_copier_sink_format()
2615 msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_set_copier_sink_format()
2616 msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_set_copier_sink_format()
2621 return iops->set_get_data(sdev, &msg, msg.data_size, true); in sof_ipc4_set_copier_sink_format()
2626 struct snd_sof_widget *src_widget = sroute->src_widget; in sof_ipc4_route_setup()
2627 struct snd_sof_widget *sink_widget = sroute->sink_widget; in sof_ipc4_route_setup()
2628 struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget; in sof_ipc4_route_setup()
2629 struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget; in sof_ipc4_route_setup()
2630 struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info; in sof_ipc4_route_setup()
2631 struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; in sof_ipc4_route_setup()
2632 struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private; in sof_ipc4_route_setup()
2633 struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private; in sof_ipc4_route_setup()
2639 if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma) { in sof_ipc4_route_setup()
2640 if (!src_pipeline->use_chain_dma || !sink_pipeline->use_chain_dma) { in sof_ipc4_route_setup()
2641 dev_err(sdev->dev, in sof_ipc4_route_setup()
2643 src_widget->widget->name, sink_widget->widget->name); in sof_ipc4_route_setup()
2644 return -EINVAL; in sof_ipc4_route_setup()
2650 dev_err(sdev->dev, in sof_ipc4_route_setup()
2651 "cannot bind %s -> %s, no firmware module for: %s%s\n", in sof_ipc4_route_setup()
2652 src_widget->widget->name, sink_widget->widget->name, in sof_ipc4_route_setup()
2656 return -ENODEV; in sof_ipc4_route_setup()
2659 sroute->src_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, in sof_ipc4_route_setup()
2661 if (sroute->src_queue_id < 0) { in sof_ipc4_route_setup()
2662 dev_err(sdev->dev, "failed to get queue ID for source widget: %s\n", in sof_ipc4_route_setup()
2663 src_widget->widget->name); in sof_ipc4_route_setup()
2664 return sroute->src_queue_id; in sof_ipc4_route_setup()
2667 sroute->dst_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, in sof_ipc4_route_setup()
2669 if (sroute->dst_queue_id < 0) { in sof_ipc4_route_setup()
2670 dev_err(sdev->dev, "failed to get queue ID for sink widget: %s\n", in sof_ipc4_route_setup()
2671 sink_widget->widget->name); in sof_ipc4_route_setup()
2672 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, in sof_ipc4_route_setup()
2674 return sroute->dst_queue_id; in sof_ipc4_route_setup()
2678 if (sroute->src_queue_id > 0 && WIDGET_IS_COPIER(src_widget->id)) { in sof_ipc4_route_setup()
2680 sroute->src_queue_id); in sof_ipc4_route_setup()
2682 dev_err(sdev->dev, "failed to set sink format for %s source queue ID %d\n", in sof_ipc4_route_setup()
2683 src_widget->widget->name, sroute->src_queue_id); in sof_ipc4_route_setup()
2688 dev_dbg(sdev->dev, "bind %s:%d -> %s:%d\n", in sof_ipc4_route_setup()
2689 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_setup()
2690 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_setup()
2692 header = src_fw_module->man4_module_entry.id; in sof_ipc4_route_setup()
2693 header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_route_setup()
2698 extension = sink_fw_module->man4_module_entry.id; in sof_ipc4_route_setup()
2699 extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id); in sof_ipc4_route_setup()
2700 extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id); in sof_ipc4_route_setup()
2701 extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id); in sof_ipc4_route_setup()
2703 msg.primary = header; in sof_ipc4_route_setup()
2706 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_route_setup()
2708 dev_err(sdev->dev, "failed to bind modules %s:%d -> %s:%d\n", in sof_ipc4_route_setup()
2709 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_setup()
2710 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_setup()
2717 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT); in sof_ipc4_route_setup()
2718 sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT); in sof_ipc4_route_setup()
2724 struct snd_sof_widget *src_widget = sroute->src_widget; in sof_ipc4_route_free()
2725 struct snd_sof_widget *sink_widget = sroute->sink_widget; in sof_ipc4_route_free()
2726 struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info; in sof_ipc4_route_free()
2727 struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; in sof_ipc4_route_free()
2729 struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget; in sof_ipc4_route_free()
2730 struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget; in sof_ipc4_route_free()
2731 struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private; in sof_ipc4_route_free()
2732 struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private; in sof_ipc4_route_free()
2737 if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma) in sof_ipc4_route_free()
2740 dev_dbg(sdev->dev, "unbind modules %s:%d -> %s:%d\n", in sof_ipc4_route_free()
2741 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_free()
2742 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_free()
2748 if (src_widget->spipe->pipe_widget == sink_widget->spipe->pipe_widget) in sof_ipc4_route_free()
2751 header = src_fw_module->man4_module_entry.id; in sof_ipc4_route_free()
2752 header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_route_free()
2757 extension = sink_fw_module->man4_module_entry.id; in sof_ipc4_route_free()
2758 extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id); in sof_ipc4_route_free()
2759 extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id); in sof_ipc4_route_free()
2760 extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id); in sof_ipc4_route_free()
2762 msg.primary = header; in sof_ipc4_route_free()
2765 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_route_free()
2767 dev_err(sdev->dev, "failed to unbind modules %s:%d -> %s:%d\n", in sof_ipc4_route_free()
2768 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_free()
2769 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_free()
2771 sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT); in sof_ipc4_route_free()
2772 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT); in sof_ipc4_route_free()
2780 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_dai_config()
2781 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_dai_config()
2782 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_dai_config() local
2787 if (!dai || !dai->private) { in sof_ipc4_dai_config()
2788 dev_err(sdev->dev, "Invalid DAI or DAI private data for %s\n", in sof_ipc4_dai_config()
2789 swidget->widget->name); in sof_ipc4_dai_config()
2790 return -EINVAL; in sof_ipc4_dai_config()
2793 ipc4_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_dai_config()
2794 copier_data = &ipc4_copier->data; in sof_ipc4_dai_config()
2799 switch (ipc4_copier->dai_type) { in sof_ipc4_dai_config()
2801 if (pipeline->use_chain_dma) { in sof_ipc4_dai_config()
2802 pipeline->msg.primary &= ~SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK; in sof_ipc4_dai_config()
2803 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID(data->dai_data); in sof_ipc4_dai_config()
2806 gtw_attr = ipc4_copier->gtw_attr; in sof_ipc4_dai_config()
2807 gtw_attr->lp_buffer_alloc = pipeline->lp_mode; in sof_ipc4_dai_config()
2816 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_dai_config()
2817 copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_data); in sof_ipc4_dai_config()
2825 dev_err(sdev->dev, "%s: unsupported dai type %d\n", __func__, in sof_ipc4_dai_config()
2826 ipc4_copier->dai_type); in sof_ipc4_dai_config()
2827 return -EINVAL; in sof_ipc4_dai_config()
2837 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_parse_manifest()
2840 u32 size = le32_to_cpu(man->priv.size); in sof_ipc4_parse_manifest()
2841 u8 *man_ptr = man->priv.data; in sof_ipc4_parse_manifest()
2846 dev_err(scomp->dev, "%s: Invalid topology ABI size: %u\n", in sof_ipc4_parse_manifest()
2848 return -EINVAL; in sof_ipc4_parse_manifest()
2853 dev_info(scomp->dev, in sof_ipc4_parse_manifest()
2855 le16_to_cpu(manifest->abi_major), le16_to_cpu(manifest->abi_minor), in sof_ipc4_parse_manifest()
2856 le16_to_cpu(manifest->abi_patch), in sof_ipc4_parse_manifest()
2865 manifest_tlv = manifest->items; in sof_ipc4_parse_manifest()
2867 for (i = 0; i < le16_to_cpu(manifest->count); i++) { in sof_ipc4_parse_manifest()
2868 len_check += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size); in sof_ipc4_parse_manifest()
2870 return -EINVAL; in sof_ipc4_parse_manifest()
2872 switch (le32_to_cpu(manifest_tlv->type)) { in sof_ipc4_parse_manifest()
2875 if (ipc4_data->nhlt) in sof_ipc4_parse_manifest()
2877 ipc4_data->nhlt = devm_kmemdup(sdev->dev, manifest_tlv->data, in sof_ipc4_parse_manifest()
2878 le32_to_cpu(manifest_tlv->size), GFP_KERNEL); in sof_ipc4_parse_manifest()
2879 if (!ipc4_data->nhlt) in sof_ipc4_parse_manifest()
2880 return -ENOMEM; in sof_ipc4_parse_manifest()
2883 dev_warn(scomp->dev, "Skipping unknown manifest data type %d\n", in sof_ipc4_parse_manifest()
2884 manifest_tlv->type); in sof_ipc4_parse_manifest()
2887 man_ptr += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size); in sof_ipc4_parse_manifest()
2894 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
2896 struct sof_ipc4_copier *ipc4_copier = dai->private; in sof_ipc4_dai_get_clk()
2906 list_for_each_entry(slink, &sdev->dai_link_list, list) { in sof_ipc4_dai_get_clk()
2907 if (!strcmp(slink->link->name, dai->name)) { in sof_ipc4_dai_get_clk()
2914 dev_err(sdev->dev, "no DAI link found for DAI %s\n", dai->name); in sof_ipc4_dai_get_clk()
2915 return -EINVAL; in sof_ipc4_dai_get_clk()
2918 for (i = 0; i < slink->num_hw_configs; i++) { in sof_ipc4_dai_get_clk()
2919 hw_config = &slink->hw_configs[i]; in sof_ipc4_dai_get_clk()
2920 if (dai->current_config == le32_to_cpu(hw_config->id)) { in sof_ipc4_dai_get_clk()
2927 dev_err(sdev->dev, "no matching hw_config found for DAI %s\n", dai->name); in sof_ipc4_dai_get_clk()
2928 return -EINVAL; in sof_ipc4_dai_get_clk()
2931 switch (ipc4_copier->dai_type) { in sof_ipc4_dai_get_clk()
2935 return le32_to_cpu(hw_config->mclk_rate); in sof_ipc4_dai_get_clk()
2937 return le32_to_cpu(hw_config->bclk_rate); in sof_ipc4_dai_get_clk()
2939 dev_err(sdev->dev, "Invalid clk type for SSP %d\n", clk_type); in sof_ipc4_dai_get_clk()
2944 dev_err(sdev->dev, "DAI type %d not supported yet!\n", ipc4_copier->dai_type); in sof_ipc4_dai_get_clk()
2948 return -EINVAL; in sof_ipc4_dai_get_clk()
2967 list_for_each_entry(spcm, &sdev->pcm_list, list) { in sof_ipc4_tear_down_all_pipelines()
2969 struct snd_pcm_substream *substream = spcm->stream[dir].substream; in sof_ipc4_tear_down_all_pipelines()
2971 if (!substream || !substream->runtime || spcm->stream[dir].suspend_ignored) in sof_ipc4_tear_down_all_pipelines()
2974 if (spcm->stream[dir].list) { in sof_ipc4_tear_down_all_pipelines()
2984 static int sof_ipc4_link_setup(struct snd_sof_dev *sdev, struct snd_soc_dai_link *link) in sof_ipc4_link_setup() argument
2986 if (link->no_pcm) in sof_ipc4_link_setup()
2996 link->trigger[SNDRV_PCM_STREAM_PLAYBACK] = SND_SOC_DPCM_TRIGGER_POST; in sof_ipc4_link_setup()
2997 link->trigger[SNDRV_PCM_STREAM_CAPTURE] = SND_SOC_DPCM_TRIGGER_PRE; in sof_ipc4_link_setup()