Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / sound / pci / emu10k1 / emumixer.c
1 /*
2  *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
3  *                   Takashi Iwai <tiwai@suse.de>
4  *                   Creative Labs, Inc.
5  *  Routines for control of EMU10K1 chips / mixer routines
6  *  Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com>
7  *
8  *  BUGS:
9  *    --
10  *
11  *  TODO:
12  *    --
13  *
14  *   This program is free software; you can redistribute it and/or modify
15  *   it under the terms of the GNU General Public License as published by
16  *   the Free Software Foundation; either version 2 of the License, or
17  *   (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 License
25  *   along with this program; if not, write to the Free Software
26  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
27  *
28  */
29
30 #include <sound/driver.h>
31 #include <linux/time.h>
32 #include <linux/init.h>
33 #include <sound/core.h>
34 #include <sound/emu10k1.h>
35
36 #define AC97_ID_STAC9758        0x83847658
37
38 static int snd_emu10k1_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
39 {
40         uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
41         uinfo->count = 1;
42         return 0;
43 }
44
45 static int snd_emu10k1_spdif_get(snd_kcontrol_t * kcontrol,
46                                  snd_ctl_elem_value_t * ucontrol)
47 {
48         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
49         unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
50         unsigned long flags;
51
52         spin_lock_irqsave(&emu->reg_lock, flags);
53         ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
54         ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
55         ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
56         ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
57         spin_unlock_irqrestore(&emu->reg_lock, flags);
58         return 0;
59 }
60
61 static int snd_emu10k1_spdif_get_mask(snd_kcontrol_t * kcontrol,
62                                       snd_ctl_elem_value_t * ucontrol)
63 {
64         ucontrol->value.iec958.status[0] = 0xff;
65         ucontrol->value.iec958.status[1] = 0xff;
66         ucontrol->value.iec958.status[2] = 0xff;
67         ucontrol->value.iec958.status[3] = 0xff;
68         return 0;
69 }
70
71 static int snd_audigy_spdif_output_rate_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
72 {
73         static char *texts[] = {"44100", "48000", "96000"};
74
75         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
76         uinfo->count = 1;
77         uinfo->value.enumerated.items = 3;
78         if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
79                 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
80         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
81         return 0;
82 }
83
84 static int snd_audigy_spdif_output_rate_get(snd_kcontrol_t * kcontrol,
85                                  snd_ctl_elem_value_t * ucontrol)
86 {
87         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
88         unsigned int tmp;
89         unsigned long flags;
90         
91
92         spin_lock_irqsave(&emu->reg_lock, flags);
93         tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
94         switch (tmp & A_SPDIF_RATE_MASK) {
95         case A_SPDIF_44100:
96                 ucontrol->value.enumerated.item[0] = 0;
97                 break;
98         case A_SPDIF_48000:
99                 ucontrol->value.enumerated.item[0] = 1;
100                 break;
101         case A_SPDIF_96000:
102                 ucontrol->value.enumerated.item[0] = 2;
103                 break;
104         default:
105                 ucontrol->value.enumerated.item[0] = 1;
106         }
107         spin_unlock_irqrestore(&emu->reg_lock, flags);
108         return 0;
109 }
110
111 static int snd_audigy_spdif_output_rate_put(snd_kcontrol_t * kcontrol,
112                                  snd_ctl_elem_value_t * ucontrol)
113 {
114         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
115         int change;
116         unsigned int reg, val, tmp;
117         unsigned long flags;
118
119         switch(ucontrol->value.enumerated.item[0]) {
120         case 0:
121                 val = A_SPDIF_44100;
122                 break;
123         case 1:
124                 val = A_SPDIF_48000;
125                 break;
126         case 2:
127                 val = A_SPDIF_96000;
128                 break;
129         default:
130                 val = A_SPDIF_48000;
131                 break;
132         }
133
134         
135         spin_lock_irqsave(&emu->reg_lock, flags);
136         reg = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
137         tmp = reg & ~A_SPDIF_RATE_MASK;
138         tmp |= val;
139         if ((change = (tmp != reg)))
140                 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
141         spin_unlock_irqrestore(&emu->reg_lock, flags);
142         return change;
143 }
144
145 static snd_kcontrol_new_t snd_audigy_spdif_output_rate =
146 {
147         .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE,
148         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
149         .name =         "Audigy SPDIF Output Sample Rate",
150         .count =        1,
151         .info =         snd_audigy_spdif_output_rate_info,
152         .get =          snd_audigy_spdif_output_rate_get,
153         .put =          snd_audigy_spdif_output_rate_put
154 };
155
156 static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol,
157                                  snd_ctl_elem_value_t * ucontrol)
158 {
159         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
160         unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
161         int change;
162         unsigned int val;
163         unsigned long flags;
164
165         val = (ucontrol->value.iec958.status[0] << 0) |
166               (ucontrol->value.iec958.status[1] << 8) |
167               (ucontrol->value.iec958.status[2] << 16) |
168               (ucontrol->value.iec958.status[3] << 24);
169         spin_lock_irqsave(&emu->reg_lock, flags);
170         change = val != emu->spdif_bits[idx];
171         if (change) {
172                 snd_emu10k1_ptr_write(emu, SPCS0 + idx, 0, val);
173                 emu->spdif_bits[idx] = val;
174         }
175         spin_unlock_irqrestore(&emu->reg_lock, flags);
176         return change;
177 }
178
179 static snd_kcontrol_new_t snd_emu10k1_spdif_mask_control =
180 {
181         .access =       SNDRV_CTL_ELEM_ACCESS_READ,
182         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
183         .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
184         .count =        4,
185         .info =         snd_emu10k1_spdif_info,
186         .get =          snd_emu10k1_spdif_get_mask
187 };
188
189 static snd_kcontrol_new_t snd_emu10k1_spdif_control =
190 {
191         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
192         .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
193         .count =        4,
194         .info =         snd_emu10k1_spdif_info,
195         .get =          snd_emu10k1_spdif_get,
196         .put =          snd_emu10k1_spdif_put
197 };
198
199
200 static void update_emu10k1_fxrt(emu10k1_t *emu, int voice, unsigned char *route)
201 {
202         if (emu->audigy) {
203                 snd_emu10k1_ptr_write(emu, A_FXRT1, voice,
204                                       snd_emu10k1_compose_audigy_fxrt1(route));
205                 snd_emu10k1_ptr_write(emu, A_FXRT2, voice,
206                                       snd_emu10k1_compose_audigy_fxrt2(route));
207         } else {
208                 snd_emu10k1_ptr_write(emu, FXRT, voice,
209                                       snd_emu10k1_compose_send_routing(route));
210         }
211 }
212
213 static void update_emu10k1_send_volume(emu10k1_t *emu, int voice, unsigned char *volume)
214 {
215         snd_emu10k1_ptr_write(emu, PTRX_FXSENDAMOUNT_A, voice, volume[0]);
216         snd_emu10k1_ptr_write(emu, PTRX_FXSENDAMOUNT_B, voice, volume[1]);
217         snd_emu10k1_ptr_write(emu, PSST_FXSENDAMOUNT_C, voice, volume[2]);
218         snd_emu10k1_ptr_write(emu, DSL_FXSENDAMOUNT_D, voice, volume[3]);
219         if (emu->audigy) {
220                 unsigned int val = ((unsigned int)volume[4] << 24) |
221                         ((unsigned int)volume[5] << 16) |
222                         ((unsigned int)volume[6] << 8) |
223                         (unsigned int)volume[7];
224                 snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, voice, val);
225         }
226 }
227
228 /* PCM stream controls */
229
230 static int snd_emu10k1_send_routing_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
231 {
232         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
233         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
234         uinfo->count = emu->audigy ? 3*8 : 3*4;
235         uinfo->value.integer.min = 0;
236         uinfo->value.integer.max = emu->audigy ? 0x3f : 0x0f;
237         return 0;
238 }
239
240 static int snd_emu10k1_send_routing_get(snd_kcontrol_t * kcontrol,
241                                         snd_ctl_elem_value_t * ucontrol)
242 {
243         unsigned long flags;
244         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
245         emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
246         int voice, idx;
247         int num_efx = emu->audigy ? 8 : 4;
248         int mask = emu->audigy ? 0x3f : 0x0f;
249
250         spin_lock_irqsave(&emu->reg_lock, flags);
251         for (voice = 0; voice < 3; voice++)
252                 for (idx = 0; idx < num_efx; idx++)
253                         ucontrol->value.integer.value[(voice * num_efx) + idx] = 
254                                 mix->send_routing[voice][idx] & mask;
255         spin_unlock_irqrestore(&emu->reg_lock, flags);
256         return 0;
257 }
258
259 static int snd_emu10k1_send_routing_put(snd_kcontrol_t * kcontrol,
260                                         snd_ctl_elem_value_t * ucontrol)
261 {
262         unsigned long flags;
263         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
264         emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
265         int change = 0, voice, idx, val;
266         int num_efx = emu->audigy ? 8 : 4;
267         int mask = emu->audigy ? 0x3f : 0x0f;
268
269         spin_lock_irqsave(&emu->reg_lock, flags);
270         for (voice = 0; voice < 3; voice++)
271                 for (idx = 0; idx < num_efx; idx++) {
272                         val = ucontrol->value.integer.value[(voice * num_efx) + idx] & mask;
273                         if (mix->send_routing[voice][idx] != val) {
274                                 mix->send_routing[voice][idx] = val;
275                                 change = 1;
276                         }
277                 }       
278         if (change && mix->epcm) {
279                 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
280                         update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number,
281                                             &mix->send_routing[1][0]);
282                         update_emu10k1_fxrt(emu, mix->epcm->voices[1]->number,
283                                             &mix->send_routing[2][0]);
284                 } else if (mix->epcm->voices[0]) {
285                         update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number,
286                                             &mix->send_routing[0][0]);
287                 }
288         }
289         spin_unlock_irqrestore(&emu->reg_lock, flags);
290         return change;
291 }
292
293 static snd_kcontrol_new_t snd_emu10k1_send_routing_control =
294 {
295         .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
296         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
297         .name =         "EMU10K1 PCM Send Routing",
298         .count =        32,
299         .info =         snd_emu10k1_send_routing_info,
300         .get =          snd_emu10k1_send_routing_get,
301         .put =          snd_emu10k1_send_routing_put
302 };
303
304 static int snd_emu10k1_send_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
305 {
306         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
307         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
308         uinfo->count = emu->audigy ? 3*8 : 3*4;
309         uinfo->value.integer.min = 0;
310         uinfo->value.integer.max = 255;
311         return 0;
312 }
313
314 static int snd_emu10k1_send_volume_get(snd_kcontrol_t * kcontrol,
315                                        snd_ctl_elem_value_t * ucontrol)
316 {
317         unsigned long flags;
318         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
319         emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
320         int idx;
321         int num_efx = emu->audigy ? 8 : 4;
322
323         spin_lock_irqsave(&emu->reg_lock, flags);
324         for (idx = 0; idx < 3*num_efx; idx++)
325                 ucontrol->value.integer.value[idx] = mix->send_volume[idx/num_efx][idx%num_efx];
326         spin_unlock_irqrestore(&emu->reg_lock, flags);
327         return 0;
328 }
329
330 static int snd_emu10k1_send_volume_put(snd_kcontrol_t * kcontrol,
331                                        snd_ctl_elem_value_t * ucontrol)
332 {
333         unsigned long flags;
334         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
335         emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
336         int change = 0, idx, val;
337         int num_efx = emu->audigy ? 8 : 4;
338
339         spin_lock_irqsave(&emu->reg_lock, flags);
340         for (idx = 0; idx < 3*num_efx; idx++) {
341                 val = ucontrol->value.integer.value[idx] & 255;
342                 if (mix->send_volume[idx/num_efx][idx%num_efx] != val) {
343                         mix->send_volume[idx/num_efx][idx%num_efx] = val;
344                         change = 1;
345                 }
346         }
347         if (change && mix->epcm) {
348                 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
349                         update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number,
350                                                    &mix->send_volume[1][0]);
351                         update_emu10k1_send_volume(emu, mix->epcm->voices[1]->number,
352                                                    &mix->send_volume[2][0]);
353                 } else if (mix->epcm->voices[0]) {
354                         update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number,
355                                                    &mix->send_volume[0][0]);
356                 }
357         }
358         spin_unlock_irqrestore(&emu->reg_lock, flags);
359         return change;
360 }
361
362 static snd_kcontrol_new_t snd_emu10k1_send_volume_control =
363 {
364         .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
365         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
366         .name =         "EMU10K1 PCM Send Volume",
367         .count =        32,
368         .info =         snd_emu10k1_send_volume_info,
369         .get =          snd_emu10k1_send_volume_get,
370         .put =          snd_emu10k1_send_volume_put
371 };
372
373 static int snd_emu10k1_attn_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
374 {
375         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
376         uinfo->count = 3;
377         uinfo->value.integer.min = 0;
378         uinfo->value.integer.max = 0xffff;
379         return 0;
380 }
381
382 static int snd_emu10k1_attn_get(snd_kcontrol_t * kcontrol,
383                                 snd_ctl_elem_value_t * ucontrol)
384 {
385         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
386         emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
387         unsigned long flags;
388         int idx;
389
390         spin_lock_irqsave(&emu->reg_lock, flags);
391         for (idx = 0; idx < 3; idx++)
392                 ucontrol->value.integer.value[idx] = mix->attn[idx];
393         spin_unlock_irqrestore(&emu->reg_lock, flags);
394         return 0;
395 }
396
397 static int snd_emu10k1_attn_put(snd_kcontrol_t * kcontrol,
398                                 snd_ctl_elem_value_t * ucontrol)
399 {
400         unsigned long flags;
401         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
402         emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
403         int change = 0, idx, val;
404
405         spin_lock_irqsave(&emu->reg_lock, flags);
406         for (idx = 0; idx < 3; idx++) {
407                 val = ucontrol->value.integer.value[idx] & 0xffff;
408                 if (mix->attn[idx] != val) {
409                         mix->attn[idx] = val;
410                         change = 1;
411                 }
412         }
413         if (change && mix->epcm) {
414                 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
415                         snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[1]);
416                         snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[1]->number, mix->attn[2]);
417                 } else if (mix->epcm->voices[0]) {
418                         snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[0]);
419                 }
420         }
421         spin_unlock_irqrestore(&emu->reg_lock, flags);
422         return change;
423 }
424
425 static snd_kcontrol_new_t snd_emu10k1_attn_control =
426 {
427         .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
428         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
429         .name =         "EMU10K1 PCM Volume",
430         .count =        32,
431         .info =         snd_emu10k1_attn_info,
432         .get =          snd_emu10k1_attn_get,
433         .put =          snd_emu10k1_attn_put
434 };
435
436 /* Mutichannel PCM stream controls */
437
438 static int snd_emu10k1_efx_send_routing_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
439 {
440         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
441         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
442         uinfo->count = emu->audigy ? 8 : 4;
443         uinfo->value.integer.min = 0;
444         uinfo->value.integer.max = emu->audigy ? 0x3f : 0x0f;
445         return 0;
446 }
447
448 static int snd_emu10k1_efx_send_routing_get(snd_kcontrol_t * kcontrol,
449                                         snd_ctl_elem_value_t * ucontrol)
450 {
451         unsigned long flags;
452         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
453         emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
454         int idx;
455         int num_efx = emu->audigy ? 8 : 4;
456         int mask = emu->audigy ? 0x3f : 0x0f;
457
458         spin_lock_irqsave(&emu->reg_lock, flags);
459         for (idx = 0; idx < num_efx; idx++)
460                 ucontrol->value.integer.value[idx] = 
461                         mix->send_routing[0][idx] & mask;
462         spin_unlock_irqrestore(&emu->reg_lock, flags);
463         return 0;
464 }
465
466 static int snd_emu10k1_efx_send_routing_put(snd_kcontrol_t * kcontrol,
467                                         snd_ctl_elem_value_t * ucontrol)
468 {
469         unsigned long flags;
470         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
471         int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
472         emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[ch];
473         int change = 0, idx, val;
474         int num_efx = emu->audigy ? 8 : 4;
475         int mask = emu->audigy ? 0x3f : 0x0f;
476
477         spin_lock_irqsave(&emu->reg_lock, flags);
478         for (idx = 0; idx < num_efx; idx++) {
479                 val = ucontrol->value.integer.value[idx] & mask;
480                 if (mix->send_routing[0][idx] != val) {
481                         mix->send_routing[0][idx] = val;
482                         change = 1;
483                 }
484         }       
485
486         if (change && mix->epcm) {
487                 if (mix->epcm->voices[ch]) {
488                         update_emu10k1_fxrt(emu, mix->epcm->voices[ch]->number,
489                                         &mix->send_routing[0][0]);
490                 }
491         }
492         spin_unlock_irqrestore(&emu->reg_lock, flags);
493         return change;
494 }
495
496 static snd_kcontrol_new_t snd_emu10k1_efx_send_routing_control =
497 {
498         .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
499         .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
500         .name =         "Multichannel PCM Send Routing",
501         .count =        16,
502         .info =         snd_emu10k1_efx_send_routing_info,
503         .get =          snd_emu10k1_efx_send_routing_get,
504         .put =          snd_emu10k1_efx_send_routing_put
505 };
506
507 static int snd_emu10k1_efx_send_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
508 {
509         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
510         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
511         uinfo->count = emu->audigy ? 8 : 4;
512         uinfo->value.integer.min = 0;
513         uinfo->value.integer.max = 255;
514         return 0;
515 }
516
517 static int snd_emu10k1_efx_send_volume_get(snd_kcontrol_t * kcontrol,
518                                        snd_ctl_elem_value_t * ucontrol)
519 {
520         unsigned long flags;
521         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
522         emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
523         int idx;
524         int num_efx = emu->audigy ? 8 : 4;
525
526         spin_lock_irqsave(&emu->reg_lock, flags);
527         for (idx = 0; idx < num_efx; idx++)
528                 ucontrol->value.integer.value[idx] = mix->send_volume[0][idx];
529         spin_unlock_irqrestore(&emu->reg_lock, flags);
530         return 0;
531 }
532
533 static int snd_emu10k1_efx_send_volume_put(snd_kcontrol_t * kcontrol,
534                                        snd_ctl_elem_value_t * ucontrol)
535 {
536         unsigned long flags;
537         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
538         int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
539         emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[ch];
540         int change = 0, idx, val;
541         int num_efx = emu->audigy ? 8 : 4;
542
543         spin_lock_irqsave(&emu->reg_lock, flags);
544         for (idx = 0; idx < num_efx; idx++) {
545                 val = ucontrol->value.integer.value[idx] & 255;
546                 if (mix->send_volume[0][idx] != val) {
547                         mix->send_volume[0][idx] = val;
548                         change = 1;
549                 }
550         }
551         if (change && mix->epcm) {
552                 if (mix->epcm->voices[ch]) {
553                         update_emu10k1_send_volume(emu, mix->epcm->voices[ch]->number,
554                                                    &mix->send_volume[0][0]);
555                 }
556         }
557         spin_unlock_irqrestore(&emu->reg_lock, flags);
558         return change;
559 }
560
561
562 static snd_kcontrol_new_t snd_emu10k1_efx_send_volume_control =
563 {
564         .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
565         .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
566         .name =         "Multichannel PCM Send Volume",
567         .count =        16,
568         .info =         snd_emu10k1_efx_send_volume_info,
569         .get =          snd_emu10k1_efx_send_volume_get,
570         .put =          snd_emu10k1_efx_send_volume_put
571 };
572
573 static int snd_emu10k1_efx_attn_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
574 {
575         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
576         uinfo->count = 1;
577         uinfo->value.integer.min = 0;
578         uinfo->value.integer.max = 0xffff;
579         return 0;
580 }
581
582 static int snd_emu10k1_efx_attn_get(snd_kcontrol_t * kcontrol,
583                                 snd_ctl_elem_value_t * ucontrol)
584 {
585         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
586         emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
587         unsigned long flags;
588
589         spin_lock_irqsave(&emu->reg_lock, flags);
590         ucontrol->value.integer.value[0] = mix->attn[0];
591         spin_unlock_irqrestore(&emu->reg_lock, flags);
592         return 0;
593 }
594
595 static int snd_emu10k1_efx_attn_put(snd_kcontrol_t * kcontrol,
596                                 snd_ctl_elem_value_t * ucontrol)
597 {
598         unsigned long flags;
599         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
600         int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
601         emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[ch];
602         int change = 0, val;
603
604         spin_lock_irqsave(&emu->reg_lock, flags);
605         val = ucontrol->value.integer.value[0] & 0xffff;
606         if (mix->attn[0] != val) {
607                 mix->attn[0] = val;
608                 change = 1;
609         }
610         if (change && mix->epcm) {
611                 if (mix->epcm->voices[ch]) {
612                         snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[ch]->number, mix->attn[0]);
613                 }
614         }
615         spin_unlock_irqrestore(&emu->reg_lock, flags);
616         return change;
617 }
618
619 static snd_kcontrol_new_t snd_emu10k1_efx_attn_control =
620 {
621         .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
622         .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
623         .name =         "Multichannel PCM Volume",
624         .count =        16,
625         .info =         snd_emu10k1_efx_attn_info,
626         .get =          snd_emu10k1_efx_attn_get,
627         .put =          snd_emu10k1_efx_attn_put
628 };
629
630 static int snd_emu10k1_shared_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
631 {
632         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
633         uinfo->count = 1;
634         uinfo->value.integer.min = 0;
635         uinfo->value.integer.max = 1;
636         return 0;
637 }
638
639 static int snd_emu10k1_shared_spdif_get(snd_kcontrol_t * kcontrol,
640                                         snd_ctl_elem_value_t * ucontrol)
641 {
642         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
643
644         if (emu->audigy)
645                 ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
646         else
647                 ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;
648         return 0;
649 }
650
651 static int snd_emu10k1_shared_spdif_put(snd_kcontrol_t * kcontrol,
652                                         snd_ctl_elem_value_t * ucontrol)
653 {
654         unsigned long flags;
655         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
656         unsigned int reg, val;
657         int change = 0;
658
659         spin_lock_irqsave(&emu->reg_lock, flags);
660         if (emu->audigy) {
661                 reg = inl(emu->port + A_IOCFG);
662                 val = ucontrol->value.integer.value[0] ? A_IOCFG_GPOUT0 : 0;
663                 change = (reg & A_IOCFG_GPOUT0) != val;
664                 if (change) {
665                         reg &= ~A_IOCFG_GPOUT0;
666                         reg |= val;
667                         outl(reg | val, emu->port + A_IOCFG);
668                 }
669         }
670         reg = inl(emu->port + HCFG);
671         val = ucontrol->value.integer.value[0] ? HCFG_GPOUT0 : 0;
672         change |= (reg & HCFG_GPOUT0) != val;
673         if (change) {
674                 reg &= ~HCFG_GPOUT0;
675                 reg |= val;
676                 outl(reg | val, emu->port + HCFG);
677         }
678         spin_unlock_irqrestore(&emu->reg_lock, flags);
679         return change;
680 }
681
682 static snd_kcontrol_new_t snd_emu10k1_shared_spdif __devinitdata =
683 {
684         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
685         .name =         "SB Live Analog/Digital Output Jack",
686         .info =         snd_emu10k1_shared_spdif_info,
687         .get =          snd_emu10k1_shared_spdif_get,
688         .put =          snd_emu10k1_shared_spdif_put
689 };
690
691 static snd_kcontrol_new_t snd_audigy_shared_spdif __devinitdata =
692 {
693         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
694         .name =         "Audigy Analog/Digital Output Jack",
695         .info =         snd_emu10k1_shared_spdif_info,
696         .get =          snd_emu10k1_shared_spdif_get,
697         .put =          snd_emu10k1_shared_spdif_put
698 };
699
700 /*
701  */
702 static void snd_emu10k1_mixer_free_ac97(ac97_t *ac97)
703 {
704         emu10k1_t *emu = ac97->private_data;
705         emu->ac97 = NULL;
706 }
707
708 /*
709  */
710 static int remove_ctl(snd_card_t *card, const char *name)
711 {
712         snd_ctl_elem_id_t id;
713         memset(&id, 0, sizeof(id));
714         strcpy(id.name, name);
715         id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
716         return snd_ctl_remove_id(card, &id);
717 }
718
719 static snd_kcontrol_t *ctl_find(snd_card_t *card, const char *name)
720 {
721         snd_ctl_elem_id_t sid;
722         memset(&sid, 0, sizeof(sid));
723         strcpy(sid.name, name);
724         sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
725         return snd_ctl_find_id(card, &sid);
726 }
727
728 static int rename_ctl(snd_card_t *card, const char *src, const char *dst)
729 {
730         snd_kcontrol_t *kctl = ctl_find(card, src);
731         if (kctl) {
732                 strcpy(kctl->id.name, dst);
733                 return 0;
734         }
735         return -ENOENT;
736 }
737
738 int __devinit snd_emu10k1_mixer(emu10k1_t *emu)
739 {
740         int err, pcm;
741         snd_kcontrol_t *kctl;
742         snd_card_t *card = emu->card;
743         char **c;
744         static char *emu10k1_remove_ctls[] = {
745                 /* no AC97 mono, surround, center/lfe */
746                 "Master Mono Playback Switch",
747                 "Master Mono Playback Volume",
748                 "PCM Out Path & Mute",
749                 "Mono Output Select",
750                 "Surround Playback Switch",
751                 "Surround Playback Volume",
752                 "Center Playback Switch",
753                 "Center Playback Volume",
754                 "LFE Playback Switch",
755                 "LFE Playback Volume",
756                 NULL
757         };
758         static char *emu10k1_rename_ctls[] = {
759                 "Surround Digital Playback Volume", "Surround Playback Volume",
760                 "Center Digital Playback Volume", "Center Playback Volume",
761                 "LFE Digital Playback Volume", "LFE Playback Volume",
762                 NULL
763         };
764         static char *audigy_remove_ctls[] = {
765                 /* Master/PCM controls on ac97 of Audigy has no effect */
766                 "PCM Playback Switch",
767                 "PCM Playback Volume",
768                 "Master Mono Playback Switch",
769                 "Master Mono Playback Volume",
770                 "Master Playback Switch",
771                 "Master Playback Volume",
772                 "PCM Out Path & Mute",
773                 "Mono Output Select",
774                 /* remove unused AC97 capture controls */
775                 "Capture Source",
776                 "Capture Switch",
777                 "Capture Volume",
778                 "Mic Select",
779                 "Video Playback Switch",
780                 "Video Playback Volume",
781                 "Mic Playback Switch",
782                 "Mic Playback Volume",
783                 NULL
784         };
785         static char *audigy_rename_ctls[] = {
786                 /* use conventional names */
787                 "Wave Playback Volume", "PCM Playback Volume",
788                 /* "Wave Capture Volume", "PCM Capture Volume", */
789                 "Wave Master Playback Volume", "Master Playback Volume",
790                 "AMic Playback Volume", "Mic Playback Volume",
791                 NULL
792         };
793
794         if (!emu->no_ac97) {
795                 ac97_bus_t *pbus;
796                 ac97_template_t ac97;
797                 static ac97_bus_ops_t ops = {
798                         .write = snd_emu10k1_ac97_write,
799                         .read = snd_emu10k1_ac97_read,
800                 };
801
802                 if ((err = snd_ac97_bus(emu->card, 0, &ops, NULL, &pbus)) < 0)
803                         return err;
804                 pbus->no_vra = 1; /* we don't need VRA */
805                 
806                 memset(&ac97, 0, sizeof(ac97));
807                 ac97.private_data = emu;
808                 ac97.private_free = snd_emu10k1_mixer_free_ac97;
809                 ac97.scaps = AC97_SCAP_NO_SPDIF;
810                 if ((err = snd_ac97_mixer(pbus, &ac97, &emu->ac97)) < 0)
811                         return err;
812                 if (emu->audigy) {
813                         /* set master volume to 0 dB */
814                         snd_ac97_write(emu->ac97, AC97_MASTER, 0x0000);
815                         /* set capture source to mic */
816                         snd_ac97_write(emu->ac97, AC97_REC_SEL, 0x0000);
817                         c = audigy_remove_ctls;
818                 } else {
819                         /*
820                          * Credits for cards based on STAC9758:
821                          *   James Courtier-Dutton <James@superbug.demon.co.uk>
822                          *   Voluspa <voluspa@comhem.se>
823                          */
824                         if (emu->ac97->id == AC97_ID_STAC9758) {
825                                 emu->rear_ac97 = 1;
826                                 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT);
827                         }
828                         /* remove unused AC97 controls */
829                         snd_ac97_write(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
830                         snd_ac97_write(emu->ac97, AC97_CENTER_LFE_MASTER, 0x0202);
831                         c = emu10k1_remove_ctls;
832                 }
833                 for (; *c; c++)
834                         remove_ctl(card, *c);
835         } else {
836                 if (emu->APS)
837                         strcpy(emu->card->mixername, "EMU APS");
838                 else if (emu->audigy)
839                         strcpy(emu->card->mixername, "SB Audigy");
840                 else
841                         strcpy(emu->card->mixername, "Emu10k1");
842         }
843
844         if (emu->audigy)
845                 c = audigy_rename_ctls;
846         else
847                 c = emu10k1_rename_ctls;
848         for (; *c; c += 2)
849                 rename_ctl(card, c[0], c[1]);
850
851         if ((kctl = emu->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu)) == NULL)
852                 return -ENOMEM;
853         if ((err = snd_ctl_add(card, kctl)))
854                 return err;
855         if ((kctl = emu->ctl_send_volume = snd_ctl_new1(&snd_emu10k1_send_volume_control, emu)) == NULL)
856                 return -ENOMEM;
857         if ((err = snd_ctl_add(card, kctl)))
858                 return err;
859         if ((kctl = emu->ctl_attn = snd_ctl_new1(&snd_emu10k1_attn_control, emu)) == NULL)
860                 return -ENOMEM;
861         if ((err = snd_ctl_add(card, kctl)))
862                 return err;
863
864         if ((kctl = emu->ctl_efx_send_routing = snd_ctl_new1(&snd_emu10k1_efx_send_routing_control, emu)) == NULL)
865                 return -ENOMEM;
866         if ((err = snd_ctl_add(card, kctl)))
867                 return err;
868         
869         if ((kctl = emu->ctl_efx_send_volume = snd_ctl_new1(&snd_emu10k1_efx_send_volume_control, emu)) == NULL)
870                 return -ENOMEM;
871         if ((err = snd_ctl_add(card, kctl)))
872                 return err;
873         
874         if ((kctl = emu->ctl_efx_attn = snd_ctl_new1(&snd_emu10k1_efx_attn_control, emu)) == NULL)
875                 return -ENOMEM;
876         if ((err = snd_ctl_add(card, kctl)))
877                 return err;
878
879         /* initialize the routing and volume table for each pcm playback stream */
880         for (pcm = 0; pcm < 32; pcm++) {
881                 emu10k1_pcm_mixer_t *mix;
882                 int v;
883                 
884                 mix = &emu->pcm_mixer[pcm];
885                 mix->epcm = NULL;
886
887                 for (v = 0; v < 4; v++)
888                         mix->send_routing[0][v] = 
889                                 mix->send_routing[1][v] = 
890                                 mix->send_routing[2][v] = v;
891                 
892                 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
893                 mix->send_volume[0][0] = mix->send_volume[0][1] =
894                 mix->send_volume[1][0] = mix->send_volume[2][1] = 255;
895                 
896                 mix->attn[0] = mix->attn[1] = mix->attn[2] = 0xffff;
897         }
898         
899         /* initialize the routing and volume table for the multichannel playback stream */
900         for (pcm = 0; pcm < NUM_EFX_PLAYBACK; pcm++) {
901                 emu10k1_pcm_mixer_t *mix;
902                 int v;
903                 
904                 mix = &emu->efx_pcm_mixer[pcm];
905                 mix->epcm = NULL;
906
907                 mix->send_routing[0][0] = pcm;
908                 mix->send_routing[0][1] = (pcm == 0) ? 1 : 0;
909                 for (v = 0; v < 2; v++)
910                         mix->send_routing[0][2+v] = 13+v;
911                 if (emu->audigy)
912                         for (v = 0; v < 4; v++)
913                                 mix->send_routing[0][4+v] = 60+v;
914                 
915                 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
916                 mix->send_volume[0][0]  = 255;
917                 
918                 mix->attn[0] = 0xffff;
919         }
920         
921         if (! emu->APS) { /* FIXME: APS has these controls? */
922                 /* sb live! and audigy */
923                 if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL)
924                         return -ENOMEM;
925                 if ((err = snd_ctl_add(card, kctl)))
926                         return err;
927                 if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_control, emu)) == NULL)
928                         return -ENOMEM;
929                 if ((err = snd_ctl_add(card, kctl)))
930                         return err;
931         }
932
933         if (emu->audigy) {
934                 if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL)
935                         return -ENOMEM;
936                 if ((err = snd_ctl_add(card, kctl)))
937                         return err;
938                 if ((kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu)) == NULL)
939                         return -ENOMEM;
940                 if ((err = snd_ctl_add(card, kctl)))
941                         return err;
942         } else if (! emu->APS) {
943                 /* sb live! */
944                 if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL)
945                         return -ENOMEM;
946                 if ((err = snd_ctl_add(card, kctl)))
947                         return err;
948         }
949         if (emu->audigy && emu->revision == 4) { /* P16V */
950                 if ((err = snd_p16v_mixer(emu)))
951                         return err;
952         }
953                 
954         return 0;
955 }