This source file includes following definitions.
- mad_read
- mad_write
- detect_mad16
- probe_mad16
- attach_mad16
- attach_mad16_mpu
- probe_mad16_mpu
- unload_mad16
- unload_mad16_mpu
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
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 #include "sound_config.h"
74
75 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_MAD16)
76
77 static int already_initialized = 0;
78
79 #define C928 1
80 #define MOZART 2
81 #define C929 3
82
83
84
85
86
87
88
89
90
91
92 #define MC1_PORT 0xf8d
93 #define MC2_PORT 0xf8e
94 #define MC3_PORT 0xf8f
95 #define PASSWD_REG 0xf8f
96 #define MC4_PORT 0xf90
97 #define MC5_PORT 0xf91
98 #define MC6_PORT 0xf92
99 #define MC7_PORT 0xf93
100
101 static int board_type = C928;
102
103 static sound_os_info *mad16_osp;
104
105 #ifndef DDB
106 #define DDB(x)
107 #endif
108
109 static unsigned char
110 mad_read (int port)
111 {
112 unsigned long flags;
113 unsigned char tmp;
114
115 save_flags (flags);
116 cli ();
117
118 switch (board_type)
119 {
120 case C928:
121 case MOZART:
122 outb (0xE2, PASSWD_REG);
123 break;
124
125 case C929:
126 outb (0xE3, PASSWD_REG);
127 break;
128 }
129
130 tmp = inb (port);
131 restore_flags (flags);
132
133 return tmp;
134 }
135
136 static void
137 mad_write (int port, int value)
138 {
139 unsigned long flags;
140
141 save_flags (flags);
142 cli ();
143
144 switch (board_type)
145 {
146 case C928:
147 case MOZART:
148 outb (0xE2, PASSWD_REG);
149 break;
150
151 case C929:
152 outb (0xE3, PASSWD_REG);
153 break;
154 }
155
156 outb ((unsigned char) (value & 0xff), port);
157 restore_flags (flags);
158 }
159
160 static int
161 detect_mad16 (void)
162 {
163 unsigned char tmp, tmp2;
164
165
166
167
168
169
170
171 if ((tmp = mad_read (MC1_PORT)) == 0xff)
172 {
173 DDB (printk ("MC1_PORT returned 0xff\n"));
174 return 0;
175 }
176
177
178
179
180
181 if ((tmp2 = inb (MC1_PORT)) == tmp)
182 {
183 DDB (printk ("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
184 return 0;
185 }
186
187 mad_write (MC1_PORT, tmp ^ 0x80);
188
189 if ((tmp2 = mad_read (MC1_PORT)) != (tmp ^ 0x80))
190 {
191 mad_write (MC1_PORT, tmp);
192 DDB (printk ("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
193 return 0;
194 }
195
196 mad_write (MC1_PORT, tmp);
197 return 1;
198
199 }
200
201 int
202 probe_mad16 (struct address_info *hw_config)
203 {
204 int i;
205 static int valid_ports[] =
206 {0x530, 0xe80, 0xf40, 0x604};
207 unsigned char tmp;
208 unsigned char cs4231_mode = 0;
209
210 int ad_flags = 0;
211
212 if (already_initialized)
213 return 0;
214
215 mad16_osp = hw_config->osp;
216
217
218
219
220
221 DDB (printk ("--- Detecting MAD16 / Mozart ---\n"));
222
223
224
225
226
227 board_type = C928;
228
229 DDB (printk ("Detect using password = 0xE2\n"));
230
231 if (!detect_mad16 ())
232 {
233 board_type = C929;
234
235 DDB (printk ("Detect using password = 0xE3\n"));
236
237 if (!detect_mad16 ())
238 return 0;
239
240 DDB (printk ("mad16.c: 82C929 detected\n"));
241 }
242 else
243 {
244 unsigned char model;
245
246 if (((model = mad_read (MC3_PORT)) & 0x03) == 0x03)
247 {
248 DDB (printk ("mad16.c: Mozart detected\n"));
249 board_type = MOZART;
250 }
251 else
252 {
253 DDB (printk ("mad16.c: 82C928 detected???\n"));
254 board_type = C928;
255 }
256 }
257
258 for (i = 0xf8d; i <= 0xf93; i++)
259 DDB (printk ("port %03x = %03x\n", i, mad_read (i)));
260
261
262
263
264
265 tmp = 0x80;
266
267 for (i = 0; i < 5; i++)
268 {
269 if (i > 3)
270 {
271 printk ("MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
272 return 0;
273 }
274
275 if (valid_ports[i] == hw_config->io_base)
276 {
277 tmp |= i << 4;
278 break;
279 }
280 }
281
282
283
284
285
286 #ifdef MAD16_CONF
287 tmp |= ((MAD16_CONF) & 0x0f);
288 #endif
289 mad_write (MC1_PORT, tmp);
290
291 #if defined(MAD16_CONF) && defined(MAD16_CDSEL)
292 tmp = MAD16_CDSEL;
293 #else
294 tmp = 0x03;
295 #endif
296
297 #ifdef MAD16_OPL4
298 tmp |= 0x20;
299 #endif
300
301 mad_write (MC2_PORT, tmp);
302 mad_write (MC3_PORT, 0xf0);
303
304 if (!ad1848_detect (hw_config->io_base + 4, &ad_flags, mad16_osp))
305 return 0;
306
307 if (ad_flags & (AD_F_CS4231 | AD_F_CS4248))
308 cs4231_mode = 0x02;
309
310 if (board_type == C929)
311 {
312 mad_write (MC4_PORT, 0xa2);
313 mad_write (MC5_PORT, 0xA5 | cs4231_mode);
314 mad_write (MC6_PORT, 0x03);
315 }
316 else
317 {
318 mad_write (MC4_PORT, 0x02);
319 mad_write (MC5_PORT, 0x30 | cs4231_mode);
320 }
321
322 for (i = 0xf8d; i <= 0xf93; i++)
323 DDB (printk ("port %03x after init = %03x\n", i, mad_read (i)));
324
325
326
327
328
329 if (check_region (hw_config->io_base, 8))
330 {
331 printk ("MSS: I/O port conflict\n");
332 return 0;
333 }
334
335
336
337
338
339
340
341 if ((inb (hw_config->io_base + 3) & 0x3f) != 0x04 &&
342 (inb (hw_config->io_base + 3) & 0x3f) != 0x00)
343 {
344 DDB (printk ("No MSS signature detected on port 0x%x (0x%x)\n",
345 hw_config->io_base, inb (hw_config->io_base + 3)));
346 return 0;
347 }
348
349 if (hw_config->irq > 11)
350 {
351 printk ("MSS: Bad IRQ %d\n", hw_config->irq);
352 return 0;
353 }
354
355 if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
356 {
357 printk ("MSS: Bad DMA %d\n", hw_config->dma);
358 return 0;
359 }
360
361
362
363
364
365 if (hw_config->dma == 0 && inb (hw_config->io_base + 3) & 0x80)
366 {
367 printk ("MSS: Can't use DMA0 with a 8 bit card/slot\n");
368 return 0;
369 }
370
371 if (hw_config->irq > 7 && hw_config->irq != 9 && inb (hw_config->io_base + 3) & 0x80)
372 {
373 printk ("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
374 return 0;
375 }
376
377 return 1;
378 }
379
380 long
381 attach_mad16 (long mem_start, struct address_info *hw_config)
382 {
383
384 static char interrupt_bits[12] =
385 {
386 -1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20
387 };
388 char bits;
389
390 static char dma_bits[4] =
391 {
392 1, 2, 0, 3
393 };
394
395 int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
396 int ad_flags = 0, dma = hw_config->dma, dma2 = hw_config->dma2;
397 unsigned char dma2_bit = 0;
398
399 already_initialized = 1;
400
401 if (!ad1848_detect (hw_config->io_base + 4, &ad_flags, mad16_osp))
402 return mem_start;
403
404
405
406
407
408 bits = interrupt_bits[hw_config->irq];
409 if (bits == -1)
410 return mem_start;
411
412 outb (bits | 0x40, config_port);
413 if ((inb (version_port) & 0x40) == 0)
414 printk ("[IRQ Conflict?]");
415
416
417
418
419
420 if (ad_flags & AD_F_CS4231 && dma2 != -1 && dma2 != dma)
421 {
422 if ((dma == 0 && dma2 == 1) ||
423 (dma == 1 && dma2 == 0) ||
424 (dma == 3 && dma2 == 0))
425 {
426 dma2_bit = 0x04;
427 }
428 else
429 {
430 printk ("MAD16: Invalid capture DMA\n");
431 dma2 = dma;
432 }
433 }
434 else
435 dma2 = dma;
436
437 outb (bits | dma_bits[dma] | dma2_bit, config_port);
438
439 ad1848_init ("MAD16 WSS", hw_config->io_base + 4,
440 hw_config->irq,
441 dma,
442 dma2, 0,
443 hw_config->osp);
444 request_region (hw_config->io_base, 4, "MAD16 WSS config");
445
446 return mem_start;
447 }
448
449 long
450 attach_mad16_mpu (long mem_start, struct address_info *hw_config)
451 {
452 if (board_type < C929)
453 {
454 #ifndef EXCLUDE_MIDI
455
456 if (mad_read (MC1_PORT) & 0x20)
457 hw_config->io_base = 0x240;
458 else
459 hw_config->io_base = 0x220;
460
461 return mad16_sb_dsp_init (mem_start, hw_config);
462 #else
463 return 0;
464 #endif
465 }
466
467 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
468 if (!already_initialized)
469 return mem_start;
470
471 return attach_mpu401 (mem_start, hw_config);
472 #else
473 return mem_start;
474 #endif
475 }
476
477 int
478 probe_mad16_mpu (struct address_info *hw_config)
479 {
480 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
481 static int mpu_attached = 0;
482 static int valid_ports[] =
483 {0x330, 0x320, 0x310, 0x300};
484 static short valid_irqs[] =
485 {9, 10, 5, 7};
486 unsigned char tmp;
487
488 int i;
489
490 if (!already_initialized)
491 return 0;
492
493 if (mpu_attached)
494 return 0;
495 mpu_attached = 1;
496
497 if (board_type < C929)
498 {
499
500 #ifndef EXCLUDE_MIDI
501 unsigned char tmp;
502
503 tmp = mad_read (MC3_PORT);
504
505
506
507
508
509
510
511 if (mad_read (MC1_PORT) & 0x20)
512 hw_config->io_base = 0x240;
513 else
514 hw_config->io_base = 0x220;
515
516 switch (hw_config->irq)
517 {
518 case 5:
519 tmp = (tmp & 0x3f) | 0x80;
520 break;
521 case 7:
522 tmp = (tmp & 0x3f);
523 break;
524 case 11:
525 tmp = (tmp & 0x3f) | 0x40;
526 break;
527 default:
528 printk ("mad16/Mozart: Invalid MIDI IRQ\n");
529 return 0;
530 }
531
532 mad_write (MC3_PORT, tmp | 0x04);
533 return mad16_sb_dsp_detect (hw_config);
534 #else
535 return 0;
536 #endif
537 }
538
539 tmp = 0x83;
540
541
542
543
544
545 for (i = 0; i < 5; i++)
546 {
547 if (i > 3)
548 {
549 printk ("MAD16 / Mozart: Invalid MIDI port 0x%x\n", hw_config->io_base);
550 return 0;
551 }
552
553 if (valid_ports[i] == hw_config->io_base)
554 {
555 tmp |= i << 5;
556 break;
557 }
558 }
559
560
561
562
563
564 for (i = 0; i < 5; i++)
565 {
566 if (i > 3)
567 {
568 printk ("MAD16 / Mozart: Invalid MIDI IRQ %d\n", hw_config->irq);
569 return 0;
570 }
571
572 if (valid_irqs[i] == hw_config->irq)
573 {
574 tmp |= i << 3;
575 break;
576 }
577 }
578 mad_write (MC6_PORT, tmp);
579
580 return probe_mpu401 (hw_config);
581 #else
582 return 0;
583 #endif
584 }
585
586 void
587 unload_mad16 (struct address_info *hw_config)
588 {
589 ad1848_unload (hw_config->io_base + 4,
590 hw_config->irq,
591 hw_config->dma,
592 hw_config->dma2, 0);
593 release_region (hw_config->io_base, 4);
594
595 }
596
597 void
598 unload_mad16_mpu (struct address_info *hw_config)
599 {
600 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
601 unload_mpu401 (hw_config);
602 #endif
603 }
604
605
606 #endif