/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <alsa/asoundlib.h>
#include <limits.h>
#include <stdio.h>
#include <syslog.h>

#include "cras_alsa_mixer.h"
#include "cras_alsa_mixer_name.h"
#include "cras_alsa_ucm.h"
#include "cras_util.h"
#include "utlist.h"

#define MIXER_CONTROL_VOLUME_DB_INVALID LONG_MAX

/* Represents an ALSA control element. Each device can have several of these,
 * each potentially having independent volume and mute controls.
 * elem - ALSA mixer element.
 * has_volume - non-zero indicates there is a volume control.
 * has_mute - non-zero indicates there is a mute switch.
 * max_volume_dB - the maximum volume for this control, or
 *                 MIXER_CONTROL_VOLUME_DB_INVALID.
 * min_volume_dB - the minimum volume for this control, or
 *                 MIXER_CONTROL_VOLUME_DB_INVALID.
 */
struct mixer_control_element {
	snd_mixer_elem_t *elem;
	int has_volume;
	int has_mute;
	long max_volume_dB;
	long min_volume_dB;
	struct mixer_control_element *prev, *next;
};

/* Represents an ALSA control element related to a specific input/output
 * node such as speakers or headphones. A device can have several of these,
 * each potentially having independent volume and mute controls.
 *
 * Each will have at least one mixer_control_element. For cases where there
 * are separate control elements for left/right channels (for example),
 * additional mixer_control_elements are added.
 *
 * For controls with volume it is assumed that all elements have the same
 * range.
 *
 * name - Name of the control (typicially this is the same as the name of the
 *        mixer_control_element when there is one, or the name of the UCM
 *        parent when there are multiple).
 * dir - Control direction, OUTPUT or INPUT only.
 * elements - The mixer_control_elements that are driven by this control.
 * has_volume - non-zero indicates there is a volume control.
 * has_mute - non-zero indicates there is a mute switch.
 * max_volume_dB - Maximum volume available in the volume control.
 * min_volume_dB - Minimum volume available in the volume control.
 */
struct mixer_control {
	const char *name;
	enum CRAS_STREAM_DIRECTION dir;
	struct mixer_control_element *elements;
	int has_volume;
	int has_mute;
	long max_volume_dB;
	long min_volume_dB;
	struct mixer_control *prev, *next;
};

/* Holds a reference to the opened mixer and the volume controls.
 * mixer - Pointer to the opened alsa mixer.
 * main_volume_controls - List of volume controls (normally 'Master' and 'PCM').
 * playback_switch - Switch used to mute the device.
 * main_capture_controls - List of capture gain controls (normally 'Capture').
 * capture_switch - Switch used to mute the capture stream.
 * max_volume_dB - Maximum volume available in main volume controls.  The dBFS
 *   value setting will be applied relative to this.
 * min_volume_dB - Minimum volume available in main volume controls.
 */
struct cras_alsa_mixer {
	snd_mixer_t *mixer;
	struct mixer_control *main_volume_controls;
	struct mixer_control *output_controls;
	snd_mixer_elem_t *playback_switch;
	struct mixer_control *main_capture_controls;
	struct mixer_control *input_controls;
	snd_mixer_elem_t *capture_switch;
	long max_volume_dB;
	long min_volume_dB;
};

/* Wrapper for snd_mixer_open and helpers.
 * Args:
 *    mixdev - Name of the device to open the mixer for.
 *    mixer - Pointer filled with the opened mixer on success, NULL on failure.
 */
static void alsa_mixer_open(const char *mixdev, snd_mixer_t **mixer)
{
	int rc;

	*mixer = NULL;
	rc = snd_mixer_open(mixer, 0);
	if (rc < 0) {
		syslog(LOG_ERR, "snd_mixer_open: %d: %s", rc, strerror(-rc));
		return;
	}
	rc = snd_mixer_attach(*mixer, mixdev);
	if (rc < 0) {
		syslog(LOG_ERR, "snd_mixer_attach: %d: %s", rc, strerror(-rc));
		goto fail_after_open;
	}
	rc = snd_mixer_selem_register(*mixer, NULL, NULL);
	if (rc < 0) {
		syslog(LOG_ERR, "snd_mixer_selem_register: %d: %s", rc,
		       strerror(-rc));
		goto fail_after_open;
	}
	rc = snd_mixer_load(*mixer);
	if (rc < 0) {
		syslog(LOG_ERR, "snd_mixer_load: %d: %s", rc, strerror(-rc));
		goto fail_after_open;
	}
	return;

fail_after_open:
	snd_mixer_close(*mixer);
	*mixer = NULL;
}

static struct mixer_control_element *
mixer_control_element_create(snd_mixer_elem_t *elem,
			     enum CRAS_STREAM_DIRECTION dir)
{
	struct mixer_control_element *c;
	long min, max;

	if (!elem)
		return NULL;

