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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [sound/] [sys_timer.c] - Blame information for rev 1626

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

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

powered by: WebSVN 2.1.0

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