This source file includes following definitions.
- mad16_sb_dsp_command
- mad16_sbintr
- mad16_sb_reset_dsp
- mad16_sb_dsp_detect
- mad16_sb_dsp_init
- mad16_sb_midi_open
- mad16_sb_midi_close
- mad16_sb_midi_out
- mad16_sb_midi_start_read
- mad16_sb_midi_end_read
- mad16_sb_midi_ioctl
- mad16_sb_midi_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include "sound_config.h"
31
32 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_MAD16) && !defined(EXCLUDE_MIDI)
33
34 #define sbc_base mad16_sb_base
35 #include "sb.h"
36
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;
43
44 int mad16_sb_midi_mode = NORMAL_MIDI;
45 int mad16_sb_midi_busy = 0;
46
47 int mad16_sb_duplex_midi = 0;
48 volatile int mad16_sb_intr_active = 0;
49
50 void (*midi_input_intr) (int dev, unsigned char data);
51
52 static void mad16_sb_midi_init (int model);
53
54 static int
55 mad16_sb_dsp_command (unsigned char val)
56 {
57 int i;
58 unsigned long limit;
59
60 limit = jiffies + HZ / 10;
61
62
63
64
65
66
67
68
69
70
71
72 for (i = 0; i < 500000 && jiffies < limit; i++)
73 {
74 if ((inb (DSP_STATUS) & 0x80) == 0)
75 {
76 outb (val, DSP_COMMAND);
77 return 1;
78 }
79 }
80
81 printk ("MAD16 (SBP mode): DSP Command(%x) Timeout.\n", val);
82 printk ("IRQ conflict???\n");
83 return 0;
84 }
85
86 void
87 mad16_sbintr (int irq, struct pt_regs *dummy)
88 {
89 int status;
90
91 unsigned long flags;
92 unsigned char data;
93
94 status = inb (DSP_DATA_AVAIL);
95
96
97
98 save_flags (flags);
99 cli ();
100
101 data = inb (DSP_READ);
102 if (input_opened)
103 midi_input_intr (my_dev, data);
104
105 restore_flags (flags);
106 }
107
108 static int
109 mad16_sb_reset_dsp (void)
110 {
111 int loopc;
112
113 outb (1, DSP_RESET);
114 tenmicrosec ();
115 outb (0, DSP_RESET);
116 tenmicrosec ();
117 tenmicrosec ();
118 tenmicrosec ();
119
120 for (loopc = 0; loopc < 1000 && !(inb (DSP_DATA_AVAIL) & 0x80); loopc++);
121
122
123
124
125
126
127
128
129 if (inb (DSP_READ) != 0xAA)
130 return 0;
131
132
133
134 return 1;
135 }
136
137 int
138 mad16_sb_dsp_detect (struct address_info *hw_config)
139 {
140 mad16_sb_base = hw_config->io_base;
141 mad16_sb_irq = hw_config->irq;
142 midi_osp = hw_config->osp;
143
144 if (check_region (hw_config->io_base, 16))
145 {
146 printk ("MAD16 SB MIDI: I/O base %x not free\n", hw_config->io_base);
147 return 0;
148 }
149
150 if (mad16_sb_dsp_ok)
151 return 0;
152
153
154 if (!mad16_sb_reset_dsp ())
155 return 0;
156
157 return 1;
158
159
160 }
161
162 long
163 mad16_sb_dsp_init (long mem_start, struct address_info *hw_config)
164
165
166 {
167
168 midi_osp = hw_config->osp;
169 if (snd_set_irq_handler (mad16_sb_irq, mad16_sbintr, "MAD16 SB MIDI", midi_osp) < 0)
170 {
171 printk ("MAD16 SB MIDI: IRQ not free\n");
172 return mem_start;
173 }
174
175 request_region (hw_config->io_base, 16, "mad16/Mozart MIDI");
176
177 printk (" <MAD16 MIDI (SB mode)>");
178 mad16_sb_midi_init (2);
179
180 mad16_sb_dsp_ok = 1;
181 return mem_start;
182 }
183
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)
188 )
189 {
190
191 if (!mad16_sb_dsp_ok)
192 {
193 printk ("MAD16_SB Error: MIDI hardware not installed\n");
194 return -ENXIO;
195 }
196
197 if (mad16_sb_midi_busy)
198 return -EBUSY;
199
200 if (mode != OPEN_WRITE && !mad16_sb_duplex_midi)
201 {
202 if (num_midis == 1)
203 printk ("MAD16 (SBP mode): Midi input not currently supported\n");
204 return -EPERM;
205 }
206
207 mad16_sb_midi_mode = NORMAL_MIDI;
208 if (mode != OPEN_WRITE)
209 {
210 if (mad16_sb_intr_active)
211 return -EBUSY;
212 mad16_sb_midi_mode = UART_MIDI;
213 }
214
215 if (mad16_sb_midi_mode == UART_MIDI)
216 {
217 mad16_sb_reset_dsp ();
218
219 if (!mad16_sb_dsp_command (0x35))
220 return -EIO;
221
222
223 mad16_sb_intr_active = 1;
224
225 input_opened = 1;
226 midi_input_intr = input;
227 }
228
229 mad16_sb_midi_busy = 1;
230
231 return 0;
232 }
233
234 static void
235 mad16_sb_midi_close (int dev)
236 {
237 if (mad16_sb_midi_mode == UART_MIDI)
238 {
239 mad16_sb_reset_dsp ();
240
241
242 }
243 mad16_sb_intr_active = 0;
244 mad16_sb_midi_busy = 0;
245 input_opened = 0;
246 }
247
248 static int
249 mad16_sb_midi_out (int dev, unsigned char midi_byte)
250 {
251 unsigned long flags;
252
253 if (mad16_sb_midi_mode == NORMAL_MIDI)
254 {
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);
262 }
263 else
264 mad16_sb_dsp_command (midi_byte);
265
266
267
268 return 1;
269 }
270
271 static int
272 mad16_sb_midi_start_read (int dev)
273 {
274 if (mad16_sb_midi_mode != UART_MIDI)
275 {
276 printk ("MAD16 (SBP mode): MIDI input not implemented.\n");
277 return -EPERM;
278 }
279 return 0;
280 }
281
282 static int
283 mad16_sb_midi_end_read (int dev)
284 {
285 if (mad16_sb_midi_mode == UART_MIDI)
286 {
287 mad16_sb_reset_dsp ();
288 mad16_sb_intr_active = 0;
289 }
290 return 0;
291 }
292
293 static int
294 mad16_sb_midi_ioctl (int dev, unsigned cmd, ioctl_arg arg)
295 {
296 return -EPERM;
297 }
298
299 #define MIDI_SYNTH_NAME "pseudo-SoundBlaster Midi"
300 #define MIDI_SYNTH_CAPS 0
301 #include "midi_synth.h"
302
303 static struct midi_operations mad16_sb_midi_operations =
304 {
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
316
317 NULL,
318
319
320 NULL,
321
322
323 NULL
324 };
325
326 static void
327 mad16_sb_midi_init (int model)
328 {
329 if (num_midis >= MAX_MIDI_DEV)
330 {
331 printk ("Sound: Too many midi devices detected\n");
332 return;
333 }
334
335 std_midi_synth.midi_dev = num_midis;
336 my_dev = num_midis;
337 midi_devs[num_midis++] = &mad16_sb_midi_operations;
338 }
339
340 #endif