diff options
Diffstat (limited to 'sys/i386/isa/sound/mad16.c')
-rw-r--r-- | sys/i386/isa/sound/mad16.c | 524 |
1 files changed, 0 insertions, 524 deletions
diff --git a/sys/i386/isa/sound/mad16.c b/sys/i386/isa/sound/mad16.c deleted file mode 100644 index 0e2064a..0000000 --- a/sys/i386/isa/sound/mad16.c +++ /dev/null @@ -1,524 +0,0 @@ -/* - * sound/mad16.c - * - * Initialization code for OPTi MAD16 compatible audio chips. Including - * - * OPTi 82C928 MAD16 (replaced by C929) OAK OTI-601D Mozart - * OPTi 82C929 MAD16 Pro - * - * These audio interface chips don't prduce sound themselves. They just connect - * some other components (OPL-[234] and a WSS compatible codec) to the PC bus - * and perform I/O, DMA and IRQ address decoding. There is also a UART for - * the MPU-401 mode (not 82C928/Mozart). The Mozart chip appears to be - * compatible with the 82C928 (can anybody confirm this?). - * - * NOTE! If you want to set CD-ROM address and/or joystick enable, define - * MAD16_CONF in local.h as combination of the following bits: - * - * 0x01 - joystick disabled - * - * CD-ROM type selection (select just one): 0x00 - none 0x02 - Sony 31A - * 0x04 - Mitsumi 0x06 - Panasonic (type "LaserMate", not - * "SoundBlaster") 0x08 - Secondary IDE (address 0x170) 0x0a - Primary - * IDE (address 0x1F0) - * - * For example Mitsumi with joystick disabled = 0x04|0x01 = 0x05 For example - * LaserMate (for use with sbpcd) plus joystick = 0x06 - * - * MAD16_CDSEL: This defaults to CD I/O 0x340, no IRQ and DMA3 (DMA5 with - * Mitsumi or IDE). If you like to change these, define MAD16_CDSEL with the - * following bits: - * - * CD-ROM port: 0x00=340, 0x40=330, 0x80=360 or 0xc0=320 OPL4 select: 0x20=OPL4, - * 0x00=OPL3 CD-ROM irq: 0x00=disabled, 0x04=IRQ5, 0x08=IRQ7, 0x0a=IRQ3, - * 0x10=IRQ9, 0x14=IRQ10 and 0x18=IRQ11. - * - * CD-ROM DMA (Sony or Panasonic): 0x00=DMA3, 0x01=DMA2, 0x02=DMA1 or - * 0x03=disabled or CD-ROM DMA (Mitsumi or IDE): 0x00=DMA5, 0x01=DMA6, - * 0x02=DMA7 or 0x03=disabled - * - * For use with sbpcd, address 0x340, set MAD16_CDSEL to 0x03 or 0x23. - * - * Copyright by Hannu Savolainen 1995 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. 2. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include <i386/isa/sound/sound_config.h> - -#if defined(CONFIG_MAD16) - -static int already_initialized = 0; - -#define C928 1 -#define MOZART 2 -#define C929 3 - -/* - * Registers - * - * The MAD16 occupies I/O ports 0xf8d to 0xf93 (fixed locations). All ports are - * inactive by default. They can be activated by writing 0xE2 or 0xE3 to the - * password register. The password is valid only until the next I/O read or - * write. - */ - -#define MC1_PORT 0xf8d /* SB address, CDROM interface type, joystick */ -#define MC2_PORT 0xf8e /* CDROM address, IRQ, DMA, plus OPL4 bit */ -#define MC3_PORT 0xf8f -#define PASSWD_REG 0xf8f -#define MC4_PORT 0xf90 -#define MC5_PORT 0xf91 -#define MC6_PORT 0xf92 -#define MC7_PORT 0xf93 - -static int board_type = C928; - -static sound_os_info *mad16_osp; - -#ifndef DDB -#define DDB(x) -#endif - -static unsigned char -mad_read(int port) -{ - unsigned long flags; - unsigned char tmp; - - flags = splhigh(); - - switch (board_type) { /* Output password */ - case C928: - case MOZART: - outb(PASSWD_REG, 0xE2); - break; - - case C929: - outb(PASSWD_REG, 0xE3); - break; - } - - tmp = inb(port); - splx(flags); - - return tmp; -} - -static void -mad_write(int port, int value) -{ - unsigned long flags; - - flags = splhigh(); - - switch (board_type) { /* Output password */ - case C928: - case MOZART: - outb(PASSWD_REG, 0xE2); - break; - - case C929: - outb(PASSWD_REG, 0xE3); - break; - } - - outb(port, (unsigned char) (value & 0xff)); - splx(flags); -} - -static int -detect_mad16(void) -{ - unsigned char tmp, tmp2; - - /* - * Check that reading a register doesn't return bus float (0xff) when - * the card is accessed using password. This may fail in case 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(printf("MC1_PORT returned 0xff\n")); - return 0; - } - /* - * 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(printf("MC1_PORT didn't close after read (0x%02x)\n", tmp2)); - return 0; - } - mad_write(MC1_PORT, tmp ^ 0x80); /* Togge a bit */ - - if ((tmp2 = mad_read(MC1_PORT)) != (tmp ^ 0x80)) { /* Compare the bit */ - mad_write(MC1_PORT, tmp); /* Restore */ - DDB(printf("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2)); - return 0; - } - mad_write(MC1_PORT, tmp); /* Restore */ - return 1; /* Bingo */ - -} - -int -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 ad_flags = 0; - - if (already_initialized) - return 0; - - mad16_osp = hw_config->osp; - /* - * Check that all ports return 0xff (bus float) when no password is - * written to the password register. - */ - - DDB(printf("--- Detecting MAD16 / Mozart ---\n")); - - - /* - * Then try to detect with the old password - */ - board_type = C928; - - DDB(printf("Detect using password = 0xE2\n")); - - if (!detect_mad16()) { /* No luck. Try different model */ - board_type = C929; - - DDB(printf("Detect using password = 0xE3\n")); - - if (!detect_mad16()) - return 0; - - DDB(printf("mad16.c: 82C929 detected\n")); - } else { - unsigned char model; - - if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03) { - DDB(printf("mad16.c: Mozart detected\n")); - board_type = MOZART; - } else { - DDB(printf("mad16.c: 82C928 detected???\n")); - board_type = C928; - } - } - - for (i = 0xf8d; i <= 0xf93; i++) - DDB(printf("port %03x = %03x\n", i, mad_read(i))); - - /* - * Set the WSS address - */ - - tmp = 0x80; /* Enable WSS, Disable SB */ - - for (i = 0; i < 5; i++) { - if (i > 3) { /* Not a valid port */ - printf("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 |= ((MAD16_CONF) & 0x0f); /* CD-ROM and joystick bits */ -#endif - mad_write(MC1_PORT, tmp); - -#if defined(MAD16_CONF) && defined(MAD16_CDSEL) - tmp = MAD16_CDSEL; -#else - tmp = 0x03; -#endif - -#ifdef MAD16_OPL4 - tmp |= 0x20; /* Enable OPL4 access */ -#endif - - mad_write(MC2_PORT, tmp); - mad_write(MC3_PORT, 0xf0); /* Disable SB */ - - 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); - } - - for (i = 0xf8d; i <= 0xf93; i++) - DDB(printf("port %03x after init = %03x\n", i, mad_read(i))); - - /* - * Verify the WSS parameters - */ - - if (0) { - printf("MSS: I/O port conflict\n"); - 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(printf("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) { - printf("MSS: Bad IRQ %d\n", hw_config->irq); - return 0; - } - if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3) { - printf("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) { - printf("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) { - printf("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq); - return 0; - } - return 1; -} - -void -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. - */ - - bits = interrupt_bits[hw_config->irq]; - if (bits == -1) - return; - - outb(config_port, bits | 0x40); - if ((inb(version_port) & 0x40) == 0) - printf("[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)) { - dma2_bit = 0x04; /* Enable capture DMA */ - } else { - printf("MAD16: Invalid capture DMA\n"); - dma2 = dma; - } - } else - dma2 = dma; - - outb(config_port, bits | dma_bits[dma] | dma2_bit); /* Write IRQ+DMA setup */ - - ad1848_init("MAD16 WSS", hw_config->io_base + 4, - hw_config->irq, - dma, - dma2, 0, - hw_config->osp); -} - -void -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; - - return mad16_sb_dsp_init(hw_config); -#else - return 0; -#endif - } -#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI) - if (!already_initialized) - return; - - attach_mpu401(hw_config); -#endif -} - -int -probe_mad16_mpu(struct address_info * hw_config) -{ -#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && 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; - - 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: - printf("mad16/Mozart: Invalid MIDI IRQ\n"); - return 0; - } - - mad_write(MC3_PORT, tmp | 0x04); - return mad16_sb_dsp_detect(hw_config); -#else - return 0; -#endif - } - tmp = 0x83; /* MPU-401 enable */ - - /* - * Set the MPU base bits - */ - - for (i = 0; i < 5; i++) { - if (i > 3) { /* Out of array bounds */ - printf("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 */ - printf("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 */ - - return probe_mpu401(hw_config); -#else - return 0; -#endif -} - -/* That's all folks */ -#endif |