aboutsummaryrefslogtreecommitdiffstats
path: root/sound/oss/mad16.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /sound/oss/mad16.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'sound/oss/mad16.c')
-rw-r--r--sound/oss/mad16.c1097
1 files changed, 1097 insertions, 0 deletions
diff --git a/sound/oss/mad16.c b/sound/oss/mad16.c
new file mode 100644
index 000000000000..a7067f169919
--- /dev/null
+++ b/sound/oss/mad16.c
@@ -0,0 +1,1097 @@
1/*
2 * Copyright (C) by Hannu Savolainen 1993-1997
3 *
4 * mad16.c
5 *
6 * Initialization code for OPTi MAD16 compatible audio chips. Including
7 *
8 * OPTi 82C928 MAD16 (replaced by C929)
9 * OAK OTI-601D Mozart
10 * OAK OTI-605 Mozart (later version with MPU401 Midi)
11 * OPTi 82C929 MAD16 Pro
12 * OPTi 82C930
13 * OPTi 82C924
14 *
15 * These audio interface chips don't produce sound themselves. They just
16 * connect some other components (OPL-[234] and a WSS compatible codec)
17 * to the PC bus and perform I/O, DMA and IRQ address decoding. There is
18 * also a UART for the MPU-401 mode (not 82C928/Mozart).
19 * The Mozart chip appears to be compatible with the 82C928, although later
20 * issues of the card, using the OTI-605 chip, have an MPU-401 compatible Midi
21 * port. This port is configured differently to that of the OPTi audio chips.
22 *
23 * Changes
24 *
25 * Alan Cox Clean up, added module selections.
26 *
27 * A. Wik Added support for Opti924 PnP.
28 * Improved debugging support. 16-May-1998
29 * Fixed bug. 16-Jun-1998
30 *
31 * Torsten Duwe Made Opti924 PnP support non-destructive
32 * 23-Dec-1998
33 *
34 * Paul Grayson Added support for Midi on later Mozart cards.
35 * 25-Nov-1999
36 * Christoph Hellwig Adapted to module_init/module_exit.
37 * Arnaldo C. de Melo got rid of attach_uart401 21-Sep-2000
38 *
39 * Pavel Rabel Clean up Nov-2000
40 */
41
42#include <linux/config.h>
43#include <linux/init.h>
44#include <linux/module.h>
45#include <linux/gameport.h>
46#include <linux/spinlock.h>
47#include "sound_config.h"
48
49#include "ad1848.h"
50#include "sb.h"
51#include "mpu401.h"
52
53static int mad16_conf;
54static int mad16_cdsel;
55static struct gameport *gameport;
56static DEFINE_SPINLOCK(lock);
57
58#define C928 1
59#define MOZART 2
60#define C929 3
61#define C930 4
62#define C924 5
63
64/*
65 * Registers
66 *
67 * The MAD16 occupies I/O ports 0xf8d to 0xf93 (fixed locations).
68 * All ports are inactive by default. They can be activated by
69 * writing 0xE2 or 0xE3 to the password register. The password is valid
70 * only until the next I/O read or write.
71 *
72 * 82C930 uses 0xE4 as the password and indirect addressing to access
73 * the config registers.
74 */
75
76#define MC0_PORT 0xf8c /* Dummy port */
77#define MC1_PORT 0xf8d /* SB address, CD-ROM interface type, joystick */
78#define MC2_PORT 0xf8e /* CD-ROM address, IRQ, DMA, plus OPL4 bit */
79#define MC3_PORT 0xf8f
80#define PASSWD_REG 0xf8f
81#define MC4_PORT 0xf90
82#define MC5_PORT 0xf91
83#define MC6_PORT 0xf92
84#define MC7_PORT 0xf93
85#define MC8_PORT 0xf94
86#define MC9_PORT 0xf95
87#define MC10_PORT 0xf96
88#define MC11_PORT 0xf97
89#define MC12_PORT 0xf98
90
91static int board_type = C928;
92
93static int *mad16_osp;
94static int c931_detected; /* minor differences from C930 */
95static char c924pnp; /* " " " C924 */
96static int debug; /* debugging output */
97
98#ifdef DDB
99#undef DDB
100#endif
101#define DDB(x) do {if (debug) x;} while (0)
102
103static unsigned char mad_read(int port)
104{
105 unsigned long flags;
106 unsigned char tmp;
107
108 spin_lock_irqsave(&lock,flags);
109
110 switch (board_type) /* Output password */
111 {
112 case C928:
113 case MOZART:
114 outb((0xE2), PASSWD_REG);
115 break;
116
117 case C929:
118 outb((0xE3), PASSWD_REG);
119 break;
120
121 case C930:
122 /* outb(( 0xE4), PASSWD_REG); */
123 break;
124
125 case C924:
126 /* the c924 has its ports relocated by -128 if
127 PnP is enabled -aw */
128 if (!c924pnp)
129 outb((0xE5), PASSWD_REG); else
130 outb((0xE5), PASSWD_REG - 0x80);
131 break;
132 }
133
134 if (board_type == C930)
135 {
136 outb((port - MC0_PORT), 0xe0e); /* Write to index reg */
137 tmp = inb(0xe0f); /* Read from data reg */
138 }
139 else
140 if (!c924pnp)
141 tmp = inb(port); else
142 tmp = inb(port-0x80);
143 spin_unlock_irqrestore(&lock,flags);
144
145 return tmp;
146}
147
148static void mad_write(int port, int value)
149{
150 unsigned long flags;
151
152 spin_lock_irqsave(&lock,flags);
153
154 switch (board_type) /* Output password */
155 {
156 case C928:
157 case MOZART:
158 outb((0xE2), PASSWD_REG);
159 break;
160
161 case C929:
162 outb((0xE3), PASSWD_REG);
163 break;
164
165 case C930:
166 /* outb(( 0xE4), PASSWD_REG); */
167 break;
168
169 case C924:
170 if (!c924pnp)
171 outb((0xE5), PASSWD_REG); else
172 outb((0xE5), PASSWD_REG - 0x80);
173 break;
174 }
175
176 if (board_type == C930)
177 {
178 outb((port - MC0_PORT), 0xe0e); /* Write to index reg */
179 outb(((unsigned char) (value & 0xff)), 0xe0f);
180 }
181 else
182 if (!c924pnp)
183 outb(((unsigned char) (value & 0xff)), port); else
184 outb(((unsigned char) (value & 0xff)), port-0x80);
185 spin_unlock_irqrestore(&lock,flags);
186}
187
188static int __init detect_c930(void)
189{
190 unsigned char tmp = mad_read(MC1_PORT);
191
192 if ((tmp & 0x06) != 0x06)
193 {
194 DDB(printk("Wrong C930 signature (%x)\n", tmp));
195 /* return 0; */
196 }
197 mad_write(MC1_PORT, 0);
198
199 if (mad_read(MC1_PORT) != 0x06)
200 {
201 DDB(printk("Wrong C930 signature2 (%x)\n", tmp));
202 /* return 0; */
203 }
204 mad_write(MC1_PORT, tmp); /* Restore bits */
205
206 mad_write(MC7_PORT, 0);
207 if ((tmp = mad_read(MC7_PORT)) != 0)
208 {
209 DDB(printk("MC7 not writable (%x)\n", tmp));
210 return 0;
211 }
212 mad_write(MC7_PORT, 0xcb);
213 if ((tmp = mad_read(MC7_PORT)) != 0xcb)
214 {
215 DDB(printk("MC7 not writable2 (%x)\n", tmp));
216 return 0;
217 }
218
219 tmp = mad_read(MC0_PORT+18);
220 if (tmp == 0xff || tmp == 0x00)
221 return 1;
222 /* We probably have a C931 */
223 DDB(printk("Detected C931 config=0x%02x\n", tmp));
224 c931_detected = 1;
225
226 /*
227 * We cannot configure the chip if it is in PnP mode.
228 * If we have a CSN assigned (bit 8 in MC13) we first try
229 * a software reset, then a software power off, finally
230 * Clearing PnP mode. The last option is not
231 * Bit 8 in MC13
232 */
233 if ((mad_read(MC0_PORT+13) & 0x80) == 0)
234 return 1;
235
236 /* Software reset */
237 mad_write(MC9_PORT, 0x02);
238 mad_write(MC9_PORT, 0x00);
239
240 if ((mad_read(MC0_PORT+13) & 0x80) == 0)
241 return 1;
242
243 /* Power off, and on again */
244 mad_write(MC9_PORT, 0xc2);
245 mad_write(MC9_PORT, 0xc0);
246
247 if ((mad_read(MC0_PORT+13) & 0x80) == 0)
248 return 1;
249
250#if 0
251 /* Force off PnP mode. This is not recommended because
252 * the PnP bios will not recognize the chip on the next
253 * warm boot and may assignd different resources to other
254 * PnP/PCI cards.
255 */
256 mad_write(MC0_PORT+17, 0x04);
257#endif
258 return 1;
259}
260
261static int __init detect_mad16(void)
262{
263 unsigned char tmp, tmp2, bit;
264 int i, port;
265
266 /*
267 * Check that reading a register doesn't return bus float (0xff)
268 * when the card is accessed using password. This may fail in case
269 * the card is in low power mode. Normally at least the power saving
270 * mode bit should be 0.
271 */
272
273 if ((tmp = mad_read(MC1_PORT)) == 0xff)
274 {
275 DDB(printk("MC1_PORT returned 0xff\n"));
276 return 0;
277 }
278 for (i = 0xf8d; i <= 0xf98; i++)
279 if (!c924pnp)
280 DDB(printk("Port %0x (init value) = %0x\n", i, mad_read(i)));
281 else
282 DDB(printk("Port %0x (init value) = %0x\n", i-0x80, mad_read(i)));
283
284 if (board_type == C930)
285 return detect_c930();
286
287 /*
288 * Now check that the gate is closed on first I/O after writing
289 * the password. (This is how a MAD16 compatible card works).
290 */
291
292 if ((tmp2 = inb(MC1_PORT)) == tmp) /* It didn't close */
293 {
294 DDB(printk("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
295 return 0;
296 }
297
298 bit = (c924pnp) ? 0x20 : 0x80;
299 port = (c924pnp) ? MC2_PORT : MC1_PORT;
300
301 tmp = mad_read(port);
302 mad_write(port, tmp ^ bit); /* Toggle a bit */
303 if ((tmp2 = mad_read(port)) != (tmp ^ bit)) /* Compare the bit */
304 {
305 mad_write(port, tmp); /* Restore */
306 DDB(printk("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
307 return 0;
308 }
309 mad_write(port, tmp); /* Restore */
310 return 1; /* Bingo */
311}
312
313static int __init wss_init(struct address_info *hw_config)
314{
315 /*
316 * Check if the IO port returns valid signature. The original MS Sound
317 * system returns 0x04 while some cards (AudioTrix Pro for example)
318 * return 0x00.
319 */
320
321 if ((inb(hw_config->io_base + 3) & 0x3f) != 0x04 &&
322 (inb(hw_config->io_base + 3) & 0x3f) != 0x00)
323 {
324 DDB(printk("No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, inb(hw_config->io_base + 3)));
325 return 0;
326 }
327 /*
328 * Check that DMA0 is not in use with a 8 bit board.
329 */
330 if (hw_config->dma == 0 && inb(hw_config->io_base + 3) & 0x80)
331 {
332 printk("MSS: Can't use DMA0 with a 8 bit card/slot\n");
333 return 0;
334 }
335 if (hw_config->irq > 9 && inb(hw_config->io_base + 3) & 0x80)
336 printk(KERN_ERR "MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
337 return 1;
338}
339
340static void __init init_c930(struct address_info *hw_config, int base)
341{
342 unsigned char cfg = 0;
343
344 cfg |= (0x0f & mad16_conf);
345
346 if(c931_detected)
347 {
348 /* Bit 0 has reversd meaning. Bits 1 and 2 sese
349 reversed on write.
350 Support only IDE cdrom. IDE port programmed
351 somewhere else. */
352 cfg = (cfg & 0x09) ^ 0x07;
353 }
354 cfg |= base << 4;
355 mad_write(MC1_PORT, cfg);
356
357 /* MC2 is CD configuration. Don't touch it. */
358
359 mad_write(MC3_PORT, 0); /* Disable SB mode IRQ and DMA */
360
361 /* bit 2 of MC4 reverses it's meaning between the C930
362 and the C931. */
363 cfg = c931_detected ? 0x04 : 0x00;
364
365 if(mad16_cdsel & 0x20)
366 mad_write(MC4_PORT, 0x62|cfg); /* opl4 */
367 else
368 mad_write(MC4_PORT, 0x52|cfg); /* opl3 */
369
370 mad_write(MC5_PORT, 0x3C); /* Init it into mode2 */
371 mad_write(MC6_PORT, 0x02); /* Enable WSS, Disable MPU and SB */
372 mad_write(MC7_PORT, 0xCB);
373 mad_write(MC10_PORT, 0x11);
374}
375
376static int __init chip_detect(void)
377{
378 int i;
379
380 /*
381 * Then try to detect with the old password
382 */
383 board_type = C924;
384
385 DDB(printk("Detect using password = 0xE5\n"));
386
387 if (detect_mad16()) {
388 return 1;
389 }
390
391 board_type = C928;
392
393 DDB(printk("Detect using password = 0xE2\n"));
394
395 if (detect_mad16())
396 {
397 unsigned char model;
398
399 if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03) {
400 DDB(printk("mad16.c: Mozart detected\n"));
401 board_type = MOZART;
402 } else {
403 DDB(printk("mad16.c: 82C928 detected???\n"));
404 board_type = C928;
405 }
406 return 1;
407 }
408
409 board_type = C929;
410
411 DDB(printk("Detect using password = 0xE3\n"));
412
413 if (detect_mad16())
414 {
415 DDB(printk("mad16.c: 82C929 detected\n"));
416 return 1;
417 }
418
419 if (inb(PASSWD_REG) != 0xff)
420 return 0;
421
422 /*
423 * First relocate MC# registers to 0xe0e/0xe0f, disable password
424 */
425
426 outb((0xE4), PASSWD_REG);
427 outb((0x80), PASSWD_REG);
428
429 board_type = C930;
430
431 DDB(printk("Detect using password = 0xE4\n"));
432
433 for (i = 0xf8d; i <= 0xf93; i++)
434 DDB(printk("port %03x = %02x\n", i, mad_read(i)));
435
436 if(detect_mad16()) {
437 DDB(printk("mad16.c: 82C930 detected\n"));
438 return 1;
439 }
440
441 /* The C931 has the password reg at F8D */
442 outb((0xE4), 0xF8D);
443 outb((0x80), 0xF8D);
444 DDB(printk("Detect using password = 0xE4 for C931\n"));
445
446 if (detect_mad16()) {
447 return 1;
448 }
449
450 board_type = C924;
451 c924pnp++;
452 DDB(printk("Detect using password = 0xE5 (again), port offset -0x80\n"));
453 if (detect_mad16()) {
454 DDB(printk("mad16.c: 82C924 PnP detected\n"));
455 return 1;
456 }
457
458 c924pnp=0;
459
460 return 0;
461}
462
463static int __init probe_mad16(struct address_info *hw_config)
464{
465 int i;
466 unsigned char tmp;
467 unsigned char cs4231_mode = 0;
468
469 int ad_flags = 0;
470
471 signed char bits;
472
473 static char dma_bits[4] = {
474 1, 2, 0, 3
475 };
476
477 int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
478 int dma = hw_config->dma, dma2 = hw_config->dma2;
479 unsigned char dma2_bit = 0;
480 int base;
481 struct resource *ports;
482
483 mad16_osp = hw_config->osp;
484
485 switch (hw_config->io_base) {
486 case 0x530:
487 base = 0;
488 break;
489 case 0xe80:
490 base = 1;
491 break;
492 case 0xf40:
493 base = 2;
494 break;
495 case 0x604:
496 base = 3;
497 break;
498 default:
499 printk(KERN_ERR "MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
500 return 0;
501 }
502
503 if (dma != 0 && dma != 1 && dma != 3) {
504 printk(KERN_ERR "MSS: Bad DMA %d\n", dma);
505 return 0;
506 }
507
508 /*
509 * Check that all ports return 0xff (bus float) when no password
510 * is written to the password register.
511 */
512
513 DDB(printk("--- Detecting MAD16 / Mozart ---\n"));
514 if (!chip_detect())
515 return 0;
516
517 switch (hw_config->irq) {
518 case 7:
519 bits = 8;
520 break;
521 case 9:
522 bits = 0x10;
523 break;
524 case 10:
525 bits = 0x18;
526 break;
527 case 12:
528 bits = 0x20;
529 break;
530 case 5: /* Also IRQ5 is possible on C930 */
531 if (board_type == C930 || c924pnp) {
532 bits = 0x28;
533 break;
534 }
535 default:
536 printk(KERN_ERR "MAD16/Mozart: Bad IRQ %d\n", hw_config->irq);
537 return 0;
538 }
539
540 ports = request_region(hw_config->io_base + 4, 4, "ad1848");
541 if (!ports) {
542 printk(KERN_ERR "MSS: I/O port conflict\n");
543 return 0;
544 }
545 if (!request_region(hw_config->io_base, 4, "mad16 WSS config")) {
546 release_region(hw_config->io_base + 4, 4);
547 printk(KERN_ERR "MSS: I/O port conflict\n");
548 return 0;
549 }
550
551 if (board_type == C930) {
552 init_c930(hw_config, base);
553 goto got_it;
554 }
555
556 for (i = 0xf8d; i <= 0xf93; i++) {
557 if (!c924pnp)
558 DDB(printk("port %03x = %02x\n", i, mad_read(i)));
559 else
560 DDB(printk("port %03x = %02x\n", i-0x80, mad_read(i)));
561 }
562
563/*
564 * Set the WSS address
565 */
566
567 tmp = (mad_read(MC1_PORT) & 0x0f) | 0x80; /* Enable WSS, Disable SB */
568 tmp |= base << 4; /* WSS port select bits */
569
570 /*
571 * Set optional CD-ROM and joystick settings.
572 */
573
574 tmp &= ~0x0f;
575 tmp |= (mad16_conf & 0x0f); /* CD-ROM and joystick bits */
576 mad_write(MC1_PORT, tmp);
577
578 tmp = mad16_cdsel;
579 mad_write(MC2_PORT, tmp);
580 mad_write(MC3_PORT, 0xf0); /* Disable SB */
581
582 if (board_type == C924) /* Specific C924 init values */
583 {
584 mad_write(MC4_PORT, 0xA0);
585 mad_write(MC5_PORT, 0x05);
586 mad_write(MC6_PORT, 0x03);
587 }
588 if (!ad1848_detect(ports, &ad_flags, mad16_osp))
589 goto fail;
590
591 if (ad_flags & (AD_F_CS4231 | AD_F_CS4248))
592 cs4231_mode = 0x02; /* CS4248/CS4231 sync delay switch */
593
594 if (board_type == C929)
595 {
596 mad_write(MC4_PORT, 0xa2);
597 mad_write(MC5_PORT, 0xA5 | cs4231_mode);
598 mad_write(MC6_PORT, 0x03); /* Disable MPU401 */
599 }
600 else
601 {
602 mad_write(MC4_PORT, 0x02);
603 mad_write(MC5_PORT, 0x30 | cs4231_mode);
604 }
605
606 for (i = 0xf8d; i <= 0xf93; i++) {
607 if (!c924pnp)
608 DDB(printk("port %03x after init = %02x\n", i, mad_read(i)));
609 else
610 DDB(printk("port %03x after init = %02x\n", i-0x80, mad_read(i)));
611 }
612
613got_it:
614 ad_flags = 0;
615 if (!ad1848_detect(ports, &ad_flags, mad16_osp))
616 goto fail;
617
618 if (!wss_init(hw_config))
619 goto fail;
620
621 /*
622 * Set the IRQ and DMA addresses.
623 */
624
625 outb((bits | 0x40), config_port);
626 if ((inb(version_port) & 0x40) == 0)
627 printk(KERN_ERR "[IRQ Conflict?]\n");
628
629 /*
630 * Handle the capture DMA channel
631 */
632
633 if (ad_flags & AD_F_CS4231 && dma2 != -1 && dma2 != dma)
634 {
635 if (!((dma == 0 && dma2 == 1) ||
636 (dma == 1 && dma2 == 0) ||
637 (dma == 3 && dma2 == 0)))
638 { /* Unsupported combination. Try to swap channels */
639 int tmp = dma;
640
641 dma = dma2;
642 dma2 = tmp;
643 }
644 if ((dma == 0 && dma2 == 1) || (dma == 1 && dma2 == 0) ||
645 (dma == 3 && dma2 == 0))
646 {
647 dma2_bit = 0x04; /* Enable capture DMA */
648 }
649 else
650 {
651 printk("MAD16: Invalid capture DMA\n");
652 dma2 = dma;
653 }
654 }
655 else dma2 = dma;
656
657 outb((bits | dma_bits[dma] | dma2_bit), config_port); /* Write IRQ+DMA setup */
658
659 hw_config->slots[0] = ad1848_init("mad16 WSS", ports,
660 hw_config->irq,
661 dma,
662 dma2, 0,
663 hw_config->osp,
664 THIS_MODULE);
665 return 1;
666
667fail:
668 release_region(hw_config->io_base + 4, 4);
669 release_region(hw_config->io_base, 4);
670 return 0;
671}
672
673static int __init probe_mad16_mpu(struct address_info *hw_config)
674{
675 unsigned char tmp;
676
677 if (board_type < C929) /* Early chip. No MPU support. Just SB MIDI */
678 {
679
680#ifdef CONFIG_MAD16_OLDCARD
681
682 tmp = mad_read(MC3_PORT);
683
684 /*
685 * MAD16 SB base is defined by the WSS base. It cannot be changed
686 * alone.
687 * Ignore configured I/O base. Use the active setting.
688 */
689
690 if (mad_read(MC1_PORT) & 0x20)
691 hw_config->io_base = 0x240;
692 else
693 hw_config->io_base = 0x220;
694
695 switch (hw_config->irq)
696 {
697 case 5:
698 tmp = (tmp & 0x3f) | 0x80;
699 break;
700 case 7:
701 tmp = (tmp & 0x3f);
702 break;
703 case 11:
704 tmp = (tmp & 0x3f) | 0x40;
705 break;
706 default:
707 printk(KERN_ERR "mad16/Mozart: Invalid MIDI IRQ\n");
708 return 0;
709 }
710
711 mad_write(MC3_PORT, tmp | 0x04);
712 hw_config->driver_use_1 = SB_MIDI_ONLY;
713 if (!request_region(hw_config->io_base, 16, "soundblaster"))
714 return 0;
715 if (!sb_dsp_detect(hw_config, 0, 0, NULL)) {
716 release_region(hw_config->io_base, 16);
717 return 0;
718 }
719
720 if (mad_read(MC1_PORT) & 0x20)
721 hw_config->io_base = 0x240;
722 else
723 hw_config->io_base = 0x220;
724
725 hw_config->name = "Mad16/Mozart";
726 sb_dsp_init(hw_config, THIS_MODULE);
727 return 1;
728#else
729 /* assuming all later Mozart cards are identified as
730 * either 82C928 or Mozart. If so, following code attempts
731 * to set MPU register. TODO - add probing
732 */
733
734 tmp = mad_read(MC8_PORT);
735
736 switch (hw_config->irq)
737 {
738 case 5:
739 tmp |= 0x08;
740 break;
741 case 7:
742 tmp |= 0x10;
743 break;
744 case 9:
745 tmp |= 0x18;
746 break;
747 case 10:
748 tmp |= 0x20;
749 break;
750 case 11:
751 tmp |= 0x28;
752 break;
753 default:
754 printk(KERN_ERR "mad16/MOZART: invalid mpu_irq\n");
755 return 0;
756 }
757
758 switch (hw_config->io_base)
759 {
760 case 0x300:
761 tmp |= 0x01;
762 break;
763 case 0x310:
764 tmp |= 0x03;
765 break;
766 case 0x320:
767 tmp |= 0x05;
768 break;
769 case 0x330:
770 tmp |= 0x07;
771 break;
772 default:
773 printk(KERN_ERR "mad16/MOZART: invalid mpu_io\n");
774 return 0;
775 }
776
777 mad_write(MC8_PORT, tmp); /* write MPU port parameters */
778 goto probe_401;
779#endif
780 }
781 tmp = mad_read(MC6_PORT) & 0x83;
782 tmp |= 0x80; /* MPU-401 enable */
783
784 /* Set the MPU base bits */
785
786 switch (hw_config->io_base)
787 {
788 case 0x300:
789 tmp |= 0x60;
790 break;
791 case 0x310:
792 tmp |= 0x40;
793 break;
794 case 0x320:
795 tmp |= 0x20;
796 break;
797 case 0x330:
798 tmp |= 0x00;
799 break;
800 default:
801 printk(KERN_ERR "MAD16: Invalid MIDI port 0x%x\n", hw_config->io_base);
802 return 0;
803 }
804
805 /* Set the MPU IRQ bits */
806
807 switch (hw_config->irq)
808 {
809 case 5:
810 tmp |= 0x10;
811 break;
812 case 7:
813 tmp |= 0x18;
814 break;
815 case 9:
816 tmp |= 0x00;
817 break;
818 case 10:
819 tmp |= 0x08;
820 break;
821 default:
822 printk(KERN_ERR "MAD16: Invalid MIDI IRQ %d\n", hw_config->irq);
823 break;
824 }
825
826 mad_write(MC6_PORT, tmp); /* Write MPU401 config */
827
828#ifndef CONFIG_MAD16_OLDCARD
829probe_401:
830#endif
831 hw_config->driver_use_1 = SB_MIDI_ONLY;
832 hw_config->name = "Mad16/Mozart";
833 return probe_uart401(hw_config, THIS_MODULE);
834}
835
836static void __exit unload_mad16(struct address_info *hw_config)
837{
838 ad1848_unload(hw_config->io_base + 4,
839 hw_config->irq,
840 hw_config->dma,
841 hw_config->dma2, 0);
842 release_region(hw_config->io_base, 4);
843 sound_unload_audiodev(hw_config->slots[0]);
844}
845
846static void __exit unload_mad16_mpu(struct address_info *hw_config)
847{
848#ifdef CONFIG_MAD16_OLDCARD
849 if (board_type < C929) /* Early chip. No MPU support. Just SB MIDI */
850 {
851 sb_dsp_unload(hw_config, 0);
852 return;
853 }
854#endif
855
856 unload_uart401(hw_config);
857}
858
859static struct address_info cfg;
860static struct address_info cfg_mpu;
861
862static int found_mpu;
863
864static int __initdata mpu_io = 0;
865static int __initdata mpu_irq = 0;
866static int __initdata io = -1;
867static int __initdata dma = -1;
868static int __initdata dma16 = -1; /* Set this for modules that need it */
869static int __initdata irq = -1;
870static int __initdata cdtype = 0;
871static int __initdata cdirq = 0;
872static int __initdata cdport = 0x340;
873static int __initdata cddma = -1;
874static int __initdata opl4 = 0;
875static int __initdata joystick = 0;
876
877module_param(mpu_io, int, 0);
878module_param(mpu_irq, int, 0);
879module_param(io, int, 0);
880module_param(dma, int, 0);
881module_param(dma16, int, 0);
882module_param(irq, int, 0);
883module_param(cdtype, int, 0);
884module_param(cdirq, int, 0);
885module_param(cdport, int, 0);
886module_param(cddma, int, 0);
887module_param(opl4, int, 0);
888module_param(joystick, bool, 0);
889module_param(debug, bool, 0644);
890
891static int __initdata dma_map[2][8] =
892{
893 {0x03, -1, -1, -1, -1, 0x00, 0x01, 0x02},
894 {0x03, -1, 0x01, 0x00, -1, -1, -1, -1}
895};
896
897static int __initdata irq_map[16] =
898{
899 0x00, -1, -1, 0x0A,
900 -1, 0x04, -1, 0x08,
901 -1, 0x10, 0x14, 0x18,
902 -1, -1, -1, -1
903};
904
905static int __devinit mad16_register_gameport(int io_port)
906{
907 if (!request_region(io_port, 1, "mad16 gameport")) {
908 printk(KERN_ERR "mad16: gameport address 0x%#x already in use\n", io_port);
909 return -EBUSY;
910 }
911
912 gameport = gameport_allocate_port();
913 if (!gameport) {
914 printk(KERN_ERR "mad16: can not allocate memory for gameport\n");
915 release_region(io_port, 1);
916 return -ENOMEM;
917 }
918
919 gameport_set_name(gameport, "MAD16 Gameport");
920 gameport_set_phys(gameport, "isa%04x/gameport0", io_port);
921 gameport->io = io_port;
922
923 gameport_register_port(gameport);
924
925 return 0;
926}
927
928static int __devinit init_mad16(void)
929{
930 int dmatype = 0;
931
932 printk(KERN_INFO "MAD16 audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
933
934 printk(KERN_INFO "CDROM ");
935 switch (cdtype)
936 {
937 case 0x00:
938 printk("Disabled");
939 cdirq = 0;
940 break;
941 case 0x02:
942 printk("Sony CDU31A");
943 dmatype = 1;
944 if(cddma == -1) cddma = 3;
945 break;
946 case 0x04:
947 printk("Mitsumi");
948 dmatype = 0;
949 if(cddma == -1) cddma = 5;
950 break;
951 case 0x06:
952 printk("Panasonic Lasermate");
953 dmatype = 1;
954 if(cddma == -1) cddma = 3;
955 break;
956 case 0x08:
957 printk("Secondary IDE");
958 dmatype = 0;
959 if(cddma == -1) cddma = 5;
960 break;
961 case 0x0A:
962 printk("Primary IDE");
963 dmatype = 0;
964 if(cddma == -1) cddma = 5;
965 break;
966 default:
967 printk("\n");
968 printk(KERN_ERR "Invalid CDROM type\n");
969 return -EINVAL;
970 }
971
972 /*
973 * Build the config words
974 */
975
976 mad16_conf = (joystick ^ 1) | cdtype;
977 mad16_cdsel = 0;
978 if (opl4)
979 mad16_cdsel |= 0x20;
980
981 if(cdtype){
982 if (cddma > 7 || cddma < 0 || dma_map[dmatype][cddma] == -1)
983 {
984 printk("\n");
985 printk(KERN_ERR "Invalid CDROM DMA\n");
986 return -EINVAL;
987 }
988 if (cddma)
989 printk(", DMA %d", cddma);
990 else
991 printk(", no DMA");
992
993 if (!cdirq)
994 printk(", no IRQ");
995 else if (cdirq < 0 || cdirq > 15 || irq_map[cdirq] == -1)
996 {
997 printk(", invalid IRQ (disabling)");
998 cdirq = 0;
999 }
1000 else printk(", IRQ %d", cdirq);
1001
1002 mad16_cdsel |= dma_map[dmatype][cddma];
1003
1004 if (cdtype < 0x08)
1005 {
1006 switch (cdport)
1007 {
1008 case 0x340:
1009 mad16_cdsel |= 0x00;
1010 break;
1011 case 0x330:
1012 mad16_cdsel |= 0x40;
1013 break;
1014 case 0x360:
1015 mad16_cdsel |= 0x80;
1016 break;
1017 case 0x320:
1018 mad16_cdsel |= 0xC0;
1019 break;
1020 default:
1021 printk(KERN_ERR "Unknown CDROM I/O base %d\n", cdport);
1022 return -EINVAL;
1023 }
1024 }
1025 mad16_cdsel |= irq_map[cdirq];
1026 }
1027
1028 printk(".\n");
1029
1030 cfg.io_base = io;
1031 cfg.irq = irq;
1032 cfg.dma = dma;
1033 cfg.dma2 = dma16;
1034
1035 if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
1036 printk(KERN_ERR "I/O, DMA and irq are mandatory\n");
1037 return -EINVAL;
1038 }
1039
1040 if (!request_region(MC0_PORT, 12, "mad16"))
1041 return -EBUSY;
1042
1043 if (!probe_mad16(&cfg)) {
1044 release_region(MC0_PORT, 12);
1045 return -ENODEV;
1046 }
1047
1048 cfg_mpu.io_base = mpu_io;
1049 cfg_mpu.irq = mpu_irq;
1050
1051 found_mpu = probe_mad16_mpu(&cfg_mpu);
1052
1053 if (joystick)
1054 mad16_register_gameport(0x201);
1055
1056 return 0;
1057}
1058
1059static void __exit cleanup_mad16(void)
1060{
1061 if (found_mpu)
1062 unload_mad16_mpu(&cfg_mpu);
1063 if (gameport) {
1064 /* the gameport was initialized so we must free it up */
1065 gameport_unregister_port(gameport);
1066 gameport = NULL;
1067 release_region(0x201, 1);
1068 }
1069 unload_mad16(&cfg);
1070 release_region(MC0_PORT, 12);
1071}
1072
1073module_init(init_mad16);
1074module_exit(cleanup_mad16);
1075
1076#ifndef MODULE
1077static int __init setup_mad16(char *str)
1078{
1079 /* io, irq */
1080 int ints[8];
1081
1082 str = get_options(str, ARRAY_SIZE(ints), ints);
1083
1084 io = ints[1];
1085 irq = ints[2];
1086 dma = ints[3];
1087 dma16 = ints[4];
1088 mpu_io = ints[5];
1089 mpu_irq = ints[6];
1090 joystick = ints[7];
1091
1092 return 1;
1093}
1094
1095__setup("mad16=", setup_mad16);
1096#endif
1097MODULE_LICENSE("GPL");