Commit 2cabd02b authored by Ranjani Sridharan's avatar Ranjani Sridharan Committed by Mark Brown

ASoC: SOF: ipc4-topology: Add support for parsing AIF_IN/AIF_OUT widgets

Add support for parsing AIF_IN/AIF_OUT type widgets in IPC4. Add all the
new required token ID's for parsing these widgets to the list of tokens in
enum sof_tokens and the definitions of the token arrays corresponding to
each of the token ID's.

Also, upgrade the sof_widget_parse_tokens() function in the common
topology parser to be able to parse multiple sets of tokens for the
audio format and copier gateway config tokens.
Co-developed-by: default avatarRander Wang <rander.wang@linux.intel.com>
Signed-off-by: default avatarRander Wang <rander.wang@linux.intel.com>
Co-developed-by: default avatarBard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: default avatarBard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarPéter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarPaul Olaru <paul.olaru@oss.nxp.com>
Link: https://lore.kernel.org/r/20220609032643.916882-4-ranjani.sridharan@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 90e89155
This diff is collapsed.
......@@ -11,6 +11,8 @@
#include <sound/sof/ipc4/header.h>
#define SOF_IPC4_NODE_TYPE(x) ((x) << 8)
/**
* struct sof_ipc4_pipeline - pipeline config data
* @priority: Priority of this pipeline
......@@ -27,4 +29,85 @@ struct sof_ipc4_pipeline {
struct sof_ipc4_msg msg;
};
/**
* struct sof_ipc4_available_audio_format - Available audio formats
* @base_config: Available base config
* @out_audio_fmt: Available output audio format
* @ref_audio_fmt: Reference audio format to match runtime audio format
* @dma_buffer_size: Available Gateway DMA buffer size (in bytes)
* @audio_fmt_num: Number of available audio formats
*/
struct sof_ipc4_available_audio_format {
struct sof_ipc4_base_module_cfg *base_config;
struct sof_ipc4_audio_format *out_audio_fmt;
struct sof_ipc4_audio_format *ref_audio_fmt;
u32 *dma_buffer_size;
int audio_fmt_num;
};
/**
* struct sof_copier_gateway_cfg - IPC gateway configuration
* @node_id: ID of Gateway Node
* @dma_buffer_size: Preferred Gateway DMA buffer size (in bytes)
* @config_length: Length of gateway node configuration blob specified in #config_data
* config_data: Gateway node configuration blob
*/
struct sof_copier_gateway_cfg {
uint32_t node_id;
uint32_t dma_buffer_size;
uint32_t config_length;
uint32_t config_data[];
};
/**
* struct sof_ipc4_copier_data - IPC data for copier
* @base_config: Base configuration including input audio format
* @out_format: Output audio format
* @copier_feature_mask: Copier feature mask
* @gtw_cfg: Gateway configuration
*/
struct sof_ipc4_copier_data {
struct sof_ipc4_base_module_cfg base_config;
struct sof_ipc4_audio_format out_format;
uint32_t copier_feature_mask;
struct sof_copier_gateway_cfg gtw_cfg;
};
/**
* struct sof_ipc4_gtw_attributes: Gateway attributes
* @lp_buffer_alloc: Gateway data requested in low power memory
* @alloc_from_reg_file: Gateway data requested in register file memory
* @rsvd: reserved for future use
*/
struct sof_ipc4_gtw_attributes {
uint32_t lp_buffer_alloc : 1;
uint32_t alloc_from_reg_file : 1;
uint32_t rsvd : 30;
};
/**
* struct sof_ipc4_copier - copier config data
* @data: IPC copier data
* @copier_config: Copier + blob
* @ipc_config_size: Size of copier_config
* @available_fmt: Available audio format
* @frame_fmt: frame format
* @msg: message structure for copier
* @gtw_attr: Gateway attributes for copier blob
* @dai_type: DAI type
* @dai_index: DAI index
*/
struct sof_ipc4_copier {
struct sof_ipc4_copier_data data;
u32 *copier_config;
uint32_t ipc_config_size;
void *ipc_config_data;
struct sof_ipc4_available_audio_format available_fmt;
u32 frame_fmt;
struct sof_ipc4_msg msg;
struct sof_ipc4_gtw_attributes *gtw_attr;
u32 dai_type;
int dai_index;
};
#endif
......@@ -225,6 +225,13 @@ enum sof_tokens {
SOF_AFE_TOKENS,
SOF_CORE_TOKENS,
SOF_COMP_EXT_TOKENS,
SOF_IN_AUDIO_FORMAT_TOKENS,
SOF_OUT_AUDIO_FORMAT_TOKENS,
SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS,
SOF_COPIER_GATEWAY_CFG_TOKENS,
SOF_COPIER_TOKENS,
SOF_AUDIO_FMT_NUM_TOKENS,
SOF_COPIER_FORMAT_TOKENS,
/* this should be the last */
SOF_TOKEN_COUNT,
......
......@@ -1141,6 +1141,21 @@ static int spcm_bind(struct snd_soc_component *scomp, struct snd_sof_pcm *spcm,
return 0;
}
static int sof_get_token_value(u32 token_id, struct snd_sof_tuple *tuples, int num_tuples)
{
int i;
if (!tuples)
return -EINVAL;
for (i = 0; i < num_tuples; i++) {
if (tuples[i].token == token_id)
return tuples[i].value.v;
}
return -EINVAL;
}
static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_sof_widget *swidget,
struct snd_soc_tplg_dapm_widget *tw,
enum sof_tokens *object_token_list, int count)
......@@ -1168,6 +1183,8 @@ static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_s
/* parse token list for widget */
for (i = 0; i < count; i++) {
int num_sets = 1;
if (object_token_list[i] >= SOF_TOKEN_COUNT) {
dev_err(scomp->dev, "Invalid token id %d for widget %s\n",
object_token_list[i], swidget->widget->name);
......@@ -1175,8 +1192,9 @@ static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_s
goto err;
}
switch (object_token_list[i]) {
case SOF_COMP_EXT_TOKENS:
/* parse and save UUID in swidget */
if (object_token_list[i] == SOF_COMP_EXT_TOKENS) {
ret = sof_parse_tokens(scomp, swidget,
token_list[object_token_list[i]].tokens,
token_list[object_token_list[i]].count,
......@@ -1189,11 +1207,41 @@ static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_s
}
continue;
case SOF_IN_AUDIO_FORMAT_TOKENS:
case SOF_OUT_AUDIO_FORMAT_TOKENS:
case SOF_COPIER_GATEWAY_CFG_TOKENS:
case SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS:
num_sets = sof_get_token_value(SOF_TKN_COMP_NUM_AUDIO_FORMATS,
swidget->tuples, swidget->num_tuples);
if (num_sets < 0) {
dev_err(sdev->dev, "Invalid audio format count for %s\n",
swidget->widget->name);
ret = num_sets;
goto err;
}
if (num_sets > 1) {
struct snd_sof_tuple *new_tuples;
num_tuples += token_list[object_token_list[i]].count * num_sets;
new_tuples = krealloc(swidget->tuples,
sizeof(*new_tuples) * num_tuples, GFP_KERNEL);
if (!new_tuples) {
ret = -ENOMEM;
goto err;
}
swidget->tuples = new_tuples;
}
break;
default:
break;
}
/* copy one set of tuples per token ID into swidget->tuples */
ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size),
object_token_list[i], 1, swidget->tuples,
object_token_list[i], num_sets, swidget->tuples,
num_tuples, &swidget->num_tuples);
if (ret < 0) {
dev_err(scomp->dev, "Failed parsing %s for widget %s err: %d\n",
......@@ -1208,21 +1256,6 @@ static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_s
return ret;
}
static int sof_get_token_value(u32 token_id, struct snd_sof_tuple *tuples, int num_tuples)
{
int i;
if (!tuples)
return -EINVAL;
for (i = 0; i < num_tuples; i++) {
if (tuples[i].token == token_id)
return tuples[i].value.v;
}
return -EINVAL;
}
/* external widget init - used for any driver specific init */
static int sof_widget_ready(struct snd_soc_component *scomp, int index,
struct snd_soc_dapm_widget *w,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment