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