	c = (struct mixer_control_element *)calloc(1, sizeof(*c));
	if (!c) {
		syslog(LOG_ERR, "No memory for mixer_control_elem.");
		return NULL;
	}

	c->elem = elem;
	c->max_volume_dB = MIXER_CONTROL_VOLUME_DB_INVALID;
	c->min_volume_dB = MIXER_CONTROL_VOLUME_DB_INVALID;

	if (dir == CRAS_STREAM_OUTPUT) {
		c->has_mute = snd_mixer_selem_has_playback_switch(elem);

		if (snd_mixer_selem_has_playback_volume(elem) &&
		    snd_mixer_selem_get_playback_dB_range(elem, &min, &max) ==
			    0) {
			c->max_volume_dB = max;
			c->min_volume_dB = min;
			c->has_volume = 1;
		}
	} else if (dir == CRAS_STREAM_INPUT) {
		c->has_mute = snd_mixer_selem_has_capture_switch(elem);

		if (snd_mixer_selem_has_capture_volume(elem) &&
		    snd_mixer_selem_get_capture_dB_range(elem, &min, &max) ==
			    0) {
			c->max_volume_dB = max;
			c->min_volume_dB = min;
			c->has_volume = 1;
		}
	}

	return c;
}

static void mixer_control_destroy(struct mixer_control *control)
{
	struct mixer_control_element *elem;

	if (!control)
		return;

	DL_FOREACH (control->elements, elem) {
		DL_DELETE(control->elements, elem);
		free(elem);
	}
	if (control->name)
		free((void *)control->name);
	free(control);
}

static void mixer_control_destroy_list(struct mixer_control *control_list)
{
	struct mixer_control *control;
	if (!control_list)
		return;
	DL_FOREACH (control_list, control) {
		DL_DELETE(control_list, control);
		mixer_control_destroy(control);
	}
}

static int mixer_control_add_element(struct mixer_control *control,
				     snd_mixer_elem_t *snd_elem)
{
	struct mixer_control_element *elem;

	if (!control)
		return -EINVAL;

	elem = mixer_control_element_create(snd_elem, control->dir);
	if (!elem)
		return -ENOMEM;

	DL_APPEND(control->elements, elem);

	if (elem->has_volume) {
		if (!control->has_volume)
			control->has_volume = 1;

		/* Assume that all elements have a common volume range, and
		 * that both min and max values are valid if one of the two
		 * is valid. */
		if (control->min_volume_dB == MIXER_CONTROL_VOLUME_DB_INVALID) {
			control->min_volume_dB = elem->min_volume_dB;
			control->max_volume_dB = elem->max_volume_dB;
		} else if (control->min_volume_dB != elem->min_volume_dB ||
			   control->max_volume_dB != elem->max_volume_dB) {
			syslog(LOG_WARNING,
			       "Element '%s' of control '%s' has different"
			       "volume range: [%ld:%ld] ctrl: [%ld:%ld]",
			       snd_mixer_selem_get_name(elem->elem),
			       control->name, elem->min_volume_dB,
			       elem->max_volume_dB, control->min_volume_dB,
			       control->max_volume_dB);
		}
	}

	if (elem->has_mute && !control->has_mute)
		control->has_mute = 1;
	return 0;
}

static int mixer_control_create(struct mixer_control **control,
				const char *name, snd_mixer_elem_t *elem,
				enum CRAS_STREAM_DIRECTION dir)
{
	struct mixer_control *c;
	int rc = 0;

	if (!control)
		return -EINVAL;

	c = (struct mixer_control *)calloc(1, sizeof(*c));
	if (!c) {
		syslog(LOG_ERR, "No memory for mixer_control: %s", name);
		rc = -ENOMEM;
		goto error;
	}

	c->dir = dir;
	c->min_volume_dB = MIXER_CONTROL_VOLUME_DB_INVALID;
	c->max_volume_dB = MIXER_CONTROL_VOLUME_DB_INVALID;

	if (!name && elem)
		name = snd_mixer_selem_get_name(elem);
	if (!name) {
		syslog(LOG_ERR, "Control does not have a name.");
		rc = -EINVAL;
		goto error;
	}

	c->name = strdup(name);
	if (!c->name) {
		syslog(LOG_ERR, "No memory for control's name: %s", name);
		rc = -ENOMEM;
		goto error;
	}

	if (elem && (rc = mixer_control_add_element(c, elem)))
		goto error;

	*control = c;
	return 0;

error:
	mixer_control_destroy(c);
	*control = NULL;
	return rc;
}

