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