added mtd driver
[linux-2.4.git] / drivers / sound / wf_midi.c
1 /*
2  * sound/wf_midi.c
3  *
4  * The low level driver for the WaveFront ICS2115 MIDI interface(s)
5  * Note that there is also an MPU-401 emulation (actually, a UART-401
6  * emulation) on the CS4232 on the Tropez Plus. This code has nothing
7  * to do with that interface at all.
8  *
9  * The interface is essentially just a UART-401, but is has the
10  * interesting property of supporting what Turtle Beach called
11  * "Virtual MIDI" mode. In this mode, there are effectively *two*
12  * MIDI buses accessible via the interface, one that is routed
13  * solely to/from the external WaveFront synthesizer and the other
14  * corresponding to the pin/socket connector used to link external
15  * MIDI devices to the board.
16  *
17  * This driver fully supports this mode, allowing two distinct
18  * midi devices (/dev/midiNN and /dev/midiNN+1) to be used
19  * completely independently, giving 32 channels of MIDI routing,
20  * 16 to the WaveFront synth and 16 to the external MIDI bus.
21  *
22  * Switching between the two is accomplished externally by the driver
23  * using the two otherwise unused MIDI bytes. See the code for more details.
24  *
25  * NOTE: VIRTUAL MIDI MODE IS ON BY DEFAULT (see wavefront.c)
26  *
27  * The main reason to turn off Virtual MIDI mode is when you want to
28  * tightly couple the WaveFront synth with an external MIDI
29  * device. You won't be able to distinguish the source of any MIDI
30  * data except via SysEx ID, but thats probably OK, since for the most
31  * part, the WaveFront won't be sending any MIDI data at all.
32  *  
33  * The main reason to turn on Virtual MIDI Mode is to provide two
34  * completely independent 16-channel MIDI buses, one to the
35  * WaveFront and one to any external MIDI devices. Given the 32
36  * voice nature of the WaveFront, its pretty easy to find a use
37  * for all 16 channels driving just that synth.
38  *
39  */
40
41 /*
42  * Copyright (C) by Paul Barton-Davis 1998
43  * Some portions of this file are derived from work that is:
44  *
45  *    CopyriGht (C) by Hannu Savolainen 1993-1996
46  *
47  * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
48  * Version 2 (June 1991). See the "COPYING" file distributed with this software
49  * for more info.
50  */
51
52 #include <linux/init.h>
53 #include "sound_config.h"
54
55 #include <linux/wavefront.h>
56
57 #ifdef MODULE
58
59 struct wf_mpu_config {
60         int             base;
61 #define DATAPORT(d)   (d)->base
62 #define COMDPORT(d)   (d)->base+1
63 #define STATPORT(d)   (d)->base+1
64
65         int             irq;
66         int             opened;
67         int             devno;
68         int             synthno;
69         int             mode;
70 #define MODE_MIDI       1
71 #define MODE_SYNTH      2
72
73         void            (*inputintr) (int dev, unsigned char data);
74         char isvirtual;                /* do virtual I/O stuff */
75 };
76
77 static struct wf_mpu_config  devs[2];
78 static struct wf_mpu_config *phys_dev = &devs[0];
79 static struct wf_mpu_config *virt_dev = &devs[1];
80
81 static void start_uart_mode (void);
82
83 #define OUTPUT_READY    0x40
84 #define INPUT_AVAIL     0x80
85 #define MPU_ACK         0xFE
86 #define UART_MODE_ON    0x3F
87
88 static inline int wf_mpu_status (void)
89 {
90         return inb (STATPORT (phys_dev));
91 }
92
93 static inline int input_avail (void)
94 {
95         return !(wf_mpu_status() & INPUT_AVAIL);
96 }
97
98 static inline int output_ready (void)
99 {
100         return !(wf_mpu_status() & OUTPUT_READY);
101 }
102
103 static inline int  read_data (void)
104 {
105         return inb (DATAPORT (phys_dev));
106 }
107
108 static inline void write_data (unsigned char byte)
109 {
110         outb (byte, DATAPORT (phys_dev));
111 }
112
113 /*
114  * States for the input scanner (should be in dev_table.h)
115  */
116
117 #define MST_SYSMSG              100     /* System message (sysx etc). */
118 #define MST_MTC                 102     /* Midi Time Code (MTC) qframe msg */
119 #define MST_SONGSEL             103     /* Song select */
120 #define MST_SONGPOS             104     /* Song position pointer */
121 #define MST_TIMED               105     /* Leading timing byte rcvd */
122
123 /* buffer space check for input scanner */
124
125 #define BUFTEST(mi) if (mi->m_ptr >= MI_MAX || mi->m_ptr < 0) \
126 {printk(KERN_ERR "WF-MPU: Invalid buffer pointer %d/%d, s=%d\n", \
127         mi->m_ptr, mi->m_left, mi->m_state);mi->m_ptr--;}
128
129 static unsigned char len_tab[] =        /* # of data bytes following a status
130                                          */
131 {
132         2,                              /* 8x */
133         2,                              /* 9x */
134         2,                              /* Ax */
135         2,                              /* Bx */
136         1,                              /* Cx */
137         1,                              /* Dx */
138         2,                              /* Ex */
139         0                               /* Fx */
140 };
141
142 static int
143 wf_mpu_input_scanner (int devno, int synthdev, unsigned char midic)
144
145 {
146         struct midi_input_info *mi = &midi_devs[devno]->in_info;
147
148         switch (mi->m_state) {
149         case MST_INIT:
150                 switch (midic) {
151                 case 0xf8:
152                         /* Timer overflow */
153                         break;
154                 
155                 case 0xfc:
156                         break;
157                 
158                 case 0xfd:
159                         /* XXX do something useful with this. If there is
160                            an external MIDI timer (e.g. a hardware sequencer,
161                            a useful timer can be derived ...
162                    
163                            For now, no timer support.
164                         */
165                         break;
166                 
167                 case 0xfe:
168                         return MPU_ACK;
169                         break;
170                 
171                 case 0xf0:
172                 case 0xf1:
173                 case 0xf2:
174                 case 0xf3:
175                 case 0xf4:
176                 case 0xf5:
177                 case 0xf6:
178                 case 0xf7:
179                         break;
180                 
181                 case 0xf9:
182                         break;
183                 
184                 case 0xff:
185                         mi->m_state = MST_SYSMSG;
186                         break;
187                 
188                 default:
189                         if (midic <= 0xef) {
190                                 mi->m_state = MST_TIMED;
191                         }
192                         else
193                                 printk (KERN_ERR "<MPU: Unknown event %02x> ",
194                                         midic);
195                 }
196                 break;
197           
198         case MST_TIMED:
199         {
200                 int             msg = ((int) (midic & 0xf0) >> 4);
201           
202                 mi->m_state = MST_DATA;
203           
204                 if (msg < 8) {  /* Data byte */
205               
206                         msg = ((int) (mi->m_prev_status & 0xf0) >> 4);
207                         msg -= 8;
208                         mi->m_left = len_tab[msg] - 1;
209               
210                         mi->m_ptr = 2;
211                         mi->m_buf[0] = mi->m_prev_status;
212                         mi->m_buf[1] = midic;
213
214                         if (mi->m_left <= 0) {
215                                 mi->m_state = MST_INIT;
216                                 do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
217                                 mi->m_ptr = 0;
218                         }
219                 } else if (msg == 0xf) {        /* MPU MARK */
220               
221                         mi->m_state = MST_INIT;
222
223                         switch (midic) {
224                         case 0xf8:
225                                 break;
226                     
227                         case 0xf9:
228                                 break;
229                     
230                         case 0xfc:
231                                 break;
232                     
233                         default:
234                                 break;
235                         }
236                 } else {
237                         mi->m_prev_status = midic;
238                         msg -= 8;
239                         mi->m_left = len_tab[msg];
240               
241                         mi->m_ptr = 1;
242                         mi->m_buf[0] = midic;
243               
244                         if (mi->m_left <= 0) {
245                                 mi->m_state = MST_INIT;
246                                 do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
247                                 mi->m_ptr = 0;
248                         }
249                 }
250         }
251         break;
252
253         case MST_SYSMSG:
254                 switch (midic) {
255                 case 0xf0:
256                         mi->m_state = MST_SYSEX;
257                         break;
258             
259                 case 0xf1:
260                         mi->m_state = MST_MTC;
261                         break;
262
263                 case 0xf2:
264                         mi->m_state = MST_SONGPOS;
265                         mi->m_ptr = 0;
266                         break;
267             
268                 case 0xf3:
269                         mi->m_state = MST_SONGSEL;
270                         break;
271             
272                 case 0xf6:
273                         mi->m_state = MST_INIT;
274             
275                         /*
276                          *    Real time messages
277                          */
278                 case 0xf8:
279                         /* midi clock */
280                         mi->m_state = MST_INIT;
281                         /* XXX need ext MIDI timer support */
282                         break;
283             
284                 case 0xfA:
285                         mi->m_state = MST_INIT;
286                         /* XXX need ext MIDI timer support */
287                         break;
288             
289                 case 0xFB:
290                         mi->m_state = MST_INIT;
291                         /* XXX need ext MIDI timer support */
292                         break;
293             
294                 case 0xFC:
295                         mi->m_state = MST_INIT;
296                         /* XXX need ext MIDI timer support */
297                         break;
298             
299                 case 0xFE:
300                         /* active sensing */
301                         mi->m_state = MST_INIT;
302                         break;
303             
304                 case 0xff:
305                         mi->m_state = MST_INIT;
306                         break;
307
308                 default:
309                         printk (KERN_ERR "unknown MIDI sysmsg %0x\n", midic);
310                         mi->m_state = MST_INIT;
311                 }
312                 break;
313
314         case MST_MTC:
315                 mi->m_state = MST_INIT;
316                 break;
317
318         case MST_SYSEX:
319                 if (midic == 0xf7) {
320                         mi->m_state = MST_INIT;
321                 } else {
322                         /* XXX fix me */
323                 }
324                 break;
325
326         case MST_SONGPOS:
327                 BUFTEST (mi);
328                 mi->m_buf[mi->m_ptr++] = midic;
329                 if (mi->m_ptr == 2) {
330                         mi->m_state = MST_INIT;
331                         mi->m_ptr = 0;
332                         /* XXX need ext MIDI timer support */
333                 }
334                 break;
335
336         case MST_DATA:
337                 BUFTEST (mi);
338                 mi->m_buf[mi->m_ptr++] = midic;
339                 if ((--mi->m_left) <= 0) {
340                         mi->m_state = MST_INIT;
341                         do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
342                         mi->m_ptr = 0;
343                 }
344                 break;
345
346         default:
347                 printk (KERN_ERR "Bad state %d ", mi->m_state);
348                 mi->m_state = MST_INIT;
349         }
350
351         return 1;
352 }
353
354 void
355 wf_mpuintr (int irq, void *dev_id, struct pt_regs *dummy)
356
357 {
358         struct wf_mpu_config *physical_dev = dev_id;
359         static struct wf_mpu_config *input_dev = 0;
360         struct midi_input_info *mi = &midi_devs[physical_dev->devno]->in_info;
361         int n;
362
363         if (!input_avail()) { /* not for us */
364                 return;
365         }
366
367         if (mi->m_busy) return;
368         mi->m_busy = 1;
369         sti (); 
370
371         if (!input_dev) {
372                 input_dev = physical_dev;
373         }
374
375         n = 50; /* XXX why ? */
376
377         do {
378                 unsigned char c = read_data ();
379       
380                 if (phys_dev->isvirtual) {
381
382                         if (c == WF_EXTERNAL_SWITCH) {
383                                 input_dev = virt_dev;
384                                 continue;
385                         } else if (c == WF_INTERNAL_SWITCH) { 
386                                 input_dev = phys_dev;
387                                 continue;
388                         } /* else just leave it as it is */
389
390                 } else {
391                         input_dev = phys_dev;
392                 }
393
394                 if (input_dev->mode == MODE_SYNTH) {
395           
396                         wf_mpu_input_scanner (input_dev->devno,
397                                               input_dev->synthno, c);
398           
399                 } else if (input_dev->opened & OPEN_READ) {
400           
401                         if (input_dev->inputintr) {
402                                 input_dev->inputintr (input_dev->devno, c);
403                         } 
404                 }
405
406         } while (input_avail() && n-- > 0);
407
408         mi->m_busy = 0;
409 }
410
411 static int
412 wf_mpu_open (int dev, int mode,
413              void            (*input) (int dev, unsigned char data),
414              void            (*output) (int dev)
415         )
416 {
417         struct wf_mpu_config *devc;
418
419         if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL)
420                 return -(ENXIO);
421
422         if (phys_dev->devno == dev) {
423                 devc = phys_dev;
424         } else if (phys_dev->isvirtual && virt_dev->devno == dev) {
425                 devc = virt_dev;
426         } else {
427                 printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
428                 return -(EINVAL);
429         }
430
431         if (devc->opened) {
432                 return -(EBUSY);
433         }
434
435         devc->mode = MODE_MIDI;
436         devc->opened = mode;
437         devc->synthno = 0;
438
439         devc->inputintr = input;
440         return 0;
441 }
442  
443 static void
444 wf_mpu_close (int dev)
445 {
446         struct wf_mpu_config *devc;
447
448         if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL)
449                 return;
450
451         if (phys_dev->devno == dev) {
452                 devc = phys_dev;
453         } else if (phys_dev->isvirtual && virt_dev->devno == dev) {
454                 devc = virt_dev;
455         } else {
456                 printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
457                 return;
458         }
459
460         devc->mode = 0;
461         devc->inputintr = NULL;
462         devc->opened = 0;
463 }
464
465 static int
466 wf_mpu_out (int dev, unsigned char midi_byte)
467 {
468         int             timeout;
469         unsigned long   flags;
470         static int lastoutdev = -1;
471         unsigned char switchch;
472
473         if (phys_dev->isvirtual && lastoutdev != dev) {
474       
475                 if (dev == phys_dev->devno) { 
476                         switchch = WF_INTERNAL_SWITCH;
477                 } else if (dev == virt_dev->devno) { 
478                         switchch = WF_EXTERNAL_SWITCH;
479                 } else {
480                         printk (KERN_ERR "WF-MPU: bad device number %d", dev);
481                         return (0);
482                 }
483
484                 /* XXX fix me */
485       
486                 for (timeout = 30000; timeout > 0 && !output_ready ();
487                      timeout--);
488       
489                 save_flags (flags);
490                 cli ();
491       
492                 if (!output_ready ()) {
493                         printk (KERN_WARNING "WF-MPU: Send switch "
494                                 "byte timeout\n");
495                         restore_flags (flags);
496                         return 0;
497                 }
498       
499                 write_data (switchch);
500                 restore_flags (flags);
501         } 
502
503         lastoutdev = dev;
504
505         /*
506          * Sometimes it takes about 30000 loops before the output becomes ready
507          * (After reset). Normally it takes just about 10 loops.
508          */
509
510         /* XXX fix me */
511
512         for (timeout = 30000; timeout > 0 && !output_ready (); timeout--);
513
514         save_flags (flags);
515         cli ();
516         if (!output_ready ()) {
517                 printk (KERN_WARNING "WF-MPU: Send data timeout\n");
518                 restore_flags (flags);
519                 return 0;
520         }
521
522         write_data (midi_byte);
523         restore_flags (flags);
524
525         return 1;
526 }
527
528 static inline int wf_mpu_start_read (int dev) {
529         return 0;
530 }
531
532 static inline int wf_mpu_end_read (int dev) {
533         return 0;
534 }
535
536 static int wf_mpu_ioctl (int dev, unsigned cmd, caddr_t arg)
537 {
538         printk (KERN_WARNING
539                 "WF-MPU: Intelligent mode not supported by hardware.\n");
540         return -(EINVAL);
541 }
542
543 static int wf_mpu_buffer_status (int dev)
544 {
545         return 0;
546 }
547
548 static struct synth_operations wf_mpu_synth_operations[2];
549 static struct midi_operations  wf_mpu_midi_operations[2];
550
551 static struct midi_operations wf_mpu_midi_proto =
552 {
553         owner:          THIS_MODULE,
554         info:           {"WF-MPU MIDI", 0, MIDI_CAP_MPU401, SNDCARD_MPU401},
555         in_info:        {0},   /* in_info */
556         open:           wf_mpu_open,
557         close:          wf_mpu_close,
558         ioctl:          wf_mpu_ioctl,
559         outputc:        wf_mpu_out,
560         start_read:     wf_mpu_start_read,
561         end_read:       wf_mpu_end_read,
562         buffer_status:  wf_mpu_buffer_status,
563 };
564
565 static struct synth_info wf_mpu_synth_info_proto =
566 {"WaveFront MPU-401 interface", 0,
567  SYNTH_TYPE_MIDI, MIDI_TYPE_MPU401, 0, 128, 0, 128, SYNTH_CAP_INPUT};
568
569 static struct synth_info wf_mpu_synth_info[2];
570
571 static int
572 wf_mpu_synth_ioctl (int dev,
573                     unsigned int cmd, caddr_t arg)
574 {
575         int             midi_dev;
576         int index;
577
578         midi_dev = synth_devs[dev]->midi_dev;
579
580         if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev]==NULL)
581                 return -(ENXIO);
582
583         if (midi_dev == phys_dev->devno) {
584                 index = 0;
585         } else if (phys_dev->isvirtual && midi_dev == virt_dev->devno) {
586                 index = 1;
587         } else {
588                 return -(EINVAL);
589         }
590
591         switch (cmd) {
592
593         case SNDCTL_SYNTH_INFO:
594                 if(copy_to_user (&((char *) arg)[0],
595                               &wf_mpu_synth_info[index],
596                               sizeof (struct synth_info)))
597                         return -EFAULT;
598                 return 0;
599         
600         case SNDCTL_SYNTH_MEMAVL:
601                 return 0x7fffffff;
602         
603         default:
604                 return -EINVAL;
605         }
606 }
607
608 static int
609 wf_mpu_synth_open (int dev, int mode)
610 {
611         int             midi_dev;
612         struct wf_mpu_config *devc;
613
614         midi_dev = synth_devs[dev]->midi_dev;
615
616         if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev]==NULL) {
617                 return -(ENXIO);
618         }
619   
620         if (phys_dev->devno == midi_dev) {
621                 devc = phys_dev;
622         } else if (phys_dev->isvirtual && virt_dev->devno == midi_dev) {
623                 devc = virt_dev;
624         } else {
625                 printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
626                 return -(EINVAL);
627         }
628
629         if (devc->opened) {
630                 return -(EBUSY);
631         }
632   
633         devc->mode = MODE_SYNTH;
634         devc->synthno = dev;
635         devc->opened = mode;
636         devc->inputintr = NULL;
637         return 0;
638 }
639
640 static void
641 wf_mpu_synth_close (int dev)
642 {
643         int             midi_dev;
644         struct wf_mpu_config *devc;
645
646         midi_dev = synth_devs[dev]->midi_dev;
647
648         if (phys_dev->devno == midi_dev) {
649                 devc = phys_dev;
650         } else if (phys_dev->isvirtual && virt_dev->devno == midi_dev) {
651                 devc = virt_dev;
652         } else {
653                 printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
654                 return;
655         }
656
657         devc->inputintr = NULL;
658         devc->opened = 0;
659         devc->mode = 0;
660 }
661
662 #define _MIDI_SYNTH_C_
663 #define MIDI_SYNTH_NAME "WaveFront (MIDI)"
664 #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
665 #include "midi_synth.h"
666
667 static struct synth_operations wf_mpu_synth_proto =
668 {
669         owner:          THIS_MODULE,
670         id:             "WaveFront (ICS2115)",
671         info:           NULL,  /* info field, filled in during configuration */
672         midi_dev:       0,     /* MIDI dev XXX should this be -1 ? */
673         synth_type:     SYNTH_TYPE_MIDI,
674         synth_subtype:  SAMPLE_TYPE_WAVEFRONT,
675         open:           wf_mpu_synth_open,
676         close:          wf_mpu_synth_close,
677         ioctl:          wf_mpu_synth_ioctl,
678         kill_note:      midi_synth_kill_note,
679         start_note:     midi_synth_start_note,
680         set_instr:      midi_synth_set_instr,
681         reset:          midi_synth_reset,
682         hw_control:     midi_synth_hw_control,
683         load_patch:     midi_synth_load_patch,
684         aftertouch:     midi_synth_aftertouch,
685         controller:     midi_synth_controller,
686         panning:        midi_synth_panning,
687         bender:         midi_synth_bender,
688         setup_voice:    midi_synth_setup_voice,
689         send_sysex:     midi_synth_send_sysex
690 };
691
692 static int
693 config_wf_mpu (struct wf_mpu_config *dev)
694
695 {
696         int is_external;
697         char *name;
698         int index;
699
700         if (dev == phys_dev) {
701                 name = "WaveFront internal MIDI";
702                 is_external = 0;
703                 index = 0;
704                 memcpy ((char *) &wf_mpu_synth_operations[index],
705                         (char *) &wf_mpu_synth_proto,
706                         sizeof (struct synth_operations));
707         } else {
708                 name = "WaveFront external MIDI";
709                 is_external = 1;
710                 index = 1;
711                 /* no synth operations for an external MIDI interface */
712         }
713
714         memcpy ((char *) &wf_mpu_synth_info[dev->devno],
715                 (char *) &wf_mpu_synth_info_proto,
716                 sizeof (struct synth_info));
717
718         strcpy (wf_mpu_synth_info[index].name, name);
719
720         wf_mpu_synth_operations[index].midi_dev = dev->devno;
721         wf_mpu_synth_operations[index].info = &wf_mpu_synth_info[index];
722
723         memcpy ((char *) &wf_mpu_midi_operations[index],
724                 (char *) &wf_mpu_midi_proto,
725                 sizeof (struct midi_operations));
726   
727         if (is_external) {
728                 wf_mpu_midi_operations[index].converter = NULL;
729         } else {
730                 wf_mpu_midi_operations[index].converter =
731                         &wf_mpu_synth_operations[index];
732         }
733
734         strcpy (wf_mpu_midi_operations[index].info.name, name);
735
736         midi_devs[dev->devno] = &wf_mpu_midi_operations[index];
737         midi_devs[dev->devno]->in_info.m_busy = 0;
738         midi_devs[dev->devno]->in_info.m_state = MST_INIT;
739         midi_devs[dev->devno]->in_info.m_ptr = 0;
740         midi_devs[dev->devno]->in_info.m_left = 0;
741         midi_devs[dev->devno]->in_info.m_prev_status = 0;
742
743         devs[index].opened = 0;
744         devs[index].mode = 0;
745
746         return (0);
747 }
748
749 int virtual_midi_enable (void)
750
751 {
752         if ((virt_dev->devno < 0) &&
753             (virt_dev->devno = sound_alloc_mididev()) == -1) {
754                 printk (KERN_ERR
755                         "WF-MPU: too many midi devices detected\n");
756                 return -1;
757         }
758
759         config_wf_mpu (virt_dev);
760
761         phys_dev->isvirtual = 1;
762         return virt_dev->devno;
763 }
764
765 int
766 virtual_midi_disable (void)
767
768 {
769         unsigned long flags;
770
771         save_flags (flags);
772         cli();
773
774         wf_mpu_close (virt_dev->devno);
775         /* no synth on virt_dev, so no need to call wf_mpu_synth_close() */
776         phys_dev->isvirtual = 0;
777
778         restore_flags (flags);
779
780         return 0;
781 }
782
783 int __init detect_wf_mpu (int irq, int io_base)
784 {
785         if (check_region (io_base, 2)) {
786                 printk (KERN_WARNING "WF-MPU: I/O port %x already in use.\n",
787                         io_base);
788                 return -1;
789         }
790
791         phys_dev->base = io_base;
792         phys_dev->irq = irq;
793         phys_dev->devno = -1;
794         virt_dev->devno = -1;
795
796         return 0;
797 }
798
799 int __init install_wf_mpu (void)
800 {
801         if ((phys_dev->devno = sound_alloc_mididev()) < 0){
802
803                 printk (KERN_ERR "WF-MPU: Too many MIDI devices detected.\n");
804                 return -1;
805
806         }
807
808         request_region (phys_dev->base, 2, "wavefront midi");
809         phys_dev->isvirtual = 0;
810
811         if (config_wf_mpu (phys_dev)) {
812
813                 printk (KERN_WARNING
814                         "WF-MPU: configuration for MIDI device %d failed\n",
815                         phys_dev->devno);
816                 sound_unload_mididev (phys_dev->devno);
817
818         }
819
820         /* OK, now we're configured to handle an interrupt ... */
821
822         if (request_irq (phys_dev->irq, wf_mpuintr, SA_INTERRUPT|SA_SHIRQ,
823                          "wavefront midi", phys_dev) < 0) {
824
825                 printk (KERN_ERR "WF-MPU: Failed to allocate IRQ%d\n",
826                         phys_dev->irq);
827                 return -1;
828
829         }
830
831         /* This being a WaveFront (ICS-2115) emulated MPU-401, we have
832            to switch it into UART (dumb) mode, because otherwise, it
833            won't do anything at all.
834         */
835   
836         start_uart_mode ();
837
838         return phys_dev->devno;
839 }
840  
841 void
842 uninstall_wf_mpu (void)
843
844 {
845         release_region (phys_dev->base, 2); 
846         free_irq (phys_dev->irq, phys_dev);
847         sound_unload_mididev (phys_dev->devno);
848
849         if (virt_dev->devno >= 0) {
850                 sound_unload_mididev (virt_dev->devno);
851         }
852 }
853
854 static void
855 start_uart_mode (void)
856
857 {
858         int             ok, i;
859         unsigned long   flags;
860
861         save_flags (flags);
862         cli ();
863
864         /* XXX fix me */
865
866         for (i = 0; i < 30000 && !output_ready (); i++);
867
868         outb (UART_MODE_ON, COMDPORT(phys_dev));
869
870         for (ok = 0, i = 50000; i > 0 && !ok; i--) {
871                 if (input_avail ()) {
872                         if (read_data () == MPU_ACK) {
873                                 ok = 1;
874                         }
875                 }
876         }
877
878         restore_flags (flags);
879 }
880 #endif