OSDN Git Service

eb7eac5b23056d25eae0ec5d5cd5769dc85d5c1d
[android-x86/external-alsa-lib.git] / src / topology / tplg_local.h
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 "topology.h"
20
21 #include <sound/asound.h>
22 #include <sound/asoc.h>
23 #include <sound/tlv.h>
24
25 #define TPLG_DEBUG
26 #ifdef TPLG_DEBUG
27 #define tplg_dbg SNDERR
28 #else
29 #define tplg_dbg(fmt, arg...) do { } while (0)
30 #endif
31
32 #define MAX_FILE                256
33 #define TPLG_MAX_PRIV_SIZE      (1024 * 128)
34 #define ALSA_TPLG_DIR   ALSA_CONFIG_DIR "/topology"
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
42 struct snd_tplg {
43
44         /* opaque vendor data */
45         int vendor_fd;
46         char *vendor_name;
47
48         /* out file */
49         int out_fd;
50
51         int verbose;
52         unsigned int version;
53
54         /* runtime state */
55         unsigned int next_hdr_pos;
56         int index;
57         int channel_idx;
58
59         /* manifest */
60         struct snd_soc_tplg_manifest manifest;
61         void *manifest_pdata;   /* copied by builder at file write */
62
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;
79
80         /* type-specific control lists */
81         struct list_head mixer_list;
82         struct list_head enum_list;
83         struct list_head bytes_ext_list;
84 };
85
86 /* object text references */
87 struct tplg_ref {
88         unsigned int type;
89         struct tplg_elem *elem;
90         char id[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
91         struct list_head list;
92 };
93
94 struct tplg_texts {
95         unsigned int num_items;
96         char items[SND_SOC_TPLG_NUM_TEXTS][SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
97 };
98
99 /* element for vendor tokens */
100 struct tplg_token {
101         char id[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
102         unsigned int value;
103 };
104
105 struct tplg_vendor_tokens {
106         unsigned int num_tokens;
107         struct tplg_token token[0];
108 };
109
110 /* element for vendor tuples */
111 struct tplg_tuple {
112         char token[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
113         union {
114                 char string[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
115                 unsigned char uuid[16];
116                 unsigned int value;
117         };
118 };
119
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];
124 };
125
126 struct tplg_vendor_tuples {
127         unsigned int  num_sets;
128         struct tplg_tuple_set **set;
129 };
130
131 /* topology element */
132 struct tplg_elem {
133
134         char id[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
135
136         int index;
137         enum snd_tplg_type type;
138
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 */
142
143         /* UAPI object for this elem */
144         union {
145                 void *obj;
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;
157
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;
165         };
166
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.
171          */
172         struct list_head ref_list;
173         struct list_head list; /* list of all elements with same type */
174
175         void (*free)(void *obj);
176 };
177
178 struct map_elem {
179         const char *name;
180         int id;
181 };
182
183 int tplg_parse_compound(snd_tplg_t *tplg, snd_config_t *cfg,
184         int (*fcn)(snd_tplg_t *, snd_config_t *, void *),
185         void *private);
186
187 int tplg_write_data(snd_tplg_t *tplg);
188
189 int tplg_parse_tlv(snd_tplg_t *tplg, snd_config_t *cfg,
190         void *private ATTRIBUTE_UNUSED);
191
192 int tplg_parse_text(snd_tplg_t *tplg, snd_config_t *cfg,
193         void *private ATTRIBUTE_UNUSED);
194
195 int tplg_parse_data(snd_tplg_t *tplg, snd_config_t *cfg,
196         void *private ATTRIBUTE_UNUSED);
197
198 int tplg_parse_tokens(snd_tplg_t *tplg, snd_config_t *cfg,
199         void *private ATTRIBUTE_UNUSED);
200
201 int tplg_parse_tuples(snd_tplg_t *tplg, snd_config_t *cfg,
202         void *private ATTRIBUTE_UNUSED);
203
204 void tplg_free_tuples(void *obj);
205
206 int tplg_parse_manifest_data(snd_tplg_t *tplg, snd_config_t *cfg,
207         void *private ATTRIBUTE_UNUSED);
208
209 int tplg_parse_control_bytes(snd_tplg_t *tplg,
210         snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
211
212 int tplg_parse_control_enum(snd_tplg_t *tplg, snd_config_t *cfg,
213         void *private ATTRIBUTE_UNUSED);
214
215 int tplg_parse_control_mixer(snd_tplg_t *tplg,
216         snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
217
218 int tplg_parse_dapm_graph(snd_tplg_t *tplg, snd_config_t *cfg,
219         void *private ATTRIBUTE_UNUSED);
220
221 int tplg_parse_dapm_widget(snd_tplg_t *tplg,
222         snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
223
224 int tplg_parse_stream_caps(snd_tplg_t *tplg,
225         snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
226
227 int tplg_parse_pcm(snd_tplg_t *tplg,
228         snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
229
230 int tplg_parse_dai(snd_tplg_t *tplg, snd_config_t *cfg,
231                    void *private ATTRIBUTE_UNUSED);
232
233 int tplg_parse_link(snd_tplg_t *tplg,
234         snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
235
236 int tplg_parse_cc(snd_tplg_t *tplg,
237         snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
238
239 int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg,
240                          void *private ATTRIBUTE_UNUSED);
241
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);
248
249 int tplg_copy_data(snd_tplg_t *tplg, struct tplg_elem *elem,
250                    struct tplg_ref *ref);
251
252 int tplg_parse_data_refs(snd_config_t *cfg, struct tplg_elem *elem);
253
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);
256
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,
261                                 const char* id,
262                                 unsigned int type,
263                                 int index);
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);
266
267 static inline void elem_copy_text(char *dest, const char *src, int len)
268 {
269         if (!dest || !src || !len)
270                 return;
271
272         strncpy(dest, src, len);
273         dest[len - 1] = 0;
274 }
275
276 int tplg_parse_channel(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
277         snd_config_t *cfg, void *private);
278
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);
283
284 struct tplg_elem *lookup_pcm_dai_stream(struct list_head *base,
285         const char* id);
286
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);
292
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);
299
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);