OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [sound/] [sys_timer.c] - Blame information for rev 1780

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * sound/sys_timer.c
3
 *
4
 * The default timer for the Level 2 sequencer interface
5
 * Uses the (1/HZ sec) timer of kernel.
6
 */
7
/*
8
 * Copyright (C) by Hannu Savolainen 1993-1997
9
 *
10
 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
11
 * Version 2 (June 1991). See the "COPYING" file distributed with this software
12
 * for more info.
13
 */
14
/*
15
 * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
16
 * Andrew Veliath  : adapted tmr2ticks from level 1 sequencer (avoid overflow)
17
 */
18
#include "sound_config.h"
19
 
20
static volatile int opened = 0, tmr_running = 0;
21
static volatile time_t tmr_offs, tmr_ctr;
22
static volatile unsigned long ticks_offs;
23
static volatile int curr_tempo, curr_timebase;
24
static volatile unsigned long curr_ticks;
25
static volatile unsigned long next_event_time;
26
static unsigned long prev_event_time;
27
 
28
static void     poll_def_tmr(unsigned long dummy);
29
 
30
 
31
static struct timer_list def_tmr =
32
{function: poll_def_tmr};
33
 
34
static unsigned long
35
tmr2ticks(int tmr_value)
36
{
37
        /*
38
         *    Convert timer ticks to MIDI ticks
39
         */
40
 
41
        unsigned long tmp;
42
        unsigned long scale;
43
 
44
        /* tmr_value (ticks per sec) *
45
           1000000 (usecs per sec) / HZ (ticks per sec) -=> usecs */
46
        tmp = tmr_value * (1000000 / HZ);
47
        scale = (60 * 1000000) / (curr_tempo * curr_timebase);  /* usecs per MIDI tick */
48
        return (tmp + scale / 2) / scale;
49
}
50
 
51
static void
52
poll_def_tmr(unsigned long dummy)
53
{
54
 
55
        if (opened)
56
          {
57
 
58
                  {
59
                          def_tmr.expires = (1) + jiffies;
60
                          add_timer(&def_tmr);
61
                  };
62
 
63
                  if (tmr_running)
64
                    {
65
                            tmr_ctr++;
66
                            curr_ticks = ticks_offs + tmr2ticks(tmr_ctr);
67
 
68
                            if (curr_ticks >= next_event_time)
69
                              {
70
                                      next_event_time = (unsigned long) -1;
71
                                      sequencer_timer(0);
72
                              }
73
                    }
74
          }
75
}
76
 
77
static void
78
tmr_reset(void)
79
{
80
        unsigned long   flags;
81
 
82
        save_flags(flags);
83
        cli();
84
        tmr_offs = 0;
85
        ticks_offs = 0;
86
        tmr_ctr = 0;
87
        next_event_time = (unsigned long) -1;
88
        prev_event_time = 0;
89
        curr_ticks = 0;
90
        restore_flags(flags);
91
}
92
 
93
static int
94
def_tmr_open(int dev, int mode)
95
{
96
        if (opened)
97
                return -EBUSY;
98
 
99
        tmr_reset();
100
        curr_tempo = 60;
101
        curr_timebase = 100;
102
        opened = 1;
103
 
104
        ;
105
 
106
        {
107
                def_tmr.expires = (1) + jiffies;
108
                add_timer(&def_tmr);
109
        };
110
 
111
        return 0;
112
}
113
 
114
static void
115
def_tmr_close(int dev)
116
{
117
        opened = tmr_running = 0;
118
        del_timer(&def_tmr);;
119
}
120
 
