Import 1.3.39
[davej-history.git] / drivers / sound / sys_timer.c
blobe251ee25cf8213d362d130c91afd1b56ef06254f
1 /*
2 * sound/sys_timer.c
4 * The default timer for the Level 2 sequencer interface
5 * Uses the (100HZ) timer of kernel.
7 * Copyright by Hannu Savolainen 1993
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are
11 * met: 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 2.
13 * Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
31 #define SEQUENCER_C
32 #include "sound_config.h"
34 #ifdef CONFIGURE_SOUNDCARD
36 #ifndef EXCLUDE_SEQUENCER
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;
46 static void poll_def_tmr (unsigned long dummy);
49 static struct timer_list def_tmr =
50 {NULL, NULL, 0, 0, poll_def_tmr};
52 static unsigned long
53 tmr2ticks (int tmr_value)
56 * Convert system timer ticks (HZ) to MIDI ticks
57 * (divide # of MIDI ticks/minute by # of system ticks/minute).
60 return ((tmr_value * curr_tempo * curr_timebase) + (30 * HZ)) / (60 * HZ);
63 static void
64 poll_def_tmr (unsigned long dummy)
67 if (opened)
71 def_tmr.expires = (1) + jiffies;
72 add_timer (&def_tmr);
75 if (tmr_running)
77 tmr_ctr++;
78 curr_ticks = ticks_offs + tmr2ticks (tmr_ctr);
80 if (curr_ticks >= next_event_time)
82 next_event_time = 0xffffffff;
83 sequencer_timer (0);
89 static void
90 tmr_reset (void)
92 unsigned long flags;
94 save_flags (flags);
95 cli ();
96 tmr_offs = 0;
97 ticks_offs = 0;
98 tmr_ctr = 0;
99 next_event_time = 0xffffffff;
100 prev_event_time = 0;
101 curr_ticks = 0;
102 restore_flags (flags);
105 static int
106 def_tmr_open (int dev, int mode)
108 if (opened)
109 return -EBUSY;
111 tmr_reset ();
112 curr_tempo = 60;
113 curr_timebase = HZ;
114 opened = 1;
118 def_tmr.expires = (1) + jiffies;
119 add_timer (&def_tmr);
122 return 0;
125 static void
126 def_tmr_close (int dev)
128 opened = tmr_running = 0;
129 del_timer (&def_tmr);;
132 static int
133 def_tmr_event (int dev, unsigned char *event)
135 unsigned char cmd = event[1];
136 unsigned long parm = *(int *) &event[4];
138 switch (cmd)
140 case TMR_WAIT_REL:
141 parm += prev_event_time;
142 case TMR_WAIT_ABS:
143 if (parm > 0)
145 long time;
147 if (parm <= curr_ticks) /* It's the time */
148 return TIMER_NOT_ARMED;
150 time = parm;
151 next_event_time = prev_event_time = time;
153 return TIMER_ARMED;
155 break;
157 case TMR_START:
158 tmr_reset ();
159 tmr_running = 1;
160 break;
162 case TMR_STOP:
163 tmr_running = 0;
164 break;
166 case TMR_CONTINUE:
167 tmr_running = 1;
168 break;
170 case TMR_TEMPO:
171 if (parm)
173 if (parm < 8)
174 parm = 8;
175 if (parm > 360)
176 parm = 360;
177 tmr_offs = tmr_ctr;
178 ticks_offs += tmr2ticks (tmr_ctr);
179 tmr_ctr = 0;
180 curr_tempo = parm;
182 break;
184 case TMR_ECHO:
185 seq_copy_to_input (event, 8);
186 break;
188 default:;
191 return TIMER_NOT_ARMED;
194 static unsigned long
195 def_tmr_get_time (int dev)
197 if (!opened)
198 return 0;
200 return curr_ticks;
203 static int
204 def_tmr_ioctl (int dev,
205 unsigned int cmd, ioctl_arg arg)
207 switch (cmd)
209 case SNDCTL_TMR_SOURCE:
210 return snd_ioctl_return ((int *) arg, TMR_INTERNAL);
211 break;
213 case SNDCTL_TMR_START:
214 tmr_reset ();
215 tmr_running = 1;
216 return 0;
217 break;
219 case SNDCTL_TMR_STOP:
220 tmr_running = 0;
221 return 0;
222 break;
224 case SNDCTL_TMR_CONTINUE:
225 tmr_running = 1;
226 return 0;
227 break;
229 case SNDCTL_TMR_TIMEBASE:
231 int val = get_fs_long ((long *) arg);
233 if (val)
235 if (val < 1)
236 val = 1;
237 if (val > 1000)
238 val = 1000;
239 curr_timebase = val;
242 return snd_ioctl_return ((int *) arg, curr_timebase);
244 break;
246 case SNDCTL_TMR_TEMPO:
248 int val = get_fs_long ((long *) arg);
250 if (val)
252 if (val < 8)
253 val = 8;
254 if (val > 250)
255 val = 250;
256 tmr_offs = tmr_ctr;
257 ticks_offs += tmr2ticks (tmr_ctr);
258 tmr_ctr = 0;
259 curr_tempo = val;
262 return snd_ioctl_return ((int *) arg, curr_tempo);
264 break;
266 case SNDCTL_SEQ_CTRLRATE:
267 if (get_fs_long ((long *) arg) != 0) /* Can't change */
268 return -EINVAL;
270 return snd_ioctl_return ((int *) arg, ((curr_tempo * curr_timebase) + 30) / 60);
271 break;
273 case SNDCTL_TMR_METRONOME:
274 /* NOP */
275 break;
277 default:;
280 return -EINVAL;
283 static void
284 def_tmr_arm (int dev, long time)
286 if (time < 0)
287 time = curr_ticks + 1;
288 else if (time <= curr_ticks) /* It's the time */
289 return;
291 next_event_time = prev_event_time = time;
293 return;
296 struct sound_timer_operations default_sound_timer =
298 {"System clock", 0},
299 0, /* Priority */
300 0, /* Local device link */
301 def_tmr_open,
302 def_tmr_close,
303 def_tmr_event,
304 def_tmr_get_time,
305 def_tmr_ioctl,
306 def_tmr_arm
309 #endif
310 #endif