Skip to content
Merged
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
88 changes: 88 additions & 0 deletions sound/soc/sof/ipc4-topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,14 @@ static const struct sof_topology_token src_tokens[] = {
offsetof(struct sof_ipc4_src_data, sink_rate)},
};

/* ASRC */
static const struct sof_topology_token asrc_tokens[] = {
{SOF_TKN_ASRC_RATE_OUT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
offsetof(struct sof_ipc4_asrc_data, out_freq)},
{SOF_TKN_ASRC_OPERATION_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
offsetof(struct sof_ipc4_asrc_data, asrc_mode)},
Comment thread
ranj063 marked this conversation as resolved.
Resolved
};

static const struct sof_token_info ipc4_token_list[SOF_TOKEN_COUNT] = {
[SOF_DAI_TOKENS] = {"DAI tokens", dai_tokens, ARRAY_SIZE(dai_tokens)},
[SOF_PIPELINE_TOKENS] = {"Pipeline tokens", pipeline_tokens, ARRAY_SIZE(pipeline_tokens)},
Expand All @@ -165,6 +173,7 @@ static const struct sof_token_info ipc4_token_list[SOF_TOKEN_COUNT] = {
ipc4_audio_fmt_num_tokens, ARRAY_SIZE(ipc4_audio_fmt_num_tokens)},
[SOF_GAIN_TOKENS] = {"Gain tokens", gain_tokens, ARRAY_SIZE(gain_tokens)},
[SOF_SRC_TOKENS] = {"SRC tokens", src_tokens, ARRAY_SIZE(src_tokens)},
[SOF_ASRC_TOKENS] = {"ASRC tokens", asrc_tokens, ARRAY_SIZE(asrc_tokens)},
};

struct snd_sof_widget *sof_ipc4_find_swidget_by_ids(struct snd_sof_dev *sdev,
Expand Down Expand Up @@ -1044,6 +1053,50 @@ static int sof_ipc4_widget_setup_comp_src(struct snd_sof_widget *swidget)
return ret;
}

static int sof_ipc4_widget_setup_comp_asrc(struct snd_sof_widget *swidget)
{
struct snd_soc_component *scomp = swidget->scomp;
struct snd_sof_pipeline *spipe = swidget->spipe;
struct sof_ipc4_asrc *asrc;
int ret;

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

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

swidget->private = asrc;

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

ret = sof_update_ipc_object(scomp, &asrc->data, SOF_ASRC_TOKENS, swidget->tuples,
swidget->num_tuples, sizeof(*asrc), 1);
if (ret) {
dev_err(scomp->dev, "Parsing ASRC tokens failed\n");
goto err;
}

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

dev_dbg(scomp->dev, "ASRC sink rate %d, mode 0x%08x\n",
asrc->data.out_freq, asrc->data.asrc_mode);

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

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

static void sof_ipc4_widget_free_comp_src(struct snd_sof_widget *swidget)
{
struct sof_ipc4_src *src = swidget->private;
Expand All @@ -1056,6 +1109,18 @@ static void sof_ipc4_widget_free_comp_src(struct snd_sof_widget *swidget)
swidget->private = NULL;
}

static void sof_ipc4_widget_free_comp_asrc(struct snd_sof_widget *swidget)
{
struct sof_ipc4_asrc *asrc = swidget->private;

if (!asrc)
return;

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

static void sof_ipc4_widget_free_comp_mixer(struct snd_sof_widget *swidget)
{
struct sof_ipc4_mixer *mixer = swidget->private;
Expand Down Expand Up @@ -2808,6 +2873,16 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
msg = &src->msg;
break;
}
case snd_soc_dapm_asrc:
{
struct sof_ipc4_asrc *asrc = swidget->private;

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

msg = &asrc->msg;
break;
}
case snd_soc_dapm_effect:
{
struct sof_ipc4_process *process = swidget->private;
Expand Down Expand Up @@ -3494,6 +3569,15 @@ static enum sof_tokens src_token_list[] = {
SOF_COMP_EXT_TOKENS,
};

static enum sof_tokens asrc_token_list[] = {
SOF_COMP_TOKENS,
SOF_ASRC_TOKENS,
SOF_AUDIO_FMT_NUM_TOKENS,
SOF_IN_AUDIO_FORMAT_TOKENS,
SOF_OUT_AUDIO_FORMAT_TOKENS,
SOF_COMP_EXT_TOKENS,
};

static enum sof_tokens process_token_list[] = {
SOF_COMP_TOKENS,
SOF_AUDIO_FMT_NUM_TOKENS,
Expand Down Expand Up @@ -3539,6 +3623,10 @@ static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TY
src_token_list, ARRAY_SIZE(src_token_list),
NULL, sof_ipc4_prepare_src_module,
NULL},
[snd_soc_dapm_asrc] = {sof_ipc4_widget_setup_comp_asrc, sof_ipc4_widget_free_comp_asrc,
asrc_token_list, ARRAY_SIZE(asrc_token_list),
NULL, sof_ipc4_prepare_src_module, /* Common prepare with SRC */
NULL},
[snd_soc_dapm_effect] = {sof_ipc4_widget_setup_comp_process,
sof_ipc4_widget_free_comp_process,
process_token_list, ARRAY_SIZE(process_token_list),
Expand Down
24 changes: 24 additions & 0 deletions sound/soc/sof/ipc4-topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,30 @@ struct sof_ipc4_src {
struct sof_ipc4_msg msg;
};

/*
* struct sof_ipc4_asrc_data - IPC data for ASRC
* @base_config: IPC base config data
* @out_freq: Output rate for sink module, passed as such from topology to FW.
* @asrc_mode: Control for ASRC features with bit-fields, passed as such from topolgy to FW.
*/
struct sof_ipc4_asrc_data {
struct sof_ipc4_base_module_cfg base_config;
uint32_t out_freq;
uint32_t asrc_mode;
} __packed __aligned(4);

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

/**
* struct sof_ipc4_base_module_cfg_ext - base module config extension containing the pin format
* information for the module. Both @num_input_pin_fmts and @num_output_pin_fmts cannot be 0 for a
Expand Down