Import 2.3.49pre2
[davej-history.git] / drivers / sound / gus_midi.c
blob92987f46d9d2ea99dd3d26d931c1041a4118ac39
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 "sound_config.h"
14 #include "gus_hw.h"
16 static int midi_busy = 0, input_opened = 0;
17 static int my_dev;
18 static int output_used = 0;
19 static volatile unsigned char gus_midi_control;
21 static void (*midi_input_intr) (int dev, unsigned char data);
23 static unsigned char tmp_queue[256];
24 extern int gus_pnp_flag;
25 static volatile int qlen;
26 static volatile unsigned char qhead, qtail;
27 extern int gus_base, gus_irq, gus_dma;
28 extern int *gus_osp;
30 static int GUS_MIDI_STATUS(void)
32 return inb(u_MidiStatus);
35 static int gus_midi_open(int dev, int mode, void (*input) (int dev, unsigned char data), void (*output) (int dev))
37 if (midi_busy)
39 /* printk("GUS: Midi busy\n");*/
40 return -EBUSY;
42 outb((MIDI_RESET), u_MidiControl);
43 gus_delay();
45 gus_midi_control = 0;
46 input_opened = 0;
48 if (mode == OPEN_READ || mode == OPEN_READWRITE)
49 if (!gus_pnp_flag)
51 gus_midi_control |= MIDI_ENABLE_RCV;
52 input_opened = 1;
54 outb((gus_midi_control), u_MidiControl); /* Enable */
56 midi_busy = 1;
57 qlen = qhead = qtail = output_used = 0;
58 midi_input_intr = input;
60 return 0;
63 static int dump_to_midi(unsigned char midi_byte)
65 unsigned long flags;
66 int ok = 0;
68 output_used = 1;
70 save_flags(flags);
71 cli();
73 if (GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY)
75 ok = 1;
76 outb((midi_byte), u_MidiData);
78 else
81 * Enable Midi xmit interrupts (again)
83 gus_midi_control |= MIDI_ENABLE_XMIT;
84 outb((gus_midi_control), u_MidiControl);
87 restore_flags(flags);
88 return ok;
91 static void gus_midi_close(int dev)
94 * Reset FIFO pointers, disable intrs
97 outb((MIDI_RESET), u_MidiControl);
98 midi_busy = 0;
101 static int gus_midi_out(int dev, unsigned char midi_byte)
103 unsigned long flags;
106 * Drain the local queue first
109 save_flags(flags);
110 cli();
112 while (qlen && dump_to_midi(tmp_queue[qhead]))
114 qlen--;
115 qhead++;
117 restore_flags(flags);
120 * Output the byte if the local queue is empty.
123 if (!qlen)
124 if (dump_to_midi(midi_byte))
125 return 1; /*
126 * OK
130 * Put to the local queue
133 if (qlen >= 256)
134 return 0; /*
135 * Local queue full
137 save_flags(flags);
138 cli();
140 tmp_queue[qtail] = midi_byte;
141 qlen++;
142 qtail++;
144 restore_flags(flags);
145 return 1;
148 static int gus_midi_start_read(int dev)
150 return 0;
153 static int gus_midi_end_read(int dev)
155 return 0;
158 static void gus_midi_kick(int dev)
162 static int gus_midi_buffer_status(int dev)
164 unsigned long flags;
166 if (!output_used)
167 return 0;
169 save_flags(flags);
170 cli();
172 if (qlen && dump_to_midi(tmp_queue[qhead]))
174 qlen--;
175 qhead++;
177 restore_flags(flags);
178 return (qlen > 0) | !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY);
181 #define MIDI_SYNTH_NAME "Gravis Ultrasound Midi"
182 #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
183 #include "midi_synth.h"
185 static struct midi_operations gus_midi_operations =
188 "Gravis UltraSound Midi", 0, 0, SNDCARD_GUS
190 &std_midi_synth,
191 {0},
192 gus_midi_open,
193 gus_midi_close,
194 NULL, /* ioctl */
195 gus_midi_out,
196 gus_midi_start_read,
197 gus_midi_end_read,
198 gus_midi_kick,
199 NULL, /*
200 * command
202 gus_midi_buffer_status,
203 NULL
206 void gus_midi_init(struct address_info *hw_config)
208 int dev = sound_alloc_mididev();
210 if (dev == -1)
212 printk(KERN_INFO "gus_midi: Too many midi devices detected\n");
213 return;
215 outb((MIDI_RESET), u_MidiControl);
217 std_midi_synth.midi_dev = my_dev = dev;
218 hw_config->slots[2] = dev;
219 midi_devs[dev] = &gus_midi_operations;
220 sequencer_init();
221 return;
224 void gus_midi_interrupt(int dummy)
226 volatile unsigned char stat, data;
227 unsigned long flags;
228 int timeout = 10;
230 save_flags(flags);
231 cli();
233 while (timeout-- > 0 && (stat = GUS_MIDI_STATUS()) & (MIDI_RCV_FULL | MIDI_XMIT_EMPTY))
235 if (stat & MIDI_RCV_FULL)
237 data = inb(u_MidiData);
238 if (input_opened)
239 midi_input_intr(my_dev, data);
241 if (stat & MIDI_XMIT_EMPTY)
243 while (qlen && dump_to_midi(tmp_queue[qhead]))
245 qlen--;
246 qhead++;
248 if (!qlen)
251 * Disable Midi output interrupts, since no data in the buffer
253 gus_midi_control &= ~MIDI_ENABLE_XMIT;
254 outb((gus_midi_control), u_MidiControl);
255 outb((gus_midi_control), u_MidiControl);
259 restore_flags(flags);