/* Creates a mixer_control by finding mixer element names in simple mixer
 * interface.
 * Args:
 *    control[out] - Storage for resulting pointer to mixer_control.
 *    cmix[in] - Parent alsa mixer.
 *    name[in] - Optional name of the control. Input NULL to take the name of
 *               the first element from mixer_names.
 *    mixer_names[in] - Names of the ASLA mixer control elements. Must not
 *                      be empty.
 *    dir[in] - Control direction: CRAS_STREAM_OUTPUT or CRAS_STREAM_INPUT.
 * Returns:
 *    Returns 0 for success, negative error code otherwise. *control is
 *    initialized to NULL on error, or has a valid pointer for success.
 */
static int mixer_control_create_by_name(struct mixer_control **control,
					struct cras_alsa_mixer *cmix,
					const char *name,
					struct mixer_name *mixer_names,
					enum CRAS_STREAM_DIRECTION dir)
{
	snd_mixer_selem_id_t *sid;
	snd_mixer_elem_t *elem;
	struct mixer_control *c;
	struct mixer_name *m_name;
	int rc;

	if (!control)
		return -EINVAL;
	*control = NULL;
	if (!mixer_names)
		return -EINVAL;
	if (!name) {
		/* Assume that we're using the first name in the list of mixer
		 * names. */
		name = mixer_names->name;
	}

	rc = mixer_control_create(&c, name, NULL, dir);
	if (rc)
		return rc;

	snd_mixer_selem_id_malloc(&sid);

	DL_FOREACH (mixer_names, m_name) {
		snd_mixer_selem_id_set_index(sid, 0);
		snd_mixer_selem_id_set_name(sid, m_name->name);
		elem = snd_mixer_find_selem(cmix->mixer, sid);
		if (!elem) {
			mixer_control_destroy(c);
			snd_mixer_selem_id_free(sid);
			syslog(LOG_ERR, "Unable to find simple control %s, 0",
			       m_name->name);
			return -ENOENT;
		}
		rc = mixer_control_add_element(c, elem);
		if (rc) {
			mixer_control_destroy(c);
			snd_mixer_selem_id_free(sid);
			return rc;
		}
	}

	snd_mixer_selem_id_free(sid);
	*control = c;
	return 0;
}

static int mixer_control_set_dBFS(const struct mixer_control *control,
				  long to_set)
{
	const struct mixer_control_element *elem = NULL;
	int rc = -EINVAL;
	if (!control)
		return rc;
	DL_FOREACH (control->elements, elem) {
		if (elem->has_volume) {
			if (control->dir == CRAS_STREAM_OUTPUT)
				rc = snd_mixer_selem_set_playback_dB_all(
					elem->elem, to_set, 1);
			else if (control->dir == CRAS_STREAM_INPUT)
				rc = snd_mixer_selem_set_capture_dB_all(
					elem->elem, to_set, 1);
			if (rc)
				break;
			syslog(LOG_DEBUG, "%s:%s volume set to %ld",
			       control->name,
			       snd_mixer_selem_get_name(elem->elem), to_set);
		}
	}
	if (rc && elem) {
		syslog(LOG_ERR, "Failed to set volume of '%s:%s': %d",
		       control->name, snd_mixer_selem_get_name(elem->elem), rc);
	}
	return rc;
}

static int mixer_control_get_dBFS(const struct mixer_control *control,
				  long *to_get)
{
	const struct mixer_control_element *elem = NULL;
	int rc = -EINVAL;
	if (!control || !to_get)
		return -EINVAL;
	DL_FOREACH (control->elements, elem) {
		if (elem->has_volume) {
			if (control->dir == CRAS_STREAM_OUTPUT)
				rc = snd_mixer_selem_get_playback_dB(
					elem->elem, SND_MIXER_SCHN_FRONT_LEFT,
					to_get);
			else if (control->dir == CRAS_STREAM_INPUT)
				rc = snd_mixer_selem_get_capture_dB(
					elem->elem, SND_MIXER_SCHN_FRONT_LEFT,
					to_get);
			/* Assume all of the elements of this control have
			 * the same value. */
			break;
		}
	}
	if (rc && elem) {
		syslog(LOG_ERR, "Failed to get volume of '%s:%s': %d",
		       control->name, snd_mixer_selem_get_name(elem->elem), rc);
	}
	return rc;
}

static int mixer_control_set_mute(const struct mixer_control *control,
				  int muted)
{
	const struct mixer_control_element *elem = NULL;
	int rc = -EINVAL;
	if (!control)
		return -EINVAL;
	DL_FOREACH (control->elements, elem) {
		if (elem->has_mute) {
			if (control->dir == CRAS_STREAM_OUTPUT)
				rc = snd_mixer_selem_set_playback_switch_all(
					elem->elem, !muted);
			else if (control->dir == CRAS_STREAM_INPUT)
				rc = snd_mixer_selem_set_capture_switch_all(
					elem->elem, !muted);
			if (rc)
				break;
		}
	}
	if (rc && elem) {
		syslog(LOG_ERR, "Failed to mute '%s:%s': %d", control->name,
		       snd_mixer_selem_get_name(elem->elem), rc);
	}
	return rc;
}

