OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [sound/] [wf_midi.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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
 
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.