Import 1.3.39
[davej-history.git] / drivers / sound / mad16_sb_midi.c
blobd6b66f8db7bb2f6391508d30dfcea75bc0ecedc2
1 /*
2 * sound/mad16_sb_midi.c
4 * The low level driver for MAD16 SoundBlaster-DS-chip-based MIDI.
6 * Copyright by Hannu Savolainen 1993, Aaron Ucko 1995
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met: 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 2.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
30 #include "sound_config.h"
32 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_MAD16) && !defined(EXCLUDE_MIDI)
34 #define sbc_base mad16_sb_base
35 #include "sb.h"
37 static int input_opened = 0;
38 static int my_dev;
39 static int mad16_sb_base = 0x220;
40 static int mad16_sb_irq = 0;
41 static int mad16_sb_dsp_ok = 0;
42 static sound_os_info *midi_osp;
44 int mad16_sb_midi_mode = NORMAL_MIDI;
45 int mad16_sb_midi_busy = 0;
47 int mad16_sb_duplex_midi = 0;
48 volatile int mad16_sb_intr_active = 0;
50 void (*midi_input_intr) (int dev, unsigned char data);
52 static void mad16_sb_midi_init (int model);
54 static int
55 mad16_sb_dsp_command (unsigned char val)
57 int i;
58 unsigned long limit;
60 limit = jiffies + HZ / 10; /*
61 * The timeout is 0.1 secods
65 * Note! the i<500000 is an emergency exit. The mad16_sb_dsp_command() is sometimes
66 * called while interrupts are disabled. This means that the timer is
67 * disabled also. However the timeout situation is a abnormal condition.
68 * Normally the DSP should be ready to accept commands after just couple of
69 * loops.
72 for (i = 0; i < 500000 && jiffies < limit; i++)
74 if ((inb (DSP_STATUS) & 0x80) == 0)
76 outb (val, DSP_COMMAND);
77 return 1;
81 printk ("MAD16 (SBP mode): DSP Command(%x) Timeout.\n", val);
82 printk ("IRQ conflict???\n");
83 return 0;
86 void
87 mad16_sbintr (int irq, struct pt_regs *dummy)
89 int status;
91 unsigned long flags;
92 unsigned char data;
94 status = inb (DSP_DATA_AVAIL); /*
95 * Clear interrupt
98 save_flags (flags);
99 cli ();
101 data = inb (DSP_READ);
102 if (input_opened)
103 midi_input_intr (my_dev, data);
105 restore_flags (flags);
108 static int
109 mad16_sb_reset_dsp (void)
111 int loopc;
113 outb (1, DSP_RESET);
114 tenmicrosec ();
115 outb (0, DSP_RESET);
116 tenmicrosec ();
117 tenmicrosec ();
118 tenmicrosec ();
120 for (loopc = 0; loopc < 1000 && !(inb (DSP_DATA_AVAIL) & 0x80); loopc++); /*
121 * Wait
122 * for
123 * data
125 * available
126 * status
129 if (inb (DSP_READ) != 0xAA)
130 return 0; /*
131 * Sorry
134 return 1;
138 mad16_sb_dsp_detect (struct address_info *hw_config)
140 mad16_sb_base = hw_config->io_base;
141 mad16_sb_irq = hw_config->irq;
142 midi_osp = hw_config->osp;
144 if (check_region (hw_config->io_base, 16))
146 printk ("MAD16 SB MIDI: I/O base %x not free\n", hw_config->io_base);
147 return 0;
150 if (mad16_sb_dsp_ok)
151 return 0; /*
152 * Already initialized
154 if (!mad16_sb_reset_dsp ())
155 return 0;
157 return 1; /*
158 * Detected
162 long
163 mad16_sb_dsp_init (long mem_start, struct address_info *hw_config)
164 /* this function now just verifies the reported version and calls
165 * mad16_sb_midi_init -- everything else is done elsewhere */
168 midi_osp = hw_config->osp;
169 if (snd_set_irq_handler (mad16_sb_irq, mad16_sbintr, "MAD16 SB MIDI", midi_osp) < 0)
171 printk ("MAD16 SB MIDI: IRQ not free\n");
172 return mem_start;
175 request_region (hw_config->io_base, 16, "mad16/Mozart MIDI");
177 printk (" <MAD16 MIDI (SB mode)>");
178 mad16_sb_midi_init (2);
180 mad16_sb_dsp_ok = 1;
181 return mem_start;
184 static int
185 mad16_sb_midi_open (int dev, int mode,
186 void (*input) (int dev, unsigned char data),
187 void (*output) (int dev)
191 if (!mad16_sb_dsp_ok)
193 printk ("MAD16_SB Error: MIDI hardware not installed\n");
194 return -ENXIO;
197 if (mad16_sb_midi_busy)
198 return -EBUSY;
200 if (mode != OPEN_WRITE && !mad16_sb_duplex_midi)
202 if (num_midis == 1)
203 printk ("MAD16 (SBP mode): Midi input not currently supported\n");
204 return -EPERM;
207 mad16_sb_midi_mode = NORMAL_MIDI;
208 if (mode != OPEN_WRITE)
210 if (mad16_sb_intr_active)
211 return -EBUSY;
212 mad16_sb_midi_mode = UART_MIDI;
215 if (mad16_sb_midi_mode == UART_MIDI)
217 mad16_sb_reset_dsp ();
219 if (!mad16_sb_dsp_command (0x35))
220 return -EIO; /*
221 * Enter the UART mode
223 mad16_sb_intr_active = 1;
225 input_opened = 1;
226 midi_input_intr = input;
229 mad16_sb_midi_busy = 1;
231 return 0;
234 static void
235 mad16_sb_midi_close (int dev)
237 if (mad16_sb_midi_mode == UART_MIDI)
239 mad16_sb_reset_dsp (); /*
240 * The only way to kill the UART mode
243 mad16_sb_intr_active = 0;
244 mad16_sb_midi_busy = 0;
245 input_opened = 0;
248 static int
249 mad16_sb_midi_out (int dev, unsigned char midi_byte)
251 unsigned long flags;
253 if (mad16_sb_midi_mode == NORMAL_MIDI)
255 save_flags (flags);
256 cli ();
257 if (mad16_sb_dsp_command (0x38))
258 mad16_sb_dsp_command (midi_byte);
259 else
260 printk ("MAD16_SB Error: Unable to send a MIDI byte\n");
261 restore_flags (flags);
263 else
264 mad16_sb_dsp_command (midi_byte); /*
265 * UART write
268 return 1;
271 static int
272 mad16_sb_midi_start_read (int dev)
274 if (mad16_sb_midi_mode != UART_MIDI)
276 printk ("MAD16 (SBP mode): MIDI input not implemented.\n");
277 return -EPERM;
279 return 0;
282 static int
283 mad16_sb_midi_end_read (int dev)
285 if (mad16_sb_midi_mode == UART_MIDI)
287 mad16_sb_reset_dsp ();
288 mad16_sb_intr_active = 0;
290 return 0;
293 static int
294 mad16_sb_midi_ioctl (int dev, unsigned cmd, ioctl_arg arg)
296 return -EPERM;
299 #define MIDI_SYNTH_NAME "pseudo-SoundBlaster Midi"
300 #define MIDI_SYNTH_CAPS 0
301 #include "midi_synth.h"
303 static struct midi_operations mad16_sb_midi_operations =
305 {"MAD16 (SBP mode)", 0, 0, SNDCARD_MAD16},
306 &std_midi_synth,
307 {0},
308 mad16_sb_midi_open,
309 mad16_sb_midi_close,
310 mad16_sb_midi_ioctl,
311 mad16_sb_midi_out,
312 mad16_sb_midi_start_read,
313 mad16_sb_midi_end_read,
314 NULL, /*
315 * Kick
317 NULL, /*
318 * command
320 NULL, /*
321 * buffer_status
323 NULL
326 static void
327 mad16_sb_midi_init (int model)
329 if (num_midis >= MAX_MIDI_DEV)
331 printk ("Sound: Too many midi devices detected\n");
332 return;
335 std_midi_synth.midi_dev = num_midis;
336 my_dev = num_midis;
337 midi_devs[num_midis++] = &mad16_sb_midi_operations;
340 #endif