121
static int
122
def_tmr_event(int dev, unsigned char *event)
123
{
124
        unsigned char   cmd = event[1];
125
        unsigned long   parm = *(int *) &event[4];
126
 
127
        switch (cmd)
128
          {
129
          case TMR_WAIT_REL:
130
                  parm += prev_event_time;
131
          case TMR_WAIT_ABS:
132
                  if (parm > 0)
133
                    {
134
                            long            time;
135
 
136
                            if (parm <= curr_ticks)     /* It's the time */
137
                                    return TIMER_NOT_ARMED;
138
 
139
                            time = parm;
140
                            next_event_time = prev_event_time = time;
141
 
142
                            return TIMER_ARMED;
143
                    }
144
                  break;
145
 
146
          case TMR_START:
147
                  tmr_reset();
148
                  tmr_running = 1;
149
                  break;
150
 
151
          case TMR_STOP:
152
                  tmr_running = 0;
153
                  break;
154
 
155
          case TMR_CONTINUE:
156
                  tmr_running = 1;
157
                  break;
158
 
159
          case TMR_TEMPO:
160
                  if (parm)
161
                    {
162
                            if (parm < 8)
163
                                    parm = 8;
164
                            if (parm > 360)
165
                                    parm = 360;
166
                            tmr_offs = tmr_ctr;
167
                            ticks_offs += tmr2ticks(tmr_ctr);
168
                            tmr_ctr = 0;
169
                            curr_tempo = parm;
170
                    }
171
                  break;
172
 
173
          case TMR_ECHO:
174
                  seq_copy_to_input(event, 8);
175
                  break;
176
 
177
          default:;
178
          }
179
 
180
        return TIMER_NOT_ARMED;
181
}
182
 
183
static unsigned long
184
def_tmr_get_time(int dev)
185
{
186
        if (!opened)
187
                return 0;
188
 
189
        return curr_ticks;
190
}
191
 
192
/* same as sound_timer.c:timer_ioctl!? */
193
static int def_tmr_ioctl(int dev, unsigned int cmd, caddr_t arg)
194
{
195
        int val;
196
 
197
        switch (cmd) {
198
        case SNDCTL_TMR_SOURCE:
199
                return __put_user(TMR_INTERNAL, (int *)arg);
200
 
201
        case SNDCTL_TMR_START:
202
                tmr_reset();
203
                tmr_running = 1;
204
                return 0;
205
 
206
        case SNDCTL_TMR_STOP:
207
                tmr_running = 0;
208
                return 0;
209
 
210
        case SNDCTL_TMR_CONTINUE:
211
                tmr_running = 1;
212
                return 0;
213
 
214
        case SNDCTL_TMR_TIMEBASE:
215
                if (__get_user(val, (int *)arg))
216
                        return -EFAULT;
217
                if (val) {
218
                        if (val < 1)
219
                                val = 1;
220
                        if (val > 1000)
221
                                val = 1000;
222
                        curr_timebase = val;
223
                }
224
                return __put_user(curr_timebase, (int *)arg);
225
 
226
        case SNDCTL_TMR_TEMPO:
227
                if (__get_user(val, (int *)arg))
228
                        return -EFAULT;
229
                if (val) {
230
                        if (val < 8)
231
                                val = 8;
232
                        if (val > 250)
233
                                val = 250;
234
                        tmr_offs = tmr_ctr;
235
                        ticks_offs += tmr2ticks(tmr_ctr);
236
                        tmr_ctr = 0;
237
                        curr_tempo = val;
238
                        reprogram_timer();
239
                }
240
                return __put_user(curr_tempo, (int *)arg);
241
 
242
        case SNDCTL_SEQ_CTRLRATE:
243
                if (__get_user(val, (int *)arg))
244
                        return -EFAULT;
245
                if (val != 0)    /* Can't change */
246
                        return -EINVAL;
247
                val = ((curr_tempo * curr_timebase) + 30) / 60;
248
                return __put_user(val, (int *)arg);
249
 
250
        case SNDCTL_SEQ_GETTIME:
251
                return __put_user(curr_ticks, (int *)arg);
252
 
253
        case SNDCTL_TMR_METRONOME:
254
                /* NOP */
255
                break;
256
 
257
        default:;
258
        }
259
        return -EINVAL;
260
}
261
 
262
static void
263
def_tmr_arm(int dev, long time)
264
{
265
        if (time < 0)
266
                time = curr_ticks + 1;
267
        else if (time <= curr_ticks)    /* It's the time */
268
                return;
269
 
270
        next_event_time = prev_event_time = time;
271
 
272
        return;
273
}
274
 
275
struct sound_timer_operations default_sound_timer =
276
{
277
        owner:          THIS_MODULE,
278
        info:           {"System clock", 0},
279
        priority:       0,       /* Priority */
280
        devlink:        0,       /* Local device link */
281
        open:           def_tmr_open,
282
        close:          def_tmr_close,
283
        event:          def_tmr_event,
284
        get_time:       def_tmr_get_time,
285
        ioctl:          def_tmr_ioctl,
286
        arm_timer:      def_tmr_arm
287
};

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.