Blame src/topology/parser.c

Packit 4a16fb
/*
Packit 4a16fb
  Copyright(c) 2014-2015 Intel Corporation
Packit 4a16fb
  All rights reserved.
Packit 4a16fb
Packit 4a16fb
  This library is free software; you can redistribute it and/or modify
Packit 4a16fb
  it under the terms of the GNU Lesser General Public License as
Packit 4a16fb
  published by the Free Software Foundation; either version 2.1 of
Packit 4a16fb
  the License, or (at your option) any later version.
Packit 4a16fb
Packit 4a16fb
  This program is distributed in the hope that it will be useful,
Packit 4a16fb
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 4a16fb
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 4a16fb
  GNU Lesser General Public License for more details.
Packit 4a16fb
Packit 4a16fb
  Authors: Mengdong Lin <mengdong.lin@intel.com>
Packit 4a16fb
           Yao Jin <yao.jin@intel.com>
Packit 4a16fb
           Liam Girdwood <liam.r.girdwood@linux.intel.com>
Packit 4a16fb
*/
Packit 4a16fb
Packit 4a16fb
#include <sys/stat.h>
Packit 4a16fb
#include "list.h"
Packit 4a16fb
#include "tplg_local.h"
Packit 4a16fb
Packit 4a16fb
/*
Packit 4a16fb
 * Parse compound
Packit 4a16fb
 */
Packit 4a16fb
int tplg_parse_compound(snd_tplg_t *tplg, snd_config_t *cfg,
Packit 4a16fb
	int (*fcn)(snd_tplg_t *, snd_config_t *, void *),
Packit 4a16fb
	void *private)
