1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 * Routines for control of GF1 chip (PCM things)
5 *
6 * InterWave chips supports interleaved DMA, but this feature isn't used in
7 * this code.
8 *
9 * This code emulates autoinit DMA transfer for playback, recording by GF1
10 * chip doesn't support autoinit DMA.
11 */
12
13 #include <asm/dma.h>
14 #include <linux/slab.h>
15 #include <linux/sched/signal.h>
16
17 #include <sound/core.h>
18 #include <sound/control.h>
19 #include <sound/gus.h>
20 #include <sound/pcm_params.h>
21 #include "gus_tables.h"
22
23 /* maximum rate */
24
25 #define SNDRV_GF1_PCM_RATE 48000
26
27 #define SNDRV_GF1_PCM_PFLG_NONE 0
28 #define SNDRV_GF1_PCM_PFLG_ACTIVE (1<<0)
29 #define SNDRV_GF1_PCM_PFLG_NEUTRAL (2<<0)
30
31 struct gus_pcm_private {
32 struct snd_gus_card * gus;
33 struct snd_pcm_substream *substream;
34 spinlock_t lock;
35 unsigned int voices;
36 struct snd_gus_voice *pvoices[2];
37 unsigned int memory;
38 unsigned short flags;
39 unsigned char voice_ctrl, ramp_ctrl;
40 unsigned int bpos;
41 unsigned int blocks;
42 unsigned int block_size;
43 unsigned int dma_size;
44 wait_queue_head_t sleep;
45 atomic_t dma_count;
46 int final_volume;
47 };
48
snd_gf1_pcm_block_change_ack(struct snd_gus_card * gus,void * private_data)49 static void snd_gf1_pcm_block_change_ack(struct snd_gus_card * gus, void *private_data)
50 {
51 struct gus_pcm_private *pcmp = private_data;
52
53 if (pcmp) {
54 atomic_dec(&pcmp->dma_count);
55 wake_up(&pcmp->sleep);
56 }
57 }
58
snd_gf1_pcm_block_change(struct snd_pcm_substream * substream,unsigned int offset,unsigned int addr,unsigned int count)59 static int snd_gf1_pcm_block_change(struct snd_pcm_substream *substream,
60 unsigned int offset,
61 unsigned int addr,
62 unsigned int count)
63 {
64 struct snd_gf1_dma_block block;
65 struct snd_pcm_runtime *runtime = substream->runtime;
66 struct gus_pcm_private *pcmp = runtime->private_data;
67
68 count += offset & 31;
69 offset &= ~31;
70 memset(&block, 0, sizeof(block));
71 block.cmd = SNDRV_GF1_DMA_IRQ;
72 if (snd_pcm_format_unsigned(runtime->format))
73 block.cmd |= SNDRV_GF1_DMA_UNSIGNED;
74 if (snd_pcm_format_width(runtime->format) == 16)
75 block.cmd |= SNDRV_GF1_DMA_16BIT;
76 block.addr = addr & ~31;
77 block.buffer = runtime->dma_area + offset;
78 block.buf_addr = runtime->dma_addr + offset;
79 block.count = count;
80 block.private_data = pcmp;
81 block.ack = snd_gf1_pcm_block_change_ack;
82 if (!snd_gf1_dma_transfer_block(pcmp->gus, &block, 0, 0))
83 atomic_inc(&pcmp->dma_count);
84 return 0;
85 }
86
snd_gf1_pcm_trigger_up(struct snd_pcm_substream * substream)87 static void snd_gf1_pcm_trigger_up(struct snd_pcm_substream *substream)
88 {
89 struct snd_pcm_runtime *runtime = substream->runtime;
90 struct gus_pcm_private *pcmp = runtime->private_data;
91 struct snd_gus_card * gus = pcmp->gus;
92 unsigned char voice_ctrl, ramp_ctrl;
93 unsigned short rate;
94 unsigned int curr, begin, end;
95 unsigned short vol;
96 unsigned char pan;
97 unsigned int voice;
98
99 scoped_guard(spinlock_irqsave, &pcmp->lock) {
100 if (pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE)
101 return;
102 pcmp->flags |= SNDRV_GF1_PCM_PFLG_ACTIVE;
103 pcmp->final_volume = 0;
104 }
105 rate = snd_gf1_translate_freq(gus, runtime->rate << 4);
106 /* enable WAVE IRQ */
107 voice_ctrl = snd_pcm_format_width(runtime->format) == 16 ? 0x24 : 0x20;
108 /* enable RAMP IRQ + rollover */
109 ramp_ctrl = 0x24;
110 if (pcmp->blocks == 1) {
111 voice_ctrl |= 0x08; /* loop enable */
112 ramp_ctrl &= ~0x04; /* disable rollover */
113 }
114 for (voice = 0; voice < pcmp->voices; voice++) {
115 begin = pcmp->memory + voice * (pcmp->dma_size / runtime->channels);
116 curr = begin + (pcmp->bpos * pcmp->block_size) / runtime->channels;
117 end = curr + (pcmp->block_size / runtime->channels);
118 end -= snd_pcm_format_width(runtime->format) == 16 ? 2 : 1;
119 pan = runtime->channels == 2 ? (!voice ? 1 : 14) : 8;
120 vol = !voice ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right;
121 guard(spinlock_irqsave)(&gus->reg_lock);
122 snd_gf1_select_voice(gus, pcmp->pvoices[voice]->number);
123 snd_gf1_write8(gus, SNDRV_GF1_VB_PAN, pan);
124 snd_gf1_write16(gus, SNDRV_GF1_VW_FREQUENCY, rate);
125 snd_gf1_write_addr(gus, SNDRV_GF1_VA_START, begin << 4, voice_ctrl & 4);
126 snd_gf1_write_addr(gus, SNDRV_GF1_VA_END, end << 4, voice_ctrl & 4);
127 snd_gf1_write_addr(gus, SNDRV_GF1_VA_CURRENT, curr << 4, voice_ctrl & 4);
128 snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, SNDRV_GF1_MIN_VOLUME << 4);
129 snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_RATE, 0x2f);
130 snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_START, SNDRV_GF1_MIN_OFFSET);
131 snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_END, vol >> 8);
132 snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, ramp_ctrl);
133 if (!gus->gf1.enh_mode) {
134 snd_gf1_delay(gus);
135 snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, ramp_ctrl);
136 }
137 }
138
139 guard(spinlock_irqsave)(&gus->reg_lock);
140 for (voice = 0; voice < pcmp->voices; voice++) {
141 snd_gf1_select_voice(gus, pcmp->pvoices[voice]->number);
142 if (gus->gf1.enh_mode)
143 snd_gf1_write8(gus, SNDRV_GF1_VB_MODE, 0x00); /* deactivate voice */
144 snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice_ctrl);
145 voice_ctrl &= ~0x20;
146 }
147 voice_ctrl |= 0x20;
148 if (!gus->gf1.enh_mode) {
149 snd_gf1_delay(gus);
150 for (voice = 0; voice < pcmp->voices; voice++) {
151 snd_gf1_select_voice(gus, pcmp->pvoices[voice]->number);
152 snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice_ctrl);
153 voice_ctrl &= ~0x20; /* disable IRQ for next voice */
154 }
155 }
156 }
157
snd_gf1_pcm_interrupt_wave(struct snd_gus_card * gus,struct snd_gus_voice * pvoice)158 static void snd_gf1_pcm_interrupt_wave(struct snd_gus_card * gus,
159 struct snd_gus_voice *pvoice)
160 {
161 struct gus_pcm_private * pcmp;
162 struct snd_pcm_runtime *runtime;
163 unsigned char voice_ctrl, ramp_ctrl;
164 unsigned int idx;
165 unsigned int end, step;
166
167 if (!pvoice->private_data) {
168 dev_dbg(gus->card->dev, "%s: unknown wave irq?\n", __func__);
169 snd_gf1_smart_stop_voice(gus, pvoice->number);
170 return;
171 }
172 pcmp = pvoice->private_data;
173 if (pcmp == NULL) {
174 dev_dbg(gus->card->dev, "%s: unknown wave irq?\n", __func__);
175 snd_gf1_smart_stop_voice(gus, pvoice->number);
176 return;
177 }
178 gus = pcmp->gus;
179 runtime = pcmp->substream->runtime;
180
181 scoped_guard(spinlock, &gus->reg_lock) {
182 snd_gf1_select_voice(gus, pvoice->number);
183 voice_ctrl = snd_gf1_read8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL) & ~0x8b;
184 ramp_ctrl = (snd_gf1_read8(gus, SNDRV_GF1_VB_VOLUME_CONTROL) & ~0xa4) | 0x03;
185 #if 0
186 snd_gf1_select_voice(gus, pvoice->number);
187 dev_dbg(gus->card->dev, "position = 0x%x\n",
188 (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4));
189 snd_gf1_select_voice(gus, pcmp->pvoices[1]->number);
190 dev_dbg(gus->card->dev, "position = 0x%x\n",
191 (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4));
192 snd_gf1_select_voice(gus, pvoice->number);
193 #endif
194 pcmp->bpos++;
195 pcmp->bpos %= pcmp->blocks;
196 if (pcmp->bpos + 1 >= pcmp->blocks) { /* last block? */
197 voice_ctrl |= 0x08; /* enable loop */
198 } else {
199 ramp_ctrl |= 0x04; /* enable rollover */
200 }
201 end = pcmp->memory + (((pcmp->bpos + 1) * pcmp->block_size) / runtime->channels);
202 end -= voice_ctrl & 4 ? 2 : 1;
203 step = pcmp->dma_size / runtime->channels;
204 voice_ctrl |= 0x20;
205 if (!pcmp->final_volume) {
206 ramp_ctrl |= 0x20;
207 ramp_ctrl &= ~0x03;
208 }
209 for (idx = 0; idx < pcmp->voices; idx++, end += step) {
210 snd_gf1_select_voice(gus, pcmp->pvoices[idx]->number);
211 snd_gf1_write_addr(gus, SNDRV_GF1_VA_END, end << 4, voice_ctrl & 4);
212 snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice_ctrl);
213 snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, ramp_ctrl);
214 voice_ctrl &= ~0x20;
215 }
216 if (!gus->gf1.enh_mode) {
217 snd_gf1_delay(gus);
218 voice_ctrl |= 0x20;
219 for (idx = 0; idx < pcmp->voices; idx++) {
220 snd_gf1_select_voice(gus, pcmp->pvoices[idx]->number);
221 snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice_ctrl);
222 snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, ramp_ctrl);
223 voice_ctrl &= ~0x20;
224 }
225 }
226 }
227
228 snd_pcm_period_elapsed(pcmp->substream);
229 #if 0
230 if ((runtime->flags & SNDRV_PCM_FLG_MMAP) &&
231 *runtime->state == SNDRV_PCM_STATE_RUNNING) {
232 end = pcmp->bpos * pcmp->block_size;
233 if (runtime->channels > 1) {
234 snd_gf1_pcm_block_change(pcmp->substream, end, pcmp->memory + (end / 2), pcmp->block_size / 2);
235 snd_gf1_pcm_block_change(pcmp->substream, end + (pcmp->block_size / 2), pcmp->memory + (pcmp->dma_size / 2) + (end / 2), pcmp->block_size / 2);
236 } else {
237 snd_gf1_pcm_block_change(pcmp->substream, end, pcmp->memory + end, pcmp->block_size);
238 }
239 }
240 #endif
241 }
242
snd_gf1_pcm_interrupt_volume(struct snd_gus_card * gus,struct snd_gus_voice * pvoice)243 static void snd_gf1_pcm_interrupt_volume(struct snd_gus_card * gus,
244 struct snd_gus_voice * pvoice)
245 {
246 unsigned short vol;
247 int cvoice;
248 struct gus_pcm_private *pcmp = pvoice->private_data;
249
250 /* stop ramp, but leave rollover bit untouched */
251 scoped_guard(spinlock, &gus->reg_lock) {
252 snd_gf1_select_voice(gus, pvoice->number);
253 snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
254 }
255 if (pcmp == NULL)
256 return;
257 /* are we active? */
258 if (!(pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE))
259 return;
260 /* load real volume - better precision */
261 cvoice = pcmp->pvoices[0] == pvoice ? 0 : 1;
262 if (pcmp->substream == NULL)
263 return;
264 vol = !cvoice ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right;
265 guard(spinlock)(&gus->reg_lock);
266 snd_gf1_select_voice(gus, pvoice->number);
267 snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, vol);
268 pcmp->final_volume = 1;
269 }
270
snd_gf1_pcm_volume_change(struct snd_gus_card * gus)271 static void snd_gf1_pcm_volume_change(struct snd_gus_card * gus)
272 {
273 }
274
snd_gf1_pcm_poke_block(struct snd_gus_card * gus,unsigned char * buf,unsigned int pos,unsigned int count,int w16,int invert)275 static int snd_gf1_pcm_poke_block(struct snd_gus_card *gus, unsigned char *buf,
276 unsigned int pos, unsigned int count,
277 int w16, int invert)
278 {
279 unsigned int len;
280
281 while (count > 0) {
282 len = count;
283 if (len > 512) /* limit, to allow IRQ */
284 len = 512;
285 count -= len;
286 if (gus->interwave) {
287 guard(spinlock_irqsave)(&gus->reg_lock);
288 snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01 | (invert ? 0x08 : 0x00));
289 snd_gf1_dram_addr(gus, pos);
290 if (w16) {
291 outb(SNDRV_GF1_GW_DRAM_IO16, GUSP(gus, GF1REGSEL));
292 outsw(GUSP(gus, GF1DATALOW), buf, len >> 1);
293 } else {
294 outsb(GUSP(gus, DRAM), buf, len);
295 }
296 buf += 512;
297 pos += 512;
298 } else {
299 invert = invert ? 0x80 : 0x00;
300 if (w16) {
301 len >>= 1;
302 while (len--) {
303 snd_gf1_poke(gus, pos++, *buf++);
304 snd_gf1_poke(gus, pos++, *buf++ ^ invert);
305 }
306 } else {
307 while (len--)
308 snd_gf1_poke(gus, pos++, *buf++ ^ invert);
309 }
310 }
311 if (count > 0 && !in_interrupt()) {
312 schedule_timeout_interruptible(1);
313 if (signal_pending(current))
314 return -EAGAIN;
315 }
316 }
317 return 0;
318 }
319
get_bpos(struct gus_pcm_private * pcmp,int voice,unsigned int pos,unsigned int len)320 static int get_bpos(struct gus_pcm_private *pcmp, int voice, unsigned int pos,
321 unsigned int len)
322 {
323 unsigned int bpos = pos + (voice * (pcmp->dma_size / 2));
324 if (snd_BUG_ON(bpos > pcmp->dma_size))
325 return -EIO;
326 if (snd_BUG_ON(bpos + len > pcmp->dma_size))
327 return -EIO;
328 return bpos;
329 }
330
playback_copy_ack(struct snd_pcm_substream * substream,unsigned int bpos,unsigned int len)331 static int playback_copy_ack(struct snd_pcm_substream *substream,
332 unsigned int bpos, unsigned int len)
333 {
334 struct snd_pcm_runtime *runtime = substream->runtime;
335 struct gus_pcm_private *pcmp = runtime->private_data;
336 struct snd_gus_card *gus = pcmp->gus;
337 int w16, invert;
338
339 if (len > 32)
340 return snd_gf1_pcm_block_change(substream, bpos,
341 pcmp->memory + bpos, len);
342
343 w16 = (snd_pcm_format_width(runtime->format) == 16);
344 invert = snd_pcm_format_unsigned(runtime->format);
345 return snd_gf1_pcm_poke_block(gus, runtime->dma_area + bpos,
346 pcmp->memory + bpos, len, w16, invert);
347 }
348
snd_gf1_pcm_playback_copy(struct snd_pcm_substream * substream,int voice,unsigned long pos,struct iov_iter * src,unsigned long count)349 static int snd_gf1_pcm_playback_copy(struct snd_pcm_substream *substream,
350 int voice, unsigned long pos,
351 struct iov_iter *src, unsigned long count)
352 {
353 struct snd_pcm_runtime *runtime = substream->runtime;
354 struct gus_pcm_private *pcmp = runtime->private_data;
355 unsigned int len = count;
356 int bpos;
357
358 bpos = get_bpos(pcmp, voice, pos, len);
359 if (bpos < 0)
360 return bpos;
361 if (copy_from_iter(runtime->dma_area + bpos, len, src) != len)
362 return -EFAULT;
363 return playback_copy_ack(substream, bpos, len);
364 }
365
snd_gf1_pcm_playback_silence(struct snd_pcm_substream * substream,int voice,unsigned long pos,unsigned long count)366 static int snd_gf1_pcm_playback_silence(struct snd_pcm_substream *substream,
367 int voice, unsigned long pos,
368 unsigned long count)
369 {
370 struct snd_pcm_runtime *runtime = substream->runtime;
371 struct gus_pcm_private *pcmp = runtime->private_data;
372 unsigned int len = count;
373 int bpos;
374
375 bpos = get_bpos(pcmp, voice, pos, len);
376 if (bpos < 0)
377 return bpos;
378 snd_pcm_format_set_silence(runtime->format, runtime->dma_area + bpos,
379 bytes_to_samples(runtime, count));
380 return playback_copy_ack(substream, bpos, len);
381 }
382
snd_gf1_pcm_playback_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params)383 static int snd_gf1_pcm_playback_hw_params(struct snd_pcm_substream *substream,
384 struct snd_pcm_hw_params *hw_params)
385 {
386 struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
387 struct snd_pcm_runtime *runtime = substream->runtime;
388 struct gus_pcm_private *pcmp = runtime->private_data;
389
390 if (runtime->buffer_changed) {
391 struct snd_gf1_mem_block *block;
392 if (pcmp->memory > 0) {
393 snd_gf1_mem_free(&gus->gf1.mem_alloc, pcmp->memory);
394 pcmp->memory = 0;
395 }
396 block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc,
397 SNDRV_GF1_MEM_OWNER_DRIVER,
398 "GF1 PCM",
399 runtime->dma_bytes, 1, 32,
400 NULL);
401 if (!block)
402 return -ENOMEM;
403 pcmp->memory = block->ptr;
404 }
405 pcmp->voices = params_channels(hw_params);
406 if (pcmp->pvoices[0] == NULL) {
407 pcmp->pvoices[0] = snd_gf1_alloc_voice(pcmp->gus, SNDRV_GF1_VOICE_TYPE_PCM, 0, 0);
408 if (!pcmp->pvoices[0])
409 return -ENOMEM;
410 pcmp->pvoices[0]->handler_wave = snd_gf1_pcm_interrupt_wave;
411 pcmp->pvoices[0]->handler_volume = snd_gf1_pcm_interrupt_volume;
412 pcmp->pvoices[0]->volume_change = snd_gf1_pcm_volume_change;
413 pcmp->pvoices[0]->private_data = pcmp;
414 }
415 if (pcmp->voices > 1 && pcmp->pvoices[1] == NULL) {
416 pcmp->pvoices[1] = snd_gf1_alloc_voice(pcmp->gus, SNDRV_GF1_VOICE_TYPE_PCM, 0, 0);
417 if (!pcmp->pvoices[1])
418 return -ENOMEM;
419 pcmp->pvoices[1]->handler_wave = snd_gf1_pcm_interrupt_wave;
420 pcmp->pvoices[1]->handler_volume = snd_gf1_pcm_interrupt_volume;
421 pcmp->pvoices[1]->volume_change = snd_gf1_pcm_volume_change;
422 pcmp->pvoices[1]->private_data = pcmp;
423 } else if (pcmp->voices == 1) {
424 if (pcmp->pvoices[1]) {
425 snd_gf1_free_voice(pcmp->gus, pcmp->pvoices[1]);
426 pcmp->pvoices[1] = NULL;
427 }
428 }
429 return 0;
430 }
431
snd_gf1_pcm_playback_hw_free(struct snd_pcm_substream * substream)432 static int snd_gf1_pcm_playback_hw_free(struct snd_pcm_substream *substream)
433 {
434 struct snd_pcm_runtime *runtime = substream->runtime;
435 struct gus_pcm_private *pcmp = runtime->private_data;
436
437 if (pcmp->pvoices[0]) {
438 snd_gf1_free_voice(pcmp->gus, pcmp->pvoices[0]);
439 pcmp->pvoices[0] = NULL;
440 }
441 if (pcmp->pvoices[1]) {
442 snd_gf1_free_voice(pcmp->gus, pcmp->pvoices[1]);
443 pcmp->pvoices[1] = NULL;
444 }
445 if (pcmp->memory > 0) {
446 snd_gf1_mem_free(&pcmp->gus->gf1.mem_alloc, pcmp->memory);
447 pcmp->memory = 0;
448 }
449 return 0;
450 }
451
snd_gf1_pcm_playback_prepare(struct snd_pcm_substream * substream)452 static int snd_gf1_pcm_playback_prepare(struct snd_pcm_substream *substream)
453 {
454 struct snd_pcm_runtime *runtime = substream->runtime;
455 struct gus_pcm_private *pcmp = runtime->private_data;
456
457 pcmp->bpos = 0;
458 pcmp->dma_size = snd_pcm_lib_buffer_bytes(substream);
459 pcmp->block_size = snd_pcm_lib_period_bytes(substream);
460 pcmp->blocks = pcmp->dma_size / pcmp->block_size;
461 return 0;
462 }
463
snd_gf1_pcm_playback_trigger(struct snd_pcm_substream * substream,int cmd)464 static int snd_gf1_pcm_playback_trigger(struct snd_pcm_substream *substream,
465 int cmd)
466 {
467 struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
468 struct snd_pcm_runtime *runtime = substream->runtime;
469 struct gus_pcm_private *pcmp = runtime->private_data;
470 int voice;
471
472 if (cmd == SNDRV_PCM_TRIGGER_START) {
473 snd_gf1_pcm_trigger_up(substream);
474 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
475 scoped_guard(spinlock, &pcmp->lock) {
476 pcmp->flags &= ~SNDRV_GF1_PCM_PFLG_ACTIVE;
477 }
478 voice = pcmp->pvoices[0]->number;
479 snd_gf1_stop_voices(gus, voice, voice);
480 if (pcmp->pvoices[1]) {
481 voice = pcmp->pvoices[1]->number;
482 snd_gf1_stop_voices(gus, voice, voice);
483 }
484 } else {
485 return -EINVAL;
486 }
487 return 0;
488 }
489
snd_gf1_pcm_playback_pointer(struct snd_pcm_substream * substream)490 static snd_pcm_uframes_t snd_gf1_pcm_playback_pointer(struct snd_pcm_substream *substream)
491 {
492 struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
493 struct snd_pcm_runtime *runtime = substream->runtime;
494 struct gus_pcm_private *pcmp = runtime->private_data;
495 unsigned int pos;
496 unsigned char voice_ctrl;
497
498 pos = 0;
499 guard(spinlock)(&gus->reg_lock);
500 if (pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE) {
501 snd_gf1_select_voice(gus, pcmp->pvoices[0]->number);
502 voice_ctrl = snd_gf1_read8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
503 pos = (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4) - pcmp->memory;
504 if (substream->runtime->channels > 1)
505 pos <<= 1;
506 pos = bytes_to_frames(runtime, pos);
507 }
508 return pos;
509 }
510
511 static const struct snd_ratnum clock = {
512 .num = 9878400/16,
513 .den_min = 2,
514 .den_max = 257,
515 .den_step = 1,
516 };
517
518 static const struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = {
519 .nrats = 1,
520 .rats = &clock,
521 };
522
snd_gf1_pcm_capture_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params)523 static int snd_gf1_pcm_capture_hw_params(struct snd_pcm_substream *substream,
524 struct snd_pcm_hw_params *hw_params)
525 {
526 struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
527
528 gus->c_dma_size = params_buffer_bytes(hw_params);
529 gus->c_period_size = params_period_bytes(hw_params);
530 gus->c_pos = 0;
531 gus->gf1.pcm_rcntrl_reg = 0x21; /* IRQ at end, enable & start */
532 if (params_channels(hw_params) > 1)
533 gus->gf1.pcm_rcntrl_reg |= 2;
534 if (gus->gf1.dma2 > 3)
535 gus->gf1.pcm_rcntrl_reg |= 4;
536 if (snd_pcm_format_unsigned(params_format(hw_params)))
537 gus->gf1.pcm_rcntrl_reg |= 0x80;
538 return 0;
539 }
540
snd_gf1_pcm_capture_prepare(struct snd_pcm_substream * substream)541 static int snd_gf1_pcm_capture_prepare(struct snd_pcm_substream *substream)
542 {
543 struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
544 struct snd_pcm_runtime *runtime = substream->runtime;
545
546 snd_gf1_i_write8(gus, SNDRV_GF1_GB_RECORD_RATE, runtime->rate_den - 2);
547 snd_gf1_i_write8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL, 0); /* disable sampling */
548 snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL); /* Sampling Control Register */
549 snd_dma_program(gus->gf1.dma2, runtime->dma_addr, gus->c_period_size, DMA_MODE_READ);
550 return 0;
551 }
552
snd_gf1_pcm_capture_trigger(struct snd_pcm_substream * substream,int cmd)553 static int snd_gf1_pcm_capture_trigger(struct snd_pcm_substream *substream,
554 int cmd)
555 {
556 struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
557 int val;
558
559 if (cmd == SNDRV_PCM_TRIGGER_START) {
560 val = gus->gf1.pcm_rcntrl_reg;
561 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
562 val = 0;
563 } else {
564 return -EINVAL;
565 }
566
567 guard(spinlock)(&gus->reg_lock);
568 snd_gf1_write8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL, val);
569 snd_gf1_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL);
570 return 0;
571 }
572
snd_gf1_pcm_capture_pointer(struct snd_pcm_substream * substream)573 static snd_pcm_uframes_t snd_gf1_pcm_capture_pointer(struct snd_pcm_substream *substream)
574 {
575 struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
576 int pos = snd_dma_pointer(gus->gf1.dma2, gus->c_period_size);
577 pos = bytes_to_frames(substream->runtime, (gus->c_pos + pos) % gus->c_dma_size);
578 return pos;
579 }
580
snd_gf1_pcm_interrupt_dma_read(struct snd_gus_card * gus)581 static void snd_gf1_pcm_interrupt_dma_read(struct snd_gus_card * gus)
582 {
583 snd_gf1_i_write8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL, 0); /* disable sampling */
584 snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL); /* Sampling Control Register */
585 if (gus->pcm_cap_substream != NULL) {
586 snd_gf1_pcm_capture_prepare(gus->pcm_cap_substream);
587 snd_gf1_pcm_capture_trigger(gus->pcm_cap_substream, SNDRV_PCM_TRIGGER_START);
588 gus->c_pos += gus->c_period_size;
589 snd_pcm_period_elapsed(gus->pcm_cap_substream);
590 }
591 }
592
593 static const struct snd_pcm_hardware snd_gf1_pcm_playback =
594 {
595 .info = SNDRV_PCM_INFO_NONINTERLEAVED,
596 .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
597 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
598 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
599 .rate_min = 5510,
600 .rate_max = 48000,
601 .channels_min = 1,
602 .channels_max = 2,
603 .buffer_bytes_max = (128*1024),
604 .period_bytes_min = 64,
605 .period_bytes_max = (128*1024),
606 .periods_min = 1,
607 .periods_max = 1024,
608 .fifo_size = 0,
609 };
610
611 static const struct snd_pcm_hardware snd_gf1_pcm_capture =
612 {
613 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
614 SNDRV_PCM_INFO_MMAP_VALID),
615 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8,
616 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_44100,
617 .rate_min = 5510,
618 .rate_max = 44100,
619 .channels_min = 1,
620 .channels_max = 2,
621 .buffer_bytes_max = (128*1024),
622 .period_bytes_min = 64,
623 .period_bytes_max = (128*1024),
624 .periods_min = 1,
625 .periods_max = 1024,
626 .fifo_size = 0,
627 };
628
snd_gf1_pcm_playback_free(struct snd_pcm_runtime * runtime)629 static void snd_gf1_pcm_playback_free(struct snd_pcm_runtime *runtime)
630 {
631 kfree(runtime->private_data);
632 }
633
snd_gf1_pcm_playback_open(struct snd_pcm_substream * substream)634 static int snd_gf1_pcm_playback_open(struct snd_pcm_substream *substream)
635 {
636 struct gus_pcm_private *pcmp;
637 struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
638 struct snd_pcm_runtime *runtime = substream->runtime;
639 int err;
640
641 pcmp = kzalloc_obj(*pcmp);
642 if (pcmp == NULL)
643 return -ENOMEM;
644 pcmp->gus = gus;
645 spin_lock_init(&pcmp->lock);
646 init_waitqueue_head(&pcmp->sleep);
647 atomic_set(&pcmp->dma_count, 0);
648
649 runtime->private_data = pcmp;
650 runtime->private_free = snd_gf1_pcm_playback_free;
651
652 #if 0
653 dev_dbg(gus->card->dev,
654 "playback.buffer = 0x%lx, gf1.pcm_buffer = 0x%lx\n",
655 (long) pcm->playback.buffer, (long) gus->gf1.pcm_buffer);
656 #endif
657 err = snd_gf1_dma_init(gus);
658 if (err < 0)
659 return err;
660 pcmp->flags = SNDRV_GF1_PCM_PFLG_NONE;
661 pcmp->substream = substream;
662 runtime->hw = snd_gf1_pcm_playback;
663 snd_pcm_limit_isa_dma_size(gus->gf1.dma1, &runtime->hw.buffer_bytes_max);
664 snd_pcm_limit_isa_dma_size(gus->gf1.dma1, &runtime->hw.period_bytes_max);
665 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64);
666 return 0;
667 }
668
snd_gf1_pcm_playback_close(struct snd_pcm_substream * substream)669 static int snd_gf1_pcm_playback_close(struct snd_pcm_substream *substream)
670 {
671 struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
672 struct snd_pcm_runtime *runtime = substream->runtime;
673 struct gus_pcm_private *pcmp = runtime->private_data;
674
675 if (!wait_event_timeout(pcmp->sleep, (atomic_read(&pcmp->dma_count) <= 0), 2*HZ))
676 dev_err(gus->card->dev, "gf1 pcm - serious DMA problem\n");
677
678 snd_gf1_dma_done(gus);
679 return 0;
680 }
681
snd_gf1_pcm_capture_open(struct snd_pcm_substream * substream)682 static int snd_gf1_pcm_capture_open(struct snd_pcm_substream *substream)
683 {
684 struct snd_pcm_runtime *runtime = substream->runtime;
685 struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
686
687 gus->gf1.interrupt_handler_dma_read = snd_gf1_pcm_interrupt_dma_read;
688 gus->pcm_cap_substream = substream;
689 substream->runtime->hw = snd_gf1_pcm_capture;
690 snd_pcm_limit_isa_dma_size(gus->gf1.dma2, &runtime->hw.buffer_bytes_max);
691 snd_pcm_limit_isa_dma_size(gus->gf1.dma2, &runtime->hw.period_bytes_max);
692 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
693 &hw_constraints_clocks);
694 return 0;
695 }
696
snd_gf1_pcm_capture_close(struct snd_pcm_substream * substream)697 static int snd_gf1_pcm_capture_close(struct snd_pcm_substream *substream)
698 {
699 struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
700
701 gus->pcm_cap_substream = NULL;
702 snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_DMA_READ);
703 return 0;
704 }
705
snd_gf1_pcm_volume_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)706 static int snd_gf1_pcm_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
707 {
708 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
709 uinfo->count = 2;
710 uinfo->value.integer.min = 0;
711 uinfo->value.integer.max = 127;
712 return 0;
713 }
714
snd_gf1_pcm_volume_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)715 static int snd_gf1_pcm_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
716 {
717 struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
718
719 guard(spinlock_irqsave)(&gus->pcm_volume_level_lock);
720 ucontrol->value.integer.value[0] = gus->gf1.pcm_volume_level_left1;
721 ucontrol->value.integer.value[1] = gus->gf1.pcm_volume_level_right1;
722 return 0;
723 }
724
snd_gf1_pcm_volume_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)725 static int snd_gf1_pcm_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
726 {
727 struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
728 int change;
729 unsigned int idx;
730 unsigned short val1, val2, vol;
731 struct gus_pcm_private *pcmp;
732 struct snd_gus_voice *pvoice;
733
734 val1 = ucontrol->value.integer.value[0] & 127;
735 val2 = ucontrol->value.integer.value[1] & 127;
736 scoped_guard(spinlock_irqsave, &gus->pcm_volume_level_lock) {
737 change = val1 != gus->gf1.pcm_volume_level_left1 ||
738 val2 != gus->gf1.pcm_volume_level_right1;
739 gus->gf1.pcm_volume_level_left1 = val1;
740 gus->gf1.pcm_volume_level_right1 = val2;
741 gus->gf1.pcm_volume_level_left = snd_gf1_lvol_to_gvol_raw(val1 << 9) << 4;
742 gus->gf1.pcm_volume_level_right = snd_gf1_lvol_to_gvol_raw(val2 << 9) << 4;
743 }
744 /* are we active? */
745 scoped_guard(spinlock_irqsave, &gus->voice_alloc) {
746 for (idx = 0; idx < 32; idx++) {
747 pvoice = &gus->gf1.voices[idx];
748 if (!pvoice->pcm)
749 continue;
750 pcmp = pvoice->private_data;
751 if (!(pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE))
752 continue;
753 /* load real volume - better precision */
754 guard(spinlock)(&gus->reg_lock);
755 snd_gf1_select_voice(gus, pvoice->number);
756 snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
757 vol = pvoice == pcmp->pvoices[0] ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right;
758 snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, vol);
759 pcmp->final_volume = 1;
760 }
761 }
762 return change;
763 }
764
765 static const struct snd_kcontrol_new snd_gf1_pcm_volume_control =
766 {
767 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
768 .name = "PCM Playback Volume",
769 .info = snd_gf1_pcm_volume_info,
770 .get = snd_gf1_pcm_volume_get,
771 .put = snd_gf1_pcm_volume_put
772 };
773
774 static const struct snd_kcontrol_new snd_gf1_pcm_volume_control1 =
775 {
776 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
777 .name = "GPCM Playback Volume",
778 .info = snd_gf1_pcm_volume_info,
779 .get = snd_gf1_pcm_volume_get,
780 .put = snd_gf1_pcm_volume_put
781 };
782
783 static const struct snd_pcm_ops snd_gf1_pcm_playback_ops = {
784 .open = snd_gf1_pcm_playback_open,
785 .close = snd_gf1_pcm_playback_close,
786 .hw_params = snd_gf1_pcm_playback_hw_params,
787 .hw_free = snd_gf1_pcm_playback_hw_free,
788 .prepare = snd_gf1_pcm_playback_prepare,
789 .trigger = snd_gf1_pcm_playback_trigger,
790 .pointer = snd_gf1_pcm_playback_pointer,
791 .copy = snd_gf1_pcm_playback_copy,
792 .fill_silence = snd_gf1_pcm_playback_silence,
793 };
794
795 static const struct snd_pcm_ops snd_gf1_pcm_capture_ops = {
796 .open = snd_gf1_pcm_capture_open,
797 .close = snd_gf1_pcm_capture_close,
798 .hw_params = snd_gf1_pcm_capture_hw_params,
799 .prepare = snd_gf1_pcm_capture_prepare,
800 .trigger = snd_gf1_pcm_capture_trigger,
801 .pointer = snd_gf1_pcm_capture_pointer,
802 };
803
snd_gf1_pcm_new(struct snd_gus_card * gus,int pcm_dev,int control_index)804 int snd_gf1_pcm_new(struct snd_gus_card *gus, int pcm_dev, int control_index)
805 {
806 struct snd_card *card;
807 struct snd_kcontrol *kctl;
808 struct snd_pcm *pcm;
809 struct snd_pcm_substream *substream;
810 int capture, err;
811
812 card = gus->card;
813 capture = !gus->interwave && !gus->ess_flag && !gus->ace_flag ? 1 : 0;
814 err = snd_pcm_new(card,
815 gus->interwave ? "AMD InterWave" : "GF1",
816 pcm_dev,
817 gus->gf1.pcm_channels / 2,
818 capture,
819 &pcm);
820 if (err < 0)
821 return err;
822 pcm->private_data = gus;
823 /* playback setup */
824 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_gf1_pcm_playback_ops);
825
826 for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
827 snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV,
828 card->dev,
829 64*1024, gus->gf1.dma1 > 3 ? 128*1024 : 64*1024);
830
831 pcm->info_flags = 0;
832 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
833 if (capture) {
834 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_gf1_pcm_capture_ops);
835 if (gus->gf1.dma2 == gus->gf1.dma1)
836 pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX;
837 snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
838 SNDRV_DMA_TYPE_DEV, card->dev,
839 64*1024, gus->gf1.dma2 > 3 ? 128*1024 : 64*1024);
840 }
841 strscpy(pcm->name, pcm->id);
842 if (gus->interwave) {
843 sprintf(pcm->name + strlen(pcm->name), " rev %c", gus->revision + 'A');
844 }
845 strcat(pcm->name, " (synth)");
846 gus->pcm = pcm;
847
848 if (gus->codec_flag)
849 kctl = snd_ctl_new1(&snd_gf1_pcm_volume_control1, gus);
850 else
851 kctl = snd_ctl_new1(&snd_gf1_pcm_volume_control, gus);
852 kctl->id.index = control_index;
853 err = snd_ctl_add(card, kctl);
854 if (err < 0)
855 return err;
856
857 return 0;
858 }
859
860