1 /**
2  * \file control/control.c
3  * \brief CTL interface - primitive controls
4  * \author Abramo Bagnara <abramo@alsa-project.org>
5  * \date 2000
6  *
7  * CTL interface is designed to access primitive controls.
8  * See \ref control page for more details.
9  */
10 /*
11  *  Control Interface - main file
12  *  Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
13  *
14  *
15  *   This library is free software; you can redistribute it and/or modify
16  *   it under the terms of the GNU Lesser General Public License as
17  *   published by the Free Software Foundation; either version 2.1 of
18  *   the License, or (at your option) any later version.
19  *
20  *   This program is distributed in the hope that it will be useful,
21  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
22  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  *   GNU Lesser General Public License for more details.
24  *
25  *   You should have received a copy of the GNU Lesser General Public
26  *   License along with this library; if not, write to the Free Software
27  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
28  *
29  */
30 
31 /*! \page control Control interface
32 
33 <P>Control interface is designed to access primitive controls. There is
34 also interface notifying about control and structure changes.
35 
36 \section control_general_overview General overview
37 
38 In ALSA control feature, each sound card can have control elements. The elements
39 are managed according to below model.
40 
41  - element set
42    - A set of elements with the same attribute (i.e. name, get/put operations).
43      Some element sets can be added to a sound card by drivers in kernel and
44      userspace applications.
45  - element
46    - An element can be identified by userspace applications. Each element has
47      own identical information.
48  - member
49    - An element includes some members to have a value. The value of each member
50      can be changed by both of userspace applications and drivers in kernel.
51 
52 Each element can be identified by two ways; a combination of name and index, or
53 numerical number (numid).
54 
55 The type of element set is one of integer, integerr64, boolean, enumerators,
56 bytes and IEC958 structure. This indicates the type of value for each member in
57 elements included in the element set.
58 
59 When the value of member is changed, corresponding events are transferred to
60 userspace applications. The applications should subscribe any events in advance.
61 
62 \section tlv_blob Supplemental data for elements in an element set
63 
64 TLV feature is designed to transfer data in a shape of Type/Length/Value,
65 between a driver and any userspace applications. The main purpose is to attach
66 supplement information for elements to an element set; e.g. dB range.
67 
68 At first, this feature was implemented to add pre-defined data readable to
69 userspace applications. Soon, it was extended to handle several operations;
70 read, write and command. The original implementation remains as the read
71 operation. The command operation allows drivers to have own implementations
72 against requests from userspace applications.
73 
74 This feature was introduced to ALSA control feature in 2006, at commit
75 c7a0708a2362, corresponding to a series of work for Linux kernel (42750b04c5ba
76 and 8aa9b586e420).
77 
78 There's no limitation about maximum size of the data, therefore it can be used
79 to deliver quite large arbitrary data from userspace to in-kernel drivers via
80 ALSA control character device. Focusing on this nature, as of 2016, some
81 in-kernel implementations utilize this feature for I/O operations. This is
82 against the original design.
83 */
84 
85 #include <stdio.h>
86 #include <stdlib.h>
87 #include <stdint.h>
88 #include <stdarg.h>
89 #include <unistd.h>
90 #include <string.h>
91 #include <fcntl.h>
92 #include <signal.h>
93 #include <poll.h>
94 #include <stdbool.h>
95 #include "control_local.h"
96 
97 /**
98  * \brief get identifier of CTL handle
99  * \param ctl CTL handle
100  * \return ascii identifier of CTL handle
101  *
102  * Returns the ASCII identifier of given CTL handle. It's the same
103  * identifier specified in snd_ctl_open().
104  */
snd_ctl_name(snd_ctl_t * ctl)105 const char *snd_ctl_name(snd_ctl_t *ctl)
106 {
107 	assert(ctl);
108 	return ctl->name;
109 }
110 
111 /**
112  * \brief get type of CTL handle
113  * \param ctl CTL handle
114  * \return type of CTL handle
115  *
116  * Returns the type #snd_ctl_type_t of given CTL handle.
117  */
snd_ctl_type(snd_ctl_t * ctl)118 snd_ctl_type_t snd_ctl_type(snd_ctl_t *ctl)
119 {
120 	assert(ctl);
121 	return ctl->type;
122 }
123 
124 /**
125  * \brief close CTL handle
126  * \param ctl CTL handle
127  * \return 0 on success otherwise a negative error code
128  *
129  * Closes the specified CTL handle and frees all associated
130  * resources.
131  */
snd_ctl_close(snd_ctl_t * ctl)132 int snd_ctl_close(snd_ctl_t *ctl)
133 {
134 	int err;
135 	while (!list_empty(&ctl->async_handlers)) {
136 		snd_async_handler_t *h = list_entry(&ctl->async_handlers.next, snd_async_handler_t, hlist);
137 		snd_async_del_handler(h);
138 	}
139 	err = ctl->ops->close(ctl);
140 	free(ctl->name);
141 	snd_dlobj_cache_put(ctl->open_func);
142 	free(ctl);
143 	return err;
144 }
145 
146 /**
147  * \brief set nonblock mode
148  * \param ctl CTL handle
149  * \param nonblock 0 = block, 1 = nonblock mode, 2 = abort
150  * \return 0 on success otherwise a negative error code
151  */
snd_ctl_nonblock(snd_ctl_t * ctl,int nonblock)152 int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock)
153 {
154 	int err;
155 	assert(ctl);
156 	err = ctl->ops->nonblock(ctl, nonblock);
157 	if (err < 0)
158 		return err;
159 	ctl->nonblock = nonblock;
160 	return 0;
161 }
162 
163 #ifndef DOC_HIDDEN
snd_ctl_new(snd_ctl_t ** ctlp,snd_ctl_type_t type,const char * name)164 int snd_ctl_new(snd_ctl_t **ctlp, snd_ctl_type_t type, const char *name)
165 {
166 	snd_ctl_t *ctl;
167 	ctl = calloc(1, sizeof(*ctl));
168 	if (!ctl)
169 		return -ENOMEM;
170 	ctl->type = type;
171 	if (name)
172 		ctl->name = strdup(name);
173 	INIT_LIST_HEAD(&ctl->async_handlers);
174 	*ctlp = ctl;
175 	return 0;
176 }
177 
178 
179 /**
180  * \brief set async mode
181  * \param ctl CTL handle
182  * \param sig Signal to raise: < 0 disable, 0 default (SIGIO)
183  * \param pid Process ID to signal: 0 current
184  * \return 0 on success otherwise a negative error code
185  *
186  * A signal is raised when a change happens.
187  */
snd_ctl_async(snd_ctl_t * ctl,int sig,pid_t pid)188 int snd_ctl_async(snd_ctl_t *ctl, int sig, pid_t pid)
189 {
190 	assert(ctl);
191 	if (sig == 0)
192 		sig = SIGIO;
193 	if (pid == 0)
194 		pid = getpid();
195 	return ctl->ops->async(ctl, sig, pid);
196 }
197 #endif
198 
199 /**
200  * \brief get count of poll descriptors for CTL handle
201  * \param ctl CTL handle
202  * \return count of poll descriptors
203  */
snd_ctl_poll_descriptors_count(snd_ctl_t * ctl)204 int snd_ctl_poll_descriptors_count(snd_ctl_t *ctl)
205 {
206 	assert(ctl);
207 	if (ctl->ops->poll_descriptors_count)
208 		return ctl->ops->poll_descriptors_count(ctl);
209 	if (ctl->poll_fd < 0)
210 		return 0;
211 	return 1;
212 }
213 
214 /**
215  * \brief get poll descriptors
216  * \param ctl CTL handle
217  * \param pfds array of poll descriptors
218  * \param space space in the poll descriptor array
219  * \return count of filled descriptors
220  */
snd_ctl_poll_descriptors(snd_ctl_t * ctl,struct pollfd * pfds,unsigned int space)221 int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int space)
222 {
223 	assert(ctl && pfds);
224 	if (ctl->ops->poll_descriptors)
225 		return ctl->ops->poll_descriptors(ctl, pfds, space);
226 	if (ctl->poll_fd < 0)
227 		return 0;
228 	if (space > 0) {
229 		pfds->fd = ctl->poll_fd;
230 		pfds->events = POLLIN|POLLERR|POLLNVAL;
231 		return 1;
232 	}
233 	return 0;
234 }
235 
236 /**
237  * \brief get returned events from poll descriptors
238  * \param ctl CTL handle
239  * \param pfds array of poll descriptors
240  * \param nfds count of poll descriptors
241  * \param revents returned events
242  * \return zero if success, otherwise a negative error code
243  */
snd_ctl_poll_descriptors_revents(snd_ctl_t * ctl,struct pollfd * pfds,unsigned int nfds,unsigned short * revents)244 int snd_ctl_poll_descriptors_revents(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
245 {
246 	assert(ctl && pfds && revents);
247 	if (ctl->ops->poll_revents)
248 		return ctl->ops->poll_revents(ctl, pfds, nfds, revents);
249 	if (nfds == 1) {
250 		*revents = pfds->revents;
251                 return 0;
252 	}
253 	return -EINVAL;
254 }
255 
256 /**
257  * \brief Ask to be informed about events (poll, #snd_async_add_ctl_handler, #snd_ctl_read)
258  * \param ctl CTL handle
259  * \param subscribe 0 = unsubscribe, 1 = subscribe, -1 = check subscribe or not
260  * \return 0 on success otherwise a negative error code
261  */
snd_ctl_subscribe_events(snd_ctl_t * ctl,int subscribe)262 int snd_ctl_subscribe_events(snd_ctl_t *ctl, int subscribe)
263 {
264 	assert(ctl);
265 	return ctl->ops->subscribe_events(ctl, subscribe);
266 }
267 
268 
269 /**
270  * \brief Get card related information
271  * \param ctl CTL handle
272  * \param info Card info pointer
273  * \return 0 on success otherwise a negative error code
274  */
snd_ctl_card_info(snd_ctl_t * ctl,snd_ctl_card_info_t * info)275 int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info)
276 {
277 	assert(ctl && info);
278 	return ctl->ops->card_info(ctl, info);
279 }
280 
281 /**
282  * \brief Get a list of element identifiers
283  * \param ctl CTL handle
284  * \param list CTL element identifiers list pointer
285  * \return 0 on success otherwise a negative error code
286  */
snd_ctl_elem_list(snd_ctl_t * ctl,snd_ctl_elem_list_t * list)287 int snd_ctl_elem_list(snd_ctl_t *ctl, snd_ctl_elem_list_t *list)
288 {
289 	assert(ctl && list);
290 	assert(list->space == 0 || list->pids);
291 	return ctl->ops->element_list(ctl, list);
292 }
293 
294 /**
295  * \brief Get CTL element information
296  * \param ctl CTL handle
297  * \param info CTL element id/information pointer
298  * \return 0 on success otherwise a negative error code
299  */
snd_ctl_elem_info(snd_ctl_t * ctl,snd_ctl_elem_info_t * info)300 int snd_ctl_elem_info(snd_ctl_t *ctl, snd_ctl_elem_info_t *info)
301 {
302 	assert(ctl && info && (info->id.name[0] || info->id.numid));
303 	return ctl->ops->element_info(ctl, info);
304 }
305 
306 #if 0 /* deprecated */
307 static bool validate_element_member_dimension(snd_ctl_elem_info_t *info)
308 {
309 	unsigned int members;
310 	unsigned int i;
311 
312 	if (info->dimen.d[0] == 0)
313 		return true;
314 
315 	members = 1;
316 	for (i = 0; i < ARRAY_SIZE(info->dimen.d); ++i) {
317 		if (info->dimen.d[i] == 0)
318 			break;
319 		members *= info->dimen.d[i];
320 
321 		if (members > info->count)
322 			return false;
323 	}
324 
325 	for (++i; i < ARRAY_SIZE(info->dimen.d); ++i) {
326 		if (info->dimen.d[i] > 0)
327 			return false;
328 	}
329 
330 	return members == info->count;
331 }
332 #else /* deprecated */
333 #define validate_element_member_dimension(info)		true
334 #endif /* deprecated */
335 
336 /**
337  * \brief Create and add some user-defined control elements of integer type.
338  * \param ctl A handle of backend module for control interface.
339  * \param info Common iformation for a new element set, with ID of the first new
340  *	       element.
341  * \param element_count The number of elements added by this operation.
342  * \param member_count The number of members which a element has to
343  *			   represent its states.
344  * \param min Minimum value for each member of the elements.
345  * \param max Maximum value for each member of the elements.
346  * \param step The step of value for each member in the elements.
347  * \return Zero on success, otherwise a negative error code.
348  *
349  * This function creates some user elements with integer type. These elements
350  * are not controlled by device drivers in kernel. They can be operated by the
351  * same way as usual elements added by the device drivers.
352  *
353  * The name field of \a id must be set with unique value to identify new control
354  * elements. After returning, all fields of \a id are filled. A element can be
355  * identified by the combination of name and index, or by numid.
356  *
357  * All of members in the new elements are locked. The value of each member is
358  * initialized with the minimum value.
359  *
360  * \par Errors:
361  * <dl>
362  * <dt>-EBUSY
363  * <dd>A element with ID \a id already exists.
364  * <dt>-EINVAL
365  * <dd>Some arguments include invalid value; i.e. ID field in \a info has no
366  *     name, or the number of members is not between 1 to 127.
367  * <dt>-ENOMEM
368  * <dd>Out of memory, or there are too many user elements.
369  * <dt>-ENXIO
370  * <dd>This backend module does not support user elements of integer type.
371  * <dt>-ENODEV
372  * <dd>Device unplugged.
373  * </dl>
374  *
375  * \par Compatibility:
376  * This function is added in version 1.1.2.
377  */
snd_ctl_add_integer_elem_set(snd_ctl_t * ctl,snd_ctl_elem_info_t * info,unsigned int element_count,unsigned int member_count,long min,long max,long step)378 int snd_ctl_add_integer_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
379 				 unsigned int element_count,
380 				 unsigned int member_count,
381 				 long min, long max, long step)
382 {
383 	snd_ctl_elem_value_t data = {0};
384 	unsigned int i;
385 	unsigned int j;
386 	unsigned int numid;
387 	int err;
388 
389 	if (ctl == NULL || info == NULL || info->id.name[0] == '\0')
390 		return -EINVAL;
391 
392 	info->type = SND_CTL_ELEM_TYPE_INTEGER;
393 	info->access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
394 		       SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE |
395 		       SNDRV_CTL_ELEM_ACCESS_USER;
396 	info->owner = element_count;
397 	info->count = member_count;
398 	info->value.integer.min = min;
399 	info->value.integer.max = max;
400 	info->value.integer.step = step;
401 
402 	if (!validate_element_member_dimension(info))
403 		return -EINVAL;
404 
405 	err = ctl->ops->element_add(ctl, info);
406 	if (err < 0)
407 		return err;
408 	numid = snd_ctl_elem_id_get_numid(&info->id);
409 
410 	/* Set initial value to all of members in all of added elements. */
411 	data.id = info->id;
412 	for (i = 0; i < element_count; i++) {
413 		snd_ctl_elem_id_set_numid(&data.id, numid + i);
414 
415 		for (j = 0; j < member_count; j++)
416 			data.value.integer.value[j] = min;
417 
418 		err = ctl->ops->element_write(ctl, &data);
419 		if (err < 0)
420 			return err;
421 	}
422 
423 	return 0;
424 }
425 
426 /**
427  * \brief Create and add some user-defined control elements of integer64 type.
428  * \param ctl A handle of backend module for control interface.
429  * \param info Common iformation for a new element set, with ID of the first new
430  *	       element.
431  * \param element_count The number of elements added by this operation.
432  * \param member_count The number of members which a element has to
433  *	    	   represent its states.
434  * \param min Minimum value for each member of the elements.
435  * \param max Maximum value for each member of the elements.
436  * \param step The step of value for each member in the elements.
437  * \return Zero on success, otherwise a negative error code.
438  *
439  * This function creates some user elements with integer64 type. These elements
440  * are not controlled by device drivers in kernel. They can be operated by the
441  * same way as usual elements added by the device drivers.
442  *
443  * The name field of \a id must be set with unique value to identify new control
444  * elements. After returning, all fields of \a id are filled. A element can be
445  * identified by the combination of name and index, or by numid.
446  *
447  * All of members in the new elements are locked. The value of each member is
448  * initialized with the minimum value.
449  *
450  * \par Errors:
451  * <dl>
452  * <dt>-EBUSY
453  * <dd>A element with ID \a id already exists.
454  * <dt>-EINVAL
455  * <dd>Some arguments include invalid value; i.e. ID has no name, or the number
456  *     of members is not between 1 to 127.
457  * <dt>-ENOMEM
458  * <dd>Out of memory, or there are too many user elements.
459  * <dt>-ENXIO
460  * <dd>This backend module does not support user elements of integer64 type.
461  * <dt>-ENODEV
462  * <dd>Device unplugged.
463  * </dl>
464  *
465  * \par Compatibility:
466  * This function is added in version 1.1.2.
467  */
snd_ctl_add_integer64_elem_set(snd_ctl_t * ctl,snd_ctl_elem_info_t * info,unsigned int element_count,unsigned int member_count,long long min,long long max,long long step)468 int snd_ctl_add_integer64_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
469 				   unsigned int element_count,
470 				   unsigned int member_count,
471 				   long long min, long long max, long long step)
472 {
473 	snd_ctl_elem_value_t data = {0};
474 	unsigned int i;
475 	unsigned int j;
476 	unsigned int numid;
477 	int err;
478 
479 	if (ctl == NULL || info == NULL || info->id.name[0] == '\0')
480 		return -EINVAL;
481 
482 	info->type = SND_CTL_ELEM_TYPE_INTEGER64;
483 	info->access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
484 		       SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE |
485 		       SNDRV_CTL_ELEM_ACCESS_USER;
486 	info->owner = element_count;
487 	info->count = member_count;
488 	info->value.integer64.min = min;
489 	info->value.integer64.max = max;
490 	info->value.integer64.step = step;
491 
492 	if (!validate_element_member_dimension(info))
493 		return -EINVAL;
494 
495 	err = ctl->ops->element_add(ctl, info);
496 	if (err < 0)
497 		return err;
498 	numid = snd_ctl_elem_id_get_numid(&info->id);
499 
500 	/* Set initial value to all of members in all of added elements. */
501 	data.id = info->id;
502 	for (i = 0; i < element_count; i++) {
503 		snd_ctl_elem_id_set_numid(&data.id, numid + i);
504 
505 		for (j = 0; j < member_count; j++)
506 			data.value.integer64.value[j] = min;
507 
508 		err = ctl->ops->element_write(ctl, &data);
509 		if (err < 0)
510 			return err;
511 	}
512 
513 	return 0;
514 }
515 
516 /**
517  * \brief Create and add some user-defined control elements of boolean type.
518  * \param ctl A handle of backend module for control interface.
519  * \param info Common iformation for a new element set, with ID of the first new
520  *	       element.
521  * \param element_count The number of elements added by this operation.
522  * \param member_count The number of members which a element has to
523  *			   represent its states.
524  *
525  * This function creates some user elements with boolean type. These elements
526  * are not controlled by device drivers in kernel. They can be operated by the
527  * same way as usual elements added by the device drivers.
528  *
529  * The name field of \a id must be set with unique value to identify new control
530  * elements. After returning, all fields of \a id are filled. A element can be
531  * identified by the combination of name and index, or by numid.
532  *
533  * All of members in the new elements are locked. The value of each member is
534  * initialized with false.
535  *
536  * \par Errors:
537  * <dl>
538  * <dt>-EBUSY
539  * <dd>A element with ID \a id already exists.
540  * <dt>-EINVAL
541  * <dd>Some parameters include invalid value; i.e. ID has no name, or the number
542  *      of members is not between 1 to 127.
543  * <dt>-ENOMEM
544  * <dd>Out of memory, or there are too many user elements.
545  * <dt>-ENXIO
546  * <dd>This backend module does not support user elements of boolean type.
547  * <dt>-ENODEV
548  * <dd>Device unplugged.
549  * </dl>
550  *
551  * \par Compatibility:
552  * This function is added in version 1.1.2.
553  */
snd_ctl_add_boolean_elem_set(snd_ctl_t * ctl,snd_ctl_elem_info_t * info,unsigned int element_count,unsigned int member_count)554 int snd_ctl_add_boolean_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
555 				 unsigned int element_count,
556 				 unsigned int member_count)
557 {
558 	if (ctl == NULL || info == NULL || info->id.name[0] == '\0')
559 		return -EINVAL;
560 
561 	info->type = SND_CTL_ELEM_TYPE_BOOLEAN;
562 	info->access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
563 		       SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE |
564 		       SNDRV_CTL_ELEM_ACCESS_USER;
565 	info->owner = element_count;
566 	info->count = member_count;
567 	info->value.integer.min = 0;
568 	info->value.integer.max = 1;
569 
570 	if (!validate_element_member_dimension(info))
571 		return -EINVAL;
572 
573 	return ctl->ops->element_add(ctl, info);
574 }
575 
576 /**
577  * \brief Create and add some user-defined control elements of enumerated type.
578  * \param ctl A handle of backend module for control interface.
579  * \param info Common iformation for a new element set, with ID of the first new
580  *	       element.
581  * \param element_count The number of elements added by this operation.
582  * \param member_count The number of members which a element has to
583  *	    	   represent its states.
584  * \param items Range of possible values (0 ... \a items - 1).
585  * \param labels An array containing \a items strings.
586  * \return Zero on success, otherwise a negative error code.
587  *
588  * This function creates some user elements with enumerated type. These elements
589  * are not controlled by device drivers in kernel. They can be operated by the
590  * same way as usual elements added by the device drivers.
591  *
592  * The name field of \a id must be set with unique value to identify new control
593  * elements. After returning, all fields of \a id are filled. A element can be
594  * identified by the combination of name and index, or by numid.
595  *
596  * All of members in the new elements are locked. The value of each member is
597  * initialized with the first entry of labels.
598  *
599  * \par Errors:
600  * <dl>
601  * <dt>-EBUSY
602  * <dd>A control element with ID \a id already exists.
603  * <dt>-EINVAL
604  * <dd>Some arguments include invalid value; i.e. \a element_count is not
605  *     between 1 to 127, or \a items is not at least one, or a string in \a
606  *     labels is empty, or longer than 63 bytes, or total length of the labels
607  *     requires more than 64 KiB storage.
608  * <dt>-ENOMEM
609  * <dd>Out of memory, or there are too many user control elements.
610  * <dt>-ENXIO
611  * <dd>This driver does not support (enumerated) user controls.
612  * <dt>-ENODEV
613  * <dd>Device unplugged.
614  * </dl>
615  *
616  * \par Compatibility:
617  * This function is added in version 1.1.2.
618  */
snd_ctl_add_enumerated_elem_set(snd_ctl_t * ctl,snd_ctl_elem_info_t * info,unsigned int element_count,unsigned int member_count,unsigned int items,const char * const labels[])619 int snd_ctl_add_enumerated_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
620 				    unsigned int element_count,
621 				    unsigned int member_count,
622 				    unsigned int items,
623 				    const char *const labels[])
624 {
625 	unsigned int i, bytes;
626 	char *buf, *p;
627 	int err;
628 
629 	if (ctl == NULL || info == NULL || info->id.name[0] == '\0' ||
630 	    labels == NULL)
631 		return -EINVAL;
632 
633 	info->type = SND_CTL_ELEM_TYPE_ENUMERATED;
634 	info->access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
635 		       SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE |
636 		       SNDRV_CTL_ELEM_ACCESS_USER;
637 	info->owner = element_count;
638 	info->count = member_count;
639 	info->value.enumerated.items = items;
640 
641 	bytes = 0;
642 	for (i = 0; i < items; ++i)
643 		bytes += strlen(labels[i]) + 1;
644 	if (bytes == 0)
645 		return -EINVAL;
646 	buf = malloc(bytes);
647 	if (buf == NULL)
648 		return -ENOMEM;
649 	info->value.enumerated.names_ptr = (uintptr_t)buf;
650 	info->value.enumerated.names_length = bytes;
651 	p = buf;
652 	for (i = 0; i < items; ++i) {
653 		strcpy(p, labels[i]);
654 		p += strlen(labels[i]) + 1;
655 	}
656 
657 	if (!validate_element_member_dimension(info))
658 		return -EINVAL;
659 
660 	err = ctl->ops->element_add(ctl, info);
661 
662 	free(buf);
663 
664 	return err;
665 }
666 
667 /**
668  * \brief Create and add some user-defined control elements of bytes type.
669  * \param ctl A handle of backend module for control interface.
670  * \param info Common iformation for a new element set, with ID of the first new
671  *	       element.
672  * \param element_count The number of elements added by this operation.
673  * \param member_count The number of members which a element has to
674  *			   represent its states.
675  * \return Zero on success, otherwise a negative error code.
676  *
677  * This function creates some user elements with bytes type. These elements are
678  * not controlled by device drivers in kernel. They can be operated by the same
679  * way as usual elements added by the device drivers.
680  *
681  * The name field of \a id must be set with unique value to identify new control
682  * elements. After returning, all fields of \a id are filled. A element can be
683  * identified by the combination of name and index, or by numid.
684  *
685  * All of members in the new elements are locked. The value of each member is
686  * initialized with the minimum value.
687  *
688  * \par Errors:
689  * <dl>
690  * <dt>-EBUSY
691  * <dd>A element with ID \a id already exists.
692  * <dt>-EINVAL
693  * <dd>Some arguments include invalid value; i.e. ID has no name, or the number
694  *     of members is not between 1 to 511.
695  * <dt>-ENOMEM
696  * <dd>Out of memory, or there are too many user elements.
697  * <dt>-ENXIO
698  * <dd>This backend module does not support user elements of bytes type.
699  * <dt>-ENODEV
700  * <dd>Device unplugged.
701  * </dl>
702  *
703  * \par Compatibility:
704  * This function is added in version 1.1.2.
705  */
snd_ctl_add_bytes_elem_set(snd_ctl_t * ctl,snd_ctl_elem_info_t * info,unsigned int element_count,unsigned int member_count)706 int snd_ctl_add_bytes_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
707 			       unsigned int element_count,
708 			       unsigned int member_count)
709 {
710 	if (ctl == NULL || info == NULL || info->id.name[0] == '\0')
711 		return -EINVAL;
712 
713 	info->type = SND_CTL_ELEM_TYPE_BYTES;
714 	info->access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
715 		       SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE |
716 		       SNDRV_CTL_ELEM_ACCESS_USER;
717 	info->owner = element_count;
718 	info->count = member_count;
719 
720 	if (!validate_element_member_dimension(info))
721 		return -EINVAL;
722 
723 	return ctl->ops->element_add(ctl, info);
724 }
725 
726 /**
727  * \brief Create and add an user-defined control element of integer type.
728  *
729  * This is a wrapper function to snd_ctl_add_integer_elem_set() for a control
730  * element. This doesn't fill the id data with full information, thus it's
731  * recommended to use snd_ctl_add_integer_elem_set(), instead.
732  */
snd_ctl_elem_add_integer(snd_ctl_t * ctl,const snd_ctl_elem_id_t * id,unsigned int member_count,long min,long max,long step)733 int snd_ctl_elem_add_integer(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
734 			     unsigned int member_count,
735 			     long min, long max, long step)
736 {
737 	snd_ctl_elem_info_t info = {0};
738 
739 	assert(ctl && id && id->name[0]);
740 
741 	info.id = *id;
742 
743 	return snd_ctl_add_integer_elem_set(ctl, &info, 1, member_count,
744 					    min, max, step);
745 }
746 
747 /**
748  * \brief Create and add an user-defined control element of integer64 type.
749  *
750  * This is a wrapper function to snd_ctl_add_integer64_elem_set() for a single
751  * control element. This doesn't fill the id data with full information, thus
752  * it's recommended to use snd_ctl_add_integer64_elem_set(), instead.
753  */
snd_ctl_elem_add_integer64(snd_ctl_t * ctl,const snd_ctl_elem_id_t * id,unsigned int member_count,long long min,long long max,long long step)754 int snd_ctl_elem_add_integer64(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
755 			       unsigned int member_count,
756 			       long long min, long long max, long long step)
757 {
758 	snd_ctl_elem_info_t info = {0};
759 
760 	assert(ctl && id && id->name[0]);
761 
762 	info.id = *id;
763 
764 	return snd_ctl_add_integer64_elem_set(ctl, &info, 1, member_count,
765 					      min, max, step);
766 }
767 
768 /**
769  * \brief Create and add an user-defined control element of boolean type.
770  *
771  * This is a wrapper function to snd_ctl_add_boolean_elem_set() for a single
772  * control element. This doesn't fill the id data with full information, thus
773  * it's recommended to use snd_ctl_add_boolean_elem_set(), instead.
774  */
snd_ctl_elem_add_boolean(snd_ctl_t * ctl,const snd_ctl_elem_id_t * id,unsigned int member_count)775 int snd_ctl_elem_add_boolean(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
776 			     unsigned int member_count)
777 {
778 	snd_ctl_elem_info_t info = {0};
779 
780 	assert(ctl && id && id->name[0]);
781 
782 	info.id = *id;
783 
784 	return snd_ctl_add_boolean_elem_set(ctl, &info, 1, member_count);
785 }
786 
787 /**
788  * \brief Create and add a user-defined control element of enumerated type.
789  *
790  * This is a wrapper function to snd_ctl_add_enumerated_elem_set() for a single
791  * control element. This doesn't fill the id data with full information, thus
792  * it's recommended to use snd_ctl_add_enumerated_elem_set(), instead.
793  *
794  * This function is added in version 1.0.25.
795  */
snd_ctl_elem_add_enumerated(snd_ctl_t * ctl,const snd_ctl_elem_id_t * id,unsigned int member_count,unsigned int items,const char * const labels[])796 int snd_ctl_elem_add_enumerated(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
797 				unsigned int member_count, unsigned int items,
798 				const char *const labels[])
799 {
800 	snd_ctl_elem_info_t info = {0};
801 
802 	assert(ctl && id && id->name[0] && labels);
803 
804 	info.id = *id;
805 
806 	return snd_ctl_add_enumerated_elem_set(ctl, &info, 1, member_count,
807 					       items, labels);
808 }
809 
810 /**
811  * \brief Create and add a user-defined control element of IEC958 type.
812  * \param[in] ctl A handle of backend module for control interface.
813  * \param[in,out] id ID of the new control element.
814  *
815  * This function creates an user element with IEC958 type. This element is not
816  * controlled by device drivers in kernel. It can be operated by the same way as
817  * usual elements added by the device drivers.
818  *
819  * The name field of \a id must be set with unique value to identify a new
820  * control element. After returning, all fields of \a id are filled. A element
821  * can be identified by the combination of name and index, or by numid.
822  *
823  * A member in the new element is locked and filled with zero.
824  *
825  * \par Errors:
826  * <dl>
827  * <dt>-EBUSY
828  * <dd>A control element with ID \a id already exists.
829  * <dt>-EINVAL
830  * <dd>ID has no name.
831  * <dt>-ENOMEM
832  * <dd>Out of memory, or there are too many user elements.
833  * <dt>-ENXIO
834  * <dd>This backend module does not support user elements of IEC958 type.
835  * <dt>-ENODEV
836  * <dd>Device unplugged.
837  * </dl>
838  */
snd_ctl_elem_add_iec958(snd_ctl_t * ctl,const snd_ctl_elem_id_t * id)839 int snd_ctl_elem_add_iec958(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id)
840 {
841 	snd_ctl_elem_info_t info = {0};
842 
843 	assert(ctl && id && id->name[0]);
844 
845 	info.id = *id;
846 	info.type = SND_CTL_ELEM_TYPE_IEC958;
847 	info.owner = 1;
848 	info.count = 1;
849 	return ctl->ops->element_add(ctl, &info);
850 }
851 
852 /**
853  * \brief Remove an user CTL element
854  * \param ctl CTL handle
855  * \param id CTL element identification
856  * \return 0 on success otherwise a negative error code
857  */
snd_ctl_elem_remove(snd_ctl_t * ctl,snd_ctl_elem_id_t * id)858 int snd_ctl_elem_remove(snd_ctl_t *ctl, snd_ctl_elem_id_t *id)
859 {
860 	assert(ctl && id && (id->name[0] || id->numid));
861 	return ctl->ops->element_remove(ctl, id);
862 }
863 
864 /**
865  * \brief Get CTL element value
866  * \param ctl CTL handle
867  * \param data Data of an element.
868  * \return 0 on success otherwise a negative error code
869  */
snd_ctl_elem_read(snd_ctl_t * ctl,snd_ctl_elem_value_t * data)870 int snd_ctl_elem_read(snd_ctl_t *ctl, snd_ctl_elem_value_t *data)
871 {
872 	assert(ctl && data && (data->id.name[0] || data->id.numid));
873 	return ctl->ops->element_read(ctl, data);
874 }
875 
876 /**
877  * \brief Set CTL element value
878  * \param ctl CTL handle
879  * \param data Data of an element.
880  * \retval 0 on success
881  * \retval >0 on success when value was changed
882  * \retval <0 a negative error code
883  */
snd_ctl_elem_write(snd_ctl_t * ctl,snd_ctl_elem_value_t * data)884 int snd_ctl_elem_write(snd_ctl_t *ctl, snd_ctl_elem_value_t *data)
885 {
886 	assert(ctl && data && (data->id.name[0] || data->id.numid));
887 	return ctl->ops->element_write(ctl, data);
888 }
889 
snd_ctl_tlv_do(snd_ctl_t * ctl,int op_flag,const snd_ctl_elem_id_t * id,unsigned int * tlv,unsigned int tlv_size)890 static int snd_ctl_tlv_do(snd_ctl_t *ctl, int op_flag,
891 			  const snd_ctl_elem_id_t *id,
892 		          unsigned int *tlv, unsigned int tlv_size)
893 {
894 	snd_ctl_elem_info_t *info = NULL;
895 	int err;
896 
897 	if (id->numid == 0) {
898 		info = calloc(1, sizeof(*info));
899 		if (info == NULL)
900 			return -ENOMEM;
901 		info->id = *id;
902 		id = &info->id;
903 		err = snd_ctl_elem_info(ctl, info);
904 		if (err < 0)
905 			goto __err;
906 		if (id->numid == 0) {
907 			err = -ENOENT;
908 			goto __err;
909 		}
910 	}
911 	err = ctl->ops->element_tlv(ctl, op_flag, id->numid, tlv, tlv_size);
912       __err:
913       	if (info)
914       		free(info);
915 	return err;
916 }
917 
918 /**
919  * \brief Read structured data from an element set to given buffer.
920  * \param ctl A handle of backend module for control interface.
921  * \param id ID of an element.
922  * \param tlv An array with members of unsigned int type.
923  * \param tlv_size The length of the array.
924  * \return 0 on success otherwise a negative error code
925  *
926  * The format of an array of \a tlv argument is:
927  *   tlv[0]:   Type. One of SND_CTL_TLVT_XXX.
928  *   tlv[1]:   Length. The length of value in units of byte.
929  *   tlv[2..]: Value. Depending on the type.
930  *
931  * Details are described in <sound/tlv.h>.
932  */
snd_ctl_elem_tlv_read(snd_ctl_t * ctl,const snd_ctl_elem_id_t * id,unsigned int * tlv,unsigned int tlv_size)933 int snd_ctl_elem_tlv_read(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
934 			  unsigned int *tlv, unsigned int tlv_size)
935 {
936 	int err;
937 	assert(ctl && id && (id->name[0] || id->numid) && tlv);
938 	if (tlv_size < 2 * sizeof(int))
939 		return -EINVAL;
940 	/* 1.0.12 driver doesn't return the error even if the user TLV
941 	 * is empty.  So, initialize TLV here with an invalid type
942 	 * and compare the returned value after ioctl for checking
943 	 * the validity of TLV.
944 	 */
945 	tlv[SNDRV_CTL_TLVO_TYPE] = -1;
946 	tlv[SNDRV_CTL_TLVO_LEN] = 0;
947 	err = snd_ctl_tlv_do(ctl, 0, id, tlv, tlv_size);
948 	if (err >= 0 && tlv[SNDRV_CTL_TLVO_TYPE] == (unsigned int)-1)
949 		err = -ENXIO;
950 	return err;
951 }
952 
953 /**
954  * \brief Write structured data from given buffer to an element set.
955  * \param ctl A handle of backend module for control interface.
956  * \param id ID of an element.
957  * \param tlv An array with members of unsigned int type. The second member
958  *	      must represent total bytes of the rest of array.
959  * \retval 0 on success
960  * \retval >0 on success when value was changed
961  * \retval <0 a negative error code
962  *
963  * The format of an array of \a tlv argument is:
964  *   tlv[0]:   Type. One of SND_CTL_TLVT_XXX.
965  *   tlv[1]:   Length. The length of value in units of byte.
966  *   tlv[2..]: Value. Depending on the type.
967  *
968  * Details are described in <sound/tlv.h>.
969  */
snd_ctl_elem_tlv_write(snd_ctl_t * ctl,const snd_ctl_elem_id_t * id,const unsigned int * tlv)970 int snd_ctl_elem_tlv_write(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
971 			   const unsigned int *tlv)
972 {
973 	assert(ctl && id && (id->name[0] || id->numid) && tlv);
974 	return snd_ctl_tlv_do(ctl, 1, id, (unsigned int *)tlv,
975 			tlv[SNDRV_CTL_TLVO_LEN] + 2 * sizeof(unsigned int));
976 }
977 
978 /**
979  * \brief Process structured data from given buffer for an element set.
980  * \param ctl A handle of backend module for control interface.
981  * \param id ID of an element.
982  * \param tlv An array with members of unsigned int type. The second member
983  *	      must represent total bytes of the rest of array.
984  * \retval 0 on success
985  * \retval >0 on success when value was changed
986  * \retval <0 a negative error code
987  *
988  * The format of an array of \a tlv argument is:
989  *   tlv[0]:   Type. One of SND_CTL_TLVT_XXX.
990  *   tlv[1]:   Length. The length of value in units of byte.
991  *   tlv[2..]: Value. Depending on the type.
992  *
993  * Details are described in <sound/tlv.h>.
994  */
snd_ctl_elem_tlv_command(snd_ctl_t * ctl,const snd_ctl_elem_id_t * id,const unsigned int * tlv)995 int snd_ctl_elem_tlv_command(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
996 			     const unsigned int *tlv)
997 {
998 	assert(ctl && id && (id->name[0] || id->numid) && tlv);
999 	return snd_ctl_tlv_do(ctl, -1, id, (unsigned int *)tlv,
1000 			tlv[SNDRV_CTL_TLVO_LEN] + 2 * sizeof(unsigned int));
1001 }
1002 
1003 /**
1004  * \brief Lock CTL element
1005  * \param ctl CTL handle
1006  * \param id CTL element id pointer
1007  * \return 0 on success otherwise a negative error code
1008  */
snd_ctl_elem_lock(snd_ctl_t * ctl,snd_ctl_elem_id_t * id)1009 int snd_ctl_elem_lock(snd_ctl_t *ctl, snd_ctl_elem_id_t *id)
1010 {
1011 	assert(ctl && id);
1012 	return ctl->ops->element_lock(ctl, id);
1013 }
1014 
1015 /**
1016  * \brief Unlock CTL element
1017  * \param ctl CTL handle
1018  * \param id CTL element id pointer
1019  * \return 0 on success otherwise a negative error code
1020  */
snd_ctl_elem_unlock(snd_ctl_t * ctl,snd_ctl_elem_id_t * id)1021 int snd_ctl_elem_unlock(snd_ctl_t *ctl, snd_ctl_elem_id_t *id)
1022 {
1023 	assert(ctl && id);
1024 	return ctl->ops->element_unlock(ctl, id);
1025 }
1026 
1027 /**
1028  * \brief Get next hardware dependent device number
1029  * \param ctl CTL handle
1030  * \param device current device on entry and next device on return
1031  * \return 0 on success otherwise a negative error code
1032  */
snd_ctl_hwdep_next_device(snd_ctl_t * ctl,int * device)1033 int snd_ctl_hwdep_next_device(snd_ctl_t *ctl, int *device)
1034 {
1035 	assert(ctl && device);
1036 	return ctl->ops->hwdep_next_device(ctl, device);
1037 }
1038 
1039 /**
1040  * \brief Get info about a hardware dependent device
1041  * \param ctl CTL handle
1042  * \param info Hardware dependent device id/info pointer
1043  * \return 0 on success otherwise a negative error code
1044  */
snd_ctl_hwdep_info(snd_ctl_t * ctl,snd_hwdep_info_t * info)1045 int snd_ctl_hwdep_info(snd_ctl_t *ctl, snd_hwdep_info_t * info)
1046 {
1047 	assert(ctl && info);
1048 	return ctl->ops->hwdep_info(ctl, info);
1049 }
1050 
1051 /**
1052  * \brief Get next PCM device number
1053  * \param ctl CTL handle
1054  * \param device current device on entry and next device on return
1055  * \return 0 on success otherwise a negative error code
1056  */
snd_ctl_pcm_next_device(snd_ctl_t * ctl,int * device)1057 int snd_ctl_pcm_next_device(snd_ctl_t *ctl, int * device)
1058 {
1059 	assert(ctl && device);
1060 	return ctl->ops->pcm_next_device(ctl, device);
1061 }
1062 
1063 /**
1064  * \brief Get info about a PCM device
1065  * \param ctl CTL handle
1066  * \param info PCM device id/info pointer
1067  * \return 0 on success otherwise a negative error code
1068  */
snd_ctl_pcm_info(snd_ctl_t * ctl,snd_pcm_info_t * info)1069 int snd_ctl_pcm_info(snd_ctl_t *ctl, snd_pcm_info_t * info)
1070 {
1071 	assert(ctl && info);
1072 	return ctl->ops->pcm_info(ctl, info);
1073 }
1074 
1075 /**
1076  * \brief Set preferred PCM subdevice number of successive PCM open
1077  * \param ctl CTL handle
1078  * \param subdev Preferred PCM subdevice number
1079  * \return 0 on success otherwise a negative error code
1080  */
snd_ctl_pcm_prefer_subdevice(snd_ctl_t * ctl,int subdev)1081 int snd_ctl_pcm_prefer_subdevice(snd_ctl_t *ctl, int subdev)
1082 {
1083 	assert(ctl);
1084 	return ctl->ops->pcm_prefer_subdevice(ctl, subdev);
1085 }
1086 
1087 /**
1088  * \brief Get next RawMidi device number
1089  * \param ctl CTL handle
1090  * \param device current device on entry and next device on return
1091  * \return 0 on success otherwise a negative error code
1092  */
snd_ctl_rawmidi_next_device(snd_ctl_t * ctl,int * device)1093 int snd_ctl_rawmidi_next_device(snd_ctl_t *ctl, int * device)
1094 {
1095 	assert(ctl && device);
1096 	return ctl->ops->rawmidi_next_device(ctl, device);
1097 }
1098 
1099 /**
1100  * \brief Get info about a RawMidi device
1101  * \param ctl CTL handle
1102  * \param info RawMidi device id/info pointer
1103  * \return 0 on success otherwise a negative error code
1104  */
snd_ctl_rawmidi_info(snd_ctl_t * ctl,snd_rawmidi_info_t * info)1105 int snd_ctl_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info)
1106 {
1107 	assert(ctl && info);
1108 	return ctl->ops->rawmidi_info(ctl, info);
1109 }
1110 
1111 /**
1112  * \brief Set preferred RawMidi subdevice number of successive RawMidi open
1113  * \param ctl CTL handle
1114  * \param subdev Preferred RawMidi subdevice number
1115  * \return 0 on success otherwise a negative error code
1116  */
snd_ctl_rawmidi_prefer_subdevice(snd_ctl_t * ctl,int subdev)1117 int snd_ctl_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev)
1118 {
1119 	assert(ctl);
1120 	return ctl->ops->rawmidi_prefer_subdevice(ctl, subdev);
1121 }
1122 
1123 /**
1124  * \brief Set Power State to given SND_CTL_POWER_* value and do the power management
1125  * \param ctl CTL handle
1126  * \param state Desired Power State
1127  * \return 0 on success otherwise a negative error code
1128  */
snd_ctl_set_power_state(snd_ctl_t * ctl,unsigned int state)1129 int snd_ctl_set_power_state(snd_ctl_t *ctl, unsigned int state)
1130 {
1131 	assert(ctl);
1132 	if (ctl->ops->set_power_state)
1133 		return ctl->ops->set_power_state(ctl, state);
1134 	return -ENXIO;
1135 }
1136 
1137 /**
1138  * \brief Get actual Power State
1139  * \param ctl CTL handle
1140  * \param state Destination value
1141  * \return 0 on success otherwise a negative error code
1142  */
snd_ctl_get_power_state(snd_ctl_t * ctl,unsigned int * state)1143 int snd_ctl_get_power_state(snd_ctl_t *ctl, unsigned int *state)
1144 {
1145 	assert(ctl);
1146 	if (ctl->ops->get_power_state)
1147 		return ctl->ops->get_power_state(ctl, state);
1148 	return -ENXIO;
1149 }
1150 
1151 /**
1152  * \brief Read an event
1153  * \param ctl CTL handle
1154  * \param event Event pointer
1155  * \return number of events read otherwise a negative error code on failure
1156  */
snd_ctl_read(snd_ctl_t * ctl,snd_ctl_event_t * event)1157 int snd_ctl_read(snd_ctl_t *ctl, snd_ctl_event_t *event)
1158 {
1159 	assert(ctl && event);
1160 	return (ctl->ops->read)(ctl, event);
1161 }
1162 
1163 /**
1164  * \brief Wait for a CTL to become ready (i.e. at least one event pending)
1165  * \param ctl CTL handle
1166  * \param timeout maximum time in milliseconds to wait
1167  * \return 0 otherwise a negative error code on failure
1168  */
snd_ctl_wait(snd_ctl_t * ctl,int timeout)1169 int snd_ctl_wait(snd_ctl_t *ctl, int timeout)
1170 {
1171 	struct pollfd *pfd;
1172 	unsigned short revents;
1173 	int npfds, err, err_poll;
1174 
1175 	npfds = snd_ctl_poll_descriptors_count(ctl);
1176 	if (npfds <= 0 || npfds >= 16) {
1177 		SNDERR("Invalid poll_fds %d\n", npfds);
1178 		return -EIO;
1179 	}
1180 	pfd = alloca(sizeof(*pfd) * npfds);
1181 	err = snd_ctl_poll_descriptors(ctl, pfd, npfds);
1182 	if (err < 0)
1183 		return err;
1184 	if (err != npfds) {
1185 		SNDMSG("invalid poll descriptors %d\n", err);
1186 		return -EIO;
1187 	}
1188 	for (;;) {
1189 		err_poll = poll(pfd, npfds, timeout);
1190 		if (err_poll < 0)
1191 			return -errno;
1192 		if (! err_poll)
1193 			return 0;
1194 		err = snd_ctl_poll_descriptors_revents(ctl, pfd, npfds, &revents);
1195 		if (err < 0)
1196 			return err;
1197 		if (revents & (POLLERR | POLLNVAL))
1198 			return -EIO;
1199 		if (revents & (POLLIN | POLLOUT))
1200 			return 1;
1201 	}
1202 }
1203 
1204 /**
1205  * \brief Add an async handler for a CTL
1206  * \param handler Returned handler handle
1207  * \param ctl CTL handle
1208  * \param callback Callback function
1209  * \param private_data Callback private data
1210  * \return 0 otherwise a negative error code on failure
1211  */
snd_async_add_ctl_handler(snd_async_handler_t ** handler,snd_ctl_t * ctl,snd_async_callback_t callback,void * private_data)1212 int snd_async_add_ctl_handler(snd_async_handler_t **handler, snd_ctl_t *ctl,
1213 			      snd_async_callback_t callback, void *private_data)
1214 {
1215 	int err;
1216 	int was_empty;
1217 	snd_async_handler_t *h;
1218 	err = snd_async_add_handler(&h, _snd_ctl_async_descriptor(ctl),
1219 				    callback, private_data);
1220 	if (err < 0)
1221 		return err;
1222 	h->type = SND_ASYNC_HANDLER_CTL;
1223 	h->u.ctl = ctl;
1224 	was_empty = list_empty(&ctl->async_handlers);
1225 	list_add_tail(&h->hlist, &ctl->async_handlers);
1226 	if (was_empty) {
1227 		err = snd_ctl_async(ctl, snd_async_handler_get_signo(h), getpid());
1228 		if (err < 0) {
1229 			snd_async_del_handler(h);
1230 			return err;
1231 		}
1232 	}
1233 	*handler = h;
1234 	return 0;
1235 }
1236 
1237 /**
1238  * \brief Return CTL handle related to an async handler
1239  * \param handler Async handler handle
1240  * \return CTL handle
1241  */
snd_async_handler_get_ctl(snd_async_handler_t * handler)1242 snd_ctl_t *snd_async_handler_get_ctl(snd_async_handler_t *handler)
1243 {
1244 	assert(handler->type == SND_ASYNC_HANDLER_CTL);
1245 	return handler->u.ctl;
1246 }
1247 
1248 static const char *const build_in_ctls[] = {
1249 	"hw", "shm", NULL
1250 };
1251 
snd_ctl_open_conf(snd_ctl_t ** ctlp,const char * name,snd_config_t * ctl_root,snd_config_t * ctl_conf,int mode)1252 static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
1253 			     snd_config_t *ctl_root, snd_config_t *ctl_conf, int mode)
1254 {
1255 	const char *str;
1256 	char *buf = NULL, *buf1 = NULL;
1257 	int err;
1258 	snd_config_t *conf, *type_conf = NULL;
1259 	snd_config_iterator_t i, next;
1260 	const char *lib = NULL, *open_name = NULL;
1261 	const char *id;
1262 	int (*open_func)(snd_ctl_t **, const char *, snd_config_t *, snd_config_t *, int) = NULL;
1263 #ifndef PIC
1264 	extern void *snd_control_open_symbols(void);
1265 #endif
1266 	if (snd_config_get_type(ctl_conf) != SND_CONFIG_TYPE_COMPOUND) {
1267 		if (name)
1268 			SNDERR("Invalid type for CTL %s definition", name);
1269 		else
1270 			SNDERR("Invalid type for CTL definition");
1271 		return -EINVAL;
1272 	}
1273 	err = snd_config_search(ctl_conf, "type", &conf);
1274 	if (err < 0) {
1275 		SNDERR("type is not defined");
1276 		return err;
1277 	}
1278 	err = snd_config_get_id(conf, &id);
1279 	if (err < 0) {
1280 		SNDERR("unable to get id");
1281 		return err;
1282 	}
1283 	err = snd_config_get_string(conf, &str);
1284 	if (err < 0) {
1285 		SNDERR("Invalid type for %s", id);
1286 		return err;
1287 	}
1288 	err = snd_config_search_definition(ctl_root, "ctl_type", str, &type_conf);
1289 	if (err >= 0) {
1290 		if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
1291 			SNDERR("Invalid type for CTL type %s definition", str);
1292 			err = -EINVAL;
1293 			goto _err;
1294 		}
1295 		snd_config_for_each(i, next, type_conf) {
1296 			snd_config_t *n = snd_config_iterator_entry(i);
1297 			const char *id;
1298 			if (snd_config_get_id(n, &id) < 0)
1299 				continue;
1300 			if (strcmp(id, "comment") == 0)
1301 				continue;
1302 			if (strcmp(id, "lib") == 0) {
1303 				err = snd_config_get_string(n, &lib);
1304 				if (err < 0) {
1305 					SNDERR("Invalid type for %s", id);
1306 					goto _err;
1307 				}
1308 				continue;
1309 			}
1310 			if (strcmp(id, "open") == 0) {
1311 				err = snd_config_get_string(n, &open_name);
1312 				if (err < 0) {
1313 					SNDERR("Invalid type for %s", id);
1314 					goto _err;
1315 				}
1316 				continue;
1317 			}
1318 			SNDERR("Unknown field %s", id);
1319 			err = -EINVAL;
1320 			goto _err;
1321 		}
1322 	}
1323 	if (!open_name) {
1324 		buf = malloc(strlen(str) + 32);
1325 		if (buf == NULL) {
1326 			err = -ENOMEM;
1327 			goto _err;
1328 		}
1329 		open_name = buf;
1330 		sprintf(buf, "_snd_ctl_%s_open", str);
1331 	}
1332 	if (!lib) {
1333 		const char *const *build_in = build_in_ctls;
1334 		while (*build_in) {
1335 			if (!strcmp(*build_in, str))
1336 				break;
1337 			build_in++;
1338 		}
1339 		if (*build_in == NULL) {
1340 			buf1 = malloc(strlen(str) + sizeof(ALSA_PLUGIN_DIR) + 32);
1341 			if (buf1 == NULL) {
1342 				err = -ENOMEM;
1343 				goto _err;
1344 			}
1345 			lib = buf1;
1346 			sprintf(buf1, "%s/libasound_module_ctl_%s.so", ALSA_PLUGIN_DIR, str);
1347 		}
1348 	}
1349 #ifndef PIC
1350 	snd_control_open_symbols();
1351 #endif
1352 	open_func = snd_dlobj_cache_get(lib, open_name,
1353 			SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 1);
1354 	if (open_func) {
1355 		err = open_func(ctlp, name, ctl_root, ctl_conf, mode);
1356 		if (err >= 0) {
1357 			(*ctlp)->open_func = open_func;
1358 			err = 0;
1359 		} else {
1360 			snd_dlobj_cache_put(open_func);
1361 		}
1362 	} else {
1363 		err = -ENXIO;
1364 	}
1365        _err:
1366 	if (type_conf)
1367 		snd_config_delete(type_conf);
1368 	free(buf);
1369 	free(buf1);
1370 	return err;
1371 }
1372 
snd_ctl_open_noupdate(snd_ctl_t ** ctlp,snd_config_t * root,const char * name,int mode)1373 static int snd_ctl_open_noupdate(snd_ctl_t **ctlp, snd_config_t *root, const char *name, int mode)
1374 {
1375 	int err;
1376 	snd_config_t *ctl_conf;
1377 	err = snd_config_search_definition(root, "ctl", name, &ctl_conf);
1378 	if (err < 0) {
1379 		SNDERR("Invalid CTL %s", name);
1380 		return err;
1381 	}
1382 	err = snd_ctl_open_conf(ctlp, name, root, ctl_conf, mode);
1383 	snd_config_delete(ctl_conf);
1384 	return err;
1385 }
1386 
1387 /**
1388  * \brief Opens a CTL
1389  * \param ctlp Returned CTL handle
1390  * \param name ASCII identifier of the CTL handle
1391  * \param mode Open mode (see #SND_CTL_NONBLOCK, #SND_CTL_ASYNC)
1392  * \return 0 on success otherwise a negative error code
1393  */
snd_ctl_open(snd_ctl_t ** ctlp,const char * name,int mode)1394 int snd_ctl_open(snd_ctl_t **ctlp, const char *name, int mode)
1395 {
1396 	snd_config_t *top;
1397 	int err;
1398 
1399 	assert(ctlp && name);
1400 	err = snd_config_update_ref(&top);
1401 	if (err < 0)
1402 		return err;
1403 	err = snd_ctl_open_noupdate(ctlp, top, name, mode);
1404 	snd_config_unref(top);
1405 	return err;
1406 }
1407 
1408 /**
1409  * \brief Opens a CTL using local configuration
1410  * \param ctlp Returned CTL handle
1411  * \param name ASCII identifier of the CTL handle
1412  * \param mode Open mode (see #SND_CTL_NONBLOCK, #SND_CTL_ASYNC)
1413  * \param lconf Local configuration
1414  * \return 0 on success otherwise a negative error code
1415  */
snd_ctl_open_lconf(snd_ctl_t ** ctlp,const char * name,int mode,snd_config_t * lconf)1416 int snd_ctl_open_lconf(snd_ctl_t **ctlp, const char *name,
1417 		       int mode, snd_config_t *lconf)
1418 {
1419 	assert(ctlp && name && lconf);
1420 	return snd_ctl_open_noupdate(ctlp, lconf, name, mode);
1421 }
1422 
1423 /**
1424  * \brief Opens a fallback CTL
1425  * \param ctlp Returned CTL handle
1426  * \param root Configuration root
1427  * \param name ASCII identifier of the CTL handle used as fallback
1428  * \param orig_name The original ASCII name
1429  * \param mode Open mode (see #SND_CTL_NONBLOCK, #SND_CTL_ASYNC)
1430  * \return 0 on success otherwise a negative error code
1431  */
snd_ctl_open_fallback(snd_ctl_t ** ctlp,snd_config_t * root,const char * name,const char * orig_name,int mode)1432 int snd_ctl_open_fallback(snd_ctl_t **ctlp, snd_config_t *root,
1433 			  const char *name, const char *orig_name, int mode)
1434 {
1435 	int err;
1436 	assert(ctlp && name && root);
1437 	err = snd_ctl_open_noupdate(ctlp, root, name, mode);
1438 	if (err >= 0) {
1439 		free((*ctlp)->name);
1440 		(*ctlp)->name = orig_name ? strdup(orig_name) : NULL;
1441 	}
1442 	return err;
1443 }
1444 
1445 #ifndef DOC_HIDDEN
1446 #define TYPE(v) [SND_CTL_ELEM_TYPE_##v] = #v
1447 #define IFACE(v) [SND_CTL_ELEM_IFACE_##v] = #v
1448 #define IFACE1(v, n) [SND_CTL_ELEM_IFACE_##v] = #n
1449 #define EVENT(v) [SND_CTL_EVENT_##v] = #v
1450 
1451 static const char *const snd_ctl_elem_type_names[] = {
1452 	TYPE(NONE),
1453 	TYPE(BOOLEAN),
1454 	TYPE(INTEGER),
1455 	TYPE(ENUMERATED),
1456 	TYPE(BYTES),
1457 	TYPE(IEC958),
1458 	TYPE(INTEGER64),
1459 };
1460 
1461 static const char *const snd_ctl_elem_iface_names[] = {
1462 	IFACE(CARD),
1463 	IFACE(HWDEP),
1464 	IFACE(MIXER),
1465 	IFACE(PCM),
1466 	IFACE(RAWMIDI),
1467 	IFACE(TIMER),
1468 	IFACE(SEQUENCER),
1469 };
1470 
1471 static const char *const snd_ctl_event_type_names[] = {
1472 	EVENT(ELEM),
1473 };
1474 #endif
1475 
1476 /**
1477  * \brief get name of a CTL element type
1478  * \param type CTL element type
1479  * \return ascii name of CTL element type
1480  */
snd_ctl_elem_type_name(snd_ctl_elem_type_t type)1481 const char *snd_ctl_elem_type_name(snd_ctl_elem_type_t type)
1482 {
1483 	assert(type <= SND_CTL_ELEM_TYPE_LAST);
1484 	return snd_ctl_elem_type_names[type];
1485 }
1486 
1487 /**
1488  * \brief get name of a CTL element related interface
1489  * \param iface CTL element related interface
1490  * \return ascii name of CTL element related interface
1491  */
snd_ctl_elem_iface_name(snd_ctl_elem_iface_t iface)1492 const char *snd_ctl_elem_iface_name(snd_ctl_elem_iface_t iface)
1493 {
1494 	assert(iface <= SND_CTL_ELEM_IFACE_LAST);
1495 	return snd_ctl_elem_iface_names[iface];
1496 }
1497 
1498 /**
1499  * \brief get name of a CTL event type
1500  * \param type CTL event type
1501  * \return ascii name of CTL event type
1502  */
snd_ctl_event_type_name(snd_ctl_event_type_t type)1503 const char *snd_ctl_event_type_name(snd_ctl_event_type_t type)
1504 {
1505 	assert(type <= SND_CTL_EVENT_LAST);
1506 	return snd_ctl_event_type_names[type];
1507 }
1508 
1509 /**
1510  * \brief allocate space for CTL element identifiers list
1511  * \param obj CTL element identifiers list
1512  * \param entries Entries to allocate
1513  * \return 0 on success otherwise a negative error code
1514  */
snd_ctl_elem_list_alloc_space(snd_ctl_elem_list_t * obj,unsigned int entries)1515 int snd_ctl_elem_list_alloc_space(snd_ctl_elem_list_t *obj, unsigned int entries)
1516 {
1517 	free(obj->pids);
1518 	obj->pids = calloc(entries, sizeof(*obj->pids));
1519 	if (!obj->pids) {
1520 		obj->space = 0;
1521 		return -ENOMEM;
1522 	}
1523 	obj->space = entries;
1524 	return 0;
1525 }
1526 
1527 /**
1528  * \brief free previously allocated space for CTL element identifiers list
1529  * \param obj CTL element identifiers list
1530  */
snd_ctl_elem_list_free_space(snd_ctl_elem_list_t * obj)1531 void snd_ctl_elem_list_free_space(snd_ctl_elem_list_t *obj)
1532 {
1533 	free(obj->pids);
1534 	obj->pids = NULL;
1535 	obj->space = 0;
1536 }
1537 
1538 /**
1539  * \brief Get event mask for an element related event
1540  * \param obj CTL event
1541  * \return event mask for element related event
1542  */
snd_ctl_event_elem_get_mask(const snd_ctl_event_t * obj)1543 unsigned int snd_ctl_event_elem_get_mask(const snd_ctl_event_t *obj)
1544 {
1545 	assert(obj);
1546 	assert(obj->type == SND_CTL_EVENT_ELEM);
1547 	return obj->data.elem.mask;
1548 }
1549 
1550 /**
1551  * \brief Get CTL element identifier for an element related event
1552  * \param obj CTL event
1553  * \param ptr Pointer to returned CTL element identifier
1554  */
snd_ctl_event_elem_get_id(const snd_ctl_event_t * obj,snd_ctl_elem_id_t * ptr)1555 void snd_ctl_event_elem_get_id(const snd_ctl_event_t *obj, snd_ctl_elem_id_t *ptr)
1556 {
1557 	assert(obj && ptr);
1558 	assert(obj->type == SND_CTL_EVENT_ELEM);
1559 	*ptr = obj->data.elem.id;
1560 }
1561 
1562 /**
1563  * \brief Get element numeric identifier for an element related event
1564  * \param obj CTL event
1565  * \return element numeric identifier
1566  */
snd_ctl_event_elem_get_numid(const snd_ctl_event_t * obj)1567 unsigned int snd_ctl_event_elem_get_numid(const snd_ctl_event_t *obj)
1568 {
1569 	assert(obj);
1570 	assert(obj->type == SND_CTL_EVENT_ELEM);
1571 	return obj->data.elem.id.numid;
1572 }
1573 
1574 /**
1575  * \brief Get interface part of CTL element identifier for an element related event
1576  * \param obj CTL event
1577  * \return interface part of element identifier
1578  */
snd_ctl_event_elem_get_interface(const snd_ctl_event_t * obj)1579 snd_ctl_elem_iface_t snd_ctl_event_elem_get_interface(const snd_ctl_event_t *obj)
1580 {
1581 	assert(obj);
1582 	assert(obj->type == SND_CTL_EVENT_ELEM);
1583 	return obj->data.elem.id.iface;
1584 }
1585 
1586 /**
1587  * \brief Get device part of CTL element identifier for an element related event
1588  * \param obj CTL event
1589  * \return device part of element identifier
1590  */
snd_ctl_event_elem_get_device(const snd_ctl_event_t * obj)1591 unsigned int snd_ctl_event_elem_get_device(const snd_ctl_event_t *obj)
1592 {
1593 	assert(obj);
1594 	assert(obj->type == SND_CTL_EVENT_ELEM);
1595 	return obj->data.elem.id.device;
1596 }
1597 
1598 /**
1599  * \brief Get subdevice part of CTL element identifier for an element related event
1600  * \param obj CTL event
1601  * \return subdevice part of element identifier
1602  */
snd_ctl_event_elem_get_subdevice(const snd_ctl_event_t * obj)1603 unsigned int snd_ctl_event_elem_get_subdevice(const snd_ctl_event_t *obj)
1604 {
1605 	assert(obj);
1606 	assert(obj->type == SND_CTL_EVENT_ELEM);
1607 	return obj->data.elem.id.subdevice;
1608 }
1609 
1610 /**
1611  * \brief Get name part of CTL element identifier for an element related event
1612  * \param obj CTL event
1613  * \return name part of element identifier
1614  */
snd_ctl_event_elem_get_name(const snd_ctl_event_t * obj)1615 const char *snd_ctl_event_elem_get_name(const snd_ctl_event_t *obj)
1616 {
1617 	assert(obj);
1618 	assert(obj->type == SND_CTL_EVENT_ELEM);
1619 	return (const char *)obj->data.elem.id.name;
1620 }
1621 
1622 /**
1623  * \brief Get index part of CTL element identifier for an element related event
1624  * \param obj CTL event
1625  * \return index part of element identifier
1626  */
snd_ctl_event_elem_get_index(const snd_ctl_event_t * obj)1627 unsigned int snd_ctl_event_elem_get_index(const snd_ctl_event_t *obj)
1628 {
1629 	assert(obj);
1630 	assert(obj->type == SND_CTL_EVENT_ELEM);
1631 	return obj->data.elem.id.index;
1632 }
1633 
1634 #ifndef DOC_HIDDEN
_snd_ctl_poll_descriptor(snd_ctl_t * ctl)1635 int _snd_ctl_poll_descriptor(snd_ctl_t *ctl)
1636 {
1637 	assert(ctl);
1638 	return ctl->poll_fd;
1639 }
1640 #endif
1641 
1642 /**
1643  * \brief get size of #snd_ctl_elem_id_t
1644  * \return size in bytes
1645  */
snd_ctl_elem_id_sizeof()1646 size_t snd_ctl_elem_id_sizeof()
1647 {
1648 	return sizeof(snd_ctl_elem_id_t);
1649 }
1650 
1651 /**
1652  * \brief allocate an invalid #snd_ctl_elem_id_t using standard malloc
1653  * \param ptr returned pointer
1654  * \return 0 on success otherwise negative error code
1655  */
snd_ctl_elem_id_malloc(snd_ctl_elem_id_t ** ptr)1656 int snd_ctl_elem_id_malloc(snd_ctl_elem_id_t **ptr)
1657 {
1658 	assert(ptr);
1659 	*ptr = calloc(1, sizeof(snd_ctl_elem_id_t));
1660 	if (!*ptr)
1661 		return -ENOMEM;
1662 	return 0;
1663 }
1664 
1665 /**
1666  * \brief frees a previously allocated #snd_ctl_elem_id_t
1667  * \param obj pointer to object to free
1668  */
snd_ctl_elem_id_free(snd_ctl_elem_id_t * obj)1669 void snd_ctl_elem_id_free(snd_ctl_elem_id_t *obj)
1670 {
1671 	free(obj);
1672 }
1673 
1674 /**
1675  * \brief clear given #snd_ctl_elem_id_t object
1676  * \param obj pointer to object to clear
1677  */
snd_ctl_elem_id_clear(snd_ctl_elem_id_t * obj)1678 void snd_ctl_elem_id_clear(snd_ctl_elem_id_t *obj)
1679 {
1680 	memset(obj, 0, sizeof(snd_ctl_elem_id_t));
1681 }
1682 
1683 /**
1684  * \brief copy one #snd_ctl_elem_id_t to another
1685  * \param dst pointer to destination
1686  * \param src pointer to source
1687  */
snd_ctl_elem_id_copy(snd_ctl_elem_id_t * dst,const snd_ctl_elem_id_t * src)1688 void snd_ctl_elem_id_copy(snd_ctl_elem_id_t *dst, const snd_ctl_elem_id_t *src)
1689 {
1690 	assert(dst && src);
1691 	*dst = *src;
1692 }
1693 
1694 /**
1695  * \brief Get numeric identifier from a CTL element identifier
1696  * \param obj CTL element identifier
1697  * \return CTL element numeric identifier
1698  */
snd_ctl_elem_id_get_numid(const snd_ctl_elem_id_t * obj)1699 unsigned int snd_ctl_elem_id_get_numid(const snd_ctl_elem_id_t *obj)
1700 {
1701 	assert(obj);
1702 	return obj->numid;
1703 }
1704 
1705 /**
1706  * \brief Get interface part of a CTL element identifier
1707  * \param obj CTL element identifier
1708  * \return CTL element related interface
1709  */
snd_ctl_elem_id_get_interface(const snd_ctl_elem_id_t * obj)1710 snd_ctl_elem_iface_t snd_ctl_elem_id_get_interface(const snd_ctl_elem_id_t *obj)
1711 {
1712 	assert(obj);
1713 	return obj->iface;
1714 }
1715 
1716 /**
1717  * \brief Get device part of a CTL element identifier
1718  * \param obj CTL element identifier
1719  * \return CTL element related device
1720  */
snd_ctl_elem_id_get_device(const snd_ctl_elem_id_t * obj)1721 unsigned int snd_ctl_elem_id_get_device(const snd_ctl_elem_id_t *obj)
1722 {
1723 	assert(obj);
1724 	return obj->device;
1725 }
1726 
1727 /**
1728  * \brief Get subdevice part of a CTL element identifier
1729  * \param obj CTL element identifier
1730  * \return CTL element related subdevice
1731  */
snd_ctl_elem_id_get_subdevice(const snd_ctl_elem_id_t * obj)1732 unsigned int snd_ctl_elem_id_get_subdevice(const snd_ctl_elem_id_t *obj)
1733 {
1734 	assert(obj);
1735 	return obj->subdevice;
1736 }
1737 
1738 /**
1739  * \brief Get name part of a CTL element identifier
1740  * \param obj CTL element identifier
1741  * \return CTL element name
1742  */
snd_ctl_elem_id_get_name(const snd_ctl_elem_id_t * obj)1743 const char *snd_ctl_elem_id_get_name(const snd_ctl_elem_id_t *obj)
1744 {
1745 	assert(obj);
1746 	return (const char *)obj->name;
1747 }
1748 
1749 /**
1750  * \brief Get index part of a CTL element identifier
1751  * \param obj CTL element identifier
1752  * \return CTL element index
1753  */
snd_ctl_elem_id_get_index(const snd_ctl_elem_id_t * obj)1754 unsigned int snd_ctl_elem_id_get_index(const snd_ctl_elem_id_t *obj)
1755 {
1756 	assert(obj);
1757 	return obj->index;
1758 }
1759 
1760 /**
1761  * \brief Set numeric identifier for a CTL element identifier
1762  * \param obj CTL element identifier
1763  * \param val CTL element numeric identifier
1764  */
snd_ctl_elem_id_set_numid(snd_ctl_elem_id_t * obj,unsigned int val)1765 void snd_ctl_elem_id_set_numid(snd_ctl_elem_id_t *obj, unsigned int val)
1766 {
1767 	assert(obj);
1768 	obj->numid = val;
1769 }
1770 
1771 /**
1772  * \brief Set interface part for a CTL element identifier
1773  * \param obj CTL element identifier
1774  * \param val CTL element related interface
1775  */
snd_ctl_elem_id_set_interface(snd_ctl_elem_id_t * obj,snd_ctl_elem_iface_t val)1776 void snd_ctl_elem_id_set_interface(snd_ctl_elem_id_t *obj, snd_ctl_elem_iface_t val)
1777 {
1778 	assert(obj);
1779 	obj->iface = val;
1780 }
1781 
1782 /**
1783  * \brief Set device part for a CTL element identifier
1784  * \param obj CTL element identifier
1785  * \param val CTL element related device
1786  */
snd_ctl_elem_id_set_device(snd_ctl_elem_id_t * obj,unsigned int val)1787 void snd_ctl_elem_id_set_device(snd_ctl_elem_id_t *obj, unsigned int val)
1788 {
1789 	assert(obj);
1790 	obj->device = val;
1791 }
1792 
1793 /**
1794  * \brief Set subdevice part for a CTL element identifier
1795  * \param obj CTL element identifier
1796  * \param val CTL element related subdevice
1797  */
snd_ctl_elem_id_set_subdevice(snd_ctl_elem_id_t * obj,unsigned int val)1798 void snd_ctl_elem_id_set_subdevice(snd_ctl_elem_id_t *obj, unsigned int val)
1799 {
1800 	assert(obj);
1801 	obj->subdevice = val;
1802 }
1803 
1804 /**
1805  * \brief Set name part for a CTL element identifier
1806  * \param obj CTL element identifier
1807  * \param val CTL element name
1808  */
snd_ctl_elem_id_set_name(snd_ctl_elem_id_t * obj,const char * val)1809 void snd_ctl_elem_id_set_name(snd_ctl_elem_id_t *obj, const char *val)
1810 {
1811 	assert(obj);
1812 	snd_strlcpy((char *)obj->name, val, sizeof(obj->name));
1813 }
1814 
1815 /**
1816  * \brief Set index part for a CTL element identifier
1817  * \param obj CTL element identifier
1818  * \param val CTL element index
1819  */
snd_ctl_elem_id_set_index(snd_ctl_elem_id_t * obj,unsigned int val)1820 void snd_ctl_elem_id_set_index(snd_ctl_elem_id_t *obj, unsigned int val)
1821 {
1822 	assert(obj);
1823 	obj->index = val;
1824 }
1825 
1826 /**
1827  * \brief get size of #snd_ctl_card_info_t
1828  * \return size in bytes
1829  */
snd_ctl_card_info_sizeof()1830 size_t snd_ctl_card_info_sizeof()
1831 {
1832 	return sizeof(snd_ctl_card_info_t);
1833 }
1834 
1835 /**
1836  * \brief allocate an invalid #snd_ctl_card_info_t using standard malloc
1837  * \param ptr returned pointer
1838  * \return 0 on success otherwise negative error code
1839  */
snd_ctl_card_info_malloc(snd_ctl_card_info_t ** ptr)1840 int snd_ctl_card_info_malloc(snd_ctl_card_info_t **ptr)
1841 {
1842 	assert(ptr);
1843 	*ptr = calloc(1, sizeof(snd_ctl_card_info_t));
1844 	if (!*ptr)
1845 		return -ENOMEM;
1846 	return 0;
1847 }
1848 
1849 /**
1850  * \brief frees a previously allocated #snd_ctl_card_info_t
1851  * \param obj pointer to object to free
1852  */
snd_ctl_card_info_free(snd_ctl_card_info_t * obj)1853 void snd_ctl_card_info_free(snd_ctl_card_info_t *obj)
1854 {
1855 	free(obj);
1856 }
1857 
1858 /**
1859  * \brief clear given #snd_ctl_card_info_t object
1860  * \param obj pointer to object to clear
1861  */
snd_ctl_card_info_clear(snd_ctl_card_info_t * obj)1862 void snd_ctl_card_info_clear(snd_ctl_card_info_t *obj)
1863 {
1864 	memset(obj, 0, sizeof(snd_ctl_card_info_t));
1865 }
1866 
1867 /**
1868  * \brief copy one #snd_ctl_card_info_t to another
1869  * \param dst pointer to destination
1870  * \param src pointer to source
1871  */
snd_ctl_card_info_copy(snd_ctl_card_info_t * dst,const snd_ctl_card_info_t * src)1872 void snd_ctl_card_info_copy(snd_ctl_card_info_t *dst, const snd_ctl_card_info_t *src)
1873 {
1874 	assert(dst && src);
1875 	*dst = *src;
1876 }
1877 
1878 /**
1879  * \brief Get card number from a CTL card info
1880  * \param obj CTL card info
1881  * \return card number
1882  */
snd_ctl_card_info_get_card(const snd_ctl_card_info_t * obj)1883 int snd_ctl_card_info_get_card(const snd_ctl_card_info_t *obj)
1884 {
1885 	assert(obj);
1886 	return obj->card;
1887 }
1888 
1889 /**
1890  * \brief Get card identifier from a CTL card info
1891  * \param obj CTL card info
1892  * \return card identifier
1893  */
snd_ctl_card_info_get_id(const snd_ctl_card_info_t * obj)1894 const char *snd_ctl_card_info_get_id(const snd_ctl_card_info_t *obj)
1895 {
1896 	assert(obj);
1897 	return (const char *)obj->id;
1898 }
1899 
1900 /**
1901  * \brief Get card driver name from a CTL card info
1902  * \param obj CTL card info
1903  * \return card driver name
1904  */
snd_ctl_card_info_get_driver(const snd_ctl_card_info_t * obj)1905 const char *snd_ctl_card_info_get_driver(const snd_ctl_card_info_t *obj)
1906 {
1907 	assert(obj);
1908 	return (const char *)obj->driver;
1909 }
1910 
1911 /**
1912  * \brief Get card name from a CTL card info
1913  * \param obj CTL card info
1914  * \return card name
1915  */
snd_ctl_card_info_get_name(const snd_ctl_card_info_t * obj)1916 const char *snd_ctl_card_info_get_name(const snd_ctl_card_info_t *obj)
1917 {
1918 	assert(obj);
1919 	return (const char *)obj->name;
1920 }
1921 
1922 /**
1923  * \brief Get card long name from a CTL card info
1924  * \param obj CTL card info
1925  * \return card long name
1926  */
snd_ctl_card_info_get_longname(const snd_ctl_card_info_t * obj)1927 const char *snd_ctl_card_info_get_longname(const snd_ctl_card_info_t *obj)
1928 {
1929 	assert(obj);
1930 	return (const char *)obj->longname;
1931 }
1932 
1933 /**
1934  * \brief Get card mixer name from a CTL card info
1935  * \param obj CTL card info
1936  * \return card mixer name
1937  */
snd_ctl_card_info_get_mixername(const snd_ctl_card_info_t * obj)1938 const char *snd_ctl_card_info_get_mixername(const snd_ctl_card_info_t *obj)
1939 {
1940 	assert(obj);
1941 	return (const char *)obj->mixername;
1942 }
1943 
1944 /**
1945  * \brief Get card component list from a CTL card info
1946  * \param obj CTL card info
1947  * \return card mixer identifier
1948  */
snd_ctl_card_info_get_components(const snd_ctl_card_info_t * obj)1949 const char *snd_ctl_card_info_get_components(const snd_ctl_card_info_t *obj)
1950 {
1951 	assert(obj);
1952 	return (const char *)obj->components;
1953 }
1954 
1955 /**
1956  * \brief get size of #snd_ctl_event_t
1957  * \return size in bytes
1958  */
snd_ctl_event_sizeof()1959 size_t snd_ctl_event_sizeof()
1960 {
1961 	return sizeof(snd_ctl_event_t);
1962 }
1963 
1964 /**
1965  * \brief allocate an invalid #snd_ctl_event_t using standard malloc
1966  * \param ptr returned pointer
1967  * \return 0 on success otherwise negative error code
1968  */
snd_ctl_event_malloc(snd_ctl_event_t ** ptr)1969 int snd_ctl_event_malloc(snd_ctl_event_t **ptr)
1970 {
1971 	assert(ptr);
1972 	*ptr = calloc(1, sizeof(snd_ctl_event_t));
1973 	if (!*ptr)
1974 		return -ENOMEM;
1975 	return 0;
1976 }
1977 
1978 /**
1979  * \brief frees a previously allocated #snd_ctl_event_t
1980  * \param obj pointer to object to free
1981  */
snd_ctl_event_free(snd_ctl_event_t * obj)1982 void snd_ctl_event_free(snd_ctl_event_t *obj)
1983 {
1984 	free(obj);
1985 }
1986 
1987 /**
1988  * \brief clear given #snd_ctl_event_t object
1989  * \param obj pointer to object to clear
1990  */
snd_ctl_event_clear(snd_ctl_event_t * obj)1991 void snd_ctl_event_clear(snd_ctl_event_t *obj)
1992 {
1993 	memset(obj, 0, sizeof(snd_ctl_event_t));
1994 }
1995 
1996 /**
1997  * \brief copy one #snd_ctl_event_t to another
1998  * \param dst pointer to destination
1999  * \param src pointer to source
2000  */
snd_ctl_event_copy(snd_ctl_event_t * dst,const snd_ctl_event_t * src)2001 void snd_ctl_event_copy(snd_ctl_event_t *dst, const snd_ctl_event_t *src)
2002 {
2003 	assert(dst && src);
2004 	*dst = *src;
2005 }
2006 
2007 /**
2008  * \brief Get type of a CTL event
2009  * \param obj CTL event
2010  * \return CTL event type
2011  */
snd_ctl_event_get_type(const snd_ctl_event_t * obj)2012 snd_ctl_event_type_t snd_ctl_event_get_type(const snd_ctl_event_t *obj)
2013 {
2014 	assert(obj);
2015 	return obj->type;
2016 }
2017 
2018 /**
2019  * \brief get size of #snd_ctl_elem_list_t
2020  * \return size in bytes
2021  */
snd_ctl_elem_list_sizeof()2022 size_t snd_ctl_elem_list_sizeof()
2023 {
2024 	return sizeof(snd_ctl_elem_list_t);
2025 }
2026 
2027 /**
2028  * \brief allocate an invalid #snd_ctl_elem_list_t using standard malloc
2029  * \param ptr returned pointer
2030  * \return 0 on success otherwise negative error code
2031  */
snd_ctl_elem_list_malloc(snd_ctl_elem_list_t ** ptr)2032 int snd_ctl_elem_list_malloc(snd_ctl_elem_list_t **ptr)
2033 {
2034 	assert(ptr);
2035 	*ptr = calloc(1, sizeof(snd_ctl_elem_list_t));
2036 	if (!*ptr)
2037 		return -ENOMEM;
2038 	return 0;
2039 }
2040 
2041 /**
2042  * \brief frees a previously allocated #snd_ctl_elem_list_t
2043  * \param obj pointer to object to free
2044  */
snd_ctl_elem_list_free(snd_ctl_elem_list_t * obj)2045 void snd_ctl_elem_list_free(snd_ctl_elem_list_t *obj)
2046 {
2047 	free(obj);
2048 }
2049 
2050 /**
2051  * \brief clear given #snd_ctl_elem_list_t object
2052  * \param obj pointer to object to clear
2053  */
snd_ctl_elem_list_clear(snd_ctl_elem_list_t * obj)2054 void snd_ctl_elem_list_clear(snd_ctl_elem_list_t *obj)
2055 {
2056 	memset(obj, 0, sizeof(snd_ctl_elem_list_t));
2057 }
2058 
2059 /**
2060  * \brief copy one #snd_ctl_elem_list_t to another
2061  * \param dst pointer to destination
2062  * \param src pointer to source
2063  */
snd_ctl_elem_list_copy(snd_ctl_elem_list_t * dst,const snd_ctl_elem_list_t * src)2064 void snd_ctl_elem_list_copy(snd_ctl_elem_list_t *dst, const snd_ctl_elem_list_t *src)
2065 {
2066 	assert(dst && src);
2067 	*dst = *src;
2068 }
2069 
2070 /**
2071  * \brief Set index of first wanted CTL element identifier in a CTL element identifiers list
2072  * \param obj CTL element identifiers list
2073  * \param val index of CTL element to put at position 0 of list
2074  */
snd_ctl_elem_list_set_offset(snd_ctl_elem_list_t * obj,unsigned int val)2075 void snd_ctl_elem_list_set_offset(snd_ctl_elem_list_t *obj, unsigned int val)
2076 {
2077 	assert(obj);
2078 	obj->offset = val;
2079 }
2080 
2081 /**
2082  * \brief Get number of used entries in CTL element identifiers list
2083  * \param obj CTL element identifier list
2084  * \return number of used entries
2085  */
snd_ctl_elem_list_get_used(const snd_ctl_elem_list_t * obj)2086 unsigned int snd_ctl_elem_list_get_used(const snd_ctl_elem_list_t *obj)
2087 {
2088 	assert(obj);
2089 	return obj->used;
2090 }
2091 
2092 /**
2093  * \brief Get total count of elements present in CTL device (information present in every filled CTL element identifiers list)
2094  * \param obj CTL element identifier list
2095  * \return total number of elements
2096  */
snd_ctl_elem_list_get_count(const snd_ctl_elem_list_t * obj)2097 unsigned int snd_ctl_elem_list_get_count(const snd_ctl_elem_list_t *obj)
2098 {
2099 	assert(obj);
2100 	return obj->count;
2101 }
2102 
2103 /**
2104  * \brief Get CTL element identifier for an entry of a CTL element identifiers list
2105  * \param obj CTL element identifier list
2106  * \param idx Index of entry
2107  * \param ptr Pointer to returned CTL element identifier
2108  */
snd_ctl_elem_list_get_id(const snd_ctl_elem_list_t * obj,unsigned int idx,snd_ctl_elem_id_t * ptr)2109 void snd_ctl_elem_list_get_id(const snd_ctl_elem_list_t *obj, unsigned int idx, snd_ctl_elem_id_t *ptr)
2110 {
2111 	assert(obj && ptr);
2112 	assert(idx < obj->used);
2113 	*ptr = obj->pids[idx];
2114 }
2115 
2116 /**
2117  * \brief Get CTL element numeric identifier for an entry of a CTL element identifiers list
2118  * \param obj CTL element identifier list
2119  * \param idx Index of entry
2120  * \return CTL element numeric identifier
2121  */
snd_ctl_elem_list_get_numid(const snd_ctl_elem_list_t * obj,unsigned int idx)2122 unsigned int snd_ctl_elem_list_get_numid(const snd_ctl_elem_list_t *obj, unsigned int idx)
2123 {
2124 	assert(obj);
2125 	assert(idx < obj->used);
2126 	return obj->pids[idx].numid;
2127 }
2128 
2129 /**
2130  * \brief Get interface part of CTL element identifier for an entry of a CTL element identifiers list
2131  * \param obj CTL element identifier list
2132  * \param idx Index of entry
2133  * \return CTL element related interface
2134  */
snd_ctl_elem_list_get_interface(const snd_ctl_elem_list_t * obj,unsigned int idx)2135 snd_ctl_elem_iface_t snd_ctl_elem_list_get_interface(const snd_ctl_elem_list_t *obj, unsigned int idx)
2136 {
2137 	assert(obj);
2138 	assert(idx < obj->used);
2139 	return obj->pids[idx].iface;
2140 }
2141 
2142 /**
2143  * \brief Get device part of CTL element identifier for an entry of a CTL element identifiers list
2144  * \param obj CTL element identifier list
2145  * \param idx Index of entry
2146  * \return CTL element related device
2147  */
snd_ctl_elem_list_get_device(const snd_ctl_elem_list_t * obj,unsigned int idx)2148 unsigned int snd_ctl_elem_list_get_device(const snd_ctl_elem_list_t *obj, unsigned int idx)
2149 {
2150 	assert(obj);
2151 	assert(idx < obj->used);
2152 	return obj->pids[idx].device;
2153 }
2154 
2155 /**
2156  * \brief Get subdevice part of CTL element identifier for an entry of a CTL element identifiers list
2157  * \param obj CTL element identifier list
2158  * \param idx Index of entry
2159  * \return CTL element related subdevice
2160  */
snd_ctl_elem_list_get_subdevice(const snd_ctl_elem_list_t * obj,unsigned int idx)2161 unsigned int snd_ctl_elem_list_get_subdevice(const snd_ctl_elem_list_t *obj, unsigned int idx)
2162 {
2163 	assert(obj);
2164 	assert(idx < obj->used);
2165 	return obj->pids[idx].subdevice;
2166 }
2167 
2168 /**
2169  * \brief Get name part of CTL element identifier for an entry of a CTL element identifiers list
2170  * \param obj CTL element identifier list
2171  * \param idx Index of entry
2172  * \return CTL element name
2173  */
snd_ctl_elem_list_get_name(const snd_ctl_elem_list_t * obj,unsigned int idx)2174 const char *snd_ctl_elem_list_get_name(const snd_ctl_elem_list_t *obj, unsigned int idx)
2175 {
2176 	assert(obj);
2177 	assert(idx < obj->used);
2178 	return (const char *)obj->pids[idx].name;
2179 }
2180 
2181 /**
2182  * \brief Get index part of CTL element identifier for an entry of a CTL element identifiers list
2183  * \param obj CTL element identifier list
2184  * \param idx Index of entry
2185  * \return CTL element index
2186  */
snd_ctl_elem_list_get_index(const snd_ctl_elem_list_t * obj,unsigned int idx)2187 unsigned int snd_ctl_elem_list_get_index(const snd_ctl_elem_list_t *obj, unsigned int idx)
2188 {
2189 	assert(obj);
2190 	assert(idx < obj->used);
2191 	return obj->pids[idx].index;
2192 }
2193 
2194 /**
2195  * \brief get size of #snd_ctl_elem_info_t
2196  * \return size in bytes
2197  */
snd_ctl_elem_info_sizeof()2198 size_t snd_ctl_elem_info_sizeof()
2199 {
2200 	return sizeof(snd_ctl_elem_info_t);
2201 }
2202 
2203 /**
2204  * \brief allocate an invalid #snd_ctl_elem_info_t using standard malloc
2205  * \param ptr returned pointer
2206  * \return 0 on success otherwise negative error code
2207  */
snd_ctl_elem_info_malloc(snd_ctl_elem_info_t ** ptr)2208 int snd_ctl_elem_info_malloc(snd_ctl_elem_info_t **ptr)
2209 {
2210 	assert(ptr);
2211 	*ptr = calloc(1, sizeof(snd_ctl_elem_info_t));
2212 	if (!*ptr)
2213 		return -ENOMEM;
2214 	return 0;
2215 }
2216 
2217 /**
2218  * \brief frees a previously allocated #snd_ctl_elem_info_t
2219  * \param obj pointer to object to free
2220  */
snd_ctl_elem_info_free(snd_ctl_elem_info_t * obj)2221 void snd_ctl_elem_info_free(snd_ctl_elem_info_t *obj)
2222 {
2223 	free(obj);
2224 }
2225 
2226 /**
2227  * \brief clear given #snd_ctl_elem_info_t object
2228  * \param obj pointer to object to clear
2229  */
snd_ctl_elem_info_clear(snd_ctl_elem_info_t * obj)2230 void snd_ctl_elem_info_clear(snd_ctl_elem_info_t *obj)
2231 {
2232 	memset(obj, 0, sizeof(snd_ctl_elem_info_t));
2233 }
2234 
2235 /**
2236  * \brief copy one #snd_ctl_elem_info_t to another
2237  * \param dst pointer to destination
2238  * \param src pointer to source
2239  */
snd_ctl_elem_info_copy(snd_ctl_elem_info_t * dst,const snd_ctl_elem_info_t * src)2240 void snd_ctl_elem_info_copy(snd_ctl_elem_info_t *dst, const snd_ctl_elem_info_t *src)
2241 {
2242 	assert(dst && src);
2243 	*dst = *src;
2244 }
2245 
2246 /**
2247  * \brief Get type from a CTL element id/info
2248  * \param obj CTL element id/info
2249  * \return CTL element content type
2250  */
snd_ctl_elem_info_get_type(const snd_ctl_elem_info_t * obj)2251 snd_ctl_elem_type_t snd_ctl_elem_info_get_type(const snd_ctl_elem_info_t *obj)
2252 {
2253 	assert(obj);
2254 	return obj->type;
2255 }
2256 
2257 /**
2258  * \brief Get info about readability from a CTL element id/info
2259  * \param obj CTL element id/info
2260  * \return 0 if element is not readable, 1 if element is readable
2261  */
snd_ctl_elem_info_is_readable(const snd_ctl_elem_info_t * obj)2262 int snd_ctl_elem_info_is_readable(const snd_ctl_elem_info_t *obj)
2263 {
2264 	assert(obj);
2265 	return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_READ);
2266 }
2267 
2268 /**
2269  * \brief Get info about writability from a CTL element id/info
2270  * \param obj CTL element id/info
2271  * \return 0 if element is not writable, 1 if element is not writable
2272  */
snd_ctl_elem_info_is_writable(const snd_ctl_elem_info_t * obj)2273 int snd_ctl_elem_info_is_writable(const snd_ctl_elem_info_t *obj)
2274 {
2275 	assert(obj);
2276 	return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_WRITE);
2277 }
2278 
2279 /**
2280  * \brief Get info about notification feasibility from a CTL element id/info
2281  * \param obj CTL element id/info
2282  * \return 0 if all element value changes are notified to subscribed applications, 1 otherwise
2283  */
snd_ctl_elem_info_is_volatile(const snd_ctl_elem_info_t * obj)2284 int snd_ctl_elem_info_is_volatile(const snd_ctl_elem_info_t *obj)
2285 {
2286 	assert(obj);
2287 	return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_VOLATILE);
2288 }
2289 
2290 /**
2291  * \brief Get info about status from a CTL element id/info
2292  * \param obj CTL element id/info
2293  * \return 0 if element value is not active, 1 if is active
2294  */
snd_ctl_elem_info_is_inactive(const snd_ctl_elem_info_t * obj)2295 int snd_ctl_elem_info_is_inactive(const snd_ctl_elem_info_t *obj)
2296 {
2297 	assert(obj);
2298 	return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE);
2299 }
2300 
2301 /**
2302  * \brief Get info whether an element is locked
2303  * \param obj CTL element id/info
2304  * \return 0 if element value is currently changeable, 1 if it's locked by another application
2305  */
snd_ctl_elem_info_is_locked(const snd_ctl_elem_info_t * obj)2306 int snd_ctl_elem_info_is_locked(const snd_ctl_elem_info_t *obj)
2307 {
2308 	assert(obj);
2309 	return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_LOCK);
2310 }
2311 
2312 /**
2313  * \brief Get info if I own an element
2314  * \param obj CTL element id/info
2315  * \return 0 if element value is currently changeable, 1 if it's locked by another application
2316  */
snd_ctl_elem_info_is_owner(const snd_ctl_elem_info_t * obj)2317 int snd_ctl_elem_info_is_owner(const snd_ctl_elem_info_t *obj)
2318 {
2319 	assert(obj);
2320 	return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_OWNER);
2321 }
2322 
2323 /**
2324  * \brief Get info if it's a user element
2325  * \param obj CTL element id/info
2326  * \return 0 if element value is a system element, 1 if it's a user-created element
2327  */
snd_ctl_elem_info_is_user(const snd_ctl_elem_info_t * obj)2328 int snd_ctl_elem_info_is_user(const snd_ctl_elem_info_t *obj)
2329 {
2330 	assert(obj);
2331 	return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_USER);
2332 }
2333 
2334 /**
2335  * \brief Get info about TLV readability from a CTL element id/info
2336  * \param obj CTL element id/info
2337  * \return 0 if element's TLV is not readable, 1 if element's TLV is readable
2338  */
snd_ctl_elem_info_is_tlv_readable(const snd_ctl_elem_info_t * obj)2339 int snd_ctl_elem_info_is_tlv_readable(const snd_ctl_elem_info_t *obj)
2340 {
2341 	assert(obj);
2342 	return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ);
2343 }
2344 
2345 /**
2346  * \brief Get info about TLV writeability from a CTL element id/info
2347  * \param obj CTL element id/info
2348  * \return 0 if element's TLV is not writable, 1 if element's TLV is writable
2349  */
snd_ctl_elem_info_is_tlv_writable(const snd_ctl_elem_info_t * obj)2350 int snd_ctl_elem_info_is_tlv_writable(const snd_ctl_elem_info_t *obj)
2351 {
2352 	assert(obj);
2353 	return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE);
2354 }
2355 
2356 /**
2357  * \brief Get info about TLV command possibility from a CTL element id/info
2358  * \param obj CTL element id/info
2359  * \return 0 if element's TLV command is not possible, 1 if element's TLV command is supported
2360  */
snd_ctl_elem_info_is_tlv_commandable(const snd_ctl_elem_info_t * obj)2361 int snd_ctl_elem_info_is_tlv_commandable(const snd_ctl_elem_info_t *obj)
2362 {
2363 	assert(obj);
2364 	return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND);
2365 }
2366 
2367 /**
2368  * \brief (DEPRECATED) Get info about values passing policy from a CTL element value
2369  * \param obj CTL element id/info
2370  * \return 0 if element value need to be passed by contents, 1 if need to be passed with a pointer
2371  */
snd_ctl_elem_info_is_indirect(const snd_ctl_elem_info_t * obj)2372 int snd_ctl_elem_info_is_indirect(const snd_ctl_elem_info_t *obj)
2373 {
2374 	assert(obj);
2375 	return 0;
2376 }
2377 link_warning(snd_ctl_elem_info_is_indirect, "Warning: snd_ctl_elem_info_is_indirect is deprecated, do not use it");
2378 
2379 /**
2380  * \brief Get owner of a locked element
2381  * \param obj CTL element id/info
2382  * \return value entries count
2383  */
snd_ctl_elem_info_get_owner(const snd_ctl_elem_info_t * obj)2384 pid_t snd_ctl_elem_info_get_owner(const snd_ctl_elem_info_t *obj)
2385 {
2386 	assert(obj);
2387 	return obj->owner;
2388 }
2389 
2390 /**
2391  * \brief Get number of value entries from a CTL element id/info
2392  * \param obj CTL element id/info
2393  * \return value entries count
2394  */
snd_ctl_elem_info_get_count(const snd_ctl_elem_info_t * obj)2395 unsigned int snd_ctl_elem_info_get_count(const snd_ctl_elem_info_t *obj)
2396 {
2397 	assert(obj);
2398 	return obj->count;
2399 }
2400 
2401 /**
2402  * \brief Get minimum value from a #SND_CTL_ELEM_TYPE_INTEGER CTL element id/info
2403  * \param obj CTL element id/info
2404  * \return Minimum value
2405  */
snd_ctl_elem_info_get_min(const snd_ctl_elem_info_t * obj)2406 long snd_ctl_elem_info_get_min(const snd_ctl_elem_info_t *obj)
2407 {
2408 	assert(obj);
2409 	assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER);
2410 	return obj->value.integer.min;
2411 }
2412 
2413 /**
2414  * \brief Get maximum value from a #SND_CTL_ELEM_TYPE_INTEGER CTL element id/info
2415  * \param obj CTL element id/info
2416  * \return Maximum value
2417  */
snd_ctl_elem_info_get_max(const snd_ctl_elem_info_t * obj)2418 long snd_ctl_elem_info_get_max(const snd_ctl_elem_info_t *obj)
2419 {
2420 	assert(obj);
2421 	assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER);
2422 	return obj->value.integer.max;
2423 }
2424 
2425 /**
2426  * \brief Get value step from a #SND_CTL_ELEM_TYPE_INTEGER CTL element id/info
2427  * \param obj CTL element id/info
2428  * \return Step
2429  */
snd_ctl_elem_info_get_step(const snd_ctl_elem_info_t * obj)2430 long snd_ctl_elem_info_get_step(const snd_ctl_elem_info_t *obj)
2431 {
2432 	assert(obj);
2433 	assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER);
2434 	return obj->value.integer.step;
2435 }
2436 
2437 /**
2438  * \brief Get minimum value from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info
2439  * \param obj CTL element id/info
2440  * \return Minimum value
2441  */
snd_ctl_elem_info_get_min64(const snd_ctl_elem_info_t * obj)2442 long long snd_ctl_elem_info_get_min64(const snd_ctl_elem_info_t *obj)
2443 {
2444 	assert(obj);
2445 	assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64);
2446 	return obj->value.integer64.min;
2447 }
2448 
2449 /**
2450  * \brief Get maximum value from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info
2451  * \param obj CTL element id/info
2452  * \return Maximum value
2453  */
snd_ctl_elem_info_get_max64(const snd_ctl_elem_info_t * obj)2454 long long snd_ctl_elem_info_get_max64(const snd_ctl_elem_info_t *obj)
2455 {
2456 	assert(obj);
2457 	assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64);
2458 	return obj->value.integer64.max;
2459 }
2460 
2461 /**
2462  * \brief Get value step from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info
2463  * \param obj CTL element id/info
2464  * \return Step
2465  */
snd_ctl_elem_info_get_step64(const snd_ctl_elem_info_t * obj)2466 long long snd_ctl_elem_info_get_step64(const snd_ctl_elem_info_t *obj)
2467 {
2468 	assert(obj);
2469 	assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64);
2470 	return obj->value.integer64.step;
2471 }
2472 
2473 /**
2474  * \brief Get number of items available from a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/info
2475  * \param obj CTL element id/info
2476  * \return items count
2477  */
snd_ctl_elem_info_get_items(const snd_ctl_elem_info_t * obj)2478 unsigned int snd_ctl_elem_info_get_items(const snd_ctl_elem_info_t *obj)
2479 {
2480 	assert(obj);
2481 	assert(obj->type == SND_CTL_ELEM_TYPE_ENUMERATED);
2482 	return obj->value.enumerated.items;
2483 }
2484 
2485 /**
2486  * \brief Select item in a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/info
2487  * \param obj CTL element id/info
2488  * \param val item number
2489  */
snd_ctl_elem_info_set_item(snd_ctl_elem_info_t * obj,unsigned int val)2490 void snd_ctl_elem_info_set_item(snd_ctl_elem_info_t *obj, unsigned int val)
2491 {
2492 	assert(obj);
2493 	obj->value.enumerated.item = val;
2494 }
2495 
2496 /**
2497  * \brief Get name for selected item in a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/info
2498  * \param obj CTL element id/info
2499  * \return name of chosen item
2500  */
snd_ctl_elem_info_get_item_name(const snd_ctl_elem_info_t * obj)2501 const char *snd_ctl_elem_info_get_item_name(const snd_ctl_elem_info_t *obj)
2502 {
2503 	assert(obj);
2504 	assert(obj->type == SND_CTL_ELEM_TYPE_ENUMERATED);
2505 	return obj->value.enumerated.name;
2506 }
2507 
2508 /**
2509  * \brief Get count of dimensions for given element
2510  * \param obj CTL element id/info
2511  * \return zero value if no dimensions are defined, otherwise positive value with count of dimensions
2512  *
2513  * \deprecated	Since 1.1.5
2514  * #snd_ctl_elem_info_get_dimensions is deprecated without any replacement.
2515  */
2516 #ifndef DOXYGEN
INTERNAL(snd_ctl_elem_info_get_dimensions)2517 EXPORT_SYMBOL int INTERNAL(snd_ctl_elem_info_get_dimensions)(const snd_ctl_elem_info_t *obj ATTRIBUTE_UNUSED)
2518 #else
2519 int snd_ctl_elem_info_get_dimensions(const snd_ctl_elem_info_t *obj)
2520 #endif
2521 {
2522 #if 0 /* deprecated */
2523 	int i;
2524 
2525 	assert(obj);
2526 	for (i = 3; i >= 0; i--)
2527 		if (obj->dimen.d[i])
2528 			break;
2529 	return i + 1;
2530 #else
2531 	return -EINVAL;
2532 #endif
2533 }
2534 use_default_symbol_version(__snd_ctl_elem_info_get_dimensions, snd_ctl_elem_info_get_dimensions, ALSA_0.9.3);
2535 
2536 /**
2537  * \brief Get specified of dimension width for given element
2538  * \param obj CTL element id/info
2539  * \param idx The dimension index
2540  * \return zero value if no dimension width is defined, otherwise positive value with with of specified dimension
2541  *
2542  * \deprecated	Since 1.1.5
2543  * #snd_ctl_elem_info_get_dimension is deprecated without any replacement.
2544  */
2545 #ifndef DOXYGEN
INTERNAL(snd_ctl_elem_info_get_dimension)2546 EXPORT_SYMBOL int INTERNAL(snd_ctl_elem_info_get_dimension)(const snd_ctl_elem_info_t *obj ATTRIBUTE_UNUSED, unsigned int idx ATTRIBUTE_UNUSED)
2547 #else
2548 int snd_ctl_elem_info_get_dimension(const snd_ctl_elem_info_t *obj, unsigned int idx)
2549 #endif
2550 {
2551 #if 0 /* deprecated */
2552 	assert(obj);
2553 	if (idx > 3)
2554 		return 0;
2555 	return obj->dimen.d[idx];
2556 #else /* deprecated */
2557 	return -EINVAL;
2558 #endif /* deprecated */
2559 }
2560 use_default_symbol_version(__snd_ctl_elem_info_get_dimension, snd_ctl_elem_info_get_dimension, ALSA_0.9.3);
2561 
2562 /**
2563  * \brief Set width to a specified dimension level of given element information.
2564  * \param info Information of an element.
2565  * \param dimension Dimension width for each level by member unit.
2566  * \return Zero on success, otherwise a negative error code.
2567  *
2568  * \par Errors:
2569  * <dl>
2570  * <dt>-EINVAL
2571  * <dd>Invalid arguments are given as parameters.
2572  * </dl>
2573  *
2574  * \par Compatibility:
2575  * This function is added in version 1.1.2.
2576  *
2577  * \deprecated Since 1.1.5
2578  * #snd_ctl_elem_info_set_dimension is deprecated without any replacement.
2579  */
snd_ctl_elem_info_set_dimension(snd_ctl_elem_info_t * info ATTRIBUTE_UNUSED,const int dimension[4]ATTRIBUTE_UNUSED)2580 int snd_ctl_elem_info_set_dimension(snd_ctl_elem_info_t *info ATTRIBUTE_UNUSED,
2581 				    const int dimension[4] ATTRIBUTE_UNUSED)
2582 {
2583 #if 0 /* deprecated */
2584 	unsigned int i;
2585 
2586 	if (info == NULL)
2587 		return -EINVAL;
2588 
2589 	for (i = 0; i < ARRAY_SIZE(info->dimen.d); i++) {
2590 		if (dimension[i] < 0)
2591 			return -EINVAL;
2592 
2593 		info->dimen.d[i] = dimension[i];
2594 	}
2595 
2596 	return 0;
2597 #else /* deprecated */
2598 	return -EINVAL;
2599 #endif /* deprecated */
2600 }
2601 
2602 /**
2603  * \brief Get CTL element identifier of a CTL element id/info
2604  * \param obj CTL element id/info
2605  * \param ptr Pointer to returned CTL element identifier
2606  */
snd_ctl_elem_info_get_id(const snd_ctl_elem_info_t * obj,snd_ctl_elem_id_t * ptr)2607 void snd_ctl_elem_info_get_id(const snd_ctl_elem_info_t *obj, snd_ctl_elem_id_t *ptr)
2608 {
2609 	assert(obj && ptr);
2610 	*ptr = obj->id;
2611 }
2612 
2613 /**
2614  * \brief Get element numeric identifier of a CTL element id/info
2615  * \param obj CTL element id/info
2616  * \return element numeric identifier
2617  */
snd_ctl_elem_info_get_numid(const snd_ctl_elem_info_t * obj)2618 unsigned int snd_ctl_elem_info_get_numid(const snd_ctl_elem_info_t *obj)
2619 {
2620 	assert(obj);
2621 	return obj->id.numid;
2622 }
2623 
2624 /**
2625  * \brief Get interface part of CTL element identifier of a CTL element id/info
2626  * \param obj CTL element id/info
2627  * \return interface part of element identifier
2628  */
snd_ctl_elem_info_get_interface(const snd_ctl_elem_info_t * obj)2629 snd_ctl_elem_iface_t snd_ctl_elem_info_get_interface(const snd_ctl_elem_info_t *obj)
2630 {
2631 	assert(obj);
2632 	return obj->id.iface;
2633 }
2634 
2635 /**
2636  * \brief Get device part of CTL element identifier of a CTL element id/info
2637  * \param obj CTL element id/info
2638  * \return device part of element identifier
2639  */
snd_ctl_elem_info_get_device(const snd_ctl_elem_info_t * obj)2640 unsigned int snd_ctl_elem_info_get_device(const snd_ctl_elem_info_t *obj)
2641 {
2642 	assert(obj);
2643 	return obj->id.device;
2644 }
2645 
2646 /**
2647  * \brief Get subdevice part of CTL element identifier of a CTL element id/info
2648  * \param obj CTL element id/info
2649  * \return subdevice part of element identifier
2650  */
snd_ctl_elem_info_get_subdevice(const snd_ctl_elem_info_t * obj)2651 unsigned int snd_ctl_elem_info_get_subdevice(const snd_ctl_elem_info_t *obj)
2652 {
2653 	assert(obj);
2654 	return obj->id.subdevice;
2655 }
2656 
2657 /**
2658  * \brief Get name part of CTL element identifier of a CTL element id/info
2659  * \param obj CTL element id/info
2660  * \return name part of element identifier
2661  */
snd_ctl_elem_info_get_name(const snd_ctl_elem_info_t * obj)2662 const char *snd_ctl_elem_info_get_name(const snd_ctl_elem_info_t *obj)
2663 {
2664 	assert(obj);
2665 	return (const char *)obj->id.name;
2666 }
2667 
2668 /**
2669  * \brief Get index part of CTL element identifier of a CTL element id/info
2670  * \param obj CTL element id/info
2671  * \return index part of element identifier
2672  */
snd_ctl_elem_info_get_index(const snd_ctl_elem_info_t * obj)2673 unsigned int snd_ctl_elem_info_get_index(const snd_ctl_elem_info_t *obj)
2674 {
2675 	assert(obj);
2676 	return obj->id.index;
2677 }
2678 
2679 /**
2680  * \brief Set CTL element identifier of a CTL element id/info
2681  * \param obj CTL element id/info
2682  * \param ptr CTL element identifier
2683  */
snd_ctl_elem_info_set_id(snd_ctl_elem_info_t * obj,const snd_ctl_elem_id_t * ptr)2684 void snd_ctl_elem_info_set_id(snd_ctl_elem_info_t *obj, const snd_ctl_elem_id_t *ptr)
2685 {
2686 	assert(obj && ptr);
2687 	obj->id = *ptr;
2688 }
2689 
2690 /**
2691  * \brief Set element numeric identifier of a CTL element id/info
2692  * \param obj CTL element id/info
2693  * \param val element numeric identifier
2694  */
snd_ctl_elem_info_set_numid(snd_ctl_elem_info_t * obj,unsigned int val)2695 void snd_ctl_elem_info_set_numid(snd_ctl_elem_info_t *obj, unsigned int val)
2696 {
2697 	assert(obj);
2698 	obj->id.numid = val;
2699 }
2700 
2701 /**
2702  * \brief Set interface part of CTL element identifier of a CTL element id/info
2703  * \param obj CTL element id/info
2704  * \param val interface part of element identifier
2705  */
snd_ctl_elem_info_set_interface(snd_ctl_elem_info_t * obj,snd_ctl_elem_iface_t val)2706 void snd_ctl_elem_info_set_interface(snd_ctl_elem_info_t *obj, snd_ctl_elem_iface_t val)
2707 {
2708 	assert(obj);
2709 	obj->id.iface = val;
2710 }
2711 
2712 /**
2713  * \brief Set device part of CTL element identifier of a CTL element id/info
2714  * \param obj CTL element id/info
2715  * \param val device part of element identifier
2716  */
snd_ctl_elem_info_set_device(snd_ctl_elem_info_t * obj,unsigned int val)2717 void snd_ctl_elem_info_set_device(snd_ctl_elem_info_t *obj, unsigned int val)
2718 {
2719 	assert(obj);
2720 	obj->id.device = val;
2721 }
2722 
2723 /**
2724  * \brief Set subdevice part of CTL element identifier of a CTL element id/info
2725  * \param obj CTL element id/info
2726  * \param val subdevice part of element identifier
2727  */
snd_ctl_elem_info_set_subdevice(snd_ctl_elem_info_t * obj,unsigned int val)2728 void snd_ctl_elem_info_set_subdevice(snd_ctl_elem_info_t *obj, unsigned int val)
2729 {
2730 	assert(obj);
2731 	obj->id.subdevice = val;
2732 }
2733 
2734 /**
2735  * \brief Set name part of CTL element identifier of a CTL element id/info
2736  * \param obj CTL element id/info
2737  * \param val name part of element identifier
2738  */
snd_ctl_elem_info_set_name(snd_ctl_elem_info_t * obj,const char * val)2739 void snd_ctl_elem_info_set_name(snd_ctl_elem_info_t *obj, const char *val)
2740 {
2741 	assert(obj);
2742 	snd_strlcpy((char *)obj->id.name, val, sizeof(obj->id.name));
2743 }
2744 
2745 /**
2746  * \brief Set index part of CTL element identifier of a CTL element id/info
2747  * \param obj CTL element id/info
2748  * \param val index part of element identifier
2749  */
snd_ctl_elem_info_set_index(snd_ctl_elem_info_t * obj,unsigned int val)2750 void snd_ctl_elem_info_set_index(snd_ctl_elem_info_t *obj, unsigned int val)
2751 {
2752 	assert(obj);
2753 	obj->id.index = val;
2754 }
2755 
2756 /**
2757  * \brief Get size of data structure for an element.
2758  * \return Size in bytes.
2759  */
snd_ctl_elem_value_sizeof()2760 size_t snd_ctl_elem_value_sizeof()
2761 {
2762 	return sizeof(snd_ctl_elem_value_t);
2763 }
2764 
2765 /**
2766  * \brief Allocate an invalid #snd_ctl_elem_value_t using standard malloc(3).
2767  * \param ptr Returned pointer for data of an element.
2768  * \return 0 on success otherwise negative error code.
2769  */
snd_ctl_elem_value_malloc(snd_ctl_elem_value_t ** ptr)2770 int snd_ctl_elem_value_malloc(snd_ctl_elem_value_t **ptr)
2771 {
2772 	assert(ptr);
2773 	*ptr = calloc(1, sizeof(snd_ctl_elem_value_t));
2774 	if (!*ptr)
2775 		return -ENOMEM;
2776 	return 0;
2777 }
2778 
2779 /**
2780  * \brief Frees a previously allocated data of an element.
2781  * \param obj Data of an element.
2782  */
snd_ctl_elem_value_free(snd_ctl_elem_value_t * obj)2783 void snd_ctl_elem_value_free(snd_ctl_elem_value_t *obj)
2784 {
2785 	free(obj);
2786 }
2787 
2788 /**
2789  * \brief Clear given data of an element.
2790  * \param obj Data of an element.
2791  */
snd_ctl_elem_value_clear(snd_ctl_elem_value_t * obj)2792 void snd_ctl_elem_value_clear(snd_ctl_elem_value_t *obj)
2793 {
2794 	memset(obj, 0, sizeof(snd_ctl_elem_value_t));
2795 }
2796 
2797 /**
2798  * \brief Copy two data of elements.
2799  * \param dst Pointer to destination.
2800  * \param src Pointer to source.
2801  */
snd_ctl_elem_value_copy(snd_ctl_elem_value_t * dst,const snd_ctl_elem_value_t * src)2802 void snd_ctl_elem_value_copy(snd_ctl_elem_value_t *dst,
2803 			     const snd_ctl_elem_value_t *src)
2804 {
2805 	assert(dst && src);
2806 	*dst = *src;
2807 }
2808 
2809 /**
2810  * \brief Compare one data of an element to the other.
2811  * \param left Pointer to first data.
2812  * \param right Pointer to second data.
2813  * \return 0 on match, less than or greater than otherwise, see memcmp(3).
2814  */
snd_ctl_elem_value_compare(snd_ctl_elem_value_t * left,const snd_ctl_elem_value_t * right)2815 int snd_ctl_elem_value_compare(snd_ctl_elem_value_t *left,
2816 			       const snd_ctl_elem_value_t *right)
2817 {
2818 	assert(left && right);
2819 	return memcmp(left, right, sizeof(*left));
2820 }
2821 
2822 /**
2823  * \brief Get element identifier from given data of an element.
2824  * \param obj Data of an element.
2825  * \param ptr Pointer for element identifier.
2826  */
snd_ctl_elem_value_get_id(const snd_ctl_elem_value_t * obj,snd_ctl_elem_id_t * ptr)2827 void snd_ctl_elem_value_get_id(const snd_ctl_elem_value_t *obj, snd_ctl_elem_id_t *ptr)
2828 {
2829 	assert(obj && ptr);
2830 	*ptr = obj->id;
2831 }
2832 
2833 /**
2834  * \brief Get element numeric identifier from given data of an element.
2835  * \param obj Data of an element.
2836  * \return Element numeric identifier.
2837  */
snd_ctl_elem_value_get_numid(const snd_ctl_elem_value_t * obj)2838 unsigned int snd_ctl_elem_value_get_numid(const snd_ctl_elem_value_t *obj)
2839 {
2840 	assert(obj);
2841 	return obj->id.numid;
2842 }
2843 
2844 /**
2845  * \brief Get interface part of element identifier from given data of an
2846  *	  element.
2847  * \param obj Data of an element.
2848  * \return Interface part of element identifier.
2849  */
snd_ctl_elem_value_get_interface(const snd_ctl_elem_value_t * obj)2850 snd_ctl_elem_iface_t snd_ctl_elem_value_get_interface(const snd_ctl_elem_value_t *obj)
2851 {
2852 	assert(obj);
2853 	return obj->id.iface;
2854 }
2855 
2856 /**
2857  * \brief Get device part of element identifier from given data of an element.
2858  * \param obj Data of an element.
2859  * \return Device part of element identifier.
2860  */
snd_ctl_elem_value_get_device(const snd_ctl_elem_value_t * obj)2861 unsigned int snd_ctl_elem_value_get_device(const snd_ctl_elem_value_t *obj)
2862 {
2863 	assert(obj);
2864 	return obj->id.device;
2865 }
2866 
2867 /**
2868  * \brief Get subdevice part of element identifier from given data of an
2869  *	  element.
2870  * \param obj Data of an element.
2871  * \return Subdevice part of element identifier.
2872  */
snd_ctl_elem_value_get_subdevice(const snd_ctl_elem_value_t * obj)2873 unsigned int snd_ctl_elem_value_get_subdevice(const snd_ctl_elem_value_t *obj)
2874 {
2875 	assert(obj);
2876 	return obj->id.subdevice;
2877 }
2878 
2879 /**
2880  * \brief Get name part of element identifier from given data of an element.
2881  * \param obj Data of an element.
2882  * \return Name part of element identifier.
2883  */
snd_ctl_elem_value_get_name(const snd_ctl_elem_value_t * obj)2884 const char *snd_ctl_elem_value_get_name(const snd_ctl_elem_value_t *obj)
2885 {
2886 	assert(obj);
2887 	return (const char *)obj->id.name;
2888 }
2889 
2890 /**
2891  * \brief Get index part of element identifier from given data of an element.
2892  * \param obj Data of an element.
2893  * \return Index part of element identifier.
2894  */
snd_ctl_elem_value_get_index(const snd_ctl_elem_value_t * obj)2895 unsigned int snd_ctl_elem_value_get_index(const snd_ctl_elem_value_t *obj)
2896 {
2897 	assert(obj);
2898 	return obj->id.index;
2899 }
2900 
2901 /**
2902  * \brief Set element identifier to given data of an element.
2903  * \param obj Data of an element.
2904  * \param ptr Pointer to an element identifier.
2905  */
snd_ctl_elem_value_set_id(snd_ctl_elem_value_t * obj,const snd_ctl_elem_id_t * ptr)2906 void snd_ctl_elem_value_set_id(snd_ctl_elem_value_t *obj, const snd_ctl_elem_id_t *ptr)
2907 {
2908 	assert(obj && ptr);
2909 	obj->id = *ptr;
2910 }
2911 
2912 /**
2913  * \brief Set numeric identifier to given data of an element.
2914  * \param obj Data of an element.
2915  * \param val Value for numeric identifier.
2916  */
snd_ctl_elem_value_set_numid(snd_ctl_elem_value_t * obj,unsigned int val)2917 void snd_ctl_elem_value_set_numid(snd_ctl_elem_value_t *obj, unsigned int val)
2918 {
2919 	assert(obj);
2920 	obj->id.numid = val;
2921 }
2922 
2923 /**
2924  * \brief Set interface part of element identifier to given data of an element.
2925  * \param obj Data of an element.
2926  * \param val Value for interface part of element identifier.
2927  */
snd_ctl_elem_value_set_interface(snd_ctl_elem_value_t * obj,snd_ctl_elem_iface_t val)2928 void snd_ctl_elem_value_set_interface(snd_ctl_elem_value_t *obj, snd_ctl_elem_iface_t val)
2929 {
2930 	assert(obj);
2931 	obj->id.iface = val;
2932 }
2933 
2934 /**
2935  * \brief Set device part of element identifier to given data of an element.
2936  * \param obj Data of an element.
2937  * \param val Value for device part of element identifier.
2938  */
snd_ctl_elem_value_set_device(snd_ctl_elem_value_t * obj,unsigned int val)2939 void snd_ctl_elem_value_set_device(snd_ctl_elem_value_t *obj, unsigned int val)
2940 {
2941 	assert(obj);
2942 	obj->id.device = val;
2943 }
2944 
2945 /**
2946  * \brief Set subdevice part of element identifier to given data of an element.
2947  * \param obj Data of an element.
2948  * \param val Value for subdevice part of element identifier.
2949  */
snd_ctl_elem_value_set_subdevice(snd_ctl_elem_value_t * obj,unsigned int val)2950 void snd_ctl_elem_value_set_subdevice(snd_ctl_elem_value_t *obj, unsigned int val)
2951 {
2952 	assert(obj);
2953 	obj->id.subdevice = val;
2954 }
2955 
2956 /**
2957  * \brief Set name part of element identifier to given data of an element.
2958  * \param obj Data of an element.
2959  * \param val Value for name part of element identifier,
2960  */
snd_ctl_elem_value_set_name(snd_ctl_elem_value_t * obj,const char * val)2961 void snd_ctl_elem_value_set_name(snd_ctl_elem_value_t *obj, const char *val)
2962 {
2963 	assert(obj);
2964 	snd_strlcpy((char *)obj->id.name, val, sizeof(obj->id.name));
2965 }
2966 
2967 /**
2968  * \brief Set index part of element identifier to given data of an element.
2969  * \param obj Data of an element.
2970  * \param val Value for index part of element identifier.
2971  */
snd_ctl_elem_value_set_index(snd_ctl_elem_value_t * obj,unsigned int val)2972 void snd_ctl_elem_value_set_index(snd_ctl_elem_value_t *obj, unsigned int val)
2973 {
2974 	assert(obj);
2975 	obj->id.index = val;
2976 }
2977 
2978 /**
2979  * \brief Get value of a specified member from given data as an element of
2980  *	  boolean type.
2981  * \param obj Data of an element.
2982  * \param idx Index of member in the element.
2983  * \return Value for the member.
2984  */
snd_ctl_elem_value_get_boolean(const snd_ctl_elem_value_t * obj,unsigned int idx)2985 int snd_ctl_elem_value_get_boolean(const snd_ctl_elem_value_t *obj, unsigned int idx)
2986 {
2987 	assert(obj);
2988 	assert(idx < ARRAY_SIZE(obj->value.integer.value));
2989 	return obj->value.integer.value[idx];
2990 }
2991 
2992 /**
2993  * \brief Get value of a specified member from given data as an element of
2994  *	  integer type.
2995  * \param obj Data of an element.
2996  * \param idx Index of member in the element.
2997  * \return Value for the member.
2998  */
snd_ctl_elem_value_get_integer(const snd_ctl_elem_value_t * obj,unsigned int idx)2999 long snd_ctl_elem_value_get_integer(const snd_ctl_elem_value_t *obj, unsigned int idx)
3000 {
3001 	assert(obj);
3002 	assert(idx < ARRAY_SIZE(obj->value.integer.value));
3003 	return obj->value.integer.value[idx];
3004 }
3005 
3006 /**
3007  * \brief Get value of a specified member from given data as an element of
3008  *	  integer64 type.
3009  * \param obj Data of an element.
3010  * \param idx Index of member in the element.
3011  * \return Value for the member.
3012  */
snd_ctl_elem_value_get_integer64(const snd_ctl_elem_value_t * obj,unsigned int idx)3013 long long snd_ctl_elem_value_get_integer64(const snd_ctl_elem_value_t *obj, unsigned int idx)
3014 {
3015 	assert(obj);
3016 	assert(idx < ARRAY_SIZE(obj->value.integer64.value));
3017 	return obj->value.integer64.value[idx];
3018 }
3019 
3020 /**
3021  * \brief Get value of a specified member from given data as an element of
3022  *	  enumerated type.
3023  * \param obj Data of an element.
3024  * \param idx Index of member in the element.
3025  * \return Value for the member. This is an index of name set in the element.
3026  */
snd_ctl_elem_value_get_enumerated(const snd_ctl_elem_value_t * obj,unsigned int idx)3027 unsigned int snd_ctl_elem_value_get_enumerated(const snd_ctl_elem_value_t *obj, unsigned int idx)
3028 {
3029 	assert(obj);
3030 	assert(idx < ARRAY_SIZE(obj->value.enumerated.item));
3031 	return obj->value.enumerated.item[idx];
3032 }
3033 
3034 /**
3035  * \brief Get value of a specified member from given data as an element of
3036  *	  bytes type.
3037  * \param obj Data of an element.
3038  * \param idx Index of member in the element.
3039  * \return Value for the member.
3040  */
snd_ctl_elem_value_get_byte(const snd_ctl_elem_value_t * obj,unsigned int idx)3041 unsigned char snd_ctl_elem_value_get_byte(const snd_ctl_elem_value_t *obj, unsigned int idx)
3042 {
3043 	assert(obj);
3044 	assert(idx < ARRAY_SIZE(obj->value.bytes.data));
3045 	return obj->value.bytes.data[idx];
3046 }
3047 
3048 /**
3049  * \brief Set value of a specified member to given data as an element of
3050  *	  boolean type.
3051  * \param obj Data of an element.
3052  * \param idx Index of member in the element.
3053  * \param val Value for the member.
3054  */
snd_ctl_elem_value_set_boolean(snd_ctl_elem_value_t * obj,unsigned int idx,long val)3055 void snd_ctl_elem_value_set_boolean(snd_ctl_elem_value_t *obj, unsigned int idx, long val)
3056 {
3057 	assert(obj);
3058 	assert(idx < ARRAY_SIZE(obj->value.integer.value));
3059 	obj->value.integer.value[idx] = val;
3060 }
3061 
3062 /**
3063  * \brief Set value of a specified member to given data as an element of
3064  *	  integer type.
3065  * \param obj Data of an element.
3066  * \param idx Index of member in the element.
3067  * \param val Value for the member.
3068  */
snd_ctl_elem_value_set_integer(snd_ctl_elem_value_t * obj,unsigned int idx,long val)3069 void snd_ctl_elem_value_set_integer(snd_ctl_elem_value_t *obj, unsigned int idx, long val)
3070 {
3071 	assert(obj);
3072 	assert(idx < ARRAY_SIZE(obj->value.integer.value));
3073 	obj->value.integer.value[idx] = val;
3074 }
3075 
3076 /**
3077  * \brief Set value of a specified member to given data as an element of
3078  *	  integer64 type.
3079  * \param obj Data of an element.
3080  * \param idx Index of member in the element.
3081  * \param val Value for the member.
3082  */
snd_ctl_elem_value_set_integer64(snd_ctl_elem_value_t * obj,unsigned int idx,long long val)3083 void snd_ctl_elem_value_set_integer64(snd_ctl_elem_value_t *obj, unsigned int idx, long long val)
3084 {
3085 	assert(obj);
3086 	assert(idx < ARRAY_SIZE(obj->value.integer64.value));
3087 	obj->value.integer64.value[idx] = val;
3088 }
3089 
3090 /**
3091  * \brief Set value of a specified member to given data as an element of
3092  * 	  enumerated type.
3093  * \param obj Data of an element.
3094  * \param idx Index of member in the element.
3095  * \param val Value for the member.
3096  */
snd_ctl_elem_value_set_enumerated(snd_ctl_elem_value_t * obj,unsigned int idx,unsigned int val)3097 void snd_ctl_elem_value_set_enumerated(snd_ctl_elem_value_t *obj, unsigned int idx, unsigned int val)
3098 {
3099 	assert(obj);
3100 	assert(idx < ARRAY_SIZE(obj->value.enumerated.item));
3101 	obj->value.enumerated.item[idx] = val;
3102 }
3103 
3104 /**
3105  * \brief Set value for a specified member to given data as an element of byte
3106  *	  type.
3107  * \param obj Data of an element.
3108  * \param idx Index of member in the element.
3109  * \param val Value for the member.
3110  */
snd_ctl_elem_value_set_byte(snd_ctl_elem_value_t * obj,unsigned int idx,unsigned char val)3111 void snd_ctl_elem_value_set_byte(snd_ctl_elem_value_t *obj, unsigned int idx, unsigned char val)
3112 {
3113 	assert(obj);
3114 	assert(idx < ARRAY_SIZE(obj->value.bytes.data));
3115 	obj->value.bytes.data[idx] = val;
3116 }
3117 
3118 /**
3119  * \brief Set values to given data as an element of bytes type.
3120  * \param obj Data of an element.
3121  * \param data Pointer for byte array.
3122  * \param size The number of bytes included in the memory block.
3123  */
snd_ctl_elem_set_bytes(snd_ctl_elem_value_t * obj,void * data,size_t size)3124 void snd_ctl_elem_set_bytes(snd_ctl_elem_value_t *obj, void *data, size_t size)
3125 {
3126 	assert(obj);
3127 	assert(size <= ARRAY_SIZE(obj->value.bytes.data));
3128 	memcpy(obj->value.bytes.data, data, size);
3129 }
3130 
3131 /**
3132  * \brief Get memory block from given data as an element of bytes type.
3133  * \param obj Data of an element.
3134  * \return Pointer for byte array.
3135  */
snd_ctl_elem_value_get_bytes(const snd_ctl_elem_value_t * obj)3136 const void * snd_ctl_elem_value_get_bytes(const snd_ctl_elem_value_t *obj)
3137 {
3138 	assert(obj);
3139 	return obj->value.bytes.data;
3140 }
3141 
3142 /**
3143  * \brief Get value from given data to given pointer as an element of IEC958
3144  *	  type.
3145  * \param obj Data of an element.
3146  * \param ptr Pointer to IEC958 data.
3147  */
snd_ctl_elem_value_get_iec958(const snd_ctl_elem_value_t * obj,snd_aes_iec958_t * ptr)3148 void snd_ctl_elem_value_get_iec958(const snd_ctl_elem_value_t *obj, snd_aes_iec958_t *ptr)
3149 {
3150 	assert(obj && ptr);
3151 	memcpy(ptr, &obj->value.iec958, sizeof(*ptr));
3152 }
3153 
3154 /**
3155  * \brief Set value from given pointer to given data as an element of IEC958
3156  *	  type.
3157  * \param obj Data of an element.
3158  * \param ptr Pointer to IEC958 data.
3159  */
snd_ctl_elem_value_set_iec958(snd_ctl_elem_value_t * obj,const snd_aes_iec958_t * ptr)3160 void snd_ctl_elem_value_set_iec958(snd_ctl_elem_value_t *obj, const snd_aes_iec958_t *ptr)
3161 {
3162 	assert(obj && ptr);
3163 	memcpy(&obj->value.iec958, ptr, sizeof(obj->value.iec958));
3164 }
3165 
3166