/* * sound/clones.c * * init code for enabling clone cards to work in sb/mss emulation. * * Note -- this code is currently unused! * * Copyright by Luigi Rizzo - 1997 * * 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. * * This file has been written using information from various sources * in the Voxware 3.5 distribution. */ #include #if NPCM > 0 /* * Known clones card include: * * Trix (emulating MSS) * MAD16 (emulating MSS) * OPTi930 -- same as the OPTi931, but no PnP ? */ #ifdef JAZZ16 /* * Initialization of a Media Vision ProSonic 16 Soundcard. The function * initializes a ProSonic 16 like PROS.EXE does for DOS. It sets the base * address, the DMA-channels, interrupts and enables the joystickport. * * Also used by Jazz 16 (same card, different name) * * written 1994 by Rainer Vranken E-Mail: * rvranken@polaris.informatik.uni-essen.de */ #ifdef SM_WAVE /* * Logitech Soundman Wave detection and initialization by Hannu Savolainen. * * There is a microcontroller (8031) in the SM Wave card for MIDI emulation. * it's located at address MPU_BASE+4. MPU_BASE+7 is a SM Wave specific * control register for MC reset, SCSI, OPL4 and DSP (future expansion) * address decoding. Otherwise the SM Wave is just a ordinary MV Jazz16 based * soundcard. */ static void smw_putmem(int base, int addr, u_char val) { u_long s; s = spltty(); outb(base + 1, addr & 0xff); /* Low address bits */ outb(base + 2, addr >> 8); /* High address bits */ outb(base, val); /* Data */ splx(s); } static u_char smw_getmem(int base, int addr) { u_long s; u_char val; s = spltty(); outb(base + 1, addr & 0xff); /* Low address bits */ outb(base + 2, addr >> 8); /* High address bits */ val = inb(base); /* Data */ splx(s); return val; } #ifdef SMW_MIDI0001_INCLUDED #include #else u_char *smw_ucode = NULL; int smw_ucodeLen = 0; #endif /* SWM_MIDI0001_INCLUDED */ static int initialize_smw(int mpu_base) { int i, mp_base = mpu_base + 4; /* Microcontroller base */ u_char control; /* * Reset the microcontroller so that the RAM can be accessed */ control = inb(mpu_base + 7); outb(mpu_base + 7, control | 3); /* Set last two bits to 1 (?) */ outb(mpu_base + 7, (control & 0xfe) | 2); /* xxxxxxx0 resets the mc */ DELAY(3000); /* Wait at least 1ms */ outb(mpu_base + 7, control & 0xfc); /* xxxxxx00 enables RAM */ /* * Detect microcontroller by probing the 8k RAM area */ smw_putmem(mp_base, 0, 0x00); smw_putmem(mp_base, 1, 0xff); DELAY(10); if (smw_getmem(mp_base, 0) != 0x00 || smw_getmem(mp_base, 1) != 0xff) { printf("\nSM Wave: No microcontroller RAM detected (%02x, %02x)\n", smw_getmem(mp_base, 0), smw_getmem(mp_base, 1)); return 0; /* No RAM */ } /* * There is RAM so assume it's really a SM Wave */ if (smw_ucodeLen > 0) { if (smw_ucodeLen != 8192) { printf("\nSM Wave: Invalid microcode (MIDI0001.BIN) length\n"); return 1; } /* * Download microcode */ for (i = 0; i < 8192; i++) smw_putmem(mp_base, i, smw_ucode[i]); /* * Verify microcode */ for (i = 0; i < 8192; i++) if (smw_getmem(mp_base, i) != smw_ucode[i]) { printf("SM Wave: Microcode verification failed\n"); return 0; } } control = 0; #ifdef SMW_SCSI_IRQ /* * Set the SCSI interrupt (IRQ2/9, IRQ3 or IRQ10). The SCSI interrupt * is disabled by default. * * Btw the Zilog 5380 SCSI controller is located at MPU base + 0x10. */ { static u_char scsi_irq_bits[] = {0, 0, 3, 1, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0}; control |= scsi_irq_bits[SMW_SCSI_IRQ] << 6; } #endif #ifdef SMW_OPL4_ENABLE /* * Make the OPL4 chip visible on the PC bus at 0x380. * * There is no need to enable this feature since VoxWare doesn't support * OPL4 yet. Also there is no RAM in SM Wave so enabling OPL4 is * pretty useless. */ control |= 0x10; /* Uses IRQ12 if bit 0x20 == 0 */ /* control |= 0x20; Uncomment this if you want to use IRQ7 */ #endif outb(mpu_base + 7, control | 0x03); /* xxxxxx11 restarts */ return 1; } #endif /* * this is only called during the probe. Variables are found in * sb_probed. */ static sbdev_info sb_probed ; static int initialize_ProSonic16(snddev_info *d) { int x; static u_char int_translat[16] = {0, 0, 2, 3, 0, 1, 0, 4, 0, 2, 5, 0, 0, 0, 0, 6}, dma_translat[8] = {0, 1, 0, 2, 0, 3, 0, 4}; struct address_info *mpu_config; int mpu_base, mpu_irq; if ((mpu_config = NULL)) { mpu_base = mpu_config->io_base; mpu_irq = mpu_config->irq; } else { mpu_base = mpu_irq = 0; } outb(0x201, 0xAF); /* ProSonic/Jazz16 wakeup */ DELAY(15000); /* wait at least 10 milliseconds */ outb(0x201, 0x50); outb(0x201, (sb_probed.io_base & 0x70) | ((mpu_base & 0x30) >> 4)); if (sb_reset_dsp(sb_probed.io_base)) { /* OK. We have at least a SB */ /* Check the version number of ProSonic (I guess) */ if (!sb_cmd(sb_probed.io_base, 0xFA)) return 1; if (sb_get_byte(sb_probed.io_base) != 0x12) return 1; if (sb_cmd(sb_probed.io_base, 0xFB) && /* set DMA and irq */ sb_cmd(sb_probed.io_base, (dma_translat[JAZZ_DMA16]<<4)|dma_translat[sb_probed.dbuf_out.chan]) && sb_cmd(sb_probed.io_base, (int_translat[mpu_irq]<<4)|int_translat[sb_probed.irq])) { d->bf_flags |= BD_F_JAZZ16 ; if (mpu_base == 0) printf("Jazz16: No MPU401 devices configured " "- MIDI port not initialized\n"); #ifdef SM_WAVE if (mpu_base != 0) if (initialize_smw(mpu_base)) d->bf_flags |= BD_F_JAZZ16_2 ; #endif /* sb_dsp_disable_midi(); */ } return 1; /* There was at least a SB */ } return 0; /* No SB or ProSonic16 detected */ } #endif /* ifdef JAZZ16 */ #endif /* NPCM */