/* Adds the main volume control to the list and grabs the first seen playback
 * switch to use for mute. */
static int add_main_volume_control(struct cras_alsa_mixer *cmix,
				   snd_mixer_elem_t *elem)
{
	if (snd_mixer_selem_has_playback_volume(elem)) {
		long range;
		struct mixer_control *c, *next;
		int rc = mixer_control_create(&c, NULL, elem,
					      CRAS_STREAM_OUTPUT);
		if (rc)
			return rc;

		if (c->has_volume) {
			cmix->max_volume_dB += c->max_volume_dB;
			cmix->min_volume_dB += c->min_volume_dB;
		}

		range = c->max_volume_dB - c->min_volume_dB;
		DL_FOREACH (cmix->main_volume_controls, next) {
			if (range > next->max_volume_dB - next->min_volume_dB)
				break;
		}

		syslog(LOG_DEBUG, "Add main volume control %s\n", c->name);
		DL_INSERT(cmix->main_volume_controls, next, c);
	}

	/* If cmix doesn't yet have a playback switch and this is a playback
	 * switch, use it. */
	if (cmix->playback_switch == NULL &&
	    snd_mixer_selem_has_playback_switch(elem)) {
		syslog(LOG_DEBUG, "Using '%s' as playback switch.",
		       snd_mixer_selem_get_name(elem));
		cmix->playback_switch = elem;
	}

	return 0;
}

/* Adds the main capture control to the list and grabs the first seen capture
 * switch to mute input. */
static int add_main_capture_control(struct cras_alsa_mixer *cmix,
				    snd_mixer_elem_t *elem)
{
	/* TODO(dgreid) handle index != 0, map to correct input. */
	if (snd_mixer_selem_get_index(elem) > 0)
		return 0;

	if (snd_mixer_selem_has_capture_volume(elem)) {
		struct mixer_control *c;
		int rc =
			mixer_control_create(&c, NULL, elem, CRAS_STREAM_INPUT);
		if (rc)
			return rc;

		syslog(LOG_DEBUG, "Add main capture control %s\n", c->name);
		DL_APPEND(cmix->main_capture_controls, c);
	}

	/* If cmix doesn't yet have a capture switch and this is a capture
	 * switch, use it. */
	if (cmix->capture_switch == NULL &&
	    snd_mixer_selem_has_capture_switch(elem)) {
		syslog(LOG_DEBUG, "Using '%s' as capture switch.",
		       snd_mixer_selem_get_name(elem));
		cmix->capture_switch = elem;
	}

	return 0;
}

/* Adds a control to the list. */
static int add_control_with_name(struct cras_alsa_mixer *cmix,
				 enum CRAS_STREAM_DIRECTION dir,
				 snd_mixer_elem_t *elem, const char *name)
{
	int index; /* Index part of mixer simple element */
	struct mixer_control *c;
	int rc;

	index = snd_mixer_selem_get_index(elem);
	syslog(LOG_DEBUG, "Add %s control: %s,%d\n",
	       dir == CRAS_STREAM_OUTPUT ? "output" : "input", name, index);

	rc = mixer_control_create(&c, name, elem, dir);
	if (rc)
		return rc;

	if (c->has_volume)
		syslog(LOG_DEBUG, "Control '%s' volume range: [%ld:%ld]",
		       c->name, c->min_volume_dB, c->max_volume_dB);

	if (dir == CRAS_STREAM_OUTPUT)
		DL_APPEND(cmix->output_controls, c);
	else if (dir == CRAS_STREAM_INPUT)
		DL_APPEND(cmix->input_controls, c);
	return 0;
}

static int add_control(struct cras_alsa_mixer *cmix,
		       enum CRAS_STREAM_DIRECTION dir, snd_mixer_elem_t *elem)
{
	return add_control_with_name(cmix, dir, elem,
				     snd_mixer_selem_get_name(elem));
}

static void list_controls(struct mixer_control *control_list,
			  cras_alsa_mixer_control_callback cb, void *cb_arg)
{
	struct mixer_control *control;

	DL_FOREACH (control_list, control)
		cb(control, cb_arg);
}

static struct mixer_control *
get_control_matching_name(struct mixer_control *control_list, const char *name)
{
	struct mixer_control *c;

	DL_FOREACH (control_list, c) {
		if (strstr(name, c->name))
			return c;
	}
	return NULL;
}

/* Creates a mixer_control with multiple control elements. */
static int add_control_with_coupled_mixers(struct cras_alsa_mixer *cmix,
					   enum CRAS_STREAM_DIRECTION dir,
					   const char *name,
					   struct mixer_name *coupled_controls)
{
	struct mixer_control *c;
	int rc;

	rc = mixer_control_create_by_name(&c, cmix, name, coupled_controls,
					  dir);
	if (rc)
		return rc;
	syslog(LOG_DEBUG, "Add %s control: %s\n",
	       dir == CRAS_STREAM_OUTPUT ? "output" : "input", c->name);
	mixer_name_dump(coupled_controls, "  elements");

