patch-2.1.67 linux/drivers/sound/mad16.c
Next file: linux/drivers/sound/maui.c
Previous file: linux/drivers/sound/lowlevel/awe_wave.c
Back to the patch index
Back to the overall index
- Lines: 1391
- Date:
Sat Nov 29 10:33:20 1997
- Orig file:
v2.1.66/linux/drivers/sound/mad16.c
- Orig date:
Wed Nov 12 13:34:27 1997
diff -u --recursive --new-file v2.1.66/linux/drivers/sound/mad16.c linux/drivers/sound/mad16.c
@@ -6,7 +6,7 @@
* for more info.
*/
#include <linux/config.h>
-
+#include <linux/module.h>
/*
* sound/mad16.c
*
@@ -59,8 +59,18 @@
*/
#include "sound_config.h"
+#include "soundmodule.h"
+
+#ifdef MODULE
+#define MAD16_CDSEL mad16_cdsel
+#define MAD16_CONF mad16_conf
+
+static int mad16_conf;
+static int mad16_cdsel;
+
+#endif
-#ifdef CONFIG_MAD16
+#if defined(CONFIG_MAD16) || defined(MODULE)
#include "sb.h"
@@ -108,127 +118,121 @@
#endif
static unsigned char
-mad_read (int port)
+mad_read(int port)
{
- unsigned long flags;
- unsigned char tmp;
+ unsigned long flags;
+ unsigned char tmp;
- save_flags (flags);
- cli ();
+ save_flags(flags);
+ cli();
- switch (board_type) /* Output password */
- {
- case C928:
- case MOZART:
- outb ((0xE2), PASSWD_REG);
- break;
-
- case C929:
- outb ((0xE3), PASSWD_REG);
- break;
-
- case C930:
- /* outb(( 0xE4), PASSWD_REG); */
- break;
-
- case C924:
- outb ((0xE5), PASSWD_REG);
- break;
- }
-
- if (board_type == C930)
- {
- outb ((port - MC0_PORT), 0xe0e); /* Write to index reg */
- tmp = inb (0xe0f); /* Read from data reg */
- }
- else
- tmp = inb (port);
- restore_flags (flags);
+ switch (board_type) /* Output password */
+ {
+ case C928:
+ case MOZART:
+ outb((0xE2), PASSWD_REG);
+ break;
+
+ case C929:
+ outb((0xE3), PASSWD_REG);
+ break;
+
+ case C930:
+ /* outb(( 0xE4), PASSWD_REG); */
+ break;
+
+ case C924:
+ outb((0xE5), PASSWD_REG);
+ break;
+ }
+
+ if (board_type == C930)
+ {
+ outb((port - MC0_PORT), 0xe0e); /* Write to index reg */
+ tmp = inb(0xe0f); /* Read from data reg */
+ } else
+ tmp = inb(port);
+ restore_flags(flags);
- return tmp;
+ return tmp;
}
static void
-mad_write (int port, int value)
+mad_write(int port, int value)
{
- unsigned long flags;
+ unsigned long flags;
- save_flags (flags);
- cli ();
+ save_flags(flags);
+ cli();
- switch (board_type) /* Output password */
- {
- case C928:
- case MOZART:
- outb ((0xE2), PASSWD_REG);
- break;
-
- case C929:
- outb ((0xE3), PASSWD_REG);
- break;
-
- case C930:
- /* outb(( 0xE4), PASSWD_REG); */
- break;
-
- case C924:
- outb ((0xE5), PASSWD_REG);
- break;
- }
-
- if (board_type == C930)
- {
- outb ((port - MC0_PORT), 0xe0e); /* Write to index reg */
- outb (((unsigned char) (value & 0xff)), 0xe0f);
- }
- else
- outb (((unsigned char) (value & 0xff)), port);
- restore_flags (flags);
+ switch (board_type) /* Output password */
+ {
+ case C928:
+ case MOZART:
+ outb((0xE2), PASSWD_REG);
+ break;
+
+ case C929:
+ outb((0xE3), PASSWD_REG);
+ break;
+
+ case C930:
+ /* outb(( 0xE4), PASSWD_REG); */
+ break;
+
+ case C924:
+ outb((0xE5), PASSWD_REG);
+ break;
+ }
+
+ if (board_type == C930)
+ {
+ outb((port - MC0_PORT), 0xe0e); /* Write to index reg */
+ outb(((unsigned char) (value & 0xff)), 0xe0f);
+ } else
+ outb(((unsigned char) (value & 0xff)), port);
+ restore_flags(flags);
}
static int
-detect_c930 (void)
+detect_c930(void)
{
- unsigned char tmp = mad_read (MC1_PORT);
+ unsigned char tmp = mad_read(MC1_PORT);
- if ((tmp & 0x06) != 0x06)
- {
- DDB (printk ("Wrong C930 signature (%x)\n", tmp));
- /* return 0; */
- }
-
- mad_write (MC1_PORT, 0);
-
- if (mad_read (MC1_PORT) != 0x06)
- {
- DDB (printk ("Wrong C930 signature2 (%x)\n", tmp));
- /* return 0; */
- }
-
- mad_write (MC1_PORT, tmp); /* Restore bits */
-
- mad_write (MC7_PORT, 0);
- if ((tmp = mad_read (MC7_PORT)) != 0)
- {
- DDB (printk ("MC7 not writable (%x)\n", tmp));
- return 0;
- }
-
- mad_write (MC7_PORT, 0xcb);
- if ((tmp = mad_read (MC7_PORT)) != 0xcb)
- {
- DDB (printk ("MC7 not writable2 (%x)\n", tmp));
- return 0;
- }
-
- return 1;
+ if ((tmp & 0x06) != 0x06)
+ {
+ DDB(printk("Wrong C930 signature (%x)\n", tmp));
+ /* return 0; */
+ }
+ mad_write(MC1_PORT, 0);
+
+ if (mad_read(MC1_PORT) != 0x06)
+ {
+ DDB(printk("Wrong C930 signature2 (%x)\n", tmp));
+ /* return 0; */
+ }
+ mad_write(MC1_PORT, tmp); /* Restore bits */
+
+ mad_write(MC7_PORT, 0);
+ if ((tmp = mad_read(MC7_PORT)) != 0)
+ {
+ DDB(printk("MC7 not writable (%x)\n", tmp));
+ return 0;
+ }
+ mad_write(MC7_PORT, 0xcb);
+ if ((tmp = mad_read(MC7_PORT)) != 0xcb)
+ {
+ DDB(printk("MC7 not writable2 (%x)\n", tmp));
+ return 0;
+ }
+ return 1;
}
static int
-detect_mad16 (void)
+detect_mad16(void)
{
- unsigned char tmp, tmp2;
- int i;
+ unsigned char tmp, tmp2;
+ int i;
/*
* Check that reading a register doesn't return bus float (0xff)
@@ -236,568 +240,715 @@
* the card is in low power mode. Normally at least the power saving mode
* bit should be 0.
*/
- if ((tmp = mad_read (MC1_PORT)) == 0xff)
- {
- DDB (printk ("MC1_PORT returned 0xff\n"));
- return 0;
- }
-
- for (i = 0xf8d; i <= 0xf98; i++)
- DDB (printk ("Port %0x (init value) = %0x\n", i, mad_read (i)));
+ if ((tmp = mad_read(MC1_PORT)) == 0xff)
+ {
+ DDB(printk("MC1_PORT returned 0xff\n"));
+ return 0;
+ }
+ for (i = 0xf8d; i <= 0xf98; i++)
+ DDB(printk("Port %0x (init value) = %0x\n", i, mad_read(i)));
- if (board_type == C930)
- return detect_c930 ();
+ if (board_type == C930)
+ return detect_c930();
/*
* Now check that the gate is closed on first I/O after writing
* the password. (This is how a MAD16 compatible card works).
*/
- if ((tmp2 = inb (MC1_PORT)) == tmp) /* It didn't close */
- {
- DDB (printk ("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
- return 0;
- }
-
- mad_write (MC1_PORT, tmp ^ 0x80); /* Toggle a bit */
- if ((tmp2 = mad_read (MC1_PORT)) != (tmp ^ 0x80)) /* Compare the bit */
- {
- mad_write (MC1_PORT, tmp); /* Restore */
- DDB (printk ("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
- return 0;
- }
-
- mad_write (MC1_PORT, tmp); /* Restore */
- return 1; /* Bingo */
+ if ((tmp2 = inb(MC1_PORT)) == tmp) /* It didn't close */
+ {
+ DDB(printk("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
+ return 0;
+ }
+ mad_write(MC1_PORT, tmp ^ 0x80); /* Toggle a bit */
+ if ((tmp2 = mad_read(MC1_PORT)) != (tmp ^ 0x80)) /* Compare the bit */
+ {
+ mad_write(MC1_PORT, tmp); /* Restore */
+ DDB(printk("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
+ return 0;
+ }
+ mad_write(MC1_PORT, tmp); /* Restore */
+ return 1; /* Bingo */
}
static int
-wss_init (struct address_info *hw_config)
+wss_init(struct address_info *hw_config)
{
- int ad_flags = 0;
+ int ad_flags = 0;
/*
* Verify the WSS parameters
*/
- if (check_region (hw_config->io_base, 8))
- {
- printk ("MSS: I/O port conflict\n");
- return 0;
- }
-
- if (!ad1848_detect (hw_config->io_base + 4, &ad_flags, mad16_osp))
- return 0;
- /*
- * Check if the IO port returns valid signature. The original MS Sound
- * system returns 0x04 while some cards (AudioTrix Pro for example)
- * return 0x00.
- */
-
- if ((inb (hw_config->io_base + 3) & 0x3f) != 0x04 &&
- (inb (hw_config->io_base + 3) & 0x3f) != 0x00)
- {
- DDB (printk ("No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, inb (hw_config->io_base + 3)));
- return 0;
- }
-
- if (hw_config->irq > 11)
- {
- printk ("MSS: Bad IRQ %d\n", hw_config->irq);
- return 0;
- }
-
- if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
- {
- printk ("MSS: Bad DMA %d\n", hw_config->dma);
- return 0;
- }
-
- /*
- * Check that DMA0 is not in use with a 8 bit board.
- */
-
- if (hw_config->dma == 0 && inb (hw_config->io_base + 3) & 0x80)
- {
- printk ("MSS: Can't use DMA0 with a 8 bit card/slot\n");
- return 0;
- }
-
- if (hw_config->irq > 7 && hw_config->irq != 9 && inb (hw_config->io_base + 3) & 0x80)
- {
- printk ("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
- }
-
- return 1;
+ if (check_region(hw_config->io_base, 8))
+ {
+ printk("MSS: I/O port conflict\n");
+ return 0;
+ }
+ if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp))
+ return 0;
+ /*
+ * Check if the IO port returns valid signature. The original MS Sound
+ * system returns 0x04 while some cards (AudioTrix Pro for example)
+ * return 0x00.
+ */
+
+ if ((inb(hw_config->io_base + 3) & 0x3f) != 0x04 &&
+ (inb(hw_config->io_base + 3) & 0x3f) != 0x00)
+ {
+ DDB(printk("No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, inb(hw_config->io_base + 3)));
+ return 0;
+ }
+ if (hw_config->irq > 11)
+ {
+ printk("MSS: Bad IRQ %d\n", hw_config->irq);
+ return 0;
+ }
+ if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
+ {
+ printk("MSS: Bad DMA %d\n", hw_config->dma);
+ return 0;
+ }
+ /*
+ * Check that DMA0 is not in use with a 8 bit board.
+ */
+
+ if (hw_config->dma == 0 && inb(hw_config->io_base + 3) & 0x80)
+ {
+ printk("MSS: Can't use DMA0 with a 8 bit card/slot\n");
+ return 0;
+ }
+ if (hw_config->irq > 7 && hw_config->irq != 9 && inb(hw_config->io_base + 3) & 0x80)
+ {
+ printk("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
+ }
+ return 1;
}
static int
-init_c930 (struct address_info *hw_config)
+init_c930(struct address_info *hw_config)
{
- unsigned char cfg;
+ unsigned char cfg;
- cfg = (mad_read (MC1_PORT) & ~0x30);
- /* mad_write(MC1_PORT, 0); */
+ cfg = (mad_read(MC1_PORT) & ~0x30);
+ /* mad_write(MC1_PORT, 0); */
- switch (hw_config->io_base)
- {
- case 0x530:
- cfg |= 0x00;
- break;
- case 0xe80:
- cfg |= 0x10;
- break;
- case 0xf40:
- cfg |= 0x20;
- break;
- case 0x604:
- cfg |= 0x30;
- break;
-
- default:
- printk ("MAD16: Invalid codec port %x\n", hw_config->io_base);
- return 0;
- }
- mad_write (MC1_PORT, cfg);
-
- /* MC2 is CD configuration. Don't touch it. */
-
- mad_write (MC3_PORT, 0); /* Disable SB mode IRQ and DMA */
- mad_write (MC4_PORT, 0x52); /* ??? */
- mad_write (MC5_PORT, 0x3C); /* Init it into mode2 */
- mad_write (MC6_PORT, 0x02); /* Enable WSS, Disable MPU and SB */
- mad_write (MC7_PORT, 0xCB);
- mad_write (MC10_PORT, 0x11);
+ switch (hw_config->io_base)
+ {
+ case 0x530:
+ cfg |= 0x00;
+ break;
+ case 0xe80:
+ cfg |= 0x10;
+ break;
+ case 0xf40:
+ cfg |= 0x20;
+ break;
+ case 0x604:
+ cfg |= 0x30;
+ break;
+
+ default:
+ printk("MAD16: Invalid codec port %x\n", hw_config->io_base);
+ return 0;
+ }
+ mad_write(MC1_PORT, cfg);
+
+ /* MC2 is CD configuration. Don't touch it. */
+
+ mad_write(MC3_PORT, 0); /* Disable SB mode IRQ and DMA */
+ mad_write(MC4_PORT, 0x52); /* ??? */
+ mad_write(MC5_PORT, 0x3C); /* Init it into mode2 */
+ mad_write(MC6_PORT, 0x02); /* Enable WSS, Disable MPU and SB */
+ mad_write(MC7_PORT, 0xCB);
+ mad_write(MC10_PORT, 0x11);
- return wss_init (hw_config);
+ return wss_init(hw_config);
}
static int
-chip_detect (void)
+chip_detect(void)
{
- int i;
+ int i;
/*
* Then try to detect with the old password
*/
- board_type = C924;
+ board_type = C924;
- DDB (printk ("Detect using password = 0xE5\n"));
+ DDB(printk("Detect using password = 0xE5\n"));
- if (!detect_mad16 ()) /* No luck. Try different model */
- {
- board_type = C928;
+ if (!detect_mad16()) /* No luck. Try different model */
+ {
+ board_type = C928;
- DDB (printk ("Detect using password = 0xE2\n"));
+ DDB(printk("Detect using password = 0xE2\n"));
- if (!detect_mad16 ())
- {
- board_type = C929;
+ if (!detect_mad16())
+ {
+ board_type = C929;
- DDB (printk ("Detect using password = 0xE3\n"));
+ DDB(printk("Detect using password = 0xE3\n"));
- if (!detect_mad16 ())
- {
- if (inb (PASSWD_REG) != 0xff)
- return 0;
+ if (!detect_mad16())
+ {
+ if (inb(PASSWD_REG) != 0xff)
+ return 0;
/*
* First relocate MC# registers to 0xe0e/0xe0f, disable password
*/
- outb ((0xE4), PASSWD_REG);
- outb ((0x80), PASSWD_REG);
-
- board_type = C930;
-
- DDB (printk ("Detect using password = 0xE4\n"));
-
- for (i = 0xf8d; i <= 0xf93; i++)
- DDB (printk ("port %03x = %02x\n", i, mad_read (i)));
+ outb((0xE4), PASSWD_REG);
+ outb((0x80), PASSWD_REG);
- if (!detect_mad16 ())
- return 0;
-
- DDB (printk ("mad16.c: 82C930 detected\n"));
- }
- else
- {
- DDB (printk ("mad16.c: 82C929 detected\n"));
- }
- }
- else
- {
- unsigned char model;
+ board_type = C930;
- if (((model = mad_read (MC3_PORT)) & 0x03) == 0x03)
- {
- DDB (printk ("mad16.c: Mozart detected\n"));
- board_type = MOZART;
- }
- else
- {
- DDB (printk ("mad16.c: 82C928 detected???\n"));
- board_type = C928;
- }
- }
- }
+ DDB(printk("Detect using password = 0xE4\n"));
- return 1;
+ for (i = 0xf8d; i <= 0xf93; i++)
+ DDB(printk("port %03x = %02x\n", i, mad_read(i)));
+
+ if (!detect_mad16())
+ return 0;
+
+ DDB(printk("mad16.c: 82C930 detected\n"));
+ } else
+ {
+ DDB(printk("mad16.c: 82C929 detected\n"));
+ }
+ } else
+ {
+ unsigned char model;
+
+ if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03)
+ {
+ DDB(printk("mad16.c: Mozart detected\n"));
+ board_type = MOZART;
+ } else
+ {
+ DDB(printk("mad16.c: 82C928 detected???\n"));
+ board_type = C928;
+ }
+ }
+ }
+ return 1;
}
int
-probe_mad16 (struct address_info *hw_config)
+probe_mad16(struct address_info *hw_config)
{
- int i;
- static int valid_ports[] =
- {0x530, 0xe80, 0xf40, 0x604};
- unsigned char tmp;
- unsigned char cs4231_mode = 0;
+ int i;
+ static int valid_ports[] =
+ {0x530, 0xe80, 0xf40, 0x604};
+ unsigned char tmp;
+ unsigned char cs4231_mode = 0;
- int ad_flags = 0;
+ int ad_flags = 0;
- if (already_initialized)
- return 0;
+ if (already_initialized)
+ return 0;
- mad16_osp = hw_config->osp;
+ mad16_osp = hw_config->osp;
/*
* Check that all ports return 0xff (bus float) when no password
* is written to the password register.
*/
- DDB (printk ("--- Detecting MAD16 / Mozart ---\n"));
- if (!chip_detect ())
- return 0;
+ DDB(printk("--- Detecting MAD16 / Mozart ---\n"));
+ if (!chip_detect())
+ return 0;
- if (board_type == C930)
- return init_c930 (hw_config);
+ if (board_type == C930)
+ return init_c930(hw_config);
- for (i = 0xf8d; i <= 0xf93; i++)
- DDB (printk ("port %03x = %02x\n", i, mad_read (i)));
+ for (i = 0xf8d; i <= 0xf93; i++)
+ DDB(printk("port %03x = %02x\n", i, mad_read(i)));
/*
* Set the WSS address
*/
- tmp = (mad_read (MC1_PORT) & 0x0f) | 0x80; /* Enable WSS, Disable SB */
+ tmp = (mad_read(MC1_PORT) & 0x0f) | 0x80; /* Enable WSS, Disable SB */
- for (i = 0; i < 5; i++)
- {
- if (i > 3) /* Not a valid port */
- {
- printk ("MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
- return 0;
- }
-
- if (valid_ports[i] == hw_config->io_base)
- {
- tmp |= i << 4; /* WSS port select bits */
- break;
- }
- }
+ for (i = 0; i < 5; i++)
+ {
+ if (i > 3) /* Not a valid port */
+ {
+ printk("MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
+ return 0;
+ }
+ if (valid_ports[i] == hw_config->io_base)
+ {
+ tmp |= i << 4; /* WSS port select bits */
+ break;
+ }
+ }
/*
* Set optional CD-ROM and joystick settings.
*/
#ifdef MAD16_CONF
- tmp &= ~0x0f;
- tmp |= ((MAD16_CONF) & 0x0f); /* CD-ROM and joystick bits */
+ tmp &= ~0x0f;
+ tmp |= ((MAD16_CONF) & 0x0f); /* CD-ROM and joystick bits */
#endif
- mad_write (MC1_PORT, tmp);
+ mad_write(MC1_PORT, tmp);
#if defined(MAD16_CONF) && defined(MAD16_CDSEL)
- tmp = MAD16_CDSEL;
+ tmp = MAD16_CDSEL;
#else
- tmp = mad_read (MC2_PORT);
+ tmp = mad_read(MC2_PORT);
#endif
#ifdef MAD16_OPL4
- tmp |= 0x20; /* Enable OPL4 access */
+ tmp |= 0x20; /* Enable OPL4 access */
#endif
- mad_write (MC2_PORT, tmp);
- mad_write (MC3_PORT, 0xf0); /* Disable SB */
+ mad_write(MC2_PORT, tmp);
+ mad_write(MC3_PORT, 0xf0); /* Disable SB */
+
+ if (board_type == C924) /* Specific C924 init values */
+ {
+ mad_write(MC4_PORT, 0xA0);
+ mad_write(MC5_PORT, 0x05);
+ mad_write(MC6_PORT, 0x03);
+ }
+ if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp))
+ return 0;
+
+ if (ad_flags & (AD_F_CS4231 | AD_F_CS4248))
+ cs4231_mode = 0x02; /* CS4248/CS4231 sync delay switch */
- if (board_type == C924) /* Specific C924 init values */
- {
- mad_write (MC4_PORT, 0xA0);
- mad_write (MC5_PORT, 0x05);
- mad_write (MC6_PORT, 0x03);
- }
-
- if (!ad1848_detect (hw_config->io_base + 4, &ad_flags, mad16_osp))
- return 0;
-
- if (ad_flags & (AD_F_CS4231 | AD_F_CS4248))
- cs4231_mode = 0x02; /* CS4248/CS4231 sync delay switch */
-
- if (board_type == C929)
- {
- mad_write (MC4_PORT, 0xa2);
- mad_write (MC5_PORT, 0xA5 | cs4231_mode);
- mad_write (MC6_PORT, 0x03); /* Disable MPU401 */
- }
- else
- {
- mad_write (MC4_PORT, 0x02);
- mad_write (MC5_PORT, 0x30 | cs4231_mode);
- }
+ if (board_type == C929)
+ {
+ mad_write(MC4_PORT, 0xa2);
+ mad_write(MC5_PORT, 0xA5 | cs4231_mode);
+ mad_write(MC6_PORT, 0x03); /* Disable MPU401 */
+ } else
+ {
+ mad_write(MC4_PORT, 0x02);
+ mad_write(MC5_PORT, 0x30 | cs4231_mode);
+ }
- for (i = 0xf8d; i <= 0xf93; i++)
- DDB (printk ("port %03x after init = %02x\n", i, mad_read (i)));
+ for (i = 0xf8d; i <= 0xf93; i++)
+ DDB(printk("port %03x after init = %02x\n", i, mad_read(i)));
- wss_init (hw_config);
+ wss_init(hw_config);
- return 1;
+ return 1;
}
void
-attach_mad16 (struct address_info *hw_config)
+attach_mad16(struct address_info *hw_config)
{
- static char interrupt_bits[12] =
- {
- -1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20
- };
- char bits;
-
- static char dma_bits[4] =
- {
- 1, 2, 0, 3
- };
-
- int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
- int ad_flags = 0, dma = hw_config->dma, dma2 = hw_config->dma2;
- unsigned char dma2_bit = 0;
-
- already_initialized = 1;
-
- if (!ad1848_detect (hw_config->io_base + 4, &ad_flags, mad16_osp))
- return;
-
- /*
- * Set the IRQ and DMA addresses.
- */
- if (board_type == C930)
- interrupt_bits[5] = 0x28; /* Also IRQ5 is possible on C930 */
-
- bits = interrupt_bits[hw_config->irq];
- if (bits == -1)
- return;
-
- outb ((bits | 0x40), config_port);
- if ((inb (version_port) & 0x40) == 0)
- printk ("[IRQ Conflict?]");
+ static char interrupt_bits[12] =
+ {
+ -1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20
+ };
+ char bits;
+
+ static char dma_bits[4] =
+ {
+ 1, 2, 0, 3
+ };
+
+ int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
+ int ad_flags = 0, dma = hw_config->dma, dma2 = hw_config->dma2;
+ unsigned char dma2_bit = 0;
+
+ already_initialized = 1;
+
+ if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp))
+ return;
+
+ /*
+ * Set the IRQ and DMA addresses.
+ */
+ if (board_type == C930)
+ interrupt_bits[5] = 0x28; /* Also IRQ5 is possible on C930 */
+
+ bits = interrupt_bits[hw_config->irq];
+ if (bits == -1)
+ return;
+
+ outb((bits | 0x40), config_port);
+ if ((inb(version_port) & 0x40) == 0)
+ printk("[IRQ Conflict?]");
/*
* Handle the capture DMA channel
*/
- if (ad_flags & AD_F_CS4231 && dma2 != -1 && dma2 != dma)
- {
- if (!((dma == 0 && dma2 == 1) ||
- (dma == 1 && dma2 == 0) ||
- (dma == 3 && dma2 == 0)))
- { /* Unsupported combination. Try to swap channels */
- int tmp = dma;
-
- dma = dma2;
- dma2 = tmp;
- }
-
- if ((dma == 0 && dma2 == 1) ||
- (dma == 1 && dma2 == 0) ||
- (dma == 3 && dma2 == 0))
- {
- dma2_bit = 0x04; /* Enable capture DMA */
- }
- else
- {
- printk ("MAD16: Invalid capture DMA\n");
- dma2 = dma;
- }
- }
- else
- dma2 = dma;
-
- outb ((bits | dma_bits[dma] | dma2_bit), config_port); /* Write IRQ+DMA setup */
-
- ad1848_init ("MAD16 WSS", hw_config->io_base + 4,
- hw_config->irq,
- dma,
- dma2, 0,
- hw_config->osp);
- request_region (hw_config->io_base, 4, "MAD16 WSS config");
+ if (ad_flags & AD_F_CS4231 && dma2 != -1 && dma2 != dma)
+ {
+ if (!((dma == 0 && dma2 == 1) ||
+ (dma == 1 && dma2 == 0) ||
+ (dma == 3 && dma2 == 0)))
+ { /* Unsupported combination. Try to swap channels */
+ int tmp = dma;
+
+ dma = dma2;
+ dma2 = tmp;
+ }
+ if ((dma == 0 && dma2 == 1) ||
+ (dma == 1 && dma2 == 0) ||
+ (dma == 3 && dma2 == 0))
+ {
+ dma2_bit = 0x04; /* Enable capture DMA */
+ } else
+ {
+ printk("MAD16: Invalid capture DMA\n");
+ dma2 = dma;
+ }
+ } else
+ dma2 = dma;
+
+ outb((bits | dma_bits[dma] | dma2_bit), config_port); /* Write IRQ+DMA setup */
+
+ hw_config->slots[0] = ad1848_init("MAD16 WSS", hw_config->io_base + 4,
+ hw_config->irq,
+ dma,
+ dma2, 0,
+ hw_config->osp);
+ request_region(hw_config->io_base, 4, "MAD16 WSS config");
}
void
-attach_mad16_mpu (struct address_info *hw_config)
+attach_mad16_mpu(struct address_info *hw_config)
{
- if (board_type < C929) /* Early chip. No MPU support. Just SB MIDI */
- {
-#ifdef CONFIG_MIDI
-
- if (mad_read (MC1_PORT) & 0x20)
- hw_config->io_base = 0x240;
- else
- hw_config->io_base = 0x220;
+ if (board_type < C929) /* Early chip. No MPU support. Just SB MIDI */
+ {
+#if defined(CONFIG_MIDI)
+
+ if (mad_read(MC1_PORT) & 0x20)
+ hw_config->io_base = 0x240;
+ else
+ hw_config->io_base = 0x220;
- hw_config->name = "Mad16/Mozart";
- sb_dsp_init (hw_config);
+ hw_config->name = "Mad16/Mozart";
+ sb_dsp_init(hw_config);
#endif
- return;
- }
-
+ return;
+ }
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
- if (!already_initialized)
- return;
+ if (!already_initialized)
+ return;
- hw_config->driver_use_1 = SB_MIDI_ONLY;
- hw_config->name = "Mad16/Mozart";
- attach_uart401 (hw_config);
+ hw_config->driver_use_1 = SB_MIDI_ONLY;
+ hw_config->name = "Mad16/Mozart";
+ attach_uart401(hw_config);
#endif
}
int
-probe_mad16_mpu (struct address_info *hw_config)
+probe_mad16_mpu(struct address_info *hw_config)
{
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
- static int mpu_attached = 0;
- static int valid_ports[] =
- {0x330, 0x320, 0x310, 0x300};
- static short valid_irqs[] =
- {9, 10, 5, 7};
- unsigned char tmp;
-
- int i; /* A variable with secret power */
-
- if (!already_initialized) /* The MSS port must be initialized first */
- return 0;
-
- if (mpu_attached) /* Don't let them call this twice */
- return 0;
- mpu_attached = 1;
-
- if (board_type < C929) /* Early chip. No MPU support. Just SB MIDI */
- {
-
-#ifdef CONFIG_MIDI
- unsigned char tmp;
-
- tmp = mad_read (MC3_PORT);
-
- /*
- * MAD16 SB base is defined by the WSS base. It cannot be changed
- * alone.
- * Ignore configured I/O base. Use the active setting.
- */
-
- if (mad_read (MC1_PORT) & 0x20)
- hw_config->io_base = 0x240;
- else
- hw_config->io_base = 0x220;
+ static int mpu_attached = 0;
+ static int valid_ports[] =
+ {0x330, 0x320, 0x310, 0x300};
+ static short valid_irqs[] =
+ {9, 10, 5, 7};
+ unsigned char tmp;
- switch (hw_config->irq)
- {
- case 5:
- tmp = (tmp & 0x3f) | 0x80;
- break;
- case 7:
- tmp = (tmp & 0x3f);
- break;
- case 11:
- tmp = (tmp & 0x3f) | 0x40;
- break;
- default:
- printk ("mad16/Mozart: Invalid MIDI IRQ\n");
- return 0;
- }
-
- mad_write (MC3_PORT, tmp | 0x04);
- hw_config->driver_use_1 = SB_MIDI_ONLY;
- return sb_dsp_detect (hw_config);
+ int i; /* A variable with secret power */
+
+ if (!already_initialized) /* The MSS port must be initialized first */
+ return 0;
+
+ if (mpu_attached) /* Don't let them call this twice */
+ return 0;
+ mpu_attached = 1;
+
+ if (board_type < C929) /* Early chip. No MPU support. Just SB MIDI */
+ {
+
+#if defined(CONFIG_MIDI)
+ unsigned char tmp;
+
+ tmp = mad_read(MC3_PORT);
+
+ /*
+ * MAD16 SB base is defined by the WSS base. It cannot be changed
+ * alone.
+ * Ignore configured I/O base. Use the active setting.
+ */
+
+ if (mad_read(MC1_PORT) & 0x20)
+ hw_config->io_base = 0x240;
+ else
+ hw_config->io_base = 0x220;
+
+ switch (hw_config->irq)
+ {
+ case 5:
+ tmp = (tmp & 0x3f) | 0x80;
+ break;
+ case 7:
+ tmp = (tmp & 0x3f);
+ break;
+ case 11:
+ tmp = (tmp & 0x3f) | 0x40;
+ break;
+ default:
+ printk("mad16/Mozart: Invalid MIDI IRQ\n");
+ return 0;
+ }
+
+ mad_write(MC3_PORT, tmp | 0x04);
+ hw_config->driver_use_1 = SB_MIDI_ONLY;
+ return sb_dsp_detect(hw_config);
#else
- return 0;
+ return 0;
#endif
- }
-
- tmp = mad_read (MC6_PORT) & 0x83;
- tmp |= 0x80; /* MPU-401 enable */
+ }
+ tmp = mad_read(MC6_PORT) & 0x83;
+ tmp |= 0x80; /* MPU-401 enable */
/*
* Set the MPU base bits
*/
- for (i = 0; i < 5; i++)
- {
- if (i > 3) /* Out of array bounds */
- {
- printk ("MAD16 / Mozart: Invalid MIDI port 0x%x\n", hw_config->io_base);
- return 0;
- }
-
- if (valid_ports[i] == hw_config->io_base)
- {
- tmp |= i << 5;
- break;
- }
- }
+ for (i = 0; i < 5; i++)
+ {
+ if (i > 3) /* Out of array bounds */
+ {
+ printk("MAD16 / Mozart: Invalid MIDI port 0x%x\n", hw_config->io_base);
+ return 0;
+ }
+ if (valid_ports[i] == hw_config->io_base)
+ {
+ tmp |= i << 5;
+ break;
+ }
+ }
/*
* Set the MPU IRQ bits
*/
- for (i = 0; i < 5; i++)
- {
- if (i > 3) /* Out of array bounds */
- {
- printk ("MAD16 / Mozart: Invalid MIDI IRQ %d\n", hw_config->irq);
- return 0;
- }
+ for (i = 0; i < 5; i++)
+ {
+ if (i > 3) /* Out of array bounds */
+ {
+ printk("MAD16 / Mozart: Invalid MIDI IRQ %d\n", hw_config->irq);
+ return 0;
+ }
+ if (valid_irqs[i] == hw_config->irq)
+ {
+ tmp |= i << 3;
+ break;
+ }
+ }
+ mad_write(MC6_PORT, tmp); /* Write MPU401 config */
- if (valid_irqs[i] == hw_config->irq)
- {
- tmp |= i << 3;
- break;
- }
- }
- mad_write (MC6_PORT, tmp); /* Write MPU401 config */
-
- return probe_uart401 (hw_config);
+ return probe_uart401(hw_config);
#else
- return 0;
+ return 0;
#endif
}
void
-unload_mad16 (struct address_info *hw_config)
+unload_mad16(struct address_info *hw_config)
{
- ad1848_unload (hw_config->io_base + 4,
- hw_config->irq,
- hw_config->dma,
- hw_config->dma2, 0);
- release_region (hw_config->io_base, 4);
+ ad1848_unload(hw_config->io_base + 4,
+ hw_config->irq,
+ hw_config->dma,
+ hw_config->dma2, 0);
+ release_region(hw_config->io_base, 4);
+ sound_unload_audiodev(hw_config->slots[0]);
}
void
-unload_mad16_mpu (struct address_info *hw_config)
+unload_mad16_mpu(struct address_info *hw_config)
{
-#ifdef CONFIG_MIDI
- if (board_type < C929) /* Early chip. No MPU support. Just SB MIDI */
- {
- sb_dsp_unload (hw_config);
- return;
- }
+#if defined(CONFIG_MIDI)
+ if (board_type < C929) /* Early chip. No MPU support. Just SB MIDI */
+ {
+ sb_dsp_unload(hw_config);
+ return;
+ }
#endif
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
- unload_uart401 (hw_config);
+ unload_uart401(hw_config);
#endif
}
+
+#ifdef MODULE
+
+int io = -1;
+int dma = -1;
+int dma16 = -1; /* Set this for modules that need it */
+int irq = -1;
+
+int cdtype = 0;
+int cdirq = 0;
+int cdport = 0x340;
+int cddma = 3;
+int opl4 = 0;
+int joystick = 0;
+
+static int found_mpu;
+
+
+static int dma_map[2][8] =
+{
+ {0x03, -1, -1, -1, -1, 0x00, 0x01, 0x02},
+ {0x03, -1, 0x01, 0x00, -1, -1, -1, -1}
+};
+
+static int irq_map[16] =
+{
+ 0x00, -1, -1, 0x0A,
+ -1, 0x04, -1, 0x08,
+ -1, 0x10, 0x14, 0x18,
+ -1, -1, -1, -1
+};
+
+struct address_info config;
+
+int
+init_module(void)
+{
+ int dmatype = 0;
+
+ printk("MAD16 audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
+
+ if (io == -1 || dma == -1 || irq == -1)
+ {
+ printk("I/O, DMA and irq are mandatory\n");
+ return -EINVAL;
+ }
+ printk("CDROM ");
+ switch (cdtype)
+ {
+ case 0x00:
+ printk("Disabled");
+ cdirq = 0;
+ break;
+ case 0x02:
+ printk("Sony CDU31A");
+ dmatype = 2;
+ break;
+ case 0x04:
+ printk("Mitsumi");
+ dmatype = 1;
+ break;
+ case 0x06:
+ printk("Panasonic Lasermate");
+ dmatype = 2;
+ break;
+ case 0x08:
+ printk("Secondary IDE");
+ dmatype = 1;
+ break;
+ case 0x0A:
+ printk("Primary IDE");
+ dmatype = 1;
+ break;
+ default:
+ printk("\nInvalid CDROM type\n");
+ return -EINVAL;
+ }
+
+ if (dmatype)
+ {
+ if (cddma > 7 || cddma < 0 || dma_map[dmatype][cddma] == -1)
+ {
+ printk("\nInvalid CDROM DMA\n");
+ return -EINVAL;
+ }
+ if (cddma)
+ printk(", DMA %d", cddma);
+ else
+ printk(", no DMA");
+ }
+ if (cdtype && !cdirq)
+ printk(", no IRQ");
+ else if (cdirq < 0 || cdirq > 15 || irq_map[cdirq] == -1)
+ {
+ printk(", invalid IRQ (disabling)");
+ cdirq = 0;
+ } else
+ printk(", IRQ %d", cdirq);
+
+ printk(".\nJoystick port ");
+ if (joystick == 1)
+ printk("enabled.\n");
+ else
+ {
+ joystick = 0;
+ printk("disabled.\n");
+ }
+
+ /*
+ * Build the config words
+ */
+
+ mad16_conf = (joystick ^ 1) | cdtype;
+ mad16_cdsel = 0;
+ if (opl4)
+ mad16_cdsel |= 0x20;
+ mad16_cdsel |= dma_map[dmatype][cddma];
+
+ if (cdtype < 0x08)
+ {
+ switch (cdport)
+ {
+ case 0x340:
+ mad16_cdsel |= 0x00;
+ break;
+ case 0x330:
+ mad16_cdsel |= 0x40;
+ break;
+ case 0x360:
+ mad16_cdsel |= 0x80;
+ break;
+ case 0x320:
+ mad16_cdsel |= 0xC0;
+ break;
+ default:
+ printk("Unknown CDROM I/O base %d\n", cdport);
+ return -EINVAL;
+ }
+ }
+ mad16_cdsel |= irq_map[cdirq];
+
+ config.io_base = io;
+ config.irq = irq;
+ config.dma = dma;
+ config.dma2 = dma16;
+
+ if (!probe_mad16(&config))
+ return -ENODEV;
+ found_mpu = probe_mad16_mpu(&config);
+
+ attach_mad16(&config);
+
+ if (found_mpu)
+ attach_mad16_mpu(&config);
+
+ SOUND_LOCK;
+ return 0;
+}
+
+void
+cleanup_module(void)
+{
+ if (found_mpu)
+ unload_mad16_mpu(&config);
+ unload_mad16(&config);
+ SOUND_LOCK_END;
+}
+
+#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov