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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50#include <sound/driver.h>
51#include <asm/io.h>
52#include <linux/init.h>
53#include <linux/time.h>
54#include <linux/wait.h>
55#include <sound/core.h>
56#include <sound/snd_wavefront.h>
57
58static inline int
59wf_mpu_status (snd_wavefront_midi_t *midi)
60
61{
62 return inb (midi->mpu_status_port);
63}
64
65static inline int
66input_avail (snd_wavefront_midi_t *midi)
67
68{
69 return !(wf_mpu_status(midi) & INPUT_AVAIL);
70}
71
72static inline int
73output_ready (snd_wavefront_midi_t *midi)
74
75{
76 return !(wf_mpu_status(midi) & OUTPUT_READY);
77}
78
79static inline int
80read_data (snd_wavefront_midi_t *midi)
81
82{
83 return inb (midi->mpu_data_port);
84}
85
86static inline void
87write_data (snd_wavefront_midi_t *midi, unsigned char byte)
88
89{
90 outb (byte, midi->mpu_data_port);
91}
92
93static snd_wavefront_midi_t *
94get_wavefront_midi (snd_rawmidi_substream_t *substream)
95
96{
97 snd_card_t *card;
98 snd_wavefront_card_t *acard;
99
100 if (substream == NULL || substream->rmidi == NULL)
101 return NULL;
102
103 card = substream->rmidi->card;
104
105 if (card == NULL)
106 return NULL;
107
108 if (card->private_data == NULL)
109 return NULL;
110
111 acard = card->private_data;
112
113 return &acard->wavefront.midi;
114}
115
116static void snd_wavefront_midi_output_write(snd_wavefront_card_t *card)
117{
118 snd_wavefront_midi_t *midi = &card->wavefront.midi;
119 snd_wavefront_mpu_id mpu;
120 unsigned long flags;
121 unsigned char midi_byte;
122 int max = 256, mask = 1;
123 int timeout;
124
125
126
127
128
129
130
131
132
133
134
135
136 if (midi->substream_output[midi->output_mpu] == NULL) {
137 goto __second;
138 }
139
140 while (max > 0) {
141
142
143
144 for (timeout = 30000; timeout > 0; timeout--) {
145 if (output_ready (midi))
146 break;
147 }
148
149 spin_lock_irqsave (&midi->virtual, flags);
150 if ((midi->mode[midi->output_mpu] & MPU401_MODE_OUTPUT) == 0) {
151 spin_unlock_irqrestore (&midi->virtual, flags);
152 goto __second;
153 }
154 if (output_ready (midi)) {
155 if (snd_rawmidi_transmit(midi->substream_output[midi->output_mpu], &midi_byte, 1) == 1) {
156 if (!midi->isvirtual ||
157 (midi_byte != WF_INTERNAL_SWITCH &&
158 midi_byte != WF_EXTERNAL_SWITCH))
159 write_data(midi, midi_byte);
160 max--;
161 } else {
162 if (midi->istimer) {
163 if (--midi->istimer <= 0)
164 del_timer(&midi->timer);
165 }
166 midi->mode[midi->output_mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
167 spin_unlock_irqrestore (&midi->virtual, flags);
168 goto __second;
169 }
170 } else {
171 spin_unlock_irqrestore (&midi->virtual, flags);
172 return;
173 }
174 spin_unlock_irqrestore (&midi->virtual, flags);
175 }
176
177 __second:
178
179 if (midi->substream_output[!midi->output_mpu] == NULL) {
180 return;
181 }
182
183 while (max > 0) {
184
185
186
187 for (timeout = 30000; timeout > 0; timeout--) {
188 if (output_ready (midi))
189 break;
190 }
191
192 spin_lock_irqsave (&midi->virtual, flags);
193 if (!midi->isvirtual)
194 mask = 0;
195 mpu = midi->output_mpu ^ mask;
196 mask = 0;
197 if ((midi->mode[mpu] & MPU401_MODE_OUTPUT) == 0) {
198 spin_unlock_irqrestore (&midi->virtual, flags);
199 return;
200 }
201 if (snd_rawmidi_transmit_empty(midi->substream_output[mpu]))
202 goto __timer;
203 if (output_ready (midi)) {
204 if (mpu != midi->output_mpu) {
205 write_data(midi, mpu == internal_mpu ?
206 WF_INTERNAL_SWITCH :
207 WF_EXTERNAL_SWITCH);
208 midi->output_mpu = mpu;
209 } else if (snd_rawmidi_transmit(midi->substream_output[mpu], &midi_byte, 1) == 1) {
210 if (!midi->isvirtual ||
211 (midi_byte != WF_INTERNAL_SWITCH &&
212 midi_byte != WF_EXTERNAL_SWITCH))
213 write_data(midi, midi_byte);
214 max--;
215 } else {
216 __timer:
217 if (midi->istimer) {
218 if (--midi->istimer <= 0)
219 del_timer(&midi->timer);
220 }
221 midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
222 spin_unlock_irqrestore (&midi->virtual, flags);
223 return;
224 }
225 } else {
226 spin_unlock_irqrestore (&midi->virtual, flags);
227 return;
228 }
229 spin_unlock_irqrestore (&midi->virtual, flags);
230 }
231}
232
233static int snd_wavefront_midi_input_open(snd_rawmidi_substream_t * substream)
234{
235 unsigned long flags;
236 snd_wavefront_midi_t *midi;
237 snd_wavefront_mpu_id mpu;
238
239 snd_assert(substream != NULL && substream->rmidi != NULL, return -EIO);
240 snd_assert(substream->rmidi->private_data != NULL, return -EIO);
241
242 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
243
244 if ((midi = get_wavefront_midi (substream)) == NULL)
245 return -EIO;
246
247 spin_lock_irqsave (&midi->open, flags);
248 midi->mode[mpu] |= MPU401_MODE_INPUT;
249 midi->substream_input[mpu] = substream;
250 spin_unlock_irqrestore (&midi->open, flags);
251
252 return 0;
253}
254
255static int snd_wavefront_midi_output_open(snd_rawmidi_substream_t * substream)
256{
257 unsigned long flags;
258 snd_wavefront_midi_t *midi;
259 snd_wavefront_mpu_id mpu;
260
261 snd_assert(substream != NULL && substream->rmidi != NULL, return -EIO);
262 snd_assert(substream->rmidi->private_data != NULL, return -EIO);
263
264 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
265
266 if ((midi = get_wavefront_midi (substream)) == NULL)
267 return -EIO;
268
269 spin_lock_irqsave (&midi->open, flags);
270 midi->mode[mpu] |= MPU401_MODE_OUTPUT;
271 midi->substream_output[mpu] = substream;
272 spin_unlock_irqrestore (&midi->open, flags);
273
274 return 0;
275}
276
277static int snd_wavefront_midi_input_close(snd_rawmidi_substream_t * substream)
278{
279 unsigned long flags;
280 snd_wavefront_midi_t *midi;
281 snd_wavefront_mpu_id mpu;
282
283 snd_assert(substream != NULL && substream->rmidi != NULL, return -EIO);
284 snd_assert(substream->rmidi->private_data != NULL, return -EIO);
285
286 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
287
288 if ((midi = get_wavefront_midi (substream)) == NULL)
289 return -EIO;
290
291 spin_lock_irqsave (&midi->open, flags);
292 midi->mode[mpu] &= ~MPU401_MODE_INPUT;
293 spin_unlock_irqrestore (&midi->open, flags);
294
295 return 0;
296}
297
298static int snd_wavefront_midi_output_close(snd_rawmidi_substream_t * substream)
299{
300 unsigned long flags;
301 snd_wavefront_midi_t *midi;
302 snd_wavefront_mpu_id mpu;
303
304 snd_assert(substream != NULL && substream->rmidi != NULL, return -EIO);
305 snd_assert(substream->rmidi->private_data != NULL, return -EIO);
306
307 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
308
309 if ((midi = get_wavefront_midi (substream)) == NULL)
310 return -EIO;
311
312 spin_lock_irqsave (&midi->open, flags);
313 midi->mode[mpu] &= ~MPU401_MODE_OUTPUT;
314 spin_unlock_irqrestore (&midi->open, flags);
315 return 0;
316}
317
318static void snd_wavefront_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
319{
320 unsigned long flags;
321 snd_wavefront_midi_t *midi;
322 snd_wavefront_mpu_id mpu;
323
324 if (substream == NULL || substream->rmidi == NULL)
325 return;
326
327 if (substream->rmidi->private_data == NULL)
328 return;
329
330 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
331
332 if ((midi = get_wavefront_midi (substream)) == NULL) {
333 return;
334 }
335
336 spin_lock_irqsave (&midi->virtual, flags);
337 if (up) {
338 midi->mode[mpu] |= MPU401_MODE_INPUT_TRIGGER;
339 } else {
340 midi->mode[mpu] &= ~MPU401_MODE_INPUT_TRIGGER;
341 }
342 spin_unlock_irqrestore (&midi->virtual, flags);
343}
344
345static void snd_wavefront_midi_output_timer(unsigned long data)
346{
347 snd_wavefront_card_t *card = (snd_wavefront_card_t *)data;
348 snd_wavefront_midi_t *midi = &card->wavefront.midi;
349 unsigned long flags;
350
351 spin_lock_irqsave (&midi->virtual, flags);
352 midi->timer.expires = 1 + jiffies;
353 add_timer(&midi->timer);
354 spin_unlock_irqrestore (&midi->virtual, flags);
355 snd_wavefront_midi_output_write(card);
356}
357
358static void snd_wavefront_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
359{
360 unsigned long flags;
361 snd_wavefront_midi_t *midi;
362 snd_wavefront_mpu_id mpu;
363
364 if (substream == NULL || substream->rmidi == NULL)
365 return;
366
367 if (substream->rmidi->private_data == NULL)
368 return;
369
370 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
371
372 if ((midi = get_wavefront_midi (substream)) == NULL) {
373 return;
374 }
375
376 spin_lock_irqsave (&midi->virtual, flags);
377 if (up) {
378 if ((midi->mode[mpu] & MPU401_MODE_OUTPUT_TRIGGER) == 0) {
379 if (!midi->istimer) {
380 init_timer(&midi->timer);
381 midi->timer.function = snd_wavefront_midi_output_timer;
382 midi->timer.data = (unsigned long) substream->rmidi->card->private_data;
383 midi->timer.expires = 1 + jiffies;
384 add_timer(&midi->timer);
385 }
386 midi->istimer++;
387 midi->mode[mpu] |= MPU401_MODE_OUTPUT_TRIGGER;
388 }
389 } else {
390 midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
391 }
392 spin_unlock_irqrestore (&midi->virtual, flags);
393
394 if (up)
395 snd_wavefront_midi_output_write((snd_wavefront_card_t *)substream->rmidi->card->private_data);
396}
397
398void
399snd_wavefront_midi_interrupt (snd_wavefront_card_t *card)
400
401{
402 unsigned long flags;
403 snd_wavefront_midi_t *midi;
404 static snd_rawmidi_substream_t *substream = NULL;
405 static int mpu = external_mpu;
406 int max = 128;
407 unsigned char byte;
408
409 midi = &card->wavefront.midi;
410
411 if (!input_avail (midi)) {
412 snd_wavefront_midi_output_write(card);
413 return;
414 }
415
416 while (--max) {
417 spin_lock_irqsave (&midi->virtual, flags);
418
419 if (input_avail (midi)) {
420 byte = read_data (midi);
421
422 if (midi->isvirtual) {
423 if (byte == WF_EXTERNAL_SWITCH) {
424 substream = midi->substream_input[external_mpu];
425 mpu = external_mpu;
426 } else if (byte == WF_INTERNAL_SWITCH) {
427 substream = midi->substream_output[internal_mpu];
428 mpu = internal_mpu;
429 }
430 } else {
431 substream = midi->substream_input[internal_mpu];
432 mpu = internal_mpu;
433 }
434
435 if (substream == NULL) {
436 spin_unlock_irqrestore (&midi->virtual, flags);
437 continue;
438 }
439
440 if (midi->mode[mpu] & MPU401_MODE_INPUT_TRIGGER) {
441 spin_unlock_irqrestore (&midi->virtual, flags);
442 snd_rawmidi_receive(substream, &byte, 1);
443 } else {
444 spin_unlock_irqrestore (&midi->virtual, flags);
445 }
446 } else {
447 spin_unlock_irqrestore (&midi->virtual, flags);
448 break;
449 }
450 }
451
452 snd_wavefront_midi_output_write(card);
453}
454
455void
456snd_wavefront_midi_enable_virtual (snd_wavefront_card_t *card)
457
458{
459 unsigned long flags;
460
461 spin_lock_irqsave (&card->wavefront.midi.virtual, flags);
462 card->wavefront.midi.isvirtual = 1;
463 card->wavefront.midi.output_mpu = internal_mpu;
464 card->wavefront.midi.input_mpu = internal_mpu;
465 spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags);
466}
467
468void
469snd_wavefront_midi_disable_virtual (snd_wavefront_card_t *card)
470
471{
472 unsigned long flags;
473
474 spin_lock_irqsave (&card->wavefront.midi.virtual, flags);
475
476
477 card->wavefront.midi.isvirtual = 0;
478 spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags);
479}
480
481int __init
482snd_wavefront_midi_start (snd_wavefront_card_t *card)
483
484{
485 int ok, i;
486 unsigned char rbuf[4], wbuf[4];
487 snd_wavefront_t *dev;
488 snd_wavefront_midi_t *midi;
489
490 dev = &card->wavefront;
491 midi = &dev->midi;
492
493
494
495
496
497
498
499 for (i = 0; i < 30000 && !output_ready (midi); i++);
500
501 if (!output_ready (midi)) {
502 snd_printk ("MIDI interface not ready for command\n");
503 return -1;
504 }
505
506
507
508
509
510 dev->interrupts_are_midi = 1;
511
512 outb (UART_MODE_ON, midi->mpu_command_port);
513
514 for (ok = 0, i = 50000; i > 0 && !ok; i--) {
515 if (input_avail (midi)) {
516 if (read_data (midi) == MPU_ACK) {
517 ok = 1;
518 break;
519 }
520 }
521 }
522
523 if (!ok) {
524 snd_printk ("cannot set UART mode for MIDI interface");
525 dev->interrupts_are_midi = 0;
526 return -1;
527 }
528
529
530
531 if (snd_wavefront_cmd (dev, WFC_MISYNTH_ON, rbuf, wbuf)) {
532 snd_printk ("can't enable MIDI-IN-2-synth routing.\n");
533
534 }
535
536
537
538
539
540
541
542
543
544
545
546
547 if (snd_wavefront_cmd (dev, WFC_VMIDI_OFF, rbuf, wbuf)) {
548 snd_printk ("virtual MIDI mode not disabled\n");
549 return 0;
550 }
551
552 snd_wavefront_midi_enable_virtual (card);
553
554 if (snd_wavefront_cmd (dev, WFC_VMIDI_ON, rbuf, wbuf)) {
555 snd_printk ("cannot enable virtual MIDI mode.\n");
556 snd_wavefront_midi_disable_virtual (card);
557 }
558 return 0;
559}
560
561snd_rawmidi_ops_t snd_wavefront_midi_output =
562{
563 .open = snd_wavefront_midi_output_open,
564 .close = snd_wavefront_midi_output_close,
565 .trigger = snd_wavefront_midi_output_trigger,
566};
567
568snd_rawmidi_ops_t snd_wavefront_midi_input =
569{
570 .open = snd_wavefront_midi_input_open,
571 .close = snd_wavefront_midi_input_close,
572 .trigger = snd_wavefront_midi_input_trigger,
573};
574
575