	if (c->has_volume)
		syslog(LOG_DEBUG, "Control '%s' volume range: [%ld:%ld]",
		       c->name, c->min_volume_dB, c->max_volume_dB);

	if (dir == CRAS_STREAM_OUTPUT)
		DL_APPEND(cmix->output_controls, c);
	else if (dir == CRAS_STREAM_INPUT)
		DL_APPEND(cmix->input_controls, c);
	return 0;
}

static int add_control_by_name(struct cras_alsa_mixer *cmix,
			       enum CRAS_STREAM_DIRECTION dir, const char *name)
{
	struct mixer_control *c;
	struct mixer_name *m_name;
	int rc;

	m_name = mixer_name_add(NULL, name, dir, MIXER_NAME_VOLUME);
	if (!m_name)
		return -ENOMEM;

	rc = mixer_control_create_by_name(&c, cmix, name, m_name, dir);
	mixer_name_free(m_name);
	if (rc)
		return rc;
	syslog(LOG_DEBUG, "Add %s control: %s\n",
	       dir == CRAS_STREAM_OUTPUT ? "output" : "input", c->name);

	if (c->has_volume)
		syslog(LOG_DEBUG, "Control '%s' volume range: [%ld:%ld]",
		       c->name, c->min_volume_dB, c->max_volume_dB);

	if (dir == CRAS_STREAM_OUTPUT)
		DL_APPEND(cmix->output_controls, c);
	else if (dir == CRAS_STREAM_INPUT)
		DL_APPEND(cmix->input_controls, c);
	return 0;
}

/*
 * Exported interface.
 */

struct cras_alsa_mixer *cras_alsa_mixer_create(const char *card_name)
{
	struct cras_alsa_mixer *cmix;

	cmix = (struct cras_alsa_mixer *)calloc(1, sizeof(*cmix));
	if (cmix == NULL)
		return NULL;

	syslog(LOG_DEBUG, "Add mixer for device %s", card_name);

	alsa_mixer_open(card_name, &cmix->mixer);

	return cmix;
}

int cras_alsa_mixer_add_controls_by_name_matching(
	struct cras_alsa_mixer *cmix, struct mixer_name *extra_controls,
	struct mixer_name *coupled_controls)
{
	/* Names of controls for main system volume. */
	static const char *const main_volume_names[] = {
		"Master",
		"Digital",
		"PCM",
	};
	/* Names of controls for individual outputs. */
	static const char *const output_names[] = {
		"Headphone",
		"Headset",
		"HDMI",
		"Speaker",
	};
	/* Names of controls for capture gain/attenuation and mute. */
	static const char *const main_capture_names[] = {
		"Capture",
		"Digital Capture",
	};
	/* Names of controls for individual inputs. */
	static const char *const input_names[] = {
		"Mic",
		"Microphone",
	};

	struct mixer_name *default_controls = NULL;
	snd_mixer_elem_t *elem;
	int extra_main_volume = 0;
	snd_mixer_elem_t *other_elem = NULL;
	long other_dB_range = 0;
	int rc = 0;

	/* Note that there is no mixer on some cards. This is acceptable. */
	if (cmix->mixer == NULL) {
		syslog(LOG_DEBUG, "Couldn't open mixer.");
		return 0;
	}

	default_controls =
		mixer_name_add_array(default_controls, output_names,
				     ARRAY_SIZE(output_names),
				     CRAS_STREAM_OUTPUT, MIXER_NAME_VOLUME);
	default_controls =
		mixer_name_add_array(default_controls, input_names,
				     ARRAY_SIZE(input_names), CRAS_STREAM_INPUT,
				     MIXER_NAME_VOLUME);
	default_controls =
		mixer_name_add_array(default_controls, main_volume_names,
				     ARRAY_SIZE(main_volume_names),
				     CRAS_STREAM_OUTPUT,
				     MIXER_NAME_MAIN_VOLUME);
	default_controls =
		mixer_name_add_array(default_controls, main_capture_names,
				     ARRAY_SIZE(main_capture_names),
				     CRAS_STREAM_INPUT, MIXER_NAME_MAIN_VOLUME);
	extra_main_volume =
		mixer_name_find(extra_controls, NULL, CRAS_STREAM_OUTPUT,
				MIXER_NAME_MAIN_VOLUME) != NULL;

