This source file includes following definitions.
- sb16midi_input_loop
- sb16midiintr
- sbmidiintr
- sb16midi_open
- sb16midi_close
- sb16midi_out
- sb16midi_start_read
- sb16midi_end_read
- sb16midi_ioctl
- sb16midi_kick
- sb16midi_buffer_status
- attach_sb16midi
- reset_sb16midi
- probe_sb16midi
- unload_sb16midi
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_SB) && defined(CONFIG_MIDI)
33
34 #include "sb.h"
35
36 #define DATAPORT (sb16midi_base)
37 #define COMDPORT (sb16midi_base+1)
38 #define STATPORT (sb16midi_base+1)
39
40 extern sound_os_info *sb_osp;
41
42 #define sb16midi_status() inb( STATPORT)
43 #define input_avail() (!(sb16midi_status()&INPUT_AVAIL))
44 #define output_ready() (!(sb16midi_status()&OUTPUT_READY))
45 #define sb16midi_cmd(cmd) outb( cmd, COMDPORT)
46 #define sb16midi_read() inb( DATAPORT)
47 #define sb16midi_write(byte) outb( byte, DATAPORT)
48
49 #define OUTPUT_READY 0x40
50 #define INPUT_AVAIL 0x80
51 #define MPU_ACK 0xFE
52 #define MPU_RESET 0xFF
53 #define UART_MODE_ON 0x3F
54
55 static int sb16midi_opened = 0;
56 static int sb16midi_base = 0x330;
57 static int sb16midi_detected = 0;
58 static int my_dev;
59 extern int sbc_base;
60
61 extern int Jazz16_detected;
62 extern int AudioDrive;
63
64 static int reset_sb16midi (void);
65 static void (*midi_input_intr) (int dev, unsigned char data);
66 static volatile unsigned char input_byte;
67
68 static void
69 sb16midi_input_loop (void)
70 {
71 while (input_avail ())
72 {
73 unsigned char c = sb16midi_read ();
74
75 if (c == MPU_ACK)
76 input_byte = c;
77 else if (sb16midi_opened & OPEN_READ && midi_input_intr)
78 midi_input_intr (my_dev, c);
79 }
80 }
81
82 void
83 sb16midiintr (int unit)
84 {
85 if (input_avail ())
86 sb16midi_input_loop ();
87 }
88
89 void
90 sbmidiintr (int irq, struct pt_regs *dummy)
91 {
92 if (input_avail ())
93 sb16midi_input_loop ();
94 }
95
96 static int
97 sb16midi_open (int dev, int mode,
98 void (*input) (int dev, unsigned char data),
99 void (*output) (int dev)
100 )
101 {
102 if (sb16midi_opened)
103 {
104 return -EBUSY;
105 }
106
107 sb16midi_input_loop ();
108
109 midi_input_intr = input;
110 sb16midi_opened = mode;
111
112 return 0;
113 }
114
115 static void
116 sb16midi_close (int dev)
117 {
118 sb16midi_opened = 0;
119 }
120
121 static int
122 sb16midi_out (int dev, unsigned char midi_byte)
123 {
124 int timeout;
125 unsigned long flags;
126
127
128
129
130
131 save_flags (flags);
132 cli ();
133
134 if (input_avail ())
135 sb16midi_input_loop ();
136
137 restore_flags (flags);
138
139
140
141
142
143
144 for (timeout = 30000; timeout > 0 && !output_ready (); timeout--);
145
146
147
148 if (!output_ready ())
149 {
150 printk ("MPU-401: Timeout\n");
151 return 0;
152 }
153
154 sb16midi_write (midi_byte);
155 return 1;
156 }
157
158 static int
159 sb16midi_start_read (int dev)
160 {
161 return 0;
162 }
163
164 static int
165 sb16midi_end_read (int dev)
166 {
167 return 0;
168 }
169
170 static int
171 sb16midi_ioctl (int dev, unsigned cmd, ioctl_arg arg)
172 {
173 return -EINVAL;
174 }
175
176 static void
177 sb16midi_kick (int dev)
178 {
179 }
180
181 static int
182 sb16midi_buffer_status (int dev)
183 {
184 return 0;
185
186
187 }
188
189 #define MIDI_SYNTH_NAME "SoundBlaster MPU"
190 #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
191 #include "midi_synth.h"
192
193 static struct midi_operations sb16midi_operations =
194 {
195 {"SoundBlaster MPU", 0, 0, SNDCARD_SB16MIDI},
196 &std_midi_synth,
197 {0},
198 sb16midi_open,
199 sb16midi_close,
200 sb16midi_ioctl,
201 sb16midi_out,
202 sb16midi_start_read,
203 sb16midi_end_read,
204 sb16midi_kick,
205 NULL,
206 sb16midi_buffer_status,
207 NULL
208 };
209
210 long
211 attach_sb16midi (long mem_start, struct address_info *hw_config)
212 {
213 int ok, timeout;
214 unsigned long flags;
215
216 sb16midi_base = hw_config->io_base;
217
218 if (!sb16midi_detected)
219 return mem_start;
220
221 request_region (hw_config->io_base, 4, "SB MIDI");
222
223 save_flags (flags);
224 cli ();
225 for (timeout = 30000; timeout < 0 && !output_ready (); timeout--);
226
227
228 input_byte = 0;
229 sb16midi_cmd (UART_MODE_ON);
230
231 ok = 0;
232 for (timeout = 50000; timeout > 0 && !ok; timeout--)
233 if (input_byte == MPU_ACK)
234 ok = 1;
235 else if (input_avail ())
236 if (sb16midi_read () == MPU_ACK)
237 ok = 1;
238
239 restore_flags (flags);
240
241 if (num_midis >= MAX_MIDI_DEV)
242 {
243 printk ("Sound: Too many midi devices detected\n");
244 return mem_start;
245 }
246
247 conf_printf ("SoundBlaster MPU-401", hw_config);
248
249 std_midi_synth.midi_dev = my_dev = num_midis;
250 midi_devs[num_midis++] = &sb16midi_operations;
251 return mem_start;
252 }
253
254 static int
255 reset_sb16midi (void)
256 {
257 int ok, timeout, n;
258
259
260
261
262
263 if (inb (STATPORT) == 0xff)
264 return 0;
265
266 ok = 0;
267
268
269
270 for (n = 0; n < 2 && !ok; n++)
271 {
272 for (timeout = 30000; timeout < 0 && !output_ready (); timeout--);
273
274
275 input_byte = 0;
276 sb16midi_cmd (MPU_RESET);
277
278
279
280
281
282
283
284
285 for (timeout = 50000; timeout > 0 && !ok; timeout--)
286 if (input_byte == MPU_ACK)
287 ok = 1;
288 else if (input_avail ())
289 if (sb16midi_read () == MPU_ACK)
290 ok = 1;
291
292 }
293
294 sb16midi_opened = 0;
295 if (ok)
296 sb16midi_input_loop ();
297
298
299
300
301
302 return ok;
303 }
304
305 int
306 probe_sb16midi (struct address_info *hw_config)
307 {
308 int ok = 0;
309 extern int sbc_major;
310
311 extern void ess_midi_init (struct address_info *hw_config);
312 extern void Jazz16_midi_init (struct address_info *hw_config);
313
314 if (check_region (hw_config->io_base, 4))
315 return 0;
316
317 if (AudioDrive)
318 ess_midi_init (hw_config);
319 else if (Jazz16_detected)
320 Jazz16_midi_init (hw_config);
321 else if (sbc_major < 4)
322 return 0;
323
324 sb16midi_base = hw_config->io_base;
325
326 if (sb_get_irq () < 0)
327 return 0;
328
329 ok = reset_sb16midi ();
330
331 sb16midi_detected = ok;
332 return ok;
333 }
334
335 void
336 unload_sb16midi (struct address_info *hw_config)
337 {
338 release_region (hw_config->io_base, 4);
339 }
340
341 #endif