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 $
33 #include <i386/isa/sound/sound_config.h>
34 #include <i386/isa/sound/ultrasound.h>
35 #include <i386/isa/sound/gus_hw.h>
36 #include <i386/isa/sound/iwdefs.h>
37 #include <machine/clock.h>
40 #define GUS_PNP_ID 0x100561e
43 #define MAX_GUS_PNP 12
47 #define PADDRESS 0x279
48 #define PWRITE_DATA 0xa79
52 /* PnP Registers. Write to ADDRESS and then use WRITE/READ_DATA */
53 #define SET_RD_DATA 0x00
54 #define SERIAL_ISOLATION 0x01
57 #if defined(CONFIG_GUS)
60 #define ENTER_CRITICAL
62 #define LEAVE_CRITICAL
64 #define MAX_SAMPLE 150
68 static u_int gus_pnp_found[MAX_GUS_PNP] =
69 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
81 int loop_irq_mode, loop_irq_parm;
82 #define LMODE_FINISH 1
84 #define LMODE_PCM_STOP 3
85 int volume_irq_mode, volume_irq_parm;
87 #define VMODE_ENVELOPE 2
88 #define VMODE_START_NOTE 3
95 * Volume computation parameters for gus_adagio_vol()
97 int main_vol, expression_vol, patch_vol;
99 /* Variables for "Ultraclick" removal */
100 int dev_pending, note_pending, volume_pending, sample_pending;
106 static struct voice_alloc_info *voice_alloc;
109 extern int gus_irq, gus_dma;
110 static int gus_dma2 = -1;
111 static int dual_dma_mode = 0;
112 static long gus_mem_size = 0;
113 static long free_mem_ptr = 0;
114 static int gus_no_dma = 0;
115 static int nr_voices = 0;
116 static int gus_devnum = 0;
117 static int volume_base, volume_scale, volume_method;
118 static int gus_recmask = SOUND_MASK_MIC;
119 static int recording_active = 0;
120 static int only_read_access = 0;
121 static int only_8_bits = 0;
123 int gus_wave_volume = 60;
124 static int gus_pcm_volume = 80;
125 int have_gus_max = 0;
126 static int gus_line_vol = 100, gus_mic_vol = 0;
127 static u_char mix_image = 0x00;
129 int gus_timer_enabled = 0;
131 * Current version of this driver doesn't allow synth and PCM functions at
132 * the same time. The active_device specifies the active driver
134 static int active_device = 0;
136 #define GUS_DEV_WAVE 1 /* Wave table synth */
137 #define GUS_DEV_PCM_DONE 2 /* PCM device, transfer done */
138 #define GUS_DEV_PCM_CONTINUE 3 /* PCM device, transfer done ch. 1/2 */
140 static int gus_sampling_speed;
141 static int gus_sampling_channels;
142 static int gus_sampling_bits;
144 static int *dram_sleeper = NULL;
145 static volatile struct snd_wait dram_sleep_flag =
149 * Variables and buffers for PCM output
151 #define MAX_PCM_BUFFERS (32*MAX_REALTIME_FACTOR) /* Don't change */
153 static int pcm_bsize, pcm_nblk, pcm_banksize;
154 static int pcm_datasize[MAX_PCM_BUFFERS];
155 static volatile int pcm_head, pcm_tail, pcm_qlen;
156 static volatile int pcm_active;
157 static volatile int dma_active;
158 static int pcm_opened = 0;
159 static int pcm_current_dev;
160 static int pcm_current_block;
161 static u_long pcm_current_buf;
162 static int pcm_current_count;
163 static int pcm_current_intrflag;
165 extern sound_os_info *gus_osp;
167 static struct voice_info voices[32];
169 static int freq_div_table[] =
192 static struct patch_info *samples;
193 static struct patch_info *dbg_samples;
194 static int dbg_samplep;
196 static long sample_ptrs[MAX_SAMPLE + 1];
197 static int sample_map[32];
198 static int free_sample;
199 static int mixer_type = 0;
202 static int patch_table[MAX_PATCH];
203 static int patch_map[32];
205 static struct synth_info gus_info =
206 {"Gravis UltraSound", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS, 0, 16, 0, MAX_PATCH};
208 static void gus_default_mixer_init(void);
210 static int guswave_start_note2(int dev, int voice, int note_num, int volume);
211 static void gus_poke(long addr, u_char data);
212 static void compute_and_set_volume(int voice, int volume, int ramp_time);
213 extern u_short gus_adagio_vol(int vel, int mainv, int xpn, int voicev);
214 extern u_short gus_linear_vol(int vol, int mainvol);
215 static void compute_volume(int voice, int volume);
216 static void do_volume_irq(int voice);
217 static void set_input_volumes(void);
218 static void gus_tmr_install(int io_base);
220 static void SEND(int d, int r);
221 static int get_serial(int rd_port, u_char *data);
222 static void send_Initiation_LFSR(void);
223 static int isolation_protocol(int rd_port);
226 #define INSTANT_RAMP -1 /* Instant change. No ramping */
227 #define FAST_RAMP 0 /* Fastest possible ramp */
231 #define CODEC_XTAL2 0x01 /* 16.9344 crystal */
232 #define CODEC_XTAL1 0x00 /* 24.576 crystal */
233 /************************************************************************/
235 /************************************************************************/
236 /* Definitions for CONFIG_1 register */
237 #define CODEC_CFIG1I_DEFAULT 0x03 | 0x8
238 #define CODEC_CAPTURE_PIO 0x80 /* Capture PIO enable */
239 #define CODEC_PLAYBACK_PIO 0x40 /* Playback PIO enable */
240 #define CODEC_AUTOCALIB 0x08 /* auto calibrate */
241 #define CODEC_SINGLE_DMA 0x04 /* Use single DMA channel */
242 #define CODEC_RE 0x02 /* Capture enable */
243 #define CODEC_PE 0x01 /* playback enable */
244 /************************************************************************/
246 /************************************************************************/
247 /* Definitions for CONFIG_2 register */
248 #define CODEC_CFIG2I_DEFAULT 0x81
249 #define CODEC_OFVS 0x80 /* Output Full Scale Voltage */
250 #define CODEC_TE 0x40 /* Timer Enable */
251 #define CODEC_RSCD 0x20 /* Recors Sample Counter Disable */
252 #define CODEC_PSCD 0x10 /* Playback Sample Counter Disable */
253 #define CODEC_DAOF 0x01 /* D/A Ouput Force Enable */
254 /************************************************************************/
256 /************************************************************************/
257 /* Definitions for CONFIG_3 register */
258 /* #define CODEC_CFIG3I_DEFAULT 0xe0 0x02 when synth DACs are working */
260 #define CODEC_CFIG3I_DEFAULT 0xc0 /* 0x02 when synth DACs are working */
261 #define CODEC_RPIE 0x80 /* Record FIFO IRQ Enable */
262 #define CODEC_PPIE 0x40 /* Playback FIFO IRQ Enable */
263 #define CODEC_FT_MASK 0x30 /* FIFO Threshold Select */
264 #define CODEC_PVFM 0x04 /* Playback Variable Frequency Mode */
265 #define CODEC_SYNA 0x02 /* AUX1/Synth Signal Select */
266 /************************************************************************/
268 /************************************************************************/
269 /* Definitions for EXTERNAL_CONTROL register */
270 #define CODEC_CEXTI_DEFAULT 0x00
271 #define CODEC_IRQ_ENABLE 0x02 /* interrupt enable */
272 #define CODEC_GPOUT1 0x80 /* external control #1 */
273 #define CODEC_GPOUT0 0x40 /* external control #0 */
274 /************************************************************************/
276 /************************************************************************/
277 /* Definitions for MODE_SELECT_ID register */
278 #define CODEC_MODE_DEFAULT 0x40
279 #define CODEC_MODE_MASK 0x60
280 #define CODEC_ID_BIT4 0x80
281 #define CODEC_ID_BIT3_0 0x0F
282 /************************************************************************/
283 #define CONFIG_1 0x09
284 #define EXTERNAL_CONTROL 0x0a/* Pin control */
285 #define STATUS_2 0x0b/* Test and initialization */
286 #define MODE_SELECT_ID 0x0c/* Miscellaneaous information */
287 #define LOOPBACK 0x0d/* Digital Mix */
288 #define UPPER_PLAY_COUNT 0x0e/* Playback Upper Base Count */
289 #define LOWER_PLAY_COUNT 0x0f/* Playback Lower Base Count */
290 #define CONFIG_2 0x10
291 #define CONFIG_3 0x11
294 #define IWL_CODEC_OUT(reg, val) \
295 { outb(iwl_codec_base, reg); outb(iwl_codec_data, val); }
297 #define IWL_CODEC_IN(reg, val) \
298 { outb(iwl_codec_base, reg); val = inb(iwl_codec_data); }
301 static u_char gus_look8(int reg);
303 static void gus_write16(int reg, u_int data);
305 static u_short gus_read16(int reg);
307 static void gus_write_addr(int reg, u_long address, int is16bit);
308 static void IwaveLineLevel(char level, char index);
309 static void IwaveInputSource(BYTE index, BYTE source);
310 static void IwavePnpGetCfg(void);
311 static void IwavePnpDevice(BYTE dev);
312 static void IwavePnpSetCfg(void);
313 static void IwavePnpKey(void);
314 static BYTE IwavePnpIsol(PORT * pnpread);
315 static void IwavePnpPeek(PORT pnprdp, WORD bytes, BYTE * data);
316 static void IwavePnpActivate(BYTE dev, BYTE bool);
317 static void IwavePnpWake(BYTE csn);
318 static BYTE IwavePnpPing(DWORD VendorID);
319 static WORD IwaveMemSize(void);
320 static BYTE IwaveMemPeek(ADDRESS addr);
321 static void IwaveMemPoke(ADDRESS addr, BYTE datum);
322 static void IwaveMemCfg(DWORD * lpbanks);
323 static void IwaveCodecIrq(BYTE mode);
324 static WORD IwaveRegPeek(DWORD reg_mnem);
326 static void IwaveRegPoke(DWORD reg_mnem, WORD datum);
327 static void IwaveCodecMode(char mode);
328 static void IwaveLineMute(BYTE mute, BYTE inx);
329 static void Iwaveinitcodec(void);
330 int IwaveOpen(char voices, char mode, struct address_info * hw);
334 reset_sample_memory(void)
338 for (i = 0; i <= MAX_SAMPLE; i++)
340 for (i = 0; i < 32; i++)
342 for (i = 0; i < 32; i++)
345 gus_poke(0, 0); /* Put a silent sample to the beginning */
351 for (i = 0; i < MAX_PATCH; i++)
360 for (i = 0; i < 7; i++)
365 gus_poke(long addr, u_char data)
366 { /* Writes a byte to the DRAM */
370 outb(u_Command, 0x43);
371 outb(u_DataLo, addr & 0xff);
372 outb(u_DataHi, (addr >> 8) & 0xff);
374 outb(u_Command, 0x44);
375 outb(u_DataHi, (addr >> 16) & 0xff);
376 outb(u_DRAMIO, data);
382 { /* Reads a byte from the DRAM */
387 outb(u_Command, 0x43);
388 outb(u_DataLo, addr & 0xff);
389 outb(u_DataHi, (addr >> 8) & 0xff);
391 outb(u_Command, 0x44);
392 outb(u_DataHi, (addr >> 16) & 0xff);
400 gus_write8(int reg, u_int data)
401 { /* Writes to an indirect register (8 bit) */
405 outb(u_Command, reg);
406 outb(u_DataHi, (u_char) (data & 0xff));
412 { /* Reads from an indirect register (8 bit). Offset 0x80. */
417 outb(u_Command, reg | 0x80);
426 { /* Reads from an indirect register (8 bit). No additional offset. */
431 outb(u_Command, reg);
439 gus_write16(int reg, u_int data)
440 { /* Writes to an indirect register (16 bit) */
445 outb(u_Command, reg);
447 outb(u_DataLo, (u_char) (data & 0xff));
448 outb(u_DataHi, (u_char) ((data >> 8) & 0xff));
455 { /* Reads from an indirect register (16 bit). Offset 0x80. */
461 outb(u_Command, reg | 0x80);
468 return ((hi << 8) & 0xff00) | lo;
472 gus_write_addr(int reg, u_long address, int is16bit)
473 { /* Writes an 24 bit memory address */
480 * Special processing required for 16 bit patches
483 hold_address = address;
484 address = address >> 1;
485 address &= 0x0001ffffL;
486 address |= (hold_address & 0x000c0000L);
488 gus_write16(reg, (u_short) ((address >> 7) & 0xffff));
489 gus_write16(reg + 1, (u_short) ((address << 9) & 0xffff));
491 * Could writing twice fix problems with GUS_VOICE_POS() ? Lets try...
494 gus_write16(reg, (u_short) ((address >> 7) & 0xffff));
495 gus_write16(reg + 1, (u_short) ((address << 9) & 0xffff));
500 gus_select_voice(int voice)
502 if (voice < 0 || voice > 31)
505 outb(u_Voice, voice);
509 gus_select_max_voices(int nvoices)
516 voice_alloc->max_voice = nr_voices = nvoices;
518 gus_write8(0x0e, (nvoices - 1) | 0xc0);
522 gus_voice_on(u_int mode)
524 gus_write8(0x00, (u_char) (mode & 0xfc));
526 gus_write8(0x00, (u_char) (mode & 0xfc));
532 gus_write8(0x00, gus_read8(0x00) | 0x03);
536 gus_voice_mode(u_int m)
538 u_char mode = (u_char) (m & 0xff);
540 gus_write8(0x00, (gus_read8(0x00) & 0x03) |
541 (mode & 0xfc)); /* Don't touch last two bits */
543 gus_write8(0x00, (gus_read8(0x00) & 0x03) | (mode & 0xfc));
547 gus_voice_freq(u_long freq)
549 u_long divisor = freq_div_table[nr_voices - 14];
552 fc = (u_short) (((freq << 9) + (divisor >> 1)) / divisor);
555 gus_write16(0x01, fc);
559 gus_voice_volume(u_int vol)
561 gus_write8(0x0d, 0x03); /* Stop ramp before setting volume */
562 gus_write16(0x09, (u_short) (vol << 4));
566 gus_voice_balance(u_int balance)
568 gus_write8(0x0c, (u_char) (balance & 0xff));
572 gus_ramp_range(u_int low, u_int high)
574 gus_write8(0x07, (u_char) ((low >> 4) & 0xff));
575 gus_write8(0x08, (u_char) ((high >> 4) & 0xff));
579 gus_ramp_rate(u_int scale, u_int rate)
581 gus_write8(0x06, (u_char) (((scale & 0x03) << 6) | (rate & 0x3f)));
587 u_char mode = (u_char) (m & 0xff);
589 gus_write8(0x0d, mode & 0xfc);
591 gus_write8(0x0d, mode & 0xfc);
595 gus_ramp_mode(u_int m)
597 u_char mode = (u_char) (m & 0xff);
599 gus_write8(0x0d, (gus_read8(0x0d) & 0x03) |
600 (mode & 0xfc)); /* Leave the last 2 bits alone */
602 gus_write8(0x0d, (gus_read8(0x0d) & 0x03) | (mode & 0xfc));
608 gus_write8(0x0d, 0x03);
612 gus_set_voice_pos(int voice, long position)
616 if ((sample_no = sample_map[voice]) != -1) {
617 if (position < samples[sample_no].len) {
618 if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
619 voices[voice].offset_pending = position;
621 gus_write_addr(0x0a, sample_ptrs[sample_no] + position,
622 samples[sample_no].mode & WAVE_16_BITS);
628 gus_voice_init(int voice)
633 gus_select_voice(voice);
636 gus_write_addr(0x0a, 0, 0); /* Set current position to 0 */
637 gus_write8(0x00, 0x03); /* Voice off */
638 gus_write8(0x0d, 0x03); /* Ramping off */
639 voice_alloc->map[voice] = 0;
640 voice_alloc->alloc_times[voice] = 0;
646 gus_voice_init2(int voice)
648 voices[voice].panning = 0;
649 voices[voice].mode = 0;
650 voices[voice].orig_freq = 20000;
651 voices[voice].current_freq = 20000;
652 voices[voice].bender = 0;
653 voices[voice].bender_range = 200;
654 voices[voice].initial_volume = 0;
655 voices[voice].current_volume = 0;
656 voices[voice].loop_irq_mode = 0;
657 voices[voice].loop_irq_parm = 0;
658 voices[voice].volume_irq_mode = 0;
659 voices[voice].volume_irq_parm = 0;
660 voices[voice].env_phase = 0;
661 voices[voice].main_vol = 127;
662 voices[voice].patch_vol = 127;
663 voices[voice].expression_vol = 127;
664 voices[voice].sample_pending = -1;
668 step_envelope(int voice)
670 u_int vol, prev_vol, phase;
674 if (voices[voice].mode & WAVE_SUSTAIN_ON && voices[voice].env_phase == 2) {
676 gus_select_voice(voice);
681 * Sustain phase begins. Continue envelope after receiving
685 if (voices[voice].env_phase >= 5) { /* Envelope finished. Shoot
687 gus_voice_init(voice);
690 prev_vol = voices[voice].current_volume;
691 phase = ++voices[voice].env_phase;
692 compute_volume(voice, voices[voice].midi_volume);
693 vol = voices[voice].initial_volume * voices[voice].env_offset[phase] / 255;
694 rate = voices[voice].env_rate[phase];
697 gus_select_voice(voice);
698 gus_voice_volume(prev_vol);
699 gus_write8(0x06, rate); /* Ramping rate */
701 voices[voice].volume_irq_mode = VMODE_ENVELOPE;
703 if (((vol - prev_vol) / 64) == 0) { /* No significant volume
706 step_envelope(voice); /* Continue the envelope on the next
710 if (vol > prev_vol) {
711 if (vol >= (4096 - 64))
713 gus_ramp_range(0, vol);
714 gus_rampon(0x20); /* Increasing volume, with IRQ */
718 gus_ramp_range(vol, 4030);
719 gus_rampon(0x60); /* Decreasing volume, with IRQ */
721 voices[voice].current_volume = vol;
726 init_envelope(int voice)
728 voices[voice].env_phase = -1;
729 voices[voice].current_volume = 64;
731 step_envelope(voice);
735 start_release(int voice, long int flags)
737 if (gus_read8(0x00) & 0x03)
738 return; /* Voice already stopped */
740 voices[voice].env_phase = 2; /* Will be incremented by
743 voices[voice].current_volume =
744 voices[voice].initial_volume =
745 gus_read16(0x09) >> 4; /* Get current volume */
747 voices[voice].mode &= ~WAVE_SUSTAIN_ON;
750 step_envelope(voice);
754 gus_voice_fade(int voice)
756 int instr_no = sample_map[voice], is16bits;
760 gus_select_voice(voice);
762 if (instr_no < 0 || instr_no > MAX_SAMPLE) {
763 gus_write8(0x00, 0x03); /* Hard stop */
764 voice_alloc->map[voice] = 0;
768 is16bits = (samples[instr_no].mode & WAVE_16_BITS) ? 1 : 0; /* 8 or 16 bits */
770 if (voices[voice].mode & WAVE_ENVELOPES) {
771 start_release(voice, flags);
775 * Ramp the volume down but not too quickly.
777 if ((int) (gus_read16(0x09) >> 4) < 100) { /* Get current volume */
780 gus_voice_init(voice);
783 gus_ramp_range(65, 4030);
785 gus_rampon(0x40 | 0x20);/* Down, once, with IRQ */
786 voices[voice].volume_irq_mode = VMODE_HALT;
795 gus_select_max_voices(24);
798 volume_method = VOL_METHOD_ADAGIO;
800 for (i = 0; i < 32; i++) {
801 gus_voice_init(i); /* Turn voice off */
805 inb(u_Status); /* Touch the status register */
807 gus_look8(0x41); /* Clear any pending DMA IRQs */
808 gus_look8(0x49); /* Clear any pending sample IRQs */
810 gus_read8(0x0f); /* Clear pending IRQs */
818 u_char dma_image, irq_image, tmp;
820 static u_char gus_irq_map[16] =
821 {0, 0, 0, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7};
823 static u_char gus_dma_map[8] =
824 {0, 1, 0, 2, 0, 3, 4, 5};
827 gus_write8(0x4c, 0); /* Reset GF1 */
831 gus_write8(0x4c, 1); /* Release Reset */
836 * Clear all interrupts
839 gus_write8(0x41, 0); /* DMA control */
840 gus_write8(0x45, 0); /* Timer control */
841 gus_write8(0x49, 0); /* Sample control */
843 gus_select_max_voices(24);
845 inb(u_Status); /* Touch the status register */
847 gus_look8(0x41); /* Clear any pending DMA IRQs */
848 gus_look8(0x49); /* Clear any pending sample IRQs */
849 gus_read8(0x0f); /* Clear pending IRQs */
851 gus_reset(); /* Resets all voices */
853 gus_look8(0x41); /* Clear any pending DMA IRQs */
854 gus_look8(0x49); /* Clear any pending sample IRQs */
855 gus_read8(0x0f); /* Clear pending IRQs */
857 gus_write8(0x4c, 7); /* Master reset | DAC enable | IRQ enable */
860 * Set up for Digital ASIC
863 outb(gus_base + 0x0f, 0x05);
865 mix_image |= 0x02; /* Disable line out (for a moment) */
866 outb(u_Mixer, mix_image);
868 outb(u_IRQDMAControl, 0x00);
870 outb(gus_base + 0x0f, 0x00);
873 * Now set up the DMA and IRQ interface
875 * The GUS supports two IRQs and two DMAs.
877 * Just one DMA channel is used. This prevents simultaneous ADC and DAC.
878 * Adding this support requires significant changes to the dmabuf.c,
879 * dsp.c and audio.c also.
883 tmp = gus_irq_map[gus_irq];
885 printf("Warning! GUS IRQ not selected\n");
887 irq_image |= 0x40; /* Combine IRQ1 (GF1) and IRQ2 (Midi) */
890 if (gus_dma2 == gus_dma || gus_dma2 == -1) {
892 dma_image = 0x40; /* Combine DMA1 (DRAM) and IRQ2 (ADC) */
894 tmp = gus_dma_map[gus_dma];
896 printf("Warning! GUS DMA not selected\n");
900 /* Setup dual DMA channel mode for GUS MAX */
902 dma_image = gus_dma_map[gus_dma];
904 printf("Warning! GUS DMA not selected\n");
906 tmp = gus_dma_map[gus_dma2] << 3;
908 printf("Warning! Invalid GUS MAX DMA\n");
909 tmp = 0x40; /* Combine DMA channels */
916 * For some reason the IRQ and DMA addresses must be written twice
920 * Doing it first time
923 outb(u_Mixer, mix_image); /* Select DMA control */
924 outb(u_IRQDMAControl, dma_image | 0x80); /* Set DMA address */
926 outb(u_Mixer, mix_image | 0x40); /* Select IRQ control */
927 outb(u_IRQDMAControl, irq_image); /* Set IRQ address */
930 * Doing it second time
933 outb(u_Mixer, mix_image); /* Select DMA control */
934 outb(u_IRQDMAControl, dma_image); /* Set DMA address */
936 outb(u_Mixer, mix_image | 0x40); /* Select IRQ control */
937 outb(u_IRQDMAControl, irq_image); /* Set IRQ address */
939 gus_select_voice(0); /* This disables writes to IRQ/DMA reg */
941 mix_image &= ~0x02; /* Enable line out */
942 mix_image |= 0x08; /* Enable IRQ */
943 outb(u_Mixer, mix_image); /* Turn mixer channels on Note! Mic
946 gus_select_voice(0); /* This disables writes to IRQ/DMA reg */
948 gusintr(0); /* Serve pending interrupts */
953 gus_wave_detect(int baseaddr)
959 gus_write8(0x4c, 0); /* Reset GF1 */
963 gus_write8(0x4c, 1); /* Release Reset */
967 /* See if there is first block there.... */
969 if (gus_peek(0L) != 0xaa)
972 /* Now zero it out so that I can check for mirroring .. */
974 for (i = 1L; i < 1024L; i++) {
977 /* check for mirroring ... */
978 if (gus_peek(0L) != 0)
982 for (n = loc - 1, failed = 0; n <= loc; n++) {
984 if (gus_peek(loc) != 0xaa)
988 if (gus_peek(loc) != 0x55)
995 gus_mem_size = i << 10;
1000 guswave_ioctl(int dev,
1001 u_int cmd, ioctl_arg arg)
1005 case SNDCTL_SYNTH_INFO:
1006 gus_info.nr_voices = nr_voices;
1007 bcopy(&gus_info, &(((char *) arg)[0]), sizeof(gus_info));
1011 case SNDCTL_SEQ_RESETSAMPLES:
1012 reset_sample_memory();
1016 case SNDCTL_SEQ_PERCMODE:
1020 case SNDCTL_SYNTH_MEMAVL:
1021 return gus_mem_size - free_mem_ptr - 32;
1029 guswave_set_instr(int dev, int voice, int instr_no)
1033 if (instr_no < 0 || instr_no > MAX_PATCH)
1036 if (voice < 0 || voice > 31)
1039 if (voices[voice].volume_irq_mode == VMODE_START_NOTE) {
1040 voices[voice].sample_pending = instr_no;
1043 sample_no = patch_table[instr_no];
1044 patch_map[voice] = -1;
1046 if (sample_no < 0) {
1047 printf("GUS: Undefined patch %d for voice %d\n", instr_no, voice);
1048 return -(EINVAL); /* Patch not defined */
1050 if (sample_ptrs[sample_no] == -1) { /* Sample not loaded */
1051 printf("GUS: Sample #%d not loaded for patch %d (voice %d)\n",
1052 sample_no, instr_no, voice);
1055 sample_map[voice] = sample_no;
1056 patch_map[voice] = instr_no;
1061 guswave_kill_note(int dev, int voice, int note, int velocity)
1066 /* voice_alloc->map[voice] = 0xffff; */
1067 if (voices[voice].volume_irq_mode == VMODE_START_NOTE) {
1068 voices[voice].kill_pending = 1;
1072 gus_voice_fade(voice);
1080 guswave_aftertouch(int dev, int voice, int pressure)
1085 guswave_panning(int dev, int voice, int value)
1087 if (voice >= 0 || voice < 32)
1088 voices[voice].panning = value;
1092 guswave_volume_method(int dev, int mode)
1094 if (mode == VOL_METHOD_LINEAR || mode == VOL_METHOD_ADAGIO)
1095 volume_method = mode;
1099 compute_volume(int voice, int volume)
1102 voices[voice].midi_volume = volume;
1104 switch (volume_method) {
1105 case VOL_METHOD_ADAGIO:
1106 voices[voice].initial_volume =
1107 gus_adagio_vol(voices[voice].midi_volume, voices[voice].main_vol,
1108 voices[voice].expression_vol, voices[voice].patch_vol);
1111 case VOL_METHOD_LINEAR:/* Totally ignores patch-volume and expression */
1112 voices[voice].initial_volume =
1113 gus_linear_vol(volume, voices[voice].main_vol);
1117 voices[voice].initial_volume = volume_base +
1118 (voices[voice].midi_volume * volume_scale);
1121 if (voices[voice].initial_volume > 4030)
1122 voices[voice].initial_volume = 4030;
1126 compute_and_set_volume(int voice, int volume, int ramp_time)
1128 int curr, target, rate;
1131 compute_volume(voice, volume);
1132 voices[voice].current_volume = voices[voice].initial_volume;
1136 * CAUTION! Interrupts disabled. Enable them before returning
1139 gus_select_voice(voice);
1141 curr = gus_read16(0x09) >> 4;
1142 target = voices[voice].initial_volume;
1144 if (ramp_time == INSTANT_RAMP) {
1146 gus_voice_volume(target);
1150 if (ramp_time == FAST_RAMP)
1154 gus_ramp_rate(0, rate);
1156 if ((target - curr) / 64 == 0) { /* Close enough to target. */
1158 gus_voice_volume(target);
1162 if (target > curr) {
1163 if (target > (4095 - 65))
1165 gus_ramp_range(curr, target);
1166 gus_rampon(0x00); /* Ramp up, once, no IRQ */
1171 gus_ramp_range(target, curr);
1172 gus_rampon(0x40); /* Ramp down, once, no irq */
1178 dynamic_volume_change(int voice)
1184 gus_select_voice(voice);
1185 status = gus_read8(0x00); /* Get voice status */
1189 return; /* Voice was not running */
1191 if (!(voices[voice].mode & WAVE_ENVELOPES)) {
1192 compute_and_set_volume(voice, voices[voice].midi_volume, 1);
1196 * Voice is running and has envelopes.
1200 gus_select_voice(voice);
1201 status = gus_read8(0x0d); /* Ramping status */
1204 if (status & 0x03) { /* Sustain phase? */
1205 compute_and_set_volume(voice, voices[voice].midi_volume, 1);
1208 if (voices[voice].env_phase < 0)
1211 compute_volume(voice, voices[voice].midi_volume);
1216 guswave_controller(int dev, int voice, int ctrl_num, int value)
1221 if (voice < 0 || voice > 31)
1225 case CTRL_PITCH_BENDER:
1226 voices[voice].bender = value;
1228 if (voices[voice].volume_irq_mode != VMODE_START_NOTE) {
1229 freq = compute_finetune(voices[voice].orig_freq, value,
1230 voices[voice].bender_range);
1231 voices[voice].current_freq = freq;
1234 gus_select_voice(voice);
1235 gus_voice_freq(freq);
1240 case CTRL_PITCH_BENDER_RANGE:
1241 voices[voice].bender_range = value;
1243 case CTL_EXPRESSION:
1245 case CTRL_EXPRESSION:
1246 if (volume_method == VOL_METHOD_ADAGIO) {
1247 voices[voice].expression_vol = value;
1248 if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
1249 dynamic_volume_change(voice);
1254 voices[voice].panning = (value * 2) - 128;
1257 case CTL_MAIN_VOLUME:
1258 value = (value * 100) / 16383;
1260 case CTRL_MAIN_VOLUME:
1261 voices[voice].main_vol = value;
1262 if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
1263 dynamic_volume_change(voice);
1272 guswave_start_note2(int dev, int voice, int note_num, int volume)
1274 int sample, best_sample, best_delta, delta_freq;
1275 int is16bits, samplep, patch, pan;
1276 u_long note_freq, base_note, freq, flags;
1279 if (voice < 0 || voice > 31) {
1280 printf("GUS: Invalid voice\n");
1283 if (note_num == 255) {
1284 if (voices[voice].mode & WAVE_ENVELOPES) {
1285 voices[voice].midi_volume = volume;
1286 dynamic_volume_change(voice);
1289 compute_and_set_volume(voice, volume, 1);
1292 if ((patch = patch_map[voice]) == -1)
1294 if ((samplep = patch_table[patch]) == -1)
1296 note_freq = note_to_freq(note_num);
1299 * Find a sample within a patch so that the note_freq is between
1300 * low_note and high_note.
1304 best_sample = samplep;
1305 best_delta = 1000000;
1306 while (samplep >= 0 && sample == -1) {
1307 dbg_samples = samples;
1308 dbg_samplep = samplep;
1310 delta_freq = note_freq - samples[samplep].base_note;
1312 delta_freq = -delta_freq;
1313 if (delta_freq < best_delta) {
1314 best_sample = samplep;
1315 best_delta = delta_freq;
1317 if (samples[samplep].low_note <= note_freq &&
1318 note_freq <= samples[samplep].high_note)
1321 samplep = samples[samplep].key; /* Follow link */
1324 sample = best_sample;
1327 printf("GUS: Patch %d not defined for note %d\n", patch, note_num);
1328 return 0; /* Should play default patch ??? */
1330 is16bits = (samples[sample].mode & WAVE_16_BITS) ? 1 : 0;
1331 voices[voice].mode = samples[sample].mode;
1332 voices[voice].patch_vol = samples[sample].volume;
1334 if (voices[voice].mode & WAVE_ENVELOPES) {
1337 for (i = 0; i < 6; i++) {
1338 voices[voice].env_rate[i] = samples[sample].env_rate[i];
1339 voices[voice].env_offset[i] = samples[sample].env_offset[i];
1342 sample_map[voice] = sample;
1344 base_note = samples[sample].base_note / 100; /* Try to avoid overflows */
1347 freq = samples[sample].base_freq * note_freq / base_note;
1349 voices[voice].orig_freq = freq;
1352 * Since the pitch bender may have been set before playing the note,
1353 * we have to calculate the bending now.
1356 freq = compute_finetune(voices[voice].orig_freq, voices[voice].bender,
1357 voices[voice].bender_range);
1358 voices[voice].current_freq = freq;
1360 pan = (samples[sample].panning + voices[voice].panning) / 32;
1367 if (samples[sample].mode & WAVE_16_BITS) {
1368 mode |= 0x04; /* 16 bits */
1369 if ((sample_ptrs[sample] >> 18) !=
1370 ((sample_ptrs[sample] + samples[sample].len) >> 18))
1371 printf("GUS: Sample address error\n");
1374 * CAUTION! Interrupts disabled. Don't return before enabling
1378 gus_select_voice(voice);
1384 if (voices[voice].mode & WAVE_ENVELOPES) {
1385 compute_volume(voice, volume);
1386 init_envelope(voice);
1388 compute_and_set_volume(voice, volume, 0);
1392 gus_select_voice(voice);
1394 if (samples[sample].mode & WAVE_LOOP_BACK)
1395 gus_write_addr(0x0a, sample_ptrs[sample] + samples[sample].len -
1396 voices[voice].offset_pending, is16bits); /* start=end */
1398 gus_write_addr(0x0a, sample_ptrs[sample] + voices[voice].offset_pending,
1399 is16bits); /* Sample start=begin */
1401 if (samples[sample].mode & WAVE_LOOPING) {
1404 if (samples[sample].mode & WAVE_BIDIR_LOOP)
1407 if (samples[sample].mode & WAVE_LOOP_BACK) {
1408 gus_write_addr(0x0a,
1409 sample_ptrs[sample] + samples[sample].loop_end -
1410 voices[voice].offset_pending, is16bits);
1413 gus_write_addr(0x02, sample_ptrs[sample] + samples[sample].loop_start,
1414 is16bits); /* Loop start location */
1415 gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].loop_end,
1416 is16bits); /* Loop end location */
1418 mode |= 0x20; /* Loop IRQ at the end */
1419 voices[voice].loop_irq_mode = LMODE_FINISH; /* Ramp down at the end */
1420 voices[voice].loop_irq_parm = 1;
1421 gus_write_addr(0x02, sample_ptrs[sample],
1422 is16bits); /* Loop start location */
1423 gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].len - 1,
1424 is16bits); /* Loop end location */
1426 gus_voice_freq(freq);
1427 gus_voice_balance(pan);
1435 * New guswave_start_note by Andrew J. Robinson attempts to minimize clicking
1436 * when the note playing on the voice is changed. It uses volume ramping.
1440 guswave_start_note(int dev, int voice, int note_num, int volume)
1447 if (note_num == 255) {
1448 if (voices[voice].volume_irq_mode == VMODE_START_NOTE) {
1449 voices[voice].volume_pending = volume;
1451 ret_val = guswave_start_note2(dev, voice, note_num, volume);
1454 gus_select_voice(voice);
1455 mode = gus_read8(0x00);
1457 gus_write8(0x00, mode & 0xdf); /* No interrupt! */
1459 voices[voice].offset_pending = 0;
1460 voices[voice].kill_pending = 0;
1461 voices[voice].volume_irq_mode = 0;
1462 voices[voice].loop_irq_mode = 0;
1464 if (voices[voice].sample_pending >= 0) {
1465 splx(flags); /* Run temporarily with interrupts
1467 guswave_set_instr(voices[voice].dev_pending, voice,
1468 voices[voice].sample_pending);
1469 voices[voice].sample_pending = -1;
1471 gus_select_voice(voice); /* Reselect the voice
1472 * (just to be sure) */
1474 if ((mode & 0x01) || (int) ((gus_read16(0x09) >> 4) < 2065)) {
1475 ret_val = guswave_start_note2(dev, voice, note_num, volume);
1477 voices[voice].dev_pending = dev;
1478 voices[voice].note_pending = note_num;
1479 voices[voice].volume_pending = volume;
1480 voices[voice].volume_irq_mode = VMODE_START_NOTE;
1483 gus_ramp_range(2000, 4065);
1484 gus_ramp_rate(0, 63); /* Fastest possible rate */
1485 gus_rampon(0x20 | 0x40); /* Ramp down, once, irq */
1493 guswave_reset(int dev)
1497 for (i = 0; i < 32; i++) {
1504 guswave_open(int dev, int mode)
1507 int otherside = audio_devs[dev]->otherside;
1509 if (otherside != -1) {
1510 if (audio_devs[otherside]->busy)
1513 if (audio_devs[dev]->busy)
1517 voice_alloc->timestamp = 0;
1519 if ((err = DMAbuf_open_dma(gus_devnum)) < 0) {
1520 printf("GUS: Loading saples without DMA\n");
1521 gus_no_dma = 1; /* Upload samples using PIO */
1525 dram_sleep_flag.aborting = 0;
1526 dram_sleep_flag.mode = WK_NONE;
1527 active_device = GUS_DEV_WAVE;
1529 audio_devs[dev]->busy = 1;
1536 guswave_close(int dev)
1538 int otherside = audio_devs[dev]->otherside;
1540 if (otherside != -1) {
1541 if (audio_devs[otherside]->busy)
1544 audio_devs[dev]->busy = 0;
1550 DMAbuf_close_dma(gus_devnum);
1554 guswave_load_patch(int dev, int format, snd_rw_buf * addr,
1555 int offs, int count, int pmgr_flag)
1557 struct patch_info patch;
1561 u_long blk_size, blk_end, left, src_offs, target;
1563 sizeof_patch = offsetof(struct patch_info, data); /* Header size */
1565 if (format != GUS_PATCH) {
1566 printf("GUS Error: Invalid patch format (key) 0x%x\n", format);
1569 if (count < sizeof_patch) {
1570 printf("GUS Error: Patch header too short\n");
1573 count -= sizeof_patch;
1575 if (free_sample >= MAX_SAMPLE) {
1576 printf("GUS: Sample table full\n");
1580 * Copy the header from user space but ignore the first bytes which
1581 * have been transferred already.
1584 if (uiomove(&((char *) &patch)[offs], sizeof_patch - offs, addr)) {
1585 printf("audio: Bad copyin()!\n");
1588 instr = patch.instr_no;
1590 if (instr < 0 || instr > MAX_PATCH) {
1591 printf("GUS: Invalid patch number %d\n", instr);
1594 if (count < patch.len) {
1595 printf("GUS Warning: Patch record too short (%d<%d)\n",
1596 count, (int) patch.len);
1599 if (patch.len <= 0 || patch.len > gus_mem_size) {
1600 printf("GUS: Invalid sample length %d\n", (int) patch.len);
1603 if (patch.mode & WAVE_LOOPING) {
1604 if (patch.loop_start < 0 || patch.loop_start >= patch.len) {
1605 printf("GUS: Invalid loop start\n");
1608 if (patch.loop_end < patch.loop_start || patch.loop_end > patch.len) {
1609 printf("GUS: Invalid loop end\n");
1613 free_mem_ptr = (free_mem_ptr + 31) & ~31; /* 32 byte alignment */
1615 #define GUS_BANK_SIZE (256*1024)
1617 if (patch.mode & WAVE_16_BITS) {
1619 * 16 bit samples must fit one 256k bank.
1621 if (patch.len >= GUS_BANK_SIZE) {
1622 printf("GUS: Sample (16 bit) too long %d\n", (int) patch.len);
1625 if ((free_mem_ptr / GUS_BANK_SIZE) !=
1626 ((free_mem_ptr + patch.len) / GUS_BANK_SIZE)) {
1627 u_long tmp_mem = /* Aligning to 256K */
1628 ((free_mem_ptr / GUS_BANK_SIZE) + 1) * GUS_BANK_SIZE;
1630 if ((tmp_mem + patch.len) > gus_mem_size)
1633 free_mem_ptr = tmp_mem; /* This leaves unusable memory */
1636 if ((free_mem_ptr + patch.len) > gus_mem_size)
1639 sample_ptrs[free_sample] = free_mem_ptr;
1642 * Tremolo is not possible with envelopes
1645 if (patch.mode & WAVE_ENVELOPES)
1646 patch.mode &= ~WAVE_TREMOLO;
1648 bcopy(&patch, (char *) &samples[free_sample], sizeof_patch);
1651 * Link this_one sample to the list of samples for patch 'instr'.
1654 samples[free_sample].key = patch_table[instr];
1655 patch_table[instr] = free_sample;
1658 * Use DMA to transfer the wave data to the DRAM
1663 target = free_mem_ptr;
1665 while (left) { /* Not completely transferred yet */
1666 /* blk_size = audio_devs[gus_devnum]->buffsize; */
1667 blk_size = audio_devs[gus_devnum]->dmap_out->bytes_in_use;
1668 if (blk_size > left)
1672 * DMA cannot cross 256k bank boundaries. Check for that.
1674 blk_end = target + blk_size;
1676 if ((target >> 18) != (blk_end >> 18)) { /* Split the block */
1677 blk_end &= ~(256 * 1024 - 1);
1678 blk_size = blk_end - target;
1682 * For some reason the DMA is not possible. We have
1688 for (i = 0; i < blk_size; i++) {
1689 uiomove((char *) &(data), 1, addr);
1690 if (patch.mode & WAVE_UNSIGNED)
1691 if (!(patch.mode & WAVE_16_BITS) || (i & 0x01))
1692 data ^= 0x80; /* Convert to signed */
1693 gus_poke(target + i, data);
1696 u_long address, hold_address;
1701 * OK, move now. First in and then out.
1704 if (uiomove(audio_devs[gus_devnum]->dmap_out->raw_buf, blk_size, addr)) {
1705 printf("audio: Bad copyin()!\n");
1709 /******** INTERRUPTS DISABLED NOW ********/
1710 gus_write8(0x41, 0); /* Disable GF1 DMA */
1711 DMAbuf_start_dma(gus_devnum,
1712 audio_devs[gus_devnum]->dmap_out->raw_buf_phys,
1716 * Set the DRAM address for the wave data
1721 if (audio_devs[gus_devnum]->dmachan1 > 3) {
1722 hold_address = address;
1723 address = address >> 1;
1724 address &= 0x0001ffffL;
1725 address |= (hold_address & 0x000c0000L);
1727 gus_write16(0x42, (address >> 4) & 0xffff); /* DRAM DMA address */
1730 * Start the DMA transfer
1733 dma_command = 0x21; /* IRQ enable, DMA start */
1734 if (patch.mode & WAVE_UNSIGNED)
1735 dma_command |= 0x80; /* Invert MSB */
1736 if (patch.mode & WAVE_16_BITS)
1737 dma_command |= 0x40; /* 16 bit _DATA_ */
1738 if (audio_devs[gus_devnum]->dmachan1 > 3)
1739 dma_command |= 0x04; /* 16 bit DMA _channel_ */
1741 gus_write8(0x41, dma_command); /* Lets bo luteet (=bugs) */
1744 * Sleep here until the DRAM DMA done interrupt is
1747 active_device = GUS_DEV_WAVE;
1753 dram_sleep_flag.mode = WK_SLEEP;
1754 dram_sleeper = &chn;
1755 DO_SLEEP(chn, dram_sleep_flag, hz);
1758 if ((dram_sleep_flag.mode & WK_TIMEOUT))
1759 printf("GUS: DMA Transfer timed out\n");
1768 src_offs += blk_size;
1771 gus_write8(0x41, 0); /* Stop DMA */
1774 free_mem_ptr += patch.len;
1777 pmgr_inform(dev, PM_E_PATCH_LOADED, instr, free_sample, 0, 0);
1783 guswave_hw_control(int dev, u_char *event)
1787 u_long plong, flags;
1791 p1 = *(u_short *) &event[4];
1792 p2 = *(u_short *) &event[6];
1793 plong = *(u_long *) &event[4];
1795 if ((voices[voice].volume_irq_mode == VMODE_START_NOTE) &&
1796 (cmd != _GUS_VOICESAMPLE) && (cmd != _GUS_VOICE_POS))
1797 do_volume_irq(voice);
1801 case _GUS_NUMVOICES:
1803 gus_select_voice(voice);
1804 gus_select_max_voices(p1);
1808 case _GUS_VOICESAMPLE:
1809 guswave_set_instr(dev, voice, p1);
1814 gus_select_voice(voice);
1815 p1 &= ~0x20; /* Don't allow interrupts */
1822 gus_select_voice(voice);
1827 case _GUS_VOICEFADE:
1828 gus_voice_fade(voice);
1831 case _GUS_VOICEMODE:
1833 gus_select_voice(voice);
1834 p1 &= ~0x20; /* Don't allow interrupts */
1839 case _GUS_VOICEBALA:
1841 gus_select_voice(voice);
1842 gus_voice_balance(p1);
1846 case _GUS_VOICEFREQ:
1848 gus_select_voice(voice);
1849 gus_voice_freq(plong);
1855 gus_select_voice(voice);
1856 gus_voice_volume(p1);
1860 case _GUS_VOICEVOL2: /* Just update the software voice level */
1861 voices[voice].initial_volume =
1862 voices[voice].current_volume = p1;
1865 case _GUS_RAMPRANGE:
1866 if (voices[voice].mode & WAVE_ENVELOPES)
1869 gus_select_voice(voice);
1870 gus_ramp_range(p1, p2);
1875 if (voices[voice].mode & WAVE_ENVELOPES)
1876 break; /* NJET-NJET */
1878 gus_select_voice(voice);
1879 gus_ramp_rate(p1, p2);
1884 if (voices[voice].mode & WAVE_ENVELOPES)
1887 gus_select_voice(voice);
1888 p1 &= ~0x20; /* Don't allow interrupts */
1894 if (voices[voice].mode & WAVE_ENVELOPES)
1897 gus_select_voice(voice);
1898 p1 &= ~0x20; /* Don't allow interrupts */
1904 if (voices[voice].mode & WAVE_ENVELOPES)
1905 break; /* NEJ-NEJ */
1907 gus_select_voice(voice);
1912 case _GUS_VOLUME_SCALE:
1917 case _GUS_VOICE_POS:
1919 gus_select_voice(voice);
1920 gus_set_voice_pos(voice, plong);
1929 gus_sampling_set_speed(int speed)
1933 speed = gus_sampling_speed;
1935 RANGE(speed, 4000, 44100);
1936 gus_sampling_speed = speed;
1938 if (only_read_access) {
1939 /* Compute nearest valid recording speed and return it */
1941 speed = (9878400 / (gus_sampling_speed + 2)) / 16;
1942 speed = (9878400 / (speed * 16)) - 2;
1948 gus_sampling_set_channels(int channels)
1951 return gus_sampling_channels;
1952 RANGE(channels, 1, 2);
1953 gus_sampling_channels = channels;
1958 gus_sampling_set_bits(int bits)
1961 return gus_sampling_bits;
1963 if (bits != 8 && bits != 16)
1969 gus_sampling_bits = bits;
1974 gus_sampling_ioctl(int dev, u_int cmd, ioctl_arg arg, int local)
1977 case SOUND_PCM_WRITE_RATE:
1979 return gus_sampling_set_speed((int) arg);
1980 return *(int *) arg = gus_sampling_set_speed((*(int *) arg));
1983 case SOUND_PCM_READ_RATE:
1985 return gus_sampling_speed;
1986 return *(int *) arg = gus_sampling_speed;
1989 case SNDCTL_DSP_STEREO:
1991 return gus_sampling_set_channels((int) arg + 1) - 1;
1992 return *(int *) arg = gus_sampling_set_channels((*(int *) arg) + 1) - 1;
1995 case SOUND_PCM_WRITE_CHANNELS:
1997 return gus_sampling_set_channels((int) arg);
1998 return *(int *) arg = gus_sampling_set_channels((*(int *) arg));
2001 case SOUND_PCM_READ_CHANNELS:
2003 return gus_sampling_channels;
2004 return *(int *) arg = gus_sampling_channels;
2007 case SNDCTL_DSP_SETFMT:
2009 return gus_sampling_set_bits((int) arg);
2010 return *(int *) arg = gus_sampling_set_bits((*(int *) arg));
2013 case SOUND_PCM_READ_BITS:
2015 return gus_sampling_bits;
2016 return *(int *) arg = gus_sampling_bits;
2018 case SOUND_PCM_WRITE_FILTER: /* NOT POSSIBLE */
2019 return *(int *) arg = -(EINVAL);
2022 case SOUND_PCM_READ_FILTER:
2023 return *(int *) arg = -(EINVAL);
2031 gus_sampling_reset(int dev)
2033 if (recording_active) {
2034 gus_write8(0x49, 0x00); /* Halt recording */
2035 set_input_volumes();
2040 gus_sampling_open(int dev, int mode)
2043 int otherside = audio_devs[dev]->otherside;
2044 if (otherside != -1) {
2045 if (audio_devs[otherside]->busy)
2048 if (audio_devs[dev]->busy)
2057 reset_sample_memory();
2058 gus_select_max_voices(14);
2063 audio_devs[dev]->busy = 1;
2065 if (mode & OPEN_READ) {
2066 recording_active = 1;
2067 set_input_volumes();
2069 only_read_access = !(mode & OPEN_WRITE);
2070 only_8_bits = mode & OPEN_READ;
2072 audio_devs[dev]->format_mask = AFMT_U8;
2074 audio_devs[dev]->format_mask = AFMT_U8 | AFMT_S16_LE;
2080 gus_sampling_close(int dev)
2082 int otherside = audio_devs[dev]->otherside;
2083 audio_devs[dev]->busy = 0;
2085 if (otherside != -1) {
2086 if (audio_devs[otherside]->busy)
2094 if (recording_active) {
2095 gus_write8(0x49, 0x00); /* Halt recording */
2096 set_input_volumes();
2098 recording_active = 0;
2102 gus_sampling_update_volume(void)
2107 if (pcm_active && pcm_opened)
2108 for (voice = 0; voice < gus_sampling_channels; voice++) {
2110 gus_select_voice(voice);
2112 gus_voice_volume(1530 + (25 * gus_pcm_volume));
2113 gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
2119 play_next_pcm_block(void)
2122 int speed = gus_sampling_speed;
2123 int this_one, is16bits, chn;
2125 u_char mode[2], ramp_mode[2];
2130 this_one = pcm_head;
2132 for (chn = 0; chn < gus_sampling_channels; chn++) {
2134 ramp_mode[chn] = 0x03; /* Ramping and rollover off */
2137 mode[chn] |= 0x20; /* Loop IRQ */
2138 voices[chn].loop_irq_mode = LMODE_PCM;
2140 if (gus_sampling_bits != 8) {
2142 mode[chn] |= 0x04; /* 16 bit data */
2146 dram_loc = this_one * pcm_bsize;
2147 dram_loc += chn * pcm_banksize;
2149 if (this_one == (pcm_nblk - 1)) { /* Last fragment of the
2151 mode[chn] |= 0x08; /* Enable loop */
2152 ramp_mode[chn] = 0x03; /* Disable rollover bit */
2155 ramp_mode[chn] = 0x04; /* Enable rollover bit */
2159 gus_select_voice(chn);
2160 gus_voice_freq(speed);
2162 if (gus_sampling_channels == 1)
2163 gus_voice_balance(7); /* mono */
2165 gus_voice_balance(0); /* left */
2167 gus_voice_balance(15); /* right */
2169 if (!pcm_active) { /* Playback not already active */
2171 * The playback was not started yet (or there has
2172 * been a pause). Start the voice (again) and ask for
2173 * a rollover irq at the end of this_one block. If
2174 * this_one one is last of the buffers, use just the
2175 * normal loop with irq.
2180 gus_voice_volume(1530 + (25 * gus_pcm_volume));
2181 gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
2183 gus_write_addr(0x0a, dram_loc, is16bits); /* Starting position */
2184 gus_write_addr(0x02, chn * pcm_banksize, is16bits); /* Loop start */
2187 gus_write_addr(0x04, pcm_banksize + (pcm_bsize * pcm_nblk) - 1,
2188 is16bits); /* Loop end location */
2191 gus_write_addr(0x04, dram_loc + pcm_datasize[this_one] - 1,
2192 is16bits); /* Loop end location */
2194 mode[chn] |= 0x08; /* Enable looping */
2196 if (pcm_datasize[this_one] != pcm_bsize) {
2198 * Incompletely filled block. Possibly the last one.
2201 mode[chn] &= ~0x08; /* Disable looping */
2202 mode[chn] |= 0x20; /* Enable IRQ at the end */
2203 voices[0].loop_irq_mode = LMODE_PCM_STOP;
2204 ramp_mode[chn] = 0x03; /* No rollover bit */
2206 gus_write_addr(0x04, dram_loc + pcm_datasize[this_one],
2207 is16bits); /* Loop end location */
2208 mode[chn] &= ~0x08; /* Disable looping */
2214 for (chn = 0; chn < gus_sampling_channels; chn++) {
2216 gus_select_voice(chn);
2217 gus_write8(0x0d, ramp_mode[chn]);
2218 gus_voice_on(mode[chn]);
2226 gus_transfer_output_block(int dev, u_long buf,
2227 int total_count, int intrflag, int chn)
2230 * This routine transfers one block of audio data to the DRAM. In
2231 * mono mode it's called just once. When in stereo mode, this_one
2232 * routine is called once for both channels.
2234 * The left/mono channel data is transferred to the beginning of dram
2235 * and the right data to the area pointed by gus_page_size.
2238 int this_one, count;
2241 u_long address, hold_address;
2245 count = total_count / gus_sampling_channels;
2248 if (pcm_qlen >= pcm_nblk)
2249 printf("GUS Warning: PCM buffers out of sync\n");
2251 this_one = pcm_current_block = pcm_tail;
2253 pcm_tail = (pcm_tail + 1) % pcm_nblk;
2254 pcm_datasize[this_one] = count;
2256 this_one = pcm_current_block;
2258 gus_write8(0x41, 0); /* Disable GF1 DMA */
2259 DMAbuf_start_dma(dev, buf + (chn * count), count, 1);
2261 address = this_one * pcm_bsize;
2262 address += chn * pcm_banksize;
2264 if (audio_devs[dev]->dmachan1 > 3) {
2265 hold_address = address;
2266 address = address >> 1;
2267 address &= 0x0001ffffL;
2268 address |= (hold_address & 0x000c0000L);
2270 gus_write16(0x42, (address >> 4) & 0xffff); /* DRAM DMA address */
2272 dma_command = 0x21; /* IRQ enable, DMA start */
2274 if (gus_sampling_bits != 8)
2275 dma_command |= 0x40; /* 16 bit _DATA_ */
2277 dma_command |= 0x80; /* Invert MSB */
2279 if (audio_devs[dev]->dmachan1 > 3)
2280 dma_command |= 0x04; /* 16 bit DMA channel */
2282 gus_write8(0x41, dma_command); /* Kickstart */
2284 if (chn == (gus_sampling_channels - 1)) { /* Last channel */
2286 * Last (right or mono) channel data
2288 dma_active = 1; /* DMA started. There is a unacknowledged
2290 active_device = GUS_DEV_PCM_DONE;
2291 if (!pcm_active && (pcm_qlen > 0 || count < pcm_bsize)) {
2292 play_next_pcm_block();
2296 * Left channel data. The right channel is transferred after
2299 active_device = GUS_DEV_PCM_CONTINUE;
2306 gus_sampling_output_block(int dev, u_long buf, int total_count,
2307 int intrflag, int restart_dma)
2309 pcm_current_buf = buf;
2310 pcm_current_count = total_count;
2311 pcm_current_intrflag = intrflag;
2312 pcm_current_dev = dev;
2313 gus_transfer_output_block(dev, buf, total_count, intrflag, 0);
2317 gus_sampling_start_input(int dev, u_long buf, int count,
2318 int intrflag, int restart_dma)
2325 DMAbuf_start_dma(dev, buf, count, 0);
2327 mode = 0xa0; /* DMA IRQ enabled, invert MSB */
2329 if (audio_devs[dev]->dmachan2 > 3)
2330 mode |= 0x04; /* 16 bit DMA channel */
2331 if (gus_sampling_channels > 1)
2332 mode |= 0x02; /* Stereo */
2333 mode |= 0x01; /* DMA enable */
2335 gus_write8(0x49, mode);
2341 gus_sampling_prepare_for_input(int dev, int bsize, int bcount)
2345 rate = (9878400 / (gus_sampling_speed + 2)) / 16;
2347 gus_write8(0x48, rate & 0xff); /* Set sampling rate */
2349 if (gus_sampling_bits != 8) {
2350 printf("GUS Error: 16 bit recording not supported\n");
2357 gus_sampling_prepare_for_output(int dev, int bsize, int bcount)
2361 long mem_ptr, mem_size;
2364 mem_size = gus_mem_size / gus_sampling_channels;
2366 if (mem_size > (256 * 1024))
2367 mem_size = 256 * 1024;
2369 pcm_bsize = bsize / gus_sampling_channels;
2370 pcm_head = pcm_tail = pcm_qlen = 0;
2372 pcm_nblk = MAX_PCM_BUFFERS;
2373 if ((pcm_bsize * pcm_nblk) > mem_size)
2374 pcm_nblk = mem_size / pcm_bsize;
2376 for (i = 0; i < pcm_nblk; i++)
2377 pcm_datasize[i] = 0;
2379 pcm_banksize = pcm_nblk * pcm_bsize;
2381 if (gus_sampling_bits != 8 && pcm_banksize == (256 * 1024))
2388 gus_local_qlen(int dev)
2394 gus_copy_from_user(int dev, char *localbuf, int localoffs,
2395 snd_rw_buf * userbuf, int useroffs, int len)
2397 if (gus_sampling_channels == 1) {
2399 if (uiomove(&localbuf[localoffs], len, userbuf)) {
2400 printf("audio: Bad copyin()!\n");
2402 } else if (gus_sampling_bits == 8) {
2403 int in_left = useroffs;
2404 int in_right = useroffs + 1;
2405 char *out_left, *out_right;
2410 out_left = &localbuf[localoffs];
2411 out_right = out_left + pcm_bsize;
2413 for (i = 0; i < len; i++) {
2414 uiomove((char *) &(*out_left++), 1, userbuf);
2416 uiomove((char *) &(*out_right++), 1, userbuf);
2420 int in_left = useroffs;
2421 int in_right = useroffs + 2;
2422 short *out_left, *out_right;
2428 out_left = (short *) &localbuf[localoffs];
2429 out_right = out_left + (pcm_bsize / 2);
2431 for (i = 0; i < len; i++) {
2432 uiomove((char *) &(*out_left++), 2, userbuf);
2434 uiomove((char *) &(*out_right++), 2, userbuf);
2440 static struct audio_operations gus_sampling_operations =
2442 "Gravis UltraSound",
2444 AFMT_U8 | AFMT_S16_LE,
2448 gus_sampling_output_block,
2449 gus_sampling_start_input,
2451 gus_sampling_prepare_for_input,
2452 gus_sampling_prepare_for_output,
2460 guswave_setup_voice(int dev, int voice, int chn)
2462 struct channel_info *info =
2463 &synth_devs[dev]->chn_info[chn];
2465 guswave_set_instr(dev, voice, info->pgm_num);
2467 voices[voice].expression_vol =
2468 info->controllers[CTL_EXPRESSION]; /* Just msb */
2469 voices[voice].main_vol =
2470 (info->controllers[CTL_MAIN_VOLUME] * 100) / 128;
2471 voices[voice].panning =
2472 (info->controllers[CTL_PAN] * 2) - 128;
2473 voices[voice].bender = info->bender_value;
2477 guswave_bender(int dev, int voice, int value)
2482 voices[voice].bender = value - 8192;
2483 freq = compute_finetune(voices[voice].orig_freq, value - 8192,
2484 voices[voice].bender_range);
2485 voices[voice].current_freq = freq;
2488 gus_select_voice(voice);
2489 gus_voice_freq(freq);
2494 guswave_patchmgr(int dev, struct patmgr_info * rec)
2498 switch (rec->command) {
2499 case PM_GET_DEVTYPE:
2500 rec->parm1 = PMTYPE_WAVE;
2505 rec->parm1 = MAX_PATCH;
2510 rec->parm1 = MAX_PATCH;
2512 for (i = 0; i < MAX_PATCH; i++) {
2513 int ptr = patch_table[i];
2515 rec->data.data8[i] = 0;
2517 while (ptr >= 0 && ptr < free_sample) {
2518 rec->data.data8[i]++;
2519 ptr = samples[ptr].key; /* Follow link */
2525 case PM_GET_PGM_PATCHES:
2527 int ptr = patch_table[rec->parm1];
2531 while (ptr >= 0 && ptr < free_sample) {
2532 rec->data.data32[n++] = ptr;
2533 ptr = samples[ptr].key; /* Follow link */
2542 int ptr = rec->parm1;
2543 struct patch_info *pat;
2545 if (ptr < 0 || ptr >= free_sample)
2548 bcopy((char *) &samples[ptr], rec->data.data8, sizeof(struct patch_info));
2550 pat = (struct patch_info *) rec->data.data8;
2552 pat->key = GUS_PATCH; /* Restore patch type */
2553 rec->parm1 = sample_ptrs[ptr]; /* DRAM location */
2554 rec->parm2 = sizeof(struct patch_info);
2561 int ptr = rec->parm1;
2562 struct patch_info *pat;
2564 if (ptr < 0 || ptr >= free_sample)
2567 pat = (struct patch_info *) rec->data.data8;
2569 if (pat->len > samples[ptr].len) /* Cannot expand sample */
2572 pat->key = samples[ptr].key; /* Ensure the link is
2575 bcopy(rec->data.data8, (char *) &samples[ptr], sizeof(struct patch_info));
2577 pat->key = GUS_PATCH;
2582 case PM_READ_PATCH: /* Returns a block of wave data from the DRAM */
2584 int sample = rec->parm1;
2586 long offs = rec->parm2;
2589 if (sample < 0 || sample >= free_sample)
2592 if (offs < 0 || offs >= samples[sample].len)
2593 return -(EINVAL); /* Invalid offset */
2595 n = samples[sample].len - offs; /* Num of bytes left */
2600 if (l > sizeof(rec->data.data8))
2601 l = sizeof(rec->data.data8);
2604 return -(EINVAL); /* Was there a bug? */
2606 offs += sample_ptrs[sample]; /* Begin offsess +
2609 for (n = 0; n < l; n++)
2610 rec->data.data8[n] = gus_peek(offs++);
2611 rec->parm1 = n; /* Nr of bytes copied */
2616 case PM_WRITE_PATCH: /* Writes a block of wave data to the DRAM */
2618 int sample = rec->parm1;
2620 long offs = rec->parm2;
2623 if (sample < 0 || sample >= free_sample)
2626 if (offs < 0 || offs >= samples[sample].len)
2627 return -(EINVAL); /* Invalid offset */
2629 n = samples[sample].len - offs; /* Nr of bytes left */
2634 if (l > sizeof(rec->data.data8))
2635 l = sizeof(rec->data.data8);
2638 return -(EINVAL); /* Was there a bug? */
2640 offs += sample_ptrs[sample]; /* Begin offsess +
2643 for (n = 0; n < l; n++)
2644 gus_poke(offs++, rec->data.data8[n]);
2645 rec->parm1 = n; /* Nr of bytes copied */
2656 guswave_alloc(int dev, int chn, int note, struct voice_alloc_info * alloc)
2658 int i, p, best = -1, best_time = 0x7fffffff;
2662 * First look for a completely stopped voice
2665 for (i = 0; i < alloc->max_voice; i++) {
2666 if (alloc->map[p] == 0) {
2670 if (alloc->alloc_times[p] < best_time) {
2672 best_time = alloc->alloc_times[p];
2674 p = (p + 1) % alloc->max_voice;
2678 * Then look for a releasing voice
2681 for (i = 0; i < alloc->max_voice; i++) {
2682 if (alloc->map[p] == 0xffff) {
2686 p = (p + 1) % alloc->max_voice;
2696 static struct synth_operations guswave_operations =
2714 guswave_volume_method,
2722 set_input_volumes(void)
2725 u_char mask = 0xff & ~0x06; /* Just line out enabled */
2727 if (have_gus_max) /* Don't disturb GUS MAX */
2733 * Enable channels having vol > 10% Note! bit 0x01 means the line in
2734 * DISABLED while 0x04 means the mic in ENABLED.
2736 if (gus_line_vol > 10)
2738 if (gus_mic_vol > 10)
2741 if (recording_active) {
2743 * Disable channel, if not selected for recording
2745 if (!(gus_recmask & SOUND_MASK_LINE))
2747 if (!(gus_recmask & SOUND_MASK_MIC))
2751 mix_image |= mask & 0x07;
2752 outb(u_Mixer, mix_image);
2758 gus_default_mixer_ioctl(int dev, u_int cmd, ioctl_arg arg)
2761 #define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \
2762 SOUND_MASK_SYNTH|SOUND_MASK_PCM)
2764 if (((cmd >> 8) & 0xff) == 'M') {
2766 switch (cmd & 0xff) {
2767 case SOUND_MIXER_RECSRC:
2768 gus_recmask = (*(int *) arg) & MIX_DEVS;
2769 if (!(gus_recmask & (SOUND_MASK_MIC | SOUND_MASK_LINE)))
2770 gus_recmask = SOUND_MASK_MIC;
2772 * Note! Input volumes are updated during
2773 * next open for recording
2775 return *(int *) arg = gus_recmask;
2778 case SOUND_MIXER_MIC:
2780 int vol = (*(int *) arg) & 0xff;
2787 set_input_volumes();
2788 return *(int *) arg = vol | (vol << 8);
2792 case SOUND_MIXER_LINE:
2794 int vol = (*(int *) arg) & 0xff;
2801 set_input_volumes();
2802 return *(int *) arg = vol | (vol << 8);
2806 case SOUND_MIXER_PCM:
2807 gus_pcm_volume = (*(int *) arg) & 0xff;
2808 RANGE (gus_pcm_volume, 0, 100);
2809 gus_sampling_update_volume();
2810 return *(int *) arg = gus_pcm_volume | (gus_pcm_volume << 8);
2813 case SOUND_MIXER_SYNTH:
2817 gus_wave_volume = (*(int *) arg) & 0xff;
2819 RANGE (gus_wave_volume , 0, 100);
2821 if (active_device == GUS_DEV_WAVE)
2822 for (voice = 0; voice < nr_voices; voice++)
2823 dynamic_volume_change(voice); /* Apply the new vol */
2825 return *(int *) arg = gus_wave_volume | (gus_wave_volume << 8);
2833 switch (cmd & 0xff) { /* Return parameters */
2835 case SOUND_MIXER_RECSRC:
2836 return *(int *) arg = gus_recmask;
2839 case SOUND_MIXER_DEVMASK:
2840 return *(int *) arg = MIX_DEVS;
2843 case SOUND_MIXER_STEREODEVS:
2844 return *(int *) arg = 0;
2847 case SOUND_MIXER_RECMASK:
2848 return *(int *) arg = SOUND_MASK_MIC | SOUND_MASK_LINE;
2851 case SOUND_MIXER_CAPS:
2852 return *(int *) arg = 0;
2855 case SOUND_MIXER_MIC:
2856 return *(int *) arg = gus_mic_vol | (gus_mic_vol << 8);
2859 case SOUND_MIXER_LINE:
2860 return *(int *) arg = gus_line_vol | (gus_line_vol << 8);
2863 case SOUND_MIXER_PCM:
2864 return *(int *) arg = gus_pcm_volume | (gus_pcm_volume << 8);
2867 case SOUND_MIXER_SYNTH:
2868 return *(int *) arg = gus_wave_volume | (gus_wave_volume << 8);
2878 static struct mixer_operations gus_mixer_operations = {"Gravis Ultrasound", gus_default_mixer_ioctl};
2881 gus_default_mixer_init()
2883 if (num_mixers < MAX_MIXER_DEV) /* Don't install if there is another
2885 mixer_devs[num_mixers++] = &gus_mixer_operations;
2889 * Enable all mixer channels on the GF1 side. Otherwise
2890 * recording will not be possible using GUS MAX.
2893 mix_image |= 0x04; /* All channels enabled */
2894 outb(u_Mixer, mix_image);
2898 /* start of pnp code */
2904 outb(PWRITE_DATA, r);
2911 * Get the device's serial number. Returns 1 if the serial is valid.
2914 get_serial(int rd_port, u_char *data)
2916 int i, bit, valid = 0, sum = 0x6a;
2918 bzero(data, sizeof(char) * 9);
2920 for (i = 0; i < 72; i++) {
2921 bit = inb((rd_port << 2) | 0x3) == 0x55;
2922 DELAY(250); /* Delay 250 usec */
2924 /* Can't Short Circuit the next evaluation, so 'and' is last */
2925 bit = (inb((rd_port << 2) | 0x3) == 0xaa) && bit;
2926 DELAY(250); /* Delay 250 usec */
2928 valid = valid || bit;
2932 (((sum ^ (sum >> 1) ^ bit) << 7) & 0xff);
2934 data[i / 8] = (data[i / 8] >> 1) | (bit ? 0x80 : 0);
2936 valid = valid && (data[8] == sum);
2942 send_Initiation_LFSR()
2946 /* Reset the LSFR */
2951 outb(PADDRESS, cur);
2953 for (i = 1; i < 32; i++) {
2954 cur = (cur >> 1) | (((cur ^ (cur >> 1)) << 7) & 0xff);
2955 outb(PADDRESS, cur);
2962 isolation_protocol(int rd_port)
2967 send_Initiation_LFSR();
2969 /* Reset CSN for All Cards */
2972 for (csn = 1; (csn < MAX_CARDS); csn++) {
2973 /* Wake up cards without a CSN */
2976 SEND(SET_RD_DATA, rd_port);
2977 outb(PADDRESS, SERIAL_ISOLATION);
2978 DELAY(1000); /* Delay 1 msec */
2979 if (get_serial(rd_port, data)) {
2980 printf("Board Vendor ID: %c%c%c%02x%02x",
2981 ((data[0] & 0x7c) >> 2) + 64,
2982 (((data[0] & 0x03) << 3) | ((data[1] & 0xe0) >> 5)) + 64,
2983 (data[1] & 0x1f) + 64, data[2], data[3]);
2984 printf(" Board Serial Number: %08x\n", *(int *) &(data[4]));
2986 SEND(SET_CSN, csn); /* Move this out of this
2988 outb(PADDRESS, PSTATUS);
3002 * ########################################################################
3004 * FUNCTION : IwaveInputSource
3006 * PROFILE: This function allows the calling program to select among any of
3007 * several possible sources to the ADC's. The possible input sources and
3008 * their corresponding symbolic constants are: - Line (LINE_IN) - Aux1
3009 * (AUX1_IN) - Microphone (MIC_IN) - Mixer (MIX_IN)
3011 * Set the first argument to either LEFT_SOURCE or RIGHT_SOURCE. Always use the
3012 * symbolic contants for the arguments.
3014 * ########################################################################
3017 IwaveInputSource(BYTE index, BYTE source)
3022 reg = inb(iw.pcodar) & 0xE0;
3023 outb(iw.pcodar, reg | index); /* select register CLICI or CRICI */
3024 reg = inb(iw.cdatap) & ~MIX_IN;
3026 outb(iw.cdatap, (BYTE) (reg | source));
3030 IwavePnpGetCfg(void)
3036 IwavePnpDevice(AUDIO);
3037 outb(_PIDXR, 0x60); /* select P2X0HI */
3038 val = ((WORD) inb(iw.pnprdp)) << 8; /* get P2XR[9:8] */
3039 outb(_PIDXR, 0x61); /* select P2XRLI */
3040 iw.p2xr = val + (WORD) inb(iw.pnprdp); /* get P2XR[7:4] */
3042 outb(_PIDXR, 0x62); /* select P3X0HI */
3043 val = ((WORD) inb(iw.pnprdp)) << 8; /* get P3XR[9:8] */
3044 outb(_PIDXR, 0x63); /* select P3X0LI */
3045 iw.p3xr = val + (WORD) inb(iw.pnprdp); /* get P3XR[7:3] */
3047 outb(_PIDXR, 0x64); /* select PHCAI */
3048 val = ((WORD) inb(iw.pnprdp)) << 8; /* get PCODAR[9:8] */
3049 outb(_PIDXR, 0x65); /* select PLCAI */
3050 iw.pcodar = val + (WORD) inb(iw.pnprdp); /* get PCODAR[7:2] */
3052 outb(_PIDXR, 0x70); /* select PUI1SI */
3053 iw.synth_irq = (WORD) (inb(iw.pnprdp) & 0x0F); /* Synth IRQ number */
3055 outb(_PIDXR, 0x72); /* select PUI2SI */
3056 iw.midi_irq = (WORD) (inb(iw.pnprdp) & 0x0F); /* MIDI IRQ number */
3058 outb(_PIDXR, 0x74); /* select PUD1SI */
3059 iw.dma1_chan = inb(iw.pnprdp) & 0x07; /* DMA1 chan (LMC/Codec Rec) */
3061 outb(_PIDXR, 0x75); /* select PUD2SI */
3062 iw.dma2_chan = inb(iw.pnprdp) & 0x07; /* DMA2 chan (codec play) */
3065 IwavePnpDevice(EXT); /* select external device */
3066 outb(_PIDXR, 0x60); /* select PRAHI */
3067 val = ((WORD) inb(iw.pnprdp)) << 8; /* get PCDRAR[9:8] */
3068 outb(_PIDXR, 0x61); /* select PRALI */
3069 iw.pcdrar = val + (WORD) inb(iw.pnprdp); /* get PCDRAR[7:4] */
3070 outb(_PIDXR, 0x62); /* select PATAHI */
3071 val = ((WORD) inb(iw.pnprdp)) << 8; /* get PATAAR[9:8] */
3072 outb(_PIDXR, 0x63); /* select PATALI */
3073 iw.pataar = val + (WORD) inb(iw.pnprdp); /* get PATAAR[7:1] */
3075 outb(_PIDXR, 0x70); /* select PRISI */
3076 iw.ext_irq = (WORD) (inb(iw.pnprdp) & 0x0F); /* Ext Dev IRQ number */
3078 outb(_PIDXR, 0x74); /* select PRDSI */
3079 iw.ext_chan = inb(iw.pnprdp) & 0x07; /* Ext Dev DMA channel */
3081 IwavePnpDevice(MPU401); /* Select MPU401 Device */
3082 outb(_PIDXR, 0x60); /* select P401HI */
3083 val = ((WORD) inb(iw.pnprdp)) << 8; /* get P401AR[9:8] */
3084 outb(_PIDXR, 0x61); /* select P401LI */
3085 iw.p401ar = val + (WORD) inb(iw.pnprdp); /* get P401AR[7:1] */
3087 outb(_PIDXR, 0x70); /* select PMISI */
3088 iw.mpu_irq = (WORD) (inb(iw.pnprdp) & 0x0F); /* MPU401 Dev IRQ number */
3090 IwavePnpDevice(GAME); /* Select GAME logical Device */
3091 outb(_PIDXR, 0x60); /* select P201HI */
3092 val = ((WORD) inb(iw.pnprdp)) << 8; /* get P201AR[9:8] */
3093 outb(_PIDXR, 0x61); /* select P201LI */
3094 iw.p201ar = val + (WORD) inb(iw.pnprdp); /* get P201AR[7:6] */
3096 IwavePnpDevice(EMULATION); /* Select SB and ADLIB Device */
3097 outb(_PIDXR, 0x60); /* select P388HI */
3098 val = ((WORD) inb(iw.pnprdp)) << 8; /* get P388AR[9:8] */
3099 outb(_PIDXR, 0x61); /* select P388LI */
3100 iw.p388ar = val + inb(iw.pnprdp); /* get P388AR[7:6] */
3101 outb(_PIDXR, 0x70); /* select PSBISI */
3102 iw.emul_irq = (WORD) (inb(iw.pnprdp) & 0x0F); /* emulation Dev IRQ
3108 IwavePnpSetCfg(void)
3111 IwavePnpDevice(AUDIO); /* select audio device */
3112 outb(_PIDXR, 0x60); /* select P2X0HI */
3113 outb(_PNPWRP, (BYTE) (iw.p2xr >> 8)); /* set P2XR[9:8] */
3114 outb(_PIDXR, 0x61); /* select P2X0LI */
3115 outb(_PNPWRP, (BYTE) iw.p2xr); /* set P2XR[7:4] */
3117 outb(_PIDXR, 0x62); /* select P3X0HI */
3118 outb(_PNPWRP, (BYTE) (iw.p3xr >> 8)); /* set P3XR[9:8] */
3119 outb(_PIDXR, 0x63); /* select P3X0LI */
3120 outb(_PNPWRP, (BYTE) (iw.p3xr)); /* set P3XR[7:3] */
3122 outb(_PIDXR, 0x64); /* select PHCAI */
3123 outb(_PNPWRP, (BYTE) (iw.pcodar >> 8)); /* set PCODAR[9:8] */
3124 outb(_PIDXR, 0x65); /* select PLCAI */
3125 outb(_PNPWRP, (BYTE) iw.pcodar); /* set PCODAR[7:2] */
3127 outb(_PIDXR, 0x70); /* select PUI1SI */
3128 outb(_PNPWRP, (BYTE) (iw.synth_irq & 0x0F)); /* Synth IRQ number */
3129 outb(_PIDXR, 0x72); /* select PUI2SI */
3130 outb(_PNPWRP, (BYTE) (iw.midi_irq & 0x0F)); /* MIDI IRQ number */
3132 outb(_PIDXR, 0x74); /* select PUD1SI */
3133 outb(_PNPWRP, (BYTE) (iw.dma1_chan & 0x07)); /* DMA channel 1 */
3134 outb(_PIDXR, 0x75); /* select PUD2SI */
3135 outb(_PNPWRP, (BYTE) (iw.dma2_chan & 0x07)); /* DMA channel 2 */
3137 IwavePnpDevice(EXT);
3138 outb(_PIDXR, 0x60); /* select PRAHI */
3139 outb(_PNPWRP, (BYTE) (iw.pcdrar >> 8)); /* set PCDRAR[9:8] */
3140 outb(_PIDXR, 0x61); /* select PRALI */
3141 outb(_PNPWRP, (BYTE) iw.pcdrar); /* set PCDRAR[7:3] */
3143 outb(_PIDXR, 0x62); /* select PATAHI */
3144 outb(_PNPWRP, (BYTE) (iw.pataar >> 8)); /* set PATAAR[9:8] */
3145 outb(_PIDXR, 0x63); /* select PATALI */
3146 outb(_PNPWRP, (BYTE) iw.pataar); /* set PATAAR[7:1] */
3148 outb(_PIDXR, 0x70); /* select PRISI */
3149 outb(_PNPWRP, (BYTE) (iw.ext_irq & 0x0F)); /* Ext Dev IRQ number */
3150 outb(_PIDXR, 0x74); /* select PRDSI */
3151 outb(_PNPWRP, (BYTE) (iw.ext_chan & 0x07)); /* Ext Dev DMA channel */
3153 IwavePnpDevice(GAME);
3154 outb(_PIDXR, 0x60); /* select P201HI */
3155 outb(_PNPWRP, (BYTE) (iw.p201ar >> 8)); /* set P201RAR[9:8] */
3156 outb(_PIDXR, 0x61); /* select P201LI */
3157 outb(_PNPWRP, (BYTE) iw.p201ar); /* set P201AR[7:6] */
3159 IwavePnpDevice(EMULATION);
3160 outb(_PIDXR, 0x60); /* select P388HI */
3161 outb(_PNPWRP, (BYTE) (iw.p388ar >> 8)); /* set P388AR[9:8] */
3162 outb(_PIDXR, 0x61); /* select P388LI */
3163 outb(_PNPWRP, (BYTE) iw.p388ar); /* set P388AR[7:6] */
3165 outb(_PIDXR, 0x70); /* select PSBISI */
3166 outb(_PNPWRP, (BYTE) (iw.emul_irq & 0x0F)); /* emulation IRQ number */
3168 IwavePnpDevice(MPU401);
3169 outb(_PIDXR, 0x60); /* select P401HI */
3170 outb(_PNPWRP, (BYTE) (iw.p401ar >> 8)); /* set P401AR[9:8] */
3171 outb(_PIDXR, 0x61); /* select P401LI */
3172 outb(_PNPWRP, (BYTE) iw.p401ar); /* set P401AR[7:1] */
3174 outb(_PIDXR, 0x70); /* select PMISI */
3175 outb(_PNPWRP, (BYTE) (iw.mpu_irq & 0x0F)); /* MPU emulation IRQ
3180 /* ######################################################################## */
3183 /* REMARKS: This file contains the definitions for the InterWave's DDK */
3184 /* functions dedicated to the configuration of the InterWave */
3187 /* UPDATE: 4/07/95 */
3188 /* ######################################################################## */
3190 /* FUNCTION: IwavePnpKey */
3192 /* PROFILE: This function issues the initiation key that places the PNP */
3193 /* logic into configuration mode. The PNP logic is quiescent at */
3194 /* power up and must be enabled by software. This function will */
3195 /* do 32 I/O writes to the PIDXR (0x0279). The function will */
3196 /* first reset the LFSR to its initial value by a sequence of two */
3197 /* write cycles of 0x00 to PIDXR before issuing the key. */
3199 /* ######################################################################## */
3203 /* send_Initiation_LFSR(); */
3209 /* ############################################### */
3210 /* Reset Linear Feedback Shift Reg. */
3211 /* ############################################### */
3215 outb(0x279, code); /* Initial value */
3217 for (i = 1; i < 32; i++) {
3218 msb = ((code & 0x01) ^ ((code & 0x02) >> 1)) << 7;
3219 code = (code >> 1) | msb;
3226 IwavePnpIsol(PORT * pnpread)
3230 printf("Checking for GUS Plug-n-Play ...\n");
3232 /* Try various READ_DATA ports from 0x203-0x3ff */
3233 for (rd_port = 0x80; (rd_port < 0xff); rd_port += 0x10) {
3235 printf("Trying Read_Port at %x\n",
3236 (rd_port << 2) | 0x3);
3238 num_pnp_devs = isolation_protocol(rd_port);
3240 *pnpread = rd_port << 2 | 0x3;
3244 if (!num_pnp_devs) {
3245 printf("No Plug-n-Play devices were found\n");
3251 /* ######################################################################## */
3253 /* FUNCTION: IwavePnpPeek */
3255 /* PROFILE: This function will return the number of specified bytes of */
3256 /* resource data from the serial EEPROM. The function will NOT */
3257 /* reset the serial EEPROM logic to allow reading the entire */
3258 /* EEPROM by issuing repeated calls. The caller must supply a */
3259 /* pointer to where the data are to be stored. */
3260 /* It is assumed that the InterWave is not in either "sleep" */
3261 /* or "wait for key" states. Note that on the first call, if */
3262 /* the caller means to read from the beggining of data the */
3263 /* serial EEPROM logic must be reset. For this, the caller */
3264 /* should issue a WAKE[CSN] command */
3266 /* ######################################################################## */
3268 IwavePnpPeek(PORT pnprdp, WORD bytes, BYTE * data)
3273 for (i = 1; i <= bytes; i++) {
3274 outb(_PIDXR, 0x05); /* select PRESSI */
3276 while (TRUE) { /* wait til new data byte is ready */
3277 if (inb(pnprdp) & PNP_DATA_RDY)
3278 break; /* new resource byte ready */
3280 outb(_PIDXR, 0x04); /* select PRESDI */
3281 datum = inb(pnprdp); /* read resource byte */
3283 *(data++) = datum; /* store it */
3286 /* ######################################################################## */
3288 /* FUNCTION: IwavePnpActivate */
3290 /* PROFILE: This function will activate or de-activate the audio device */
3291 /* or the external device on the InterWave. Set the "dev" arg */
3292 /* to AUDIO for the audio device or EXT for the external device. */
3293 /* Set "bool" to ON or OFF to turn the device on or off the ISA */
3294 /* bus. Notice that for a logical device to work, it must be */
3297 /* ######################################################################## */
3299 IwavePnpActivate(BYTE dev, BYTE bool)
3301 IwavePnpDevice(dev); /* select audio device */
3303 outb(_PIDXR, ACTIVATE_DEV); /* select Activate Register */
3304 outb(_PNPWRP, bool); /* write register */
3308 /* ######################################################################## */
3310 /* FUNCTION: IwavePnpDevice */
3312 /* PROFILE: This function allows the caller to select between five */
3313 /* logical devices available on the InterWave.It is assumed */
3314 /* that the PNP state machine is in configuration mode. */
3316 /* ######################################################################## */
3318 IwavePnpDevice(BYTE dev)
3321 outb(_PIDXR, _PLDNI); /* select PLDNI */
3322 outb(_PNPWRP, dev); /* write PLDNI */
3325 /* ######################################################################## */
3327 /* FUNCTION: IwavePnpWake */
3329 /* PROFILE: This function issues a WAKE[CSN] command to the InterWave. If */
3330 /* the CSN matches the PNP state machine will enter the */
3331 /* configuration state. Otherwise it will enter the sleep mode. */
3333 /* It is assumed that the PNP state machine is not in the */
3334 /* "wait for key" state. */
3336 /* ######################################################################## */
3338 IwavePnpWake(BYTE csn)
3341 outb(_PIDXR, _PWAKEI); /* select PWAKEI */
3342 outb(_PNPWRP, csn); /* write csn */
3345 /* ######################################################################## */
3348 * FUNCTION: IwavePnpPing
3351 /* PROFILE: This function allows the caller to detect an InterWave based */
3352 /* adapter board and will return its asigned CSN so that an */
3353 /* an application can access its PnP interface and determine the */
3354 /* borad's current configuration. In conducting its search for */
3355 /* the InterWave IC, the function will use the first 32 bits of */
3356 /* the Serial Identifier called the vendor ID in the PnP ISA */
3357 /* spec. The last 4 bits in the Vendor ID represent a revision */
3358 /* number for the particular product and will not be included */
3359 /* in the search. The function will return the Vendor ID and the */
3360 /* calling application should check the revision bits to make */
3361 /* sure they are compatible with the board. */
3363 /* ######################################################################## */
3365 IwavePnpPing(DWORD VendorID)
3369 VendorID &= (0xFFFFFFF0); /* reset 4 least significant bits */
3370 IwavePnpKey(); /* Key to access PnP Interface */
3371 while (iw.pnprdp <= 0x23F) {
3372 for (csn = 1; csn <= 10; csn++) {
3373 IwavePnpWake(csn); /* Select card */
3374 IwavePnpPeek(iw.pnprdp, 4, (BYTE *) & iw.vendor); /* get vendor ID */
3377 if (((iw.vendor) & 0xFFFFFFF0) == VendorID) { /* If IDs match,
3378 * InterWave is found */
3380 outb(_PIDXR, 0x02); /* Place all cards in
3381 * wait-for-key state */
3388 outb(_PIDXR, 0x02); /* Place all cards in wait-for-key state */
3390 return (FALSE); /* InterWave IC not found */
3393 /* end of pnp code */
3401 outb(iw.igidxr, _LMCI);
3402 outb(iw.i8dp, inb(iw.i8dp) & 0xFD); /* DRAM I/O cycles selected */
3405 IwaveMemPoke(local, datum);
3406 IwaveMemPoke(local + 1L, datum + 1);
3407 if (IwaveMemPeek(local) != datum || IwaveMemPeek(local + 1L) != (datum + 1) || IwaveMemPeek(0L) != 0x55)
3412 return ((WORD) (local >> 10));
3416 IwaveMemPeek(ADDRESS addr)
3423 outb(iw.igidxr, 0x43); /* Select LMALI */
3424 outw(iw.i16dp, (WORD) addr); /* Lower 16 bits of LM */
3425 outb(iw.igidxr, 0x44); /* Select LMAHI */
3426 outb(iw.i8dp, (BYTE) (addr >> 16)); /* Upper 8 bits of LM */
3427 return (inb(iw.lmbdr)); /* return byte from LMBDR */
3432 IwaveMemPoke(ADDRESS addr, BYTE datum)
3438 outb(iw.igidxr, 0x43); /* Select LMALI */
3439 outw(iw.i16dp, (WORD) addr); /* Lower 16 bits of LM */
3440 outb(iw.igidxr, 0x44); /* Select LMAHI */
3441 outb(iw.i8dp, (BYTE) (addr >> 16)); /* Upper 8 bits of LM */
3442 outb(iw.lmbdr, datum); /* Write byte to LMBDR */
3445 /* ######################################################################## */
3447 /* FUNCTION: IwaveMemCfg */
3449 /* PROFILE : This function determines the amount of DRAM from its */
3450 /* configuration accross all banks. It sets the configuration */
3451 /* into register LMCFI and stores the total amount of DRAM */
3452 /* into iw.size_mem (Kbytes). */
3454 /* The function first places the IC in enhanced mode to allow */
3455 /* full access to all DRAM locations. Then it selects full */
3456 /* addressing span (LMCFI[3:0]=0x0C). Finally, it determines */
3457 /* the amount of DRAM in each bank and from this the actual */
3458 /* configuration. */
3460 /* Note that if a configuration other than one indicated in */
3461 /* the manual is implemented, this function will select */
3462 /* full addressing span (LMCFI[3:0]=0xC). */
3464 /* ######################################################################## */
3466 IwaveMemCfg(DWORD * lpbanks)
3468 DWORD bank[4] = {0L, 0L, 0L, 0L};
3469 DWORD addr = 0L, base = 0L, cnt = 0L;
3470 BYTE i, reg, ram = FALSE;
3474 outb(iw.igidxr, 0x99);
3475 reg = inb(iw.i8dp); /* image of sgmi */
3476 outb(iw.igidxr, 0x19);
3477 outb(iw.i8dp, (BYTE) (reg | 0x01)); /* enable enhaced mode */
3478 outb(iw.igidxr, _LMCFI);/* select LM Conf Reg */
3479 lmcfi = inw(iw.i16dp) & 0xFFF0;
3480 outw(iw.i16dp, lmcfi | 0x000C); /* max addr span */
3482 /* Clear every RAM_STEPth location */
3484 while (addr < RAM_MAX) {
3485 IwaveMemPoke(addr, 0x00);
3489 /* Determine amount of RAM in each bank */
3491 for (i = 0; i < 4; i++) {
3492 IwaveMemPoke(base, 0xAA); /* mark start of bank */
3493 IwaveMemPoke(base + 1L, 0x55);
3494 if ((IwaveMemPeek(base) == 0xAA) && (IwaveMemPeek(base + 1L) == 0x55))
3497 while (cnt < BANK_MAX) {
3498 bank[i] += RAM_STEP;
3501 if (IwaveMemPeek(addr) == 0xAA)
3505 if (lpbanks != NULL) {
3509 bank[i] = bank[i] >> 10;
3515 iw.flags &= ~DRAM_HOLES;
3516 outb(iw.igidxr, _LMCFI);
3517 if (bank[0] == 256 && bank[1] == 0 && bank[2] == 0 && bank[3] == 0)
3518 outw(iw.i16dp, lmcfi);
3519 else if (bank[0] == 256 && bank[1] == 256 && bank[2] == 0 && bank[3] == 0)
3520 outw(iw.i16dp, lmcfi | 0x01);
3521 else if (bank[0] == 256 && bank[1] == 256 && bank[2] == 256 && bank[3] == 256)
3522 outw(iw.i16dp, lmcfi | 0x02);
3523 else if (bank[0] == 256 && bank[1] == 1024 && bank[2] == 0 && bank[3] == 0)
3524 outw(iw.i16dp, lmcfi | 0x03);
3525 else if (bank[0] == 256 && bank[1] == 1024 && bank[2] == 1024 && bank[3] == 1024)
3526 outw(iw.i16dp, lmcfi | 0x04);
3527 else if (bank[0] == 256 && bank[1] == 256 && bank[2] == 1024 && bank[3] == 0)
3528 outw(iw.i16dp, lmcfi | 0x05);
3529 else if (bank[0] == 256 && bank[1] == 256 && bank[2] == 1024 && bank[3] == 1024)
3530 outw(iw.i16dp, lmcfi | 0x06);
3531 else if (bank[0] == 1024 && bank[1] == 0 && bank[2] == 0 && bank[3] == 0)
3532 outw(iw.i16dp, lmcfi | 0x07);
3533 else if (bank[0] == 1024 && bank[1] == 1024 && bank[2] == 0 && bank[3] == 0)
3534 outw(iw.i16dp, lmcfi | 0x08);
3535 else if (bank[0] == 1024 && bank[1] == 1024 && bank[2] == 1024 && bank[3] == 1024)
3536 outw(iw.i16dp, lmcfi | 0x09);
3537 else if (bank[0] == 4096 && bank[1] == 0 && bank[2] == 0 && bank[3] == 0)
3538 outw(iw.i16dp, lmcfi | 0x0A);
3539 else if (bank[0] == 4096 && bank[1] == 4096 && bank[2] == 0 && bank[3] == 0)
3540 outw(iw.i16dp, lmcfi | 0x0B);
3541 else /* Flag the non-contiguous config of memory */
3542 iw.flags |= DRAM_HOLES;
3544 outb(iw.igidxr, 0x19); /* restore sgmi */
3550 /* ######################################################################## */
3552 /* FUNCTION: IwaveCodecIrq */
3554 /* PROFILE: This function disables or enables the Codec Interrupts. To */
3555 /* enable interrupts set CEXTI[2] high thus causing all interrupt */
3556 /* sources (CSR3I[6:4]) to pass onto the IRQ pin. To disable */
3557 /* interrupts set CEXTI[1]=0. To enable Code IRQs issue this call: */
3559 /* IwaveCodecIrq(CODEC_IRQ_ENABLE). To disable IRQs issue the call */
3561 /* IwaveCodeIrq(~CODEC_IRQ_ENABLE). */
3563 /* ######################################################################## */
3565 IwaveCodecIrq(BYTE mode)
3570 reg = inb(iw.pcodar) & 0xE0;
3571 outb(iw.pcodar, reg | _CSR3I); /* select CSR3I */
3572 outb(iw.cdatap, 0x00); /* clear all interrupts */
3573 outb(iw.pcodar + 0x02, 0x00); /* clear CSR1R */
3574 outb(iw.pcodar, reg | _CEXTI); /* select CEXTI */
3575 reg = inb(iw.cdatap);
3576 if (mode == CODEC_IRQ_ENABLE) /* enable Codec Irqs */
3577 outb(iw.cdatap, (BYTE) (reg | CODEC_IRQ_ENABLE));
3578 else /* disable Codec Irqs */
3579 outb(iw.cdatap, (BYTE) (reg & ~CODEC_IRQ_ENABLE));
3584 /* ######################################################################### */
3586 /* FUNCTION: IwaveRegPeek */
3588 /* PROFILE : This function returns the value stored in any readable */
3589 /* InterWave register. It takes as input a pointer to a */
3590 /* structure containing the addresses of the relocatable I/O */
3591 /* space as well as a register mnemonic. To correctly use this */
3592 /* function, the programmer must use the mnemonics defined in */
3593 /* "iwdefs.h". These mnemonics contain coded information used */
3594 /* by the function to properly access the desired register. */
3596 /* An attempt to read from a write-only register will return */
3597 /* meaningless data. */
3599 /* ######################################################################### */
3601 IwaveRegPeek(DWORD reg_mnem)
3604 WORD reg_id, offset;
3606 offset = (WORD) ((BYTE) reg_mnem);
3607 reg_id = (WORD) (reg_mnem >> 16);
3608 index = (BYTE) (reg_mnem >> 8);
3610 /* ################################################### */
3611 /* Logic to read registers in P2XR block & GMCR */
3612 /* ################################################### */
3614 if (reg_id >= 0x0001 && reg_id <= 0x001A) { /* UMCR to GMCR */
3615 if (reg_id <= 0x000E) /* UMCR to USRR */
3616 return ((WORD) inb(iw.p2xr + offset));
3618 if (reg_id == 0x0019)
3619 return ((WORD) inb(iw.p201ar));
3621 else { /* GUS Hidden registers or GMCR */
3624 outb(iw.igidxr, 0x5B); /* select IVERI */
3625 iveri = inb(iw.i8dp); /* read IVERI */
3626 outb(iw.i8dp, (BYTE) (iveri | 0x09)); /* set IVERI[3,0] */
3627 if (reg_id == 0x001A) { /* GMCR */
3629 outb(iw.i8dp, iveri); /* restore IVERI */
3630 return ((WORD) val);
3632 val = inb(iw.p2xr + 0x0F); /* read URCR */
3633 val = (val & 0xF8) | index; /* value for URCR[2:0] */
3634 outb(iw.p2xr + 0x0F, val); /* set URCR[2:0] */
3636 if (reg_mnem == UDCI || reg_mnem == UICI) {
3638 if (reg_mnem == UDCI)
3639 outb(iw.p2xr, (BYTE) (val & 0xBF));
3641 outb(iw.p2xr, (BYTE) (val | 0x40));
3643 val = inb(iw.p2xr + 0x0B);
3644 outb(iw.igidxr, 0x5B); /* select IVERI */
3645 outb(iw.i8dp, iveri); /* restore IVERI */
3646 return ((WORD) val); /* read register */
3649 /* ################################################### */
3650 /* Logic to read registers in P3XR block */
3651 /* ################################################### */
3653 if (reg_id >= 0x001B && reg_id <= 0x005C) { /* GMSR to LMBDR */
3654 if (reg_id == 0x005C) /* LMBDR */
3655 return ((WORD) inb(iw.lmbdr));
3657 if (reg_id >= 0x001B && reg_id <= 0x0021) /* GMSR to I8DP */
3659 return (inw(iw.i16dp));
3661 return ((WORD) inb(iw.p3xr + offset));
3662 else { /* indexed registers */
3664 if (reg_id <= 0x003F)
3665 index |= 0x80; /* adjust for reading */
3667 outb(iw.igidxr, index); /* select register */
3670 return (inw(iw.i16dp));
3672 return ((WORD) inb(iw.i8dp));
3675 /* #################################################### */
3676 /* Logic to read registers in PCODAR block */
3677 /* #################################################### */
3679 if (reg_id >= 0x005D && reg_id <= 0x0081) { /* CIDXR to CLRCTI */
3680 if (reg_id <= 0x0061)
3681 return ((WORD) inb(iw.pcodar + offset)); /* CRDR */
3683 else { /* indexed registers */
3686 cidxr = inb(iw.pcodar);
3687 cidxr = (cidxr & 0xE0) + index;
3688 outb(iw.pcodar, cidxr); /* select register */
3689 return ((WORD) inb(iw.cdatap));
3692 /* ##################################################### */
3693 /* Logic to read the PnP registers */
3694 /* ##################################################### */
3695 if (reg_id >= 0x0082 && reg_id <= 0x00B7) { /* PCSNBR to PMITI */
3696 if (reg_id == 0x0085)
3697 return ((WORD) inb(iw.pnprdp));
3699 if (reg_id < 0x0085)
3700 return ((WORD) inb((WORD) reg_mnem));
3702 else { /* indexed registers */
3703 if (reg_id >= 0x008E && reg_id <= 0x00B7) {
3704 outb(0x0279, 0x07); /* select PLDNI */
3705 outb(0xA79, (BYTE) offset); /* select logical dev */
3707 outb(0x0279, index); /* select the register */
3708 return ((WORD) inb(iw.pnprdp));
3713 /* ######################################################################### */
3715 /* FUNCTION: IwaveRegPoke */
3717 /* PROFILE : This function writes a value to any writable */
3718 /* InterWave register. It takes as input a pointer to a */
3719 /* structure containing the addresses of the relocatable I/O */
3720 /* space as well as a register mnemonic. To correctly use this */
3721 /* function, the programmer must use the mnemonics defined in */
3722 /* "iwdefs.h". These mnemonics contain coded information used */
3723 /* by the function to properly access the desired register. */
3725 /* This function does not guard against writing to read-only */
3726 /* registers. It is the programmer's responsibility to ensure */
3727 /* that the writes are to valid registers. */
3729 /* ######################################################################### */
3731 IwaveRegPoke(DWORD reg_mnem, WORD datum)
3738 offset = (WORD) ((BYTE) reg_mnem);
3739 reg_id = (WORD) (reg_mnem >> 16);
3740 index = (BYTE) (reg_mnem >> 8);
3743 /* ####################################################### */
3744 /* Logic to write to registers in P2XR block */
3745 /* ####################################################### */
3746 if (reg_id >= 0x0001 && reg_id <= 0x0019) { /* UMCR to GGCR */
3747 if (reg_id <= 0x000E) { /* UMCR to USRR */
3748 outb(iw.p2xr + offset, (BYTE) datum);
3751 if (reg_id == 0x0019) {
3752 outb(iw.p201ar, (BYTE) datum);
3754 } else { /* GUS Hidden registers */
3758 outb(iw.igidxr, 0x5B); /* select IVERI */
3759 iveri = inb(iw.i8dp); /* read IVERI */
3760 outb(iw.i8dp, (BYTE) (iveri | 0x09)); /* set IVERI[3,0] */
3761 val = inb(iw.p2xr + 0x0F); /* read URCR */
3762 val = (val & 0xF8) | index; /* value for URCR[2:0] */
3763 outb(iw.p2xr + 0x0F, val); /* set URCR[2:0] */
3765 if (reg_mnem == UDCI || reg_mnem == UICI) {
3766 val = inb(iw.p2xr); /* read UMCR */
3767 if (reg_mnem == UDCI)
3768 outb(iw.p2xr, (BYTE) (val & 0xBF)); /* set UMCR[6]=0 */
3770 outb(iw.p2xr, (BYTE) (val | 0x40)); /* set UMCR[6]=1 */
3772 outb(iw.p2xr + 0x0B, (BYTE) datum); /* write register */
3773 outb(iw.igidxr, 0x5B); /* select IVERI */
3774 outb(iw.i8dp, iveri); /* restore IVERI */
3778 /* ############################################################# */
3779 /* Logic to write to registers in P3XR block */
3780 /* ############################################################# */
3782 if (reg_id >= 0x001A && reg_id <= 0x005C) { /* GMCR to LMBDR */
3784 if (reg_id == 0x005C) { /* LMBDR */
3785 outb(iw.lmbdr, (BYTE) datum);
3788 if (reg_id == 0x001B) /* GMSR */
3791 if (reg_id >= 0x001A && reg_id <= 0x0021) /* GMCR to I8DP */
3793 outw(iw.i16dp, datum);
3795 outb(iw.p3xr + offset, (BYTE) datum);
3796 else { /* indexed registers */
3797 outb(iw.igidxr, index); /* select register */
3800 outw(iw.i16dp, datum);
3802 outb(iw.i8dp, (BYTE) datum);
3805 /* /################################################### */
3806 /* Logic to write to registers in PCODAR block */
3807 /* ################################################### */
3809 if (reg_id >= 0x005C && reg_id <= 0x0081) { /* CIDXR to CLRCTI */
3810 if (reg_id <= 0x0061)
3811 outb(iw.pcodar + offset, (BYTE) datum);
3813 else { /* one of the indexed registers */
3816 cidxr = inb(iw.pcodar);
3817 cidxr = (cidxr & 0xE0) + index;
3818 outb(iw.pcodar, cidxr); /* select register */
3819 outb(iw.cdatap, (BYTE) datum);
3822 /* ###################################################### */
3823 /* Logic to write to the PnP registers */
3824 /* ###################################################### */
3825 if (reg_id >= 0x0082 && reg_id <= 0x00B7) {
3826 if (reg_id == 0x0085) {
3827 outb(iw.pnprdp, (BYTE) datum);
3830 if (reg_id < 0x0085)
3831 outb((WORD) reg_mnem, (BYTE) datum);
3833 else { /* one of the indexed registers */
3834 if (reg_id >= 0x008E && reg_id <= 0x00B7) {
3835 outb(0x0279, 0x07); /* select PLDNI */
3836 outb(0xA79, (BYTE) offset); /* select logical dev */
3838 outb(0x0279, index); /* select the register */
3839 outb(0xA79, (BYTE) datum);
3846 IwaveLineLevel(char level, char index)
3853 reg = inb(iw.pcodar) & 0xE0;
3854 outb(iw.pcodar, reg | index); /* select register */
3855 outb(iw.cdatap, (BYTE) ((inb(iw.cdatap) & 0x80) | level)); /* set level */
3860 IwaveCodecMode(char mode)
3865 reg = inb(iw.pcodar) & 0xE0;
3866 outb(iw.pcodar, reg | _CMODEI); /* select CMODEI */
3867 outb(iw.cdatap, mode);
3873 IwaveLineMute(BYTE mute, BYTE inx)
3878 reg = inb(iw.pcodar) & 0xE0;
3879 outb(iw.pcodar, reg | inx); /* select register */
3881 outb(iw.cdatap, (BYTE) (inb(iw.cdatap) | 0x80)); /* mute */
3883 outb(iw.cdatap, (BYTE) (inb(iw.cdatap) & 0x7F)); /* unmute */
3891 u_short iwl_codec_base = iw.pcodar;
3892 u_short iwl_codec_data = iw.pcodar + 1;
3898 * Set the CEXTI register foo = CODEC_CEXTI_DEFAULT;
3899 * IWL_CODEC_OUT(EXTERNAL_CONTROL, foo);
3902 * Disable Interrupts iwl_codec_disable_irqs();
3905 /* Set the CODEC to Operate in Mode 3 */
3906 IWL_CODEC_OUT(MODE_SELECT_ID, 0x6C);
3907 foo = inb(iwl_codec_data);
3909 /* Set the configuration registers to their default values */
3910 foo = CODEC_CFIG1I_DEFAULT;
3911 IWL_CODEC_OUT(CONFIG_1 | CODEC_MCE, foo);
3912 outb(iwl_codec_base, CONFIG_1);
3913 foo = CODEC_CFIG2I_DEFAULT;
3914 IWL_CODEC_OUT(CONFIG_2, foo);
3916 foo = CODEC_CFIG3I_DEFAULT;
3917 IWL_CODEC_OUT(CONFIG_3, foo);
3924 IwaveOpen(char voices, char mode, struct address_info * hw)
3933 if (IwavePnpIsol(&iw.pnprdp)) {
3935 iw.vendor = GUS_PNP_ID;
3937 iw.csn = IwavePnpPing(iw.vendor);
3941 IwavePnpWake(iw.csn);
3946 IwavePnpWake(iw.csn);
3949 /* I see the user wants to set the GUS PnP */
3950 /* Okay lets do it */
3952 iw.p2xr = hw->io_base;
3953 iw.p3xr = hw->io_base + 0x100;
3954 iw.pcodar = hw->io_base + 0x10c;
3956 iw.synth_irq = hw->irq;
3958 iw.midi_irq = hw->irq;
3960 iw.dma1_chan = hw->dma;
3962 if (hw->dma2 == -1) {
3963 iw.dma2_chan = hw->dma;
3965 iw.dma2_chan = hw->dma2;
3971 /* tell the os what we are doing 8) */
3972 hw->io_base = iw.p2xr;
3973 hw->irq = iw.synth_irq;
3975 * iw.dma1_chan = 1; iw.dma2_chan = 3 ;
3977 hw->dma = iw.dma1_chan;
3978 hw->dma2 = iw.dma2_chan;
3983 if (iw.csn > 0 && iw.csn < MAX_GUS_PNP) {
3984 gus_pnp_found[iw.csn] = hw->io_base;
3987 iw.cdatap = iw.pcodar + 1;
3988 iw.csr1r = iw.pcodar + 2;
3989 iw.cxdr = iw.pcodar + 3;/* CPDR or CRDR */
3991 iw.gmxdr = iw.p3xr + 1; /* GMTDR or GMRDR */
3992 iw.svsr = iw.p3xr + 2;
3993 iw.igidxr = iw.p3xr + 3;
3994 iw.i16dp = iw.p3xr + 4;
3995 iw.i8dp = iw.p3xr + 5;
3996 iw.lmbdr = iw.p3xr + 7;
3999 if (iw.pnprdp > 0 && iw.csn > 0) {
4001 IwavePnpActivate(AUDIO, ON);
4002 IwavePnpActivate(EXT, ON);
4004 /* IwavePnpActivate(EMULATION,ON); */
4008 outb(iw.igidxr, _URSTI);/* Pull reset */
4009 outb(iw.i8dp, 0x00);
4012 outb(iw.i8dp, 0x01); /* Release reset */
4021 tmp = IwaveRegPeek(IDECI);
4023 IwaveRegPoke(IDECI, tmp | 0x18);
4025 IwaveCodecMode(CODEC_MODE2); /* Default codec mode */
4026 IwaveRegPoke(ICMPTI, 0);
4028 outb(iw.igidxr, 0x99);
4030 outb(iw.igidxr, 0x19);
4035 IwaveCodecIrq(~CODEC_IRQ_ENABLE);
4039 outb(iw.p2xr, 0x0c); /* Disable line in, mic and line out */
4041 IwaveRegPoke(CLCI, 0x3f << 2);
4043 IwaveLineLevel(0, _CLOAI);
4044 IwaveLineLevel(0, _CROAI);
4046 IwaveLineMute(OFF, _CLOAI);
4047 IwaveLineMute(OFF, _CROAI);
4049 IwaveLineLevel(0, _CLLICI);
4050 IwaveLineLevel(0, _CRLICI);
4051 IwaveLineMute(OFF, _CLLICI);
4052 IwaveLineMute(OFF, _CRLICI);
4054 IwaveLineLevel(0, _CLDACI);
4055 IwaveLineLevel(0, _CRDACI);
4056 IwaveLineMute(ON, _CLDACI);
4057 IwaveLineMute(ON, _CRDACI);
4059 IwaveLineLevel(0, _CLLICI);
4060 IwaveLineLevel(0, _CRLICI);
4061 IwaveLineMute(ON, _CLLICI);
4062 IwaveLineMute(ON, _CRLICI);
4065 IwaveInputSource(LEFT_SOURCE, MIC_IN);
4066 IwaveInputSource(RIGHT_SOURCE, MIC_IN);
4068 outb(iw.pcodar, 0x9 | 0x40);
4070 IwaveCodecIrq(CODEC_IRQ_ENABLE);
4071 outb(iw.pcodar, _CFIG3I | 0x20);
4074 outb(iw.cdatap, 0xC2); /* Enable Mode 3 IRQs & Synth */
4076 outb(iw.igidxr, _URSTI);
4077 outb(iw.i8dp, GF1_SET | GF1_OUT_ENABLE | GF1_IRQ_ENABLE);
4079 iw.size_mem = IwaveMemSize(); /* Bytes of RAM in this mode */
4080 outb(iw.p2xr, 0xc); /* enable output */
4081 IwaveRegPoke(CLCI, 0x3f << 2);
4083 IwaveCodecIrq(CODEC_IRQ_ENABLE);
4087 IwaveRegPoke(CPDFI, 0);
4094 gus_wave_init(struct address_info * hw_config)
4097 u_char val, gus_pnp_seen = 0;
4098 char *model_num = "2.4";
4099 int gus_type = 0x24; /* 2.4 */
4100 int irq = hw_config->irq, dma = hw_config->dma, dma2 = hw_config->dma2;
4101 int otherside = -1, i;
4103 if (irq < 0 || irq > 15) {
4104 printf("ERROR! Invalid IRQ#%d. GUS Disabled", irq);
4107 if (dma < 0 || dma > 7) {
4108 printf("ERROR! Invalid DMA#%d. GUS Disabled", dma);
4111 for (i = 0; i < MAX_GUS_PNP; i++) {
4112 if (gus_pnp_found[i] != 0 && gus_pnp_found[i] == hw_config->io_base)
4127 * Try to identify the GUS model.
4129 * Versions < 3.6 don't have the digital ASIC. Try to probe it first.
4133 outb(gus_base + 0x0f, 0x20);
4134 val = inb(gus_base + 0x0f);
4137 if (val != 0xff && (val & 0x06)) { /* Should be 0x02?? */
4139 * It has the digital ASIC so the card is at least v3.4. Next
4140 * try to detect the true model.
4143 val = inb(u_MixSelect);
4146 * Value 255 means pre-3.7 which don't have mixer. Values 5
4147 * thru 9 mean v3.7 which has a ICS2101 mixer. 10 and above
4148 * is GUS MAX which has the CS4231 codec/mixer.
4155 if (val == 255 || val < 5) {
4158 } else if (val < 10) {
4161 mixer_type = ICS2101;
4169 mixer_type = CS4231;
4170 #ifdef CONFIG_GUSMAX
4172 u_char max_config = 0x40; /* Codec enable */
4178 max_config |= 0x10; /* 16 bit capture DMA */
4181 max_config |= 0x20; /* 16 bit playback DMA */
4183 max_config |= (gus_base >> 4) & 0x0f; /* Extract the X from
4186 outb(gus_base + 0x106, max_config); /* UltraMax control */
4189 if (ad1848_detect(gus_base + 0x10c, NULL, hw_config->osp)) {
4191 gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
4192 gus_wave_volume = 90;
4196 ad1848_init("GUS PNP", gus_base + 0x10c,
4198 gus_dma2, /* Playback DMA */
4199 gus_dma, /* Capture DMA */
4200 1, /* Share DMA channels with GF1 */
4205 ad1848_init("GUS MAX", gus_base + 0x10c,
4207 gus_dma2, /* Playback DMA */
4208 gus_dma, /* Capture DMA */
4209 1, /* Share DMA channels with GF1 */
4212 otherside = num_audiodevs - 1;
4215 printf("[Where's the CS4231?]");
4217 printf("\n\n\nGUS MAX support was not compiled in!!!\n\n\n\n");
4222 * ASIC not detected so the card must be 2.2 or 2.4. There
4223 * could still be the 16-bit/mixer daughter card.
4228 snprintf(gus_info.name, sizeof(gus_info.name),
4229 "Gravis %s (%dk)", model_num, (int) gus_mem_size / 1024);
4231 snprintf(gus_info.name, sizeof(gus_info.name),
4232 "Gravis UltraSound %s (%dk)", model_num, (int) gus_mem_size / 1024);
4234 conf_printf(gus_info.name, hw_config);
4236 if (num_synths >= MAX_SYNTH_DEV)
4237 printf("GUS Error: Too many synthesizers\n");
4239 voice_alloc = &guswave_operations.alloc;
4240 synth_devs[num_synths++] = &guswave_operations;
4241 #ifdef CONFIG_SEQUENCER
4242 gus_tmr_install(gus_base + 8);
4245 samples = (struct patch_info *) malloc((MAX_SAMPLE + 1) * sizeof(*samples), M_DEVBUF, M_NOWAIT);
4247 panic("SOUND: Cannot allocate memory\n");
4249 reset_sample_memory();
4253 if (num_audiodevs < MAX_AUDIO_DEV) {
4254 audio_devs[gus_devnum = num_audiodevs++] = &gus_sampling_operations;
4255 audio_devs[gus_devnum]->otherside = otherside;
4256 audio_devs[gus_devnum]->dmachan1 = dma;
4257 audio_devs[gus_devnum]->dmachan2 = dma2;
4258 audio_devs[gus_devnum]->buffsize = DSP_BUFFSIZE;
4259 if (otherside != -1) {
4261 * glue logic to prevent people from opening the gus
4262 * max via the gf1 and the cs4231 side . Only the gf1
4263 * or the cs4231 are allowed to be open
4266 audio_devs[otherside]->otherside = gus_devnum;
4268 if (dma2 != dma && dma2 != -1)
4269 audio_devs[gus_devnum]->flags |= DMA_DUPLEX;
4271 printf("GUS: Too many PCM devices available\n");
4274 * Mixer dependent initialization.
4277 switch (mixer_type) {
4279 gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
4280 gus_wave_volume = 90;
4281 ics2101_mixer_init();
4285 /* Initialized elsewhere (ad1848.c) */
4287 gus_default_mixer_init();
4293 do_loop_irq(int voice)
4300 gus_select_voice(voice);
4302 tmp = gus_read8(0x00);
4303 tmp &= ~0x20; /* Disable wave IRQ for this_one voice */
4304 gus_write8(0x00, tmp);
4306 if (tmp & 0x03) /* Voice stopped */
4307 voice_alloc->map[voice] = 0;
4309 mode = voices[voice].loop_irq_mode;
4310 voices[voice].loop_irq_mode = 0;
4311 parm = voices[voice].loop_irq_parm;
4315 case LMODE_FINISH: /* Final loop finished, shoot volume down */
4317 if ((int) (gus_read16(0x09) >> 4) < 100) { /* Get current volume */
4320 gus_voice_init(voice);
4323 gus_ramp_range(65, 4065);
4324 gus_ramp_rate(0, 63); /* Fastest possible rate */
4325 gus_rampon(0x20 | 0x40); /* Ramp down, once, irq */
4326 voices[voice].volume_irq_mode = VMODE_HALT;
4329 case LMODE_PCM_STOP:
4330 pcm_active = 0; /* Signal to the play_next_pcm_block routine */
4333 int flag; /* 0 or 2 */
4336 pcm_head = (pcm_head + 1) % pcm_nblk;
4337 if (pcm_qlen && pcm_active) {
4338 play_next_pcm_block();
4339 } else {/* Underrun. Just stop the voice */
4340 gus_select_voice(0); /* Left channel */
4343 gus_select_voice(1); /* Right channel */
4350 * If the queue was full before this interrupt, the
4351 * DMA transfer was suspended. Let it continue now.
4355 flag = 1; /* Underflow */
4360 flag = 2; /* Just notify the dmabuf.c */
4361 DMAbuf_outputintr(gus_devnum, flag);
4371 do_volume_irq(int voice)
4379 gus_select_voice(voice);
4381 tmp = gus_read8(0x0d);
4382 tmp &= ~0x20; /* Disable volume ramp IRQ */
4383 gus_write8(0x0d, tmp);
4385 mode = voices[voice].volume_irq_mode;
4386 voices[voice].volume_irq_mode = 0;
4387 parm = voices[voice].volume_irq_parm;
4390 case VMODE_HALT: /* Decay phase finished */
4392 gus_voice_init(voice);
4395 case VMODE_ENVELOPE:
4398 step_envelope(voice);
4401 case VMODE_START_NOTE:
4403 guswave_start_note2(voices[voice].dev_pending, voice,
4404 voices[voice].note_pending, voices[voice].volume_pending);
4405 if (voices[voice].kill_pending)
4406 guswave_kill_note(voices[voice].dev_pending, voice,
4407 voices[voice].note_pending, 0);
4409 if (voices[voice].sample_pending >= 0) {
4410 guswave_set_instr(voices[voice].dev_pending, voice,
4411 voices[voice].sample_pending);
4412 voices[voice].sample_pending = -1;
4423 u_long wave_ignore = 0, volume_ignore = 0;
4429 src = gus_read8(0x0f); /* Get source info */
4433 if (src == (0x80 | 0x40))
4434 return; /* No interrupt */
4436 voice_bit = 1 << voice;
4438 if (!(src & 0x80)) /* Wave IRQ pending */
4439 if (!(wave_ignore & voice_bit) && (int) voice < nr_voices) { /* Not done yet */
4440 wave_ignore |= voice_bit;
4443 if (!(src & 0x40)) /* Volume IRQ pending */
4444 if (!(volume_ignore & voice_bit) && (int) voice < nr_voices) { /* Not done yet */
4445 volume_ignore |= voice_bit;
4446 do_volume_irq(voice);
4452 guswave_dma_irq(void)
4456 status = gus_look8(0x41); /* Get DMA IRQ Status */
4457 if (status & 0x40) /* DMA interrupt pending */
4458 switch (active_device) {
4460 if ((dram_sleep_flag.mode & WK_SLEEP)) {
4461 dram_sleep_flag.mode = WK_WAKEUP;
4462 wakeup(dram_sleeper);
4466 case GUS_DEV_PCM_CONTINUE: /* Left channel data transferred */
4467 gus_transfer_output_block(pcm_current_dev, pcm_current_buf,
4468 pcm_current_count, pcm_current_intrflag, 1);
4471 case GUS_DEV_PCM_DONE: /* Right or mono channel data transferred */
4472 if (pcm_qlen < pcm_nblk) {
4473 int flag = (1 - dma_active) * 2; /* 0 or 2 */
4476 flag = 1; /* Underrun */
4478 DMAbuf_outputintr(gus_devnum, flag);
4485 status = gus_look8(0x49); /* Get Sampling IRQ Status */
4486 if (status & 0x40) { /* Sampling Irq pending */
4487 DMAbuf_inputintr(gus_devnum);
4491 #ifdef CONFIG_SEQUENCER
4496 static volatile int select_addr, data_addr;
4497 static volatile int curr_timer = 0;
4500 gus_timer_command(u_int addr, u_int val)
4504 outb(select_addr, (u_char) (addr & 0xff));
4506 for (i = 0; i < 2; i++)
4509 outb(data_addr, (u_char) (val & 0xff));
4511 for (i = 0; i < 2; i++)
4516 arm_timer(int timer, u_int interval)
4521 gus_write8(0x46, 256 - interval); /* Set counter for timer 1 */
4522 gus_write8(0x45, 0x04); /* Enable timer 1 IRQ */
4523 gus_timer_command(0x04, 0x01); /* Start timer 1 */
4525 gus_write8(0x47, 256 - interval); /* Set counter for timer 2 */
4526 gus_write8(0x45, 0x08); /* Enable timer 2 IRQ */
4527 gus_timer_command(0x04, 0x02); /* Start timer 2 */
4530 gus_timer_enabled = 0;
4534 gus_tmr_start(int dev, u_int usecs_per_tick)
4536 int timer_no, resolution;
4539 if (usecs_per_tick > (256 * 80)) {
4541 resolution = 320; /* usec */
4544 resolution = 80;/* usec */
4547 divisor = (usecs_per_tick + (resolution / 2)) / resolution;
4549 arm_timer(timer_no, divisor);
4551 return divisor * resolution;
4555 gus_tmr_disable(int dev)
4557 gus_write8(0x45, 0); /* Disable both timers */
4558 gus_timer_enabled = 0;
4562 gus_tmr_restart(int dev)
4564 if (curr_timer == 1)
4565 gus_write8(0x45, 0x04); /* Start timer 1 again */
4567 gus_write8(0x45, 0x08); /* Start timer 2 again */
4570 static struct sound_lowlev_timer gus_tmr =
4579 gus_tmr_install(int io_base)
4581 select_addr = io_base;
4582 data_addr = io_base + 1;
4584 sound_timer_init(&gus_tmr, "GUS");