Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <sound/gus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) extern int snd_gf1_synth_init(struct snd_gus_card * gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) extern void snd_gf1_synth_done(struct snd_gus_card * gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *  ok.. default interrupt handlers...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) static void snd_gf1_default_interrupt_handler_midi_out(struct snd_gus_card * gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd &= ~0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) static void snd_gf1_default_interrupt_handler_midi_in(struct snd_gus_card * gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd &= ~0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) static void snd_gf1_default_interrupt_handler_timer1(struct snd_gus_card * gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, gus->gf1.timer_enabled &= ~4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) static void snd_gf1_default_interrupt_handler_timer2(struct snd_gus_card * gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, gus->gf1.timer_enabled &= ~8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static void snd_gf1_default_interrupt_handler_wave_and_volume(struct snd_gus_card * gus, struct snd_gus_voice * voice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	snd_gf1_i_ctrl_stop(gus, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	snd_gf1_i_ctrl_stop(gus, 0x0d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) static void snd_gf1_default_interrupt_handler_dma_write(struct snd_gus_card * gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	snd_gf1_i_write8(gus, 0x41, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static void snd_gf1_default_interrupt_handler_dma_read(struct snd_gus_card * gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	snd_gf1_i_write8(gus, 0x49, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) void snd_gf1_set_default_handlers(struct snd_gus_card * gus, unsigned int what)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	if (what & SNDRV_GF1_HANDLER_MIDI_OUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		gus->gf1.interrupt_handler_midi_out = snd_gf1_default_interrupt_handler_midi_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	if (what & SNDRV_GF1_HANDLER_MIDI_IN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		gus->gf1.interrupt_handler_midi_in = snd_gf1_default_interrupt_handler_midi_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	if (what & SNDRV_GF1_HANDLER_TIMER1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		gus->gf1.interrupt_handler_timer1 = snd_gf1_default_interrupt_handler_timer1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	if (what & SNDRV_GF1_HANDLER_TIMER2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		gus->gf1.interrupt_handler_timer2 = snd_gf1_default_interrupt_handler_timer2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	if (what & SNDRV_GF1_HANDLER_VOICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		struct snd_gus_voice *voice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		voice = &gus->gf1.voices[what & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		voice->handler_wave =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		voice->handler_volume = snd_gf1_default_interrupt_handler_wave_and_volume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		voice->handler_effect = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		voice->volume_change = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	if (what & SNDRV_GF1_HANDLER_DMA_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		gus->gf1.interrupt_handler_dma_write = snd_gf1_default_interrupt_handler_dma_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	if (what & SNDRV_GF1_HANDLER_DMA_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		gus->gf1.interrupt_handler_dma_read = snd_gf1_default_interrupt_handler_dma_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) static void snd_gf1_clear_regs(struct snd_gus_card * gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	spin_lock_irqsave(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	inb(GUSP(gus, IRQSTAT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	snd_gf1_write8(gus, 0x41, 0);	/* DRAM DMA Control Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	snd_gf1_write8(gus, 0x45, 0);	/* Timer Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	snd_gf1_write8(gus, 0x49, 0);	/* Sampling Control Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	spin_unlock_irqrestore(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) static void snd_gf1_look_regs(struct snd_gus_card * gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	spin_lock_irqsave(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	snd_gf1_look8(gus, 0x41);	/* DRAM DMA Control Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	snd_gf1_look8(gus, 0x49);	/* Sampling Control Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	inb(GUSP(gus, IRQSTAT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	snd_gf1_read8(gus, 0x0f);	/* IRQ Source Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	spin_unlock_irqrestore(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  *  put selected GF1 voices to initial stage...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) void snd_gf1_smart_stop_voice(struct snd_gus_card * gus, unsigned short voice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	spin_lock_irqsave(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	snd_gf1_select_voice(gus, voice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	printk(KERN_DEBUG " -%i- smart stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	spin_unlock_irqrestore(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) void snd_gf1_stop_voice(struct snd_gus_card * gus, unsigned short voice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	spin_lock_irqsave(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	snd_gf1_select_voice(gus, voice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	printk(KERN_DEBUG " -%i- stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	if (gus->gf1.enh_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		snd_gf1_write8(gus, SNDRV_GF1_VB_ACCUMULATOR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	spin_unlock_irqrestore(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	snd_gf1_lfo_shutdown(gus, voice, ULTRA_LFO_VIBRATO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	snd_gf1_lfo_shutdown(gus, voice, ULTRA_LFO_TREMOLO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static void snd_gf1_clear_voices(struct snd_gus_card * gus, unsigned short v_min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 				 unsigned short v_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	unsigned int daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	unsigned short i, w_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	daddr = gus->gf1.default_voice_address << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	for (i = v_min; i <= v_max; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		if (gus->gf1.syn_voices)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			gus->gf1.syn_voices[i].flags = ~VFLG_DYNAMIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		spin_lock_irqsave(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		snd_gf1_select_voice(gus, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);	/* Voice Control Register = voice stop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);	/* Volume Ramp Control Register = ramp off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		if (gus->gf1.enh_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			snd_gf1_write8(gus, SNDRV_GF1_VB_MODE, gus->gf1.memory ? 0x02 : 0x82);	/* Deactivate voice */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		w_16 = snd_gf1_read8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL) & 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		snd_gf1_write16(gus, SNDRV_GF1_VW_FREQUENCY, 0x400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		snd_gf1_write_addr(gus, SNDRV_GF1_VA_START, daddr, w_16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		snd_gf1_write_addr(gus, SNDRV_GF1_VA_END, daddr, w_16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_START, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_END, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_RATE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		snd_gf1_write_addr(gus, SNDRV_GF1_VA_CURRENT, daddr, w_16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		snd_gf1_write8(gus, SNDRV_GF1_VB_PAN, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		if (gus->gf1.enh_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			snd_gf1_write8(gus, SNDRV_GF1_VB_ACCUMULATOR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			snd_gf1_write16(gus, SNDRV_GF1_VW_EFFECT_VOLUME, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			snd_gf1_write16(gus, SNDRV_GF1_VW_EFFECT_VOLUME_FINAL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		spin_unlock_irqrestore(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		snd_gf1_lfo_shutdown(gus, i, ULTRA_LFO_VIBRATO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		snd_gf1_lfo_shutdown(gus, i, ULTRA_LFO_TREMOLO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) void snd_gf1_stop_voices(struct snd_gus_card * gus, unsigned short v_min, unsigned short v_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	short i, ramp_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	unsigned short ramp_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	if (!in_interrupt()) {	/* this can't be done in interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		for (i = v_min, ramp_ok = 0; i <= v_max; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 			spin_lock_irqsave(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 			snd_gf1_select_voice(gus, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			ramp_end = snd_gf1_read16(gus, 9) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 			if (ramp_end > SNDRV_GF1_MIN_OFFSET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 				ramp_ok++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 				snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_RATE, 20);	/* ramp rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 				snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_START, SNDRV_GF1_MIN_OFFSET);	/* ramp start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 				snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_END, ramp_end);	/* ramp end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 				snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, 0x40);	/* ramp down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 				if (gus->gf1.enh_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 					snd_gf1_delay(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 					snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 			spin_unlock_irqrestore(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		msleep_interruptible(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	snd_gf1_clear_voices(gus, v_min, v_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static void snd_gf1_alloc_voice_use(struct snd_gus_card * gus, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 				    struct snd_gus_voice * pvoice,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 				    int type, int client, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	pvoice->use = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	case SNDRV_GF1_VOICE_TYPE_PCM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		gus->gf1.pcm_alloc_voices++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		pvoice->pcm = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	case SNDRV_GF1_VOICE_TYPE_SYNTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		pvoice->synth = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		pvoice->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		pvoice->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	case SNDRV_GF1_VOICE_TYPE_MIDI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		pvoice->midi = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		pvoice->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		pvoice->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct snd_gus_voice *snd_gf1_alloc_voice(struct snd_gus_card * gus, int type, int client, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	struct snd_gus_voice *pvoice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	spin_lock_irqsave(&gus->voice_alloc, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	if (type == SNDRV_GF1_VOICE_TYPE_PCM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		if (gus->gf1.pcm_alloc_voices >= gus->gf1.pcm_channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 			spin_unlock_irqrestore(&gus->voice_alloc, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	for (idx = 0; idx < 32; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		pvoice = &gus->gf1.voices[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		if (!pvoice->use) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 			snd_gf1_alloc_voice_use(gus, pvoice, type, client, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 			spin_unlock_irqrestore(&gus->voice_alloc, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 			return pvoice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	} 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	for (idx = 0; idx < 32; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		pvoice = &gus->gf1.voices[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		if (pvoice->midi && !pvoice->client) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			snd_gf1_clear_voices(gus, pvoice->number, pvoice->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			snd_gf1_alloc_voice_use(gus, pvoice, type, client, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			spin_unlock_irqrestore(&gus->voice_alloc, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 			return pvoice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	} 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	spin_unlock_irqrestore(&gus->voice_alloc, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) void snd_gf1_free_voice(struct snd_gus_card * gus, struct snd_gus_voice *voice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	void (*private_free)(struct snd_gus_voice *voice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	if (voice == NULL || !voice->use)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_VOICE | voice->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	snd_gf1_clear_voices(gus, voice->number, voice->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	spin_lock_irqsave(&gus->voice_alloc, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	private_free = voice->private_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	voice->private_free = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	voice->private_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	if (voice->pcm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		gus->gf1.pcm_alloc_voices--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	voice->use = voice->pcm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	voice->sample_ops = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	spin_unlock_irqrestore(&gus->voice_alloc, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	if (private_free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		private_free(voice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)  *  call this function only by start of driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int snd_gf1_start(struct snd_gus_card * gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0);	/* reset GF1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	udelay(160);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1);	/* disable IRQ & DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	udelay(160);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_JOYSTICK_DAC_LEVEL, gus->joystick_dac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	for (i = 0; i < 32; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		gus->gf1.voices[i].number = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_VOICE | i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	snd_gf1_uart_cmd(gus, 0x03);	/* huh.. this cleanup took me some time... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	if (gus->gf1.enh_mode) {	/* enhanced mode !!!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		snd_gf1_i_write8(gus, SNDRV_GF1_GB_GLOBAL_MODE, snd_gf1_i_look8(gus, SNDRV_GF1_GB_GLOBAL_MODE) | 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		snd_gf1_i_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	snd_gf1_clear_regs(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	snd_gf1_select_active_voices(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	snd_gf1_delay(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	gus->gf1.default_voice_address = gus->gf1.memory > 0 ? 0 : 512 - 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	/* initialize LFOs & clear LFOs memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	if (gus->gf1.enh_mode && gus->gf1.memory) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		gus->gf1.hw_lfo = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		gus->gf1.default_voice_address += 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		gus->gf1.sw_lfo = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	snd_gf1_lfo_init(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	if (gus->gf1.memory > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 			snd_gf1_poke(gus, gus->gf1.default_voice_address + i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	snd_gf1_clear_regs(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	snd_gf1_clear_voices(gus, 0, 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	snd_gf1_look_regs(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	udelay(160);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 7);	/* Reset Register = IRQ enable, DAC enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	udelay(160);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 7);	/* Reset Register = IRQ enable, DAC enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	if (gus->gf1.enh_mode) {	/* enhanced mode !!!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		snd_gf1_i_write8(gus, SNDRV_GF1_GB_GLOBAL_MODE, snd_gf1_i_look8(gus, SNDRV_GF1_GB_GLOBAL_MODE) | 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		snd_gf1_i_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	while ((snd_gf1_i_read8(gus, SNDRV_GF1_GB_VOICES_IRQ) & 0xc0) != 0xc0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	spin_lock_irqsave(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	outb(gus->gf1.active_voice = 0, GUSP(gus, GF1PAGE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	outb(gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	spin_unlock_irqrestore(&gus->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	snd_gf1_timers_init(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	snd_gf1_look_regs(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	snd_gf1_mem_init(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	snd_gf1_mem_proc_init(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) #ifdef CONFIG_SND_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	snd_gus_irq_profile_init(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	if (gus->pnp_flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		if (gus->chip.playback_fifo_size > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 			snd_gf1_i_write16(gus, SNDRV_GF1_GW_FIFO_RECORD_BASE_ADDR, gus->chip.playback_fifo_block->ptr >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		if (gus->chip.record_fifo_size > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 			snd_gf1_i_write16(gus, SNDRV_GF1_GW_FIFO_PLAY_BASE_ADDR, gus->chip.record_fifo_block->ptr >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		snd_gf1_i_write16(gus, SNDRV_GF1_GW_FIFO_SIZE, gus->chip.interwave_fifo_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)  *  call this function only by shutdown of driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) int snd_gf1_stop(struct snd_gus_card * gus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, 0); /* stop all timers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	snd_gf1_stop_voices(gus, 0, 31);		/* stop all voices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1);	/* disable IRQ & DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	snd_gf1_timers_done(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	snd_gf1_mem_done(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	snd_gf1_lfo_done(gus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }