/* * sound/gus_card.c * * Detection routine for the Gravis Ultrasound. * * Copyright by Hannu Savolainen 1993 * * 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 "sound_config.h" #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS) #include "gus_hw.h" void gusintr (int, struct pt_regs * regs); int gus_base, gus_irq, gus_dma; extern int gus_wave_volume; extern int gus_pcm_volume; extern int have_gus_max; long attach_gus_card (long mem_start, struct address_info *hw_config) { int io_addr; snd_set_irq_handler (hw_config->irq, gusintr); if (gus_wave_detect (hw_config->io_base)) /* * Try first the default */ { mem_start = gus_wave_init (mem_start, hw_config->irq, hw_config->dma); #ifndef EXCLUDE_MIDI mem_start = gus_midi_init (mem_start); #endif #ifndef EXCLUDE_SEQUENCER sound_timer_init (hw_config->io_base + 8); #endif return mem_start; } #ifndef EXCLUDE_GUS_IODETECT /* * Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6) */ for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10) if (io_addr != hw_config->io_base) /* * Already tested */ if (gus_wave_detect (io_addr)) { printk (" WARNING! GUS found at %x, config was %x ", io_addr, hw_config->io_base); mem_start = gus_wave_init (mem_start, hw_config->irq, hw_config->dma); #ifndef EXCLUDE_MIDI mem_start = gus_midi_init (mem_start); #endif #ifndef EXCLUDE_SEQUENCER sound_timer_init (io_addr + 8); #endif return mem_start; } #endif return mem_start; /* * Not detected */ } int probe_gus (struct address_info *hw_config) { int io_addr; if (gus_wave_detect (hw_config->io_base)) return 1; #ifndef EXCLUDE_GUS_IODETECT /* * Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6) */ for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10) if (io_addr != hw_config->io_base) /* * Already tested */ if (gus_wave_detect (io_addr)) return 1; #endif return 0; } void gusintr (int irq, struct pt_regs * regs) { unsigned char src; #ifdef linux sti (); #endif #ifndef EXCLUDE_GUSMAX if (have_gus_max) ad1848_interrupt (irq, regs); #endif while (1) { if (!(src = INB (u_IrqStatus))) return; if (src & DMA_TC_IRQ) { guswave_dma_irq (); } if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ)) { #ifndef EXCLUDE_MIDI gus_midi_interrupt (0); #endif } if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ)) { #ifndef EXCLUDE_SEQUENCER sound_timer_interrupt (); #else gus_write8 (0x45, 0); /* Stop timers */ #endif } if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ)) { gus_voice_irq (); } } } #endif /* * Some extra code for the 16 bit sampling option */ #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS16) int probe_gus_db16 (struct address_info *hw_config) { return ad1848_detect (hw_config->io_base); } long attach_gus_db16 (long mem_start, struct address_info *hw_config) { gus_pcm_volume = 100; gus_wave_volume = 90; ad1848_init ("GUS 16 bit sampling", hw_config->io_base, hw_config->irq, hw_config->dma, hw_config->dma); return mem_start; } #endif