	/* Find volume and mute controls. */
	for (elem = snd_mixer_first_elem(cmix->mixer); elem != NULL;
	     elem = snd_mixer_elem_next(elem)) {
		const char *name;
		struct mixer_name *control;
		int found = 0;

		name = snd_mixer_selem_get_name(elem);
		if (name == NULL)
			continue;

		/* Find a matching control. */
		control = mixer_name_find(default_controls, name,
					  CRAS_STREAM_OUTPUT,
					  MIXER_NAME_UNDEFINED);

		/* If our extra controls contain a main volume
		 * entry, and we found a main volume entry, then
		 * skip it. */
		if (extra_main_volume && control &&
		    control->type == MIXER_NAME_MAIN_VOLUME)
			control = NULL;

		/* If we didn't match any of the defaults, match
		 * the extras list. */
		if (!control)
			control = mixer_name_find(extra_controls, name,
						  CRAS_STREAM_OUTPUT,
						  MIXER_NAME_UNDEFINED);

		if (control) {
			int rc = -1;
			switch (control->type) {
			case MIXER_NAME_MAIN_VOLUME:
				rc = add_main_volume_control(cmix, elem);
				break;
			case MIXER_NAME_VOLUME:
				/* TODO(dgreid) - determine device index. */
				rc = add_control(cmix, CRAS_STREAM_OUTPUT,
						 elem);
				break;
			case MIXER_NAME_UNDEFINED:
				rc = -EINVAL;
				break;
			}
			if (rc) {
				syslog(LOG_ERR,
				       "Failed to add mixer control '%s'"
				       " with type '%d'",
				       control->name, control->type);
				goto out;
			}
			found = 1;
		}

		/* Find a matching input control. */
		control = mixer_name_find(default_controls, name,
					  CRAS_STREAM_INPUT,
					  MIXER_NAME_UNDEFINED);

		/* If we didn't match any of the defaults, match
		   the extras list */
		if (!control)
			control = mixer_name_find(extra_controls, name,
						  CRAS_STREAM_INPUT,
						  MIXER_NAME_UNDEFINED);

		if (control) {
			int rc = -1;
			switch (control->type) {
			case MIXER_NAME_MAIN_VOLUME:
				rc = add_main_capture_control(cmix, elem);
				break;
			case MIXER_NAME_VOLUME:
				rc = add_control(cmix, CRAS_STREAM_INPUT, elem);
				break;
			case MIXER_NAME_UNDEFINED:
				rc = -EINVAL;
				break;
			}
			if (rc) {
				syslog(LOG_ERR,
				       "Failed to add mixer control '%s'"
				       " with type '%d'",
				       control->name, control->type);
				goto out;
			}
			found = 1;
		}

		if (!found && snd_mixer_selem_has_playback_volume(elem)) {
			/* Temporarily cache one elem whose name is not
			 * in the list above, but has a playback volume
			 * control and the largest volume range. */
			long min, max, range;
			if (snd_mixer_selem_get_playback_dB_range(elem, &min,
								  &max) != 0)
				continue;

			range = max - min;
			if (other_dB_range < range) {
				other_dB_range = range;
				other_elem = elem;
			}
		}
	}

	/* Handle coupled output names for speaker */
	if (coupled_controls) {
		rc = add_control_with_coupled_mixers(
			cmix, CRAS_STREAM_OUTPUT, "Speaker", coupled_controls);
		if (rc) {
			syslog(LOG_ERR, "Could not add coupled output");
			goto out;
		}
	}

	/* If there is no volume control and output control found,
	 * use the volume control which has the largest volume range
	 * in the mixer as a main volume control. */
	if (!cmix->main_volume_controls && !cmix->output_controls &&
	    other_elem) {
		rc = add_main_volume_control(cmix, other_elem);
		if (rc) {
			syslog(LOG_ERR, "Could not add other volume control");
			goto out;
		}
	}

out:
	mixer_name_free(default_controls);
	return rc;
}

int cras_alsa_mixer_add_main_volume_control_by_name(
	struct cras_alsa_mixer *cmix, struct mixer_name *mixer_names)
{
	snd_mixer_elem_t *elem;
	struct mixer_name *m_name;
	int rc = 0;
	snd_mixer_selem_id_t *sid;

	if (!mixer_names)
		return -EINVAL;

	snd_mixer_selem_id_malloc(&sid);

	DL_FOREACH (mixer_names, m_name) {
		snd_mixer_selem_id_set_index(sid, 0);
		snd_mixer_selem_id_set_name(sid, m_name->name);
		elem = snd_mixer_find_selem(cmix->mixer, sid);
		if (!elem) {
			rc = -ENOENT;
			syslog(LOG_ERR, "Unable to find simple control %s, 0",
			       m_name->name);
			break;
		}
		rc = add_main_volume_control(cmix, elem);
		if (rc)
			break;
	}

	snd_mixer_selem_id_free(sid);
	return rc;
}

int cras_alsa_mixer_add_controls_in_section(struct cras_alsa_mixer *cmix,
					    struct ucm_section *section)
{
	int rc;

	/* Note that there is no mixer on some cards. This is acceptable. */
	if (cmix->mixer == NULL) {
		syslog(LOG_DEBUG, "Couldn't open mixer.");
		return 0;
	}

