This source file includes following definitions.
- mad_read
- mad_write
- detect_mad16
- probe_mad16
- attach_mad16
- attach_mad16_mpu
- probe_mad16_mpu
1 #define MAD16_OPL4
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 #include "sound_config.h"
75
76 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_MAD16)
77
78 static int already_initialized = 0;
79
80 #define C928 1
81 #define MOZART 2
82 #define C929 3
83
84
85
86
87
88
89
90
91
92
93 #define MC1_PORT 0xf8d
94 #define MC2_PORT 0xf8e
95 #define MC3_PORT 0xf8f
96 #define PASSWD_REG 0xf8f
97 #define MC4_PORT 0xf90
98 #define MC5_PORT 0xf91
99 #define MC6_PORT 0xf92
100 #define MC7_PORT 0xf93
101
102 static int board_type = C928;
103
104 #ifndef DDB
105 #define DDB(x)
106 #endif
107
108 static unsigned char
109 mad_read (int port)
110 {
111 unsigned long flags;
112 unsigned char tmp;
113
114 DISABLE_INTR (flags);
115
116 switch (board_type)
117 {
118 case C928:
119 case MOZART:
120 OUTB (0xE2, PASSWD_REG);
121 break;
122
123 case C929:
124 OUTB (0xE3, PASSWD_REG);
125 break;
126 }
127
128 tmp = INB (port);
129 RESTORE_INTR (flags);
130
131 return tmp;
132 }
133
134 static void
135 mad_write (int port, int value)
136 {
137 unsigned long flags;
138
139 DISABLE_INTR (flags);
140
141 switch (board_type)
142 {
143 case C928:
144 case MOZART:
145 OUTB (0xE2, PASSWD_REG);
146 break;
147
148 case C929:
149 OUTB (0xE3, PASSWD_REG);
150 break;
151 }
152
153 OUTB ((unsigned char) (value & 0xff), port);
154 RESTORE_INTR (flags);
155 }
156
157 static int
158 detect_mad16 (void)
159 {
160 unsigned char tmp, tmp2;
161
162
163
164
165
166
167
168 if ((tmp = mad_read (MC1_PORT)) == 0xff)
169 {
170 DDB (printk ("MC1_PORT returned 0xff\n"));
171 return 0;
172 }
173
174
175
176
177
178 if ((tmp2 = INB (MC1_PORT)) == tmp)
179 {
180 DDB (printk ("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
181 return 0;
182 }
183
184 mad_write (MC1_PORT, tmp ^ 0x80);
185
186 if ((tmp2 = mad_read (MC1_PORT)) != (tmp ^ 0x80))
187 {
188 mad_write (MC1_PORT, tmp);
189 DDB (printk ("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
190 return 0;
191 }
192
193 mad_write (MC1_PORT, tmp);
194 return 1;
195
196 }
197
198 int
199 probe_mad16 (struct address_info *hw_config)
200 {
201 int i;
202 static int valid_ports[] =
203 {0x530, 0xe80, 0xf40, 0x604};
204 unsigned char tmp;
205
206 if (already_initialized)
207 return 0;
208
209
210
211
212
213
214 DDB (printk ("--- Detecting MAD16 / Mozart ---\n"));
215
216 #if 0
217 for (i = 0xf8d; i <= 0xf93; i++)
218 if (INB (i) != 0xff)
219 {
220 DDB (printk ("port 0x%03x != 0xff (0x%02x)\n", i, INB (i)));
221 return 0;
222 }
223 #endif
224
225
226
227
228 board_type = C928;
229
230 DDB (printk ("Detect using password = 0xE2\n"));
231
232 if (!detect_mad16 ())
233 {
234 board_type = C929;
235
236 DDB (printk ("Detect using password = 0xE3\n"));
237
238 if (!detect_mad16 ())
239 return 0;
240
241 printk ("mad16.c: 82C929 detected???\n");
242 }
243 else
244 {
245 unsigned char model;
246
247 if (((model = mad_read (MC3_PORT)) & 0x03) == 0x03)
248 {
249 printk ("mad16.c: Mozart detected???\n");
250 board_type = MOZART;
251 }
252 else
253 {
254 printk ("mad16.c: 82C928 detected???\n");
255 board_type = C928;
256 }
257 }
258
259 for (i = 0xf8d; i <= 0xf93; i++)
260 DDB (printk ("port %03x = %03x\n", i, mad_read (i)));
261
262
263
264
265
266 tmp = 0x80;
267
268 for (i = 0; i < 5; i++)
269 {
270 if (i > 3)
271 {
272 printk ("MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
273 return 0;
274 }
275
276 if (valid_ports[i] == hw_config->io_base)
277 {
278 tmp |= i << 4;
279 break;
280 }
281 }
282
283
284
285
286 #define MAD16_CONF 0x06
287 #define MAD16_CDSEL 0x03
288
289 #ifdef MAD16_CONF
290 tmp |= ((MAD16_CONF) & 0x0f);
291 #endif
292 mad_write (MC1_PORT, tmp);
293
294 #if defined(MAD16_CONF) && defined(MAD16_CDSEL)
295 tmp = MAD16_CDSEL;
296 #else
297 tmp = 0x03;
298 #endif
299
300 #ifdef MAD16_OPL4
301 tmp |= 0x20;
302 #endif
303
304 mad_write (MC2_PORT, tmp);
305 mad_write (MC3_PORT, 0xf0);
306
307 if (board_type == C929)
308 {
309 mad_write (MC4_PORT, 0xa2);
310 mad_write (MC5_PORT, 0x95);
311 mad_write (MC6_PORT, 0x03);
312 }
313 else
314 {
315 mad_write (MC4_PORT, 0x02);
316 mad_write (MC5_PORT, 0x10);
317 }
318
319 for (i = 0xf8d; i <= 0xf93; i++)
320 DDB (printk ("port %03x after init = %03x\n", i, mad_read (i)));
321
322 return probe_ms_sound (hw_config);
323 }
324
325 long
326 attach_mad16 (long mem_start, struct address_info *hw_config)
327 {
328
329 already_initialized = 1;
330
331 return attach_ms_sound (mem_start, hw_config);
332 }
333
334 long
335 attach_mad16_mpu (long mem_start, struct address_info *hw_config)
336 {
337
338 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
339 if (!already_initialized)
340 return mem_start;
341
342 return attach_mpu401 (mem_start, hw_config);
343 #else
344 return mem_start;
345 #endif
346 }
347
348 int
349 probe_mad16_mpu (struct address_info *hw_config)
350 {
351 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
352 static int mpu_attached = 0;
353 static int valid_ports[] =
354 {0x330, 0x320, 0x310, 0x300};
355 static short valid_irqs[] =
356 {9, 10, 5, 7};
357 unsigned char tmp;
358
359 int i;
360
361 if (!already_initialized)
362 return 0;
363
364 if (mpu_attached)
365 return 0;
366 mpu_attached = 1;
367
368 if (board_type < C929)
369 {
370 printk ("Mozart and OPTi 82C928 based cards don't support MPU401. Sorry\n");
371 return 0;
372 }
373
374 tmp = 0x83;
375
376
377
378
379
380 for (i = 0; i < 5; i++)
381 {
382 if (i > 3)
383 {
384 printk ("MAD16 / Mozart: Invalid MIDI port 0x%x\n", hw_config->io_base);
385 return 0;
386 }
387
388 if (valid_ports[i] == hw_config->io_base)
389 {
390 tmp |= i << 5;
391 break;
392 }
393 }
394
395
396
397
398
399 for (i = 0; i < 5; i++)
400 {
401 if (i > 3)
402 {
403 printk ("MAD16 / Mozart: Invalid MIDI IRQ %d\n", hw_config->irq);
404 return 0;
405 }
406
407 if (valid_irqs[i] == hw_config->irq)
408 {
409 tmp |= i << 3;
410 break;
411 }
412 }
413 mad_write (MC6_PORT, tmp);
414
415 return probe_mpu401 (hw_config);
416 #else
417 return 0;
418 #endif
419 }
420
421
422 #endif