1 /*
2  **********************************************************************
3  *     voicemgr.c - Voice manager for emu10k1 driver
4  *     Copyright 1999, 2000 Creative Labs, Inc.
5  *
6  **********************************************************************
7  *
8  *     Date                 Author          Summary of changes
9  *     ----                 ------          ------------------
10  *     October 20, 1999     Bertrand Lee    base code release
11  *
12  **********************************************************************
13  *
14  *     This program is free software; you can redistribute it and/or
15  *     modify it under the terms of the GNU General Public License as
16  *     published by the Free Software Foundation; either version 2 of
17  *     the License, or (at your option) any later version.
18  *
19  *     This program is distributed in the hope that it will be useful,
20  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
21  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  *     GNU General Public License for more details.
23  *
24  *     You should have received a copy of the GNU General Public
25  *     License along with this program; if not, write to the Free
26  *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27  *     USA.
28  *
29  **********************************************************************
30  */
31 
32 #include "voicemgr.h"
33 #include "8010.h"
34 
35 /**
36  * emu10k1_voice_alloc_buffer -
37  *
38  * allocates the memory buffer for a voice. Two page tables are kept for each buffer.
39  * One (dma_handle) keeps track of the host memory pages used and the other (virtualpagetable)
40  * is passed to the device so that it can do DMA to host memory.
41  *
42  */
emu10k1_voice_alloc_buffer(struct emu10k1_card * card,struct voice_mem * mem,u32 pages)43 int emu10k1_voice_alloc_buffer(struct emu10k1_card *card, struct voice_mem *mem, u32 pages)
44 {
45 	u32 pageindex, pagecount;
46 	u32 busaddx;
47 	int i;
48 
49 	DPD(2, "requested pages is: %d\n", pages);
50 
51 	if ((mem->emupageindex = emu10k1_addxmgr_alloc(pages * PAGE_SIZE, card)) < 0)
52 	{
53 		DPF(1, "couldn't allocate emu10k1 address space\n");
54 		return -1;
55 	}
56 
57 	/* Fill in virtual memory table */
58 	for (pagecount = 0; pagecount < pages; pagecount++) {
59 		if ((mem->addr[pagecount] = pci_alloc_consistent(card->pci_dev, PAGE_SIZE, &mem->dma_handle[pagecount]))
60 			== NULL) {
61 			mem->pages = pagecount;
62 			DPF(1, "couldn't allocate dma memory\n");
63 			return -1;
64 		}
65 
66 		DPD(2, "Virtual Addx: %p\n", mem->addr[pagecount]);
67 
68 		for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) {
69 			busaddx = (u32) mem->dma_handle[pagecount] + i * EMUPAGESIZE;
70 
71 			DPD(3, "Bus Addx: %#x\n", busaddx);
72 
73 			pageindex = mem->emupageindex + pagecount * PAGE_SIZE / EMUPAGESIZE + i;
74 
75 			((u32 *) card->virtualpagetable.addr)[pageindex] = cpu_to_le32((busaddx * 2) | pageindex);
76 		}
77 	}
78 
79 	mem->pages = pagecount;
80 
81 	return 0;
82 }
83 
84 /**
85  * emu10k1_voice_free_buffer -
86  *
87  * frees the memory buffer for a voice.
88  */
emu10k1_voice_free_buffer(struct emu10k1_card * card,struct voice_mem * mem)89 void emu10k1_voice_free_buffer(struct emu10k1_card *card, struct voice_mem *mem)
90 {
91 	u32 pagecount, pageindex;
92 	int i;
93 
94 	if (mem->emupageindex < 0)
95 		return;
96 
97 	for (pagecount = 0; pagecount < mem->pages; pagecount++) {
98 		pci_free_consistent(card->pci_dev, PAGE_SIZE,
99 					mem->addr[pagecount],
100 					mem->dma_handle[pagecount]);
101 
102 		for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) {
103 			pageindex = mem->emupageindex + pagecount * PAGE_SIZE / EMUPAGESIZE + i;
104 			((u32 *) card->virtualpagetable.addr)[pageindex] =
105 				cpu_to_le32(((u32) card->silentpage.dma_handle * 2) | pageindex);
106 		}
107 	}
108 
109 	emu10k1_addxmgr_free(card, mem->emupageindex);
110 	mem->emupageindex = -1;
111 }
112 
emu10k1_voice_alloc(struct emu10k1_card * card,struct emu_voice * voice)113 int emu10k1_voice_alloc(struct emu10k1_card *card, struct emu_voice *voice)
114 {
115 	u8 *voicetable = card->voicetable;
116 	int i;
117 	unsigned long flags;
118 
119 	DPF(2, "emu10k1_voice_alloc()\n");
120 
121 	spin_lock_irqsave(&card->lock, flags);
122 
123 	if (voice->flags & VOICE_FLAGS_STEREO) {
124 		for (i = 0; i < NUM_G; i += 2)
125 			if ((voicetable[i] == VOICE_USAGE_FREE) && (voicetable[i + 1] == VOICE_USAGE_FREE)) {
126 				voicetable[i] = voice->usage;
127 				voicetable[i + 1] = voice->usage;
128 				break;
129 			}
130 	} else {
131 		for (i = 0; i < NUM_G; i++)
132 			if (voicetable[i] == VOICE_USAGE_FREE) {
133 				voicetable[i] = voice->usage;
134 				break;
135 			}
136 	}
137 
138 	spin_unlock_irqrestore(&card->lock, flags);
139 
140 	if (i >= NUM_G)
141 		return -1;
142 
143 	voice->card = card;
144 	voice->num = i;
145 
146 	for (i = 0; i < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); i++) {
147 		DPD(2, " voice allocated -> %d\n", voice->num + i);
148 
149 		sblive_writeptr_tag(card, voice->num + i, IFATN, 0xffff,
150 							DCYSUSV, 0,
151 							VTFT, 0x0000ffff,
152 							PTRX, 0,
153 							TAGLIST_END);
154 	}
155 
156 	return 0;
157 }
158 
emu10k1_voice_free(struct emu_voice * voice)159 void emu10k1_voice_free(struct emu_voice *voice)
160 {
161 	struct emu10k1_card *card = voice->card;
162 	int i;
163 	unsigned long flags;
164 
165 	DPF(2, "emu10k1_voice_free()\n");
166 
167 	if (voice->usage == VOICE_USAGE_FREE)
168 		return;
169 
170 	for (i = 0; i < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); i++) {
171 		DPD(2, " voice released -> %d\n", voice->num + i);
172 
173 		sblive_writeptr_tag(card, voice->num + i, DCYSUSV, 0,
174 							VTFT, 0x0000ffff,
175 							PTRX_PITCHTARGET, 0,
176 							CVCF, 0x0000ffff,
177 							//CPF, 0,
178 							TAGLIST_END);
179 
180 		sblive_writeptr(card, CPF, voice->num + i, 0);
181 	}
182 
183 	voice->usage = VOICE_USAGE_FREE;
184 
185 	spin_lock_irqsave(&card->lock, flags);
186 
187 	card->voicetable[voice->num] = VOICE_USAGE_FREE;
188 
189 	if (voice->flags & VOICE_FLAGS_STEREO)
190 		card->voicetable[voice->num + 1] = VOICE_USAGE_FREE;
191 
192 	spin_unlock_irqrestore(&card->lock, flags);
193 }
194 
emu10k1_voice_playback_setup(struct emu_voice * voice)195 void emu10k1_voice_playback_setup(struct emu_voice *voice)
196 {
197 	struct emu10k1_card *card = voice->card;
198 	u32 start;
199 	int i;
200 
201 	DPF(2, "emu10k1_voice_playback_setup()\n");
202 
203 	if (voice->flags & VOICE_FLAGS_STEREO) {
204 		/* Set stereo bit */
205 		start = 28;
206 		sblive_writeptr(card, CPF, voice->num, CPF_STEREO_MASK);
207 		sblive_writeptr(card, CPF, voice->num + 1, CPF_STEREO_MASK);
208 	} else {
209 		start = 30;
210 		sblive_writeptr(card, CPF, voice->num, 0);
211 	}
212 
213 	if(!(voice->flags & VOICE_FLAGS_16BIT))
214 		start *= 2;
215 
216 	voice->start += start;
217 
218 	for (i = 0; i < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); i++) {
219 		sblive_writeptr(card, FXRT, voice->num + i, voice->params[i].send_routing << 16);
220 
221 		/* Stop CA */
222 		/* Assumption that PT is already 0 so no harm overwriting */
223 		sblive_writeptr(card, PTRX, voice->num + i, (voice->params[i].send_a << 8) | voice->params[i].send_b);
224 
225 		sblive_writeptr_tag(card, voice->num + i,
226 				/* CSL, ST, CA */
227 				    DSL, voice->endloop | (voice->params[i].send_d << 24),
228 				    PSST, voice->startloop | (voice->params[i].send_c << 24),
229 				    CCCA, (voice->start) | CCCA_INTERPROM_0 | ((voice->flags & VOICE_FLAGS_16BIT) ? 0 : CCCA_8BITSELECT),
230 				    /* Clear filter delay memory */
231 				    Z1, 0,
232 				    Z2, 0,
233 				    /* Invalidate maps */
234 				    MAPA, MAP_PTI_MASK | ((u32) card->silentpage.dma_handle * 2),
235 				    MAPB, MAP_PTI_MASK | ((u32) card->silentpage.dma_handle * 2),
236 				/* modulation envelope */
237 				    CVCF, 0x0000ffff,
238 				    VTFT, 0x0000ffff,
239 				    ATKHLDM, 0,
240 				    DCYSUSM, 0x007f,
241 				    LFOVAL1, 0x8000,
242 				    LFOVAL2, 0x8000,
243 				    FMMOD, 0,
244 				    TREMFRQ, 0,
245 				    FM2FRQ2, 0,
246 				    ENVVAL, 0x8000,
247 				/* volume envelope */
248 				    ATKHLDV, 0x7f7f,
249 				    ENVVOL, 0x8000,
250 				/* filter envelope */
251 				    PEFE_FILTERAMOUNT, 0x7f,
252 				/* pitch envelope */
253 				    PEFE_PITCHAMOUNT, 0, TAGLIST_END);
254 
255 		voice->params[i].fc_target = 0xffff;
256 	}
257 }
258 
emu10k1_voices_start(struct emu_voice * first_voice,unsigned int num_voices,int set)259 void emu10k1_voices_start(struct emu_voice *first_voice, unsigned int num_voices, int set)
260 {
261 	struct emu10k1_card *card = first_voice->card;
262 	struct emu_voice *voice;
263 	unsigned int voicenum;
264 	int j;
265 
266 	DPF(2, "emu10k1_voices_start()\n");
267 
268 	for (voicenum = 0; voicenum < num_voices; voicenum++)
269 	{
270 		voice = first_voice + voicenum;
271 
272 		if (!set) {
273 			u32 cra, ccis, cs, sample;
274 			if (voice->flags & VOICE_FLAGS_STEREO) {
275 				cra = 64;
276 				ccis = 28;
277 				cs = 4;
278 			} else {
279 				cra = 64;
280 				ccis = 30;
281 				cs = 2;
282 			}
283 
284 			if(voice->flags & VOICE_FLAGS_16BIT) {
285 				sample = 0x00000000;
286 			} else {
287 				sample = 0x80808080;
288 				ccis *= 2;
289 			}
290 
291 			for(j = 0; j < cs; j++)
292 	        	        sblive_writeptr(card, CD0 + j, voice->num, sample);
293 
294 			/* Reset cache */
295 			sblive_writeptr(card, CCR_CACHEINVALIDSIZE, voice->num, 0);
296 			if (voice->flags & VOICE_FLAGS_STEREO)
297 				sblive_writeptr(card, CCR_CACHEINVALIDSIZE, voice->num + 1, 0);
298 
299 			sblive_writeptr(card, CCR_READADDRESS, voice->num, cra);
300 
301 			if (voice->flags & VOICE_FLAGS_STEREO)
302 				sblive_writeptr(card, CCR_READADDRESS, voice->num + 1, cra);
303 
304 			/* Fill cache */
305 			sblive_writeptr(card, CCR_CACHEINVALIDSIZE, voice->num, ccis);
306 		}
307 
308 		for (j = 0; j < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); j++) {
309 			sblive_writeptr_tag(card, voice->num + j,
310 				    IFATN, (voice->params[j].initial_fc << 8) | voice->params[j].initial_attn,
311 				    VTFT, (voice->params[j].volume_target << 16) | voice->params[j].fc_target,
312 				    CVCF, (voice->params[j].volume_target << 16) | voice->params[j].fc_target,
313 				    DCYSUSV, (voice->params[j].byampl_env_sustain << 8) | voice->params[j].byampl_env_decay,
314 				    TAGLIST_END);
315 
316 			emu10k1_clear_stop_on_loop(card, voice->num + j);
317 		}
318 	}
319 
320 
321         for (voicenum = 0; voicenum < num_voices; voicenum++)
322 	{
323 		voice = first_voice + voicenum;
324 
325 		for (j = 0; j < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); j++) {
326 			sblive_writeptr(card, PTRX_PITCHTARGET, voice->num + j, voice->pitch_target);
327 
328 			if (j == 0)
329 				sblive_writeptr(card, CPF_CURRENTPITCH, voice->num, voice->pitch_target);
330 
331 			sblive_writeptr(card, IP, voice->num + j, voice->initial_pitch);
332 		}
333 	}
334 }
335 
emu10k1_voices_stop(struct emu_voice * first_voice,int num_voices)336 void emu10k1_voices_stop(struct emu_voice *first_voice, int num_voices)
337 {
338 	struct emu10k1_card *card = first_voice->card;
339 	struct emu_voice *voice;
340 	unsigned int voice_num;
341 	int j;
342 
343 	DPF(2, "emu10k1_voice_stop()\n");
344 
345         for (voice_num = 0; voice_num < num_voices; voice_num++)
346 	{
347 		voice = first_voice + voice_num;
348 
349 		for (j = 0; j < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); j++) {
350 			sblive_writeptr_tag(card, voice->num + j,
351 						PTRX_PITCHTARGET, 0,
352 						CPF_CURRENTPITCH, 0,
353 						IFATN, 0xffff,
354 						VTFT, 0x0000ffff,
355 						CVCF, 0x0000ffff,
356 						IP, 0,
357 						TAGLIST_END);
358 		}
359 	}
360 }
361 
362