1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 #ifndef __SOUND_TIMER_H
3 #define __SOUND_TIMER_H
7 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
8 * Abramo Bagnara <abramo@alsa-project.org>
11 #include <sound/asound.h>
12 #include <linux/interrupt.h>
14 #define snd_timer_chip(timer) ((timer)->private_data)
16 #define SNDRV_TIMER_DEVICES 16
18 #define SNDRV_TIMER_DEV_FLG_PCM 0x10000000
20 #define SNDRV_TIMER_HW_AUTO 0x00000001 /* auto trigger is supported */
21 #define SNDRV_TIMER_HW_STOP 0x00000002 /* call stop before start */
22 #define SNDRV_TIMER_HW_SLAVE 0x00000004 /* only slave timer (variable resolution) */
23 #define SNDRV_TIMER_HW_FIRST 0x00000008 /* first tick can be incomplete */
24 #define SNDRV_TIMER_HW_TASKLET 0x00000010 /* timer is called from tasklet */
26 #define SNDRV_TIMER_IFLG_SLAVE 0x00000001
27 #define SNDRV_TIMER_IFLG_RUNNING 0x00000002
28 #define SNDRV_TIMER_IFLG_START 0x00000004
29 #define SNDRV_TIMER_IFLG_AUTO 0x00000008 /* auto restart */
30 #define SNDRV_TIMER_IFLG_FAST 0x00000010 /* fast callback (do not use tasklet) */
31 #define SNDRV_TIMER_IFLG_CALLBACK 0x00000020 /* timer callback is active */
32 #define SNDRV_TIMER_IFLG_EXCLUSIVE 0x00000040 /* exclusive owner - no more instances */
33 #define SNDRV_TIMER_IFLG_EARLY_EVENT 0x00000080 /* write early event to the poll queue */
35 #define SNDRV_TIMER_FLG_CHANGE 0x00000001
36 #define SNDRV_TIMER_FLG_RESCHED 0x00000002 /* need reschedule */
40 struct snd_timer_hardware
{
41 /* -- must be filled with low-level driver */
42 unsigned int flags
; /* various flags */
43 unsigned long resolution
; /* average timer resolution for one tick in nsec */
44 unsigned long resolution_min
; /* minimal resolution */
45 unsigned long resolution_max
; /* maximal resolution */
46 unsigned long ticks
; /* max timer ticks per interrupt */
47 /* -- low-level functions -- */
48 int (*open
) (struct snd_timer
* timer
);
49 int (*close
) (struct snd_timer
* timer
);
50 unsigned long (*c_resolution
) (struct snd_timer
* timer
);
51 int (*start
) (struct snd_timer
* timer
);
52 int (*stop
) (struct snd_timer
* timer
);
53 int (*set_period
) (struct snd_timer
* timer
, unsigned long period_num
, unsigned long period_den
);
54 int (*precise_resolution
) (struct snd_timer
* timer
, unsigned long *num
, unsigned long *den
);
59 struct snd_card
*card
;
60 struct module
*module
;
66 int running
; /* running instances */
67 unsigned long sticks
; /* schedule ticks */
69 void (*private_free
) (struct snd_timer
*timer
);
70 struct snd_timer_hardware hw
;
72 struct list_head device_list
;
73 struct list_head open_list_head
;
74 struct list_head active_list_head
;
75 struct list_head ack_list_head
;
76 struct list_head sack_list_head
; /* slow ack list head */
77 struct tasklet_struct task_queue
;
78 int max_instances
; /* upper limit of timer instances */
79 int num_instances
; /* current number of timer instances */
82 struct snd_timer_instance
{
83 struct snd_timer
*timer
;
87 void (*private_free
) (struct snd_timer_instance
*ti
);
88 void (*callback
) (struct snd_timer_instance
*timeri
,
89 unsigned long ticks
, unsigned long resolution
);
90 void (*ccallback
) (struct snd_timer_instance
* timeri
,
92 struct timespec64
* tstamp
,
93 unsigned long resolution
);
94 void (*disconnect
)(struct snd_timer_instance
*timeri
);
96 unsigned long ticks
; /* auto-load ticks when expired */
97 unsigned long cticks
; /* current ticks */
98 unsigned long pticks
; /* accumulated ticks for callback */
99 unsigned long resolution
; /* current resolution for tasklet */
100 unsigned long lost
; /* lost ticks */
102 unsigned int slave_id
;
103 struct list_head open_list
;
104 struct list_head active_list
;
105 struct list_head ack_list
;
106 struct list_head slave_list_head
;
107 struct list_head slave_active_head
;
108 struct snd_timer_instance
*master
;
115 int snd_timer_new(struct snd_card
*card
, char *id
, struct snd_timer_id
*tid
, struct snd_timer
**rtimer
);
116 void snd_timer_notify(struct snd_timer
*timer
, int event
, struct timespec64
*tstamp
);
117 int snd_timer_global_new(char *id
, int device
, struct snd_timer
**rtimer
);
118 int snd_timer_global_free(struct snd_timer
*timer
);
119 int snd_timer_global_register(struct snd_timer
*timer
);
121 struct snd_timer_instance
*snd_timer_instance_new(const char *owner
);
122 void snd_timer_instance_free(struct snd_timer_instance
*timeri
);
123 int snd_timer_open(struct snd_timer_instance
*timeri
, struct snd_timer_id
*tid
, unsigned int slave_id
);
124 void snd_timer_close(struct snd_timer_instance
*timeri
);
125 unsigned long snd_timer_resolution(struct snd_timer_instance
*timeri
);
126 int snd_timer_start(struct snd_timer_instance
*timeri
, unsigned int ticks
);
127 int snd_timer_stop(struct snd_timer_instance
*timeri
);
128 int snd_timer_continue(struct snd_timer_instance
*timeri
);
129 int snd_timer_pause(struct snd_timer_instance
*timeri
);
131 void snd_timer_interrupt(struct snd_timer
*timer
, unsigned long ticks_left
);
133 #endif /* __SOUND_TIMER_H */