1/*
2 * Copyright (C) by Paul Barton-Davis 1998-1999
3 *
4 * This file is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
5 * Version 2 (June 1991). See the "COPYING" file distributed with this
6 * software for more info.
7 */
8
9/* The low level driver for the WaveFront ICS2115 MIDI interface(s)
10 *
11 * Note that there is also an MPU-401 emulation (actually, a UART-401
12 * emulation) on the CS4232 on the Tropez and Tropez Plus. This code
13 * has nothing to do with that interface at all.
14 *
15 * The interface is essentially just a UART-401, but is has the
16 * interesting property of supporting what Turtle Beach called
17 * "Virtual MIDI" mode. In this mode, there are effectively *two*
18 * MIDI buses accessible via the interface, one that is routed
19 * solely to/from the external WaveFront synthesizer and the other
20 * corresponding to the pin/socket connector used to link external
21 * MIDI devices to the board.
22 *
23 * This driver fully supports this mode, allowing two distinct MIDI
24 * busses to be used completely independently, giving 32 channels of
25 * MIDI routing, 16 to the WaveFront synth and 16 to the external MIDI
26 * bus. The devices are named /dev/snd/midiCnD0 and /dev/snd/midiCnD1,
27 * where `n' is the card number. Note that the device numbers may be
28 * something other than 0 and 1 if the CS4232 UART/MPU-401 interface
29 * is enabled.
30 *
31 * Switching between the two is accomplished externally by the driver
32 * using the two otherwise unused MIDI bytes. See the code for more details.
33 *
34 * NOTE: VIRTUAL MIDI MODE IS ON BY DEFAULT (see lowlevel/isa/wavefront.c)
35 *
36 * The main reason to turn off Virtual MIDI mode is when you want to
37 * tightly couple the WaveFront synth with an external MIDI
38 * device. You won't be able to distinguish the source of any MIDI
39 * data except via SysEx ID, but thats probably OK, since for the most
40 * part, the WaveFront won't be sending any MIDI data at all.
41 *
42 * The main reason to turn on Virtual MIDI Mode is to provide two
43 * completely independent 16-channel MIDI buses, one to the
44 * WaveFront and one to any external MIDI devices. Given the 32
45 * voice nature of the WaveFront, its pretty easy to find a use
46 * for all 16 channels driving just that synth.
47 *
48 */
49
50#include <linux/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	/* Its not OK to try to change the status of "virtuality" of
125	   the MIDI interface while we're outputting stuff.  See
126	   snd_wavefront_midi_{enable,disable}_virtual () for the
127	   other half of this.
128
129	   The first loop attempts to flush any data from the
130	   current output device, and then the second
131	   emits the switch byte (if necessary), and starts
132	   outputting data for the output device currently in use.
133	*/
134
135	if (midi->substream_output[midi->output_mpu] == NULL) {
136		goto __second;
137	}
138
139	while (max > 0) {
140
141		/* XXX fix me - no hard timing loops allowed! */
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		/* XXX fix me - no hard timing loops allowed! */
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;	/* don't invert the value from now */
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	mod_timer(&midi->timer, 1 + jiffies);
360	spin_unlock_irqrestore (&midi->virtual, flags);
361	snd_wavefront_midi_output_write(card);
362}
363
364static void snd_wavefront_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
365{
366	unsigned long flags;
367	snd_wavefront_midi_t *midi;
368	snd_wavefront_mpu_id mpu;
369
370	if (substream == NULL || substream->rmidi == NULL)
371	        return;
372
373	if (substream->rmidi->private_data == NULL)
374	        return;
375
376	mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
377
378	if ((midi = get_wavefront_midi (substream)) == NULL) {
379		return;
380	}
381
382	spin_lock_irqsave (&midi->virtual, flags);
383	if (up) {
384		if ((midi->mode[mpu] & MPU401_MODE_OUTPUT_TRIGGER) == 0) {
385			if (!midi->istimer) {
386				setup_timer(&midi->timer,
387					    snd_wavefront_midi_output_timer,
388					    (unsigned long) substream->rmidi->card->private_data);
389				mod_timer(&midi->timer, 1 + jiffies);
390			}
391			midi->istimer++;
392			midi->mode[mpu] |= MPU401_MODE_OUTPUT_TRIGGER;
393		}
394	} else {
395		midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
396	}
397	spin_unlock_irqrestore (&midi->virtual, flags);
398
399	if (up)
400		snd_wavefront_midi_output_write((snd_wavefront_card_t *)substream->rmidi->card->private_data);
401}
402
403void
404snd_wavefront_midi_interrupt (snd_wavefront_card_t *card)
405
406{
407	unsigned long flags;
408	snd_wavefront_midi_t *midi;
409	static struct snd_rawmidi_substream *substream = NULL;
410	static int mpu = external_mpu;
411	int max = 128;
412	unsigned char byte;
413
414	midi = &card->wavefront.midi;
415
416	if (!input_avail (midi)) { /* not for us */
417		snd_wavefront_midi_output_write(card);
418		return;
419	}
420
421	spin_lock_irqsave (&midi->virtual, flags);
422	while (--max) {
423
424		if (input_avail (midi)) {
425			byte = read_data (midi);
426
427			if (midi->isvirtual) {
428				if (byte == WF_EXTERNAL_SWITCH) {
429					substream = midi->substream_input[external_mpu];
430					mpu = external_mpu;
431				} else if (byte == WF_INTERNAL_SWITCH) {
432					substream = midi->substream_output[internal_mpu];
433					mpu = internal_mpu;
434				} /* else just leave it as it is */
435			} else {
436				substream = midi->substream_input[internal_mpu];
437				mpu = internal_mpu;
438			}
439
440			if (substream == NULL) {
441				continue;
442			}
443
444			if (midi->mode[mpu] & MPU401_MODE_INPUT_TRIGGER) {
445				snd_rawmidi_receive(substream, &byte, 1);
446			}
447		} else {
448			break;
449		}
450	}
451	spin_unlock_irqrestore (&midi->virtual, flags);
452
453	snd_wavefront_midi_output_write(card);
454}
455
456void
457snd_wavefront_midi_enable_virtual (snd_wavefront_card_t *card)
458
459{
460	unsigned long flags;
461
462	spin_lock_irqsave (&card->wavefront.midi.virtual, flags);
463	card->wavefront.midi.isvirtual = 1;
464	card->wavefront.midi.output_mpu = internal_mpu;
465	card->wavefront.midi.input_mpu = internal_mpu;
466	spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags);
467}
468
469void
470snd_wavefront_midi_disable_virtual (snd_wavefront_card_t *card)
471
472{
473	unsigned long flags;
474
475	spin_lock_irqsave (&card->wavefront.midi.virtual, flags);
476	// snd_wavefront_midi_input_close (card->ics2115_external_rmidi);
477	// snd_wavefront_midi_output_close (card->ics2115_external_rmidi);
478	card->wavefront.midi.isvirtual = 0;
479	spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags);
480}
481
482int
483snd_wavefront_midi_start (snd_wavefront_card_t *card)
484
485{
486	int ok, i;
487	unsigned char rbuf[4], wbuf[4];
488	snd_wavefront_t *dev;
489	snd_wavefront_midi_t *midi;
490
491	dev = &card->wavefront;
492	midi = &dev->midi;
493
494	/* The ICS2115 MPU-401 interface doesn't do anything
495	   until its set into UART mode.
496	*/
497
498	/* XXX fix me - no hard timing loops allowed! */
499
500	for (i = 0; i < 30000 && !output_ready (midi); i++);
501
502	if (!output_ready (midi)) {
503		snd_printk ("MIDI interface not ready for command\n");
504		return -1;
505	}
506
507	/* Any interrupts received from now on
508	   are owned by the MIDI side of things.
509	*/
510
511	dev->interrupts_are_midi = 1;
512
513	outb (UART_MODE_ON, midi->mpu_command_port);
514
515	for (ok = 0, i = 50000; i > 0 && !ok; i--) {
516		if (input_avail (midi)) {
517			if (read_data (midi) == MPU_ACK) {
518				ok = 1;
519				break;
520			}
521		}
522	}
523
524	if (!ok) {
525		snd_printk ("cannot set UART mode for MIDI interface");
526		dev->interrupts_are_midi = 0;
527		return -1;
528	}
529
530	/* Route external MIDI to WaveFront synth (by default) */
531
532	if (snd_wavefront_cmd (dev, WFC_MISYNTH_ON, rbuf, wbuf)) {
533		snd_printk ("can't enable MIDI-IN-2-synth routing.\n");
534		/* XXX error ? */
535	}
536
537	/* Turn on Virtual MIDI, but first *always* turn it off,
538	   since otherwise consecutive reloads of the driver will
539	   never cause the hardware to generate the initial "internal" or
540	   "external" source bytes in the MIDI data stream. This
541	   is pretty important, since the internal hardware generally will
542	   be used to generate none or very little MIDI output, and
543	   thus the only source of MIDI data is actually external. Without
544	   the switch bytes, the driver will think it all comes from
545	   the internal interface. Duh.
546	*/
547
548	if (snd_wavefront_cmd (dev, WFC_VMIDI_OFF, rbuf, wbuf)) {
549		snd_printk ("virtual MIDI mode not disabled\n");
550		return 0; /* We're OK, but missing the external MIDI dev */
551	}
552
553	snd_wavefront_midi_enable_virtual (card);
554
555	if (snd_wavefront_cmd (dev, WFC_VMIDI_ON, rbuf, wbuf)) {
556		snd_printk ("cannot enable virtual MIDI mode.\n");
557		snd_wavefront_midi_disable_virtual (card);
558	}
559	return 0;
560}
561
562struct snd_rawmidi_ops snd_wavefront_midi_output =
563{
564	.open =		snd_wavefront_midi_output_open,
565	.close =	snd_wavefront_midi_output_close,
566	.trigger =	snd_wavefront_midi_output_trigger,
567};
568
569struct snd_rawmidi_ops snd_wavefront_midi_input =
570{
571	.open =		snd_wavefront_midi_input_open,
572	.close =	snd_wavefront_midi_input_close,
573	.trigger =	snd_wavefront_midi_input_trigger,
574};
575
576