Import 2.3.18pre1
[davej-history.git] / drivers / sound / gus_midi.c
blob7f82d3997ccaba4b6aaef42f1e9a29d19bcf0bc9
1 /*
2 * sound/gus2_midi.c
4 * The low level driver for the GUS Midi Interface.
5 */
6 /*
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 #include <linux/config.h>
16 #include "sound_config.h"
18 #include "gus_hw.h"
20 #ifdef CONFIG_GUS
21 #ifdef CONFIG_MIDI
23 static int midi_busy = 0, input_opened = 0;
24 static int my_dev;
25 static int output_used = 0;
26 static volatile unsigned char gus_midi_control;
28 static void (*midi_input_intr) (int dev, unsigned char data);
30 static unsigned char tmp_queue[256];
31 extern int gus_pnp_flag;
32 static volatile int qlen;
33 static volatile unsigned char qhead, qtail;
34 extern int gus_base, gus_irq, gus_dma;
35 extern int *gus_osp;
37 static int GUS_MIDI_STATUS(void)
39 return inb(u_MidiStatus);
42 static int gus_midi_open(int dev, int mode, void (*input) (int dev, unsigned char data), void (*output) (int dev))
44 if (midi_busy)
46 /* printk("GUS: Midi busy\n");*/
47 return -EBUSY;
49 outb((MIDI_RESET), u_MidiControl);
50 gus_delay();
52 gus_midi_control = 0;
53 input_opened = 0;
55 if (mode == OPEN_READ || mode == OPEN_READWRITE)
56 if (!gus_pnp_flag)
58 gus_midi_control |= MIDI_ENABLE_RCV;
59 input_opened = 1;
61 outb((gus_midi_control), u_MidiControl); /* Enable */
63 midi_busy = 1;
64 qlen = qhead = qtail = output_used = 0;
65 midi_input_intr = input;
67 return 0;
70 static int dump_to_midi(unsigned char midi_byte)
72 unsigned long flags;
73 int ok = 0;
75 output_used = 1;
77 save_flags(flags);
78 cli();
80 if (GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY)
82 ok = 1;
83 outb((midi_byte), u_MidiData);
85 else
88 * Enable Midi xmit interrupts (again)
90 gus_midi_control |= MIDI_ENABLE_XMIT;
91 outb((gus_midi_control), u_MidiControl);
94 restore_flags(flags);
95 return ok;
98 static void gus_midi_close(int dev)
101 * Reset FIFO pointers, disable intrs
104 outb((MIDI_RESET), u_MidiControl);
105 midi_busy = 0;
108 static int gus_midi_out(int dev, unsigned char midi_byte)
110 unsigned long flags;
113 * Drain the local queue first
116 save_flags(flags);
117 cli();
119 while (qlen && dump_to_midi(tmp_queue[qhead]))
121 qlen--;
122 qhead++;
124 restore_flags(flags);
127 * Output the byte if the local queue is empty.
130 if (!qlen)
131 if (dump_to_midi(midi_byte))
132 return 1; /*
133 * OK
137 * Put to the local queue
140 if (qlen >= 256)
141 return 0; /*
142 * Local queue full
144 save_flags(flags);
145 cli();
147 tmp_queue[qtail] = midi_byte;
148 qlen++;
149 qtail++;
151 restore_flags(flags);
152 return 1;
155 static int gus_midi_start_read(int dev)
157 return 0;
160 static int gus_midi_end_read(int dev)
162 return 0;
165 static void gus_midi_kick(int dev)
169 static int gus_midi_buffer_status(int dev)
171 unsigned long flags;
173 if (!output_used)
174 return 0;
176 save_flags(flags);
177 cli();
179 if (qlen && dump_to_midi(tmp_queue[qhead]))
181 qlen--;
182 qhead++;
184 restore_flags(flags);
185 return (qlen > 0) | !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY);
188 #define MIDI_SYNTH_NAME "Gravis Ultrasound Midi"
189 #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
190 #include "midi_synth.h"
192 static struct midi_operations gus_midi_operations =
195 "Gravis UltraSound Midi", 0, 0, SNDCARD_GUS
197 &std_midi_synth,
198 {0},
199 gus_midi_open,
200 gus_midi_close,
201 NULL, /* ioctl */
202 gus_midi_out,
203 gus_midi_start_read,
204 gus_midi_end_read,
205 gus_midi_kick,
206 NULL, /*
207 * command
209 gus_midi_buffer_status,
210 NULL
213 void gus_midi_init(struct address_info *hw_config)
215 int dev = sound_alloc_mididev();
217 if (dev == -1)
219 printk(KERN_INFO "gus_midi: Too many midi devices detected\n");
220 return;
222 outb((MIDI_RESET), u_MidiControl);
224 std_midi_synth.midi_dev = my_dev = dev;
225 hw_config->slots[2] = dev;
226 midi_devs[dev] = &gus_midi_operations;
227 sequencer_init();
228 return;
231 void gus_midi_interrupt(int dummy)
233 volatile unsigned char stat, data;
234 unsigned long flags;
235 int timeout = 10;
237 save_flags(flags);
238 cli();
240 while (timeout-- > 0 && (stat = GUS_MIDI_STATUS()) & (MIDI_RCV_FULL | MIDI_XMIT_EMPTY))
242 if (stat & MIDI_RCV_FULL)
244 data = inb(u_MidiData);
245 if (input_opened)
246 midi_input_intr(my_dev, data);
248 if (stat & MIDI_XMIT_EMPTY)
250 while (qlen && dump_to_midi(tmp_queue[qhead]))
252 qlen--;
253 qhead++;
255 if (!qlen)
258 * Disable Midi output interrupts, since no data in the buffer
260 gus_midi_control &= ~MIDI_ENABLE_XMIT;
261 outb((gus_midi_control), u_MidiControl);
262 outb((gus_midi_control), u_MidiControl);
266 restore_flags(flags);
269 #endif
270 #endif