2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) any later version.
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
21 #include <sound/asound.h>
22 #include <sound/asoc.h>
23 #include <sound/tlv.h>
27 #define tplg_dbg SNDERR
29 #define tplg_dbg(fmt, arg...) do { } while (0)
33 #define TPLG_MAX_PRIV_SIZE (1024 * 128)
34 #define ALSA_TPLG_DIR ALSA_CONFIG_DIR "/topology"
36 /** The name of the environment variable containing the tplg directory */
37 #define ALSA_CONFIG_TPLG_VAR "ALSA_CONFIG_TPLG"
44 /* opaque vendor data */
55 unsigned int next_hdr_pos;
60 struct snd_soc_tplg_manifest manifest;
61 void *manifest_pdata; /* copied by builder at file write */
63 /* list of each element type */
64 struct list_head tlv_list;
65 struct list_head widget_list;
66 struct list_head pcm_list;
67 struct list_head dai_list;
68 struct list_head be_list;
69 struct list_head cc_list;
70 struct list_head route_list;
71 struct list_head text_list;
72 struct list_head pdata_list;
73 struct list_head token_list;
74 struct list_head tuple_list;
75 struct list_head manifest_list;
76 struct list_head pcm_config_list;
77 struct list_head pcm_caps_list;
78 struct list_head hw_cfg_list;
80 /* type-specific control lists */
81 struct list_head mixer_list;
82 struct list_head enum_list;
83 struct list_head bytes_ext_list;
86 /* object text references */
89 struct tplg_elem *elem;
90 char id[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
91 struct list_head list;
95 unsigned int num_items;
96 char items[SND_SOC_TPLG_NUM_TEXTS][SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
99 /* element for vendor tokens */
101 char id[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
105 struct tplg_vendor_tokens {
106 unsigned int num_tokens;
107 struct tplg_token token[0];
110 /* element for vendor tuples */
112 char token[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
114 char string[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
115 unsigned char uuid[16];
120 struct tplg_tuple_set {
121 unsigned int type; /* uuid, bool, byte, short, word, string*/
122 unsigned int num_tuples;
123 struct tplg_tuple tuple[0];
126 struct tplg_vendor_tuples {
127 unsigned int num_sets;
128 struct tplg_tuple_set **set;
131 /* topology element */
134 char id[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
137 enum snd_tplg_type type;
139 int size; /* total size of this object inc pdata and ref objects */
140 int compound_elem; /* dont write this element as individual elem */
141 int vendor_type; /* vendor type for private data */
143 /* UAPI object for this elem */
146 struct snd_soc_tplg_mixer_control *mixer_ctrl;
147 struct snd_soc_tplg_enum_control *enum_ctrl;
148 struct snd_soc_tplg_bytes_control *bytes_ext;
149 struct snd_soc_tplg_dapm_widget *widget;
150 struct snd_soc_tplg_pcm *pcm;
151 struct snd_soc_tplg_dai *dai;
152 struct snd_soc_tplg_link_config *link;/* physical link */
153 struct snd_soc_tplg_dapm_graph_elem *route;
154 struct snd_soc_tplg_stream *stream_cfg;
155 struct snd_soc_tplg_stream_caps *stream_caps;
156 struct snd_soc_tplg_hw_config *hw_cfg;
158 /* these do not map to UAPI structs but are internal only */
159 struct snd_soc_tplg_ctl_tlv *tlv;
160 struct tplg_texts *texts;
161 struct snd_soc_tplg_private *data;
162 struct tplg_vendor_tokens *tokens;
163 struct tplg_vendor_tuples *tuples;
164 struct snd_soc_tplg_manifest *manifest;
167 /* an element may refer to other elements:
168 * a mixer control may refer to a tlv,
169 * a widget may refer to a mixer control array,
170 * a graph may refer to some widgets.
172 struct list_head ref_list;
173 struct list_head list; /* list of all elements with same type */
175 void (*free)(void *obj);
183 int tplg_parse_compound(snd_tplg_t *tplg, snd_config_t *cfg,
184 int (*fcn)(snd_tplg_t *, snd_config_t *, void *),
187 int tplg_write_data(snd_tplg_t *tplg);
189 int tplg_parse_tlv(snd_tplg_t *tplg, snd_config_t *cfg,
190 void *private ATTRIBUTE_UNUSED);
192 int tplg_parse_text(snd_tplg_t *tplg, snd_config_t *cfg,
193 void *private ATTRIBUTE_UNUSED);
195 int tplg_parse_data(snd_tplg_t *tplg, snd_config_t *cfg,
196 void *private ATTRIBUTE_UNUSED);
198 int tplg_parse_tokens(snd_tplg_t *tplg, snd_config_t *cfg,
199 void *private ATTRIBUTE_UNUSED);
201 int tplg_parse_tuples(snd_tplg_t *tplg, snd_config_t *cfg,
202 void *private ATTRIBUTE_UNUSED);
204 void tplg_free_tuples(void *obj);
206 int tplg_parse_manifest_data(snd_tplg_t *tplg, snd_config_t *cfg,
207 void *private ATTRIBUTE_UNUSED);
209 int tplg_parse_control_bytes(snd_tplg_t *tplg,
210 snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
212 int tplg_parse_control_enum(snd_tplg_t *tplg, snd_config_t *cfg,
213 void *private ATTRIBUTE_UNUSED);
215 int tplg_parse_control_mixer(snd_tplg_t *tplg,
216 snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
218 int tplg_parse_dapm_graph(snd_tplg_t *tplg, snd_config_t *cfg,
219 void *private ATTRIBUTE_UNUSED);
221 int tplg_parse_dapm_widget(snd_tplg_t *tplg,
222 snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
224 int tplg_parse_stream_caps(snd_tplg_t *tplg,
225 snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
227 int tplg_parse_pcm(snd_tplg_t *tplg,
228 snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
230 int tplg_parse_dai(snd_tplg_t *tplg, snd_config_t *cfg,
231 void *private ATTRIBUTE_UNUSED);
233 int tplg_parse_link(snd_tplg_t *tplg,
234 snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
236 int tplg_parse_cc(snd_tplg_t *tplg,
237 snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
239 int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg,
240 void *private ATTRIBUTE_UNUSED);
242 int tplg_build_data(snd_tplg_t *tplg);
243 int tplg_build_manifest_data(snd_tplg_t *tplg);
244 int tplg_build_controls(snd_tplg_t *tplg);
245 int tplg_build_widgets(snd_tplg_t *tplg);
246 int tplg_build_routes(snd_tplg_t *tplg);
247 int tplg_build_pcm_dai(snd_tplg_t *tplg, unsigned int type);
249 int tplg_copy_data(snd_tplg_t *tplg, struct tplg_elem *elem,
250 struct tplg_ref *ref);
252 int tplg_parse_data_refs(snd_config_t *cfg, struct tplg_elem *elem);
254 int tplg_ref_add(struct tplg_elem *elem, int type, const char* id);
255 int tplg_ref_add_elem(struct tplg_elem *elem, struct tplg_elem *elem_ref);
257 struct tplg_elem *tplg_elem_new(void);
258 void tplg_elem_free(struct tplg_elem *elem);
259 void tplg_elem_free_list(struct list_head *base);
260 struct tplg_elem *tplg_elem_lookup(struct list_head *base,
264 struct tplg_elem* tplg_elem_new_common(snd_tplg_t *tplg,
265 snd_config_t *cfg, const char *name, enum snd_tplg_type type);
267 static inline void elem_copy_text(char *dest, const char *src, int len)
269 if (!dest || !src || !len)
272 strncpy(dest, src, len);
276 int tplg_parse_channel(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
277 snd_config_t *cfg, void *private);
279 int tplg_parse_ops(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
280 snd_config_t *cfg, void *private);
281 int tplg_parse_ext_ops(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
282 snd_config_t *cfg, void *private);
284 struct tplg_elem *lookup_pcm_dai_stream(struct list_head *base,
287 int tplg_add_mixer_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
288 int tplg_add_enum_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
289 int tplg_add_bytes_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
290 int tplg_add_widget_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
291 int tplg_add_graph_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
293 int tplg_add_mixer(snd_tplg_t *tplg, struct snd_tplg_mixer_template *mixer,
294 struct tplg_elem **e);
295 int tplg_add_enum(snd_tplg_t *tplg, struct snd_tplg_enum_template *enum_ctl,
296 struct tplg_elem **e);
297 int tplg_add_bytes(snd_tplg_t *tplg, struct snd_tplg_bytes_template *bytes_ctl,
298 struct tplg_elem **e);
300 int tplg_build_pcms(snd_tplg_t *tplg, unsigned int type);
301 int tplg_build_dais(snd_tplg_t *tplg, unsigned int type);
302 int tplg_build_links(snd_tplg_t *tplg, unsigned int type);
303 int tplg_add_link_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
304 int tplg_add_pcm_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
305 int tplg_add_dai_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);