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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [sound/] [pas2_midi.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/pas2_midi.c
3
 *
4
 * The low level driver for the PAS Midi Interface.
5
 */
6
 
7
#include <linux/config.h>
8
 
9
#include "sound_config.h"
10
 
11
#if defined(CONFIG_PAS) && defined(CONFIG_MIDI)
12
 
13
static int      midi_busy = 0, input_opened = 0;
14
static int      my_dev;
15
static volatile int ofifo_bytes = 0;
16
 
17
static unsigned char tmp_queue[256];
18
static volatile int qlen;
19
static volatile unsigned char qhead, qtail;
20
 
21
static void     (*midi_input_intr) (int dev, unsigned char data);
22
 
23
static int
24
pas_midi_open (int dev, int mode,
25
               void            (*input) (int dev, unsigned char data),
26
               void            (*output) (int dev)
27
)
28
{
29
  int             err;
30
  unsigned long   flags;
31
  unsigned char   ctrl;
32
 
33
 
34
  if (midi_busy)
35
    {
36
      printk ("PAS2: Midi busy\n");
37
      return -(EBUSY);
38
    }
39
 
40
  /*
41
   * Reset input and output FIFO pointers
42
   */
43
  pas_write (0x20 | 0x40,
44
             0x178b);
45
 
46
  save_flags (flags);
47
  cli ();
48
 
49
  if ((err = pas_set_intr (0x10)) < 0)
50
    return err;
51
 
52
  /*
53
   * Enable input available and output FIFO empty interrupts
54
   */
55
 
56
  ctrl = 0;
57
  input_opened = 0;
58
  midi_input_intr = input;
59
 
60
  if (mode == OPEN_READ || mode == OPEN_READWRITE)
61
    {
62
      ctrl |= 0x04;             /*
63
                                   * Enable input
64
                                 */
65
      input_opened = 1;
66
    }
67
 
68
  if (mode == OPEN_WRITE || mode == OPEN_READWRITE)
69
    {
70
      ctrl |= 0x08 |            /*
71
                                   * Enable output
72
                                 */
73
        0x10;
74
    }
75
 
76
  pas_write (ctrl,
77
             0x178b);
78
 
79
  /*
80
   * Acknowledge any pending interrupts
81
   */
82
 
83
  pas_write (0xff, 0x1B88);
84
  ofifo_bytes = 0;
85
 
86
  restore_flags (flags);
87
 
88
  midi_busy = 1;
89
  qlen = qhead = qtail = 0;
90
  return 0;
91
}
92
 
93
static void
94
pas_midi_close (int dev)
95
{
96
 
97
  /*
98
   * Reset FIFO pointers, disable intrs
99
   */
100
  pas_write (0x20 | 0x40, 0x178b);
101
 
102
  pas_remove_intr (0x10);
103
  midi_busy = 0;
104
}
105
 
106
static int
107
dump_to_midi (unsigned char midi_byte)
108
{
109
  int             fifo_space, x;
110
 
111
  fifo_space = ((x = pas_read (0x1B89)) >> 4) & 0x0f;
112
 
113
  if (fifo_space == 15 || (fifo_space < 2 && ofifo_bytes > 13))         /*
114
                                                                           * Fifo
115
                                                                           * full
116
                                                                         */
117
    {
118
      return 0;                  /*
119
                                 * Upper layer will call again
120
                                 */
121
    }
122
 
123
  ofifo_bytes++;
124
 
125
  pas_write (midi_byte, 0x178A);
126
 
127
  return 1;
128
}
129
 
130
static int
131
pas_midi_out (int dev, unsigned char midi_byte)
132
{
133
 
134
  unsigned long   flags;
135
 
136
  /*
137
   * Drain the local queue first
138
   */
139
 
140
  save_flags (flags);
141
  cli ();
142
 
143
  while (qlen && dump_to_midi (tmp_queue[qhead]))
144
    {
145
      qlen--;
146
      qhead++;
147
    }
148
 
149
  restore_flags (flags);
150
 
151
  /*
152
   * Output the byte if the local queue is empty.
153
   */
154
 
155
  if (!qlen)
156
    if (dump_to_midi (midi_byte))
157
      return 1;                 /*
158
                                 * OK
159
                                 */
160
 
161
  /*
162
   * Put to the local queue
163
   */
164
 
165
  if (qlen >= 256)
166
    return 0;                    /*
167
                                 * Local queue full
168
                                 */
169
 
170
  save_flags (flags);
171
  cli ();
172
 
173
  tmp_queue[qtail] = midi_byte;
174
  qlen++;
175
  qtail++;
176
 
177
  restore_flags (flags);
178
 
179
  return 1;
180
}
181
 
182
static int
183
pas_midi_start_read (int dev)
184
{
185
  return 0;
186
}
187
 
188
static int
189
pas_midi_end_read (int dev)
190
{
191
  return 0;
192
}
193
 
194
static int
195
pas_midi_ioctl (int dev, unsigned cmd, caddr_t arg)
196
{
197
  return -(EINVAL);
198
}
199
 
200
static void
201
pas_midi_kick (int dev)
202
{
203
  ofifo_bytes = 0;
204
}
205
 
206
static int
207
pas_buffer_status (int dev)
208
{
209
  return qlen;
210
}
211
 
212
#define MIDI_SYNTH_NAME "Pro Audio Spectrum Midi"
213
#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
214
#include "midi_synth.h"
215
 
216
static struct midi_operations pas_midi_operations =
217
{
218
  {"Pro Audio Spectrum", 0, 0, SNDCARD_PAS},
219
  &std_midi_synth,
220
  {0},
221
  pas_midi_open,
222
  pas_midi_close,
223
  pas_midi_ioctl,
224
  pas_midi_out,
225
  pas_midi_start_read,
226
  pas_midi_end_read,
227
  pas_midi_kick,
228
  NULL,                         /*
229
                                 * command
230
                                 */
231
  pas_buffer_status,
232
  NULL
233
};
234
 
235
void
236
pas_midi_init (void)
237
{
238
  if (num_midis >= MAX_MIDI_DEV)
239
    {
240
      printk ("Sound: Too many midi devices detected\n");
241
      return;
242
    }
243
 
244
  std_midi_synth.midi_dev = my_dev = num_midis;
245
  midi_devs[num_midis++] = &pas_midi_operations;
246
}
247
 
248
void
249
pas_midi_interrupt (void)
250
{
251
  unsigned char   stat;
252
  int             i, incount;
253
  unsigned long   flags;
254
 
255
  stat = pas_read (0x1B88);
256
 
257
  if (stat & 0x04)              /*
258
                                   * Input byte available
259
                                 */
260
    {
261
      incount = pas_read (0x1B89) & 0x0f;       /*
262
                                                   * Input FIFO count
263
                                                 */
264
      if (!incount)
265
        incount = 16;
266
 
267
      for (i = 0; i < incount; i++)
268
        if (input_opened)
269
          {
270
            midi_input_intr (my_dev, pas_read (0x178A));
271
          }
272
        else
273
          pas_read (0x178A);    /*
274
                                 * Flush
275
                                 */
276
    }
277
 
278
  if (stat & (0x08 | 0x10))
279
    {
280
      if (!(stat & 0x08))
281
        {
282
          ofifo_bytes = 8;
283
        }
284
      else
285
        {
286
          ofifo_bytes = 0;
287
        }
288
 
289
      save_flags (flags);
290
      cli ();
291
 
292
      while (qlen && dump_to_midi (tmp_queue[qhead]))
293
        {
294
          qlen--;
295
          qhead++;
296
        }
297
 
298
      restore_flags (flags);
299
    }
300
 
301
 
302
  if (stat & 0x40)
303
    {
304
      printk ("MIDI output overrun %x,%x,%d \n", pas_read (0x1B89), stat, ofifo_bytes);
305
      ofifo_bytes = 100;
306
    }
307
 
308
  pas_write (stat, 0x1B88);     /*
309
                                   * Acknowledge interrupts
310
                                 */
311
}
312
 
313
#endif

powered by: WebSVN 2.1.0

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