summaryrefslogtreecommitdiff
path: root/sound/soc/sof/ipc4-topology.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sof/ipc4-topology.c')
-rw-r--r--sound/soc/sof/ipc4-topology.c76
1 files changed, 62 insertions, 14 deletions
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index 7cb63e6b24dc..b24a64377f68 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -44,6 +44,8 @@ static const struct sof_topology_token ipc4_sched_tokens[] = {
offsetof(struct sof_ipc4_pipeline, use_chain_dma)},
{SOF_TKN_SCHED_CORE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
offsetof(struct sof_ipc4_pipeline, core_id)},
+ {SOF_TKN_SCHED_PRIORITY, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+ offsetof(struct sof_ipc4_pipeline, priority)},
};
static const struct sof_topology_token pipeline_tokens[] = {
@@ -683,9 +685,6 @@ static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
goto err;
}
- /* TODO: Get priority from topology */
- pipeline->priority = 0;
-
dev_dbg(scomp->dev, "pipeline '%s': id %d, pri %d, core_id %u, lp mode %d\n",
swidget->widget->name, swidget->pipeline_id,
pipeline->priority, pipeline->core_id, pipeline->lp_mode);
@@ -895,7 +894,8 @@ static int sof_ipc4_widget_setup_comp_process(struct snd_sof_widget *swidget)
if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) {
struct sof_ipc4_base_module_cfg_ext *base_cfg_ext;
u32 ext_size = struct_size(base_cfg_ext, pin_formats,
- swidget->num_input_pins + swidget->num_output_pins);
+ size_add(swidget->num_input_pins,
+ swidget->num_output_pins));
base_cfg_ext = kzalloc(ext_size, GFP_KERNEL);
if (!base_cfg_ext) {
@@ -1369,9 +1369,9 @@ static int snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_s
}
#endif
-static bool sof_ipc4_copier_is_single_format(struct snd_sof_dev *sdev,
- struct sof_ipc4_pin_format *pin_fmts,
- u32 pin_fmts_size)
+bool sof_ipc4_copier_is_single_format(struct snd_sof_dev *sdev,
+ struct sof_ipc4_pin_format *pin_fmts,
+ u32 pin_fmts_size)
{
struct sof_ipc4_audio_format *fmt;
u32 valid_bits;
@@ -1380,7 +1380,7 @@ static bool sof_ipc4_copier_is_single_format(struct snd_sof_dev *sdev,
fmt = &pin_fmts[0].audio_fmt;
valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
- /* check if all output formats in topology are the same */
+ /* check if all formats in topology are the same */
for (i = 1; i < pin_fmts_size; i++) {
u32 _valid_bits;
@@ -1726,9 +1726,14 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.ibs;
break;
case snd_soc_dapm_aif_in:
- copier_data->gtw_cfg.dma_buffer_size =
- max((u32)SOF_IPC4_MIN_DMA_BUFFER_SIZE, deep_buffer_dma_ms) *
- copier_data->base_config.ibs;
+ copier_data->gtw_cfg.dma_buffer_size =
+ max((u32)SOF_IPC4_MIN_DMA_BUFFER_SIZE, deep_buffer_dma_ms) *
+ copier_data->base_config.ibs;
+ dev_dbg(sdev->dev, "copier %s, dma buffer%s: %u ms (%u bytes)",
+ swidget->widget->name,
+ deep_buffer_dma_ms ? " (using Deep Buffer)" : "",
+ max((u32)SOF_IPC4_MIN_DMA_BUFFER_SIZE, deep_buffer_dma_ms),
+ copier_data->gtw_cfg.dma_buffer_size);
break;
case snd_soc_dapm_dai_out:
case snd_soc_dapm_aif_out:
@@ -2102,17 +2107,57 @@ static int sof_ipc4_control_load_volume(struct snd_sof_dev *sdev, struct snd_sof
msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);
- msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_GAIN_PARAM_ID);
+ /* volume controls with range 0-1 (off/on) are switch controls */
+ if (scontrol->max == 1)
+ msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_SWITCH_CONTROL_PARAM_ID);
+ else
+ msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_GAIN_PARAM_ID);
- /* set default volume values to 0dB in control */
for (i = 0; i < scontrol->num_channels; i++) {
control_data->chanv[i].channel = i;
- control_data->chanv[i].value = SOF_IPC4_VOL_ZERO_DB;
+ /*
+ * Default, initial values:
+ * - 0dB for volume controls
+ * - off (0) for switch controls - value already zero after
+ * memory allocation
+ */
+ if (scontrol->max > 1)
+ control_data->chanv[i].value = SOF_IPC4_VOL_ZERO_DB;
}
return 0;
}
+static int sof_ipc4_control_load_enum(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol)
+{
+ struct sof_ipc4_control_data *control_data;
+ struct sof_ipc4_msg *msg;
+ int i;
+
+ scontrol->size = struct_size(control_data, chanv, scontrol->num_channels);
+
+ /* scontrol->ipc_control_data will be freed in sof_control_unload */
+ scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL);
+ if (!scontrol->ipc_control_data)
+ return -ENOMEM;
+
+ control_data = scontrol->ipc_control_data;
+ control_data->index = scontrol->index;
+
+ msg = &control_data->msg;
+ msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET);
+ msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
+ msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);
+
+ msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_ENUM_CONTROL_PARAM_ID);
+
+ /* Default, initial value for enums: first enum entry is selected (0) */
+ for (i = 0; i < scontrol->num_channels; i++)
+ control_data->chanv[i].channel = i;
+
+ return 0;
+}
+
static int sof_ipc4_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol)
{
struct sof_ipc4_control_data *control_data;
@@ -2187,6 +2232,9 @@ static int sof_ipc4_control_setup(struct snd_sof_dev *sdev, struct snd_sof_contr
return sof_ipc4_control_load_volume(sdev, scontrol);
case SND_SOC_TPLG_CTL_BYTES:
return sof_ipc4_control_load_bytes(sdev, scontrol);
+ case SND_SOC_TPLG_CTL_ENUM:
+ case SND_SOC_TPLG_CTL_ENUM_VALUE:
+ return sof_ipc4_control_load_enum(sdev, scontrol);
default:
break;
}