OSDN Git Service

ucm: add _fboot / FixedBootSequence
[android-x86/external-alsa-lib.git] / src / ucm / ucm_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  *  You should have received a copy of the GNU Lesser General Public
13  *  License along with this library; if not, write to the Free Software  
14  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
15  *
16  *  Support for the verb/device/modifier core logic and API,
17  *  command line tool and file parser was kindly sponsored by
18  *  Texas Instruments Inc.
19  *  Support for multiple active modifiers and devices,
20  *  transition sequences, multiple client access and user defined use
21  *  cases was kindly sponsored by Wolfson Microelectronics PLC.
22  *
23  *  Copyright (C) 2008-2010 SlimLogic Ltd
24  *  Copyright (C) 2010 Wolfson Microelectronics PLC
25  *  Copyright (C) 2010 Texas Instruments Inc.
26  *  Copyright (C) 2010 Red Hat Inc.
27  *  Authors: Liam Girdwood <lrg@slimlogic.co.uk>
28  *               Stefan Schmidt <stefan@slimlogic.co.uk>
29  *               Justin Xu <justinx@slimlogic.co.uk>
30  *               Jaroslav Kysela <perex@perex.cz>
31  */
32
33
34
35 #if 0
36 #define UC_MGR_DEBUG
37 #endif
38
39 #include "local.h"
40 #include <pthread.h>
41 #include "use-case.h"
42
43 #define SYNTAX_VERSION_MAX      4
44
45 #define MAX_CARD_SHORT_NAME     32
46 #define MAX_CARD_LONG_NAME      80
47
48 #define SEQUENCE_ELEMENT_TYPE_CDEV      1
49 #define SEQUENCE_ELEMENT_TYPE_CSET      2
50 #define SEQUENCE_ELEMENT_TYPE_SLEEP     3
51 #define SEQUENCE_ELEMENT_TYPE_EXEC      4
52 #define SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE     5
53 #define SEQUENCE_ELEMENT_TYPE_CSET_TLV  6
54 #define SEQUENCE_ELEMENT_TYPE_CMPT_SEQ  7
55
56 struct ucm_value {
57         struct list_head list;
58         char *name;
59         char *data;
60 };
61
62 /* sequence of a component device */
63 struct component_sequence {
64         struct use_case_device *device; /* component device */
65         int enable; /* flag to choose enable or disable list of the device */
66 };
67
68 struct sequence_element {
69         struct list_head list;
70         unsigned int type;
71         union {
72                 long sleep; /* Sleep time in microseconds if sleep element, else 0 */
73                 char *cdev;
74                 char *cset;
75                 char *exec;
76                 struct component_sequence cmpt_seq; /* component sequence */
77         } data;
78 };
79
80 /*
81  * Transition sequences. i.e. transition between one verb, device, mod to another
82  */
83 struct transition_sequence {
84         struct list_head list;
85         char *name;
86         struct list_head transition_list;
87 };
88
89 /*
90  * Modifier Supported Devices.
91  */
92 enum dev_list_type {
93         DEVLIST_NONE,
94         DEVLIST_SUPPORTED,
95         DEVLIST_CONFLICTING
96 };
97
98 struct dev_list_node {
99         struct list_head list;
100         char *name;
101 };
102
103 struct dev_list {
104         enum dev_list_type type;
105         struct list_head list;
106 };
107
108 struct ctl_dev {
109         struct list_head list;
110         char *device;
111 };
112
113 struct ctl_list {
114         struct list_head list;
115         struct list_head dev_list;
116         snd_ctl_t *ctl;
117         snd_ctl_card_info_t *ctl_info;
118         int slave;
119 };
120
121 struct ucm_dev_name {
122         struct list_head list;
123         char *name1;
124         char *name2;
125 };
126
127 /*
128  * Describes a Use Case Modifier and it's enable and disable sequences.
129  * A use case verb can have N modifiers.
130  */
131 struct use_case_modifier {
132         struct list_head list;
133         struct list_head active_list;
134
135         char *name;
136         char *comment;
137
138         /* modifier enable and disable sequences */
139         struct list_head enable_list;
140         struct list_head disable_list;
141
142         /* modifier transition list */
143         struct list_head transition_list;
144
145         /* list of devices supported or conflicting */
146         struct dev_list dev_list;
147
148         /* values */
149         struct list_head value_list;
150 };
151
152 /*
153  * Describes a Use Case Device and it's enable and disable sequences.
154  * A use case verb can have N devices.
155  */
156 struct use_case_device {
157         struct list_head list;
158         struct list_head active_list;
159
160         char *name;
161         char *comment;
162
163         /* device enable and disable sequences */
164         struct list_head enable_list;
165         struct list_head disable_list;
166
167         /* device transition list */
168         struct list_head transition_list;
169
170         /* list of devices supported or conflicting */
171         struct dev_list dev_list;
172
173         /* value list */
174         struct list_head value_list;
175 };
176
177 /*
178  * Describes a Use Case Verb and it's enable and disable sequences.
179  * A use case verb can have N devices and N modifiers.
180  */
181 struct use_case_verb {
182         struct list_head list;
183
184         unsigned int active: 1;
185
186         char *name;
187         char *comment;
188
189         /* verb enable and disable sequences */
190         struct list_head enable_list;
191         struct list_head disable_list;
192
193         /* verb transition list */
194         struct list_head transition_list;
195
196         struct list_head device_list;
197
198         /* component device list */
199         struct list_head cmpt_device_list;
200
201         /* modifiers that can be used with this use case */
202         struct list_head modifier_list;
203
204         /* value list */
205         struct list_head value_list;
206
207         /* temporary modifications lists */
208         struct list_head rename_list;
209         struct list_head remove_list;
210 };
211
212 /*
213  *  Manages a sound card and all its use cases.
214  */
215 struct snd_use_case_mgr {
216         char *card_name;
217         char *conf_file_name;
218         char *conf_dir_name;
219         char *comment;
220         int conf_format;
221
222         /* use case verb, devices and modifier configs parsed from files */
223         struct list_head verb_list;
224
225         /* force boot settings - sequence */
226         struct list_head fixedboot_list;
227
228         /* boot settings - sequence */
229         struct list_head boot_list;
230
231         /* default settings - sequence */
232         struct list_head default_list;
233         int default_list_executed;
234
235         /* default settings - value list */
236         struct list_head value_list;
237
238         /* current status */
239         struct use_case_verb *active_verb;
240         struct list_head active_devices;
241         struct list_head active_modifiers;
242
243         /* locking */
244         pthread_mutex_t mutex;
245
246         /* UCM internal variables defined in configuration files */
247         struct list_head variable_list;
248
249         /* list of opened control devices */
250         struct list_head ctl_list;
251
252         /* Components don't define cdev, the card device. When executing
253          * a sequence of a component device, ucm manager enters component
254          * domain and needs to provide cdev to the component. This cdev
255          * should be defined by the machine, parent of the component.
256          */
257         int in_component_domain;
258         char *cdev;
259 };
260
261 #define uc_error SNDERR
262
263 #ifdef UC_MGR_DEBUG
264 #define uc_dbg SNDERR
265 #else
266 #define uc_dbg(fmt, arg...) do { } while (0)
267 #endif
268
269 void uc_mgr_error(const char *fmt, ...);
270 void uc_mgr_stdout(const char *fmt, ...);
271
272 const char *uc_mgr_config_dir(int format);
273 int uc_mgr_config_load(int format, const char *file, snd_config_t **cfg);
274 int uc_mgr_config_load_file(snd_use_case_mgr_t *uc_mgr,  const char *file, snd_config_t **cfg);
275 int uc_mgr_import_master_config(snd_use_case_mgr_t *uc_mgr);
276 int uc_mgr_scan_master_configs(const char **_list[]);
277
278 int uc_mgr_put_to_dev_list(struct dev_list *dev_list, const char *name);
279 int uc_mgr_remove_device(struct use_case_verb *verb, const char *name);
280 int uc_mgr_rename_device(struct use_case_verb *verb, const char *src,
281                          const char *dst);
282
283 void uc_mgr_free_dev_name_list(struct list_head *base);
284 void uc_mgr_free_sequence_element(struct sequence_element *seq);
285 void uc_mgr_free_transition_element(struct transition_sequence *seq);
286 void uc_mgr_free_verb(snd_use_case_mgr_t *uc_mgr);
287 void uc_mgr_free(snd_use_case_mgr_t *uc_mgr);
288
289 int uc_mgr_open_ctl(snd_use_case_mgr_t *uc_mgr,
290                     struct ctl_list **ctl_list,
291                     const char *device,
292                     int slave);
293
294 struct ctl_list *uc_mgr_get_master_ctl(snd_use_case_mgr_t *uc_mgr);
295 struct ctl_list *uc_mgr_get_ctl_by_card(snd_use_case_mgr_t *uc_mgr, int card);
296 struct ctl_list *uc_mgr_get_ctl_by_name(snd_use_case_mgr_t *uc_mgr,
297                                         const char *name, int idx);
298 snd_ctl_t *uc_mgr_get_ctl(snd_use_case_mgr_t *uc_mgr);
299 void uc_mgr_free_ctl_list(snd_use_case_mgr_t *uc_mgr);
300
301 int uc_mgr_add_value(struct list_head *base, const char *key, char *val);
302
303 const char *uc_mgr_get_variable(snd_use_case_mgr_t *uc_mgr,
304                                 const char *name);
305
306 int uc_mgr_set_variable(snd_use_case_mgr_t *uc_mgr,
307                         const char *name,
308                         const char *val);
309
310 int uc_mgr_get_substituted_value(snd_use_case_mgr_t *uc_mgr,
311                                  char **_rvalue,
312                                  const char *value);
313
314 int uc_mgr_substitute_tree(snd_use_case_mgr_t *uc_mgr,
315                            snd_config_t *node);
316
317 int uc_mgr_config_tree_merge(snd_use_case_mgr_t *uc_mgr,
318                              snd_config_t *parent, snd_config_t *new_ctx,
319                              snd_config_t *before, snd_config_t *after);
320
321 int uc_mgr_evaluate_inplace(snd_use_case_mgr_t *uc_mgr,
322                             snd_config_t *cfg);
323
324 int uc_mgr_evaluate_include(snd_use_case_mgr_t *uc_mgr,
325                             snd_config_t *parent,
326                             snd_config_t *inc);
327
328 int uc_mgr_evaluate_condition(snd_use_case_mgr_t *uc_mgr,
329                               snd_config_t *parent,
330                               snd_config_t *cond);
331
332 int uc_mgr_define_regex(snd_use_case_mgr_t *uc_mgr,
333                         const char *name,
334                         snd_config_t *eval);
335
336 /** The name of the environment variable containing the UCM directory */
337 #define ALSA_CONFIG_UCM_VAR "ALSA_CONFIG_UCM"
338
339 /** The name of the environment variable containing the UCM directory (new syntax) */
340 #define ALSA_CONFIG_UCM2_VAR "ALSA_CONFIG_UCM2"