Lines Matching +full:3 +full:- +full:tuples
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"
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, in sof_ipc4_dbg_audio_format()
200 SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg), in sof_ipc4_dbg_audio_format()
201 fmt->ch_map, fmt->ch_cfg, fmt->interleaving_style, fmt->fmt_cfg, in sof_ipc4_dbg_audio_format()
217 if (!available_fmt->num_input_formats && in sof_ipc4_dbg_module_audio_format()
218 !available_fmt->num_output_formats) in sof_ipc4_dbg_module_audio_format()
222 if (!available_fmt->num_input_formats) { in sof_ipc4_dbg_module_audio_format()
223 if (available_fmt->num_output_formats == 1) in sof_ipc4_dbg_module_audio_format()
225 swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
229 out_fmt_index, swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
231 pin_fmt = &available_fmt->output_pin_fmts[out_fmt_index]; in sof_ipc4_dbg_module_audio_format()
235 } else if (!available_fmt->num_output_formats) { in sof_ipc4_dbg_module_audio_format()
236 if (available_fmt->num_input_formats == 1) in sof_ipc4_dbg_module_audio_format()
238 swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
242 out_fmt_index, swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
244 pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index]; in sof_ipc4_dbg_module_audio_format()
250 in_fmt = &available_fmt->input_pin_fmts[in_fmt_index].audio_fmt; in sof_ipc4_dbg_module_audio_format()
251 out_fmt = &available_fmt->output_pin_fmts[out_fmt_index].audio_fmt; in sof_ipc4_dbg_module_audio_format()
253 in_rate = in_fmt->sampling_frequency; in sof_ipc4_dbg_module_audio_format()
254 in_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_dbg_module_audio_format()
255 in_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_dbg_module_audio_format()
257 out_rate = out_fmt->sampling_frequency; in sof_ipc4_dbg_module_audio_format()
258 out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(out_fmt->fmt_cfg); in sof_ipc4_dbg_module_audio_format()
259 out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); in sof_ipc4_dbg_module_audio_format()
264 if (available_fmt->num_input_formats == 1 && in sof_ipc4_dbg_module_audio_format()
265 available_fmt->num_output_formats == 1) in sof_ipc4_dbg_module_audio_format()
267 swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
271 in_fmt_index, out_fmt_index, swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
273 pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index]; in sof_ipc4_dbg_module_audio_format()
280 if (available_fmt->num_input_formats == 1) in sof_ipc4_dbg_module_audio_format()
282 swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
285 in_fmt_index, swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
287 pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index]; in sof_ipc4_dbg_module_audio_format()
290 if (available_fmt->num_output_formats == 1) in sof_ipc4_dbg_module_audio_format()
292 swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
295 out_fmt_index, swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
297 pin_fmt = &available_fmt->output_pin_fmts[out_fmt_index]; in sof_ipc4_dbg_module_audio_format()
308 if (swidget->id != snd_soc_dapm_effect) { in sof_ipc4_get_input_pin_audio_fmt()
309 struct sof_ipc4_base_module_cfg *base = swidget->private; in sof_ipc4_get_input_pin_audio_fmt()
311 /* For non-process modules, base module config format is used for all input pins */ in sof_ipc4_get_input_pin_audio_fmt()
312 return &base->audio_fmt; in sof_ipc4_get_input_pin_audio_fmt()
315 process = swidget->private; in sof_ipc4_get_input_pin_audio_fmt()
321 if (process->init_config != SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) in sof_ipc4_get_input_pin_audio_fmt()
322 return &process->base_config.audio_fmt; in sof_ipc4_get_input_pin_audio_fmt()
324 base_cfg_ext = process->base_config_ext; in sof_ipc4_get_input_pin_audio_fmt()
330 for (i = 0; i < base_cfg_ext->num_input_pin_fmts; i++) { in sof_ipc4_get_input_pin_audio_fmt()
331 struct sof_ipc4_pin_format *pin_format = &base_cfg_ext->pin_formats[i]; in sof_ipc4_get_input_pin_audio_fmt()
333 if (pin_format->pin_index == pin_index) in sof_ipc4_get_input_pin_audio_fmt()
334 return &pin_format->audio_fmt; in sof_ipc4_get_input_pin_audio_fmt()
341 * sof_ipc4_get_audio_fmt - get available audio formats from swidget->tuples
343 * @swidget: pointer to struct snd_sof_widget containing tuples
359 SOF_AUDIO_FMT_NUM_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
360 swidget->num_tuples, sizeof(*available_fmt), 1); in sof_ipc4_get_audio_fmt()
362 dev_err(scomp->dev, "Failed to parse audio format token count\n"); in sof_ipc4_get_audio_fmt()
366 if (!available_fmt->num_input_formats && !available_fmt->num_output_formats) { in sof_ipc4_get_audio_fmt()
367 dev_err(scomp->dev, "No input/output pin formats set in topology\n"); in sof_ipc4_get_audio_fmt()
368 return -EINVAL; in sof_ipc4_get_audio_fmt()
371 dev_dbg(scomp->dev, in sof_ipc4_get_audio_fmt()
373 available_fmt->num_input_formats, available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
376 ret = sof_update_ipc_object(scomp, module_base_cfg, SOF_COMP_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
377 swidget->num_tuples, sizeof(*module_base_cfg), 1); in sof_ipc4_get_audio_fmt()
379 dev_err(scomp->dev, "parse comp tokens for %s failed, error: %d\n", in sof_ipc4_get_audio_fmt()
380 swidget->widget->name, ret); in sof_ipc4_get_audio_fmt()
384 dev_dbg(scomp->dev, "widget %s: is_pages: %d\n", swidget->widget->name, in sof_ipc4_get_audio_fmt()
385 module_base_cfg->is_pages); in sof_ipc4_get_audio_fmt()
387 if (available_fmt->num_input_formats) { in sof_ipc4_get_audio_fmt()
388 in_format = kcalloc(available_fmt->num_input_formats, in sof_ipc4_get_audio_fmt()
391 return -ENOMEM; in sof_ipc4_get_audio_fmt()
392 available_fmt->input_pin_fmts = in_format; in sof_ipc4_get_audio_fmt()
395 SOF_IN_AUDIO_FORMAT_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
396 swidget->num_tuples, sizeof(*in_format), in sof_ipc4_get_audio_fmt()
397 available_fmt->num_input_formats); in sof_ipc4_get_audio_fmt()
399 dev_err(scomp->dev, "parse input audio fmt tokens failed %d\n", ret); in sof_ipc4_get_audio_fmt()
403 dev_dbg(scomp->dev, "Input audio formats for %s\n", swidget->widget->name); in sof_ipc4_get_audio_fmt()
404 sof_ipc4_dbg_audio_format(scomp->dev, in_format, in sof_ipc4_get_audio_fmt()
405 available_fmt->num_input_formats); in sof_ipc4_get_audio_fmt()
408 if (available_fmt->num_output_formats) { in sof_ipc4_get_audio_fmt()
409 out_format = kcalloc(available_fmt->num_output_formats, sizeof(*out_format), in sof_ipc4_get_audio_fmt()
412 ret = -ENOMEM; in sof_ipc4_get_audio_fmt()
417 SOF_OUT_AUDIO_FORMAT_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
418 swidget->num_tuples, sizeof(*out_format), in sof_ipc4_get_audio_fmt()
419 available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
421 dev_err(scomp->dev, "parse output audio fmt tokens failed\n"); in sof_ipc4_get_audio_fmt()
425 available_fmt->output_pin_fmts = out_format; in sof_ipc4_get_audio_fmt()
426 dev_dbg(scomp->dev, "Output audio formats for %s\n", swidget->widget->name); in sof_ipc4_get_audio_fmt()
427 sof_ipc4_dbg_audio_format(scomp->dev, out_format, in sof_ipc4_get_audio_fmt()
428 available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
437 available_fmt->input_pin_fmts = NULL; in sof_ipc4_get_audio_fmt()
445 kfree(available_fmt->output_pin_fmts); in sof_ipc4_free_audio_fmt()
446 available_fmt->output_pin_fmts = NULL; in sof_ipc4_free_audio_fmt()
447 kfree(available_fmt->input_pin_fmts); in sof_ipc4_free_audio_fmt()
448 available_fmt->input_pin_fmts = NULL; in sof_ipc4_free_audio_fmt()
453 kfree(swidget->private); in sof_ipc4_widget_free_comp_pipeline()
458 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_set_module_info()
461 swidget->module_info = sof_ipc4_find_module_by_uuid(sdev, &swidget->uuid); in sof_ipc4_widget_set_module_info()
463 if (swidget->module_info) in sof_ipc4_widget_set_module_info()
466 dev_err(sdev->dev, "failed to find module info for widget %s with UUID %pUL\n", in sof_ipc4_widget_set_module_info()
467 swidget->widget->name, &swidget->uuid); in sof_ipc4_widget_set_module_info()
468 return -EINVAL; in sof_ipc4_widget_set_module_info()
481 fw_module = swidget->module_info; in sof_ipc4_widget_setup_msg()
483 msg->primary = fw_module->man4_module_entry.id; in sof_ipc4_widget_setup_msg()
484 msg->primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_INIT_INSTANCE); in sof_ipc4_widget_setup_msg()
485 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_widget_setup_msg()
486 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_widget_setup_msg()
488 msg->extension = SOF_IPC4_MOD_EXT_CORE_ID(swidget->core); in sof_ipc4_widget_setup_msg()
490 type = (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_DP) ? 1 : 0; in sof_ipc4_widget_setup_msg()
491 msg->extension |= SOF_IPC4_MOD_EXT_DOMAIN(type); in sof_ipc4_widget_setup_msg()
498 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_update_kcontrol_module_id()
500 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_update_kcontrol_module_id()
504 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { in sof_ipc4_widget_update_kcontrol_module_id()
505 if (scontrol->comp_id == swidget->comp_id) { in sof_ipc4_widget_update_kcontrol_module_id()
506 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; in sof_ipc4_widget_update_kcontrol_module_id()
507 struct sof_ipc4_msg *msg = &cdata->msg; in sof_ipc4_widget_update_kcontrol_module_id()
509 msg->primary |= fw_module->man4_module_entry.id; in sof_ipc4_widget_update_kcontrol_module_id()
518 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_update_card_components_string()
519 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_update_card_components_string()
520 struct snd_soc_component *scomp = spcm->scomp; in sof_ipc4_update_card_components_string()
521 struct snd_soc_card *card = scomp->card; in sof_ipc4_update_card_components_string()
522 const char *pt_marker = "iec61937-pcm"; in sof_ipc4_update_card_components_string()
525 * Update the card's components list with iec61937-pcm and a list of PCM in sof_ipc4_update_card_components_string()
529 if (!pipeline->use_chain_dma) in sof_ipc4_update_card_components_string()
532 if (card->components) { in sof_ipc4_update_card_components_string()
533 const char *tmp = card->components; in sof_ipc4_update_card_components_string()
535 if (strstr(card->components, pt_marker)) in sof_ipc4_update_card_components_string()
536 card->components = devm_kasprintf(card->dev, GFP_KERNEL, in sof_ipc4_update_card_components_string()
538 card->components, in sof_ipc4_update_card_components_string()
539 spcm->pcm.pcm_id); in sof_ipc4_update_card_components_string()
541 card->components = devm_kasprintf(card->dev, GFP_KERNEL, in sof_ipc4_update_card_components_string()
543 card->components, in sof_ipc4_update_card_components_string()
545 spcm->pcm.pcm_id); in sof_ipc4_update_card_components_string()
547 devm_kfree(card->dev, tmp); in sof_ipc4_update_card_components_string()
549 card->components = devm_kasprintf(card->dev, GFP_KERNEL, in sof_ipc4_update_card_components_string()
551 spcm->pcm.pcm_id); in sof_ipc4_update_card_components_string()
554 if (!card->components) in sof_ipc4_update_card_components_string()
555 return -ENOMEM; in sof_ipc4_update_card_components_string()
563 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_pcm()
571 return -ENOMEM; in sof_ipc4_widget_setup_pcm()
573 swidget->private = ipc4_copier; in sof_ipc4_widget_setup_pcm()
574 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_setup_pcm()
576 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_pcm()
579 &ipc4_copier->data.base_config); in sof_ipc4_widget_setup_pcm()
584 * This callback is used by host copier and module-to-module copier, in sof_ipc4_widget_setup_pcm()
587 if (!WIDGET_IS_AIF(swidget->id)) in sof_ipc4_widget_setup_pcm()
591 SOF_COPIER_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_pcm()
592 swidget->num_tuples, sizeof(node_type), 1); in sof_ipc4_widget_setup_pcm()
595 dev_err(scomp->dev, "parse host copier node type token failed %d\n", in sof_ipc4_widget_setup_pcm()
599 dev_dbg(scomp->dev, "host copier '%s' node_type %u\n", swidget->widget->name, node_type); in sof_ipc4_widget_setup_pcm()
601 spcm = snd_sof_find_spcm_comp(scomp, swidget->comp_id, &dir); in sof_ipc4_widget_setup_pcm()
610 struct snd_sof_pcm_stream *sps = &spcm->stream[dir]; in sof_ipc4_widget_setup_pcm()
612 sof_update_ipc_object(scomp, &sps->dsp_max_burst_size_in_ms, in sof_ipc4_widget_setup_pcm()
614 swidget->tuples, in sof_ipc4_widget_setup_pcm()
615 swidget->num_tuples, sizeof(u32), 1); in sof_ipc4_widget_setup_pcm()
617 if (!sps->dsp_max_burst_size_in_ms) in sof_ipc4_widget_setup_pcm()
618 sps->dsp_max_burst_size_in_ms = SOF_IPC4_MIN_DMA_BUFFER_SIZE; in sof_ipc4_widget_setup_pcm()
621 spcm->stream[dir].dsp_max_burst_size_in_ms = 1; in sof_ipc4_widget_setup_pcm()
625 ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); in sof_ipc4_widget_setup_pcm()
626 if (!ipc4_copier->gtw_attr) { in sof_ipc4_widget_setup_pcm()
627 ret = -ENOMEM; in sof_ipc4_widget_setup_pcm()
631 ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; in sof_ipc4_widget_setup_pcm()
632 ipc4_copier->data.gtw_cfg.config_length = in sof_ipc4_widget_setup_pcm()
635 switch (swidget->id) { in sof_ipc4_widget_setup_pcm()
638 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); in sof_ipc4_widget_setup_pcm()
641 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID; in sof_ipc4_widget_setup_pcm()
642 ipc4_copier->ipc_config_size = 0; in sof_ipc4_widget_setup_pcm()
645 dev_err(scomp->dev, "invalid widget type %d\n", swidget->id); in sof_ipc4_widget_setup_pcm()
646 ret = -EINVAL; in sof_ipc4_widget_setup_pcm()
651 ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg); in sof_ipc4_widget_setup_pcm()
658 kfree(ipc4_copier->gtw_attr); in sof_ipc4_widget_setup_pcm()
663 swidget->private = NULL; in sof_ipc4_widget_setup_pcm()
669 struct sof_ipc4_copier *ipc4_copier = swidget->private; in sof_ipc4_widget_free_comp_pcm()
675 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_free_comp_pcm()
676 kfree(available_fmt->output_pin_fmts); in sof_ipc4_widget_free_comp_pcm()
677 kfree(ipc4_copier->gtw_attr); in sof_ipc4_widget_free_comp_pcm()
679 swidget->private = NULL; in sof_ipc4_widget_free_comp_pcm()
685 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_dai()
687 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_setup_comp_dai()
696 return -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
698 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_setup_comp_dai()
700 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_dai()
703 &ipc4_copier->data.base_config); in sof_ipc4_widget_setup_comp_dai()
708 SOF_COPIER_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_dai()
709 swidget->num_tuples, sizeof(node_type), 1); in sof_ipc4_widget_setup_comp_dai()
711 dev_err(scomp->dev, "parse dai node type failed %d\n", ret); in sof_ipc4_widget_setup_comp_dai()
716 SOF_DAI_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_dai()
717 swidget->num_tuples, sizeof(u32), 1); in sof_ipc4_widget_setup_comp_dai()
719 dev_err(scomp->dev, "parse dai copier node token failed %d\n", ret); in sof_ipc4_widget_setup_comp_dai()
723 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()
724 node_type, ipc4_copier->dai_type, ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
726 dai->type = ipc4_copier->dai_type; in sof_ipc4_widget_setup_comp_dai()
727 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); in sof_ipc4_widget_setup_comp_dai()
729 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_setup_comp_dai()
730 pipeline = pipe_widget->private; in sof_ipc4_widget_setup_comp_dai()
732 if (pipeline->use_chain_dma && in sof_ipc4_widget_setup_comp_dai()
733 !snd_sof_is_chain_dma_supported(sdev, ipc4_copier->dai_type)) { in sof_ipc4_widget_setup_comp_dai()
734 dev_err(scomp->dev, "Bad DAI type '%d', Chain DMA is not supported\n", in sof_ipc4_widget_setup_comp_dai()
735 ipc4_copier->dai_type); in sof_ipc4_widget_setup_comp_dai()
736 ret = -ENODEV; in sof_ipc4_widget_setup_comp_dai()
740 switch (ipc4_copier->dai_type) { in sof_ipc4_widget_setup_comp_dai()
748 snd_soc_dapm_widget_for_each_source_path(swidget->widget, p) in sof_ipc4_widget_setup_comp_dai()
751 if (swidget->id == snd_soc_dapm_dai_in && src_num == 0) { in sof_ipc4_widget_setup_comp_dai()
755 * It is fine to call kfree(ipc4_copier->copier_config) since in sof_ipc4_widget_setup_comp_dai()
756 * ipc4_copier->copier_config is null. in sof_ipc4_widget_setup_comp_dai()
763 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
767 list_for_each_entry(w, &sdev->widget_list, list) { in sof_ipc4_widget_setup_comp_dai()
770 if (!WIDGET_IS_DAI(w->id) || !w->widget->sname || in sof_ipc4_widget_setup_comp_dai()
771 strcmp(w->widget->sname, swidget->widget->sname)) in sof_ipc4_widget_setup_comp_dai()
774 alh_dai = w->private; in sof_ipc4_widget_setup_comp_dai()
775 if (alh_dai->type != SOF_DAI_INTEL_ALH) in sof_ipc4_widget_setup_comp_dai()
778 blob->alh_cfg.device_count++; in sof_ipc4_widget_setup_comp_dai()
781 ipc4_copier->copier_config = (uint32_t *)blob; in sof_ipc4_widget_setup_comp_dai()
783 ipc4_copier->data.gtw_cfg.config_length = (sizeof(blob->gw_attr) + in sof_ipc4_widget_setup_comp_dai()
784 sizeof(blob->alh_cfg.device_count) + in sof_ipc4_widget_setup_comp_dai()
785 sizeof(*blob->alh_cfg.mapping) * in sof_ipc4_widget_setup_comp_dai()
786 blob->alh_cfg.device_count) >> 2; in sof_ipc4_widget_setup_comp_dai()
791 ipc4_copier->data.gtw_cfg.node_id |= in sof_ipc4_widget_setup_comp_dai()
792 SOF_IPC4_NODE_INDEX_INTEL_SSP(ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
796 ipc4_copier->data.gtw_cfg.node_id |= in sof_ipc4_widget_setup_comp_dai()
797 SOF_IPC4_NODE_INDEX_INTEL_DMIC(ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
800 ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); in sof_ipc4_widget_setup_comp_dai()
801 if (!ipc4_copier->gtw_attr) { in sof_ipc4_widget_setup_comp_dai()
802 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
806 ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; in sof_ipc4_widget_setup_comp_dai()
807 ipc4_copier->data.gtw_cfg.config_length = in sof_ipc4_widget_setup_comp_dai()
812 dai->scomp = scomp; in sof_ipc4_widget_setup_comp_dai()
813 dai->private = ipc4_copier; in sof_ipc4_widget_setup_comp_dai()
816 ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg); in sof_ipc4_widget_setup_comp_dai()
823 kfree(ipc4_copier->copier_config); in sof_ipc4_widget_setup_comp_dai()
828 dai->private = NULL; in sof_ipc4_widget_setup_comp_dai()
829 dai->scomp = NULL; in sof_ipc4_widget_setup_comp_dai()
836 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_free_comp_dai()
842 if (!dai->private) { in sof_ipc4_widget_free_comp_dai()
844 swidget->private = NULL; in sof_ipc4_widget_free_comp_dai()
848 ipc4_copier = dai->private; in sof_ipc4_widget_free_comp_dai()
849 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_free_comp_dai()
851 kfree(available_fmt->output_pin_fmts); in sof_ipc4_widget_free_comp_dai()
852 if (ipc4_copier->dai_type != SOF_DAI_INTEL_SSP && in sof_ipc4_widget_free_comp_dai()
853 ipc4_copier->dai_type != SOF_DAI_INTEL_DMIC) in sof_ipc4_widget_free_comp_dai()
854 kfree(ipc4_copier->copier_config); in sof_ipc4_widget_free_comp_dai()
855 kfree(dai->private); in sof_ipc4_widget_free_comp_dai()
857 swidget->private = NULL; in sof_ipc4_widget_free_comp_dai()
862 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_pipeline()
864 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_pipeline()
869 return -ENOMEM; in sof_ipc4_widget_setup_comp_pipeline()
871 ret = sof_update_ipc_object(scomp, pipeline, SOF_SCHED_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_pipeline()
872 swidget->num_tuples, sizeof(*pipeline), 1); in sof_ipc4_widget_setup_comp_pipeline()
874 dev_err(scomp->dev, "parsing scheduler tokens failed\n"); in sof_ipc4_widget_setup_comp_pipeline()
878 swidget->core = pipeline->core_id; in sof_ipc4_widget_setup_comp_pipeline()
879 spipe->core_mask |= BIT(pipeline->core_id); in sof_ipc4_widget_setup_comp_pipeline()
881 if (pipeline->use_chain_dma) { in sof_ipc4_widget_setup_comp_pipeline()
882 dev_dbg(scomp->dev, "Set up chain DMA for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_pipeline()
883 swidget->private = pipeline; in sof_ipc4_widget_setup_comp_pipeline()
888 ret = sof_update_ipc_object(scomp, swidget, SOF_PIPELINE_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_pipeline()
889 swidget->num_tuples, sizeof(*swidget), 1); in sof_ipc4_widget_setup_comp_pipeline()
891 dev_err(scomp->dev, "parsing pipeline tokens failed\n"); in sof_ipc4_widget_setup_comp_pipeline()
895 dev_dbg(scomp->dev, "pipeline '%s': id %d, pri %d, core_id %u, lp mode %d\n", in sof_ipc4_widget_setup_comp_pipeline()
896 swidget->widget->name, swidget->pipeline_id, in sof_ipc4_widget_setup_comp_pipeline()
897 pipeline->priority, pipeline->core_id, pipeline->lp_mode); in sof_ipc4_widget_setup_comp_pipeline()
899 swidget->private = pipeline; in sof_ipc4_widget_setup_comp_pipeline()
901 pipeline->msg.primary = SOF_IPC4_GLB_PIPE_PRIORITY(pipeline->priority); in sof_ipc4_widget_setup_comp_pipeline()
902 pipeline->msg.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_CREATE_PIPELINE); in sof_ipc4_widget_setup_comp_pipeline()
903 pipeline->msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_widget_setup_comp_pipeline()
904 pipeline->msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG); in sof_ipc4_widget_setup_comp_pipeline()
906 pipeline->msg.extension = pipeline->lp_mode; in sof_ipc4_widget_setup_comp_pipeline()
907 pipeline->msg.extension |= SOF_IPC4_GLB_PIPE_EXT_CORE_ID(pipeline->core_id); in sof_ipc4_widget_setup_comp_pipeline()
908 pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED; in sof_ipc4_widget_setup_comp_pipeline()
918 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_pga()
924 return -ENOMEM; in sof_ipc4_widget_setup_comp_pga()
926 swidget->private = gain; in sof_ipc4_widget_setup_comp_pga()
928 gain->data.params.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK; in sof_ipc4_widget_setup_comp_pga()
929 gain->data.params.init_val = SOF_IPC4_VOL_ZERO_DB; in sof_ipc4_widget_setup_comp_pga()
931 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, &gain->data.base_config); in sof_ipc4_widget_setup_comp_pga()
935 ret = sof_update_ipc_object(scomp, &gain->data.params, SOF_GAIN_TOKENS, in sof_ipc4_widget_setup_comp_pga()
936 swidget->tuples, swidget->num_tuples, sizeof(gain->data), 1); in sof_ipc4_widget_setup_comp_pga()
938 dev_err(scomp->dev, "Parsing gain tokens failed\n"); in sof_ipc4_widget_setup_comp_pga()
942 dev_dbg(scomp->dev, in sof_ipc4_widget_setup_comp_pga()
944 swidget->widget->name, gain->data.params.curve_type, in sof_ipc4_widget_setup_comp_pga()
945 gain->data.params.curve_duration_l, gain->data.params.init_val); in sof_ipc4_widget_setup_comp_pga()
947 ret = sof_ipc4_widget_setup_msg(swidget, &gain->msg); in sof_ipc4_widget_setup_comp_pga()
955 sof_ipc4_free_audio_fmt(&gain->available_fmt); in sof_ipc4_widget_setup_comp_pga()
957 swidget->private = NULL; in sof_ipc4_widget_setup_comp_pga()
963 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_widget_free_comp_pga()
968 sof_ipc4_free_audio_fmt(&gain->available_fmt); in sof_ipc4_widget_free_comp_pga()
969 kfree(swidget->private); in sof_ipc4_widget_free_comp_pga()
970 swidget->private = NULL; in sof_ipc4_widget_free_comp_pga()
975 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_mixer()
979 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_mixer()
983 return -ENOMEM; in sof_ipc4_widget_setup_comp_mixer()
985 swidget->private = mixer; in sof_ipc4_widget_setup_comp_mixer()
987 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &mixer->available_fmt, in sof_ipc4_widget_setup_comp_mixer()
988 &mixer->base_config); in sof_ipc4_widget_setup_comp_mixer()
992 ret = sof_ipc4_widget_setup_msg(swidget, &mixer->msg); in sof_ipc4_widget_setup_comp_mixer()
998 sof_ipc4_free_audio_fmt(&mixer->available_fmt); in sof_ipc4_widget_setup_comp_mixer()
1000 swidget->private = NULL; in sof_ipc4_widget_setup_comp_mixer()
1006 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_src()
1007 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_src()
1011 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_src()
1015 return -ENOMEM; in sof_ipc4_widget_setup_comp_src()
1017 swidget->private = src; in sof_ipc4_widget_setup_comp_src()
1019 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt, in sof_ipc4_widget_setup_comp_src()
1020 &src->data.base_config); in sof_ipc4_widget_setup_comp_src()
1024 ret = sof_update_ipc_object(scomp, &src->data, SOF_SRC_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_src()
1025 swidget->num_tuples, sizeof(*src), 1); in sof_ipc4_widget_setup_comp_src()
1027 dev_err(scomp->dev, "Parsing SRC tokens failed\n"); in sof_ipc4_widget_setup_comp_src()
1031 spipe->core_mask |= BIT(swidget->core); in sof_ipc4_widget_setup_comp_src()
1033 dev_dbg(scomp->dev, "SRC sink rate %d\n", src->data.sink_rate); in sof_ipc4_widget_setup_comp_src()
1035 ret = sof_ipc4_widget_setup_msg(swidget, &src->msg); in sof_ipc4_widget_setup_comp_src()
1041 sof_ipc4_free_audio_fmt(&src->available_fmt); in sof_ipc4_widget_setup_comp_src()
1043 swidget->private = NULL; in sof_ipc4_widget_setup_comp_src()
1049 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_widget_free_comp_src()
1054 sof_ipc4_free_audio_fmt(&src->available_fmt); in sof_ipc4_widget_free_comp_src()
1055 kfree(swidget->private); in sof_ipc4_widget_free_comp_src()
1056 swidget->private = NULL; in sof_ipc4_widget_free_comp_src()
1061 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_widget_free_comp_mixer()
1066 sof_ipc4_free_audio_fmt(&mixer->available_fmt); in sof_ipc4_widget_free_comp_mixer()
1067 kfree(swidget->private); in sof_ipc4_widget_free_comp_mixer()
1068 swidget->private = NULL; in sof_ipc4_widget_free_comp_mixer()
1076 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_process()
1078 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_process()
1085 return -ENOMEM; in sof_ipc4_widget_setup_comp_process()
1087 swidget->private = process; in sof_ipc4_widget_setup_comp_process()
1089 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &process->available_fmt, in sof_ipc4_widget_setup_comp_process()
1090 &process->base_config); in sof_ipc4_widget_setup_comp_process()
1094 ret = sof_ipc4_widget_setup_msg(swidget, &process->msg); in sof_ipc4_widget_setup_comp_process()
1099 fw_module = swidget->module_info; in sof_ipc4_widget_setup_comp_process()
1100 process->init_config = FIELD_GET(SOF_IPC4_MODULE_INIT_CONFIG_MASK, in sof_ipc4_widget_setup_comp_process()
1101 fw_module->man4_module_entry.type); in sof_ipc4_widget_setup_comp_process()
1103 process->ipc_config_size = sizeof(struct sof_ipc4_base_module_cfg); in sof_ipc4_widget_setup_comp_process()
1106 if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) { in sof_ipc4_widget_setup_comp_process()
1109 size_add(swidget->num_input_pins, in sof_ipc4_widget_setup_comp_process()
1110 swidget->num_output_pins)); in sof_ipc4_widget_setup_comp_process()
1114 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_process()
1118 base_cfg_ext->num_input_pin_fmts = swidget->num_input_pins; in sof_ipc4_widget_setup_comp_process()
1119 base_cfg_ext->num_output_pin_fmts = swidget->num_output_pins; in sof_ipc4_widget_setup_comp_process()
1120 process->base_config_ext = base_cfg_ext; in sof_ipc4_widget_setup_comp_process()
1121 process->base_config_ext_size = ext_size; in sof_ipc4_widget_setup_comp_process()
1122 process->ipc_config_size += ext_size; in sof_ipc4_widget_setup_comp_process()
1125 cfg = kzalloc(process->ipc_config_size, GFP_KERNEL); in sof_ipc4_widget_setup_comp_process()
1127 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_process()
1131 process->ipc_config_data = cfg; in sof_ipc4_widget_setup_comp_process()
1136 spipe->core_mask |= BIT(swidget->core); in sof_ipc4_widget_setup_comp_process()
1140 kfree(process->base_config_ext); in sof_ipc4_widget_setup_comp_process()
1141 process->base_config_ext = NULL; in sof_ipc4_widget_setup_comp_process()
1143 sof_ipc4_free_audio_fmt(&process->available_fmt); in sof_ipc4_widget_setup_comp_process()
1146 swidget->private = NULL; in sof_ipc4_widget_setup_comp_process()
1152 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_widget_free_comp_process()
1157 kfree(process->ipc_config_data); in sof_ipc4_widget_free_comp_process()
1158 kfree(process->base_config_ext); in sof_ipc4_widget_free_comp_process()
1159 sof_ipc4_free_audio_fmt(&process->available_fmt); in sof_ipc4_widget_free_comp_process()
1160 kfree(swidget->private); in sof_ipc4_widget_free_comp_process()
1161 swidget->private = NULL; in sof_ipc4_widget_free_comp_process()
1168 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_update_resource_usage()
1174 ibs = base_config->ibs; in sof_ipc4_update_resource_usage()
1175 bss = base_config->is_pages; in sof_ipc4_update_resource_usage()
1180 if (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_LL) { in sof_ipc4_update_resource_usage()
1194 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_update_resource_usage()
1195 pipeline = pipe_widget->private; in sof_ipc4_update_resource_usage()
1196 pipeline->mem_usage += total; in sof_ipc4_update_resource_usage()
1198 /* Update base_config->cpc from the module manifest */ in sof_ipc4_update_resource_usage()
1202 dev_dbg(sdev->dev, "%s: ibs / obs: %u / %u, forcing cpc to 0 from %u\n", in sof_ipc4_update_resource_usage()
1203 swidget->widget->name, base_config->ibs, base_config->obs, in sof_ipc4_update_resource_usage()
1204 base_config->cpc); in sof_ipc4_update_resource_usage()
1205 base_config->cpc = 0; in sof_ipc4_update_resource_usage()
1207 dev_dbg(sdev->dev, "%s: ibs / obs / cpc: %u / %u / %u\n", in sof_ipc4_update_resource_usage()
1208 swidget->widget->name, base_config->ibs, base_config->obs, in sof_ipc4_update_resource_usage()
1209 base_config->cpc); in sof_ipc4_update_resource_usage()
1216 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_assign_instance_id()
1217 int max_instances = fw_module->man4_module_entry.instance_max_count; in sof_ipc4_widget_assign_instance_id()
1219 swidget->instance_id = ida_alloc_max(&fw_module->m_ida, max_instances, GFP_KERNEL); in sof_ipc4_widget_assign_instance_id()
1220 if (swidget->instance_id < 0) { in sof_ipc4_widget_assign_instance_id()
1221 dev_err(sdev->dev, "failed to assign instance id for widget %s", in sof_ipc4_widget_assign_instance_id()
1222 swidget->widget->name); in sof_ipc4_widget_assign_instance_id()
1223 return swidget->instance_id; in sof_ipc4_widget_assign_instance_id()
1236 int valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_update_hw_params()
1251 dev_err(sdev->dev, "invalid PCM valid_bits %d\n", valid_bits); in sof_ipc4_update_hw_params()
1252 return -EINVAL; in sof_ipc4_update_hw_params()
1261 unsigned int rate = fmt->sampling_frequency; in sof_ipc4_update_hw_params()
1264 i->min = rate; in sof_ipc4_update_hw_params()
1265 i->max = rate; in sof_ipc4_update_hw_params()
1269 unsigned int channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_update_hw_params()
1272 i->min = channels; in sof_ipc4_update_hw_params()
1273 i->max = channels; in sof_ipc4_update_hw_params()
1287 rate = fmt->sampling_frequency; in sof_ipc4_is_single_format()
1288 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1289 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1296 _rate = fmt->sampling_frequency; in sof_ipc4_is_single_format()
1297 _channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1298 _valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1314 struct sof_ipc4_pin_format *pin_fmts = available_fmt->output_pin_fmts; in sof_ipc4_init_output_audio_fmt()
1315 u32 pin_fmts_size = available_fmt->num_output_formats; in sof_ipc4_init_output_audio_fmt()
1320 dev_err(sdev->dev, "no output formats for %s\n", in sof_ipc4_init_output_audio_fmt()
1321 swidget->widget->name); in sof_ipc4_init_output_audio_fmt()
1322 return -EINVAL; in sof_ipc4_init_output_audio_fmt()
1340 _out_rate = fmt->sampling_frequency; in sof_ipc4_init_output_audio_fmt()
1341 _out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_init_output_audio_fmt()
1342 _out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_init_output_audio_fmt()
1349 dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n", in sof_ipc4_init_output_audio_fmt()
1352 return -EINVAL; in sof_ipc4_init_output_audio_fmt()
1355 base_config->obs = pin_fmts[i].buffer_size; in sof_ipc4_init_output_audio_fmt()
1370 dev_err(sdev->dev, "invalid pcm frame format %d\n", params_format(params)); in sof_ipc4_get_valid_bits()
1371 return -EINVAL; in sof_ipc4_get_valid_bits()
1381 struct sof_ipc4_pin_format *pin_fmts = available_fmt->input_pin_fmts; in sof_ipc4_init_input_audio_fmt()
1382 u32 pin_fmts_size = available_fmt->num_input_formats; in sof_ipc4_init_input_audio_fmt()
1391 dev_err(sdev->dev, "no input formats for %s\n", swidget->widget->name); in sof_ipc4_init_input_audio_fmt()
1392 return -EINVAL; in sof_ipc4_init_input_audio_fmt()
1413 rate = fmt->sampling_frequency; in sof_ipc4_init_input_audio_fmt()
1414 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_init_input_audio_fmt()
1415 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_init_input_audio_fmt()
1422 dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n", in sof_ipc4_init_input_audio_fmt()
1424 return -EINVAL; in sof_ipc4_init_input_audio_fmt()
1429 memcpy(&base_config->audio_fmt, &pin_fmts[i].audio_fmt, in sof_ipc4_init_input_audio_fmt()
1433 base_config->ibs = pin_fmts[i].buffer_size; in sof_ipc4_init_input_audio_fmt()
1445 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_unprepare_copier_module()
1446 pipeline = pipe_widget->private; in sof_ipc4_unprepare_copier_module()
1447 pipeline->mem_usage = 0; in sof_ipc4_unprepare_copier_module()
1449 if (WIDGET_IS_AIF(swidget->id) || swidget->id == snd_soc_dapm_buffer) { in sof_ipc4_unprepare_copier_module()
1450 if (pipeline->use_chain_dma) { in sof_ipc4_unprepare_copier_module()
1451 pipeline->msg.primary = 0; in sof_ipc4_unprepare_copier_module()
1452 pipeline->msg.extension = 0; in sof_ipc4_unprepare_copier_module()
1454 ipc4_copier = swidget->private; in sof_ipc4_unprepare_copier_module()
1455 } else if (WIDGET_IS_DAI(swidget->id)) { in sof_ipc4_unprepare_copier_module()
1456 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_unprepare_copier_module()
1458 ipc4_copier = dai->private; in sof_ipc4_unprepare_copier_module()
1460 if (pipeline->use_chain_dma) { in sof_ipc4_unprepare_copier_module()
1465 * re-configuration in sof_ipc4_unprepare_copier_module()
1467 pipeline->msg.primary &= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK; in sof_ipc4_unprepare_copier_module()
1468 pipeline->msg.extension = 0; in sof_ipc4_unprepare_copier_module()
1471 if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { in sof_ipc4_unprepare_copier_module()
1475 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; in sof_ipc4_unprepare_copier_module()
1476 if (blob->alh_cfg.device_count > 1) { in sof_ipc4_unprepare_copier_module()
1477 group_id = SOF_IPC4_NODE_INDEX(ipc4_copier->data.gtw_cfg.node_id) - in sof_ipc4_unprepare_copier_module()
1485 kfree(ipc4_copier->ipc_config_data); in sof_ipc4_unprepare_copier_module()
1486 ipc4_copier->ipc_config_data = NULL; in sof_ipc4_unprepare_copier_module()
1487 ipc4_copier->ipc_config_size = 0; in sof_ipc4_unprepare_copier_module()
1502 list_for_each_entry(slink, &sdev->dai_link_list, list) { in snd_sof_get_hw_config_params()
1503 if (!strcmp(slink->link->name, dai->name)) { in snd_sof_get_hw_config_params()
1510 dev_err(sdev->dev, "%s: no DAI link found for DAI %s\n", __func__, dai->name); in snd_sof_get_hw_config_params()
1511 return -EINVAL; in snd_sof_get_hw_config_params()
1514 for (i = 0; i < slink->num_hw_configs; i++) { in snd_sof_get_hw_config_params()
1515 hw_config = &slink->hw_configs[i]; in snd_sof_get_hw_config_params()
1516 if (dai->current_config == le32_to_cpu(hw_config->id)) { in snd_sof_get_hw_config_params()
1523 dev_err(sdev->dev, "%s: no matching hw_config found for DAI %s\n", __func__, in snd_sof_get_hw_config_params()
1524 dai->name); in snd_sof_get_hw_config_params()
1525 return -EINVAL; in snd_sof_get_hw_config_params()
1528 *bit_depth = le32_to_cpu(hw_config->tdm_slot_width); in snd_sof_get_hw_config_params()
1529 *channel_count = le32_to_cpu(hw_config->tdm_slots); in snd_sof_get_hw_config_params()
1530 *sample_rate = le32_to_cpu(hw_config->fsync_rate); in snd_sof_get_hw_config_params()
1532 dev_dbg(sdev->dev, "sample rate: %d sample width: %d channels: %d\n", in snd_sof_get_hw_config_params()
1544 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in snd_sof_get_nhlt_endpoint_data()
1560 * Look for 32-bit blob first instead of 16-bit if copier in snd_sof_get_nhlt_endpoint_data()
1564 dev_dbg(sdev->dev, "Looking for 32-bit blob first for DMIC\n"); in snd_sof_get_nhlt_endpoint_data()
1583 dev_type = intel_nhlt_ssp_device_type(sdev->dev, ipc4_data->nhlt, in snd_sof_get_nhlt_endpoint_data()
1592 dev_dbg(sdev->dev, "dai index %d nhlt type %d direction %d dev type %d\n", in snd_sof_get_nhlt_endpoint_data()
1596 cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, dai_index, nhlt_type, in snd_sof_get_nhlt_endpoint_data()
1605 * The 32-bit blob was not found in NHLT table, try to in snd_sof_get_nhlt_endpoint_data()
1613 * The requested 32-bit blob (no format change for the in snd_sof_get_nhlt_endpoint_data()
1615 * look for 16-bit blob if the copier supports multiple in snd_sof_get_nhlt_endpoint_data()
1624 cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, in snd_sof_get_nhlt_endpoint_data()
1633 dev_err(sdev->dev, in snd_sof_get_nhlt_endpoint_data()
1636 return -EINVAL; in snd_sof_get_nhlt_endpoint_data()
1641 *len = cfg->size >> 2; in snd_sof_get_nhlt_endpoint_data()
1642 *dst = (u32 *)cfg->caps; in snd_sof_get_nhlt_endpoint_data()
1647 * instead of the requested bit depth (16 -> 32 or 32 -> 16). in snd_sof_get_nhlt_endpoint_data()
1684 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_copier_is_single_bitdepth()
1691 _valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_copier_is_single_bitdepth()
1714 rate = fmt->sampling_frequency; in sof_ipc4_adjust_params_to_dai_format()
1715 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_adjust_params_to_dai_format()
1716 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_adjust_params_to_dai_format()
1725 val = fmt->sampling_frequency; in sof_ipc4_adjust_params_to_dai_format()
1730 val = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_adjust_params_to_dai_format()
1735 val = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_adjust_params_to_dai_format()
1762 ipc4_copier = dai->private; in sof_ipc4_prepare_dai_copier()
1763 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_dai_copier()
1764 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_dai_copier()
1772 pin_fmts = available_fmt->output_pin_fmts; in sof_ipc4_prepare_dai_copier()
1773 num_pin_fmts = available_fmt->num_output_formats; in sof_ipc4_prepare_dai_copier()
1775 pin_fmts = available_fmt->input_pin_fmts; in sof_ipc4_prepare_dai_copier()
1776 num_pin_fmts = available_fmt->num_input_formats; in sof_ipc4_prepare_dai_copier()
1788 ipc4_copier->dai_index, in sof_ipc4_prepare_dai_copier()
1789 ipc4_copier->dai_type, dir, in sof_ipc4_prepare_dai_copier()
1790 &ipc4_copier->copier_config, in sof_ipc4_prepare_dai_copier()
1791 &copier_data->gtw_cfg.config_length); in sof_ipc4_prepare_dai_copier()
1806 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_copier_module()
1824 dev_dbg(sdev->dev, "copier %s, type %d", swidget->widget->name, swidget->id); in sof_ipc4_prepare_copier_module()
1826 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1836 SOF_COPIER_DEEP_BUFFER_TOKENS, swidget->tuples, in sof_ipc4_prepare_copier_module()
1837 swidget->num_tuples, sizeof(u32), 1); in sof_ipc4_prepare_copier_module()
1839 dev_err(scomp->dev, "Failed to parse deep buffer dma size for %s\n", in sof_ipc4_prepare_copier_module()
1840 swidget->widget->name); in sof_ipc4_prepare_copier_module()
1844 ipc4_copier = (struct sof_ipc4_copier *)swidget->private; in sof_ipc4_prepare_copier_module()
1845 gtw_attr = ipc4_copier->gtw_attr; in sof_ipc4_prepare_copier_module()
1846 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1847 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1849 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_prepare_copier_module()
1850 pipeline = pipe_widget->private; in sof_ipc4_prepare_copier_module()
1852 if (pipeline->use_chain_dma) { in sof_ipc4_prepare_copier_module()
1856 host_dma_id = platform_params->stream_tag - 1; in sof_ipc4_prepare_copier_module()
1857 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_HOST_ID(host_dma_id); in sof_ipc4_prepare_copier_module()
1861 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK; in sof_ipc4_prepare_copier_module()
1871 pipeline->msg.extension |= SOF_IPC4_GLB_EXT_CHAIN_DMA_FIFO_SIZE(fifo_size); in sof_ipc4_prepare_copier_module()
1877 copier_data->gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID; in sof_ipc4_prepare_copier_module()
1891 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_prepare_copier_module()
1892 copier_data->gtw_cfg.node_id |= in sof_ipc4_prepare_copier_module()
1893 SOF_IPC4_NODE_INDEX(platform_params->stream_tag - 1); in sof_ipc4_prepare_copier_module()
1896 gtw_attr->lp_buffer_alloc = pipeline->lp_mode; in sof_ipc4_prepare_copier_module()
1902 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_prepare_copier_module()
1903 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_prepare_copier_module()
1905 if (pipeline->use_chain_dma) in sof_ipc4_prepare_copier_module()
1908 dai = swidget->private; in sof_ipc4_prepare_copier_module()
1910 ipc4_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_prepare_copier_module()
1911 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1912 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1938 ipc4_copier = (struct sof_ipc4_copier *)swidget->private; in sof_ipc4_prepare_copier_module()
1939 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1940 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1946 dev_err(sdev->dev, "unsupported type %d for copier %s", in sof_ipc4_prepare_copier_module()
1947 swidget->id, swidget->widget->name); in sof_ipc4_prepare_copier_module()
1948 return -EINVAL; in sof_ipc4_prepare_copier_module()
1953 &copier_data->base_config, in sof_ipc4_prepare_copier_module()
1960 available_fmt->output_pin_fmts, in sof_ipc4_prepare_copier_module()
1961 available_fmt->num_output_formats); in sof_ipc4_prepare_copier_module()
1962 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1969 in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; in sof_ipc4_prepare_copier_module()
1970 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_copier_module()
1971 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
1975 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
1993 return -EINVAL; in sof_ipc4_prepare_copier_module()
2003 out_fmt = &available_fmt->output_pin_fmts[0].audio_fmt; in sof_ipc4_prepare_copier_module()
2005 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
2009 &copier_data->base_config, in sof_ipc4_prepare_copier_module()
2022 memcpy(&copier_data->out_format, in sof_ipc4_prepare_copier_module()
2023 &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt, in sof_ipc4_prepare_copier_module()
2026 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
2034 if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { in sof_ipc4_prepare_copier_module()
2046 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; in sof_ipc4_prepare_copier_module()
2048 blob->gw_attr.lp_buffer_alloc = 0; in sof_ipc4_prepare_copier_module()
2051 ch_map = copier_data->base_config.audio_fmt.ch_map; in sof_ipc4_prepare_copier_module()
2060 step = ch_count / blob->alh_cfg.device_count; in sof_ipc4_prepare_copier_module()
2061 mask = GENMASK(step - 1, 0); in sof_ipc4_prepare_copier_module()
2063 * Set each gtw_cfg.node_id to blob->alh_cfg.mapping[] in sof_ipc4_prepare_copier_module()
2067 list_for_each_entry(w, &sdev->widget_list, list) { in sof_ipc4_prepare_copier_module()
2070 if (!WIDGET_IS_DAI(w->id) || !w->widget->sname || in sof_ipc4_prepare_copier_module()
2071 strcmp(w->widget->sname, swidget->widget->sname)) in sof_ipc4_prepare_copier_module()
2074 dai = w->private; in sof_ipc4_prepare_copier_module()
2075 if (dai->type != SOF_DAI_INTEL_ALH) in sof_ipc4_prepare_copier_module()
2077 alh_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_prepare_copier_module()
2078 alh_data = &alh_copier->data; in sof_ipc4_prepare_copier_module()
2079 node_type = SOF_IPC4_GET_NODE_TYPE(alh_data->gtw_cfg.node_id); in sof_ipc4_prepare_copier_module()
2080 blob->alh_cfg.mapping[i].device = SOF_IPC4_NODE_TYPE(node_type); in sof_ipc4_prepare_copier_module()
2081 blob->alh_cfg.mapping[i].device |= in sof_ipc4_prepare_copier_module()
2082 SOF_IPC4_NODE_INDEX(alh_copier->dai_index); in sof_ipc4_prepare_copier_module()
2089 if (ipc4_copier->dma_config_tlv[i].length) { in sof_ipc4_prepare_copier_module()
2090 dma_config = &ipc4_copier->dma_config_tlv[i].dma_config; in sof_ipc4_prepare_copier_module()
2091 blob->alh_cfg.mapping[i].device = in sof_ipc4_prepare_copier_module()
2092 dma_config->dma_stream_channel_map.mapping[0].device; in sof_ipc4_prepare_copier_module()
2106 if (w->id == snd_soc_dapm_dai_in) in sof_ipc4_prepare_copier_module()
2107 blob->alh_cfg.mapping[i].channel_mask = ch_mask; in sof_ipc4_prepare_copier_module()
2109 blob->alh_cfg.mapping[i].channel_mask = mask << (step * i); in sof_ipc4_prepare_copier_module()
2113 if (blob->alh_cfg.device_count > 1) { in sof_ipc4_prepare_copier_module()
2116 group_id = ida_alloc_max(&alh_group_ida, ALH_MULTI_GTW_COUNT - 1, in sof_ipc4_prepare_copier_module()
2122 /* add multi-gateway base */ in sof_ipc4_prepare_copier_module()
2124 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_prepare_copier_module()
2125 copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(group_id); in sof_ipc4_prepare_copier_module()
2133 &copier_data->out_format, in sof_ipc4_prepare_copier_module()
2145 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
2147 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
2148 SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.ibs; in sof_ipc4_prepare_copier_module()
2151 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
2153 copier_data->base_config.ibs; in sof_ipc4_prepare_copier_module()
2154 dev_dbg(sdev->dev, "copier %s, dma buffer%s: %u ms (%u bytes)", in sof_ipc4_prepare_copier_module()
2155 swidget->widget->name, in sof_ipc4_prepare_copier_module()
2158 copier_data->gtw_cfg.dma_buffer_size); in sof_ipc4_prepare_copier_module()
2162 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
2163 SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.obs; in sof_ipc4_prepare_copier_module()
2169 data = &ipc4_copier->copier_config; in sof_ipc4_prepare_copier_module()
2170 ipc_config_size = &ipc4_copier->ipc_config_size; in sof_ipc4_prepare_copier_module()
2171 ipc_config_data = &ipc4_copier->ipc_config_data; in sof_ipc4_prepare_copier_module()
2174 gtw_cfg_config_length = copier_data->gtw_cfg.config_length * 4; in sof_ipc4_prepare_copier_module()
2179 if (ipc4_copier->dma_config_tlv[i].type != SOF_IPC4_GTW_DMA_CONFIG_ID) in sof_ipc4_prepare_copier_module()
2181 dma_config_tlv_size += ipc4_copier->dma_config_tlv[i].length; in sof_ipc4_prepare_copier_module()
2183 ipc4_copier->dma_config_tlv[i].dma_config.dma_priv_config_size; in sof_ipc4_prepare_copier_module()
2184 dma_config_tlv_size += (sizeof(ipc4_copier->dma_config_tlv[i]) - in sof_ipc4_prepare_copier_module()
2185 sizeof(ipc4_copier->dma_config_tlv[i].dma_config)); in sof_ipc4_prepare_copier_module()
2192 copier_data->gtw_cfg.config_length += dma_config_tlv_size / 4; in sof_ipc4_prepare_copier_module()
2195 dev_dbg(sdev->dev, "copier %s, IPC size is %d", swidget->widget->name, ipc_size); in sof_ipc4_prepare_copier_module()
2199 return -ENOMEM; in sof_ipc4_prepare_copier_module()
2203 sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, in sof_ipc4_prepare_copier_module()
2207 sof_ipc4_update_resource_usage(sdev, swidget, &copier_data->base_config); in sof_ipc4_prepare_copier_module()
2219 &ipc4_copier->dma_config_tlv, dma_config_tlv_size); in sof_ipc4_prepare_copier_module()
2225 copier_data->gtw_cfg.config_length = gtw_cfg_config_length / 4; in sof_ipc4_prepare_copier_module()
2235 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_gain_module()
2237 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_prepare_gain_module()
2238 struct sof_ipc4_available_audio_format *available_fmt = &gain->available_fmt; in sof_ipc4_prepare_gain_module()
2244 &gain->data.base_config, in sof_ipc4_prepare_gain_module()
2250 in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; in sof_ipc4_prepare_gain_module()
2251 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_gain_module()
2252 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_gain_module()
2253 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_gain_module()
2256 &gain->data.base_config, in sof_ipc4_prepare_gain_module()
2264 sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, in sof_ipc4_prepare_gain_module()
2268 sof_ipc4_update_resource_usage(sdev, swidget, &gain->data.base_config); in sof_ipc4_prepare_gain_module()
2278 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_mixer_module()
2280 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_prepare_mixer_module()
2281 struct sof_ipc4_available_audio_format *available_fmt = &mixer->available_fmt; in sof_ipc4_prepare_mixer_module()
2287 &mixer->base_config, in sof_ipc4_prepare_mixer_module()
2293 in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; in sof_ipc4_prepare_mixer_module()
2294 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_mixer_module()
2295 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_mixer_module()
2296 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_mixer_module()
2299 &mixer->base_config, in sof_ipc4_prepare_mixer_module()
2307 sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, in sof_ipc4_prepare_mixer_module()
2311 sof_ipc4_update_resource_usage(sdev, swidget, &mixer->base_config); in sof_ipc4_prepare_mixer_module()
2321 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_src_module()
2323 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_prepare_src_module()
2324 struct sof_ipc4_available_audio_format *available_fmt = &src->available_fmt; in sof_ipc4_prepare_src_module()
2331 &src->data.base_config, in sof_ipc4_prepare_src_module()
2341 if (dir == SNDRV_PCM_STREAM_PLAYBACK && available_fmt->num_output_formats > 1) { in sof_ipc4_prepare_src_module()
2342 dev_err(sdev->dev, "Invalid number of output formats: %d for SRC %s\n", in sof_ipc4_prepare_src_module()
2343 available_fmt->num_output_formats, swidget->widget->name); in sof_ipc4_prepare_src_module()
2344 return -EINVAL; in sof_ipc4_prepare_src_module()
2351 in_audio_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; in sof_ipc4_prepare_src_module()
2352 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_audio_fmt->fmt_cfg); in sof_ipc4_prepare_src_module()
2353 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_audio_fmt->fmt_cfg); in sof_ipc4_prepare_src_module()
2363 &src->data.base_config, in sof_ipc4_prepare_src_module()
2371 sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, in sof_ipc4_prepare_src_module()
2375 sof_ipc4_update_resource_usage(sdev, swidget, &src->data.base_config); in sof_ipc4_prepare_src_module()
2377 out_audio_fmt = &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt; in sof_ipc4_prepare_src_module()
2378 src->data.sink_rate = out_audio_fmt->sampling_frequency; in sof_ipc4_prepare_src_module()
2390 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_process_set_pin_formats()
2391 struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext; in sof_ipc4_process_set_pin_formats()
2392 struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt; in sof_ipc4_process_set_pin_formats()
2394 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_process_set_pin_formats()
2401 num_pins = swidget->num_input_pins; in sof_ipc4_process_set_pin_formats()
2402 format_list_to_search = available_fmt->input_pin_fmts; in sof_ipc4_process_set_pin_formats()
2403 format_list_count = available_fmt->num_input_formats; in sof_ipc4_process_set_pin_formats()
2405 num_pins = swidget->num_output_pins; in sof_ipc4_process_set_pin_formats()
2406 pin_format_offset = swidget->num_input_pins; in sof_ipc4_process_set_pin_formats()
2407 format_list_to_search = available_fmt->output_pin_fmts; in sof_ipc4_process_set_pin_formats()
2408 format_list_count = available_fmt->num_output_formats; in sof_ipc4_process_set_pin_formats()
2412 pin_format = &base_cfg_ext->pin_formats[i]; in sof_ipc4_process_set_pin_formats()
2417 pin_format->buffer_size = process->base_config.ibs; in sof_ipc4_process_set_pin_formats()
2418 pin_format->audio_fmt = process->base_config.audio_fmt; in sof_ipc4_process_set_pin_formats()
2420 pin_format->buffer_size = process->base_config.obs; in sof_ipc4_process_set_pin_formats()
2421 pin_format->audio_fmt = process->output_format; in sof_ipc4_process_set_pin_formats()
2434 if (pin_format_item->pin_index == i - pin_format_offset) { in sof_ipc4_process_set_pin_formats()
2441 dev_err(scomp->dev, "%s pin %d format not found for %s\n", in sof_ipc4_process_set_pin_formats()
2443 i - pin_format_offset, swidget->widget->name); in sof_ipc4_process_set_pin_formats()
2444 return -EINVAL; in sof_ipc4_process_set_pin_formats()
2470 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_process_module()
2472 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_prepare_process_module()
2473 struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt; in sof_ipc4_prepare_process_module()
2474 void *cfg = process->ipc_config_data; in sof_ipc4_prepare_process_module()
2480 &process->base_config, in sof_ipc4_prepare_process_module()
2487 if (available_fmt->num_output_formats) { in sof_ipc4_prepare_process_module()
2493 in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; in sof_ipc4_prepare_process_module()
2495 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_process_module()
2496 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_process_module()
2497 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_process_module()
2500 &process->base_config, in sof_ipc4_prepare_process_module()
2508 pin_fmt = &available_fmt->output_pin_fmts[output_fmt_index]; in sof_ipc4_prepare_process_module()
2511 if (pin_fmt->pin_index == 0) { in sof_ipc4_prepare_process_module()
2512 memcpy(&process->output_format, &pin_fmt->audio_fmt, in sof_ipc4_prepare_process_module()
2517 &process->output_format, in sof_ipc4_prepare_process_module()
2526 sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, in sof_ipc4_prepare_process_module()
2530 sof_ipc4_update_resource_usage(sdev, swidget, &process->base_config); in sof_ipc4_prepare_process_module()
2533 memcpy(cfg, &process->base_config, sizeof(struct sof_ipc4_base_module_cfg)); in sof_ipc4_prepare_process_module()
2536 if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) { in sof_ipc4_prepare_process_module()
2537 struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext; in sof_ipc4_prepare_process_module()
2543 memcpy(cfg, base_cfg_ext, process->base_config_ext_size); in sof_ipc4_prepare_process_module()
2555 scontrol->size = struct_size(control_data, chanv, scontrol->num_channels); in sof_ipc4_control_load_volume()
2557 /* scontrol->ipc_control_data will be freed in sof_control_unload */ in sof_ipc4_control_load_volume()
2558 scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL); in sof_ipc4_control_load_volume()
2559 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_volume()
2560 return -ENOMEM; in sof_ipc4_control_load_volume()
2562 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_volume()
2563 control_data->index = scontrol->index; in sof_ipc4_control_load_volume()
2565 msg = &control_data->msg; in sof_ipc4_control_load_volume()
2566 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_volume()
2567 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_volume()
2568 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_volume()
2570 /* volume controls with range 0-1 (off/on) are switch controls */ in sof_ipc4_control_load_volume()
2571 if (scontrol->max == 1) in sof_ipc4_control_load_volume()
2572 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_SWITCH_CONTROL_PARAM_ID); in sof_ipc4_control_load_volume()
2574 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_GAIN_PARAM_ID); in sof_ipc4_control_load_volume()
2576 for (i = 0; i < scontrol->num_channels; i++) { in sof_ipc4_control_load_volume()
2577 control_data->chanv[i].channel = i; in sof_ipc4_control_load_volume()
2580 * - 0dB for volume controls in sof_ipc4_control_load_volume()
2581 * - off (0) for switch controls - value already zero after in sof_ipc4_control_load_volume()
2584 if (scontrol->max > 1) in sof_ipc4_control_load_volume()
2585 control_data->chanv[i].value = SOF_IPC4_VOL_ZERO_DB; in sof_ipc4_control_load_volume()
2597 scontrol->size = struct_size(control_data, chanv, scontrol->num_channels); in sof_ipc4_control_load_enum()
2599 /* scontrol->ipc_control_data will be freed in sof_control_unload */ in sof_ipc4_control_load_enum()
2600 scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL); in sof_ipc4_control_load_enum()
2601 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_enum()
2602 return -ENOMEM; in sof_ipc4_control_load_enum()
2604 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_enum()
2605 control_data->index = scontrol->index; in sof_ipc4_control_load_enum()
2607 msg = &control_data->msg; in sof_ipc4_control_load_enum()
2608 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_enum()
2609 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_enum()
2610 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_enum()
2612 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_ENUM_CONTROL_PARAM_ID); in sof_ipc4_control_load_enum()
2615 for (i = 0; i < scontrol->num_channels; i++) in sof_ipc4_control_load_enum()
2616 control_data->chanv[i].channel = i; in sof_ipc4_control_load_enum()
2627 if (scontrol->max_size < (sizeof(*control_data) + sizeof(struct sof_abi_hdr))) { in sof_ipc4_control_load_bytes()
2628 dev_err(sdev->dev, "insufficient size for a bytes control %s: %zu.\n", in sof_ipc4_control_load_bytes()
2629 scontrol->name, scontrol->max_size); in sof_ipc4_control_load_bytes()
2630 return -EINVAL; in sof_ipc4_control_load_bytes()
2633 if (scontrol->priv_size > scontrol->max_size - sizeof(*control_data)) { in sof_ipc4_control_load_bytes()
2634 dev_err(sdev->dev, "scontrol %s bytes data size %zu exceeds max %zu.\n", in sof_ipc4_control_load_bytes()
2635 scontrol->name, scontrol->priv_size, in sof_ipc4_control_load_bytes()
2636 scontrol->max_size - sizeof(*control_data)); in sof_ipc4_control_load_bytes()
2637 return -EINVAL; in sof_ipc4_control_load_bytes()
2640 scontrol->size = sizeof(struct sof_ipc4_control_data) + scontrol->priv_size; in sof_ipc4_control_load_bytes()
2642 scontrol->ipc_control_data = kzalloc(scontrol->max_size, GFP_KERNEL); in sof_ipc4_control_load_bytes()
2643 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_bytes()
2644 return -ENOMEM; in sof_ipc4_control_load_bytes()
2646 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_bytes()
2647 control_data->index = scontrol->index; in sof_ipc4_control_load_bytes()
2648 if (scontrol->priv_size > 0) { in sof_ipc4_control_load_bytes()
2649 memcpy(control_data->data, scontrol->priv, scontrol->priv_size); in sof_ipc4_control_load_bytes()
2650 kfree(scontrol->priv); in sof_ipc4_control_load_bytes()
2651 scontrol->priv = NULL; in sof_ipc4_control_load_bytes()
2653 if (control_data->data->magic != SOF_IPC4_ABI_MAGIC) { in sof_ipc4_control_load_bytes()
2654 dev_err(sdev->dev, "Wrong ABI magic (%#x) for control: %s\n", in sof_ipc4_control_load_bytes()
2655 control_data->data->magic, scontrol->name); in sof_ipc4_control_load_bytes()
2656 ret = -EINVAL; in sof_ipc4_control_load_bytes()
2662 if (control_data->data->size + sizeof(struct sof_abi_hdr) != in sof_ipc4_control_load_bytes()
2663 scontrol->priv_size) { in sof_ipc4_control_load_bytes()
2664 dev_err(sdev->dev, "Control %s conflict in bytes %zu vs. priv size %zu.\n", in sof_ipc4_control_load_bytes()
2665 scontrol->name, in sof_ipc4_control_load_bytes()
2666 control_data->data->size + sizeof(struct sof_abi_hdr), in sof_ipc4_control_load_bytes()
2667 scontrol->priv_size); in sof_ipc4_control_load_bytes()
2668 ret = -EINVAL; in sof_ipc4_control_load_bytes()
2673 msg = &control_data->msg; in sof_ipc4_control_load_bytes()
2674 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_bytes()
2675 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_bytes()
2676 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_bytes()
2681 kfree(scontrol->ipc_control_data); in sof_ipc4_control_load_bytes()
2682 scontrol->ipc_control_data = NULL; in sof_ipc4_control_load_bytes()
2688 switch (scontrol->info_type) { in sof_ipc4_control_setup()
2707 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_setup()
2708 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_widget_setup()
2715 switch (swidget->id) { in sof_ipc4_widget_setup()
2717 pipeline = swidget->private; in sof_ipc4_widget_setup()
2719 if (pipeline->use_chain_dma) { in sof_ipc4_widget_setup()
2720 dev_warn(sdev->dev, "use_chain_dma set for scheduler %s", in sof_ipc4_widget_setup()
2721 swidget->widget->name); in sof_ipc4_widget_setup()
2725 dev_dbg(sdev->dev, "pipeline: %d memory pages: %d\n", swidget->pipeline_id, in sof_ipc4_widget_setup()
2726 pipeline->mem_usage); in sof_ipc4_widget_setup()
2728 msg = &pipeline->msg; in sof_ipc4_widget_setup()
2729 msg->primary |= pipeline->mem_usage; in sof_ipc4_widget_setup()
2731 swidget->instance_id = ida_alloc_max(&pipeline_ida, ipc4_data->max_num_pipelines, in sof_ipc4_widget_setup()
2733 if (swidget->instance_id < 0) { in sof_ipc4_widget_setup()
2734 dev_err(sdev->dev, "failed to assign pipeline id for %s: %d\n", in sof_ipc4_widget_setup()
2735 swidget->widget->name, swidget->instance_id); in sof_ipc4_widget_setup()
2736 return swidget->instance_id; in sof_ipc4_widget_setup()
2738 msg->primary &= ~SOF_IPC4_GLB_PIPE_INSTANCE_MASK; in sof_ipc4_widget_setup()
2739 msg->primary |= SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id); in sof_ipc4_widget_setup()
2745 struct sof_ipc4_copier *ipc4_copier = swidget->private; in sof_ipc4_widget_setup()
2747 pipeline = pipe_widget->private; in sof_ipc4_widget_setup()
2748 if (pipeline->use_chain_dma) in sof_ipc4_widget_setup()
2751 ipc_size = ipc4_copier->ipc_config_size; in sof_ipc4_widget_setup()
2752 ipc_data = ipc4_copier->ipc_config_data; in sof_ipc4_widget_setup()
2754 msg = &ipc4_copier->msg; in sof_ipc4_widget_setup()
2760 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_setup()
2761 struct sof_ipc4_copier *ipc4_copier = dai->private; in sof_ipc4_widget_setup()
2763 pipeline = pipe_widget->private; in sof_ipc4_widget_setup()
2764 if (pipeline->use_chain_dma) in sof_ipc4_widget_setup()
2767 ipc_size = ipc4_copier->ipc_config_size; in sof_ipc4_widget_setup()
2768 ipc_data = ipc4_copier->ipc_config_data; in sof_ipc4_widget_setup()
2770 msg = &ipc4_copier->msg; in sof_ipc4_widget_setup()
2775 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_widget_setup()
2777 ipc_size = sizeof(gain->data); in sof_ipc4_widget_setup()
2778 ipc_data = &gain->data; in sof_ipc4_widget_setup()
2780 msg = &gain->msg; in sof_ipc4_widget_setup()
2785 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_widget_setup()
2787 ipc_size = sizeof(mixer->base_config); in sof_ipc4_widget_setup()
2788 ipc_data = &mixer->base_config; in sof_ipc4_widget_setup()
2790 msg = &mixer->msg; in sof_ipc4_widget_setup()
2795 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_widget_setup()
2797 ipc_size = sizeof(src->data); in sof_ipc4_widget_setup()
2798 ipc_data = &src->data; in sof_ipc4_widget_setup()
2800 msg = &src->msg; in sof_ipc4_widget_setup()
2805 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_widget_setup()
2807 if (!process->ipc_config_size) { in sof_ipc4_widget_setup()
2808 dev_err(sdev->dev, "module %s has no config data!\n", in sof_ipc4_widget_setup()
2809 swidget->widget->name); in sof_ipc4_widget_setup()
2810 return -EINVAL; in sof_ipc4_widget_setup()
2813 ipc_size = process->ipc_config_size; in sof_ipc4_widget_setup()
2814 ipc_data = process->ipc_config_data; in sof_ipc4_widget_setup()
2816 msg = &process->msg; in sof_ipc4_widget_setup()
2820 dev_err(sdev->dev, "widget type %d not supported", swidget->id); in sof_ipc4_widget_setup()
2821 return -EINVAL; in sof_ipc4_widget_setup()
2824 if (swidget->id != snd_soc_dapm_scheduler) { in sof_ipc4_widget_setup()
2825 int module_id = msg->primary & SOF_IPC4_MOD_ID_MASK; in sof_ipc4_widget_setup()
2829 dev_err(sdev->dev, "failed to assign instance id for %s\n", in sof_ipc4_widget_setup()
2830 swidget->widget->name); in sof_ipc4_widget_setup()
2834 msg->primary &= ~SOF_IPC4_MOD_INSTANCE_MASK; in sof_ipc4_widget_setup()
2835 msg->primary |= SOF_IPC4_MOD_INSTANCE(swidget->instance_id); in sof_ipc4_widget_setup()
2837 msg->extension &= ~SOF_IPC4_MOD_EXT_PARAM_SIZE_MASK; in sof_ipc4_widget_setup()
2838 msg->extension |= SOF_IPC4_MOD_EXT_PARAM_SIZE(ipc_size >> 2); in sof_ipc4_widget_setup()
2840 msg->extension &= ~SOF_IPC4_MOD_EXT_PPL_ID_MASK; in sof_ipc4_widget_setup()
2841 msg->extension |= SOF_IPC4_MOD_EXT_PPL_ID(pipe_widget->instance_id); in sof_ipc4_widget_setup()
2843 dev_dbg(sdev->dev, "Create widget %s (pipe %d) - ID %d, instance %d, core %d\n", in sof_ipc4_widget_setup()
2844 swidget->widget->name, swidget->pipeline_id, module_id, in sof_ipc4_widget_setup()
2845 swidget->instance_id, swidget->core); in sof_ipc4_widget_setup()
2847 dev_dbg(sdev->dev, "Create pipeline %s (pipe %d) - instance %d, core %d\n", in sof_ipc4_widget_setup()
2848 swidget->widget->name, swidget->pipeline_id, in sof_ipc4_widget_setup()
2849 swidget->instance_id, swidget->core); in sof_ipc4_widget_setup()
2852 msg->data_size = ipc_size; in sof_ipc4_widget_setup()
2853 msg->data_ptr = ipc_data; in sof_ipc4_widget_setup()
2855 ret = sof_ipc_tx_message_no_reply(sdev->ipc, msg, ipc_size); in sof_ipc4_widget_setup()
2857 dev_err(sdev->dev, "failed to create module %s\n", swidget->widget->name); in sof_ipc4_widget_setup()
2859 if (swidget->id != snd_soc_dapm_scheduler) { in sof_ipc4_widget_setup()
2860 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_setup()
2862 ida_free(&fw_module->m_ida, swidget->instance_id); in sof_ipc4_widget_setup()
2864 ida_free(&pipeline_ida, swidget->instance_id); in sof_ipc4_widget_setup()
2873 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_free()
2874 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_widget_free()
2877 mutex_lock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2880 if (swidget->id == snd_soc_dapm_scheduler) { in sof_ipc4_widget_free()
2881 struct sof_ipc4_pipeline *pipeline = swidget->private; in sof_ipc4_widget_free()
2885 if (pipeline->use_chain_dma) { in sof_ipc4_widget_free()
2886 dev_warn(sdev->dev, "use_chain_dma set for scheduler %s", in sof_ipc4_widget_free()
2887 swidget->widget->name); in sof_ipc4_widget_free()
2888 mutex_unlock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2892 header = SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id); in sof_ipc4_widget_free()
2899 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_widget_free()
2901 dev_err(sdev->dev, "failed to free pipeline widget %s\n", in sof_ipc4_widget_free()
2902 swidget->widget->name); in sof_ipc4_widget_free()
2904 pipeline->mem_usage = 0; in sof_ipc4_widget_free()
2905 pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED; in sof_ipc4_widget_free()
2906 ida_free(&pipeline_ida, swidget->instance_id); in sof_ipc4_widget_free()
2907 swidget->instance_id = -EINVAL; in sof_ipc4_widget_free()
2909 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_free()
2910 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_widget_free()
2912 if (!pipeline->use_chain_dma) in sof_ipc4_widget_free()
2913 ida_free(&fw_module->m_ida, swidget->instance_id); in sof_ipc4_widget_free()
2916 mutex_unlock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2934 pin_binding = src_widget->output_pin_binding; in sof_ipc4_get_queue_id()
2935 queue_ida = &src_widget->output_queue_ida; in sof_ipc4_get_queue_id()
2936 num_pins = src_widget->num_output_pins; in sof_ipc4_get_queue_id()
2937 buddy_name = sink_widget->widget->name; in sof_ipc4_get_queue_id()
2940 pin_binding = sink_widget->input_pin_binding; in sof_ipc4_get_queue_id()
2941 queue_ida = &sink_widget->input_queue_ida; in sof_ipc4_get_queue_id()
2942 num_pins = sink_widget->num_input_pins; in sof_ipc4_get_queue_id()
2943 buddy_name = src_widget->widget->name; in sof_ipc4_get_queue_id()
2946 scomp = current_swidget->scomp; in sof_ipc4_get_queue_id()
2949 dev_err(scomp->dev, "invalid %s num_pins: %d for queue allocation for %s\n", in sof_ipc4_get_queue_id()
2951 num_pins, current_swidget->widget->name); in sof_ipc4_get_queue_id()
2952 return -EINVAL; in sof_ipc4_get_queue_id()
2969 dev_err(scomp->dev, "no %s queue id found from pin binding array for %s\n", in sof_ipc4_get_queue_id()
2971 current_swidget->widget->name); in sof_ipc4_get_queue_id()
2972 return -EINVAL; in sof_ipc4_get_queue_id()
2987 pin_binding = swidget->output_pin_binding; in sof_ipc4_put_queue_id()
2988 queue_ida = &swidget->output_queue_ida; in sof_ipc4_put_queue_id()
2989 num_pins = swidget->num_output_pins; in sof_ipc4_put_queue_id()
2991 pin_binding = swidget->input_pin_binding; in sof_ipc4_put_queue_id()
2992 queue_ida = &swidget->input_queue_ida; in sof_ipc4_put_queue_id()
2993 num_pins = swidget->num_input_pins; in sof_ipc4_put_queue_id()
3009 const struct sof_ipc_ops *iops = sdev->ipc->ops; in sof_ipc4_set_copier_sink_format()
3015 if (WIDGET_IS_DAI(src_widget->id)) { in sof_ipc4_set_copier_sink_format()
3016 struct snd_sof_dai *dai = src_widget->private; in sof_ipc4_set_copier_sink_format()
3018 src_config = dai->private; in sof_ipc4_set_copier_sink_format()
3020 src_config = src_widget->private; in sof_ipc4_set_copier_sink_format()
3023 fw_module = src_widget->module_info; in sof_ipc4_set_copier_sink_format()
3025 format.sink_id = sroute->src_queue_id; in sof_ipc4_set_copier_sink_format()
3026 memcpy(&format.source_fmt, &src_config->audio_fmt, sizeof(format.source_fmt)); in sof_ipc4_set_copier_sink_format()
3028 pin_fmt = sof_ipc4_get_input_pin_audio_fmt(sink_widget, sroute->dst_queue_id); in sof_ipc4_set_copier_sink_format()
3030 dev_err(sdev->dev, in sof_ipc4_set_copier_sink_format()
3032 sink_widget->widget->name, sroute->dst_queue_id, in sof_ipc4_set_copier_sink_format()
3033 src_widget->widget->name, sroute->src_queue_id); in sof_ipc4_set_copier_sink_format()
3034 return -EINVAL; in sof_ipc4_set_copier_sink_format()
3042 msg.primary = fw_module->man4_module_entry.id; in sof_ipc4_set_copier_sink_format()
3043 msg.primary |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_set_copier_sink_format()
3050 return iops->set_get_data(sdev, &msg, msg.data_size, true); in sof_ipc4_set_copier_sink_format()
3055 struct snd_sof_widget *src_widget = sroute->src_widget; in sof_ipc4_route_setup()
3056 struct snd_sof_widget *sink_widget = sroute->sink_widget; in sof_ipc4_route_setup()
3057 struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget; in sof_ipc4_route_setup()
3058 struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget; in sof_ipc4_route_setup()
3059 struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info; in sof_ipc4_route_setup()
3060 struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; in sof_ipc4_route_setup()
3061 struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private; in sof_ipc4_route_setup()
3062 struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private; in sof_ipc4_route_setup()
3068 if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma) { in sof_ipc4_route_setup()
3069 if (!src_pipeline->use_chain_dma || !sink_pipeline->use_chain_dma) { in sof_ipc4_route_setup()
3070 dev_err(sdev->dev, in sof_ipc4_route_setup()
3072 src_widget->widget->name, sink_widget->widget->name); in sof_ipc4_route_setup()
3073 return -EINVAL; in sof_ipc4_route_setup()
3079 dev_err(sdev->dev, in sof_ipc4_route_setup()
3080 "cannot bind %s -> %s, no firmware module for: %s%s\n", in sof_ipc4_route_setup()
3081 src_widget->widget->name, sink_widget->widget->name, in sof_ipc4_route_setup()
3085 return -ENODEV; in sof_ipc4_route_setup()
3088 sroute->src_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, in sof_ipc4_route_setup()
3090 if (sroute->src_queue_id < 0) { in sof_ipc4_route_setup()
3091 dev_err(sdev->dev, in sof_ipc4_route_setup()
3093 src_widget->widget->name); in sof_ipc4_route_setup()
3094 return sroute->src_queue_id; in sof_ipc4_route_setup()
3097 sroute->dst_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, in sof_ipc4_route_setup()
3099 if (sroute->dst_queue_id < 0) { in sof_ipc4_route_setup()
3100 dev_err(sdev->dev, in sof_ipc4_route_setup()
3102 sink_widget->widget->name); in sof_ipc4_route_setup()
3103 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, in sof_ipc4_route_setup()
3105 return sroute->dst_queue_id; in sof_ipc4_route_setup()
3109 if (sroute->src_queue_id > 0 && WIDGET_IS_COPIER(src_widget->id)) { in sof_ipc4_route_setup()
3113 dev_err(sdev->dev, in sof_ipc4_route_setup()
3115 src_widget->widget->name, sroute->src_queue_id); in sof_ipc4_route_setup()
3120 dev_dbg(sdev->dev, "bind %s:%d -> %s:%d\n", in sof_ipc4_route_setup()
3121 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_setup()
3122 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_setup()
3124 header = src_fw_module->man4_module_entry.id; in sof_ipc4_route_setup()
3125 header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_route_setup()
3130 extension = sink_fw_module->man4_module_entry.id; in sof_ipc4_route_setup()
3131 extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id); in sof_ipc4_route_setup()
3132 extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id); in sof_ipc4_route_setup()
3133 extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id); in sof_ipc4_route_setup()
3138 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_route_setup()
3140 dev_err(sdev->dev, "failed to bind modules %s:%d -> %s:%d\n", in sof_ipc4_route_setup()
3141 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_setup()
3142 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_setup()
3149 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT); in sof_ipc4_route_setup()
3150 sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT); in sof_ipc4_route_setup()
3156 struct snd_sof_widget *src_widget = sroute->src_widget; in sof_ipc4_route_free()
3157 struct snd_sof_widget *sink_widget = sroute->sink_widget; in sof_ipc4_route_free()
3158 struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info; in sof_ipc4_route_free()
3159 struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; in sof_ipc4_route_free()
3161 struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget; in sof_ipc4_route_free()
3162 struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget; in sof_ipc4_route_free()
3163 struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private; in sof_ipc4_route_free()
3164 struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private; in sof_ipc4_route_free()
3169 if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma) in sof_ipc4_route_free()
3172 dev_dbg(sdev->dev, "unbind modules %s:%d -> %s:%d\n", in sof_ipc4_route_free()
3173 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_free()
3174 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_free()
3180 if (src_widget->spipe->pipe_widget == sink_widget->spipe->pipe_widget) in sof_ipc4_route_free()
3183 header = src_fw_module->man4_module_entry.id; in sof_ipc4_route_free()
3184 header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_route_free()
3189 extension = sink_fw_module->man4_module_entry.id; in sof_ipc4_route_free()
3190 extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id); in sof_ipc4_route_free()
3191 extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id); in sof_ipc4_route_free()
3192 extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id); in sof_ipc4_route_free()
3197 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_route_free()
3199 dev_err(sdev->dev, "failed to unbind modules %s:%d -> %s:%d\n", in sof_ipc4_route_free()
3200 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_free()
3201 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_free()
3203 sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT); in sof_ipc4_route_free()
3204 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT); in sof_ipc4_route_free()
3212 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_dai_config()
3213 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_dai_config()
3214 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_dai_config()
3219 if (!dai || !dai->private) { in sof_ipc4_dai_config()
3220 dev_err(sdev->dev, "Invalid DAI or DAI private data for %s\n", in sof_ipc4_dai_config()
3221 swidget->widget->name); in sof_ipc4_dai_config()
3222 return -EINVAL; in sof_ipc4_dai_config()
3225 ipc4_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_dai_config()
3226 copier_data = &ipc4_copier->data; in sof_ipc4_dai_config()
3231 if (pipeline->use_chain_dma) { in sof_ipc4_dai_config()
3237 pipeline->msg.primary &= ~SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK; in sof_ipc4_dai_config()
3238 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID(data->dai_data); in sof_ipc4_dai_config()
3243 switch (ipc4_copier->dai_type) { in sof_ipc4_dai_config()
3245 gtw_attr = ipc4_copier->gtw_attr; in sof_ipc4_dai_config()
3246 gtw_attr->lp_buffer_alloc = pipeline->lp_mode; in sof_ipc4_dai_config()
3248 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_dai_config()
3249 copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_data); in sof_ipc4_dai_config()
3256 * unprepare. The node_id for multi-gateway DAI's will be overwritten with the in sof_ipc4_dai_config()
3262 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; in sof_ipc4_dai_config()
3263 ipc4_copier->dai_index = data->dai_node_id; in sof_ipc4_dai_config()
3269 if (blob->alh_cfg.device_count == 1) { in sof_ipc4_dai_config()
3270 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_dai_config()
3271 copier_data->gtw_cfg.node_id |= in sof_ipc4_dai_config()
3272 SOF_IPC4_NODE_INDEX(data->dai_node_id); in sof_ipc4_dai_config()
3282 dev_err(sdev->dev, "%s: unsupported dai type %d\n", __func__, in sof_ipc4_dai_config()
3283 ipc4_copier->dai_type); in sof_ipc4_dai_config()
3284 return -EINVAL; in sof_ipc4_dai_config()
3294 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_parse_manifest()
3297 u32 size = le32_to_cpu(man->priv.size); in sof_ipc4_parse_manifest()
3298 u8 *man_ptr = man->priv.data; in sof_ipc4_parse_manifest()
3303 dev_err(scomp->dev, "%s: Invalid topology ABI size: %u\n", in sof_ipc4_parse_manifest()
3305 return -EINVAL; in sof_ipc4_parse_manifest()
3310 dev_info(scomp->dev, in sof_ipc4_parse_manifest()
3312 le16_to_cpu(manifest->abi_major), le16_to_cpu(manifest->abi_minor), in sof_ipc4_parse_manifest()
3313 le16_to_cpu(manifest->abi_patch), in sof_ipc4_parse_manifest()
3322 manifest_tlv = manifest->items; in sof_ipc4_parse_manifest()
3324 for (i = 0; i < le16_to_cpu(manifest->count); i++) { in sof_ipc4_parse_manifest()
3325 len_check += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size); in sof_ipc4_parse_manifest()
3327 return -EINVAL; in sof_ipc4_parse_manifest()
3329 switch (le32_to_cpu(manifest_tlv->type)) { in sof_ipc4_parse_manifest()
3332 if (ipc4_data->nhlt) in sof_ipc4_parse_manifest()
3334 ipc4_data->nhlt = devm_kmemdup(sdev->dev, manifest_tlv->data, in sof_ipc4_parse_manifest()
3335 le32_to_cpu(manifest_tlv->size), GFP_KERNEL); in sof_ipc4_parse_manifest()
3336 if (!ipc4_data->nhlt) in sof_ipc4_parse_manifest()
3337 return -ENOMEM; in sof_ipc4_parse_manifest()
3340 dev_warn(scomp->dev, "Skipping unknown manifest data type %d\n", in sof_ipc4_parse_manifest()
3341 manifest_tlv->type); in sof_ipc4_parse_manifest()
3344 man_ptr += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size); in sof_ipc4_parse_manifest()
3353 struct sof_ipc4_copier *ipc4_copier = dai->private; in sof_ipc4_dai_get_param()
3363 list_for_each_entry(slink, &sdev->dai_link_list, list) { in sof_ipc4_dai_get_param()
3364 if (!strcmp(slink->link->name, dai->name)) { in sof_ipc4_dai_get_param()
3371 dev_err(sdev->dev, "no DAI link found for DAI %s\n", dai->name); in sof_ipc4_dai_get_param()
3372 return -EINVAL; in sof_ipc4_dai_get_param()
3375 for (i = 0; i < slink->num_hw_configs; i++) { in sof_ipc4_dai_get_param()
3376 hw_config = &slink->hw_configs[i]; in sof_ipc4_dai_get_param()
3377 if (dai->current_config == le32_to_cpu(hw_config->id)) { in sof_ipc4_dai_get_param()
3384 dev_err(sdev->dev, "no matching hw_config found for DAI %s\n", dai->name); in sof_ipc4_dai_get_param()
3385 return -EINVAL; in sof_ipc4_dai_get_param()
3388 switch (ipc4_copier->dai_type) { in sof_ipc4_dai_get_param()
3392 return le32_to_cpu(hw_config->mclk_rate); in sof_ipc4_dai_get_param()
3394 return le32_to_cpu(hw_config->bclk_rate); in sof_ipc4_dai_get_param()
3396 return le32_to_cpu(hw_config->tdm_slots); in sof_ipc4_dai_get_param()
3398 dev_err(sdev->dev, "invalid SSP param %d\n", param_type); in sof_ipc4_dai_get_param()
3403 dev_err(sdev->dev, "DAI type %d not supported yet!\n", ipc4_copier->dai_type); in sof_ipc4_dai_get_param()
3407 return -EINVAL; in sof_ipc4_dai_get_param()
3426 list_for_each_entry(spcm, &sdev->pcm_list, list) { in sof_ipc4_tear_down_all_pipelines()
3428 struct snd_pcm_substream *substream = spcm->stream[dir].substream; in sof_ipc4_tear_down_all_pipelines()
3430 if (!substream || !substream->runtime || spcm->stream[dir].suspend_ignored) in sof_ipc4_tear_down_all_pipelines()
3433 if (spcm->stream[dir].list) { in sof_ipc4_tear_down_all_pipelines()
3445 if (link->no_pcm) in sof_ipc4_link_setup()
3455 link->trigger[SNDRV_PCM_STREAM_PLAYBACK] = SND_SOC_DPCM_TRIGGER_POST; in sof_ipc4_link_setup()
3456 link->trigger[SNDRV_PCM_STREAM_CAPTURE] = SND_SOC_DPCM_TRIGGER_PRE; in sof_ipc4_link_setup()