aboutsummaryrefslogtreecommitdiff
path: root/sound/oss/gus_wave.c
diff options
context:
space:
mode:
authorAdrian Bunk <bunk@stusta.de>2006-10-04 02:17:22 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 07:55:32 -0700
commitd56b9b9c464a10ab1ee51a4c6190a2b57b8ef7a6 (patch)
treea48388734053900a8379042757ee241d1e9dfc7b /sound/oss/gus_wave.c
parent595182bcdf64fbfd7ae22c67ea6081b7d387d246 (diff)
[PATCH] The scheduled removal of some OSS drivers
This patch contains the scheduled removal of OSS drivers that: - have ALSA drivers for the same hardware without known regressions and - whose Kconfig options have been removed in 2.6.17. [michal.k.k.piotrowski@gmail.com: build fix] Signed-off-by: Adrian Bunk <bunk@stusta.de> Signed-off-by: Michal Piotrowski <michal.k.k.piotrowski@gmail.com> Cc: David Woodhouse <dwmw2@infradead.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'sound/oss/gus_wave.c')
-rw-r--r--sound/oss/gus_wave.c3464
1 files changed, 0 insertions, 3464 deletions
diff --git a/sound/oss/gus_wave.c b/sound/oss/gus_wave.c
deleted file mode 100644
index 597db7aee63..00000000000
--- a/sound/oss/gus_wave.c
+++ /dev/null
@@ -1,3464 +0,0 @@
-/*
- * sound/oss/gus_wave.c
- *
- * Driver for the Gravis UltraSound wave table synth.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- * Frank van de Pol : Fixed GUS MAX interrupt handling. Enabled simultanious
- * usage of CS4231A codec, GUS wave and MIDI for GUS MAX.
- * Bartlomiej Zolnierkiewicz : added some __init/__exit
- */
-
-#include <linux/init.h>
-#include <linux/config.h>
-#include <linux/spinlock.h>
-
-#define GUSPNP_AUTODETECT
-
-#include "sound_config.h"
-#include <linux/ultrasound.h>
-
-#include "gus.h"
-#include "gus_hw.h"
-
-#define GUS_BANK_SIZE (((iw_mode) ? 256*1024*1024 : 256*1024))
-
-#define MAX_SAMPLE 150
-#define MAX_PATCH 256
-
-#define NOT_SAMPLE 0xffff
-
-struct voice_info
-{
- unsigned long orig_freq;
- unsigned long current_freq;
- unsigned long mode;
- int fixed_pitch;
- int bender;
- int bender_range;
- int panning;
- int midi_volume;
- unsigned int initial_volume;
- unsigned int current_volume;
- int loop_irq_mode, loop_irq_parm;
-#define LMODE_FINISH 1
-#define LMODE_PCM 2
-#define LMODE_PCM_STOP 3
- int volume_irq_mode, volume_irq_parm;
-#define VMODE_HALT 1
-#define VMODE_ENVELOPE 2
-#define VMODE_START_NOTE 3
-
- int env_phase;
- unsigned char env_rate[6];
- unsigned char env_offset[6];
-
- /*
- * Volume computation parameters for gus_adagio_vol()
- */
- int main_vol, expression_vol, patch_vol;
-
- /* Variables for "Ultraclick" removal */
- int dev_pending, note_pending, volume_pending,
- sample_pending;
- char kill_pending;
- long offset_pending;
-
-};
-
-static struct voice_alloc_info *voice_alloc;
-static struct address_info *gus_hw_config;
-extern int gus_base;
-extern int gus_irq, gus_dma;
-extern int gus_pnp_flag;
-extern int gus_no_wave_dma;
-static int gus_dma2 = -1;
-static int dual_dma_mode;
-static long gus_mem_size;
-static long free_mem_ptr;
-static int gus_busy;
-static int gus_no_dma;
-static int nr_voices;
-static int gus_devnum;
-static int volume_base, volume_scale, volume_method;
-static int gus_recmask = SOUND_MASK_MIC;
-static int recording_active;
-static int only_read_access;
-static int only_8_bits;
-
-static int iw_mode = 0;
-int gus_wave_volume = 60;
-int gus_pcm_volume = 80;
-int have_gus_max = 0;
-static int gus_line_vol = 100, gus_mic_vol;
-static unsigned char mix_image = 0x00;
-
-int gus_timer_enabled = 0;
-
-/*
- * Current version of this driver doesn't allow synth and PCM functions
- * at the same time. The active_device specifies the active driver
- */
-
-static int active_device;
-
-#define GUS_DEV_WAVE 1 /* Wave table synth */
-#define GUS_DEV_PCM_DONE 2 /* PCM device, transfer done */
-#define GUS_DEV_PCM_CONTINUE 3 /* PCM device, transfer done ch. 1/2 */
-
-static int gus_audio_speed;
-static int gus_audio_channels;
-static int gus_audio_bits;
-static int gus_audio_bsize;
-static char bounce_buf[8 * 1024]; /* Must match value set to max_fragment */
-
-static DECLARE_WAIT_QUEUE_HEAD(dram_sleeper);
-
-/*
- * Variables and buffers for PCM output
- */
-
-#define MAX_PCM_BUFFERS (128*MAX_REALTIME_FACTOR) /* Don't change */
-
-static int pcm_bsize, pcm_nblk, pcm_banksize;
-static int pcm_datasize[MAX_PCM_BUFFERS];
-static volatile int pcm_head, pcm_tail, pcm_qlen;
-static volatile int pcm_active;
-static volatile int dma_active;
-static int pcm_opened;
-static int pcm_current_dev;
-static int pcm_current_block;
-static unsigned long pcm_current_buf;
-static int pcm_current_count;
-static int pcm_current_intrflag;
-DEFINE_SPINLOCK(gus_lock);
-
-extern int *gus_osp;
-
-static struct voice_info voices[32];
-
-static int freq_div_table[] =
-{
- 44100, /* 14 */
- 41160, /* 15 */
- 38587, /* 16 */
- 36317, /* 17 */
- 34300, /* 18 */
- 32494, /* 19 */
- 30870, /* 20 */
- 29400, /* 21 */
- 28063, /* 22 */
- 26843, /* 23 */
- 25725, /* 24 */
- 24696, /* 25 */
- 23746, /* 26 */
- 22866, /* 27 */
- 22050, /* 28 */
- 21289, /* 29 */
- 20580, /* 30 */
- 19916, /* 31 */
- 19293 /* 32 */
-};
-
-static struct patch_info *samples;
-static long sample_ptrs[MAX_SAMPLE + 1];
-static int sample_map[32];
-static int free_sample;
-static int mixer_type;
-
-
-static int patch_table[MAX_PATCH];
-static int patch_map[32];
-
-static struct synth_info gus_info = {
- "Gravis UltraSound", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS,
- 0, 16, 0, MAX_PATCH
-};
-
-static void gus_poke(long addr, unsigned char data);
-static void compute_and_set_volume(int voice, int volume, int ramp_time);
-extern unsigned short gus_adagio_vol(int vel, int mainv, int xpn, int voicev);
-extern unsigned short gus_linear_vol(int vol, int mainvol);
-static void compute_volume(int voice, int volume);
-static void do_volume_irq(int voice);
-static void set_input_volumes(void);
-static void gus_tmr_install(int io_base);
-
-#define INSTANT_RAMP -1 /* Instant change. No ramping */
-#define FAST_RAMP 0 /* Fastest possible ramp */
-
-static void reset_sample_memory(void)
-{
- int i;
-
- for (i = 0; i <= MAX_SAMPLE; i++)
- sample_ptrs[i] = -1;
- for (i = 0; i < 32; i++)
- sample_map[i] = -1;
- for (i = 0; i < 32; i++)
- patch_map[i] = -1;
-
- gus_poke(0, 0); /* Put a silent sample to the beginning */
- gus_poke(1, 0);
- free_mem_ptr = 2;
-
- free_sample = 0;
-
- for (i = 0; i < MAX_PATCH; i++)
- patch_table[i] = NOT_SAMPLE;
-}
-
-void gus_delay(void)
-{
- int i;
-
- for (i = 0; i < 7; i++)
- inb(u_DRAMIO);
-}
-
-static void gus_poke(long addr, unsigned char data)
-{ /* Writes a byte to the DRAM */
- outb((0x43), u_Command);
- outb((addr & 0xff), u_DataLo);
- outb(((addr >> 8) & 0xff), u_DataHi);
-
- outb((0x44), u_Command);
- outb(((addr >> 16) & 0xff), u_DataHi);
- outb((data), u_DRAMIO);
-}
-
-static unsigned char gus_peek(long addr)
-{ /* Reads a byte from the DRAM */
- unsigned char tmp;
-
- outb((0x43), u_Command);
- outb((addr & 0xff), u_DataLo);
- outb(((addr >> 8) & 0xff), u_DataHi);
-
- outb((0x44), u_Command);
- outb(((addr >> 16) & 0xff), u_DataHi);
- tmp = inb(u_DRAMIO);
-
- return tmp;
-}
-
-void gus_write8(int reg, unsigned int data)
-{ /* Writes to an indirect register (8 bit) */
- outb((reg), u_Command);
- outb(((unsigned char) (data & 0xff)), u_DataHi);
-}
-
-static unsigned char gus_read8(int reg)
-{
- /* Reads from an indirect register (8 bit). Offset 0x80. */
- unsigned char val;
-
- outb((reg | 0x80), u_Command);
- val = inb(u_DataHi);
-
- return val;
-}
-
-static unsigned char gus_look8(int reg)
-{
- /* Reads from an indirect register (8 bit). No additional offset. */
- unsigned char val;
-
- outb((reg), u_Command);
- val = inb(u_DataHi);
-
- return val;
-}
-
-static void gus_write16(int reg, unsigned int data)
-{
- /* Writes to an indirect register (16 bit) */
- outb((reg), u_Command);
-
- outb(((unsigned char) (data & 0xff)), u_DataLo);
- outb(((unsigned char) ((data >> 8) & 0xff)), u_DataHi);
-}
-
-static unsigned short gus_read16(int reg)
-{
- /* Reads from an indirect register (16 bit). Offset 0x80. */
- unsigned char hi, lo;
-
- outb((reg | 0x80), u_Command);
-
- lo = inb(u_DataLo);
- hi = inb(u_DataHi);
-
- return ((hi << 8) & 0xff00) | lo;
-}
-
-static unsigned short gus_look16(int reg)
-{
- /* Reads from an indirect register (16 bit). No additional offset. */
- unsigned char hi, lo;
-
- outb((reg), u_Command);
-
- lo = inb(u_DataLo);
- hi = inb(u_DataHi);
-
- return ((hi << 8) & 0xff00) | lo;
-}
-
-static void gus_write_addr(int reg, unsigned long address, int frac, int is16bit)
-{
- /* Writes an 24 bit memory address */
- unsigned long hold_address;
-
- if (is16bit)
- {
- if (iw_mode)
- {
- /* Interwave spesific address translations */
- address >>= 1;
- }
- else
- {
- /*
- * Special processing required for 16 bit patches
- */
-
- hold_address = address;
- address = address >> 1;
- address &= 0x0001ffffL;
- address |= (hold_address & 0x000c0000L);
- }
- }
- gus_write16(reg, (unsigned short) ((address >> 7) & 0xffff));
- gus_write16(reg + 1, (unsigned short) ((address << 9) & 0xffff)
- + (frac << 5));
- /* Could writing twice fix problems with GUS_VOICE_POS()? Let's try. */
- gus_delay();
- gus_write16(reg, (unsigned short) ((address >> 7) & 0xffff));
- gus_write16(reg + 1, (unsigned short) ((address << 9) & 0xffff)
- + (frac << 5));
-}
-
-static void gus_select_voice(int voice)
-{
- if (voice < 0 || voice > 31)
- return;
- outb((voice), u_Voice);
-}
-
-static void gus_select_max_voices(int nvoices)
-{
- if (iw_mode)
- nvoices = 32;
- if (nvoices < 14)
- nvoices = 14;
- if (nvoices > 32)
- nvoices = 32;
-
- voice_alloc->max_voice = nr_voices = nvoices;
- gus_write8(0x0e, (nvoices - 1) | 0xc0);
-}
-
-static void gus_voice_on(unsigned int mode)
-{
- gus_write8(0x00, (unsigned char) (mode & 0xfc));
- gus_delay();
- gus_write8(0x00, (unsigned char) (mode & 0xfc));
-}
-
-static void gus_voice_off(void)
-{
- gus_write8(0x00, gus_read8(0x00) | 0x03);
-}
-
-static void gus_voice_mode(unsigned int m)
-{
- unsigned char mode = (unsigned char) (m & 0xff);
-
- gus_write8(0x00, (gus_read8(0x00) & 0x03) |
- (mode & 0xfc)); /* Don't touch last two bits */
- gus_delay();
- gus_write8(0x00, (gus_read8(0x00) & 0x03) | (mode & 0xfc));
-}
-
-static void gus_voice_freq(unsigned long freq)
-{
- unsigned long divisor = freq_div_table[nr_voices - 14];
- unsigned short fc;
-
- /* Interwave plays at 44100 Hz with any number of voices */
- if (iw_mode)
- fc = (unsigned short) (((freq << 9) + (44100 >> 1)) / 44100);
- else
- fc = (unsigned short) (((freq << 9) + (divisor >> 1)) / divisor);
- fc = fc << 1;
-
- gus_write16(0x01, fc);
-}
-
-static void gus_voice_volume(unsigned int vol)
-{
- gus_write8(0x0d, 0x03); /* Stop ramp before setting volume */
- gus_write16(0x09, (unsigned short) (vol << 4));
-}
-
-static void gus_voice_balance(unsigned int balance)
-{
- gus_write8(0x0c, (unsigned char) (balance & 0xff));
-}
-
-static void gus_ramp_range(unsigned int low, unsigned int high)
-{
- gus_write8(0x07, (unsigned char) ((low >> 4) & 0xff));
- gus_write8(0x08, (unsigned char) ((high >> 4) & 0xff));
-}
-
-static void gus_ramp_rate(unsigned int scale, unsigned int rate)
-{
- gus_write8(0x06, (unsigned char) (((scale & 0x03) << 6) | (rate & 0x3f)));
-}
-
-static void gus_rampon(unsigned int m)
-{
- unsigned char mode = (unsigned char) (m & 0xff);
-
- gus_write8(0x0d, mode & 0xfc);
- gus_delay();
- gus_write8(0x0d, mode & 0xfc);
-}
-
-static void gus_ramp_mode(unsigned int m)
-{
- unsigned char mode = (unsigned char) (m & 0xff);
-
- gus_write8(0x0d, (gus_read8(0x0d) & 0x03) |
- (mode & 0xfc)); /* Leave the last 2 bits alone */
- gus_delay();
- gus_write8(0x0d, (gus_read8(0x0d) & 0x03) | (mode & 0xfc));
-}
-
-static void gus_rampoff(void)
-{
- gus_write8(0x0d, 0x03);
-}
-
-static void gus_set_voice_pos(int voice, long position)
-{
- int sample_no;
-
- if ((sample_no = sample_map[voice]) != -1) {
- if (position < samples[sample_no].len) {
- if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
- voices[voice].offset_pending = position;
- else
- gus_write_addr(0x0a, sample_ptrs[sample_no] + position, 0,
- samples[sample_no].mode & WAVE_16_BITS);
- }
- }
-}
-
-static void gus_voice_init(int voice)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&gus_lock,flags);
- gus_select_voice(voice);
- gus_voice_volume(0);
- gus_voice_off();
- gus_write_addr(0x0a, 0, 0, 0); /* Set current position to 0 */
- gus_write8(0x00, 0x03); /* Voice off */
- gus_write8(0x0d, 0x03); /* Ramping off */
- voice_alloc->map[voice] = 0;
- voice_alloc->alloc_times[voice] = 0;
- spin_unlock_irqrestore(&gus_lock,flags);
-
-}
-
-static void gus_voice_init2(int voice)
-{
- voices[voice].panning = 0;
- voices[voice].mode = 0;
- voices[voice].orig_freq = 20000;
- voices[voice].current_freq = 20000;
- voices[voice].bender = 0;
- voices[voice].bender_range = 200;
- voices[voice].initial_volume = 0;
- voices[voice].current_volume = 0;
- voices[voice].loop_irq_mode = 0;
- voices[voice].loop_irq_parm = 0;
- voices[voice].volume_irq_mode = 0;
- voices[voice].volume_irq_parm = 0;
- voices[voice].env_phase = 0;
- voices[voice].main_vol = 127;
- voices[voice].patch_vol = 127;
- voices[voice].expression_vol = 127;
- voices[voice].sample_pending = -1;
- voices[voice].fixed_pitch = 0;
-}
-
-static void step_envelope(int voice)
-{
- unsigned vol, prev_vol, phase;
- unsigned char rate;
- unsigned long flags;
-
- if (voices[voice].mode & WAVE_SUSTAIN_ON && voices[voice].env_phase == 2)
- {
- spin_lock_irqsave(&gus_lock,flags);
- gus_select_voice(voice);
- gus_rampoff();
- spin_unlock_irqrestore(&gus_lock,flags);
- return;
- /*
- * Sustain phase begins. Continue envelope after receiving note off.
- */
- }
- if (voices[voice].env_phase >= 5)
- {
- /* Envelope finished. Shoot the voice down */
- gus_voice_init(voice);
- return;
- }
- prev_vol = voices[voice].current_volume;
- phase = ++voices[voice].env_phase;
- compute_volume(voice, voices[voice].midi_volume);
- vol = voices[voice].initial_volume * voices[voice].env_offset[phase] / 255;
- rate = voices[voice].env_rate[phase];
-
- spin_lock_irqsave(&gus_lock,flags);
- gus_select_voice(voice);
-
- gus_voice_volume(prev_vol);
-
-
- gus_write8(0x06, rate); /* Ramping rate */
-
- voices[voice].volume_irq_mode = VMODE_ENVELOPE;
-
- if (((vol - prev_vol) / 64) == 0) /* No significant volume change */
- {
- spin_unlock_irqrestore(&gus_lock,flags);
- step_envelope(voice); /* Continue the envelope on the next step */
- return;
- }
- if (vol > prev_vol)
- {
- if (vol >= (4096 - 64))
- vol = 4096 - 65;
- gus_ramp_range(0, vol);
- gus_rampon(0x20); /* Increasing volume, with IRQ */
- }
- else
- {
- if (vol <= 64)
- vol = 65;
- gus_ramp_range(vol, 4030);
- gus_rampon(0x60); /* Decreasing volume, with IRQ */
- }
- voices[voice].current_volume = vol;
- spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static void init_envelope(int voice)
-{
- voices[voice].env_phase = -1;
- voices[voice].current_volume = 64;
-
- step_envelope(voice);
-}
-
-static void start_release(int voice)
-{
- if (gus_read8(0x00) & 0x03)
- return; /* Voice already stopped */
-
- voices[voice].env_phase = 2; /* Will be incremented by step_envelope */
-
- voices[voice].current_volume = voices[voice].initial_volume =
- gus_read16(0x09) >> 4; /* Get current volume */
-
- voices[voice].mode &= ~WAVE_SUSTAIN_ON;
- gus_rampoff();
- step_envelope(voice);
-}
-
-static void gus_voice_fade(int voice)
-{
- int instr_no = sample_map[voice], is16bits;
- unsigned long flags;
-
- spin_lock_irqsave(&gus_lock,flags);
- gus_select_voice(voice);
-
- if (instr_no < 0 || instr_no > MAX_SAMPLE)
- {
- gus_write8(0x00, 0x03); /* Hard stop */
- voice_alloc->map[voice] = 0;
- spin_unlock_irqrestore(&gus_lock,flags);
- return;
- }
- is16bits = (samples[instr_no].mode & WAVE_16_BITS) ? 1 : 0; /* 8 or 16 bits */
-
- if (voices[voice].mode & WAVE_ENVELOPES)
- {
- start_release(voice);
- spin_unlock_irqrestore(&gus_lock,flags);
- return;
- }
- /*
- * Ramp the volume down but not too quickly.
- */
- if ((int) (gus_read16(0x09) >> 4) < 100) /* Get current volume */
- {
- gus_voice_off();
- gus_rampoff();
- gus_voice_init(voice);
- spin_unlock_irqrestore(&gus_lock,flags);
- return;
- }
- gus_ramp_range(65, 4030);
- gus_ramp_rate(2, 4);
- gus_rampon(0x40 | 0x20); /* Down, once, with IRQ */
- voices[voice].volume_irq_mode = VMODE_HALT;
- spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static void gus_reset(void)
-{
- int i;
-
- gus_select_max_voices(24);
- volume_base = 3071;
- volume_scale = 4;
- volume_method = VOL_METHOD_ADAGIO;
-
- for (i = 0; i < 32; i++)
- {
- gus_voice_init(i); /* Turn voice off */
- gus_voice_init2(i);
- }
-}
-
-static void gus_initialize(void)
-{
- unsigned long flags;
- unsigned char dma_image, irq_image, tmp;
-
- static unsigned char gus_irq_map[16] = {
- 0, 0, 0, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7
- };
-
- static unsigned char gus_dma_map[8] = {
- 0, 1, 0, 2, 0, 3, 4, 5
- };
-
- spin_lock_irqsave(&gus_lock,flags);
- gus_write8(0x4c, 0); /* Reset GF1 */
- gus_delay();
- gus_delay();
-
- gus_write8(0x4c, 1); /* Release Reset */
- gus_delay();
- gus_delay();
-
- /*
- * Clear all interrupts
- */
-
- gus_write8(0x41, 0); /* DMA control */
- gus_write8(0x45, 0); /* Timer control */
- gus_write8(0x49, 0); /* Sample control */
-
- gus_select_max_voices(24);
-
- inb(u_Status); /* Touch the status register */
-
- gus_look8(0x41); /* Clear any pending DMA IRQs */
- gus_look8(0x49); /* Clear any pending sample IRQs */
- gus_read8(0x0f); /* Clear pending IRQs */
-
- gus_reset(); /* Resets all voices */
-
- gus_look8(0x41); /* Clear any pending DMA IRQs */
- gus_look8(0x49); /* Clear any pending sample IRQs */
- gus_read8(0x0f); /* Clear pending IRQs */
-
- gus_write8(0x4c, 7); /* Master reset | DAC enable | IRQ enable */
-
- /*
- * Set up for Digital ASIC
- */
-
- outb((0x05), gus_base + 0x0f);
-
- mix_image |= 0x02; /* Disable line out (for a moment) */
- outb((mix_image), u_Mixer);
-
- outb((0x00), u_IRQDMAControl);
-
- outb((0x00), gus_base + 0x0f);
-
- /*
- * Now set up the DMA and IRQ interface
- *
- * The GUS supports two IRQs and two DMAs.
- *
- * Just one DMA channel is used. This prevents simultaneous ADC and DAC.
- * Adding this support requires significant changes to the dmabuf.c, dsp.c
- * and audio.c also.
- */
-
- irq_image = 0;
- tmp = gus_irq_map[gus_irq];
- if (!gus_pnp_flag && !tmp)
- printk(KERN_WARNING "Warning! GUS IRQ not selected\n");
- irq_image |= tmp;
- irq_image |= 0x40; /* Combine IRQ1 (GF1) and IRQ2 (Midi) */
-
- dual_dma_mode = 1;
- if (gus_dma2 == gus_dma || gus_dma2 == -1)
- {
- dual_dma_mode = 0;
- dma_image = 0x40; /* Combine DMA1 (DRAM) and IRQ2 (ADC) */
-
- tmp = gus_dma_map[gus_dma];
- if (!tmp)
- printk(KERN_WARNING "Warning! GUS DMA not selected\n");
-
- dma_image |= tmp;
- }
- else
- {
- /* Setup dual DMA channel mode for GUS MAX */
-
- dma_image = gus_dma_map[gus_dma];
- if (!dma_image)
- printk(KERN_WARNING "Warning! GUS DMA not selected\n");
-
- tmp = gus_dma_map[gus_dma2] << 3;
- if (!tmp)
- {
- printk(KERN_WARNING "Warning! Invalid GUS MAX DMA\n");
- tmp = 0x40; /* Combine DMA channels */
- dual_dma_mode = 0;
- }
- dma_image |= tmp;
- }
-
- /*
- * For some reason the IRQ and DMA addresses must be written twice
- */
-
- /*
- * Doing it first time
- */
-
- outb((mix_image), u_Mixer); /* Select DMA control */
- outb((dma_image | 0x80), u_IRQDMAControl); /* Set DMA address */
-
- outb((mix_image | 0x40), u_Mixer); /* Select IRQ control */
- outb((irq_image), u_IRQDMAControl); /* Set IRQ address */
-
- /*
- * Doing it second time
- */
-
- outb((mix_image), u_Mixer); /* Select DMA control */
- outb((dma_image), u_IRQDMAControl); /* Set DMA address */
-
- outb((mix_image | 0x40), u_Mixer); /* Select IRQ control */
- outb((irq_image), u_IRQDMAControl); /* Set IRQ address */
-
- gus_select_voice(0); /* This disables writes to IRQ/DMA reg */
-
- mix_image &= ~0x02; /* Enable line out */
- mix_image |= 0x08; /* Enable IRQ */
- outb((mix_image), u_Mixer); /*
- * Turn mixer channels on
- * Note! Mic in is left off.
- */
-
- gus_select_voice(0); /* This disables writes to IRQ/DMA reg */
-
- gusintr(gus_irq, (void *)gus_hw_config, NULL); /* Serve pending interrupts */
-
- inb(u_Status); /* Touch the status register */
-
- gus_look8(0x41); /* Clear any pending DMA IRQs */
- gus_look8(0x49); /* Clear any pending sample IRQs */
-
- gus_read8(0x0f); /* Clear pending IRQs */
-
- if (iw_mode)
- gus_write8(0x19, gus_read8(0x19) | 0x01);
- spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-
-static void __init pnp_mem_init(void)
-{
-#include "iwmem.h"
-#define CHUNK_SIZE (256*1024)
-#define BANK_SIZE (4*1024*1024)
-#define CHUNKS_PER_BANK (BANK_SIZE/CHUNK_SIZE)
-
- int bank, chunk, addr, total = 0;
- int bank_sizes[4];
- int i, j, bits = -1, testbits = -1, nbanks = 0;
-
- /*
- * This routine determines what kind of RAM is installed in each of the four
- * SIMM banks and configures the DRAM address decode logic accordingly.
- */
-
- /*
- * Place the chip into enhanced mode
- */
- gus_write8(0x19, gus_read8(0x19) | 0x01);
- gus_write8(0x53, gus_look8(0x53) & ~0x02); /* Select DRAM I/O access */
-
- /*
- * Set memory configuration to 4 DRAM banks of 4M in each (16M total).
- */
-
- gus_write16(0x52, (gus_look16(0x52) & 0xfff0) | 0x000c);
-
- /*
- * Perform the DRAM size detection for each bank individually.
- */
- for (bank = 0; bank < 4; bank++)
- {
- int size = 0;
-
- addr = bank * BANK_SIZE;
-
- /* Clean check points of each chunk */
- for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++)
- {
- gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00);
- gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00);
- }
-
- /* Write a value to each chunk point and verify the result */
- for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++)
- {
- gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x55);
- gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0xAA);
-
- if (gus_peek(addr + chunk * CHUNK_SIZE + 0L) == 0x55 &&
- gus_peek(addr + chunk * CHUNK_SIZE + 1L) == 0xAA)
- {
- /* OK. There is RAM. Now check for possible shadows */
- int ok = 1, chunk2;
-
- for (chunk2 = 0; ok && chunk2 < chunk; chunk2++)
- if (gus_peek(addr + chunk2 * CHUNK_SIZE + 0L) ||
- gus_peek(addr + chunk2 * CHUNK_SIZE + 1L))
- ok = 0; /* Addressing wraps */
-
- if (ok)
- size = (chunk + 1) * CHUNK_SIZE;
- }
- gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00);
- gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00);
- }
- bank_sizes[bank] = size;
- if (size)
- nbanks = bank + 1;
- DDB(printk("Interwave: Bank %d, size=%dk\n", bank, size / 1024));
- }
-
- if (nbanks == 0) /* No RAM - Give up */
- {
- printk(KERN_ERR "Sound: An Interwave audio chip detected but no DRAM\n");
- printk(KERN_ERR "Sound: Unable to work with this card.\n");
- gus_write8(0x19, gus_read8(0x19) & ~0x01);
- gus_mem_size = 0;
- return;
- }
-
- /*
- * Now we know how much DRAM there is in each bank. The next step is
- * to find a DRAM size encoding (0 to 12) which is best for the combination
- * we have.
- *
- * First try if any of the possible alternatives matches exactly the amount
- * of memory we have.
- */
-
- for (i = 0; bits == -1 && i < 13; i++)
- {
- bits = i;
-
- for (j = 0; bits != -1 && j < 4; j++)
- if (mem_decode[i][j] != bank_sizes[j])
- bits = -1; /* No hit */
- }
-
- /*
- * If necessary, try to find a combination where other than the last
- * bank matches our configuration and the last bank is left oversized.
- * In this way we don't leave holes in the middle of memory.
- */
-
- if (bits == -1) /* No luck yet */
- {
- for (i = 0; bits == -1 && i < 13; i++)
- {
- bits = i;
-
- for (j = 0; bits != -1 && j < nbanks - 1; j++)
- if (mem_decode[i][j] != bank_sizes[j])
- bits = -1; /* No hit */
- if (mem_decode[i][nbanks - 1] < bank_sizes[nbanks - 1])
- bits = -1; /* The last bank is too small */
- }
- }
- /*
- * The last resort is to search for a combination where the banks are
- * smaller than the actual SIMMs. This leaves some memory in the banks
- * unused but doesn't leave holes in the DRAM address space.
- */
- if (bits == -1) /* No luck yet */
- {
- for (i = 0; i < 13; i++)
- {
- testbits = i;
- for (j = 0; testbits != -1 && j < nbanks - 1; j++)
- if (mem_decode[i][j] > bank_sizes[j]) {
- testbits = -1;
- }
- if(testbits > bits) bits = testbits;
- }
- if (bits != -1)
- {
- printk(KERN_INFO "Interwave: Can't use all installed RAM.\n");
- printk(KERN_INFO "Interwave: Try reordering SIMMS.\n");
- }
- printk(KERN_INFO "Interwave: Can't find working DRAM encoding.\n");
- printk(KERN_INFO "Interwave: Defaulting to 256k. Try reordering SIMMS.\n");
- bits = 0;
- }
- DDB(printk("Interwave: Selecting DRAM addressing mode %d\n", bits));
-
- for (bank = 0; bank < 4; bank++)
- {
- DDB(printk(" Bank %d, mem=%dk (limit %dk)\n", bank, bank_sizes[bank] / 1024, mem_decode[bits][bank] / 1024));
-
- if (bank_sizes[bank] > mem_decode[bits][bank])
- total += mem_decode[bits][bank];
- else
- total += bank_sizes[bank];
- }
-
- DDB(printk("Total %dk of DRAM (enhanced mode)\n", total / 1024));
-
- /*
- * Set the memory addressing mode.
- */
- gus_write16(0x52, (gus_look16(0x52) & 0xfff0) | bits);
-
-/* Leave the chip into enhanced mode. Disable LFO */
- gus_mem_size = total;
- iw_mode = 1;
- gus_write8(0x19, (gus_read8(0x19) | 0x01) & ~0x02);
-}
-
-int __init gus_wave_detect(int baseaddr)
-{
- unsigned long i, max_mem = 1024L;
- unsigned long loc;
- unsigned char val;
-
- if (!request_region(baseaddr, 16, "GUS"))
- return 0;
- if (!request_region(baseaddr + 0x100, 12, "GUS")) { /* 0x10c-> is MAX */
- release_region(baseaddr, 16);
- return 0;
- }
-
- gus_base = baseaddr;
-
- gus_write8(0x4c, 0); /* Reset GF1 */
- gus_delay();
- gus_delay();
-
- gus_write8(0x4c, 1); /* Release Reset */
- gus_delay();
- gus_delay();
-
-#ifdef GUSPNP_AUTODETECT
- val = gus_look8(0x5b); /* Version number register */
- gus_write8(0x5b, ~val); /* Invert all bits */
-
- if ((gus_look8(0x5b) & 0xf0) == (val & 0xf0)) /* No change */
- {
- if ((gus_look8(0x5b) & 0x0f) == ((~val) & 0x0f)) /* Change */
- {
- DDB(printk("Interwave chip version %d detected\n", (val & 0xf0) >> 4));
- gus_pnp_flag = 1;
- }
- else
- {
- DDB(printk("Not an Interwave chip (%x)\n", gus_look8(0x5b)));
- gus_pnp_flag = 0;
- }
- }
- gus_write8(0x5b, val); /* Restore all bits */
-#endif
-
- if (gus_pnp_flag)
- pnp_mem_init();
- if (iw_mode)
- return 1;
-
- /* See if there is first block there.... */
- gus_poke(0L, 0xaa);
- if (gus_peek(0L) != 0xaa) {
- release_region(baseaddr + 0x100, 12);
- release_region(baseaddr, 16);
- return 0;
- }
-
- /* Now zero it out so that I can check for mirroring .. */
- gus_poke(0L, 0x00);
- for (i = 1L; i < max_mem; i++)
- {
- int n, failed;
-
- /* check for mirroring ... */
- if (gus_peek(0L) != 0)
- break;
- loc = i << 10;
-
- for (n = loc - 1, failed = 0; n <= loc; n++)
- {
- gus_poke(loc, 0xaa);
- if (gus_peek(loc) != 0xaa)
- failed = 1;
- gus_poke(loc, 0x55);
- if (gus_peek(loc) != 0x55)
- failed = 1;
- }
- if (failed)
- break;
- }
- gus_mem_size = i << 10;
- return 1;
-}
-
-static int guswave_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
-
- switch (cmd)
- {
- case SNDCTL_SYNTH_INFO:
- gus_info.nr_voices = nr_voices;
- if (copy_to_user(arg, &gus_info, sizeof(gus_info)))
- return -EFAULT;
- return 0;
-
- case SNDCTL_SEQ_RESETSAMPLES:
- reset_sample_memory();
- return 0;
-
- case SNDCTL_SEQ_PERCMODE:
- return 0;
-
- case SNDCTL_SYNTH_MEMAVL:
- return (gus_mem_size == 0) ? 0 : gus_mem_size - free_mem_ptr - 32;
-
- default:
- return -EINVAL;
- }
-}
-
-static int guswave_set_instr(int dev, int voice, int instr_no)
-{
- int sample_no;
-
- if (instr_no < 0 || instr_no > MAX_PATCH)
- instr_no = 0; /* Default to acoustic piano */
-
- if (voice < 0 || voice > 31)
- return -EINVAL;
-
- if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
- {
- voices[voice].sample_pending = instr_no;
- return 0;
- }
- sample_no = patch_table[instr_no];
- patch_map[voice] = -1;
-
- if (sample_no == NOT_SAMPLE)
- {
-/* printk("GUS: Undefined patch %d for voice %d\n", instr_no, voice);*/
- return -EINVAL; /* Patch not defined */
- }
- if (sample_ptrs[sample_no] == -1) /* Sample not loaded */
- {
-/* printk("GUS: Sample #%d not loaded for patch %d (voice %d)\n", sample_no, instr_no, voice);*/
- return -EINVAL;
- }
- sample_map[voice] = sample_no;
- patch_map[voice] = instr_no;
- return 0;
-}
-
-static int guswave_kill_note(int dev, int voice, int note, int velocity)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&gus_lock,flags);
- /* voice_alloc->map[voice] = 0xffff; */
- if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
- {
- voices[voice].kill_pending = 1;
- spin_unlock_irqrestore(&gus_lock,flags);
- }
- else
- {
- spin_unlock_irqrestore(&gus_lock,flags);
- gus_voice_fade(voice);
- }
-
- return 0;
-}
-
-static void guswave_aftertouch(int dev, int voice, int pressure)
-{
-}
-
-static void guswave_panning(int dev, int voice, int value)
-{
- if (voice >= 0 || voice < 32)
- voices[voice].panning = value;
-}
-
-static void guswave_volume_method(int dev, int mode)
-{
- if (mode == VOL_METHOD_LINEAR || mode == VOL_METHOD_ADAGIO)
- volume_method = mode;
-}
-
-static void compute_volume(int voice, int volume)
-{
- if (volume < 128)
- voices[voice].midi_volume = volume;
-
- switch (volume_method)
- {
- case VOL_METHOD_ADAGIO:
- voices[voice].initial_volume =
- gus_adagio_vol(voices[voice].midi_volume, voices[voice].main_vol,
- voices[voice].expression_vol,
- voices[voice].patch_vol);
- break;
-
- case VOL_METHOD_LINEAR: /* Totally ignores patch-volume and expression */
- voices[voice].initial_volume = gus_linear_vol(volume, voices[voice].main_vol);
- break;
-
- default:
- voices[voice].initial_volume = volume_base +
- (voices[voice].midi_volume * volume_scale);
- }
-
- if (voices[voice].initial_volume > 4030)
- voices[voice].initial_volume = 4030;
-}
-
-static void compute_and_set_volume(int voice, int volume, int ramp_time)
-{
- int curr, target, rate;
- unsigned long flags;
-
- compute_volume(voice, volume);
- voices[voice].current_volume = voices[voice].initial_volume;
-
- spin_lock_irqsave(&gus_lock,flags);
- /*
- * CAUTION! Interrupts disabled. Enable them before returning
- */
-
- gus_select_voice(voice);
-
- curr = gus_read16(0x09) >> 4;
- target = voices[voice].initial_volume;
-
- if (ramp_time == INSTANT_RAMP)
- {
- gus_rampoff();
- gus_voice_volume(target);
- spin_unlock_irqrestore(&gus_lock,flags);
- return;
- }
- if (ramp_time == FAST_RAMP)
- rate = 63;
- else
- rate = 16;
- gus_ramp_rate(0, rate);
-
- if ((target - curr) / 64 == 0) /* Close enough to target. */
- {
- gus_rampoff(