mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	ucm: implement CardIdByName substitution
The syntax is ${CardIdByName:CARDNAME[#INDEX]}.
The CARDNAME is the ALSA's soundcard name (short form).
The INDEX is the instance (0 = first, 1 = second etc.).
Example: ${CardIdByName:HDA Intel PCH}
(which is identical to ${CardIdByName:HDA Intel PCH#0})
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
			
			
This commit is contained in:
		
							parent
							
								
									f60e0d5fdc
								
							
						
					
					
						commit
						eee879d381
					
				
					 6 changed files with 135 additions and 56 deletions
				
			
		| 
						 | 
				
			
			@ -333,6 +333,7 @@ static int execute_sequence(snd_use_case_mgr_t *uc_mgr,
 | 
			
		|||
	struct sequence_element *s;
 | 
			
		||||
	char *cdev = NULL;
 | 
			
		||||
	snd_ctl_t *ctl = NULL;
 | 
			
		||||
	struct ctl_list *ctl_list;
 | 
			
		||||
	int err = 0;
 | 
			
		||||
 | 
			
		||||
	list_for_each(pos, seq) {
 | 
			
		||||
| 
						 | 
				
			
			@ -400,11 +401,12 @@ static int execute_sequence(snd_use_case_mgr_t *uc_mgr,
 | 
			
		|||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (ctl == NULL) {
 | 
			
		||||
				err = uc_mgr_open_ctl(uc_mgr, &ctl, cdev);
 | 
			
		||||
				err = uc_mgr_open_ctl(uc_mgr, &ctl_list, cdev, 1);
 | 
			
		||||
				if (err < 0) {
 | 
			
		||||
					uc_error("unable to open ctl device '%s'", cdev);
 | 
			
		||||
					goto __fail;
 | 
			
		||||
				}
 | 
			
		||||
				ctl = ctl_list->ctl;
 | 
			
		||||
			}
 | 
			
		||||
			err = execute_cset(ctl, s->data.cset, s->type);
 | 
			
		||||
			if (err < 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -516,7 +518,7 @@ static int add_auto_values(snd_use_case_mgr_t *uc_mgr)
 | 
			
		|||
	char buf[40];
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
	ctl_list = uc_mgr_get_one_ctl(uc_mgr);
 | 
			
		||||
	ctl_list = uc_mgr_get_master_ctl(uc_mgr);
 | 
			
		||||
	if (ctl_list) {
 | 
			
		||||
		id = snd_ctl_card_info_get_id(ctl_list->ctl_info);
 | 
			
		||||
		snprintf(buf, sizeof(buf), "hw:%s", id);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1901,25 +1901,16 @@ static int parse_master_file(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg)
 | 
			
		|||
/* get the card info */
 | 
			
		||||
static int get_card_info(snd_use_case_mgr_t *mgr,
 | 
			
		||||
			 const char *ctl_name,
 | 
			
		||||
			 snd_ctl_t **_handle,
 | 
			
		||||
			 snd_ctl_card_info_t *info)
 | 
			
		||||
			 snd_ctl_card_info_t **info)
 | 
			
		||||
{
 | 
			
		||||
	snd_ctl_t *handle;
 | 
			
		||||
	struct ctl_list *ctl_list;
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
	*_handle = NULL;
 | 
			
		||||
 | 
			
		||||
	err = uc_mgr_open_ctl(mgr, &handle, ctl_name);
 | 
			
		||||
	err = uc_mgr_open_ctl(mgr, &ctl_list, ctl_name, 0);
 | 
			
		||||
	if (err < 0)
 | 
			
		||||
		return err;
 | 
			
		||||
 | 
			
		||||
	err = snd_ctl_card_info(handle, info);
 | 
			
		||||
	if (err < 0) {
 | 
			
		||||
		uc_error("control hardware info (%s): %s", ctl_name, snd_strerror(err));
 | 
			
		||||
	} else {
 | 
			
		||||
		*_handle = handle;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*info = ctl_list->ctl_info;
 | 
			
		||||
	return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1927,7 +1918,6 @@ static int get_card_info(snd_use_case_mgr_t *mgr,
 | 
			
		|||
static int get_by_card_name(snd_use_case_mgr_t *mgr, const char *card_name)
 | 
			
		||||
{
 | 
			
		||||
	int card, err;
 | 
			
		||||
	snd_ctl_t *ctl;
 | 
			
		||||
	snd_ctl_card_info_t *info;
 | 
			
		||||
	const char *_driver, *_name, *_long_name;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1942,11 +1932,11 @@ static int get_by_card_name(snd_use_case_mgr_t *mgr, const char *card_name)
 | 
			
		|||
	while (card >= 0) {
 | 
			
		||||
		char name[32];
 | 
			
		||||
 | 
			
		||||
		/* mandatory - clear the list, keep the only one CTL device */
 | 
			
		||||
		/* clear the list, keep the only one CTL device */
 | 
			
		||||
		uc_mgr_free_ctl_list(mgr);
 | 
			
		||||
 | 
			
		||||
		sprintf(name, "hw:%d", card);
 | 
			
		||||
		err = get_card_info(mgr, name, &ctl, info);
 | 
			
		||||
		err = get_card_info(mgr, name, &info);
 | 
			
		||||
 | 
			
		||||
		if (err == 0) {
 | 
			
		||||
			_driver = snd_ctl_card_info_get_driver(info);
 | 
			
		||||
| 
						 | 
				
			
			@ -1972,13 +1962,12 @@ static int get_by_card_name(snd_use_case_mgr_t *mgr, const char *card_name)
 | 
			
		|||
/* set the driver name and long name by the card ctl name */
 | 
			
		||||
static int get_by_card(snd_use_case_mgr_t *mgr, const char *ctl_name)
 | 
			
		||||
{
 | 
			
		||||
	snd_ctl_t *ctl;
 | 
			
		||||
	snd_ctl_card_info_t *info;
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
	snd_ctl_card_info_alloca(&info);
 | 
			
		||||
 | 
			
		||||
	err = get_card_info(mgr, ctl_name, &ctl, info);
 | 
			
		||||
	err = get_card_info(mgr, ctl_name, &info);
 | 
			
		||||
	if (err)
 | 
			
		||||
		return err;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -228,7 +228,7 @@ static int if_eval_control_exists(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval
 | 
			
		|||
		err = uc_mgr_get_substituted_value(uc_mgr, &s, device);
 | 
			
		||||
		if (err < 0)
 | 
			
		||||
			return err;
 | 
			
		||||
		err = uc_mgr_open_ctl(uc_mgr, &ctl, s);
 | 
			
		||||
		err = uc_mgr_open_ctl(uc_mgr, &ctl, s, 1);
 | 
			
		||||
		free(s);
 | 
			
		||||
		if (err < 0)
 | 
			
		||||
			return err;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,6 +115,7 @@ struct ctl_list {
 | 
			
		|||
	struct list_head dev_list;
 | 
			
		||||
	snd_ctl_t *ctl;
 | 
			
		||||
	snd_ctl_card_info_t *ctl_info;
 | 
			
		||||
	int slave;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ucm_dev_name {
 | 
			
		||||
| 
						 | 
				
			
			@ -283,10 +284,13 @@ void uc_mgr_free_verb(snd_use_case_mgr_t *uc_mgr);
 | 
			
		|||
void uc_mgr_free(snd_use_case_mgr_t *uc_mgr);
 | 
			
		||||
 | 
			
		||||
int uc_mgr_open_ctl(snd_use_case_mgr_t *uc_mgr,
 | 
			
		||||
                    snd_ctl_t **ctl,
 | 
			
		||||
                    const char *device);
 | 
			
		||||
		    struct ctl_list **ctl_list,
 | 
			
		||||
		    const char *device,
 | 
			
		||||
		    int slave);
 | 
			
		||||
 | 
			
		||||
struct ctl_list *uc_mgr_get_one_ctl(snd_use_case_mgr_t *uc_mgr);
 | 
			
		||||
struct ctl_list *uc_mgr_get_master_ctl(snd_use_case_mgr_t *uc_mgr);
 | 
			
		||||
struct ctl_list *uc_mgr_get_ctl_by_name(snd_use_case_mgr_t *uc_mgr,
 | 
			
		||||
					const char *name, int idx);
 | 
			
		||||
snd_ctl_t *uc_mgr_get_ctl(snd_use_case_mgr_t *uc_mgr);
 | 
			
		||||
void uc_mgr_free_ctl_list(snd_use_case_mgr_t *uc_mgr);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,7 +73,7 @@ static char *rval_card_number(snd_use_case_mgr_t *uc_mgr)
 | 
			
		|||
 | 
			
		||||
	if (uc_mgr->conf_format < 3)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	ctl_list = uc_mgr_get_one_ctl(uc_mgr);
 | 
			
		||||
	ctl_list = uc_mgr_get_master_ctl(uc_mgr);
 | 
			
		||||
	if (ctl_list == NULL)
 | 
			
		||||
		return strdup("");
 | 
			
		||||
	snprintf(num, sizeof(num), "%i", snd_ctl_card_info_get_card(ctl_list->ctl_info));
 | 
			
		||||
| 
						 | 
				
			
			@ -84,7 +84,7 @@ static char *rval_card_id(snd_use_case_mgr_t *uc_mgr)
 | 
			
		|||
{
 | 
			
		||||
	struct ctl_list *ctl_list;
 | 
			
		||||
 | 
			
		||||
	ctl_list = uc_mgr_get_one_ctl(uc_mgr);
 | 
			
		||||
	ctl_list = uc_mgr_get_master_ctl(uc_mgr);
 | 
			
		||||
	if (ctl_list == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	return strdup(snd_ctl_card_info_get_id(ctl_list->ctl_info));
 | 
			
		||||
| 
						 | 
				
			
			@ -94,7 +94,7 @@ static char *rval_card_driver(snd_use_case_mgr_t *uc_mgr)
 | 
			
		|||
{
 | 
			
		||||
	struct ctl_list *ctl_list;
 | 
			
		||||
 | 
			
		||||
	ctl_list = uc_mgr_get_one_ctl(uc_mgr);
 | 
			
		||||
	ctl_list = uc_mgr_get_master_ctl(uc_mgr);
 | 
			
		||||
	if (ctl_list == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	return strdup(snd_ctl_card_info_get_driver(ctl_list->ctl_info));
 | 
			
		||||
| 
						 | 
				
			
			@ -104,7 +104,7 @@ static char *rval_card_name(snd_use_case_mgr_t *uc_mgr)
 | 
			
		|||
{
 | 
			
		||||
	struct ctl_list *ctl_list;
 | 
			
		||||
 | 
			
		||||
	ctl_list = uc_mgr_get_one_ctl(uc_mgr);
 | 
			
		||||
	ctl_list = uc_mgr_get_master_ctl(uc_mgr);
 | 
			
		||||
	if (ctl_list == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	return strdup(snd_ctl_card_info_get_name(ctl_list->ctl_info));
 | 
			
		||||
| 
						 | 
				
			
			@ -114,7 +114,7 @@ static char *rval_card_longname(snd_use_case_mgr_t *uc_mgr)
 | 
			
		|||
{
 | 
			
		||||
	struct ctl_list *ctl_list;
 | 
			
		||||
 | 
			
		||||
	ctl_list = uc_mgr_get_one_ctl(uc_mgr);
 | 
			
		||||
	ctl_list = uc_mgr_get_master_ctl(uc_mgr);
 | 
			
		||||
	if (ctl_list == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	return strdup(snd_ctl_card_info_get_longname(ctl_list->ctl_info));
 | 
			
		||||
| 
						 | 
				
			
			@ -124,12 +124,37 @@ static char *rval_card_components(snd_use_case_mgr_t *uc_mgr)
 | 
			
		|||
{
 | 
			
		||||
	struct ctl_list *ctl_list;
 | 
			
		||||
 | 
			
		||||
	ctl_list = uc_mgr_get_one_ctl(uc_mgr);
 | 
			
		||||
	ctl_list = uc_mgr_get_master_ctl(uc_mgr);
 | 
			
		||||
	if (ctl_list == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	return strdup(snd_ctl_card_info_get_components(ctl_list->ctl_info));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *rval_card_id_by_name(snd_use_case_mgr_t *uc_mgr, const char *id)
 | 
			
		||||
{
 | 
			
		||||
	struct ctl_list *ctl_list;
 | 
			
		||||
	char *name, *index;
 | 
			
		||||
	long idx = 0;
 | 
			
		||||
 | 
			
		||||
	if (uc_mgr->conf_format < 3) {
 | 
			
		||||
		uc_error("CardIdByName substitution is supported in v3+ syntax");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	name = alloca(strlen(id) + 1);
 | 
			
		||||
	strcpy(name, id);
 | 
			
		||||
	index = strchr(name, '#');
 | 
			
		||||
	if (index) {
 | 
			
		||||
		*index = '\0';
 | 
			
		||||
		if (safe_strtol(index + 1, &idx))
 | 
			
		||||
			return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	ctl_list = uc_mgr_get_ctl_by_name(uc_mgr, name, idx);
 | 
			
		||||
	if (ctl_list == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	return strdup(snd_ctl_card_info_get_id(ctl_list->ctl_info));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *rval_env(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED, const char *id)
 | 
			
		||||
{
 | 
			
		||||
	char *e;
 | 
			
		||||
| 
						 | 
				
			
			@ -265,6 +290,7 @@ int uc_mgr_get_substituted_value(snd_use_case_mgr_t *uc_mgr,
 | 
			
		|||
			MATCH_VARIABLE2(value, "${env:", rval_env);
 | 
			
		||||
			MATCH_VARIABLE2(value, "${sys:", rval_sysfs);
 | 
			
		||||
			MATCH_VARIABLE2(value, "${var:", rval_var);
 | 
			
		||||
			MATCH_VARIABLE2(value, "${CardIdByName:", rval_card_id_by_name);
 | 
			
		||||
			err = -EINVAL;
 | 
			
		||||
			tmp = strchr(value, '}');
 | 
			
		||||
			if (tmp) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										110
									
								
								src/ucm/utils.c
									
										
									
									
									
								
							
							
						
						
									
										110
									
								
								src/ucm/utils.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -49,26 +49,73 @@ void uc_mgr_stdout(const char *fmt,...)
 | 
			
		|||
	va_end(va);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct ctl_list *uc_mgr_get_one_ctl(snd_use_case_mgr_t *uc_mgr)
 | 
			
		||||
struct ctl_list *uc_mgr_get_master_ctl(snd_use_case_mgr_t *uc_mgr)
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *pos;
 | 
			
		||||
	struct ctl_list *ctl_list = NULL;
 | 
			
		||||
	struct ctl_list *ctl_list = NULL, *ctl_list2;
 | 
			
		||||
 | 
			
		||||
	list_for_each(pos, &uc_mgr->ctl_list) {
 | 
			
		||||
		ctl_list2 = list_entry(pos, struct ctl_list, list);
 | 
			
		||||
		if (ctl_list2->slave)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (ctl_list) {
 | 
			
		||||
			uc_error("multiple control device names were found!");
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
		ctl_list = list_entry(pos, struct ctl_list, list);
 | 
			
		||||
		ctl_list = ctl_list2;
 | 
			
		||||
	}
 | 
			
		||||
	return ctl_list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct ctl_list *uc_mgr_get_ctl_by_name(snd_use_case_mgr_t *uc_mgr, const char *name, int idx)
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *pos;
 | 
			
		||||
	struct ctl_list *ctl_list = NULL;
 | 
			
		||||
	const char *s;
 | 
			
		||||
	char cname[32];
 | 
			
		||||
	int idx2, card, err;
 | 
			
		||||
 | 
			
		||||
	idx2 = idx;
 | 
			
		||||
	list_for_each(pos, &uc_mgr->ctl_list) {
 | 
			
		||||
		ctl_list = list_entry(pos, struct ctl_list, list);
 | 
			
		||||
		s = snd_ctl_card_info_get_name(ctl_list->ctl_info);
 | 
			
		||||
		if (s == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (strcmp(s, name) == 0) {
 | 
			
		||||
			if (idx2 == 0)
 | 
			
		||||
				return ctl_list;
 | 
			
		||||
			idx2--;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	idx2 = idx;
 | 
			
		||||
	card = -1;
 | 
			
		||||
	if (snd_card_next(&card) < 0 || card < 0)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	while (card >= 0) {
 | 
			
		||||
		sprintf(cname, "hw:%d", card);
 | 
			
		||||
		err = uc_mgr_open_ctl(uc_mgr, &ctl_list, cname, 1);
 | 
			
		||||
		if (err < 0)
 | 
			
		||||
			continue;	/* really? */
 | 
			
		||||
		s = snd_ctl_card_info_get_name(ctl_list->ctl_info);
 | 
			
		||||
		if (s && strcmp(s, name) == 0) {
 | 
			
		||||
			if (idx2 == 0)
 | 
			
		||||
				return ctl_list;
 | 
			
		||||
			idx2--;
 | 
			
		||||
		}
 | 
			
		||||
		if (snd_card_next(&card) < 0)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
snd_ctl_t *uc_mgr_get_ctl(snd_use_case_mgr_t *uc_mgr)
 | 
			
		||||
{
 | 
			
		||||
	struct ctl_list *ctl_list;
 | 
			
		||||
 | 
			
		||||
	ctl_list = uc_mgr_get_one_ctl(uc_mgr);
 | 
			
		||||
	ctl_list = uc_mgr_get_master_ctl(uc_mgr);
 | 
			
		||||
	if (ctl_list)
 | 
			
		||||
		return ctl_list->ctl;
 | 
			
		||||
	return NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -127,10 +174,11 @@ static int uc_mgr_ctl_add_dev(struct ctl_list *ctl_list, const char *device)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static int uc_mgr_ctl_add(snd_use_case_mgr_t *uc_mgr,
 | 
			
		||||
			  struct ctl_list *ctl_list,
 | 
			
		||||
			  struct ctl_list **ctl_list,
 | 
			
		||||
			  snd_ctl_t *ctl, int card,
 | 
			
		||||
			  snd_ctl_card_info_t *info,
 | 
			
		||||
			  const char *device)
 | 
			
		||||
			  const char *device,
 | 
			
		||||
			  int slave)
 | 
			
		||||
{
 | 
			
		||||
	struct ctl_list *cl = NULL;
 | 
			
		||||
	const char *id = snd_ctl_card_info_get_id(info);
 | 
			
		||||
| 
						 | 
				
			
			@ -139,7 +187,7 @@ static int uc_mgr_ctl_add(snd_use_case_mgr_t *uc_mgr,
 | 
			
		|||
 | 
			
		||||
	if (id == NULL || id[0] == '\0')
 | 
			
		||||
		return -ENOENT;
 | 
			
		||||
	if (!ctl_list) {
 | 
			
		||||
	if (!(*ctl_list)) {
 | 
			
		||||
		cl = malloc(sizeof(*cl));
 | 
			
		||||
		if (cl == NULL)
 | 
			
		||||
			return -ENOMEM;
 | 
			
		||||
| 
						 | 
				
			
			@ -150,41 +198,49 @@ static int uc_mgr_ctl_add(snd_use_case_mgr_t *uc_mgr,
 | 
			
		|||
			return -ENOMEM;
 | 
			
		||||
		}
 | 
			
		||||
		snd_ctl_card_info_copy(cl->ctl_info, info);
 | 
			
		||||
		ctl_list = cl;
 | 
			
		||||
		cl->slave = slave;
 | 
			
		||||
		*ctl_list = cl;
 | 
			
		||||
	} else {
 | 
			
		||||
		if (!slave)
 | 
			
		||||
			(*ctl_list)->slave = slave;
 | 
			
		||||
	}
 | 
			
		||||
	if (card >= 0) {
 | 
			
		||||
		snprintf(dev, sizeof(dev), "hw:%d", card);
 | 
			
		||||
		hit |= !!(device && (strcmp(dev, device) == 0));
 | 
			
		||||
		err = uc_mgr_ctl_add_dev(ctl_list, dev);
 | 
			
		||||
		err = uc_mgr_ctl_add_dev(*ctl_list, dev);
 | 
			
		||||
		if (err < 0)
 | 
			
		||||
			goto __nomem;
 | 
			
		||||
	}
 | 
			
		||||
	snprintf(dev, sizeof(dev), "hw:%s", id);
 | 
			
		||||
	hit |= !!(device && (strcmp(dev, device) == 0));
 | 
			
		||||
	err = uc_mgr_ctl_add_dev(ctl_list, dev);
 | 
			
		||||
	err = uc_mgr_ctl_add_dev(*ctl_list, dev);
 | 
			
		||||
	if (err < 0)
 | 
			
		||||
		goto __nomem;
 | 
			
		||||
	/* the UCM name not based on the card name / id */
 | 
			
		||||
	if (!hit && device) {
 | 
			
		||||
		err = uc_mgr_ctl_add_dev(ctl_list, device);
 | 
			
		||||
		err = uc_mgr_ctl_add_dev(*ctl_list, device);
 | 
			
		||||
		if (err < 0)
 | 
			
		||||
			goto __nomem;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	list_add_tail(&ctl_list->list, &uc_mgr->ctl_list);
 | 
			
		||||
	list_add_tail(&(*ctl_list)->list, &uc_mgr->ctl_list);
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
__nomem:
 | 
			
		||||
	if (ctl_list == cl)
 | 
			
		||||
	if (*ctl_list == cl) {
 | 
			
		||||
		uc_mgr_free_ctl(cl);
 | 
			
		||||
		*ctl_list = NULL;
 | 
			
		||||
	}
 | 
			
		||||
	return -ENOMEM;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int uc_mgr_open_ctl(snd_use_case_mgr_t *uc_mgr,
 | 
			
		||||
		    snd_ctl_t **ctl,
 | 
			
		||||
		    const char *device)
 | 
			
		||||
		    struct ctl_list **ctll,
 | 
			
		||||
		    const char *device,
 | 
			
		||||
		    int slave)
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *pos1, *pos2;
 | 
			
		||||
	snd_ctl_t *ctl;
 | 
			
		||||
	struct ctl_list *ctl_list;
 | 
			
		||||
	struct ctl_dev *ctl_dev;
 | 
			
		||||
	snd_ctl_card_info_t *info;
 | 
			
		||||
| 
						 | 
				
			
			@ -199,24 +255,25 @@ int uc_mgr_open_ctl(snd_use_case_mgr_t *uc_mgr,
 | 
			
		|||
		list_for_each(pos2, &ctl_list->dev_list) {
 | 
			
		||||
			ctl_dev = list_entry(pos2, struct ctl_dev, list);
 | 
			
		||||
			if (strcmp(ctl_dev->device, device) == 0) {
 | 
			
		||||
				*ctl = ctl_list->ctl;
 | 
			
		||||
				*ctll = ctl_list;
 | 
			
		||||
				if (!slave)
 | 
			
		||||
					ctl_list->slave = 0;
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = snd_ctl_open(ctl, device, 0);
 | 
			
		||||
	err = snd_ctl_open(&ctl, device, 0);
 | 
			
		||||
	if (err < 0)
 | 
			
		||||
		return err;
 | 
			
		||||
 | 
			
		||||
	id = NULL;
 | 
			
		||||
	err = snd_ctl_card_info(*ctl, info);
 | 
			
		||||
	err = snd_ctl_card_info(ctl, info);
 | 
			
		||||
	if (err == 0)
 | 
			
		||||
		id = snd_ctl_card_info_get_id(info);
 | 
			
		||||
	if (err < 0 || id == NULL || id[0] == '\0') {
 | 
			
		||||
		uc_error("control hardware info (%s): %s", device, snd_strerror(err));
 | 
			
		||||
		snd_ctl_close(*ctl);
 | 
			
		||||
		*ctl = NULL;
 | 
			
		||||
		snd_ctl_close(ctl);
 | 
			
		||||
		return err;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -225,24 +282,25 @@ int uc_mgr_open_ctl(snd_use_case_mgr_t *uc_mgr,
 | 
			
		|||
		ctl_list = list_entry(pos1, struct ctl_list, list);
 | 
			
		||||
		if (strcmp(id, snd_ctl_card_info_get_id(ctl_list->ctl_info)) == 0) {
 | 
			
		||||
			card = snd_card_get_index(id);
 | 
			
		||||
			err = uc_mgr_ctl_add(uc_mgr, ctl_list, *ctl, card, info, device);
 | 
			
		||||
			err = uc_mgr_ctl_add(uc_mgr, &ctl_list, ctl, card, info, device, slave);
 | 
			
		||||
			if (err < 0)
 | 
			
		||||
				goto __nomem;
 | 
			
		||||
			snd_ctl_close(*ctl);
 | 
			
		||||
			*ctl = ctl_list->ctl;
 | 
			
		||||
			snd_ctl_close(ctl);
 | 
			
		||||
			*ctll = ctl_list;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = uc_mgr_ctl_add(uc_mgr, NULL, *ctl, -1, info, device);
 | 
			
		||||
	ctl_list = NULL;
 | 
			
		||||
	err = uc_mgr_ctl_add(uc_mgr, &ctl_list, ctl, -1, info, device, slave);
 | 
			
		||||
	if (err < 0)
 | 
			
		||||
		goto __nomem;
 | 
			
		||||
 | 
			
		||||
	*ctll = ctl_list;
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
__nomem:
 | 
			
		||||
	snd_ctl_close(*ctl);
 | 
			
		||||
	*ctl = NULL;
 | 
			
		||||
	snd_ctl_close(ctl);
 | 
			
		||||
	return -ENOMEM;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue