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 <asm/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 midi->timer.expires = 1 + jiffies;
360 add_timer(&midi->timer);
361 spin_unlock_irqrestore (&midi->virtual, flags);
362 snd_wavefront_midi_output_write(card);
363}
364
365static void snd_wavefront_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
366{
367 unsigned long flags;
368 snd_wavefront_midi_t *midi;
369 snd_wavefront_mpu_id mpu;
370
371 if (substream == NULL || substream->rmidi == NULL)
372 return;
373
374 if (substream->rmidi->private_data == NULL)
375 return;
376
377 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
378
379 if ((midi = get_wavefront_midi (substream)) == NULL) {
380 return;
381 }
382
383 spin_lock_irqsave (&midi->virtual, flags);
384 if (up) {
385 if ((midi->mode[mpu] & MPU401_MODE_OUTPUT_TRIGGER) == 0) {
386 if (!midi->istimer) {
387 init_timer(&midi->timer);
388 midi->timer.function = snd_wavefront_midi_output_timer;
389 midi->timer.data = (unsigned long) substream->rmidi->card->private_data;
390 midi->timer.expires = 1 + jiffies;
391 add_timer(&midi->timer);
392 }
393 midi->istimer++;
394 midi->mode[mpu] |= MPU401_MODE_OUTPUT_TRIGGER;
395 }
396 } else {
397 midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
398 }
399 spin_unlock_irqrestore (&midi->virtual, flags);
400
401 if (up)
402 snd_wavefront_midi_output_write((snd_wavefront_card_t *)substream->rmidi->card->private_data);
403}
404
405void
406snd_wavefront_midi_interrupt (snd_wavefront_card_t *card)
407
408{
409 unsigned long flags;
410 snd_wavefront_midi_t *midi;
411 static struct snd_rawmidi_substream *substream = NULL;
412 static int mpu = external_mpu;
413 int max = 128;
414 unsigned char byte;
415
416 midi = &card->wavefront.midi;
417
418 if (!input_avail (midi)) {
419 snd_wavefront_midi_output_write(card);
420 return;
421 }
422
423 spin_lock_irqsave (&midi->virtual, flags);
424 while (--max) {
425
426 if (input_avail (midi)) {
427 byte = read_data (midi);
428
429 if (midi->isvirtual) {
430 if (byte == WF_EXTERNAL_SWITCH) {
431 substream = midi->substream_input[external_mpu];
432 mpu = external_mpu;
433 } else if (byte == WF_INTERNAL_SWITCH) {
434 substream = midi->substream_output[internal_mpu];
435 mpu = internal_mpu;
436 }
437 } else {
438 substream = midi->substream_input[internal_mpu];
439 mpu = internal_mpu;
440 }
441
442 if (substream == NULL) {
443 continue;
444 }
445
446 if (midi->mode[mpu] & MPU401_MODE_INPUT_TRIGGER) {
447 snd_rawmidi_receive(substream, &byte, 1);
448 }
449 } else {
450 break;
451 }
452 }
453 spin_unlock_irqrestore (&midi->virtual, flags);
454
455 snd_wavefront_midi_output_write(card);
456}
457
458void
459snd_wavefront_midi_enable_virtual (snd_wavefront_card_t *card)
460
461{
462 unsigned long flags;
463
464 spin_lock_irqsave (&card->wavefront.midi.virtual, flags);
465 card->wavefront.midi.isvirtual = 1;
466 card->wavefront.midi.output_mpu = internal_mpu;
467 card->wavefront.midi.input_mpu = internal_mpu;
468 spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags);
469}
470
471void
472snd_wavefront_midi_disable_virtual (snd_wavefront_card_t *card)
473
474{
475 unsigned long flags;
476
477 spin_lock_irqsave (&card->wavefront.midi.virtual, flags);
478
479
480 card->wavefront.midi.isvirtual = 0;
481 spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags);
482}
483
484int __devinit
485snd_wavefront_midi_start (snd_wavefront_card_t *card)
486
487{
488 int ok, i;
489 unsigned char rbuf[4], wbuf[4];
490 snd_wavefront_t *dev;
491 snd_wavefront_midi_t *midi;
492
493 dev = &card->wavefront;
494 midi = &dev->midi;
495
496
497
498
499
500
501
502 for (i = 0; i < 30000 && !output_ready (midi); i++);
503
504 if (!output_ready (midi)) {
505 snd_printk ("MIDI interface not ready for command\n");
506 return -1;
507 }
508
509
510
511
512
513 dev->interrupts_are_midi = 1;
514
515 outb (UART_MODE_ON, midi->mpu_command_port);
516
517 for (ok = 0, i = 50000; i > 0 && !ok; i--) {
518 if (input_avail (midi)) {
519 if (read_data (midi) == MPU_ACK) {
520 ok = 1;
521 break;
522 }
523 }
524 }
525
526 if (!ok) {
527 snd_printk ("cannot set UART mode for MIDI interface");
528 dev->interrupts_are_midi = 0;
529 return -1;
530 }
531
532
533
534 if (snd_wavefront_cmd (dev, WFC_MISYNTH_ON, rbuf, wbuf)) {
535 snd_printk ("can't enable MIDI-IN-2-synth routing.\n");
536
537 }
538
539
540
541
542
543
544
545
546
547
548
549
550 if (snd_wavefront_cmd (dev, WFC_VMIDI_OFF, rbuf, wbuf)) {
551 snd_printk ("virtual MIDI mode not disabled\n");
552 return 0;
553 }
554
555 snd_wavefront_midi_enable_virtual (card);
556
557 if (snd_wavefront_cmd (dev, WFC_VMIDI_ON, rbuf, wbuf)) {
558 snd_printk ("cannot enable virtual MIDI mode.\n");
559 snd_wavefront_midi_disable_virtual (card);
560 }
561 return 0;
562}
563
564struct snd_rawmidi_ops snd_wavefront_midi_output =
565{
566 .open = snd_wavefront_midi_output_open,
567 .close = snd_wavefront_midi_output_close,
568 .trigger = snd_wavefront_midi_output_trigger,
569};
570
571struct snd_rawmidi_ops snd_wavefront_midi_input =
572{
573 .open = snd_wavefront_midi_input_open,
574 .close = snd_wavefront_midi_input_close,
575 .trigger = snd_wavefront_midi_input_trigger,
576};
577
578