Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/sound/sof/ipc4/header.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,12 @@ enum sof_ipc4_pipeline_state {
#define SOF_IPC4_GLB_PIPE_EXT_CORE_ID_MASK GENMASK(23, 20)
#define SOF_IPC4_GLB_PIPE_EXT_CORE_ID(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_CORE_ID_SHIFT)

#define SOF_IPC4_GLB_PIPE_EXT_DIRECTION_SET_SHIFT 24
#define SOF_IPC4_GLB_PIPE_EXT_DIRECTION_SET(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_DIRECTION_SET_SHIFT)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SOF_IPC4_GLB_PIPE_EXT_DIRECTION_VALID ?


#define SOF_IPC4_GLB_PIPE_EXT_DIRECTION_SHIFT 25
#define SOF_IPC4_GLB_PIPE_EXT_DIRECTION(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_DIRECTION_SHIFT)

/* pipeline set state ipc msg */
#define SOF_IPC4_GLB_PIPE_STATE_ID_SHIFT 16
#define SOF_IPC4_GLB_PIPE_STATE_ID_MASK GENMASK(23, 16)
Expand Down
111 changes: 105 additions & 6 deletions sound/soc/sof/ipc4-topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -1063,6 +1063,52 @@ static int sof_ipc4_widget_setup_comp_mixer(struct snd_sof_widget *swidget)
return ret;
}

static int sof_ipc4_widget_setup_comp_siggen(struct snd_sof_widget *swidget)
{
struct snd_soc_component *scomp = swidget->scomp;
struct snd_sof_pipeline *spipe = swidget->spipe;
struct sof_ipc4_siggen *siggen;
int ret;

dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name);

siggen = kzalloc(sizeof(*siggen), GFP_KERNEL);
if (!siggen)
return -ENOMEM;

swidget->private = siggen;

ret = sof_ipc4_get_audio_fmt(scomp, swidget, &siggen->available_fmt,
&siggen->data.base_config);
if (ret)
goto err;

spipe->core_mask |= BIT(swidget->core);

ret = sof_ipc4_widget_setup_msg(swidget, &siggen->msg);
if (ret)
goto err;

return 0;
err:
sof_ipc4_free_audio_fmt(&siggen->available_fmt);
kfree(siggen);
swidget->private = NULL;
return ret;
}

static void sof_ipc4_widget_free_comp_siggen(struct snd_sof_widget *swidget)
{
struct sof_ipc4_siggen *siggen = swidget->private;

if (!siggen)
return;

sof_ipc4_free_audio_fmt(&siggen->available_fmt);
kfree(swidget->private);
swidget->private = NULL;
}

static int sof_ipc4_widget_setup_comp_src(struct snd_sof_widget *swidget)
{
struct snd_soc_component *scomp = swidget->scomp;
Expand Down Expand Up @@ -1281,7 +1327,7 @@ static void sof_ipc4_widget_free_comp_process(struct snd_sof_widget *swidget)

static void
sof_ipc4_update_resource_usage(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget,
struct sof_ipc4_base_module_cfg *base_config)
struct sof_ipc4_base_module_cfg *base_config, int dir)
{
struct sof_ipc4_fw_module *fw_module = swidget->module_info;
struct snd_sof_widget *pipe_widget;
Expand Down Expand Up @@ -1313,6 +1359,10 @@ sof_ipc4_update_resource_usage(struct snd_sof_dev *sdev, struct snd_sof_widget *
pipeline = pipe_widget->private;
pipeline->mem_usage += total;

/* set pipeline direction */
pipeline->msg.extension |= SOF_IPC4_GLB_PIPE_EXT_DIRECTION_SET(0x1);
pipeline->msg.extension |= SOF_IPC4_GLB_PIPE_EXT_DIRECTION(dir);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document what dir value is what direction, I assume playback is 0, capture is 1?
and to be safe with the integer:

	pipeline->msg.extension |= SOF_IPC4_GLB_PIPE_EXT_DIRECTION(!!dir);

Another way to put this could be to
#define SOF_IPC4_GLB_PIPE_EXT_DIR_MASK GENMASK(25, 24)
#define SOF_IPC4_GLB_PIPE_EXT_DIR_SET(dir) ((dir + 1) << 24)

so:
0 means it is not provided
1 means it is playback direction
2 means capture
3 for later use


/* Update base_config->cpc from the module manifest */
sof_ipc4_update_cpc_from_manifest(sdev, fw_module, base_config);

Expand Down Expand Up @@ -2452,7 +2502,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
input_fmt_index, output_fmt_index);

/* update pipeline memory usage */
sof_ipc4_update_resource_usage(sdev, swidget, &copier_data->base_config);
sof_ipc4_update_resource_usage(sdev, swidget, &copier_data->base_config, dir);

/* copy IPC data */
memcpy(*ipc_config_data, (void *)copier_data, sizeof(*copier_data));
Expand All @@ -2475,6 +2525,34 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
return 0;
}

