summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--firmware/target/hosted/alsa-controls.c69
-rw-r--r--firmware/target/hosted/alsa-controls.h8
2 files changed, 63 insertions, 14 deletions
diff --git a/firmware/target/hosted/alsa-controls.c b/firmware/target/hosted/alsa-controls.c
index 289f2e76c9..1d6d73e751 100644
--- a/firmware/target/hosted/alsa-controls.c
+++ b/firmware/target/hosted/alsa-controls.c
@@ -108,8 +108,8 @@ int alsa_controls_find_enum(const char *name, const char *enum_name)
return -1;
}
-/* set a control, potentially supports several values */
-void alsa_controls_set(const char *name, snd_ctl_elem_type_t type,
+/* set/get a control, potentially supports several values */
+void alsa_controls_get_set(bool get, const char *name, snd_ctl_elem_type_t type,
unsigned nr_values, long *val)
{
snd_ctl_elem_id_t *id;
@@ -132,21 +132,54 @@ void alsa_controls_set(const char *name, snd_ctl_elem_type_t type,
if(snd_ctl_elem_info_get_count(info) != nr_values)
panicf("Control '%s' has wrong count (got %u, expected %u)",
name, snd_ctl_elem_info_get_count(info), nr_values);
- /* set value */
snd_ctl_elem_value_set_id(value, id);
- for(unsigned i = 0; i < nr_values; i++)
+ /* set value */
+ if(get)
+ {
+ /* read value */
+ if(snd_ctl_elem_read(alsa_ctl, value) < 0)
+ panicf("Cannot read control '%s'", name);
+ for(unsigned i = 0; i < nr_values; i++)
+ {
+ /* ALSA is braindead: there are "typed" setters but they all take long anyway */
+ if(type == SND_CTL_ELEM_TYPE_BOOLEAN)
+ val[i] = snd_ctl_elem_value_get_boolean(value, i);
+ else if(type == SND_CTL_ELEM_TYPE_INTEGER)
+ val[i] = snd_ctl_elem_value_get_integer(value, i);
+ else if(type == SND_CTL_ELEM_TYPE_ENUMERATED)
+ val[i] = snd_ctl_elem_value_get_enumerated(value, i);
+ }
+ }
+ else
{
- /* ALSA is braindead: there are "typed" setters but they all take long anyway */
- if(type == SND_CTL_ELEM_TYPE_BOOLEAN)
- snd_ctl_elem_value_set_boolean(value, i, val[i]);
- else if(type == SND_CTL_ELEM_TYPE_INTEGER)
- snd_ctl_elem_value_set_integer(value, i, val[i]);
- else if(type == SND_CTL_ELEM_TYPE_ENUMERATED)
- snd_ctl_elem_value_set_enumerated(value, i, val[i]);
+ for(unsigned i = 0; i < nr_values; i++)
+ {
+ /* ALSA is braindead: there are "typed" setters but they all take long anyway */
+ if(type == SND_CTL_ELEM_TYPE_BOOLEAN)
+ snd_ctl_elem_value_set_boolean(value, i, val[i]);
+ else if(type == SND_CTL_ELEM_TYPE_INTEGER)
+ snd_ctl_elem_value_set_integer(value, i, val[i]);
+ else if(type == SND_CTL_ELEM_TYPE_ENUMERATED)
+ snd_ctl_elem_value_set_enumerated(value, i, val[i]);
+ }
+ /* write value */
+ if(snd_ctl_elem_write(alsa_ctl, value) < 0)
+ panicf("Cannot write control '%s'", name);
}
- /* write value */
- if(snd_ctl_elem_write(alsa_ctl, value) < 0)
- panicf("Cannot write control '%s'", name);
+}
+
+/* set a control, potentially supports several values */
+void alsa_controls_set(const char *name, snd_ctl_elem_type_t type,
+ unsigned nr_values, long *val)
+{
+ return alsa_controls_get_set(false, name, type, nr_values, val);
+}
+
+/* get a control, potentially supports several values */
+void alsa_controls_get(const char *name, snd_ctl_elem_type_t type,
+ unsigned nr_values, long *val)
+{
+ return alsa_controls_get_set(true, name, type, nr_values, val);
}
/* get control information */
@@ -188,3 +221,11 @@ void alsa_controls_set_ints(const char *name, int count, long *val)
{
return alsa_controls_set(name, SND_CTL_ELEM_TYPE_INTEGER, count, val);
}
+
+/* helper function: get a control with a single boolean value */
+bool alsa_controls_get_bool(const char *name)
+{
+ long lval = 0;
+ alsa_controls_get(name, SND_CTL_ELEM_TYPE_BOOLEAN, 1, &lval);
+ return lval != 0;
+}
diff --git a/firmware/target/hosted/alsa-controls.h b/firmware/target/hosted/alsa-controls.h
index f5c8439721..870797c5b8 100644
--- a/firmware/target/hosted/alsa-controls.h
+++ b/firmware/target/hosted/alsa-controls.h
@@ -31,6 +31,9 @@ void alsa_controls_init(void);
/* close alsa controls */
void alsa_controls_close(void);
+/* NOTE: all the following functions panic on error. This behaviour could be changed with the
+ * functions returning proper values but that would make errors happen silently */
+
/* find a control element ID by name, return false of not found, the id needs
* to be allocated */
bool alsa_controls_find(snd_ctl_elem_id_t *id, const char *name);
@@ -49,5 +52,10 @@ void alsa_controls_set_bool(const char *name, bool val);
void alsa_controls_set_enum(const char *name, const char *enum_name);
/* helper function: set a control with one or more integers */
void alsa_controls_set_ints(const char *name, int count, long *val);
+/* get a control value, potentially supports several values */
+void alsa_controls_get(const char *name, snd_ctl_elem_type_t type,
+ unsigned nr_values, long *val);
+/* helper function: set a control with a single boolean value */
+bool alsa_controls_get_bool(const char *name);
#endif /* __ALSA_CONTROLS_RB_H__ */