This source file includes following definitions.
- tmr2ticks
- poll_def_tmr
- tmr_reset
- def_tmr_open
- def_tmr_close
- def_tmr_event
- def_tmr_get_time
- def_tmr_ioctl
- def_tmr_arm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include <linux/config.h>
31
32
33 #define SEQUENCER_C
34 #include "sound_config.h"
35
36 #ifdef CONFIG_SEQUENCER
37
38 static volatile int opened = 0, tmr_running = 0;
39 static volatile time_t tmr_offs, tmr_ctr;
40 static volatile unsigned long ticks_offs;
41 static volatile int curr_tempo, curr_timebase;
42 static volatile unsigned long curr_ticks;
43 static volatile unsigned long next_event_time;
44 static unsigned long prev_event_time;
45
46 static void poll_def_tmr (unsigned long dummy);
47
48
49 static struct timer_list def_tmr =
50 {NULL, NULL, 0, 0, poll_def_tmr};
51
52 static unsigned long
53 tmr2ticks (int tmr_value)
54 {
55
56
57
58
59
60 return ((tmr_value * curr_tempo * curr_timebase) + (30 * 100)) / (60 * HZ);
61 }
62
63 static void
64 poll_def_tmr (unsigned long dummy)
65 {
66
67 if (opened)
68 {
69
70 {
71 def_tmr.expires = (1) + jiffies;
72 add_timer (&def_tmr);
73 };
74
75 if (tmr_running)
76 {
77 tmr_ctr++;
78 curr_ticks = ticks_offs + tmr2ticks (tmr_ctr);
79
80 if (curr_ticks >= next_event_time)
81 {
82 next_event_time = (unsigned long) -1;
83 sequencer_timer (0);
84 }
85 }
86 }
87 }
88
89 static void
90 tmr_reset (void)
91 {
92 unsigned long flags;
93
94 save_flags (flags);
95 cli ();
96 tmr_offs = 0;
97 ticks_offs = 0;
98 tmr_ctr = 0;
99 next_event_time = (unsigned long) -1;
100 prev_event_time = 0;
101 curr_ticks = 0;
102 restore_flags (flags);
103 }
104
105 static int
106 def_tmr_open (int dev, int mode)
107 {
108 if (opened)
109 return -EBUSY;
110
111 tmr_reset ();
112 curr_tempo = 60;
113 curr_timebase = 100;
114 opened = 1;
115
116 ;
117
118 {
119 def_tmr.expires = (1) + jiffies;
120 add_timer (&def_tmr);
121 };
122
123 return 0;
124 }
125
126 static void
127 def_tmr_close (int dev)
128 {
129 opened = tmr_running = 0;
130 del_timer (&def_tmr);;
131 }
132
133 static int
134 def_tmr_event (int dev, unsigned char *event)
135 {
136 unsigned char cmd = event[1];
137 unsigned long parm = *(int *) &event[4];
138
139 switch (cmd)
140 {
141 case TMR_WAIT_REL:
142 parm += prev_event_time;
143 case TMR_WAIT_ABS:
144 if (parm > 0)
145 {
146 long time;
147
148 if (parm <= curr_ticks)
149 return TIMER_NOT_ARMED;
150
151 time = parm;
152 next_event_time = prev_event_time = time;
153
154 return TIMER_ARMED;
155 }
156 break;
157
158 case TMR_START:
159 tmr_reset ();
160 tmr_running = 1;
161 break;
162
163 case TMR_STOP:
164 tmr_running = 0;
165 break;
166
167 case TMR_CONTINUE:
168 tmr_running = 1;
169 break;
170
171 case TMR_TEMPO:
172 if (parm)
173 {
174 if (parm < 8)
175 parm = 8;
176 if (parm > 360)
177 parm = 360;
178 tmr_offs = tmr_ctr;
179 ticks_offs += tmr2ticks (tmr_ctr);
180 tmr_ctr = 0;
181 curr_tempo = parm;
182 }
183 break;
184
185 case TMR_ECHO:
186 seq_copy_to_input (event, 8);
187 break;
188
189 default:;
190 }
191
192 return TIMER_NOT_ARMED;
193 }
194
195 static unsigned long
196 def_tmr_get_time (int dev)
197 {
198 if (!opened)
199 return 0;
200
201 return curr_ticks;
202 }
203
204 static int
205 def_tmr_ioctl (int dev,
206 unsigned int cmd, caddr_t arg)
207 {
208 switch (cmd)
209 {
210 case SNDCTL_TMR_SOURCE:
211 return snd_ioctl_return ((int *) arg, TMR_INTERNAL);
212 break;
213
214 case SNDCTL_TMR_START:
215 tmr_reset ();
216 tmr_running = 1;
217 return 0;
218 break;
219
220 case SNDCTL_TMR_STOP:
221 tmr_running = 0;
222 return 0;
223 break;
224
225 case SNDCTL_TMR_CONTINUE:
226 tmr_running = 1;
227 return 0;
228 break;
229
230 case SNDCTL_TMR_TIMEBASE:
231 {
232 int val = get_fs_long ((long *) arg);
233
234 if (val)
235 {
236 if (val < 1)
237 val = 1;
238 if (val > 1000)
239 val = 1000;
240 curr_timebase = val;
241 }
242
243 return snd_ioctl_return ((int *) arg, curr_timebase);
244 }
245 break;
246
247 case SNDCTL_TMR_TEMPO:
248 {
249 int val = get_fs_long ((long *) arg);
250
251 if (val)
252 {
253 if (val < 8)
254 val = 8;
255 if (val > 250)
256 val = 250;
257 tmr_offs = tmr_ctr;
258 ticks_offs += tmr2ticks (tmr_ctr);
259 tmr_ctr = 0;
260 curr_tempo = val;
261 }
262
263 return snd_ioctl_return ((int *) arg, curr_tempo);
264 }
265 break;
266
267 case SNDCTL_SEQ_CTRLRATE:
268 if (get_fs_long ((long *) arg) != 0)
269 return -EINVAL;
270
271 return snd_ioctl_return ((int *) arg, ((curr_tempo * curr_timebase) + 30) / 60);
272 break;
273
274 case SNDCTL_TMR_METRONOME:
275
276 break;
277
278 default:;
279 }
280
281 return -EINVAL;
282 }
283
284 static void
285 def_tmr_arm (int dev, long time)
286 {
287 if (time < 0)
288 time = curr_ticks + 1;
289 else if (time <= curr_ticks)
290 return;
291
292 next_event_time = prev_event_time = time;
293
294 return;
295 }
296
297 struct sound_timer_operations default_sound_timer =
298 {
299 {"System clock", 0},
300 0,
301 0,
302 def_tmr_open,
303 def_tmr_close,
304 def_tmr_event,
305 def_tmr_get_time,
306 def_tmr_ioctl,
307 def_tmr_arm
308 };
309
310 #endif