vserver 1.9.3
[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  *
7  *  BUGS:
8  *    --
9  *
10  *  TODO:
11  *    --
12  *
13  *   This program is free software; you can redistribute it and/or modify
14  *   it under the terms of the GNU General Public License as published by
15  *   the Free Software Foundation; either version 2 of the License, or
16  *   (at your option) any later version.
17  *
18  *   This program is distributed in the hope that it will be useful,
19  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *   GNU General Public License for more details.
22  *
23  *   You should have received a copy of the GNU General Public License
24  *   along with this program; if not, write to the Free Software
25  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
26  *
27  */
28
29 #include <sound/driver.h>
30 #include <linux/time.h>
31 #include <linux/init.h>
32 #include <sound/core.h>
33 #include <sound/emu10k1.h>
34
35 #define AC97_ID_STAC9758        0x83847658
36
37 static int snd_emu10k1_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
38 {
39         uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
40         uinfo->count = 1;
41         return 0;
42 }
43
44 static int snd_emu10k1_spdif_get(snd_kcontrol_t * kcontrol,
45                                  snd_ctl_elem_value_t * ucontrol)
46 {
47         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
48         unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
49         unsigned long flags;
50
51         spin_lock_irqsave(&emu->reg_lock, flags);
52         ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
53         ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
54         ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
55         ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
56         spin_unlock_irqrestore(&emu->reg_lock, flags);
57         return 0;
58 }
59
60 static int snd_emu10k1_spdif_get_mask(snd_kcontrol_t * kcontrol,
61                                       snd_ctl_elem_value_t * ucontrol)
62 {
63         ucontrol->value.iec958.status[0] = 0xff;
64         ucontrol->value.iec958.status[1] = 0xff;
65         ucontrol->value.iec958.status[2] = 0xff;
66         ucontrol->value.iec958.status[3] = 0xff;
67         return 0;
68 }
69
70 static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol,
71                                  snd_ctl_elem_value_t * ucontrol)
72 {
73         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
74         unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
75         int change;
76         unsigned int val;
77         unsigned long flags;
78
79         val = (ucontrol->value.iec958.status[0] << 0) |
80               (ucontrol->value.iec958.status[1] << 8) |
81               (ucontrol->value.iec958.status[2] << 16) |
82               (ucontrol->value.iec958.status[3] << 24);
83         spin_lock_irqsave(&emu->reg_lock, flags);
84         change = val != emu->spdif_bits[idx];
85         if (change) {
86                 snd_emu10k1_ptr_write(emu, SPCS0 + idx, 0, val);
87                 emu->spdif_bits[idx] = val;
88         }
89         spin_unlock_irqrestore(&emu->reg_lock, flags);
90         return change;
91 }
92
93 static snd_kcontrol_new_t snd_emu10k1_spdif_mask_control =
94 {
95         .access =       SNDRV_CTL_ELEM_ACCESS_READ,
96         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
97         .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
98         .count =        4,
99         .info =         snd_emu10k1_spdif_info,
100         .get =          snd_emu10k1_spdif_get_mask
101 };
102
103 static snd_kcontrol_new_t snd_emu10k1_spdif_control =
104 {
105         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
106         .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
107         .count =        4,
108         .info =         snd_emu10k1_spdif_info,
109         .get =          snd_emu10k1_spdif_get,
110         .put =          snd_emu10k1_spdif_put
111 };
112
113
114 static void update_emu10k1_fxrt(emu10k1_t *emu, int voice, unsigned char *route)
115 {
116         if (emu->audigy) {
117                 snd_emu10k1_ptr_write(emu, A_FXRT1, voice,
118                                       snd_emu10k1_compose_audigy_fxrt1(route));
119                 snd_emu10k1_ptr_write(emu, A_FXRT2, voice,
120                                       snd_emu10k1_compose_audigy_fxrt2(route));
121         } else {
122                 snd_emu10k1_ptr_write(emu, FXRT, voice,
123                                       snd_emu10k1_compose_send_routing(route));
124         }
125 }
126
127 static void update_emu10k1_send_volume(emu10k1_t *emu, int voice, unsigned char *volume)
128 {
129         snd_emu10k1_ptr_write(emu, PTRX_FXSENDAMOUNT_A, voice, volume[0]);
130         snd_emu10k1_ptr_write(emu, PTRX_FXSENDAMOUNT_B, voice, volume[1]);
131         snd_emu10k1_ptr_write(emu, PSST_FXSENDAMOUNT_C, voice, volume[2]);
132         snd_emu10k1_ptr_write(emu, DSL_FXSENDAMOUNT_D, voice, volume[3]);
133         if (emu->audigy) {
134                 unsigned int val = ((unsigned int)volume[4] << 24) |
135                         ((unsigned int)volume[5] << 16) |
136                         ((unsigned int)volume[6] << 8) |
137                         (unsigned int)volume[7];
138                 snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, voice, val);
139         }
140 }
141
142 static int snd_emu10k1_send_routing_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
143 {
144         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
145         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
146         uinfo->count = emu->audigy ? 3*8 : 3*4;
147         uinfo->value.integer.min = 0;
148         uinfo->value.integer.max = emu->audigy ? 0x3f : 0x0f;
149         return 0;
150 }
151
152 static int snd_emu10k1_send_routing_get(snd_kcontrol_t * kcontrol,
153                                         snd_ctl_elem_value_t * ucontrol)
154 {
155         unsigned long flags;
156         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
157         emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
158         int voice, idx;
159         int num_efx = emu->audigy ? 8 : 4;
160         int mask = emu->audigy ? 0x3f : 0x0f;
161
162         spin_lock_irqsave(&emu->reg_lock, flags);
163         for (voice = 0; voice < 3; voice++)
164                 for (idx = 0; idx < num_efx; idx++)
165                         ucontrol->value.integer.value[(voice * num_efx) + idx] = 
166                                 mix->send_routing[voice][idx] & mask;
167         spin_unlock_irqrestore(&emu->reg_lock, flags);
168         return 0;
169 }
170
171 static int snd_emu10k1_send_routing_put(snd_kcontrol_t * kcontrol,
172                                         snd_ctl_elem_value_t * ucontrol)
173 {
174         unsigned long flags;
175         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
176         emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
177         int change = 0, voice, idx, val;
178         int num_efx = emu->audigy ? 8 : 4;
179         int mask = emu->audigy ? 0x3f : 0x0f;
180
181         spin_lock_irqsave(&emu->reg_lock, flags);
182         for (voice = 0; voice < 3; voice++)
183                 for (idx = 0; idx < num_efx; idx++) {
184                         val = ucontrol->value.integer.value[(voice * num_efx) + idx] & mask;
185                         if (mix->send_routing[voice][idx] != val) {
186                                 mix->send_routing[voice][idx] = val;
187                                 change = 1;
188                         }
189                 }       
190         if (change && mix->epcm) {
191                 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
192                         update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number,
193                                             &mix->send_routing[1][0]);
194                         update_emu10k1_fxrt(emu, mix->epcm->voices[1]->number,
195                                             &mix->send_routing[2][0]);
196                 } else if (mix->epcm->voices[0]) {
197                         update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number,
198                                             &mix->send_routing[0][0]);
199                 }
200         }
201         spin_unlock_irqrestore(&emu->reg_lock, flags);
202         return change;
203 }
204
205 static snd_kcontrol_new_t snd_emu10k1_send_routing_control =
206 {
207         .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
208         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
209         .name =         "EMU10K1 PCM Send Routing",
210         .count =        32,
211         .info =         snd_emu10k1_send_routing_info,
212         .get =          snd_emu10k1_send_routing_get,
213         .put =          snd_emu10k1_send_routing_put
214 };
215
216 static int snd_emu10k1_send_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
217 {
218         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
219         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
220         uinfo->count = emu->audigy ? 3*8 : 3*4;
221         uinfo->value.integer.min = 0;
222         uinfo->value.integer.max = 255;
223         return 0;
224 }
225
226 static int snd_emu10k1_send_volume_get(snd_kcontrol_t * kcontrol,
227                                        snd_ctl_elem_value_t * ucontrol)
228 {
229         unsigned long flags;
230         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
231         emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
232         int idx;
233         int num_efx = emu->audigy ? 8 : 4;
234
235         spin_lock_irqsave(&emu->reg_lock, flags);
236         for (idx = 0; idx < 3*num_efx; idx++)
237                 ucontrol->value.integer.value[idx] = mix->send_volume[idx/num_efx][idx%num_efx];
238         spin_unlock_irqrestore(&emu->reg_lock, flags);
239         return 0;
240 }
241
242 static int snd_emu10k1_send_volume_put(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 change = 0, idx, val;
249         int num_efx = emu->audigy ? 8 : 4;
250
251         spin_lock_irqsave(&emu->reg_lock, flags);
252         for (idx = 0; idx < 3*num_efx; idx++) {
253                 val = ucontrol->value.integer.value[idx] & 255;
254                 if (mix->send_volume[idx/num_efx][idx%num_efx] != val) {
255                         mix->send_volume[idx/num_efx][idx%num_efx] = val;
256                         change = 1;
257                 }
258         }
259         if (change && mix->epcm) {
260                 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
261                         update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number,
262                                                    &mix->send_volume[1][0]);
263                         update_emu10k1_send_volume(emu, mix->epcm->voices[1]->number,
264                                                    &mix->send_volume[2][0]);
265                 } else if (mix->epcm->voices[0]) {
266                         update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number,
267                                                    &mix->send_volume[0][0]);
268                 }
269         }
270         spin_unlock_irqrestore(&emu->reg_lock, flags);
271         return change;
272 }
273
274 static snd_kcontrol_new_t snd_emu10k1_send_volume_control =
275 {
276         .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
277         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
278         .name =         "EMU10K1 PCM Send Volume",
279         .count =        32,
280         .info =         snd_emu10k1_send_volume_info,
281         .get =          snd_emu10k1_send_volume_get,
282         .put =          snd_emu10k1_send_volume_put
283 };
284
285 static int snd_emu10k1_attn_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
286 {
287         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
288         uinfo->count = 3;
289         uinfo->value.integer.min = 0;
290         uinfo->value.integer.max = 0xffff;
291         return 0;
292 }
293
294 static int snd_emu10k1_attn_get(snd_kcontrol_t * kcontrol,
295                                 snd_ctl_elem_value_t * ucontrol)
296 {
297         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
298         emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
299         unsigned long flags;
300         int idx;
301
302         spin_lock_irqsave(&emu->reg_lock, flags);
303         for (idx = 0; idx < 3; idx++)
304                 ucontrol->value.integer.value[idx] = mix->attn[idx];
305         spin_unlock_irqrestore(&emu->reg_lock, flags);
306         return 0;
307 }
308
309 static int snd_emu10k1_attn_put(snd_kcontrol_t * kcontrol,
310                                 snd_ctl_elem_value_t * ucontrol)
311 {
312         unsigned long flags;
313         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
314         emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
315         int change = 0, idx, val;
316
317         spin_lock_irqsave(&emu->reg_lock, flags);
318         for (idx = 0; idx < 3; idx++) {
319                 val = ucontrol->value.integer.value[idx] & 0xffff;
320                 if (mix->attn[idx] != val) {
321                         mix->attn[idx] = val;
322                         change = 1;
323                 }
324         }
325         if (change && mix->epcm) {
326                 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
327                         snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[1]);
328                         snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[1]->number, mix->attn[2]);
329                 } else if (mix->epcm->voices[0]) {
330                         snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[0]);
331                 }
332         }
333         spin_unlock_irqrestore(&emu->reg_lock, flags);
334         return change;
335 }
336
337 static snd_kcontrol_new_t snd_emu10k1_attn_control =
338 {
339         .access =       SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
340         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
341         .name =         "EMU10K1 PCM Volume",
342         .count =        32,
343         .info =         snd_emu10k1_attn_info,
344         .get =          snd_emu10k1_attn_get,
345         .put =          snd_emu10k1_attn_put
346 };
347
348 static int snd_emu10k1_shared_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
349 {
350         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
351         uinfo->count = 1;
352         uinfo->value.integer.min = 0;
353         uinfo->value.integer.max = 1;
354         return 0;
355 }
356
357 static int snd_emu10k1_shared_spdif_get(snd_kcontrol_t * kcontrol,
358                                         snd_ctl_elem_value_t * ucontrol)
359 {
360         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
361
362         if (emu->audigy)
363                 ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
364         else
365                 ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;
366         return 0;
367 }
368
369 static int snd_emu10k1_shared_spdif_put(snd_kcontrol_t * kcontrol,
370                                         snd_ctl_elem_value_t * ucontrol)
371 {
372         unsigned long flags;
373         emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
374         unsigned int reg, val;
375         int change = 0;
376
377         spin_lock_irqsave(&emu->reg_lock, flags);
378         if (emu->audigy) {
379                 reg = inl(emu->port + A_IOCFG);
380                 val = ucontrol->value.integer.value[0] ? A_IOCFG_GPOUT0 : 0;
381                 change = (reg & A_IOCFG_GPOUT0) != val;
382                 if (change) {
383                         reg &= ~A_IOCFG_GPOUT0;
384                         reg |= val;
385                         outl(reg | val, emu->port + A_IOCFG);
386                 }
387         }
388         reg = inl(emu->port + HCFG);
389         val = ucontrol->value.integer.value[0] ? HCFG_GPOUT0 : 0;
390         change |= (reg & HCFG_GPOUT0) != val;
391         if (change) {
392                 reg &= ~HCFG_GPOUT0;
393                 reg |= val;
394                 outl(reg | val, emu->port + HCFG);
395         }
396         spin_unlock_irqrestore(&emu->reg_lock, flags);
397         return change;
398 }
399
400 static snd_kcontrol_new_t snd_emu10k1_shared_spdif __devinitdata =
401 {
402         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
403         .name =         "SB Live Analog/Digital Output Jack",
404         .info =         snd_emu10k1_shared_spdif_info,
405         .get =          snd_emu10k1_shared_spdif_get,
406         .put =          snd_emu10k1_shared_spdif_put
407 };
408
409 static snd_kcontrol_new_t snd_audigy_shared_spdif __devinitdata =
410 {
411         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
412         .name =         "Audigy Analog/Digital Output Jack",
413         .info =         snd_emu10k1_shared_spdif_info,
414         .get =          snd_emu10k1_shared_spdif_get,
415         .put =          snd_emu10k1_shared_spdif_put
416 };
417
418 /*
419  */
420 static void snd_emu10k1_mixer_free_ac97(ac97_t *ac97)
421 {
422         emu10k1_t *emu = ac97->private_data;
423         emu->ac97 = NULL;
424 }
425
426 /*
427  */
428 static int remove_ctl(snd_card_t *card, const char *name)
429 {
430         snd_ctl_elem_id_t id;
431         memset(&id, 0, sizeof(id));
432         strcpy(id.name, name);
433         id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
434         return snd_ctl_remove_id(card, &id);
435 }
436
437 static snd_kcontrol_t *ctl_find(snd_card_t *card, const char *name)
438 {
439         snd_ctl_elem_id_t sid;
440         memset(&sid, 0, sizeof(sid));
441         strcpy(sid.name, name);
442         sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
443         return snd_ctl_find_id(card, &sid);
444 }
445
446 static int rename_ctl(snd_card_t *card, const char *src, const char *dst)
447 {
448         snd_kcontrol_t *kctl = ctl_find(card, src);
449         if (kctl) {
450                 strcpy(kctl->id.name, dst);
451                 return 0;
452         }
453         return -ENOENT;
454 }
455
456 int __devinit snd_emu10k1_mixer(emu10k1_t *emu)
457 {
458         int err, pcm;
459         snd_kcontrol_t *kctl;
460         snd_card_t *card = emu->card;
461         char **c;
462         static char *emu10k1_remove_ctls[] = {
463                 /* no AC97 mono, surround, center/lfe */
464                 "Master Mono Playback Switch",
465                 "Master Mono Playback Volume",
466                 "PCM Out Path & Mute",
467                 "Mono Output Select",
468                 "Surround Playback Switch",
469                 "Surround Playback Volume",
470                 "Center Playback Switch",
471                 "Center Playback Volume",
472                 "LFE Playback Switch",
473                 "LFE Playback Volume",
474                 NULL
475         };
476         static char *emu10k1_rename_ctls[] = {
477                 "Surround Digital Playback Volume", "Surround Playback Volume",
478                 "Center Digital Playback Volume", "Center Playback Volume",
479                 "LFE Digital Playback Volume", "LFE Playback Volume",
480                 NULL
481         };
482         static char *audigy_remove_ctls[] = {
483                 /* Master/PCM controls on ac97 of Audigy has no effect */
484                 "PCM Playback Switch",
485                 "PCM Playback Volume",
486                 "Master Mono Playback Switch",
487                 "Master Mono Playback Volume",
488                 "Master Playback Switch",
489                 "Master Playback Volume",
490                 "PCM Out Path & Mute",
491                 "Mono Output Select",
492                 /* remove unused AC97 capture controls */
493                 "Capture Source",
494                 "Capture Switch",
495                 "Capture Volume",
496                 "Mic Select",
497                 "Video Playback Switch",
498                 "Video Playback Volume",
499                 "Mic Playback Switch",
500                 "Mic Playback Volume",
501                 NULL
502         };
503         static char *audigy_rename_ctls[] = {
504                 /* use conventional names */
505                 "Wave Playback Volume", "PCM Playback Volume",
506                 /* "Wave Capture Volume", "PCM Capture Volume", */
507                 "Wave Master Playback Volume", "Master Playback Volume",
508                 "AMic Playback Volume", "Mic Playback Volume",
509                 NULL
510         };
511
512         if (!emu->no_ac97) {
513                 ac97_bus_t *pbus;
514                 ac97_template_t ac97;
515                 static ac97_bus_ops_t ops = {
516                         .write = snd_emu10k1_ac97_write,
517                         .read = snd_emu10k1_ac97_read,
518                 };
519
520                 if ((err = snd_ac97_bus(emu->card, 0, &ops, NULL, &pbus)) < 0)
521                         return err;
522                 
523                 memset(&ac97, 0, sizeof(ac97));
524                 ac97.private_data = emu;
525                 ac97.private_free = snd_emu10k1_mixer_free_ac97;
526                 if ((err = snd_ac97_mixer(pbus, &ac97, &emu->ac97)) < 0)
527                         return err;
528                 if (emu->audigy) {
529                         /* set master volume to 0 dB */
530                         snd_ac97_write(emu->ac97, AC97_MASTER, 0x0000);
531                         /* set capture source to mic */
532                         snd_ac97_write(emu->ac97, AC97_REC_SEL, 0x0000);
533                         c = audigy_remove_ctls;
534                 } else {
535                         /*
536                          * Credits for cards based on STAC9758:
537                          *   James Courtier-Dutton <James@superbug.demon.co.uk>
538                          *   Voluspa <voluspa@comhem.se>
539                          */
540                         if (emu->ac97->id == AC97_ID_STAC9758) {
541                                 emu->rear_ac97 = 1;
542                                 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT);
543                         }
544                         /* remove unused AC97 controls */
545                         snd_ac97_write(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
546                         snd_ac97_write(emu->ac97, AC97_CENTER_LFE_MASTER, 0x0202);
547                         c = emu10k1_remove_ctls;
548                 }
549                 for (; *c; c++)
550                         remove_ctl(card, *c);
551         } else {
552                 if (emu->APS)
553                         strcpy(emu->card->mixername, "EMU APS");
554                 else if (emu->audigy)
555                         strcpy(emu->card->mixername, "SB Audigy");
556                 else
557                         strcpy(emu->card->mixername, "Emu10k1");
558         }
559
560         if (emu->audigy)
561                 c = audigy_rename_ctls;
562         else
563                 c = emu10k1_rename_ctls;
564         for (; *c; c += 2)
565                 rename_ctl(card, c[0], c[1]);
566
567         if ((kctl = emu->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu)) == NULL)
568                 return -ENOMEM;
569         if ((err = snd_ctl_add(card, kctl)))
570                 return err;
571         if ((kctl = emu->ctl_send_volume = snd_ctl_new1(&snd_emu10k1_send_volume_control, emu)) == NULL)
572                 return -ENOMEM;
573         if ((err = snd_ctl_add(card, kctl)))
574                 return err;
575         if ((kctl = emu->ctl_attn = snd_ctl_new1(&snd_emu10k1_attn_control, emu)) == NULL)
576                 return -ENOMEM;
577         if ((err = snd_ctl_add(card, kctl)))
578                 return err;
579
580         /* intiailize the routing and volume table for each pcm playback stream */
581         for (pcm = 0; pcm < 32; pcm++) {
582                 emu10k1_pcm_mixer_t *mix;
583                 int v;
584                 
585                 mix = &emu->pcm_mixer[pcm];
586                 mix->epcm = NULL;
587
588                 for (v = 0; v < 4; v++)
589                         mix->send_routing[0][v] = 
590                                 mix->send_routing[1][v] = 
591                                 mix->send_routing[2][v] = v;
592                 
593                 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
594                 mix->send_volume[0][0] = mix->send_volume[0][1] =
595                 mix->send_volume[1][0] = mix->send_volume[2][1] = 255;
596                 
597                 mix->attn[0] = mix->attn[1] = mix->attn[2] = 0xffff;
598         }
599         
600         if (! emu->APS) { /* FIXME: APS has these controls? */
601                 /* sb live! and audigy */
602                 if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL)
603                         return -ENOMEM;
604                 if ((err = snd_ctl_add(card, kctl)))
605                         return err;
606                 if ((kctl = ctl_find(card, SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT))) != NULL) {
607                         /* already defined by ac97, remove it */
608                         /* FIXME: or do we need both controls? */
609                         remove_ctl(card, SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT));
610                 }
611                 if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_control, emu)) == NULL)
612                         return -ENOMEM;
613                 if ((err = snd_ctl_add(card, kctl)))
614                         return err;
615         }
616
617         if (emu->audigy) {
618                 if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL)
619                         return -ENOMEM;
620                 if ((err = snd_ctl_add(card, kctl)))
621                         return err;
622         } else if (! emu->APS) {
623                 /* sb live! */
624                 if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL)
625                         return -ENOMEM;
626                 if ((err = snd_ctl_add(card, kctl)))
627                         return err;
628         }
629
630         return 0;
631 }