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