Blame src/topology/parser.c

Packit Service db8eaa
/*
Packit Service db8eaa
  Copyright(c) 2014-2015 Intel Corporation
Packit Service db8eaa
  All rights reserved.
Packit Service db8eaa
Packit Service db8eaa
  This library is free software; you can redistribute it and/or modify
Packit Service db8eaa
  it under the terms of the GNU Lesser General Public License as
Packit Service db8eaa
  published by the Free Software Foundation; either version 2.1 of
Packit Service db8eaa
  the License, or (at your option) any later version.
Packit Service db8eaa
Packit Service db8eaa
  This program is distributed in the hope that it will be useful,
Packit Service db8eaa
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service db8eaa
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service db8eaa
  GNU Lesser General Public License for more details.
Packit Service db8eaa
Packit Service db8eaa
  Authors: Mengdong Lin <mengdong.lin@intel.com>
Packit Service db8eaa
           Yao Jin <yao.jin@intel.com>
Packit Service db8eaa
           Liam Girdwood <liam.r.girdwood@linux.intel.com>
Packit Service db8eaa
*/
Packit Service db8eaa
Packit Service db8eaa
#include <sys/stat.h>
Packit Service db8eaa
#include "list.h"
Packit Service db8eaa
#include "tplg_local.h"
Packit Service db8eaa
Packit Service db8eaa
/*
Packit Service db8eaa
 * Get integer value
Packit Service db8eaa
 */
