Merge tag 'scsi-sg' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[sfrench/cifs-2.6.git] / include / sound / timer.h
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 #ifndef __SOUND_TIMER_H
3 #define __SOUND_TIMER_H
4
5 /*
6  *  Timer abstract layer
7  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
8  *                   Abramo Bagnara <abramo@alsa-project.org>
9  */
10
11 #include <sound/asound.h>
12 #include <linux/interrupt.h>
13
14 #define snd_timer_chip(timer) ((timer)->private_data)
15
16 #define SNDRV_TIMER_DEVICES     16
17
18 #define SNDRV_TIMER_DEV_FLG_PCM 0x10000000
19
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 */
25
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 */
34
35 #define SNDRV_TIMER_FLG_CHANGE  0x00000001
36 #define SNDRV_TIMER_FLG_RESCHED 0x00000002      /* need reschedule */
37
38 struct snd_timer;
39
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);
55 };
56
57 struct snd_timer {
58         int tmr_class;
59         struct snd_card *card;
60         struct module *module;
61         int tmr_device;
62         int tmr_subdevice;
63         char id[64];
64         char name[80];
65         unsigned int flags;
66         int running;                    /* running instances */
67         unsigned long sticks;           /* schedule ticks */
68         void *private_data;
69         void (*private_free) (struct snd_timer *timer);
70         struct snd_timer_hardware hw;
71         spinlock_t lock;
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 */
80 };
81
82 struct snd_timer_instance {
83         struct snd_timer *timer;
84         char *owner;
85         unsigned int flags;
86         void *private_data;
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,
91                            int event,
92                            struct timespec * tstamp,
93                            unsigned long resolution);
94         void (*disconnect)(struct snd_timer_instance *timeri);
95         void *callback_data;
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 */
101         int slave_class;
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;
109 };
110
111 /*
112  *  Registering
113  */
114
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 timespec *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);
120
121 int snd_timer_open(struct snd_timer_instance **ti, char *owner, struct snd_timer_id *tid, unsigned int slave_id);
122 int snd_timer_close(struct snd_timer_instance *timeri);
123 unsigned long snd_timer_resolution(struct snd_timer_instance *timeri);
124 int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks);
125 int snd_timer_stop(struct snd_timer_instance *timeri);
126 int snd_timer_continue(struct snd_timer_instance *timeri);
127 int snd_timer_pause(struct snd_timer_instance *timeri);
128
129 void snd_timer_interrupt(struct snd_timer *timer, unsigned long ticks_left);
130
131 #endif /* __SOUND_TIMER_H */