	if (!section) {
		syslog(LOG_ERR, "No UCM SectionDevice specified.");
		return -EINVAL;
	}

	/* TODO(muirj) - Extra main volume controls when fully-specified. */

	if (section->mixer_name) {
		rc = add_control_by_name(cmix, section->dir,
					 section->mixer_name);
		if (rc) {
			syslog(LOG_ERR, "Could not add mixer control '%s': %s",
			       section->mixer_name, strerror(-rc));
			return rc;
		}
	}

	if (section->coupled) {
		rc = add_control_with_coupled_mixers(
			cmix, section->dir, section->name, section->coupled);
		if (rc) {
			syslog(LOG_ERR, "Could not add coupled control: %s",
			       strerror(-rc));
			return rc;
		}
	}
	return 0;
}

void cras_alsa_mixer_destroy(struct cras_alsa_mixer *cras_mixer)
{
	assert(cras_mixer);

	mixer_control_destroy_list(cras_mixer->main_volume_controls);
	mixer_control_destroy_list(cras_mixer->main_capture_controls);
	mixer_control_destroy_list(cras_mixer->output_controls);
	mixer_control_destroy_list(cras_mixer->input_controls);
	if (cras_mixer->mixer)
		snd_mixer_close(cras_mixer->mixer);
	free(cras_mixer);
}

int cras_alsa_mixer_has_main_volume(const struct cras_alsa_mixer *cras_mixer)
{
	return !!cras_mixer->main_volume_controls;
}

int cras_alsa_mixer_has_volume(const struct mixer_control *mixer_control)
{
	return mixer_control && mixer_control->has_volume;
}

void cras_alsa_mixer_set_dBFS(struct cras_alsa_mixer *cras_mixer, long dBFS,
			      struct mixer_control *mixer_output)
{
	struct mixer_control *c;
	long to_set;

	assert(cras_mixer);

	/* dBFS is normally < 0 to specify the attenuation from max. max is the
	 * combined max of the master controls and the current output.
	 */
	to_set = dBFS + cras_mixer->max_volume_dB;
	if (cras_alsa_mixer_has_volume(mixer_output))
		to_set += mixer_output->max_volume_dB;
	/* Go through all the controls, set the volume level for each,
	 * taking the value closest but greater than the desired volume.  If the
	 * entire volume can't be set on the current control, move on to the
	 * next one until we have the exact volume, or gotten as close as we
	 * can. Once all of the volume is set the rest of the controls should be
	 * set to 0dB. */
	DL_FOREACH (cras_mixer->main_volume_controls, c) {
		long actual_dB;

		if (!c->has_volume)
			continue;
		if (mixer_control_set_dBFS(c, to_set) == 0 &&
		    mixer_control_get_dBFS(c, &actual_dB) == 0)
			to_set -= actual_dB;
	}
	/* Apply the rest to the output-specific control. */
	if (cras_alsa_mixer_has_volume(mixer_output))
		mixer_control_set_dBFS(mixer_output, to_set);
}

long cras_alsa_mixer_get_dB_range(struct cras_alsa_mixer *cras_mixer)
{
	if (!cras_mixer)
		return 0;
	return cras_mixer->max_volume_dB - cras_mixer->min_volume_dB;
}

long cras_alsa_mixer_get_output_dB_range(struct mixer_control *mixer_output)
{
	if (!cras_alsa_mixer_has_volume(mixer_output))
		return 0;

	return mixer_output->max_volume_dB - mixer_output->min_volume_dB;
}

void cras_alsa_mixer_set_capture_dBFS(struct cras_alsa_mixer *cras_mixer,
				      long dBFS,
				      struct mixer_control *mixer_input)
{
	struct mixer_control *c;
	long to_set;

	assert(cras_mixer);
	to_set = dBFS;
	/* Go through all the controls, set the gain for each, taking the value
	 * closest but greater than the desired gain.  If the entire gain can't
	 * be set on the current control, move on to the next one until we have
	 * the exact gain, or gotten as close as we can. Once all of the gain is
	 * set the rest of the controls should be set to 0dB. */
	DL_FOREACH (cras_mixer->main_capture_controls, c) {
		long actual_dB;

		if (!c->has_volume)
			continue;
		if (mixer_control_set_dBFS(c, to_set) == 0 &&
		    mixer_control_get_dBFS(c, &actual_dB) == 0)
			to_set -= actual_dB;
	}

	/* Apply the reset to input specific control */
	if (cras_alsa_mixer_has_volume(mixer_input))
		mixer_control_set_dBFS(mixer_input, to_set);
}

long cras_alsa_mixer_get_minimum_capture_gain(struct cras_alsa_mixer *cmix,
					      struct mixer_control *mixer_input)
{
	struct mixer_control *c;
	long total_min = 0;

