This source file includes following definitions.
- pas_midi_open
- pas_midi_close
- dump_to_midi
- pas_midi_out
- pas_midi_start_read
- pas_midi_end_read
- pas_midi_ioctl
- pas_midi_kick
- pas_buffer_status
- pas_midi_init
- pas_midi_interrupt
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 "sound_config.h"
31
32 #ifdef CONFIGURE_SOUNDCARD
33
34 #include "pas.h"
35
36 #if !defined(EXCLUDE_PAS) && !defined(EXCLUDE_MIDI)
37
38 static int midi_busy = 0, input_opened = 0;
39 static int my_dev;
40 static volatile int ofifo_bytes = 0;
41
42 static unsigned char tmp_queue[256];
43 static volatile int qlen;
44 static volatile unsigned char qhead, qtail;
45
46 static void (*midi_input_intr) (int dev, unsigned char data);
47
48 static int
49 pas_midi_open (int dev, int mode,
50 void (*input) (int dev, unsigned char data),
51 void (*output) (int dev)
52 )
53 {
54 int err;
55 unsigned long flags;
56 unsigned char ctrl;
57
58
59 if (midi_busy)
60 {
61 printk ("PAS2: Midi busy\n");
62 return RET_ERROR (EBUSY);
63 }
64
65
66
67
68 pas_write (M_C_RESET_INPUT_FIFO | M_C_RESET_OUTPUT_FIFO,
69 MIDI_CONTROL);
70
71 DISABLE_INTR (flags);
72
73 if ((err = pas_set_intr (I_M_MIDI_IRQ_ENABLE)) < 0)
74 return err;
75
76
77
78
79
80 ctrl = 0;
81 input_opened = 0;
82 midi_input_intr = input;
83
84 if (mode == OPEN_READ || mode == OPEN_READWRITE)
85 {
86 ctrl |= M_C_ENA_INPUT_IRQ;
87
88
89 input_opened = 1;
90 }
91
92 if (mode == OPEN_WRITE || mode == OPEN_READWRITE)
93 {
94 ctrl |= M_C_ENA_OUTPUT_IRQ |
95
96
97 M_C_ENA_OUTPUT_HALF_IRQ;
98 }
99
100 pas_write (ctrl,
101 MIDI_CONTROL);
102
103
104
105
106
107 pas_write (0xff, MIDI_STATUS);
108 ofifo_bytes = 0;
109
110 RESTORE_INTR (flags);
111
112 midi_busy = 1;
113 qlen = qhead = qtail = 0;
114 return 0;
115 }
116
117 static void
118 pas_midi_close (int dev)
119 {
120
121
122
123
124 pas_write (M_C_RESET_INPUT_FIFO | M_C_RESET_OUTPUT_FIFO, MIDI_CONTROL);
125
126 pas_remove_intr (I_M_MIDI_IRQ_ENABLE);
127 midi_busy = 0;
128 }
129
130 static int
131 dump_to_midi (unsigned char midi_byte)
132 {
133 int fifo_space, x;
134
135 fifo_space = ((x = pas_read (MIDI_FIFO_STATUS)) >> 4) & 0x0f;
136
137 if (fifo_space == 15 || (fifo_space < 2 && ofifo_bytes > 13))
138
139
140
141 {
142 return 0;
143
144
145 }
146
147 ofifo_bytes++;
148
149 pas_write (midi_byte, MIDI_DATA);
150
151 return 1;
152 }
153
154 static int
155 pas_midi_out (int dev, unsigned char midi_byte)
156 {
157
158 unsigned long flags;
159
160
161
162
163
164 DISABLE_INTR (flags);
165
166 while (qlen && dump_to_midi (tmp_queue[qhead]))
167 {
168 qlen--;
169 qhead++;
170 }
171
172 RESTORE_INTR (flags);
173
174
175
176
177
178 if (!qlen)
179 if (dump_to_midi (midi_byte))
180 return 1;
181
182
183
184
185
186
187
188 if (qlen >= 256)
189 return 0;
190
191
192
193 DISABLE_INTR (flags);
194
195 tmp_queue[qtail] = midi_byte;
196 qlen++;
197 qtail++;
198
199 RESTORE_INTR (flags);
200
201 return 1;
202 }
203
204 static int
205 pas_midi_start_read (int dev)
206 {
207 return 0;
208 }
209
210 static int
211 pas_midi_end_read (int dev)
212 {
213 return 0;
214 }
215
216 static int
217 pas_midi_ioctl (int dev, unsigned cmd, unsigned arg)
218 {
219 return RET_ERROR (EINVAL);
220 }
221
222 static void
223 pas_midi_kick (int dev)
224 {
225 ofifo_bytes = 0;
226 }
227
228 static int
229 pas_buffer_status (int dev)
230 {
231 return !qlen;
232 }
233
234 #define MIDI_SYNTH_NAME "Pro Audio Spectrum Midi"
235 #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
236 #include "midi_synth.h"
237
238 static struct midi_operations pas_midi_operations =
239 {
240 {"Pro Audio Spectrum", 0, 0, SNDCARD_PAS},
241 &std_midi_synth,
242 {0},
243 pas_midi_open,
244 pas_midi_close,
245 pas_midi_ioctl,
246 pas_midi_out,
247 pas_midi_start_read,
248 pas_midi_end_read,
249 pas_midi_kick,
250 NULL,
251
252
253 pas_buffer_status,
254 NULL
255 };
256
257 long
258 pas_midi_init (long mem_start)
259 {
260 if (num_midis >= MAX_MIDI_DEV)
261 {
262 printk ("Sound: Too many midi devices detected\n");
263 return mem_start;
264 }
265
266 std_midi_synth.midi_dev = my_dev = num_midis;
267 midi_devs[num_midis++] = &pas_midi_operations;
268 return mem_start;
269 }
270
271 void
272 pas_midi_interrupt (void)
273 {
274 unsigned char stat;
275 int i, incount;
276 unsigned long flags;
277
278 stat = pas_read (MIDI_STATUS);
279
280 if (stat & M_S_INPUT_AVAIL)
281
282
283 {
284 incount = pas_read (MIDI_FIFO_STATUS) & 0x0f;
285
286
287 if (!incount)
288 incount = 16;
289
290 for (i = 0; i < incount; i++)
291 if (input_opened)
292 {
293 midi_input_intr (my_dev, pas_read (MIDI_DATA));
294 }
295 else
296 pas_read (MIDI_DATA);
297
298
299 }
300
301 if (stat & (M_S_OUTPUT_EMPTY | M_S_OUTPUT_HALF_EMPTY))
302 {
303 if (!(stat & M_S_OUTPUT_EMPTY))
304 {
305 ofifo_bytes = 8;
306 }
307 else
308 {
309 ofifo_bytes = 0;
310 }
311
312 DISABLE_INTR (flags);
313
314 while (qlen && dump_to_midi (tmp_queue[qhead]))
315 {
316 qlen--;
317 qhead++;
318 }
319
320 RESTORE_INTR (flags);
321 }
322
323 #if 0
324 if (stat & M_S_FRAMING_ERROR)
325 printk ("MIDI framing error\n");
326 #endif
327
328 if (stat & M_S_OUTPUT_OVERRUN)
329 {
330 printk ("MIDI output overrun %x,%x,%d \n", pas_read (MIDI_FIFO_STATUS), stat, ofifo_bytes);
331 ofifo_bytes = 100;
332 }
333
334 pas_write (stat, MIDI_STATUS);
335
336
337 }
338
339 #endif
340
341 #endif