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.
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.
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.
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.
25 * NOTE: VIRTUAL MIDI MODE IS ON BY DEFAULT (see wavefront.c)
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.
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.
42 * Copyright (C) by Paul Barton-Davis 1998
43 * Some portions of this file are derived from work that is:
45 * CopyriGht (C) by Hannu Savolainen 1993-1996
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
52 #include <linux/init.h>
53 #include <linux/interrupt.h>
54 #include <linux/spinlock.h>
55 #include "sound_config.h"
57 #include <linux/wavefront.h>
61 struct wf_mpu_config
{
63 #define DATAPORT(d) (d)->base
64 #define COMDPORT(d) (d)->base+1
65 #define STATPORT(d) (d)->base+1
75 void (*inputintr
) (int dev
, unsigned char data
);
76 char isvirtual
; /* do virtual I/O stuff */
79 static struct wf_mpu_config devs
[2];
80 static struct wf_mpu_config
*phys_dev
= &devs
[0];
81 static struct wf_mpu_config
*virt_dev
= &devs
[1];
83 static void start_uart_mode (void);
84 static DEFINE_SPINLOCK(lock
);
86 #define OUTPUT_READY 0x40
87 #define INPUT_AVAIL 0x80
89 #define UART_MODE_ON 0x3F
91 static inline int wf_mpu_status (void)
93 return inb (STATPORT (phys_dev
));
96 static inline int input_avail (void)
98 return !(wf_mpu_status() & INPUT_AVAIL
);
101 static inline int output_ready (void)
103 return !(wf_mpu_status() & OUTPUT_READY
);
106 static inline int read_data (void)
108 return inb (DATAPORT (phys_dev
));
111 static inline void write_data (unsigned char byte
)
113 outb (byte
, DATAPORT (phys_dev
));
117 * States for the input scanner (should be in dev_table.h)
120 #define MST_SYSMSG 100 /* System message (sysx etc). */
121 #define MST_MTC 102 /* Midi Time Code (MTC) qframe msg */
122 #define MST_SONGSEL 103 /* Song select */
123 #define MST_SONGPOS 104 /* Song position pointer */
124 #define MST_TIMED 105 /* Leading timing byte rcvd */
126 /* buffer space check for input scanner */
128 #define BUFTEST(mi) if (mi->m_ptr >= MI_MAX || mi->m_ptr < 0) \
129 {printk(KERN_ERR "WF-MPU: Invalid buffer pointer %d/%d, s=%d\n", \
130 mi->m_ptr, mi->m_left, mi->m_state);mi->m_ptr--;}
132 static unsigned char len_tab
[] = /* # of data bytes following a status
146 wf_mpu_input_scanner (int devno
, int synthdev
, unsigned char midic
)
149 struct midi_input_info
*mi
= &midi_devs
[devno
]->in_info
;
151 switch (mi
->m_state
) {
162 /* XXX do something useful with this. If there is
163 an external MIDI timer (e.g. a hardware sequencer,
164 a useful timer can be derived ...
166 For now, no timer support.
188 mi
->m_state
= MST_SYSMSG
;
193 mi
->m_state
= MST_TIMED
;
196 printk (KERN_ERR
"<MPU: Unknown event %02x> ",
203 int msg
= ((int) (midic
& 0xf0) >> 4);
205 mi
->m_state
= MST_DATA
;
207 if (msg
< 8) { /* Data byte */
209 msg
= ((int) (mi
->m_prev_status
& 0xf0) >> 4);
211 mi
->m_left
= len_tab
[msg
] - 1;
214 mi
->m_buf
[0] = mi
->m_prev_status
;
215 mi
->m_buf
[1] = midic
;
217 if (mi
->m_left
<= 0) {
218 mi
->m_state
= MST_INIT
;
219 do_midi_msg (synthdev
, mi
->m_buf
, mi
->m_ptr
);
222 } else if (msg
== 0xf) { /* MPU MARK */
224 mi
->m_state
= MST_INIT
;
240 mi
->m_prev_status
= midic
;
242 mi
->m_left
= len_tab
[msg
];
245 mi
->m_buf
[0] = midic
;
247 if (mi
->m_left
<= 0) {
248 mi
->m_state
= MST_INIT
;
249 do_midi_msg (synthdev
, mi
->m_buf
, mi
->m_ptr
);
259 mi
->m_state
= MST_SYSEX
;
263 mi
->m_state
= MST_MTC
;
267 mi
->m_state
= MST_SONGPOS
;
272 mi
->m_state
= MST_SONGSEL
;
276 mi
->m_state
= MST_INIT
;
283 mi
->m_state
= MST_INIT
;
284 /* XXX need ext MIDI timer support */
288 mi
->m_state
= MST_INIT
;
289 /* XXX need ext MIDI timer support */
293 mi
->m_state
= MST_INIT
;
294 /* XXX need ext MIDI timer support */
298 mi
->m_state
= MST_INIT
;
299 /* XXX need ext MIDI timer support */
304 mi
->m_state
= MST_INIT
;
308 mi
->m_state
= MST_INIT
;
312 printk (KERN_ERR
"unknown MIDI sysmsg %0x\n", midic
);
313 mi
->m_state
= MST_INIT
;
318 mi
->m_state
= MST_INIT
;
323 mi
->m_state
= MST_INIT
;
331 mi
->m_buf
[mi
->m_ptr
++] = midic
;
332 if (mi
->m_ptr
== 2) {
333 mi
->m_state
= MST_INIT
;
335 /* XXX need ext MIDI timer support */
341 mi
->m_buf
[mi
->m_ptr
++] = midic
;
342 if ((--mi
->m_left
) <= 0) {
343 mi
->m_state
= MST_INIT
;
344 do_midi_msg (synthdev
, mi
->m_buf
, mi
->m_ptr
);
350 printk (KERN_ERR
"Bad state %d ", mi
->m_state
);
351 mi
->m_state
= MST_INIT
;
358 wf_mpuintr(int irq
, void *dev_id
, struct pt_regs
*dummy
)
361 struct wf_mpu_config
*physical_dev
= dev_id
;
362 static struct wf_mpu_config
*input_dev
;
363 struct midi_input_info
*mi
= &midi_devs
[physical_dev
->devno
]->in_info
;
366 if (!input_avail()) { /* not for us */
376 input_dev
= physical_dev
;
379 n
= 50; /* XXX why ? */
382 unsigned char c
= read_data ();
384 if (phys_dev
->isvirtual
) {
386 if (c
== WF_EXTERNAL_SWITCH
) {
387 input_dev
= virt_dev
;
389 } else if (c
== WF_INTERNAL_SWITCH
) {
390 input_dev
= phys_dev
;
392 } /* else just leave it as it is */
395 input_dev
= phys_dev
;
398 if (input_dev
->mode
== MODE_SYNTH
) {
400 wf_mpu_input_scanner (input_dev
->devno
,
401 input_dev
->synthno
, c
);
403 } else if (input_dev
->opened
& OPEN_READ
) {
405 if (input_dev
->inputintr
) {
406 input_dev
->inputintr (input_dev
->devno
, c
);
410 } while (input_avail() && n
-- > 0);
418 wf_mpu_open (int dev
, int mode
,
419 void (*input
) (int dev
, unsigned char data
),
420 void (*output
) (int dev
)
423 struct wf_mpu_config
*devc
;
425 if (dev
< 0 || dev
>= num_midis
|| midi_devs
[dev
]==NULL
)
428 if (phys_dev
->devno
== dev
) {
430 } else if (phys_dev
->isvirtual
&& virt_dev
->devno
== dev
) {
433 printk (KERN_ERR
"WF-MPU: unknown device number %d\n", dev
);
441 devc
->mode
= MODE_MIDI
;
445 devc
->inputintr
= input
;
450 wf_mpu_close (int dev
)
452 struct wf_mpu_config
*devc
;
454 if (dev
< 0 || dev
>= num_midis
|| midi_devs
[dev
]==NULL
)
457 if (phys_dev
->devno
== dev
) {
459 } else if (phys_dev
->isvirtual
&& virt_dev
->devno
== dev
) {
462 printk (KERN_ERR
"WF-MPU: unknown device number %d\n", dev
);
467 devc
->inputintr
= NULL
;
472 wf_mpu_out (int dev
, unsigned char midi_byte
)
476 static int lastoutdev
= -1;
477 unsigned char switchch
;
479 if (phys_dev
->isvirtual
&& lastoutdev
!= dev
) {
481 if (dev
== phys_dev
->devno
) {
482 switchch
= WF_INTERNAL_SWITCH
;
483 } else if (dev
== virt_dev
->devno
) {
484 switchch
= WF_EXTERNAL_SWITCH
;
486 printk (KERN_ERR
"WF-MPU: bad device number %d", dev
);
492 for (timeout
= 30000; timeout
> 0 && !output_ready ();
495 spin_lock_irqsave(&lock
,flags
);
497 if (!output_ready ()) {
498 printk (KERN_WARNING
"WF-MPU: Send switch "
500 spin_unlock_irqrestore(&lock
,flags
);
504 write_data (switchch
);
505 spin_unlock_irqrestore(&lock
,flags
);
511 * Sometimes it takes about 30000 loops before the output becomes ready
512 * (After reset). Normally it takes just about 10 loops.
517 for (timeout
= 30000; timeout
> 0 && !output_ready (); timeout
--);
519 spin_lock_irqsave(&lock
,flags
);
520 if (!output_ready ()) {
521 spin_unlock_irqrestore(&lock
,flags
);
522 printk (KERN_WARNING
"WF-MPU: Send data timeout\n");
526 write_data (midi_byte
);
527 spin_unlock_irqrestore(&lock
,flags
);
532 static inline int wf_mpu_start_read (int dev
) {
536 static inline int wf_mpu_end_read (int dev
) {
540 static int wf_mpu_ioctl (int dev
, unsigned cmd
, void __user
*arg
)
543 "WF-MPU: Intelligent mode not supported by hardware.\n");
547 static int wf_mpu_buffer_status (int dev
)
552 static struct synth_operations wf_mpu_synth_operations
[2];
553 static struct midi_operations wf_mpu_midi_operations
[2];
555 static struct midi_operations wf_mpu_midi_proto
=
557 .owner
= THIS_MODULE
,
558 .info
= {"WF-MPU MIDI", 0, MIDI_CAP_MPU401
, SNDCARD_MPU401
},
559 .in_info
= {0}, /* in_info */
561 .close
= wf_mpu_close
,
562 .ioctl
= wf_mpu_ioctl
,
563 .outputc
= wf_mpu_out
,
564 .start_read
= wf_mpu_start_read
,
565 .end_read
= wf_mpu_end_read
,
566 .buffer_status
= wf_mpu_buffer_status
,
569 static struct synth_info wf_mpu_synth_info_proto
=
570 {"WaveFront MPU-401 interface", 0,
571 SYNTH_TYPE_MIDI
, MIDI_TYPE_MPU401
, 0, 128, 0, 128, SYNTH_CAP_INPUT
};
573 static struct synth_info wf_mpu_synth_info
[2];
576 wf_mpu_synth_ioctl (int dev
, unsigned int cmd
, void __user
*arg
)
581 midi_dev
= synth_devs
[dev
]->midi_dev
;
583 if (midi_dev
< 0 || midi_dev
> num_midis
|| midi_devs
[midi_dev
]==NULL
)
586 if (midi_dev
== phys_dev
->devno
) {
588 } else if (phys_dev
->isvirtual
&& midi_dev
== virt_dev
->devno
) {
596 case SNDCTL_SYNTH_INFO
:
597 if (copy_to_user(arg
,
598 &wf_mpu_synth_info
[index
],
599 sizeof (struct synth_info
)))
603 case SNDCTL_SYNTH_MEMAVL
:
612 wf_mpu_synth_open (int dev
, int mode
)
615 struct wf_mpu_config
*devc
;
617 midi_dev
= synth_devs
[dev
]->midi_dev
;
619 if (midi_dev
< 0 || midi_dev
> num_midis
|| midi_devs
[midi_dev
]==NULL
) {
623 if (phys_dev
->devno
== midi_dev
) {
625 } else if (phys_dev
->isvirtual
&& virt_dev
->devno
== midi_dev
) {
628 printk (KERN_ERR
"WF-MPU: unknown device number %d\n", dev
);
636 devc
->mode
= MODE_SYNTH
;
639 devc
->inputintr
= NULL
;
644 wf_mpu_synth_close (int dev
)
647 struct wf_mpu_config
*devc
;
649 midi_dev
= synth_devs
[dev
]->midi_dev
;
651 if (phys_dev
->devno
== midi_dev
) {
653 } else if (phys_dev
->isvirtual
&& virt_dev
->devno
== midi_dev
) {
656 printk (KERN_ERR
"WF-MPU: unknown device number %d\n", dev
);
660 devc
->inputintr
= NULL
;
665 #define _MIDI_SYNTH_C_
666 #define MIDI_SYNTH_NAME "WaveFront (MIDI)"
667 #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
668 #include "midi_synth.h"
670 static struct synth_operations wf_mpu_synth_proto
=
672 .owner
= THIS_MODULE
,
673 .id
= "WaveFront (ICS2115)",
674 .info
= NULL
, /* info field, filled in during configuration */
675 .midi_dev
= 0, /* MIDI dev XXX should this be -1 ? */
676 .synth_type
= SYNTH_TYPE_MIDI
,
677 .synth_subtype
= SAMPLE_TYPE_WAVEFRONT
,
678 .open
= wf_mpu_synth_open
,
679 .close
= wf_mpu_synth_close
,
680 .ioctl
= wf_mpu_synth_ioctl
,
681 .kill_note
= midi_synth_kill_note
,
682 .start_note
= midi_synth_start_note
,
683 .set_instr
= midi_synth_set_instr
,
684 .reset
= midi_synth_reset
,
685 .hw_control
= midi_synth_hw_control
,
686 .load_patch
= midi_synth_load_patch
,
687 .aftertouch
= midi_synth_aftertouch
,
688 .controller
= midi_synth_controller
,
689 .panning
= midi_synth_panning
,
690 .bender
= midi_synth_bender
,
691 .setup_voice
= midi_synth_setup_voice
,
692 .send_sysex
= midi_synth_send_sysex
696 config_wf_mpu (struct wf_mpu_config
*dev
)
703 if (dev
== phys_dev
) {
704 name
= "WaveFront internal MIDI";
707 memcpy ((char *) &wf_mpu_synth_operations
[index
],
708 (char *) &wf_mpu_synth_proto
,
709 sizeof (struct synth_operations
));
711 name
= "WaveFront external MIDI";
714 /* no synth operations for an external MIDI interface */
717 memcpy ((char *) &wf_mpu_synth_info
[dev
->devno
],
718 (char *) &wf_mpu_synth_info_proto
,
719 sizeof (struct synth_info
));
721 strcpy (wf_mpu_synth_info
[index
].name
, name
);
723 wf_mpu_synth_operations
[index
].midi_dev
= dev
->devno
;
724 wf_mpu_synth_operations
[index
].info
= &wf_mpu_synth_info
[index
];
726 memcpy ((char *) &wf_mpu_midi_operations
[index
],
727 (char *) &wf_mpu_midi_proto
,
728 sizeof (struct midi_operations
));
731 wf_mpu_midi_operations
[index
].converter
= NULL
;
733 wf_mpu_midi_operations
[index
].converter
=
734 &wf_mpu_synth_operations
[index
];
737 strcpy (wf_mpu_midi_operations
[index
].info
.name
, name
);
739 midi_devs
[dev
->devno
] = &wf_mpu_midi_operations
[index
];
740 midi_devs
[dev
->devno
]->in_info
.m_busy
= 0;
741 midi_devs
[dev
->devno
]->in_info
.m_state
= MST_INIT
;
742 midi_devs
[dev
->devno
]->in_info
.m_ptr
= 0;
743 midi_devs
[dev
->devno
]->in_info
.m_left
= 0;
744 midi_devs
[dev
->devno
]->in_info
.m_prev_status
= 0;
746 devs
[index
].opened
= 0;
747 devs
[index
].mode
= 0;
752 int virtual_midi_enable (void)
755 if ((virt_dev
->devno
< 0) &&
756 (virt_dev
->devno
= sound_alloc_mididev()) == -1) {
758 "WF-MPU: too many midi devices detected\n");
762 config_wf_mpu (virt_dev
);
764 phys_dev
->isvirtual
= 1;
765 return virt_dev
->devno
;
769 virtual_midi_disable (void)
774 spin_lock_irqsave(&lock
,flags
);
776 wf_mpu_close (virt_dev
->devno
);
777 /* no synth on virt_dev, so no need to call wf_mpu_synth_close() */
778 phys_dev
->isvirtual
= 0;
780 spin_unlock_irqrestore(&lock
,flags
);
785 int __init
detect_wf_mpu (int irq
, int io_base
)
787 if (!request_region(io_base
, 2, "wavefront midi")) {
788 printk (KERN_WARNING
"WF-MPU: I/O port %x already in use.\n",
793 phys_dev
->base
= io_base
;
795 phys_dev
->devno
= -1;
796 virt_dev
->devno
= -1;
801 int __init
install_wf_mpu (void)
803 if ((phys_dev
->devno
= sound_alloc_mididev()) < 0){
805 printk (KERN_ERR
"WF-MPU: Too many MIDI devices detected.\n");
806 release_region(phys_dev
->base
, 2);
810 phys_dev
->isvirtual
= 0;
812 if (config_wf_mpu (phys_dev
)) {
815 "WF-MPU: configuration for MIDI device %d failed\n",
817 sound_unload_mididev (phys_dev
->devno
);
821 /* OK, now we're configured to handle an interrupt ... */
823 if (request_irq (phys_dev
->irq
, wf_mpuintr
, SA_INTERRUPT
|SA_SHIRQ
,
824 "wavefront midi", phys_dev
) < 0) {
826 printk (KERN_ERR
"WF-MPU: Failed to allocate IRQ%d\n",
832 /* This being a WaveFront (ICS-2115) emulated MPU-401, we have
833 to switch it into UART (dumb) mode, because otherwise, it
834 won't do anything at all.
839 return phys_dev
->devno
;
843 uninstall_wf_mpu (void)
846 release_region (phys_dev
->base
, 2);
847 free_irq (phys_dev
->irq
, phys_dev
);
848 sound_unload_mididev (phys_dev
->devno
);
850 if (virt_dev
->devno
>= 0) {
851 sound_unload_mididev (virt_dev
->devno
);
856 start_uart_mode (void)
862 spin_lock_irqsave(&lock
,flags
);
866 for (i
= 0; i
< 30000 && !output_ready (); i
++);
868 outb (UART_MODE_ON
, COMDPORT(phys_dev
));
870 for (ok
= 0, i
= 50000; i
> 0 && !ok
; i
--) {
871 if (input_avail ()) {
872 if (read_data () == MPU_ACK
) {
878 spin_unlock_irqrestore(&lock
,flags
);