1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) by Paul Barton-Davis 1998-1999
6 /* The low level driver for the WaveFront ICS2115 MIDI interface(s)
8 * Note that there is also an MPU-401 emulation (actually, a UART-401
9 * emulation) on the CS4232 on the Tropez and Tropez Plus. This code
10 * has nothing to do with that interface at all.
12 * The interface is essentially just a UART-401, but is has the
13 * interesting property of supporting what Turtle Beach called
14 * "Virtual MIDI" mode. In this mode, there are effectively *two*
15 * MIDI buses accessible via the interface, one that is routed
16 * solely to/from the external WaveFront synthesizer and the other
17 * corresponding to the pin/socket connector used to link external
18 * MIDI devices to the board.
20 * This driver fully supports this mode, allowing two distinct MIDI
21 * busses to be used completely independently, giving 32 channels of
22 * MIDI routing, 16 to the WaveFront synth and 16 to the external MIDI
23 * bus. The devices are named /dev/snd/midiCnD0 and /dev/snd/midiCnD1,
24 * where `n' is the card number. Note that the device numbers may be
25 * something other than 0 and 1 if the CS4232 UART/MPU-401 interface
28 * Switching between the two is accomplished externally by the driver
29 * using the two otherwise unused MIDI bytes. See the code for more details.
31 * NOTE: VIRTUAL MIDI MODE IS ON BY DEFAULT (see lowlevel/isa/wavefront.c)
33 * The main reason to turn off Virtual MIDI mode is when you want to
34 * tightly couple the WaveFront synth with an external MIDI
35 * device. You won't be able to distinguish the source of any MIDI
36 * data except via SysEx ID, but thats probably OK, since for the most
37 * part, the WaveFront won't be sending any MIDI data at all.
39 * The main reason to turn on Virtual MIDI Mode is to provide two
40 * completely independent 16-channel MIDI buses, one to the
41 * WaveFront and one to any external MIDI devices. Given the 32
42 * voice nature of the WaveFront, its pretty easy to find a use
43 * for all 16 channels driving just that synth.
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>
55 wf_mpu_status (snd_wavefront_midi_t *midi)
58 return inb (midi->mpu_status_port);
62 input_avail (snd_wavefront_midi_t *midi)
65 return !(wf_mpu_status(midi) & INPUT_AVAIL);
69 output_ready (snd_wavefront_midi_t *midi)
72 return !(wf_mpu_status(midi) & OUTPUT_READY);
76 read_data (snd_wavefront_midi_t *midi)
79 return inb (midi->mpu_data_port);
83 write_data (snd_wavefront_midi_t *midi, unsigned char byte)
86 outb (byte, midi->mpu_data_port);
89 static snd_wavefront_midi_t *
90 get_wavefront_midi (struct snd_rawmidi_substream *substream)
93 struct snd_card *card;
94 snd_wavefront_card_t *acard;
96 if (substream == NULL || substream->rmidi == NULL)
99 card = substream->rmidi->card;
104 if (card->private_data == NULL)
107 acard = card->private_data;
109 return &acard->wavefront.midi;
112 static void snd_wavefront_midi_output_write(snd_wavefront_card_t *card)
114 snd_wavefront_midi_t *midi = &card->wavefront.midi;
115 snd_wavefront_mpu_id mpu;
117 unsigned char midi_byte;
118 int max = 256, mask = 1;
121 /* Its not OK to try to change the status of "virtuality" of
122 the MIDI interface while we're outputting stuff. See
123 snd_wavefront_midi_{enable,disable}_virtual () for the
126 The first loop attempts to flush any data from the
127 current output device, and then the second
128 emits the switch byte (if necessary), and starts
129 outputting data for the output device currently in use.
132 if (midi->substream_output[midi->output_mpu] == NULL) {
138 /* XXX fix me - no hard timing loops allowed! */
140 for (timeout = 30000; timeout > 0; timeout--) {
141 if (output_ready (midi))
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);
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);
159 if (--midi->istimer <= 0)
160 del_timer(&midi->timer);
162 midi->mode[midi->output_mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
163 spin_unlock_irqrestore (&midi->virtual, flags);
167 spin_unlock_irqrestore (&midi->virtual, flags);
170 spin_unlock_irqrestore (&midi->virtual, flags);
175 if (midi->substream_output[!midi->output_mpu] == NULL) {
181 /* XXX fix me - no hard timing loops allowed! */
183 for (timeout = 30000; timeout > 0; timeout--) {
184 if (output_ready (midi))
188 spin_lock_irqsave (&midi->virtual, flags);
189 if (!midi->isvirtual)
191 mpu = midi->output_mpu ^ mask;
192 mask = 0; /* don't invert the value from now */
193 if ((midi->mode[mpu] & MPU401_MODE_OUTPUT) == 0) {
194 spin_unlock_irqrestore (&midi->virtual, flags);
197 if (snd_rawmidi_transmit_empty(midi->substream_output[mpu]))
199 if (output_ready (midi)) {
200 if (mpu != midi->output_mpu) {
201 write_data(midi, mpu == internal_mpu ?
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);
214 if (--midi->istimer <= 0)
215 del_timer(&midi->timer);
217 midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
218 spin_unlock_irqrestore (&midi->virtual, flags);
222 spin_unlock_irqrestore (&midi->virtual, flags);
225 spin_unlock_irqrestore (&midi->virtual, flags);
229 static int snd_wavefront_midi_input_open(struct snd_rawmidi_substream *substream)
232 snd_wavefront_midi_t *midi;
233 snd_wavefront_mpu_id mpu;
235 if (snd_BUG_ON(!substream || !substream->rmidi))
237 if (snd_BUG_ON(!substream->rmidi->private_data))
240 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
242 midi = get_wavefront_midi(substream);
246 spin_lock_irqsave (&midi->open, flags);
247 midi->mode[mpu] |= MPU401_MODE_INPUT;
248 midi->substream_input[mpu] = substream;
249 spin_unlock_irqrestore (&midi->open, flags);
254 static int snd_wavefront_midi_output_open(struct snd_rawmidi_substream *substream)
257 snd_wavefront_midi_t *midi;
258 snd_wavefront_mpu_id mpu;
260 if (snd_BUG_ON(!substream || !substream->rmidi))
262 if (snd_BUG_ON(!substream->rmidi->private_data))
265 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
267 midi = get_wavefront_midi(substream);
271 spin_lock_irqsave (&midi->open, flags);
272 midi->mode[mpu] |= MPU401_MODE_OUTPUT;
273 midi->substream_output[mpu] = substream;
274 spin_unlock_irqrestore (&midi->open, flags);
279 static int snd_wavefront_midi_input_close(struct snd_rawmidi_substream *substream)
282 snd_wavefront_midi_t *midi;
283 snd_wavefront_mpu_id mpu;
285 if (snd_BUG_ON(!substream || !substream->rmidi))
287 if (snd_BUG_ON(!substream->rmidi->private_data))
290 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
292 midi = get_wavefront_midi(substream);
296 spin_lock_irqsave (&midi->open, flags);
297 midi->mode[mpu] &= ~MPU401_MODE_INPUT;
298 spin_unlock_irqrestore (&midi->open, flags);
303 static int snd_wavefront_midi_output_close(struct snd_rawmidi_substream *substream)
306 snd_wavefront_midi_t *midi;
307 snd_wavefront_mpu_id mpu;
309 if (snd_BUG_ON(!substream || !substream->rmidi))
311 if (snd_BUG_ON(!substream->rmidi->private_data))
314 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
316 midi = get_wavefront_midi(substream);
320 spin_lock_irqsave (&midi->open, flags);
321 midi->mode[mpu] &= ~MPU401_MODE_OUTPUT;
322 spin_unlock_irqrestore (&midi->open, flags);
326 static void snd_wavefront_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
329 snd_wavefront_midi_t *midi;
330 snd_wavefront_mpu_id mpu;
332 if (substream == NULL || substream->rmidi == NULL)
335 if (substream->rmidi->private_data == NULL)
338 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
340 midi = get_wavefront_midi(substream);
344 spin_lock_irqsave (&midi->virtual, flags);
346 midi->mode[mpu] |= MPU401_MODE_INPUT_TRIGGER;
348 midi->mode[mpu] &= ~MPU401_MODE_INPUT_TRIGGER;
350 spin_unlock_irqrestore (&midi->virtual, flags);
353 static void snd_wavefront_midi_output_timer(struct timer_list *t)
355 snd_wavefront_midi_t *midi = from_timer(midi, t, timer);
356 snd_wavefront_card_t *card = midi->timer_card;
359 spin_lock_irqsave (&midi->virtual, flags);
360 mod_timer(&midi->timer, 1 + jiffies);
361 spin_unlock_irqrestore (&midi->virtual, flags);
362 snd_wavefront_midi_output_write(card);
365 static void snd_wavefront_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
368 snd_wavefront_midi_t *midi;
369 snd_wavefront_mpu_id mpu;
371 if (substream == NULL || substream->rmidi == NULL)
374 if (substream->rmidi->private_data == NULL)
377 mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
379 midi = get_wavefront_midi(substream);
383 spin_lock_irqsave (&midi->virtual, flags);
385 if ((midi->mode[mpu] & MPU401_MODE_OUTPUT_TRIGGER) == 0) {
386 if (!midi->istimer) {
387 timer_setup(&midi->timer,
388 snd_wavefront_midi_output_timer,
390 mod_timer(&midi->timer, 1 + jiffies);
393 midi->mode[mpu] |= MPU401_MODE_OUTPUT_TRIGGER;
396 midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
398 spin_unlock_irqrestore (&midi->virtual, flags);
401 snd_wavefront_midi_output_write((snd_wavefront_card_t *)substream->rmidi->card->private_data);
405 snd_wavefront_midi_interrupt (snd_wavefront_card_t *card)
409 snd_wavefront_midi_t *midi;
410 static struct snd_rawmidi_substream *substream = NULL;
411 static int mpu = external_mpu;
415 midi = &card->wavefront.midi;
417 if (!input_avail (midi)) { /* not for us */
418 snd_wavefront_midi_output_write(card);
422 spin_lock_irqsave (&midi->virtual, flags);
425 if (input_avail (midi)) {
426 byte = read_data (midi);
428 if (midi->isvirtual) {
429 if (byte == WF_EXTERNAL_SWITCH) {
430 substream = midi->substream_input[external_mpu];
432 } else if (byte == WF_INTERNAL_SWITCH) {
433 substream = midi->substream_output[internal_mpu];
435 } /* else just leave it as it is */
437 substream = midi->substream_input[internal_mpu];
441 if (substream == NULL) {
445 if (midi->mode[mpu] & MPU401_MODE_INPUT_TRIGGER) {
446 snd_rawmidi_receive(substream, &byte, 1);
452 spin_unlock_irqrestore (&midi->virtual, flags);
454 snd_wavefront_midi_output_write(card);
458 snd_wavefront_midi_enable_virtual (snd_wavefront_card_t *card)
463 spin_lock_irqsave (&card->wavefront.midi.virtual, flags);
464 card->wavefront.midi.isvirtual = 1;
465 card->wavefront.midi.output_mpu = internal_mpu;
466 card->wavefront.midi.input_mpu = internal_mpu;
467 spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags);
471 snd_wavefront_midi_disable_virtual (snd_wavefront_card_t *card)
476 spin_lock_irqsave (&card->wavefront.midi.virtual, flags);
477 // snd_wavefront_midi_input_close (card->ics2115_external_rmidi);
478 // snd_wavefront_midi_output_close (card->ics2115_external_rmidi);
479 card->wavefront.midi.isvirtual = 0;
480 spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags);
484 snd_wavefront_midi_start (snd_wavefront_card_t *card)
488 unsigned char rbuf[4], wbuf[4];
489 snd_wavefront_t *dev;
490 snd_wavefront_midi_t *midi;
492 dev = &card->wavefront;
495 /* The ICS2115 MPU-401 interface doesn't do anything
496 until its set into UART mode.
499 /* XXX fix me - no hard timing loops allowed! */
501 for (i = 0; i < 30000 && !output_ready (midi); i++);
503 if (!output_ready (midi)) {
504 snd_printk ("MIDI interface not ready for command\n");
508 /* Any interrupts received from now on
509 are owned by the MIDI side of things.
512 dev->interrupts_are_midi = 1;
514 outb (UART_MODE_ON, midi->mpu_command_port);
516 for (ok = 0, i = 50000; i > 0 && !ok; i--) {
517 if (input_avail (midi)) {
518 if (read_data (midi) == MPU_ACK) {
526 snd_printk ("cannot set UART mode for MIDI interface");
527 dev->interrupts_are_midi = 0;
531 /* Route external MIDI to WaveFront synth (by default) */
533 if (snd_wavefront_cmd (dev, WFC_MISYNTH_ON, rbuf, wbuf)) {
534 snd_printk ("can't enable MIDI-IN-2-synth routing.\n");
538 /* Turn on Virtual MIDI, but first *always* turn it off,
539 since otherwise consecutive reloads of the driver will
540 never cause the hardware to generate the initial "internal" or
541 "external" source bytes in the MIDI data stream. This
542 is pretty important, since the internal hardware generally will
543 be used to generate none or very little MIDI output, and
544 thus the only source of MIDI data is actually external. Without
545 the switch bytes, the driver will think it all comes from
546 the internal interface. Duh.
549 if (snd_wavefront_cmd (dev, WFC_VMIDI_OFF, rbuf, wbuf)) {
550 snd_printk ("virtual MIDI mode not disabled\n");
551 return 0; /* We're OK, but missing the external MIDI dev */
554 snd_wavefront_midi_enable_virtual (card);
556 if (snd_wavefront_cmd (dev, WFC_VMIDI_ON, rbuf, wbuf)) {
557 snd_printk ("cannot enable virtual MIDI mode.\n");
558 snd_wavefront_midi_disable_virtual (card);
563 const struct snd_rawmidi_ops snd_wavefront_midi_output =
565 .open = snd_wavefront_midi_output_open,
566 .close = snd_wavefront_midi_output_close,
567 .trigger = snd_wavefront_midi_output_trigger,
570 const struct snd_rawmidi_ops snd_wavefront_midi_input =
572 .open = snd_wavefront_midi_input_open,
573 .close = snd_wavefront_midi_input_close,
574 .trigger = snd_wavefront_midi_input_trigger,