summaryrefslogtreecommitdiff
path: root/src/mixer/simple_none.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mixer/simple_none.c')
-rw-r--r--src/mixer/simple_none.c539
1 files changed, 302 insertions, 237 deletions
diff --git a/src/mixer/simple_none.c b/src/mixer/simple_none.c
index 48022004..63442111 100644
--- a/src/mixer/simple_none.c
+++ b/src/mixer/simple_none.c
@@ -5,7 +5,7 @@
* \author Abramo Bagnara <abramo@alsa-project.org>
* \date 2001-2004
*
- * Mixer simple element class interface.
+ * Mixer simple element interface.
*/
/*
* Mixer Interface - simple controls
@@ -39,7 +39,12 @@
#include <math.h>
#include <limits.h>
#include <alsa/asoundlib.h>
-#include "mixer_simple.h"
+#include "mixer_abst.h"
+
+#ifndef PIC
+/* entry for static linking */
+const char *_snd_module_mixer_none = "";
+#endif
#ifndef DOC_HIDDEN
@@ -66,7 +71,7 @@ typedef enum _selem_ctl_type {
} selem_ctl_type_t;
typedef struct _selem_ctl {
- snd_hctl_elem_t *elem;
+ snd_ctl_elem_t *elem;
snd_ctl_elem_type_t type;
unsigned int inactive: 1;
unsigned int values;
@@ -74,7 +79,6 @@ typedef struct _selem_ctl {
} selem_ctl_t;
typedef struct _selem_none {
- sm_selem_t selem;
selem_ctl_t ctls[CTL_LAST + 1];
unsigned int capture_item;
struct selem_str {
@@ -211,7 +215,7 @@ static int get_compare_weight(const char *name, unsigned int idx)
return MIXER_COMPARE_WEIGHT_SIMPLE_BASE + res + idx;
}
-static long to_user(selem_none_t *s, int dir, selem_ctl_t *c, long value)
+static long to_user(selem_none_t *s, snd_amixer_dir_t dir, selem_ctl_t *c, long value)
{
int64_t n;
if (c->max == c->min)
@@ -220,7 +224,7 @@ static long to_user(selem_none_t *s, int dir, selem_ctl_t *c, long value)
return s->str[dir].min + (n + (c->max - c->min) / 2) / (c->max - c->min);
}
-static long from_user(selem_none_t *s, int dir, selem_ctl_t *c, long value)
+static long from_user(selem_none_t *s, snd_amixer_dir_t dir, selem_ctl_t *c, long value)
{
int64_t n;
if (s->str[dir].max == s->str[dir].min)
@@ -229,14 +233,15 @@ static long from_user(selem_none_t *s, int dir, selem_ctl_t *c, long value)
return c->min + (n + (s->str[dir].max - s->str[dir].min) / 2) / (s->str[dir].max - s->str[dir].min);
}
-static int elem_read_volume(selem_none_t *s, int dir, selem_ctl_type_t type)
+static int elem_read_volume(snd_amixer_elem_t *elem, snd_amixer_dir_t dir, selem_ctl_type_t type)
{
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
snd_ctl_elem_value_t *ctl;
unsigned int idx;
int err;
selem_ctl_t *c = &s->ctls[type];
snd_ctl_elem_value_alloca(&ctl);
- if ((err = snd_hctl_elem_read(c->elem, ctl)) < 0)
+ if ((err = snd_ctl_celem_read(c->elem, ctl)) < 0)
return err;
for (idx = 0; idx < s->str[dir].channels; idx++) {
unsigned int idx1 = idx;
@@ -247,14 +252,15 @@ static int elem_read_volume(selem_none_t *s, int dir, selem_ctl_type_t type)
return 0;
}
-static int elem_read_switch(selem_none_t *s, int dir, selem_ctl_type_t type)
+static int elem_read_switch(snd_amixer_elem_t *elem, snd_amixer_dir_t dir, selem_ctl_type_t type)
{
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
snd_ctl_elem_value_t *ctl;
unsigned int idx;
int err;
selem_ctl_t *c = &s->ctls[type];
snd_ctl_elem_value_alloca(&ctl);
- if ((err = snd_hctl_elem_read(c->elem, ctl)) < 0)
+ if ((err = snd_ctl_celem_read(c->elem, ctl)) < 0)
return err;
for (idx = 0; idx < s->str[dir].channels; idx++) {
unsigned int idx1 = idx;
@@ -266,14 +272,15 @@ static int elem_read_switch(selem_none_t *s, int dir, selem_ctl_type_t type)
return 0;
}
-static int elem_read_route(selem_none_t *s, int dir, selem_ctl_type_t type)
+static int elem_read_route(snd_amixer_elem_t *elem, snd_amixer_dir_t dir, selem_ctl_type_t type)
{
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
snd_ctl_elem_value_t *ctl;
unsigned int idx;
int err;
selem_ctl_t *c = &s->ctls[type];
snd_ctl_elem_value_alloca(&ctl);
- if ((err = snd_hctl_elem_read(c->elem, ctl)) < 0)
+ if ((err = snd_ctl_celem_read(c->elem, ctl)) < 0)
return err;
for (idx = 0; idx < s->str[dir].channels; idx++) {
unsigned int idx1 = idx;
@@ -285,23 +292,25 @@ static int elem_read_route(selem_none_t *s, int dir, selem_ctl_type_t type)
return 0;
}
-static int elem_read_enum(selem_none_t *s)
+static int elem_read_enum(snd_amixer_elem_t *elem)
{
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
+ sm_elem_t *sm = snd_amixer_elem_get_sm(elem);
snd_ctl_elem_value_t *ctl;
unsigned int idx;
int err;
int type;
selem_ctl_t *c;
type = CTL_GLOBAL_ENUM;
- if ( (s->selem.caps & (SM_CAP_CENUM | SM_CAP_PENUM)) == (SM_CAP_CENUM | SM_CAP_PENUM) )
+ if ( (sm->caps & (SM_CAP_CENUM | SM_CAP_PENUM)) == (SM_CAP_CENUM | SM_CAP_PENUM) )
type = CTL_GLOBAL_ENUM;
- else if (s->selem.caps & SM_CAP_PENUM)
+ else if (sm->caps & SM_CAP_PENUM)
type = CTL_PLAYBACK_ENUM;
- else if (s->selem.caps & SM_CAP_CENUM)
+ else if (sm->caps & SM_CAP_CENUM)
type = CTL_CAPTURE_ENUM;
c = &s->ctls[type];
snd_ctl_elem_value_alloca(&ctl);
- if ((err = snd_hctl_elem_read(c->elem, ctl)) < 0)
+ if ((err = snd_ctl_celem_read(c->elem, ctl)) < 0)
return err;
for (idx = 0; idx < s->str[0].channels; idx++) {
unsigned int idx1 = idx;
@@ -312,17 +321,15 @@ static int elem_read_enum(selem_none_t *s)
return 0;
}
-static int selem_read(snd_mixer_elem_t *elem)
+static int selem_read(snd_amixer_elem_t *elem)
{
- selem_none_t *s;
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
+ sm_elem_t *sm = snd_amixer_elem_get_sm(elem);
unsigned int idx;
int err = 0;
long pvol[32], cvol[32];
unsigned int psw, csw;
- assert(snd_mixer_elem_get_type(elem) == SND_MIXER_ELEM_SIMPLE);
- s = snd_mixer_elem_get_private(elem);
-
memcpy(pvol, s->str[SM_PLAY].vol, sizeof(pvol));
memset(&s->str[SM_PLAY].vol, 0, sizeof(s->str[SM_PLAY].vol));
psw = s->str[SM_PLAY].sw;
@@ -333,21 +340,21 @@ static int selem_read(snd_mixer_elem_t *elem)
s->str[SM_CAPT].sw = ~0U;
if (s->ctls[CTL_GLOBAL_ENUM].elem) {
- err = elem_read_enum(s);
+ err = elem_read_enum(elem);
if (err < 0)
return err;
goto __skip_cswitch;
}
if (s->ctls[CTL_CAPTURE_ENUM].elem) {
- err = elem_read_enum(s);
+ err = elem_read_enum(elem);
if (err < 0)
return err;
goto __skip_cswitch;
}
if (s->ctls[CTL_PLAYBACK_ENUM].elem) {
- err = elem_read_enum(s);
+ err = elem_read_enum(elem);
if (err < 0)
return err;
goto __skip_cswitch;
@@ -355,84 +362,84 @@ static int selem_read(snd_mixer_elem_t *elem)
if (s->ctls[CTL_PLAYBACK_VOLUME].elem)
- err = elem_read_volume(s, SM_PLAY, CTL_PLAYBACK_VOLUME);
+ err = elem_read_volume(elem, SM_PLAY, CTL_PLAYBACK_VOLUME);
else if (s->ctls[CTL_GLOBAL_VOLUME].elem)
- err = elem_read_volume(s, SM_PLAY, CTL_GLOBAL_VOLUME);
+ err = elem_read_volume(elem, SM_PLAY, CTL_GLOBAL_VOLUME);
else if (s->ctls[CTL_SINGLE].elem &&
s->ctls[CTL_SINGLE].type == SND_CTL_ELEM_TYPE_INTEGER)
- err = elem_read_volume(s, SM_PLAY, CTL_SINGLE);
+ err = elem_read_volume(elem, SM_PLAY, CTL_SINGLE);
if (err < 0)
return err;
- if ((s->selem.caps & (SM_CAP_GSWITCH|SM_CAP_PSWITCH)) == 0) {
+ if ((sm->caps & (SM_CAP_GSWITCH|SM_CAP_PSWITCH)) == 0) {
s->str[SM_PLAY].sw = 0;
goto __skip_pswitch;
}
if (s->ctls[CTL_PLAYBACK_SWITCH].elem) {
- err = elem_read_switch(s, SM_PLAY, CTL_PLAYBACK_SWITCH);
+ err = elem_read_switch(elem, SM_PLAY, CTL_PLAYBACK_SWITCH);
if (err < 0)
return err;
}
if (s->ctls[CTL_GLOBAL_SWITCH].elem) {
- err = elem_read_switch(s, SM_PLAY, CTL_GLOBAL_SWITCH);
+ err = elem_read_switch(elem, SM_PLAY, CTL_GLOBAL_SWITCH);
if (err < 0)
return err;
}
if (s->ctls[CTL_SINGLE].elem &&
s->ctls[CTL_SINGLE].type == SND_CTL_ELEM_TYPE_BOOLEAN) {
- err = elem_read_switch(s, SM_PLAY, CTL_SINGLE);
+ err = elem_read_switch(elem, SM_PLAY, CTL_SINGLE);
if (err < 0)
return err;
}
if (s->ctls[CTL_PLAYBACK_ROUTE].elem) {
- err = elem_read_route(s, SM_PLAY, CTL_PLAYBACK_ROUTE);
+ err = elem_read_route(elem, SM_PLAY, CTL_PLAYBACK_ROUTE);
if (err < 0)
return err;
}
if (s->ctls[CTL_GLOBAL_ROUTE].elem) {
- err = elem_read_route(s, SM_PLAY, CTL_GLOBAL_ROUTE);
+ err = elem_read_route(elem, SM_PLAY, CTL_GLOBAL_ROUTE);
if (err < 0)
return err;
}
__skip_pswitch:
if (s->ctls[CTL_CAPTURE_VOLUME].elem)
- err = elem_read_volume(s, SM_CAPT, CTL_CAPTURE_VOLUME);
+ err = elem_read_volume(elem, SM_CAPT, CTL_CAPTURE_VOLUME);
else if (s->ctls[CTL_GLOBAL_VOLUME].elem)
- err = elem_read_volume(s, SM_CAPT, CTL_GLOBAL_VOLUME);
+ err = elem_read_volume(elem, SM_CAPT, CTL_GLOBAL_VOLUME);
else if (s->ctls[CTL_SINGLE].elem &&
s->ctls[CTL_SINGLE].type == SND_CTL_ELEM_TYPE_INTEGER)
- err = elem_read_volume(s, SM_CAPT, CTL_SINGLE);
+ err = elem_read_volume(elem, SM_CAPT, CTL_SINGLE);
if (err < 0)
return err;
- if ((s->selem.caps & (SM_CAP_GSWITCH|SM_CAP_CSWITCH)) == 0) {
+ if ((sm->caps & (SM_CAP_GSWITCH|SM_CAP_CSWITCH)) == 0) {
s->str[SM_CAPT].sw = 0;
goto __skip_cswitch;
}
if (s->ctls[CTL_CAPTURE_SWITCH].elem) {
- err = elem_read_switch(s, SM_CAPT, CTL_CAPTURE_SWITCH);
+ err = elem_read_switch(elem, SM_CAPT, CTL_CAPTURE_SWITCH);
if (err < 0)
return err;
}
if (s->ctls[CTL_GLOBAL_SWITCH].elem) {
- err = elem_read_switch(s, SM_CAPT, CTL_GLOBAL_SWITCH);
+ err = elem_read_switch(elem, SM_CAPT, CTL_GLOBAL_SWITCH);
if (err < 0)
return err;
}
if (s->ctls[CTL_SINGLE].elem &&
s->ctls[CTL_SINGLE].type == SND_CTL_ELEM_TYPE_BOOLEAN) {
- err = elem_read_switch(s, SM_CAPT, CTL_SINGLE);
+ err = elem_read_switch(elem, SM_CAPT, CTL_SINGLE);
if (err < 0)
return err;
}
if (s->ctls[CTL_CAPTURE_ROUTE].elem) {
- err = elem_read_route(s, SM_CAPT, CTL_CAPTURE_ROUTE);
+ err = elem_read_route(elem, SM_CAPT, CTL_CAPTURE_ROUTE);
if (err < 0)
return err;
}
if (s->ctls[CTL_GLOBAL_ROUTE].elem) {
- err = elem_read_route(s, SM_CAPT, CTL_GLOBAL_ROUTE);
+ err = elem_read_route(elem, SM_CAPT, CTL_GLOBAL_ROUTE);
if (err < 0)
return err;
}
@@ -440,7 +447,7 @@ static int selem_read(snd_mixer_elem_t *elem)
snd_ctl_elem_value_t *ctl;
selem_ctl_t *c = &s->ctls[CTL_CAPTURE_SOURCE];
snd_ctl_elem_value_alloca(&ctl);
- err = snd_hctl_elem_read(c->elem, ctl);
+ err = snd_ctl_celem_read(c->elem, ctl);
if (err < 0)
return err;
for (idx = 0; idx < s->str[SM_CAPT].channels; idx++) {
@@ -461,34 +468,34 @@ static int selem_read(snd_mixer_elem_t *elem)
return 0;
}
-static int elem_write_volume(selem_none_t *s, int dir, selem_ctl_type_t type)
+static int elem_write_volume(selem_none_t *s, snd_amixer_dir_t dir, selem_ctl_type_t type)
{
snd_ctl_elem_value_t *ctl;
unsigned int idx;
int err;
selem_ctl_t *c = &s->ctls[type];
snd_ctl_elem_value_alloca(&ctl);
- if ((err = snd_hctl_elem_read(c->elem, ctl)) < 0)
+ if ((err = snd_ctl_celem_read(c->elem, ctl)) < 0)
return err;
for (idx = 0; idx < c->values; idx++)
snd_ctl_elem_value_set_integer(ctl, idx, from_user(s, dir, c, s->str[dir].vol[idx]));
- if ((err = snd_hctl_elem_write(c->elem, ctl)) < 0)
+ if ((err = snd_ctl_celem_write(c->elem, ctl)) < 0)
return err;
return 0;
}
-static int elem_write_switch(selem_none_t *s, int dir, selem_ctl_type_t type)
+static int elem_write_switch(selem_none_t *s, snd_amixer_dir_t dir, selem_ctl_type_t type)
{
snd_ctl_elem_value_t *ctl;
unsigned int idx;
int err;
selem_ctl_t *c = &s->ctls[type];
snd_ctl_elem_value_alloca(&ctl);
- if ((err = snd_hctl_elem_read(c->elem, ctl)) < 0)
+ if ((err = snd_ctl_celem_read(c->elem, ctl)) < 0)
return err;
for (idx = 0; idx < c->values; idx++)
snd_ctl_elem_value_set_integer(ctl, idx, !!(s->str[dir].sw & (1 << idx)));
- if ((err = snd_hctl_elem_write(c->elem, ctl)) < 0)
+ if ((err = snd_ctl_celem_write(c->elem, ctl)) < 0)
return err;
return 0;
}
@@ -500,75 +507,75 @@ static int elem_write_switch_constant(selem_none_t *s, selem_ctl_type_t type, in
int err;
selem_ctl_t *c = &s->ctls[type];
snd_ctl_elem_value_alloca(&ctl);
- if ((err = snd_hctl_elem_read(c->elem, ctl)) < 0)
+ if ((err = snd_ctl_celem_read(c->elem, ctl)) < 0)
return err;
for (idx = 0; idx < c->values; idx++)
snd_ctl_elem_value_set_integer(ctl, idx, !!val);
- if ((err = snd_hctl_elem_write(c->elem, ctl)) < 0)
+ if ((err = snd_ctl_celem_write(c->elem, ctl)) < 0)
return err;
return 0;
}
-static int elem_write_route(selem_none_t *s, int dir, selem_ctl_type_t type)
+static int elem_write_route(selem_none_t *s, snd_amixer_dir_t dir, selem_ctl_type_t type)
{
snd_ctl_elem_value_t *ctl;
unsigned int idx;
int err;
selem_ctl_t *c = &s->ctls[type];
snd_ctl_elem_value_alloca(&ctl);
- if ((err = snd_hctl_elem_read(c->elem, ctl)) < 0)
+ if ((err = snd_ctl_celem_read(c->elem, ctl)) < 0)
return err;
for (idx = 0; idx < c->values * c->values; idx++)
snd_ctl_elem_value_set_integer(ctl, idx, 0);
for (idx = 0; idx < c->values; idx++)
snd_ctl_elem_value_set_integer(ctl, idx * c->values + idx, !!(s->str[dir].sw & (1 << idx)));
- if ((err = snd_hctl_elem_write(c->elem, ctl)) < 0)
+ if ((err = snd_ctl_celem_write(c->elem, ctl)) < 0)
return err;
return 0;
}
-static int elem_write_enum(selem_none_t *s)
+static int elem_write_enum(snd_amixer_elem_t *elem)
{
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
+ sm_elem_t *sm = snd_amixer_elem_get_sm(elem);
snd_ctl_elem_value_t *ctl;
+
unsigned int idx;
int err;
int type;
selem_ctl_t *c;
type = CTL_GLOBAL_ENUM;
- if ( (s->selem.caps & (SM_CAP_CENUM | SM_CAP_PENUM) ) == (SM_CAP_CENUM | SM_CAP_PENUM) )
+ if ( (sm->caps & (SM_CAP_CENUM | SM_CAP_PENUM) ) == (SM_CAP_CENUM | SM_CAP_PENUM) )
type = CTL_GLOBAL_ENUM;
- else if (s->selem.caps & SM_CAP_PENUM)
+ else if (sm->caps & SM_CAP_PENUM)
type = CTL_PLAYBACK_ENUM;
- else if (s->selem.caps & SM_CAP_CENUM)
+ else if (sm->caps & SM_CAP_CENUM)
type = CTL_CAPTURE_ENUM;
c = &s->ctls[type];
snd_ctl_elem_value_alloca(&ctl);
- if ((err = snd_hctl_elem_read(c->elem, ctl)) < 0)
+ if ((err = snd_ctl_celem_read(c->elem, ctl)) < 0)
return err;
for (idx = 0; idx < c->values; idx++)
snd_ctl_elem_value_set_enumerated(ctl, idx, (unsigned int)s->str[0].vol[idx]);
- if ((err = snd_hctl_elem_write(c->elem, ctl)) < 0)
+ if ((err = snd_ctl_celem_write(c->elem, ctl)) < 0)
return err;
return 0;
}
-static int selem_write_main(snd_mixer_elem_t *elem)
+static int selem_write_main(snd_amixer_elem_t *elem)
{
- selem_none_t *s;
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
unsigned int idx;
int err;
- assert(snd_mixer_elem_get_type(elem) == SND_MIXER_ELEM_SIMPLE);
- s = snd_mixer_elem_get_private(elem);
-
if (s->ctls[CTL_GLOBAL_ENUM].elem)
- return elem_write_enum(s);
+ return elem_write_enum(elem);
if (s->ctls[CTL_PLAYBACK_ENUM].elem)
- return elem_write_enum(s);
+ return elem_write_enum(elem);
if (s->ctls[CTL_CAPTURE_ENUM].elem)
- return elem_write_enum(s);
+ return elem_write_enum(elem);
if (s->ctls[CTL_SINGLE].elem) {
if (s->ctls[CTL_SINGLE].type == SND_CTL_ELEM_TYPE_INTEGER)
@@ -625,13 +632,13 @@ static int selem_write_main(snd_mixer_elem_t *elem)
snd_ctl_elem_value_t *ctl;
selem_ctl_t *c = &s->ctls[CTL_CAPTURE_SOURCE];
snd_ctl_elem_value_alloca(&ctl);
- if ((err = snd_hctl_elem_read(c->elem, ctl)) < 0)
+ if ((err = snd_ctl_celem_read(c->elem, ctl)) < 0)
return err;
for (idx = 0; idx < c->values; idx++) {
if (s->str[SM_CAPT].sw & (1 << idx))
snd_ctl_elem_value_set_enumerated(ctl, idx, s->capture_item);
}
- if ((err = snd_hctl_elem_write(c->elem, ctl)) < 0)
+ if ((err = snd_ctl_celem_write(c->elem, ctl)) < 0)
return err;
/* update the element, don't remove */
err = selem_read(elem);
@@ -641,7 +648,7 @@ static int selem_write_main(snd_mixer_elem_t *elem)
return 0;
}
-static int selem_write(snd_mixer_elem_t *elem)
+static int selem_write(snd_amixer_elem_t *elem)
{
int err;
@@ -651,21 +658,19 @@ static int selem_write(snd_mixer_elem_t *elem)
return err;
}
-static void selem_free(snd_mixer_elem_t *elem)
+static void selem_free(snd_amixer_elem_t *elem)
{
- selem_none_t *simple = snd_mixer_elem_get_private(elem);
- assert(snd_mixer_elem_get_type(elem) == SND_MIXER_ELEM_SIMPLE);
- if (simple->selem.id)
- snd_mixer_selem_id_free(simple->selem.id);
+ selem_none_t *simple = snd_amixer_elem_get_private(elem);
/* free db range information */
free(simple->str[0].db_info);
free(simple->str[1].db_info);
free(simple);
}
-static int simple_update(snd_mixer_elem_t *melem)
+static int simple_update(snd_amixer_elem_t *melem)
{
selem_none_t *simple;
+ sm_elem_t *sm;
unsigned int caps, pchannels, cchannels;
long pmin, pmax, cmin, cmax;
selem_ctl_t *ctl;
@@ -678,9 +683,9 @@ static int simple_update(snd_mixer_elem_t *melem)
cchannels = 0;
cmin = LONG_MAX;
cmax = LONG_MIN;
- assert(snd_mixer_elem_get_type(melem) == SND_MIXER_ELEM_SIMPLE);
- simple = snd_mixer_elem_get_private(melem);
- name = snd_mixer_selem_get_name(melem);
+ simple = snd_amixer_elem_get_private(melem);
+ sm = snd_amixer_elem_get_sm(melem);
+ name = snd_amixer_elem_get_name(melem);
ctl = &simple->ctls[CTL_SINGLE];
if (ctl->elem) {
pchannels = cchannels = ctl->values;
@@ -868,7 +873,7 @@ static int simple_update(snd_mixer_elem_t *melem)
(caps & (SM_CAP_PVOLUME|SM_CAP_CVOLUME)) == 0)
caps |= SM_CAP_PVOLUME|SM_CAP_CVOLUME;
- simple->selem.caps = caps;
+ sm->caps = caps;
simple->str[SM_PLAY].channels = pchannels;
if (!simple->str[SM_PLAY].range) {
simple->str[SM_PLAY].min = pmin != LONG_MAX ? pmin : 0;
@@ -943,16 +948,17 @@ static int base_len(const char *name, selem_ctl_type_t *type)
* Simple Mixer Operations
*/
-static int _snd_mixer_selem_set_volume(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long value)
+static int _snd_amixer_selem_set_volume(snd_amixer_elem_t *elem, snd_amixer_dir_t dir, snd_amixer_elem_channel_id_t channel, long value)
{
- selem_none_t *s = snd_mixer_elem_get_private(elem);
- if (s->selem.caps & SM_CAP_GVOLUME)
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
+ sm_elem_t *sm = snd_amixer_elem_get_sm(elem);
+ if (sm->caps & SM_CAP_GVOLUME)
dir = SM_PLAY;
if ((unsigned int) channel >= s->str[dir].channels)
return 0;
if (value < s->str[dir].min || value > s->str[dir].max)
return 0;
- if (s->selem.caps &
+ if (sm->caps &
(dir == SM_PLAY ? SM_CAP_PVOLUME_JOIN : SM_CAP_CVOLUME_JOIN))
channel = 0;
if (value != s->str[dir].vol[channel]) {
@@ -962,12 +968,14 @@ static int _snd_mixer_selem_set_volume(snd_mixer_elem_t *elem, int dir, snd_mixe
return 0;
}
-static int _snd_mixer_selem_set_switch(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, int value)
+static int _snd_amixer_selem_set_switch(snd_amixer_elem_t *elem, snd_amixer_dir_t dir, snd_amixer_elem_channel_id_t channel, int value)
{
- selem_none_t *s = snd_mixer_elem_get_private(elem);
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
+ sm_elem_t *sm = snd_amixer_elem_get_sm(elem);
+
if ((unsigned int) channel >= s->str[dir].channels)
return 0;
- if (s->selem.caps &
+ if (sm->caps &
(dir == SM_PLAY ? SM_CAP_PSWITCH_JOIN : SM_CAP_CSWITCH_JOIN))
channel = 0;
if (value) {
@@ -984,9 +992,10 @@ static int _snd_mixer_selem_set_switch(snd_mixer_elem_t *elem, int dir, snd_mixe
return 0;
}
-static int is_ops(snd_mixer_elem_t *elem, int dir, int cmd, int val)
+static int is_ops(snd_amixer_elem_t *elem, snd_amixer_dir_t dir, int cmd, int val)
{
- selem_none_t *s = snd_mixer_elem_get_private(elem);
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
+ sm_elem_t *sm = snd_amixer_elem_get_sm(elem);
switch (cmd) {
@@ -998,37 +1007,31 @@ static int is_ops(snd_mixer_elem_t *elem, int dir, int cmd, int val)
return 1;
}
- case SM_OPS_IS_MONO:
- return s->str[dir].channels == 1;
-
case SM_OPS_IS_CHANNEL:
return (unsigned int) val < s->str[dir].channels;
case SM_OPS_IS_ENUMERATED:
- if (val == 1) {
- if (dir == SM_PLAY && (s->selem.caps & SM_CAP_PENUM) && !(s->selem.caps & SM_CAP_CENUM) )
- return 1;
- if (dir == SM_CAPT && (s->selem.caps & SM_CAP_CENUM) && !(s->selem.caps & SM_CAP_PENUM) )
- return 1;
- return 0;
- }
- if (s->selem.caps & (SM_CAP_CENUM | SM_CAP_PENUM) )
+ if (dir == SM_PLAY && (sm->caps & SM_CAP_PENUM) && !(sm->caps & SM_CAP_CENUM))
+ return 1;
+ if (dir == SM_CAPT && (sm->caps & SM_CAP_CENUM) && !(sm->caps & SM_CAP_PENUM))
+ return 1;
+ if (dir == SM_COMM && (sm->caps & (SM_CAP_CENUM|SM_CAP_PENUM)) == (SM_CAP_CENUM|SM_CAP_PENUM))
return 1;
return 0;
case SM_OPS_IS_ENUMCNT:
/* Both */
- if ( (s->selem.caps & (SM_CAP_CENUM | SM_CAP_PENUM)) == (SM_CAP_CENUM | SM_CAP_PENUM) ) {
+ if ( (sm->caps & (SM_CAP_CENUM | SM_CAP_PENUM)) == (SM_CAP_CENUM | SM_CAP_PENUM) ) {
if (! s->ctls[CTL_GLOBAL_ENUM].elem)
return -EINVAL;
return s->ctls[CTL_GLOBAL_ENUM].max;
/* Only Playback */
- } else if (s->selem.caps & SM_CAP_PENUM ) {
+ } else if (sm->caps & SM_CAP_PENUM ) {
if (! s->ctls[CTL_PLAYBACK_ENUM].elem)
return -EINVAL;
return s->ctls[CTL_PLAYBACK_ENUM].max;
/* Only Capture */
- } else if (s->selem.caps & SM_CAP_CENUM ) {
+ } else if (sm->caps & SM_CAP_CENUM ) {
if (! s->ctls[CTL_CAPTURE_ENUM].elem)
return -EINVAL;
return s->ctls[CTL_CAPTURE_ENUM].max;
@@ -1039,19 +1042,25 @@ static int is_ops(snd_mixer_elem_t *elem, int dir, int cmd, int val)
return 1;
}
-static int get_range_ops(snd_mixer_elem_t *elem, int dir,
+static int get_channels_ops(snd_amixer_elem_t *elem, snd_amixer_dir_t dir)
+{
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
+ return s->str[dir].channels;
+}
+
+static int get_range_ops(snd_amixer_elem_t *elem, snd_amixer_dir_t dir,
long *min, long *max)
{
- selem_none_t *s = snd_mixer_elem_get_private(elem);
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
*min = s->str[dir].min;
*max = s->str[dir].max;
return 0;
}
-static int set_range_ops(snd_mixer_elem_t *elem, int dir,
+static int set_range_ops(snd_amixer_elem_t *elem, snd_amixer_dir_t dir,
long min, long max)
{
- selem_none_t *s = snd_mixer_elem_get_private(elem);
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
int err;
s->str[dir].range = 1;
@@ -1062,11 +1071,12 @@ static int set_range_ops(snd_mixer_elem_t *elem, int dir,
return 0;
}
-static int get_volume_ops(snd_mixer_elem_t *elem, int dir,
- snd_mixer_selem_channel_id_t channel, long *value)
+static int get_volume_ops(snd_amixer_elem_t *elem, snd_amixer_dir_t dir,
+ snd_amixer_elem_channel_id_t channel, long *value)
{
- selem_none_t *s = snd_mixer_elem_get_private(elem);
- if (s->selem.caps & SM_CAP_GVOLUME)
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
+ sm_elem_t *sm = snd_amixer_elem_get_sm(elem);
+ if (sm->caps & SM_CAP_GVOLUME)
dir = SM_PLAY;
if ((unsigned int) channel >= s->str[dir].channels)
return -EINVAL;
@@ -1074,9 +1084,9 @@ static int get_volume_ops(snd_mixer_elem_t *elem, int dir,
return 0;
}
-static int init_db_range(snd_hctl_elem_t *ctl, struct selem_str *rec);
+static int init_db_range(snd_ctl_elem_t *ctl, struct selem_str *rec);
-static int convert_to_dB(snd_hctl_elem_t *ctl, struct selem_str *rec,
+static int convert_to_dB(snd_ctl_elem_t *ctl, struct selem_str *rec,
long volume, long *db_gain)
{
if (init_db_range(ctl, rec) < 0)
@@ -1087,7 +1097,7 @@ static int convert_to_dB(snd_hctl_elem_t *ctl, struct selem_str *rec,
/* initialize dB range information, reading TLV via hcontrol
*/
-static int init_db_range(snd_hctl_elem_t *ctl, struct selem_str *rec)
+static int init_db_range(snd_ctl_elem_t *ctl, struct selem_str *rec)
{
snd_ctl_elem_info_t *info;
unsigned int *tlv = NULL;
@@ -1101,14 +1111,14 @@ static int init_db_range(snd_hctl_elem_t *ctl, struct selem_str *rec)
return 0;
snd_ctl_elem_info_alloca(&info);
- if (snd_hctl_elem_info(ctl, info) < 0)
+ if (snd_ctl_celem_info(ctl, info) < 0)
goto error;
if (! snd_ctl_elem_info_is_tlv_readable(info))
goto error;
tlv = malloc(tlv_size);
if (! tlv)
return -ENOMEM;
- if (snd_hctl_elem_tlv_read(ctl, tlv, tlv_size) < 0)
+ if (snd_ctl_celem_tlv_read(ctl, tlv, tlv_size) < 0)
goto error;
db_size = snd_tlv_parse_dB_info(tlv, tlv_size, &dbrec);
if (db_size < 0)
@@ -1128,7 +1138,7 @@ static int init_db_range(snd_hctl_elem_t *ctl, struct selem_str *rec)
}
/* get selem_ctl for TLV access */
-static selem_ctl_t *get_selem_ctl(selem_none_t *s, int dir)
+static selem_ctl_t *get_selem_ctl(selem_none_t *s, snd_amixer_dir_t dir)
{
selem_ctl_t *c;
if (dir == SM_PLAY)
@@ -1147,7 +1157,7 @@ static selem_ctl_t *get_selem_ctl(selem_none_t *s, int dir)
return c;
}
-static int get_dB_range(snd_hctl_elem_t *ctl, struct selem_str *rec,
+static int get_dB_range(snd_ctl_elem_t *ctl, struct selem_str *rec,
long *min, long *max)
{
if (init_db_range(ctl, rec) < 0)
@@ -1156,13 +1166,14 @@ static int get_dB_range(snd_hctl_elem_t *ctl, struct selem_str *rec,
return snd_tlv_get_dB_range(rec->db_info, rec->min, rec->max, min, max);
}
-static int get_dB_range_ops(snd_mixer_elem_t *elem, int dir,
+static int get_dB_range_ops(snd_amixer_elem_t *elem, snd_amixer_dir_t dir,
long *min, long *max)
{
- selem_none_t *s = snd_mixer_elem_get_private(elem);
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
+ sm_elem_t *sm = snd_amixer_elem_get_sm(elem);
selem_ctl_t *c;
- if (s->selem.caps & SM_CAP_GVOLUME)
+ if (sm->caps & SM_CAP_GVOLUME)
dir = SM_PLAY;
c = get_selem_ctl(s, dir);
if (! c)
@@ -1170,7 +1181,7 @@ static int get_dB_range_ops(snd_mixer_elem_t *elem, int dir,
return get_dB_range(c->elem, &s->str[dir], min, max);
}
-static int convert_from_dB(snd_hctl_elem_t *ctl, struct selem_str *rec,
+static int convert_from_dB(snd_ctl_elem_t *ctl, struct selem_str *rec,
long db_gain, long *value, int xdir)
{
if (init_db_range(ctl, rec) < 0)
@@ -1180,12 +1191,12 @@ static int convert_from_dB(snd_hctl_elem_t *ctl, struct selem_str *rec,
db_gain, value, xdir);
}
-static int ask_vol_dB_ops(snd_mixer_elem_t *elem,
- int dir,
+static int ask_vol_dB_ops(snd_amixer_elem_t *elem,
+ snd_amixer_dir_t dir,
long value,
long *dBvalue)
{
- selem_none_t *s = snd_mixer_elem_get_private(elem);
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
selem_ctl_t *c;
c = get_selem_ctl(s, dir);
@@ -1195,17 +1206,18 @@ static int ask_vol_dB_ops(snd_mixer_elem_t *elem,
return res;
}
-static int get_dB_ops(snd_mixer_elem_t *elem,
- int dir,
- snd_mixer_selem_channel_id_t channel,
+static int get_dB_ops(snd_amixer_elem_t *elem,
+ snd_amixer_dir_t dir,
+ snd_amixer_elem_channel_id_t channel,
long *value)
{
- selem_none_t *s = snd_mixer_elem_get_private(elem);
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
+ sm_elem_t *sm = snd_amixer_elem_get_sm(elem);
selem_ctl_t *c;
int err;
long volume, db_gain;
- if (s->selem.caps & SM_CAP_GVOLUME)
+ if (sm->caps & SM_CAP_GVOLUME)
dir = SM_PLAY;
c = get_selem_ctl(s, dir);
if (! c)
@@ -1220,11 +1232,12 @@ static int get_dB_ops(snd_mixer_elem_t *elem,
return err;
}
-static int get_switch_ops(snd_mixer_elem_t *elem, int dir,
- snd_mixer_selem_channel_id_t channel, int *value)
+static int get_switch_ops(snd_amixer_elem_t *elem, snd_amixer_dir_t dir,
+ snd_amixer_elem_channel_id_t channel, int *value)
{
- selem_none_t *s = snd_mixer_elem_get_private(elem);
- if (s->selem.caps & SM_CAP_GSWITCH)
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
+ sm_elem_t *sm = snd_amixer_elem_get_sm(elem);
+ if (sm->caps & SM_CAP_GSWITCH)
dir = SM_PLAY;
if ((unsigned int) channel >= s->str[dir].channels)
return -EINVAL;
@@ -1232,11 +1245,11 @@ static int get_switch_ops(snd_mixer_elem_t *elem, int dir,
return 0;
}
-static int set_volume_ops(snd_mixer_elem_t *elem, int dir,
- snd_mixer_selem_channel_id_t channel, long value)
+static int set_volume_ops(snd_amixer_elem_t *elem, snd_amixer_dir_t dir,
+ snd_amixer_elem_channel_id_t channel, long value)
{
int changed;
- changed = _snd_mixer_selem_set_volume(elem, dir, channel, value);
+ changed = _snd_amixer_selem_set_volume(elem, dir, channel, value);
if (changed < 0)
return changed;
if (changed)
@@ -1244,13 +1257,14 @@ static int set_volume_ops(snd_mixer_elem_t *elem, int dir,
return 0;
}
-static int ask_dB_vol_ops(snd_mixer_elem_t *elem, int dir,
+static int ask_dB_vol_ops(snd_amixer_elem_t *elem, snd_amixer_dir_t dir,
long dbValue, long *value, int xdir)
{
- selem_none_t *s = snd_mixer_elem_get_private(elem);
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
+ sm_elem_t *sm = snd_amixer_elem_get_sm(elem);
selem_ctl_t *c;
- if (s->selem.caps & SM_CAP_GVOLUME)
+ if (sm->caps & SM_CAP_GVOLUME)
dir = SM_PLAY;
c = get_selem_ctl(s, dir);
if (! c)
@@ -1258,16 +1272,17 @@ static int ask_dB_vol_ops(snd_mixer_elem_t *elem, int dir,
return convert_from_dB(c->elem, &s->str[dir], dbValue, value, xdir);
}
-static int set_dB_ops(snd_mixer_elem_t *elem, int dir,
- snd_mixer_selem_channel_id_t channel,
+static int set_dB_ops(snd_amixer_elem_t *elem, snd_amixer_dir_t dir,
+ snd_amixer_elem_channel_id_t channel,
long db_gain, int xdir)
{
- selem_none_t *s = snd_mixer_elem_get_private(elem);
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
+ sm_elem_t *sm = snd_amixer_elem_get_sm(elem);
selem_ctl_t *c;
long value;
int err;
- if (s->selem.caps & SM_CAP_GVOLUME)
+ if (sm->caps & SM_CAP_GVOLUME)
dir = SM_PLAY;
c = get_selem_ctl(s, dir);
if (! c)
@@ -1278,21 +1293,21 @@ static int set_dB_ops(snd_mixer_elem_t *elem, int dir,
return set_volume_ops(elem, dir, channel, value);
}
-static int set_switch_ops(snd_mixer_elem_t *elem, int dir,
- snd_mixer_selem_channel_id_t channel, int value)
+static int set_switch_ops(snd_amixer_elem_t *elem, snd_amixer_dir_t dir,
+ snd_amixer_elem_channel_id_t channel, int value)
{
int changed;
- selem_none_t *s = snd_mixer_elem_get_private(elem);
- if (s->selem.caps & SM_CAP_GSWITCH)
+ sm_elem_t *sm = snd_amixer_elem_get_sm(elem);
+ if (sm->caps & SM_CAP_GSWITCH)
dir = SM_PLAY;
if (dir == SM_PLAY) {
- if (! (s->selem.caps & (SM_CAP_GSWITCH|SM_CAP_PSWITCH)))
+ if (! (sm->caps & (SM_CAP_GSWITCH|SM_CAP_PSWITCH)))
return -EINVAL;
} else {
- if (! (s->selem.caps & (SM_CAP_GSWITCH|SM_CAP_CSWITCH)))
+ if (! (sm->caps & (SM_CAP_GSWITCH|SM_CAP_CSWITCH)))
return -EINVAL;
}
- changed = _snd_mixer_selem_set_switch(elem, dir, channel, value);
+ changed = _snd_amixer_selem_set_switch(elem, dir, channel, value);
if (changed < 0)
return changed;
if (changed)
@@ -1300,13 +1315,13 @@ static int set_switch_ops(snd_mixer_elem_t *elem, int dir,
return 0;
}
-static int enum_item_name_ops(snd_mixer_elem_t *elem,
+static int enum_item_name_ops(snd_amixer_elem_t *elem,
unsigned int item,
size_t maxlen, char *buf)
{
- selem_none_t *s = snd_mixer_elem_get_private(elem);
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
snd_ctl_elem_info_t *info;
- snd_hctl_elem_t *helem;
+ snd_ctl_elem_t *helem;
int type;
type = CTL_GLOBAL_ENUM;
@@ -1323,20 +1338,20 @@ static int enum_item_name_ops(snd_mixer_elem_t *elem,
if (item >= (unsigned int)s->ctls[type].max)
return -EINVAL;
snd_ctl_elem_info_alloca(&info);
- snd_hctl_elem_info(helem, info);
+ snd_ctl_celem_info(helem, info);
snd_ctl_elem_info_set_item(info, item);
- snd_hctl_elem_info(helem, info);
+ snd_ctl_celem_info(helem, info);
strncpy(buf, snd_ctl_elem_info_get_item_name(info), maxlen);
return 0;
}
-static int get_enum_item_ops(snd_mixer_elem_t *elem,
- snd_mixer_selem_channel_id_t channel,
+static int get_enum_item_ops(snd_amixer_elem_t *elem,
+ snd_amixer_elem_channel_id_t channel,
unsigned int *itemp)
{
- selem_none_t *s = snd_mixer_elem_get_private(elem);
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
snd_ctl_elem_value_t *ctl;
- snd_hctl_elem_t *helem;
+ snd_ctl_elem_t *helem;
int err;
if ((unsigned int) channel >= s->str[0].channels)
@@ -1346,19 +1361,19 @@ static int get_enum_item_ops(snd_mixer_elem_t *elem,
if (!helem) helem = s->ctls[CTL_CAPTURE_ENUM].elem;
assert(helem);
snd_ctl_elem_value_alloca(&ctl);
- err = snd_hctl_elem_read(helem, ctl);
+ err = snd_ctl_celem_read(helem, ctl);
if (! err)
*itemp = snd_ctl_elem_value_get_enumerated(ctl, channel);
return err;
}
-static int set_enum_item_ops(snd_mixer_elem_t *elem,
- snd_mixer_selem_channel_id_t channel,
+static int set_enum_item_ops(snd_amixer_elem_t *elem,
+ snd_amixer_elem_channel_id_t channel,
unsigned int item)
{
- selem_none_t *s = snd_mixer_elem_get_private(elem);
+ selem_none_t *s = snd_amixer_elem_get_private(elem);
snd_ctl_elem_value_t *ctl;
- snd_hctl_elem_t *helem;
+ snd_ctl_elem_t *helem;
int err;
int type;
@@ -1380,16 +1395,17 @@ static int set_enum_item_ops(snd_mixer_elem_t *elem,
return -EINVAL;
}
snd_ctl_elem_value_alloca(&ctl);
- err = snd_hctl_elem_read(helem, ctl);
+ err = snd_ctl_celem_read(helem, ctl);
if (err < 0) {
return err;
}
snd_ctl_elem_value_set_enumerated(ctl, channel, item);
- return snd_hctl_elem_write(helem, ctl);
+ return snd_ctl_celem_write(helem, ctl);
}
static struct sm_elem_ops simple_none_ops = {
.is = is_ops,
+ .get_channels = get_channels_ops,
.get_range = get_range_ops,
.get_dB_range = get_dB_range_ops,
.set_range = set_range_ops,
@@ -1406,12 +1422,13 @@ static struct sm_elem_ops simple_none_ops = {
.set_enum_item = set_enum_item_ops
};
-static int simple_add1(snd_mixer_class_t *class, const char *name,
- snd_hctl_elem_t *helem, selem_ctl_type_t type,
+static int simple_add1(snd_amixer_t *amixer, const char *name,
+ snd_ctl_elem_t *helem, selem_ctl_type_t type,
unsigned int value)
{
- snd_mixer_elem_t *melem;
- snd_mixer_selem_id_t *id;
+ snd_amixer_elem_t *melem;
+ sm_elem_t *sm;
+ snd_amixer_elem_id_t *id;
int new = 0;
int err;
snd_ctl_elem_info_t *info;
@@ -1421,7 +1438,7 @@ static int simple_add1(snd_mixer_class_t *class, const char *name,
unsigned long values;
snd_ctl_elem_info_alloca(&info);
- err = snd_hctl_elem_info(helem, info);
+ err = snd_ctl_celem_info(helem, info);
if (err < 0)
return err;
ctype = snd_ctl_elem_info_get_type(info);
@@ -1508,39 +1525,42 @@ static int simple_add1(snd_mixer_class_t *class, const char *name,
break;
}
name1 = get_short_name(name);
- if (snd_mixer_selem_id_malloc(&id))
+ if (snd_amixer_elem_id_malloc(&id))
return -ENOMEM;
- snd_mixer_selem_id_set_name(id, name1);
- snd_mixer_selem_id_set_index(id, snd_hctl_elem_get_index(helem));
- melem = snd_mixer_find_selem(snd_mixer_class_get_mixer(class), id);
+ snd_amixer_elem_id_set_name(id, name1);
+ snd_amixer_elem_id_set_index(id, snd_ctl_elem_get_index(helem));
+ melem = snd_amixer_find_elem(amixer, id);
if (!melem) {
simple = calloc(1, sizeof(*simple));
if (!simple) {
- snd_mixer_selem_id_free(id);
+ snd_amixer_elem_id_free(id);
return -ENOMEM;
}
- simple->selem.id = id;
- simple->selem.ops = &simple_none_ops;
- err = snd_mixer_elem_new(&melem, SND_MIXER_ELEM_SIMPLE,
- get_compare_weight(snd_mixer_selem_id_get_name(simple->selem.id), snd_mixer_selem_id_get_index(simple->selem.id)),
- simple, selem_free);
+ err = snd_amixer_elem_new(amixer,
+ &melem,
+ id,
+ get_compare_weight(snd_amixer_elem_id_get_name(id), snd_amixer_elem_id_get_index(id)),
+ simple, selem_free);
+ snd_amixer_elem_id_free(id);
if (err < 0) {
- snd_mixer_selem_id_free(id);
+ snd_amixer_elem_id_free(id);
free(simple);
return err;
}
+ sm = snd_amixer_elem_get_sm(melem);
+ sm->ops = &simple_none_ops;
new = 1;
} else {
- simple = snd_mixer_elem_get_private(melem);
- snd_mixer_selem_id_free(id);
+ simple = snd_amixer_elem_get_private(melem);
+ snd_amixer_elem_id_free(id);
}
if (simple->ctls[type].elem) {
SNDERR("helem (%s,'%s',%u,%u,%u) appears twice or more",
- snd_ctl_elem_iface_name(snd_hctl_elem_get_interface(helem)),
- snd_hctl_elem_get_name(helem),
- snd_hctl_elem_get_index(helem),
- snd_hctl_elem_get_device(helem),
- snd_hctl_elem_get_subdevice(helem));
+ snd_ctl_elem_iface_name(snd_ctl_elem_get_interface(helem)),
+ snd_ctl_elem_get_name(helem),
+ snd_ctl_elem_get_index(helem),
+ snd_ctl_elem_get_device(helem),
+ snd_ctl_elem_get_subdevice(helem));
err = -EINVAL;
goto __error;
}
@@ -1566,7 +1586,7 @@ static int simple_add1(snd_mixer_class_t *class, const char *name,
default:
break;
}
- err = snd_mixer_elem_attach(melem, helem);
+ err = snd_amixer_elem_attach(melem, helem);
if (err < 0)
goto __error;
err = simple_update(melem);
@@ -1576,36 +1596,36 @@ static int simple_add1(snd_mixer_class_t *class, const char *name,
return err;
}
if (new)
- err = snd_mixer_elem_add(melem, class);
+ err = snd_amixer_elem_add(amixer, melem);
else
- err = snd_mixer_elem_info(melem);
+ err = snd_amixer_elem_info(melem);
if (err < 0)
return err;
err = selem_read(melem);
if (err < 0)
return err;
if (err)
- err = snd_mixer_elem_value(melem);
+ err = snd_amixer_elem_value(melem);
return err;
__error:
if (new)
- snd_mixer_elem_free(melem);
+ snd_amixer_elem_free(melem);
return -EINVAL;
}
-static int simple_event_add(snd_mixer_class_t *class, snd_hctl_elem_t *helem)
+static int simple_event_add(snd_amixer_t *amixer, snd_ctl_elem_t *helem)
{
- const char *name = snd_hctl_elem_get_name(helem);
+ const char *name = snd_ctl_elem_get_name(helem);
size_t len;
selem_ctl_type_t type = CTL_SINGLE; /* to shut up warning */
- if (snd_hctl_elem_get_interface(helem) != SND_CTL_ELEM_IFACE_MIXER)
+ if (snd_ctl_elem_get_interface(helem) != SND_CTL_ELEM_IFACE_MIXER)
return 0;
if (strcmp(name, "Capture Source") == 0) {
snd_ctl_elem_info_t *info;
unsigned int k, items;
int err;
snd_ctl_elem_info_alloca(&info);
- err = snd_hctl_elem_info(helem, info);
+ err = snd_ctl_celem_info(helem, info);
assert(err >= 0);
if (snd_ctl_elem_info_get_type(info) != SND_CTL_ELEM_TYPE_ENUMERATED)
return 0;
@@ -1613,11 +1633,11 @@ static int simple_event_add(snd_mixer_class_t *class, snd_hctl_elem_t *helem)
for (k = 0; k < items; ++k) {
const char *n;
snd_ctl_elem_info_set_item(info, k);
- err = snd_hctl_elem_info(helem, info);
+ err = snd_ctl_celem_info(helem, info);
if (err < 0)
return err;
n = snd_ctl_elem_info_get_item_name(info);
- err = simple_add1(class, n, helem, CTL_CAPTURE_SOURCE, k);
+ err = simple_add1(amixer, n, helem, CTL_CAPTURE_SOURCE, k);
if (err < 0)
return err;
}
@@ -1625,7 +1645,7 @@ static int simple_event_add(snd_mixer_class_t *class, snd_hctl_elem_t *helem)
}
len = base_len(name, &type);
if (len == 0) {
- return simple_add1(class, name, helem, CTL_SINGLE, 0);
+ return simple_add1(amixer, name, helem, CTL_SINGLE, 0);
} else {
char ename[128];
if (len >= sizeof(ename))
@@ -1637,14 +1657,14 @@ static int simple_event_add(snd_mixer_class_t *class, snd_hctl_elem_t *helem)
type = CTL_CAPTURE_VOLUME;
else if (type == CTL_GLOBAL_SWITCH && !strcmp(ename, "Capture"))
type = CTL_CAPTURE_SWITCH;
- return simple_add1(class, ename, helem, type, 0);
+ return simple_add1(amixer, ename, helem, type, 0);
}
}
-static int simple_event_remove(snd_hctl_elem_t *helem,
- snd_mixer_elem_t *melem)
+static int simple_event_remove(snd_ctl_elem_t *helem,
+ snd_amixer_elem_t *melem)
{
- selem_none_t *simple = snd_mixer_elem_get_private(melem);
+ selem_none_t *simple = snd_amixer_elem_get_private(melem);
int err;
int k;
for (k = 0; k <= CTL_LAST; k++) {
@@ -1653,23 +1673,23 @@ static int simple_event_remove(snd_hctl_elem_t *helem,
}
assert(k <= CTL_LAST);
simple->ctls[k].elem = NULL;
- err = snd_mixer_elem_detach(melem, helem);
+ err = snd_amixer_elem_detach(melem, helem);
if (err < 0)
return err;
- if (snd_mixer_elem_empty(melem))
- return snd_mixer_elem_remove(melem);
+ if (snd_amixer_elem_is_empty(melem))
+ return snd_amixer_elem_remove(melem);
err = simple_update(melem);
- return snd_mixer_elem_info(melem);
+ return snd_amixer_elem_info(melem);
}
-static int simple_event(snd_mixer_class_t *class, unsigned int mask,
- snd_hctl_elem_t *helem, snd_mixer_elem_t *melem)
+static int simple_event(snd_amixer_t *amixer, unsigned int mask,
+ snd_ctl_elem_t *helem, snd_amixer_elem_t *melem)
{
int err;
if (mask == SND_CTL_EVENT_MASK_REMOVE)
return simple_event_remove(helem, melem);
if (mask & SND_CTL_EVENT_MASK_ADD) {
- err = simple_event_add(class, helem);
+ err = simple_event_add(amixer, helem);
if (err < 0)
return err;
}
@@ -1677,7 +1697,7 @@ static int simple_event(snd_mixer_class_t *class, unsigned int mask,
err = simple_event_remove(helem, melem);
if (err < 0)
return err;
- err = simple_event_add(class, helem);
+ err = simple_event_add(amixer, helem);
if (err < 0)
return err;
return 0;
@@ -1687,7 +1707,7 @@ static int simple_event(snd_mixer_class_t *class, unsigned int mask,
if (err < 0)
return err;
if (err) {
- err = snd_mixer_elem_value(melem);
+ err = snd_amixer_elem_value(melem);
if (err < 0)
return err;
}
@@ -1695,30 +1715,75 @@ static int simple_event(snd_mixer_class_t *class, unsigned int mask,
return 0;
}
+#ifndef DOC_HIDDEN
/**
- * \brief Register mixer simple element class - none abstraction
- * \param mixer Mixer handle
- * \param options Options container
- * \param classp Pointer to returned mixer simple element class handle (or NULL)
+ * \brief Open mixer - none abstraction
+ * \param amixer Mixer handle
+ * \param name Device name
+ * \param pcm_playback PCM handle for playback
+ * \param pcm_capture PCM handle for capture
+ * \param mode Open mode
* \return 0 on success otherwise a negative error code
*/
-int snd_mixer_simple_none_register(snd_mixer_t *mixer,
- struct snd_mixer_selem_regopt *options ATTRIBUTE_UNUSED,
- snd_mixer_class_t **classp)
+int _snd_amixer_none_open(snd_amixer_t *amixer,
+ snd_config_t *root ATTRIBUTE_UNUSED,
+ snd_config_t *conf,
+ struct sm_open *sm_open)
{
- snd_mixer_class_t *class;
+ snd_config_iterator_t i, next;
+ const char *str;
int err;
-
- if (snd_mixer_class_malloc(&class))
- return -ENOMEM;
- snd_mixer_class_set_event(class, simple_event);
- snd_mixer_class_set_compare(class, snd_mixer_selem_compare);
- err = snd_mixer_class_register(class, mixer);
- if (err < 0) {
- free(class);
- return err;
+ snd_config_t *n;
+ char ctlname[64];
+
+ ctlname[0] = '\0';
+ if (sm_open->pcm_playback || sm_open->pcm_capture)
+ return -ENXIO;
+ snd_config_for_each(i, next, conf) {
+ const char *id;
+ n = snd_config_iterator_entry(i);
+ if (snd_config_get_id(n, &id) < 0)
+ continue;
+ if (snd_amixer_conf_generic_id(id))
+ continue;
+ if (strcmp(id, "card") == 0) {
+ long card = -1;
+ err = snd_config_get_integer(n, &card);
+ if (err < 0) {
+ err = snd_config_get_string(n, &str);
+ if (err < 0) {
+ SNDERR("Invalid type for %s", id);
+ return -EINVAL;
+ }
+ card = snd_card_get_index(str);
+ if (card < 0) {
+ SNDERR("Invalid value for %s", id);
+ return card;
+ }
+ }
+ sprintf(ctlname, "hw:%li", card);
+ continue;
+ }
+ if (strcmp(id, "ctlname") == 0) {
+ err = snd_config_get_string(n, &str);
+ if (err < 0) {
+ SNDERR("ctlname must be a string");
+ return -EINVAL;
+ }
+ strncpy(ctlname, str, sizeof(ctlname)-1);
+ ctlname[sizeof(ctlname)-1] = '\0';
+ continue;
+ }
+ SNDERR("Unknown field %s", id);
+ return -EINVAL;
}
- if (classp)
- *classp = class;
- return 0;
+ if (ctlname[0] == '\0') {
+ SNDERR("card or ctlname is not defined");
+ return -EINVAL;
+ }
+ snd_amixer_set_event(amixer, simple_event);
+ return snd_ctl_open(&sm_open->ctl[0], ctlname, SND_CTL_CACHE);
}
+
+SND_DLSYM_BUILD_VERSION(_snd_amixer_none_open, SND_AMIXER_DLSYM_VERSION);
+#endif