|
Packit |
4a16fb |
/*
|
|
Packit |
4a16fb |
* This library is free software; you can redistribute it and/or
|
|
Packit |
4a16fb |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
4a16fb |
* License as published by the Free Software Foundation; either
|
|
Packit |
4a16fb |
* version 2 of the License, or (at your option) any later version.
|
|
Packit |
4a16fb |
*
|
|
Packit |
4a16fb |
* This library 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 GNU
|
|
Packit |
4a16fb |
* Lesser General Public License for more details.
|
|
Packit |
4a16fb |
*/
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#include <limits.h>
|
|
Packit |
4a16fb |
#include <stdint.h>
|
|
Packit |
4a16fb |
#include <stdbool.h>
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#include "local.h"
|
|
Packit |
4a16fb |
#include "list.h"
|
|
Packit |
4a16fb |
#include "topology.h"
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#define __packed __attribute__((__packed__))
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#include <sound/asound.h>
|
|
Packit |
4a16fb |
#include <sound/asoc.h>
|
|
Packit |
4a16fb |
#include <sound/tlv.h>
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#ifdef TPLG_DEBUG
|
|
Packit |
4a16fb |
#define tplg_dbg SNDERR
|
|
Packit |
4a16fb |
#else
|
|
Packit |
4a16fb |
#define tplg_dbg(fmt, arg...) do { } while (0)
|
|
Packit |
4a16fb |
#endif
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#define MAX_FILE 256
|
|
Packit |
4a16fb |
#define TPLG_MAX_PRIV_SIZE (1024 * 128)
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/** The name of the environment variable containing the tplg directory */
|
|
Packit |
4a16fb |
#define ALSA_CONFIG_TPLG_VAR "ALSA_CONFIG_TPLG"
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
struct tplg_ref;
|
|
Packit |
4a16fb |
struct tplg_elem;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
typedef enum _snd_pcm_rates {
|
|
Packit |
4a16fb |
SND_PCM_RATE_UNKNOWN = -1,
|
|
Packit |
4a16fb |
SND_PCM_RATE_5512 = 0,
|
|
Packit |
4a16fb |
SND_PCM_RATE_8000,
|
|
Packit |
4a16fb |
SND_PCM_RATE_11025,
|
|
Packit |
4a16fb |
SND_PCM_RATE_16000,
|
|
Packit |
4a16fb |
SND_PCM_RATE_22050,
|
|
Packit |
4a16fb |
SND_PCM_RATE_32000,
|
|
Packit |
4a16fb |
SND_PCM_RATE_44100,
|
|
Packit |
4a16fb |
SND_PCM_RATE_48000,
|
|
Packit |
4a16fb |
SND_PCM_RATE_64000,
|
|
Packit |
4a16fb |
SND_PCM_RATE_88200,
|
|
Packit |
4a16fb |
SND_PCM_RATE_96000,
|
|
Packit |
4a16fb |
SND_PCM_RATE_176400,
|
|
Packit |
4a16fb |
SND_PCM_RATE_192000,
|
|
Packit |
4a16fb |
SND_PCM_RATE_CONTINUOUS = 30,
|
|
Packit |
4a16fb |
SND_PCM_RATE_KNOT = 31,
|
|
Packit |
4a16fb |
SND_PCM_RATE_LAST = SND_PCM_RATE_KNOT,
|
|
Packit |
4a16fb |
} snd_pcm_rates_t;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
struct snd_tplg {
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* opaque vendor data */
|
|
Packit |
4a16fb |
int vendor_fd;
|
|
Packit |
4a16fb |
char *vendor_name;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* out file */
|
|
Packit |
4a16fb |
int out_fd;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int verbose;
|
|
Packit |
4a16fb |
unsigned int version;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* runtime state */
|
|
Packit |
4a16fb |
unsigned int next_hdr_pos;
|
|
Packit |
4a16fb |
int index;
|
|
Packit |
4a16fb |
int channel_idx;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* manifest */
|
|
Packit |
4a16fb |
struct snd_soc_tplg_manifest manifest;
|
|
Packit |
4a16fb |
void *manifest_pdata; /* copied by builder at file write */
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* list of each element type */
|
|
Packit |
4a16fb |
struct list_head tlv_list;
|
|
Packit |
4a16fb |
struct list_head widget_list;
|
|
Packit |
4a16fb |
struct list_head pcm_list;
|
|
Packit |
4a16fb |
struct list_head dai_list;
|
|
Packit |
4a16fb |
struct list_head be_list;
|
|
Packit |
4a16fb |
struct list_head cc_list;
|
|
Packit |
4a16fb |
struct list_head route_list;
|
|
Packit |
4a16fb |
struct list_head text_list;
|
|
Packit |
4a16fb |
struct list_head pdata_list;
|
|
Packit |
4a16fb |
struct list_head token_list;
|
|
Packit |
4a16fb |
struct list_head tuple_list;
|
|
Packit |
4a16fb |
struct list_head manifest_list;
|
|
Packit |
4a16fb |
struct list_head pcm_config_list;
|
|
Packit |
4a16fb |
struct list_head pcm_caps_list;
|
|
Packit |
4a16fb |
struct list_head hw_cfg_list;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* type-specific control lists */
|
|
Packit |
4a16fb |
struct list_head mixer_list;
|
|
Packit |
4a16fb |
struct list_head enum_list;
|
|
Packit |
4a16fb |
struct list_head bytes_ext_list;
|
|
Packit |
4a16fb |
};
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* object text references */
|
|
Packit |
4a16fb |
struct tplg_ref {
|
|
Packit |
4a16fb |
unsigned int type;
|
|
Packit |
4a16fb |
struct tplg_elem *elem;
|
|
Packit |
4a16fb |
char id[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
|
Packit |
4a16fb |
struct list_head list;
|
|
Packit |
4a16fb |
};
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
struct tplg_texts {
|
|
Packit |
4a16fb |
unsigned int num_items;
|
|
Packit |
4a16fb |
char items[SND_SOC_TPLG_NUM_TEXTS][SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
|
Packit |
4a16fb |
};
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* element for vendor tokens */
|
|
Packit |
4a16fb |
struct tplg_token {
|
|
Packit |
4a16fb |
char id[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
|
Packit |
4a16fb |
unsigned int value;
|
|
Packit |
4a16fb |
};
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
struct tplg_vendor_tokens {
|
|
Packit |
4a16fb |
unsigned int num_tokens;
|
|
Packit |
4a16fb |
struct tplg_token token[0];
|
|
Packit |
4a16fb |
};
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* element for vendor tuples */
|
|
Packit |
4a16fb |
struct tplg_tuple {
|
|
Packit |
4a16fb |
char token[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
|
Packit |
4a16fb |
union {
|
|
Packit |
4a16fb |
char string[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
|
Packit |
4a16fb |
unsigned char uuid[16];
|
|
Packit |
4a16fb |
unsigned int value;
|
|
Packit |
4a16fb |
};
|
|
Packit |
4a16fb |
};
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
struct tplg_tuple_set {
|
|
Packit |
4a16fb |
unsigned int type; /* uuid, bool, byte, short, word, string*/
|
|
Packit |
4a16fb |
unsigned int num_tuples;
|
|
Packit |
4a16fb |
struct tplg_tuple tuple[0];
|
|
Packit |
4a16fb |
};
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
struct tplg_vendor_tuples {
|
|
Packit |
4a16fb |
unsigned int num_sets;
|
|
Packit |
4a16fb |
struct tplg_tuple_set **set;
|
|
Packit |
4a16fb |
};
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* topology element */
|
|
Packit |
4a16fb |
struct tplg_elem {
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
char id[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int index;
|
|
Packit |
4a16fb |
enum snd_tplg_type type;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int size; /* total size of this object inc pdata and ref objects */
|
|
Packit |
4a16fb |
int compound_elem; /* dont write this element as individual elem */
|
|
Packit |
4a16fb |
int vendor_type; /* vendor type for private data */
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* UAPI object for this elem */
|
|
Packit |
4a16fb |
union {
|
|
Packit |
4a16fb |
void *obj;
|
|
Packit |
4a16fb |
struct snd_soc_tplg_mixer_control *mixer_ctrl;
|
|
Packit |
4a16fb |
struct snd_soc_tplg_enum_control *enum_ctrl;
|
|
Packit |
4a16fb |
struct snd_soc_tplg_bytes_control *bytes_ext;
|
|
Packit |
4a16fb |
struct snd_soc_tplg_dapm_widget *widget;
|
|
Packit |
4a16fb |
struct snd_soc_tplg_pcm *pcm;
|
|
Packit |
4a16fb |
struct snd_soc_tplg_dai *dai;
|
|
Packit |
4a16fb |
struct snd_soc_tplg_link_config *link;/* physical link */
|
|
Packit |
4a16fb |
struct snd_soc_tplg_dapm_graph_elem *route;
|
|
Packit |
4a16fb |
struct snd_soc_tplg_stream *stream_cfg;
|
|
Packit |
4a16fb |
struct snd_soc_tplg_stream_caps *stream_caps;
|
|
Packit |
4a16fb |
struct snd_soc_tplg_hw_config *hw_cfg;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* these do not map to UAPI structs but are internal only */
|
|
Packit |
4a16fb |
struct snd_soc_tplg_ctl_tlv *tlv;
|
|
Packit |
4a16fb |
struct tplg_texts *texts;
|
|
Packit |
4a16fb |
struct snd_soc_tplg_private *data;
|
|
Packit |
4a16fb |
struct tplg_vendor_tokens *tokens;
|
|
Packit |
4a16fb |
struct tplg_vendor_tuples *tuples;
|
|
Packit |
4a16fb |
struct snd_soc_tplg_manifest *manifest;
|
|
Packit |
4a16fb |
};
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* an element may refer to other elements:
|
|
Packit |
4a16fb |
* a mixer control may refer to a tlv,
|
|
Packit |
4a16fb |
* a widget may refer to a mixer control array,
|
|
Packit |
4a16fb |
* a graph may refer to some widgets.
|
|
Packit |
4a16fb |
*/
|
|
Packit |
4a16fb |
struct list_head ref_list;
|
|
Packit |
4a16fb |
struct list_head list; /* list of all elements with same type */
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
void (*free)(void *obj);
|
|
Packit |
4a16fb |
};
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
struct map_elem {
|
|
Packit |
4a16fb |
const char *name;
|
|
Packit |
4a16fb |
int id;
|
|
Packit |
4a16fb |
};
|
|
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 |
int tplg_write_data(snd_tplg_t *tplg);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_tlv(snd_tplg_t *tplg, snd_config_t *cfg,
|
|
Packit |
4a16fb |
void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_text(snd_tplg_t *tplg, snd_config_t *cfg,
|
|
Packit |
4a16fb |
void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_data(snd_tplg_t *tplg, snd_config_t *cfg,
|
|
Packit |
4a16fb |
void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_tokens(snd_tplg_t *tplg, snd_config_t *cfg,
|
|
Packit |
4a16fb |
void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_tuples(snd_tplg_t *tplg, snd_config_t *cfg,
|
|
Packit |
4a16fb |
void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
void tplg_free_tuples(void *obj);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_manifest_data(snd_tplg_t *tplg, snd_config_t *cfg,
|
|
Packit |
4a16fb |
void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_control_bytes(snd_tplg_t *tplg,
|
|
Packit |
4a16fb |
snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_control_enum(snd_tplg_t *tplg, snd_config_t *cfg,
|
|
Packit |
4a16fb |
void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_control_mixer(snd_tplg_t *tplg,
|
|
Packit |
4a16fb |
snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_dapm_graph(snd_tplg_t *tplg, snd_config_t *cfg,
|
|
Packit |
4a16fb |
void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_dapm_widget(snd_tplg_t *tplg,
|
|
Packit |
4a16fb |
snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_stream_caps(snd_tplg_t *tplg,
|
|
Packit |
4a16fb |
snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_pcm(snd_tplg_t *tplg,
|
|
Packit |
4a16fb |
snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_dai(snd_tplg_t *tplg, snd_config_t *cfg,
|
|
Packit |
4a16fb |
void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_link(snd_tplg_t *tplg,
|
|
Packit |
4a16fb |
snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_cc(snd_tplg_t *tplg,
|
|
Packit |
4a16fb |
snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg,
|
|
Packit |
4a16fb |
void *private ATTRIBUTE_UNUSED);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_build_data(snd_tplg_t *tplg);
|
|
Packit |
4a16fb |
int tplg_build_manifest_data(snd_tplg_t *tplg);
|
|
Packit |
4a16fb |
int tplg_build_controls(snd_tplg_t *tplg);
|
|
Packit |
4a16fb |
int tplg_build_widgets(snd_tplg_t *tplg);
|
|
Packit |
4a16fb |
int tplg_build_routes(snd_tplg_t *tplg);
|
|
Packit |
4a16fb |
int tplg_build_pcm_dai(snd_tplg_t *tplg, unsigned int type);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_copy_data(snd_tplg_t *tplg, struct tplg_elem *elem,
|
|
Packit |
4a16fb |
struct tplg_ref *ref);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_data_refs(snd_config_t *cfg, struct tplg_elem *elem);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_ref_add(struct tplg_elem *elem, int type, const char* id);
|
|
Packit |
4a16fb |
int tplg_ref_add_elem(struct tplg_elem *elem, struct tplg_elem *elem_ref);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
struct tplg_elem *tplg_elem_new(void);
|
|
Packit |
4a16fb |
void tplg_elem_free(struct tplg_elem *elem);
|
|
Packit |
4a16fb |
void tplg_elem_free_list(struct list_head *base);
|
|
Packit |
4a16fb |
struct tplg_elem *tplg_elem_lookup(struct list_head *base,
|
|
Packit |
4a16fb |
const char* id,
|
|
Packit |
4a16fb |
unsigned int type,
|
|
Packit |
4a16fb |
int index);
|
|
Packit |
4a16fb |
struct tplg_elem* tplg_elem_new_common(snd_tplg_t *tplg,
|
|
Packit |
4a16fb |
snd_config_t *cfg, const char *name, enum snd_tplg_type type);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_channel(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
|
Packit |
4a16fb |
snd_config_t *cfg, void *private);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_parse_ops(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
|
Packit |
4a16fb |
snd_config_t *cfg, void *private);
|
|
Packit |
4a16fb |
int tplg_parse_ext_ops(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
|
Packit |
4a16fb |
snd_config_t *cfg, void *private);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
struct tplg_elem *lookup_pcm_dai_stream(struct list_head *base,
|
|
Packit |
4a16fb |
const char* id);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_add_mixer_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
|
|
Packit |
4a16fb |
int tplg_add_enum_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
|
|
Packit |
4a16fb |
int tplg_add_bytes_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
|
|
Packit |
4a16fb |
int tplg_add_widget_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
|
|
Packit |
4a16fb |
int tplg_add_graph_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_add_mixer(snd_tplg_t *tplg, struct snd_tplg_mixer_template *mixer,
|
|
Packit |
4a16fb |
struct tplg_elem **e);
|
|
Packit |
4a16fb |
int tplg_add_enum(snd_tplg_t *tplg, struct snd_tplg_enum_template *enum_ctl,
|
|
Packit |
4a16fb |
struct tplg_elem **e);
|
|
Packit |
4a16fb |
int tplg_add_bytes(snd_tplg_t *tplg, struct snd_tplg_bytes_template *bytes_ctl,
|
|
Packit |
4a16fb |
struct tplg_elem **e);
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
int tplg_build_pcms(snd_tplg_t *tplg, unsigned int type);
|
|
Packit |
4a16fb |
int tplg_build_dais(snd_tplg_t *tplg, unsigned int type);
|
|
Packit |
4a16fb |
int tplg_build_links(snd_tplg_t *tplg, unsigned int type);
|
|
Packit |
4a16fb |
int tplg_add_link_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
|
|
Packit |
4a16fb |
int tplg_add_pcm_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
|
|
Packit |
4a16fb |
int tplg_add_dai_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
|