KVM: x86/mmu: remove "bool base_only" arguments
[linux-2.6-microblaze.git] / sound / isa / wavefront / wavefront_midi.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) by Paul Barton-Davis 1998-1999
4  */
5
6 /* The low level driver for the WaveFront ICS2115 MIDI interface(s)
7  *
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.
11  *
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.
19  *
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
26  * is enabled.
27  *
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.
30  *
31  * NOTE: VIRTUAL MIDI MODE IS ON BY DEFAULT (see lowlevel/isa/wavefront.c)
32  *
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.
38  *  
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.
44  *  
45  */
46
47 #include <linux/io.h>
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>
53
54 static inline int 
55 wf_mpu_status (snd_wavefront_midi_t *midi)
56
57 {
58         return inb (midi->mpu_status_port);
59 }
60
61 static inline int 
62 input_avail (snd_wavefront_midi_t *midi)
63
64 {
65         return !(wf_mpu_status(midi) & INPUT_AVAIL);
66 }
67
68 static inline int
69 output_ready (snd_wavefront_midi_t *midi)
70
71 {
72         return !(wf_mpu_status(midi) & OUTPUT_READY);
73 }
74
75 static inline int 
76 read_data (snd_wavefront_midi_t *midi)
77
78 {
79         return inb (midi->mpu_data_port);
80 }
81
82 static inline void 
83 write_data (snd_wavefront_midi_t *midi, unsigned char byte)
84
85 {
86         outb (byte, midi->mpu_data_port);
87 }
88
89 static snd_wavefront_midi_t *
90 get_wavefront_midi (struct snd_rawmidi_substream *substream)
91
92 {
93         struct snd_card *card;
94         snd_wavefront_card_t *acard;
95
96         if (substream == NULL || substream->rmidi == NULL) 
97                 return NULL;
98
99         card = substream->rmidi->card;
100
101         if (card == NULL) 
102                 return NULL;
103
104         if (card->private_data == NULL) 
105                 return NULL;
106
107         acard = card->private_data;
108
109         return &acard->wavefront.midi;
110 }
111
112 static void snd_wavefront_midi_output_write(snd_wavefront_card_t *card)
113 {
114         snd_wavefront_midi_t *midi = &card->wavefront.midi;
115         snd_wavefront_mpu_id  mpu;
116         unsigned long flags;
117         unsigned char midi_byte;
118         int max = 256, mask = 1;
119         int timeout;
120
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
124            other half of this.  
125
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.
130         */
131
132         if (midi->substream_output[midi->output_mpu] == NULL) {
133                 goto __second;
134         }
135
136         while (max > 0) {
137
138                 /* XXX fix me - no hard timing loops allowed! */
139
140                 for (timeout = 30000; timeout > 0; timeout--) {
141                         if (output_ready (midi))
142                                 break;
143                 }
144         
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);
148                         goto __second;
149                 }
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);
156                                 max--;
157                         } else {
158                                 if (midi->istimer) {
159                                         if (--midi->istimer <= 0)
160                                                 del_timer(&midi->timer);
161                                 }
162                                 midi->mode[midi->output_mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
163                                 spin_unlock_irqrestore (&midi->virtual, flags);
164                                 goto __second;
165                         }
166                 } else {
167                         spin_unlock_irqrestore (&midi->virtual, flags);
168                         return;
169                 }
170                 spin_unlock_irqrestore (&midi->virtual, flags);
171         }
172
173       __second:
174
175         if (midi->substream_output[!midi->output_mpu] == NULL) {
176                 return;
177         }
178
179         while (max > 0) {
180
181                 /* XXX fix me - no hard timing loops allowed! */
182
183                 for (timeout = 30000; timeout > 0; timeout--) {
184                         if (output_ready (midi))
185                                 break;
186                 }
187         
188                 spin_lock_irqsave (&midi->virtual, flags);
189                 if (!midi->isvirtual)
190                         mask = 0;
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);
195                         return;
196                 }
197                 if (snd_rawmidi_transmit_empty(midi->substream_output[mpu]))
198                         goto __timer;
199                 if (output_ready (midi)) {
200                         if (mpu != midi->output_mpu) {
201                                 write_data(midi, mpu == internal_mpu ?
202                                                         WF_INTERNAL_SWITCH :
203                                                         WF_EXTERNAL_SWITCH);
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);
210                                 max--;
211                         } else {
212                               __timer:
213                                 if (midi->istimer) {
214                                         if (--midi->istimer <= 0)
215                                                 del_timer(&midi->timer);
216                                 }
217                                 midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
218                                 spin_unlock_irqrestore (&midi->virtual, flags);
219                                 return;
220                         }
221                 } else {
222                         spin_unlock_irqrestore (&midi->virtual, flags);
223                         return;
224                 }
225                 spin_unlock_irqrestore (&midi->virtual, flags);
226         }
227 }
228
229 static int snd_wavefront_midi_input_open(struct snd_rawmidi_substream *substream)
230 {
231         unsigned long flags;
232         snd_wavefront_midi_t *midi;
233         snd_wavefront_mpu_id mpu;
234
235         if (snd_BUG_ON(!substream || !substream->rmidi))
236                 return -ENXIO;
237         if (snd_BUG_ON(!substream->rmidi->private_data))
238                 return -ENXIO;
239
240         mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
241
242         midi = get_wavefront_midi(substream);
243         if (!midi)
244                 return -EIO;
245
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);
250
251         return 0;
252 }
253
254 static int snd_wavefront_midi_output_open(struct snd_rawmidi_substream *substream)
255 {
256         unsigned long flags;
257         snd_wavefront_midi_t *midi;
258         snd_wavefront_mpu_id mpu;
259
260         if (snd_BUG_ON(!substream || !substream->rmidi))
261                 return -ENXIO;
262         if (snd_BUG_ON(!substream->rmidi->private_data))
263                 return -ENXIO;
264
265         mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
266
267         midi = get_wavefront_midi(substream);
268         if (!midi)
269                 return -EIO;
270
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);
275
276         return 0;
277 }
278
279 static int snd_wavefront_midi_input_close(struct snd_rawmidi_substream *substream)
280 {
281         unsigned long flags;
282         snd_wavefront_midi_t *midi;
283         snd_wavefront_mpu_id mpu;
284
285         if (snd_BUG_ON(!substream || !substream->rmidi))
286                 return -ENXIO;
287         if (snd_BUG_ON(!substream->rmidi->private_data))
288                 return -ENXIO;
289
290         mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
291
292         midi = get_wavefront_midi(substream);
293         if (!midi)
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
303 static 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         midi = get_wavefront_midi(substream);
317         if (!midi)
318                 return -EIO;
319
320         spin_lock_irqsave (&midi->open, flags);
321         midi->mode[mpu] &= ~MPU401_MODE_OUTPUT;
322         spin_unlock_irqrestore (&midi->open, flags);
323         return 0;
324 }
325
326 static void snd_wavefront_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
327 {
328         unsigned long flags;
329         snd_wavefront_midi_t *midi;
330         snd_wavefront_mpu_id mpu;
331
332         if (substream == NULL || substream->rmidi == NULL) 
333                 return;
334
335         if (substream->rmidi->private_data == NULL)
336                 return;
337
338         mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
339
340         midi = get_wavefront_midi(substream);
341         if (!midi)
342                 return;
343
344         spin_lock_irqsave (&midi->virtual, flags);
345         if (up) {
346                 midi->mode[mpu] |= MPU401_MODE_INPUT_TRIGGER;
347         } else {
348                 midi->mode[mpu] &= ~MPU401_MODE_INPUT_TRIGGER;
349         }
350         spin_unlock_irqrestore (&midi->virtual, flags);
351 }
352
353 static void snd_wavefront_midi_output_timer(struct timer_list *t)
354 {
355         snd_wavefront_midi_t *midi = from_timer(midi, t, timer);
356         snd_wavefront_card_t *card = midi->timer_card;
357         unsigned long flags;
358         
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);
363 }
364
365 static 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         midi = get_wavefront_midi(substream);
380         if (!midi)
381                 return;
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                                 timer_setup(&midi->timer,
388                                             snd_wavefront_midi_output_timer,
389                                             0);
390                                 mod_timer(&midi->timer, 1 + jiffies);
391                         }
392                         midi->istimer++;
393                         midi->mode[mpu] |= MPU401_MODE_OUTPUT_TRIGGER;
394                 }
395         } else {
396                 midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
397         }
398         spin_unlock_irqrestore (&midi->virtual, flags);
399
400         if (up)
401                 snd_wavefront_midi_output_write((snd_wavefront_card_t *)substream->rmidi->card->private_data);
402 }
403
404 void
405 snd_wavefront_midi_interrupt (snd_wavefront_card_t *card)
406
407 {
408         unsigned long flags;
409         snd_wavefront_midi_t *midi;
410         static struct snd_rawmidi_substream *substream = NULL;
411         static int mpu = external_mpu; 
412         int max = 128;
413         unsigned char byte;
414
415         midi = &card->wavefront.midi;
416
417         if (!input_avail (midi)) { /* not for us */
418                 snd_wavefront_midi_output_write(card);
419                 return;
420         }
421
422         spin_lock_irqsave (&midi->virtual, flags);
423         while (--max) {
424
425                 if (input_avail (midi)) {
426                         byte = read_data (midi);
427
428                         if (midi->isvirtual) {                          
429                                 if (byte == WF_EXTERNAL_SWITCH) {
430                                         substream = midi->substream_input[external_mpu];
431                                         mpu = external_mpu;
432                                 } else if (byte == WF_INTERNAL_SWITCH) { 
433                                         substream = midi->substream_output[internal_mpu];
434                                         mpu = internal_mpu;
435                                 } /* else just leave it as it is */
436                         } else {
437                                 substream = midi->substream_input[internal_mpu];
438                                 mpu = internal_mpu;
439                         }
440
441                         if (substream == NULL) {
442                                 continue;
443                         }
444
445                         if (midi->mode[mpu] & MPU401_MODE_INPUT_TRIGGER) {
446                                 snd_rawmidi_receive(substream, &byte, 1);
447                         }
448                 } else {
449                         break;
450                 }
451         } 
452         spin_unlock_irqrestore (&midi->virtual, flags);
453
454         snd_wavefront_midi_output_write(card);
455 }
456
457 void
458 snd_wavefront_midi_enable_virtual (snd_wavefront_card_t *card)
459
460 {
461         unsigned long flags;
462
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);
468 }
469
470 void
471 snd_wavefront_midi_disable_virtual (snd_wavefront_card_t *card)
472
473 {
474         unsigned long flags;
475
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);
481 }
482
483 int
484 snd_wavefront_midi_start (snd_wavefront_card_t *card)
485
486 {
487         int ok, i;
488         unsigned char rbuf[4], wbuf[4];
489         snd_wavefront_t *dev;
490         snd_wavefront_midi_t *midi;
491
492         dev = &card->wavefront;
493         midi = &dev->midi;
494
495         /* The ICS2115 MPU-401 interface doesn't do anything
496            until its set into UART mode.
497         */
498
499         /* XXX fix me - no hard timing loops allowed! */
500
501         for (i = 0; i < 30000 && !output_ready (midi); i++);
502
503         if (!output_ready (midi)) {
504                 snd_printk ("MIDI interface not ready for command\n");
505                 return -1;
506         }
507
508         /* Any interrupts received from now on
509            are owned by the MIDI side of things.
510         */
511
512         dev->interrupts_are_midi = 1;
513         
514         outb (UART_MODE_ON, midi->mpu_command_port);
515
516         for (ok = 0, i = 50000; i > 0 && !ok; i--) {
517                 if (input_avail (midi)) {
518                         if (read_data (midi) == MPU_ACK) {
519                                 ok = 1;
520                                 break;
521                         }
522                 }
523         }
524
525         if (!ok) {
526                 snd_printk ("cannot set UART mode for MIDI interface");
527                 dev->interrupts_are_midi = 0;
528                 return -1;
529         }
530
531         /* Route external MIDI to WaveFront synth (by default) */
532     
533         if (snd_wavefront_cmd (dev, WFC_MISYNTH_ON, rbuf, wbuf)) {
534                 snd_printk ("can't enable MIDI-IN-2-synth routing.\n");
535                 /* XXX error ? */
536         }
537
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.
547         */
548
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 */
552         }
553
554         snd_wavefront_midi_enable_virtual (card);
555
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);
559         } 
560         return 0;
561 }
562
563 const struct snd_rawmidi_ops snd_wavefront_midi_output =
564 {
565         .open =         snd_wavefront_midi_output_open,
566         .close =        snd_wavefront_midi_output_close,
567         .trigger =      snd_wavefront_midi_output_trigger,
568 };
569
570 const struct snd_rawmidi_ops snd_wavefront_midi_input =
571 {
572         .open =         snd_wavefront_midi_input_open,
573         .close =        snd_wavefront_midi_input_close,
574         .trigger =      snd_wavefront_midi_input_trigger,
575 };
576