Home | History | Annotate | Download | only in server
      1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
      2  * Use of this source code is governed by a BSD-style license that can be
      3  * found in the LICENSE file.
      4  */
      5 
      6 #include <alsa/asoundlib.h>
      7 #include <limits.h>
      8 #include <stdio.h>
      9 #include <syslog.h>
     10 
     11 #include "cras_alsa_mixer.h"
     12 #include "cras_alsa_mixer_name.h"
     13 #include "cras_alsa_ucm.h"
     14 #include "cras_util.h"
     15 #include "utlist.h"
     16 
     17 #define MIXER_CONTROL_VOLUME_DB_INVALID LONG_MAX
     18 
     19 /* Represents an ALSA control element. Each device can have several of these,
     20  * each potentially having independent volume and mute controls.
     21  * elem - ALSA mixer element.
     22  * has_volume - non-zero indicates there is a volume control.
     23  * has_mute - non-zero indicates there is a mute switch.
     24  * max_volume_dB - the maximum volume for this control, or
     25  *                 MIXER_CONTROL_VOLUME_DB_INVALID.
     26  * min_volume_dB - the minimum volume for this control, or
     27  *                 MIXER_CONTROL_VOLUME_DB_INVALID.
     28  */
     29 struct mixer_control_element {
     30 	snd_mixer_elem_t *elem;
     31 	int has_volume;
     32 	int has_mute;
     33 	long max_volume_dB;
     34 	long min_volume_dB;
     35 	struct mixer_control_element *prev, *next;
     36 };
     37 
     38 /* Represents an ALSA control element related to a specific input/output
     39  * node such as speakers or headphones. A device can have several of these,
     40  * each potentially having independent volume and mute controls.
     41  *
     42  * Each will have at least one mixer_control_element. For cases where there
     43  * are separate control elements for left/right channels (for example),
     44  * additional mixer_control_elements are added.
     45  *
     46  * For controls with volume it is assumed that all elements have the same
     47  * range.
     48  *
     49  * name - Name of the control (typicially this is the same as the name of the
     50  *        mixer_control_element when there is one, or the name of the UCM
     51  *        parent when there are multiple).
     52  * dir - Control direction, OUTPUT or INPUT only.
     53  * elements - The mixer_control_elements that are driven by this control.
     54  * has_volume - non-zero indicates there is a volume control.
     55  * has_mute - non-zero indicates there is a mute switch.
     56  * max_volume_dB - Maximum volume available in the volume control.
     57  * min_volume_dB - Minimum volume available in the volume control.
     58  */
     59 struct mixer_control {
     60 	const char *name;
     61 	enum CRAS_STREAM_DIRECTION dir;
     62 	struct mixer_control_element *elements;
     63 	int has_volume;
     64 	int has_mute;
     65 	long max_volume_dB;
     66 	long min_volume_dB;
     67 	struct mixer_control *prev, *next;
     68 };
     69 
     70 /* Holds a reference to the opened mixer and the volume controls.
     71  * mixer - Pointer to the opened alsa mixer.
     72  * main_volume_controls - List of volume controls (normally 'Master' and 'PCM').
     73  * playback_switch - Switch used to mute the device.
     74  * main_capture_controls - List of capture gain controls (normally 'Capture').
     75  * capture_switch - Switch used to mute the capture stream.
     76  * max_volume_dB - Maximum volume available in main volume controls.  The dBFS
     77  *   value setting will be applied relative to this.
     78  * min_volume_dB - Minimum volume available in main volume controls.
     79  */
     80 struct cras_alsa_mixer {
     81 	snd_mixer_t *mixer;
     82 	struct mixer_control *main_volume_controls;
     83 	struct mixer_control *output_controls;
     84 	snd_mixer_elem_t *playback_switch;
     85 	struct mixer_control *main_capture_controls;
     86 	struct mixer_control *input_controls;
     87 	snd_mixer_elem_t *capture_switch;
     88 	long max_volume_dB;
     89 	long min_volume_dB;
     90 };
     91 
     92 /* Wrapper for snd_mixer_open and helpers.
     93  * Args:
     94  *    mixdev - Name of the device to open the mixer for.
     95  *    mixer - Pointer filled with the opened mixer on success, NULL on failure.
     96  */
     97 static void alsa_mixer_open(const char *mixdev,
     98 			    snd_mixer_t **mixer)
     99 {
    100 	int rc;
    101 
    102 	*mixer = NULL;
    103 	rc = snd_mixer_open(mixer, 0);
    104 	if (rc < 0) {
    105 		syslog(LOG_ERR, "snd_mixer_open: %d: %s", rc, strerror(-rc));
    106 		return;
    107 	}
    108 	rc = snd_mixer_attach(*mixer, mixdev);
    109 	if (rc < 0) {
    110 		syslog(LOG_ERR, "snd_mixer_attach: %d: %s", rc, strerror(-rc));
    111 		goto fail_after_open;
    112 	}
    113 	rc = snd_mixer_selem_register(*mixer, NULL, NULL);
    114 	if (rc < 0) {
    115 		syslog(LOG_ERR, "snd_mixer_selem_register: %d: %s", rc, strerror(-rc));
    116 		goto fail_after_open;
    117 	}
    118 	rc = snd_mixer_load(*mixer);
    119 	if (rc < 0) {
    120 		syslog(LOG_ERR, "snd_mixer_load: %d: %s", rc, strerror(-rc));
    121 		goto fail_after_open;
    122 	}
    123 	return;
    124 
    125 fail_after_open:
    126 	snd_mixer_close(*mixer);
    127 	*mixer = NULL;
    128 }
    129 
    130 static struct mixer_control_element *mixer_control_element_create(
    131 					snd_mixer_elem_t *elem,
    132 					enum CRAS_STREAM_DIRECTION dir)
    133 {
    134 	struct mixer_control_element *c;
    135 	long min, max;
    136 
    137 	if (!elem)
    138 		return NULL;
    139 
    140 	c = (struct mixer_control_element *)calloc(1, sizeof(*c));
    141 	if (!c) {
    142 		syslog(LOG_ERR, "No memory for mixer_control_elem.");
    143 		return NULL;
    144 	}
    145 
    146 	c->elem = elem;
    147 	c->max_volume_dB = MIXER_CONTROL_VOLUME_DB_INVALID;
    148 	c->min_volume_dB = MIXER_CONTROL_VOLUME_DB_INVALID;
    149 
    150 	if (dir == CRAS_STREAM_OUTPUT) {
    151 		c->has_mute = snd_mixer_selem_has_playback_switch(elem);
    152 
    153 		if (snd_mixer_selem_has_playback_volume(elem) &&
    154 		    snd_mixer_selem_get_playback_dB_range(
    155 						elem, &min, &max) == 0) {
    156 			c->max_volume_dB = max;
    157 			c->min_volume_dB = min;
    158 			c->has_volume = 1;
    159 		}
    160 	}
    161 	else if (dir == CRAS_STREAM_INPUT) {
    162 		c->has_mute = snd_mixer_selem_has_capture_switch(elem);
    163 
    164 		if (snd_mixer_selem_has_capture_volume(elem) &&
    165 		    snd_mixer_selem_get_capture_dB_range(
    166 						elem, &min, &max) == 0) {
    167 			c->max_volume_dB = max;
    168 			c->min_volume_dB = min;
    169 			c->has_volume = 1;
    170 		}
    171 	}
    172 
    173 	return c;
    174 }
    175 
    176 static void mixer_control_destroy(struct mixer_control *control) {
    177 	struct mixer_control_element *elem;
    178 
    179 	if (!control)
    180 		return;
    181 
    182 	DL_FOREACH(control->elements, elem) {
    183 		DL_DELETE(control->elements, elem);
    184 		free(elem);
    185 	}
    186 	if (control->name)
    187 		free((void *)control->name);
    188 	free(control);
    189 }
    190 
    191 static void mixer_control_destroy_list(struct mixer_control *control_list)
    192 {
    193 	struct mixer_control *control;
    194 	if (!control_list)
    195 		return;
    196 	DL_FOREACH(control_list, control) {
    197 		DL_DELETE(control_list, control);
    198 		mixer_control_destroy(control);
    199 	}
    200 }
    201 
    202 static int mixer_control_add_element(struct mixer_control *control,
    203 				     snd_mixer_elem_t *snd_elem)
    204 {
    205 	struct mixer_control_element *elem;
    206 
    207 	if (!control)
    208 		return -EINVAL;
    209 
    210 	elem = mixer_control_element_create(snd_elem, control->dir);
    211 	if (!elem)
    212 		return -ENOMEM;
    213 
    214 	DL_APPEND(control->elements, elem);
    215 
    216 	if (elem->has_volume) {
    217 		if (!control->has_volume)
    218 			control->has_volume = 1;
    219 
    220 		/* Assume that all elements have a common volume range, and
    221 		 * that both min and max values are valid if one of the two
    222 		 * is valid. */
    223 		if (control->min_volume_dB ==
    224 		    MIXER_CONTROL_VOLUME_DB_INVALID) {
    225 			control->min_volume_dB = elem->min_volume_dB;
    226 			control->max_volume_dB = elem->max_volume_dB;
    227 		} else if (control->min_volume_dB != elem->min_volume_dB ||
    228 			   control->max_volume_dB != elem->max_volume_dB) {
    229 			syslog(LOG_WARNING,
    230 			    "Element '%s' of control '%s' has different"
    231 			    "volume range: [%ld:%ld] ctrl: [%ld:%ld]",
    232 			    snd_mixer_selem_get_name(elem->elem),
    233 			    control->name,
    234 			    elem->min_volume_dB, elem->max_volume_dB,
    235 			    control->min_volume_dB, control->max_volume_dB);
    236 		}
    237 	}
    238 
    239 	if (elem->has_mute && !control->has_mute)
    240 		control->has_mute = 1;
    241 	return 0;
    242 }
    243 
    244 static int mixer_control_create(struct mixer_control **control,
    245 				const char *name,
    246 				snd_mixer_elem_t *elem,
    247 				enum CRAS_STREAM_DIRECTION dir)
    248 {
    249 	struct mixer_control *c;
    250 	int rc = 0;
    251 
    252 	if (!control)
    253 		return -EINVAL;
    254 
    255 	c = (struct mixer_control *)calloc(1, sizeof(*c));
    256 	if (!c) {
    257 		syslog(LOG_ERR, "No memory for mixer_control: %s", name);
    258 		rc = -ENOMEM;
    259 		goto error;
    260 	}
    261 
    262 	c->dir = dir;
    263 	c->min_volume_dB = MIXER_CONTROL_VOLUME_DB_INVALID;
    264 	c->max_volume_dB = MIXER_CONTROL_VOLUME_DB_INVALID;
    265 
    266 	if (!name && elem)
    267 		name = snd_mixer_selem_get_name(elem);
    268 	if (!name) {
    269 		syslog(LOG_ERR, "Control does not have a name.");
    270 		rc = -EINVAL;
    271 		goto error;
    272 	}
    273 
    274 	c->name = strdup(name);
    275 	if (!c->name) {
    276 		syslog(LOG_ERR, "No memory for control's name: %s", name);
    277 		rc = -ENOMEM;
    278 		goto error;
    279 	}
    280 
    281 	if (elem && (rc = mixer_control_add_element(c, elem)))
    282 		goto error;
    283 
    284 	*control = c;
    285 	return 0;
    286 
    287 error:
    288 	mixer_control_destroy(c);
    289 	*control = NULL;
    290 	return rc;
    291 }
    292 
    293 /* Creates a mixer_control by finding mixer element names in simple mixer
    294  * interface.
    295  * Args:
    296  *    control[out] - Storage for resulting pointer to mixer_control.
    297  *    cmix[in] - Parent alsa mixer.
    298  *    name[in] - Optional name of the control. Input NULL to take the name of
    299  *               the first element from mixer_names.
    300  *    mixer_names[in] - Names of the ASLA mixer control elements. Must not
    301  *                      be empty.
    302  *    dir[in] - Control direction: CRAS_STREAM_OUTPUT or CRAS_STREAM_INPUT.
    303  * Returns:
    304  *    Returns 0 for success, negative error code otherwise. *control is
    305  *    initialized to NULL on error, or has a valid pointer for success.
    306  */
    307 static int mixer_control_create_by_name(
    308 		struct mixer_control **control,
    309 		struct cras_alsa_mixer *cmix,
    310 		const char *name,
    311 		struct mixer_name *mixer_names,
    312 		enum CRAS_STREAM_DIRECTION dir)
    313 {
    314 	snd_mixer_selem_id_t *sid;
    315 	snd_mixer_elem_t *elem;
    316 	struct mixer_control *c;
    317 	struct mixer_name *m_name;
    318 	int rc;
    319 
    320 	if (!control)
    321 		return -EINVAL;
    322 	*control = NULL;
    323 	if (!mixer_names)
    324 		return -EINVAL;
    325 	if (!name) {
    326 		/* Assume that we're using the first name in the list of mixer
    327 		 * names. */
    328 		name = mixer_names->name;
    329 	}
    330 
    331 	rc = mixer_control_create(&c, name, NULL, dir);
    332 	if (rc)
    333 		return rc;
    334 
    335 	snd_mixer_selem_id_malloc(&sid);
    336 
    337 	DL_FOREACH(mixer_names, m_name) {
    338 		snd_mixer_selem_id_set_index(sid, 0);
    339 		snd_mixer_selem_id_set_name(sid, m_name->name);
    340 		elem = snd_mixer_find_selem(cmix->mixer, sid);
    341 		if (!elem) {
    342 			mixer_control_destroy(c);
    343 			snd_mixer_selem_id_free(sid);
    344 			syslog(LOG_ERR, "Unable to find simple control %s, 0",
    345 			       m_name->name);
    346 			return -ENOENT;
    347 		}
    348 		rc = mixer_control_add_element(c, elem);
    349 		if (rc) {
    350 			mixer_control_destroy(c);
    351 			snd_mixer_selem_id_free(sid);
    352 			return rc;
    353 		}
    354 	}
    355 
    356 	snd_mixer_selem_id_free(sid);
    357 	*control = c;
    358 	return 0;
    359 }
    360 
    361 static int mixer_control_set_dBFS(
    362 		const struct mixer_control *control, long to_set)
    363 {
    364 	const struct mixer_control_element *elem = NULL;
    365 	int rc = -EINVAL;
    366 	if (!control)
    367 		return rc;
    368 	DL_FOREACH(control->elements, elem) {
    369 		if(elem->has_volume) {
    370 			if (control->dir == CRAS_STREAM_OUTPUT)
    371 				rc = snd_mixer_selem_set_playback_dB_all(
    372 						elem->elem, to_set, 1);
    373 			else if (control->dir == CRAS_STREAM_INPUT)
    374 				rc = snd_mixer_selem_set_capture_dB_all(
    375 						elem->elem, to_set, 1);
    376 			if (rc)
    377 				break;
    378 			syslog(LOG_DEBUG, "%s:%s volume set to %ld",
    379 			       control->name,
    380 			       snd_mixer_selem_get_name(elem->elem),
    381 			       to_set);
    382 		}
    383 	}
    384 	if (rc && elem) {
    385 		syslog(LOG_ERR, "Failed to set volume of '%s:%s': %d",
    386 		       control->name,
    387 		       snd_mixer_selem_get_name(elem->elem), rc);
    388 	}
    389 	return rc;
    390 }
    391 
    392 static int mixer_control_get_dBFS(
    393 		const struct mixer_control *control, long *to_get)
    394 {
    395 	const struct mixer_control_element *elem = NULL;
    396 	int rc = -EINVAL;
    397 	if (!control || !to_get)
    398 		return -EINVAL;
    399 	DL_FOREACH(control->elements, elem) {
    400 		if (elem->has_volume) {
    401 			if (control->dir == CRAS_STREAM_OUTPUT)
    402 				rc = snd_mixer_selem_get_playback_dB(
    403 						elem->elem,
    404 						SND_MIXER_SCHN_FRONT_LEFT,
    405 						to_get);
    406 			else if (control->dir == CRAS_STREAM_INPUT)
    407 				rc = snd_mixer_selem_get_capture_dB(
    408 						elem->elem,
    409 						SND_MIXER_SCHN_FRONT_LEFT,
    410 						to_get);
    411 			/* Assume all of the elements of this control have
    412 			 * the same value. */
    413 			break;
    414 		}
    415 	}
    416 	if (rc && elem) {
    417 		syslog(LOG_ERR, "Failed to get volume of '%s:%s': %d",
    418 		       control->name,
    419 		       snd_mixer_selem_get_name(elem->elem), rc);
    420 	}
    421 	return rc;
    422 }
    423 
    424 static int mixer_control_set_mute(
    425 		const struct mixer_control *control, int muted)
    426 {
    427 	const struct mixer_control_element *elem = NULL;
    428 	int rc;
    429 	if (!control)
    430 		return -EINVAL;
    431 	DL_FOREACH(control->elements, elem) {
    432 		if(elem->has_mute) {
    433 			if (control->dir == CRAS_STREAM_OUTPUT)
    434 				rc = snd_mixer_selem_set_playback_switch_all(
    435 					elem->elem, !muted);
    436 			else if (control->dir == CRAS_STREAM_INPUT)
    437 				rc = snd_mixer_selem_set_capture_switch_all(
    438 					elem->elem, !muted);
    439 			if (rc)
    440 				break;
    441 		}
    442 	}
    443 	if (rc && elem) {
    444 		syslog(LOG_ERR, "Failed to mute '%s:%s': %d",
    445 		       control->name,
    446 		       snd_mixer_selem_get_name(elem->elem), rc);
    447 	}
    448 	return rc;
    449 }
    450 
    451 /* Adds the main volume control to the list and grabs the first seen playback
    452  * switch to use for mute. */
    453 static int add_main_volume_control(struct cras_alsa_mixer *cmix,
    454 				   snd_mixer_elem_t *elem)
    455 {
    456 	if (snd_mixer_selem_has_playback_volume(elem)) {
    457 		long range;
    458 		struct mixer_control *c, *next;
    459 		int rc = mixer_control_create(&c, NULL, elem, CRAS_STREAM_OUTPUT);
    460 		if (rc)
    461 			return rc;
    462 
    463 		if (c->has_volume) {
    464 			cmix->max_volume_dB += c->max_volume_dB;
    465 			cmix->min_volume_dB += c->min_volume_dB;
    466 		}
    467 
    468 		range = c->max_volume_dB - c->min_volume_dB;
    469 		DL_FOREACH(cmix->main_volume_controls, next) {
    470 			if (range > next->max_volume_dB - next->min_volume_dB)
    471 				break;
    472 		}
    473 
    474 		syslog(LOG_DEBUG, "Add main volume control %s\n", c->name);
    475 		DL_INSERT(cmix->main_volume_controls, next, c);
    476 	}
    477 
    478 	/* If cmix doesn't yet have a playback switch and this is a playback
    479 	 * switch, use it. */
    480 	if (cmix->playback_switch == NULL &&
    481 			snd_mixer_selem_has_playback_switch(elem)) {
    482 		syslog(LOG_DEBUG, "Using '%s' as playback switch.",
    483 		       snd_mixer_selem_get_name(elem));
    484 		cmix->playback_switch = elem;
    485 	}
    486 
    487 	return 0;
    488 }
    489 
    490 /* Adds the main capture control to the list and grabs the first seen capture
    491  * switch to mute input. */
    492 static int add_main_capture_control(struct cras_alsa_mixer *cmix,
    493 				    snd_mixer_elem_t *elem)
    494 {
    495 	/* TODO(dgreid) handle index != 0, map to correct input. */
    496 	if (snd_mixer_selem_get_index(elem) > 0)
    497 		return 0;
    498 
    499 	if (snd_mixer_selem_has_capture_volume(elem)) {
    500 		struct mixer_control *c;
    501 		int rc = mixer_control_create(&c, NULL, elem, CRAS_STREAM_INPUT);
    502 		if (rc)
    503 			return rc;
    504 
    505 		syslog(LOG_DEBUG, "Add main capture control %s\n", c->name);
    506 		DL_APPEND(cmix->main_capture_controls, c);
    507 	}
    508 
    509 	/* If cmix doesn't yet have a capture switch and this is a capture
    510 	 * switch, use it. */
    511 	if (cmix->capture_switch == NULL &&
    512 	    snd_mixer_selem_has_capture_switch(elem)) {
    513 		syslog(LOG_DEBUG, "Using '%s' as capture switch.",
    514 		       snd_mixer_selem_get_name(elem));
    515 		cmix->capture_switch = elem;
    516 	}
    517 
    518 	return 0;
    519 }
    520 
    521 /* Adds a control to the list. */
    522 static int add_control_with_name(struct cras_alsa_mixer *cmix,
    523 				 enum CRAS_STREAM_DIRECTION dir,
    524 				 snd_mixer_elem_t *elem,
    525 				 const char *name)
    526 {
    527 	int index; /* Index part of mixer simple element */
    528 	struct mixer_control *c;
    529 	int rc;
    530 
    531 	index = snd_mixer_selem_get_index(elem);
    532 	syslog(LOG_DEBUG, "Add %s control: %s,%d\n",
    533 	       dir == CRAS_STREAM_OUTPUT ? "output" : "input",
    534 	       name, index);
    535 
    536 	rc = mixer_control_create(&c, name, elem, dir);
    537 	if (rc)
    538 		return rc;
    539 
    540 	if (c->has_volume)
    541 		syslog(LOG_DEBUG, "Control '%s' volume range: [%ld:%ld]",
    542 		       c->name, c->min_volume_dB, c->max_volume_dB);
    543 
    544 	if (dir == CRAS_STREAM_OUTPUT)
    545 		DL_APPEND(cmix->output_controls, c);
    546 	else if (dir == CRAS_STREAM_INPUT)
    547 		DL_APPEND(cmix->input_controls, c);
    548 	return 0;
    549 }
    550 
    551 static int add_control(struct cras_alsa_mixer *cmix,
    552 		       enum CRAS_STREAM_DIRECTION dir,
    553 		       snd_mixer_elem_t *elem)
    554 {
    555 	return add_control_with_name(cmix, dir, elem,
    556 				     snd_mixer_selem_get_name(elem));
    557 }
    558 
    559 static void list_controls(struct mixer_control *control_list,
    560 			  cras_alsa_mixer_control_callback cb,
    561 			  void *cb_arg)
    562 {
    563 	struct mixer_control *control;
    564 
    565 	DL_FOREACH(control_list, control)
    566 		cb(control, cb_arg);
    567 }
    568 
    569 static struct mixer_control *get_control_matching_name(
    570 		struct mixer_control *control_list,
    571 		const char *name)
    572 {
    573 	struct mixer_control *c;
    574 
    575 	DL_FOREACH(control_list, c) {
    576 		if (strstr(name, c->name))
    577 			return c;
    578 	}
    579 	return NULL;
    580 }
    581 
    582 /* Creates a mixer_control with multiple control elements. */
    583 static int add_control_with_coupled_mixers(
    584 				struct cras_alsa_mixer *cmix,
    585 				enum CRAS_STREAM_DIRECTION dir,
    586 				const char *name,
    587 				struct mixer_name *coupled_controls)
    588 {
    589 	struct mixer_control *c;
    590 	int rc;
    591 
    592 	rc = mixer_control_create_by_name(
    593 		 &c, cmix, name, coupled_controls, dir);
    594 	if (rc)
    595 		return rc;
    596 	syslog(LOG_DEBUG, "Add %s control: %s\n",
    597 	       dir == CRAS_STREAM_OUTPUT ? "output" : "input",
    598 	       c->name);
    599 	mixer_name_dump(coupled_controls, "  elements");
    600 
    601 	if (c->has_volume)
    602 		syslog(LOG_DEBUG, "Control '%s' volume range: [%ld:%ld]",
    603 		       c->name, c->min_volume_dB, c->max_volume_dB);
    604 
    605 	if (dir == CRAS_STREAM_OUTPUT)
    606 		DL_APPEND(cmix->output_controls, c);
    607 	else if (dir == CRAS_STREAM_INPUT)
    608 		DL_APPEND(cmix->input_controls, c);
    609 	return 0;
    610 }
    611 
    612 static int add_control_by_name(struct cras_alsa_mixer *cmix,
    613 			       enum CRAS_STREAM_DIRECTION dir,
    614 			       const char *name)
    615 {
    616 	struct mixer_control *c;
    617 	struct mixer_name *m_name;
    618 	int rc;
    619 
    620 	m_name = mixer_name_add(NULL, name, dir, MIXER_NAME_VOLUME);
    621 	if (!m_name)
    622 		return -ENOMEM;
    623 
    624 	rc = mixer_control_create_by_name(&c, cmix, name, m_name, dir);
    625 	mixer_name_free(m_name);
    626 	if (rc)
    627 		return rc;
    628 	syslog(LOG_DEBUG, "Add %s control: %s\n",
    629 	       dir == CRAS_STREAM_OUTPUT ? "output" : "input",
    630 	       c->name);
    631 
    632 	if (c->has_volume)
    633 		syslog(LOG_DEBUG, "Control '%s' volume range: [%ld:%ld]",
    634 		       c->name, c->min_volume_dB, c->max_volume_dB);
    635 
    636 	if (dir == CRAS_STREAM_OUTPUT)
    637 		DL_APPEND(cmix->output_controls, c);
    638 	else if (dir == CRAS_STREAM_INPUT)
    639 		DL_APPEND(cmix->input_controls, c);
    640 	return 0;
    641 }
    642 
    643 /*
    644  * Exported interface.
    645  */
    646 
    647 struct cras_alsa_mixer *cras_alsa_mixer_create(const char *card_name)
    648 {
    649 	struct cras_alsa_mixer *cmix;
    650 
    651 	cmix = (struct cras_alsa_mixer *)calloc(1, sizeof(*cmix));
    652 	if (cmix == NULL)
    653 		return NULL;
    654 
    655 	syslog(LOG_DEBUG, "Add mixer for device %s", card_name);
    656 
    657 	alsa_mixer_open(card_name, &cmix->mixer);
    658 
    659 	return cmix;
    660 }
    661 
    662 int cras_alsa_mixer_add_controls_by_name_matching(
    663 		struct cras_alsa_mixer *cmix,
    664 		struct mixer_name *extra_controls,
    665 		struct mixer_name *coupled_controls)
    666 {
    667 	/* Names of controls for main system volume. */
    668 	static const char * const main_volume_names[] = {
    669 		"Master",
    670 		"Digital",
    671 		"PCM",
    672 	};
    673 	/* Names of controls for individual outputs. */
    674 	static const char * const output_names[] = {
    675 		"Headphone",
    676 		"Headset",
    677 		"HDMI",
    678 		"Speaker",
    679 	};
    680 	/* Names of controls for capture gain/attenuation and mute. */
    681 	static const char * const main_capture_names[] = {
    682 		"Capture",
    683 		"Digital Capture",
    684 	};
    685 	/* Names of controls for individual inputs. */
    686 	static const char * const input_names[] = {
    687 		"Mic",
    688 		"Microphone",
    689 	};
    690 
    691 	struct mixer_name *default_controls = NULL;
    692 	snd_mixer_elem_t *elem;
    693 	int extra_main_volume = 0;
    694 	snd_mixer_elem_t *other_elem = NULL;
    695 	long other_dB_range = 0;
    696 	int rc = 0;
    697 
    698 	/* Note that there is no mixer on some cards. This is acceptable. */
    699 	if (cmix->mixer == NULL) {
    700 		syslog(LOG_DEBUG, "Couldn't open mixer.");
    701 		return 0;
    702 	}
    703 
    704 	default_controls = mixer_name_add_array(default_controls,
    705 				output_names, ARRAY_SIZE(output_names),
    706 				CRAS_STREAM_OUTPUT, MIXER_NAME_VOLUME);
    707 	default_controls = mixer_name_add_array(default_controls,
    708 				input_names, ARRAY_SIZE(input_names),
    709 				CRAS_STREAM_INPUT, MIXER_NAME_VOLUME);
    710 	default_controls =
    711 		mixer_name_add_array(default_controls,
    712 			main_volume_names, ARRAY_SIZE(main_volume_names),
    713 			CRAS_STREAM_OUTPUT, MIXER_NAME_MAIN_VOLUME);
    714 	default_controls =
    715 		mixer_name_add_array(default_controls,
    716 			main_capture_names, ARRAY_SIZE(main_capture_names),
    717 			CRAS_STREAM_INPUT, MIXER_NAME_MAIN_VOLUME);
    718 	extra_main_volume =
    719 		mixer_name_find(extra_controls, NULL,
    720 				CRAS_STREAM_OUTPUT,
    721 				MIXER_NAME_MAIN_VOLUME) != NULL;
    722 
    723 	/* Find volume and mute controls. */
    724 	for(elem = snd_mixer_first_elem(cmix->mixer);
    725 			elem != NULL; elem = snd_mixer_elem_next(elem)) {
    726 		const char *name;
    727 		struct mixer_name *control;
    728 		int found = 0;
    729 
    730 		name = snd_mixer_selem_get_name(elem);
    731 		if (name == NULL)
    732 			continue;
    733 
    734 		/* Find a matching control. */
    735 		control = mixer_name_find(default_controls, name,
    736 					  CRAS_STREAM_OUTPUT,
    737 					  MIXER_NAME_UNDEFINED);
    738 
    739 		/* If our extra controls contain a main volume
    740 		 * entry, and we found a main volume entry, then
    741 		 * skip it. */
    742 		if (extra_main_volume &&
    743 		    control && control->type == MIXER_NAME_MAIN_VOLUME)
    744 			control = NULL;
    745 
    746 		/* If we didn't match any of the defaults, match
    747 		 * the extras list. */
    748 		if (!control)
    749 			control = mixer_name_find(extra_controls, name,
    750 					  CRAS_STREAM_OUTPUT,
    751 					  MIXER_NAME_UNDEFINED);
    752 
    753 		if (control) {
    754 			int rc = -1;
    755 			switch(control->type) {
    756 			case MIXER_NAME_MAIN_VOLUME:
    757 				rc = add_main_volume_control(cmix, elem);
    758 				break;
    759 			case MIXER_NAME_VOLUME:
    760 				/* TODO(dgreid) - determine device index. */
    761 				rc = add_control(
    762 					cmix, CRAS_STREAM_OUTPUT, elem);
    763 				break;
    764 			case MIXER_NAME_UNDEFINED:
    765 				rc = -EINVAL;
    766 				break;
    767 			}
    768 			if (rc) {
    769 				syslog(LOG_ERR,
    770 				       "Failed to add mixer control '%s'"
    771 				       " with type '%d'",
    772 				       control->name, control->type);
    773 				return rc;
    774 			}
    775 			found = 1;
    776 		}
    777 
    778 		/* Find a matching input control. */
    779 		control = mixer_name_find(default_controls, name,
    780 					  CRAS_STREAM_INPUT,
    781 					  MIXER_NAME_UNDEFINED);
    782 
    783 		/* If we didn't match any of the defaults, match
    784 		   the extras list */
    785 		if (!control)
    786 			control = mixer_name_find(extra_controls, name,
    787 					  CRAS_STREAM_INPUT,
    788 					  MIXER_NAME_UNDEFINED);
    789 
    790 		if (control) {
    791 			int rc = -1;
    792 			switch(control->type) {
    793 			case MIXER_NAME_MAIN_VOLUME:
    794 				rc = add_main_capture_control(cmix, elem);
    795 				break;
    796 			case MIXER_NAME_VOLUME:
    797 				rc = add_control(
    798 					cmix, CRAS_STREAM_INPUT, elem);
    799 				break;
    800 			case MIXER_NAME_UNDEFINED:
    801 				rc = -EINVAL;
    802 				break;
    803 			}
    804 			if (rc) {
    805 				syslog(LOG_ERR,
    806 				       "Failed to add mixer control '%s'"
    807 				       " with type '%d'",
    808 				       control->name, control->type);
    809 				return rc;
    810 			}
    811 			found = 1;
    812 		}
    813 
    814 		if (!found && snd_mixer_selem_has_playback_volume(elem)) {
    815 			/* Temporarily cache one elem whose name is not
    816 			 * in the list above, but has a playback volume
    817 			 * control and the largest volume range. */
    818 			long min, max, range;
    819 			if (snd_mixer_selem_get_playback_dB_range(elem,
    820 								  &min,
    821 								  &max) != 0)
    822 				continue;
    823 
    824 			range = max - min;
    825 			if (other_dB_range < range) {
    826 				other_dB_range = range;
    827 				other_elem = elem;
    828 			}
    829 		}
    830 	}
    831 
    832 	/* Handle coupled output names for speaker */
    833 	if (coupled_controls) {
    834 		rc = add_control_with_coupled_mixers(
    835 				cmix, CRAS_STREAM_OUTPUT,
    836 				"Speaker", coupled_controls);
    837 		if (rc) {
    838 			syslog(LOG_ERR, "Could not add coupled output");
    839 			return rc;
    840 		}
    841 	}
    842 
    843 	/* If there is no volume control and output control found,
    844 	 * use the volume control which has the largest volume range
    845 	 * in the mixer as a main volume control. */
    846 	if (!cmix->main_volume_controls && !cmix->output_controls &&
    847 	    other_elem) {
    848 		rc = add_main_volume_control(cmix, other_elem);
    849 		if (rc) {
    850 			syslog(LOG_ERR, "Could not add other volume control");
    851 			return rc;
    852 		}
    853 	}
    854 
    855 	return rc;
    856 }
    857 
    858 int cras_alsa_mixer_add_controls_in_section(
    859 		struct cras_alsa_mixer *cmix,
    860 		struct ucm_section *section)
    861 {
    862 	int rc;
    863 
    864 	/* Note that there is no mixer on some cards. This is acceptable. */
    865 	if (cmix->mixer == NULL) {
    866 		syslog(LOG_DEBUG, "Couldn't open mixer.");
    867 		return 0;
    868 	}
    869 
    870 	if (!section) {
    871 		syslog(LOG_ERR, "No UCM SectionDevice specified.");
    872 		return -EINVAL;
    873 	}
    874 
    875 	/* TODO(muirj) - Extra main volume controls when fully-specified. */
    876 
    877 	if (section->mixer_name) {
    878 		rc = add_control_by_name(
    879 				cmix, section->dir, section->mixer_name);
    880 		if (rc) {
    881 			syslog(LOG_ERR, "Could not add mixer control '%s': %s",
    882 			       section->mixer_name, strerror(-rc));
    883 			return rc;
    884 		}
    885 	}
    886 
    887 	if (section->coupled) {
    888 		rc = add_control_with_coupled_mixers(
    889 				cmix, section->dir,
    890 				section->name, section->coupled);
    891 		if (rc) {
    892 			syslog(LOG_ERR, "Could not add coupled control: %s",
    893 			       strerror(-rc));
    894 			return rc;
    895 		}
    896 	}
    897 	return 0;
    898 }
    899 
    900 void cras_alsa_mixer_destroy(struct cras_alsa_mixer *cras_mixer)
    901 {
    902 	assert(cras_mixer);
    903 
    904 	mixer_control_destroy_list(cras_mixer->main_volume_controls);
    905 	mixer_control_destroy_list(cras_mixer->main_capture_controls);
    906 	mixer_control_destroy_list(cras_mixer->output_controls);
    907 	mixer_control_destroy_list(cras_mixer->input_controls);
    908 	if (cras_mixer->mixer)
    909 		snd_mixer_close(cras_mixer->mixer);
    910 	free(cras_mixer);
    911 }
    912 
    913 int cras_alsa_mixer_has_main_volume(
    914 		const struct cras_alsa_mixer *cras_mixer)
    915 {
    916 	return !!cras_mixer->main_volume_controls;
    917 }
    918 
    919 int cras_alsa_mixer_has_volume(const struct mixer_control *mixer_control)
    920 {
    921 	return mixer_control && mixer_control->has_volume;
    922 }
    923 
    924 void cras_alsa_mixer_set_dBFS(struct cras_alsa_mixer *cras_mixer,
    925 			      long dBFS,
    926 			      struct mixer_control *mixer_output)
    927 {
    928 	struct mixer_control *c;
    929 	long to_set;
    930 
    931 	assert(cras_mixer);
    932 
    933 	/* dBFS is normally < 0 to specify the attenuation from max. max is the
    934 	 * combined max of the master controls and the current output.
    935 	 */
    936 	to_set = dBFS + cras_mixer->max_volume_dB;
    937 	if (cras_alsa_mixer_has_volume(mixer_output))
    938 		to_set += mixer_output->max_volume_dB;
    939 	/* Go through all the controls, set the volume level for each,
    940 	 * taking the value closest but greater than the desired volume.  If the
    941 	 * entire volume can't be set on the current control, move on to the
    942 	 * next one until we have the exact volume, or gotten as close as we
    943 	 * can. Once all of the volume is set the rest of the controls should be
    944 	 * set to 0dB. */
    945 	DL_FOREACH(cras_mixer->main_volume_controls, c) {
    946 		long actual_dB;
    947 
    948 		if (!c->has_volume)
    949 			continue;
    950 		mixer_control_set_dBFS(c, to_set);
    951 		mixer_control_get_dBFS(c, &actual_dB);
    952 		to_set -= actual_dB;
    953 	}
    954 	/* Apply the rest to the output-specific control. */
    955 	if (cras_alsa_mixer_has_volume(mixer_output))
    956 		mixer_control_set_dBFS(mixer_output, to_set);
    957 }
    958 
    959 long cras_alsa_mixer_get_dB_range(struct cras_alsa_mixer *cras_mixer)
    960 {
    961 	if (!cras_mixer)
    962 		return 0;
    963 	return cras_mixer->max_volume_dB - cras_mixer->min_volume_dB;
    964 }
    965 
    966 long cras_alsa_mixer_get_output_dB_range(
    967 		struct mixer_control *mixer_output)
    968 {
    969 	if (!cras_alsa_mixer_has_volume(mixer_output))
    970 		return 0;
    971 
    972 	return mixer_output->max_volume_dB - mixer_output->min_volume_dB;
    973 }
    974 
    975 void cras_alsa_mixer_set_capture_dBFS(struct cras_alsa_mixer *cras_mixer,
    976 				      long dBFS,
    977 				      struct mixer_control *mixer_input)
    978 {
    979 	struct mixer_control *c;
    980 	long to_set;
    981 
    982 	assert(cras_mixer);
    983 	to_set = dBFS;
    984 	/* Go through all the controls, set the gain for each, taking the value
    985 	 * closest but greater than the desired gain.  If the entire gain can't
    986 	 * be set on the current control, move on to the next one until we have
    987 	 * the exact gain, or gotten as close as we can. Once all of the gain is
    988 	 * set the rest of the controls should be set to 0dB. */
    989 	DL_FOREACH(cras_mixer->main_capture_controls, c) {
    990 		long actual_dB;
    991 
    992 		if (!c->has_volume)
    993 			continue;
    994 		mixer_control_set_dBFS(c, to_set);
    995 		mixer_control_get_dBFS(c, &actual_dB);
    996 		to_set -= actual_dB;
    997 	}
    998 
    999 	/* Apply the reset to input specific control */
   1000 	if (cras_alsa_mixer_has_volume(mixer_input))
   1001 		mixer_control_set_dBFS(mixer_input, to_set);
   1002 }
   1003 
   1004 long cras_alsa_mixer_get_minimum_capture_gain(
   1005                 struct cras_alsa_mixer *cmix,
   1006 		struct mixer_control *mixer_input)
   1007 {
   1008 	struct mixer_control *c;
   1009 	long total_min = 0;
   1010 
   1011 	assert(cmix);
   1012 	DL_FOREACH(cmix->main_capture_controls, c)
   1013 		if (c->has_volume)
   1014 			total_min += c->min_volume_dB;
   1015 	if (mixer_input &&
   1016 	    mixer_input->has_volume)
   1017 		total_min += mixer_input->min_volume_dB;
   1018 
   1019 	return total_min;
   1020 }
   1021 
   1022 long cras_alsa_mixer_get_maximum_capture_gain(
   1023 		struct cras_alsa_mixer *cmix,
   1024 		struct mixer_control *mixer_input)
   1025 {
   1026 	struct mixer_control *c;
   1027 	long total_max = 0;
   1028 
   1029 	assert(cmix);
   1030 	DL_FOREACH(cmix->main_capture_controls, c)
   1031 		if (c->has_volume)
   1032 			total_max += c->max_volume_dB;
   1033 
   1034 	if (mixer_input &&
   1035 	    mixer_input->has_volume)
   1036 		total_max += mixer_input->max_volume_dB;
   1037 
   1038 	return total_max;
   1039 }
   1040 
   1041 void cras_alsa_mixer_set_mute(struct cras_alsa_mixer *cras_mixer,
   1042 			      int muted,
   1043 			      struct mixer_control *mixer_output)
   1044 {
   1045 	assert(cras_mixer);
   1046 
   1047 	if (cras_mixer->playback_switch) {
   1048 		snd_mixer_selem_set_playback_switch_all(
   1049 				cras_mixer->playback_switch, !muted);
   1050 	}
   1051 	if (mixer_output && mixer_output->has_mute) {
   1052 		mixer_control_set_mute(mixer_output, muted);
   1053 	}
   1054 }
   1055 
   1056 void cras_alsa_mixer_set_capture_mute(struct cras_alsa_mixer *cras_mixer,
   1057 				      int muted,
   1058 				      struct mixer_control *mixer_input)
   1059 {
   1060 	assert(cras_mixer);
   1061 	if (cras_mixer->capture_switch) {
   1062 		snd_mixer_selem_set_capture_switch_all(
   1063 				cras_mixer->capture_switch, !muted);
   1064 		return;
   1065 	}
   1066 	if (mixer_input && mixer_input->has_mute)
   1067 		mixer_control_set_mute(mixer_input, muted);
   1068 }
   1069 
   1070 void cras_alsa_mixer_list_outputs(struct cras_alsa_mixer *cras_mixer,
   1071 				  cras_alsa_mixer_control_callback cb,
   1072 				  void *cb_arg)
   1073 {
   1074 	assert(cras_mixer);
   1075 	list_controls(cras_mixer->output_controls, cb, cb_arg);
   1076 }
   1077 
   1078 void cras_alsa_mixer_list_inputs(struct cras_alsa_mixer *cras_mixer,
   1079 				 cras_alsa_mixer_control_callback cb,
   1080 				 void *cb_arg)
   1081 {
   1082 	assert(cras_mixer);
   1083 	list_controls(cras_mixer->input_controls, cb, cb_arg);
   1084 }
   1085 
   1086 const char *cras_alsa_mixer_get_control_name(
   1087 		const struct mixer_control *control)
   1088 {
   1089 	if (!control)
   1090 		return NULL;
   1091 	return control->name;
   1092 }
   1093 
   1094 struct mixer_control *cras_alsa_mixer_get_control_matching_name(
   1095 		struct cras_alsa_mixer *cras_mixer,
   1096 		enum CRAS_STREAM_DIRECTION dir, const char *name,
   1097 		int create_missing)
   1098 {
   1099 	struct mixer_control *c;
   1100 
   1101 	assert(cras_mixer);
   1102 	if (!name)
   1103 		return NULL;
   1104 
   1105 	if (dir == CRAS_STREAM_OUTPUT) {
   1106 		c = get_control_matching_name(
   1107 				cras_mixer->output_controls, name);
   1108 	} else if (dir == CRAS_STREAM_INPUT) {
   1109 		c = get_control_matching_name(
   1110 				cras_mixer->input_controls, name);
   1111 	} else {
   1112 		return NULL;
   1113         }
   1114 
   1115 	/* TODO: Allowing creation of a new control is a workaround: we
   1116 	 * should pass the input names in ucm config to
   1117 	 * cras_alsa_mixer_create. */
   1118 	if (!c && cras_mixer->mixer && create_missing) {
   1119 		int rc = add_control_by_name(cras_mixer, dir, name);
   1120 		if (rc)
   1121 			return NULL;
   1122 		c = cras_alsa_mixer_get_control_matching_name(
   1123 				cras_mixer, dir, name, 0);
   1124 	}
   1125 	return c;
   1126 }
   1127 
   1128 struct mixer_control *cras_alsa_mixer_get_control_for_section(
   1129 		struct cras_alsa_mixer *cras_mixer,
   1130 		const struct ucm_section *section)
   1131 {
   1132 	assert(cras_mixer && section);
   1133 	if (section->mixer_name) {
   1134 		return cras_alsa_mixer_get_control_matching_name(
   1135 			   cras_mixer, section->dir, section->mixer_name, 0);
   1136 	} else if (section->coupled) {
   1137 		return cras_alsa_mixer_get_control_matching_name(
   1138 			   cras_mixer, section->dir, section->name, 0);
   1139 	}
   1140 	return NULL;
   1141 }
   1142 
   1143 struct mixer_control *cras_alsa_mixer_get_output_matching_name(
   1144 		struct cras_alsa_mixer *cras_mixer,
   1145 		const char * const name)
   1146 {
   1147 	return cras_alsa_mixer_get_control_matching_name(
   1148 			cras_mixer, CRAS_STREAM_OUTPUT, name, 0);
   1149 }
   1150 
   1151 struct mixer_control *cras_alsa_mixer_get_input_matching_name(
   1152 		struct cras_alsa_mixer *cras_mixer,
   1153 		const char *name)
   1154 {
   1155 	/* TODO: Allowing creation of a new control is a workaround: we
   1156 	 * should pass the input names in ucm config to
   1157 	 * cras_alsa_mixer_create. */
   1158 	return cras_alsa_mixer_get_control_matching_name(
   1159 			cras_mixer, CRAS_STREAM_INPUT, name, 1);
   1160 }
   1161 
   1162 int cras_alsa_mixer_set_output_active_state(
   1163 		struct mixer_control *output,
   1164 		int active)
   1165 {
   1166 	assert(output);
   1167 	if (!output->has_mute)
   1168 		return -1;
   1169 	return mixer_control_set_mute(output, !active);
   1170 }
   1171