4 * Driver for the Gravis UltraSound wave table synth.
6 * Copyright by Hannu Savolainen 1993, 1994
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met: 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 2.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * $FreeBSD: src/sys/i386/isa/sound/gus_wave.c,v 1.32 1999/12/20 18:05:00 eivind Exp $
29 * $DragonFly: src/sys/dev/sound/isa/i386/gus/Attic/gus_wave.c,v 1.2 2003/06/17 04:28:38 dillon Exp $
34 #include <i386/isa/sound/sound_config.h>
35 #include <i386/isa/sound/ultrasound.h>
36 #include <i386/isa/sound/gus_hw.h>
37 #include <i386/isa/sound/iwdefs.h>
38 #include <machine/clock.h>
41 #define GUS_PNP_ID 0x100561e
44 #define MAX_GUS_PNP 12
48 #define PADDRESS 0x279
49 #define PWRITE_DATA 0xa79
53 /* PnP Registers. Write to ADDRESS and then use WRITE/READ_DATA */
54 #define SET_RD_DATA 0x00
55 #define SERIAL_ISOLATION 0x01
58 #if defined(CONFIG_GUS)
61 #define ENTER_CRITICAL
63 #define LEAVE_CRITICAL
65 #define MAX_SAMPLE 150
69 static u_int gus_pnp_found[MAX_GUS_PNP] =
70 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
82 int loop_irq_mode, loop_irq_parm;
83 #define LMODE_FINISH 1
85 #define LMODE_PCM_STOP 3
86 int volume_irq_mode, volume_irq_parm;
88 #define VMODE_ENVELOPE 2
89 #define VMODE_START_NOTE 3
96 * Volume computation parameters for gus_adagio_vol()
98 int main_vol, expression_vol, patch_vol;
100 /* Variables for "Ultraclick" removal */
101 int dev_pending, note_pending, volume_pending, sample_pending;
107 static struct voice_alloc_info *voice_alloc;
110 extern int gus_irq, gus_dma;
111 static int gus_dma2 = -1;
112 static int dual_dma_mode = 0;
113 static long gus_mem_size = 0;
114 static long free_mem_ptr = 0;
115 static int gus_no_dma = 0;
116 static int nr_voices = 0;
117 static int gus_devnum = 0;
118 static int volume_base, volume_scale, volume_method;
119 static int gus_recmask = SOUND_MASK_MIC;
120 static int recording_active = 0;
121 static int only_read_access = 0;
122 static int only_8_bits = 0;
124 int gus_wave_volume = 60;
125 static int gus_pcm_volume = 80;
126 int have_gus_max = 0;
127 static int gus_line_vol = 100, gus_mic_vol = 0;
128 static u_char mix_image = 0x00;
130 int gus_timer_enabled = 0;
132 * Current version of this driver doesn't allow synth and PCM functions at
133 * the same time. The active_device specifies the active driver
135 static int active_device = 0;
137 #define GUS_DEV_WAVE 1 /* Wave table synth */
138 #define GUS_DEV_PCM_DONE 2 /* PCM device, transfer done */
139 #define GUS_DEV_PCM_CONTINUE 3 /* PCM device, transfer done ch. 1/2 */
141 static int gus_sampling_speed;
142 static int gus_sampling_channels;
143 static int gus_sampling_bits;
145 static int *dram_sleeper = NULL;
146 static volatile struct snd_wait dram_sleep_flag =
150 * Variables and buffers for PCM output
152 #define MAX_PCM_BUFFERS (32*MAX_REALTIME_FACTOR) /* Don't change */
154 static int pcm_bsize, pcm_nblk, pcm_banksize;
155 static int pcm_datasize[MAX_PCM_BUFFERS];
156 static volatile int pcm_head, pcm_tail, pcm_qlen;
157 static volatile int pcm_active;
158 static volatile int dma_active;
159 static int pcm_opened = 0;
160 static int pcm_current_dev;
161 static int pcm_current_block;
162 static u_long pcm_current_buf;
163 static int pcm_current_count;
164 static int pcm_current_intrflag;
166 extern sound_os_info *gus_osp;
168 static struct voice_info voices[32];
170 static int freq_div_table[] =
193 static struct patch_info *samples;
194 static struct patch_info *dbg_samples;
195 static int dbg_samplep;
197 static long sample_ptrs[MAX_SAMPLE + 1];
198 static int sample_map[32];
199 static int free_sample;
200 static int mixer_type = 0;
203 static int patch_table[MAX_PATCH];
204 static int patch_map[32];
206 static struct synth_info gus_info =
207 {"Gravis UltraSound", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS, 0, 16, 0, MAX_PATCH};
209 static void gus_default_mixer_init(void);
211 static int guswave_start_note2(int dev, int voice, int note_num, int volume);
212 static void gus_poke(long addr, u_char data);
213 static void compute_and_set_volume(int voice, int volume, int ramp_time);
214 extern u_short gus_adagio_vol(int vel, int mainv, int xpn, int voicev);
215 extern u_short gus_linear_vol(int vol, int mainvol);
216 static void compute_volume(int voice, int volume);
217 static void do_volume_irq(int voice);
218 static void set_input_volumes(void);
219 static void gus_tmr_install(int io_base);
221 static void SEND(int d, int r);
222 static int get_serial(int rd_port, u_char *data);
223 static void send_Initiation_LFSR(void);
224 static int isolation_protocol(int rd_port);
227 #define INSTANT_RAMP -1 /* Instant change. No ramping */
228 #define FAST_RAMP 0 /* Fastest possible ramp */
232 #define CODEC_XTAL2 0x01 /* 16.9344 crystal */
233 #define CODEC_XTAL1 0x00 /* 24.576 crystal */
234 /************************************************************************/
236 /************************************************************************/
237 /* Definitions for CONFIG_1 register */
238 #define CODEC_CFIG1I_DEFAULT 0x03 | 0x8
239 #define CODEC_CAPTURE_PIO 0x80 /* Capture PIO enable */
240 #define CODEC_PLAYBACK_PIO 0x40 /* Playback PIO enable */
241 #define CODEC_AUTOCALIB 0x08 /* auto calibrate */
242 #define CODEC_SINGLE_DMA 0x04 /* Use single DMA channel */
243 #define CODEC_RE 0x02 /* Capture enable */
244 #define CODEC_PE 0x01 /* playback enable */
245 /************************************************************************/
247 /************************************************************************/
248 /* Definitions for CONFIG_2 register */
249 #define CODEC_CFIG2I_DEFAULT 0x81
250 #define CODEC_OFVS 0x80 /* Output Full Scale Voltage */
251 #define CODEC_TE 0x40 /* Timer Enable */
252 #define CODEC_RSCD 0x20 /* Recors Sample Counter Disable */
253 #define CODEC_PSCD 0x10 /* Playback Sample Counter Disable */
254 #define CODEC_DAOF 0x01 /* D/A Ouput Force Enable */
255 /************************************************************************/
257 /************************************************************************/
258 /* Definitions for CONFIG_3 register */
259 /* #define CODEC_CFIG3I_DEFAULT 0xe0 0x02 when synth DACs are working */
261 #define CODEC_CFIG3I_DEFAULT 0xc0 /* 0x02 when synth DACs are working */
262 #define CODEC_RPIE 0x80 /* Record FIFO IRQ Enable */
263 #define CODEC_PPIE 0x40 /* Playback FIFO IRQ Enable */
264 #define CODEC_FT_MASK 0x30 /* FIFO Threshold Select */
265 #define CODEC_PVFM 0x04 /* Playback Variable Frequency Mode */
266 #define CODEC_SYNA 0x02 /* AUX1/Synth Signal Select */
267 /************************************************************************/
269 /************************************************************************/
270 /* Definitions for EXTERNAL_CONTROL register */
271 #define CODEC_CEXTI_DEFAULT 0x00
272 #define CODEC_IRQ_ENABLE 0x02 /* interrupt enable */
273 #define CODEC_GPOUT1 0x80 /* external control #1 */
274 #define CODEC_GPOUT0 0x40 /* external control #0 */
275 /************************************************************************/
277 /************************************************************************/
278 /* Definitions for MODE_SELECT_ID register */
279 #define CODEC_MODE_DEFAULT 0x40
280 #define CODEC_MODE_MASK 0x60
281 #define CODEC_ID_BIT4 0x80
282 #define CODEC_ID_BIT3_0 0x0F
283 /************************************************************************/
284 #define CONFIG_1 0x09
285 #define EXTERNAL_CONTROL 0x0a/* Pin control */
286 #define STATUS_2 0x0b/* Test and initialization */
287 #define MODE_SELECT_ID 0x0c/* Miscellaneaous information */
288 #define LOOPBACK 0x0d/* Digital Mix */
289 #define UPPER_PLAY_COUNT 0x0e/* Playback Upper Base Count */
290 #define LOWER_PLAY_COUNT 0x0f/* Playback Lower Base Count */
291 #define CONFIG_2 0x10
292 #define CONFIG_3 0x11
295 #define IWL_CODEC_OUT(reg, val) \
296 { outb(iwl_codec_base, reg); outb(iwl_codec_data, val); }
298 #define IWL_CODEC_IN(reg, val) \
299 { outb(iwl_codec_base, reg); val = inb(iwl_codec_data); }
302 static u_char gus_look8(int reg);
304 static void gus_write16(int reg, u_int data);
306 static u_short gus_read16(int reg);
308 static void gus_write_addr(int reg, u_long address, int is16bit);
309 static void IwaveLineLevel(char level, char index);
310 static void IwaveInputSource(BYTE index, BYTE source);
311 static void IwavePnpGetCfg(void);
312 static void IwavePnpDevice(BYTE dev);
313 static void IwavePnpSetCfg(void);
314 static void IwavePnpKey(void);
315 static BYTE IwavePnpIsol(PORT * pnpread);
316 static void IwavePnpPeek(PORT pnprdp, WORD bytes, BYTE * data);
317 static void IwavePnpActivate(BYTE dev, BYTE bool);
318 static void IwavePnpWake(BYTE csn);
319 static BYTE IwavePnpPing(DWORD VendorID);
320 static WORD IwaveMemSize(void);
321 static BYTE IwaveMemPeek(ADDRESS addr);
322 static void IwaveMemPoke(ADDRESS addr, BYTE datum);
323 static void IwaveMemCfg(DWORD * lpbanks);
324 static void IwaveCodecIrq(BYTE mode);
325 static WORD IwaveRegPeek(DWORD reg_mnem);
327 static void IwaveRegPoke(DWORD reg_mnem, WORD datum);
328 static void IwaveCodecMode(char mode);
329 static void IwaveLineMute(BYTE mute, BYTE inx);
330 static void Iwaveinitcodec(void);
331 int IwaveOpen(char voices, char mode, struct address_info * hw);
335 reset_sample_memory(void)
339 for (i = 0; i <= MAX_SAMPLE; i++)
341 for (i = 0; i < 32; i++)
343 for (i = 0; i < 32; i++)
346 gus_poke(0, 0); /* Put a silent sample to the beginning */
352 for (i = 0; i < MAX_PATCH; i++)
361 for (i = 0; i < 7; i++)
366 gus_poke(long addr, u_char data)
367 { /* Writes a byte to the DRAM */
371 outb(u_Command, 0x43);
372 outb(u_DataLo, addr & 0xff);
373 outb(u_DataHi, (addr >> 8) & 0xff);
375 outb(u_Command, 0x44);
376 outb(u_DataHi, (addr >> 16) & 0xff);
377 outb(u_DRAMIO, data);
383 { /* Reads a byte from the DRAM */
388 outb(u_Command, 0x43);
389 outb(u_DataLo, addr & 0xff);
390 outb(u_DataHi, (addr >> 8) & 0xff);
392 outb(u_Command, 0x44);
393 outb(u_DataHi, (addr >> 16) & 0xff);
401 gus_write8(int reg, u_int data)
402 { /* Writes to an indirect register (8 bit) */
406 outb(u_Command, reg);
407 outb(u_DataHi, (u_char) (data & 0xff));
413 { /* Reads from an indirect register (8 bit). Offset 0x80. */
418 outb(u_Command, reg | 0x80);
427 { /* Reads from an indirect register (8 bit). No additional offset. */
432 outb(u_Command, reg);
440 gus_write16(int reg, u_int data)
441 { /* Writes to an indirect register (16 bit) */
446 outb(u_Command, reg);
448 outb(u_DataLo, (u_char) (data & 0xff));
449 outb(u_DataHi, (u_char) ((data >> 8) & 0xff));
456 { /* Reads from an indirect register (16 bit). Offset 0x80. */
462 outb(u_Command, reg | 0x80);
469 return ((hi << 8) & 0xff00) | lo;
473 gus_write_addr(int reg, u_long address, int is16bit)
474 { /* Writes an 24 bit memory address */
481 * Special processing required for 16 bit patches
484 hold_address = address;
485 address = address >> 1;
486 address &= 0x0001ffffL;
487 address |= (hold_address & 0x000c0000L);
489 gus_write16(reg, (u_short) ((address >> 7) & 0xffff));
490 gus_write16(reg + 1, (u_short) ((address << 9) & 0xffff));
492 * Could writing twice fix problems with GUS_VOICE_POS() ? Lets try...
495 gus_write16(reg, (u_short) ((address >> 7) & 0xffff));
496 gus_write16(reg + 1, (u_short) ((address << 9) & 0xffff));
501 gus_select_voice(int voice)
503 if (voice < 0 || voice > 31)
506 outb(u_Voice, voice);
510 gus_select_max_voices(int nvoices)
517 voice_alloc->max_voice = nr_voices = nvoices;
519 gus_write8(0x0e, (nvoices - 1) | 0xc0);
523 gus_voice_on(u_int mode)
525 gus_write8(0x00, (u_char) (mode & 0xfc));
527 gus_write8(0x00, (u_char) (mode & 0xfc));
533 gus_write8(0x00, gus_read8(0x00) | 0x03);
537 gus_voice_mode(u_int m)
539 u_char mode = (u_char) (m & 0xff);
541 gus_write8(0x00, (gus_read8(0x00) & 0x03) |
542 (mode & 0xfc)); /* Don't touch last two bits */
544 gus_write8(0x00, (gus_read8(0x00) & 0x03) | (mode & 0xfc));
548 gus_voice_freq(u_long freq)
550 u_long divisor = freq_div_table[nr_voices - 14];
553 fc = (u_short) (((freq << 9) + (divisor >> 1)) / divisor);
556 gus_write16(0x01, fc);
560 gus_voice_volume(u_int vol)
562 gus_write8(0x0d, 0x03); /* Stop ramp before setting volume */
563 gus_write16(0x09, (u_short) (vol << 4));
567 gus_voice_balance(u_int balance)
569 gus_write8(0x0c, (u_char) (balance & 0xff));
573 gus_ramp_range(u_int low, u_int high)
575 gus_write8(0x07, (u_char) ((low >> 4) & 0xff));
576 gus_write8(0x08, (u_char) ((high >> 4) & 0xff));
580 gus_ramp_rate(u_int scale, u_int rate)
582 gus_write8(0x06, (u_char) (((scale & 0x03) << 6) | (rate & 0x3f)));
588 u_char mode = (u_char) (m & 0xff);
590 gus_write8(0x0d, mode & 0xfc);
592 gus_write8(0x0d, mode & 0xfc);
596 gus_ramp_mode(u_int m)
598 u_char mode = (u_char) (m & 0xff);
600 gus_write8(0x0d, (gus_read8(0x0d) & 0x03) |
601 (mode & 0xfc)); /* Leave the last 2 bits alone */
603 gus_write8(0x0d, (gus_read8(0x0d) & 0x03) | (mode & 0xfc));
609 gus_write8(0x0d, 0x03);
613 gus_set_voice_pos(int voice, long position)
617 if ((sample_no = sample_map[voice]) != -1) {
618 if (position < samples[sample_no].len) {
619 if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
620 voices[voice].offset_pending = position;
622 gus_write_addr(0x0a, sample_ptrs[sample_no] + position,
623 samples[sample_no].mode & WAVE_16_BITS);
629 gus_voice_init(int voice)
634 gus_select_voice(voice);
637 gus_write_addr(0x0a, 0, 0); /* Set current position to 0 */
638 gus_write8(0x00, 0x03); /* Voice off */
639 gus_write8(0x0d, 0x03); /* Ramping off */
640 voice_alloc->map[voice] = 0;
641 voice_alloc->alloc_times[voice] = 0;
647 gus_voice_init2(int voice)
649 voices[voice].panning = 0;
650 voices[voice].mode = 0;
651 voices[voice].orig_freq = 20000;
652 voices[voice].current_freq = 20000;
653 voices[voice].bender = 0;
654 voices[voice].bender_range = 200;
655 voices[voice].initial_volume = 0;
656 voices[voice].current_volume = 0;
657 voices[voice].loop_irq_mode = 0;
658 voices[voice].loop_irq_parm = 0;
659 voices[voice].volume_irq_mode = 0;
660 voices[voice].volume_irq_parm = 0;
661 voices[voice].env_phase = 0;
662 voices[voice].main_vol = 127;
663 voices[voice].patch_vol = 127;
664 voices[voice].expression_vol = 127;
665 voices[voice].sample_pending = -1;
669 step_envelope(int voice)
671 u_int vol, prev_vol, phase;
675 if (voices[voice].mode & WAVE_SUSTAIN_ON && voices[voice].env_phase == 2) {
677 gus_select_voice(voice);
682 * Sustain phase begins. Continue envelope after receiving
686 if (voices[voice].env_phase >= 5) { /* Envelope finished. Shoot
688 gus_voice_init(voice);
691 prev_vol = voices[voice].current_volume;
692 phase = ++voices[voice].env_phase;
693 compute_volume(voice, voices[voice].midi_volume);
694 vol = voices[voice].initial_volume * voices[voice].env_offset[phase] / 255;
695 rate = voices[voice].env_rate[phase];
698 gus_select_voice(voice);
699 gus_voice_volume(prev_vol);
700 gus_write8(0x06, rate); /* Ramping rate */
702 voices[voice].volume_irq_mode = VMODE_ENVELOPE;
704 if (((vol - prev_vol) / 64) == 0) { /* No significant volume
707 step_envelope(voice); /* Continue the envelope on the next
711 if (vol > prev_vol) {
712 if (vol >= (4096 - 64))
714 gus_ramp_range(0, vol);
715 gus_rampon(0x20); /* Increasing volume, with IRQ */
719 gus_ramp_range(vol, 4030);
720 gus_rampon(0x60); /* Decreasing volume, with IRQ */
722 voices[voice].current_volume = vol;
727 init_envelope(int voice)
729 voices[voice].env_phase = -1;
730 voices[voice].current_volume = 64;
732 step_envelope(voice);
736 start_release(int voice, long int flags)
738 if (gus_read8(0x00) & 0x03)
739 return; /* Voice already stopped */
741 voices[voice].env_phase = 2; /* Will be incremented by
744 voices[voice].current_volume =
745 voices[voice].initial_volume =
746 gus_read16(0x09) >> 4; /* Get current volume */
748 voices[voice].mode &= ~WAVE_SUSTAIN_ON;
751 step_envelope(voice);
755 gus_voice_fade(int voice)
757 int instr_no = sample_map[voice], is16bits;
761 gus_select_voice(voice);
763 if (instr_no < 0 || instr_no > MAX_SAMPLE) {
764 gus_write8(0x00, 0x03); /* Hard stop */
765 voice_alloc->map[voice] = 0;
769 is16bits = (samples[instr_no].mode & WAVE_16_BITS) ? 1 : 0; /* 8 or 16 bits */
771 if (voices[voice].mode & WAVE_ENVELOPES) {
772 start_release(voice, flags);
776 * Ramp the volume down but not too quickly.
778 if ((int) (gus_read16(0x09) >> 4) < 100) { /* Get current volume */
781 gus_voice_init(voice);
784 gus_ramp_range(65, 4030);
786 gus_rampon(0x40 | 0x20);/* Down, once, with IRQ */
787 voices[voice].volume_irq_mode = VMODE_HALT;
796 gus_select_max_voices(24);
799 volume_method = VOL_METHOD_ADAGIO;
801 for (i = 0; i < 32; i++) {
802 gus_voice_init(i); /* Turn voice off */
806 inb(u_Status); /* Touch the status register */
808 gus_look8(0x41); /* Clear any pending DMA IRQs */
809 gus_look8(0x49); /* Clear any pending sample IRQs */
811 gus_read8(0x0f); /* Clear pending IRQs */
819 u_char dma_image, irq_image, tmp;
821 static u_char gus_irq_map[16] =
822 {0, 0, 0, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7};
824 static u_char gus_dma_map[8] =
825 {0, 1, 0, 2, 0, 3, 4, 5};
828 gus_write8(0x4c, 0); /* Reset GF1 */
832 gus_write8(0x4c, 1); /* Release Reset */
837 * Clear all interrupts
840 gus_write8(0x41, 0); /* DMA control */
841 gus_write8(0x45, 0); /* Timer control */
842 gus_write8(0x49, 0); /* Sample control */
844 gus_select_max_voices(24);
846 inb(u_Status); /* Touch the status register */
848 gus_look8(0x41); /* Clear any pending DMA IRQs */
849 gus_look8(0x49); /* Clear any pending sample IRQs */
850 gus_read8(0x0f); /* Clear pending IRQs */
852 gus_reset(); /* Resets all voices */
854 gus_look8(0x41); /* Clear any pending DMA IRQs */
855 gus_look8(0x49); /* Clear any pending sample IRQs */
856 gus_read8(0x0f); /* Clear pending IRQs */
858 gus_write8(0x4c, 7); /* Master reset | DAC enable | IRQ enable */
861 * Set up for Digital ASIC
864 outb(gus_base + 0x0f, 0x05);
866 mix_image |= 0x02; /* Disable line out (for a moment) */
867 outb(u_Mixer, mix_image);
869 outb(u_IRQDMAControl, 0x00);
871 outb(gus_base + 0x0f, 0x00);
874 * Now set up the DMA and IRQ interface
876 * The GUS supports two IRQs and two DMAs.
878 * Just one DMA channel is used. This prevents simultaneous ADC and DAC.
879 * Adding this support requires significant changes to the dmabuf.c,
880 * dsp.c and audio.c also.
884 tmp = gus_irq_map[gus_irq];
886 printf("Warning! GUS IRQ not selected\n");
888 irq_image |= 0x40; /* Combine IRQ1 (GF1) and IRQ2 (Midi) */
891 if (gus_dma2 == gus_dma || gus_dma2 == -1) {
893 dma_image = 0x40; /* Combine DMA1 (DRAM) and IRQ2 (ADC) */
895 tmp = gus_dma_map[gus_dma];
897 printf("Warning! GUS DMA not selected\n");
901 /* Setup dual DMA channel mode for GUS MAX */
903 dma_image = gus_dma_map[gus_dma];
905 printf("Warning! GUS DMA not selected\n");
907 tmp = gus_dma_map[gus_dma2] << 3;
909 printf("Warning! Invalid GUS MAX DMA\n");
910 tmp = 0x40; /* Combine DMA channels */
917 * For some reason the IRQ and DMA addresses must be written twice
921 * Doing it first time
924 outb(u_Mixer, mix_image); /* Select DMA control */
925 outb(u_IRQDMAControl, dma_image | 0x80); /* Set DMA address */
927 outb(u_Mixer, mix_image | 0x40); /* Select IRQ control */
928 outb(u_IRQDMAControl, irq_image); /* Set IRQ address */
931 * Doing it second time
934 outb(u_Mixer, mix_image); /* Select DMA control */
935 outb(u_IRQDMAControl, dma_image); /* Set DMA address */
937 outb(u_Mixer, mix_image | 0x40); /* Select IRQ control */
938 outb(u_IRQDMAControl, irq_image); /* Set IRQ address */
940 gus_select_voice(0); /* This disables writes to IRQ/DMA reg */
942 mix_image &= ~0x02; /* Enable line out */
943 mix_image |= 0x08; /* Enable IRQ */
944 outb(u_Mixer, mix_image); /* Turn mixer channels on Note! Mic
947 gus_select_voice(0); /* This disables writes to IRQ/DMA reg */
949 gusintr(0); /* Serve pending interrupts */
954 gus_wave_detect(int baseaddr)
960 gus_write8(0x4c, 0); /* Reset GF1 */
964 gus_write8(0x4c, 1); /* Release Reset */
968 /* See if there is first block there.... */
970 if (gus_peek(0L) != 0xaa)
973 /* Now zero it out so that I can check for mirroring .. */
975 for (i = 1L; i < 1024L; i++) {
978 /* check for mirroring ... */
979 if (gus_peek(0L) != 0)
983 for (n = loc - 1, failed = 0; n <= loc; n++) {
985 if (gus_peek(loc) != 0xaa)
989 if (gus_peek(loc) != 0x55)
996 gus_mem_size = i << 10;
1001 guswave_ioctl(int dev,
1002 u_int cmd, ioctl_arg arg)
1006 case SNDCTL_SYNTH_INFO:
1007 gus_info.nr_voices = nr_voices;
1008 bcopy(&gus_info, &(((char *) arg)[0]), sizeof(gus_info));
1012 case SNDCTL_SEQ_RESETSAMPLES:
1013 reset_sample_memory();
1017 case SNDCTL_SEQ_PERCMODE:
1021 case SNDCTL_SYNTH_MEMAVL:
1022 return gus_mem_size - free_mem_ptr - 32;
1030 guswave_set_instr(int dev, int voice, int instr_no)
1034 if (instr_no < 0 || instr_no > MAX_PATCH)
1037 if (voice < 0 || voice > 31)
1040 if (voices[voice].volume_irq_mode == VMODE_START_NOTE) {
1041 voices[voice].sample_pending = instr_no;
1044 sample_no = patch_table[instr_no];
1045 patch_map[voice] = -1;
1047 if (sample_no < 0) {
1048 printf("GUS: Undefined patch %d for voice %d\n", instr_no, voice);
1049 return -(EINVAL); /* Patch not defined */
1051 if (sample_ptrs[sample_no] == -1) { /* Sample not loaded */
1052 printf("GUS: Sample #%d not loaded for patch %d (voice %d)\n",
1053 sample_no, instr_no, voice);
1056 sample_map[voice] = sample_no;
1057 patch_map[voice] = instr_no;
1062 guswave_kill_note(int dev, int voice, int note, int velocity)
1067 /* voice_alloc->map[voice] = 0xffff; */
1068 if (voices[voice].volume_irq_mode == VMODE_START_NOTE) {
1069 voices[voice].kill_pending = 1;
1073 gus_voice_fade(voice);
1081 guswave_aftertouch(int dev, int voice, int pressure)
1086 guswave_panning(int dev, int voice, int value)
1088 if (voice >= 0 || voice < 32)
1089 voices[voice].panning = value;
1093 guswave_volume_method(int dev, int mode)
1095 if (mode == VOL_METHOD_LINEAR || mode == VOL_METHOD_ADAGIO)
1096 volume_method = mode;
1100 compute_volume(int voice, int volume)
1103 voices[voice].midi_volume = volume;
1105 switch (volume_method) {
1106 case VOL_METHOD_ADAGIO:
1107 voices[voice].initial_volume =
1108 gus_adagio_vol(voices[voice].midi_volume, voices[voice].main_vol,
1109 voices[voice].expression_vol, voices[voice].patch_vol);
1112 case VOL_METHOD_LINEAR:/* Totally ignores patch-volume and expression */
1113 voices[voice].initial_volume =
1114 gus_linear_vol(volume, voices[voice].main_vol);
1118 voices[voice].initial_volume = volume_base +
1119 (voices[voice].midi_volume * volume_scale);
1122 if (voices[voice].initial_volume > 4030)
1123 voices[voice].initial_volume = 4030;
1127 compute_and_set_volume(int voice, int volume, int ramp_time)
1129 int curr, target, rate;
1132 compute_volume(voice, volume);
1133 voices[voice].current_volume = voices[voice].initial_volume;
1137 * CAUTION! Interrupts disabled. Enable them before returning
1140 gus_select_voice(voice);
1142 curr = gus_read16(0x09) >> 4;
1143 target = voices[voice].initial_volume;
1145 if (ramp_time == INSTANT_RAMP) {
1147 gus_voice_volume(target);
1151 if (ramp_time == FAST_RAMP)
1155 gus_ramp_rate(0, rate);
1157 if ((target - curr) / 64 == 0) { /* Close enough to target. */
1159 gus_voice_volume(target);
1163 if (target > curr) {
1164 if (target > (4095 - 65))
1166 gus_ramp_range(curr, target);
1167 gus_rampon(0x00); /* Ramp up, once, no IRQ */
1172 gus_ramp_range(target, curr);
1173 gus_rampon(0x40); /* Ramp down, once, no irq */
1179 dynamic_volume_change(int voice)
1185 gus_select_voice(voice);
1186 status = gus_read8(0x00); /* Get voice status */
1190 return; /* Voice was not running */
1192 if (!(voices[voice].mode & WAVE_ENVELOPES)) {
1193 compute_and_set_volume(voice, voices[voice].midi_volume, 1);
1197 * Voice is running and has envelopes.
1201 gus_select_voice(voice);
1202 status = gus_read8(0x0d); /* Ramping status */
1205 if (status & 0x03) { /* Sustain phase? */
1206 compute_and_set_volume(voice, voices[voice].midi_volume, 1);
1209 if (voices[voice].env_phase < 0)
1212 compute_volume(voice, voices[voice].midi_volume);
1217 guswave_controller(int dev, int voice, int ctrl_num, int value)
1222 if (voice < 0 || voice > 31)
1226 case CTRL_PITCH_BENDER:
1227 voices[voice].bender = value;
1229 if (voices[voice].volume_irq_mode != VMODE_START_NOTE) {
1230 freq = compute_finetune(voices[voice].orig_freq, value,
1231 voices[voice].bender_range);
1232 voices[voice].current_freq = freq;
1235 gus_select_voice(voice);
1236 gus_voice_freq(freq);
1241 case CTRL_PITCH_BENDER_RANGE:
1242 voices[voice].bender_range = value;
1244 case CTL_EXPRESSION:
1246 case CTRL_EXPRESSION:
1247 if (volume_method == VOL_METHOD_ADAGIO) {
1248 voices[voice].expression_vol = value;
1249 if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
1250 dynamic_volume_change(voice);
1255 voices[voice].panning = (value * 2) - 128;
1258 case CTL_MAIN_VOLUME:
1259 value = (value * 100) / 16383;
1261 case CTRL_MAIN_VOLUME:
1262 voices[voice].main_vol = value;
1263 if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
1264 dynamic_volume_change(voice);
1273 guswave_start_note2(int dev, int voice, int note_num, int volume)
1275 int sample, best_sample, best_delta, delta_freq;
1276 int is16bits, samplep, patch, pan;
1277 u_long note_freq, base_note, freq, flags;
1280 if (voice < 0 || voice > 31) {
1281 printf("GUS: Invalid voice\n");
1284 if (note_num == 255) {
1285 if (voices[voice].mode & WAVE_ENVELOPES) {
1286 voices[voice].midi_volume = volume;
1287 dynamic_volume_change(voice);
1290 compute_and_set_volume(voice, volume, 1);
1293 if ((patch = patch_map[voice]) == -1)
1295 if ((samplep = patch_table[patch]) == -1)
1297 note_freq = note_to_freq(note_num);
1300 * Find a sample within a patch so that the note_freq is between
1301 * low_note and high_note.
1305 best_sample = samplep;
1306 best_delta = 1000000;
1307 while (samplep >= 0 && sample == -1) {
1308 dbg_samples = samples;
1309 dbg_samplep = samplep;
1311 delta_freq = note_freq - samples[samplep].base_note;
1313 delta_freq = -delta_freq;
1314 if (delta_freq < best_delta) {
1315 best_sample = samplep;
1316 best_delta = delta_freq;
1318 if (samples[samplep].low_note <= note_freq &&
1319 note_freq <= samples[samplep].high_note)
1322 samplep = samples[samplep].key; /* Follow link */
1325 sample = best_sample;
1328 printf("GUS: Patch %d not defined for note %d\n", patch, note_num);
1329 return 0; /* Should play default patch ??? */
1331 is16bits = (samples[sample].mode & WAVE_16_BITS) ? 1 : 0;
1332 voices[voice].mode = samples[sample].mode;
1333 voices[voice].patch_vol = samples[sample].volume;
1335 if (voices[voice].mode & WAVE_ENVELOPES) {
1338 for (i = 0; i < 6; i++) {
1339 voices[voice].env_rate[i] = samples[sample].env_rate[i];
1340 voices[voice].env_offset[i] = samples[sample].env_offset[i];
1343 sample_map[voice] = sample;
1345 base_note = samples[sample].base_note / 100; /* Try to avoid overflows */
1348 freq = samples[sample].base_freq * note_freq / base_note;
1350 voices[voice].orig_freq = freq;
1353 * Since the pitch bender may have been set before playing the note,
1354 * we have to calculate the bending now.
1357 freq = compute_finetune(voices[voice].orig_freq, voices[voice].bender,
1358 voices[voice].bender_range);
1359 voices[voice].current_freq = freq;
1361 pan = (samples[sample].panning + voices[voice].panning) / 32;
1368 if (samples[sample].mode & WAVE_16_BITS) {
1369 mode |= 0x04; /* 16 bits */
1370 if ((sample_ptrs[sample] >> 18) !=
1371 ((sample_ptrs[sample] + samples[sample].len) >> 18))
1372 printf("GUS: Sample address error\n");
1375 * CAUTION! Interrupts disabled. Don't return before enabling
1379 gus_select_voice(voice);
1385 if (voices[voice].mode & WAVE_ENVELOPES) {
1386 compute_volume(voice, volume);
1387 init_envelope(voice);
1389 compute_and_set_volume(voice, volume, 0);
1393 gus_select_voice(voice);
1395 if (samples[sample].mode & WAVE_LOOP_BACK)
1396 gus_write_addr(0x0a, sample_ptrs[sample] + samples[sample].len -
1397 voices[voice].offset_pending, is16bits); /* start=end */
1399 gus_write_addr(0x0a, sample_ptrs[sample] + voices[voice].offset_pending,
1400 is16bits); /* Sample start=begin */
1402 if (samples[sample].mode & WAVE_LOOPING) {
1405 if (samples[sample].mode & WAVE_BIDIR_LOOP)
1408 if (samples[sample].mode & WAVE_LOOP_BACK) {
1409 gus_write_addr(0x0a,
1410 sample_ptrs[sample] + samples[sample].loop_end -
1411 voices[voice].offset_pending, is16bits);
1414 gus_write_addr(0x02, sample_ptrs[sample] + samples[sample].loop_start,
1415 is16bits); /* Loop start location */
1416 gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].loop_end,
1417 is16bits); /* Loop end location */
1419 mode |= 0x20; /* Loop IRQ at the end */
1420 voices[voice].loop_irq_mode = LMODE_FINISH; /* Ramp down at the end */
1421 voices[voice].loop_irq_parm = 1;
1422 gus_write_addr(0x02, sample_ptrs[sample],
1423 is16bits); /* Loop start location */
1424 gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].len - 1,
1425 is16bits); /* Loop end location */
1427 gus_voice_freq(freq);
1428 gus_voice_balance(pan);
1436 * New guswave_start_note by Andrew J. Robinson attempts to minimize clicking
1437 * when the note playing on the voice is changed. It uses volume ramping.
1441 guswave_start_note(int dev, int voice, int note_num, int volume)
1448 if (note_num == 255) {
1449 if (voices[voice].volume_irq_mode == VMODE_START_NOTE) {
1450 voices[voice].volume_pending = volume;
1452 ret_val = guswave_start_note2(dev, voice, note_num, volume);
1455 gus_select_voice(voice);
1456 mode = gus_read8(0x00);
1458 gus_write8(0x00, mode & 0xdf); /* No interrupt! */
1460 voices[voice].offset_pending = 0;
1461 voices[voice].kill_pending = 0;
1462 voices[voice].volume_irq_mode = 0;
1463 voices[voice].loop_irq_mode = 0;
1465 if (voices[voice].sample_pending >= 0) {
1466 splx(flags); /* Run temporarily with interrupts
1468 guswave_set_instr(voices[voice].dev_pending, voice,
1469 voices[voice].sample_pending);
1470 voices[voice].sample_pending = -1;
1472 gus_select_voice(voice); /* Reselect the voice
1473 * (just to be sure) */
1475 if ((mode & 0x01) || (int) ((gus_read16(0x09) >> 4) < 2065)) {
1476 ret_val = guswave_start_note2(dev, voice, note_num, volume);
1478 voices[voice].dev_pending = dev;
1479 voices[voice].note_pending = note_num;
1480 voices[voice].volume_pending = volume;
1481 voices[voice].volume_irq_mode = VMODE_START_NOTE;
1484 gus_ramp_range(2000, 4065);
1485 gus_ramp_rate(0, 63); /* Fastest possible rate */
1486 gus_rampon(0x20 | 0x40); /* Ramp down, once, irq */
1494 guswave_reset(int dev)
1498 for (i = 0; i < 32; i++) {
1505 guswave_open(int dev, int mode)
1508 int otherside = audio_devs[dev]->otherside;
1510 if (otherside != -1) {
1511 if (audio_devs[otherside]->busy)
1514 if (audio_devs[dev]->busy)
1518 voice_alloc->timestamp = 0;
1520 if ((err = DMAbuf_open_dma(gus_devnum)) < 0) {
1521 printf("GUS: Loading saples without DMA\n");
1522 gus_no_dma = 1; /* Upload samples using PIO */
1526 dram_sleep_flag.aborting = 0;
1527 dram_sleep_flag.mode = WK_NONE;
1528 active_device = GUS_DEV_WAVE;
1530 audio_devs[dev]->busy = 1;
1537 guswave_close(int dev)
1539 int otherside = audio_devs[dev]->otherside;
1541 if (otherside != -1) {
1542 if (audio_devs[otherside]->busy)
1545 audio_devs[dev]->busy = 0;
1551 DMAbuf_close_dma(gus_devnum);
1555 guswave_load_patch(int dev, int format, snd_rw_buf * addr,
1556 int offs, int count, int pmgr_flag)
1558 struct patch_info patch;
1562 u_long blk_size, blk_end, left, src_offs, target;
1564 sizeof_patch = offsetof(struct patch_info, data); /* Header size */
1566 if (format != GUS_PATCH) {
1567 printf("GUS Error: Invalid patch format (key) 0x%x\n", format);
1570 if (count < sizeof_patch) {
1571 printf("GUS Error: Patch header too short\n");
1574 count -= sizeof_patch;
1576 if (free_sample >= MAX_SAMPLE) {
1577 printf("GUS: Sample table full\n");
1581 * Copy the header from user space but ignore the first bytes which
1582 * have been transferred already.
1585 if (uiomove(&((char *) &patch)[offs], sizeof_patch - offs, addr)) {
1586 printf("audio: Bad copyin()!\n");
1589 instr = patch.instr_no;
1591 if (instr < 0 || instr > MAX_PATCH) {
1592 printf("GUS: Invalid patch number %d\n", instr);
1595 if (count < patch.len) {
1596 printf("GUS Warning: Patch record too short (%d<%d)\n",
1597 count, (int) patch.len);
1600 if (patch.len <= 0 || patch.len > gus_mem_size) {
1601 printf("GUS: Invalid sample length %d\n", (int) patch.len);
1604 if (patch.mode & WAVE_LOOPING) {
1605 if (patch.loop_start < 0 || patch.loop_start >= patch.len) {
1606 printf("GUS: Invalid loop start\n");
1609 if (patch.loop_end < patch.loop_start || patch.loop_end > patch.len) {
1610 printf("GUS: Invalid loop end\n");
1614 free_mem_ptr = (free_mem_ptr + 31) & ~31; /* 32 byte alignment */
1616 #define GUS_BANK_SIZE (256*1024)
1618 if (patch.mode & WAVE_16_BITS) {
1620 * 16 bit samples must fit one 256k bank.
1622 if (patch.len >= GUS_BANK_SIZE) {
1623 printf("GUS: Sample (16 bit) too long %d\n", (int) patch.len);
1626 if ((free_mem_ptr / GUS_BANK_SIZE) !=
1627 ((free_mem_ptr + patch.len) / GUS_BANK_SIZE)) {
1628 u_long tmp_mem = /* Aligning to 256K */
1629 ((free_mem_ptr / GUS_BANK_SIZE) + 1) * GUS_BANK_SIZE;
1631 if ((tmp_mem + patch.len) > gus_mem_size)
1634 free_mem_ptr = tmp_mem; /* This leaves unusable memory */
1637 if ((free_mem_ptr + patch.len) > gus_mem_size)
1640 sample_ptrs[free_sample] = free_mem_ptr;
1643 * Tremolo is not possible with envelopes
1646 if (patch.mode & WAVE_ENVELOPES)
1647 patch.mode &= ~WAVE_TREMOLO;
1649 bcopy(&patch, (char *) &samples[free_sample], sizeof_patch);
1652 * Link this_one sample to the list of samples for patch 'instr'.
1655 samples[free_sample].key = patch_table[instr];
1656 patch_table[instr] = free_sample;
1659 * Use DMA to transfer the wave data to the DRAM
1664 target = free_mem_ptr;
1666 while (left) { /* Not completely transferred yet */
1667 /* blk_size = audio_devs[gus_devnum]->buffsize; */
1668 blk_size = audio_devs[gus_devnum]->dmap_out->bytes_in_use;
1669 if (blk_size > left)
1673 * DMA cannot cross 256k bank boundaries. Check for that.
1675 blk_end = target + blk_size;
1677 if ((target >> 18) != (blk_end >> 18)) { /* Split the block */
1678 blk_end &= ~(256 * 1024 - 1);
1679 blk_size = blk_end - target;
1683 * For some reason the DMA is not possible. We have
1689 for (i = 0; i < blk_size; i++) {
1690 uiomove((char *) &(data), 1, addr);
1691 if (patch.mode & WAVE_UNSIGNED)
1692 if (!(patch.mode & WAVE_16_BITS) || (i & 0x01))
1693 data ^= 0x80; /* Convert to signed */
1694 gus_poke(target + i, data);
1697 u_long address, hold_address;
1702 * OK, move now. First in and then out.
1705 if (uiomove(audio_devs[gus_devnum]->dmap_out->raw_buf, blk_size, addr)) {
1706 printf("audio: Bad copyin()!\n");
1710 /******** INTERRUPTS DISABLED NOW ********/
1711 gus_write8(0x41, 0); /* Disable GF1 DMA */
1712 DMAbuf_start_dma(gus_devnum,
1713 audio_devs[gus_devnum]->dmap_out->raw_buf_phys,
1717 * Set the DRAM address for the wave data
1722 if (audio_devs[gus_devnum]->dmachan1 > 3) {
1723 hold_address = address;
1724 address = address >> 1;
1725 address &= 0x0001ffffL;
1726 address |= (hold_address & 0x000c0000L);
1728 gus_write16(0x42, (address >> 4) & 0xffff); /* DRAM DMA address */
1731 * Start the DMA transfer
1734 dma_command = 0x21; /* IRQ enable, DMA start */
1735 if (patch.mode & WAVE_UNSIGNED)
1736 dma_command |= 0x80; /* Invert MSB */
1737 if (patch.mode & WAVE_16_BITS)
1738 dma_command |= 0x40; /* 16 bit _DATA_ */
1739 if (audio_devs[gus_devnum]->dmachan1 > 3)
1740 dma_command |= 0x04; /* 16 bit DMA _channel_ */
1742 gus_write8(0x41, dma_command); /* Lets bo luteet (=bugs) */
1745 * Sleep here until the DRAM DMA done interrupt is
1748 active_device = GUS_DEV_WAVE;
1754 dram_sleep_flag.mode = WK_SLEEP;
1755 dram_sleeper = &chn;
1756 DO_SLEEP(chn, dram_sleep_flag, hz);
1759 if ((dram_sleep_flag.mode & WK_TIMEOUT))
1760 printf("GUS: DMA Transfer timed out\n");
1769 src_offs += blk_size;
1772 gus_write8(0x41, 0); /* Stop DMA */
1775 free_mem_ptr += patch.len;
1778 pmgr_inform(dev, PM_E_PATCH_LOADED, instr, free_sample, 0, 0);
1784 guswave_hw_control(int dev, u_char *event)
1788 u_long plong, flags;
1792 p1 = *(u_short *) &event[4];
1793 p2 = *(u_short *) &event[6];
1794 plong = *(u_long *) &event[4];
1796 if ((voices[voice].volume_irq_mode == VMODE_START_NOTE) &&
1797 (cmd != _GUS_VOICESAMPLE) && (cmd != _GUS_VOICE_POS))
1798 do_volume_irq(voice);
1802 case _GUS_NUMVOICES:
1804 gus_select_voice(voice);
1805 gus_select_max_voices(p1);
1809 case _GUS_VOICESAMPLE:
1810 guswave_set_instr(dev, voice, p1);
1815 gus_select_voice(voice);
1816 p1 &= ~0x20; /* Don't allow interrupts */
1823 gus_select_voice(voice);
1828 case _GUS_VOICEFADE:
1829 gus_voice_fade(voice);
1832 case _GUS_VOICEMODE:
1834 gus_select_voice(voice);
1835 p1 &= ~0x20; /* Don't allow interrupts */
1840 case _GUS_VOICEBALA:
1842 gus_select_voice(voice);
1843 gus_voice_balance(p1);
1847 case _GUS_VOICEFREQ:
1849 gus_select_voice(voice);
1850 gus_voice_freq(plong);
1856 gus_select_voice(voice);
1857 gus_voice_volume(p1);
1861 case _GUS_VOICEVOL2: /* Just update the software voice level */
1862 voices[voice].initial_volume =
1863 voices[voice].current_volume = p1;
1866 case _GUS_RAMPRANGE:
1867 if (voices[voice].mode & WAVE_ENVELOPES)
1870 gus_select_voice(voice);
1871 gus_ramp_range(p1, p2);
1876 if (voices[voice].mode & WAVE_ENVELOPES)
1877 break; /* NJET-NJET */
1879 gus_select_voice(voice);
1880 gus_ramp_rate(p1, p2);
1885 if (voices[voice].mode & WAVE_ENVELOPES)
1888 gus_select_voice(voice);
1889 p1 &= ~0x20; /* Don't allow interrupts */
1895 if (voices[voice].mode & WAVE_ENVELOPES)
1898 gus_select_voice(voice);
1899 p1 &= ~0x20; /* Don't allow interrupts */
1905 if (voices[voice].mode & WAVE_ENVELOPES)
1906 break; /* NEJ-NEJ */
1908 gus_select_voice(voice);
1913 case _GUS_VOLUME_SCALE:
1918 case _GUS_VOICE_POS:
1920 gus_select_voice(voice);
1921 gus_set_voice_pos(voice, plong);
1930 gus_sampling_set_speed(int speed)
1934 speed = gus_sampling_speed;
1936 RANGE(speed, 4000, 44100);
1937 gus_sampling_speed = speed;
1939 if (only_read_access) {
1940 /* Compute nearest valid recording speed and return it */
1942 speed = (9878400 / (gus_sampling_speed + 2)) / 16;
1943 speed = (9878400 / (speed * 16)) - 2;
1949 gus_sampling_set_channels(int channels)
1952 return gus_sampling_channels;
1953 RANGE(channels, 1, 2);
1954 gus_sampling_channels = channels;
1959 gus_sampling_set_bits(int bits)
1962 return gus_sampling_bits;
1964 if (bits != 8 && bits != 16)
1970 gus_sampling_bits = bits;
1975 gus_sampling_ioctl(int dev, u_int cmd, ioctl_arg arg, int local)
1978 case SOUND_PCM_WRITE_RATE:
1980 return gus_sampling_set_speed((int) arg);
1981 return *(int *) arg = gus_sampling_set_speed((*(int *) arg));
1984 case SOUND_PCM_READ_RATE:
1986 return gus_sampling_speed;
1987 return *(int *) arg = gus_sampling_speed;
1990 case SNDCTL_DSP_STEREO:
1992 return gus_sampling_set_channels((int) arg + 1) - 1;
1993 return *(int *) arg = gus_sampling_set_channels((*(int *) arg) + 1) - 1;
1996 case SOUND_PCM_WRITE_CHANNELS:
1998 return gus_sampling_set_channels((int) arg);
1999 return *(int *) arg = gus_sampling_set_channels((*(int *) arg));
2002 case SOUND_PCM_READ_CHANNELS:
2004 return gus_sampling_channels;
2005 return *(int *) arg = gus_sampling_channels;
2008 case SNDCTL_DSP_SETFMT:
2010 return gus_sampling_set_bits((int) arg);
2011 return *(int *) arg = gus_sampling_set_bits((*(int *) arg));
2014 case SOUND_PCM_READ_BITS:
2016 return gus_sampling_bits;
2017 return *(int *) arg = gus_sampling_bits;
2019 case SOUND_PCM_WRITE_FILTER: /* NOT POSSIBLE */
2020 return *(int *) arg = -(EINVAL);
2023 case SOUND_PCM_READ_FILTER:
2024 return *(int *) arg = -(EINVAL);
2032 gus_sampling_reset(int dev)
2034 if (recording_active) {
2035 gus_write8(0x49, 0x00); /* Halt recording */
2036 set_input_volumes();
2041 gus_sampling_open(int dev, int mode)
2044 int otherside = audio_devs[dev]->otherside;
2045 if (otherside != -1) {
2046 if (audio_devs[otherside]->busy)
2049 if (audio_devs[dev]->busy)
2058 reset_sample_memory();
2059 gus_select_max_voices(14);
2064 audio_devs[dev]->busy = 1;
2066 if (mode & OPEN_READ) {
2067 recording_active = 1;
2068 set_input_volumes();
2070 only_read_access = !(mode & OPEN_WRITE);
2071 only_8_bits = mode & OPEN_READ;
2073 audio_devs[dev]->format_mask = AFMT_U8;
2075 audio_devs[dev]->format_mask = AFMT_U8 | AFMT_S16_LE;
2081 gus_sampling_close(int dev)
2083 int otherside = audio_devs[dev]->otherside;
2084 audio_devs[dev]->busy = 0;
2086 if (otherside != -1) {
2087 if (audio_devs[otherside]->busy)
2095 if (recording_active) {
2096 gus_write8(0x49, 0x00); /* Halt recording */
2097 set_input_volumes();
2099 recording_active = 0;
2103 gus_sampling_update_volume(void)
2108 if (pcm_active && pcm_opened)
2109 for (voice = 0; voice < gus_sampling_channels; voice++) {
2111 gus_select_voice(voice);
2113 gus_voice_volume(1530 + (25 * gus_pcm_volume));
2114 gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
2120 play_next_pcm_block(void)
2123 int speed = gus_sampling_speed;
2124 int this_one, is16bits, chn;
2126 u_char mode[2], ramp_mode[2];
2131 this_one = pcm_head;
2133 for (chn = 0; chn < gus_sampling_channels; chn++) {
2135 ramp_mode[chn] = 0x03; /* Ramping and rollover off */
2138 mode[chn] |= 0x20; /* Loop IRQ */
2139 voices[chn].loop_irq_mode = LMODE_PCM;
2141 if (gus_sampling_bits != 8) {
2143 mode[chn] |= 0x04; /* 16 bit data */
2147 dram_loc = this_one * pcm_bsize;
2148 dram_loc += chn * pcm_banksize;
2150 if (this_one == (pcm_nblk - 1)) { /* Last fragment of the
2152 mode[chn] |= 0x08; /* Enable loop */
2153 ramp_mode[chn] = 0x03; /* Disable rollover bit */
2156 ramp_mode[chn] = 0x04; /* Enable rollover bit */
2160 gus_select_voice(chn);
2161 gus_voice_freq(speed);
2163 if (gus_sampling_channels == 1)
2164 gus_voice_balance(7); /* mono */
2166 gus_voice_balance(0); /* left */
2168 gus_voice_balance(15); /* right */
2170 if (!pcm_active) { /* Playback not already active */
2172 * The playback was not started yet (or there has
2173 * been a pause). Start the voice (again) and ask for
2174 * a rollover irq at the end of this_one block. If
2175 * this_one one is last of the buffers, use just the
2176 * normal loop with irq.
2181 gus_voice_volume(1530 + (25 * gus_pcm_volume));
2182 gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
2184 gus_write_addr(0x0a, dram_loc, is16bits); /* Starting position */
2185 gus_write_addr(0x02, chn * pcm_banksize, is16bits); /* Loop start */
2188 gus_write_addr(0x04, pcm_banksize + (pcm_bsize * pcm_nblk) - 1,
2189 is16bits); /* Loop end location */
2192 gus_write_addr(0x04, dram_loc + pcm_datasize[this_one] - 1,
2193 is16bits); /* Loop end location */
2195 mode[chn] |= 0x08; /* Enable looping */
2197 if (pcm_datasize[this_one] != pcm_bsize) {
2199 * Incompletely filled block. Possibly the last one.
2202 mode[chn] &= ~0x08; /* Disable looping */
2203 mode[chn] |= 0x20; /* Enable IRQ at the end */
2204 voices[0].loop_irq_mode = LMODE_PCM_STOP;
2205 ramp_mode[chn] = 0x03; /* No rollover bit */
2207 gus_write_addr(0x04, dram_loc + pcm_datasize[this_one],
2208 is16bits); /* Loop end location */
2209 mode[chn] &= ~0x08; /* Disable looping */
2215 for (chn = 0; chn < gus_sampling_channels; chn++) {
2217 gus_select_voice(chn);
2218 gus_write8(0x0d, ramp_mode[chn]);
2219 gus_voice_on(mode[chn]);
2227 gus_transfer_output_block(int dev, u_long buf,
2228 int total_count, int intrflag, int chn)
2231 * This routine transfers one block of audio data to the DRAM. In
2232 * mono mode it's called just once. When in stereo mode, this_one
2233 * routine is called once for both channels.
2235 * The left/mono channel data is transferred to the beginning of dram
2236 * and the right data to the area pointed by gus_page_size.
2239 int this_one, count;
2242 u_long address, hold_address;
2246 count = total_count / gus_sampling_channels;
2249 if (pcm_qlen >= pcm_nblk)
2250 printf("GUS Warning: PCM buffers out of sync\n");
2252 this_one = pcm_current_block = pcm_tail;
2254 pcm_tail = (pcm_tail + 1) % pcm_nblk;
2255 pcm_datasize[this_one] = count;
2257 this_one = pcm_current_block;
2259 gus_write8(0x41, 0); /* Disable GF1 DMA */
2260 DMAbuf_start_dma(dev, buf + (chn * count), count, 1);
2262 address = this_one * pcm_bsize;
2263 address += chn * pcm_banksize;
2265 if (audio_devs[dev]->dmachan1 > 3) {
2266 hold_address = address;
2267 address = address >> 1;
2268 address &= 0x0001ffffL;
2269 address |= (hold_address & 0x000c0000L);
2271 gus_write16(0x42, (address >> 4) & 0xffff); /* DRAM DMA address */
2273 dma_command = 0x21; /* IRQ enable, DMA start */
2275 if (gus_sampling_bits != 8)
2276 dma_command |= 0x40; /* 16 bit _DATA_ */
2278 dma_command |= 0x80; /* Invert MSB */
2280 if (audio_devs[dev]->dmachan1 > 3)
2281 dma_command |= 0x04; /* 16 bit DMA channel */
2283 gus_write8(0x41, dma_command); /* Kickstart */
2285 if (chn == (gus_sampling_channels - 1)) { /* Last channel */
2287 * Last (right or mono) channel data
2289 dma_active = 1; /* DMA started. There is a unacknowledged
2291 active_device = GUS_DEV_PCM_DONE;
2292 if (!pcm_active && (pcm_qlen > 0 || count < pcm_bsize)) {
2293 play_next_pcm_block();
2297 * Left channel data. The right channel is transferred after
2300 active_device = GUS_DEV_PCM_CONTINUE;
2307 gus_sampling_output_block(int dev, u_long buf, int total_count,
2308 int intrflag, int restart_dma)
2310 pcm_current_buf = buf;
2311 pcm_current_count = total_count;
2312 pcm_current_intrflag = intrflag;
2313 pcm_current_dev = dev;
2314 gus_transfer_output_block(dev, buf, total_count, intrflag, 0);
2318 gus_sampling_start_input(int dev, u_long buf, int count,
2319 int intrflag, int restart_dma)
2326 DMAbuf_start_dma(dev, buf, count, 0);
2328 mode = 0xa0; /* DMA IRQ enabled, invert MSB */
2330 if (audio_devs[dev]->dmachan2 > 3)
2331 mode |= 0x04; /* 16 bit DMA channel */
2332 if (gus_sampling_channels > 1)
2333 mode |= 0x02; /* Stereo */
2334 mode |= 0x01; /* DMA enable */
2336 gus_write8(0x49, mode);
2342 gus_sampling_prepare_for_input(int dev, int bsize, int bcount)
2346 rate = (9878400 / (gus_sampling_speed + 2)) / 16;
2348 gus_write8(0x48, rate & 0xff); /* Set sampling rate */
2350 if (gus_sampling_bits != 8) {
2351 printf("GUS Error: 16 bit recording not supported\n");
2358 gus_sampling_prepare_for_output(int dev, int bsize, int bcount)
2362 long mem_ptr, mem_size;
2365 mem_size = gus_mem_size / gus_sampling_channels;
2367 if (mem_size > (256 * 1024))
2368 mem_size = 256 * 1024;
2370 pcm_bsize = bsize / gus_sampling_channels;
2371 pcm_head = pcm_tail = pcm_qlen = 0;
2373 pcm_nblk = MAX_PCM_BUFFERS;
2374 if ((pcm_bsize * pcm_nblk) > mem_size)
2375 pcm_nblk = mem_size / pcm_bsize;
2377 for (i = 0; i < pcm_nblk; i++)
2378 pcm_datasize[i] = 0;
2380 pcm_banksize = pcm_nblk * pcm_bsize;
2382 if (gus_sampling_bits != 8 && pcm_banksize == (256 * 1024))
2389 gus_local_qlen(int dev)
2395 gus_copy_from_user(int dev, char *localbuf, int localoffs,
2396 snd_rw_buf * userbuf, int useroffs, int len)
2398 if (gus_sampling_channels == 1) {
2400 if (uiomove(&localbuf[localoffs], len, userbuf)) {
2401 printf("audio: Bad copyin()!\n");
2403 } else if (gus_sampling_bits == 8) {
2404 int in_left = useroffs;
2405 int in_right = useroffs + 1;
2406 char *out_left, *out_right;
2411 out_left = &localbuf[localoffs];
2412 out_right = out_left + pcm_bsize;
2414 for (i = 0; i < len; i++) {
2415 uiomove((char *) &(*out_left++), 1, userbuf);
2417 uiomove((char *) &(*out_right++), 1, userbuf);
2421 int in_left = useroffs;
2422 int in_right = useroffs + 2;
2423 short *out_left, *out_right;
2429 out_left = (short *) &localbuf[localoffs];
2430 out_right = out_left + (pcm_bsize / 2);
2432 for (i = 0; i < len; i++) {
2433 uiomove((char *) &(*out_left++), 2, userbuf);
2435 uiomove((char *) &(*out_right++), 2, userbuf);
2441 static struct audio_operations gus_sampling_operations =
2443 "Gravis UltraSound",
2445 AFMT_U8 | AFMT_S16_LE,
2449 gus_sampling_output_block,
2450 gus_sampling_start_input,
2452 gus_sampling_prepare_for_input,
2453 gus_sampling_prepare_for_output,
2461 guswave_setup_voice(int dev, int voice, int chn)
2463 struct channel_info *info =
2464 &synth_devs[dev]->chn_info[chn];
2466 guswave_set_instr(dev, voice, info->pgm_num);
2468 voices[voice].expression_vol =
2469 info->controllers[CTL_EXPRESSION]; /* Just msb */
2470 voices[voice].main_vol =
2471 (info->controllers[CTL_MAIN_VOLUME] * 100) / 128;
2472 voices[voice].panning =
2473 (info->controllers[CTL_PAN] * 2) - 128;
2474 voices[voice].bender = info->bender_value;
2478 guswave_bender(int dev, int voice, int value)
2483 voices[voice].bender = value - 8192;
2484 freq = compute_finetune(voices[voice].orig_freq, value - 8192,
2485 voices[voice].bender_range);
2486 voices[voice].current_freq = freq;
2489 gus_select_voice(voice);
2490 gus_voice_freq(freq);
2495 guswave_patchmgr(int dev, struct patmgr_info * rec)
2499 switch (rec->command) {
2500 case PM_GET_DEVTYPE:
2501 rec->parm1 = PMTYPE_WAVE;
2506 rec->parm1 = MAX_PATCH;
2511 rec->parm1 = MAX_PATCH;
2513 for (i = 0; i < MAX_PATCH; i++) {
2514 int ptr = patch_table[i];
2516 rec->data.data8[i] = 0;
2518 while (ptr >= 0 && ptr < free_sample) {
2519 rec->data.data8[i]++;
2520 ptr = samples[ptr].key; /* Follow link */
2526 case PM_GET_PGM_PATCHES:
2528 int ptr = patch_table[rec->parm1];
2532 while (ptr >= 0 && ptr < free_sample) {
2533 rec->data.data32[n++] = ptr;
2534 ptr = samples[ptr].key; /* Follow link */
2543 int ptr = rec->parm1;
2544 struct patch_info *pat;
2546 if (ptr < 0 || ptr >= free_sample)
2549 bcopy((char *) &samples[ptr], rec->data.data8, sizeof(struct patch_info));
2551 pat = (struct patch_info *) rec->data.data8;
2553 pat->key = GUS_PATCH; /* Restore patch type */
2554 rec->parm1 = sample_ptrs[ptr]; /* DRAM location */
2555 rec->parm2 = sizeof(struct patch_info);
2562 int ptr = rec->parm1;
2563 struct patch_info *pat;
2565 if (ptr < 0 || ptr >= free_sample)
2568 pat = (struct patch_info *) rec->data.data8;
2570 if (pat->len > samples[ptr].len) /* Cannot expand sample */
2573 pat->key = samples[ptr].key; /* Ensure the link is
2576 bcopy(rec->data.data8, (char *) &samples[ptr], sizeof(struct patch_info));
2578 pat->key = GUS_PATCH;
2583 case PM_READ_PATCH: /* Returns a block of wave data from the DRAM */
2585 int sample = rec->parm1;
2587 long offs = rec->parm2;
2590 if (sample < 0 || sample >= free_sample)
2593 if (offs < 0 || offs >= samples[sample].len)
2594 return -(EINVAL); /* Invalid offset */
2596 n = samples[sample].len - offs; /* Num of bytes left */
2601 if (l > sizeof(rec->data.data8))
2602 l = sizeof(rec->data.data8);
2605 return -(EINVAL); /* Was there a bug? */
2607 offs += sample_ptrs[sample]; /* Begin offsess +
2610 for (n = 0; n < l; n++)
2611 rec->data.data8[n] = gus_peek(offs++);
2612 rec->parm1 = n; /* Nr of bytes copied */
2617 case PM_WRITE_PATCH: /* Writes a block of wave data to the DRAM */
2619 int sample = rec->parm1;
2621 long offs = rec->parm2;
2624 if (sample < 0 || sample >= free_sample)
2627 if (offs < 0 || offs >= samples[sample].len)
2628 return -(EINVAL); /* Invalid offset */
2630 n = samples[sample].len - offs; /* Nr of bytes left */
2635 if (l > sizeof(rec->data.data8))
2636 l = sizeof(rec->data.data8);
2639 return -(EINVAL); /* Was there a bug? */
2641 offs += sample_ptrs[sample]; /* Begin offsess +
2644 for (n = 0; n < l; n++)
2645 gus_poke(offs++, rec->data.data8[n]);
2646 rec->parm1 = n; /* Nr of bytes copied */
2657 guswave_alloc(int dev, int chn, int note, struct voice_alloc_info * alloc)
2659 int i, p, best = -1, best_time = 0x7fffffff;
2663 * First look for a completely stopped voice
2666 for (i = 0; i < alloc->max_voice; i++) {
2667 if (alloc->map[p] == 0) {
2671 if (alloc->alloc_times[p] < best_time) {
2673 best_time = alloc->alloc_times[p];
2675 p = (p + 1) % alloc->max_voice;
2679 * Then look for a releasing voice
2682 for (i = 0; i < alloc->max_voice; i++) {
2683 if (alloc->map[p] == 0xffff) {
2687 p = (p + 1) % alloc->max_voice;
2697 static struct synth_operations guswave_operations =
2715 guswave_volume_method,
2723 set_input_volumes(void)
2726 u_char mask = 0xff & ~0x06; /* Just line out enabled */
2728 if (have_gus_max) /* Don't disturb GUS MAX */
2734 * Enable channels having vol > 10% Note! bit 0x01 means the line in
2735 * DISABLED while 0x04 means the mic in ENABLED.
2737 if (gus_line_vol > 10)
2739 if (gus_mic_vol > 10)
2742 if (recording_active) {
2744 * Disable channel, if not selected for recording
2746 if (!(gus_recmask & SOUND_MASK_LINE))
2748 if (!(gus_recmask & SOUND_MASK_MIC))
2752 mix_image |= mask & 0x07;
2753 outb(u_Mixer, mix_image);
2759 gus_default_mixer_ioctl(int dev, u_int cmd, ioctl_arg arg)
2762 #define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \
2763 SOUND_MASK_SYNTH|SOUND_MASK_PCM)
2765 if (((cmd >> 8) & 0xff) == 'M') {
2767 switch (cmd & 0xff) {
2768 case SOUND_MIXER_RECSRC:
2769 gus_recmask = (*(int *) arg) & MIX_DEVS;
2770 if (!(gus_recmask & (SOUND_MASK_MIC | SOUND_MASK_LINE)))
2771 gus_recmask = SOUND_MASK_MIC;
2773 * Note! Input volumes are updated during
2774 * next open for recording
2776 return *(int *) arg = gus_recmask;
2779 case SOUND_MIXER_MIC:
2781 int vol = (*(int *) arg) & 0xff;
2788 set_input_volumes();
2789 return *(int *) arg = vol | (vol << 8);
2793 case SOUND_MIXER_LINE:
2795 int vol = (*(int *) arg) & 0xff;
2802 set_input_volumes();
2803 return *(int *) arg = vol | (vol << 8);
2807 case SOUND_MIXER_PCM:
2808 gus_pcm_volume = (*(int *) arg) & 0xff;
2809 RANGE (gus_pcm_volume, 0, 100);
2810 gus_sampling_update_volume();
2811 return *(int *) arg = gus_pcm_volume | (gus_pcm_volume << 8);
2814 case SOUND_MIXER_SYNTH:
2818 gus_wave_volume = (*(int *) arg) & 0xff;
2820 RANGE (gus_wave_volume , 0, 100);
2822 if (active_device == GUS_DEV_WAVE)
2823 for (voice = 0; voice < nr_voices; voice++)
2824 dynamic_volume_change(voice); /* Apply the new vol */
2826 return *(int *) arg = gus_wave_volume | (gus_wave_volume << 8);
2834 switch (cmd & 0xff) { /* Return parameters */
2836 case SOUND_MIXER_RECSRC:
2837 return *(int *) arg = gus_recmask;
2840 case SOUND_MIXER_DEVMASK:
2841 return *(int *) arg = MIX_DEVS;
2844 case SOUND_MIXER_STEREODEVS:
2845 return *(int *) arg = 0;
2848 case SOUND_MIXER_RECMASK:
2849 return *(int *) arg = SOUND_MASK_MIC | SOUND_MASK_LINE;
2852 case SOUND_MIXER_CAPS:
2853 return *(int *) arg = 0;
2856 case SOUND_MIXER_MIC:
2857 return *(int *) arg = gus_mic_vol | (gus_mic_vol << 8);
2860 case SOUND_MIXER_LINE:
2861 return *(int *) arg = gus_line_vol | (gus_line_vol << 8);
2864 case SOUND_MIXER_PCM:
2865 return *(int *) arg = gus_pcm_volume | (gus_pcm_volume << 8);
2868 case SOUND_MIXER_SYNTH:
2869 return *(int *) arg = gus_wave_volume | (gus_wave_volume << 8);
2879 static struct mixer_operations gus_mixer_operations = {"Gravis Ultrasound", gus_default_mixer_ioctl};
2882 gus_default_mixer_init()
2884 if (num_mixers < MAX_MIXER_DEV) /* Don't install if there is another
2886 mixer_devs[num_mixers++] = &gus_mixer_operations;
2890 * Enable all mixer channels on the GF1 side. Otherwise
2891 * recording will not be possible using GUS MAX.
2894 mix_image |= 0x04; /* All channels enabled */
2895 outb(u_Mixer, mix_image);
2899 /* start of pnp code */
2905 outb(PWRITE_DATA, r);
2912 * Get the device's serial number. Returns 1 if the serial is valid.
2915 get_serial(int rd_port, u_char *data)
2917 int i, bit, valid = 0, sum = 0x6a;
2919 bzero(data, sizeof(char) * 9);
2921 for (i = 0; i < 72; i++) {
2922 bit = inb((rd_port << 2) | 0x3) == 0x55;
2923 DELAY(250); /* Delay 250 usec */
2925 /* Can't Short Circuit the next evaluation, so 'and' is last */
2926 bit = (inb((rd_port << 2) | 0x3) == 0xaa) && bit;
2927 DELAY(250); /* Delay 250 usec */
2929 valid = valid || bit;
2933 (((sum ^ (sum >> 1) ^ bit) << 7) & 0xff);
2935 data[i / 8] = (data[i / 8] >> 1) | (bit ? 0x80 : 0);
2937 valid = valid && (data[8] == sum);
2943 send_Initiation_LFSR()
2947 /* Reset the LSFR */
2952 outb(PADDRESS, cur);
2954 for (i = 1; i < 32; i++) {
2955 cur = (cur >> 1) | (((cur ^ (cur >> 1)) << 7) & 0xff);
2956 outb(PADDRESS, cur);
2963 isolation_protocol(int rd_port)
2968 send_Initiation_LFSR();
2970 /* Reset CSN for All Cards */
2973 for (csn = 1; (csn < MAX_CARDS); csn++) {
2974 /* Wake up cards without a CSN */
2977 SEND(SET_RD_DATA, rd_port);
2978 outb(PADDRESS, SERIAL_ISOLATION);
2979 DELAY(1000); /* Delay 1 msec */
2980 if (get_serial(rd_port, data)) {
2981 printf("Board Vendor ID: %c%c%c%02x%02x",
2982 ((data[0] & 0x7c) >> 2) + 64,
2983 (((data[0] & 0x03) << 3) | ((data[1] & 0xe0) >> 5)) + 64,
2984 (data[1] & 0x1f) + 64, data[2], data[3]);
2985 printf(" Board Serial Number: %08x\n", *(int *) &(data[4]));
2987 SEND(SET_CSN, csn); /* Move this out of this
2989 outb(PADDRESS, PSTATUS);
3003 * ########################################################################
3005 * FUNCTION : IwaveInputSource
3007 * PROFILE: This function allows the calling program to select among any of
3008 * several possible sources to the ADC's. The possible input sources and
3009 * their corresponding symbolic constants are: - Line (LINE_IN) - Aux1
3010 * (AUX1_IN) - Microphone (MIC_IN) - Mixer (MIX_IN)
3012 * Set the first argument to either LEFT_SOURCE or RIGHT_SOURCE. Always use the
3013 * symbolic contants for the arguments.
3015 * ########################################################################
3018 IwaveInputSource(BYTE index, BYTE source)
3023 reg = inb(iw.pcodar) & 0xE0;
3024 outb(iw.pcodar, reg | index); /* select register CLICI or CRICI */
3025 reg = inb(iw.cdatap) & ~MIX_IN;
3027 outb(iw.cdatap, (BYTE) (reg | source));
3031 IwavePnpGetCfg(void)
3037 IwavePnpDevice(AUDIO);
3038 outb(_PIDXR, 0x60); /* select P2X0HI */
3039 val = ((WORD) inb(iw.pnprdp)) << 8; /* get P2XR[9:8] */
3040 outb(_PIDXR, 0x61); /* select P2XRLI */
3041 iw.p2xr = val + (WORD) inb(iw.pnprdp); /* get P2XR[7:4] */
3043 outb(_PIDXR, 0x62); /* select P3X0HI */
3044 val = ((WORD) inb(iw.pnprdp)) << 8; /* get P3XR[9:8] */
3045 outb(_PIDXR, 0x63); /* select P3X0LI */
3046 iw.p3xr = val + (WORD) inb(iw.pnprdp); /* get P3XR[7:3] */
3048 outb(_PIDXR, 0x64); /* select PHCAI */
3049 val = ((WORD) inb(iw.pnprdp)) << 8; /* get PCODAR[9:8] */
3050 outb(_PIDXR, 0x65); /* select PLCAI */
3051 iw.pcodar = val + (WORD) inb(iw.pnprdp); /* get PCODAR[7:2] */
3053 outb(_PIDXR, 0x70); /* select PUI1SI */
3054 iw.synth_irq = (WORD) (inb(iw.pnprdp) & 0x0F); /* Synth IRQ number */
3056 outb(_PIDXR, 0x72); /* select PUI2SI */
3057 iw.midi_irq = (WORD) (inb(iw.pnprdp) & 0x0F); /* MIDI IRQ number */
3059 outb(_PIDXR, 0x74); /* select PUD1SI */
3060 iw.dma1_chan = inb(iw.pnprdp) & 0x07; /* DMA1 chan (LMC/Codec Rec) */
3062 outb(_PIDXR, 0x75); /* select PUD2SI */
3063 iw.dma2_chan = inb(iw.pnprdp) & 0x07; /* DMA2 chan (codec play) */
3066 IwavePnpDevice(EXT); /* select external device */
3067 outb(_PIDXR, 0x60); /* select PRAHI */
3068 val = ((WORD) inb(iw.pnprdp)) << 8; /* get PCDRAR[9:8] */
3069 outb(_PIDXR, 0x61); /* select PRALI */
3070 iw.pcdrar = val + (WORD) inb(iw.pnprdp); /* get PCDRAR[7:4] */
3071 outb(_PIDXR, 0x62); /* select PATAHI */
3072 val = ((WORD) inb(iw.pnprdp)) << 8; /* get PATAAR[9:8] */
3073 outb(_PIDXR, 0x63); /* select PATALI */
3074 iw.pataar = val + (WORD) inb(iw.pnprdp); /* get PATAAR[7:1] */
3076 outb(_PIDXR, 0x70); /* select PRISI */
3077 iw.ext_irq = (WORD) (inb(iw.pnprdp) & 0x0F); /* Ext Dev IRQ number */
3079 outb(_PIDXR, 0x74); /* select PRDSI */
3080 iw.ext_chan = inb(iw.pnprdp) & 0x07; /* Ext Dev DMA channel */
3082 IwavePnpDevice(MPU401); /* Select MPU401 Device */
3083 outb(_PIDXR, 0x60); /* select P401HI */
3084 val = ((WORD) inb(iw.pnprdp)) << 8; /* get P401AR[9:8] */
3085 outb(_PIDXR, 0x61); /* select P401LI */
3086 iw.p401ar = val + (WORD) inb(iw.pnprdp); /* get P401AR[7:1] */
3088 outb(_PIDXR, 0x70); /* select PMISI */
3089 iw.mpu_irq = (WORD) (inb(iw.pnprdp) & 0x0F); /* MPU401 Dev IRQ number */
3091 IwavePnpDevice(GAME); /* Select GAME logical Device */
3092 outb(_PIDXR, 0x60); /* select P201HI */
3093 val = ((WORD) inb(iw.pnprdp)) << 8; /* get P201AR[9:8] */
3094 outb(_PIDXR, 0x61); /* select P201LI */
3095 iw.p201ar = val + (WORD) inb(iw.pnprdp); /* get P201AR[7:6] */
3097 IwavePnpDevice(EMULATION); /* Select SB and ADLIB Device */
3098 outb(_PIDXR, 0x60); /* select P388HI */
3099 val = ((WORD) inb(iw.pnprdp)) << 8; /* get P388AR[9:8] */
3100 outb(_PIDXR, 0x61); /* select P388LI */
3101 iw.p388ar = val + inb(iw.pnprdp); /* get P388AR[7:6] */
3102 outb(_PIDXR, 0x70); /* select PSBISI */
3103 iw.emul_irq = (WORD) (inb(iw.pnprdp) & 0x0F); /* emulation Dev IRQ
3109 IwavePnpSetCfg(void)
3112 IwavePnpDevice(AUDIO); /* select audio device */
3113 outb(_PIDXR, 0x60); /* select P2X0HI */
3114 outb(_PNPWRP, (BYTE) (iw.p2xr >> 8)); /* set P2XR[9:8] */
3115 outb(_PIDXR, 0x61); /* select P2X0LI */
3116 outb(_PNPWRP, (BYTE) iw.p2xr); /* set P2XR[7:4] */
3118 outb(_PIDXR, 0x62); /* select P3X0HI */
3119 outb(_PNPWRP, (BYTE) (iw.p3xr >> 8)); /* set P3XR[9:8] */
3120 outb(_PIDXR, 0x63); /* select P3X0LI */
3121 outb(_PNPWRP, (BYTE) (iw.p3xr)); /* set P3XR[7:3] */
3123 outb(_PIDXR, 0x64); /* select PHCAI */
3124 outb(_PNPWRP, (BYTE) (iw.pcodar >> 8)); /* set PCODAR[9:8] */
3125 outb(_PIDXR, 0x65); /* select PLCAI */
3126 outb(_PNPWRP, (BYTE) iw.pcodar); /* set PCODAR[7:2] */
3128 outb(_PIDXR, 0x70); /* select PUI1SI */
3129 outb(_PNPWRP, (BYTE) (iw.synth_irq & 0x0F)); /* Synth IRQ number */
3130 outb(_PIDXR, 0x72); /* select PUI2SI */
3131 outb(_PNPWRP, (BYTE) (iw.midi_irq & 0x0F)); /* MIDI IRQ number */
3133 outb(_PIDXR, 0x74); /* select PUD1SI */
3134 outb(_PNPWRP, (BYTE) (iw.dma1_chan & 0x07)); /* DMA channel 1 */
3135 outb(_PIDXR, 0x75); /* select PUD2SI */
3136 outb(_PNPWRP, (BYTE) (iw.dma2_chan & 0x07)); /* DMA channel 2 */
3138 IwavePnpDevice(EXT);
3139 outb(_PIDXR, 0x60); /* select PRAHI */
3140 outb(_PNPWRP, (BYTE) (iw.pcdrar >> 8)); /* set PCDRAR[9:8] */
3141 outb(_PIDXR, 0x61); /* select PRALI */
3142 outb(_PNPWRP, (BYTE) iw.pcdrar); /* set PCDRAR[7:3] */
3144 outb(_PIDXR, 0x62); /* select PATAHI */
3145 outb(_PNPWRP, (BYTE) (iw.pataar >> 8)); /* set PATAAR[9:8] */
3146 outb(_PIDXR, 0x63); /* select PATALI */
3147 outb(_PNPWRP, (BYTE) iw.pataar); /* set PATAAR[7:1] */
3149 outb(_PIDXR, 0x70); /* select PRISI */
3150 outb(_PNPWRP, (BYTE) (iw.ext_irq & 0x0F)); /* Ext Dev IRQ number */
3151 outb(_PIDXR, 0x74); /* select PRDSI */
3152 outb(_PNPWRP, (BYTE) (iw.ext_chan & 0x07)); /* Ext Dev DMA channel */
3154 IwavePnpDevice(GAME);
3155 outb(_PIDXR, 0x60); /* select P201HI */
3156 outb(_PNPWRP, (BYTE) (iw.p201ar >> 8)); /* set P201RAR[9:8] */
3157 outb(_PIDXR, 0x61); /* select P201LI */
3158 outb(_PNPWRP, (BYTE) iw.p201ar); /* set P201AR[7:6] */
3160 IwavePnpDevice(EMULATION);
3161 outb(_PIDXR, 0x60); /* select P388HI */
3162 outb(_PNPWRP, (BYTE) (iw.p388ar >> 8)); /* set P388AR[9:8] */
3163 outb(_PIDXR, 0x61); /* select P388LI */
3164 outb(_PNPWRP, (BYTE) iw.p388ar); /* set P388AR[7:6] */
3166 outb(_PIDXR, 0x70); /* select PSBISI */
3167 outb(_PNPWRP, (BYTE) (iw.emul_irq & 0x0F)); /* emulation IRQ number */
3169 IwavePnpDevice(MPU401);
3170 outb(_PIDXR, 0x60); /* select P401HI */
3171 outb(_PNPWRP, (BYTE) (iw.p401ar >> 8)); /* set P401AR[9:8] */
3172 outb(_PIDXR, 0x61); /* select P401LI */
3173 outb(_PNPWRP, (BYTE) iw.p401ar); /* set P401AR[7:1] */
3175 outb(_PIDXR, 0x70); /* select PMISI */
3176 outb(_PNPWRP, (BYTE) (iw.mpu_irq & 0x0F)); /* MPU emulation IRQ
3181 /* ######################################################################## */
3184 /* REMARKS: This file contains the definitions for the InterWave's DDK */
3185 /* functions dedicated to the configuration of the InterWave */
3188 /* UPDATE: 4/07/95 */
3189 /* ######################################################################## */
3191 /* FUNCTION: IwavePnpKey */
3193 /* PROFILE: This function issues the initiation key that places the PNP */
3194 /* logic into configuration mode. The PNP logic is quiescent at */
3195 /* power up and must be enabled by software. This function will */
3196 /* do 32 I/O writes to the PIDXR (0x0279). The function will */
3197 /* first reset the LFSR to its initial value by a sequence of two */
3198 /* write cycles of 0x00 to PIDXR before issuing the key. */
3200 /* ######################################################################## */
3204 /* send_Initiation_LFSR(); */
3210 /* ############################################### */
3211 /* Reset Linear Feedback Shift Reg. */
3212 /* ############################################### */
3216 outb(0x279, code); /* Initial value */
3218 for (i = 1; i < 32; i++) {
3219 msb = ((code & 0x01) ^ ((code & 0x02) >> 1)) << 7;
3220 code = (code >> 1) | msb;
3227 IwavePnpIsol(PORT * pnpread)
3231 printf("Checking for GUS Plug-n-Play ...\n");
3233 /* Try various READ_DATA ports from 0x203-0x3ff */
3234 for (rd_port = 0x80; (rd_port < 0xff); rd_port += 0x10) {
3236 printf("Trying Read_Port at %x\n",
3237 (rd_port << 2) | 0x3);
3239 num_pnp_devs = isolation_protocol(rd_port);
3241 *pnpread = rd_port << 2 | 0x3;
3245 if (!num_pnp_devs) {
3246 printf("No Plug-n-Play devices were found\n");
3252 /* ######################################################################## */
3254 /* FUNCTION: IwavePnpPeek */
3256 /* PROFILE: This function will return the number of specified bytes of */
3257 /* resource data from the serial EEPROM. The function will NOT */
3258 /* reset the serial EEPROM logic to allow reading the entire */
3259 /* EEPROM by issuing repeated calls. The caller must supply a */
3260 /* pointer to where the data are to be stored. */
3261 /* It is assumed that the InterWave is not in either "sleep" */
3262 /* or "wait for key" states. Note that on the first call, if */
3263 /* the caller means to read from the beggining of data the */
3264 /* serial EEPROM logic must be reset. For this, the caller */
3265 /* should issue a WAKE[CSN] command */
3267 /* ######################################################################## */
3269 IwavePnpPeek(PORT pnprdp, WORD bytes, BYTE * data)
3274 for (i = 1; i <= bytes; i++) {
3275 outb(_PIDXR, 0x05); /* select PRESSI */
3277 while (TRUE) { /* wait til new data byte is ready */
3278 if (inb(pnprdp) & PNP_DATA_RDY)
3279 break; /* new resource byte ready */
3281 outb(_PIDXR, 0x04); /* select PRESDI */
3282 datum = inb(pnprdp); /* read resource byte */
3284 *(data++) = datum; /* store it */
3287 /* ######################################################################## */
3289 /* FUNCTION: IwavePnpActivate */
3291 /* PROFILE: This function will activate or de-activate the audio device */
3292 /* or the external device on the InterWave. Set the "dev" arg */
3293 /* to AUDIO for the audio device or EXT for the external device. */
3294 /* Set "bool" to ON or OFF to turn the device on or off the ISA */
3295 /* bus. Notice that for a logical device to work, it must be */
3298 /* ######################################################################## */
3300 IwavePnpActivate(BYTE dev, BYTE bool)
3302 IwavePnpDevice(dev); /* select audio device */
3304 outb(_PIDXR, ACTIVATE_DEV); /* select Activate Register */
3305 outb(_PNPWRP, bool); /* write register */
3309 /* ######################################################################## */
3311 /* FUNCTION: IwavePnpDevice */
3313 /* PROFILE: This function allows the caller to select between five */
3314 /* logical devices available on the InterWave.It is assumed */
3315 /* that the PNP state machine is in configuration mode. */
3317 /* ######################################################################## */
3319 IwavePnpDevice(BYTE dev)
3322 outb(_PIDXR, _PLDNI); /* select PLDNI */
3323 outb(_PNPWRP, dev); /* write PLDNI */
3326 /* ######################################################################## */
3328 /* FUNCTION: IwavePnpWake */
3330 /* PROFILE: This function issues a WAKE[CSN] command to the InterWave. If */
3331 /* the CSN matches the PNP state machine will enter the */
3332 /* configuration state. Otherwise it will enter the sleep mode. */
3334 /* It is assumed that the PNP state machine is not in the */
3335 /* "wait for key" state. */
3337 /* ######################################################################## */
3339 IwavePnpWake(BYTE csn)
3342 outb(_PIDXR, _PWAKEI); /* select PWAKEI */
3343 outb(_PNPWRP, csn); /* write csn */
3346 /* ######################################################################## */
3349 * FUNCTION: IwavePnpPing
3352 /* PROFILE: This function allows the caller to detect an InterWave based */
3353 /* adapter board and will return its asigned CSN so that an */
3354 /* an application can access its PnP interface and determine the */
3355 /* borad's current configuration. In conducting its search for */
3356 /* the InterWave IC, the function will use the first 32 bits of */
3357 /* the Serial Identifier called the vendor ID in the PnP ISA */
3358 /* spec. The last 4 bits in the Vendor ID represent a revision */
3359 /* number for the particular product and will not be included */
3360 /* in the search. The function will return the Vendor ID and the */
3361 /* calling application should check the revision bits to make */
3362 /* sure they are compatible with the board. */
3364 /* ######################################################################## */
3366 IwavePnpPing(DWORD VendorID)
3370 VendorID &= (0xFFFFFFF0); /* reset 4 least significant bits */
3371 IwavePnpKey(); /* Key to access PnP Interface */
3372 while (iw.pnprdp <= 0x23F) {
3373 for (csn = 1; csn <= 10; csn++) {
3374 IwavePnpWake(csn); /* Select card */
3375 IwavePnpPeek(iw.pnprdp, 4, (BYTE *) & iw.vendor); /* get vendor ID */
3378 if (((iw.vendor) & 0xFFFFFFF0) == VendorID) { /* If IDs match,
3379 * InterWave is found */
3381 outb(_PIDXR, 0x02); /* Place all cards in
3382 * wait-for-key state */
3389 outb(_PIDXR, 0x02); /* Place all cards in wait-for-key state */
3391 return (FALSE); /* InterWave IC not found */
3394 /* end of pnp code */
3402 outb(iw.igidxr, _LMCI);
3403 outb(iw.i8dp, inb(iw.i8dp) & 0xFD); /* DRAM I/O cycles selected */
3406 IwaveMemPoke(local, datum);
3407 IwaveMemPoke(local + 1L, datum + 1);
3408 if (IwaveMemPeek(local) != datum || IwaveMemPeek(local + 1L) != (datum + 1) || IwaveMemPeek(0L) != 0x55)
3413 return ((WORD) (local >> 10));
3417 IwaveMemPeek(ADDRESS addr)
3424 outb(iw.igidxr, 0x43); /* Select LMALI */
3425 outw(iw.i16dp, (WORD) addr); /* Lower 16 bits of LM */
3426 outb(iw.igidxr, 0x44); /* Select LMAHI */
3427 outb(iw.i8dp, (BYTE) (addr >> 16)); /* Upper 8 bits of LM */
3428 return (inb(iw.lmbdr)); /* return byte from LMBDR */
3433 IwaveMemPoke(ADDRESS addr, BYTE datum)
3439 outb(iw.igidxr, 0x43); /* Select LMALI */
3440 outw(iw.i16dp, (WORD) addr); /* Lower 16 bits of LM */
3441 outb(iw.igidxr, 0x44); /* Select LMAHI */
3442 outb(iw.i8dp, (BYTE) (addr >> 16)); /* Upper 8 bits of LM */
3443 outb(iw.lmbdr, datum); /* Write byte to LMBDR */
3446 /* ######################################################################## */
3448 /* FUNCTION: IwaveMemCfg */
3450 /* PROFILE : This function determines the amount of DRAM from its */
3451 /* configuration accross all banks. It sets the configuration */
3452 /* into register LMCFI and stores the total amount of DRAM */
3453 /* into iw.size_mem (Kbytes). */
3455 /* The function first places the IC in enhanced mode to allow */
3456 /* full access to all DRAM locations. Then it selects full */
3457 /* addressing span (LMCFI[3:0]=0x0C). Finally, it determines */
3458 /* the amount of DRAM in each bank and from this the actual */
3459 /* configuration. */
3461 /* Note that if a configuration other than one indicated in */
3462 /* the manual is implemented, this function will select */
3463 /* full addressing span (LMCFI[3:0]=0xC). */
3465 /* ######################################################################## */
3467 IwaveMemCfg(DWORD * lpbanks)
3469 DWORD bank[4] = {0L, 0L, 0L, 0L};
3470 DWORD addr = 0L, base = 0L, cnt = 0L;
3471 BYTE i, reg, ram = FALSE;
3475 outb(iw.igidxr, 0x99);
3476 reg = inb(iw.i8dp); /* image of sgmi */
3477 outb(iw.igidxr, 0x19);
3478 outb(iw.i8dp, (BYTE) (reg | 0x01)); /* enable enhaced mode */
3479 outb(iw.igidxr, _LMCFI);/* select LM Conf Reg */
3480 lmcfi = inw(iw.i16dp) & 0xFFF0;
3481 outw(iw.i16dp, lmcfi | 0x000C); /* max addr span */
3483 /* Clear every RAM_STEPth location */
3485 while (addr < RAM_MAX) {
3486 IwaveMemPoke(addr, 0x00);
3490 /* Determine amount of RAM in each bank */
3492 for (i = 0; i < 4; i++) {
3493 IwaveMemPoke(base, 0xAA); /* mark start of bank */
3494 IwaveMemPoke(base + 1L, 0x55);
3495 if ((IwaveMemPeek(base) == 0xAA) && (IwaveMemPeek(base + 1L) == 0x55))
3498 while (cnt < BANK_MAX) {
3499 bank[i] += RAM_STEP;
3502 if (IwaveMemPeek(addr) == 0xAA)
3506 if (lpbanks != NULL) {
3510 bank[i] = bank[i] >> 10;
3516 iw.flags &= ~DRAM_HOLES;
3517 outb(iw.igidxr, _LMCFI);
3518 if (bank[0] == 256 && bank[1] == 0 && bank[2] == 0 && bank[3] == 0)
3519 outw(iw.i16dp, lmcfi);
3520 else if (bank[0] == 256 && bank[1] == 256 && bank[2] == 0 && bank[3] == 0)
3521 outw(iw.i16dp, lmcfi | 0x01);
3522 else if (bank[0] == 256 && bank[1] == 256 && bank[2] == 256 && bank[3] == 256)
3523 outw(iw.i16dp, lmcfi | 0x02);
3524 else if (bank[0] == 256 && bank[1] == 1024 && bank[2] == 0 && bank[3] == 0)
3525 outw(iw.i16dp, lmcfi | 0x03);
3526 else if (bank[0] == 256 && bank[1] == 1024 && bank[2] == 1024 && bank[3] == 1024)
3527 outw(iw.i16dp, lmcfi | 0x04);
3528 else if (bank[0] == 256 && bank[1] == 256 && bank[2] == 1024 && bank[3] == 0)
3529 outw(iw.i16dp, lmcfi | 0x05);
3530 else if (bank[0] == 256 && bank[1] == 256 && bank[2] == 1024 && bank[3] == 1024)
3531 outw(iw.i16dp, lmcfi | 0x06);
3532 else if (bank[0] == 1024 && bank[1] == 0 && bank[2] == 0 && bank[3] == 0)
3533 outw(iw.i16dp, lmcfi | 0x07);
3534 else if (bank[0] == 1024 && bank[1] == 1024 && bank[2] == 0 && bank[3] == 0)
3535 outw(iw.i16dp, lmcfi | 0x08);
3536 else if (bank[0] == 1024 && bank[1] == 1024 && bank[2] == 1024 && bank[3] == 1024)
3537 outw(iw.i16dp, lmcfi | 0x09);
3538 else if (bank[0] == 4096 && bank[1] == 0 && bank[2] == 0 && bank[3] == 0)
3539 outw(iw.i16dp, lmcfi | 0x0A);
3540 else if (bank[0] == 4096 && bank[1] == 4096 && bank[2] == 0 && bank[3] == 0)
3541 outw(iw.i16dp, lmcfi | 0x0B);
3542 else /* Flag the non-contiguous config of memory */
3543 iw.flags |= DRAM_HOLES;
3545 outb(iw.igidxr, 0x19); /* restore sgmi */
3551 /* ######################################################################## */
3553 /* FUNCTION: IwaveCodecIrq */
3555 /* PROFILE: This function disables or enables the Codec Interrupts. To */
3556 /* enable interrupts set CEXTI[2] high thus causing all interrupt */
3557 /* sources (CSR3I[6:4]) to pass onto the IRQ pin. To disable */
3558 /* interrupts set CEXTI[1]=0. To enable Code IRQs issue this call: */
3560 /* IwaveCodecIrq(CODEC_IRQ_ENABLE). To disable IRQs issue the call */
3562 /* IwaveCodeIrq(~CODEC_IRQ_ENABLE). */
3564 /* ######################################################################## */
3566 IwaveCodecIrq(BYTE mode)
3571 reg = inb(iw.pcodar) & 0xE0;
3572 outb(iw.pcodar, reg | _CSR3I); /* select CSR3I */
3573 outb(iw.cdatap, 0x00); /* clear all interrupts */
3574 outb(iw.pcodar + 0x02, 0x00); /* clear CSR1R */
3575 outb(iw.pcodar, reg | _CEXTI); /* select CEXTI */
3576 reg = inb(iw.cdatap);
3577 if (mode == CODEC_IRQ_ENABLE) /* enable Codec Irqs */
3578 outb(iw.cdatap, (BYTE) (reg | CODEC_IRQ_ENABLE));
3579 else /* disable Codec Irqs */
3580 outb(iw.cdatap, (BYTE) (reg & ~CODEC_IRQ_ENABLE));
3585 /* ######################################################################### */
3587 /* FUNCTION: IwaveRegPeek */
3589 /* PROFILE : This function returns the value stored in any readable */
3590 /* InterWave register. It takes as input a pointer to a */
3591 /* structure containing the addresses of the relocatable I/O */
3592 /* space as well as a register mnemonic. To correctly use this */
3593 /* function, the programmer must use the mnemonics defined in */
3594 /* "iwdefs.h". These mnemonics contain coded information used */
3595 /* by the function to properly access the desired register. */
3597 /* An attempt to read from a write-only register will return */
3598 /* meaningless data. */
3600 /* ######################################################################### */
3602 IwaveRegPeek(DWORD reg_mnem)
3605 WORD reg_id, offset;
3607 offset = (WORD) ((BYTE) reg_mnem);
3608 reg_id = (WORD) (reg_mnem >> 16);
3609 index = (BYTE) (reg_mnem >> 8);
3611 /* ################################################### */
3612 /* Logic to read registers in P2XR block & GMCR */
3613 /* ################################################### */
3615 if (reg_id >= 0x0001 && reg_id <= 0x001A) { /* UMCR to GMCR */
3616 if (reg_id <= 0x000E) /* UMCR to USRR */
3617 return ((WORD) inb(iw.p2xr + offset));
3619 if (reg_id == 0x0019)
3620 return ((WORD) inb(iw.p201ar));
3622 else { /* GUS Hidden registers or GMCR */
3625 outb(iw.igidxr, 0x5B); /* select IVERI */
3626 iveri = inb(iw.i8dp); /* read IVERI */
3627 outb(iw.i8dp, (BYTE) (iveri | 0x09)); /* set IVERI[3,0] */
3628 if (reg_id == 0x001A) { /* GMCR */
3630 outb(iw.i8dp, iveri); /* restore IVERI */
3631 return ((WORD) val);
3633 val = inb(iw.p2xr + 0x0F); /* read URCR */
3634 val = (val & 0xF8) | index; /* value for URCR[2:0] */
3635 outb(iw.p2xr + 0x0F, val); /* set URCR[2:0] */
3637 if (reg_mnem == UDCI || reg_mnem == UICI) {
3639 if (reg_mnem == UDCI)
3640 outb(iw.p2xr, (BYTE) (val & 0xBF));
3642 outb(iw.p2xr, (BYTE) (val | 0x40));
3644 val = inb(iw.p2xr + 0x0B);
3645 outb(iw.igidxr, 0x5B); /* select IVERI */
3646 outb(iw.i8dp, iveri); /* restore IVERI */
3647 return ((WORD) val); /* read register */
3650 /* ################################################### */
3651 /* Logic to read registers in P3XR block */
3652 /* ################################################### */
3654 if (reg_id >= 0x001B && reg_id <= 0x005C) { /* GMSR to LMBDR */
3655 if (reg_id == 0x005C) /* LMBDR */
3656 return ((WORD) inb(iw.lmbdr));
3658 if (reg_id >= 0x001B && reg_id <= 0x0021) /* GMSR to I8DP */
3660 return (inw(iw.i16dp));
3662 return ((WORD) inb(iw.p3xr + offset));
3663 else { /* indexed registers */
3665 if (reg_id <= 0x003F)
3666 index |= 0x80; /* adjust for reading */
3668 outb(iw.igidxr, index); /* select register */
3671 return (inw(iw.i16dp));
3673 return ((WORD) inb(iw.i8dp));
3676 /* #################################################### */
3677 /* Logic to read registers in PCODAR block */
3678 /* #################################################### */
3680 if (reg_id >= 0x005D && reg_id <= 0x0081) { /* CIDXR to CLRCTI */
3681 if (reg_id <= 0x0061)
3682 return ((WORD) inb(iw.pcodar + offset)); /* CRDR */
3684 else { /* indexed registers */
3687 cidxr = inb(iw.pcodar);
3688 cidxr = (cidxr & 0xE0) + index;
3689 outb(iw.pcodar, cidxr); /* select register */
3690 return ((WORD) inb(iw.cdatap));
3693 /* ##################################################### */
3694 /* Logic to read the PnP registers */
3695 /* ##################################################### */
3696 if (reg_id >= 0x0082 && reg_id <= 0x00B7) { /* PCSNBR to PMITI */
3697 if (reg_id == 0x0085)
3698 return ((WORD) inb(iw.pnprdp));
3700 if (reg_id < 0x0085)
3701 return ((WORD) inb((WORD) reg_mnem));
3703 else { /* indexed registers */
3704 if (reg_id >= 0x008E && reg_id <= 0x00B7) {
3705 outb(0x0279, 0x07); /* select PLDNI */
3706 outb(0xA79, (BYTE) offset); /* select logical dev */
3708 outb(0x0279, index); /* select the register */
3709 return ((WORD) inb(iw.pnprdp));
3714 /* ######################################################################### */
3716 /* FUNCTION: IwaveRegPoke */
3718 /* PROFILE : This function writes a value to any writable */
3719 /* InterWave register. It takes as input a pointer to a */
3720 /* structure containing the addresses of the relocatable I/O */
3721 /* space as well as a register mnemonic. To correctly use this */
3722 /* function, the programmer must use the mnemonics defined in */
3723 /* "iwdefs.h". These mnemonics contain coded information used */
3724 /* by the function to properly access the desired register. */
3726 /* This function does not guard against writing to read-only */
3727 /* registers. It is the programmer's responsibility to ensure */
3728 /* that the writes are to valid registers. */
3730 /* ######################################################################### */
3732 IwaveRegPoke(DWORD reg_mnem, WORD datum)
3739 offset = (WORD) ((BYTE) reg_mnem);
3740 reg_id = (WORD) (reg_mnem >> 16);
3741 index = (BYTE) (reg_mnem >> 8);
3744 /* ####################################################### */
3745 /* Logic to write to registers in P2XR block */
3746 /* ####################################################### */
3747 if (reg_id >= 0x0001 && reg_id <= 0x0019) { /* UMCR to GGCR */
3748 if (reg_id <= 0x000E) { /* UMCR to USRR */
3749 outb(iw.p2xr + offset, (BYTE) datum);
3752 if (reg_id == 0x0019) {
3753 outb(iw.p201ar, (BYTE) datum);
3755 } else { /* GUS Hidden registers */
3759 outb(iw.igidxr, 0x5B); /* select IVERI */
3760 iveri = inb(iw.i8dp); /* read IVERI */
3761 outb(iw.i8dp, (BYTE) (iveri | 0x09)); /* set IVERI[3,0] */
3762 val = inb(iw.p2xr + 0x0F); /* read URCR */
3763 val = (val & 0xF8) | index; /* value for URCR[2:0] */
3764 outb(iw.p2xr + 0x0F, val); /* set URCR[2:0] */
3766 if (reg_mnem == UDCI || reg_mnem == UICI) {
3767 val = inb(iw.p2xr); /* read UMCR */
3768 if (reg_mnem == UDCI)
3769 outb(iw.p2xr, (BYTE) (val & 0xBF)); /* set UMCR[6]=0 */
3771 outb(iw.p2xr, (BYTE) (val | 0x40)); /* set UMCR[6]=1 */
3773 outb(iw.p2xr + 0x0B, (BYTE) datum); /* write register */
3774 outb(iw.igidxr, 0x5B); /* select IVERI */
3775 outb(iw.i8dp, iveri); /* restore IVERI */
3779 /* ############################################################# */
3780 /* Logic to write to registers in P3XR block */
3781 /* ############################################################# */
3783 if (reg_id >= 0x001A && reg_id <= 0x005C) { /* GMCR to LMBDR */
3785 if (reg_id == 0x005C) { /* LMBDR */
3786 outb(iw.lmbdr, (BYTE) datum);
3789 if (reg_id == 0x001B) /* GMSR */
3792 if (reg_id >= 0x001A && reg_id <= 0x0021) /* GMCR to I8DP */
3794 outw(iw.i16dp, datum);
3796 outb(iw.p3xr + offset, (BYTE) datum);
3797 else { /* indexed registers */
3798 outb(iw.igidxr, index); /* select register */
3801 outw(iw.i16dp, datum);
3803 outb(iw.i8dp, (BYTE) datum);
3806 /* /################################################### */
3807 /* Logic to write to registers in PCODAR block */
3808 /* ################################################### */
3810 if (reg_id >= 0x005C && reg_id <= 0x0081) { /* CIDXR to CLRCTI */
3811 if (reg_id <= 0x0061)
3812 outb(iw.pcodar + offset, (BYTE) datum);
3814 else { /* one of the indexed registers */
3817 cidxr = inb(iw.pcodar);
3818 cidxr = (cidxr & 0xE0) + index;
3819 outb(iw.pcodar, cidxr); /* select register */
3820 outb(iw.cdatap, (BYTE) datum);
3823 /* ###################################################### */
3824 /* Logic to write to the PnP registers */
3825 /* ###################################################### */
3826 if (reg_id >= 0x0082 && reg_id <= 0x00B7) {
3827 if (reg_id == 0x0085) {
3828 outb(iw.pnprdp, (BYTE) datum);
3831 if (reg_id < 0x0085)
3832 outb((WORD) reg_mnem, (BYTE) datum);
3834 else { /* one of the indexed registers */
3835 if (reg_id >= 0x008E && reg_id <= 0x00B7) {
3836 outb(0x0279, 0x07); /* select PLDNI */
3837 outb(0xA79, (BYTE) offset); /* select logical dev */
3839 outb(0x0279, index); /* select the register */
3840 outb(0xA79, (BYTE) datum);
3847 IwaveLineLevel(char level, char index)
3854 reg = inb(iw.pcodar) & 0xE0;
3855 outb(iw.pcodar, reg | index); /* select register */
3856 outb(iw.cdatap, (BYTE) ((inb(iw.cdatap) & 0x80) | level)); /* set level */
3861 IwaveCodecMode(char mode)
3866 reg = inb(iw.pcodar) & 0xE0;
3867 outb(iw.pcodar, reg | _CMODEI); /* select CMODEI */
3868 outb(iw.cdatap, mode);
3874 IwaveLineMute(BYTE mute, BYTE inx)
3879 reg = inb(iw.pcodar) & 0xE0;
3880 outb(iw.pcodar, reg | inx); /* select register */
3882 outb(iw.cdatap, (BYTE) (inb(iw.cdatap) | 0x80)); /* mute */
3884 outb(iw.cdatap, (BYTE) (inb(iw.cdatap) & 0x7F)); /* unmute */
3892 u_short iwl_codec_base = iw.pcodar;
3893 u_short iwl_codec_data = iw.pcodar + 1;
3899 * Set the CEXTI register foo = CODEC_CEXTI_DEFAULT;
3900 * IWL_CODEC_OUT(EXTERNAL_CONTROL, foo);
3903 * Disable Interrupts iwl_codec_disable_irqs();
3906 /* Set the CODEC to Operate in Mode 3 */
3907 IWL_CODEC_OUT(MODE_SELECT_ID, 0x6C);
3908 foo = inb(iwl_codec_data);
3910 /* Set the configuration registers to their default values */
3911 foo = CODEC_CFIG1I_DEFAULT;
3912 IWL_CODEC_OUT(CONFIG_1 | CODEC_MCE, foo);
3913 outb(iwl_codec_base, CONFIG_1);
3914 foo = CODEC_CFIG2I_DEFAULT;
3915 IWL_CODEC_OUT(CONFIG_2, foo);
3917 foo = CODEC_CFIG3I_DEFAULT;
3918 IWL_CODEC_OUT(CONFIG_3, foo);
3925 IwaveOpen(char voices, char mode, struct address_info * hw)
3934 if (IwavePnpIsol(&iw.pnprdp)) {
3936 iw.vendor = GUS_PNP_ID;
3938 iw.csn = IwavePnpPing(iw.vendor);
3942 IwavePnpWake(iw.csn);
3947 IwavePnpWake(iw.csn);
3950 /* I see the user wants to set the GUS PnP */
3951 /* Okay lets do it */
3953 iw.p2xr = hw->io_base;
3954 iw.p3xr = hw->io_base + 0x100;
3955 iw.pcodar = hw->io_base + 0x10c;
3957 iw.synth_irq = hw->irq;
3959 iw.midi_irq = hw->irq;
3961 iw.dma1_chan = hw->dma;
3963 if (hw->dma2 == -1) {
3964 iw.dma2_chan = hw->dma;
3966 iw.dma2_chan = hw->dma2;
3972 /* tell the os what we are doing 8) */
3973 hw->io_base = iw.p2xr;
3974 hw->irq = iw.synth_irq;
3976 * iw.dma1_chan = 1; iw.dma2_chan = 3 ;
3978 hw->dma = iw.dma1_chan;
3979 hw->dma2 = iw.dma2_chan;
3984 if (iw.csn > 0 && iw.csn < MAX_GUS_PNP) {
3985 gus_pnp_found[iw.csn] = hw->io_base;
3988 iw.cdatap = iw.pcodar + 1;
3989 iw.csr1r = iw.pcodar + 2;
3990 iw.cxdr = iw.pcodar + 3;/* CPDR or CRDR */
3992 iw.gmxdr = iw.p3xr + 1; /* GMTDR or GMRDR */
3993 iw.svsr = iw.p3xr + 2;
3994 iw.igidxr = iw.p3xr + 3;
3995 iw.i16dp = iw.p3xr + 4;
3996 iw.i8dp = iw.p3xr + 5;
3997 iw.lmbdr = iw.p3xr + 7;
4000 if (iw.pnprdp > 0 && iw.csn > 0) {
4002 IwavePnpActivate(AUDIO, ON);
4003 IwavePnpActivate(EXT, ON);
4005 /* IwavePnpActivate(EMULATION,ON); */
4009 outb(iw.igidxr, _URSTI);/* Pull reset */
4010 outb(iw.i8dp, 0x00);
4013 outb(iw.i8dp, 0x01); /* Release reset */
4022 tmp = IwaveRegPeek(IDECI);
4024 IwaveRegPoke(IDECI, tmp | 0x18);
4026 IwaveCodecMode(CODEC_MODE2); /* Default codec mode */
4027 IwaveRegPoke(ICMPTI, 0);
4029 outb(iw.igidxr, 0x99);
4031 outb(iw.igidxr, 0x19);
4036 IwaveCodecIrq(~CODEC_IRQ_ENABLE);
4040 outb(iw.p2xr, 0x0c); /* Disable line in, mic and line out */
4042 IwaveRegPoke(CLCI, 0x3f << 2);
4044 IwaveLineLevel(0, _CLOAI);
4045 IwaveLineLevel(0, _CROAI);
4047 IwaveLineMute(OFF, _CLOAI);
4048 IwaveLineMute(OFF, _CROAI);
4050 IwaveLineLevel(0, _CLLICI);
4051 IwaveLineLevel(0, _CRLICI);
4052 IwaveLineMute(OFF, _CLLICI);
4053 IwaveLineMute(OFF, _CRLICI);
4055 IwaveLineLevel(0, _CLDACI);
4056 IwaveLineLevel(0, _CRDACI);
4057 IwaveLineMute(ON, _CLDACI);
4058 IwaveLineMute(ON, _CRDACI);
4060 IwaveLineLevel(0, _CLLICI);
4061 IwaveLineLevel(0, _CRLICI);
4062 IwaveLineMute(ON, _CLLICI);
4063 IwaveLineMute(ON, _CRLICI);
4066 IwaveInputSource(LEFT_SOURCE, MIC_IN);
4067 IwaveInputSource(RIGHT_SOURCE, MIC_IN);
4069 outb(iw.pcodar, 0x9 | 0x40);
4071 IwaveCodecIrq(CODEC_IRQ_ENABLE);
4072 outb(iw.pcodar, _CFIG3I | 0x20);
4075 outb(iw.cdatap, 0xC2); /* Enable Mode 3 IRQs & Synth */
4077 outb(iw.igidxr, _URSTI);
4078 outb(iw.i8dp, GF1_SET | GF1_OUT_ENABLE | GF1_IRQ_ENABLE);
4080 iw.size_mem = IwaveMemSize(); /* Bytes of RAM in this mode */
4081 outb(iw.p2xr, 0xc); /* enable output */
4082 IwaveRegPoke(CLCI, 0x3f << 2);
4084 IwaveCodecIrq(CODEC_IRQ_ENABLE);
4088 IwaveRegPoke(CPDFI, 0);
4095 gus_wave_init(struct address_info * hw_config)
4098 u_char val, gus_pnp_seen = 0;
4099 char *model_num = "2.4";
4100 int gus_type = 0x24; /* 2.4 */
4101 int irq = hw_config->irq, dma = hw_config->dma, dma2 = hw_config->dma2;
4102 int otherside = -1, i;
4104 if (irq < 0 || irq > 15) {
4105 printf("ERROR! Invalid IRQ#%d. GUS Disabled", irq);
4108 if (dma < 0 || dma > 7) {
4109 printf("ERROR! Invalid DMA#%d. GUS Disabled", dma);
4112 for (i = 0; i < MAX_GUS_PNP; i++) {
4113 if (gus_pnp_found[i] != 0 && gus_pnp_found[i] == hw_config->io_base)
4128 * Try to identify the GUS model.
4130 * Versions < 3.6 don't have the digital ASIC. Try to probe it first.
4134 outb(gus_base + 0x0f, 0x20);
4135 val = inb(gus_base + 0x0f);
4138 if (val != 0xff && (val & 0x06)) { /* Should be 0x02?? */
4140 * It has the digital ASIC so the card is at least v3.4. Next
4141 * try to detect the true model.
4144 val = inb(u_MixSelect);
4147 * Value 255 means pre-3.7 which don't have mixer. Values 5
4148 * thru 9 mean v3.7 which has a ICS2101 mixer. 10 and above
4149 * is GUS MAX which has the CS4231 codec/mixer.
4156 if (val == 255 || val < 5) {
4159 } else if (val < 10) {
4162 mixer_type = ICS2101;
4170 mixer_type = CS4231;
4171 #ifdef CONFIG_GUSMAX
4173 u_char max_config = 0x40; /* Codec enable */
4179 max_config |= 0x10; /* 16 bit capture DMA */
4182 max_config |= 0x20; /* 16 bit playback DMA */
4184 max_config |= (gus_base >> 4) & 0x0f; /* Extract the X from
4187 outb(gus_base + 0x106, max_config); /* UltraMax control */
4190 if (ad1848_detect(gus_base + 0x10c, NULL, hw_config->osp)) {
4192 gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
4193 gus_wave_volume = 90;
4197 ad1848_init("GUS PNP", gus_base + 0x10c,
4199 gus_dma2, /* Playback DMA */
4200 gus_dma, /* Capture DMA */
4201 1, /* Share DMA channels with GF1 */
4206 ad1848_init("GUS MAX", gus_base + 0x10c,
4208 gus_dma2, /* Playback DMA */
4209 gus_dma, /* Capture DMA */
4210 1, /* Share DMA channels with GF1 */
4213 otherside = num_audiodevs - 1;
4216 printf("[Where's the CS4231?]");
4218 printf("\n\n\nGUS MAX support was not compiled in!!!\n\n\n\n");
4223 * ASIC not detected so the card must be 2.2 or 2.4. There
4224 * could still be the 16-bit/mixer daughter card.
4229 snprintf(gus_info.name, sizeof(gus_info.name),
4230 "Gravis %s (%dk)", model_num, (int) gus_mem_size / 1024);
4232 snprintf(gus_info.name, sizeof(gus_info.name),
4233 "Gravis UltraSound %s (%dk)", model_num, (int) gus_mem_size / 1024);
4235 conf_printf(gus_info.name, hw_config);
4237 if (num_synths >= MAX_SYNTH_DEV)
4238 printf("GUS Error: Too many synthesizers\n");
4240 voice_alloc = &guswave_operations.alloc;
4241 synth_devs[num_synths++] = &guswave_operations;
4242 #ifdef CONFIG_SEQUENCER
4243 gus_tmr_install(gus_base + 8);
4246 samples = (struct patch_info *) malloc((MAX_SAMPLE + 1) * sizeof(*samples), M_DEVBUF, M_NOWAIT);
4248 panic("SOUND: Cannot allocate memory\n");
4250 reset_sample_memory();
4254 if (num_audiodevs < MAX_AUDIO_DEV) {
4255 audio_devs[gus_devnum = num_audiodevs++] = &gus_sampling_operations;
4256 audio_devs[gus_devnum]->otherside = otherside;
4257 audio_devs[gus_devnum]->dmachan1 = dma;
4258 audio_devs[gus_devnum]->dmachan2 = dma2;
4259 audio_devs[gus_devnum]->buffsize = DSP_BUFFSIZE;
4260 if (otherside != -1) {
4262 * glue logic to prevent people from opening the gus
4263 * max via the gf1 and the cs4231 side . Only the gf1
4264 * or the cs4231 are allowed to be open
4267 audio_devs[otherside]->otherside = gus_devnum;
4269 if (dma2 != dma && dma2 != -1)
4270 audio_devs[gus_devnum]->flags |= DMA_DUPLEX;
4272 printf("GUS: Too many PCM devices available\n");
4275 * Mixer dependent initialization.
4278 switch (mixer_type) {
4280 gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
4281 gus_wave_volume = 90;
4282 ics2101_mixer_init();
4286 /* Initialized elsewhere (ad1848.c) */
4288 gus_default_mixer_init();
4294 do_loop_irq(int voice)
4301 gus_select_voice(voice);
4303 tmp = gus_read8(0x00);
4304 tmp &= ~0x20; /* Disable wave IRQ for this_one voice */
4305 gus_write8(0x00, tmp);
4307 if (tmp & 0x03) /* Voice stopped */
4308 voice_alloc->map[voice] = 0;
4310 mode = voices[voice].loop_irq_mode;
4311 voices[voice].loop_irq_mode = 0;
4312 parm = voices[voice].loop_irq_parm;
4316 case LMODE_FINISH: /* Final loop finished, shoot volume down */
4318 if ((int) (gus_read16(0x09) >> 4) < 100) { /* Get current volume */
4321 gus_voice_init(voice);
4324 gus_ramp_range(65, 4065);
4325 gus_ramp_rate(0, 63); /* Fastest possible rate */
4326 gus_rampon(0x20 | 0x40); /* Ramp down, once, irq */
4327 voices[voice].volume_irq_mode = VMODE_HALT;
4330 case LMODE_PCM_STOP:
4331 pcm_active = 0; /* Signal to the play_next_pcm_block routine */
4334 int flag; /* 0 or 2 */
4337 pcm_head = (pcm_head + 1) % pcm_nblk;
4338 if (pcm_qlen && pcm_active) {
4339 play_next_pcm_block();
4340 } else {/* Underrun. Just stop the voice */
4341 gus_select_voice(0); /* Left channel */
4344 gus_select_voice(1); /* Right channel */
4351 * If the queue was full before this interrupt, the
4352 * DMA transfer was suspended. Let it continue now.
4356 flag = 1; /* Underflow */
4361 flag = 2; /* Just notify the dmabuf.c */
4362 DMAbuf_outputintr(gus_devnum, flag);
4372 do_volume_irq(int voice)
4380 gus_select_voice(voice);
4382 tmp = gus_read8(0x0d);
4383 tmp &= ~0x20; /* Disable volume ramp IRQ */
4384 gus_write8(0x0d, tmp);
4386 mode = voices[voice].volume_irq_mode;
4387 voices[voice].volume_irq_mode = 0;
4388 parm = voices[voice].volume_irq_parm;
4391 case VMODE_HALT: /* Decay phase finished */
4393 gus_voice_init(voice);
4396 case VMODE_ENVELOPE:
4399 step_envelope(voice);
4402 case VMODE_START_NOTE:
4404 guswave_start_note2(voices[voice].dev_pending, voice,
4405 voices[voice].note_pending, voices[voice].volume_pending);
4406 if (voices[voice].kill_pending)
4407 guswave_kill_note(voices[voice].dev_pending, voice,
4408 voices[voice].note_pending, 0);
4410 if (voices[voice].sample_pending >= 0) {
4411 guswave_set_instr(voices[voice].dev_pending, voice,
4412 voices[voice].sample_pending);
4413 voices[voice].sample_pending = -1;
4424 u_long wave_ignore = 0, volume_ignore = 0;
4430 src = gus_read8(0x0f); /* Get source info */
4434 if (src == (0x80 | 0x40))
4435 return; /* No interrupt */
4437 voice_bit = 1 << voice;
4439 if (!(src & 0x80)) /* Wave IRQ pending */
4440 if (!(wave_ignore & voice_bit) && (int) voice < nr_voices) { /* Not done yet */
4441 wave_ignore |= voice_bit;
4444 if (!(src & 0x40)) /* Volume IRQ pending */
4445 if (!(volume_ignore & voice_bit) && (int) voice < nr_voices) { /* Not done yet */
4446 volume_ignore |= voice_bit;
4447 do_volume_irq(voice);
4453 guswave_dma_irq(void)
4457 status = gus_look8(0x41); /* Get DMA IRQ Status */
4458 if (status & 0x40) /* DMA interrupt pending */
4459 switch (active_device) {
4461 if ((dram_sleep_flag.mode & WK_SLEEP)) {
4462 dram_sleep_flag.mode = WK_WAKEUP;
4463 wakeup(dram_sleeper);
4467 case GUS_DEV_PCM_CONTINUE: /* Left channel data transferred */
4468 gus_transfer_output_block(pcm_current_dev, pcm_current_buf,
4469 pcm_current_count, pcm_current_intrflag, 1);
4472 case GUS_DEV_PCM_DONE: /* Right or mono channel data transferred */
4473 if (pcm_qlen < pcm_nblk) {
4474 int flag = (1 - dma_active) * 2; /* 0 or 2 */
4477 flag = 1; /* Underrun */
4479 DMAbuf_outputintr(gus_devnum, flag);
4486 status = gus_look8(0x49); /* Get Sampling IRQ Status */
4487 if (status & 0x40) { /* Sampling Irq pending */
4488 DMAbuf_inputintr(gus_devnum);
4492 #ifdef CONFIG_SEQUENCER
4497 static volatile int select_addr, data_addr;
4498 static volatile int curr_timer = 0;
4501 gus_timer_command(u_int addr, u_int val)
4505 outb(select_addr, (u_char) (addr & 0xff));
4507 for (i = 0; i < 2; i++)
4510 outb(data_addr, (u_char) (val & 0xff));
4512 for (i = 0; i < 2; i++)
4517 arm_timer(int timer, u_int interval)
4522 gus_write8(0x46, 256 - interval); /* Set counter for timer 1 */
4523 gus_write8(0x45, 0x04); /* Enable timer 1 IRQ */
4524 gus_timer_command(0x04, 0x01); /* Start timer 1 */
4526 gus_write8(0x47, 256 - interval); /* Set counter for timer 2 */
4527 gus_write8(0x45, 0x08); /* Enable timer 2 IRQ */
4528 gus_timer_command(0x04, 0x02); /* Start timer 2 */
4531 gus_timer_enabled = 0;
4535 gus_tmr_start(int dev, u_int usecs_per_tick)
4537 int timer_no, resolution;
4540 if (usecs_per_tick > (256 * 80)) {
4542 resolution = 320; /* usec */
4545 resolution = 80;/* usec */
4548 divisor = (usecs_per_tick + (resolution / 2)) / resolution;
4550 arm_timer(timer_no, divisor);
4552 return divisor * resolution;
4556 gus_tmr_disable(int dev)
4558 gus_write8(0x45, 0); /* Disable both timers */
4559 gus_timer_enabled = 0;
4563 gus_tmr_restart(int dev)
4565 if (curr_timer == 1)
4566 gus_write8(0x45, 0x04); /* Start timer 1 again */
4568 gus_write8(0x45, 0x08); /* Start timer 2 again */
4571 static struct sound_lowlev_timer gus_tmr =
4580 gus_tmr_install(int io_base)
4582 select_addr = io_base;
4583 data_addr = io_base + 1;
4585 sound_timer_init(&gus_tmr, "GUS");