Blame src/mixer/simple.c

Packit 4a16fb
/**
Packit 4a16fb
 * \file mixer/simple.c
Packit 4a16fb
 * \brief Mixer Simple Element Class Interface
Packit 4a16fb
 * \author Jaroslav Kysela <perex@perex.cz>
Packit 4a16fb
 * \author Abramo Bagnara <abramo@alsa-project.org>
Packit 4a16fb
 * \date 2001-2004
Packit 4a16fb
 *
Packit 4a16fb
 * Mixer simple element class interface.
Packit 4a16fb
 */
Packit 4a16fb
/*
Packit 4a16fb
 *  Mixer Interface - simple controls
Packit 4a16fb
 *  Copyright (c) 2000,2004 by Jaroslav Kysela <perex@perex.cz>
Packit 4a16fb
 *  Copyright (c) 2001 by Abramo Bagnara <abramo@alsa-project.org>
Packit 4a16fb
 *
Packit 4a16fb
 *
Packit 4a16fb
 *   This library is free software; you can redistribute it and/or modify
Packit 4a16fb
 *   it under the terms of the GNU Lesser General Public License as
Packit 4a16fb
 *   published by the Free Software Foundation; either version 2.1 of
Packit 4a16fb
 *   the License, or (at your option) any later version.
Packit 4a16fb
 *
Packit 4a16fb
 *   This program is distributed in the hope that it will be useful,
Packit 4a16fb
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 4a16fb
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 4a16fb
 *   GNU Lesser General Public License for more details.
Packit 4a16fb
 *
Packit 4a16fb
 *   You should have received a copy of the GNU Lesser General Public
Packit 4a16fb
 *   License along with this library; if not, write to the Free Software
Packit 4a16fb
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Packit 4a16fb
 *
Packit 4a16fb
 */
Packit 4a16fb
Packit 4a16fb
#include <stdio.h>
Packit 4a16fb
#include <stdlib.h>
Packit 4a16fb
#include <unistd.h>
Packit 4a16fb
#include <string.h>
Packit 4a16fb
#include <fcntl.h>
Packit 4a16fb
#include <sys/ioctl.h>
Packit 4a16fb
#include <math.h>
Packit 4a16fb
#include "config.h"
Packit 4a16fb
#include "mixer_local.h"
Packit 4a16fb
#include "mixer_simple.h"
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Register mixer simple element class
Packit 4a16fb
 * \param mixer Mixer handle
Packit 4a16fb
 * \param options Options container
Packit 4a16fb
 * \param classp Pointer to returned mixer simple element class handle (or NULL)
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_register(snd_mixer_t *mixer,
Packit 4a16fb
			     struct snd_mixer_selem_regopt *options,
Packit 4a16fb
			     snd_mixer_class_t **classp)
