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