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