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