OSDN Git Service

79f1e87ec0ead80d842a459646dbcbe956ce4668
[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_CSET_NEW          7
55 #define SEQUENCE_ELEMENT_TYPE_CTL_REMOVE        8
56 #define SEQUENCE_ELEMENT_TYPE_CMPT_SEQ          9
57 #define SEQUENCE_ELEMENT_TYPE_SYSSET            10
58
59 struct ucm_value {
60         struct list_head list;
61         char *name;
62         char *data;
63 };
64
65 /* sequence of a component device */
66 struct component_sequence {
67         struct use_case_device *device; /* component device */
68         int enable; /* flag to choose enable or disable list of the device */
69 };
70
71 struct sequence_element {
72         struct list_head list;
73         unsigned int type;
74         union {
75                 long sleep; /* Sleep time in microseconds if sleep element, else 0 */
76                 char *cdev;
77                 char *cset;
78                 char *exec;
79                 char *sysw;
80                 struct component_sequence cmpt_seq; /* component sequence */
81         } data;
82 };
83
84 /*
85  * Transition sequences. i.e. transition between one verb, device, mod to another
86  */
87 struct transition_sequence {
88         struct list_head list;
89         char *name;
90         struct list_head transition_list;
91 };
92
93 /*
94  * Modifier Supported Devices.
95  */
96 enum dev_list_type {
97         DEVLIST_NONE,
98         DEVLIST_SUPPORTED,
99         DEVLIST_CONFLICTING
100 };
101
102 struct dev_list_node {
103         struct list_head list;
104         char *name;
105 };
106
107 struct dev_list {
108         enum dev_list_type type;
109         struct list_head list;
110 };
111
112 struct ctl_dev {
113         struct list_head list;
114         char *device;
115 };
116
117 struct ctl_list {
118         struct list_head list;
119         struct list_head dev_list;
120         snd_ctl_t *ctl;
121         snd_ctl_card_info_t *ctl_info;
122         int slave;
123 };
124
125 struct ucm_dev_name {
126         struct list_head list;
127         char *name1;
128         char *name2;
129 };
130
131 /*
132  * Describes a Use Case Modifier and it's enable and disable sequences.
133  * A use case verb can have N modifiers.
134  */
135 struct use_case_modifier {
136         struct list_head list;
137         struct list_head active_list;
138
139         char *name;
140         char *comment;
141
142         /* modifier enable and disable sequences */
143         struct list_head enable_list;
144         struct list_head disable_list;
145
146         /* modifier transition list */
147         struct list_head transition_list;
148
149         /* list of devices supported or conflicting */
150         struct dev_list dev_list;
151
152         /* values */
153         struct list_head value_list;
154 };
155
156 /*
157  * Describes a Use Case Device and it's enable and disable sequences.
158  * A use case verb can have N devices.
159  */
160 struct use_case_device {
161         struct list_head list;
162         struct list_head active_list;
163
164         char *name;
165         char *comment;
166
167         /* device enable and disable sequences */
168         struct list_head enable_list;
169         struct list_head disable_list;
170
171         /* device transition list */
172         struct list_head transition_list;
173
174         /* list of devices supported or conflicting */
175         struct dev_list dev_list;
176
177         /* value list */
178         struct list_head value_list;
179 };
180
181 /*
182  * Describes a Use Case Verb and it's enable and disable sequences.
183  * A use case verb can have N devices and N modifiers.
184  */
185 struct use_case_verb {
186         struct list_head list;
187
188         unsigned int active: 1;
189
190         char *name;
191         char *comment;
192
193         /* verb enable and disable sequences */
194         struct list_head enable_list;
195         struct list_head disable_list;
196
197         /* verb transition list */
198         struct list_head transition_list;
199
200         struct list_head device_list;
201
202         /* component device list */
203         struct list_head cmpt_device_list;
204
205         /* modifiers that can be used with this use case */
206         struct list_head modifier_list;
207
208         /* value list */
209         struct list_head value_list;
210
211         /* temporary modifications lists */
212         struct list_head rename_list;
213         struct list_head remove_list;
214 };
215
216 /*
217  *  Manages a sound card and all its use cases.
218  */
219 struct snd_use_case_mgr {
220         char *card_name;
221         char *conf_file_name;
222         char *conf_dir_name;
223         char *comment;
224         int conf_format;
225         unsigned int ucm_card_number;
226
227         /* UCM cards list */
228         struct list_head cards_list;
229
230         /* use case verb, devices and modifier configs parsed from files */
231         struct list_head verb_list;
232
233         /* force boot settings - sequence */
234         struct list_head fixedboot_list;
235
236         /* boot settings - sequence */
237         struct list_head boot_list;
238
239         /* default settings - sequence */
240         struct list_head default_list;
241         int default_list_executed;
242
243         /* default settings - value list */
244         struct list_head value_list;
245
246         /* current status */
247         struct use_case_verb *active_verb;
248         struct list_head active_devices;
249         struct list_head active_modifiers;
250
251         /* locking */
252         pthread_mutex_t mutex;
253
254         /* UCM internal variables defined in configuration files */
255         struct list_head variable_list;
256
257         /* list of opened control devices */
258         struct list_head ctl_list;
259
260         /* local library configuration */
261         snd_config_t *local_config;
262
263         /* Components don't define cdev, the card device. When executing
264          * a sequence of a component device, ucm manager enters component
265          * domain and needs to provide cdev to the component. This cdev
266          * should be defined by the machine, parent of the component.
267          */
268         int in_component_domain;
269         char *cdev;
270 };
271
272 #define uc_error SNDERR
273
274 #ifdef UC_MGR_DEBUG
275 #define uc_dbg SNDERR
276 #else
277 #define uc_dbg(fmt, arg...) do { } while (0)
278 #endif
279
280 void uc_mgr_error(const char *fmt, ...);
281 void uc_mgr_stdout(const char *fmt, ...);
282
283 const char *uc_mgr_sysfs_root(void);
284 const char *uc_mgr_config_dir(int format);
285 int uc_mgr_config_load_into(int format, const char *file, snd_config_t *cfg);
286 int uc_mgr_config_load(int format, const char *file, snd_config_t **cfg);
287 int uc_mgr_config_load_file(snd_use_case_mgr_t *uc_mgr,  const char *file, snd_config_t **cfg);
288 int uc_mgr_import_master_config(snd_use_case_mgr_t *uc_mgr);
289 int uc_mgr_scan_master_configs(const char **_list[]);
290
291 int uc_mgr_put_to_dev_list(struct dev_list *dev_list, const char *name);
292 int uc_mgr_remove_device(struct use_case_verb *verb, const char *name);
293 int uc_mgr_rename_device(struct use_case_verb *verb, const char *src,
294                          const char *dst);
295
296 void uc_mgr_free_dev_name_list(struct list_head *base);
297 void uc_mgr_free_sequence_element(struct sequence_element *seq);
298 void uc_mgr_free_transition_element(struct transition_sequence *seq);
299 void uc_mgr_free_verb(snd_use_case_mgr_t *uc_mgr);
300 void uc_mgr_free(snd_use_case_mgr_t *uc_mgr);
301
302 static inline int uc_mgr_has_local_config(snd_use_case_mgr_t *uc_mgr)
303 {
304         return uc_mgr && snd_config_iterator_first(uc_mgr->local_config) !=
305                          snd_config_iterator_end(uc_mgr->local_config);
306 }
307
308 int uc_mgr_card_open(snd_use_case_mgr_t *uc_mgr);
309 void uc_mgr_card_close(snd_use_case_mgr_t *uc_mgr);
310
311 int uc_mgr_open_ctl(snd_use_case_mgr_t *uc_mgr,
312                     struct ctl_list **ctl_list,
313                     const char *device,
314                     int slave);
315
316 struct ctl_list *uc_mgr_get_master_ctl(snd_use_case_mgr_t *uc_mgr);
317 struct ctl_list *uc_mgr_get_ctl_by_card(snd_use_case_mgr_t *uc_mgr, int card);
318 struct ctl_list *uc_mgr_get_ctl_by_name(snd_use_case_mgr_t *uc_mgr,
319                                         const char *name, int idx);
320 snd_ctl_t *uc_mgr_get_ctl(snd_use_case_mgr_t *uc_mgr);
321 void uc_mgr_free_ctl_list(snd_use_case_mgr_t *uc_mgr);
322
323 int uc_mgr_add_value(struct list_head *base, const char *key, char *val);
324
325 const char *uc_mgr_get_variable(snd_use_case_mgr_t *uc_mgr,
326                                 const char *name);
327
328 int uc_mgr_set_variable(snd_use_case_mgr_t *uc_mgr,
329                         const char *name,
330                         const char *val);
331
332 int uc_mgr_get_substituted_value(snd_use_case_mgr_t *uc_mgr,
333                                  char **_rvalue,
334                                  const char *value);
335
336 int uc_mgr_substitute_tree(snd_use_case_mgr_t *uc_mgr,
337                            snd_config_t *node);
338
339 int uc_mgr_config_tree_merge(snd_use_case_mgr_t *uc_mgr,
340                              snd_config_t *parent, snd_config_t *new_ctx,
341                              snd_config_t *before, snd_config_t *after);
342
343 int uc_mgr_evaluate_inplace(snd_use_case_mgr_t *uc_mgr,
344                             snd_config_t *cfg);
345
346 int uc_mgr_evaluate_include(snd_use_case_mgr_t *uc_mgr,
347                             snd_config_t *parent,
348                             snd_config_t *inc);
349
350 int uc_mgr_evaluate_condition(snd_use_case_mgr_t *uc_mgr,
351                               snd_config_t *parent,
352                               snd_config_t *cond);
353
354 int uc_mgr_define_regex(snd_use_case_mgr_t *uc_mgr,
355                         const char *name,
356                         snd_config_t *eval);
357
358 /** The name of the environment variable containing the UCM directory */
359 #define ALSA_CONFIG_UCM_VAR "ALSA_CONFIG_UCM"
360
361 /** The name of the environment variable containing the UCM directory (new syntax) */
362 #define ALSA_CONFIG_UCM2_VAR "ALSA_CONFIG_UCM2"