Unverified Commit d87524bf authored by Ranjani Sridharan's avatar Ranjani Sridharan Committed by Mark Brown
Browse files

ASoC: SOF: topology: Add helper function for processing tuple arrays



Add a helper function for processing tuple arrays and populating the
IPC structure objects based on the token ID passed.

Introduce a new enum representing token ID for the tokens
currently used in the topology parse and a new struct sof_token_info
to store the information about a token set. Finally, expose the struct
snd_sof_topology token as it will be used by IPC-specific code.

Signed-off-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarBard Liao <yung-chuan.liao@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>
Link: https://lore.kernel.org/r/20220314200520.1233427-5-ranjani.sridharan@linux.intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 226abb75
Loading
Loading
Loading
Loading
+54 −0
Original line number Diff line number Diff line
@@ -78,6 +78,57 @@ struct snd_sof_tuple {
	} value;
};

/*
 * List of SOF token ID's. The order of ID's does not matter as token arrays are looked up based on
 * the ID.
 */
enum sof_tokens {
	SOF_PCM_TOKENS,
	SOF_PIPELINE_TOKENS,
	SOF_SCHED_TOKENS,
	SOF_ASRC_TOKENS,
	SOF_SRC_TOKENS,
	SOF_COMP_TOKENS,
	SOF_BUFFER_TOKENS,
	SOF_VOLUME_TOKENS,
	SOF_PROCESS_TOKENS,
	SOF_DAI_TOKENS,
	SOF_DAI_LINK_TOKENS,
	SOF_HDA_TOKENS,
	SOF_SSP_TOKENS,
	SOF_ALH_TOKENS,
	SOF_DMIC_TOKENS,
	SOF_DMIC_PDM_TOKENS,
	SOF_ESAI_TOKENS,
	SOF_SAI_TOKENS,
	SOF_AFE_TOKENS,
	SOF_CORE_TOKENS,
	SOF_COMP_EXT_TOKENS,

	/* this should be the last */
	SOF_TOKEN_COUNT,
};

/**
 * struct sof_topology_token - SOF topology token definition
 * @token:		Token number
 * @type:		Token type
 * @get_token:		Function pointer to parse the token value and save it in a object
 * @offset:		Offset within an object to save the token value into
 */
struct sof_topology_token {
	u32 token;
	u32 type;
	int (*get_token)(void *elem, void *object, u32 offset);
	u32 offset;
};

struct sof_token_info {
	const char *name;
	const struct sof_topology_token *tokens;
	int count;
};

/* PCM stream, mapped to FW component  */
struct snd_sof_pcm_stream {
	u32 comp_id;
@@ -333,4 +384,7 @@ int get_token_u16(void *elem, void *object, u32 offset);
int get_token_comp_format(void *elem, void *object, u32 offset);
int get_token_dai_type(void *elem, void *object, u32 offset);
int get_token_uuid(void *elem, void *object, u32 offset);
int sof_update_ipc_object(struct snd_soc_component *scomp, void *object, enum sof_tokens token_id,
			  struct snd_sof_tuple *tuples, int num_tuples,
			  size_t object_size, int token_instance_num);
#endif
+94 −12
Original line number Diff line number Diff line
@@ -47,6 +47,100 @@
/* size of tplg abi in byte */
#define SOF_TPLG_ABI_SIZE 3

/**
 * sof_update_ipc_object - Parse multiple sets of tokens within the token array associated with the
 *			    token ID.
 * @scomp: pointer to SOC component
 * @object: target IPC struct to save the parsed values
 * @token_id: token ID for the token array to be searched
 * @tuples: pointer to the tuples array
 * @num_tuples: number of tuples in the tuples array
 * @object_size: size of the object
 * @token_instance_num: number of times the same @token_id needs to be parsed i.e. the function
 *			looks for @token_instance_num of each token in the token array associated
 *			with the @token_id
 */
int sof_update_ipc_object(struct snd_soc_component *scomp, void *object, enum sof_tokens token_id,
			  struct snd_sof_tuple *tuples, int num_tuples,
			  size_t object_size, int token_instance_num)
{
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
	const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
	const struct sof_token_info *token_list = ipc_tplg_ops->token_list;
	const struct sof_topology_token *tokens;
	int i, j;

	if (token_list[token_id].count < 0) {
		dev_err(scomp->dev, "Invalid token count for token ID: %d\n", token_id);
		return -EINVAL;
	}

	/* No tokens to match */
	if (!token_list[token_id].count)
		return 0;

	tokens = token_list[token_id].tokens;
	if (!tokens) {
		dev_err(scomp->dev, "Invalid tokens for token id: %d\n", token_id);
		return -EINVAL;
	}

	for (i = 0; i < token_list[token_id].count; i++) {
		int offset = 0;
		int num_tokens_matched = 0;

		for (j = 0; j < num_tuples; j++) {
			if (tokens[i].token == tuples[j].token) {
				switch (tokens[i].type) {
				case SND_SOC_TPLG_TUPLE_TYPE_WORD:
				{
					u32 *val = (u32 *)((u8 *)object + tokens[i].offset +
							   offset);

					*val = tuples[j].value.v;
					break;
				}
				case SND_SOC_TPLG_TUPLE_TYPE_SHORT:
				case SND_SOC_TPLG_TUPLE_TYPE_BOOL:
				{
					u16 *val = (u16 *)((u8 *)object + tokens[i].offset +
							    offset);

					*val = (u16)tuples[j].value.v;
					break;
				}
				case SND_SOC_TPLG_TUPLE_TYPE_STRING:
				{
					if (!tokens[i].get_token) {
						dev_err(scomp->dev,
							"get_token not defined for token %d in %s\n",
							tokens[i].token, token_list[token_id].name);
						return -EINVAL;
					}

					tokens[i].get_token((void *)tuples[j].value.s, object,
							    tokens[i].offset + offset);
					break;
				}
				default:
					break;
				}

				num_tokens_matched++;

				/* found all required sets of current token. Move to the next one */
				if (!(num_tokens_matched % token_instance_num))
					break;

				/* move to the next object */
				offset += object_size;
			}
		}
	}

	return 0;
}

struct sof_widget_data {
	int ctrl_type;
	int ipc_cmd;
@@ -465,18 +559,6 @@ static enum sof_comp_type find_process_comp_type(enum sof_ipc_process_type type)
	return SOF_COMP_NONE;
}

/*
 * Topology Token Parsing.
 * New tokens should be added to headers and parsing tables below.
 */

struct sof_topology_token {
	u32 token;
	u32 type;
	int (*get_token)(void *elem, void *object, u32 offset);
	u32 offset;
};

int get_token_u32(void *elem, void *object, u32 offset)
{
	struct snd_soc_tplg_vendor_value_elem *velem = elem;