Packit Service db8eaa
int tplg_get_integer(snd_config_t *n, int *val, int base)
Packit Service db8eaa
{
Packit Service db8eaa
	const char *str;
Packit Service db8eaa
	long lval;
Packit Service db8eaa
	int err;
Packit Service db8eaa
Packit Service db8eaa
	switch (snd_config_get_type(n)) {
Packit Service db8eaa
	case SND_CONFIG_TYPE_INTEGER:
Packit Service db8eaa
		err = snd_config_get_integer(n, &lval);
Packit Service db8eaa
		if (err < 0)
Packit Service db8eaa
			return err;
Packit Service db8eaa
		if (lval < INT_MIN || lval > INT_MAX)
Packit Service db8eaa
			return -ERANGE;
Packit Service db8eaa
		*val = lval;
Packit Service db8eaa
		return err;
Packit Service db8eaa
	case SND_CONFIG_TYPE_STRING:
Packit Service db8eaa
		err = snd_config_get_string(n, &str);
Packit Service db8eaa
		if (err < 0)
Packit Service db8eaa
			return err;
Packit Service db8eaa
		errno = 0;
Packit Service db8eaa
		*val = strtol(str, NULL, base);
Packit Service db8eaa
		if (errno == ERANGE)
Packit Service db8eaa
			return -ERANGE;
Packit Service db8eaa
		if (errno && *val == 0)
Packit Service db8eaa
			return -EINVAL;
Packit Service db8eaa
		return 0;
Packit Service db8eaa
	default:
Packit Service db8eaa
		return -EINVAL;
Packit Service db8eaa
	}
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
/*
Packit Service db8eaa
 * Get unsigned integer value
Packit Service db8eaa
 */
Packit Service db8eaa
int tplg_get_unsigned(snd_config_t *n, unsigned *val, int base)
Packit Service db8eaa
{
Packit Service db8eaa
	const char *str;
Packit Service db8eaa
	long lval;
Packit Service db8eaa
	long long llval;
Packit Service db8eaa
	unsigned long uval;
Packit Service db8eaa
	int err;
Packit Service db8eaa
Packit Service db8eaa
	switch (snd_config_get_type(n)) {
Packit Service db8eaa
	case SND_CONFIG_TYPE_INTEGER:
Packit Service db8eaa
		err = snd_config_get_integer(n, &lval);
Packit Service db8eaa
		if (err < 0)
Packit Service db8eaa
			return err;
Packit Service db8eaa
		if (lval < 0 && lval >= INT_MIN)
Packit Service db8eaa
			lval = UINT_MAX + lval + 1;
Packit Service db8eaa
		if (lval < 0 || lval > UINT_MAX)
Packit Service db8eaa
			return -ERANGE;
Packit Service db8eaa
		*val = lval;
Packit Service db8eaa
		return err;
Packit Service db8eaa
	case SND_CONFIG_TYPE_INTEGER64:
Packit Service db8eaa
		err = snd_config_get_integer64(n, &llval);
Packit Service db8eaa
		if (err < 0)
Packit Service db8eaa
			return err;
Packit Service db8eaa
		if (llval < 0 && llval >= INT_MIN)
Packit Service db8eaa
			llval = UINT_MAX + llval + 1;
Packit Service db8eaa
		if (llval < 0 || llval > UINT_MAX)
Packit Service db8eaa
			return -ERANGE;
Packit Service db8eaa
		*val = llval;
Packit Service db8eaa
		return err;
Packit Service db8eaa
	case SND_CONFIG_TYPE_STRING:
Packit Service db8eaa
		err = snd_config_get_string(n, &str);
Packit Service db8eaa
		if (err < 0)
Packit Service db8eaa
			return err;
Packit Service db8eaa
		errno = 0;
Packit Service db8eaa
		uval = strtoul(str, NULL, base);
Packit Service db8eaa
		if (errno == ERANGE && uval == ULONG_MAX)
Packit Service db8eaa
			return -ERANGE;
Packit Service db8eaa
		if (errno && uval == 0)
Packit Service db8eaa
			return -EINVAL;
Packit Service db8eaa
		if (uval > UINT_MAX)
Packit Service db8eaa
			return -ERANGE;
Packit Service db8eaa
		*val = uval;
Packit Service db8eaa
		return 0;
Packit Service db8eaa
	default:
Packit Service db8eaa
		return -EINVAL;
Packit Service db8eaa
	}
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
/*
Packit Service db8eaa
 * Parse compound
Packit Service db8eaa
 */
Packit Service db8eaa
int tplg_parse_compound(snd_tplg_t *tplg, snd_config_t *cfg,
Packit Service db8eaa
			int (*fcn)(snd_tplg_t *, snd_config_t *, void *),
Packit Service db8eaa
			void *private)
Packit Service db8eaa
{
Packit Service db8eaa
	const char *id;
Packit Service db8eaa
	snd_config_iterator_t i, next;
Packit Service db8eaa
	snd_config_t *n;
Packit Service db8eaa
	int err = -EINVAL;
Packit Service db8eaa
Packit Service db8eaa
	if (snd_config_get_id(cfg, &id) < 0)
Packit Service db8eaa
		return -EINVAL;
Packit Service db8eaa
Packit Service db8eaa
	if (snd_config_get_type(cfg) != SND_CONFIG_TYPE_COMPOUND) {
Packit Service db8eaa
		SNDERR("compound type expected for %s", id);
Packit Service db8eaa
		return -EINVAL;
Packit Service db8eaa
	}
Packit Service db8eaa
Packit Service db8eaa
	/* parse compound */
Packit Service db8eaa
	snd_config_for_each(i, next, cfg) {
Packit Service db8eaa
		n = snd_config_iterator_entry(i);
Packit Service db8eaa
Packit Service db8eaa
		if (snd_config_get_type(cfg) != SND_CONFIG_TYPE_COMPOUND) {
Packit Service db8eaa
			SNDERR("compound type expected for %s, is %d",
Packit Service db8eaa
				id, snd_config_get_type(cfg));
Packit Service db8eaa
			return -EINVAL;
Packit Service db8eaa
		}
Packit Service db8eaa
Packit Service db8eaa
		err = fcn(tplg, n, private);
Packit Service db8eaa
		if (err < 0)
Packit Service db8eaa
			return err;
Packit Service db8eaa
	}
Packit Service db8eaa
Packit Service db8eaa
	return err;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int tplg_parse_config(snd_tplg_t *tplg, snd_config_t *cfg)
Packit Service db8eaa
{
Packit Service db8eaa
	int (*parser)(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
Packit Service db8eaa
	snd_config_iterator_t i, next;
Packit Service db8eaa
	snd_config_t *n;
Packit Service db8eaa
	const char *id;
Packit Service db8eaa
	struct tplg_table *p;
Packit Service db8eaa
	unsigned int idx;
Packit Service db8eaa
	int err;
Packit Service db8eaa
Packit Service db8eaa
	if (snd_config_get_type(cfg) != SND_CONFIG_TYPE_COMPOUND) {
Packit Service db8eaa
		SNDERR("compound type expected at top level");
Packit Service db8eaa
		return -EINVAL;
Packit Service db8eaa
	}
Packit Service db8eaa
Packit Service db8eaa
	/* parse topology config sections */
Packit Service db8eaa
	snd_config_for_each(i, next, cfg) {
Packit Service db8eaa
Packit Service db8eaa
		n = snd_config_iterator_entry(i);
Packit Service db8eaa
		if (snd_config_get_id(n, &id) < 0)
Packit Service db8eaa
			continue;
Packit Service db8eaa
Packit Service db8eaa
		parser = NULL;
Packit Service db8eaa
		for (idx = 0; idx < tplg_table_items; idx++) {
Packit Service db8eaa
			p = &tplg_table[idx];
Packit Service db8eaa
			if (p->id && strcmp(id, p->id) == 0) {
Packit Service db8eaa
				parser = p->parse;
Packit Service db8eaa
				break;
Packit Service db8eaa
			}
Packit Service db8eaa
			if (p->id2 && strcmp(id, p->id2) == 0) {
Packit Service db8eaa
				parser = p->parse;
Packit Service db8eaa
				break;
Packit Service db8eaa
			}
Packit Service db8eaa
		}
Packit Service db8eaa
Packit Service db8eaa
		if (parser == NULL) {
Packit Service db8eaa
			SNDERR("unknown section %s", id);
Packit Service db8eaa
			continue;
Packit Service db8eaa
		}
Packit Service db8eaa
Packit Service db8eaa
		err = tplg_parse_compound(tplg, n, parser, NULL);
Packit Service db8eaa
		if (err < 0)
Packit Service db8eaa
			return err;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int tplg_load_config(snd_tplg_t *tplg, snd_input_t *in)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_config_t *top;
Packit Service db8eaa
	int ret;
Packit Service db8eaa
Packit Service db8eaa
	ret = snd_config_top(&top);
Packit Service db8eaa
	if (ret < 0)
Packit Service db8eaa
		return ret;
Packit Service db8eaa
Packit Service db8eaa
	ret = snd_config_load(top, in);
Packit Service db8eaa
	if (ret < 0) {
Packit Service db8eaa
		SNDERR("could not load configuration");
Packit Service db8eaa
		snd_config_delete(top);
Packit Service db8eaa
		return ret;
Packit Service db8eaa
	}
Packit Service db8eaa
Packit Service db8eaa
	ret = tplg_parse_config(tplg, top);
Packit Service db8eaa
	snd_config_delete(top);
Packit Service db8eaa
	if (ret < 0) {
Packit Service db8eaa
		SNDERR("failed to parse topology");
Packit Service db8eaa
		return ret;
Packit Service db8eaa
	}
Packit Service db8eaa
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int tplg_build_integ(snd_tplg_t *tplg)
Packit Service db8eaa
{
Packit Service db8eaa
	int err;
Packit Service db8eaa
Packit Service db8eaa
	err = tplg_build_data(tplg);
Packit Service db8eaa
	if (err <  0)
Packit Service db8eaa
		return err;
Packit Service db8eaa
Packit Service db8eaa
	err = tplg_build_manifest_data(tplg);
Packit Service db8eaa
	if (err <  0)
Packit Service db8eaa
		return err;
Packit Service db8eaa
Packit Service db8eaa
	err = tplg_build_controls(tplg);
Packit Service db8eaa
	if (err <  0)
Packit Service db8eaa
		return err;
Packit Service db8eaa
Packit Service db8eaa
	err = tplg_build_widgets(tplg);
Packit Service db8eaa
	if (err <  0)
Packit Service db8eaa
		return err;
Packit Service db8eaa
Packit Service db8eaa
	err = tplg_build_pcms(tplg, SND_TPLG_TYPE_PCM);
Packit Service db8eaa
	if (err <  0)
Packit Service db8eaa
		return err;
Packit Service db8eaa
Packit Service db8eaa
	err = tplg_build_dais(tplg, SND_TPLG_TYPE_DAI);
Packit Service db8eaa
	if (err <  0)
Packit Service db8eaa
		return err;
Packit Service db8eaa
Packit Service db8eaa
	err = tplg_build_links(tplg, SND_TPLG_TYPE_BE);
Packit Service db8eaa
	if (err <  0)
Packit Service db8eaa
		return err;
Packit Service db8eaa
Packit Service db8eaa
	err = tplg_build_links(tplg, SND_TPLG_TYPE_CC);
Packit Service db8eaa
	if (err <  0)
Packit Service db8eaa
		return err;
Packit Service db8eaa
Packit Service db8eaa
	err = tplg_build_routes(tplg);
Packit Service db8eaa
	if (err <  0)
Packit Service db8eaa
		return err;
Packit Service db8eaa
Packit Service db8eaa
	return err;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
int snd_tplg_load(snd_tplg_t *tplg, const char *buf, size_t size)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_input_t *in;
Packit Service db8eaa
	int err;
Packit Service db8eaa
Packit Service db8eaa
	err = snd_input_buffer_open(&in, buf, size);
Packit Service db8eaa
	if (err < 0) {
Packit Service db8eaa
		SNDERR("could not create input buffer");
Packit Service db8eaa
		return err;
Packit Service db8eaa
	}
Packit Service db8eaa
Packit Service db8eaa
	err = tplg_load_config(tplg, in);
Packit Service db8eaa
	snd_input_close(in);
Packit Service db8eaa
	return err;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int tplg_build(snd_tplg_t *tplg)
Packit Service db8eaa
{
Packit Service db8eaa
	int err;
Packit Service db8eaa
Packit Service db8eaa
	err = tplg_build_integ(tplg);
Packit Service db8eaa
	if (err < 0) {
Packit Service db8eaa
		SNDERR("failed to check topology integrity");
Packit Service db8eaa
		return err;
Packit Service db8eaa
	}
Packit Service db8eaa
Packit Service db8eaa
	err = tplg_write_data(tplg);
Packit Service db8eaa
	if (err < 0) {
Packit Service db8eaa
		SNDERR("failed to write data %d", err);
Packit Service db8eaa
		return err;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
int snd_tplg_build_file(snd_tplg_t *tplg,
Packit Service db8eaa
			const char *infile,
Packit Service db8eaa
			const char *outfile)
Packit Service db8eaa
{
Packit Service db8eaa
	FILE *fp;
Packit Service db8eaa
	snd_input_t *in;
Packit Service db8eaa
	int err;
Packit Service db8eaa
Packit Service db8eaa
	fp = fopen(infile, "r");
Packit Service db8eaa
	if (fp == NULL) {
Packit Service db8eaa
		SNDERR("could not open configuration file %s", infile);
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
Packit Service db8eaa
	err = snd_input_stdio_attach(&in, fp, 1);
Packit Service db8eaa
	if (err < 0) {
Packit Service db8eaa
		fclose(fp);
Packit Service db8eaa
		SNDERR("could not attach stdio %s", infile);
Packit Service db8eaa
		return err;
Packit Service db8eaa
	}
Packit Service db8eaa
Packit Service db8eaa
	err = tplg_load_config(tplg, in);
Packit Service db8eaa
	snd_input_close(in);
Packit Service db8eaa
	if (err < 0)
Packit Service db8eaa
		return err;
Packit Service db8eaa
Packit Service db8eaa
	return snd_tplg_build(tplg, outfile);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
int snd_tplg_add_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t)
Packit Service db8eaa
{
Packit Service db8eaa
	switch (t->type) {
Packit Service db8eaa
	case SND_TPLG_TYPE_MIXER:
Packit Service db8eaa
		return tplg_add_mixer_object(tplg, t);
Packit Service db8eaa
	case SND_TPLG_TYPE_ENUM:
Packit Service db8eaa
		return tplg_add_enum_object(tplg, t);
Packit Service db8eaa
	case SND_TPLG_TYPE_BYTES:
Packit Service db8eaa
		return tplg_add_bytes_object(tplg, t);
Packit Service db8eaa
	case SND_TPLG_TYPE_DAPM_WIDGET:
Packit Service db8eaa
		return tplg_add_widget_object(tplg, t);
Packit Service db8eaa
	case SND_TPLG_TYPE_DAPM_GRAPH:
Packit Service db8eaa
		return tplg_add_graph_object(tplg, t);
Packit Service db8eaa
	case SND_TPLG_TYPE_PCM:
Packit Service db8eaa
		return tplg_add_pcm_object(tplg, t);
Packit Service db8eaa
	case SND_TPLG_TYPE_DAI:
Packit Service db8eaa
		return tplg_add_dai_object(tplg, t);
Packit Service db8eaa
	case SND_TPLG_TYPE_LINK:
Packit Service db8eaa
	case SND_TPLG_TYPE_BE:
Packit Service db8eaa
	case SND_TPLG_TYPE_CC:
Packit Service db8eaa
		return tplg_add_link_object(tplg, t);
Packit Service db8eaa
	default:
Packit Service db8eaa
		SNDERR("invalid object type %d", t->type);
Packit Service db8eaa
		return -EINVAL;
Packit Service db8eaa
	};
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
int snd_tplg_build(snd_tplg_t *tplg, const char *outfile)
Packit Service db8eaa
{
Packit Service db8eaa
	int fd, err;
Packit Service db8eaa
	ssize_t r;
Packit Service db8eaa
Packit Service db8eaa
	err = tplg_build(tplg);
Packit Service db8eaa
	if (err < 0)
Packit Service db8eaa
		return err;
Packit Service db8eaa
Packit Service db8eaa
	fd = open(outfile, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
Packit Service db8eaa
	if (fd < 0) {
Packit Service db8eaa
		SNDERR("failed to open %s err %d", outfile, -errno);
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	r = write(fd, tplg->bin, tplg->bin_size);
Packit Service db8eaa
	close(fd);
Packit Service db8eaa
	if (r < 0) {
Packit Service db8eaa
		err = -errno;
Packit Service db8eaa
		SNDERR("write error: %s", strerror(errno));
Packit Service db8eaa
		return err;
Packit Service db8eaa
	}
Packit Service db8eaa
	if ((size_t)r != tplg->bin_size) {
Packit Service db8eaa
		SNDERR("partial write (%zd != %zd)", r, tplg->bin_size);
Packit Service db8eaa
		return -EIO;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
int snd_tplg_build_bin(snd_tplg_t *tplg,
Packit Service db8eaa
		       void **bin, size_t *size)
Packit Service db8eaa
{
Packit Service db8eaa
	int err;
Packit Service db8eaa
Packit Service db8eaa
	err = tplg_build(tplg);
Packit Service db8eaa
	if (err < 0)
Packit Service db8eaa
		return err;
Packit Service db8eaa
Packit Service db8eaa
	*bin = tplg->bin;
Packit Service db8eaa
	*size = tplg->bin_size;
Packit Service db8eaa
	tplg->bin = NULL;
Packit Service db8eaa
	tplg->bin_size = tplg->bin_pos = 0;
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
int snd_tplg_set_manifest_data(snd_tplg_t *tplg, const void *data, int len)
Packit Service db8eaa
{
Packit Service db8eaa
	struct tplg_elem *elem;
Packit Service db8eaa
Packit Service db8eaa
	elem = tplg_elem_type_lookup(tplg, SND_TPLG_TYPE_MANIFEST);
Packit Service db8eaa
	if (elem == NULL) {
Packit Service db8eaa
		elem = tplg_elem_new_common(tplg, NULL, "manifest",
Packit Service db8eaa
					    SND_TPLG_TYPE_MANIFEST);
Packit Service db8eaa
		if (!elem)
Packit Service db8eaa
			return -ENOMEM;
Packit Service db8eaa
		tplg->manifest.size = elem->size;
Packit Service db8eaa
	}
Packit Service db8eaa
Packit Service db8eaa
	if (len <= 0)
Packit Service db8eaa
		return 0;
Packit Service db8eaa
Packit Service db8eaa
	return tplg_add_data_bytes(tplg, elem, NULL, data, len);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
int snd_tplg_set_version(snd_tplg_t *tplg, unsigned int version)
Packit Service db8eaa
{
Packit Service db8eaa
	tplg->version = version;
Packit Service db8eaa
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
void snd_tplg_verbose(snd_tplg_t *tplg, int verbose)
Packit Service db8eaa
{
Packit Service db8eaa
	tplg->verbose = verbose;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static bool is_little_endian(void)
Packit Service db8eaa
{
Packit Service db8eaa
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_INT__ == 4
Packit Service db8eaa
	return true;
Packit Service db8eaa
#endif
Packit Service db8eaa
	return false;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
snd_tplg_t *snd_tplg_create(int flags)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_tplg_t *tplg;
Packit Service db8eaa
Packit Service db8eaa
	if (!is_little_endian()) {
Packit Service db8eaa
		SNDERR("cannot support big-endian machines");
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
Packit Service db8eaa
	tplg = calloc(1, sizeof(snd_tplg_t));
Packit Service db8eaa
	if (!tplg)
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
Packit Service db8eaa
	tplg->verbose = !!(flags & SND_TPLG_CREATE_VERBOSE);
Packit Service db8eaa
	tplg->dapm_sort = (flags & SND_TPLG_CREATE_DAPM_NOSORT) == 0;
Packit Service db8eaa
Packit Service db8eaa
	tplg->manifest.size = sizeof(struct snd_soc_tplg_manifest);
Packit Service db8eaa
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->tlv_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->widget_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->pcm_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->dai_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->be_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->cc_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->route_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->pdata_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->manifest_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->text_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->pcm_config_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->pcm_caps_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->mixer_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->enum_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->bytes_ext_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->token_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->tuple_list);
Packit Service db8eaa
	INIT_LIST_HEAD(&tplg->hw_cfg_list);
Packit Service db8eaa
Packit Service db8eaa
	return tplg;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
snd_tplg_t *snd_tplg_new(void)
Packit Service db8eaa
{
Packit Service db8eaa
	return snd_tplg_create(0);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
void snd_tplg_free(snd_tplg_t *tplg)
Packit Service db8eaa
{
Packit Service db8eaa
	free(tplg->bin);
Packit Service db8eaa
	free(tplg->manifest_pdata);
Packit Service db8eaa
Packit Service db8eaa
	tplg_elem_free_list(&tplg->tlv_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->widget_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->pcm_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->dai_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->be_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->cc_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->route_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->pdata_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->manifest_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->text_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->pcm_config_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->pcm_caps_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->mixer_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->enum_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->bytes_ext_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->token_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->tuple_list);
Packit Service db8eaa
	tplg_elem_free_list(&tplg->hw_cfg_list);
Packit Service db8eaa
Packit Service db8eaa
	free(tplg);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
const char *snd_tplg_version(void)
Packit Service db8eaa
{
Packit Service db8eaa
	return SND_LIB_VERSION_STR;
Packit Service db8eaa
}