Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/core/timer.c
10814 views
1
/*
2
* Timers abstract layer
3
* Copyright (c) by Jaroslav Kysela <[email protected]>
4
*
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
*
20
*/
21
22
#include <linux/delay.h>
23
#include <linux/init.h>
24
#include <linux/slab.h>
25
#include <linux/time.h>
26
#include <linux/mutex.h>
27
#include <linux/moduleparam.h>
28
#include <linux/string.h>
29
#include <sound/core.h>
30
#include <sound/timer.h>
31
#include <sound/control.h>
32
#include <sound/info.h>
33
#include <sound/minors.h>
34
#include <sound/initval.h>
35
#include <linux/kmod.h>
36
37
#if defined(CONFIG_SND_HRTIMER) || defined(CONFIG_SND_HRTIMER_MODULE)
38
#define DEFAULT_TIMER_LIMIT 4
39
#elif defined(CONFIG_SND_RTCTIMER) || defined(CONFIG_SND_RTCTIMER_MODULE)
40
#define DEFAULT_TIMER_LIMIT 2
41
#else
42
#define DEFAULT_TIMER_LIMIT 1
43
#endif
44
45
static int timer_limit = DEFAULT_TIMER_LIMIT;
46
static int timer_tstamp_monotonic = 1;
47
MODULE_AUTHOR("Jaroslav Kysela <[email protected]>, Takashi Iwai <[email protected]>");
48
MODULE_DESCRIPTION("ALSA timer interface");
49
MODULE_LICENSE("GPL");
50
module_param(timer_limit, int, 0444);
51
MODULE_PARM_DESC(timer_limit, "Maximum global timers in system.");
52
module_param(timer_tstamp_monotonic, int, 0444);
53
MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default).");
54
55
MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_TIMER);
56
MODULE_ALIAS("devname:snd/timer");
57
58
struct snd_timer_user {
59
struct snd_timer_instance *timeri;
60
int tread; /* enhanced read with timestamps and events */
61
unsigned long ticks;
62
unsigned long overrun;
63
int qhead;
64
int qtail;
65
int qused;
66
int queue_size;
67
struct snd_timer_read *queue;
68
struct snd_timer_tread *tqueue;
69
spinlock_t qlock;
70
unsigned long last_resolution;
71
unsigned int filter;
72
struct timespec tstamp; /* trigger tstamp */
73
wait_queue_head_t qchange_sleep;
74
struct fasync_struct *fasync;
75
struct mutex tread_sem;
76
};
77
78
/* list of timers */
79
static LIST_HEAD(snd_timer_list);
80
81
/* list of slave instances */
82
static LIST_HEAD(snd_timer_slave_list);
83
84
/* lock for slave active lists */
85
static DEFINE_SPINLOCK(slave_active_lock);
86
87
static DEFINE_MUTEX(register_mutex);
88
89
static int snd_timer_free(struct snd_timer *timer);
90
static int snd_timer_dev_free(struct snd_device *device);
91
static int snd_timer_dev_register(struct snd_device *device);
92
static int snd_timer_dev_disconnect(struct snd_device *device);
93
94
static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_left);
95
96
/*
97
* create a timer instance with the given owner string.
98
* when timer is not NULL, increments the module counter
99
*/
100
static struct snd_timer_instance *snd_timer_instance_new(char *owner,
101
struct snd_timer *timer)
102
{
103
struct snd_timer_instance *timeri;
104
timeri = kzalloc(sizeof(*timeri), GFP_KERNEL);
105
if (timeri == NULL)
106
return NULL;
107
timeri->owner = kstrdup(owner, GFP_KERNEL);
108
if (! timeri->owner) {
109
kfree(timeri);
110
return NULL;
111
}
112
INIT_LIST_HEAD(&timeri->open_list);
113
INIT_LIST_HEAD(&timeri->active_list);
114
INIT_LIST_HEAD(&timeri->ack_list);
115
INIT_LIST_HEAD(&timeri->slave_list_head);
116
INIT_LIST_HEAD(&timeri->slave_active_head);
117
118
timeri->timer = timer;
119
if (timer && !try_module_get(timer->module)) {
120
kfree(timeri->owner);
121
kfree(timeri);
122
return NULL;
123
}
124
125
return timeri;
126
}
127
128
/*
129
* find a timer instance from the given timer id
130
*/
131
static struct snd_timer *snd_timer_find(struct snd_timer_id *tid)
132
{
133
struct snd_timer *timer = NULL;
134
135
list_for_each_entry(timer, &snd_timer_list, device_list) {
136
if (timer->tmr_class != tid->dev_class)
137
continue;
138
if ((timer->tmr_class == SNDRV_TIMER_CLASS_CARD ||
139
timer->tmr_class == SNDRV_TIMER_CLASS_PCM) &&
140
(timer->card == NULL ||
141
timer->card->number != tid->card))
142
continue;
143
if (timer->tmr_device != tid->device)
144
continue;
145
if (timer->tmr_subdevice != tid->subdevice)
146
continue;
147
return timer;
148
}
149
return NULL;
150
}
151
152
#ifdef CONFIG_MODULES
153
154
static void snd_timer_request(struct snd_timer_id *tid)
155
{
156
switch (tid->dev_class) {
157
case SNDRV_TIMER_CLASS_GLOBAL:
158
if (tid->device < timer_limit)
159
request_module("snd-timer-%i", tid->device);
160
break;
161
case SNDRV_TIMER_CLASS_CARD:
162
case SNDRV_TIMER_CLASS_PCM:
163
if (tid->card < snd_ecards_limit)
164
request_module("snd-card-%i", tid->card);
165
break;
166
default:
167
break;
168
}
169
}
170
171
#endif
172
173
/*
174
* look for a master instance matching with the slave id of the given slave.
175
* when found, relink the open_link of the slave.
176
*
177
* call this with register_mutex down.
178
*/
179
static void snd_timer_check_slave(struct snd_timer_instance *slave)
180
{
181
struct snd_timer *timer;
182
struct snd_timer_instance *master;
183
184
/* FIXME: it's really dumb to look up all entries.. */
185
list_for_each_entry(timer, &snd_timer_list, device_list) {
186
list_for_each_entry(master, &timer->open_list_head, open_list) {
187
if (slave->slave_class == master->slave_class &&
188
slave->slave_id == master->slave_id) {
189
list_move_tail(&slave->open_list,
190
&master->slave_list_head);
191
spin_lock_irq(&slave_active_lock);
192
slave->master = master;
193
slave->timer = master->timer;
194
spin_unlock_irq(&slave_active_lock);
195
return;
196
}
197
}
198
}
199
}
200
201
/*
202
* look for slave instances matching with the slave id of the given master.
203
* when found, relink the open_link of slaves.
204
*
205
* call this with register_mutex down.
206
*/
207
static void snd_timer_check_master(struct snd_timer_instance *master)
208
{
209
struct snd_timer_instance *slave, *tmp;
210
211
/* check all pending slaves */
212
list_for_each_entry_safe(slave, tmp, &snd_timer_slave_list, open_list) {
213
if (slave->slave_class == master->slave_class &&
214
slave->slave_id == master->slave_id) {
215
list_move_tail(&slave->open_list, &master->slave_list_head);
216
spin_lock_irq(&slave_active_lock);
217
slave->master = master;
218
slave->timer = master->timer;
219
if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
220
list_add_tail(&slave->active_list,
221
&master->slave_active_head);
222
spin_unlock_irq(&slave_active_lock);
223
}
224
}
225
}
226
227
/*
228
* open a timer instance
229
* when opening a master, the slave id must be here given.
230
*/
231
int snd_timer_open(struct snd_timer_instance **ti,
232
char *owner, struct snd_timer_id *tid,
233
unsigned int slave_id)
234
{
235
struct snd_timer *timer;
236
struct snd_timer_instance *timeri = NULL;
237
238
if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) {
239
/* open a slave instance */
240
if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE ||
241
tid->dev_sclass > SNDRV_TIMER_SCLASS_OSS_SEQUENCER) {
242
snd_printd("invalid slave class %i\n", tid->dev_sclass);
243
return -EINVAL;
244
}
245
mutex_lock(&register_mutex);
246
timeri = snd_timer_instance_new(owner, NULL);
247
if (!timeri) {
248
mutex_unlock(&register_mutex);
249
return -ENOMEM;
250
}
251
timeri->slave_class = tid->dev_sclass;
252
timeri->slave_id = tid->device;
253
timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
254
list_add_tail(&timeri->open_list, &snd_timer_slave_list);
255
snd_timer_check_slave(timeri);
256
mutex_unlock(&register_mutex);
257
*ti = timeri;
258
return 0;
259
}
260
261
/* open a master instance */
262
mutex_lock(&register_mutex);
263
timer = snd_timer_find(tid);
264
#ifdef CONFIG_MODULES
265
if (!timer) {
266
mutex_unlock(&register_mutex);
267
snd_timer_request(tid);
268
mutex_lock(&register_mutex);
269
timer = snd_timer_find(tid);
270
}
271
#endif
272
if (!timer) {
273
mutex_unlock(&register_mutex);
274
return -ENODEV;
275
}
276
if (!list_empty(&timer->open_list_head)) {
277
timeri = list_entry(timer->open_list_head.next,
278
struct snd_timer_instance, open_list);
279
if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
280
mutex_unlock(&register_mutex);
281
return -EBUSY;
282
}
283
}
284
timeri = snd_timer_instance_new(owner, timer);
285
if (!timeri) {
286
mutex_unlock(&register_mutex);
287
return -ENOMEM;
288
}
289
timeri->slave_class = tid->dev_sclass;
290
timeri->slave_id = slave_id;
291
if (list_empty(&timer->open_list_head) && timer->hw.open)
292
timer->hw.open(timer);
293
list_add_tail(&timeri->open_list, &timer->open_list_head);
294
snd_timer_check_master(timeri);
295
mutex_unlock(&register_mutex);
296
*ti = timeri;
297
return 0;
298
}
299
300
static int _snd_timer_stop(struct snd_timer_instance *timeri,
301
int keep_flag, int event);
302
303
/*
304
* close a timer instance
305
*/
306
int snd_timer_close(struct snd_timer_instance *timeri)
307
{
308
struct snd_timer *timer = NULL;
309
struct snd_timer_instance *slave, *tmp;
310
311
if (snd_BUG_ON(!timeri))
312
return -ENXIO;
313
314
/* force to stop the timer */
315
snd_timer_stop(timeri);
316
317
if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
318
/* wait, until the active callback is finished */
319
spin_lock_irq(&slave_active_lock);
320
while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {
321
spin_unlock_irq(&slave_active_lock);
322
udelay(10);
323
spin_lock_irq(&slave_active_lock);
324
}
325
spin_unlock_irq(&slave_active_lock);
326
mutex_lock(&register_mutex);
327
list_del(&timeri->open_list);
328
mutex_unlock(&register_mutex);
329
} else {
330
timer = timeri->timer;
331
/* wait, until the active callback is finished */
332
spin_lock_irq(&timer->lock);
333
while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {
334
spin_unlock_irq(&timer->lock);
335
udelay(10);
336
spin_lock_irq(&timer->lock);
337
}
338
spin_unlock_irq(&timer->lock);
339
mutex_lock(&register_mutex);
340
list_del(&timeri->open_list);
341
if (timer && list_empty(&timer->open_list_head) &&
342
timer->hw.close)
343
timer->hw.close(timer);
344
/* remove slave links */
345
list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head,
346
open_list) {
347
spin_lock_irq(&slave_active_lock);
348
_snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
349
list_move_tail(&slave->open_list, &snd_timer_slave_list);
350
slave->master = NULL;
351
slave->timer = NULL;
352
spin_unlock_irq(&slave_active_lock);
353
}
354
mutex_unlock(&register_mutex);
355
}
356
if (timeri->private_free)
357
timeri->private_free(timeri);
358
kfree(timeri->owner);
359
kfree(timeri);
360
if (timer)
361
module_put(timer->module);
362
return 0;
363
}
364
365
unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
366
{
367
struct snd_timer * timer;
368
369
if (timeri == NULL)
370
return 0;
371
if ((timer = timeri->timer) != NULL) {
372
if (timer->hw.c_resolution)
373
return timer->hw.c_resolution(timer);
374
return timer->hw.resolution;
375
}
376
return 0;
377
}
378
379
static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
380
{
381
struct snd_timer *timer;
382
unsigned long flags;
383
unsigned long resolution = 0;
384
struct snd_timer_instance *ts;
385
struct timespec tstamp;
386
387
if (timer_tstamp_monotonic)
388
do_posix_clock_monotonic_gettime(&tstamp);
389
else
390
getnstimeofday(&tstamp);
391
if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_START ||
392
event > SNDRV_TIMER_EVENT_PAUSE))
393
return;
394
if (event == SNDRV_TIMER_EVENT_START ||
395
event == SNDRV_TIMER_EVENT_CONTINUE)
396
resolution = snd_timer_resolution(ti);
397
if (ti->ccallback)
398
ti->ccallback(ti, event, &tstamp, resolution);
399
if (ti->flags & SNDRV_TIMER_IFLG_SLAVE)
400
return;
401
timer = ti->timer;
402
if (timer == NULL)
403
return;
404
if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
405
return;
406
spin_lock_irqsave(&timer->lock, flags);
407
list_for_each_entry(ts, &ti->slave_active_head, active_list)
408
if (ts->ccallback)
409
ts->ccallback(ti, event + 100, &tstamp, resolution);
410
spin_unlock_irqrestore(&timer->lock, flags);
411
}
412
413
static int snd_timer_start1(struct snd_timer *timer, struct snd_timer_instance *timeri,
414
unsigned long sticks)
415
{
416
list_move_tail(&timeri->active_list, &timer->active_list_head);
417
if (timer->running) {
418
if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
419
goto __start_now;
420
timer->flags |= SNDRV_TIMER_FLG_RESCHED;
421
timeri->flags |= SNDRV_TIMER_IFLG_START;
422
return 1; /* delayed start */
423
} else {
424
timer->sticks = sticks;
425
timer->hw.start(timer);
426
__start_now:
427
timer->running++;
428
timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
429
return 0;
430
}
431
}
432
433
static int snd_timer_start_slave(struct snd_timer_instance *timeri)
434
{
435
unsigned long flags;
436
437
spin_lock_irqsave(&slave_active_lock, flags);
438
timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
439
if (timeri->master)
440
list_add_tail(&timeri->active_list,
441
&timeri->master->slave_active_head);
442
spin_unlock_irqrestore(&slave_active_lock, flags);
443
return 1; /* delayed start */
444
}
445
446
/*
447
* start the timer instance
448
*/
449
int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks)
450
{
451
struct snd_timer *timer;
452
int result = -EINVAL;
453
unsigned long flags;
454
455
if (timeri == NULL || ticks < 1)
456
return -EINVAL;
457
if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
458
result = snd_timer_start_slave(timeri);
459
snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
460
return result;
461
}
462
timer = timeri->timer;
463
if (timer == NULL)
464
return -EINVAL;
465
spin_lock_irqsave(&timer->lock, flags);
466
timeri->ticks = timeri->cticks = ticks;
467
timeri->pticks = 0;
468
result = snd_timer_start1(timer, timeri, ticks);
469
spin_unlock_irqrestore(&timer->lock, flags);
470
snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
471
return result;
472
}
473
474
static int _snd_timer_stop(struct snd_timer_instance * timeri,
475
int keep_flag, int event)
476
{
477
struct snd_timer *timer;
478
unsigned long flags;
479
480
if (snd_BUG_ON(!timeri))
481
return -ENXIO;
482
483
if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
484
if (!keep_flag) {
485
spin_lock_irqsave(&slave_active_lock, flags);
486
timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
487
spin_unlock_irqrestore(&slave_active_lock, flags);
488
}
489
goto __end;
490
}
491
timer = timeri->timer;
492
if (!timer)
493
return -EINVAL;
494
spin_lock_irqsave(&timer->lock, flags);
495
list_del_init(&timeri->ack_list);
496
list_del_init(&timeri->active_list);
497
if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) &&
498
!(--timer->running)) {
499
timer->hw.stop(timer);
500
if (timer->flags & SNDRV_TIMER_FLG_RESCHED) {
501
timer->flags &= ~SNDRV_TIMER_FLG_RESCHED;
502
snd_timer_reschedule(timer, 0);
503
if (timer->flags & SNDRV_TIMER_FLG_CHANGE) {
504
timer->flags &= ~SNDRV_TIMER_FLG_CHANGE;
505
timer->hw.start(timer);
506
}
507
}
508
}
509
if (!keep_flag)
510
timeri->flags &=
511
~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
512
spin_unlock_irqrestore(&timer->lock, flags);
513
__end:
514
if (event != SNDRV_TIMER_EVENT_RESOLUTION)
515
snd_timer_notify1(timeri, event);
516
return 0;
517
}
518
519
/*
520
* stop the timer instance.
521
*
522
* do not call this from the timer callback!
523
*/
524
int snd_timer_stop(struct snd_timer_instance *timeri)
525
{
526
struct snd_timer *timer;
527
unsigned long flags;
528
int err;
529
530
err = _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_STOP);
531
if (err < 0)
532
return err;
533
timer = timeri->timer;
534
spin_lock_irqsave(&timer->lock, flags);
535
timeri->cticks = timeri->ticks;
536
timeri->pticks = 0;
537
spin_unlock_irqrestore(&timer->lock, flags);
538
return 0;
539
}
540
541
/*
542
* start again.. the tick is kept.
543
*/
544
int snd_timer_continue(struct snd_timer_instance *timeri)
545
{
546
struct snd_timer *timer;
547
int result = -EINVAL;
548
unsigned long flags;
549
550
if (timeri == NULL)
551
return result;
552
if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
553
return snd_timer_start_slave(timeri);
554
timer = timeri->timer;
555
if (! timer)
556
return -EINVAL;
557
spin_lock_irqsave(&timer->lock, flags);
558
if (!timeri->cticks)
559
timeri->cticks = 1;
560
timeri->pticks = 0;
561
result = snd_timer_start1(timer, timeri, timer->sticks);
562
spin_unlock_irqrestore(&timer->lock, flags);
563
snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_CONTINUE);
564
return result;
565
}
566
567
/*
568
* pause.. remember the ticks left
569
*/
570
int snd_timer_pause(struct snd_timer_instance * timeri)
571
{
572
return _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_PAUSE);
573
}
574
575
/*
576
* reschedule the timer
577
*
578
* start pending instances and check the scheduling ticks.
579
* when the scheduling ticks is changed set CHANGE flag to reprogram the timer.
580
*/
581
static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_left)
582
{
583
struct snd_timer_instance *ti;
584
unsigned long ticks = ~0UL;
585
586
list_for_each_entry(ti, &timer->active_list_head, active_list) {
587
if (ti->flags & SNDRV_TIMER_IFLG_START) {
588
ti->flags &= ~SNDRV_TIMER_IFLG_START;
589
ti->flags |= SNDRV_TIMER_IFLG_RUNNING;
590
timer->running++;
591
}
592
if (ti->flags & SNDRV_TIMER_IFLG_RUNNING) {
593
if (ticks > ti->cticks)
594
ticks = ti->cticks;
595
}
596
}
597
if (ticks == ~0UL) {
598
timer->flags &= ~SNDRV_TIMER_FLG_RESCHED;
599
return;
600
}
601
if (ticks > timer->hw.ticks)
602
ticks = timer->hw.ticks;
603
if (ticks_left != ticks)
604
timer->flags |= SNDRV_TIMER_FLG_CHANGE;
605
timer->sticks = ticks;
606
}
607
608
/*
609
* timer tasklet
610
*
611
*/
612
static void snd_timer_tasklet(unsigned long arg)
613
{
614
struct snd_timer *timer = (struct snd_timer *) arg;
615
struct snd_timer_instance *ti;
616
struct list_head *p;
617
unsigned long resolution, ticks;
618
unsigned long flags;
619
620
spin_lock_irqsave(&timer->lock, flags);
621
/* now process all callbacks */
622
while (!list_empty(&timer->sack_list_head)) {
623
p = timer->sack_list_head.next; /* get first item */
624
ti = list_entry(p, struct snd_timer_instance, ack_list);
625
626
/* remove from ack_list and make empty */
627
list_del_init(p);
628
629
ticks = ti->pticks;
630
ti->pticks = 0;
631
resolution = ti->resolution;
632
633
ti->flags |= SNDRV_TIMER_IFLG_CALLBACK;
634
spin_unlock(&timer->lock);
635
if (ti->callback)
636
ti->callback(ti, resolution, ticks);
637
spin_lock(&timer->lock);
638
ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK;
639
}
640
spin_unlock_irqrestore(&timer->lock, flags);
641
}
642
643
/*
644
* timer interrupt
645
*
646
* ticks_left is usually equal to timer->sticks.
647
*
648
*/
649
void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
650
{
651
struct snd_timer_instance *ti, *ts, *tmp;
652
unsigned long resolution, ticks;
653
struct list_head *p, *ack_list_head;
654
unsigned long flags;
655
int use_tasklet = 0;
656
657
if (timer == NULL)
658
return;
659
660
spin_lock_irqsave(&timer->lock, flags);
661
662
/* remember the current resolution */
663
if (timer->hw.c_resolution)
664
resolution = timer->hw.c_resolution(timer);
665
else
666
resolution = timer->hw.resolution;
667
668
/* loop for all active instances
669
* Here we cannot use list_for_each_entry because the active_list of a
670
* processed instance is relinked to done_list_head before the callback
671
* is called.
672
*/
673
list_for_each_entry_safe(ti, tmp, &timer->active_list_head,
674
active_list) {
675
if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING))
676
continue;
677
ti->pticks += ticks_left;
678
ti->resolution = resolution;
679
if (ti->cticks < ticks_left)
680
ti->cticks = 0;
681
else
682
ti->cticks -= ticks_left;
683
if (ti->cticks) /* not expired */
684
continue;
685
if (ti->flags & SNDRV_TIMER_IFLG_AUTO) {
686
ti->cticks = ti->ticks;
687
} else {
688
ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
689
if (--timer->running)
690
list_del(&ti->active_list);
691
}
692
if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
693
(ti->flags & SNDRV_TIMER_IFLG_FAST))
694
ack_list_head = &timer->ack_list_head;
695
else
696
ack_list_head = &timer->sack_list_head;
697
if (list_empty(&ti->ack_list))
698
list_add_tail(&ti->ack_list, ack_list_head);
699
list_for_each_entry(ts, &ti->slave_active_head, active_list) {
700
ts->pticks = ti->pticks;
701
ts->resolution = resolution;
702
if (list_empty(&ts->ack_list))
703
list_add_tail(&ts->ack_list, ack_list_head);
704
}
705
}
706
if (timer->flags & SNDRV_TIMER_FLG_RESCHED)
707
snd_timer_reschedule(timer, timer->sticks);
708
if (timer->running) {
709
if (timer->hw.flags & SNDRV_TIMER_HW_STOP) {
710
timer->hw.stop(timer);
711
timer->flags |= SNDRV_TIMER_FLG_CHANGE;
712
}
713
if (!(timer->hw.flags & SNDRV_TIMER_HW_AUTO) ||
714
(timer->flags & SNDRV_TIMER_FLG_CHANGE)) {
715
/* restart timer */
716
timer->flags &= ~SNDRV_TIMER_FLG_CHANGE;
717
timer->hw.start(timer);
718
}
719
} else {
720
timer->hw.stop(timer);
721
}
722
723
/* now process all fast callbacks */
724
while (!list_empty(&timer->ack_list_head)) {
725
p = timer->ack_list_head.next; /* get first item */
726
ti = list_entry(p, struct snd_timer_instance, ack_list);
727
728
/* remove from ack_list and make empty */
729
list_del_init(p);
730
731
ticks = ti->pticks;
732
ti->pticks = 0;
733
734
ti->flags |= SNDRV_TIMER_IFLG_CALLBACK;
735
spin_unlock(&timer->lock);
736
if (ti->callback)
737
ti->callback(ti, resolution, ticks);
738
spin_lock(&timer->lock);
739
ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK;
740
}
741
742
/* do we have any slow callbacks? */
743
use_tasklet = !list_empty(&timer->sack_list_head);
744
spin_unlock_irqrestore(&timer->lock, flags);
745
746
if (use_tasklet)
747
tasklet_schedule(&timer->task_queue);
748
}
749
750
/*
751
752
*/
753
754
int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
755
struct snd_timer **rtimer)
756
{
757
struct snd_timer *timer;
758
int err;
759
static struct snd_device_ops ops = {
760
.dev_free = snd_timer_dev_free,
761
.dev_register = snd_timer_dev_register,
762
.dev_disconnect = snd_timer_dev_disconnect,
763
};
764
765
if (snd_BUG_ON(!tid))
766
return -EINVAL;
767
if (rtimer)
768
*rtimer = NULL;
769
timer = kzalloc(sizeof(*timer), GFP_KERNEL);
770
if (timer == NULL) {
771
snd_printk(KERN_ERR "timer: cannot allocate\n");
772
return -ENOMEM;
773
}
774
timer->tmr_class = tid->dev_class;
775
timer->card = card;
776
timer->tmr_device = tid->device;
777
timer->tmr_subdevice = tid->subdevice;
778
if (id)
779
strlcpy(timer->id, id, sizeof(timer->id));
780
INIT_LIST_HEAD(&timer->device_list);
781
INIT_LIST_HEAD(&timer->open_list_head);
782
INIT_LIST_HEAD(&timer->active_list_head);
783
INIT_LIST_HEAD(&timer->ack_list_head);
784
INIT_LIST_HEAD(&timer->sack_list_head);
785
spin_lock_init(&timer->lock);
786
tasklet_init(&timer->task_queue, snd_timer_tasklet,
787
(unsigned long)timer);
788
if (card != NULL) {
789
timer->module = card->module;
790
err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops);
791
if (err < 0) {
792
snd_timer_free(timer);
793
return err;
794
}
795
}
796
if (rtimer)
797
*rtimer = timer;
798
return 0;
799
}
800
801
static int snd_timer_free(struct snd_timer *timer)
802
{
803
if (!timer)
804
return 0;
805
806
mutex_lock(&register_mutex);
807
if (! list_empty(&timer->open_list_head)) {
808
struct list_head *p, *n;
809
struct snd_timer_instance *ti;
810
snd_printk(KERN_WARNING "timer %p is busy?\n", timer);
811
list_for_each_safe(p, n, &timer->open_list_head) {
812
list_del_init(p);
813
ti = list_entry(p, struct snd_timer_instance, open_list);
814
ti->timer = NULL;
815
}
816
}
817
list_del(&timer->device_list);
818
mutex_unlock(&register_mutex);
819
820
if (timer->private_free)
821
timer->private_free(timer);
822
kfree(timer);
823
return 0;
824
}
825
826
static int snd_timer_dev_free(struct snd_device *device)
827
{
828
struct snd_timer *timer = device->device_data;
829
return snd_timer_free(timer);
830
}
831
832
static int snd_timer_dev_register(struct snd_device *dev)
833
{
834
struct snd_timer *timer = dev->device_data;
835
struct snd_timer *timer1;
836
837
if (snd_BUG_ON(!timer || !timer->hw.start || !timer->hw.stop))
838
return -ENXIO;
839
if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) &&
840
!timer->hw.resolution && timer->hw.c_resolution == NULL)
841
return -EINVAL;
842
843
mutex_lock(&register_mutex);
844
list_for_each_entry(timer1, &snd_timer_list, device_list) {
845
if (timer1->tmr_class > timer->tmr_class)
846
break;
847
if (timer1->tmr_class < timer->tmr_class)
848
continue;
849
if (timer1->card && timer->card) {
850
if (timer1->card->number > timer->card->number)
851
break;
852
if (timer1->card->number < timer->card->number)
853
continue;
854
}
855
if (timer1->tmr_device > timer->tmr_device)
856
break;
857
if (timer1->tmr_device < timer->tmr_device)
858
continue;
859
if (timer1->tmr_subdevice > timer->tmr_subdevice)
860
break;
861
if (timer1->tmr_subdevice < timer->tmr_subdevice)
862
continue;
863
/* conflicts.. */
864
mutex_unlock(&register_mutex);
865
return -EBUSY;
866
}
867
list_add_tail(&timer->device_list, &timer1->device_list);
868
mutex_unlock(&register_mutex);
869
return 0;
870
}
871
872
static int snd_timer_dev_disconnect(struct snd_device *device)
873
{
874
struct snd_timer *timer = device->device_data;
875
mutex_lock(&register_mutex);
876
list_del_init(&timer->device_list);
877
mutex_unlock(&register_mutex);
878
return 0;
879
}
880
881
void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstamp)
882
{
883
unsigned long flags;
884
unsigned long resolution = 0;
885
struct snd_timer_instance *ti, *ts;
886
887
if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE))
888
return;
889
if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_MSTART ||
890
event > SNDRV_TIMER_EVENT_MRESUME))
891
return;
892
spin_lock_irqsave(&timer->lock, flags);
893
if (event == SNDRV_TIMER_EVENT_MSTART ||
894
event == SNDRV_TIMER_EVENT_MCONTINUE ||
895
event == SNDRV_TIMER_EVENT_MRESUME) {
896
if (timer->hw.c_resolution)
897
resolution = timer->hw.c_resolution(timer);
898
else
899
resolution = timer->hw.resolution;
900
}
901
list_for_each_entry(ti, &timer->active_list_head, active_list) {
902
if (ti->ccallback)
903
ti->ccallback(ti, event, tstamp, resolution);
904
list_for_each_entry(ts, &ti->slave_active_head, active_list)
905
if (ts->ccallback)
906
ts->ccallback(ts, event, tstamp, resolution);
907
}
908
spin_unlock_irqrestore(&timer->lock, flags);
909
}
910
911
/*
912
* exported functions for global timers
913
*/
914
int snd_timer_global_new(char *id, int device, struct snd_timer **rtimer)
915
{
916
struct snd_timer_id tid;
917
918
tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL;
919
tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
920
tid.card = -1;
921
tid.device = device;
922
tid.subdevice = 0;
923
return snd_timer_new(NULL, id, &tid, rtimer);
924
}
925
926
int snd_timer_global_free(struct snd_timer *timer)
927
{
928
return snd_timer_free(timer);
929
}
930
931
int snd_timer_global_register(struct snd_timer *timer)
932
{
933
struct snd_device dev;
934
935
memset(&dev, 0, sizeof(dev));
936
dev.device_data = timer;
937
return snd_timer_dev_register(&dev);
938
}
939
940
/*
941
* System timer
942
*/
943
944
struct snd_timer_system_private {
945
struct timer_list tlist;
946
unsigned long last_expires;
947
unsigned long last_jiffies;
948
unsigned long correction;
949
};
950
951
static void snd_timer_s_function(unsigned long data)
952
{
953
struct snd_timer *timer = (struct snd_timer *)data;
954
struct snd_timer_system_private *priv = timer->private_data;
955
unsigned long jiff = jiffies;
956
if (time_after(jiff, priv->last_expires))
957
priv->correction += (long)jiff - (long)priv->last_expires;
958
snd_timer_interrupt(timer, (long)jiff - (long)priv->last_jiffies);
959
}
960
961
static int snd_timer_s_start(struct snd_timer * timer)
962
{
963
struct snd_timer_system_private *priv;
964
unsigned long njiff;
965
966
priv = (struct snd_timer_system_private *) timer->private_data;
967
njiff = (priv->last_jiffies = jiffies);
968
if (priv->correction > timer->sticks - 1) {
969
priv->correction -= timer->sticks - 1;
970
njiff++;
971
} else {
972
njiff += timer->sticks - priv->correction;
973
priv->correction = 0;
974
}
975
priv->last_expires = priv->tlist.expires = njiff;
976
add_timer(&priv->tlist);
977
return 0;
978
}
979
980
static int snd_timer_s_stop(struct snd_timer * timer)
981
{
982
struct snd_timer_system_private *priv;
983
unsigned long jiff;
984
985
priv = (struct snd_timer_system_private *) timer->private_data;
986
del_timer(&priv->tlist);
987
jiff = jiffies;
988
if (time_before(jiff, priv->last_expires))
989
timer->sticks = priv->last_expires - jiff;
990
else
991
timer->sticks = 1;
992
priv->correction = 0;
993
return 0;
994
}
995
996
static struct snd_timer_hardware snd_timer_system =
997
{
998
.flags = SNDRV_TIMER_HW_FIRST | SNDRV_TIMER_HW_TASKLET,
999
.resolution = 1000000000L / HZ,
1000
.ticks = 10000000L,
1001
.start = snd_timer_s_start,
1002
.stop = snd_timer_s_stop
1003
};
1004
1005
static void snd_timer_free_system(struct snd_timer *timer)
1006
{
1007
kfree(timer->private_data);
1008
}
1009
1010
static int snd_timer_register_system(void)
1011
{
1012
struct snd_timer *timer;
1013
struct snd_timer_system_private *priv;
1014
int err;
1015
1016
err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer);
1017
if (err < 0)
1018
return err;
1019
strcpy(timer->name, "system timer");
1020
timer->hw = snd_timer_system;
1021
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1022
if (priv == NULL) {
1023
snd_timer_free(timer);
1024
return -ENOMEM;
1025
}
1026
init_timer(&priv->tlist);
1027
priv->tlist.function = snd_timer_s_function;
1028
priv->tlist.data = (unsigned long) timer;
1029
timer->private_data = priv;
1030
timer->private_free = snd_timer_free_system;
1031
return snd_timer_global_register(timer);
1032
}
1033
1034
#ifdef CONFIG_PROC_FS
1035
/*
1036
* Info interface
1037
*/
1038
1039
static void snd_timer_proc_read(struct snd_info_entry *entry,
1040
struct snd_info_buffer *buffer)
1041
{
1042
struct snd_timer *timer;
1043
struct snd_timer_instance *ti;
1044
1045
mutex_lock(&register_mutex);
1046
list_for_each_entry(timer, &snd_timer_list, device_list) {
1047
switch (timer->tmr_class) {
1048
case SNDRV_TIMER_CLASS_GLOBAL:
1049
snd_iprintf(buffer, "G%i: ", timer->tmr_device);
1050
break;
1051
case SNDRV_TIMER_CLASS_CARD:
1052
snd_iprintf(buffer, "C%i-%i: ",
1053
timer->card->number, timer->tmr_device);
1054
break;
1055
case SNDRV_TIMER_CLASS_PCM:
1056
snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number,
1057
timer->tmr_device, timer->tmr_subdevice);
1058
break;
1059
default:
1060
snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class,
1061
timer->card ? timer->card->number : -1,
1062
timer->tmr_device, timer->tmr_subdevice);
1063
}
1064
snd_iprintf(buffer, "%s :", timer->name);
1065
if (timer->hw.resolution)
1066
snd_iprintf(buffer, " %lu.%03luus (%lu ticks)",
1067
timer->hw.resolution / 1000,
1068
timer->hw.resolution % 1000,
1069
timer->hw.ticks);
1070
if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
1071
snd_iprintf(buffer, " SLAVE");
1072
snd_iprintf(buffer, "\n");
1073
list_for_each_entry(ti, &timer->open_list_head, open_list)
1074
snd_iprintf(buffer, " Client %s : %s\n",
1075
ti->owner ? ti->owner : "unknown",
1076
ti->flags & (SNDRV_TIMER_IFLG_START |
1077
SNDRV_TIMER_IFLG_RUNNING)
1078
? "running" : "stopped");
1079
}
1080
mutex_unlock(&register_mutex);
1081
}
1082
1083
static struct snd_info_entry *snd_timer_proc_entry;
1084
1085
static void __init snd_timer_proc_init(void)
1086
{
1087
struct snd_info_entry *entry;
1088
1089
entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL);
1090
if (entry != NULL) {
1091
entry->c.text.read = snd_timer_proc_read;
1092
if (snd_info_register(entry) < 0) {
1093
snd_info_free_entry(entry);
1094
entry = NULL;
1095
}
1096
}
1097
snd_timer_proc_entry = entry;
1098
}
1099
1100
static void __exit snd_timer_proc_done(void)
1101
{
1102
snd_info_free_entry(snd_timer_proc_entry);
1103
}
1104
#else /* !CONFIG_PROC_FS */
1105
#define snd_timer_proc_init()
1106
#define snd_timer_proc_done()
1107
#endif
1108
1109
/*
1110
* USER SPACE interface
1111
*/
1112
1113
static void snd_timer_user_interrupt(struct snd_timer_instance *timeri,
1114
unsigned long resolution,
1115
unsigned long ticks)
1116
{
1117
struct snd_timer_user *tu = timeri->callback_data;
1118
struct snd_timer_read *r;
1119
int prev;
1120
1121
spin_lock(&tu->qlock);
1122
if (tu->qused > 0) {
1123
prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1;
1124
r = &tu->queue[prev];
1125
if (r->resolution == resolution) {
1126
r->ticks += ticks;
1127
goto __wake;
1128
}
1129
}
1130
if (tu->qused >= tu->queue_size) {
1131
tu->overrun++;
1132
} else {
1133
r = &tu->queue[tu->qtail++];
1134
tu->qtail %= tu->queue_size;
1135
r->resolution = resolution;
1136
r->ticks = ticks;
1137
tu->qused++;
1138
}
1139
__wake:
1140
spin_unlock(&tu->qlock);
1141
kill_fasync(&tu->fasync, SIGIO, POLL_IN);
1142
wake_up(&tu->qchange_sleep);
1143
}
1144
1145
static void snd_timer_user_append_to_tqueue(struct snd_timer_user *tu,
1146
struct snd_timer_tread *tread)
1147
{
1148
if (tu->qused >= tu->queue_size) {
1149
tu->overrun++;
1150
} else {
1151
memcpy(&tu->tqueue[tu->qtail++], tread, sizeof(*tread));
1152
tu->qtail %= tu->queue_size;
1153
tu->qused++;
1154
}
1155
}
1156
1157
static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
1158
int event,
1159
struct timespec *tstamp,
1160
unsigned long resolution)
1161
{
1162
struct snd_timer_user *tu = timeri->callback_data;
1163
struct snd_timer_tread r1;
1164
unsigned long flags;
1165
1166
if (event >= SNDRV_TIMER_EVENT_START &&
1167
event <= SNDRV_TIMER_EVENT_PAUSE)
1168
tu->tstamp = *tstamp;
1169
if ((tu->filter & (1 << event)) == 0 || !tu->tread)
1170
return;
1171
r1.event = event;
1172
r1.tstamp = *tstamp;
1173
r1.val = resolution;
1174
spin_lock_irqsave(&tu->qlock, flags);
1175
snd_timer_user_append_to_tqueue(tu, &r1);
1176
spin_unlock_irqrestore(&tu->qlock, flags);
1177
kill_fasync(&tu->fasync, SIGIO, POLL_IN);
1178
wake_up(&tu->qchange_sleep);
1179
}
1180
1181
static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
1182
unsigned long resolution,
1183
unsigned long ticks)
1184
{
1185
struct snd_timer_user *tu = timeri->callback_data;
1186
struct snd_timer_tread *r, r1;
1187
struct timespec tstamp;
1188
int prev, append = 0;
1189
1190
memset(&tstamp, 0, sizeof(tstamp));
1191
spin_lock(&tu->qlock);
1192
if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) |
1193
(1 << SNDRV_TIMER_EVENT_TICK))) == 0) {
1194
spin_unlock(&tu->qlock);
1195
return;
1196
}
1197
if (tu->last_resolution != resolution || ticks > 0) {
1198
if (timer_tstamp_monotonic)
1199
do_posix_clock_monotonic_gettime(&tstamp);
1200
else
1201
getnstimeofday(&tstamp);
1202
}
1203
if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
1204
tu->last_resolution != resolution) {
1205
r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
1206
r1.tstamp = tstamp;
1207
r1.val = resolution;
1208
snd_timer_user_append_to_tqueue(tu, &r1);
1209
tu->last_resolution = resolution;
1210
append++;
1211
}
1212
if ((tu->filter & (1 << SNDRV_TIMER_EVENT_TICK)) == 0)
1213
goto __wake;
1214
if (ticks == 0)
1215
goto __wake;
1216
if (tu->qused > 0) {
1217
prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1;
1218
r = &tu->tqueue[prev];
1219
if (r->event == SNDRV_TIMER_EVENT_TICK) {
1220
r->tstamp = tstamp;
1221
r->val += ticks;
1222
append++;
1223
goto __wake;
1224
}
1225
}
1226
r1.event = SNDRV_TIMER_EVENT_TICK;
1227
r1.tstamp = tstamp;
1228
r1.val = ticks;
1229
snd_timer_user_append_to_tqueue(tu, &r1);
1230
append++;
1231
__wake:
1232
spin_unlock(&tu->qlock);
1233
if (append == 0)
1234
return;
1235
kill_fasync(&tu->fasync, SIGIO, POLL_IN);
1236
wake_up(&tu->qchange_sleep);
1237
}
1238
1239
static int snd_timer_user_open(struct inode *inode, struct file *file)
1240
{
1241
struct snd_timer_user *tu;
1242
int err;
1243
1244
err = nonseekable_open(inode, file);
1245
if (err < 0)
1246
return err;
1247
1248
tu = kzalloc(sizeof(*tu), GFP_KERNEL);
1249
if (tu == NULL)
1250
return -ENOMEM;
1251
spin_lock_init(&tu->qlock);
1252
init_waitqueue_head(&tu->qchange_sleep);
1253
mutex_init(&tu->tread_sem);
1254
tu->ticks = 1;
1255
tu->queue_size = 128;
1256
tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
1257
GFP_KERNEL);
1258
if (tu->queue == NULL) {
1259
kfree(tu);
1260
return -ENOMEM;
1261
}
1262
file->private_data = tu;
1263
return 0;
1264
}
1265
1266
static int snd_timer_user_release(struct inode *inode, struct file *file)
1267
{
1268
struct snd_timer_user *tu;
1269
1270
if (file->private_data) {
1271
tu = file->private_data;
1272
file->private_data = NULL;
1273
if (tu->timeri)
1274
snd_timer_close(tu->timeri);
1275
kfree(tu->queue);
1276
kfree(tu->tqueue);
1277
kfree(tu);
1278
}
1279
return 0;
1280
}
1281
1282
static void snd_timer_user_zero_id(struct snd_timer_id *id)
1283
{
1284
id->dev_class = SNDRV_TIMER_CLASS_NONE;
1285
id->dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1286
id->card = -1;
1287
id->device = -1;
1288
id->subdevice = -1;
1289
}
1290
1291
static void snd_timer_user_copy_id(struct snd_timer_id *id, struct snd_timer *timer)
1292
{
1293
id->dev_class = timer->tmr_class;
1294
id->dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1295
id->card = timer->card ? timer->card->number : -1;
1296
id->device = timer->tmr_device;
1297
id->subdevice = timer->tmr_subdevice;
1298
}
1299
1300
static int snd_timer_user_next_device(struct snd_timer_id __user *_tid)
1301
{
1302
struct snd_timer_id id;
1303
struct snd_timer *timer;
1304
struct list_head *p;
1305
1306
if (copy_from_user(&id, _tid, sizeof(id)))
1307
return -EFAULT;
1308
mutex_lock(&register_mutex);
1309
if (id.dev_class < 0) { /* first item */
1310
if (list_empty(&snd_timer_list))
1311
snd_timer_user_zero_id(&id);
1312
else {
1313
timer = list_entry(snd_timer_list.next,
1314
struct snd_timer, device_list);
1315
snd_timer_user_copy_id(&id, timer);
1316
}
1317
} else {
1318
switch (id.dev_class) {
1319
case SNDRV_TIMER_CLASS_GLOBAL:
1320
id.device = id.device < 0 ? 0 : id.device + 1;
1321
list_for_each(p, &snd_timer_list) {
1322
timer = list_entry(p, struct snd_timer, device_list);
1323
if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) {
1324
snd_timer_user_copy_id(&id, timer);
1325
break;
1326
}
1327
if (timer->tmr_device >= id.device) {
1328
snd_timer_user_copy_id(&id, timer);
1329
break;
1330
}
1331
}
1332
if (p == &snd_timer_list)
1333
snd_timer_user_zero_id(&id);
1334
break;
1335
case SNDRV_TIMER_CLASS_CARD:
1336
case SNDRV_TIMER_CLASS_PCM:
1337
if (id.card < 0) {
1338
id.card = 0;
1339
} else {
1340
if (id.card < 0) {
1341
id.card = 0;
1342
} else {
1343
if (id.device < 0) {
1344
id.device = 0;
1345
} else {
1346
if (id.subdevice < 0) {
1347
id.subdevice = 0;
1348
} else {
1349
id.subdevice++;
1350
}
1351
}
1352
}
1353
}
1354
list_for_each(p, &snd_timer_list) {
1355
timer = list_entry(p, struct snd_timer, device_list);
1356
if (timer->tmr_class > id.dev_class) {
1357
snd_timer_user_copy_id(&id, timer);
1358
break;
1359
}
1360
if (timer->tmr_class < id.dev_class)
1361
continue;
1362
if (timer->card->number > id.card) {
1363
snd_timer_user_copy_id(&id, timer);
1364
break;
1365
}
1366
if (timer->card->number < id.card)
1367
continue;
1368
if (timer->tmr_device > id.device) {
1369
snd_timer_user_copy_id(&id, timer);
1370
break;
1371
}
1372
if (timer->tmr_device < id.device)
1373
continue;
1374
if (timer->tmr_subdevice > id.subdevice) {
1375
snd_timer_user_copy_id(&id, timer);
1376
break;
1377
}
1378
if (timer->tmr_subdevice < id.subdevice)
1379
continue;
1380
snd_timer_user_copy_id(&id, timer);
1381
break;
1382
}
1383
if (p == &snd_timer_list)
1384
snd_timer_user_zero_id(&id);
1385
break;
1386
default:
1387
snd_timer_user_zero_id(&id);
1388
}
1389
}
1390
mutex_unlock(&register_mutex);
1391
if (copy_to_user(_tid, &id, sizeof(*_tid)))
1392
return -EFAULT;
1393
return 0;
1394
}
1395
1396
static int snd_timer_user_ginfo(struct file *file,
1397
struct snd_timer_ginfo __user *_ginfo)
1398
{
1399
struct snd_timer_ginfo *ginfo;
1400
struct snd_timer_id tid;
1401
struct snd_timer *t;
1402
struct list_head *p;
1403
int err = 0;
1404
1405
ginfo = memdup_user(_ginfo, sizeof(*ginfo));
1406
if (IS_ERR(ginfo))
1407
return PTR_ERR(ginfo);
1408
1409
tid = ginfo->tid;
1410
memset(ginfo, 0, sizeof(*ginfo));
1411
ginfo->tid = tid;
1412
mutex_lock(&register_mutex);
1413
t = snd_timer_find(&tid);
1414
if (t != NULL) {
1415
ginfo->card = t->card ? t->card->number : -1;
1416
if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
1417
ginfo->flags |= SNDRV_TIMER_FLG_SLAVE;
1418
strlcpy(ginfo->id, t->id, sizeof(ginfo->id));
1419
strlcpy(ginfo->name, t->name, sizeof(ginfo->name));
1420
ginfo->resolution = t->hw.resolution;
1421
if (t->hw.resolution_min > 0) {
1422
ginfo->resolution_min = t->hw.resolution_min;
1423
ginfo->resolution_max = t->hw.resolution_max;
1424
}
1425
list_for_each(p, &t->open_list_head) {
1426
ginfo->clients++;
1427
}
1428
} else {
1429
err = -ENODEV;
1430
}
1431
mutex_unlock(&register_mutex);
1432
if (err >= 0 && copy_to_user(_ginfo, ginfo, sizeof(*ginfo)))
1433
err = -EFAULT;
1434
kfree(ginfo);
1435
return err;
1436
}
1437
1438
static int snd_timer_user_gparams(struct file *file,
1439
struct snd_timer_gparams __user *_gparams)
1440
{
1441
struct snd_timer_gparams gparams;
1442
struct snd_timer *t;
1443
int err;
1444
1445
if (copy_from_user(&gparams, _gparams, sizeof(gparams)))
1446
return -EFAULT;
1447
mutex_lock(&register_mutex);
1448
t = snd_timer_find(&gparams.tid);
1449
if (!t) {
1450
err = -ENODEV;
1451
goto _error;
1452
}
1453
if (!list_empty(&t->open_list_head)) {
1454
err = -EBUSY;
1455
goto _error;
1456
}
1457
if (!t->hw.set_period) {
1458
err = -ENOSYS;
1459
goto _error;
1460
}
1461
err = t->hw.set_period(t, gparams.period_num, gparams.period_den);
1462
_error:
1463
mutex_unlock(&register_mutex);
1464
return err;
1465
}
1466
1467
static int snd_timer_user_gstatus(struct file *file,
1468
struct snd_timer_gstatus __user *_gstatus)
1469
{
1470
struct snd_timer_gstatus gstatus;
1471
struct snd_timer_id tid;
1472
struct snd_timer *t;
1473
int err = 0;
1474
1475
if (copy_from_user(&gstatus, _gstatus, sizeof(gstatus)))
1476
return -EFAULT;
1477
tid = gstatus.tid;
1478
memset(&gstatus, 0, sizeof(gstatus));
1479
gstatus.tid = tid;
1480
mutex_lock(&register_mutex);
1481
t = snd_timer_find(&tid);
1482
if (t != NULL) {
1483
if (t->hw.c_resolution)
1484
gstatus.resolution = t->hw.c_resolution(t);
1485
else
1486
gstatus.resolution = t->hw.resolution;
1487
if (t->hw.precise_resolution) {
1488
t->hw.precise_resolution(t, &gstatus.resolution_num,
1489
&gstatus.resolution_den);
1490
} else {
1491
gstatus.resolution_num = gstatus.resolution;
1492
gstatus.resolution_den = 1000000000uL;
1493
}
1494
} else {
1495
err = -ENODEV;
1496
}
1497
mutex_unlock(&register_mutex);
1498
if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus)))
1499
err = -EFAULT;
1500
return err;
1501
}
1502
1503
static int snd_timer_user_tselect(struct file *file,
1504
struct snd_timer_select __user *_tselect)
1505
{
1506
struct snd_timer_user *tu;
1507
struct snd_timer_select tselect;
1508
char str[32];
1509
int err = 0;
1510
1511
tu = file->private_data;
1512
mutex_lock(&tu->tread_sem);
1513
if (tu->timeri) {
1514
snd_timer_close(tu->timeri);
1515
tu->timeri = NULL;
1516
}
1517
if (copy_from_user(&tselect, _tselect, sizeof(tselect))) {
1518
err = -EFAULT;
1519
goto __err;
1520
}
1521
sprintf(str, "application %i", current->pid);
1522
if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE)
1523
tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION;
1524
err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid);
1525
if (err < 0)
1526
goto __err;
1527
1528
kfree(tu->queue);
1529
tu->queue = NULL;
1530
kfree(tu->tqueue);
1531
tu->tqueue = NULL;
1532
if (tu->tread) {
1533
tu->tqueue = kmalloc(tu->queue_size * sizeof(struct snd_timer_tread),
1534
GFP_KERNEL);
1535
if (tu->tqueue == NULL)
1536
err = -ENOMEM;
1537
} else {
1538
tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
1539
GFP_KERNEL);
1540
if (tu->queue == NULL)
1541
err = -ENOMEM;
1542
}
1543
1544
if (err < 0) {
1545
snd_timer_close(tu->timeri);
1546
tu->timeri = NULL;
1547
} else {
1548
tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST;
1549
tu->timeri->callback = tu->tread
1550
? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
1551
tu->timeri->ccallback = snd_timer_user_ccallback;
1552
tu->timeri->callback_data = (void *)tu;
1553
}
1554
1555
__err:
1556
mutex_unlock(&tu->tread_sem);
1557
return err;
1558
}
1559
1560
static int snd_timer_user_info(struct file *file,
1561
struct snd_timer_info __user *_info)
1562
{
1563
struct snd_timer_user *tu;
1564
struct snd_timer_info *info;
1565
struct snd_timer *t;
1566
int err = 0;
1567
1568
tu = file->private_data;
1569
if (!tu->timeri)
1570
return -EBADFD;
1571
t = tu->timeri->timer;
1572
if (!t)
1573
return -EBADFD;
1574
1575
info = kzalloc(sizeof(*info), GFP_KERNEL);
1576
if (! info)
1577
return -ENOMEM;
1578
info->card = t->card ? t->card->number : -1;
1579
if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
1580
info->flags |= SNDRV_TIMER_FLG_SLAVE;
1581
strlcpy(info->id, t->id, sizeof(info->id));
1582
strlcpy(info->name, t->name, sizeof(info->name));
1583
info->resolution = t->hw.resolution;
1584
if (copy_to_user(_info, info, sizeof(*_info)))
1585
err = -EFAULT;
1586
kfree(info);
1587
return err;
1588
}
1589
1590
static int snd_timer_user_params(struct file *file,
1591
struct snd_timer_params __user *_params)
1592
{
1593
struct snd_timer_user *tu;
1594
struct snd_timer_params params;
1595
struct snd_timer *t;
1596
struct snd_timer_read *tr;
1597
struct snd_timer_tread *ttr;
1598
int err;
1599
1600
tu = file->private_data;
1601
if (!tu->timeri)
1602
return -EBADFD;
1603
t = tu->timeri->timer;
1604
if (!t)
1605
return -EBADFD;
1606
if (copy_from_user(&params, _params, sizeof(params)))
1607
return -EFAULT;
1608
if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE) && params.ticks < 1) {
1609
err = -EINVAL;
1610
goto _end;
1611
}
1612
if (params.queue_size > 0 &&
1613
(params.queue_size < 32 || params.queue_size > 1024)) {
1614
err = -EINVAL;
1615
goto _end;
1616
}
1617
if (params.filter & ~((1<<SNDRV_TIMER_EVENT_RESOLUTION)|
1618
(1<<SNDRV_TIMER_EVENT_TICK)|
1619
(1<<SNDRV_TIMER_EVENT_START)|
1620
(1<<SNDRV_TIMER_EVENT_STOP)|
1621
(1<<SNDRV_TIMER_EVENT_CONTINUE)|
1622
(1<<SNDRV_TIMER_EVENT_PAUSE)|
1623
(1<<SNDRV_TIMER_EVENT_SUSPEND)|
1624
(1<<SNDRV_TIMER_EVENT_RESUME)|
1625
(1<<SNDRV_TIMER_EVENT_MSTART)|
1626
(1<<SNDRV_TIMER_EVENT_MSTOP)|
1627
(1<<SNDRV_TIMER_EVENT_MCONTINUE)|
1628
(1<<SNDRV_TIMER_EVENT_MPAUSE)|
1629
(1<<SNDRV_TIMER_EVENT_MSUSPEND)|
1630
(1<<SNDRV_TIMER_EVENT_MRESUME))) {
1631
err = -EINVAL;
1632
goto _end;
1633
}
1634
snd_timer_stop(tu->timeri);
1635
spin_lock_irq(&t->lock);
1636
tu->timeri->flags &= ~(SNDRV_TIMER_IFLG_AUTO|
1637
SNDRV_TIMER_IFLG_EXCLUSIVE|
1638
SNDRV_TIMER_IFLG_EARLY_EVENT);
1639
if (params.flags & SNDRV_TIMER_PSFLG_AUTO)
1640
tu->timeri->flags |= SNDRV_TIMER_IFLG_AUTO;
1641
if (params.flags & SNDRV_TIMER_PSFLG_EXCLUSIVE)
1642
tu->timeri->flags |= SNDRV_TIMER_IFLG_EXCLUSIVE;
1643
if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT)
1644
tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT;
1645
spin_unlock_irq(&t->lock);
1646
if (params.queue_size > 0 &&
1647
(unsigned int)tu->queue_size != params.queue_size) {
1648
if (tu->tread) {
1649
ttr = kmalloc(params.queue_size * sizeof(*ttr),
1650
GFP_KERNEL);
1651
if (ttr) {
1652
kfree(tu->tqueue);
1653
tu->queue_size = params.queue_size;
1654
tu->tqueue = ttr;
1655
}
1656
} else {
1657
tr = kmalloc(params.queue_size * sizeof(*tr),
1658
GFP_KERNEL);
1659
if (tr) {
1660
kfree(tu->queue);
1661
tu->queue_size = params.queue_size;
1662
tu->queue = tr;
1663
}
1664
}
1665
}
1666
tu->qhead = tu->qtail = tu->qused = 0;
1667
if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) {
1668
if (tu->tread) {
1669
struct snd_timer_tread tread;
1670
tread.event = SNDRV_TIMER_EVENT_EARLY;
1671
tread.tstamp.tv_sec = 0;
1672
tread.tstamp.tv_nsec = 0;
1673
tread.val = 0;
1674
snd_timer_user_append_to_tqueue(tu, &tread);
1675
} else {
1676
struct snd_timer_read *r = &tu->queue[0];
1677
r->resolution = 0;
1678
r->ticks = 0;
1679
tu->qused++;
1680
tu->qtail++;
1681
}
1682
}
1683
tu->filter = params.filter;
1684
tu->ticks = params.ticks;
1685
err = 0;
1686
_end:
1687
if (copy_to_user(_params, &params, sizeof(params)))
1688
return -EFAULT;
1689
return err;
1690
}
1691
1692
static int snd_timer_user_status(struct file *file,
1693
struct snd_timer_status __user *_status)
1694
{
1695
struct snd_timer_user *tu;
1696
struct snd_timer_status status;
1697
1698
tu = file->private_data;
1699
if (!tu->timeri)
1700
return -EBADFD;
1701
memset(&status, 0, sizeof(status));
1702
status.tstamp = tu->tstamp;
1703
status.resolution = snd_timer_resolution(tu->timeri);
1704
status.lost = tu->timeri->lost;
1705
status.overrun = tu->overrun;
1706
spin_lock_irq(&tu->qlock);
1707
status.queue = tu->qused;
1708
spin_unlock_irq(&tu->qlock);
1709
if (copy_to_user(_status, &status, sizeof(status)))
1710
return -EFAULT;
1711
return 0;
1712
}
1713
1714
static int snd_timer_user_start(struct file *file)
1715
{
1716
int err;
1717
struct snd_timer_user *tu;
1718
1719
tu = file->private_data;
1720
if (!tu->timeri)
1721
return -EBADFD;
1722
snd_timer_stop(tu->timeri);
1723
tu->timeri->lost = 0;
1724
tu->last_resolution = 0;
1725
return (err = snd_timer_start(tu->timeri, tu->ticks)) < 0 ? err : 0;
1726
}
1727
1728
static int snd_timer_user_stop(struct file *file)
1729
{
1730
int err;
1731
struct snd_timer_user *tu;
1732
1733
tu = file->private_data;
1734
if (!tu->timeri)
1735
return -EBADFD;
1736
return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0;
1737
}
1738
1739
static int snd_timer_user_continue(struct file *file)
1740
{
1741
int err;
1742
struct snd_timer_user *tu;
1743
1744
tu = file->private_data;
1745
if (!tu->timeri)
1746
return -EBADFD;
1747
tu->timeri->lost = 0;
1748
return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0;
1749
}
1750
1751
static int snd_timer_user_pause(struct file *file)
1752
{
1753
int err;
1754
struct snd_timer_user *tu;
1755
1756
tu = file->private_data;
1757
if (!tu->timeri)
1758
return -EBADFD;
1759
return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0;
1760
}
1761
1762
enum {
1763
SNDRV_TIMER_IOCTL_START_OLD = _IO('T', 0x20),
1764
SNDRV_TIMER_IOCTL_STOP_OLD = _IO('T', 0x21),
1765
SNDRV_TIMER_IOCTL_CONTINUE_OLD = _IO('T', 0x22),
1766
SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23),
1767
};
1768
1769
static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
1770
unsigned long arg)
1771
{
1772
struct snd_timer_user *tu;
1773
void __user *argp = (void __user *)arg;
1774
int __user *p = argp;
1775
1776
tu = file->private_data;
1777
switch (cmd) {
1778
case SNDRV_TIMER_IOCTL_PVERSION:
1779
return put_user(SNDRV_TIMER_VERSION, p) ? -EFAULT : 0;
1780
case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
1781
return snd_timer_user_next_device(argp);
1782
case SNDRV_TIMER_IOCTL_TREAD:
1783
{
1784
int xarg;
1785
1786
mutex_lock(&tu->tread_sem);
1787
if (tu->timeri) { /* too late */
1788
mutex_unlock(&tu->tread_sem);
1789
return -EBUSY;
1790
}
1791
if (get_user(xarg, p)) {
1792
mutex_unlock(&tu->tread_sem);
1793
return -EFAULT;
1794
}
1795
tu->tread = xarg ? 1 : 0;
1796
mutex_unlock(&tu->tread_sem);
1797
return 0;
1798
}
1799
case SNDRV_TIMER_IOCTL_GINFO:
1800
return snd_timer_user_ginfo(file, argp);
1801
case SNDRV_TIMER_IOCTL_GPARAMS:
1802
return snd_timer_user_gparams(file, argp);
1803
case SNDRV_TIMER_IOCTL_GSTATUS:
1804
return snd_timer_user_gstatus(file, argp);
1805
case SNDRV_TIMER_IOCTL_SELECT:
1806
return snd_timer_user_tselect(file, argp);
1807
case SNDRV_TIMER_IOCTL_INFO:
1808
return snd_timer_user_info(file, argp);
1809
case SNDRV_TIMER_IOCTL_PARAMS:
1810
return snd_timer_user_params(file, argp);
1811
case SNDRV_TIMER_IOCTL_STATUS:
1812
return snd_timer_user_status(file, argp);
1813
case SNDRV_TIMER_IOCTL_START:
1814
case SNDRV_TIMER_IOCTL_START_OLD:
1815
return snd_timer_user_start(file);
1816
case SNDRV_TIMER_IOCTL_STOP:
1817
case SNDRV_TIMER_IOCTL_STOP_OLD:
1818
return snd_timer_user_stop(file);
1819
case SNDRV_TIMER_IOCTL_CONTINUE:
1820
case SNDRV_TIMER_IOCTL_CONTINUE_OLD:
1821
return snd_timer_user_continue(file);
1822
case SNDRV_TIMER_IOCTL_PAUSE:
1823
case SNDRV_TIMER_IOCTL_PAUSE_OLD:
1824
return snd_timer_user_pause(file);
1825
}
1826
return -ENOTTY;
1827
}
1828
1829
static int snd_timer_user_fasync(int fd, struct file * file, int on)
1830
{
1831
struct snd_timer_user *tu;
1832
1833
tu = file->private_data;
1834
return fasync_helper(fd, file, on, &tu->fasync);
1835
}
1836
1837
static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
1838
size_t count, loff_t *offset)
1839
{
1840
struct snd_timer_user *tu;
1841
long result = 0, unit;
1842
int err = 0;
1843
1844
tu = file->private_data;
1845
unit = tu->tread ? sizeof(struct snd_timer_tread) : sizeof(struct snd_timer_read);
1846
spin_lock_irq(&tu->qlock);
1847
while ((long)count - result >= unit) {
1848
while (!tu->qused) {
1849
wait_queue_t wait;
1850
1851
if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
1852
err = -EAGAIN;
1853
break;
1854
}
1855
1856
set_current_state(TASK_INTERRUPTIBLE);
1857
init_waitqueue_entry(&wait, current);
1858
add_wait_queue(&tu->qchange_sleep, &wait);
1859
1860
spin_unlock_irq(&tu->qlock);
1861
schedule();
1862
spin_lock_irq(&tu->qlock);
1863
1864
remove_wait_queue(&tu->qchange_sleep, &wait);
1865
1866
if (signal_pending(current)) {
1867
err = -ERESTARTSYS;
1868
break;
1869
}
1870
}
1871
1872
spin_unlock_irq(&tu->qlock);
1873
if (err < 0)
1874
goto _error;
1875
1876
if (tu->tread) {
1877
if (copy_to_user(buffer, &tu->tqueue[tu->qhead++],
1878
sizeof(struct snd_timer_tread))) {
1879
err = -EFAULT;
1880
goto _error;
1881
}
1882
} else {
1883
if (copy_to_user(buffer, &tu->queue[tu->qhead++],
1884
sizeof(struct snd_timer_read))) {
1885
err = -EFAULT;
1886
goto _error;
1887
}
1888
}
1889
1890
tu->qhead %= tu->queue_size;
1891
1892
result += unit;
1893
buffer += unit;
1894
1895
spin_lock_irq(&tu->qlock);
1896
tu->qused--;
1897
}
1898
spin_unlock_irq(&tu->qlock);
1899
_error:
1900
return result > 0 ? result : err;
1901
}
1902
1903
static unsigned int snd_timer_user_poll(struct file *file, poll_table * wait)
1904
{
1905
unsigned int mask;
1906
struct snd_timer_user *tu;
1907
1908
tu = file->private_data;
1909
1910
poll_wait(file, &tu->qchange_sleep, wait);
1911
1912
mask = 0;
1913
if (tu->qused)
1914
mask |= POLLIN | POLLRDNORM;
1915
1916
return mask;
1917
}
1918
1919
#ifdef CONFIG_COMPAT
1920
#include "timer_compat.c"
1921
#else
1922
#define snd_timer_user_ioctl_compat NULL
1923
#endif
1924
1925
static const struct file_operations snd_timer_f_ops =
1926
{
1927
.owner = THIS_MODULE,
1928
.read = snd_timer_user_read,
1929
.open = snd_timer_user_open,
1930
.release = snd_timer_user_release,
1931
.llseek = no_llseek,
1932
.poll = snd_timer_user_poll,
1933
.unlocked_ioctl = snd_timer_user_ioctl,
1934
.compat_ioctl = snd_timer_user_ioctl_compat,
1935
.fasync = snd_timer_user_fasync,
1936
};
1937
1938
/*
1939
* ENTRY functions
1940
*/
1941
1942
static int __init alsa_timer_init(void)
1943
{
1944
int err;
1945
1946
#ifdef SNDRV_OSS_INFO_DEV_TIMERS
1947
snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1,
1948
"system timer");
1949
#endif
1950
1951
if ((err = snd_timer_register_system()) < 0)
1952
snd_printk(KERN_ERR "unable to register system timer (%i)\n",
1953
err);
1954
if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0,
1955
&snd_timer_f_ops, NULL, "timer")) < 0)
1956
snd_printk(KERN_ERR "unable to register timer device (%i)\n",
1957
err);
1958
snd_timer_proc_init();
1959
return 0;
1960
}
1961
1962
static void __exit alsa_timer_exit(void)
1963
{
1964
struct list_head *p, *n;
1965
1966
snd_unregister_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0);
1967
/* unregister the system timer */
1968
list_for_each_safe(p, n, &snd_timer_list) {
1969
struct snd_timer *timer = list_entry(p, struct snd_timer, device_list);
1970
snd_timer_free(timer);
1971
}
1972
snd_timer_proc_done();
1973
#ifdef SNDRV_OSS_INFO_DEV_TIMERS
1974
snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1);
1975
#endif
1976
}
1977
1978
module_init(alsa_timer_init)
1979
module_exit(alsa_timer_exit)
1980
1981
EXPORT_SYMBOL(snd_timer_open);
1982
EXPORT_SYMBOL(snd_timer_close);
1983
EXPORT_SYMBOL(snd_timer_resolution);
1984
EXPORT_SYMBOL(snd_timer_start);
1985
EXPORT_SYMBOL(snd_timer_stop);
1986
EXPORT_SYMBOL(snd_timer_continue);
1987
EXPORT_SYMBOL(snd_timer_pause);
1988
EXPORT_SYMBOL(snd_timer_new);
1989
EXPORT_SYMBOL(snd_timer_notify);
1990
EXPORT_SYMBOL(snd_timer_global_new);
1991
EXPORT_SYMBOL(snd_timer_global_free);
1992
EXPORT_SYMBOL(snd_timer_global_register);
1993
EXPORT_SYMBOL(snd_timer_interrupt);
1994
1995