1 /*
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.
6 *
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.
11 */
12
13 #include <limits.h>
14 #include <stdint.h>
15 #include <stdbool.h>
16
17 #include "local.h"
18 #include "list.h"
19 #include "bswap.h"
20 #include "topology.h"
21
22 #include <sound/type_compat.h>
23 #include <sound/asound.h>
24 #include <sound/asoc.h>
25 #include <sound/tlv.h>
26
27 #ifdef TPLG_DEBUG
28 #define tplg_dbg SNDERR
29 #else
30 #define tplg_dbg(fmt, arg...) do { } while (0)
31 #endif
32
33 #define TPLG_MAX_PRIV_SIZE (1024 * 128)
34
35 /** The name of the environment variable containing the tplg directory */
36 #define ALSA_CONFIG_TPLG_VAR "ALSA_CONFIG_TPLG"
37
38 struct tplg_ref;
39 struct tplg_elem;
40 struct tplg_table;
41
42 typedef enum _snd_pcm_rates {
43 SND_PCM_RATE_UNKNOWN = -1,
44 SND_PCM_RATE_5512 = 0,
45 SND_PCM_RATE_8000,
46 SND_PCM_RATE_11025,
47 SND_PCM_RATE_16000,
48 SND_PCM_RATE_22050,
49 SND_PCM_RATE_32000,
50 SND_PCM_RATE_44100,
51 SND_PCM_RATE_48000,
52 SND_PCM_RATE_64000,
53 SND_PCM_RATE_88200,
54 SND_PCM_RATE_96000,
55 SND_PCM_RATE_176400,
56 SND_PCM_RATE_192000,
57 SND_PCM_RATE_CONTINUOUS = 30,
58 SND_PCM_RATE_KNOT = 31,
59 SND_PCM_RATE_LAST = SND_PCM_RATE_KNOT,
60 } snd_pcm_rates_t;
61
62 struct snd_tplg {
63 /* out file */
64 unsigned char *bin;
65 size_t bin_pos;
66 size_t bin_size;
67
68 int verbose;
69 unsigned int dapm_sort: 1;
70 unsigned int version;
71
72 /* runtime state */
73 size_t next_hdr_pos;
74 int index;
75 int channel_idx;
76
77 /* manifest */
78 struct snd_soc_tplg_manifest manifest;
79 void *manifest_pdata; /* copied by builder at file write */
80
81 /* list of each element type */
82 struct list_head tlv_list;
83 struct list_head widget_list;
84 struct list_head pcm_list;
85 struct list_head dai_list;
86 struct list_head be_list;
87 struct list_head cc_list;
88 struct list_head route_list;
89 struct list_head text_list;
90 struct list_head pdata_list;
91 struct list_head token_list;
92 struct list_head tuple_list;
93 struct list_head manifest_list;
94 struct list_head pcm_config_list;
95 struct list_head pcm_caps_list;
96 struct list_head hw_cfg_list;
97
98 /* type-specific control lists */
99 struct list_head mixer_list;
100 struct list_head enum_list;
101 struct list_head bytes_ext_list;
102 };
103
104 /* object text references */
105 struct tplg_ref {
106 unsigned int type;
107 struct tplg_elem *elem;
108 char id[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
109 struct list_head list;
110 };
111
112 struct tplg_texts {
113 unsigned int num_items;
114 char items[SND_SOC_TPLG_NUM_TEXTS][SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
115 };
116
117 /* element for vendor tokens */
118 struct tplg_token {
119 char id[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
120 unsigned int value;
121 };
122
123 struct tplg_vendor_tokens {
124 unsigned int num_tokens;
125 struct tplg_token token[0];
126 };
127
128 /* element for vendor tuples */
129 struct tplg_tuple {
130 char token[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
131 union {
132 char string[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
133 unsigned char uuid[16];
134 unsigned int value;
135 };
136 };
137
138 struct tplg_tuple_set {
139 unsigned int type; /* uuid, bool, byte, short, word, string*/
140 unsigned int num_tuples;
141 struct tplg_tuple tuple[0];
142 };
143
144 struct tplg_vendor_tuples {
145 unsigned int num_sets;
146 unsigned int alloc_sets;
147 struct tplg_tuple_set **set;
148 };
149
150 /* topology element */
151 struct tplg_elem {
152
153 struct tplg_table *table;
154
155 char id[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
156
157 int index;
158 enum snd_tplg_type type;
159
160 int size; /* total size of this object inc pdata and ref objects */
161 int compound_elem; /* dont write this element as individual elem */
162 int vendor_type; /* vendor type for private data */
163
164 /* UAPI object for this elem */
165 union {
166 void *obj;
167 struct snd_soc_tplg_mixer_control *mixer_ctrl;
168 struct snd_soc_tplg_enum_control *enum_ctrl;
169 struct snd_soc_tplg_bytes_control *bytes_ext;
170 struct snd_soc_tplg_dapm_widget *widget;
171 struct snd_soc_tplg_pcm *pcm;
172 struct snd_soc_tplg_dai *dai;
173 struct snd_soc_tplg_link_config *link;/* physical link */
174 struct snd_soc_tplg_dapm_graph_elem *route;
175 struct snd_soc_tplg_stream *stream_cfg;
176 struct snd_soc_tplg_stream_caps *stream_caps;
177 struct snd_soc_tplg_hw_config *hw_cfg;
178
179 /* these do not map to UAPI structs but are internal only */
180 struct snd_soc_tplg_ctl_tlv *tlv;
181 struct tplg_texts *texts;
182 struct snd_soc_tplg_private *data;
183 struct tplg_vendor_tokens *tokens;
184 struct tplg_vendor_tuples *tuples;
185 struct snd_soc_tplg_manifest *manifest;
186 };
187
188 /* an element may refer to other elements:
189 * a mixer control may refer to a tlv,
190 * a widget may refer to a mixer control array,
191 * a graph may refer to some widgets.
192 */
193 struct list_head ref_list;
194 struct list_head list; /* list of all elements with same type */
195
196 void (*free)(void *obj);
197 };
198
199 struct map_elem {
200 const char *name;
201 int id;
202 };
203
204 /* output buffer */
205 struct tplg_buf {
206 char *dst;
207 size_t dst_len;
208 char *printf_buf;
209 size_t printf_buf_size;
210 };
211
212 /* mapping table */
213 struct tplg_table {
214 const char *name;
215 const char *id;
216 const char *id2;
217 off_t loff;
218 size_t size;
219 int type;
220 int tsoc;
221 unsigned build: 1;
222 unsigned enew: 1;
223 void (*free)(void *);
224 int (*parse)(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
225 int (*save)(snd_tplg_t *tplg, struct tplg_elem *elem,
226 struct tplg_buf *dst, const char *prefix);
227 int (*gsave)(snd_tplg_t *tplg, int index,
228 struct tplg_buf *dst, const char *prefix);
229 int (*decod)(snd_tplg_t *tplg, size_t pos,
230 struct snd_soc_tplg_hdr *hdr,
231 void *bin, size_t size);
232 };
233
234 extern struct tplg_table tplg_table[];
235 extern unsigned int tplg_table_items;
236
237 #if __SIZEOF_INT__ == 4
unaligned_get32(void * src)238 static inline unsigned int unaligned_get32(void *src)
239 {
240 unsigned int ret;
241 memcpy(&ret, src, sizeof(ret));
242 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
243 ret = bswap_32(ret);
244 #endif
245 return ret;
246 }
unaligned_put32(void * dst,unsigned int val)247 static inline void unaligned_put32(void *dst, unsigned int val)
248 {
249 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
250 val = bswap_32(val);
251 #endif
252 memcpy(dst, &val, sizeof(val));
253 }
254 #endif
255
256 #define tplg_log(tplg, type, pos, fmt, args...) do { \
257 if ((tplg)->verbose) \
258 tplg_log_((tplg), (type), (pos), (fmt), ##args); \
259 } while (0)
260
261 void tplg_log_(snd_tplg_t *tplg, char type, size_t pos, const char *fmt, ...);
262
263 void *tplg_calloc(struct list_head *heap, size_t size);
264 void tplg_free(struct list_head *heap);
265
266 int tplg_get_type(int asoc_type);
267
268 int tplg_parse_compound(snd_tplg_t *tplg, snd_config_t *cfg,
269 int (*fcn)(snd_tplg_t *, snd_config_t *, void *),
270 void *private);
271
272 int tplg_write_data(snd_tplg_t *tplg);
273
274 int tplg_parse_tlv(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
275 int tplg_parse_text(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
276 int tplg_parse_data(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
277 int tplg_parse_tokens(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
278 int tplg_parse_tuples(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
279 int tplg_parse_manifest_data(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
280 int tplg_parse_control_bytes(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
281 int tplg_parse_control_enum(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
282 int tplg_parse_control_mixer(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
283 int tplg_parse_dapm_graph(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
284 int tplg_parse_dapm_widget(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
285 int tplg_parse_stream_caps(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
286 int tplg_parse_pcm(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
287 int tplg_parse_dai(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
288 int tplg_parse_link(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
289 int tplg_parse_cc(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
290 int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
291
292 unsigned int tplg_get_tuple_size(int type);
293 void tplg_free_tuples(void *obj);
294
295 int tplg_build_data(snd_tplg_t *tplg);
296 int tplg_build_manifest_data(snd_tplg_t *tplg);
297 int tplg_build_controls(snd_tplg_t *tplg);
298 int tplg_build_widgets(snd_tplg_t *tplg);
299 int tplg_build_routes(snd_tplg_t *tplg);
300 int tplg_build_pcm_dai(snd_tplg_t *tplg, unsigned int type);
301
302 int tplg_copy_data(snd_tplg_t *tplg, struct tplg_elem *elem,
303 struct tplg_ref *ref);
304
305 int tplg_parse_refs(snd_config_t *cfg, struct tplg_elem *elem,
306 unsigned int type);
307
308 int tplg_ref_add(struct tplg_elem *elem, int type, const char* id);
309 int tplg_ref_add_elem(struct tplg_elem *elem, struct tplg_elem *elem_ref);
310
311 struct tplg_elem *tplg_elem_new(void);
312 void tplg_elem_free(struct tplg_elem *elem);
313 void tplg_elem_free_list(struct list_head *base);
314 void tplg_elem_insert(struct tplg_elem *elem_p, struct list_head *list);
315 struct tplg_elem *tplg_elem_lookup(struct list_head *base,
316 const char* id,
317 unsigned int type,
318 int index);
319 struct tplg_elem *tplg_elem_type_lookup(snd_tplg_t *tplg,
320 enum snd_tplg_type type);
321 struct tplg_elem* tplg_elem_new_common(snd_tplg_t *tplg,
322 snd_config_t *cfg, const char *name, enum snd_tplg_type type);
323
324 int tplg_get_integer(snd_config_t *n, int *val, int base);
325 int tplg_get_unsigned(snd_config_t *n, unsigned *val, int base);
326
327 const char *tplg_channel_name(int type);
328 int tplg_parse_channel(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
329 snd_config_t *cfg, void *private);
330
331 const char *tplg_ops_name(int type);
332 int tplg_parse_ops(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
333 snd_config_t *cfg, void *private);
334 int tplg_parse_ext_ops(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
335 snd_config_t *cfg, void *private);
336
337 struct tplg_elem *lookup_pcm_dai_stream(struct list_head *base,
338 const char* id);
339
340 int tplg_add_data(snd_tplg_t *tplg, struct tplg_elem *parent,
341 const void *bin, size_t size);
342 int tplg_add_data_bytes(snd_tplg_t *tplg, struct tplg_elem *parent,
343 const char *suffix, const void *bin, size_t size);
344 int tplg_add_mixer_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
345 int tplg_add_enum_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
346 int tplg_add_bytes_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
347 int tplg_add_widget_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
348 int tplg_add_graph_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
349
350 int tplg_add_mixer(snd_tplg_t *tplg, struct snd_tplg_mixer_template *mixer,
351 struct tplg_elem **e);
352 int tplg_add_enum(snd_tplg_t *tplg, struct snd_tplg_enum_template *enum_ctl,
353 struct tplg_elem **e);
354 int tplg_add_bytes(snd_tplg_t *tplg, struct snd_tplg_bytes_template *bytes_ctl,
355 struct tplg_elem **e);
356
357 int tplg_build_pcms(snd_tplg_t *tplg, unsigned int type);
358 int tplg_build_dais(snd_tplg_t *tplg, unsigned int type);
359 int tplg_build_links(snd_tplg_t *tplg, unsigned int type);
360 int tplg_add_link_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
361 int tplg_add_pcm_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
362 int tplg_add_dai_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
363
364 int tplg_nice_value_format(char *dst, size_t dst_size, unsigned int value);
365
366 int tplg_save_printf(struct tplg_buf *dst, const char *prefix, const char *fmt, ...);
367 int tplg_save_refs(snd_tplg_t *tplg, struct tplg_elem *elem, unsigned int type,
368 const char *id, struct tplg_buf *dst, const char *pfx);
369 int tplg_save_channels(snd_tplg_t *tplg, struct snd_soc_tplg_channel *channel,
370 unsigned int channel_count, struct tplg_buf *dst, const char *pfx);
371 int tplg_save_ops(snd_tplg_t *tplg, struct snd_soc_tplg_ctl_hdr *hdr,
372 struct tplg_buf *dst, const char *pfx);
373 int tplg_save_ext_ops(snd_tplg_t *tplg, struct snd_soc_tplg_bytes_control *be,
374 struct tplg_buf *dst, const char *pfx);
375 int tplg_save_manifest_data(snd_tplg_t *tplg, struct tplg_elem *elem,
376 struct tplg_buf *dst, const char *pfx);
377 int tplg_save_control_mixer(snd_tplg_t *tplg, struct tplg_elem *elem,
378 struct tplg_buf *dst, const char *pfx);
379 int tplg_save_control_enum(snd_tplg_t *tplg, struct tplg_elem *elem,
380 struct tplg_buf *dst, const char *pfx);
381 int tplg_save_control_bytes(snd_tplg_t *tplg, struct tplg_elem *elem,
382 struct tplg_buf *dst, const char *pfx);
383 int tplg_save_tlv(snd_tplg_t *tplg, struct tplg_elem *elem,
384 struct tplg_buf *dst, const char *pfx);
385 int tplg_save_data(snd_tplg_t *tplg, struct tplg_elem *elem,
386 struct tplg_buf *dst, const char *pfx);
387 int tplg_save_text(snd_tplg_t *tplg, struct tplg_elem *elem,
388 struct tplg_buf *dst, const char *pfx);
389 int tplg_save_tokens(snd_tplg_t *tplg, struct tplg_elem *elem,
390 struct tplg_buf *dst, const char *pfx);
391 int tplg_save_tuples(snd_tplg_t *tplg, struct tplg_elem *elem,
392 struct tplg_buf *dst, const char *pfx);
393 int tplg_save_dapm_graph(snd_tplg_t *tplg, int index,
394 struct tplg_buf *dst, const char *pfx);
395 int tplg_save_dapm_widget(snd_tplg_t *tplg, struct tplg_elem *elem,
396 struct tplg_buf *dst, const char *pfx);
397 int tplg_save_link(snd_tplg_t *tplg, struct tplg_elem *elem,
398 struct tplg_buf *dst, const char *pfx);
399 int tplg_save_cc(snd_tplg_t *tplg, struct tplg_elem *elem,
400 struct tplg_buf *dst, const char *pfx);
401 int tplg_save_pcm(snd_tplg_t *tplg, struct tplg_elem *elem,
402 struct tplg_buf *dst, const char *pfx);
403 int tplg_save_hw_config(snd_tplg_t *tplg, struct tplg_elem *elem,
404 struct tplg_buf *dst, const char *pfx);
405 int tplg_save_stream_caps(snd_tplg_t *tplg, struct tplg_elem *elem,
406 struct tplg_buf *dst, const char *pfx);
407 int tplg_save_dai(snd_tplg_t *tplg, struct tplg_elem *elem,
408 struct tplg_buf *dst, const char *pfx);
409
410 int tplg_decode_template(snd_tplg_t *tplg,
411 size_t pos,
412 struct snd_soc_tplg_hdr *hdr,
413 snd_tplg_obj_template_t *t);
414 int tplg_decode_manifest_data(snd_tplg_t *tplg, size_t pos,
415 struct snd_soc_tplg_hdr *hdr,
416 void *bin, size_t size);
417 int tplg_decode_control_mixer1(snd_tplg_t *tplg,
418 struct list_head *heap,
419 struct snd_tplg_mixer_template *mt,
420 size_t pos,
421 void *bin, size_t size);
422 int tplg_decode_control_mixer(snd_tplg_t *tplg, size_t pos,
423 struct snd_soc_tplg_hdr *hdr,
424 void *bin, size_t size);
425 int tplg_decode_control_enum1(snd_tplg_t *tplg,
426 struct list_head *heap,
427 struct snd_tplg_enum_template *et,
428 size_t pos,
429 struct snd_soc_tplg_enum_control *ec);
430 int tplg_decode_control_enum(snd_tplg_t *tplg, size_t pos,
431 struct snd_soc_tplg_hdr *hdr,
432 void *bin, size_t size);
433 int tplg_decode_control_bytes1(snd_tplg_t *tplg,
434 struct snd_tplg_bytes_template *bt,
435 size_t pos,
436 void *bin, size_t size);
437 int tplg_decode_control_bytes(snd_tplg_t *tplg, size_t pos,
438 struct snd_soc_tplg_hdr *hdr,
439 void *bin, size_t size);
440 int tplg_decode_data(snd_tplg_t *tplg, size_t pos,
441 struct snd_soc_tplg_hdr *hdr,
442 void *bin, size_t size);
443 int tplg_decode_dapm_graph(snd_tplg_t *tplg, size_t pos,
444 struct snd_soc_tplg_hdr *hdr,
445 void *bin, size_t size);
446 int tplg_decode_dapm_widget(snd_tplg_t *tplg, size_t pos,
447 struct snd_soc_tplg_hdr *hdr,
448 void *bin, size_t size);
449 int tplg_decode_link(snd_tplg_t *tplg, size_t pos,
450 struct snd_soc_tplg_hdr *hdr,
451 void *bin, size_t size);
452 int tplg_decode_cc(snd_tplg_t *tplg, size_t pos,
453 struct snd_soc_tplg_hdr *hdr,
454 void *bin, size_t size);
455 int tplg_decode_pcm(snd_tplg_t *tplg, size_t pos,
456 struct snd_soc_tplg_hdr *hdr,
457 void *bin, size_t size);
458 int tplg_decode_dai(snd_tplg_t *tplg, size_t pos,
459 struct snd_soc_tplg_hdr *hdr,
460 void *bin, size_t size);
461