Packit 4a16fb
{
Packit 4a16fb
	const char *id;
Packit 4a16fb
	snd_config_iterator_t i, next;
Packit 4a16fb
	snd_config_t *n;
Packit 4a16fb
	int err = -EINVAL;
Packit 4a16fb
Packit 4a16fb
	if (snd_config_get_id(cfg, &id) < 0)
Packit 4a16fb
		return -EINVAL;
Packit 4a16fb
Packit 4a16fb
	if (snd_config_get_type(cfg) != SND_CONFIG_TYPE_COMPOUND) {
Packit 4a16fb
		SNDERR("error: compound type expected for %s", id);
Packit 4a16fb
		return -EINVAL;
Packit 4a16fb
	}
Packit 4a16fb
Packit 4a16fb
	/* parse compound */
Packit 4a16fb
	snd_config_for_each(i, next, cfg) {
Packit 4a16fb
		n = snd_config_iterator_entry(i);
Packit 4a16fb
Packit 4a16fb
		if (snd_config_get_type(cfg) != SND_CONFIG_TYPE_COMPOUND) {
Packit 4a16fb
			SNDERR("error: compound type expected for %s, is %d",
Packit 4a16fb
				id, snd_config_get_type(cfg));
Packit 4a16fb
			return -EINVAL;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		err = fcn(tplg, n, private);
Packit 4a16fb
		if (err < 0)
Packit 4a16fb
			return err;
Packit 4a16fb
	}
Packit 4a16fb
Packit 4a16fb
	return err;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
static int tplg_parse_config(snd_tplg_t *tplg, snd_config_t *cfg)
Packit 4a16fb
{
Packit 4a16fb
	snd_config_iterator_t i, next;
Packit 4a16fb
	snd_config_t *n;
Packit 4a16fb
	const char *id;
Packit 4a16fb
	int err;
Packit 4a16fb
Packit 4a16fb
	if (snd_config_get_type(cfg) != SND_CONFIG_TYPE_COMPOUND) {
Packit 4a16fb
		SNDERR("error: compound type expected at top level");
Packit 4a16fb
		return -EINVAL;
Packit 4a16fb
	}
Packit 4a16fb
Packit 4a16fb
	/* parse topology config sections */
Packit 4a16fb
	snd_config_for_each(i, next, cfg) {
Packit 4a16fb
Packit 4a16fb
		n = snd_config_iterator_entry(i);
Packit 4a16fb
		if (snd_config_get_id(n, &id) < 0)
Packit 4a16fb
			continue;
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionTLV") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n, tplg_parse_tlv,
Packit 4a16fb
				NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionControlMixer") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n,
Packit 4a16fb
				tplg_parse_control_mixer, NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionControlEnum") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n,
Packit 4a16fb
				tplg_parse_control_enum, NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionControlBytes") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n,
Packit 4a16fb
				tplg_parse_control_bytes, NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionWidget") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n,
Packit 4a16fb
				tplg_parse_dapm_widget, NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionPCMCapabilities") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n,
Packit 4a16fb
				tplg_parse_stream_caps, NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionPCM") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n,
Packit 4a16fb
				tplg_parse_pcm, NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionDAI") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n,
Packit 4a16fb
				tplg_parse_dai, NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionHWConfig") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n, tplg_parse_hw_config,
Packit 4a16fb
				NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionLink") == 0
Packit 4a16fb
			|| strcmp(id, "SectionBE") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n, tplg_parse_link,
Packit 4a16fb
				NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionCC") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n, tplg_parse_cc,
Packit 4a16fb
				NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionGraph") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n,
Packit 4a16fb
				tplg_parse_dapm_graph, NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionText") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n, tplg_parse_text,
Packit 4a16fb
				NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionData") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n, tplg_parse_data,
Packit 4a16fb
				NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionVendorTokens") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n, tplg_parse_tokens,
Packit 4a16fb
				NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionVendorTuples") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n, tplg_parse_tuples,
Packit 4a16fb
				NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		if (strcmp(id, "SectionManifest") == 0) {
Packit 4a16fb
			err = tplg_parse_compound(tplg, n,
Packit 4a16fb
						  tplg_parse_manifest_data,
Packit 4a16fb
				NULL);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
			continue;
Packit 4a16fb
		}
Packit 4a16fb
Packit 4a16fb
		SNDERR("error: unknown section %s\n", id);
Packit 4a16fb
	}
Packit 4a16fb
	return 0;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
static int tplg_load_config(const char *file, snd_config_t **cfg)
Packit 4a16fb
{
Packit 4a16fb
	FILE *fp;
Packit 4a16fb
	snd_input_t *in;
Packit 4a16fb
	snd_config_t *top;
Packit 4a16fb
	int ret;
Packit 4a16fb
Packit 4a16fb
	fp = fopen(file, "r");
Packit 4a16fb
	if (fp == NULL) {
Packit 4a16fb
		SNDERR("error: could not open configuration file %s",
Packit 4a16fb
			file);
Packit 4a16fb
		return -errno;
Packit 4a16fb
	}
Packit 4a16fb
Packit 4a16fb
	ret = snd_input_stdio_attach(&in, fp, 1);
Packit 4a16fb
	if (ret < 0) {
Packit 4a16fb
		fclose(fp);
Packit 4a16fb
		SNDERR("error: could not attach stdio %s", file);
Packit 4a16fb
		return ret;
Packit 4a16fb
	}
Packit 4a16fb
	ret = snd_config_top(&top);
Packit 4a16fb
	if (ret < 0)
Packit 4a16fb
		goto err;
Packit 4a16fb
Packit 4a16fb
	ret = snd_config_load(top, in);
Packit 4a16fb
	if (ret < 0) {
Packit 4a16fb
		SNDERR("error: could not load configuration file %s",
Packit 4a16fb
			file);
Packit 4a16fb
		goto err_load;
Packit 4a16fb
	}
Packit 4a16fb
Packit 4a16fb
	ret = snd_input_close(in);
Packit 4a16fb
	if (ret < 0) {
Packit 4a16fb
		in = NULL;
Packit 4a16fb
		goto err_load;
Packit 4a16fb
	}
Packit 4a16fb
Packit 4a16fb
	*cfg = top;
Packit 4a16fb
	return 0;
Packit 4a16fb
Packit 4a16fb
err_load:
Packit 4a16fb
	snd_config_delete(top);
Packit 4a16fb
err:
Packit 4a16fb
	if (in)
Packit 4a16fb
		snd_input_close(in);
Packit 4a16fb
	return ret;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
static int tplg_build_integ(snd_tplg_t *tplg)
Packit 4a16fb
{
Packit 4a16fb
	int err;
Packit 4a16fb
Packit 4a16fb
	err = tplg_build_data(tplg);
Packit 4a16fb
	if (err <  0)
Packit 4a16fb
		return err;
Packit 4a16fb
Packit 4a16fb
	err = tplg_build_manifest_data(tplg);
Packit 4a16fb
	if (err <  0)
Packit 4a16fb
		return err;
Packit 4a16fb
Packit 4a16fb
	err = tplg_build_controls(tplg);
Packit 4a16fb
	if (err <  0)
Packit 4a16fb
		return err;
Packit 4a16fb
Packit 4a16fb
	err = tplg_build_widgets(tplg);
Packit 4a16fb
	if (err <  0)
Packit 4a16fb
		return err;
Packit 4a16fb
Packit 4a16fb
	err = tplg_build_pcms(tplg, SND_TPLG_TYPE_PCM);
Packit 4a16fb
	if (err <  0)
Packit 4a16fb
		return err;
Packit 4a16fb
Packit 4a16fb
	err = tplg_build_dais(tplg, SND_TPLG_TYPE_DAI);
Packit 4a16fb
	if (err <  0)
Packit 4a16fb
		return err;
Packit 4a16fb
Packit 4a16fb
	err = tplg_build_links(tplg, SND_TPLG_TYPE_BE);
Packit 4a16fb
	if (err <  0)
Packit 4a16fb
		return err;
Packit 4a16fb
Packit 4a16fb
	err = tplg_build_links(tplg, SND_TPLG_TYPE_CC);
Packit 4a16fb
	if (err <  0)
Packit 4a16fb
		return err;
Packit 4a16fb
Packit 4a16fb
	err = tplg_build_routes(tplg);
Packit 4a16fb
	if (err <  0)
Packit 4a16fb
		return err;
Packit 4a16fb
Packit 4a16fb
	return err;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
int snd_tplg_build_file(snd_tplg_t *tplg, const char *infile,
Packit 4a16fb
	const char *outfile)
Packit 4a16fb
{
Packit 4a16fb
	snd_config_t *cfg = NULL;
Packit 4a16fb
	int err = 0;
Packit 4a16fb
Packit 4a16fb
	tplg->out_fd =
Packit 4a16fb
		open(outfile, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
Packit 4a16fb
	if (tplg->out_fd < 0) {
Packit 4a16fb
		SNDERR("error: failed to open %s err %d\n",
Packit 4a16fb
			outfile, -errno);
Packit 4a16fb
		return -errno;
Packit 4a16fb
	}
Packit 4a16fb
Packit 4a16fb
	err = tplg_load_config(infile, &cfg;;
Packit 4a16fb
	if (err < 0) {
Packit 4a16fb
		SNDERR("error: failed to load topology file %s\n",
Packit 4a16fb
			infile);
Packit 4a16fb
		goto out_close;
Packit 4a16fb
	}
Packit 4a16fb
Packit 4a16fb
	err = tplg_parse_config(tplg, cfg);
Packit 4a16fb
	if (err < 0) {
Packit 4a16fb
		SNDERR("error: failed to parse topology\n");
Packit 4a16fb
		goto out;
Packit 4a16fb
	}
Packit 4a16fb
Packit 4a16fb
	err = tplg_build_integ(tplg);
Packit 4a16fb
	if (err < 0) {
Packit 4a16fb
		SNDERR("error: failed to check topology integrity\n");
Packit 4a16fb
		goto out;
Packit 4a16fb
	}
Packit 4a16fb
Packit 4a16fb
	err = tplg_write_data(tplg);
Packit 4a16fb
	if (err < 0) {
Packit 4a16fb
		SNDERR("error: failed to write data %d\n", err);
Packit 4a16fb
		goto out;
Packit 4a16fb
	}
Packit 4a16fb
Packit 4a16fb
out:
Packit 4a16fb
	snd_config_delete(cfg);
Packit 4a16fb
out_close:
Packit 4a16fb
	close(tplg->out_fd);
Packit 4a16fb
	return err;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
int snd_tplg_add_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t)
Packit 4a16fb
{
Packit 4a16fb
	switch (t->type) {
Packit 4a16fb
	case SND_TPLG_TYPE_MIXER:
Packit 4a16fb
		return tplg_add_mixer_object(tplg, t);
Packit 4a16fb
	case SND_TPLG_TYPE_ENUM:
Packit 4a16fb
		return tplg_add_enum_object(tplg, t);
Packit 4a16fb
	case SND_TPLG_TYPE_BYTES:
Packit 4a16fb
		return tplg_add_bytes_object(tplg, t);
Packit 4a16fb
	case SND_TPLG_TYPE_DAPM_WIDGET:
Packit 4a16fb
		return tplg_add_widget_object(tplg, t);
Packit 4a16fb
	case SND_TPLG_TYPE_DAPM_GRAPH:
Packit 4a16fb
		return tplg_add_graph_object(tplg, t);
Packit 4a16fb
	case SND_TPLG_TYPE_PCM:
Packit 4a16fb
		return tplg_add_pcm_object(tplg, t);
Packit 4a16fb
	case SND_TPLG_TYPE_DAI:
Packit 4a16fb
		return tplg_add_dai_object(tplg, t);
Packit 4a16fb
	case SND_TPLG_TYPE_LINK:
Packit 4a16fb
	case SND_TPLG_TYPE_BE:
Packit 4a16fb
	case SND_TPLG_TYPE_CC:
Packit 4a16fb
		return tplg_add_link_object(tplg, t);
Packit 4a16fb
	default:
Packit 4a16fb
		SNDERR("error: invalid object type %d\n", t->type);
Packit 4a16fb
		return -EINVAL;
Packit 4a16fb
	};
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
int snd_tplg_build(snd_tplg_t *tplg, const char *outfile)
Packit 4a16fb
{
Packit 4a16fb
	int err;
Packit 4a16fb
Packit 4a16fb
	tplg->out_fd =
Packit 4a16fb
		open(outfile, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
Packit 4a16fb
	if (tplg->out_fd < 0) {
Packit 4a16fb
		SNDERR("error: failed to open %s err %d\n",
Packit 4a16fb
			outfile, -errno);
Packit 4a16fb
		return -errno;
Packit 4a16fb
	}
Packit 4a16fb
Packit 4a16fb
	err = tplg_build_integ(tplg);
Packit 4a16fb
	if (err < 0) {
Packit 4a16fb
		SNDERR("error: failed to check topology integrity\n");
Packit 4a16fb
		goto out;
Packit 4a16fb
	}
Packit 4a16fb
Packit 4a16fb
	err = tplg_write_data(tplg);
Packit 4a16fb
	if (err < 0) {
Packit 4a16fb
		SNDERR("error: failed to write data %d\n", err);
Packit 4a16fb
		goto out;
Packit 4a16fb
	}
Packit 4a16fb
Packit 4a16fb
out:
Packit 4a16fb
	close(tplg->out_fd);
Packit 4a16fb
	return err;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
int snd_tplg_set_manifest_data(snd_tplg_t *tplg, const void *data, int len)
Packit 4a16fb
{
Packit 4a16fb
	if (len <= 0)
Packit 4a16fb
		return 0;
Packit 4a16fb
Packit 4a16fb
	tplg->manifest.priv.size = len;
Packit 4a16fb
Packit 4a16fb
	tplg->manifest_pdata = malloc(len);
Packit 4a16fb
	if (!tplg->manifest_pdata)
Packit 4a16fb
		return -ENOMEM;
Packit 4a16fb
Packit 4a16fb
	memcpy(tplg->manifest_pdata, data, len);
Packit 4a16fb
	return 0;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
int snd_tplg_set_version(snd_tplg_t *tplg, unsigned int version)
Packit 4a16fb
{
Packit 4a16fb
	tplg->version = version;
Packit 4a16fb
Packit 4a16fb
	return 0;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
void snd_tplg_verbose(snd_tplg_t *tplg, int verbose)
Packit 4a16fb
{
Packit 4a16fb
	tplg->verbose = verbose;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
static bool is_little_endian(void)
Packit 4a16fb
{
Packit 4a16fb
#ifdef __BYTE_ORDER
Packit 4a16fb
	#if __BYTE_ORDER == __LITTLE_ENDIAN
Packit 4a16fb
		return true;
Packit 4a16fb
	#endif
Packit 4a16fb
#endif
Packit 4a16fb
	return false;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
snd_tplg_t *snd_tplg_new(void)
Packit 4a16fb
{
Packit 4a16fb
	snd_tplg_t *tplg;
Packit 4a16fb
Packit 4a16fb
	if (!is_little_endian()) {
Packit 4a16fb
		SNDERR("error: cannot support big-endian machines\n");
Packit 4a16fb
		return NULL;
Packit 4a16fb
	}
Packit 4a16fb
Packit 4a16fb
	tplg = calloc(1, sizeof(snd_tplg_t));
Packit 4a16fb
	if (!tplg)
Packit 4a16fb
		return NULL;
Packit 4a16fb
Packit 4a16fb
	tplg->manifest.size = sizeof(struct snd_soc_tplg_manifest);
Packit 4a16fb
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->tlv_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->widget_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->pcm_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->dai_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->be_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->cc_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->route_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->pdata_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->manifest_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->text_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->pcm_config_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->pcm_caps_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->mixer_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->enum_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->bytes_ext_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->token_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->tuple_list);
Packit 4a16fb
	INIT_LIST_HEAD(&tplg->hw_cfg_list);
Packit 4a16fb
Packit 4a16fb
	return tplg;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
void snd_tplg_free(snd_tplg_t *tplg)
Packit 4a16fb
{
Packit 4a16fb
	if (tplg->manifest_pdata)
Packit 4a16fb
		free(tplg->manifest_pdata);
Packit 4a16fb
Packit 4a16fb
	tplg_elem_free_list(&tplg->tlv_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->widget_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->pcm_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->dai_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->be_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->cc_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->route_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->pdata_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->manifest_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->text_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->pcm_config_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->pcm_caps_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->mixer_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->enum_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->bytes_ext_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->token_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->tuple_list);
Packit 4a16fb
	tplg_elem_free_list(&tplg->hw_cfg_list);
Packit 4a16fb
Packit 4a16fb
	free(tplg);
Packit 4a16fb
}