static int sof_ipc4_prepare_siggen_module(struct snd_sof_widget *swidget,
struct snd_pcm_hw_params *fe_params,
struct snd_sof_platform_stream_params *platform_params,
struct snd_pcm_hw_params *pipeline_params, int dir)
{
struct snd_soc_component *scomp = swidget->scomp;
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
struct sof_ipc4_siggen *siggen = swidget->private;
struct sof_ipc4_available_audio_format *available_fmt = &siggen->available_fmt;
struct sof_ipc4_audio_format *out_fmt;

/* use the first available output format to set the base config audio format */
if (available_fmt->num_output_formats != 1) {
dev_err(sdev->dev, "siggen should only have one available output format");
return -EINVAL;
}
out_fmt = &available_fmt->output_pin_fmts[0].audio_fmt;

/* copy output format */
memcpy(&siggen->data.base_config.audio_fmt, out_fmt, sizeof(struct sof_ipc4_audio_format));
siggen->data.base_config.obs = available_fmt->output_pin_fmts[0].buffer_size;

/* update pipeline memory usage */
sof_ipc4_update_resource_usage(sdev, swidget, &siggen->data.base_config, dir);

return 0;
}

static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
struct snd_pcm_hw_params *fe_params,
struct snd_sof_platform_stream_params *platform_params,
Expand Down Expand Up @@ -2515,7 +2593,7 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
input_fmt_index, output_fmt_index);

/* update pipeline memory usage */
sof_ipc4_update_resource_usage(sdev, swidget, &gain->data.base_config);
sof_ipc4_update_resource_usage(sdev, swidget, &gain->data.base_config, dir);

return 0;
}
Expand Down Expand Up @@ -2560,7 +2638,7 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
input_fmt_index, output_fmt_index);

/* update pipeline memory usage */
sof_ipc4_update_resource_usage(sdev, swidget, &mixer->base_config);
sof_ipc4_update_resource_usage(sdev, swidget, &mixer->base_config, dir);

return 0;
}
Expand Down Expand Up @@ -2626,7 +2704,7 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
input_fmt_index, output_fmt_index);

/* update pipeline memory usage */
sof_ipc4_update_resource_usage(sdev, swidget, &src->data.base_config);
sof_ipc4_update_resource_usage(sdev, swidget, &src->data.base_config, dir);

out_audio_fmt = &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt;
src->data.sink_rate = out_audio_fmt->sampling_frequency;
Expand Down Expand Up @@ -2783,7 +2861,7 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
input_fmt_index, output_fmt_index);

/* update pipeline memory usage */
sof_ipc4_update_resource_usage(sdev, swidget, &process->base_config);
sof_ipc4_update_resource_usage(sdev, swidget, &process->base_config, dir);

/* ipc_config_data is composed of the base_config followed by an optional extension */
memcpy(cfg, &process->base_config, sizeof(struct sof_ipc4_base_module_cfg));
Expand Down Expand Up @@ -3158,6 +3236,16 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
msg = &asrc->msg;
break;
}
case snd_soc_dapm_siggen:
{
struct sof_ipc4_siggen *siggen = swidget->private;

ipc_size = sizeof(siggen->data);
ipc_data = &siggen->data;

msg = &siggen->msg;
break;
}
case snd_soc_dapm_effect:
{
struct sof_ipc4_process *process = swidget->private;
Expand Down Expand Up @@ -3848,6 +3936,13 @@ static enum sof_tokens mixer_token_list[] = {
SOF_COMP_EXT_TOKENS,
};

static enum sof_tokens siggen_token_list[] = {
SOF_COMP_TOKENS,
SOF_AUDIO_FMT_NUM_TOKENS,
SOF_OUT_AUDIO_FORMAT_TOKENS,
SOF_COMP_EXT_TOKENS,
};

static enum sof_tokens src_token_list[] = {
SOF_COMP_TOKENS,
SOF_SRC_TOKENS,
Expand Down Expand Up @@ -3920,6 +4015,10 @@ static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TY
process_token_list, ARRAY_SIZE(process_token_list),
NULL, sof_ipc4_prepare_process_module,
NULL},
[snd_soc_dapm_siggen] = {sof_ipc4_widget_setup_comp_siggen,
sof_ipc4_widget_free_comp_siggen,
siggen_token_list, ARRAY_SIZE(siggen_token_list), NULL,
sof_ipc4_prepare_siggen_module, NULL},
};

const struct sof_ipc_tplg_ops ipc4_tplg_ops = {
Expand Down
21 changes: 21 additions & 0 deletions sound/soc/sof/ipc4-topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,27 @@ struct sof_ipc4_src {
struct sof_ipc4_msg msg;
};

/*
* struct sof_ipc4_siggen_data - IPC data for siggen
* @base_config: IPC base config data
* @sink_rate: Output rate for sink module
*/
struct sof_ipc4_siggen_data {
struct sof_ipc4_base_module_cfg base_config;
} __packed __aligned(4);

/**
* struct sof_ipc4_siggen - siggen config data
* @data: IPC base config data
* @available_fmt: Available audio format
* @msg: IPC4 message struct containing header and data info
*/
struct sof_ipc4_siggen {
struct sof_ipc4_siggen_data data;
struct sof_ipc4_available_audio_format available_fmt;
struct sof_ipc4_msg msg;
};

/*
* struct sof_ipc4_asrc_data - IPC data for ASRC
* @base_config: IPC base config data
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/sof/pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
}

/* set the host DMA ID */
if (tplg_ops && tplg_ops->host_config)
if (WIDGET_IS_AIF(host_widget->id) && tplg_ops && tplg_ops->host_config)
tplg_ops->host_config(sdev, host_widget, platform_params);
}

Expand Down
Loading
Loading