Packit 4a16fb
{
Packit 4a16fb
	if (options && options->ver == 1) {
Packit 4a16fb
		if (options->device != NULL &&
Packit 4a16fb
		    (options->playback_pcm != NULL ||
Packit 4a16fb
		     options->capture_pcm != NULL))
Packit 4a16fb
			return -EINVAL;
Packit 4a16fb
		if (options->device == NULL &&
Packit 4a16fb
		    options->playback_pcm == NULL &&
Packit 4a16fb
		    options->capture_pcm == NULL)
Packit 4a16fb
			return -EINVAL;
Packit 4a16fb
	}
Packit 4a16fb
	if (options == NULL ||
Packit 4a16fb
	    (options->ver == 1 && options->abstract == SND_MIXER_SABSTRACT_NONE)) {
Packit 4a16fb
		int err = snd_mixer_simple_none_register(mixer, options, classp);
Packit 4a16fb
		if (err < 0)
Packit 4a16fb
			return err;
Packit 4a16fb
		if (options != NULL) {
Packit 4a16fb
			err = snd_mixer_attach(mixer, options->device);
Packit 4a16fb
			if (err < 0)
Packit 4a16fb
				return err;
Packit 4a16fb
		}
Packit 4a16fb
		return 0;
Packit 4a16fb
	} else if (options->ver == 1) {
Packit 4a16fb
		if (options->abstract == SND_MIXER_SABSTRACT_BASIC)
Packit 4a16fb
			return snd_mixer_simple_basic_register(mixer, options, classp);
Packit 4a16fb
	}
Packit 4a16fb
	return -ENXIO;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
#ifndef DOC_HIDDEN
Packit 4a16fb
Packit 4a16fb
#define CHECK_BASIC(xelem) \
Packit 4a16fb
{ \
Packit 4a16fb
	assert(xelem); \
Packit 4a16fb
	assert((xelem)->type == SND_MIXER_ELEM_SIMPLE); \
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
#define CHECK_DIR(xelem, xwhat) \
Packit 4a16fb
{ \
Packit 4a16fb
	unsigned int xcaps = ((sm_selem_t *)(elem)->private_data)->caps; \
Packit 4a16fb
	if (! (xcaps & (xwhat))) \
Packit 4a16fb
		return -EINVAL; \
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
#define CHECK_DIR_CHN(xelem, xwhat, xjoin, xchannel) \
Packit 4a16fb
{ \
Packit 4a16fb
	unsigned int xcaps = ((sm_selem_t *)(elem)->private_data)->caps; \
Packit 4a16fb
	if (! (xcaps & (xwhat))) \
Packit 4a16fb
		return -EINVAL; \
Packit 4a16fb
	if (xcaps & (xjoin)) \
Packit 4a16fb
		xchannel = 0; \
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
#define CHECK_ENUM(xelem) \
Packit 4a16fb
	if (!(((sm_selem_t *)(elem)->private_data)->caps & (SM_CAP_PENUM|SM_CAP_CENUM))) \
Packit 4a16fb
		return -EINVAL;
Packit 4a16fb
Packit 4a16fb
#define COND_CAPS(xelem, what) \
Packit 4a16fb
	!!(((sm_selem_t *)(elem)->private_data)->caps & (what))
Packit 4a16fb
Packit 4a16fb
#endif /* !DOC_HIDDEN */
Packit 4a16fb
Packit 4a16fb
#ifndef DOC_HIDDEN
Packit 4a16fb
int snd_mixer_selem_compare(const snd_mixer_elem_t *c1, const snd_mixer_elem_t *c2)
Packit 4a16fb
{
Packit 4a16fb
	sm_selem_t *s1 = c1->private_data;
Packit 4a16fb
	sm_selem_t *s2 = c2->private_data;
Packit 4a16fb
	int res = strcmp(s1->id->name, s2->id->name);
Packit 4a16fb
	if (res)
Packit 4a16fb
		return res;
Packit 4a16fb
	return s1->id->index - s2->id->index;
Packit 4a16fb
}
Packit 4a16fb
#endif
Packit 4a16fb
	
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Find a mixer simple element
Packit 4a16fb
 * \param mixer Mixer handle
Packit 4a16fb
 * \param id Mixer simple element identifier
Packit 4a16fb
 * \return mixer simple element handle or NULL if not found
Packit 4a16fb
 */
Packit 4a16fb
snd_mixer_elem_t *snd_mixer_find_selem(snd_mixer_t *mixer,
Packit 4a16fb
				       const snd_mixer_selem_id_t *id)
Packit 4a16fb
{
Packit 4a16fb
	struct list_head *list;
Packit 4a16fb
	snd_mixer_elem_t *e;
Packit 4a16fb
	sm_selem_t *s;
Packit 4a16fb
Packit 4a16fb
	list_for_each(list, &mixer->elems) {
Packit 4a16fb
		e = list_entry(list, snd_mixer_elem_t, list);
Packit 4a16fb
		if (e->type != SND_MIXER_ELEM_SIMPLE)
Packit 4a16fb
			continue;
Packit 4a16fb
		s = e->private_data;
Packit 4a16fb
		if (!strcmp(s->id->name, id->name) && s->id->index == id->index)
Packit 4a16fb
			return e;
Packit 4a16fb
	}
Packit 4a16fb
	return NULL;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Get mixer simple element identifier
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param id returned mixer simple element identifier
Packit 4a16fb
 */
Packit 4a16fb
void snd_mixer_selem_get_id(snd_mixer_elem_t *elem,
Packit 4a16fb
			    snd_mixer_selem_id_t *id)
Packit 4a16fb
{
Packit 4a16fb
	sm_selem_t *s;
Packit 4a16fb
	assert(id);
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	s = elem->private_data;
Packit 4a16fb
	*id = *s->id;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Get name part of mixer simple element identifier
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return name part of simple element identifier
Packit 4a16fb
 */
Packit 4a16fb
const char *snd_mixer_selem_get_name(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	sm_selem_t *s;
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	s = elem->private_data;
Packit 4a16fb
	return s->id->name;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Get index part of mixer simple element identifier
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return index part of simple element identifier
Packit 4a16fb
 */
Packit 4a16fb
unsigned int snd_mixer_selem_get_index(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	sm_selem_t *s;
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	s = elem->private_data;
Packit 4a16fb
	return s->id->index;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return true if mixer simple element has only one volume control for both playback and capture
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 separated control, 1 common control
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_has_common_volume(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return COND_CAPS(elem, SM_CAP_GVOLUME);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return true if mixer simple element has only one switch control for both playback and capture
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 separated control, 1 common control
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_has_common_switch(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return COND_CAPS(elem, SM_CAP_GSWITCH);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return name of mixer simple element channel
Packit 4a16fb
 * \param channel mixer simple element channel identifier
Packit 4a16fb
 * \return channel name
Packit 4a16fb
 */
Packit 4a16fb
const char *snd_mixer_selem_channel_name(snd_mixer_selem_channel_id_t channel)
Packit 4a16fb
{
Packit 4a16fb
	static const char *const array[SND_MIXER_SCHN_LAST + 1] = {
Packit 4a16fb
		[SND_MIXER_SCHN_FRONT_LEFT] = "Front Left",
Packit 4a16fb
		[SND_MIXER_SCHN_FRONT_RIGHT] = "Front Right",
Packit 4a16fb
		[SND_MIXER_SCHN_REAR_LEFT] = "Rear Left",
Packit 4a16fb
		[SND_MIXER_SCHN_REAR_RIGHT] = "Rear Right",
Packit 4a16fb
		[SND_MIXER_SCHN_FRONT_CENTER] = "Front Center",
Packit 4a16fb
		[SND_MIXER_SCHN_WOOFER] = "Woofer",
Packit 4a16fb
		[SND_MIXER_SCHN_SIDE_LEFT] = "Side Left",
Packit 4a16fb
		[SND_MIXER_SCHN_SIDE_RIGHT] = "Side Right",
Packit 4a16fb
		[SND_MIXER_SCHN_REAR_CENTER] = "Rear Center"
Packit 4a16fb
	};
Packit 4a16fb
	const char *p;
Packit 4a16fb
	assert(channel <= SND_MIXER_SCHN_LAST);
Packit 4a16fb
	p = array[channel];
Packit 4a16fb
	if (!p)
Packit 4a16fb
		return "?";
Packit 4a16fb
	return p;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Get info about the active state of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 if not active, 1 if active
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_is_active(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return sm_selem_ops(elem)->is(elem, SM_PLAY, SM_OPS_IS_ACTIVE, 0);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Get info about channels of playback stream of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 if not mono, 1 if mono
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_is_playback_mono(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return sm_selem_ops(elem)->is(elem, SM_PLAY, SM_OPS_IS_MONO, 0);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Get info about channels of playback stream of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param channel Mixer simple element channel identifier
Packit 4a16fb
 * \return 0 if channel is not present, 1 if present
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_has_playback_channel(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return sm_selem_ops(elem)->is(elem, SM_PLAY, SM_OPS_IS_CHANNEL, (int)channel);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Get range for playback volume of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param min Pointer to returned minimum
Packit 4a16fb
 * \param max Pointer to returned maximum
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_get_playback_volume_range(snd_mixer_elem_t *elem,
Packit 4a16fb
					       long *min, long *max)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR(elem, SM_CAP_PVOLUME);
Packit 4a16fb
	return sm_selem_ops(elem)->get_range(elem, SM_PLAY, min, max);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Get range in dB for playback volume of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param min Pointer to returned minimum (dB * 100)
Packit 4a16fb
 * \param max Pointer to returned maximum (dB * 100)
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_get_playback_dB_range(snd_mixer_elem_t *elem,
Packit 4a16fb
					  long *min, long *max)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR(elem, SM_CAP_PVOLUME);
Packit 4a16fb
	return sm_selem_ops(elem)->get_dB_range(elem, SM_PLAY, min, max);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Set range for playback volume of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param min minimum volume value
Packit 4a16fb
 * \param max maximum volume value
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_set_playback_volume_range(snd_mixer_elem_t *elem, 
Packit 4a16fb
					      long min, long max)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	assert(min < max);
Packit 4a16fb
	CHECK_DIR(elem, SM_CAP_PVOLUME);
Packit 4a16fb
	return sm_selem_ops(elem)->set_range(elem, SM_PLAY, min, max);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return info about playback volume control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 if no control is present, 1 if it's present
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_has_playback_volume(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return COND_CAPS(elem, SM_CAP_PVOLUME);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return info about playback volume control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 if control is separated per channel, 1 if control acts on all channels together
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_has_playback_volume_joined(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return COND_CAPS(elem, SM_CAP_PVOLUME_JOIN);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return info about playback switch control existence of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 if no control is present, 1 if it's present
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_has_playback_switch(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return COND_CAPS(elem, SM_CAP_PSWITCH);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return info about playback switch control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 if control is separated per channel, 1 if control acts on all channels together
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_has_playback_switch_joined(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return COND_CAPS(elem, SM_CAP_PSWITCH_JOIN);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return corresponding dB value to an integer playback volume for a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param value value to be converted to dB range
Packit 4a16fb
 * \param dBvalue pointer to returned dB value
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_ask_playback_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR(elem, SM_CAP_PVOLUME);
Packit 4a16fb
	return sm_selem_ops(elem)->ask_vol_dB(elem, SM_PLAY, value, dBvalue);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return corresponding integer playback volume for given dB value for a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param value value to be converted to dB range
Packit Service f36a15
 * \param dir rounding mode - rounds up if dir > 0, round to nearest if dir == 0,
Packit Service f36a15
 *            rounds down if dir < 0
Packit 4a16fb
 * \param dBvalue pointer to returned dB value
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_ask_playback_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR(elem, SM_CAP_PVOLUME);
Packit 4a16fb
	return sm_selem_ops(elem)->ask_dB_vol(elem, SM_PLAY, dBvalue, value, dir);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return value of playback volume control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param channel mixer simple element channel identifier
Packit 4a16fb
 * \param value pointer to returned value
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR_CHN(elem, SM_CAP_PVOLUME, SM_CAP_PVOLUME_JOIN, channel);
Packit 4a16fb
	return sm_selem_ops(elem)->get_volume(elem, SM_PLAY, channel, value);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return value of playback volume in dB control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param channel mixer simple element channel identifier
Packit 4a16fb
 * \param value pointer to returned value (dB * 100)
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_get_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
Packit 4a16fb
{
Packit 4a16fb
	unsigned int caps;
Packit 4a16fb
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	caps = ((sm_selem_t *)elem->private_data)->caps;
Packit 4a16fb
	if (!(caps & SM_CAP_PVOLUME))
Packit 4a16fb
		return -EINVAL;
Packit 4a16fb
	if (caps & SM_CAP_PVOLUME_JOIN)
Packit 4a16fb
		channel = 0;
Packit 4a16fb
	return sm_selem_ops(elem)->get_dB(elem, SM_PLAY, channel, value);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return value of playback switch control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param channel mixer simple element channel identifier
Packit 4a16fb
 * \param value pointer to returned value
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_get_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR_CHN(elem, SM_CAP_PSWITCH, SM_CAP_PSWITCH_JOIN, channel);
Packit 4a16fb
	return sm_selem_ops(elem)->get_switch(elem, SM_PLAY, channel, value);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Set value of playback volume control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param channel mixer simple element channel identifier
Packit 4a16fb
 * \param value control value
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_set_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR_CHN(elem, SM_CAP_PVOLUME, SM_CAP_PVOLUME_JOIN, channel);
Packit 4a16fb
	return sm_selem_ops(elem)->set_volume(elem, SM_PLAY, channel, value);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Set value in dB of playback volume control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param channel mixer simple element channel identifier
Packit 4a16fb
 * \param value control value in dB * 100
Packit Service f36a15
 * \param dir rounding mode - rounds up if dir > 0, round to nearest if dir == 0,
Packit Service f36a15
 *            rounds down if dir < 0
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_set_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR_CHN(elem, SM_CAP_PVOLUME, SM_CAP_PVOLUME_JOIN, channel);
Packit 4a16fb
	return sm_selem_ops(elem)->set_dB(elem, SM_PLAY, channel, value, dir);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Set value of playback volume control for all channels of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param value control value
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_set_playback_volume_all(snd_mixer_elem_t *elem, long value)
Packit 4a16fb
{
Packit 4a16fb
	snd_mixer_selem_channel_id_t chn;
Packit 4a16fb
	int err;
Packit 4a16fb
Packit 4a16fb
	for (chn = 0; chn < 32; chn++) {
Packit 4a16fb
		if (!snd_mixer_selem_has_playback_channel(elem, chn))
Packit 4a16fb
			continue;
Packit 4a16fb
		err = snd_mixer_selem_set_playback_volume(elem, chn, value);
Packit 4a16fb
		if (err < 0)
Packit 4a16fb
			return err;
Packit 4a16fb
		if (chn == 0 && snd_mixer_selem_has_playback_volume_joined(elem))
Packit 4a16fb
			return 0;
Packit 4a16fb
	}
Packit 4a16fb
	return 0;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Set value in dB of playback volume control for all channels of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param value control value in dB * 100
Packit Service f36a15
 * \param dir rounding mode - rounds up if dir > 0, round to nearest if dir == 0,
Packit Service f36a15
 *            rounds down if dir < 0
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_set_playback_dB_all(snd_mixer_elem_t *elem, long value, int dir)
Packit 4a16fb
{
Packit 4a16fb
	snd_mixer_selem_channel_id_t chn;
Packit 4a16fb
	int err;
Packit 4a16fb
Packit 4a16fb
	for (chn = 0; chn < 32; chn++) {
Packit 4a16fb
		if (!snd_mixer_selem_has_playback_channel(elem, chn))
Packit 4a16fb
			continue;
Packit 4a16fb
		err = snd_mixer_selem_set_playback_dB(elem, chn, value, dir);
Packit 4a16fb
		if (err < 0)
Packit 4a16fb
			return err;
Packit 4a16fb
		if (chn == 0 && snd_mixer_selem_has_playback_volume_joined(elem))
Packit 4a16fb
			return 0;
Packit 4a16fb
	}
Packit 4a16fb
	return 0;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Set value of playback switch control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param channel mixer simple element channel identifier
Packit 4a16fb
 * \param value control value
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_set_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR_CHN(elem, SM_CAP_PSWITCH, SM_CAP_PSWITCH_JOIN, channel);
Packit 4a16fb
	return sm_selem_ops(elem)->set_switch(elem, SM_PLAY, channel, value);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Set value of playback switch control for all channels of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param value control value
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_set_playback_switch_all(snd_mixer_elem_t *elem, int value)
Packit 4a16fb
{
Packit 4a16fb
	snd_mixer_selem_channel_id_t chn;
Packit 4a16fb
	int err;
Packit 4a16fb
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	for (chn = 0; chn < 32; chn++) {
Packit 4a16fb
		if (!snd_mixer_selem_has_playback_channel(elem, chn))
Packit 4a16fb
			continue;
Packit 4a16fb
		err = snd_mixer_selem_set_playback_switch(elem, chn, value);
Packit 4a16fb
		if (err < 0)
Packit 4a16fb
			return err;
Packit 4a16fb
		if (chn == 0 && snd_mixer_selem_has_playback_switch_joined(elem))
Packit 4a16fb
			return 0;
Packit 4a16fb
	}
Packit 4a16fb
	return 0;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Get info about channels of capture stream of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 if not mono, 1 if mono
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_is_capture_mono(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR(elem, SM_CAP_CVOLUME|SM_CAP_CSWITCH);
Packit 4a16fb
	return sm_selem_ops(elem)->is(elem, SM_CAPT, SM_OPS_IS_MONO, 0);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Get info about channels of capture stream of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param channel Mixer simple element channel identifier
Packit 4a16fb
 * \return 0 if channel is not present, 1 if present
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_has_capture_channel(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR(elem, SM_CAP_CVOLUME|SM_CAP_CSWITCH);
Packit 4a16fb
	return sm_selem_ops(elem)->is(elem, SM_CAPT, SM_OPS_IS_CHANNEL, channel);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Get range for capture volume of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param min Pointer to returned minimum
Packit 4a16fb
 * \param max Pointer to returned maximum
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_get_capture_volume_range(snd_mixer_elem_t *elem,
Packit 4a16fb
					     long *min, long *max)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR(elem, SM_CAP_CVOLUME);
Packit 4a16fb
	return sm_selem_ops(elem)->get_range(elem, SM_CAPT, min, max);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Get range in dB for capture volume of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param min Pointer to returned minimum (dB * 100)
Packit 4a16fb
 * \param max Pointer to returned maximum (dB * 100)
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_get_capture_dB_range(snd_mixer_elem_t *elem,
Packit 4a16fb
					 long *min, long *max)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR(elem, SM_CAP_CVOLUME);
Packit 4a16fb
	return sm_selem_ops(elem)->get_dB_range(elem, SM_CAPT, min, max);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Set range for capture volume of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param min minimum volume value
Packit 4a16fb
 * \param max maximum volume value
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_set_capture_volume_range(snd_mixer_elem_t *elem, 
Packit 4a16fb
					     long min, long max)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	assert(min < max);
Packit 4a16fb
	CHECK_DIR(elem, SM_CAP_CVOLUME);
Packit 4a16fb
	return sm_selem_ops(elem)->set_range(elem, SM_CAPT, min, max);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return info about capture volume control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 if no control is present, 1 if it's present
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_has_capture_volume(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return COND_CAPS(elem, SM_CAP_CVOLUME);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return info about capture volume control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 if control is separated per channel, 1 if control acts on all channels together
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_has_capture_volume_joined(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return COND_CAPS(elem, SM_CAP_CVOLUME_JOIN);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return info about capture switch control existence of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 if no control is present, 1 if it's present
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_has_capture_switch(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return COND_CAPS(elem, SM_CAP_CSWITCH);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return info about capture switch control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 if control is separated per channel, 1 if control acts on all channels together
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_has_capture_switch_joined(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return COND_CAPS(elem, SM_CAP_CSWITCH_JOIN);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return info about capture switch control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 if control is separated per element, 1 if control acts on other elements too (i.e. only one active at a time inside a group)
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_has_capture_switch_exclusive(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return COND_CAPS(elem, SM_CAP_CSWITCH_EXCL);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return info about capture switch control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return group for switch exclusivity (see #snd_mixer_selem_has_capture_switch_exclusive)
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_get_capture_group(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	sm_selem_t *s;
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	s = elem->private_data;
Packit 4a16fb
	if (! (s->caps & SM_CAP_CSWITCH_EXCL))
Packit 4a16fb
		return -EINVAL;
Packit 4a16fb
	return s->capture_group;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return corresponding dB value to an integer capture volume for a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param value value to be converted to dB range
Packit 4a16fb
 * \param dBvalue pointer to returned dB value
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_ask_capture_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR(elem, SM_CAP_CVOLUME);
Packit 4a16fb
	return sm_selem_ops(elem)->ask_vol_dB(elem, SM_CAPT, value, dBvalue);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return corresponding integer capture volume for given dB value for a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param dBvalue dB value to be converted to integer range
Packit 4a16fb
 * \param value pointer to returned integer value
Packit Service f36a15
 * \param dir rounding mode - rounds up if dir > 0, round to nearest if dir == 0,
Packit Service f36a15
 *            rounds down if dir < 0
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_ask_capture_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR(elem, SM_CAP_CVOLUME);
Packit 4a16fb
	return sm_selem_ops(elem)->ask_dB_vol(elem, SM_CAPT, dBvalue, value, dir);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return value of capture volume control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param channel mixer simple element channel identifier
Packit 4a16fb
 * \param value pointer to returned value
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_get_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR_CHN(elem, SM_CAP_CVOLUME, SM_CAP_CVOLUME_JOIN, channel);
Packit 4a16fb
	return sm_selem_ops(elem)->get_volume(elem, SM_CAPT, channel, value);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return value of capture volume in dB control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param channel mixer simple element channel identifier
Packit 4a16fb
 * \param value pointer to returned value (dB * 100)
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_get_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR_CHN(elem, SM_CAP_CVOLUME, SM_CAP_CVOLUME_JOIN, channel);
Packit 4a16fb
	return sm_selem_ops(elem)->get_dB(elem, SM_CAPT, channel, value);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return value of capture switch control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param channel mixer simple element channel identifier
Packit 4a16fb
 * \param value pointer to returned value
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_get_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR_CHN(elem, SM_CAP_CSWITCH, SM_CAP_CSWITCH_JOIN, channel);
Packit 4a16fb
	return sm_selem_ops(elem)->get_switch(elem, SM_CAPT, channel, value);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Set value of capture volume control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param channel mixer simple element channel identifier
Packit 4a16fb
 * \param value control value
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_set_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR_CHN(elem, SM_CAP_CVOLUME, SM_CAP_CVOLUME_JOIN, channel);
Packit 4a16fb
	return sm_selem_ops(elem)->set_volume(elem, SM_CAPT, channel, value);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Set value in dB of capture volume control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param channel mixer simple element channel identifier
Packit 4a16fb
 * \param value control value in dB * 100
Packit Service f36a15
 * \param dir rounding mode - rounds up if dir > 0, round to nearest if dir == 0,
Packit Service f36a15
 *            rounds down if dir < 0
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_set_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR_CHN(elem, SM_CAP_CVOLUME, SM_CAP_CVOLUME_JOIN, channel);
Packit 4a16fb
	return sm_selem_ops(elem)->set_dB(elem, SM_CAPT, channel, value, dir);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Set value of capture volume control for all channels of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param value control value
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_set_capture_volume_all(snd_mixer_elem_t *elem, long value)
Packit 4a16fb
{
Packit 4a16fb
	snd_mixer_selem_channel_id_t chn;
Packit 4a16fb
	int err;
Packit 4a16fb
Packit 4a16fb
	for (chn = 0; chn < 32; chn++) {
Packit 4a16fb
		if (!snd_mixer_selem_has_capture_channel(elem, chn))
Packit 4a16fb
			continue;
Packit 4a16fb
		err = snd_mixer_selem_set_capture_volume(elem, chn, value);
Packit 4a16fb
		if (err < 0)
Packit 4a16fb
			return err;
Packit 4a16fb
		if (chn == 0 && snd_mixer_selem_has_capture_volume_joined(elem))
Packit 4a16fb
			return 0;
Packit 4a16fb
	}
Packit 4a16fb
	return 0;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Set value in dB of capture volume control for all channels of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param value control value in dB * 100
Packit Service f36a15
 * \param dir rounding mode - rounds up if dir > 0, round to nearest if dir == 0,
Packit Service f36a15
 *            rounds down if dir < 0
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_set_capture_dB_all(snd_mixer_elem_t *elem, long value, int dir)
Packit 4a16fb
{
Packit 4a16fb
	snd_mixer_selem_channel_id_t chn;
Packit 4a16fb
	int err;
Packit 4a16fb
Packit 4a16fb
	for (chn = 0; chn < 32; chn++) {
Packit 4a16fb
		if (!snd_mixer_selem_has_capture_channel(elem, chn))
Packit 4a16fb
			continue;
Packit 4a16fb
		err = snd_mixer_selem_set_capture_dB(elem, chn, value, dir);
Packit 4a16fb
		if (err < 0)
Packit 4a16fb
			return err;
Packit 4a16fb
		if (chn == 0 && snd_mixer_selem_has_capture_volume_joined(elem))
Packit 4a16fb
			return 0;
Packit 4a16fb
	}
Packit 4a16fb
	return 0;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Set value of capture switch control of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param channel mixer simple element channel identifier
Packit 4a16fb
 * \param value control value
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_set_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_DIR_CHN(elem, SM_CAP_CSWITCH, SM_CAP_CSWITCH_JOIN, channel);
Packit 4a16fb
	return sm_selem_ops(elem)->set_switch(elem, SM_CAPT, channel, value);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Set value of capture switch control for all channels of a mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param value control value
Packit 4a16fb
 * \return 0 on success otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_set_capture_switch_all(snd_mixer_elem_t *elem, int value)
Packit 4a16fb
{
Packit 4a16fb
	snd_mixer_selem_channel_id_t chn;
Packit 4a16fb
	int err;
Packit 4a16fb
Packit 4a16fb
	for (chn = 0; chn < 32; chn++) {
Packit 4a16fb
		if (!snd_mixer_selem_has_capture_channel(elem, chn))
Packit 4a16fb
			continue;
Packit 4a16fb
		err = snd_mixer_selem_set_capture_switch(elem, chn, value);
Packit 4a16fb
		if (err < 0)
Packit 4a16fb
			return err;
Packit 4a16fb
		if (chn == 0 && snd_mixer_selem_has_capture_switch_joined(elem))
Packit 4a16fb
			return 0;
Packit 4a16fb
	}
Packit 4a16fb
	return 0;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return true if mixer simple element is an enumerated control
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 normal volume/switch control, 1 enumerated control
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_is_enumerated(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return sm_selem_ops(elem)->is(elem, SM_PLAY, SM_OPS_IS_ENUMERATED, 0);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return true if mixer simple enumerated element belongs to the playback direction
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 no playback direction, 1 playback direction
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_is_enum_playback(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return sm_selem_ops(elem)->is(elem, SM_PLAY, SM_OPS_IS_ENUMERATED, 1);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return true if mixer simple enumerated element belongs to the capture direction
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return 0 no capture direction, 1 capture direction
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_is_enum_capture(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	return sm_selem_ops(elem)->is(elem, SM_CAPT, SM_OPS_IS_ENUMERATED, 1);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Return the number of enumerated items of the given mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \return the number of enumerated items, otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_get_enum_items(snd_mixer_elem_t *elem)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_ENUM(elem);
Packit 4a16fb
	return sm_selem_ops(elem)->is(elem, SM_PLAY, SM_OPS_IS_ENUMCNT, 0);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief get the enumerated item string for the given mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param item the index of the enumerated item to query
Packit 4a16fb
 * \param maxlen the maximal length to be stored
Packit 4a16fb
 * \param buf the buffer to store the name string
Packit 4a16fb
 * \return 0 if successful, otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_get_enum_item_name(snd_mixer_elem_t *elem,
Packit 4a16fb
				       unsigned int item,
Packit 4a16fb
				       size_t maxlen, char *buf)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_ENUM(elem);
Packit 4a16fb
	return sm_selem_ops(elem)->enum_item_name(elem, item, maxlen, buf);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief get the current selected enumerated item for the given mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param channel mixer simple element channel identifier
Packit 4a16fb
 * \param itemp the pointer to store the index of the enumerated item
Packit 4a16fb
 * \return 0 if successful, otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_get_enum_item(snd_mixer_elem_t *elem,
Packit 4a16fb
				  snd_mixer_selem_channel_id_t channel,
Packit 4a16fb
				  unsigned int *itemp)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_ENUM(elem);
Packit 4a16fb
	return sm_selem_ops(elem)->get_enum_item(elem, channel, itemp);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief set the current selected enumerated item for the given mixer simple element
Packit 4a16fb
 * \param elem Mixer simple element handle
Packit 4a16fb
 * \param channel mixer simple element channel identifier
Packit 4a16fb
 * \param item the enumerated item index
Packit 4a16fb
 * \return 0 if successful, otherwise a negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_set_enum_item(snd_mixer_elem_t *elem,
Packit 4a16fb
				  snd_mixer_selem_channel_id_t channel,
Packit 4a16fb
				  unsigned int item)
Packit 4a16fb
{
Packit 4a16fb
	CHECK_BASIC(elem);
Packit 4a16fb
	CHECK_ENUM(elem);
Packit 4a16fb
	return sm_selem_ops(elem)->set_enum_item(elem, channel, item);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief get size of #snd_mixer_selem_id_t
Packit 4a16fb
 * \return size in bytes
Packit 4a16fb
 */
Packit 4a16fb
size_t snd_mixer_selem_id_sizeof()
Packit 4a16fb
{
Packit 4a16fb
	return sizeof(snd_mixer_selem_id_t);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief allocate an invalid #snd_mixer_selem_id_t using standard malloc
Packit 4a16fb
 * \param ptr returned pointer
Packit 4a16fb
 * \return 0 on success otherwise negative error code
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_id_malloc(snd_mixer_selem_id_t **ptr)
Packit 4a16fb
{
Packit 4a16fb
	assert(ptr);
Packit 4a16fb
	*ptr = calloc(1, sizeof(snd_mixer_selem_id_t));
Packit 4a16fb
	if (!*ptr)
Packit 4a16fb
		return -ENOMEM;
Packit 4a16fb
	return 0;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief frees a previously allocated #snd_mixer_selem_id_t
Packit 4a16fb
 * \param obj pointer to object to free
Packit 4a16fb
 */
Packit 4a16fb
void snd_mixer_selem_id_free(snd_mixer_selem_id_t *obj)
Packit 4a16fb
{
Packit 4a16fb
	free(obj);
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief copy one #snd_mixer_selem_id_t to another
Packit 4a16fb
 * \param dst pointer to destination
Packit 4a16fb
 * \param src pointer to source
Packit 4a16fb
 */
Packit 4a16fb
void snd_mixer_selem_id_copy(snd_mixer_selem_id_t *dst, const snd_mixer_selem_id_t *src)
Packit 4a16fb
{
Packit 4a16fb
	assert(dst && src);
Packit 4a16fb
	*dst = *src;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Get name part of a mixer simple element identifier
Packit 4a16fb
 * \param obj Mixer simple element identifier
Packit 4a16fb
 * \return name part
Packit 4a16fb
 */
Packit 4a16fb
const char *snd_mixer_selem_id_get_name(const snd_mixer_selem_id_t *obj)
Packit 4a16fb
{
Packit 4a16fb
	assert(obj);
Packit 4a16fb
	return obj->name;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Get index part of a mixer simple element identifier
Packit 4a16fb
 * \param obj Mixer simple element identifier
Packit 4a16fb
 * \return index part
Packit 4a16fb
 */
Packit 4a16fb
unsigned int snd_mixer_selem_id_get_index(const snd_mixer_selem_id_t *obj)
Packit 4a16fb
{
Packit 4a16fb
	assert(obj);
Packit 4a16fb
	return obj->index;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Set name part of a mixer simple element identifier
Packit 4a16fb
 * \param obj Mixer simple element identifier
Packit 4a16fb
 * \param val name part
Packit 4a16fb
 */
Packit 4a16fb
void snd_mixer_selem_id_set_name(snd_mixer_selem_id_t *obj, const char *val)
Packit 4a16fb
{
Packit 4a16fb
	assert(obj);
Packit 4a16fb
	strncpy(obj->name, val, sizeof(obj->name));
Packit 4a16fb
	obj->name[sizeof(obj->name)-1] = '\0';
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Set index part of a mixer simple element identifier
Packit 4a16fb
 * \param obj Mixer simple element identifier
Packit 4a16fb
 * \param val index part
Packit 4a16fb
 */
Packit 4a16fb
void snd_mixer_selem_id_set_index(snd_mixer_selem_id_t *obj, unsigned int val)
Packit 4a16fb
{
Packit 4a16fb
	assert(obj);
Packit 4a16fb
	obj->index = val;
Packit 4a16fb
}
Packit 4a16fb
Packit 4a16fb
/**
Packit 4a16fb
 * \brief Parse ASCII simple mixer element identifier
Packit 4a16fb
 * \param dst Parsed simple mixer element identifier
Packit 4a16fb
 * \param str Mixer simple element ASCII representation
Packit 4a16fb
 */
Packit 4a16fb
int snd_mixer_selem_id_parse(snd_mixer_selem_id_t *dst, const char *str)
Packit 4a16fb
{
Packit 4a16fb
	int c, size;
Packit 4a16fb
	char buf[128];
Packit 4a16fb
	char *ptr = buf;
Packit 4a16fb
Packit 4a16fb
	memset(dst, 0, sizeof(*dst));
Packit 4a16fb
	while (*str == ' ' || *str == '\t')
Packit 4a16fb
		str++;
Packit 4a16fb
	if (!(*str))
Packit 4a16fb
		return -EINVAL;
Packit 4a16fb
	size = 1;	/* for '\0' */
Packit 4a16fb
	if (*str != '"' && *str != '\'') {
Packit 4a16fb
		while (*str && *str != ',') {
Packit 4a16fb
			if (size < (int)sizeof(buf)) {
Packit 4a16fb
				*ptr++ = *str;
Packit 4a16fb
				size++;
Packit 4a16fb
			}
Packit 4a16fb
			str++;
Packit 4a16fb
		}
Packit 4a16fb
	} else {
Packit 4a16fb
		c = *str++;
Packit 4a16fb
		while (*str && *str != c) {
Packit 4a16fb
			if (size < (int)sizeof(buf)) {
Packit 4a16fb
				*ptr++ = *str;
Packit 4a16fb
				size++;
Packit 4a16fb
			}
Packit 4a16fb
			str++;
Packit 4a16fb
		}
Packit 4a16fb
		if (*str == c)
Packit 4a16fb
			str++;
Packit 4a16fb
	}
Packit 4a16fb
	if (*str == '\0') {
Packit 4a16fb
		*ptr = 0;
Packit 4a16fb
		goto _set;
Packit 4a16fb
	}
Packit 4a16fb
	if (*str != ',')
Packit 4a16fb
		return -EINVAL;
Packit 4a16fb
	*ptr = 0;	/* terminate the string */
Packit 4a16fb
	str++;
Packit 4a16fb
	if (str[0] < '0' || str[1] > '9')
Packit 4a16fb
		return -EINVAL;
Packit 4a16fb
	dst->index = atoi(str);
Packit 4a16fb
       _set:
Packit 4a16fb
	snd_strlcpy(dst->name, buf, sizeof(dst->name));
Packit 4a16fb
	return 0;
Packit 4a16fb
}