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