Lines Matching +full:3 +full:- +full:tuples
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
14 #include <sound/intel-nhlt.h>
15 #include "sof-priv.h"
16 #include "sof-audio.h"
17 #include "ipc4-priv.h"
18 #include "ipc4-topology.h"
176 list_for_each_entry(swidget, &sdev->widget_list, list) { in sof_ipc4_find_swidget_by_ids()
177 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_find_swidget_by_ids()
180 if (!swidget->use_count) in sof_ipc4_find_swidget_by_ids()
183 if (fw_module && fw_module->man4_module_entry.id == module_id && in sof_ipc4_find_swidget_by_ids()
184 swidget->instance_id == instance_id) in sof_ipc4_find_swidget_by_ids()
200 pin_fmt[i].pin_index, fmt->sampling_frequency, fmt->bit_depth, in sof_ipc4_dbg_audio_format()
201 SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg), in sof_ipc4_dbg_audio_format()
202 fmt->ch_map, fmt->ch_cfg, fmt->interleaving_style, fmt->fmt_cfg, in sof_ipc4_dbg_audio_format()
218 if (!available_fmt->num_input_formats && in sof_ipc4_dbg_module_audio_format()
219 !available_fmt->num_output_formats) in sof_ipc4_dbg_module_audio_format()
223 if (!available_fmt->num_input_formats) { in sof_ipc4_dbg_module_audio_format()
224 if (available_fmt->num_output_formats == 1) in sof_ipc4_dbg_module_audio_format()
226 swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
230 out_fmt_index, swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
232 pin_fmt = &available_fmt->output_pin_fmts[out_fmt_index]; in sof_ipc4_dbg_module_audio_format()
236 } else if (!available_fmt->num_output_formats) { in sof_ipc4_dbg_module_audio_format()
237 if (available_fmt->num_input_formats == 1) in sof_ipc4_dbg_module_audio_format()
239 swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
243 out_fmt_index, swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
245 pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index]; in sof_ipc4_dbg_module_audio_format()
251 in_fmt = &available_fmt->input_pin_fmts[in_fmt_index].audio_fmt; in sof_ipc4_dbg_module_audio_format()
252 out_fmt = &available_fmt->output_pin_fmts[out_fmt_index].audio_fmt; in sof_ipc4_dbg_module_audio_format()
254 in_rate = in_fmt->sampling_frequency; in sof_ipc4_dbg_module_audio_format()
255 in_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_dbg_module_audio_format()
256 in_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_dbg_module_audio_format()
258 out_rate = out_fmt->sampling_frequency; in sof_ipc4_dbg_module_audio_format()
259 out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(out_fmt->fmt_cfg); in sof_ipc4_dbg_module_audio_format()
260 out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); in sof_ipc4_dbg_module_audio_format()
265 if (available_fmt->num_input_formats == 1 && in sof_ipc4_dbg_module_audio_format()
266 available_fmt->num_output_formats == 1) in sof_ipc4_dbg_module_audio_format()
268 swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
272 in_fmt_index, out_fmt_index, swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
274 pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index]; in sof_ipc4_dbg_module_audio_format()
281 if (available_fmt->num_input_formats == 1) in sof_ipc4_dbg_module_audio_format()
283 swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
286 in_fmt_index, swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
288 pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index]; in sof_ipc4_dbg_module_audio_format()
291 if (available_fmt->num_output_formats == 1) in sof_ipc4_dbg_module_audio_format()
293 swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
296 out_fmt_index, swidget->widget->name); in sof_ipc4_dbg_module_audio_format()
298 pin_fmt = &available_fmt->output_pin_fmts[out_fmt_index]; in sof_ipc4_dbg_module_audio_format()
309 if (swidget->id != snd_soc_dapm_effect) { in sof_ipc4_get_input_pin_audio_fmt()
310 struct sof_ipc4_base_module_cfg *base = swidget->private; in sof_ipc4_get_input_pin_audio_fmt()
312 /* For non-process modules, base module config format is used for all input pins */ in sof_ipc4_get_input_pin_audio_fmt()
313 return &base->audio_fmt; in sof_ipc4_get_input_pin_audio_fmt()
316 process = swidget->private; in sof_ipc4_get_input_pin_audio_fmt()
322 if (process->init_config != SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) in sof_ipc4_get_input_pin_audio_fmt()
323 return &process->base_config.audio_fmt; in sof_ipc4_get_input_pin_audio_fmt()
325 base_cfg_ext = process->base_config_ext; in sof_ipc4_get_input_pin_audio_fmt()
331 for (i = 0; i < base_cfg_ext->num_input_pin_fmts; i++) { in sof_ipc4_get_input_pin_audio_fmt()
332 struct sof_ipc4_pin_format *pin_format = &base_cfg_ext->pin_formats[i]; in sof_ipc4_get_input_pin_audio_fmt()
334 if (pin_format->pin_index == pin_index) in sof_ipc4_get_input_pin_audio_fmt()
335 return &pin_format->audio_fmt; in sof_ipc4_get_input_pin_audio_fmt()
342 * sof_ipc4_get_audio_fmt - get available audio formats from swidget->tuples
344 * @swidget: pointer to struct snd_sof_widget containing tuples
360 SOF_AUDIO_FMT_NUM_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
361 swidget->num_tuples, sizeof(*available_fmt), 1); in sof_ipc4_get_audio_fmt()
363 dev_err(scomp->dev, "Failed to parse audio format token count\n"); in sof_ipc4_get_audio_fmt()
367 if (!available_fmt->num_input_formats && !available_fmt->num_output_formats) { in sof_ipc4_get_audio_fmt()
368 dev_err(scomp->dev, "No input/output pin formats set in topology\n"); in sof_ipc4_get_audio_fmt()
369 return -EINVAL; in sof_ipc4_get_audio_fmt()
372 dev_dbg(scomp->dev, in sof_ipc4_get_audio_fmt()
374 available_fmt->num_input_formats, available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
377 ret = sof_update_ipc_object(scomp, module_base_cfg, SOF_COMP_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
378 swidget->num_tuples, sizeof(*module_base_cfg), 1); in sof_ipc4_get_audio_fmt()
380 dev_err(scomp->dev, "parse comp tokens for %s failed, error: %d\n", in sof_ipc4_get_audio_fmt()
381 swidget->widget->name, ret); in sof_ipc4_get_audio_fmt()
385 dev_dbg(scomp->dev, "widget %s: is_pages: %d\n", swidget->widget->name, in sof_ipc4_get_audio_fmt()
386 module_base_cfg->is_pages); in sof_ipc4_get_audio_fmt()
388 if (available_fmt->num_input_formats) { in sof_ipc4_get_audio_fmt()
389 in_format = kcalloc(available_fmt->num_input_formats, in sof_ipc4_get_audio_fmt()
392 return -ENOMEM; in sof_ipc4_get_audio_fmt()
393 available_fmt->input_pin_fmts = in_format; in sof_ipc4_get_audio_fmt()
396 SOF_IN_AUDIO_FORMAT_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
397 swidget->num_tuples, sizeof(*in_format), in sof_ipc4_get_audio_fmt()
398 available_fmt->num_input_formats); in sof_ipc4_get_audio_fmt()
400 dev_err(scomp->dev, "parse input audio fmt tokens failed %d\n", ret); in sof_ipc4_get_audio_fmt()
404 dev_dbg(scomp->dev, "Input audio formats for %s\n", swidget->widget->name); in sof_ipc4_get_audio_fmt()
405 sof_ipc4_dbg_audio_format(scomp->dev, in_format, in sof_ipc4_get_audio_fmt()
406 available_fmt->num_input_formats); in sof_ipc4_get_audio_fmt()
409 if (available_fmt->num_output_formats) { in sof_ipc4_get_audio_fmt()
410 out_format = kcalloc(available_fmt->num_output_formats, sizeof(*out_format), in sof_ipc4_get_audio_fmt()
413 ret = -ENOMEM; in sof_ipc4_get_audio_fmt()
418 SOF_OUT_AUDIO_FORMAT_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
419 swidget->num_tuples, sizeof(*out_format), in sof_ipc4_get_audio_fmt()
420 available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
422 dev_err(scomp->dev, "parse output audio fmt tokens failed\n"); in sof_ipc4_get_audio_fmt()
426 available_fmt->output_pin_fmts = out_format; in sof_ipc4_get_audio_fmt()
427 dev_dbg(scomp->dev, "Output audio formats for %s\n", swidget->widget->name); in sof_ipc4_get_audio_fmt()
428 sof_ipc4_dbg_audio_format(scomp->dev, out_format, in sof_ipc4_get_audio_fmt()
429 available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
438 available_fmt->input_pin_fmts = NULL; in sof_ipc4_get_audio_fmt()
446 kfree(available_fmt->output_pin_fmts); in sof_ipc4_free_audio_fmt()
447 available_fmt->output_pin_fmts = NULL; in sof_ipc4_free_audio_fmt()
448 kfree(available_fmt->input_pin_fmts); in sof_ipc4_free_audio_fmt()
449 available_fmt->input_pin_fmts = NULL; in sof_ipc4_free_audio_fmt()
454 kfree(swidget->private); in sof_ipc4_widget_free_comp_pipeline()
459 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_set_module_info()
462 swidget->module_info = sof_ipc4_find_module_by_uuid(sdev, &swidget->uuid); in sof_ipc4_widget_set_module_info()
464 if (swidget->module_info) in sof_ipc4_widget_set_module_info()
467 dev_err(sdev->dev, "failed to find module info for widget %s with UUID %pUL\n", in sof_ipc4_widget_set_module_info()
468 swidget->widget->name, &swidget->uuid); in sof_ipc4_widget_set_module_info()
469 return -EINVAL; in sof_ipc4_widget_set_module_info()
482 fw_module = swidget->module_info; in sof_ipc4_widget_setup_msg()
484 msg->primary = fw_module->man4_module_entry.id; in sof_ipc4_widget_setup_msg()
485 msg->primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_INIT_INSTANCE); in sof_ipc4_widget_setup_msg()
486 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_widget_setup_msg()
487 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_widget_setup_msg()
489 msg->extension = SOF_IPC4_MOD_EXT_CORE_ID(swidget->core); in sof_ipc4_widget_setup_msg()
491 type = (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_DP) ? 1 : 0; in sof_ipc4_widget_setup_msg()
492 msg->extension |= SOF_IPC4_MOD_EXT_DOMAIN(type); in sof_ipc4_widget_setup_msg()
499 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_update_kcontrol_module_id()
501 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_update_kcontrol_module_id()
505 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { in sof_ipc4_widget_update_kcontrol_module_id()
506 if (scontrol->comp_id == swidget->comp_id) { in sof_ipc4_widget_update_kcontrol_module_id()
507 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; in sof_ipc4_widget_update_kcontrol_module_id()
508 struct sof_ipc4_msg *msg = &cdata->msg; in sof_ipc4_widget_update_kcontrol_module_id()
510 msg->primary |= fw_module->man4_module_entry.id; in sof_ipc4_widget_update_kcontrol_module_id()
519 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_update_card_components_string()
520 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_update_card_components_string()
521 struct snd_soc_component *scomp = spcm->scomp; in sof_ipc4_update_card_components_string()
522 struct snd_soc_card *card = scomp->card; in sof_ipc4_update_card_components_string()
523 const char *pt_marker = "iec61937-pcm"; in sof_ipc4_update_card_components_string()
526 * Update the card's components list with iec61937-pcm and a list of PCM in sof_ipc4_update_card_components_string()
530 if (!pipeline->use_chain_dma) in sof_ipc4_update_card_components_string()
533 if (card->components) { in sof_ipc4_update_card_components_string()
534 const char *tmp = card->components; in sof_ipc4_update_card_components_string()
536 if (strstr(card->components, pt_marker)) in sof_ipc4_update_card_components_string()
537 card->components = devm_kasprintf(card->dev, GFP_KERNEL, in sof_ipc4_update_card_components_string()
539 card->components, in sof_ipc4_update_card_components_string()
540 spcm->pcm.pcm_id); in sof_ipc4_update_card_components_string()
542 card->components = devm_kasprintf(card->dev, GFP_KERNEL, in sof_ipc4_update_card_components_string()
544 card->components, in sof_ipc4_update_card_components_string()
546 spcm->pcm.pcm_id); in sof_ipc4_update_card_components_string()
548 devm_kfree(card->dev, tmp); in sof_ipc4_update_card_components_string()
550 card->components = devm_kasprintf(card->dev, GFP_KERNEL, in sof_ipc4_update_card_components_string()
552 spcm->pcm.pcm_id); in sof_ipc4_update_card_components_string()
555 if (!card->components) in sof_ipc4_update_card_components_string()
556 return -ENOMEM; in sof_ipc4_update_card_components_string()
564 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_pcm()
572 return -ENOMEM; in sof_ipc4_widget_setup_pcm()
574 swidget->private = ipc4_copier; in sof_ipc4_widget_setup_pcm()
575 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_setup_pcm()
577 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_pcm()
580 &ipc4_copier->data.base_config); in sof_ipc4_widget_setup_pcm()
585 * This callback is used by host copier and module-to-module copier, in sof_ipc4_widget_setup_pcm()
588 if (!WIDGET_IS_AIF(swidget->id)) in sof_ipc4_widget_setup_pcm()
592 SOF_COPIER_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_pcm()
593 swidget->num_tuples, sizeof(node_type), 1); in sof_ipc4_widget_setup_pcm()
596 dev_err(scomp->dev, "parse host copier node type token failed %d\n", in sof_ipc4_widget_setup_pcm()
600 dev_dbg(scomp->dev, "host copier '%s' node_type %u\n", swidget->widget->name, node_type); in sof_ipc4_widget_setup_pcm()
602 spcm = snd_sof_find_spcm_comp(scomp, swidget->comp_id, &dir); in sof_ipc4_widget_setup_pcm()
611 struct snd_sof_pcm_stream *sps = &spcm->stream[dir]; in sof_ipc4_widget_setup_pcm()
613 sof_update_ipc_object(scomp, &sps->dsp_max_burst_size_in_ms, in sof_ipc4_widget_setup_pcm()
615 swidget->tuples, in sof_ipc4_widget_setup_pcm()
616 swidget->num_tuples, sizeof(u32), 1); in sof_ipc4_widget_setup_pcm()
618 if (!sps->dsp_max_burst_size_in_ms) in sof_ipc4_widget_setup_pcm()
619 sps->dsp_max_burst_size_in_ms = SOF_IPC4_MIN_DMA_BUFFER_SIZE; in sof_ipc4_widget_setup_pcm()
622 spcm->stream[dir].dsp_max_burst_size_in_ms = 1; in sof_ipc4_widget_setup_pcm()
626 ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); in sof_ipc4_widget_setup_pcm()
627 if (!ipc4_copier->gtw_attr) { in sof_ipc4_widget_setup_pcm()
628 ret = -ENOMEM; in sof_ipc4_widget_setup_pcm()
632 ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; in sof_ipc4_widget_setup_pcm()
633 ipc4_copier->data.gtw_cfg.config_length = in sof_ipc4_widget_setup_pcm()
636 switch (swidget->id) { in sof_ipc4_widget_setup_pcm()
639 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); in sof_ipc4_widget_setup_pcm()
642 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID; in sof_ipc4_widget_setup_pcm()
643 ipc4_copier->ipc_config_size = 0; in sof_ipc4_widget_setup_pcm()
646 dev_err(scomp->dev, "invalid widget type %d\n", swidget->id); in sof_ipc4_widget_setup_pcm()
647 ret = -EINVAL; in sof_ipc4_widget_setup_pcm()
652 ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg); in sof_ipc4_widget_setup_pcm()
659 kfree(ipc4_copier->gtw_attr); in sof_ipc4_widget_setup_pcm()
664 swidget->private = NULL; in sof_ipc4_widget_setup_pcm()
670 struct sof_ipc4_copier *ipc4_copier = swidget->private; in sof_ipc4_widget_free_comp_pcm()
676 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_free_comp_pcm()
677 kfree(available_fmt->output_pin_fmts); in sof_ipc4_widget_free_comp_pcm()
678 kfree(ipc4_copier->gtw_attr); in sof_ipc4_widget_free_comp_pcm()
680 swidget->private = NULL; in sof_ipc4_widget_free_comp_pcm()
686 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_dai()
688 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_setup_comp_dai()
697 return -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
699 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_setup_comp_dai()
701 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_dai()
704 &ipc4_copier->data.base_config); in sof_ipc4_widget_setup_comp_dai()
709 SOF_COPIER_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_dai()
710 swidget->num_tuples, sizeof(node_type), 1); in sof_ipc4_widget_setup_comp_dai()
712 dev_err(scomp->dev, "parse dai node type failed %d\n", ret); in sof_ipc4_widget_setup_comp_dai()
717 SOF_DAI_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_dai()
718 swidget->num_tuples, sizeof(u32), 1); in sof_ipc4_widget_setup_comp_dai()
720 dev_err(scomp->dev, "parse dai copier node token failed %d\n", ret); in sof_ipc4_widget_setup_comp_dai()
724 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()
725 node_type, ipc4_copier->dai_type, ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
727 dai->type = ipc4_copier->dai_type; in sof_ipc4_widget_setup_comp_dai()
728 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); in sof_ipc4_widget_setup_comp_dai()
730 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_setup_comp_dai()
731 pipeline = pipe_widget->private; in sof_ipc4_widget_setup_comp_dai()
733 if (pipeline->use_chain_dma && in sof_ipc4_widget_setup_comp_dai()
734 !snd_sof_is_chain_dma_supported(sdev, ipc4_copier->dai_type)) { in sof_ipc4_widget_setup_comp_dai()
735 dev_err(scomp->dev, "Bad DAI type '%d', Chain DMA is not supported\n", in sof_ipc4_widget_setup_comp_dai()
736 ipc4_copier->dai_type); in sof_ipc4_widget_setup_comp_dai()
737 ret = -ENODEV; in sof_ipc4_widget_setup_comp_dai()
741 switch (ipc4_copier->dai_type) { in sof_ipc4_widget_setup_comp_dai()
749 snd_soc_dapm_widget_for_each_source_path(swidget->widget, p) in sof_ipc4_widget_setup_comp_dai()
752 if (swidget->id == snd_soc_dapm_dai_in && src_num == 0) { in sof_ipc4_widget_setup_comp_dai()
756 * It is fine to call kfree(ipc4_copier->copier_config) since in sof_ipc4_widget_setup_comp_dai()
757 * ipc4_copier->copier_config is null. in sof_ipc4_widget_setup_comp_dai()
764 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
768 list_for_each_entry(w, &sdev->widget_list, list) { in sof_ipc4_widget_setup_comp_dai()
771 if (!WIDGET_IS_DAI(w->id) || !w->widget->sname || in sof_ipc4_widget_setup_comp_dai()
772 strcmp(w->widget->sname, swidget->widget->sname)) in sof_ipc4_widget_setup_comp_dai()
775 alh_dai = w->private; in sof_ipc4_widget_setup_comp_dai()
776 if (alh_dai->type != SOF_DAI_INTEL_ALH) in sof_ipc4_widget_setup_comp_dai()
779 blob->alh_cfg.device_count++; in sof_ipc4_widget_setup_comp_dai()
782 ipc4_copier->copier_config = (uint32_t *)blob; in sof_ipc4_widget_setup_comp_dai()
784 ipc4_copier->data.gtw_cfg.config_length = (sizeof(blob->gw_attr) + in sof_ipc4_widget_setup_comp_dai()
785 sizeof(blob->alh_cfg.device_count) + in sof_ipc4_widget_setup_comp_dai()
786 sizeof(*blob->alh_cfg.mapping) * in sof_ipc4_widget_setup_comp_dai()
787 blob->alh_cfg.device_count) >> 2; in sof_ipc4_widget_setup_comp_dai()
792 ipc4_copier->data.gtw_cfg.node_id |= in sof_ipc4_widget_setup_comp_dai()
793 SOF_IPC4_NODE_INDEX_INTEL_SSP(ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
797 ipc4_copier->data.gtw_cfg.node_id |= in sof_ipc4_widget_setup_comp_dai()
798 SOF_IPC4_NODE_INDEX_INTEL_DMIC(ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
801 ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); in sof_ipc4_widget_setup_comp_dai()
802 if (!ipc4_copier->gtw_attr) { in sof_ipc4_widget_setup_comp_dai()
803 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
807 ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; in sof_ipc4_widget_setup_comp_dai()
808 ipc4_copier->data.gtw_cfg.config_length = in sof_ipc4_widget_setup_comp_dai()
813 dai->scomp = scomp; in sof_ipc4_widget_setup_comp_dai()
814 dai->private = ipc4_copier; in sof_ipc4_widget_setup_comp_dai()
817 ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg); in sof_ipc4_widget_setup_comp_dai()
824 kfree(ipc4_copier->copier_config); in sof_ipc4_widget_setup_comp_dai()
829 dai->private = NULL; in sof_ipc4_widget_setup_comp_dai()
830 dai->scomp = NULL; in sof_ipc4_widget_setup_comp_dai()
837 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_free_comp_dai()
843 if (!dai->private) { in sof_ipc4_widget_free_comp_dai()
845 swidget->private = NULL; in sof_ipc4_widget_free_comp_dai()
849 ipc4_copier = dai->private; in sof_ipc4_widget_free_comp_dai()
850 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_free_comp_dai()
852 kfree(available_fmt->output_pin_fmts); in sof_ipc4_widget_free_comp_dai()
853 if (ipc4_copier->dai_type != SOF_DAI_INTEL_SSP && in sof_ipc4_widget_free_comp_dai()
854 ipc4_copier->dai_type != SOF_DAI_INTEL_DMIC) in sof_ipc4_widget_free_comp_dai()
855 kfree(ipc4_copier->copier_config); in sof_ipc4_widget_free_comp_dai()
856 kfree(dai->private); in sof_ipc4_widget_free_comp_dai()
858 swidget->private = NULL; in sof_ipc4_widget_free_comp_dai()
863 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_pipeline()
865 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_pipeline()
870 return -ENOMEM; in sof_ipc4_widget_setup_comp_pipeline()
872 ret = sof_update_ipc_object(scomp, pipeline, SOF_SCHED_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_pipeline()
873 swidget->num_tuples, sizeof(*pipeline), 1); in sof_ipc4_widget_setup_comp_pipeline()
875 dev_err(scomp->dev, "parsing scheduler tokens failed\n"); in sof_ipc4_widget_setup_comp_pipeline()
879 swidget->core = pipeline->core_id; in sof_ipc4_widget_setup_comp_pipeline()
880 spipe->core_mask |= BIT(pipeline->core_id); in sof_ipc4_widget_setup_comp_pipeline()
882 if (pipeline->use_chain_dma) { in sof_ipc4_widget_setup_comp_pipeline()
883 dev_dbg(scomp->dev, "Set up chain DMA for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_pipeline()
884 swidget->private = pipeline; in sof_ipc4_widget_setup_comp_pipeline()
889 ret = sof_update_ipc_object(scomp, swidget, SOF_PIPELINE_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_pipeline()
890 swidget->num_tuples, sizeof(*swidget), 1); in sof_ipc4_widget_setup_comp_pipeline()
892 dev_err(scomp->dev, "parsing pipeline tokens failed\n"); in sof_ipc4_widget_setup_comp_pipeline()
896 dev_dbg(scomp->dev, "pipeline '%s': id %d, pri %d, core_id %u, lp mode %d\n", in sof_ipc4_widget_setup_comp_pipeline()
897 swidget->widget->name, swidget->pipeline_id, in sof_ipc4_widget_setup_comp_pipeline()
898 pipeline->priority, pipeline->core_id, pipeline->lp_mode); in sof_ipc4_widget_setup_comp_pipeline()
900 swidget->private = pipeline; in sof_ipc4_widget_setup_comp_pipeline()
902 pipeline->msg.primary = SOF_IPC4_GLB_PIPE_PRIORITY(pipeline->priority); in sof_ipc4_widget_setup_comp_pipeline()
903 pipeline->msg.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_CREATE_PIPELINE); in sof_ipc4_widget_setup_comp_pipeline()
904 pipeline->msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_widget_setup_comp_pipeline()
905 pipeline->msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG); in sof_ipc4_widget_setup_comp_pipeline()
907 pipeline->msg.extension = pipeline->lp_mode; in sof_ipc4_widget_setup_comp_pipeline()
908 pipeline->msg.extension |= SOF_IPC4_GLB_PIPE_EXT_CORE_ID(pipeline->core_id); in sof_ipc4_widget_setup_comp_pipeline()
909 pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED; in sof_ipc4_widget_setup_comp_pipeline()
919 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_pga()
925 return -ENOMEM; in sof_ipc4_widget_setup_comp_pga()
927 swidget->private = gain; in sof_ipc4_widget_setup_comp_pga()
929 gain->data.params.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK; in sof_ipc4_widget_setup_comp_pga()
930 gain->data.params.init_val = SOF_IPC4_VOL_ZERO_DB; in sof_ipc4_widget_setup_comp_pga()
932 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, &gain->data.base_config); in sof_ipc4_widget_setup_comp_pga()
936 ret = sof_update_ipc_object(scomp, &gain->data.params, SOF_GAIN_TOKENS, in sof_ipc4_widget_setup_comp_pga()
937 swidget->tuples, swidget->num_tuples, sizeof(gain->data), 1); in sof_ipc4_widget_setup_comp_pga()
939 dev_err(scomp->dev, "Parsing gain tokens failed\n"); in sof_ipc4_widget_setup_comp_pga()
943 dev_dbg(scomp->dev, in sof_ipc4_widget_setup_comp_pga()
945 swidget->widget->name, gain->data.params.curve_type, in sof_ipc4_widget_setup_comp_pga()
946 gain->data.params.curve_duration_l, gain->data.params.init_val); in sof_ipc4_widget_setup_comp_pga()
948 ret = sof_ipc4_widget_setup_msg(swidget, &gain->msg); in sof_ipc4_widget_setup_comp_pga()
956 sof_ipc4_free_audio_fmt(&gain->available_fmt); in sof_ipc4_widget_setup_comp_pga()
958 swidget->private = NULL; in sof_ipc4_widget_setup_comp_pga()
964 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_widget_free_comp_pga()
969 sof_ipc4_free_audio_fmt(&gain->available_fmt); in sof_ipc4_widget_free_comp_pga()
970 kfree(swidget->private); in sof_ipc4_widget_free_comp_pga()
971 swidget->private = NULL; in sof_ipc4_widget_free_comp_pga()
976 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_mixer()
980 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_mixer()
984 return -ENOMEM; in sof_ipc4_widget_setup_comp_mixer()
986 swidget->private = mixer; in sof_ipc4_widget_setup_comp_mixer()
988 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &mixer->available_fmt, in sof_ipc4_widget_setup_comp_mixer()
989 &mixer->base_config); in sof_ipc4_widget_setup_comp_mixer()
993 ret = sof_ipc4_widget_setup_msg(swidget, &mixer->msg); in sof_ipc4_widget_setup_comp_mixer()
999 sof_ipc4_free_audio_fmt(&mixer->available_fmt); in sof_ipc4_widget_setup_comp_mixer()
1001 swidget->private = NULL; in sof_ipc4_widget_setup_comp_mixer()
1007 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_src()
1008 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_src()
1012 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_src()
1016 return -ENOMEM; in sof_ipc4_widget_setup_comp_src()
1018 swidget->private = src; in sof_ipc4_widget_setup_comp_src()
1020 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt, in sof_ipc4_widget_setup_comp_src()
1021 &src->data.base_config); in sof_ipc4_widget_setup_comp_src()
1025 ret = sof_update_ipc_object(scomp, &src->data, SOF_SRC_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_src()
1026 swidget->num_tuples, sizeof(*src), 1); in sof_ipc4_widget_setup_comp_src()
1028 dev_err(scomp->dev, "Parsing SRC tokens failed\n"); in sof_ipc4_widget_setup_comp_src()
1032 spipe->core_mask |= BIT(swidget->core); in sof_ipc4_widget_setup_comp_src()
1034 dev_dbg(scomp->dev, "SRC sink rate %d\n", src->data.sink_rate); in sof_ipc4_widget_setup_comp_src()
1036 ret = sof_ipc4_widget_setup_msg(swidget, &src->msg); in sof_ipc4_widget_setup_comp_src()
1042 sof_ipc4_free_audio_fmt(&src->available_fmt); in sof_ipc4_widget_setup_comp_src()
1044 swidget->private = NULL; in sof_ipc4_widget_setup_comp_src()
1050 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_widget_free_comp_src()
1055 sof_ipc4_free_audio_fmt(&src->available_fmt); in sof_ipc4_widget_free_comp_src()
1056 kfree(swidget->private); in sof_ipc4_widget_free_comp_src()
1057 swidget->private = NULL; in sof_ipc4_widget_free_comp_src()
1062 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_widget_free_comp_mixer()
1067 sof_ipc4_free_audio_fmt(&mixer->available_fmt); in sof_ipc4_widget_free_comp_mixer()
1068 kfree(swidget->private); in sof_ipc4_widget_free_comp_mixer()
1069 swidget->private = NULL; in sof_ipc4_widget_free_comp_mixer()
1077 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_process()
1079 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_process()
1086 return -ENOMEM; in sof_ipc4_widget_setup_comp_process()
1088 swidget->private = process; in sof_ipc4_widget_setup_comp_process()
1090 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &process->available_fmt, in sof_ipc4_widget_setup_comp_process()
1091 &process->base_config); in sof_ipc4_widget_setup_comp_process()
1095 ret = sof_ipc4_widget_setup_msg(swidget, &process->msg); in sof_ipc4_widget_setup_comp_process()
1100 fw_module = swidget->module_info; in sof_ipc4_widget_setup_comp_process()
1101 process->init_config = FIELD_GET(SOF_IPC4_MODULE_INIT_CONFIG_MASK, in sof_ipc4_widget_setup_comp_process()
1102 fw_module->man4_module_entry.type); in sof_ipc4_widget_setup_comp_process()
1104 process->ipc_config_size = sizeof(struct sof_ipc4_base_module_cfg); in sof_ipc4_widget_setup_comp_process()
1107 if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) { in sof_ipc4_widget_setup_comp_process()
1110 size_add(swidget->num_input_pins, in sof_ipc4_widget_setup_comp_process()
1111 swidget->num_output_pins)); in sof_ipc4_widget_setup_comp_process()
1115 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_process()
1119 base_cfg_ext->num_input_pin_fmts = swidget->num_input_pins; in sof_ipc4_widget_setup_comp_process()
1120 base_cfg_ext->num_output_pin_fmts = swidget->num_output_pins; in sof_ipc4_widget_setup_comp_process()
1121 process->base_config_ext = base_cfg_ext; in sof_ipc4_widget_setup_comp_process()
1122 process->base_config_ext_size = ext_size; in sof_ipc4_widget_setup_comp_process()
1123 process->ipc_config_size += ext_size; in sof_ipc4_widget_setup_comp_process()
1126 cfg = kzalloc(process->ipc_config_size, GFP_KERNEL); in sof_ipc4_widget_setup_comp_process()
1128 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_process()
1132 process->ipc_config_data = cfg; in sof_ipc4_widget_setup_comp_process()
1137 spipe->core_mask |= BIT(swidget->core); in sof_ipc4_widget_setup_comp_process()
1141 kfree(process->base_config_ext); in sof_ipc4_widget_setup_comp_process()
1142 process->base_config_ext = NULL; in sof_ipc4_widget_setup_comp_process()
1144 sof_ipc4_free_audio_fmt(&process->available_fmt); in sof_ipc4_widget_setup_comp_process()
1147 swidget->private = NULL; in sof_ipc4_widget_setup_comp_process()
1153 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_widget_free_comp_process()
1158 kfree(process->ipc_config_data); in sof_ipc4_widget_free_comp_process()
1159 kfree(process->base_config_ext); in sof_ipc4_widget_free_comp_process()
1160 sof_ipc4_free_audio_fmt(&process->available_fmt); in sof_ipc4_widget_free_comp_process()
1161 kfree(swidget->private); in sof_ipc4_widget_free_comp_process()
1162 swidget->private = NULL; in sof_ipc4_widget_free_comp_process()
1169 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_update_resource_usage()
1175 ibs = base_config->ibs; in sof_ipc4_update_resource_usage()
1176 bss = base_config->is_pages; in sof_ipc4_update_resource_usage()
1181 if (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_LL) { in sof_ipc4_update_resource_usage()
1195 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_update_resource_usage()
1196 pipeline = pipe_widget->private; in sof_ipc4_update_resource_usage()
1197 pipeline->mem_usage += total; in sof_ipc4_update_resource_usage()
1199 /* Update base_config->cpc from the module manifest */ in sof_ipc4_update_resource_usage()
1203 dev_dbg(sdev->dev, "%s: ibs / obs: %u / %u, forcing cpc to 0 from %u\n", in sof_ipc4_update_resource_usage()
1204 swidget->widget->name, base_config->ibs, base_config->obs, in sof_ipc4_update_resource_usage()
1205 base_config->cpc); in sof_ipc4_update_resource_usage()
1206 base_config->cpc = 0; in sof_ipc4_update_resource_usage()
1208 dev_dbg(sdev->dev, "%s: ibs / obs / cpc: %u / %u / %u\n", in sof_ipc4_update_resource_usage()
1209 swidget->widget->name, base_config->ibs, base_config->obs, in sof_ipc4_update_resource_usage()
1210 base_config->cpc); in sof_ipc4_update_resource_usage()
1217 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_assign_instance_id()
1218 int max_instances = fw_module->man4_module_entry.instance_max_count; in sof_ipc4_widget_assign_instance_id()
1220 swidget->instance_id = ida_alloc_max(&fw_module->m_ida, max_instances, GFP_KERNEL); in sof_ipc4_widget_assign_instance_id()
1221 if (swidget->instance_id < 0) { in sof_ipc4_widget_assign_instance_id()
1222 dev_err(sdev->dev, "failed to assign instance id for widget %s", in sof_ipc4_widget_assign_instance_id()
1223 swidget->widget->name); in sof_ipc4_widget_assign_instance_id()
1224 return swidget->instance_id; in sof_ipc4_widget_assign_instance_id()
1237 int valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_update_hw_params()
1252 dev_err(sdev->dev, "invalid PCM valid_bits %d\n", valid_bits); in sof_ipc4_update_hw_params()
1253 return -EINVAL; in sof_ipc4_update_hw_params()
1262 unsigned int rate = fmt->sampling_frequency; in sof_ipc4_update_hw_params()
1265 i->min = rate; in sof_ipc4_update_hw_params()
1266 i->max = rate; in sof_ipc4_update_hw_params()
1270 unsigned int channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_update_hw_params()
1273 i->min = channels; in sof_ipc4_update_hw_params()
1274 i->max = channels; in sof_ipc4_update_hw_params()
1288 rate = fmt->sampling_frequency; in sof_ipc4_is_single_format()
1289 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1290 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1297 _rate = fmt->sampling_frequency; in sof_ipc4_is_single_format()
1298 _channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1299 _valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1315 struct sof_ipc4_pin_format *pin_fmts = available_fmt->output_pin_fmts; in sof_ipc4_init_output_audio_fmt()
1316 u32 pin_fmts_size = available_fmt->num_output_formats; in sof_ipc4_init_output_audio_fmt()
1321 dev_err(sdev->dev, "no output formats for %s\n", in sof_ipc4_init_output_audio_fmt()
1322 swidget->widget->name); in sof_ipc4_init_output_audio_fmt()
1323 return -EINVAL; in sof_ipc4_init_output_audio_fmt()
1341 _out_rate = fmt->sampling_frequency; in sof_ipc4_init_output_audio_fmt()
1342 _out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_init_output_audio_fmt()
1343 _out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_init_output_audio_fmt()
1350 dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n", in sof_ipc4_init_output_audio_fmt()
1353 return -EINVAL; in sof_ipc4_init_output_audio_fmt()
1356 base_config->obs = pin_fmts[i].buffer_size; in sof_ipc4_init_output_audio_fmt()
1371 dev_err(sdev->dev, "invalid pcm frame format %d\n", params_format(params)); in sof_ipc4_get_valid_bits()
1372 return -EINVAL; in sof_ipc4_get_valid_bits()
1382 struct sof_ipc4_pin_format *pin_fmts = available_fmt->input_pin_fmts; in sof_ipc4_init_input_audio_fmt()
1383 u32 pin_fmts_size = available_fmt->num_input_formats; in sof_ipc4_init_input_audio_fmt()
1392 dev_err(sdev->dev, "no input formats for %s\n", swidget->widget->name); in sof_ipc4_init_input_audio_fmt()
1393 return -EINVAL; in sof_ipc4_init_input_audio_fmt()
1414 rate = fmt->sampling_frequency; in sof_ipc4_init_input_audio_fmt()
1415 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_init_input_audio_fmt()
1416 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_init_input_audio_fmt()
1423 dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n", in sof_ipc4_init_input_audio_fmt()
1425 return -EINVAL; in sof_ipc4_init_input_audio_fmt()
1430 memcpy(&base_config->audio_fmt, &pin_fmts[i].audio_fmt, in sof_ipc4_init_input_audio_fmt()
1434 base_config->ibs = pin_fmts[i].buffer_size; in sof_ipc4_init_input_audio_fmt()
1446 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_unprepare_copier_module()
1447 pipeline = pipe_widget->private; in sof_ipc4_unprepare_copier_module()
1448 pipeline->mem_usage = 0; in sof_ipc4_unprepare_copier_module()
1450 if (WIDGET_IS_AIF(swidget->id) || swidget->id == snd_soc_dapm_buffer) { in sof_ipc4_unprepare_copier_module()
1451 if (pipeline->use_chain_dma) { in sof_ipc4_unprepare_copier_module()
1452 pipeline->msg.primary = 0; in sof_ipc4_unprepare_copier_module()
1453 pipeline->msg.extension = 0; in sof_ipc4_unprepare_copier_module()
1455 ipc4_copier = swidget->private; in sof_ipc4_unprepare_copier_module()
1456 } else if (WIDGET_IS_DAI(swidget->id)) { in sof_ipc4_unprepare_copier_module()
1457 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_unprepare_copier_module()
1459 ipc4_copier = dai->private; in sof_ipc4_unprepare_copier_module()
1461 if (pipeline->use_chain_dma) { in sof_ipc4_unprepare_copier_module()
1466 * re-configuration in sof_ipc4_unprepare_copier_module()
1468 pipeline->msg.primary &= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK; in sof_ipc4_unprepare_copier_module()
1469 pipeline->msg.extension = 0; in sof_ipc4_unprepare_copier_module()
1472 if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { in sof_ipc4_unprepare_copier_module()
1476 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; in sof_ipc4_unprepare_copier_module()
1477 if (blob->alh_cfg.device_count > 1) { in sof_ipc4_unprepare_copier_module()
1478 group_id = SOF_IPC4_NODE_INDEX(ipc4_copier->data.gtw_cfg.node_id) - in sof_ipc4_unprepare_copier_module()
1486 kfree(ipc4_copier->ipc_config_data); in sof_ipc4_unprepare_copier_module()
1487 ipc4_copier->ipc_config_data = NULL; in sof_ipc4_unprepare_copier_module()
1488 ipc4_copier->ipc_config_size = 0; in sof_ipc4_unprepare_copier_module()
1503 list_for_each_entry(slink, &sdev->dai_link_list, list) { in snd_sof_get_hw_config_params()
1504 if (!strcmp(slink->link->name, dai->name)) { in snd_sof_get_hw_config_params()
1511 dev_err(sdev->dev, "%s: no DAI link found for DAI %s\n", __func__, dai->name); in snd_sof_get_hw_config_params()
1512 return -EINVAL; in snd_sof_get_hw_config_params()
1515 for (i = 0; i < slink->num_hw_configs; i++) { in snd_sof_get_hw_config_params()
1516 hw_config = &slink->hw_configs[i]; in snd_sof_get_hw_config_params()
1517 if (dai->current_config == le32_to_cpu(hw_config->id)) { in snd_sof_get_hw_config_params()
1524 dev_err(sdev->dev, "%s: no matching hw_config found for DAI %s\n", __func__, in snd_sof_get_hw_config_params()
1525 dai->name); in snd_sof_get_hw_config_params()
1526 return -EINVAL; in snd_sof_get_hw_config_params()
1529 *bit_depth = le32_to_cpu(hw_config->tdm_slot_width); in snd_sof_get_hw_config_params()
1530 *channel_count = le32_to_cpu(hw_config->tdm_slots); in snd_sof_get_hw_config_params()
1531 *sample_rate = le32_to_cpu(hw_config->fsync_rate); in snd_sof_get_hw_config_params()
1533 dev_dbg(sdev->dev, "sample rate: %d sample width: %d channels: %d\n", in snd_sof_get_hw_config_params()
1545 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in snd_sof_get_nhlt_endpoint_data()
1561 * Look for 32-bit blob first instead of 16-bit if copier in snd_sof_get_nhlt_endpoint_data()
1565 dev_dbg(sdev->dev, "Looking for 32-bit blob first for DMIC\n"); in snd_sof_get_nhlt_endpoint_data()
1584 dev_type = intel_nhlt_ssp_device_type(sdev->dev, ipc4_data->nhlt, in snd_sof_get_nhlt_endpoint_data()
1593 dev_dbg(sdev->dev, "dai index %d nhlt type %d direction %d dev type %d\n", in snd_sof_get_nhlt_endpoint_data()
1597 cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, dai_index, nhlt_type, in snd_sof_get_nhlt_endpoint_data()
1606 * The 32-bit blob was not found in NHLT table, try to in snd_sof_get_nhlt_endpoint_data()
1614 * The requested 32-bit blob (no format change for the in snd_sof_get_nhlt_endpoint_data()
1616 * look for 16-bit blob if the copier supports multiple in snd_sof_get_nhlt_endpoint_data()
1625 cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, in snd_sof_get_nhlt_endpoint_data()
1634 dev_err(sdev->dev, in snd_sof_get_nhlt_endpoint_data()
1637 return -EINVAL; in snd_sof_get_nhlt_endpoint_data()
1642 *len = cfg->size >> 2; in snd_sof_get_nhlt_endpoint_data()
1643 *dst = (u32 *)cfg->caps; in snd_sof_get_nhlt_endpoint_data()
1648 * instead of the requested bit depth (16 -> 32 or 32 -> 16). in snd_sof_get_nhlt_endpoint_data()
1685 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_copier_is_single_bitdepth()
1692 _valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_copier_is_single_bitdepth()
1715 rate = fmt->sampling_frequency; in sof_ipc4_adjust_params_to_dai_format()
1716 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_adjust_params_to_dai_format()
1717 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_adjust_params_to_dai_format()
1726 val = fmt->sampling_frequency; in sof_ipc4_adjust_params_to_dai_format()
1731 val = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_adjust_params_to_dai_format()
1736 val = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_adjust_params_to_dai_format()
1763 ipc4_copier = dai->private; in sof_ipc4_prepare_dai_copier()
1764 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_dai_copier()
1765 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_dai_copier()
1773 pin_fmts = available_fmt->output_pin_fmts; in sof_ipc4_prepare_dai_copier()
1774 num_pin_fmts = available_fmt->num_output_formats; in sof_ipc4_prepare_dai_copier()
1776 pin_fmts = available_fmt->input_pin_fmts; in sof_ipc4_prepare_dai_copier()
1777 num_pin_fmts = available_fmt->num_input_formats; in sof_ipc4_prepare_dai_copier()
1789 ipc4_copier->dai_index, in sof_ipc4_prepare_dai_copier()
1790 ipc4_copier->dai_type, dir, in sof_ipc4_prepare_dai_copier()
1791 &ipc4_copier->copier_config, in sof_ipc4_prepare_dai_copier()
1792 &copier_data->gtw_cfg.config_length); in sof_ipc4_prepare_dai_copier()
1807 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_copier_module()
1825 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1829 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_prepare_copier_module()
1830 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_prepare_copier_module()
1833 dev_dbg(sdev->dev, in sof_ipc4_prepare_copier_module()
1835 swidget->widget->name, swidget->id, in sof_ipc4_prepare_copier_module()
1836 str_yes_no(pipeline->use_chain_dma), in sof_ipc4_prepare_copier_module()
1837 platform_params->stream_tag); in sof_ipc4_prepare_copier_module()
1841 SOF_COPIER_DEEP_BUFFER_TOKENS, swidget->tuples, in sof_ipc4_prepare_copier_module()
1842 swidget->num_tuples, sizeof(u32), 1); in sof_ipc4_prepare_copier_module()
1844 dev_err(scomp->dev, "Failed to parse deep buffer dma size for %s\n", in sof_ipc4_prepare_copier_module()
1845 swidget->widget->name); in sof_ipc4_prepare_copier_module()
1849 ipc4_copier = (struct sof_ipc4_copier *)swidget->private; in sof_ipc4_prepare_copier_module()
1850 gtw_attr = ipc4_copier->gtw_attr; in sof_ipc4_prepare_copier_module()
1851 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1852 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1854 if (pipeline->use_chain_dma) { in sof_ipc4_prepare_copier_module()
1858 host_dma_id = platform_params->stream_tag - 1; in sof_ipc4_prepare_copier_module()
1859 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_HOST_ID(host_dma_id); in sof_ipc4_prepare_copier_module()
1863 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK; in sof_ipc4_prepare_copier_module()
1873 pipeline->msg.extension |= SOF_IPC4_GLB_EXT_CHAIN_DMA_FIFO_SIZE(fifo_size); in sof_ipc4_prepare_copier_module()
1879 copier_data->gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID; in sof_ipc4_prepare_copier_module()
1893 return -ENOMEM; in sof_ipc4_prepare_copier_module()
1895 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_prepare_copier_module()
1896 copier_data->gtw_cfg.node_id |= in sof_ipc4_prepare_copier_module()
1897 SOF_IPC4_NODE_INDEX(platform_params->stream_tag - 1); in sof_ipc4_prepare_copier_module()
1900 gtw_attr->lp_buffer_alloc = pipeline->lp_mode; in sof_ipc4_prepare_copier_module()
1906 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_prepare_copier_module()
1907 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_prepare_copier_module()
1909 dev_dbg(sdev->dev, "Dai copier %s, type %d, ChainDMA: %s\n", in sof_ipc4_prepare_copier_module()
1910 swidget->widget->name, swidget->id, in sof_ipc4_prepare_copier_module()
1911 str_yes_no(pipeline->use_chain_dma)); in sof_ipc4_prepare_copier_module()
1913 if (pipeline->use_chain_dma) in sof_ipc4_prepare_copier_module()
1916 dai = swidget->private; in sof_ipc4_prepare_copier_module()
1918 ipc4_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_prepare_copier_module()
1919 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1920 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1932 return -ENOMEM; in sof_ipc4_prepare_copier_module()
1949 dev_dbg(sdev->dev, "Module copier %s, type %d\n", in sof_ipc4_prepare_copier_module()
1950 swidget->widget->name, swidget->id); in sof_ipc4_prepare_copier_module()
1952 ipc4_copier = (struct sof_ipc4_copier *)swidget->private; in sof_ipc4_prepare_copier_module()
1953 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1954 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1958 return -ENOMEM; in sof_ipc4_prepare_copier_module()
1963 dev_err(sdev->dev, "unsupported type %d for copier %s", in sof_ipc4_prepare_copier_module()
1964 swidget->id, swidget->widget->name); in sof_ipc4_prepare_copier_module()
1965 return -EINVAL; in sof_ipc4_prepare_copier_module()
1970 &copier_data->base_config, in sof_ipc4_prepare_copier_module()
1977 available_fmt->output_pin_fmts, in sof_ipc4_prepare_copier_module()
1978 available_fmt->num_output_formats); in sof_ipc4_prepare_copier_module()
1979 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1986 in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; in sof_ipc4_prepare_copier_module()
1987 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_copier_module()
1988 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
1992 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
2010 return -EINVAL; in sof_ipc4_prepare_copier_module()
2020 out_fmt = &available_fmt->output_pin_fmts[0].audio_fmt; in sof_ipc4_prepare_copier_module()
2022 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
2026 &copier_data->base_config, in sof_ipc4_prepare_copier_module()
2039 memcpy(&copier_data->out_format, in sof_ipc4_prepare_copier_module()
2040 &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt, in sof_ipc4_prepare_copier_module()
2043 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
2051 if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { in sof_ipc4_prepare_copier_module()
2063 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; in sof_ipc4_prepare_copier_module()
2065 blob->gw_attr.lp_buffer_alloc = 0; in sof_ipc4_prepare_copier_module()
2068 ch_map = copier_data->base_config.audio_fmt.ch_map; in sof_ipc4_prepare_copier_module()
2077 step = ch_count / blob->alh_cfg.device_count; in sof_ipc4_prepare_copier_module()
2078 mask = GENMASK(step - 1, 0); in sof_ipc4_prepare_copier_module()
2080 * Set each gtw_cfg.node_id to blob->alh_cfg.mapping[] in sof_ipc4_prepare_copier_module()
2084 list_for_each_entry(w, &sdev->widget_list, list) { in sof_ipc4_prepare_copier_module()
2087 if (!WIDGET_IS_DAI(w->id) || !w->widget->sname || in sof_ipc4_prepare_copier_module()
2088 strcmp(w->widget->sname, swidget->widget->sname)) in sof_ipc4_prepare_copier_module()
2091 dai = w->private; in sof_ipc4_prepare_copier_module()
2092 if (dai->type != SOF_DAI_INTEL_ALH) in sof_ipc4_prepare_copier_module()
2094 alh_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_prepare_copier_module()
2095 alh_data = &alh_copier->data; in sof_ipc4_prepare_copier_module()
2096 node_type = SOF_IPC4_GET_NODE_TYPE(alh_data->gtw_cfg.node_id); in sof_ipc4_prepare_copier_module()
2097 blob->alh_cfg.mapping[i].device = SOF_IPC4_NODE_TYPE(node_type); in sof_ipc4_prepare_copier_module()
2098 blob->alh_cfg.mapping[i].device |= in sof_ipc4_prepare_copier_module()
2099 SOF_IPC4_NODE_INDEX(alh_copier->dai_index); in sof_ipc4_prepare_copier_module()
2106 if (ipc4_copier->dma_config_tlv[i].length) { in sof_ipc4_prepare_copier_module()
2107 dma_config = &ipc4_copier->dma_config_tlv[i].dma_config; in sof_ipc4_prepare_copier_module()
2108 blob->alh_cfg.mapping[i].device = in sof_ipc4_prepare_copier_module()
2109 dma_config->dma_stream_channel_map.mapping[0].device; in sof_ipc4_prepare_copier_module()
2123 if (w->id == snd_soc_dapm_dai_in) in sof_ipc4_prepare_copier_module()
2124 blob->alh_cfg.mapping[i].channel_mask = ch_mask; in sof_ipc4_prepare_copier_module()
2126 blob->alh_cfg.mapping[i].channel_mask = mask << (step * i); in sof_ipc4_prepare_copier_module()
2130 if (blob->alh_cfg.device_count > 1) { in sof_ipc4_prepare_copier_module()
2133 group_id = ida_alloc_max(&alh_group_ida, ALH_MULTI_GTW_COUNT - 1, in sof_ipc4_prepare_copier_module()
2139 /* add multi-gateway base */ in sof_ipc4_prepare_copier_module()
2141 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_prepare_copier_module()
2142 copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(group_id); in sof_ipc4_prepare_copier_module()
2150 &copier_data->out_format, in sof_ipc4_prepare_copier_module()
2162 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
2164 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
2165 SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.ibs; in sof_ipc4_prepare_copier_module()
2168 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
2170 copier_data->base_config.ibs; in sof_ipc4_prepare_copier_module()
2171 dev_dbg(sdev->dev, "copier %s, dma buffer%s: %u ms (%u bytes)", in sof_ipc4_prepare_copier_module()
2172 swidget->widget->name, in sof_ipc4_prepare_copier_module()
2175 copier_data->gtw_cfg.dma_buffer_size); in sof_ipc4_prepare_copier_module()
2179 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
2180 SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.obs; in sof_ipc4_prepare_copier_module()
2186 data = &ipc4_copier->copier_config; in sof_ipc4_prepare_copier_module()
2187 ipc_config_size = &ipc4_copier->ipc_config_size; in sof_ipc4_prepare_copier_module()
2188 ipc_config_data = &ipc4_copier->ipc_config_data; in sof_ipc4_prepare_copier_module()
2191 gtw_cfg_config_length = copier_data->gtw_cfg.config_length * 4; in sof_ipc4_prepare_copier_module()
2196 if (ipc4_copier->dma_config_tlv[i].type != SOF_IPC4_GTW_DMA_CONFIG_ID) in sof_ipc4_prepare_copier_module()
2198 dma_config_tlv_size += ipc4_copier->dma_config_tlv[i].length; in sof_ipc4_prepare_copier_module()
2200 ipc4_copier->dma_config_tlv[i].dma_config.dma_priv_config_size; in sof_ipc4_prepare_copier_module()
2201 dma_config_tlv_size += (sizeof(ipc4_copier->dma_config_tlv[i]) - in sof_ipc4_prepare_copier_module()
2202 sizeof(ipc4_copier->dma_config_tlv[i].dma_config)); in sof_ipc4_prepare_copier_module()
2209 copier_data->gtw_cfg.config_length += dma_config_tlv_size / 4; in sof_ipc4_prepare_copier_module()
2212 dev_dbg(sdev->dev, "copier %s, IPC size is %d", swidget->widget->name, ipc_size); in sof_ipc4_prepare_copier_module()
2216 return -ENOMEM; in sof_ipc4_prepare_copier_module()
2220 sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, in sof_ipc4_prepare_copier_module()
2224 sof_ipc4_update_resource_usage(sdev, swidget, &copier_data->base_config); in sof_ipc4_prepare_copier_module()
2236 &ipc4_copier->dma_config_tlv, dma_config_tlv_size); in sof_ipc4_prepare_copier_module()
2242 copier_data->gtw_cfg.config_length = gtw_cfg_config_length / 4; in sof_ipc4_prepare_copier_module()
2252 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_gain_module()
2254 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_prepare_gain_module()
2255 struct sof_ipc4_available_audio_format *available_fmt = &gain->available_fmt; in sof_ipc4_prepare_gain_module()
2261 &gain->data.base_config, in sof_ipc4_prepare_gain_module()
2267 in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; in sof_ipc4_prepare_gain_module()
2268 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_gain_module()
2269 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_gain_module()
2270 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_gain_module()
2273 &gain->data.base_config, in sof_ipc4_prepare_gain_module()
2281 sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, in sof_ipc4_prepare_gain_module()
2285 sof_ipc4_update_resource_usage(sdev, swidget, &gain->data.base_config); in sof_ipc4_prepare_gain_module()
2295 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_mixer_module()
2297 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_prepare_mixer_module()
2298 struct sof_ipc4_available_audio_format *available_fmt = &mixer->available_fmt; in sof_ipc4_prepare_mixer_module()
2304 &mixer->base_config, in sof_ipc4_prepare_mixer_module()
2310 in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; in sof_ipc4_prepare_mixer_module()
2311 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_mixer_module()
2312 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_mixer_module()
2313 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_mixer_module()
2316 &mixer->base_config, in sof_ipc4_prepare_mixer_module()
2324 sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, in sof_ipc4_prepare_mixer_module()
2328 sof_ipc4_update_resource_usage(sdev, swidget, &mixer->base_config); in sof_ipc4_prepare_mixer_module()
2338 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_src_module()
2340 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_prepare_src_module()
2341 struct sof_ipc4_available_audio_format *available_fmt = &src->available_fmt; in sof_ipc4_prepare_src_module()
2348 &src->data.base_config, in sof_ipc4_prepare_src_module()
2358 if (dir == SNDRV_PCM_STREAM_PLAYBACK && available_fmt->num_output_formats > 1) { in sof_ipc4_prepare_src_module()
2359 dev_err(sdev->dev, "Invalid number of output formats: %d for SRC %s\n", in sof_ipc4_prepare_src_module()
2360 available_fmt->num_output_formats, swidget->widget->name); in sof_ipc4_prepare_src_module()
2361 return -EINVAL; in sof_ipc4_prepare_src_module()
2368 in_audio_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; in sof_ipc4_prepare_src_module()
2369 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_audio_fmt->fmt_cfg); in sof_ipc4_prepare_src_module()
2370 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_audio_fmt->fmt_cfg); in sof_ipc4_prepare_src_module()
2380 &src->data.base_config, in sof_ipc4_prepare_src_module()
2388 sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, in sof_ipc4_prepare_src_module()
2392 sof_ipc4_update_resource_usage(sdev, swidget, &src->data.base_config); in sof_ipc4_prepare_src_module()
2394 out_audio_fmt = &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt; in sof_ipc4_prepare_src_module()
2395 src->data.sink_rate = out_audio_fmt->sampling_frequency; in sof_ipc4_prepare_src_module()
2407 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_process_set_pin_formats()
2408 struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext; in sof_ipc4_process_set_pin_formats()
2409 struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt; in sof_ipc4_process_set_pin_formats()
2411 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_process_set_pin_formats()
2418 num_pins = swidget->num_input_pins; in sof_ipc4_process_set_pin_formats()
2419 format_list_to_search = available_fmt->input_pin_fmts; in sof_ipc4_process_set_pin_formats()
2420 format_list_count = available_fmt->num_input_formats; in sof_ipc4_process_set_pin_formats()
2422 num_pins = swidget->num_output_pins; in sof_ipc4_process_set_pin_formats()
2423 pin_format_offset = swidget->num_input_pins; in sof_ipc4_process_set_pin_formats()
2424 format_list_to_search = available_fmt->output_pin_fmts; in sof_ipc4_process_set_pin_formats()
2425 format_list_count = available_fmt->num_output_formats; in sof_ipc4_process_set_pin_formats()
2429 pin_format = &base_cfg_ext->pin_formats[i]; in sof_ipc4_process_set_pin_formats()
2434 pin_format->buffer_size = process->base_config.ibs; in sof_ipc4_process_set_pin_formats()
2435 pin_format->audio_fmt = process->base_config.audio_fmt; in sof_ipc4_process_set_pin_formats()
2437 pin_format->buffer_size = process->base_config.obs; in sof_ipc4_process_set_pin_formats()
2438 pin_format->audio_fmt = process->output_format; in sof_ipc4_process_set_pin_formats()
2451 if (pin_format_item->pin_index == i - pin_format_offset) { in sof_ipc4_process_set_pin_formats()
2458 dev_err(scomp->dev, "%s pin %d format not found for %s\n", in sof_ipc4_process_set_pin_formats()
2460 i - pin_format_offset, swidget->widget->name); in sof_ipc4_process_set_pin_formats()
2461 return -EINVAL; in sof_ipc4_process_set_pin_formats()
2487 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_process_module()
2489 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_prepare_process_module()
2490 struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt; in sof_ipc4_prepare_process_module()
2491 void *cfg = process->ipc_config_data; in sof_ipc4_prepare_process_module()
2497 &process->base_config, in sof_ipc4_prepare_process_module()
2504 if (available_fmt->num_output_formats) { in sof_ipc4_prepare_process_module()
2510 in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; in sof_ipc4_prepare_process_module()
2512 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_process_module()
2513 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_process_module()
2514 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_process_module()
2517 &process->base_config, in sof_ipc4_prepare_process_module()
2525 pin_fmt = &available_fmt->output_pin_fmts[output_fmt_index]; in sof_ipc4_prepare_process_module()
2528 if (pin_fmt->pin_index == 0) { in sof_ipc4_prepare_process_module()
2529 memcpy(&process->output_format, &pin_fmt->audio_fmt, in sof_ipc4_prepare_process_module()
2534 &process->output_format, in sof_ipc4_prepare_process_module()
2543 sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, in sof_ipc4_prepare_process_module()
2547 sof_ipc4_update_resource_usage(sdev, swidget, &process->base_config); in sof_ipc4_prepare_process_module()
2550 memcpy(cfg, &process->base_config, sizeof(struct sof_ipc4_base_module_cfg)); in sof_ipc4_prepare_process_module()
2553 if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) { in sof_ipc4_prepare_process_module()
2554 struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext; in sof_ipc4_prepare_process_module()
2560 memcpy(cfg, base_cfg_ext, process->base_config_ext_size); in sof_ipc4_prepare_process_module()
2572 scontrol->size = struct_size(control_data, chanv, scontrol->num_channels); in sof_ipc4_control_load_volume()
2574 /* scontrol->ipc_control_data will be freed in sof_control_unload */ in sof_ipc4_control_load_volume()
2575 scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL); in sof_ipc4_control_load_volume()
2576 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_volume()
2577 return -ENOMEM; in sof_ipc4_control_load_volume()
2579 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_volume()
2580 control_data->index = scontrol->index; in sof_ipc4_control_load_volume()
2582 msg = &control_data->msg; in sof_ipc4_control_load_volume()
2583 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_volume()
2584 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_volume()
2585 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_volume()
2587 /* volume controls with range 0-1 (off/on) are switch controls */ in sof_ipc4_control_load_volume()
2588 if (scontrol->max == 1) in sof_ipc4_control_load_volume()
2589 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_SWITCH_CONTROL_PARAM_ID); in sof_ipc4_control_load_volume()
2591 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_GAIN_PARAM_ID); in sof_ipc4_control_load_volume()
2593 for (i = 0; i < scontrol->num_channels; i++) { in sof_ipc4_control_load_volume()
2594 control_data->chanv[i].channel = i; in sof_ipc4_control_load_volume()
2597 * - 0dB for volume controls in sof_ipc4_control_load_volume()
2598 * - off (0) for switch controls - value already zero after in sof_ipc4_control_load_volume()
2601 if (scontrol->max > 1) in sof_ipc4_control_load_volume()
2602 control_data->chanv[i].value = SOF_IPC4_VOL_ZERO_DB; in sof_ipc4_control_load_volume()
2614 scontrol->size = struct_size(control_data, chanv, scontrol->num_channels); in sof_ipc4_control_load_enum()
2616 /* scontrol->ipc_control_data will be freed in sof_control_unload */ in sof_ipc4_control_load_enum()
2617 scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL); in sof_ipc4_control_load_enum()
2618 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_enum()
2619 return -ENOMEM; in sof_ipc4_control_load_enum()
2621 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_enum()
2622 control_data->index = scontrol->index; in sof_ipc4_control_load_enum()
2624 msg = &control_data->msg; in sof_ipc4_control_load_enum()
2625 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_enum()
2626 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_enum()
2627 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_enum()
2629 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_ENUM_CONTROL_PARAM_ID); in sof_ipc4_control_load_enum()
2632 for (i = 0; i < scontrol->num_channels; i++) in sof_ipc4_control_load_enum()
2633 control_data->chanv[i].channel = i; in sof_ipc4_control_load_enum()
2644 if (scontrol->max_size < (sizeof(*control_data) + sizeof(struct sof_abi_hdr))) { in sof_ipc4_control_load_bytes()
2645 dev_err(sdev->dev, "insufficient size for a bytes control %s: %zu.\n", in sof_ipc4_control_load_bytes()
2646 scontrol->name, scontrol->max_size); in sof_ipc4_control_load_bytes()
2647 return -EINVAL; in sof_ipc4_control_load_bytes()
2650 if (scontrol->priv_size > scontrol->max_size - sizeof(*control_data)) { in sof_ipc4_control_load_bytes()
2651 dev_err(sdev->dev, "scontrol %s bytes data size %zu exceeds max %zu.\n", in sof_ipc4_control_load_bytes()
2652 scontrol->name, scontrol->priv_size, in sof_ipc4_control_load_bytes()
2653 scontrol->max_size - sizeof(*control_data)); in sof_ipc4_control_load_bytes()
2654 return -EINVAL; in sof_ipc4_control_load_bytes()
2657 scontrol->size = sizeof(struct sof_ipc4_control_data) + scontrol->priv_size; in sof_ipc4_control_load_bytes()
2659 scontrol->ipc_control_data = kzalloc(scontrol->max_size, GFP_KERNEL); in sof_ipc4_control_load_bytes()
2660 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_bytes()
2661 return -ENOMEM; in sof_ipc4_control_load_bytes()
2663 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_bytes()
2664 control_data->index = scontrol->index; in sof_ipc4_control_load_bytes()
2665 if (scontrol->priv_size > 0) { in sof_ipc4_control_load_bytes()
2666 memcpy(control_data->data, scontrol->priv, scontrol->priv_size); in sof_ipc4_control_load_bytes()
2667 kfree(scontrol->priv); in sof_ipc4_control_load_bytes()
2668 scontrol->priv = NULL; in sof_ipc4_control_load_bytes()
2670 if (control_data->data->magic != SOF_IPC4_ABI_MAGIC) { in sof_ipc4_control_load_bytes()
2671 dev_err(sdev->dev, "Wrong ABI magic (%#x) for control: %s\n", in sof_ipc4_control_load_bytes()
2672 control_data->data->magic, scontrol->name); in sof_ipc4_control_load_bytes()
2673 ret = -EINVAL; in sof_ipc4_control_load_bytes()
2679 if (control_data->data->size + sizeof(struct sof_abi_hdr) != in sof_ipc4_control_load_bytes()
2680 scontrol->priv_size) { in sof_ipc4_control_load_bytes()
2681 dev_err(sdev->dev, "Control %s conflict in bytes %zu vs. priv size %zu.\n", in sof_ipc4_control_load_bytes()
2682 scontrol->name, in sof_ipc4_control_load_bytes()
2683 control_data->data->size + sizeof(struct sof_abi_hdr), in sof_ipc4_control_load_bytes()
2684 scontrol->priv_size); in sof_ipc4_control_load_bytes()
2685 ret = -EINVAL; in sof_ipc4_control_load_bytes()
2690 msg = &control_data->msg; in sof_ipc4_control_load_bytes()
2691 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_bytes()
2692 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_bytes()
2693 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_bytes()
2698 kfree(scontrol->ipc_control_data); in sof_ipc4_control_load_bytes()
2699 scontrol->ipc_control_data = NULL; in sof_ipc4_control_load_bytes()
2705 switch (scontrol->info_type) { in sof_ipc4_control_setup()
2724 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_setup()
2725 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_widget_setup()
2732 switch (swidget->id) { in sof_ipc4_widget_setup()
2734 pipeline = swidget->private; in sof_ipc4_widget_setup()
2736 if (pipeline->use_chain_dma) { in sof_ipc4_widget_setup()
2737 dev_warn(sdev->dev, "use_chain_dma set for scheduler %s", in sof_ipc4_widget_setup()
2738 swidget->widget->name); in sof_ipc4_widget_setup()
2742 dev_dbg(sdev->dev, "pipeline: %d memory pages: %d\n", swidget->pipeline_id, in sof_ipc4_widget_setup()
2743 pipeline->mem_usage); in sof_ipc4_widget_setup()
2745 msg = &pipeline->msg; in sof_ipc4_widget_setup()
2746 msg->primary |= pipeline->mem_usage; in sof_ipc4_widget_setup()
2748 swidget->instance_id = ida_alloc_max(&pipeline_ida, ipc4_data->max_num_pipelines, in sof_ipc4_widget_setup()
2750 if (swidget->instance_id < 0) { in sof_ipc4_widget_setup()
2751 dev_err(sdev->dev, "failed to assign pipeline id for %s: %d\n", in sof_ipc4_widget_setup()
2752 swidget->widget->name, swidget->instance_id); in sof_ipc4_widget_setup()
2753 return swidget->instance_id; in sof_ipc4_widget_setup()
2755 msg->primary &= ~SOF_IPC4_GLB_PIPE_INSTANCE_MASK; in sof_ipc4_widget_setup()
2756 msg->primary |= SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id); in sof_ipc4_widget_setup()
2762 struct sof_ipc4_copier *ipc4_copier = swidget->private; in sof_ipc4_widget_setup()
2764 pipeline = pipe_widget->private; in sof_ipc4_widget_setup()
2765 if (pipeline->use_chain_dma) in sof_ipc4_widget_setup()
2768 ipc_size = ipc4_copier->ipc_config_size; in sof_ipc4_widget_setup()
2769 ipc_data = ipc4_copier->ipc_config_data; in sof_ipc4_widget_setup()
2771 msg = &ipc4_copier->msg; in sof_ipc4_widget_setup()
2777 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_setup()
2778 struct sof_ipc4_copier *ipc4_copier = dai->private; in sof_ipc4_widget_setup()
2780 pipeline = pipe_widget->private; in sof_ipc4_widget_setup()
2781 if (pipeline->use_chain_dma) in sof_ipc4_widget_setup()
2784 ipc_size = ipc4_copier->ipc_config_size; in sof_ipc4_widget_setup()
2785 ipc_data = ipc4_copier->ipc_config_data; in sof_ipc4_widget_setup()
2787 msg = &ipc4_copier->msg; in sof_ipc4_widget_setup()
2792 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_widget_setup()
2794 ipc_size = sizeof(gain->data); in sof_ipc4_widget_setup()
2795 ipc_data = &gain->data; in sof_ipc4_widget_setup()
2797 msg = &gain->msg; in sof_ipc4_widget_setup()
2802 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_widget_setup()
2804 ipc_size = sizeof(mixer->base_config); in sof_ipc4_widget_setup()
2805 ipc_data = &mixer->base_config; in sof_ipc4_widget_setup()
2807 msg = &mixer->msg; in sof_ipc4_widget_setup()
2812 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_widget_setup()
2814 ipc_size = sizeof(src->data); in sof_ipc4_widget_setup()
2815 ipc_data = &src->data; in sof_ipc4_widget_setup()
2817 msg = &src->msg; in sof_ipc4_widget_setup()
2822 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_widget_setup()
2824 if (!process->ipc_config_size) { in sof_ipc4_widget_setup()
2825 dev_err(sdev->dev, "module %s has no config data!\n", in sof_ipc4_widget_setup()
2826 swidget->widget->name); in sof_ipc4_widget_setup()
2827 return -EINVAL; in sof_ipc4_widget_setup()
2830 ipc_size = process->ipc_config_size; in sof_ipc4_widget_setup()
2831 ipc_data = process->ipc_config_data; in sof_ipc4_widget_setup()
2833 msg = &process->msg; in sof_ipc4_widget_setup()
2837 dev_err(sdev->dev, "widget type %d not supported", swidget->id); in sof_ipc4_widget_setup()
2838 return -EINVAL; in sof_ipc4_widget_setup()
2841 if (swidget->id != snd_soc_dapm_scheduler) { in sof_ipc4_widget_setup()
2842 int module_id = msg->primary & SOF_IPC4_MOD_ID_MASK; in sof_ipc4_widget_setup()
2846 dev_err(sdev->dev, "failed to assign instance id for %s\n", in sof_ipc4_widget_setup()
2847 swidget->widget->name); in sof_ipc4_widget_setup()
2851 msg->primary &= ~SOF_IPC4_MOD_INSTANCE_MASK; in sof_ipc4_widget_setup()
2852 msg->primary |= SOF_IPC4_MOD_INSTANCE(swidget->instance_id); in sof_ipc4_widget_setup()
2854 msg->extension &= ~SOF_IPC4_MOD_EXT_PARAM_SIZE_MASK; in sof_ipc4_widget_setup()
2855 msg->extension |= SOF_IPC4_MOD_EXT_PARAM_SIZE(ipc_size >> 2); in sof_ipc4_widget_setup()
2857 msg->extension &= ~SOF_IPC4_MOD_EXT_PPL_ID_MASK; in sof_ipc4_widget_setup()
2858 msg->extension |= SOF_IPC4_MOD_EXT_PPL_ID(pipe_widget->instance_id); in sof_ipc4_widget_setup()
2860 dev_dbg(sdev->dev, "Create widget %s (pipe %d) - ID %d, instance %d, core %d\n", in sof_ipc4_widget_setup()
2861 swidget->widget->name, swidget->pipeline_id, module_id, in sof_ipc4_widget_setup()
2862 swidget->instance_id, swidget->core); in sof_ipc4_widget_setup()
2864 dev_dbg(sdev->dev, "Create pipeline %s (pipe %d) - instance %d, core %d\n", in sof_ipc4_widget_setup()
2865 swidget->widget->name, swidget->pipeline_id, in sof_ipc4_widget_setup()
2866 swidget->instance_id, swidget->core); in sof_ipc4_widget_setup()
2869 msg->data_size = ipc_size; in sof_ipc4_widget_setup()
2870 msg->data_ptr = ipc_data; in sof_ipc4_widget_setup()
2872 ret = sof_ipc_tx_message_no_reply(sdev->ipc, msg, ipc_size); in sof_ipc4_widget_setup()
2874 dev_err(sdev->dev, "failed to create module %s\n", swidget->widget->name); in sof_ipc4_widget_setup()
2876 if (swidget->id != snd_soc_dapm_scheduler) { in sof_ipc4_widget_setup()
2877 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_setup()
2879 ida_free(&fw_module->m_ida, swidget->instance_id); in sof_ipc4_widget_setup()
2881 ida_free(&pipeline_ida, swidget->instance_id); in sof_ipc4_widget_setup()
2890 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_free()
2891 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_widget_free()
2894 mutex_lock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2897 if (swidget->id == snd_soc_dapm_scheduler) { in sof_ipc4_widget_free()
2898 struct sof_ipc4_pipeline *pipeline = swidget->private; in sof_ipc4_widget_free()
2902 if (pipeline->use_chain_dma) { in sof_ipc4_widget_free()
2903 dev_warn(sdev->dev, "use_chain_dma set for scheduler %s", in sof_ipc4_widget_free()
2904 swidget->widget->name); in sof_ipc4_widget_free()
2905 mutex_unlock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2909 header = SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id); in sof_ipc4_widget_free()
2916 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_widget_free()
2918 dev_err(sdev->dev, "failed to free pipeline widget %s\n", in sof_ipc4_widget_free()
2919 swidget->widget->name); in sof_ipc4_widget_free()
2921 pipeline->mem_usage = 0; in sof_ipc4_widget_free()
2922 pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED; in sof_ipc4_widget_free()
2923 ida_free(&pipeline_ida, swidget->instance_id); in sof_ipc4_widget_free()
2924 swidget->instance_id = -EINVAL; in sof_ipc4_widget_free()
2926 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_free()
2927 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_widget_free()
2929 if (!pipeline->use_chain_dma) in sof_ipc4_widget_free()
2930 ida_free(&fw_module->m_ida, swidget->instance_id); in sof_ipc4_widget_free()
2933 mutex_unlock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2951 pin_binding = src_widget->output_pin_binding; in sof_ipc4_get_queue_id()
2952 queue_ida = &src_widget->output_queue_ida; in sof_ipc4_get_queue_id()
2953 num_pins = src_widget->num_output_pins; in sof_ipc4_get_queue_id()
2954 buddy_name = sink_widget->widget->name; in sof_ipc4_get_queue_id()
2957 pin_binding = sink_widget->input_pin_binding; in sof_ipc4_get_queue_id()
2958 queue_ida = &sink_widget->input_queue_ida; in sof_ipc4_get_queue_id()
2959 num_pins = sink_widget->num_input_pins; in sof_ipc4_get_queue_id()
2960 buddy_name = src_widget->widget->name; in sof_ipc4_get_queue_id()
2963 scomp = current_swidget->scomp; in sof_ipc4_get_queue_id()
2966 dev_err(scomp->dev, "invalid %s num_pins: %d for queue allocation for %s\n", in sof_ipc4_get_queue_id()
2968 num_pins, current_swidget->widget->name); in sof_ipc4_get_queue_id()
2969 return -EINVAL; in sof_ipc4_get_queue_id()
2986 dev_err(scomp->dev, "no %s queue id found from pin binding array for %s\n", in sof_ipc4_get_queue_id()
2988 current_swidget->widget->name); in sof_ipc4_get_queue_id()
2989 return -EINVAL; in sof_ipc4_get_queue_id()
3004 pin_binding = swidget->output_pin_binding; in sof_ipc4_put_queue_id()
3005 queue_ida = &swidget->output_queue_ida; in sof_ipc4_put_queue_id()
3006 num_pins = swidget->num_output_pins; in sof_ipc4_put_queue_id()
3008 pin_binding = swidget->input_pin_binding; in sof_ipc4_put_queue_id()
3009 queue_ida = &swidget->input_queue_ida; in sof_ipc4_put_queue_id()
3010 num_pins = swidget->num_input_pins; in sof_ipc4_put_queue_id()
3026 const struct sof_ipc_ops *iops = sdev->ipc->ops; in sof_ipc4_set_copier_sink_format()
3032 if (WIDGET_IS_DAI(src_widget->id)) { in sof_ipc4_set_copier_sink_format()
3033 struct snd_sof_dai *dai = src_widget->private; in sof_ipc4_set_copier_sink_format()
3035 src_config = dai->private; in sof_ipc4_set_copier_sink_format()
3037 src_config = src_widget->private; in sof_ipc4_set_copier_sink_format()
3040 fw_module = src_widget->module_info; in sof_ipc4_set_copier_sink_format()
3042 format.sink_id = sroute->src_queue_id; in sof_ipc4_set_copier_sink_format()
3043 memcpy(&format.source_fmt, &src_config->audio_fmt, sizeof(format.source_fmt)); in sof_ipc4_set_copier_sink_format()
3045 pin_fmt = sof_ipc4_get_input_pin_audio_fmt(sink_widget, sroute->dst_queue_id); in sof_ipc4_set_copier_sink_format()
3047 dev_err(sdev->dev, in sof_ipc4_set_copier_sink_format()
3049 sink_widget->widget->name, sroute->dst_queue_id, in sof_ipc4_set_copier_sink_format()
3050 src_widget->widget->name, sroute->src_queue_id); in sof_ipc4_set_copier_sink_format()
3051 return -EINVAL; in sof_ipc4_set_copier_sink_format()
3059 msg.primary = fw_module->man4_module_entry.id; in sof_ipc4_set_copier_sink_format()
3060 msg.primary |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_set_copier_sink_format()
3067 return iops->set_get_data(sdev, &msg, msg.data_size, true); in sof_ipc4_set_copier_sink_format()
3072 struct snd_sof_widget *src_widget = sroute->src_widget; in sof_ipc4_route_setup()
3073 struct snd_sof_widget *sink_widget = sroute->sink_widget; in sof_ipc4_route_setup()
3074 struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget; in sof_ipc4_route_setup()
3075 struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget; in sof_ipc4_route_setup()
3076 struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info; in sof_ipc4_route_setup()
3077 struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; in sof_ipc4_route_setup()
3078 struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private; in sof_ipc4_route_setup()
3079 struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private; in sof_ipc4_route_setup()
3085 if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma) { in sof_ipc4_route_setup()
3086 if (!src_pipeline->use_chain_dma || !sink_pipeline->use_chain_dma) { in sof_ipc4_route_setup()
3087 dev_err(sdev->dev, in sof_ipc4_route_setup()
3089 src_widget->widget->name, sink_widget->widget->name); in sof_ipc4_route_setup()
3090 return -EINVAL; in sof_ipc4_route_setup()
3096 dev_err(sdev->dev, in sof_ipc4_route_setup()
3097 "cannot bind %s -> %s, no firmware module for: %s%s\n", in sof_ipc4_route_setup()
3098 src_widget->widget->name, sink_widget->widget->name, in sof_ipc4_route_setup()
3102 return -ENODEV; in sof_ipc4_route_setup()
3105 sroute->src_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, in sof_ipc4_route_setup()
3107 if (sroute->src_queue_id < 0) { in sof_ipc4_route_setup()
3108 dev_err(sdev->dev, in sof_ipc4_route_setup()
3110 src_widget->widget->name); in sof_ipc4_route_setup()
3111 return sroute->src_queue_id; in sof_ipc4_route_setup()
3114 sroute->dst_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, in sof_ipc4_route_setup()
3116 if (sroute->dst_queue_id < 0) { in sof_ipc4_route_setup()
3117 dev_err(sdev->dev, in sof_ipc4_route_setup()
3119 sink_widget->widget->name); in sof_ipc4_route_setup()
3120 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, in sof_ipc4_route_setup()
3122 return sroute->dst_queue_id; in sof_ipc4_route_setup()
3126 if (sroute->src_queue_id > 0 && WIDGET_IS_COPIER(src_widget->id)) { in sof_ipc4_route_setup()
3130 dev_err(sdev->dev, in sof_ipc4_route_setup()
3132 src_widget->widget->name, sroute->src_queue_id); in sof_ipc4_route_setup()
3137 dev_dbg(sdev->dev, "bind %s:%d -> %s:%d\n", in sof_ipc4_route_setup()
3138 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_setup()
3139 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_setup()
3141 header = src_fw_module->man4_module_entry.id; in sof_ipc4_route_setup()
3142 header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_route_setup()
3147 extension = sink_fw_module->man4_module_entry.id; in sof_ipc4_route_setup()
3148 extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id); in sof_ipc4_route_setup()
3149 extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id); in sof_ipc4_route_setup()
3150 extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id); in sof_ipc4_route_setup()
3155 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_route_setup()
3157 dev_err(sdev->dev, "failed to bind modules %s:%d -> %s:%d\n", in sof_ipc4_route_setup()
3158 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_setup()
3159 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_setup()
3166 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT); in sof_ipc4_route_setup()
3167 sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT); in sof_ipc4_route_setup()
3173 struct snd_sof_widget *src_widget = sroute->src_widget; in sof_ipc4_route_free()
3174 struct snd_sof_widget *sink_widget = sroute->sink_widget; in sof_ipc4_route_free()
3175 struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info; in sof_ipc4_route_free()
3176 struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; in sof_ipc4_route_free()
3178 struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget; in sof_ipc4_route_free()
3179 struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget; in sof_ipc4_route_free()
3180 struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private; in sof_ipc4_route_free()
3181 struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private; in sof_ipc4_route_free()
3186 if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma) in sof_ipc4_route_free()
3189 dev_dbg(sdev->dev, "unbind modules %s:%d -> %s:%d\n", in sof_ipc4_route_free()
3190 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_free()
3191 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_free()
3197 if (src_widget->spipe->pipe_widget == sink_widget->spipe->pipe_widget) in sof_ipc4_route_free()
3200 header = src_fw_module->man4_module_entry.id; in sof_ipc4_route_free()
3201 header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_route_free()
3206 extension = sink_fw_module->man4_module_entry.id; in sof_ipc4_route_free()
3207 extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id); in sof_ipc4_route_free()
3208 extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id); in sof_ipc4_route_free()
3209 extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id); in sof_ipc4_route_free()
3214 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_route_free()
3216 dev_err(sdev->dev, "failed to unbind modules %s:%d -> %s:%d\n", in sof_ipc4_route_free()
3217 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_free()
3218 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_free()
3220 sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT); in sof_ipc4_route_free()
3221 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT); in sof_ipc4_route_free()
3229 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_dai_config()
3230 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_dai_config()
3231 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_dai_config()
3236 if (!dai || !dai->private) { in sof_ipc4_dai_config()
3237 dev_err(sdev->dev, "Invalid DAI or DAI private data for %s\n", in sof_ipc4_dai_config()
3238 swidget->widget->name); in sof_ipc4_dai_config()
3239 return -EINVAL; in sof_ipc4_dai_config()
3242 ipc4_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_dai_config()
3243 copier_data = &ipc4_copier->data; in sof_ipc4_dai_config()
3248 if (pipeline->use_chain_dma) { in sof_ipc4_dai_config()
3254 pipeline->msg.primary &= ~SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK; in sof_ipc4_dai_config()
3255 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID(data->dai_data); in sof_ipc4_dai_config()
3260 switch (ipc4_copier->dai_type) { in sof_ipc4_dai_config()
3262 gtw_attr = ipc4_copier->gtw_attr; in sof_ipc4_dai_config()
3263 gtw_attr->lp_buffer_alloc = pipeline->lp_mode; in sof_ipc4_dai_config()
3265 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_dai_config()
3266 copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_data); in sof_ipc4_dai_config()
3273 * unprepare. The node_id for multi-gateway DAI's will be overwritten with the in sof_ipc4_dai_config()
3279 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; in sof_ipc4_dai_config()
3280 ipc4_copier->dai_index = data->dai_node_id; in sof_ipc4_dai_config()
3286 if (blob->alh_cfg.device_count == 1) { in sof_ipc4_dai_config()
3287 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_dai_config()
3288 copier_data->gtw_cfg.node_id |= in sof_ipc4_dai_config()
3289 SOF_IPC4_NODE_INDEX(data->dai_node_id); in sof_ipc4_dai_config()
3299 dev_err(sdev->dev, "%s: unsupported dai type %d\n", __func__, in sof_ipc4_dai_config()
3300 ipc4_copier->dai_type); in sof_ipc4_dai_config()
3301 return -EINVAL; in sof_ipc4_dai_config()
3311 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_parse_manifest()
3314 u32 size = le32_to_cpu(man->priv.size); in sof_ipc4_parse_manifest()
3315 u8 *man_ptr = man->priv.data; in sof_ipc4_parse_manifest()
3320 dev_err(scomp->dev, "%s: Invalid topology ABI size: %u\n", in sof_ipc4_parse_manifest()
3322 return -EINVAL; in sof_ipc4_parse_manifest()
3327 dev_info(scomp->dev, in sof_ipc4_parse_manifest()
3329 le16_to_cpu(manifest->abi_major), le16_to_cpu(manifest->abi_minor), in sof_ipc4_parse_manifest()
3330 le16_to_cpu(manifest->abi_patch), in sof_ipc4_parse_manifest()
3339 manifest_tlv = manifest->items; in sof_ipc4_parse_manifest()
3341 for (i = 0; i < le16_to_cpu(manifest->count); i++) { in sof_ipc4_parse_manifest()
3342 len_check += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size); in sof_ipc4_parse_manifest()
3344 return -EINVAL; in sof_ipc4_parse_manifest()
3346 switch (le32_to_cpu(manifest_tlv->type)) { in sof_ipc4_parse_manifest()
3349 if (ipc4_data->nhlt) in sof_ipc4_parse_manifest()
3351 ipc4_data->nhlt = devm_kmemdup(sdev->dev, manifest_tlv->data, in sof_ipc4_parse_manifest()
3352 le32_to_cpu(manifest_tlv->size), GFP_KERNEL); in sof_ipc4_parse_manifest()
3353 if (!ipc4_data->nhlt) in sof_ipc4_parse_manifest()
3354 return -ENOMEM; in sof_ipc4_parse_manifest()
3357 dev_warn(scomp->dev, "Skipping unknown manifest data type %d\n", in sof_ipc4_parse_manifest()
3358 manifest_tlv->type); in sof_ipc4_parse_manifest()
3361 man_ptr += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size); in sof_ipc4_parse_manifest()
3370 struct sof_ipc4_copier *ipc4_copier = dai->private; in sof_ipc4_dai_get_param()
3380 list_for_each_entry(slink, &sdev->dai_link_list, list) { in sof_ipc4_dai_get_param()
3381 if (!strcmp(slink->link->name, dai->name)) { in sof_ipc4_dai_get_param()
3388 dev_err(sdev->dev, "no DAI link found for DAI %s\n", dai->name); in sof_ipc4_dai_get_param()
3389 return -EINVAL; in sof_ipc4_dai_get_param()
3392 for (i = 0; i < slink->num_hw_configs; i++) { in sof_ipc4_dai_get_param()
3393 hw_config = &slink->hw_configs[i]; in sof_ipc4_dai_get_param()
3394 if (dai->current_config == le32_to_cpu(hw_config->id)) { in sof_ipc4_dai_get_param()
3401 dev_err(sdev->dev, "no matching hw_config found for DAI %s\n", dai->name); in sof_ipc4_dai_get_param()
3402 return -EINVAL; in sof_ipc4_dai_get_param()
3405 switch (ipc4_copier->dai_type) { in sof_ipc4_dai_get_param()
3409 return le32_to_cpu(hw_config->mclk_rate); in sof_ipc4_dai_get_param()
3411 return le32_to_cpu(hw_config->bclk_rate); in sof_ipc4_dai_get_param()
3413 return le32_to_cpu(hw_config->tdm_slots); in sof_ipc4_dai_get_param()
3415 dev_err(sdev->dev, "invalid SSP param %d\n", param_type); in sof_ipc4_dai_get_param()
3420 dev_err(sdev->dev, "DAI type %d not supported yet!\n", ipc4_copier->dai_type); in sof_ipc4_dai_get_param()
3424 return -EINVAL; in sof_ipc4_dai_get_param()
3446 if (link->no_pcm) in sof_ipc4_link_setup()
3456 link->trigger[SNDRV_PCM_STREAM_PLAYBACK] = SND_SOC_DPCM_TRIGGER_POST; in sof_ipc4_link_setup()
3457 link->trigger[SNDRV_PCM_STREAM_CAPTURE] = SND_SOC_DPCM_TRIGGER_PRE; in sof_ipc4_link_setup()