	assert(cmix);
	DL_FOREACH (cmix->main_capture_controls, c)
		if (c->has_volume)
			total_min += c->min_volume_dB;
	if (mixer_input && mixer_input->has_volume)
		total_min += mixer_input->min_volume_dB;

	return total_min;
}

long cras_alsa_mixer_get_maximum_capture_gain(struct cras_alsa_mixer *cmix,
					      struct mixer_control *mixer_input)
{
	struct mixer_control *c;
	long total_max = 0;

	assert(cmix);
	DL_FOREACH (cmix->main_capture_controls, c)
		if (c->has_volume)
			total_max += c->max_volume_dB;

	if (mixer_input && mixer_input->has_volume)
		total_max += mixer_input->max_volume_dB;

	return total_max;
}

void cras_alsa_mixer_set_mute(struct cras_alsa_mixer *cras_mixer, int muted,
			      struct mixer_control *mixer_output)
{
	assert(cras_mixer);

	if (cras_mixer->playback_switch) {
		snd_mixer_selem_set_playback_switch_all(
			cras_mixer->playback_switch, !muted);
	}
	if (mixer_output && mixer_output->has_mute) {
		mixer_control_set_mute(mixer_output, muted);
	}
}

void cras_alsa_mixer_set_capture_mute(struct cras_alsa_mixer *cras_mixer,
				      int muted,
				      struct mixer_control *mixer_input)
{
	assert(cras_mixer);
	if (cras_mixer->capture_switch) {
		snd_mixer_selem_set_capture_switch_all(
			cras_mixer->capture_switch, !muted);
		return;
	}
	if (mixer_input && mixer_input->has_mute)
		mixer_control_set_mute(mixer_input, muted);
}

void cras_alsa_mixer_list_outputs(struct cras_alsa_mixer *cras_mixer,
				  cras_alsa_mixer_control_callback cb,
				  void *cb_arg)
{
	assert(cras_mixer);
	list_controls(cras_mixer->output_controls, cb, cb_arg);
}

void cras_alsa_mixer_list_inputs(struct cras_alsa_mixer *cras_mixer,
				 cras_alsa_mixer_control_callback cb,
				 void *cb_arg)
{
	assert(cras_mixer);
	list_controls(cras_mixer->input_controls, cb, cb_arg);
}

const char *
cras_alsa_mixer_get_control_name(const struct mixer_control *control)
{
	if (!control)
		return NULL;
	return control->name;
}

struct mixer_control *
cras_alsa_mixer_get_control_matching_name(struct cras_alsa_mixer *cras_mixer,
					  enum CRAS_STREAM_DIRECTION dir,
					  const char *name, int create_missing)
{
	struct mixer_control *c;

	assert(cras_mixer);
	if (!name)
		return NULL;

	if (dir == CRAS_STREAM_OUTPUT) {
		c = get_control_matching_name(cras_mixer->output_controls,
					      name);
	} else if (dir == CRAS_STREAM_INPUT) {
		c = get_control_matching_name(cras_mixer->input_controls, name);
	} else {
		return NULL;
	}

	/* TODO: Allowing creation of a new control is a workaround: we
	 * should pass the input names in ucm config to
	 * cras_alsa_mixer_create. */
	if (!c && cras_mixer->mixer && create_missing) {
		int rc = add_control_by_name(cras_mixer, dir, name);
		if (rc)
			return NULL;
		c = cras_alsa_mixer_get_control_matching_name(cras_mixer, dir,
							      name, 0);
	}
	return c;
}

struct mixer_control *
cras_alsa_mixer_get_control_for_section(struct cras_alsa_mixer *cras_mixer,
					const struct ucm_section *section)
{
	assert(cras_mixer && section);
	if (section->mixer_name) {
		return cras_alsa_mixer_get_control_matching_name(
			cras_mixer, section->dir, section->mixer_name, 0);
	} else if (section->coupled) {
		return cras_alsa_mixer_get_control_matching_name(
			cras_mixer, section->dir, section->name, 0);
	}
	return NULL;
}

struct mixer_control *
cras_alsa_mixer_get_output_matching_name(struct cras_alsa_mixer *cras_mixer,
					 const char *const name)
{
	return cras_alsa_mixer_get_control_matching_name(
		cras_mixer, CRAS_STREAM_OUTPUT, name, 0);
}

struct mixer_control *
cras_alsa_mixer_get_input_matching_name(struct cras_alsa_mixer *cras_mixer,
					const char *name)
{
	/* TODO: Allowing creation of a new control is a workaround: we
	 * should pass the input names in ucm config to
	 * cras_alsa_mixer_create. */
	return cras_alsa_mixer_get_control_matching_name(
		cras_mixer, CRAS_STREAM_INPUT, name, 1);
}

int cras_alsa_mixer_set_output_active_state(struct mixer_control *output,
					    int active)
{
	assert(output);
	if (!output->has_mute)
		return -1;
	return mixer_control_set_mute(output, !active);
}
