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