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