Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / drivers / sound / gus_midi.c
blob6fb1ac7627e06a3237f4cb7481287ff9ccd26d1f
1 /*
2 * sound/gus2_midi.c
4 * The low level driver for the GUS Midi Interface.
7 * Copyright (C) by Hannu Savolainen 1993-1997
9 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
10 * Version 2 (June 1991). See the "COPYING" file distributed with this software
11 * for more info.
13 * Changes:
14 * 11-10-2000 Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
15 * Added __init to gus_midi_init()
18 #include "linux/init.h"
19 #include "sound_config.h"
21 #include "gus.h"
22 #include "gus_hw.h"
24 static int midi_busy = 0, input_opened = 0;
25 static int my_dev;
26 static int output_used = 0;
27 static volatile unsigned char gus_midi_control;
29 static void (*midi_input_intr) (int dev, unsigned char data);
31 static unsigned char tmp_queue[256];
32 extern int gus_pnp_flag;
33 static volatile int qlen;
34 static volatile unsigned char qhead, qtail;
35 extern int gus_base, gus_irq, gus_dma;
36 extern int *gus_osp;
38 static int GUS_MIDI_STATUS(void)
40 return inb(u_MidiStatus);
43 static int gus_midi_open(int dev, int mode, void (*input) (int dev, unsigned char data), void (*output) (int dev))
45 if (midi_busy)
47 /* printk("GUS: Midi busy\n");*/
48 return -EBUSY;
50 outb((MIDI_RESET), u_MidiControl);
51 gus_delay();
53 gus_midi_control = 0;
54 input_opened = 0;
56 if (mode == OPEN_READ || mode == OPEN_READWRITE)
57 if (!gus_pnp_flag)
59 gus_midi_control |= MIDI_ENABLE_RCV;
60 input_opened = 1;
62 outb((gus_midi_control), u_MidiControl); /* Enable */
64 midi_busy = 1;
65 qlen = qhead = qtail = output_used = 0;
66 midi_input_intr = input;
68 return 0;
71 static int dump_to_midi(unsigned char midi_byte)
73 unsigned long flags;
74 int ok = 0;
76 output_used = 1;
78 save_flags(flags);
79 cli();
81 if (GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY)
83 ok = 1;
84 outb((midi_byte), u_MidiData);
86 else
89 * Enable Midi xmit interrupts (again)
91 gus_midi_control |= MIDI_ENABLE_XMIT;
92 outb((gus_midi_control), u_MidiControl);
95 restore_flags(flags);
96 return ok;
99 static void gus_midi_close(int dev)
102 * Reset FIFO pointers, disable intrs
105 outb((MIDI_RESET), u_MidiControl);
106 midi_busy = 0;
109 static int gus_midi_out(int dev, unsigned char midi_byte)
111 unsigned long flags;
114 * Drain the local queue first
117 save_flags(flags);
118 cli();
120 while (qlen && dump_to_midi(tmp_queue[qhead]))
122 qlen--;
123 qhead++;
125 restore_flags(flags);
128 * Output the byte if the local queue is empty.
131 if (!qlen)
132 if (dump_to_midi(midi_byte))
133 return 1; /*
134 * OK
138 * Put to the local queue
141 if (qlen >= 256)
142 return 0; /*
143 * Local queue full
145 save_flags(flags);
146 cli();
148 tmp_queue[qtail] = midi_byte;
149 qlen++;
150 qtail++;
152 restore_flags(flags);
153 return 1;
156 static int gus_midi_start_read(int dev)
158 return 0;
161 static int gus_midi_end_read(int dev)
163 return 0;
166 static void gus_midi_kick(int dev)
170 static int gus_midi_buffer_status(int dev)
172 unsigned long flags;
174 if (!output_used)
175 return 0;
177 save_flags(flags);
178 cli();
180 if (qlen && dump_to_midi(tmp_queue[qhead]))
182 qlen--;
183 qhead++;
185 restore_flags(flags);
186 return (qlen > 0) | !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY);
189 #define MIDI_SYNTH_NAME "Gravis Ultrasound Midi"
190 #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
191 #include "midi_synth.h"
193 static struct midi_operations gus_midi_operations =
195 owner: THIS_MODULE,
196 info: {"Gravis UltraSound Midi", 0, 0, SNDCARD_GUS},
197 converter: &std_midi_synth,
198 in_info: {0},
199 open: gus_midi_open,
200 close: gus_midi_close,
201 outputc: gus_midi_out,
202 start_read: gus_midi_start_read,
203 end_read: gus_midi_end_read,
204 kick: gus_midi_kick,
205 buffer_status: gus_midi_buffer_status,
208 void __init gus_midi_init(struct address_info *hw_config)
210 int dev = sound_alloc_mididev();
212 if (dev == -1)
214 printk(KERN_INFO "gus_midi: Too many midi devices detected\n");
215 return;
217 outb((MIDI_RESET), u_MidiControl);
219 std_midi_synth.midi_dev = my_dev = dev;
220 hw_config->slots[2] = dev;
221 midi_devs[dev] = &gus_midi_operations;
222 sequencer_init();
223 return;
226 void gus_midi_interrupt(int dummy)
228 volatile unsigned char stat, data;
229 unsigned long flags;
230 int timeout = 10;
232 save_flags(flags);
233 cli();
235 while (timeout-- > 0 && (stat = GUS_MIDI_STATUS()) & (MIDI_RCV_FULL | MIDI_XMIT_EMPTY))
237 if (stat & MIDI_RCV_FULL)
239 data = inb(u_MidiData);
240 if (input_opened)
241 midi_input_intr(my_dev, data);
243 if (stat & MIDI_XMIT_EMPTY)
245 while (qlen && dump_to_midi(tmp_queue[qhead]))
247 qlen--;
248 qhead++;
250 if (!qlen)
253 * Disable Midi output interrupts, since no data in the buffer
255 gus_midi_control &= ~MIDI_ENABLE_XMIT;
256 outb((gus_midi_control), u_MidiControl);
257 outb((gus_midi_control), u_MidiControl);
261 restore_flags(flags);