2010-09-07 15:35:14 +02:00
|
|
|
/*
|
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
|
*
|
2011-03-28 11:04:19 +02:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
* License along with this library; if not, write to the Free Software
|
2017-11-14 14:29:26 +01:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
2010-09-07 15:35:14 +02:00
|
|
|
*
|
|
|
|
|
* Support for the verb/device/modifier core logic and API,
|
|
|
|
|
* command line tool and file parser was kindly sponsored by
|
|
|
|
|
* Texas Instruments Inc.
|
|
|
|
|
* Support for multiple active modifiers and devices,
|
|
|
|
|
* transition sequences, multiple client access and user defined use
|
|
|
|
|
* cases was kindly sponsored by Wolfson Microelectronics PLC.
|
|
|
|
|
*
|
|
|
|
|
* Copyright (C) 2008-2010 SlimLogic Ltd
|
|
|
|
|
* Copyright (C) 2010 Wolfson Microelectronics PLC
|
|
|
|
|
* Copyright (C) 2010 Texas Instruments Inc.
|
|
|
|
|
* Copyright (C) 2010 Red Hat Inc.
|
|
|
|
|
* Authors: Liam Girdwood <lrg@slimlogic.co.uk>
|
|
|
|
|
* Stefan Schmidt <stefan@slimlogic.co.uk>
|
|
|
|
|
* Justin Xu <justinx@slimlogic.co.uk>
|
|
|
|
|
* Jaroslav Kysela <perex@perex.cz>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
#define UC_MGR_DEBUG
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "local.h"
|
2015-10-09 17:47:40 -04:00
|
|
|
#include <pthread.h>
|
2010-09-07 15:35:14 +02:00
|
|
|
#include "use-case.h"
|
|
|
|
|
|
2025-04-14 09:44:40 +02:00
|
|
|
#define SYNTAX_VERSION_MAX 7
|
2019-11-09 11:53:32 +01:00
|
|
|
|
2019-11-04 16:18:07 +01:00
|
|
|
#define MAX_CARD_SHORT_NAME 32
|
2017-01-18 11:52:35 +08:00
|
|
|
#define MAX_CARD_LONG_NAME 80
|
2010-09-07 15:35:14 +02:00
|
|
|
|
2021-03-05 19:55:06 +01:00
|
|
|
#define SEQUENCE_ELEMENT_TYPE_CDEV 1
|
|
|
|
|
#define SEQUENCE_ELEMENT_TYPE_CSET 2
|
|
|
|
|
#define SEQUENCE_ELEMENT_TYPE_SLEEP 3
|
|
|
|
|
#define SEQUENCE_ELEMENT_TYPE_EXEC 4
|
2021-05-11 14:48:16 +02:00
|
|
|
#define SEQUENCE_ELEMENT_TYPE_SHELL 5
|
|
|
|
|
#define SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE 6
|
|
|
|
|
#define SEQUENCE_ELEMENT_TYPE_CSET_TLV 7
|
|
|
|
|
#define SEQUENCE_ELEMENT_TYPE_CSET_NEW 8
|
|
|
|
|
#define SEQUENCE_ELEMENT_TYPE_CTL_REMOVE 9
|
|
|
|
|
#define SEQUENCE_ELEMENT_TYPE_CMPT_SEQ 10
|
|
|
|
|
#define SEQUENCE_ELEMENT_TYPE_SYSSET 11
|
2021-05-14 12:20:18 +02:00
|
|
|
#define SEQUENCE_ELEMENT_TYPE_CFGSAVE 12
|
2022-05-19 10:08:48 +02:00
|
|
|
#define SEQUENCE_ELEMENT_TYPE_DEV_ENABLE_SEQ 13
|
|
|
|
|
#define SEQUENCE_ELEMENT_TYPE_DEV_DISABLE_SEQ 14
|
2022-05-24 16:28:21 +02:00
|
|
|
#define SEQUENCE_ELEMENT_TYPE_DEV_DISABLE_ALL 15
|
2010-09-07 15:35:14 +02:00
|
|
|
|
2010-09-22 14:31:15 +02:00
|
|
|
struct ucm_value {
|
|
|
|
|
struct list_head list;
|
|
|
|
|
char *name;
|
|
|
|
|
char *data;
|
|
|
|
|
};
|
|
|
|
|
|
2016-11-28 13:33:54 +08:00
|
|
|
/* sequence of a component device */
|
|
|
|
|
struct component_sequence {
|
|
|
|
|
struct use_case_device *device; /* component device */
|
|
|
|
|
int enable; /* flag to choose enable or disable list of the device */
|
|
|
|
|
};
|
|
|
|
|
|
2010-09-07 15:35:14 +02:00
|
|
|
struct sequence_element {
|
|
|
|
|
struct list_head list;
|
|
|
|
|
unsigned int type;
|
|
|
|
|
union {
|
2011-08-22 13:35:32 +08:00
|
|
|
long sleep; /* Sleep time in microseconds if sleep element, else 0 */
|
2010-11-23 15:58:14 +01:00
|
|
|
char *cdev;
|
2010-09-07 15:35:14 +02:00
|
|
|
char *cset;
|
|
|
|
|
char *exec;
|
2021-03-23 11:40:30 +01:00
|
|
|
char *sysw;
|
2021-05-14 12:20:18 +02:00
|
|
|
char *cfgsave;
|
2022-05-19 10:08:48 +02:00
|
|
|
char *device;
|
2016-11-28 13:33:54 +08:00
|
|
|
struct component_sequence cmpt_seq; /* component sequence */
|
2010-09-07 15:35:14 +02:00
|
|
|
} data;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Transition sequences. i.e. transition between one verb, device, mod to another
|
|
|
|
|
*/
|
|
|
|
|
struct transition_sequence {
|
|
|
|
|
struct list_head list;
|
|
|
|
|
char *name;
|
|
|
|
|
struct list_head transition_list;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Modifier Supported Devices.
|
|
|
|
|
*/
|
2011-06-03 14:56:31 -06:00
|
|
|
enum dev_list_type {
|
|
|
|
|
DEVLIST_NONE,
|
|
|
|
|
DEVLIST_SUPPORTED,
|
|
|
|
|
DEVLIST_CONFLICTING
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct dev_list_node {
|
2010-09-07 15:35:14 +02:00
|
|
|
struct list_head list;
|
|
|
|
|
char *name;
|
|
|
|
|
};
|
|
|
|
|
|
2011-06-03 14:56:31 -06:00
|
|
|
struct dev_list {
|
|
|
|
|
enum dev_list_type type;
|
|
|
|
|
struct list_head list;
|
|
|
|
|
};
|
2010-09-07 15:35:14 +02:00
|
|
|
|
2019-11-04 14:42:45 +01:00
|
|
|
struct ctl_dev {
|
|
|
|
|
struct list_head list;
|
|
|
|
|
char *device;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct ctl_list {
|
|
|
|
|
struct list_head list;
|
|
|
|
|
struct list_head dev_list;
|
|
|
|
|
snd_ctl_t *ctl;
|
2019-11-05 10:06:37 +01:00
|
|
|
snd_ctl_card_info_t *ctl_info;
|
2020-06-03 17:12:19 +02:00
|
|
|
int slave;
|
2021-04-23 17:24:36 +02:00
|
|
|
int ucm_group;
|
2019-11-04 14:42:45 +01:00
|
|
|
};
|
|
|
|
|
|
2020-02-07 10:09:07 +01:00
|
|
|
struct ucm_dev_name {
|
|
|
|
|
struct list_head list;
|
|
|
|
|
char *name1;
|
|
|
|
|
char *name2;
|
|
|
|
|
};
|
|
|
|
|
|
2010-09-07 15:35:14 +02:00
|
|
|
/*
|
|
|
|
|
* Describes a Use Case Modifier and it's enable and disable sequences.
|
|
|
|
|
* A use case verb can have N modifiers.
|
|
|
|
|
*/
|
|
|
|
|
struct use_case_modifier {
|
|
|
|
|
struct list_head list;
|
|
|
|
|
struct list_head active_list;
|
|
|
|
|
|
|
|
|
|
char *name;
|
|
|
|
|
char *comment;
|
|
|
|
|
|
|
|
|
|
/* modifier enable and disable sequences */
|
|
|
|
|
struct list_head enable_list;
|
|
|
|
|
struct list_head disable_list;
|
|
|
|
|
|
|
|
|
|
/* modifier transition list */
|
|
|
|
|
struct list_head transition_list;
|
|
|
|
|
|
2011-06-03 14:56:31 -06:00
|
|
|
/* list of devices supported or conflicting */
|
|
|
|
|
struct dev_list dev_list;
|
2010-09-07 15:35:14 +02:00
|
|
|
|
2010-09-22 14:31:15 +02:00
|
|
|
/* values */
|
|
|
|
|
struct list_head value_list;
|
2010-09-07 15:35:14 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Describes a Use Case Device and it's enable and disable sequences.
|
|
|
|
|
* A use case verb can have N devices.
|
|
|
|
|
*/
|
|
|
|
|
struct use_case_device {
|
|
|
|
|
struct list_head list;
|
|
|
|
|
struct list_head active_list;
|
|
|
|
|
|
|
|
|
|
char *name;
|
|
|
|
|
char *comment;
|
|
|
|
|
|
|
|
|
|
/* device enable and disable sequences */
|
|
|
|
|
struct list_head enable_list;
|
|
|
|
|
struct list_head disable_list;
|
|
|
|
|
|
|
|
|
|
/* device transition list */
|
|
|
|
|
struct list_head transition_list;
|
|
|
|
|
|
2011-06-03 14:56:31 -06:00
|
|
|
/* list of devices supported or conflicting */
|
|
|
|
|
struct dev_list dev_list;
|
|
|
|
|
|
2010-09-22 14:31:15 +02:00
|
|
|
/* value list */
|
|
|
|
|
struct list_head value_list;
|
2010-09-07 15:35:14 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Describes a Use Case Verb and it's enable and disable sequences.
|
|
|
|
|
* A use case verb can have N devices and N modifiers.
|
|
|
|
|
*/
|
|
|
|
|
struct use_case_verb {
|
|
|
|
|
struct list_head list;
|
|
|
|
|
|
|
|
|
|
unsigned int active: 1;
|
|
|
|
|
|
|
|
|
|
char *name;
|
|
|
|
|
char *comment;
|
|
|
|
|
|
|
|
|
|
/* verb enable and disable sequences */
|
|
|
|
|
struct list_head enable_list;
|
|
|
|
|
struct list_head disable_list;
|
|
|
|
|
|
|
|
|
|
/* verb transition list */
|
|
|
|
|
struct list_head transition_list;
|
|
|
|
|
|
|
|
|
|
struct list_head device_list;
|
|
|
|
|
|
2016-11-28 13:33:54 +08:00
|
|
|
/* component device list */
|
|
|
|
|
struct list_head cmpt_device_list;
|
|
|
|
|
|
2010-09-07 15:35:14 +02:00
|
|
|
/* modifiers that can be used with this use case */
|
|
|
|
|
struct list_head modifier_list;
|
2010-09-22 14:31:15 +02:00
|
|
|
|
|
|
|
|
/* value list */
|
|
|
|
|
struct list_head value_list;
|
2020-02-07 10:09:07 +01:00
|
|
|
|
|
|
|
|
/* temporary modifications lists */
|
|
|
|
|
struct list_head rename_list;
|
|
|
|
|
struct list_head remove_list;
|
2010-09-07 15:35:14 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Manages a sound card and all its use cases.
|
|
|
|
|
*/
|
|
|
|
|
struct snd_use_case_mgr {
|
|
|
|
|
char *card_name;
|
2020-01-15 10:31:56 +01:00
|
|
|
char *conf_file_name;
|
|
|
|
|
char *conf_dir_name;
|
2010-09-07 15:35:14 +02:00
|
|
|
char *comment;
|
2019-11-09 11:53:32 +01:00
|
|
|
int conf_format;
|
2021-04-12 18:09:21 +02:00
|
|
|
unsigned int ucm_card_number;
|
2021-10-28 11:48:54 +02:00
|
|
|
int suppress_nodev_errors;
|
2022-05-18 13:10:35 +02:00
|
|
|
const char *parse_variant;
|
|
|
|
|
int parse_master_section;
|
2022-05-19 10:08:48 +02:00
|
|
|
int sequence_hops;
|
2021-04-12 18:09:21 +02:00
|
|
|
|
|
|
|
|
/* UCM cards list */
|
|
|
|
|
struct list_head cards_list;
|
2010-09-07 15:35:14 +02:00
|
|
|
|
|
|
|
|
/* use case verb, devices and modifier configs parsed from files */
|
|
|
|
|
struct list_head verb_list;
|
|
|
|
|
|
2021-03-05 18:50:02 +01:00
|
|
|
/* force boot settings - sequence */
|
|
|
|
|
struct list_head fixedboot_list;
|
|
|
|
|
|
2020-05-14 16:03:00 +02:00
|
|
|
/* boot settings - sequence */
|
2020-10-06 10:47:11 +02:00
|
|
|
struct list_head boot_list;
|
2020-05-14 16:03:00 +02:00
|
|
|
|
2010-09-07 15:35:14 +02:00
|
|
|
/* default settings - sequence */
|
|
|
|
|
struct list_head default_list;
|
2020-05-14 16:12:23 +02:00
|
|
|
int default_list_executed;
|
2010-09-07 15:35:14 +02:00
|
|
|
|
2010-11-29 15:41:34 +01:00
|
|
|
/* default settings - value list */
|
|
|
|
|
struct list_head value_list;
|
|
|
|
|
|
2010-09-07 15:35:14 +02:00
|
|
|
/* current status */
|
|
|
|
|
struct use_case_verb *active_verb;
|
|
|
|
|
struct list_head active_devices;
|
|
|
|
|
struct list_head active_modifiers;
|
|
|
|
|
|
|
|
|
|
/* locking */
|
|
|
|
|
pthread_mutex_t mutex;
|
2010-11-29 17:33:27 +01:00
|
|
|
|
2020-05-20 19:04:36 +02:00
|
|
|
/* UCM internal variables defined in configuration files */
|
|
|
|
|
struct list_head variable_list;
|
|
|
|
|
|
2019-11-04 14:42:45 +01:00
|
|
|
/* list of opened control devices */
|
|
|
|
|
struct list_head ctl_list;
|
2016-11-28 13:34:21 +08:00
|
|
|
|
2022-05-13 16:07:38 +02:00
|
|
|
/* tree with macros */
|
|
|
|
|
snd_config_t *macros;
|
2022-05-17 19:25:20 +02:00
|
|
|
int macro_hops;
|
2022-05-13 16:07:38 +02:00
|
|
|
|
2021-04-12 18:09:21 +02:00
|
|
|
/* local library configuration */
|
|
|
|
|
snd_config_t *local_config;
|
|
|
|
|
|
2016-11-28 13:34:21 +08:00
|
|
|
/* Components don't define cdev, the card device. When executing
|
|
|
|
|
* a sequence of a component device, ucm manager enters component
|
|
|
|
|
* domain and needs to provide cdev to the component. This cdev
|
|
|
|
|
* should be defined by the machine, parent of the component.
|
|
|
|
|
*/
|
|
|
|
|
int in_component_domain;
|
|
|
|
|
char *cdev;
|
2010-09-07 15:35:14 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#define uc_error SNDERR
|
|
|
|
|
|
|
|
|
|
#ifdef UC_MGR_DEBUG
|
|
|
|
|
#define uc_dbg SNDERR
|
|
|
|
|
#else
|
2011-01-31 14:24:19 +01:00
|
|
|
#define uc_dbg(fmt, arg...) do { } while (0)
|
2010-09-07 15:35:14 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void uc_mgr_error(const char *fmt, ...);
|
|
|
|
|
void uc_mgr_stdout(const char *fmt, ...);
|
|
|
|
|
|
2021-03-05 19:55:06 +01:00
|
|
|
const char *uc_mgr_sysfs_root(void);
|
2020-05-16 15:47:19 +02:00
|
|
|
const char *uc_mgr_config_dir(int format);
|
2021-04-12 18:09:21 +02:00
|
|
|
int uc_mgr_config_load_into(int format, const char *file, snd_config_t *cfg);
|
2019-11-09 11:53:32 +01:00
|
|
|
int uc_mgr_config_load(int format, const char *file, snd_config_t **cfg);
|
2020-05-16 15:47:19 +02:00
|
|
|
int uc_mgr_config_load_file(snd_use_case_mgr_t *uc_mgr, const char *file, snd_config_t **cfg);
|
2010-09-07 15:35:14 +02:00
|
|
|
int uc_mgr_import_master_config(snd_use_case_mgr_t *uc_mgr);
|
2010-10-13 11:48:52 +02:00
|
|
|
int uc_mgr_scan_master_configs(const char **_list[]);
|
2010-09-07 15:35:14 +02:00
|
|
|
|
2020-02-07 16:18:11 +01:00
|
|
|
int uc_mgr_put_to_dev_list(struct dev_list *dev_list, const char *name);
|
2020-02-07 10:09:07 +01:00
|
|
|
int uc_mgr_remove_device(struct use_case_verb *verb, const char *name);
|
|
|
|
|
int uc_mgr_rename_device(struct use_case_verb *verb, const char *src,
|
|
|
|
|
const char *dst);
|
|
|
|
|
|
|
|
|
|
void uc_mgr_free_dev_name_list(struct list_head *base);
|
2010-09-07 15:35:14 +02:00
|
|
|
void uc_mgr_free_sequence_element(struct sequence_element *seq);
|
2010-10-26 14:26:46 +02:00
|
|
|
void uc_mgr_free_transition_element(struct transition_sequence *seq);
|
2010-09-07 15:35:14 +02:00
|
|
|
void uc_mgr_free_verb(snd_use_case_mgr_t *uc_mgr);
|
|
|
|
|
void uc_mgr_free(snd_use_case_mgr_t *uc_mgr);
|
2018-11-28 16:25:41 +01:00
|
|
|
|
2021-04-12 18:09:21 +02:00
|
|
|
static inline int uc_mgr_has_local_config(snd_use_case_mgr_t *uc_mgr)
|
|
|
|
|
{
|
2021-04-15 11:49:32 +02:00
|
|
|
return uc_mgr && snd_config_iterator_first(uc_mgr->local_config) !=
|
|
|
|
|
snd_config_iterator_end(uc_mgr->local_config);
|
2021-04-12 18:09:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int uc_mgr_card_open(snd_use_case_mgr_t *uc_mgr);
|
|
|
|
|
void uc_mgr_card_close(snd_use_case_mgr_t *uc_mgr);
|
|
|
|
|
|
2019-11-04 14:42:45 +01:00
|
|
|
int uc_mgr_open_ctl(snd_use_case_mgr_t *uc_mgr,
|
2020-06-03 17:12:19 +02:00
|
|
|
struct ctl_list **ctl_list,
|
|
|
|
|
const char *device,
|
|
|
|
|
int slave);
|
2019-11-04 14:42:45 +01:00
|
|
|
|
2020-06-03 17:12:19 +02:00
|
|
|
struct ctl_list *uc_mgr_get_master_ctl(snd_use_case_mgr_t *uc_mgr);
|
2021-02-02 19:26:24 +01:00
|
|
|
struct ctl_list *uc_mgr_get_ctl_by_card(snd_use_case_mgr_t *uc_mgr, int card);
|
2020-06-03 17:12:19 +02:00
|
|
|
struct ctl_list *uc_mgr_get_ctl_by_name(snd_use_case_mgr_t *uc_mgr,
|
|
|
|
|
const char *name, int idx);
|
2019-11-05 13:02:41 +01:00
|
|
|
snd_ctl_t *uc_mgr_get_ctl(snd_use_case_mgr_t *uc_mgr);
|
2019-11-04 14:42:45 +01:00
|
|
|
void uc_mgr_free_ctl_list(snd_use_case_mgr_t *uc_mgr);
|
|
|
|
|
|
2019-11-05 14:21:07 +01:00
|
|
|
int uc_mgr_add_value(struct list_head *base, const char *key, char *val);
|
|
|
|
|
|
2020-05-20 19:04:36 +02:00
|
|
|
const char *uc_mgr_get_variable(snd_use_case_mgr_t *uc_mgr,
|
|
|
|
|
const char *name);
|
|
|
|
|
|
|
|
|
|
int uc_mgr_set_variable(snd_use_case_mgr_t *uc_mgr,
|
|
|
|
|
const char *name,
|
|
|
|
|
const char *val);
|
|
|
|
|
|
2022-05-13 16:07:38 +02:00
|
|
|
int uc_mgr_delete_variable(snd_use_case_mgr_t *uc_mgr, const char *name);
|
|
|
|
|
|
2019-11-05 13:02:41 +01:00
|
|
|
int uc_mgr_get_substituted_value(snd_use_case_mgr_t *uc_mgr,
|
|
|
|
|
char **_rvalue,
|
|
|
|
|
const char *value);
|
|
|
|
|
|
2020-07-06 16:34:33 +02:00
|
|
|
int uc_mgr_substitute_tree(snd_use_case_mgr_t *uc_mgr,
|
|
|
|
|
snd_config_t *node);
|
|
|
|
|
|
|
|
|
|
int uc_mgr_config_tree_merge(snd_use_case_mgr_t *uc_mgr,
|
|
|
|
|
snd_config_t *parent, snd_config_t *new_ctx,
|
2020-05-16 15:47:19 +02:00
|
|
|
snd_config_t *before, snd_config_t *after);
|
|
|
|
|
|
|
|
|
|
int uc_mgr_evaluate_inplace(snd_use_case_mgr_t *uc_mgr,
|
|
|
|
|
snd_config_t *cfg);
|
|
|
|
|
|
|
|
|
|
int uc_mgr_evaluate_include(snd_use_case_mgr_t *uc_mgr,
|
|
|
|
|
snd_config_t *parent,
|
|
|
|
|
snd_config_t *inc);
|
|
|
|
|
|
2019-11-05 13:02:41 +01:00
|
|
|
int uc_mgr_evaluate_condition(snd_use_case_mgr_t *uc_mgr,
|
|
|
|
|
snd_config_t *parent,
|
|
|
|
|
snd_config_t *cond);
|
|
|
|
|
|
2020-05-19 16:48:43 +02:00
|
|
|
int uc_mgr_define_regex(snd_use_case_mgr_t *uc_mgr,
|
|
|
|
|
const char *name,
|
|
|
|
|
snd_config_t *eval);
|
|
|
|
|
|
2021-05-11 14:48:16 +02:00
|
|
|
int uc_mgr_exec(const char *prog);
|
|
|
|
|
|
2018-11-28 16:25:41 +01:00
|
|
|
/** The name of the environment variable containing the UCM directory */
|
|
|
|
|
#define ALSA_CONFIG_UCM_VAR "ALSA_CONFIG_UCM"
|
2019-11-09 11:53:32 +01:00
|
|
|
|
|
|
|
|
/** The name of the environment variable containing the UCM directory (new syntax) */
|
|
|
|
|
#define ALSA_CONFIG_UCM2_VAR "ALSA_CONFIG_UCM2"
|