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