2 * Copyright (C) by Hannu Savolainen 1993-1997
6 * Initialization code for OPTi MAD16 compatible audio chips. Including
8 * OPTi 82C928 MAD16 (replaced by C929)
10 * OAK OTI-605 Mozart (later version with MPU401 Midi)
11 * OPTi 82C929 MAD16 Pro
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 compatable Midi
21 * port. This port is configured differently to that of the OPTi audio chips.
23 * NOTE! If you want to set CD-ROM address and/or joystick enable, define
24 * MAD16_CONF in local.h as combination of the following bits:
26 * 0x01 - joystick disabled
28 * CD-ROM type selection (select just one):
32 * 0x06 - Panasonic (type "LaserMate", not "Sound Blaster")
33 * 0x08 - Secondary IDE (address 0x170)
34 * 0x0a - Primary IDE (address 0x1F0)
36 * For example Mitsumi with joystick disabled = 0x04|0x01 = 0x05
37 * For example LaserMate (for use with sbpcd) plus joystick = 0x06
40 * This defaults to CD I/O 0x340, no IRQ and DMA3
41 * (DMA5 with Mitsumi or IDE). If you like to change these, define
42 * MAD16_CDSEL with the following bits:
44 * CD-ROM port: 0x00=340, 0x40=330, 0x80=360 or 0xc0=320
45 * OPL4 select: 0x20=OPL4, 0x00=OPL3
46 * CD-ROM irq: 0x00=disabled, 0x04=IRQ5, 0x08=IRQ7, 0x0c=IRQ3, 0x10=IRQ9,
47 * 0x14=IRQ10 and 0x18=IRQ11.
49 * CD-ROM DMA (Sony or Panasonic): 0x00=DMA3, 0x01=DMA2, 0x02=DMA1 or 0x03=disabled
51 * CD-ROM DMA (Mitsumi or IDE): 0x00=DMA5, 0x01=DMA6, 0x02=DMA7 or 0x03=disabled
53 * For use with sbpcd, address 0x340, set MAD16_CDSEL to 0x03 or 0x23.
57 * Alan Cox Clean up, added module selections.
59 * A. Wik Added support for Opti924 PnP.
60 * Improved debugging support. 16-May-1998
61 * Fixed bug. 16-Jun-1998
63 * Torsten Duwe Made Opti924 PnP support non-destructive
66 * Paul Grayson Added support for Midi on later Mozart cards.
68 * Christoph Hellwig Adapted to module_init/module_exit.
71 #include <linux/config.h>
72 #include <linux/init.h>
73 #include <linux/module.h>
75 #include "sound_config.h"
76 #include "soundmodule.h"
82 static int mad16_conf
;
83 static int mad16_cdsel
;
85 static int already_initialized
= 0;
96 * The MAD16 occupies I/O ports 0xf8d to 0xf93 (fixed locations).
97 * All ports are inactive by default. They can be activated by
98 * writing 0xE2 or 0xE3 to the password register. The password is valid
99 * only until the next I/O read or write.
101 * 82C930 uses 0xE4 as the password and indirect addressing to access
102 * the config registers.
105 #define MC0_PORT 0xf8c /* Dummy port */
106 #define MC1_PORT 0xf8d /* SB address, CD-ROM interface type, joystick */
107 #define MC2_PORT 0xf8e /* CD-ROM address, IRQ, DMA, plus OPL4 bit */
108 #define MC3_PORT 0xf8f
109 #define PASSWD_REG 0xf8f
110 #define MC4_PORT 0xf90
111 #define MC5_PORT 0xf91
112 #define MC6_PORT 0xf92
113 #define MC7_PORT 0xf93
114 #define MC8_PORT 0xf94
115 #define MC9_PORT 0xf95
116 #define MC10_PORT 0xf96
117 #define MC11_PORT 0xf97
118 #define MC12_PORT 0xf98
120 static int board_type
= C928
;
122 static int *mad16_osp
;
123 static int c931_detected
; /* minor differences from C930 */
124 static char c924pnp
= 0; /* " " " C924 */
125 static int debug
= 0; /* debugging output */
130 #define DDB(x) {if (debug) x;}
132 static unsigned char mad_read(int port
)
140 switch (board_type
) /* Output password */
144 outb((0xE2), PASSWD_REG
);
148 outb((0xE3), PASSWD_REG
);
152 /* outb(( 0xE4), PASSWD_REG); */
156 /* the c924 has its ports relocated by -128 if
157 PnP is enabled -aw */
159 outb((0xE5), PASSWD_REG
); else
160 outb((0xE5), PASSWD_REG
- 0x80);
164 if (board_type
== C930
)
166 outb((port
- MC0_PORT
), 0xe0e); /* Write to index reg */
167 tmp
= inb(0xe0f); /* Read from data reg */
171 tmp
= inb(port
); else
172 tmp
= inb(port
-0x80);
173 restore_flags(flags
);
178 static void mad_write(int port
, int value
)
185 switch (board_type
) /* Output password */
189 outb((0xE2), PASSWD_REG
);
193 outb((0xE3), PASSWD_REG
);
197 /* outb(( 0xE4), PASSWD_REG); */
202 outb((0xE5), PASSWD_REG
); else
203 outb((0xE5), PASSWD_REG
- 0x80);
207 if (board_type
== C930
)
209 outb((port
- MC0_PORT
), 0xe0e); /* Write to index reg */
210 outb(((unsigned char) (value
& 0xff)), 0xe0f);
214 outb(((unsigned char) (value
& 0xff)), port
); else
215 outb(((unsigned char) (value
& 0xff)), port
-0x80);
216 restore_flags(flags
);
219 static int __init
detect_c930(void)
221 unsigned char tmp
= mad_read(MC1_PORT
);
223 if ((tmp
& 0x06) != 0x06)
225 DDB(printk("Wrong C930 signature (%x)\n", tmp
));
228 mad_write(MC1_PORT
, 0);
230 if (mad_read(MC1_PORT
) != 0x06)
232 DDB(printk("Wrong C930 signature2 (%x)\n", tmp
));
235 mad_write(MC1_PORT
, tmp
); /* Restore bits */
237 mad_write(MC7_PORT
, 0);
238 if ((tmp
= mad_read(MC7_PORT
)) != 0)
240 DDB(printk("MC7 not writable (%x)\n", tmp
));
243 mad_write(MC7_PORT
, 0xcb);
244 if ((tmp
= mad_read(MC7_PORT
)) != 0xcb)
246 DDB(printk("MC7 not writable2 (%x)\n", tmp
));
250 tmp
= mad_read(MC0_PORT
+18);
251 if (tmp
== 0xff || tmp
== 0x00)
253 /* We probably have a C931 */
254 DDB(printk("Detected C931 config=0x%02x\n", tmp
));
258 * We cannot configure the chip if it is in PnP mode.
259 * If we have a CSN assigned (bit 8 in MC13) we first try
260 * a software reset, then a software power off, finally
261 * Clearing PnP mode. The last option is not
264 if ((mad_read(MC0_PORT
+13) & 0x80) == 0)
268 mad_write(MC9_PORT
, 0x02);
269 mad_write(MC9_PORT
, 0x00);
271 if ((mad_read(MC0_PORT
+13) & 0x80) == 0)
274 /* Power off, and on again */
275 mad_write(MC9_PORT
, 0xc2);
276 mad_write(MC9_PORT
, 0xc0);
278 if ((mad_read(MC0_PORT
+13) & 0x80) == 0)
282 /* Force off PnP mode. This is not recommended because
283 * the PnP bios will not recognize the chip on the next
284 * warm boot and may assignd different resources to other
287 mad_write(MC0_PORT
+17, 0x04);
292 static int __init
detect_mad16(void)
294 unsigned char tmp
, tmp2
, bit
;
298 * Check that reading a register doesn't return bus float (0xff)
299 * when the card is accessed using password. This may fail in case
300 * the card is in low power mode. Normally at least the power saving
301 * mode bit should be 0.
304 if ((tmp
= mad_read(MC1_PORT
)) == 0xff)
306 DDB(printk("MC1_PORT returned 0xff\n"));
309 for (i
= 0xf8d; i
<= 0xf98; i
++)
311 DDB(printk("Port %0x (init value) = %0x\n", i
, mad_read(i
))) else
312 DDB(printk("Port %0x (init value) = %0x\n", i
-0x80, mad_read(i
)));
314 if (board_type
== C930
)
315 return detect_c930();
318 * Now check that the gate is closed on first I/O after writing
319 * the password. (This is how a MAD16 compatible card works).
322 if ((tmp2
= inb(MC1_PORT
)) == tmp
) /* It didn't close */
324 DDB(printk("MC1_PORT didn't close after read (0x%02x)\n", tmp2
));
328 bit
= (c924pnp
) ? 0x20 : 0x80;
329 port
= (c924pnp
) ? MC2_PORT
: MC1_PORT
;
331 tmp
= mad_read(port
);
332 mad_write(port
, tmp
^ bit
); /* Toggle a bit */
333 if ((tmp2
= mad_read(port
)) != (tmp
^ bit
)) /* Compare the bit */
335 mad_write(port
, tmp
); /* Restore */
336 DDB(printk("Bit revert test failed (0x%02x, 0x%02x)\n", tmp
, tmp2
));
339 mad_write(port
, tmp
); /* Restore */
340 return 1; /* Bingo */
343 static int __init
wss_init(struct address_info
*hw_config
)
348 * Verify the WSS parameters
351 if (check_region(hw_config
->io_base
, 8))
353 printk(KERN_ERR
"MSS: I/O port conflict\n");
356 if (!ad1848_detect(hw_config
->io_base
+ 4, &ad_flags
, mad16_osp
))
359 * Check if the IO port returns valid signature. The original MS Sound
360 * system returns 0x04 while some cards (AudioTrix Pro for example)
364 if ((inb(hw_config
->io_base
+ 3) & 0x3f) != 0x04 &&
365 (inb(hw_config
->io_base
+ 3) & 0x3f) != 0x00)
367 DDB(printk("No MSS signature detected on port 0x%x (0x%x)\n", hw_config
->io_base
, inb(hw_config
->io_base
+ 3)));
370 if (hw_config
->irq
> 11)
372 printk(KERN_ERR
"MSS: Bad IRQ %d\n", hw_config
->irq
);
375 if (hw_config
->dma
!= 0 && hw_config
->dma
!= 1 && hw_config
->dma
!= 3)
377 printk(KERN_ERR
"MSS: Bad DMA %d\n", hw_config
->dma
);
381 * Check that DMA0 is not in use with a 8 bit board.
384 if (hw_config
->dma
== 0 && inb(hw_config
->io_base
+ 3) & 0x80)
386 printk("MSS: Can't use DMA0 with a 8 bit card/slot\n");
389 if (hw_config
->irq
> 7 && hw_config
->irq
!= 9 && inb(hw_config
->io_base
+ 3) & 0x80)
390 printk(KERN_ERR
"MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config
->irq
);
394 static int __init
init_c930(struct address_info
*hw_config
)
396 unsigned char cfg
= 0;
399 cfg
|= (0x0f & MAD16_CONF
);
404 /* Bit 0 has reversd meaning. Bits 1 and 2 sese
406 Support only IDE cdrom. IDE port programmed
408 cfg
= (cfg
& 0x09) ^ 0x07;
411 switch (hw_config
->io_base
)
426 printk(KERN_ERR
"MAD16: Invalid codec port %x\n", hw_config
->io_base
);
429 mad_write(MC1_PORT
, cfg
);
431 /* MC2 is CD configuration. Don't touch it. */
433 mad_write(MC3_PORT
, 0); /* Disable SB mode IRQ and DMA */
435 /* bit 2 of MC4 reverses it's meaning between the C930
437 cfg
= c931_detected
? 0x04 : 0x00;
439 if(MAD16_CDSEL
& 0x20)
440 mad_write(MC4_PORT
, 0x62|cfg
); /* opl4 */
442 mad_write(MC4_PORT
, 0x52|cfg
); /* opl3 */
444 mad_write(MC4_PORT
, 0x52|cfg
);
446 mad_write(MC5_PORT
, 0x3C); /* Init it into mode2 */
447 mad_write(MC6_PORT
, 0x02); /* Enable WSS, Disable MPU and SB */
448 mad_write(MC7_PORT
, 0xCB);
449 mad_write(MC10_PORT
, 0x11);
451 return wss_init(hw_config
);
454 static int __init
chip_detect(void)
459 * Then try to detect with the old password
463 DDB(printk("Detect using password = 0xE5\n"));
465 if (!detect_mad16()) /* No luck. Try different model */
469 DDB(printk("Detect using password = 0xE2\n"));
475 DDB(printk("Detect using password = 0xE3\n"));
479 if (inb(PASSWD_REG
) != 0xff)
483 * First relocate MC# registers to 0xe0e/0xe0f, disable password
486 outb((0xE4), PASSWD_REG
);
487 outb((0x80), PASSWD_REG
);
491 DDB(printk("Detect using password = 0xE4\n"));
493 for (i
= 0xf8d; i
<= 0xf93; i
++)
494 DDB(printk("port %03x = %02x\n", i
, mad_read(i
)));
495 if(!detect_mad16()) {
497 /* The C931 has the password reg at F8D */
500 DDB(printk("Detect using password = 0xE4 for C931\n"));
502 if (!detect_mad16()) {
505 DDB(printk("Detect using password = 0xE5 (again), port offset -0x80\n"));
506 if (!detect_mad16()) {
511 DDB(printk("mad16.c: 82C924 PnP detected\n"));
515 DDB(printk("mad16.c: 82C930 detected\n"));
517 DDB(printk("mad16.c: 82C929 detected\n"));
521 if (((model
= mad_read(MC3_PORT
)) & 0x03) == 0x03) {
522 DDB(printk("mad16.c: Mozart detected\n"));
525 DDB(printk("mad16.c: 82C928 detected???\n"));
533 static int __init
probe_mad16(struct address_info
*hw_config
)
536 static int valid_ports
[] =
538 0x530, 0xe80, 0xf40, 0x604
541 unsigned char cs4231_mode
= 0;
545 if (already_initialized
)
548 mad16_osp
= hw_config
->osp
;
551 * Check that all ports return 0xff (bus float) when no password
552 * is written to the password register.
555 DDB(printk("--- Detecting MAD16 / Mozart ---\n"));
559 if (board_type
== C930
)
560 return init_c930(hw_config
);
563 for (i
= 0xf8d; i
<= 0xf93; i
++)
565 DDB(printk("port %03x = %02x\n", i
, mad_read(i
))) else
566 DDB(printk("port %03x = %02x\n", i
-0x80, mad_read(i
)));
569 * Set the WSS address
572 tmp
= (mad_read(MC1_PORT
) & 0x0f) | 0x80; /* Enable WSS, Disable SB */
574 for (i
= 0; i
< 5; i
++)
576 if (i
> 3) /* Not a valid port */
578 printk(KERN_ERR
"MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config
->io_base
);
581 if (valid_ports
[i
] == hw_config
->io_base
)
583 tmp
|= i
<< 4; /* WSS port select bits */
589 * Set optional CD-ROM and joystick settings.
593 #if defined(MAD16_CONF)
594 tmp
|= ((MAD16_CONF
) & 0x0f); /* CD-ROM and joystick bits */
596 mad_write(MC1_PORT
, tmp
);
598 #if defined(MAD16_CONF) && defined(MAD16_CDSEL)
601 tmp
= mad_read(MC2_PORT
);
605 tmp
|= 0x20; /* Enable OPL4 access */
608 mad_write(MC2_PORT
, tmp
);
609 mad_write(MC3_PORT
, 0xf0); /* Disable SB */
611 if (board_type
== C924
) /* Specific C924 init values */
613 mad_write(MC4_PORT
, 0xA0);
614 mad_write(MC5_PORT
, 0x05);
615 mad_write(MC6_PORT
, 0x03);
617 if (!ad1848_detect(hw_config
->io_base
+ 4, &ad_flags
, mad16_osp
))
620 if (ad_flags
& (AD_F_CS4231
| AD_F_CS4248
))
621 cs4231_mode
= 0x02; /* CS4248/CS4231 sync delay switch */
623 if (board_type
== C929
)
625 mad_write(MC4_PORT
, 0xa2);
626 mad_write(MC5_PORT
, 0xA5 | cs4231_mode
);
627 mad_write(MC6_PORT
, 0x03); /* Disable MPU401 */
631 mad_write(MC4_PORT
, 0x02);
632 mad_write(MC5_PORT
, 0x30 | cs4231_mode
);
635 for (i
= 0xf8d; i
<= 0xf93; i
++) if (!c924pnp
)
636 DDB(printk("port %03x after init = %02x\n", i
, mad_read(i
))) else
637 DDB(printk("port %03x after init = %02x\n", i
-0x80, mad_read(i
)));
643 static void __init
attach_mad16(struct address_info
*hw_config
)
646 static signed char interrupt_bits
[12] = {
647 -1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20
651 static char dma_bits
[4] = {
655 int config_port
= hw_config
->io_base
+ 0, version_port
= hw_config
->io_base
+ 3;
656 int ad_flags
= 0, dma
= hw_config
->dma
, dma2
= hw_config
->dma2
;
657 unsigned char dma2_bit
= 0;
659 already_initialized
= 1;
661 if (!ad1848_detect(hw_config
->io_base
+ 4, &ad_flags
, mad16_osp
))
665 * Set the IRQ and DMA addresses.
668 if (board_type
== C930
|| c924pnp
)
669 interrupt_bits
[5] = 0x28; /* Also IRQ5 is possible on C930 */
671 bits
= interrupt_bits
[hw_config
->irq
];
675 outb((bits
| 0x40), config_port
);
676 if ((inb(version_port
) & 0x40) == 0)
677 printk(KERN_ERR
"[IRQ Conflict?]\n");
680 * Handle the capture DMA channel
683 if (ad_flags
& AD_F_CS4231
&& dma2
!= -1 && dma2
!= dma
)
685 if (!((dma
== 0 && dma2
== 1) ||
686 (dma
== 1 && dma2
== 0) ||
687 (dma
== 3 && dma2
== 0)))
688 { /* Unsupported combination. Try to swap channels */
694 if ((dma
== 0 && dma2
== 1) || (dma
== 1 && dma2
== 0) ||
695 (dma
== 3 && dma2
== 0))
697 dma2_bit
= 0x04; /* Enable capture DMA */
701 printk("MAD16: Invalid capture DMA\n");
707 outb((bits
| dma_bits
[dma
] | dma2_bit
), config_port
); /* Write IRQ+DMA setup */
709 hw_config
->slots
[0] = ad1848_init("MAD16 WSS", hw_config
->io_base
+ 4,
714 request_region(hw_config
->io_base
, 4, "MAD16 WSS config");
717 static void __init
attach_mad16_mpu(struct address_info
*hw_config
)
719 #ifdef CONFIG_MAD16_OLDCARD
721 if (mad_read(MC1_PORT
) & 0x20)
722 hw_config
->io_base
= 0x240;
724 hw_config
->io_base
= 0x220;
726 hw_config
->name
= "Mad16/Mozart";
727 sb_dsp_init(hw_config
);
731 if (!already_initialized
)
734 hw_config
->driver_use_1
= SB_MIDI_ONLY
;
735 hw_config
->name
= "Mad16/Mozart";
736 attach_uart401(hw_config
);
739 static int __init
probe_mad16_mpu(struct address_info
*hw_config
)
741 static int mpu_attached
= 0;
742 static int valid_ports
[] = {
743 0x330, 0x320, 0x310, 0x300
746 static short valid_irqs
[] = {9, 10, 5, 7};
748 int i
; /* A variable with secret power */
750 if (!already_initialized
) /* The MSS port must be initialized first */
753 if (mpu_attached
) /* Don't let them call this twice */
757 if (board_type
< C929
) /* Early chip. No MPU support. Just SB MIDI */
760 #ifdef CONFIG_MAD16_OLDCARD
763 tmp
= mad_read(MC3_PORT
);
766 * MAD16 SB base is defined by the WSS base. It cannot be changed
768 * Ignore configured I/O base. Use the active setting.
771 if (mad_read(MC1_PORT
) & 0x20)
772 hw_config
->io_base
= 0x240;
774 hw_config
->io_base
= 0x220;
776 switch (hw_config
->irq
)
779 tmp
= (tmp
& 0x3f) | 0x80;
785 tmp
= (tmp
& 0x3f) | 0x40;
788 printk(KERN_ERR
"mad16/Mozart: Invalid MIDI IRQ\n");
792 mad_write(MC3_PORT
, tmp
| 0x04);
793 hw_config
->driver_use_1
= SB_MIDI_ONLY
;
794 return sb_dsp_detect(hw_config
, 0, 0, NULL
);
796 /* assuming all later Mozart cards are identified as
797 * either 82C928 or Mozart. If so, following code attempts
798 * to set MPU register. TODO - add probing
804 tmp
= mad_read(MC8_PORT
);
806 switch (hw_config
->irq
)
824 printk(KERN_ERR
"mad16/MOZART: invalid mpu_irq\n");
828 switch (hw_config
->io_base
)
843 printk(KERN_ERR
"mad16/MOZART: invalid mpu_io\n");
847 mad_write(MC8_PORT
, tmp
); /* write MPU port parameters */
849 return probe_uart401(hw_config
);
852 tmp
= mad_read(MC6_PORT
) & 0x83;
853 tmp
|= 0x80; /* MPU-401 enable */
856 * Set the MPU base bits
859 for (i
= 0; i
< 5; i
++)
861 if (i
> 3) /* Out of array bounds */
863 printk(KERN_ERR
"MAD16 / Mozart: Invalid MIDI port 0x%x\n", hw_config
->io_base
);
866 if (valid_ports
[i
] == hw_config
->io_base
)
874 * Set the MPU IRQ bits
877 for (i
= 0; i
< 5; i
++)
879 if (i
> 3) /* Out of array bounds */
881 printk(KERN_ERR
"MAD16 / Mozart: Invalid MIDI IRQ %d\n", hw_config
->irq
);
884 if (valid_irqs
[i
] == hw_config
->irq
)
890 mad_write(MC6_PORT
, tmp
); /* Write MPU401 config */
892 return probe_uart401(hw_config
);
895 static void __exit
unload_mad16(struct address_info
*hw_config
)
897 ad1848_unload(hw_config
->io_base
+ 4,
901 release_region(hw_config
->io_base
, 4);
902 sound_unload_audiodev(hw_config
->slots
[0]);
905 static void __exit
unload_mad16_mpu(struct address_info
*hw_config
)
907 #ifdef CONFIG_MAD16_OLDCARD
908 if (board_type
< C929
) /* Early chip. No MPU support. Just SB MIDI */
910 sb_dsp_unload(hw_config
, 0);
915 unload_uart401(hw_config
);
918 static struct address_info cfg
;
919 static struct address_info cfg_mpu
;
921 static int found_mpu
;
923 static int __initdata mpu_io
= 0;
924 static int __initdata mpu_irq
= 0;
925 static int __initdata io
= -1;
926 static int __initdata dma
= -1;
927 static int __initdata dma16
= -1; /* Set this for modules that need it */
928 static int __initdata irq
= -1;
929 static int __initdata cdtype
= 0;
930 static int __initdata cdirq
= 0;
931 static int __initdata cdport
= 0x340;
932 static int __initdata cddma
= -1;
933 static int __initdata opl4
= 0;
934 static int __initdata joystick
= 0;
936 MODULE_PARM(mpu_io
, "i");
937 MODULE_PARM(mpu_irq
, "i");
939 MODULE_PARM(dma
,"i");
940 MODULE_PARM(dma16
,"i");
941 MODULE_PARM(irq
,"i");
942 MODULE_PARM(cdtype
,"i");
943 MODULE_PARM(cdirq
,"i");
944 MODULE_PARM(cdport
,"i");
945 MODULE_PARM(cddma
,"i");
946 MODULE_PARM(opl4
,"i");
947 MODULE_PARM(joystick
,"i");
948 MODULE_PARM(debug
,"i");
950 static int __initdata dma_map
[2][8] =
952 {0x03, -1, -1, -1, -1, 0x00, 0x01, 0x02},
953 {0x03, -1, 0x01, 0x00, -1, -1, -1, -1}
956 static int __initdata irq_map
[16] =
960 -1, 0x10, 0x14, 0x18,
964 static int __init
init_mad16(void)
968 printk(KERN_INFO
"MAD16 audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
970 printk(KERN_INFO
"CDROM ");
978 printk("Sony CDU31A");
980 if(cddma
== -1) cddma
= 3;
985 if(cddma
== -1) cddma
= 5;
988 printk("Panasonic Lasermate");
990 if(cddma
== -1) cddma
= 3;
993 printk("Secondary IDE");
995 if(cddma
== -1) cddma
= 5;
998 printk("Primary IDE");
1000 if(cddma
== -1) cddma
= 5;
1004 printk(KERN_ERR
"Invalid CDROM type\n");
1009 * Build the config words
1012 mad16_conf
= (joystick
^ 1) | cdtype
;
1015 mad16_cdsel
|= 0x20;
1018 if (cddma
> 7 || cddma
< 0 || dma_map
[dmatype
][cddma
] == -1)
1021 printk(KERN_ERR
"Invalid CDROM DMA\n");
1025 printk(", DMA %d", cddma
);
1031 else if (cdirq
< 0 || cdirq
> 15 || irq_map
[cdirq
] == -1)
1033 printk(", invalid IRQ (disabling)");
1036 else printk(", IRQ %d", cdirq
);
1038 mad16_cdsel
|= dma_map
[dmatype
][cddma
];
1045 mad16_cdsel
|= 0x00;
1048 mad16_cdsel
|= 0x40;
1051 mad16_cdsel
|= 0x80;
1054 mad16_cdsel
|= 0xC0;
1057 printk(KERN_ERR
"Unknown CDROM I/O base %d\n", cdport
);
1061 mad16_cdsel
|= irq_map
[cdirq
];
1065 printk(KERN_INFO
"Joystick port ");
1067 printk("enabled.\n");
1071 printk("disabled.\n");
1079 if (cfg
.io_base
== -1 || cfg
.dma
== -1 || cfg
.irq
== -1) {
1080 printk(KERN_ERR
"I/O, DMA and irq are mandatory\n");
1084 if (!probe_mad16(&cfg
))
1087 cfg_mpu
.io_base
= mpu_io
;
1088 cfg_mpu
.irq
= mpu_irq
;
1092 found_mpu
= probe_mad16_mpu(&cfg_mpu
);
1095 attach_mad16_mpu(&cfg_mpu
);
1101 static void __exit
cleanup_mad16(void)
1104 unload_mad16_mpu(&cfg_mpu
);
1109 module_init(init_mad16
);
1110 module_exit(cleanup_mad16
);
1113 static int __init
setup_mad16(char *str
)
1118 str
= get_options(str
, ARRAY_SIZE(ints
), ints
);
1130 __setup("mad16=", setup_mad16
);