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.
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.
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
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.
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>
43 #define SYNTAX_VERSION_MAX 4
45 #define MAX_CARD_SHORT_NAME 32
46 #define MAX_CARD_LONG_NAME 80
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
60 struct list_head list;
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 */
71 struct sequence_element {
72 struct list_head list;
75 long sleep; /* Sleep time in microseconds if sleep element, else 0 */
80 struct component_sequence cmpt_seq; /* component sequence */
85 * Transition sequences. i.e. transition between one verb, device, mod to another
87 struct transition_sequence {
88 struct list_head list;
90 struct list_head transition_list;
94 * Modifier Supported Devices.
102 struct dev_list_node {
103 struct list_head list;
108 enum dev_list_type type;
109 struct list_head list;
113 struct list_head list;
118 struct list_head list;
119 struct list_head dev_list;
121 snd_ctl_card_info_t *ctl_info;
125 struct ucm_dev_name {
126 struct list_head list;
132 * Describes a Use Case Modifier and it's enable and disable sequences.
133 * A use case verb can have N modifiers.
135 struct use_case_modifier {
136 struct list_head list;
137 struct list_head active_list;
142 /* modifier enable and disable sequences */
143 struct list_head enable_list;
144 struct list_head disable_list;
146 /* modifier transition list */
147 struct list_head transition_list;
149 /* list of devices supported or conflicting */
150 struct dev_list dev_list;
153 struct list_head value_list;
157 * Describes a Use Case Device and it's enable and disable sequences.
158 * A use case verb can have N devices.
160 struct use_case_device {
161 struct list_head list;
162 struct list_head active_list;
167 /* device enable and disable sequences */
168 struct list_head enable_list;
169 struct list_head disable_list;
171 /* device transition list */
172 struct list_head transition_list;
174 /* list of devices supported or conflicting */
175 struct dev_list dev_list;
178 struct list_head value_list;
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.
185 struct use_case_verb {
186 struct list_head list;
188 unsigned int active: 1;
193 /* verb enable and disable sequences */
194 struct list_head enable_list;
195 struct list_head disable_list;
197 /* verb transition list */
198 struct list_head transition_list;
200 struct list_head device_list;
202 /* component device list */
203 struct list_head cmpt_device_list;
205 /* modifiers that can be used with this use case */
206 struct list_head modifier_list;
209 struct list_head value_list;
211 /* temporary modifications lists */
212 struct list_head rename_list;
213 struct list_head remove_list;
217 * Manages a sound card and all its use cases.
219 struct snd_use_case_mgr {
221 char *conf_file_name;
225 unsigned int ucm_card_number;
228 struct list_head cards_list;
230 /* use case verb, devices and modifier configs parsed from files */
231 struct list_head verb_list;
233 /* force boot settings - sequence */
234 struct list_head fixedboot_list;
236 /* boot settings - sequence */
237 struct list_head boot_list;
239 /* default settings - sequence */
240 struct list_head default_list;
241 int default_list_executed;
243 /* default settings - value list */
244 struct list_head value_list;
247 struct use_case_verb *active_verb;
248 struct list_head active_devices;
249 struct list_head active_modifiers;
252 pthread_mutex_t mutex;
254 /* UCM internal variables defined in configuration files */
255 struct list_head variable_list;
257 /* list of opened control devices */
258 struct list_head ctl_list;
260 /* local library configuration */
261 snd_config_t *local_config;
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.
268 int in_component_domain;
272 #define uc_error SNDERR
275 #define uc_dbg SNDERR
277 #define uc_dbg(fmt, arg...) do { } while (0)
280 void uc_mgr_error(const char *fmt, ...);
281 void uc_mgr_stdout(const char *fmt, ...);
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[]);
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,
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);
302 static inline int uc_mgr_has_local_config(snd_use_case_mgr_t *uc_mgr)
304 return uc_mgr && snd_config_iterator_first(uc_mgr->local_config) !=
305 snd_config_iterator_end(uc_mgr->local_config);
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);
311 int uc_mgr_open_ctl(snd_use_case_mgr_t *uc_mgr,
312 struct ctl_list **ctl_list,
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);
323 int uc_mgr_add_value(struct list_head *base, const char *key, char *val);
325 const char *uc_mgr_get_variable(snd_use_case_mgr_t *uc_mgr,
328 int uc_mgr_set_variable(snd_use_case_mgr_t *uc_mgr,
332 int uc_mgr_get_substituted_value(snd_use_case_mgr_t *uc_mgr,
336 int uc_mgr_substitute_tree(snd_use_case_mgr_t *uc_mgr,
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);
343 int uc_mgr_evaluate_inplace(snd_use_case_mgr_t *uc_mgr,
346 int uc_mgr_evaluate_include(snd_use_case_mgr_t *uc_mgr,
347 snd_config_t *parent,
350 int uc_mgr_evaluate_condition(snd_use_case_mgr_t *uc_mgr,
351 snd_config_t *parent,
354 int uc_mgr_define_regex(snd_use_case_mgr_t *uc_mgr,
358 /** The name of the environment variable containing the UCM directory */
359 #define ALSA_CONFIG_UCM_VAR "ALSA_CONFIG_UCM"
361 /** The name of the environment variable containing the UCM directory (new syntax) */
362 #define ALSA_CONFIG_UCM2_VAR "ALSA_CONFIG_UCM2"