Merge phase #3 (IOMMU) of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux...
[linux-2.6] / sound / pci / emu10k1 / emu10k1_callback.c
1 /*
2  *  synth callback routines for Emu10k1
3  *
4  *  Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19  */
20
21 #include "emu10k1_synth_local.h"
22 #include <sound/asoundef.h>
23
24 /* voice status */
25 enum {
26         V_FREE=0, V_OFF, V_RELEASED, V_PLAYING, V_END
27 };
28
29 /* Keeps track of what we are finding */
30 struct best_voice {
31         unsigned int time;
32         int voice;
33 };
34
35 /*
36  * prototypes
37  */
38 static void lookup_voices(struct snd_emux *emux, struct snd_emu10k1 *hw,
39                           struct best_voice *best, int active_only);
40 static struct snd_emux_voice *get_voice(struct snd_emux *emux,
41                                         struct snd_emux_port *port);
42 static int start_voice(struct snd_emux_voice *vp);
43 static void trigger_voice(struct snd_emux_voice *vp);
44 static void release_voice(struct snd_emux_voice *vp);
45 static void update_voice(struct snd_emux_voice *vp, int update);
46 static void terminate_voice(struct snd_emux_voice *vp);
47 static void free_voice(struct snd_emux_voice *vp);
48 static void set_fmmod(struct snd_emu10k1 *hw, struct snd_emux_voice *vp);
49 static void set_fm2frq2(struct snd_emu10k1 *hw, struct snd_emux_voice *vp);
50 static void set_filterQ(struct snd_emu10k1 *hw, struct snd_emux_voice *vp);
51
52 /*
53  * Ensure a value is between two points
54  * macro evaluates its args more than once, so changed to upper-case.
55  */
56 #define LIMITVALUE(x, a, b) do { if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b); } while (0)
57 #define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0)
58
59
60 /*
61  * set up operators
62  */
63 static struct snd_emux_operators emu10k1_ops = {
64         .owner =        THIS_MODULE,
65         .get_voice =    get_voice,
66         .prepare =      start_voice,
67         .trigger =      trigger_voice,
68         .release =      release_voice,
69         .update =       update_voice,
70         .terminate =    terminate_voice,
71         .free_voice =   free_voice,
72         .sample_new =   snd_emu10k1_sample_new,
73         .sample_free =  snd_emu10k1_sample_free,
74 };
75
76 void
77 snd_emu10k1_ops_setup(struct snd_emux *emux)
78 {
79         emux->ops = emu10k1_ops;
80 }
81
82
83 /*
84  * get more voice for pcm
85  *
86  * terminate most inactive voice and give it as a pcm voice.
87  */
88 int
89 snd_emu10k1_synth_get_voice(struct snd_emu10k1 *hw)
90 {
91         struct snd_emux *emu;
92         struct snd_emux_voice *vp;
93         struct best_voice best[V_END];
94         unsigned long flags;
95         int i;
96
97         emu = hw->synth;
98
99         spin_lock_irqsave(&emu->voice_lock, flags);
100         lookup_voices(emu, hw, best, 1); /* no OFF voices */
101         for (i = 0; i < V_END; i++) {
102                 if (best[i].voice >= 0) {
103                         int ch;
104                         vp = &emu->voices[best[i].voice];
105                         if ((ch = vp->ch) < 0) {
106                                 //printk("synth_get_voice: ch < 0 (%d) ??", i);
107                                 continue;
108                         }
109                         vp->emu->num_voices--;
110                         vp->ch = -1;
111                         vp->state = SNDRV_EMUX_ST_OFF;
112                         spin_unlock_irqrestore(&emu->voice_lock, flags);
113                         return ch;
114                 }
115         }
116         spin_unlock_irqrestore(&emu->voice_lock, flags);
117
118         /* not found */
119         return -ENOMEM;
120 }
121
122
123 /*
124  * turn off the voice (not terminated)
125  */
126 static void
127 release_voice(struct snd_emux_voice *vp)
128 {
129         int dcysusv;
130         struct snd_emu10k1 *hw;
131         
132         hw = vp->hw;
133         dcysusv = 0x8000 | (unsigned char)vp->reg.parm.modrelease;
134         snd_emu10k1_ptr_write(hw, DCYSUSM, vp->ch, dcysusv);
135         dcysusv = 0x8000 | (unsigned char)vp->reg.parm.volrelease | DCYSUSV_CHANNELENABLE_MASK;
136         snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, dcysusv);
137 }
138
139
140 /*
141  * terminate the voice
142  */
143 static void
144 terminate_voice(struct snd_emux_voice *vp)
145 {
146         struct snd_emu10k1 *hw;
147         
148         if (snd_BUG_ON(!vp))
149                 return;
150         hw = vp->hw;
151         snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK);
152         if (vp->block) {
153                 struct snd_emu10k1_memblk *emem;
154                 emem = (struct snd_emu10k1_memblk *)vp->block;
155                 if (emem->map_locked > 0)
156                         emem->map_locked--;
157         }
158 }
159
160 /*
161  * release the voice to system
162  */
163 static void
164 free_voice(struct snd_emux_voice *vp)
165 {
166         struct snd_emu10k1 *hw;
167         
168         hw = vp->hw;
169         /* FIXME: emu10k1_synth is broken. */
170         /* This can get called with hw == 0 */
171         /* Problem apparent on plug, unplug then plug */
172         /* on the Audigy 2 ZS Notebook. */
173         if (hw && (vp->ch >= 0)) {
174                 snd_emu10k1_ptr_write(hw, IFATN, vp->ch, 0xff00);
175                 snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK);
176                 // snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0);
177                 snd_emu10k1_ptr_write(hw, VTFT, vp->ch, 0xffff);
178                 snd_emu10k1_ptr_write(hw, CVCF, vp->ch, 0xffff);
179                 snd_emu10k1_voice_free(hw, &hw->voices[vp->ch]);
180                 vp->emu->num_voices--;
181                 vp->ch = -1;
182         }
183 }
184
185
186 /*
187  * update registers
188  */
189 static void
190 update_voice(struct snd_emux_voice *vp, int update)
191 {
192         struct snd_emu10k1 *hw;
193         
194         hw = vp->hw;
195         if (update & SNDRV_EMUX_UPDATE_VOLUME)
196                 snd_emu10k1_ptr_write(hw, IFATN_ATTENUATION, vp->ch, vp->avol);
197         if (update & SNDRV_EMUX_UPDATE_PITCH)
198                 snd_emu10k1_ptr_write(hw, IP, vp->ch, vp->apitch);
199         if (update & SNDRV_EMUX_UPDATE_PAN) {
200                 snd_emu10k1_ptr_write(hw, PTRX_FXSENDAMOUNT_A, vp->ch, vp->apan);
201                 snd_emu10k1_ptr_write(hw, PTRX_FXSENDAMOUNT_B, vp->ch, vp->aaux);
202         }
203         if (update & SNDRV_EMUX_UPDATE_FMMOD)
204                 set_fmmod(hw, vp);
205         if (update & SNDRV_EMUX_UPDATE_TREMFREQ)
206                 snd_emu10k1_ptr_write(hw, TREMFRQ, vp->ch, vp->reg.parm.tremfrq);
207         if (update & SNDRV_EMUX_UPDATE_FM2FRQ2)
208                 set_fm2frq2(hw, vp);
209         if (update & SNDRV_EMUX_UPDATE_Q)
210                 set_filterQ(hw, vp);
211 }
212
213
214 /*
215  * look up voice table - get the best voice in order of preference
216  */
217 /* spinlock held! */
218 static void
219 lookup_voices(struct snd_emux *emu, struct snd_emu10k1 *hw,
220               struct best_voice *best, int active_only)
221 {
222         struct snd_emux_voice *vp;
223         struct best_voice *bp;
224         int  i;
225
226         for (i = 0; i < V_END; i++) {
227                 best[i].time = (unsigned int)-1; /* XXX MAX_?INT really */;
228                 best[i].voice = -1;
229         }
230
231         /*
232          * Go through them all and get a best one to use.
233          * NOTE: could also look at volume and pick the quietest one.
234          */
235         for (i = 0; i < emu->max_voices; i++) {
236                 int state, val;
237
238                 vp = &emu->voices[i];
239                 state = vp->state;
240                 if (state == SNDRV_EMUX_ST_OFF) {
241                         if (vp->ch < 0) {
242                                 if (active_only)
243                                         continue;
244                                 bp = best + V_FREE;
245                         } else
246                                 bp = best + V_OFF;
247                 }
248                 else if (state == SNDRV_EMUX_ST_RELEASED ||
249                          state == SNDRV_EMUX_ST_PENDING) {
250                         bp = best + V_RELEASED;
251 #if 1
252                         val = snd_emu10k1_ptr_read(hw, CVCF_CURRENTVOL, vp->ch);
253                         if (! val)
254                                 bp = best + V_OFF;
255 #endif
256                 }
257                 else if (state == SNDRV_EMUX_ST_STANDBY)
258                         continue;
259                 else if (state & SNDRV_EMUX_ST_ON)
260                         bp = best + V_PLAYING;
261                 else
262                         continue;
263
264                 /* check if sample is finished playing (non-looping only) */
265                 if (bp != best + V_OFF && bp != best + V_FREE &&
266                     (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_SINGLESHOT)) {
267                         val = snd_emu10k1_ptr_read(hw, CCCA_CURRADDR, vp->ch);
268                         if (val >= vp->reg.loopstart)
269                                 bp = best + V_OFF;
270                 }
271
272                 if (vp->time < bp->time) {
273                         bp->time = vp->time;
274                         bp->voice = i;
275                 }
276         }
277 }
278
279 /*
280  * get an empty voice
281  *
282  * emu->voice_lock is already held.
283  */
284 static struct snd_emux_voice *
285 get_voice(struct snd_emux *emu, struct snd_emux_port *port)
286 {
287         struct snd_emu10k1 *hw;
288         struct snd_emux_voice *vp;
289         struct best_voice best[V_END];
290         int i;
291
292         hw = emu->hw;
293
294         lookup_voices(emu, hw, best, 0);
295         for (i = 0; i < V_END; i++) {
296                 if (best[i].voice >= 0) {
297                         vp = &emu->voices[best[i].voice];
298                         if (vp->ch < 0) {
299                                 /* allocate a voice */
300                                 struct snd_emu10k1_voice *hwvoice;
301                                 if (snd_emu10k1_voice_alloc(hw, EMU10K1_SYNTH, 1, &hwvoice) < 0 || hwvoice == NULL)
302                                         continue;
303                                 vp->ch = hwvoice->number;
304                                 emu->num_voices++;
305                         }
306                         return vp;
307                 }
308         }
309
310         /* not found */
311         return NULL;
312 }
313
314 /*
315  * prepare envelopes and LFOs
316  */
317 static int
318 start_voice(struct snd_emux_voice *vp)
319 {
320         unsigned int temp;
321         int ch;
322         unsigned int addr, mapped_offset;
323         struct snd_midi_channel *chan;
324         struct snd_emu10k1 *hw;
325         struct snd_emu10k1_memblk *emem;
326         
327         hw = vp->hw;
328         ch = vp->ch;
329         if (snd_BUG_ON(ch < 0))
330                 return -EINVAL;
331         chan = vp->chan;
332
333         emem = (struct snd_emu10k1_memblk *)vp->block;
334         if (emem == NULL)
335                 return -EINVAL;
336         emem->map_locked++;
337         if (snd_emu10k1_memblk_map(hw, emem) < 0) {
338                 // printk("emu: cannot map!\n");
339                 return -ENOMEM;
340         }
341         mapped_offset = snd_emu10k1_memblk_offset(emem) >> 1;
342         vp->reg.start += mapped_offset;
343         vp->reg.end += mapped_offset;
344         vp->reg.loopstart += mapped_offset;
345         vp->reg.loopend += mapped_offset;
346
347         /* set channel routing */
348         /* A = left(0), B = right(1), C = reverb(c), D = chorus(d) */
349         if (hw->audigy) {
350                 temp = FXBUS_MIDI_LEFT | (FXBUS_MIDI_RIGHT << 8) | 
351                         (FXBUS_MIDI_REVERB << 16) | (FXBUS_MIDI_CHORUS << 24);
352                 snd_emu10k1_ptr_write(hw, A_FXRT1, ch, temp);
353         } else {
354                 temp = (FXBUS_MIDI_LEFT << 16) | (FXBUS_MIDI_RIGHT << 20) | 
355                         (FXBUS_MIDI_REVERB << 24) | (FXBUS_MIDI_CHORUS << 28);
356                 snd_emu10k1_ptr_write(hw, FXRT, ch, temp);
357         }
358
359         /* channel to be silent and idle */
360         snd_emu10k1_ptr_write(hw, DCYSUSV, ch, 0x0000);
361         snd_emu10k1_ptr_write(hw, VTFT, ch, 0x0000FFFF);
362         snd_emu10k1_ptr_write(hw, CVCF, ch, 0x0000FFFF);
363         snd_emu10k1_ptr_write(hw, PTRX, ch, 0);
364         snd_emu10k1_ptr_write(hw, CPF, ch, 0);
365
366         /* set pitch offset */
367         snd_emu10k1_ptr_write(hw, IP, vp->ch, vp->apitch);
368
369         /* set envelope parameters */
370         snd_emu10k1_ptr_write(hw, ENVVAL, ch, vp->reg.parm.moddelay);
371         snd_emu10k1_ptr_write(hw, ATKHLDM, ch, vp->reg.parm.modatkhld);
372         snd_emu10k1_ptr_write(hw, DCYSUSM, ch, vp->reg.parm.moddcysus);
373         snd_emu10k1_ptr_write(hw, ENVVOL, ch, vp->reg.parm.voldelay);
374         snd_emu10k1_ptr_write(hw, ATKHLDV, ch, vp->reg.parm.volatkhld);
375         /* decay/sustain parameter for volume envelope is used
376            for triggerg the voice */
377
378         /* cutoff and volume */
379         temp = (unsigned int)vp->acutoff << 8 | (unsigned char)vp->avol;
380         snd_emu10k1_ptr_write(hw, IFATN, vp->ch, temp);
381
382         /* modulation envelope heights */
383         snd_emu10k1_ptr_write(hw, PEFE, ch, vp->reg.parm.pefe);
384
385         /* lfo1/2 delay */
386         snd_emu10k1_ptr_write(hw, LFOVAL1, ch, vp->reg.parm.lfo1delay);
387         snd_emu10k1_ptr_write(hw, LFOVAL2, ch, vp->reg.parm.lfo2delay);
388
389         /* lfo1 pitch & cutoff shift */
390         set_fmmod(hw, vp);
391         /* lfo1 volume & freq */
392         snd_emu10k1_ptr_write(hw, TREMFRQ, vp->ch, vp->reg.parm.tremfrq);
393         /* lfo2 pitch & freq */
394         set_fm2frq2(hw, vp);
395
396         /* reverb and loop start (reverb 8bit, MSB) */
397         temp = vp->reg.parm.reverb;
398         temp += (int)vp->chan->control[MIDI_CTL_E1_REVERB_DEPTH] * 9 / 10;
399         LIMITMAX(temp, 255);
400         addr = vp->reg.loopstart;
401         snd_emu10k1_ptr_write(hw, PSST, vp->ch, (temp << 24) | addr);
402
403         /* chorus & loop end (chorus 8bit, MSB) */
404         addr = vp->reg.loopend;
405         temp = vp->reg.parm.chorus;
406         temp += (int)chan->control[MIDI_CTL_E3_CHORUS_DEPTH] * 9 / 10;
407         LIMITMAX(temp, 255);
408         temp = (temp <<24) | addr;
409         snd_emu10k1_ptr_write(hw, DSL, ch, temp);
410
411         /* clear filter delay memory */
412         snd_emu10k1_ptr_write(hw, Z1, ch, 0);
413         snd_emu10k1_ptr_write(hw, Z2, ch, 0);
414
415         /* invalidate maps */
416         temp = (hw->silent_page.addr << 1) | MAP_PTI_MASK;
417         snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
418         snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
419 #if 0
420         /* cache */
421         {
422                 unsigned int val, sample;
423                 val = 32;
424                 if (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS)
425                         sample = 0x80808080;
426                 else {
427                         sample = 0;
428                         val *= 2;
429                 }
430
431                 /* cache */
432                 snd_emu10k1_ptr_write(hw, CCR, ch, 0x1c << 16);
433                 snd_emu10k1_ptr_write(hw, CDE, ch, sample);
434                 snd_emu10k1_ptr_write(hw, CDF, ch, sample);
435
436                 /* invalidate maps */
437                 temp = ((unsigned int)hw->silent_page.addr << 1) | MAP_PTI_MASK;
438                 snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
439                 snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
440                 
441                 /* fill cache */
442                 val -= 4;
443                 val <<= 25;
444                 val |= 0x1c << 16;
445                 snd_emu10k1_ptr_write(hw, CCR, ch, val);
446         }
447 #endif
448
449         /* Q & current address (Q 4bit value, MSB) */
450         addr = vp->reg.start;
451         temp = vp->reg.parm.filterQ;
452         temp = (temp<<28) | addr;
453         if (vp->apitch < 0xe400)
454                 temp |= CCCA_INTERPROM_0;
455         else {
456                 unsigned int shift = (vp->apitch - 0xe000) >> 10;
457                 temp |= shift << 25;
458         }
459         if (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS)
460                 temp |= CCCA_8BITSELECT;
461         snd_emu10k1_ptr_write(hw, CCCA, ch, temp);
462
463         /* reset volume */
464         temp = (unsigned int)vp->vtarget << 16;
465         snd_emu10k1_ptr_write(hw, VTFT, ch, temp | vp->ftarget);
466         snd_emu10k1_ptr_write(hw, CVCF, ch, temp | 0xff00);
467         return 0;
468 }
469
470 /*
471  * Start envelope
472  */
473 static void
474 trigger_voice(struct snd_emux_voice *vp)
475 {
476         unsigned int temp, ptarget;
477         struct snd_emu10k1 *hw;
478         struct snd_emu10k1_memblk *emem;
479         
480         hw = vp->hw;
481
482         emem = (struct snd_emu10k1_memblk *)vp->block;
483         if (! emem || emem->mapped_page < 0)
484                 return; /* not mapped */
485
486 #if 0
487         ptarget = (unsigned int)vp->ptarget << 16;
488 #else
489         ptarget = IP_TO_CP(vp->apitch);
490 #endif
491         /* set pitch target and pan (volume) */
492         temp = ptarget | (vp->apan << 8) | vp->aaux;
493         snd_emu10k1_ptr_write(hw, PTRX, vp->ch, temp);
494
495         /* pitch target */
496         snd_emu10k1_ptr_write(hw, CPF, vp->ch, ptarget);
497
498         /* trigger voice */
499         snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, vp->reg.parm.voldcysus|DCYSUSV_CHANNELENABLE_MASK);
500 }
501
502 #define MOD_SENSE 18
503
504 /* set lfo1 modulation height and cutoff */
505 static void
506 set_fmmod(struct snd_emu10k1 *hw, struct snd_emux_voice *vp)
507 {
508         unsigned short fmmod;
509         short pitch;
510         unsigned char cutoff;
511         int modulation;
512
513         pitch = (char)(vp->reg.parm.fmmod>>8);
514         cutoff = (vp->reg.parm.fmmod & 0xff);
515         modulation = vp->chan->gm_modulation + vp->chan->midi_pressure;
516         pitch += (MOD_SENSE * modulation) / 1200;
517         LIMITVALUE(pitch, -128, 127);
518         fmmod = ((unsigned char)pitch<<8) | cutoff;
519         snd_emu10k1_ptr_write(hw, FMMOD, vp->ch, fmmod);
520 }
521
522 /* set lfo2 pitch & frequency */
523 static void
524 set_fm2frq2(struct snd_emu10k1 *hw, struct snd_emux_voice *vp)
525 {
526         unsigned short fm2frq2;
527         short pitch;
528         unsigned char freq;
529         int modulation;
530
531         pitch = (char)(vp->reg.parm.fm2frq2>>8);
532         freq = vp->reg.parm.fm2frq2 & 0xff;
533         modulation = vp->chan->gm_modulation + vp->chan->midi_pressure;
534         pitch += (MOD_SENSE * modulation) / 1200;
535         LIMITVALUE(pitch, -128, 127);
536         fm2frq2 = ((unsigned char)pitch<<8) | freq;
537         snd_emu10k1_ptr_write(hw, FM2FRQ2, vp->ch, fm2frq2);
538 }
539
540 /* set filterQ */
541 static void
542 set_filterQ(struct snd_emu10k1 *hw, struct snd_emux_voice *vp)
543 {
544         unsigned int val;
545         val = snd_emu10k1_ptr_read(hw, CCCA, vp->ch) & ~CCCA_RESONANCE;
546         val |= (vp->reg.parm.filterQ << 28);
547         snd_emu10k1_ptr_write(hw, CCCA, vp->ch, val);
548 }