4 * The low level driver for the SoundBlaster DS chips.
6 * Copyright by Hannu Savolainen 1993
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
30 #include <i386/isa/sound/sound_config.h>
32 #if (NSND > 0) && defined(CONFIG_SB) && defined(CONFIG_MIDI)
34 #include <i386/isa/sound/sbcard.h>
38 * The DSP channel can be used either for input or output. Variable
39 * 'sb_irq_mode' will be set when the program calls read or write first time
40 * after open. Current version doesn't support mode changes without closing
41 * and reopening the device. Support for this feature may be implemented in a
42 * future version of this driver.
45 extern int sb_dsp_ok; /* Set to 1 atfer successful initialization */
48 extern int sb_midi_mode;
49 extern int sb_midi_busy; /* 1 if the process has output to MIDI */
50 extern int sb_dsp_busy;
51 extern int sb_dsp_highspeed;
53 extern volatile int sb_irq_mode;
54 extern int sb_duplex_midi;
55 extern int sb_intr_active;
56 static int input_opened = 0;
59 extern sound_os_info *sb_osp;
61 static void (*midi_input_intr) (int dev, u_char data);
64 sb_midi_open(int dev, int mode, void (*input) (int dev, u_char data),
65 void (*output) (int dev))
70 printf("SB Error: MIDI hardware not installed\n");
76 if (mode != OPEN_WRITE && !sb_duplex_midi) {
78 printf("SoundBlaster: Midi input not currently supported\n");
81 sb_midi_mode = NORMAL_MIDI;
82 if (mode != OPEN_WRITE) {
83 if (sb_dsp_busy || sb_intr_active)
85 sb_midi_mode = UART_MIDI;
87 if (sb_dsp_highspeed) {
88 printf("SB Error: Midi output not possible during stereo or high speed audio\n");
91 if (sb_midi_mode == UART_MIDI) {
92 sb_irq_mode = IMODE_MIDI;
96 if (!sb_dsp_command(0x35))
97 return -(EIO); /* Enter the UART mode */
101 midi_input_intr = input;
109 sb_midi_close(int dev)
111 if (sb_midi_mode == UART_MIDI) {
112 sb_reset_dsp(); /* The only way to kill the UART mode */
120 sb_midi_out(int dev, u_char midi_byte)
124 if (sb_midi_mode == NORMAL_MIDI) {
126 if (sb_dsp_command(0x38))
127 sb_dsp_command(midi_byte);
129 printf("SB Error: Unable to send a MIDI byte\n");
132 sb_dsp_command(midi_byte); /* UART write */
138 sb_midi_start_read(int dev)
140 if (sb_midi_mode != UART_MIDI) {
141 printf("SoundBlaster: MIDI input not implemented.\n");
148 sb_midi_end_read(int dev)
150 if (sb_midi_mode == UART_MIDI) {
158 sb_midi_ioctl(int dev, u_int cmd, ioctl_arg arg)
164 sb_midi_interrupt(int dummy)
171 data = inb(DSP_READ);
173 midi_input_intr(my_dev, data);
178 #define MIDI_SYNTH_NAME "SoundBlaster Midi"
179 #define MIDI_SYNTH_CAPS 0
180 #include <i386/isa/sound/midi_synth.h>
182 static struct midi_operations sb_midi_operations =
184 {"SoundBlaster", 0, 0, SNDCARD_SB},
195 NULL, /* buffer_status */
200 sb_midi_init(int model)
202 if (num_midis >= MAX_MIDI_DEV) {
203 printf("Sound: Too many midi devices detected\n");
206 std_midi_synth.midi_dev = num_midis;
208 midi_devs[num_midis++] = &sb_midi_operations;