• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * \file timer/timer.c
3  * \brief Timer Interface
4  * \author Jaroslav Kysela <perex@perex.cz>
5  * \date 1998-2001
6  *
7  * Timer Interface is designed to access timers.
8  * See \ref timer page for more details.
9  */
10 /*
11  *  Timer Interface - main file
12  *  Copyright (c) 1998-2001 by Jaroslav Kysela <perex@perex.cz>
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 timer Timer interface
32 
33 <P> Timer interface is designed to use internal timers in sound hardware, but
34 it can be driven with any timer.
35 
36 \section timer_general_overview General overview
37 
38 The timer implementation uses ring buffer to store information about timing
39 events. In this buffer is recorded count of ticks and current tick resolution
40 in nanoseconds.
41 
42 \section timer_open Opening
43 
44 Timer devices can be opened in two ways. When #SND_TIMER_OPEN_NONBLOCK flag
45 is used, then the open functions return immediately with -EBUSY error code when
46 resources are occupied with another application. When #SND_TIMER_OPEN_NONBLOCK
47 is not used (by default) the open functions block the application requesting
48 device until resources are not free.
49 
50 \section timer_events Events
51 
52 Events are read via snd_timer_read() function.
53 
54 \section timer_examples Examples
55 
56 The full featured examples with cross-links:
57 
58 \par Simple timer test program
59 \ref example_test_timer "example code"
60 \par
61 This example shows opening a timer device and reading of timer events.
62 
63 */
64 
65 /**
66  * \example ../test/timer.c
67  * \anchor example_test_timer
68  */
69 
70 #include "timer_local.h"
71 
72 #include <signal.h>
73 
snd_timer_open_conf(snd_timer_t ** timer,const char * name,snd_config_t * timer_root,snd_config_t * timer_conf,int mode)74 static int snd_timer_open_conf(snd_timer_t **timer,
75 			       const char *name, snd_config_t *timer_root,
76 			       snd_config_t *timer_conf, int mode)
77 {
78 	const char *str;
79 	char buf[256], errbuf[256];
80 	int err;
81 	snd_config_t *conf, *type_conf = NULL;
82 	snd_config_iterator_t i, next;
83 	const char *id;
84 	const char *lib = NULL, *open_name = NULL;
85 	int (*open_func)(snd_timer_t **, const char *, snd_config_t *, snd_config_t *, int) = NULL;
86 #ifndef PIC
87 	extern void *snd_timer_open_symbols(void);
88 #endif
89 	void *h = NULL;
90 	if (snd_config_get_type(timer_conf) != SND_CONFIG_TYPE_COMPOUND) {
91 		if (name)
92 			SNDERR("Invalid type for TIMER %s definition", name);
93 		else
94 			SNDERR("Invalid type for TIMER definition");
95 		return -EINVAL;
96 	}
97 	err = snd_config_search(timer_conf, "type", &conf);
98 	if (err < 0) {
99 		SNDERR("type is not defined");
100 		return err;
101 	}
102 	err = snd_config_get_id(conf, &id);
103 	if (err < 0) {
104 		SNDERR("unable to get id");
105 		return err;
106 	}
107 	err = snd_config_get_string(conf, &str);
108 	if (err < 0) {
109 		SNDERR("Invalid type for %s", id);
110 		return err;
111 	}
112 	err = snd_config_search_definition(timer_root, "timer_type", str, &type_conf);
113 	if (err >= 0) {
114 		if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
115 			SNDERR("Invalid type for TIMER type %s definition", str);
116 			goto _err;
117 		}
118 		snd_config_for_each(i, next, type_conf) {
119 			snd_config_t *n = snd_config_iterator_entry(i);
120 			const char *id;
121 			if (snd_config_get_id(n, &id) < 0)
122 				continue;
123 			if (strcmp(id, "comment") == 0)
124 				continue;
125 			if (strcmp(id, "lib") == 0) {
126 				err = snd_config_get_string(n, &lib);
127 				if (err < 0) {
128 					SNDERR("Invalid type for %s", id);
129 					goto _err;
130 				}
131 				continue;
132 			}
133 			if (strcmp(id, "open") == 0) {
134 				err = snd_config_get_string(n, &open_name);
135 				if (err < 0) {
136 					SNDERR("Invalid type for %s", id);
137 					goto _err;
138 				}
139 				continue;
140 			}
141 			SNDERR("Unknown field %s", id);
142 			err = -EINVAL;
143 			goto _err;
144 		}
145 	}
146 	if (!open_name) {
147 		open_name = buf;
148 		snprintf(buf, sizeof(buf), "_snd_timer_%s_open", str);
149 	}
150 #ifndef PIC
151 	snd_timer_open_symbols();
152 #endif
153 	h = INTERNAL(snd_dlopen)(lib, RTLD_NOW, errbuf, sizeof(errbuf));
154 	if (h)
155 		open_func = snd_dlsym(h, open_name, SND_DLSYM_VERSION(SND_TIMER_DLSYM_VERSION));
156 	err = 0;
157 	if (!h) {
158 		SNDERR("Cannot open shared library %s (%s)", lib, errbuf);
159 		err = -ENOENT;
160 	} else if (!open_func) {
161 		SNDERR("symbol %s is not defined inside %s", open_name, lib);
162 		snd_dlclose(h);
163 		err = -ENXIO;
164 	}
165        _err:
166 	if (type_conf)
167 		snd_config_delete(type_conf);
168 	if (! err) {
169 		err = open_func(timer, name, timer_root, timer_conf, mode);
170 		if (err < 0)
171 			snd_dlclose(h);
172 		else
173 			(*timer)->dl_handle = h;
174 	}
175 	return err;
176 }
177 
snd_timer_open_noupdate(snd_timer_t ** timer,snd_config_t * root,const char * name,int mode)178 static int snd_timer_open_noupdate(snd_timer_t **timer, snd_config_t *root, const char *name, int mode)
179 {
180 	int err;
181 	snd_config_t *timer_conf;
182 	err = snd_config_search_definition(root, "timer", name, &timer_conf);
183 	if (err < 0) {
184 		SNDERR("Unknown timer %s", name);
185 		return err;
186 	}
187 	err = snd_timer_open_conf(timer, name, root, timer_conf, mode);
188 	snd_config_delete(timer_conf);
189 	return err;
190 }
191 
192 /**
193  * \brief Opens a new connection to the timer interface.
194  * \param timer Returned handle (NULL if not wanted)
195  * \param name ASCII identifier of the timer handle
196  * \param mode Open mode
197  * \return 0 on success otherwise a negative error code
198  *
199  * Opens a new connection to the timer interface specified with
200  * an ASCII identifier and mode.
201  */
snd_timer_open(snd_timer_t ** timer,const char * name,int mode)202 int snd_timer_open(snd_timer_t **timer, const char *name, int mode)
203 {
204 	snd_config_t *top;
205 	int err;
206 
207 	assert(timer && name);
208 	if (_snd_is_ucm_device(name)) {
209 		name = uc_mgr_alibcfg_by_device(&top, name);
210 		if (name == NULL)
211 			return -ENODEV;
212 	} else {
213 		err = snd_config_update_ref(&top);
214 		if (err < 0)
215 			return err;
216 	}
217 	err = snd_timer_open_noupdate(timer, top, name, mode);
218 	snd_config_unref(top);
219 	return err;
220 }
221 
222 /**
223  * \brief Opens a new connection to the timer interface using local configuration
224  * \param timer Returned handle (NULL if not wanted)
225  * \param name ASCII identifier of the timer handle
226  * \param mode Open mode
227  * \param lconf Local configuration
228  * \return 0 on success otherwise a negative error code
229  *
230  * Opens a new connection to the timer interface specified with
231  * an ASCII identifier and mode.
232  */
snd_timer_open_lconf(snd_timer_t ** timer,const char * name,int mode,snd_config_t * lconf)233 int snd_timer_open_lconf(snd_timer_t **timer, const char *name,
234 			 int mode, snd_config_t *lconf)
235 {
236 	assert(timer && name && lconf);
237 	return snd_timer_open_noupdate(timer, lconf, name, mode);
238 }
239 
240 /**
241  * \brief close timer handle
242  * \param timer timer handle
243  * \return 0 on success otherwise a negative error code
244  *
245  * Closes the specified timer handle and frees all associated
246  * resources.
247  */
snd_timer_close(snd_timer_t * timer)248 int snd_timer_close(snd_timer_t *timer)
249 {
250 	int err;
251   	assert(timer);
252 	while (!list_empty(&timer->async_handlers)) {
253 		snd_async_handler_t *h = list_entry(timer->async_handlers.next, snd_async_handler_t, hlist);
254 		snd_async_del_handler(h);
255 	}
256 	err = timer->ops->close(timer);
257 	if (timer->dl_handle)
258 		snd_dlclose(timer->dl_handle);
259 	free(timer->name);
260 	free(timer);
261 	return err;
262 }
263 
264 /**
265  * \brief get identifier of timer handle
266  * \param timer a timer handle
267  * \return ascii identifier of timer handle
268  *
269  * Returns the ASCII identifier of given timer handle. It's the same
270  * identifier specified in snd_timer_open().
271  */
snd_timer_name(snd_timer_t * timer)272 const char *snd_timer_name(snd_timer_t *timer)
273 {
274 	assert(timer);
275 	return timer->name;
276 }
277 
278 /**
279  * \brief get type of timer handle
280  * \param timer a timer handle
281  * \return type of timer handle
282  *
283  * Returns the type #snd_timer_type_t of given timer handle.
284  */
snd_timer_type(snd_timer_t * timer)285 snd_timer_type_t snd_timer_type(snd_timer_t *timer)
286 {
287 	assert(timer);
288 	return timer->type;
289 }
290 
291 /**
292  * \brief Add an async handler for a timer
293  * \param handler Returned handler handle
294  * \param timer timer handle
295  * \param callback Callback function
296  * \param private_data Callback private data
297  * \return 0 otherwise a negative error code on failure
298  *
299  * The asynchronous callback is called when new timer event occurs.
300  */
snd_async_add_timer_handler(snd_async_handler_t ** handler,snd_timer_t * timer,snd_async_callback_t callback,void * private_data)301 int snd_async_add_timer_handler(snd_async_handler_t **handler, snd_timer_t *timer,
302 				snd_async_callback_t callback, void *private_data)
303 {
304 	int err;
305 	int was_empty;
306 	snd_async_handler_t *h;
307 	err = snd_async_add_handler(&h, timer->poll_fd,
308 				    callback, private_data);
309 	if (err < 0)
310 		return err;
311 	h->type = SND_ASYNC_HANDLER_TIMER;
312 	h->u.timer = timer;
313 	was_empty = list_empty(&timer->async_handlers);
314 	list_add_tail(&h->hlist, &timer->async_handlers);
315 	if (was_empty) {
316 		err = snd_timer_async(timer, snd_async_handler_get_signo(h), getpid());
317 		if (err < 0) {
318 			snd_async_del_handler(h);
319 			return err;
320 		}
321 	}
322 	*handler = h;
323 	return 0;
324 }
325 
326 /**
327  * \brief Return timer handle related to an async handler
328  * \param handler Async handler handle
329  * \return timer handle
330  */
snd_async_handler_get_timer(snd_async_handler_t * handler)331 snd_timer_t *snd_async_handler_get_timer(snd_async_handler_t *handler)
332 {
333 	if (handler->type != SND_ASYNC_HANDLER_TIMER) {
334 		SNDMSG("invalid handler type %d", handler->type);
335 		return NULL;
336 	}
337 	return handler->u.timer;
338 }
339 
340 /**
341  * \brief get count of poll descriptors for timer handle
342  * \param timer timer handle
343  * \return count of poll descriptors
344  */
snd_timer_poll_descriptors_count(snd_timer_t * timer)345 int snd_timer_poll_descriptors_count(snd_timer_t *timer)
346 {
347 	assert(timer);
348 	return 1;
349 }
350 
351 /**
352  * \brief get poll descriptors
353  * \param timer timer handle
354  * \param pfds array of poll descriptors
355  * \param space space in the poll descriptor array
356  * \return count of filled descriptors
357  */
snd_timer_poll_descriptors(snd_timer_t * timer,struct pollfd * pfds,unsigned int space)358 int snd_timer_poll_descriptors(snd_timer_t *timer, struct pollfd *pfds, unsigned int space)
359 {
360 	assert(timer);
361 	if (space >= 1) {
362 		pfds->fd = timer->poll_fd;
363 		switch (timer->mode & O_ACCMODE) {
364 		case O_WRONLY:
365 			pfds->events = POLLOUT|POLLERR|POLLNVAL;
366 			break;
367 		case O_RDONLY:
368 			pfds->events = POLLIN|POLLERR|POLLNVAL;
369 			break;
370 		case O_RDWR:
371 			pfds->events = POLLOUT|POLLIN|POLLERR|POLLNVAL;
372 			break;
373 		default:
374 			return -EIO;
375 		}
376 		return 1;
377 	}
378 	return 0;
379 }
380 
381 /**
382  * \brief get returned events from poll descriptors
383  * \param timer timer handle
384  * \param pfds array of poll descriptors
385  * \param nfds count of poll descriptors
386  * \param revents returned events
387  * \return zero if success, otherwise a negative error code
388  */
snd_timer_poll_descriptors_revents(snd_timer_t * timer,struct pollfd * pfds,unsigned int nfds,unsigned short * revents)389 int snd_timer_poll_descriptors_revents(snd_timer_t *timer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
390 {
391         assert(timer && pfds && revents);
392         if (nfds == 1) {
393                 *revents = pfds->revents;
394                 return 0;
395         }
396         return -EINVAL;
397 }
398 
399 /**
400  * \brief set nonblock mode
401  * \param timer timer handle
402  * \param nonblock 0 = block, 1 = nonblock mode
403  * \return 0 on success otherwise a negative error code
404  */
snd_timer_nonblock(snd_timer_t * timer,int nonblock)405 int snd_timer_nonblock(snd_timer_t *timer, int nonblock)
406 {
407 	int err;
408 	assert(timer);
409 	if ((err = timer->ops->nonblock(timer, nonblock)) < 0)
410 		return err;
411 	if (nonblock)
412 		timer->mode |= SND_TIMER_OPEN_NONBLOCK;
413 	else
414 		timer->mode &= ~SND_TIMER_OPEN_NONBLOCK;
415 	return 0;
416 }
417 
418 #ifndef DOC_HIDDEN
419 /**
420  * \brief set async mode
421  * \param timer timer handle
422  * \param sig Signal to raise: < 0 disable, 0 default (SIGIO)
423  * \param pid Process ID to signal: 0 current
424  * \return 0 on success otherwise a negative error code
425  *
426  * A signal is raised every period.
427  */
snd_timer_async(snd_timer_t * timer,int sig,pid_t pid)428 int snd_timer_async(snd_timer_t *timer, int sig, pid_t pid)
429 {
430 	assert(timer);
431         if (sig == 0)
432                 sig = SIGIO;
433 	if (pid == 0)
434 		pid = getpid();
435 	return timer->ops->async(timer, sig, pid);
436 }
437 #endif
438 
439 /**
440  * \brief get size of the snd_timer_info_t structure in bytes
441  * \return size of the snd_timer_info_t structure in bytes
442  */
snd_timer_info_sizeof()443 size_t snd_timer_info_sizeof()
444 {
445 	return sizeof(snd_timer_info_t);
446 }
447 
448 /**
449  * \brief allocate a new snd_timer_info_t structure
450  * \param info returned pointer
451  * \return 0 on success otherwise a negative error code if fails
452  *
453  * Allocates a new snd_timer_info_t structure using the standard
454  * malloc C library function.
455  */
snd_timer_info_malloc(snd_timer_info_t ** info)456 int snd_timer_info_malloc(snd_timer_info_t **info)
457 {
458 	assert(info);
459 	*info = calloc(1, sizeof(snd_timer_info_t));
460 	if (!*info)
461 		return -ENOMEM;
462 	return 0;
463 }
464 
465 /**
466  * \brief frees the snd_timer_info_t structure
467  * \param info pointer to the snd_timer_info_t structure to free
468  *
469  * Frees the given snd_timer_info_t structure using the standard
470  * free C library function.
471  */
snd_timer_info_free(snd_timer_info_t * info)472 void snd_timer_info_free(snd_timer_info_t *info)
473 {
474 	assert(info);
475 	free(info);
476 }
477 
478 /**
479  * \brief copy one snd_timer_info_t structure to another
480  * \param dst destination snd_timer_info_t structure
481  * \param src source snd_timer_info_t structure
482  */
snd_timer_info_copy(snd_timer_info_t * dst,const snd_timer_info_t * src)483 void snd_timer_info_copy(snd_timer_info_t *dst, const snd_timer_info_t *src)
484 {
485 	assert(dst && src);
486 	*dst = *src;
487 }
488 
489 /**
490  * \brief determine, if timer is slave
491  * \param info pointer to #snd_timer_info_t structure
492  * \return nonzero if timer is slave
493  */
snd_timer_info_is_slave(snd_timer_info_t * info)494 int snd_timer_info_is_slave(snd_timer_info_t * info)
495 {
496 	assert(info);
497 	return info->flags & SNDRV_TIMER_FLG_SLAVE ? 1 : 0;
498 }
499 
500 /**
501  * \brief get timer card
502  * \param info pointer to #snd_timer_info_t structure
503  * \return timer card number
504  */
snd_timer_info_get_card(snd_timer_info_t * info)505 int snd_timer_info_get_card(snd_timer_info_t * info)
506 {
507 	assert(info);
508 	return info->card;
509 }
510 
511 /**
512  * \brief get timer id
513  * \param info pointer to #snd_timer_info_t structure
514  * \return timer id
515  */
snd_timer_info_get_id(snd_timer_info_t * info)516 const char *snd_timer_info_get_id(snd_timer_info_t * info)
517 {
518 	assert(info);
519 	return (const char *)info->id;
520 }
521 
522 /**
523  * \brief get timer name
524  * \param info pointer to #snd_timer_info_t structure
525  * \return timer name
526  */
snd_timer_info_get_name(snd_timer_info_t * info)527 const char *snd_timer_info_get_name(snd_timer_info_t * info)
528 {
529 	assert(info);
530 	return (const char *)info->name;
531 }
532 
533 
534 /**
535  * \brief get timer resolution in us
536  * \param info pointer to #snd_timer_info_t structure
537  * \return timer resolution
538  */
snd_timer_info_get_resolution(snd_timer_info_t * info)539 long snd_timer_info_get_resolution(snd_timer_info_t * info)
540 {
541 	assert(info);
542 	return info->resolution;
543 }
544 
545 /**
546  * \brief get information about timer handle
547  * \param timer timer handle
548  * \param info pointer to a snd_timer_info_t structure to be filled
549  * \return 0 on success otherwise a negative error code
550  */
snd_timer_info(snd_timer_t * timer,snd_timer_info_t * info)551 int snd_timer_info(snd_timer_t *timer, snd_timer_info_t * info)
552 {
553 	assert(timer);
554 	assert(info);
555 	return timer->ops->info(timer, info);
556 }
557 
558 /**
559  * \brief get size of the snd_timer_params_t structure in bytes
560  * \return size of the snd_timer_params_t structure in bytes
561  */
snd_timer_params_sizeof()562 size_t snd_timer_params_sizeof()
563 {
564 	return sizeof(snd_timer_params_t);
565 }
566 
567 /**
568  * \brief allocate a new snd_timer_params_t structure
569  * \param params returned pointer
570  * \return 0 on success otherwise a negative error code if fails
571  *
572  * Allocates a new snd_timer_params_t structure using the standard
573  * malloc C library function.
574  */
snd_timer_params_malloc(snd_timer_params_t ** params)575 int snd_timer_params_malloc(snd_timer_params_t **params)
576 {
577 	assert(params);
578 	*params = calloc(1, sizeof(snd_timer_params_t));
579 	if (!*params)
580 		return -ENOMEM;
581 	return 0;
582 }
583 
584 /**
585  * \brief frees the snd_timer_params_t structure
586  * \param params pointer to the snd_timer_params_t structure to free
587  *
588  * Frees the given snd_timer_params_t structure using the standard
589  * free C library function.
590  */
snd_timer_params_free(snd_timer_params_t * params)591 void snd_timer_params_free(snd_timer_params_t *params)
592 {
593 	assert(params);
594 	free(params);
595 }
596 
597 /**
598  * \brief copy one snd_timer_params_t structure to another
599  * \param dst destination snd_timer_params_t structure
600  * \param src source snd_timer_params_t structure
601  */
snd_timer_params_copy(snd_timer_params_t * dst,const snd_timer_params_t * src)602 void snd_timer_params_copy(snd_timer_params_t *dst, const snd_timer_params_t *src)
603 {
604 	assert(dst && src);
605 	*dst = *src;
606 }
607 
608 /**
609  * \brief set timer auto start
610  * \param params pointer to #snd_timer_params_t structure
611  * \param auto_start The boolean value to set
612  */
snd_timer_params_set_auto_start(snd_timer_params_t * params,int auto_start)613 int snd_timer_params_set_auto_start(snd_timer_params_t * params, int auto_start)
614 {
615 	assert(params);
616 	if (auto_start)
617 		params->flags |= SNDRV_TIMER_PSFLG_AUTO;
618 	else
619 		params->flags &= ~SNDRV_TIMER_PSFLG_AUTO;
620 	return 0;
621 }
622 
623 /**
624  * \brief determine if timer has auto start flag
625  * \param params pointer to #snd_timer_params_t structure
626  * \return nonzero if timer has auto start flag
627  */
snd_timer_params_get_auto_start(snd_timer_params_t * params)628 int snd_timer_params_get_auto_start(snd_timer_params_t * params)
629 {
630 	assert(params);
631 	return params->flags & SNDRV_TIMER_PSFLG_AUTO ? 1 : 0;
632 }
633 
634 /**
635  * \brief set timer exclusive use
636  * \param params pointer to #snd_timer_params_t structure
637  * \param exclusive The boolean value to set
638  */
639 #ifndef DOXYGEN
INTERNAL(snd_timer_params_set_exclusive)640 EXPORT_SYMBOL int INTERNAL(snd_timer_params_set_exclusive)(snd_timer_params_t * params, int exclusive)
641 #else
642 int snd_timer_params_set_exclusive(snd_timer_params_t * params, int exclusive)
643 #endif
644 {
645 	assert(params);
646 	if (exclusive)
647 		params->flags |= SNDRV_TIMER_PSFLG_EXCLUSIVE;
648 	else
649 		params->flags &= ~SNDRV_TIMER_PSFLG_EXCLUSIVE;
650 	return 0;
651 }
652 use_default_symbol_version(__snd_timer_params_set_exclusive, snd_timer_params_set_exclusive, ALSA_0.9.0);
653 
654 /**
655  * \brief determine if timer has exclusive flag
656  * \param params pointer to #snd_timer_params_t structure
657  * \return nonzero if timer has exclusive flag
658  */
659 #ifndef DOXYGEN
INTERNAL(snd_timer_params_get_exclusive)660 EXPORT_SYMBOL int INTERNAL(snd_timer_params_get_exclusive)(snd_timer_params_t * params)
661 #else
662 int snd_timer_params_get_exclusive(snd_timer_params_t * params)
663 #endif
664 {
665 	assert(params);
666 	return params->flags & SNDRV_TIMER_PSFLG_EXCLUSIVE ? 1 : 0;
667 }
668 use_default_symbol_version(__snd_timer_params_get_exclusive, snd_timer_params_get_exclusive, ALSA_0.9.0);
669 
670 /**
671  * \brief set timer early event
672  * \param params pointer to #snd_timer_params_t structure
673  * \param early_event The boolean value to set
674  */
snd_timer_params_set_early_event(snd_timer_params_t * params,int early_event)675 int snd_timer_params_set_early_event(snd_timer_params_t * params, int early_event)
676 {
677 	assert(params);
678 	if (early_event)
679 		params->flags |= SNDRV_TIMER_PSFLG_EARLY_EVENT;
680 	else
681 		params->flags &= ~SNDRV_TIMER_PSFLG_EARLY_EVENT;
682 	return 0;
683 }
684 
685 /**
686  * \brief determine if timer has early event flag
687  * \param params pointer to #snd_timer_params_t structure
688  * \return nonzero if timer has early event flag set
689  */
snd_timer_params_get_early_event(snd_timer_params_t * params)690 int snd_timer_params_get_early_event(snd_timer_params_t * params)
691 {
692 	assert(params);
693 	return params->flags & SNDRV_TIMER_PSFLG_EARLY_EVENT ? 1 : 0;
694 }
695 
696 /**
697  * \brief set timer ticks
698  * \param params pointer to #snd_timer_params_t structure
699  * \param ticks Ticks to set
700  */
snd_timer_params_set_ticks(snd_timer_params_t * params,long ticks)701 void snd_timer_params_set_ticks(snd_timer_params_t * params, long ticks)
702 {
703 	assert(params);
704 	params->ticks = ticks;
705 }
706 
707 /**
708  * \brief get timer ticks
709  * \param params pointer to #snd_timer_params_t structure
710  * \return timer ticks
711  */
snd_timer_params_get_ticks(snd_timer_params_t * params)712 long snd_timer_params_get_ticks(snd_timer_params_t * params)
713 {
714 	assert(params);
715 	return params->ticks;
716 }
717 
718 /**
719  * \brief set timer queue size (32-1024)
720  * \param params pointer to #snd_timer_params_t structure
721  * \param queue_size The queue size to set
722  */
snd_timer_params_set_queue_size(snd_timer_params_t * params,long queue_size)723 void snd_timer_params_set_queue_size(snd_timer_params_t * params, long queue_size)
724 {
725 	assert(params);
726 	params->queue_size = queue_size;
727 }
728 
729 /**
730  * \brief get queue size
731  * \param params pointer to #snd_timer_params_t structure
732  * \return queue size
733  */
snd_timer_params_get_queue_size(snd_timer_params_t * params)734 long snd_timer_params_get_queue_size(snd_timer_params_t * params)
735 {
736 	assert(params);
737 	return params->queue_size;
738 }
739 
740 /**
741  * \brief set timer event filter
742  * \param params pointer to #snd_timer_params_t structure
743  * \param filter The event filter bits to set
744  */
745 #ifndef DOXYGEN
INTERNAL(snd_timer_params_set_filter)746 EXPORT_SYMBOL void INTERNAL(snd_timer_params_set_filter)(snd_timer_params_t * params, unsigned int filter)
747 #else
748 void snd_timer_params_set_filter(snd_timer_params_t * params, unsigned int filter)
749 #endif
750 {
751 	assert(params);
752 	params->filter = filter;
753 }
754 use_default_symbol_version(__snd_timer_params_set_filter, snd_timer_params_set_filter, ALSA_0.9.0);
755 
756 /**
757  * \brief get timer event filter
758  * \param params pointer to #snd_timer_params_t structure
759  * \return timer event filter
760  */
761 #ifndef DOXYGEN
INTERNAL(snd_timer_params_get_filter)762 EXPORT_SYMBOL unsigned int INTERNAL(snd_timer_params_get_filter)(snd_timer_params_t * params)
763 #else
764 unsigned int snd_timer_params_get_filter(snd_timer_params_t * params)
765 #endif
766 {
767 	assert(params);
768 	return params->filter;
769 }
770 use_default_symbol_version(__snd_timer_params_get_filter, snd_timer_params_get_filter, ALSA_0.9.0);
771 
772 /**
773  * \brief set parameters for timer handle
774  * \param timer timer handle
775  * \param params pointer to a #snd_timer_params_t structure
776  * \return 0 on success otherwise a negative error code
777  */
snd_timer_params(snd_timer_t * timer,snd_timer_params_t * params)778 int snd_timer_params(snd_timer_t *timer, snd_timer_params_t * params)
779 {
780 	assert(timer);
781 	assert(params);
782 	return timer->ops->params(timer, params);
783 }
784 
785 /**
786  * \brief get size of the snd_timer_status_t structure in bytes
787  * \return size of the snd_timer_status_t structure in bytes
788  */
snd_timer_status_sizeof()789 size_t snd_timer_status_sizeof()
790 {
791 	return sizeof(snd_timer_status_t);
792 }
793 
794 /**
795  * \brief allocate a new snd_timer_status_t structure
796  * \param status returned pointer
797  * \return 0 on success otherwise a negative error code if fails
798  *
799  * Allocates a new snd_timer_status_t structure using the standard
800  * malloc C library function.
801  */
snd_timer_status_malloc(snd_timer_status_t ** status)802 int snd_timer_status_malloc(snd_timer_status_t **status)
803 {
804 	assert(status);
805 	*status = calloc(1, sizeof(snd_timer_status_t));
806 	if (!*status)
807 		return -ENOMEM;
808 	return 0;
809 }
810 
811 /**
812  * \brief frees the snd_timer_status_t structure
813  * \param status pointer to the snd_timer_status_t structure to free
814  *
815  * Frees the given snd_timer_status_t structure using the standard
816  * free C library function.
817  */
snd_timer_status_free(snd_timer_status_t * status)818 void snd_timer_status_free(snd_timer_status_t *status)
819 {
820 	assert(status);
821 	free(status);
822 }
823 
824 /**
825  * \brief copy one snd_timer_status_t structure to another
826  * \param dst destination snd_timer_status_t structure
827  * \param src source snd_timer_status_t structure
828  */
snd_timer_status_copy(snd_timer_status_t * dst,const snd_timer_status_t * src)829 void snd_timer_status_copy(snd_timer_status_t *dst, const snd_timer_status_t *src)
830 {
831 	assert(dst && src);
832 	*dst = *src;
833 }
834 
835 
836 
837 /**
838  * \brief get timestamp
839  * \param status pointer to #snd_timer_status_t structure
840  * \return timestamp
841  */
snd_timer_status_get_timestamp(snd_timer_status_t * status)842 snd_htimestamp_t snd_timer_status_get_timestamp(snd_timer_status_t * status)
843 {
844 	assert(status);
845 	return status->tstamp;
846 }
847 
848 /**
849  * \brief get resolution in us
850  * \param status pointer to #snd_timer_status_t structure
851  * \return resolution
852  */
snd_timer_status_get_resolution(snd_timer_status_t * status)853 long snd_timer_status_get_resolution(snd_timer_status_t * status)
854 {
855 	assert(status);
856 	return status->resolution;
857 }
858 
859 /**
860  * \brief get master tick lost count
861  * \param status pointer to #snd_timer_status_t structure
862  * \return master tick lost count
863  */
snd_timer_status_get_lost(snd_timer_status_t * status)864 long snd_timer_status_get_lost(snd_timer_status_t * status)
865 {
866 	assert(status);
867 	return status->lost;
868 }
869 
870 /**
871  * \brief get overrun count
872  * \param status pointer to #snd_timer_status_t structure
873  * \return overrun count
874  */
snd_timer_status_get_overrun(snd_timer_status_t * status)875 long snd_timer_status_get_overrun(snd_timer_status_t * status)
876 {
877 	assert(status);
878 	return status->overrun;
879 }
880 
881 /**
882  * \brief get count of used queue elements
883  * \param status pointer to #snd_timer_status_t structure
884  * \return count of used queue elements
885  */
snd_timer_status_get_queue(snd_timer_status_t * status)886 long snd_timer_status_get_queue(snd_timer_status_t * status)
887 {
888 	assert(status);
889 	return status->queue;
890 }
891 
892 /**
893  * \brief get status from timer handle
894  * \param timer timer handle
895  * \param status pointer to a #snd_timer_status_t structure to be filled
896  * \return 0 on success otherwise a negative error code
897  */
snd_timer_status(snd_timer_t * timer,snd_timer_status_t * status)898 int snd_timer_status(snd_timer_t *timer, snd_timer_status_t * status)
899 {
900 	assert(timer);
901 	assert(status);
902 	return timer->ops->status(timer, status);
903 }
904 
905 /**
906  * \brief start the timer
907  * \param timer timer handle
908  * \return 0 on success otherwise a negative error code
909  */
snd_timer_start(snd_timer_t * timer)910 int snd_timer_start(snd_timer_t *timer)
911 {
912 	assert(timer);
913 	return timer->ops->rt_start(timer);
914 }
915 
916 /**
917  * \brief stop the timer
918  * \param timer timer handle
919  * \return 0 on success otherwise a negative error code
920  */
snd_timer_stop(snd_timer_t * timer)921 int snd_timer_stop(snd_timer_t *timer)
922 {
923 	assert(timer);
924 	return timer->ops->rt_stop(timer);
925 }
926 
927 /**
928  * \brief continue the timer
929  * \param timer timer handle
930  * \return 0 on success otherwise a negative error code
931  */
snd_timer_continue(snd_timer_t * timer)932 int snd_timer_continue(snd_timer_t *timer)
933 {
934 	assert(timer);
935 	return timer->ops->rt_continue(timer);
936 }
937 
938 /**
939  * \brief read bytes using timer handle
940  * \param timer timer handle
941  * \param buffer buffer to store the input bytes
942  * \param size input buffer size in bytes
943  */
snd_timer_read(snd_timer_t * timer,void * buffer,size_t size)944 ssize_t snd_timer_read(snd_timer_t *timer, void *buffer, size_t size)
945 {
946 	assert(timer);
947 	assert(((timer->mode & O_ACCMODE) == O_RDONLY) || ((timer->mode & O_ACCMODE) == O_RDWR));
948 	assert(buffer || size == 0);
949 	return (timer->ops->read)(timer, buffer, size);
950 }
951 
952 /**
953  * \brief (DEPRECATED) get maximum timer ticks
954  * \param info pointer to #snd_timer_info_t structure
955  * \return maximum timer ticks
956  */
snd_timer_info_get_ticks(snd_timer_info_t * info)957 long snd_timer_info_get_ticks(snd_timer_info_t * info)
958 {
959 	assert(info);
960 	return 1;
961 }
962 #ifndef DOC_HIDDEN
963 link_warning(snd_timer_info_get_ticks, "Warning: snd_timer_info_get_ticks is deprecated");
964 #endif
965