diff options
Diffstat (limited to 'firmware/target/hosted')
-rw-r--r-- | firmware/target/hosted/alsa-controls.c | 69 | ||||
-rw-r--r-- | firmware/target/hosted/alsa-controls.h | 8 |
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) | |||
108 | return -1; | 108 | return -1; |
109 | } | 109 | } |
110 | 110 | ||
111 | /* set a control, potentially supports several values */ | 111 | /* set/get a control, potentially supports several values */ |
112 | void alsa_controls_set(const char *name, snd_ctl_elem_type_t type, | 112 | void alsa_controls_get_set(bool get, const char *name, snd_ctl_elem_type_t type, |
113 | unsigned nr_values, long *val) | 113 | unsigned nr_values, long *val) |
114 | { | 114 | { |
115 | snd_ctl_elem_id_t *id; | 115 | snd_ctl_elem_id_t *id; |
@@ -132,21 +132,54 @@ void alsa_controls_set(const char *name, snd_ctl_elem_type_t type, | |||
132 | if(snd_ctl_elem_info_get_count(info) != nr_values) | 132 | if(snd_ctl_elem_info_get_count(info) != nr_values) |
133 | panicf("Control '%s' has wrong count (got %u, expected %u)", | 133 | panicf("Control '%s' has wrong count (got %u, expected %u)", |
134 | name, snd_ctl_elem_info_get_count(info), nr_values); | 134 | name, snd_ctl_elem_info_get_count(info), nr_values); |
135 | /* set value */ | ||
136 | snd_ctl_elem_value_set_id(value, id); | 135 | snd_ctl_elem_value_set_id(value, id); |
137 | for(unsigned i = 0; i < nr_values; i++) | 136 | /* set value */ |
137 | if(get) | ||
138 | { | ||
139 | /* read value */ | ||
140 | if(snd_ctl_elem_read(alsa_ctl, value) < 0) | ||
141 | panicf("Cannot read control '%s'", name); | ||
142 | for(unsigned i = 0; i < nr_values; i++) | ||
143 | { | ||
144 | /* ALSA is braindead: there are "typed" setters but they all take long anyway */ | ||
145 | if(type == SND_CTL_ELEM_TYPE_BOOLEAN) | ||
146 | val[i] = snd_ctl_elem_value_get_boolean(value, i); | ||
147 | else if(type == SND_CTL_ELEM_TYPE_INTEGER) | ||
148 | val[i] = snd_ctl_elem_value_get_integer(value, i); | ||
149 | else if(type == SND_CTL_ELEM_TYPE_ENUMERATED) | ||
150 | val[i] = snd_ctl_elem_value_get_enumerated(value, i); | ||
151 | } | ||
152 | } | ||
153 | else | ||
138 | { | 154 | { |
139 | /* ALSA is braindead: there are "typed" setters but they all take long anyway */ | 155 | for(unsigned i = 0; i < nr_values; i++) |
140 | if(type == SND_CTL_ELEM_TYPE_BOOLEAN) | 156 | { |
141 | snd_ctl_elem_value_set_boolean(value, i, val[i]); | 157 | /* ALSA is braindead: there are "typed" setters but they all take long anyway */ |
142 | else if(type == SND_CTL_ELEM_TYPE_INTEGER) | 158 | if(type == SND_CTL_ELEM_TYPE_BOOLEAN) |
143 | snd_ctl_elem_value_set_integer(value, i, val[i]); | 159 | snd_ctl_elem_value_set_boolean(value, i, val[i]); |
144 | else if(type == SND_CTL_ELEM_TYPE_ENUMERATED) | 160 | else if(type == SND_CTL_ELEM_TYPE_INTEGER) |
145 | snd_ctl_elem_value_set_enumerated(value, i, val[i]); | 161 | snd_ctl_elem_value_set_integer(value, i, val[i]); |
162 | else if(type == SND_CTL_ELEM_TYPE_ENUMERATED) | ||
163 | snd_ctl_elem_value_set_enumerated(value, i, val[i]); | ||
164 | } | ||
165 | /* write value */ | ||
166 | if(snd_ctl_elem_write(alsa_ctl, value) < 0) | ||
167 | panicf("Cannot write control '%s'", name); | ||
146 | } | 168 | } |
147 | /* write value */ | 169 | } |
148 | if(snd_ctl_elem_write(alsa_ctl, value) < 0) | 170 | |
149 | panicf("Cannot write control '%s'", name); | 171 | /* set a control, potentially supports several values */ |
172 | void alsa_controls_set(const char *name, snd_ctl_elem_type_t type, | ||
173 | unsigned nr_values, long *val) | ||
174 | { | ||
175 | return alsa_controls_get_set(false, name, type, nr_values, val); | ||
176 | } | ||
177 | |||
178 | /* get a control, potentially supports several values */ | ||
179 | void alsa_controls_get(const char *name, snd_ctl_elem_type_t type, | ||
180 | unsigned nr_values, long *val) | ||
181 | { | ||
182 | return alsa_controls_get_set(true, name, type, nr_values, val); | ||
150 | } | 183 | } |
151 | 184 | ||
152 | /* get control information */ | 185 | /* get control information */ |
@@ -188,3 +221,11 @@ void alsa_controls_set_ints(const char *name, int count, long *val) | |||
188 | { | 221 | { |
189 | return alsa_controls_set(name, SND_CTL_ELEM_TYPE_INTEGER, count, val); | 222 | return alsa_controls_set(name, SND_CTL_ELEM_TYPE_INTEGER, count, val); |
190 | } | 223 | } |
224 | |||
225 | /* helper function: get a control with a single boolean value */ | ||
226 | bool alsa_controls_get_bool(const char *name) | ||
227 | { | ||
228 | long lval = 0; | ||
229 | alsa_controls_get(name, SND_CTL_ELEM_TYPE_BOOLEAN, 1, &lval); | ||
230 | return lval != 0; | ||
231 | } | ||
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); | |||
31 | /* close alsa controls */ | 31 | /* close alsa controls */ |
32 | void alsa_controls_close(void); | 32 | void alsa_controls_close(void); |
33 | 33 | ||
34 | /* NOTE: all the following functions panic on error. This behaviour could be changed with the | ||
35 | * functions returning proper values but that would make errors happen silently */ | ||
36 | |||
34 | /* find a control element ID by name, return false of not found, the id needs | 37 | /* find a control element ID by name, return false of not found, the id needs |
35 | * to be allocated */ | 38 | * to be allocated */ |
36 | bool alsa_controls_find(snd_ctl_elem_id_t *id, const char *name); | 39 | 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); | |||
49 | void alsa_controls_set_enum(const char *name, const char *enum_name); | 52 | void alsa_controls_set_enum(const char *name, const char *enum_name); |
50 | /* helper function: set a control with one or more integers */ | 53 | /* helper function: set a control with one or more integers */ |
51 | void alsa_controls_set_ints(const char *name, int count, long *val); | 54 | void alsa_controls_set_ints(const char *name, int count, long *val); |
55 | /* get a control value, potentially supports several values */ | ||
56 | void alsa_controls_get(const char *name, snd_ctl_elem_type_t type, | ||
57 | unsigned nr_values, long *val); | ||
58 | /* helper function: set a control with a single boolean value */ | ||
59 | bool alsa_controls_get_bool(const char *name); | ||
52 | 60 | ||
53 | #endif /* __ALSA_CONTROLS_RB_H__ */ | 61 | #endif /* __ALSA_CONTROLS_RB_H__ */ |