Lines Matching +full:gain +full:- +full:scaling +full:- +full:p

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"
24 * message and it is used for clock scaling.
26 * deactivating the clock scaling.
31 "Ignore CPC values. This option will disable clock scaling in firmware.");
166 [SOF_GAIN_TOKENS] = {"Gain tokens", gain_tokens, ARRAY_SIZE(gain_tokens)},
175 list_for_each_entry(swidget, &sdev->widget_list, list) { in sof_ipc4_find_swidget_by_ids()
176 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_find_swidget_by_ids()
179 if (!swidget->use_count) in sof_ipc4_find_swidget_by_ids()
182 if (fw_module && fw_module->man4_module_entry.id == module_id && in sof_ipc4_find_swidget_by_ids()
183 swidget->instance_id == instance_id) in sof_ipc4_find_swidget_by_ids()
199 pin_fmt[i].pin_index, fmt->sampling_frequency, fmt->bit_depth, 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()
213 if (swidget->id != snd_soc_dapm_effect) { in sof_ipc4_get_input_pin_audio_fmt()
214 struct sof_ipc4_base_module_cfg *base = swidget->private; in sof_ipc4_get_input_pin_audio_fmt()
216 /* For non-process modules, base module config format is used for all input pins */ in sof_ipc4_get_input_pin_audio_fmt()
217 return &base->audio_fmt; in sof_ipc4_get_input_pin_audio_fmt()
220 process = swidget->private; in sof_ipc4_get_input_pin_audio_fmt()
226 if (process->init_config != SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) in sof_ipc4_get_input_pin_audio_fmt()
227 return &process->base_config.audio_fmt; in sof_ipc4_get_input_pin_audio_fmt()
229 base_cfg_ext = process->base_config_ext; in sof_ipc4_get_input_pin_audio_fmt()
235 for (i = 0; i < base_cfg_ext->num_input_pin_fmts; i++) { in sof_ipc4_get_input_pin_audio_fmt()
236 struct sof_ipc4_pin_format *pin_format = &base_cfg_ext->pin_formats[i]; in sof_ipc4_get_input_pin_audio_fmt()
238 if (pin_format->pin_index == pin_index) in sof_ipc4_get_input_pin_audio_fmt()
239 return &pin_format->audio_fmt; in sof_ipc4_get_input_pin_audio_fmt()
246 * sof_ipc4_get_audio_fmt - get available audio formats from swidget->tuples
264 SOF_AUDIO_FMT_NUM_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
265 swidget->num_tuples, sizeof(*available_fmt), 1); in sof_ipc4_get_audio_fmt()
267 dev_err(scomp->dev, "Failed to parse audio format token count\n"); in sof_ipc4_get_audio_fmt()
271 if (!available_fmt->num_input_formats && !available_fmt->num_output_formats) { in sof_ipc4_get_audio_fmt()
272 dev_err(scomp->dev, "No input/output pin formats set in topology\n"); in sof_ipc4_get_audio_fmt()
273 return -EINVAL; in sof_ipc4_get_audio_fmt()
276 dev_dbg(scomp->dev, in sof_ipc4_get_audio_fmt()
278 available_fmt->num_input_formats, available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
281 ret = sof_update_ipc_object(scomp, module_base_cfg, SOF_COMP_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
282 swidget->num_tuples, sizeof(*module_base_cfg), 1); in sof_ipc4_get_audio_fmt()
284 dev_err(scomp->dev, "parse comp tokens for %s failed, error: %d\n", in sof_ipc4_get_audio_fmt()
285 swidget->widget->name, ret); in sof_ipc4_get_audio_fmt()
289 dev_dbg(scomp->dev, "widget %s: is_pages: %d\n", swidget->widget->name, in sof_ipc4_get_audio_fmt()
290 module_base_cfg->is_pages); in sof_ipc4_get_audio_fmt()
292 if (available_fmt->num_input_formats) { in sof_ipc4_get_audio_fmt()
293 in_format = kcalloc(available_fmt->num_input_formats, in sof_ipc4_get_audio_fmt()
296 return -ENOMEM; in sof_ipc4_get_audio_fmt()
297 available_fmt->input_pin_fmts = in_format; in sof_ipc4_get_audio_fmt()
300 SOF_IN_AUDIO_FORMAT_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
301 swidget->num_tuples, sizeof(*in_format), in sof_ipc4_get_audio_fmt()
302 available_fmt->num_input_formats); in sof_ipc4_get_audio_fmt()
304 dev_err(scomp->dev, "parse input audio fmt tokens failed %d\n", ret); in sof_ipc4_get_audio_fmt()
308 dev_dbg(scomp->dev, "Input audio formats for %s\n", swidget->widget->name); in sof_ipc4_get_audio_fmt()
309 sof_ipc4_dbg_audio_format(scomp->dev, in_format, in sof_ipc4_get_audio_fmt()
310 available_fmt->num_input_formats); in sof_ipc4_get_audio_fmt()
313 if (available_fmt->num_output_formats) { in sof_ipc4_get_audio_fmt()
314 out_format = kcalloc(available_fmt->num_output_formats, sizeof(*out_format), in sof_ipc4_get_audio_fmt()
317 ret = -ENOMEM; in sof_ipc4_get_audio_fmt()
322 SOF_OUT_AUDIO_FORMAT_TOKENS, swidget->tuples, in sof_ipc4_get_audio_fmt()
323 swidget->num_tuples, sizeof(*out_format), in sof_ipc4_get_audio_fmt()
324 available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
326 dev_err(scomp->dev, "parse output audio fmt tokens failed\n"); in sof_ipc4_get_audio_fmt()
330 available_fmt->output_pin_fmts = out_format; in sof_ipc4_get_audio_fmt()
331 dev_dbg(scomp->dev, "Output audio formats for %s\n", swidget->widget->name); in sof_ipc4_get_audio_fmt()
332 sof_ipc4_dbg_audio_format(scomp->dev, out_format, in sof_ipc4_get_audio_fmt()
333 available_fmt->num_output_formats); in sof_ipc4_get_audio_fmt()
342 available_fmt->input_pin_fmts = NULL; in sof_ipc4_get_audio_fmt()
350 kfree(available_fmt->output_pin_fmts); in sof_ipc4_free_audio_fmt()
351 available_fmt->output_pin_fmts = NULL; in sof_ipc4_free_audio_fmt()
352 kfree(available_fmt->input_pin_fmts); in sof_ipc4_free_audio_fmt()
353 available_fmt->input_pin_fmts = NULL; in sof_ipc4_free_audio_fmt()
358 kfree(swidget->private); in sof_ipc4_widget_free_comp_pipeline()
363 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_set_module_info()
366 swidget->module_info = sof_ipc4_find_module_by_uuid(sdev, &swidget->uuid); in sof_ipc4_widget_set_module_info()
368 if (swidget->module_info) in sof_ipc4_widget_set_module_info()
371 dev_err(sdev->dev, "failed to find module info for widget %s with UUID %pUL\n", in sof_ipc4_widget_set_module_info()
372 swidget->widget->name, &swidget->uuid); in sof_ipc4_widget_set_module_info()
373 return -EINVAL; in sof_ipc4_widget_set_module_info()
386 fw_module = swidget->module_info; in sof_ipc4_widget_setup_msg()
388 msg->primary = fw_module->man4_module_entry.id; in sof_ipc4_widget_setup_msg()
389 msg->primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_INIT_INSTANCE); in sof_ipc4_widget_setup_msg()
390 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_widget_setup_msg()
391 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_widget_setup_msg()
393 msg->extension = SOF_IPC4_MOD_EXT_CORE_ID(swidget->core); in sof_ipc4_widget_setup_msg()
395 type = (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_DP) ? 1 : 0; in sof_ipc4_widget_setup_msg()
396 msg->extension |= SOF_IPC4_MOD_EXT_DOMAIN(type); in sof_ipc4_widget_setup_msg()
403 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_update_kcontrol_module_id()
405 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_update_kcontrol_module_id()
409 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { in sof_ipc4_widget_update_kcontrol_module_id()
410 if (scontrol->comp_id == swidget->comp_id) { in sof_ipc4_widget_update_kcontrol_module_id()
411 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; in sof_ipc4_widget_update_kcontrol_module_id()
412 struct sof_ipc4_msg *msg = &cdata->msg; in sof_ipc4_widget_update_kcontrol_module_id()
414 msg->primary |= fw_module->man4_module_entry.id; in sof_ipc4_widget_update_kcontrol_module_id()
423 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_update_card_components_string()
424 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_update_card_components_string()
425 struct snd_soc_component *scomp = spcm->scomp; in sof_ipc4_update_card_components_string()
426 struct snd_soc_card *card = scomp->card; in sof_ipc4_update_card_components_string()
427 const char *pt_marker = "iec61937-pcm"; in sof_ipc4_update_card_components_string()
430 * Update the card's components list with iec61937-pcm and a list of PCM in sof_ipc4_update_card_components_string()
434 if (!pipeline->use_chain_dma) in sof_ipc4_update_card_components_string()
437 if (card->components) { in sof_ipc4_update_card_components_string()
438 const char *tmp = card->components; in sof_ipc4_update_card_components_string()
440 if (strstr(card->components, pt_marker)) in sof_ipc4_update_card_components_string()
441 card->components = devm_kasprintf(card->dev, GFP_KERNEL, in sof_ipc4_update_card_components_string()
443 card->components, in sof_ipc4_update_card_components_string()
444 spcm->pcm.pcm_id); in sof_ipc4_update_card_components_string()
446 card->components = devm_kasprintf(card->dev, GFP_KERNEL, in sof_ipc4_update_card_components_string()
448 card->components, in sof_ipc4_update_card_components_string()
450 spcm->pcm.pcm_id); in sof_ipc4_update_card_components_string()
452 devm_kfree(card->dev, tmp); in sof_ipc4_update_card_components_string()
454 card->components = devm_kasprintf(card->dev, GFP_KERNEL, in sof_ipc4_update_card_components_string()
456 spcm->pcm.pcm_id); in sof_ipc4_update_card_components_string()
459 if (!card->components) in sof_ipc4_update_card_components_string()
460 return -ENOMEM; in sof_ipc4_update_card_components_string()
468 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_pcm()
476 return -ENOMEM; in sof_ipc4_widget_setup_pcm()
478 swidget->private = ipc4_copier; in sof_ipc4_widget_setup_pcm()
479 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_setup_pcm()
481 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_pcm()
484 &ipc4_copier->data.base_config); in sof_ipc4_widget_setup_pcm()
489 * This callback is used by host copier and module-to-module copier, in sof_ipc4_widget_setup_pcm()
492 if (!WIDGET_IS_AIF(swidget->id)) in sof_ipc4_widget_setup_pcm()
496 SOF_COPIER_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_pcm()
497 swidget->num_tuples, sizeof(node_type), 1); in sof_ipc4_widget_setup_pcm()
500 dev_err(scomp->dev, "parse host copier node type token failed %d\n", in sof_ipc4_widget_setup_pcm()
504 dev_dbg(scomp->dev, "host copier '%s' node_type %u\n", swidget->widget->name, node_type); in sof_ipc4_widget_setup_pcm()
506 spcm = snd_sof_find_spcm_comp(scomp, swidget->comp_id, &dir); in sof_ipc4_widget_setup_pcm()
515 struct snd_sof_pcm_stream *sps = &spcm->stream[dir]; in sof_ipc4_widget_setup_pcm()
517 sof_update_ipc_object(scomp, &sps->dsp_max_burst_size_in_ms, in sof_ipc4_widget_setup_pcm()
519 swidget->tuples, in sof_ipc4_widget_setup_pcm()
520 swidget->num_tuples, sizeof(u32), 1); in sof_ipc4_widget_setup_pcm()
522 if (!sps->dsp_max_burst_size_in_ms) in sof_ipc4_widget_setup_pcm()
523 sps->dsp_max_burst_size_in_ms = SOF_IPC4_MIN_DMA_BUFFER_SIZE; in sof_ipc4_widget_setup_pcm()
526 spcm->stream[dir].dsp_max_burst_size_in_ms = 1; in sof_ipc4_widget_setup_pcm()
530 ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); in sof_ipc4_widget_setup_pcm()
531 if (!ipc4_copier->gtw_attr) { in sof_ipc4_widget_setup_pcm()
532 ret = -ENOMEM; in sof_ipc4_widget_setup_pcm()
536 ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; in sof_ipc4_widget_setup_pcm()
537 ipc4_copier->data.gtw_cfg.config_length = in sof_ipc4_widget_setup_pcm()
540 switch (swidget->id) { in sof_ipc4_widget_setup_pcm()
543 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); in sof_ipc4_widget_setup_pcm()
546 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID; in sof_ipc4_widget_setup_pcm()
547 ipc4_copier->ipc_config_size = 0; in sof_ipc4_widget_setup_pcm()
550 dev_err(scomp->dev, "invalid widget type %d\n", swidget->id); in sof_ipc4_widget_setup_pcm()
551 ret = -EINVAL; in sof_ipc4_widget_setup_pcm()
556 ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg); in sof_ipc4_widget_setup_pcm()
563 kfree(ipc4_copier->gtw_attr); in sof_ipc4_widget_setup_pcm()
568 swidget->private = NULL; in sof_ipc4_widget_setup_pcm()
574 struct sof_ipc4_copier *ipc4_copier = swidget->private; in sof_ipc4_widget_free_comp_pcm()
580 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_free_comp_pcm()
581 kfree(available_fmt->output_pin_fmts); in sof_ipc4_widget_free_comp_pcm()
582 kfree(ipc4_copier->gtw_attr); in sof_ipc4_widget_free_comp_pcm()
584 swidget->private = NULL; in sof_ipc4_widget_free_comp_pcm()
590 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_dai()
592 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_setup_comp_dai()
601 return -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
603 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_setup_comp_dai()
605 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_dai()
608 &ipc4_copier->data.base_config); in sof_ipc4_widget_setup_comp_dai()
613 SOF_COPIER_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_dai()
614 swidget->num_tuples, sizeof(node_type), 1); in sof_ipc4_widget_setup_comp_dai()
616 dev_err(scomp->dev, "parse dai node type failed %d\n", ret); in sof_ipc4_widget_setup_comp_dai()
621 SOF_DAI_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_dai()
622 swidget->num_tuples, sizeof(u32), 1); in sof_ipc4_widget_setup_comp_dai()
624 dev_err(scomp->dev, "parse dai copier node token failed %d\n", ret); in sof_ipc4_widget_setup_comp_dai()
628 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()
629 node_type, ipc4_copier->dai_type, ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
631 dai->type = ipc4_copier->dai_type; in sof_ipc4_widget_setup_comp_dai()
632 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); in sof_ipc4_widget_setup_comp_dai()
634 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_setup_comp_dai()
635 pipeline = pipe_widget->private; in sof_ipc4_widget_setup_comp_dai()
637 if (pipeline->use_chain_dma && in sof_ipc4_widget_setup_comp_dai()
638 !snd_sof_is_chain_dma_supported(sdev, ipc4_copier->dai_type)) { in sof_ipc4_widget_setup_comp_dai()
639 dev_err(scomp->dev, "Bad DAI type '%d', Chain DMA is not supported\n", in sof_ipc4_widget_setup_comp_dai()
640 ipc4_copier->dai_type); in sof_ipc4_widget_setup_comp_dai()
641 ret = -ENODEV; in sof_ipc4_widget_setup_comp_dai()
645 switch (ipc4_copier->dai_type) { in sof_ipc4_widget_setup_comp_dai()
649 struct snd_soc_dapm_path *p; in sof_ipc4_widget_setup_comp_dai() local
653 snd_soc_dapm_widget_for_each_source_path(swidget->widget, p) in sof_ipc4_widget_setup_comp_dai()
656 if (swidget->id == snd_soc_dapm_dai_in && src_num == 0) { in sof_ipc4_widget_setup_comp_dai()
660 * It is fine to call kfree(ipc4_copier->copier_config) since in sof_ipc4_widget_setup_comp_dai()
661 * ipc4_copier->copier_config is null. in sof_ipc4_widget_setup_comp_dai()
669 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
673 list_for_each_entry(w, &sdev->widget_list, list) { in sof_ipc4_widget_setup_comp_dai()
674 if (w->widget->sname && in sof_ipc4_widget_setup_comp_dai()
675 strcmp(w->widget->sname, swidget->widget->sname)) in sof_ipc4_widget_setup_comp_dai()
678 blob->alh_cfg.device_count++; in sof_ipc4_widget_setup_comp_dai()
681 ipc4_copier->copier_config = (uint32_t *)blob; in sof_ipc4_widget_setup_comp_dai()
683 ipc4_copier->data.gtw_cfg.config_length = (sizeof(blob->gw_attr) + in sof_ipc4_widget_setup_comp_dai()
684 sizeof(blob->alh_cfg.device_count) + in sof_ipc4_widget_setup_comp_dai()
685 sizeof(*blob->alh_cfg.mapping) * in sof_ipc4_widget_setup_comp_dai()
686 blob->alh_cfg.device_count) >> 2; in sof_ipc4_widget_setup_comp_dai()
691 ipc4_copier->data.gtw_cfg.node_id |= in sof_ipc4_widget_setup_comp_dai()
692 SOF_IPC4_NODE_INDEX_INTEL_SSP(ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
696 ipc4_copier->data.gtw_cfg.node_id |= in sof_ipc4_widget_setup_comp_dai()
697 SOF_IPC4_NODE_INDEX_INTEL_DMIC(ipc4_copier->dai_index); in sof_ipc4_widget_setup_comp_dai()
700 ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); in sof_ipc4_widget_setup_comp_dai()
701 if (!ipc4_copier->gtw_attr) { in sof_ipc4_widget_setup_comp_dai()
702 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_dai()
706 ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; in sof_ipc4_widget_setup_comp_dai()
707 ipc4_copier->data.gtw_cfg.config_length = in sof_ipc4_widget_setup_comp_dai()
712 dai->scomp = scomp; in sof_ipc4_widget_setup_comp_dai()
713 dai->private = ipc4_copier; in sof_ipc4_widget_setup_comp_dai()
716 ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg); in sof_ipc4_widget_setup_comp_dai()
723 kfree(ipc4_copier->copier_config); in sof_ipc4_widget_setup_comp_dai()
728 dai->private = NULL; in sof_ipc4_widget_setup_comp_dai()
729 dai->scomp = NULL; in sof_ipc4_widget_setup_comp_dai()
736 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_free_comp_dai()
742 if (!dai->private) { in sof_ipc4_widget_free_comp_dai()
744 swidget->private = NULL; in sof_ipc4_widget_free_comp_dai()
748 ipc4_copier = dai->private; in sof_ipc4_widget_free_comp_dai()
749 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_widget_free_comp_dai()
751 kfree(available_fmt->output_pin_fmts); in sof_ipc4_widget_free_comp_dai()
752 if (ipc4_copier->dai_type != SOF_DAI_INTEL_SSP && in sof_ipc4_widget_free_comp_dai()
753 ipc4_copier->dai_type != SOF_DAI_INTEL_DMIC) in sof_ipc4_widget_free_comp_dai()
754 kfree(ipc4_copier->copier_config); in sof_ipc4_widget_free_comp_dai()
755 kfree(dai->private); in sof_ipc4_widget_free_comp_dai()
757 swidget->private = NULL; in sof_ipc4_widget_free_comp_dai()
762 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_pipeline()
764 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_pipeline()
769 return -ENOMEM; in sof_ipc4_widget_setup_comp_pipeline()
771 ret = sof_update_ipc_object(scomp, pipeline, SOF_SCHED_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_pipeline()
772 swidget->num_tuples, sizeof(*pipeline), 1); in sof_ipc4_widget_setup_comp_pipeline()
774 dev_err(scomp->dev, "parsing scheduler tokens failed\n"); in sof_ipc4_widget_setup_comp_pipeline()
778 swidget->core = pipeline->core_id; in sof_ipc4_widget_setup_comp_pipeline()
779 spipe->core_mask |= BIT(pipeline->core_id); in sof_ipc4_widget_setup_comp_pipeline()
781 if (pipeline->use_chain_dma) { in sof_ipc4_widget_setup_comp_pipeline()
782 dev_dbg(scomp->dev, "Set up chain DMA for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_pipeline()
783 swidget->private = pipeline; in sof_ipc4_widget_setup_comp_pipeline()
788 ret = sof_update_ipc_object(scomp, swidget, SOF_PIPELINE_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_pipeline()
789 swidget->num_tuples, sizeof(*swidget), 1); in sof_ipc4_widget_setup_comp_pipeline()
791 dev_err(scomp->dev, "parsing pipeline tokens failed\n"); in sof_ipc4_widget_setup_comp_pipeline()
795 dev_dbg(scomp->dev, "pipeline '%s': id %d, pri %d, core_id %u, lp mode %d\n", in sof_ipc4_widget_setup_comp_pipeline()
796 swidget->widget->name, swidget->pipeline_id, in sof_ipc4_widget_setup_comp_pipeline()
797 pipeline->priority, pipeline->core_id, pipeline->lp_mode); in sof_ipc4_widget_setup_comp_pipeline()
799 swidget->private = pipeline; in sof_ipc4_widget_setup_comp_pipeline()
801 pipeline->msg.primary = SOF_IPC4_GLB_PIPE_PRIORITY(pipeline->priority); in sof_ipc4_widget_setup_comp_pipeline()
802 pipeline->msg.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_CREATE_PIPELINE); in sof_ipc4_widget_setup_comp_pipeline()
803 pipeline->msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_widget_setup_comp_pipeline()
804 pipeline->msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG); in sof_ipc4_widget_setup_comp_pipeline()
806 pipeline->msg.extension = pipeline->lp_mode; in sof_ipc4_widget_setup_comp_pipeline()
807 pipeline->msg.extension |= SOF_IPC4_GLB_PIPE_EXT_CORE_ID(pipeline->core_id); in sof_ipc4_widget_setup_comp_pipeline()
808 pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED; in sof_ipc4_widget_setup_comp_pipeline()
818 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_pga()
819 struct sof_ipc4_gain *gain; in sof_ipc4_widget_setup_comp_pga() local
822 gain = kzalloc(sizeof(*gain), GFP_KERNEL); in sof_ipc4_widget_setup_comp_pga()
823 if (!gain) in sof_ipc4_widget_setup_comp_pga()
824 return -ENOMEM; in sof_ipc4_widget_setup_comp_pga()
826 swidget->private = gain; in sof_ipc4_widget_setup_comp_pga()
828 gain->data.params.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK; in sof_ipc4_widget_setup_comp_pga()
829 gain->data.params.init_val = SOF_IPC4_VOL_ZERO_DB; in sof_ipc4_widget_setup_comp_pga()
831 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, &gain->data.base_config); in sof_ipc4_widget_setup_comp_pga()
835 ret = sof_update_ipc_object(scomp, &gain->data.params, SOF_GAIN_TOKENS, in sof_ipc4_widget_setup_comp_pga()
836 swidget->tuples, swidget->num_tuples, sizeof(gain->data), 1); in sof_ipc4_widget_setup_comp_pga()
838 dev_err(scomp->dev, "Parsing gain tokens failed\n"); in sof_ipc4_widget_setup_comp_pga()
842 dev_dbg(scomp->dev, in sof_ipc4_widget_setup_comp_pga()
843 "pga widget %s: ramp type: %d, ramp duration %d, initial gain value: %#x\n", in sof_ipc4_widget_setup_comp_pga()
844 swidget->widget->name, gain->data.params.curve_type, in sof_ipc4_widget_setup_comp_pga()
845 gain->data.params.curve_duration_l, gain->data.params.init_val); in sof_ipc4_widget_setup_comp_pga()
847 ret = sof_ipc4_widget_setup_msg(swidget, &gain->msg); in sof_ipc4_widget_setup_comp_pga()
855 sof_ipc4_free_audio_fmt(&gain->available_fmt); in sof_ipc4_widget_setup_comp_pga()
856 kfree(gain); in sof_ipc4_widget_setup_comp_pga()
857 swidget->private = NULL; in sof_ipc4_widget_setup_comp_pga()
863 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_widget_free_comp_pga() local
865 if (!gain) in sof_ipc4_widget_free_comp_pga()
868 sof_ipc4_free_audio_fmt(&gain->available_fmt); in sof_ipc4_widget_free_comp_pga()
869 kfree(swidget->private); in sof_ipc4_widget_free_comp_pga()
870 swidget->private = NULL; in sof_ipc4_widget_free_comp_pga()
875 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_mixer()
879 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_mixer()
883 return -ENOMEM; in sof_ipc4_widget_setup_comp_mixer()
885 swidget->private = mixer; in sof_ipc4_widget_setup_comp_mixer()
887 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &mixer->available_fmt, in sof_ipc4_widget_setup_comp_mixer()
888 &mixer->base_config); in sof_ipc4_widget_setup_comp_mixer()
892 ret = sof_ipc4_widget_setup_msg(swidget, &mixer->msg); in sof_ipc4_widget_setup_comp_mixer()
898 sof_ipc4_free_audio_fmt(&mixer->available_fmt); in sof_ipc4_widget_setup_comp_mixer()
900 swidget->private = NULL; in sof_ipc4_widget_setup_comp_mixer()
906 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_src()
907 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_src()
911 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); in sof_ipc4_widget_setup_comp_src()
915 return -ENOMEM; in sof_ipc4_widget_setup_comp_src()
917 swidget->private = src; in sof_ipc4_widget_setup_comp_src()
919 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt, in sof_ipc4_widget_setup_comp_src()
920 &src->data.base_config); in sof_ipc4_widget_setup_comp_src()
924 ret = sof_update_ipc_object(scomp, &src->data, SOF_SRC_TOKENS, swidget->tuples, in sof_ipc4_widget_setup_comp_src()
925 swidget->num_tuples, sizeof(*src), 1); in sof_ipc4_widget_setup_comp_src()
927 dev_err(scomp->dev, "Parsing SRC tokens failed\n"); in sof_ipc4_widget_setup_comp_src()
931 spipe->core_mask |= BIT(swidget->core); in sof_ipc4_widget_setup_comp_src()
933 dev_dbg(scomp->dev, "SRC sink rate %d\n", src->data.sink_rate); in sof_ipc4_widget_setup_comp_src()
935 ret = sof_ipc4_widget_setup_msg(swidget, &src->msg); in sof_ipc4_widget_setup_comp_src()
941 sof_ipc4_free_audio_fmt(&src->available_fmt); in sof_ipc4_widget_setup_comp_src()
943 swidget->private = NULL; in sof_ipc4_widget_setup_comp_src()
949 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_widget_free_comp_src()
954 sof_ipc4_free_audio_fmt(&src->available_fmt); in sof_ipc4_widget_free_comp_src()
955 kfree(swidget->private); in sof_ipc4_widget_free_comp_src()
956 swidget->private = NULL; in sof_ipc4_widget_free_comp_src()
961 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_widget_free_comp_mixer()
966 sof_ipc4_free_audio_fmt(&mixer->available_fmt); in sof_ipc4_widget_free_comp_mixer()
967 kfree(swidget->private); in sof_ipc4_widget_free_comp_mixer()
968 swidget->private = NULL; in sof_ipc4_widget_free_comp_mixer()
976 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_widget_setup_comp_process()
978 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_ipc4_widget_setup_comp_process()
985 return -ENOMEM; in sof_ipc4_widget_setup_comp_process()
987 swidget->private = process; in sof_ipc4_widget_setup_comp_process()
989 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &process->available_fmt, in sof_ipc4_widget_setup_comp_process()
990 &process->base_config); in sof_ipc4_widget_setup_comp_process()
994 ret = sof_ipc4_widget_setup_msg(swidget, &process->msg); in sof_ipc4_widget_setup_comp_process()
999 fw_module = swidget->module_info; in sof_ipc4_widget_setup_comp_process()
1000 process->init_config = FIELD_GET(SOF_IPC4_MODULE_INIT_CONFIG_MASK, in sof_ipc4_widget_setup_comp_process()
1001 fw_module->man4_module_entry.type); in sof_ipc4_widget_setup_comp_process()
1003 process->ipc_config_size = sizeof(struct sof_ipc4_base_module_cfg); in sof_ipc4_widget_setup_comp_process()
1006 if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) { in sof_ipc4_widget_setup_comp_process()
1009 size_add(swidget->num_input_pins, in sof_ipc4_widget_setup_comp_process()
1010 swidget->num_output_pins)); in sof_ipc4_widget_setup_comp_process()
1014 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_process()
1018 base_cfg_ext->num_input_pin_fmts = swidget->num_input_pins; in sof_ipc4_widget_setup_comp_process()
1019 base_cfg_ext->num_output_pin_fmts = swidget->num_output_pins; in sof_ipc4_widget_setup_comp_process()
1020 process->base_config_ext = base_cfg_ext; in sof_ipc4_widget_setup_comp_process()
1021 process->base_config_ext_size = ext_size; in sof_ipc4_widget_setup_comp_process()
1022 process->ipc_config_size += ext_size; in sof_ipc4_widget_setup_comp_process()
1025 cfg = kzalloc(process->ipc_config_size, GFP_KERNEL); in sof_ipc4_widget_setup_comp_process()
1027 ret = -ENOMEM; in sof_ipc4_widget_setup_comp_process()
1031 process->ipc_config_data = cfg; in sof_ipc4_widget_setup_comp_process()
1036 spipe->core_mask |= BIT(swidget->core); in sof_ipc4_widget_setup_comp_process()
1040 kfree(process->base_config_ext); in sof_ipc4_widget_setup_comp_process()
1041 process->base_config_ext = NULL; in sof_ipc4_widget_setup_comp_process()
1043 sof_ipc4_free_audio_fmt(&process->available_fmt); in sof_ipc4_widget_setup_comp_process()
1046 swidget->private = NULL; in sof_ipc4_widget_setup_comp_process()
1052 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_widget_free_comp_process()
1057 kfree(process->ipc_config_data); in sof_ipc4_widget_free_comp_process()
1058 kfree(process->base_config_ext); in sof_ipc4_widget_free_comp_process()
1059 sof_ipc4_free_audio_fmt(&process->available_fmt); in sof_ipc4_widget_free_comp_process()
1060 kfree(swidget->private); in sof_ipc4_widget_free_comp_process()
1061 swidget->private = NULL; in sof_ipc4_widget_free_comp_process()
1068 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_update_resource_usage()
1074 ibs = base_config->ibs; in sof_ipc4_update_resource_usage()
1075 bss = base_config->is_pages; in sof_ipc4_update_resource_usage()
1080 if (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_LL) { in sof_ipc4_update_resource_usage()
1094 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_update_resource_usage()
1095 pipeline = pipe_widget->private; in sof_ipc4_update_resource_usage()
1096 pipeline->mem_usage += total; in sof_ipc4_update_resource_usage()
1098 /* Update base_config->cpc from the module manifest */ in sof_ipc4_update_resource_usage()
1102 dev_dbg(sdev->dev, "%s: ibs / obs: %u / %u, forcing cpc to 0 from %u\n", in sof_ipc4_update_resource_usage()
1103 swidget->widget->name, base_config->ibs, base_config->obs, in sof_ipc4_update_resource_usage()
1104 base_config->cpc); in sof_ipc4_update_resource_usage()
1105 base_config->cpc = 0; in sof_ipc4_update_resource_usage()
1107 dev_dbg(sdev->dev, "%s: ibs / obs / cpc: %u / %u / %u\n", in sof_ipc4_update_resource_usage()
1108 swidget->widget->name, base_config->ibs, base_config->obs, in sof_ipc4_update_resource_usage()
1109 base_config->cpc); in sof_ipc4_update_resource_usage()
1116 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_assign_instance_id()
1117 int max_instances = fw_module->man4_module_entry.instance_max_count; in sof_ipc4_widget_assign_instance_id()
1119 swidget->instance_id = ida_alloc_max(&fw_module->m_ida, max_instances, GFP_KERNEL); in sof_ipc4_widget_assign_instance_id()
1120 if (swidget->instance_id < 0) { in sof_ipc4_widget_assign_instance_id()
1121 dev_err(sdev->dev, "failed to assign instance id for widget %s", in sof_ipc4_widget_assign_instance_id()
1122 swidget->widget->name); in sof_ipc4_widget_assign_instance_id()
1123 return swidget->instance_id; in sof_ipc4_widget_assign_instance_id()
1136 int valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_update_hw_params()
1151 dev_err(sdev->dev, "invalid PCM valid_bits %d\n", valid_bits); in sof_ipc4_update_hw_params()
1152 return -EINVAL; in sof_ipc4_update_hw_params()
1161 unsigned int rate = fmt->sampling_frequency; in sof_ipc4_update_hw_params()
1164 i->min = rate; in sof_ipc4_update_hw_params()
1165 i->max = rate; in sof_ipc4_update_hw_params()
1169 unsigned int channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_update_hw_params()
1172 i->min = channels; in sof_ipc4_update_hw_params()
1173 i->max = channels; in sof_ipc4_update_hw_params()
1187 rate = fmt->sampling_frequency; in sof_ipc4_is_single_format()
1188 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1189 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1196 _rate = fmt->sampling_frequency; in sof_ipc4_is_single_format()
1197 _channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1198 _valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_is_single_format()
1217 if (!available_fmt->num_output_formats) in sof_ipc4_init_output_audio_fmt()
1218 return -EINVAL; in sof_ipc4_init_output_audio_fmt()
1220 single_format = sof_ipc4_is_single_format(sdev, available_fmt->output_pin_fmts, in sof_ipc4_init_output_audio_fmt()
1221 available_fmt->num_output_formats); in sof_ipc4_init_output_audio_fmt()
1225 base_config->obs = available_fmt->output_pin_fmts[0].buffer_size; in sof_ipc4_init_output_audio_fmt()
1233 for (i = 0; i < available_fmt->num_output_formats; i++) { in sof_ipc4_init_output_audio_fmt()
1236 out_fmt = &available_fmt->output_pin_fmts[i].audio_fmt; in sof_ipc4_init_output_audio_fmt()
1237 _out_rate = out_fmt->sampling_frequency; in sof_ipc4_init_output_audio_fmt()
1238 _out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(out_fmt->fmt_cfg); in sof_ipc4_init_output_audio_fmt()
1239 _out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); in sof_ipc4_init_output_audio_fmt()
1243 base_config->obs = available_fmt->output_pin_fmts[i].buffer_size; in sof_ipc4_init_output_audio_fmt()
1248 return -EINVAL; in sof_ipc4_init_output_audio_fmt()
1261 dev_err(sdev->dev, "invalid pcm frame format %d\n", params_format(params)); in sof_ipc4_get_valid_bits()
1262 return -EINVAL; in sof_ipc4_get_valid_bits()
1272 struct sof_ipc4_pin_format *pin_fmts = available_fmt->input_pin_fmts; in sof_ipc4_init_input_audio_fmt()
1273 u32 pin_fmts_size = available_fmt->num_input_formats; in sof_ipc4_init_input_audio_fmt()
1281 if (!available_fmt->num_input_formats) { in sof_ipc4_init_input_audio_fmt()
1282 dev_err(sdev->dev, "no input formats for %s\n", swidget->widget->name); in sof_ipc4_init_input_audio_fmt()
1283 return -EINVAL; in sof_ipc4_init_input_audio_fmt()
1286 single_format = sof_ipc4_is_single_format(sdev, available_fmt->input_pin_fmts, in sof_ipc4_init_input_audio_fmt()
1287 available_fmt->num_input_formats); in sof_ipc4_init_input_audio_fmt()
1305 rate = fmt->sampling_frequency; in sof_ipc4_init_input_audio_fmt()
1306 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_init_input_audio_fmt()
1307 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_init_input_audio_fmt()
1310 dev_dbg(sdev->dev, "matched audio format index for %uHz, %ubit, %u channels: %d\n", in sof_ipc4_init_input_audio_fmt()
1317 dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n", in sof_ipc4_init_input_audio_fmt()
1319 return -EINVAL; in sof_ipc4_init_input_audio_fmt()
1324 if (available_fmt->num_input_formats && i < available_fmt->num_input_formats) { in sof_ipc4_init_input_audio_fmt()
1325 memcpy(&base_config->audio_fmt, &available_fmt->input_pin_fmts[i].audio_fmt, in sof_ipc4_init_input_audio_fmt()
1329 base_config->ibs = available_fmt->input_pin_fmts[i].buffer_size; in sof_ipc4_init_input_audio_fmt()
1331 dev_dbg(sdev->dev, "Init input audio formats for %s\n", swidget->widget->name); in sof_ipc4_init_input_audio_fmt()
1332 sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->input_pin_fmts[i], 1); in sof_ipc4_init_input_audio_fmt()
1345 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_unprepare_copier_module()
1346 pipeline = pipe_widget->private; in sof_ipc4_unprepare_copier_module()
1347 pipeline->mem_usage = 0; in sof_ipc4_unprepare_copier_module()
1349 if (WIDGET_IS_AIF(swidget->id) || swidget->id == snd_soc_dapm_buffer) { in sof_ipc4_unprepare_copier_module()
1350 if (pipeline->use_chain_dma) { in sof_ipc4_unprepare_copier_module()
1351 pipeline->msg.primary = 0; in sof_ipc4_unprepare_copier_module()
1352 pipeline->msg.extension = 0; in sof_ipc4_unprepare_copier_module()
1354 ipc4_copier = swidget->private; in sof_ipc4_unprepare_copier_module()
1355 } else if (WIDGET_IS_DAI(swidget->id)) { in sof_ipc4_unprepare_copier_module()
1356 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_unprepare_copier_module()
1358 ipc4_copier = dai->private; in sof_ipc4_unprepare_copier_module()
1360 if (pipeline->use_chain_dma) { in sof_ipc4_unprepare_copier_module()
1365 * re-configuration in sof_ipc4_unprepare_copier_module()
1367 pipeline->msg.primary &= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK; in sof_ipc4_unprepare_copier_module()
1368 pipeline->msg.extension = 0; in sof_ipc4_unprepare_copier_module()
1371 if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { in sof_ipc4_unprepare_copier_module()
1375 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; in sof_ipc4_unprepare_copier_module()
1376 if (blob->alh_cfg.device_count > 1) { in sof_ipc4_unprepare_copier_module()
1377 group_id = SOF_IPC4_NODE_INDEX(ipc4_copier->data.gtw_cfg.node_id) - in sof_ipc4_unprepare_copier_module()
1385 kfree(ipc4_copier->ipc_config_data); in sof_ipc4_unprepare_copier_module()
1386 ipc4_copier->ipc_config_data = NULL; in sof_ipc4_unprepare_copier_module()
1387 ipc4_copier->ipc_config_size = 0; in sof_ipc4_unprepare_copier_module()
1402 list_for_each_entry(slink, &sdev->dai_link_list, list) { in snd_sof_get_hw_config_params()
1403 if (!strcmp(slink->link->name, dai->name)) { in snd_sof_get_hw_config_params()
1410 dev_err(sdev->dev, "%s: no DAI link found for DAI %s\n", __func__, dai->name); in snd_sof_get_hw_config_params()
1411 return -EINVAL; in snd_sof_get_hw_config_params()
1414 for (i = 0; i < slink->num_hw_configs; i++) { in snd_sof_get_hw_config_params()
1415 hw_config = &slink->hw_configs[i]; in snd_sof_get_hw_config_params()
1416 if (dai->current_config == le32_to_cpu(hw_config->id)) { in snd_sof_get_hw_config_params()
1423 dev_err(sdev->dev, "%s: no matching hw_config found for DAI %s\n", __func__, in snd_sof_get_hw_config_params()
1424 dai->name); in snd_sof_get_hw_config_params()
1425 return -EINVAL; in snd_sof_get_hw_config_params()
1428 *bit_depth = le32_to_cpu(hw_config->tdm_slot_width); in snd_sof_get_hw_config_params()
1429 *channel_count = le32_to_cpu(hw_config->tdm_slots); in snd_sof_get_hw_config_params()
1430 *sample_rate = le32_to_cpu(hw_config->fsync_rate); in snd_sof_get_hw_config_params()
1432 dev_dbg(sdev->dev, "sample rate: %d sample width: %d channels: %d\n", in snd_sof_get_hw_config_params()
1444 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in snd_sof_get_nhlt_endpoint_data()
1460 * Look for 32-bit blob first instead of 16-bit if copier in snd_sof_get_nhlt_endpoint_data()
1464 dev_dbg(sdev->dev, "Looking for 32-bit blob first for DMIC\n"); in snd_sof_get_nhlt_endpoint_data()
1483 dev_type = intel_nhlt_ssp_device_type(sdev->dev, ipc4_data->nhlt, in snd_sof_get_nhlt_endpoint_data()
1492 dev_dbg(sdev->dev, "dai index %d nhlt type %d direction %d dev type %d\n", in snd_sof_get_nhlt_endpoint_data()
1496 cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, dai_index, nhlt_type, in snd_sof_get_nhlt_endpoint_data()
1505 * The 32-bit blob was not found in NHLT table, try to in snd_sof_get_nhlt_endpoint_data()
1513 * The requested 32-bit blob (no format change for the in snd_sof_get_nhlt_endpoint_data()
1515 * look for 16-bit blob if the copier supports multiple in snd_sof_get_nhlt_endpoint_data()
1524 cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, in snd_sof_get_nhlt_endpoint_data()
1533 dev_err(sdev->dev, in snd_sof_get_nhlt_endpoint_data()
1536 return -EINVAL; in snd_sof_get_nhlt_endpoint_data()
1541 *len = cfg->size >> 2; in snd_sof_get_nhlt_endpoint_data()
1542 *dst = (u32 *)cfg->caps; in snd_sof_get_nhlt_endpoint_data()
1547 * instead of the requested bit depth (16 -> 32 or 32 -> 16). in snd_sof_get_nhlt_endpoint_data()
1584 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_copier_is_single_bitdepth()
1591 _valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_copier_is_single_bitdepth()
1614 rate = fmt->sampling_frequency; in sof_ipc4_adjust_params_to_dai_format()
1615 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_adjust_params_to_dai_format()
1616 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_adjust_params_to_dai_format()
1625 val = fmt->sampling_frequency; in sof_ipc4_adjust_params_to_dai_format()
1630 val = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); in sof_ipc4_adjust_params_to_dai_format()
1635 val = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); in sof_ipc4_adjust_params_to_dai_format()
1662 ipc4_copier = dai->private; in sof_ipc4_prepare_dai_copier()
1663 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_dai_copier()
1664 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_dai_copier()
1672 pin_fmts = available_fmt->output_pin_fmts; in sof_ipc4_prepare_dai_copier()
1673 num_pin_fmts = available_fmt->num_output_formats; in sof_ipc4_prepare_dai_copier()
1675 pin_fmts = available_fmt->input_pin_fmts; in sof_ipc4_prepare_dai_copier()
1676 num_pin_fmts = available_fmt->num_input_formats; in sof_ipc4_prepare_dai_copier()
1688 ipc4_copier->dai_index, in sof_ipc4_prepare_dai_copier()
1689 ipc4_copier->dai_type, dir, in sof_ipc4_prepare_dai_copier()
1690 &ipc4_copier->copier_config, in sof_ipc4_prepare_dai_copier()
1691 &copier_data->gtw_cfg.config_length); in sof_ipc4_prepare_dai_copier()
1706 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_copier_module()
1724 dev_dbg(sdev->dev, "copier %s, type %d", swidget->widget->name, swidget->id); in sof_ipc4_prepare_copier_module()
1726 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1736 SOF_COPIER_DEEP_BUFFER_TOKENS, swidget->tuples, in sof_ipc4_prepare_copier_module()
1737 swidget->num_tuples, sizeof(u32), 1); in sof_ipc4_prepare_copier_module()
1739 dev_err(scomp->dev, "Failed to parse deep buffer dma size for %s\n", in sof_ipc4_prepare_copier_module()
1740 swidget->widget->name); in sof_ipc4_prepare_copier_module()
1744 ipc4_copier = (struct sof_ipc4_copier *)swidget->private; in sof_ipc4_prepare_copier_module()
1745 gtw_attr = ipc4_copier->gtw_attr; in sof_ipc4_prepare_copier_module()
1746 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1747 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1749 pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_prepare_copier_module()
1750 pipeline = pipe_widget->private; in sof_ipc4_prepare_copier_module()
1752 if (pipeline->use_chain_dma) { in sof_ipc4_prepare_copier_module()
1756 host_dma_id = platform_params->stream_tag - 1; in sof_ipc4_prepare_copier_module()
1757 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_HOST_ID(host_dma_id); in sof_ipc4_prepare_copier_module()
1761 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK; in sof_ipc4_prepare_copier_module()
1771 pipeline->msg.extension |= SOF_IPC4_GLB_EXT_CHAIN_DMA_FIFO_SIZE(fifo_size); in sof_ipc4_prepare_copier_module()
1777 copier_data->gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID; in sof_ipc4_prepare_copier_module()
1791 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_prepare_copier_module()
1792 copier_data->gtw_cfg.node_id |= in sof_ipc4_prepare_copier_module()
1793 SOF_IPC4_NODE_INDEX(platform_params->stream_tag - 1); in sof_ipc4_prepare_copier_module()
1796 gtw_attr->lp_buffer_alloc = pipeline->lp_mode; in sof_ipc4_prepare_copier_module()
1802 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_prepare_copier_module()
1803 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_prepare_copier_module()
1805 if (pipeline->use_chain_dma) in sof_ipc4_prepare_copier_module()
1808 dai = swidget->private; in sof_ipc4_prepare_copier_module()
1810 ipc4_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_prepare_copier_module()
1811 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1812 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1838 ipc4_copier = (struct sof_ipc4_copier *)swidget->private; in sof_ipc4_prepare_copier_module()
1839 copier_data = &ipc4_copier->data; in sof_ipc4_prepare_copier_module()
1840 available_fmt = &ipc4_copier->available_fmt; in sof_ipc4_prepare_copier_module()
1846 dev_err(sdev->dev, "unsupported type %d for copier %s", in sof_ipc4_prepare_copier_module()
1847 swidget->id, swidget->widget->name); in sof_ipc4_prepare_copier_module()
1848 return -EINVAL; in sof_ipc4_prepare_copier_module()
1852 ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &copier_data->base_config, in sof_ipc4_prepare_copier_module()
1859 available_fmt->output_pin_fmts, in sof_ipc4_prepare_copier_module()
1860 available_fmt->num_output_formats); in sof_ipc4_prepare_copier_module()
1861 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1868 in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; in sof_ipc4_prepare_copier_module()
1869 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_copier_module()
1870 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
1874 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
1892 return -EINVAL; in sof_ipc4_prepare_copier_module()
1902 out_fmt = &available_fmt->output_pin_fmts[0].audio_fmt; in sof_ipc4_prepare_copier_module()
1904 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); in sof_ipc4_prepare_copier_module()
1907 dev_dbg(sdev->dev, "copier %s: reference output rate %d, channels %d valid_bits %d\n", in sof_ipc4_prepare_copier_module()
1908 swidget->widget->name, out_ref_rate, out_ref_channels, out_ref_valid_bits); in sof_ipc4_prepare_copier_module()
1910 output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &copier_data->base_config, in sof_ipc4_prepare_copier_module()
1914 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_copier_module()
1915 swidget->widget->name); in sof_ipc4_prepare_copier_module()
1926 memcpy(&copier_data->out_format, in sof_ipc4_prepare_copier_module()
1927 &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt, in sof_ipc4_prepare_copier_module()
1929 dev_dbg(sdev->dev, "Output audio format for %s\n", swidget->widget->name); in sof_ipc4_prepare_copier_module()
1930 sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->output_pin_fmts[output_fmt_index], 1); in sof_ipc4_prepare_copier_module()
1932 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
1940 if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { in sof_ipc4_prepare_copier_module()
1952 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; in sof_ipc4_prepare_copier_module()
1954 blob->gw_attr.lp_buffer_alloc = 0; in sof_ipc4_prepare_copier_module()
1957 ch_map = copier_data->base_config.audio_fmt.ch_map; in sof_ipc4_prepare_copier_module()
1966 step = ch_count / blob->alh_cfg.device_count; in sof_ipc4_prepare_copier_module()
1967 mask = GENMASK(step - 1, 0); in sof_ipc4_prepare_copier_module()
1969 * Set each gtw_cfg.node_id to blob->alh_cfg.mapping[] in sof_ipc4_prepare_copier_module()
1973 list_for_each_entry(w, &sdev->widget_list, list) { in sof_ipc4_prepare_copier_module()
1976 if (w->widget->sname && in sof_ipc4_prepare_copier_module()
1977 strcmp(w->widget->sname, swidget->widget->sname)) in sof_ipc4_prepare_copier_module()
1980 dai = w->private; in sof_ipc4_prepare_copier_module()
1981 alh_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_prepare_copier_module()
1982 alh_data = &alh_copier->data; in sof_ipc4_prepare_copier_module()
1983 node_type = SOF_IPC4_GET_NODE_TYPE(alh_data->gtw_cfg.node_id); in sof_ipc4_prepare_copier_module()
1984 blob->alh_cfg.mapping[i].device = SOF_IPC4_NODE_TYPE(node_type); in sof_ipc4_prepare_copier_module()
1985 blob->alh_cfg.mapping[i].device |= in sof_ipc4_prepare_copier_module()
1986 SOF_IPC4_NODE_INDEX(alh_copier->dai_index); in sof_ipc4_prepare_copier_module()
1993 if (ipc4_copier->dma_config_tlv[i].length) { in sof_ipc4_prepare_copier_module()
1994 dma_config = &ipc4_copier->dma_config_tlv[i].dma_config; in sof_ipc4_prepare_copier_module()
1995 blob->alh_cfg.mapping[i].device = in sof_ipc4_prepare_copier_module()
1996 dma_config->dma_stream_channel_map.mapping[0].device; in sof_ipc4_prepare_copier_module()
2010 if (w->id == snd_soc_dapm_dai_in) in sof_ipc4_prepare_copier_module()
2011 blob->alh_cfg.mapping[i].channel_mask = ch_mask; in sof_ipc4_prepare_copier_module()
2013 blob->alh_cfg.mapping[i].channel_mask = mask << (step * i); in sof_ipc4_prepare_copier_module()
2017 if (blob->alh_cfg.device_count > 1) { in sof_ipc4_prepare_copier_module()
2020 group_id = ida_alloc_max(&alh_group_ida, ALH_MULTI_GTW_COUNT - 1, in sof_ipc4_prepare_copier_module()
2026 /* add multi-gateway base */ in sof_ipc4_prepare_copier_module()
2028 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_prepare_copier_module()
2029 copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(group_id); in sof_ipc4_prepare_copier_module()
2037 &copier_data->out_format, in sof_ipc4_prepare_copier_module()
2049 switch (swidget->id) { in sof_ipc4_prepare_copier_module()
2051 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
2052 SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.ibs; in sof_ipc4_prepare_copier_module()
2055 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
2057 copier_data->base_config.ibs; in sof_ipc4_prepare_copier_module()
2058 dev_dbg(sdev->dev, "copier %s, dma buffer%s: %u ms (%u bytes)", in sof_ipc4_prepare_copier_module()
2059 swidget->widget->name, in sof_ipc4_prepare_copier_module()
2062 copier_data->gtw_cfg.dma_buffer_size); in sof_ipc4_prepare_copier_module()
2066 copier_data->gtw_cfg.dma_buffer_size = in sof_ipc4_prepare_copier_module()
2067 SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.obs; in sof_ipc4_prepare_copier_module()
2073 data = &ipc4_copier->copier_config; in sof_ipc4_prepare_copier_module()
2074 ipc_config_size = &ipc4_copier->ipc_config_size; in sof_ipc4_prepare_copier_module()
2075 ipc_config_data = &ipc4_copier->ipc_config_data; in sof_ipc4_prepare_copier_module()
2078 gtw_cfg_config_length = copier_data->gtw_cfg.config_length * 4; in sof_ipc4_prepare_copier_module()
2083 if (ipc4_copier->dma_config_tlv[i].type != SOF_IPC4_GTW_DMA_CONFIG_ID) in sof_ipc4_prepare_copier_module()
2085 dma_config_tlv_size += ipc4_copier->dma_config_tlv[i].length; in sof_ipc4_prepare_copier_module()
2087 ipc4_copier->dma_config_tlv[i].dma_config.dma_priv_config_size; in sof_ipc4_prepare_copier_module()
2088 dma_config_tlv_size += (sizeof(ipc4_copier->dma_config_tlv[i]) - in sof_ipc4_prepare_copier_module()
2089 sizeof(ipc4_copier->dma_config_tlv[i].dma_config)); in sof_ipc4_prepare_copier_module()
2096 copier_data->gtw_cfg.config_length += dma_config_tlv_size / 4; in sof_ipc4_prepare_copier_module()
2099 dev_dbg(sdev->dev, "copier %s, IPC size is %d", swidget->widget->name, ipc_size); in sof_ipc4_prepare_copier_module()
2103 return -ENOMEM; in sof_ipc4_prepare_copier_module()
2108 sof_ipc4_update_resource_usage(sdev, swidget, &copier_data->base_config); in sof_ipc4_prepare_copier_module()
2120 &ipc4_copier->dma_config_tlv, dma_config_tlv_size); in sof_ipc4_prepare_copier_module()
2126 copier_data->gtw_cfg.config_length = gtw_cfg_config_length / 4; in sof_ipc4_prepare_copier_module()
2136 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_gain_module()
2138 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_prepare_gain_module() local
2139 struct sof_ipc4_available_audio_format *available_fmt = &gain->available_fmt; in sof_ipc4_prepare_gain_module()
2144 ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &gain->data.base_config, in sof_ipc4_prepare_gain_module()
2149 in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; in sof_ipc4_prepare_gain_module()
2150 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_gain_module()
2151 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_gain_module()
2152 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_gain_module()
2154 ret = sof_ipc4_init_output_audio_fmt(sdev, &gain->data.base_config, available_fmt, in sof_ipc4_prepare_gain_module()
2157 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_gain_module()
2158 swidget->widget->name); in sof_ipc4_prepare_gain_module()
2163 sof_ipc4_update_resource_usage(sdev, swidget, &gain->data.base_config); in sof_ipc4_prepare_gain_module()
2173 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_mixer_module()
2175 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_prepare_mixer_module()
2176 struct sof_ipc4_available_audio_format *available_fmt = &mixer->available_fmt; in sof_ipc4_prepare_mixer_module()
2181 ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &mixer->base_config, in sof_ipc4_prepare_mixer_module()
2186 in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; in sof_ipc4_prepare_mixer_module()
2187 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_mixer_module()
2188 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_mixer_module()
2189 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_mixer_module()
2191 ret = sof_ipc4_init_output_audio_fmt(sdev, &mixer->base_config, available_fmt, in sof_ipc4_prepare_mixer_module()
2194 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_mixer_module()
2195 swidget->widget->name); in sof_ipc4_prepare_mixer_module()
2200 sof_ipc4_update_resource_usage(sdev, swidget, &mixer->base_config); in sof_ipc4_prepare_mixer_module()
2210 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_src_module()
2212 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_prepare_src_module()
2213 struct sof_ipc4_available_audio_format *available_fmt = &src->available_fmt; in sof_ipc4_prepare_src_module()
2219 input_format_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, &src->data.base_config, in sof_ipc4_prepare_src_module()
2228 if (dir == SNDRV_PCM_STREAM_PLAYBACK && available_fmt->num_output_formats > 1) { in sof_ipc4_prepare_src_module()
2229 dev_err(sdev->dev, "Invalid number of output formats: %d for SRC %s\n", in sof_ipc4_prepare_src_module()
2230 available_fmt->num_output_formats, swidget->widget->name); in sof_ipc4_prepare_src_module()
2231 return -EINVAL; in sof_ipc4_prepare_src_module()
2238 in_audio_fmt = &available_fmt->input_pin_fmts[input_format_index].audio_fmt; in sof_ipc4_prepare_src_module()
2239 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_audio_fmt->fmt_cfg); in sof_ipc4_prepare_src_module()
2240 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_audio_fmt->fmt_cfg); in sof_ipc4_prepare_src_module()
2249 output_format_index = sof_ipc4_init_output_audio_fmt(sdev, &src->data.base_config, in sof_ipc4_prepare_src_module()
2253 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_src_module()
2254 swidget->widget->name); in sof_ipc4_prepare_src_module()
2259 sof_ipc4_update_resource_usage(sdev, swidget, &src->data.base_config); in sof_ipc4_prepare_src_module()
2261 out_audio_fmt = &available_fmt->output_pin_fmts[output_format_index].audio_fmt; in sof_ipc4_prepare_src_module()
2262 src->data.sink_rate = out_audio_fmt->sampling_frequency; in sof_ipc4_prepare_src_module()
2274 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_process_set_pin_formats()
2275 struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext; in sof_ipc4_process_set_pin_formats()
2276 struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt; in sof_ipc4_process_set_pin_formats()
2278 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_process_set_pin_formats()
2285 num_pins = swidget->num_input_pins; in sof_ipc4_process_set_pin_formats()
2286 format_list_to_search = available_fmt->input_pin_fmts; in sof_ipc4_process_set_pin_formats()
2287 format_list_count = available_fmt->num_input_formats; in sof_ipc4_process_set_pin_formats()
2289 num_pins = swidget->num_output_pins; in sof_ipc4_process_set_pin_formats()
2290 pin_format_offset = swidget->num_input_pins; in sof_ipc4_process_set_pin_formats()
2291 format_list_to_search = available_fmt->output_pin_fmts; in sof_ipc4_process_set_pin_formats()
2292 format_list_count = available_fmt->num_output_formats; in sof_ipc4_process_set_pin_formats()
2296 pin_format = &base_cfg_ext->pin_formats[i]; in sof_ipc4_process_set_pin_formats()
2301 pin_format->buffer_size = process->base_config.ibs; in sof_ipc4_process_set_pin_formats()
2302 pin_format->audio_fmt = process->base_config.audio_fmt; in sof_ipc4_process_set_pin_formats()
2304 pin_format->buffer_size = process->base_config.obs; in sof_ipc4_process_set_pin_formats()
2305 pin_format->audio_fmt = process->output_format; in sof_ipc4_process_set_pin_formats()
2318 if (pin_format_item->pin_index == i - pin_format_offset) { in sof_ipc4_process_set_pin_formats()
2325 dev_err(scomp->dev, "%s pin %d format not found for %s\n", in sof_ipc4_process_set_pin_formats()
2327 i - pin_format_offset, swidget->widget->name); in sof_ipc4_process_set_pin_formats()
2328 return -EINVAL; in sof_ipc4_process_set_pin_formats()
2354 struct snd_soc_component *scomp = swidget->scomp; in sof_ipc4_prepare_process_module()
2356 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_prepare_process_module()
2357 struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt; in sof_ipc4_prepare_process_module()
2360 void *cfg = process->ipc_config_data; in sof_ipc4_prepare_process_module()
2364 ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &process->base_config, in sof_ipc4_prepare_process_module()
2369 in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; in sof_ipc4_prepare_process_module()
2370 out_ref_rate = in_fmt->sampling_frequency; in sof_ipc4_prepare_process_module()
2371 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); in sof_ipc4_prepare_process_module()
2372 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); in sof_ipc4_prepare_process_module()
2374 output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &process->base_config, in sof_ipc4_prepare_process_module()
2377 if (output_fmt_index < 0 && available_fmt->num_output_formats) { in sof_ipc4_prepare_process_module()
2378 dev_err(sdev->dev, "Failed to initialize output format for %s", in sof_ipc4_prepare_process_module()
2379 swidget->widget->name); in sof_ipc4_prepare_process_module()
2384 if (available_fmt->num_output_formats && in sof_ipc4_prepare_process_module()
2385 output_fmt_index < available_fmt->num_output_formats && in sof_ipc4_prepare_process_module()
2386 !available_fmt->output_pin_fmts[output_fmt_index].pin_index) { in sof_ipc4_prepare_process_module()
2387 memcpy(&process->output_format, in sof_ipc4_prepare_process_module()
2388 &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt, in sof_ipc4_prepare_process_module()
2393 &process->output_format, in sof_ipc4_prepare_process_module()
2402 sof_ipc4_update_resource_usage(sdev, swidget, &process->base_config); in sof_ipc4_prepare_process_module()
2405 memcpy(cfg, &process->base_config, sizeof(struct sof_ipc4_base_module_cfg)); in sof_ipc4_prepare_process_module()
2408 if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) { in sof_ipc4_prepare_process_module()
2409 struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext; in sof_ipc4_prepare_process_module()
2415 memcpy(cfg, base_cfg_ext, process->base_config_ext_size); in sof_ipc4_prepare_process_module()
2427 scontrol->size = struct_size(control_data, chanv, scontrol->num_channels); in sof_ipc4_control_load_volume()
2429 /* scontrol->ipc_control_data will be freed in sof_control_unload */ in sof_ipc4_control_load_volume()
2430 scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL); in sof_ipc4_control_load_volume()
2431 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_volume()
2432 return -ENOMEM; in sof_ipc4_control_load_volume()
2434 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_volume()
2435 control_data->index = scontrol->index; in sof_ipc4_control_load_volume()
2437 msg = &control_data->msg; in sof_ipc4_control_load_volume()
2438 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_volume()
2439 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_volume()
2440 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_volume()
2442 /* volume controls with range 0-1 (off/on) are switch controls */ in sof_ipc4_control_load_volume()
2443 if (scontrol->max == 1) in sof_ipc4_control_load_volume()
2444 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_SWITCH_CONTROL_PARAM_ID); in sof_ipc4_control_load_volume()
2446 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_GAIN_PARAM_ID); in sof_ipc4_control_load_volume()
2448 for (i = 0; i < scontrol->num_channels; i++) { in sof_ipc4_control_load_volume()
2449 control_data->chanv[i].channel = i; in sof_ipc4_control_load_volume()
2452 * - 0dB for volume controls in sof_ipc4_control_load_volume()
2453 * - off (0) for switch controls - value already zero after in sof_ipc4_control_load_volume()
2456 if (scontrol->max > 1) in sof_ipc4_control_load_volume()
2457 control_data->chanv[i].value = SOF_IPC4_VOL_ZERO_DB; in sof_ipc4_control_load_volume()
2469 scontrol->size = struct_size(control_data, chanv, scontrol->num_channels); in sof_ipc4_control_load_enum()
2471 /* scontrol->ipc_control_data will be freed in sof_control_unload */ in sof_ipc4_control_load_enum()
2472 scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL); in sof_ipc4_control_load_enum()
2473 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_enum()
2474 return -ENOMEM; in sof_ipc4_control_load_enum()
2476 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_enum()
2477 control_data->index = scontrol->index; in sof_ipc4_control_load_enum()
2479 msg = &control_data->msg; in sof_ipc4_control_load_enum()
2480 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_enum()
2481 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_enum()
2482 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_enum()
2484 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_ENUM_CONTROL_PARAM_ID); in sof_ipc4_control_load_enum()
2487 for (i = 0; i < scontrol->num_channels; i++) in sof_ipc4_control_load_enum()
2488 control_data->chanv[i].channel = i; in sof_ipc4_control_load_enum()
2499 if (scontrol->max_size < (sizeof(*control_data) + sizeof(struct sof_abi_hdr))) { in sof_ipc4_control_load_bytes()
2500 dev_err(sdev->dev, "insufficient size for a bytes control %s: %zu.\n", in sof_ipc4_control_load_bytes()
2501 scontrol->name, scontrol->max_size); in sof_ipc4_control_load_bytes()
2502 return -EINVAL; in sof_ipc4_control_load_bytes()
2505 if (scontrol->priv_size > scontrol->max_size - sizeof(*control_data)) { in sof_ipc4_control_load_bytes()
2506 dev_err(sdev->dev, "scontrol %s bytes data size %zu exceeds max %zu.\n", in sof_ipc4_control_load_bytes()
2507 scontrol->name, scontrol->priv_size, in sof_ipc4_control_load_bytes()
2508 scontrol->max_size - sizeof(*control_data)); in sof_ipc4_control_load_bytes()
2509 return -EINVAL; in sof_ipc4_control_load_bytes()
2512 scontrol->size = sizeof(struct sof_ipc4_control_data) + scontrol->priv_size; in sof_ipc4_control_load_bytes()
2514 scontrol->ipc_control_data = kzalloc(scontrol->max_size, GFP_KERNEL); in sof_ipc4_control_load_bytes()
2515 if (!scontrol->ipc_control_data) in sof_ipc4_control_load_bytes()
2516 return -ENOMEM; in sof_ipc4_control_load_bytes()
2518 control_data = scontrol->ipc_control_data; in sof_ipc4_control_load_bytes()
2519 control_data->index = scontrol->index; in sof_ipc4_control_load_bytes()
2520 if (scontrol->priv_size > 0) { in sof_ipc4_control_load_bytes()
2521 memcpy(control_data->data, scontrol->priv, scontrol->priv_size); in sof_ipc4_control_load_bytes()
2522 kfree(scontrol->priv); in sof_ipc4_control_load_bytes()
2523 scontrol->priv = NULL; in sof_ipc4_control_load_bytes()
2525 if (control_data->data->magic != SOF_IPC4_ABI_MAGIC) { in sof_ipc4_control_load_bytes()
2526 dev_err(sdev->dev, "Wrong ABI magic (%#x) for control: %s\n", in sof_ipc4_control_load_bytes()
2527 control_data->data->magic, scontrol->name); in sof_ipc4_control_load_bytes()
2528 ret = -EINVAL; in sof_ipc4_control_load_bytes()
2534 if (control_data->data->size + sizeof(struct sof_abi_hdr) != in sof_ipc4_control_load_bytes()
2535 scontrol->priv_size) { in sof_ipc4_control_load_bytes()
2536 dev_err(sdev->dev, "Control %s conflict in bytes %zu vs. priv size %zu.\n", in sof_ipc4_control_load_bytes()
2537 scontrol->name, in sof_ipc4_control_load_bytes()
2538 control_data->data->size + sizeof(struct sof_abi_hdr), in sof_ipc4_control_load_bytes()
2539 scontrol->priv_size); in sof_ipc4_control_load_bytes()
2540 ret = -EINVAL; in sof_ipc4_control_load_bytes()
2545 msg = &control_data->msg; in sof_ipc4_control_load_bytes()
2546 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); in sof_ipc4_control_load_bytes()
2547 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); in sof_ipc4_control_load_bytes()
2548 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); in sof_ipc4_control_load_bytes()
2553 kfree(scontrol->ipc_control_data); in sof_ipc4_control_load_bytes()
2554 scontrol->ipc_control_data = NULL; in sof_ipc4_control_load_bytes()
2560 switch (scontrol->info_type) { in sof_ipc4_control_setup()
2579 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_setup()
2580 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_widget_setup()
2587 switch (swidget->id) { in sof_ipc4_widget_setup()
2589 pipeline = swidget->private; in sof_ipc4_widget_setup()
2591 if (pipeline->use_chain_dma) { in sof_ipc4_widget_setup()
2592 dev_warn(sdev->dev, "use_chain_dma set for scheduler %s", in sof_ipc4_widget_setup()
2593 swidget->widget->name); in sof_ipc4_widget_setup()
2597 dev_dbg(sdev->dev, "pipeline: %d memory pages: %d\n", swidget->pipeline_id, in sof_ipc4_widget_setup()
2598 pipeline->mem_usage); in sof_ipc4_widget_setup()
2600 msg = &pipeline->msg; in sof_ipc4_widget_setup()
2601 msg->primary |= pipeline->mem_usage; in sof_ipc4_widget_setup()
2603 swidget->instance_id = ida_alloc_max(&pipeline_ida, ipc4_data->max_num_pipelines, in sof_ipc4_widget_setup()
2605 if (swidget->instance_id < 0) { in sof_ipc4_widget_setup()
2606 dev_err(sdev->dev, "failed to assign pipeline id for %s: %d\n", in sof_ipc4_widget_setup()
2607 swidget->widget->name, swidget->instance_id); in sof_ipc4_widget_setup()
2608 return swidget->instance_id; in sof_ipc4_widget_setup()
2610 msg->primary &= ~SOF_IPC4_GLB_PIPE_INSTANCE_MASK; in sof_ipc4_widget_setup()
2611 msg->primary |= SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id); in sof_ipc4_widget_setup()
2617 struct sof_ipc4_copier *ipc4_copier = swidget->private; in sof_ipc4_widget_setup()
2619 pipeline = pipe_widget->private; in sof_ipc4_widget_setup()
2620 if (pipeline->use_chain_dma) in sof_ipc4_widget_setup()
2623 ipc_size = ipc4_copier->ipc_config_size; in sof_ipc4_widget_setup()
2624 ipc_data = ipc4_copier->ipc_config_data; in sof_ipc4_widget_setup()
2626 msg = &ipc4_copier->msg; in sof_ipc4_widget_setup()
2632 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_widget_setup()
2633 struct sof_ipc4_copier *ipc4_copier = dai->private; in sof_ipc4_widget_setup()
2635 pipeline = pipe_widget->private; in sof_ipc4_widget_setup()
2636 if (pipeline->use_chain_dma) in sof_ipc4_widget_setup()
2639 ipc_size = ipc4_copier->ipc_config_size; in sof_ipc4_widget_setup()
2640 ipc_data = ipc4_copier->ipc_config_data; in sof_ipc4_widget_setup()
2642 msg = &ipc4_copier->msg; in sof_ipc4_widget_setup()
2647 struct sof_ipc4_gain *gain = swidget->private; in sof_ipc4_widget_setup() local
2649 ipc_size = sizeof(gain->data); in sof_ipc4_widget_setup()
2650 ipc_data = &gain->data; in sof_ipc4_widget_setup()
2652 msg = &gain->msg; in sof_ipc4_widget_setup()
2657 struct sof_ipc4_mixer *mixer = swidget->private; in sof_ipc4_widget_setup()
2659 ipc_size = sizeof(mixer->base_config); in sof_ipc4_widget_setup()
2660 ipc_data = &mixer->base_config; in sof_ipc4_widget_setup()
2662 msg = &mixer->msg; in sof_ipc4_widget_setup()
2667 struct sof_ipc4_src *src = swidget->private; in sof_ipc4_widget_setup()
2669 ipc_size = sizeof(src->data); in sof_ipc4_widget_setup()
2670 ipc_data = &src->data; in sof_ipc4_widget_setup()
2672 msg = &src->msg; in sof_ipc4_widget_setup()
2677 struct sof_ipc4_process *process = swidget->private; in sof_ipc4_widget_setup()
2679 if (!process->ipc_config_size) { in sof_ipc4_widget_setup()
2680 dev_err(sdev->dev, "module %s has no config data!\n", in sof_ipc4_widget_setup()
2681 swidget->widget->name); in sof_ipc4_widget_setup()
2682 return -EINVAL; in sof_ipc4_widget_setup()
2685 ipc_size = process->ipc_config_size; in sof_ipc4_widget_setup()
2686 ipc_data = process->ipc_config_data; in sof_ipc4_widget_setup()
2688 msg = &process->msg; in sof_ipc4_widget_setup()
2692 dev_err(sdev->dev, "widget type %d not supported", swidget->id); in sof_ipc4_widget_setup()
2693 return -EINVAL; in sof_ipc4_widget_setup()
2696 if (swidget->id != snd_soc_dapm_scheduler) { in sof_ipc4_widget_setup()
2697 int module_id = msg->primary & SOF_IPC4_MOD_ID_MASK; in sof_ipc4_widget_setup()
2701 dev_err(sdev->dev, "failed to assign instance id for %s\n", in sof_ipc4_widget_setup()
2702 swidget->widget->name); in sof_ipc4_widget_setup()
2706 msg->primary &= ~SOF_IPC4_MOD_INSTANCE_MASK; in sof_ipc4_widget_setup()
2707 msg->primary |= SOF_IPC4_MOD_INSTANCE(swidget->instance_id); in sof_ipc4_widget_setup()
2709 msg->extension &= ~SOF_IPC4_MOD_EXT_PARAM_SIZE_MASK; in sof_ipc4_widget_setup()
2710 msg->extension |= ipc_size >> 2; in sof_ipc4_widget_setup()
2712 msg->extension &= ~SOF_IPC4_MOD_EXT_PPL_ID_MASK; in sof_ipc4_widget_setup()
2713 msg->extension |= SOF_IPC4_MOD_EXT_PPL_ID(pipe_widget->instance_id); in sof_ipc4_widget_setup()
2715 dev_dbg(sdev->dev, "Create widget %s (pipe %d) - ID %d, instance %d, core %d\n", in sof_ipc4_widget_setup()
2716 swidget->widget->name, swidget->pipeline_id, module_id, in sof_ipc4_widget_setup()
2717 swidget->instance_id, swidget->core); in sof_ipc4_widget_setup()
2719 dev_dbg(sdev->dev, "Create pipeline %s (pipe %d) - instance %d, core %d\n", in sof_ipc4_widget_setup()
2720 swidget->widget->name, swidget->pipeline_id, in sof_ipc4_widget_setup()
2721 swidget->instance_id, swidget->core); in sof_ipc4_widget_setup()
2724 msg->data_size = ipc_size; in sof_ipc4_widget_setup()
2725 msg->data_ptr = ipc_data; in sof_ipc4_widget_setup()
2727 ret = sof_ipc_tx_message_no_reply(sdev->ipc, msg, ipc_size); in sof_ipc4_widget_setup()
2729 dev_err(sdev->dev, "failed to create module %s\n", swidget->widget->name); in sof_ipc4_widget_setup()
2731 if (swidget->id != snd_soc_dapm_scheduler) { in sof_ipc4_widget_setup()
2732 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_setup()
2734 ida_free(&fw_module->m_ida, swidget->instance_id); in sof_ipc4_widget_setup()
2736 ida_free(&pipeline_ida, swidget->instance_id); in sof_ipc4_widget_setup()
2745 struct sof_ipc4_fw_module *fw_module = swidget->module_info; in sof_ipc4_widget_free()
2746 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_widget_free()
2749 mutex_lock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2752 if (swidget->id == snd_soc_dapm_scheduler) { in sof_ipc4_widget_free()
2753 struct sof_ipc4_pipeline *pipeline = swidget->private; in sof_ipc4_widget_free()
2757 if (pipeline->use_chain_dma) { in sof_ipc4_widget_free()
2758 dev_warn(sdev->dev, "use_chain_dma set for scheduler %s", in sof_ipc4_widget_free()
2759 swidget->widget->name); in sof_ipc4_widget_free()
2760 mutex_unlock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2764 header = SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id); in sof_ipc4_widget_free()
2771 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_widget_free()
2773 dev_err(sdev->dev, "failed to free pipeline widget %s\n", in sof_ipc4_widget_free()
2774 swidget->widget->name); in sof_ipc4_widget_free()
2776 pipeline->mem_usage = 0; in sof_ipc4_widget_free()
2777 pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED; in sof_ipc4_widget_free()
2778 ida_free(&pipeline_ida, swidget->instance_id); in sof_ipc4_widget_free()
2779 swidget->instance_id = -EINVAL; in sof_ipc4_widget_free()
2781 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_widget_free()
2782 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_widget_free()
2784 if (!pipeline->use_chain_dma) in sof_ipc4_widget_free()
2785 ida_free(&fw_module->m_ida, swidget->instance_id); in sof_ipc4_widget_free()
2788 mutex_unlock(&ipc4_data->pipeline_state_mutex); in sof_ipc4_widget_free()
2806 pin_binding = src_widget->output_pin_binding; in sof_ipc4_get_queue_id()
2807 queue_ida = &src_widget->output_queue_ida; in sof_ipc4_get_queue_id()
2808 num_pins = src_widget->num_output_pins; in sof_ipc4_get_queue_id()
2809 buddy_name = sink_widget->widget->name; in sof_ipc4_get_queue_id()
2812 pin_binding = sink_widget->input_pin_binding; in sof_ipc4_get_queue_id()
2813 queue_ida = &sink_widget->input_queue_ida; in sof_ipc4_get_queue_id()
2814 num_pins = sink_widget->num_input_pins; in sof_ipc4_get_queue_id()
2815 buddy_name = src_widget->widget->name; in sof_ipc4_get_queue_id()
2818 scomp = current_swidget->scomp; in sof_ipc4_get_queue_id()
2821 dev_err(scomp->dev, "invalid %s num_pins: %d for queue allocation for %s\n", in sof_ipc4_get_queue_id()
2823 num_pins, current_swidget->widget->name); in sof_ipc4_get_queue_id()
2824 return -EINVAL; in sof_ipc4_get_queue_id()
2841 dev_err(scomp->dev, "no %s queue id found from pin binding array for %s\n", in sof_ipc4_get_queue_id()
2843 current_swidget->widget->name); in sof_ipc4_get_queue_id()
2844 return -EINVAL; in sof_ipc4_get_queue_id()
2859 pin_binding = swidget->output_pin_binding; in sof_ipc4_put_queue_id()
2860 queue_ida = &swidget->output_queue_ida; in sof_ipc4_put_queue_id()
2861 num_pins = swidget->num_output_pins; in sof_ipc4_put_queue_id()
2863 pin_binding = swidget->input_pin_binding; in sof_ipc4_put_queue_id()
2864 queue_ida = &swidget->input_queue_ida; in sof_ipc4_put_queue_id()
2865 num_pins = swidget->num_input_pins; in sof_ipc4_put_queue_id()
2881 const struct sof_ipc_ops *iops = sdev->ipc->ops; in sof_ipc4_set_copier_sink_format()
2887 if (WIDGET_IS_DAI(src_widget->id)) { in sof_ipc4_set_copier_sink_format()
2888 struct snd_sof_dai *dai = src_widget->private; in sof_ipc4_set_copier_sink_format()
2890 src_config = dai->private; in sof_ipc4_set_copier_sink_format()
2892 src_config = src_widget->private; in sof_ipc4_set_copier_sink_format()
2895 fw_module = src_widget->module_info; in sof_ipc4_set_copier_sink_format()
2897 format.sink_id = sroute->src_queue_id; in sof_ipc4_set_copier_sink_format()
2898 memcpy(&format.source_fmt, &src_config->audio_fmt, sizeof(format.source_fmt)); in sof_ipc4_set_copier_sink_format()
2900 pin_fmt = sof_ipc4_get_input_pin_audio_fmt(sink_widget, sroute->dst_queue_id); in sof_ipc4_set_copier_sink_format()
2902 dev_err(sdev->dev, in sof_ipc4_set_copier_sink_format()
2904 sink_widget->widget->name, sroute->dst_queue_id, in sof_ipc4_set_copier_sink_format()
2905 src_widget->widget->name, sroute->src_queue_id); in sof_ipc4_set_copier_sink_format()
2906 return -EINVAL; in sof_ipc4_set_copier_sink_format()
2914 msg.primary = fw_module->man4_module_entry.id; in sof_ipc4_set_copier_sink_format()
2915 msg.primary |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_set_copier_sink_format()
2922 return iops->set_get_data(sdev, &msg, msg.data_size, true); in sof_ipc4_set_copier_sink_format()
2927 struct snd_sof_widget *src_widget = sroute->src_widget; in sof_ipc4_route_setup()
2928 struct snd_sof_widget *sink_widget = sroute->sink_widget; in sof_ipc4_route_setup()
2929 struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget; in sof_ipc4_route_setup()
2930 struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget; in sof_ipc4_route_setup()
2931 struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info; in sof_ipc4_route_setup()
2932 struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; in sof_ipc4_route_setup()
2933 struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private; in sof_ipc4_route_setup()
2934 struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private; in sof_ipc4_route_setup()
2940 if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma) { in sof_ipc4_route_setup()
2941 if (!src_pipeline->use_chain_dma || !sink_pipeline->use_chain_dma) { in sof_ipc4_route_setup()
2942 dev_err(sdev->dev, in sof_ipc4_route_setup()
2944 src_widget->widget->name, sink_widget->widget->name); in sof_ipc4_route_setup()
2945 return -EINVAL; in sof_ipc4_route_setup()
2951 dev_err(sdev->dev, in sof_ipc4_route_setup()
2952 "cannot bind %s -> %s, no firmware module for: %s%s\n", in sof_ipc4_route_setup()
2953 src_widget->widget->name, sink_widget->widget->name, in sof_ipc4_route_setup()
2957 return -ENODEV; in sof_ipc4_route_setup()
2960 sroute->src_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, in sof_ipc4_route_setup()
2962 if (sroute->src_queue_id < 0) { in sof_ipc4_route_setup()
2963 dev_err(sdev->dev, in sof_ipc4_route_setup()
2965 src_widget->widget->name); in sof_ipc4_route_setup()
2966 return sroute->src_queue_id; in sof_ipc4_route_setup()
2969 sroute->dst_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, in sof_ipc4_route_setup()
2971 if (sroute->dst_queue_id < 0) { in sof_ipc4_route_setup()
2972 dev_err(sdev->dev, in sof_ipc4_route_setup()
2974 sink_widget->widget->name); in sof_ipc4_route_setup()
2975 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, in sof_ipc4_route_setup()
2977 return sroute->dst_queue_id; in sof_ipc4_route_setup()
2981 if (sroute->src_queue_id > 0 && WIDGET_IS_COPIER(src_widget->id)) { in sof_ipc4_route_setup()
2985 dev_err(sdev->dev, in sof_ipc4_route_setup()
2987 src_widget->widget->name, sroute->src_queue_id); in sof_ipc4_route_setup()
2992 dev_dbg(sdev->dev, "bind %s:%d -> %s:%d\n", in sof_ipc4_route_setup()
2993 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_setup()
2994 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_setup()
2996 header = src_fw_module->man4_module_entry.id; in sof_ipc4_route_setup()
2997 header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_route_setup()
3002 extension = sink_fw_module->man4_module_entry.id; in sof_ipc4_route_setup()
3003 extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id); in sof_ipc4_route_setup()
3004 extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id); in sof_ipc4_route_setup()
3005 extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id); in sof_ipc4_route_setup()
3010 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_route_setup()
3012 dev_err(sdev->dev, "failed to bind modules %s:%d -> %s:%d\n", in sof_ipc4_route_setup()
3013 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_setup()
3014 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_setup()
3021 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT); in sof_ipc4_route_setup()
3022 sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT); in sof_ipc4_route_setup()
3028 struct snd_sof_widget *src_widget = sroute->src_widget; in sof_ipc4_route_free()
3029 struct snd_sof_widget *sink_widget = sroute->sink_widget; in sof_ipc4_route_free()
3030 struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info; in sof_ipc4_route_free()
3031 struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; in sof_ipc4_route_free()
3033 struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget; in sof_ipc4_route_free()
3034 struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget; in sof_ipc4_route_free()
3035 struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private; in sof_ipc4_route_free()
3036 struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private; in sof_ipc4_route_free()
3041 if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma) in sof_ipc4_route_free()
3044 dev_dbg(sdev->dev, "unbind modules %s:%d -> %s:%d\n", in sof_ipc4_route_free()
3045 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_free()
3046 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_free()
3052 if (src_widget->spipe->pipe_widget == sink_widget->spipe->pipe_widget) in sof_ipc4_route_free()
3055 header = src_fw_module->man4_module_entry.id; in sof_ipc4_route_free()
3056 header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); in sof_ipc4_route_free()
3061 extension = sink_fw_module->man4_module_entry.id; in sof_ipc4_route_free()
3062 extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id); in sof_ipc4_route_free()
3063 extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id); in sof_ipc4_route_free()
3064 extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id); in sof_ipc4_route_free()
3069 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); in sof_ipc4_route_free()
3071 dev_err(sdev->dev, "failed to unbind modules %s:%d -> %s:%d\n", in sof_ipc4_route_free()
3072 src_widget->widget->name, sroute->src_queue_id, in sof_ipc4_route_free()
3073 sink_widget->widget->name, sroute->dst_queue_id); in sof_ipc4_route_free()
3075 sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT); in sof_ipc4_route_free()
3076 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT); in sof_ipc4_route_free()
3084 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; in sof_ipc4_dai_config()
3085 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; in sof_ipc4_dai_config()
3086 struct snd_sof_dai *dai = swidget->private; in sof_ipc4_dai_config()
3091 if (!dai || !dai->private) { in sof_ipc4_dai_config()
3092 dev_err(sdev->dev, "Invalid DAI or DAI private data for %s\n", in sof_ipc4_dai_config()
3093 swidget->widget->name); in sof_ipc4_dai_config()
3094 return -EINVAL; in sof_ipc4_dai_config()
3097 ipc4_copier = (struct sof_ipc4_copier *)dai->private; in sof_ipc4_dai_config()
3098 copier_data = &ipc4_copier->data; in sof_ipc4_dai_config()
3103 if (pipeline->use_chain_dma) { in sof_ipc4_dai_config()
3109 pipeline->msg.primary &= ~SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK; in sof_ipc4_dai_config()
3110 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID(data->dai_data); in sof_ipc4_dai_config()
3115 switch (ipc4_copier->dai_type) { in sof_ipc4_dai_config()
3117 gtw_attr = ipc4_copier->gtw_attr; in sof_ipc4_dai_config()
3118 gtw_attr->lp_buffer_alloc = pipeline->lp_mode; in sof_ipc4_dai_config()
3120 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_dai_config()
3121 copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_data); in sof_ipc4_dai_config()
3128 * unprepare. The node_id for multi-gateway DAI's will be overwritten with the in sof_ipc4_dai_config()
3134 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; in sof_ipc4_dai_config()
3135 ipc4_copier->dai_index = data->dai_node_id; in sof_ipc4_dai_config()
3141 if (blob->alh_cfg.device_count == 1) { in sof_ipc4_dai_config()
3142 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; in sof_ipc4_dai_config()
3143 copier_data->gtw_cfg.node_id |= in sof_ipc4_dai_config()
3144 SOF_IPC4_NODE_INDEX(data->dai_node_id); in sof_ipc4_dai_config()
3154 dev_err(sdev->dev, "%s: unsupported dai type %d\n", __func__, in sof_ipc4_dai_config()
3155 ipc4_copier->dai_type); in sof_ipc4_dai_config()
3156 return -EINVAL; in sof_ipc4_dai_config()
3166 struct sof_ipc4_fw_data *ipc4_data = sdev->private; in sof_ipc4_parse_manifest()
3169 u32 size = le32_to_cpu(man->priv.size); in sof_ipc4_parse_manifest()
3170 u8 *man_ptr = man->priv.data; in sof_ipc4_parse_manifest()
3175 dev_err(scomp->dev, "%s: Invalid topology ABI size: %u\n", in sof_ipc4_parse_manifest()
3177 return -EINVAL; in sof_ipc4_parse_manifest()
3182 dev_info(scomp->dev, in sof_ipc4_parse_manifest()
3184 le16_to_cpu(manifest->abi_major), le16_to_cpu(manifest->abi_minor), in sof_ipc4_parse_manifest()
3185 le16_to_cpu(manifest->abi_patch), in sof_ipc4_parse_manifest()
3194 manifest_tlv = manifest->items; in sof_ipc4_parse_manifest()
3196 for (i = 0; i < le16_to_cpu(manifest->count); i++) { in sof_ipc4_parse_manifest()
3197 len_check += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size); in sof_ipc4_parse_manifest()
3199 return -EINVAL; in sof_ipc4_parse_manifest()
3201 switch (le32_to_cpu(manifest_tlv->type)) { in sof_ipc4_parse_manifest()
3204 if (ipc4_data->nhlt) in sof_ipc4_parse_manifest()
3206 ipc4_data->nhlt = devm_kmemdup(sdev->dev, manifest_tlv->data, in sof_ipc4_parse_manifest()
3207 le32_to_cpu(manifest_tlv->size), GFP_KERNEL); in sof_ipc4_parse_manifest()
3208 if (!ipc4_data->nhlt) in sof_ipc4_parse_manifest()
3209 return -ENOMEM; in sof_ipc4_parse_manifest()
3212 dev_warn(scomp->dev, "Skipping unknown manifest data type %d\n", in sof_ipc4_parse_manifest()
3213 manifest_tlv->type); in sof_ipc4_parse_manifest()
3216 man_ptr += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size); in sof_ipc4_parse_manifest()
3225 struct sof_ipc4_copier *ipc4_copier = dai->private; in sof_ipc4_dai_get_param()
3235 list_for_each_entry(slink, &sdev->dai_link_list, list) { in sof_ipc4_dai_get_param()
3236 if (!strcmp(slink->link->name, dai->name)) { in sof_ipc4_dai_get_param()
3243 dev_err(sdev->dev, "no DAI link found for DAI %s\n", dai->name); in sof_ipc4_dai_get_param()
3244 return -EINVAL; in sof_ipc4_dai_get_param()
3247 for (i = 0; i < slink->num_hw_configs; i++) { in sof_ipc4_dai_get_param()
3248 hw_config = &slink->hw_configs[i]; in sof_ipc4_dai_get_param()
3249 if (dai->current_config == le32_to_cpu(hw_config->id)) { in sof_ipc4_dai_get_param()
3256 dev_err(sdev->dev, "no matching hw_config found for DAI %s\n", dai->name); in sof_ipc4_dai_get_param()
3257 return -EINVAL; in sof_ipc4_dai_get_param()
3260 switch (ipc4_copier->dai_type) { in sof_ipc4_dai_get_param()
3264 return le32_to_cpu(hw_config->mclk_rate); in sof_ipc4_dai_get_param()
3266 return le32_to_cpu(hw_config->bclk_rate); in sof_ipc4_dai_get_param()
3268 return le32_to_cpu(hw_config->tdm_slots); in sof_ipc4_dai_get_param()
3270 dev_err(sdev->dev, "invalid SSP param %d\n", param_type); in sof_ipc4_dai_get_param()
3275 dev_err(sdev->dev, "DAI type %d not supported yet!\n", ipc4_copier->dai_type); in sof_ipc4_dai_get_param()
3279 return -EINVAL; in sof_ipc4_dai_get_param()
3298 list_for_each_entry(spcm, &sdev->pcm_list, list) { in sof_ipc4_tear_down_all_pipelines()
3300 struct snd_pcm_substream *substream = spcm->stream[dir].substream; in sof_ipc4_tear_down_all_pipelines()
3302 if (!substream || !substream->runtime || spcm->stream[dir].suspend_ignored) in sof_ipc4_tear_down_all_pipelines()
3305 if (spcm->stream[dir].list) { in sof_ipc4_tear_down_all_pipelines()
3317 if (link->no_pcm) in sof_ipc4_link_setup()
3327 link->trigger[SNDRV_PCM_STREAM_PLAYBACK] = SND_SOC_DPCM_TRIGGER_POST; in sof_ipc4_link_setup()
3328 link->trigger[SNDRV_PCM_STREAM_CAPTURE] = SND_SOC_DPCM_TRIGGER_PRE; in sof_ipc4_link_setup()