2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
3 * Takashi Iwai <tiwai@suse.de>
5 * Routines for control of EMU10K1 chips / mixer routines
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.
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.
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
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>
35 #define chip_t emu10k1_t
37 static int snd_emu10k1_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
39 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
44 static int snd_emu10k1_spdif_get(snd_kcontrol_t * kcontrol,
45 snd_ctl_elem_value_t * ucontrol)
47 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
48 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
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);
60 static int snd_emu10k1_spdif_get_mask(snd_kcontrol_t * kcontrol,
61 snd_ctl_elem_value_t * ucontrol)
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;
70 static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol,
71 snd_ctl_elem_value_t * ucontrol)
73 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
74 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
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];
86 snd_emu10k1_ptr_write(emu, SPCS0 + idx, 0, val);
87 emu->spdif_bits[idx] = val;
89 spin_unlock_irqrestore(&emu->reg_lock, flags);
93 static snd_kcontrol_new_t snd_emu10k1_spdif_mask_control =
95 .access = SNDRV_CTL_ELEM_ACCESS_READ,
96 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
97 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
99 .info = snd_emu10k1_spdif_info,
100 .get = snd_emu10k1_spdif_get_mask
103 static snd_kcontrol_new_t snd_emu10k1_spdif_control =
105 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
106 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
108 .info = snd_emu10k1_spdif_info,
109 .get = snd_emu10k1_spdif_get,
110 .put = snd_emu10k1_spdif_put
114 static void update_emu10k1_fxrt(emu10k1_t *emu, int voice, unsigned char *route)
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));
122 snd_emu10k1_ptr_write(emu, FXRT, voice,
123 snd_emu10k1_compose_send_routing(route));
127 static void update_emu10k1_send_volume(emu10k1_t *emu, int voice, unsigned char *volume)
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]);
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);
142 static int snd_emu10k1_send_routing_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
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;
152 static int snd_emu10k1_send_routing_get(snd_kcontrol_t * kcontrol,
153 snd_ctl_elem_value_t * ucontrol)
156 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
157 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
159 int num_efx = emu->audigy ? 8 : 4;
160 int mask = emu->audigy ? 0x3f : 0x0f;
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);
171 static int snd_emu10k1_send_routing_put(snd_kcontrol_t * kcontrol,
172 snd_ctl_elem_value_t * ucontrol)
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;
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;
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]);
201 spin_unlock_irqrestore(&emu->reg_lock, flags);
205 static snd_kcontrol_new_t snd_emu10k1_send_routing_control =
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",
211 .info = snd_emu10k1_send_routing_info,
212 .get = snd_emu10k1_send_routing_get,
213 .put = snd_emu10k1_send_routing_put
216 static int snd_emu10k1_send_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
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;
226 static int snd_emu10k1_send_volume_get(snd_kcontrol_t * kcontrol,
227 snd_ctl_elem_value_t * ucontrol)
230 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
231 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
233 int num_efx = emu->audigy ? 8 : 4;
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);
242 static int snd_emu10k1_send_volume_put(snd_kcontrol_t * kcontrol,
243 snd_ctl_elem_value_t * ucontrol)
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;
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;
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]);
270 spin_unlock_irqrestore(&emu->reg_lock, flags);
274 static snd_kcontrol_new_t snd_emu10k1_send_volume_control =
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",
280 .info = snd_emu10k1_send_volume_info,
281 .get = snd_emu10k1_send_volume_get,
282 .put = snd_emu10k1_send_volume_put
285 static int snd_emu10k1_attn_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
287 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
289 uinfo->value.integer.min = 0;
290 uinfo->value.integer.max = 0xffff;
294 static int snd_emu10k1_attn_get(snd_kcontrol_t * kcontrol,
295 snd_ctl_elem_value_t * ucontrol)
297 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
298 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
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);
309 static int snd_emu10k1_attn_put(snd_kcontrol_t * kcontrol,
310 snd_ctl_elem_value_t * ucontrol)
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;
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;
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]);
333 spin_unlock_irqrestore(&emu->reg_lock, flags);
337 static snd_kcontrol_new_t snd_emu10k1_attn_control =
339 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
340 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
341 .name = "EMU10K1 PCM Volume",
343 .info = snd_emu10k1_attn_info,
344 .get = snd_emu10k1_attn_get,
345 .put = snd_emu10k1_attn_put
348 static int snd_emu10k1_shared_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
350 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
352 uinfo->value.integer.min = 0;
353 uinfo->value.integer.max = 1;
357 static int snd_emu10k1_shared_spdif_get(snd_kcontrol_t * kcontrol,
358 snd_ctl_elem_value_t * ucontrol)
360 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
363 ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
365 ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;
369 static int snd_emu10k1_shared_spdif_put(snd_kcontrol_t * kcontrol,
370 snd_ctl_elem_value_t * ucontrol)
373 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
374 unsigned int reg, val;
377 spin_lock_irqsave(&emu->reg_lock, flags);
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;
383 reg &= ~A_IOCFG_GPOUT0;
385 outl(reg | val, emu->port + A_IOCFG);
388 reg = inl(emu->port + HCFG);
389 val = ucontrol->value.integer.value[0] ? HCFG_GPOUT0 : 0;
390 change |= (reg & HCFG_GPOUT0) != val;
394 outl(reg | val, emu->port + HCFG);
396 spin_unlock_irqrestore(&emu->reg_lock, flags);
400 static snd_kcontrol_new_t snd_emu10k1_shared_spdif __devinitdata =
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
409 static snd_kcontrol_new_t snd_audigy_shared_spdif __devinitdata =
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
420 static void snd_emu10k1_mixer_free_ac97(ac97_t *ac97)
422 emu10k1_t *emu = snd_magic_cast(emu10k1_t, ac97->private_data, return);
428 static int remove_ctl(snd_card_t *card, const char *name)
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);
437 static snd_kcontrol_t *ctl_find(snd_card_t *card, const char *name)
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);
446 static int rename_ctl(snd_card_t *card, const char *src, const char *dst)
448 snd_kcontrol_t *kctl = ctl_find(card, src);
450 strcpy(kctl->id.name, dst);
456 int __devinit snd_emu10k1_mixer(emu10k1_t *emu)
459 snd_kcontrol_t *kctl;
460 snd_card_t *card = emu->card;
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",
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",
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 */
497 "Video Playback Switch",
498 "Video Playback Volume",
499 "Mic Playback Switch",
500 "Mic Playback Volume",
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",
513 ac97_bus_t bus, *pbus;
516 memset(&bus, 0, sizeof(bus));
517 bus.write = snd_emu10k1_ac97_write;
518 bus.read = snd_emu10k1_ac97_read;
519 if ((err = snd_ac97_bus(emu->card, &bus, &pbus)) < 0)
522 memset(&ac97, 0, sizeof(ac97));
523 ac97.private_data = emu;
524 ac97.private_free = snd_emu10k1_mixer_free_ac97;
525 if ((err = snd_ac97_mixer(pbus, &ac97, &emu->ac97)) < 0)
528 /* set master volume to 0 dB */
529 snd_ac97_write(emu->ac97, AC97_MASTER, 0x0202);
530 /* set capture source to mic */
531 snd_ac97_write(emu->ac97, AC97_REC_SEL, 0x0000);
532 c = audigy_remove_ctls;
534 /* remove unused AC97 controls */
535 snd_ac97_write(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
536 snd_ac97_write(emu->ac97, AC97_CENTER_LFE_MASTER, 0x0202);
537 c = emu10k1_remove_ctls;
540 remove_ctl(card, *c);
543 strcpy(emu->card->mixername, "EMU APS");
544 else if (emu->audigy)
545 strcpy(emu->card->mixername, "SB Audigy");
547 strcpy(emu->card->mixername, "Emu10k1");
551 c = audigy_rename_ctls;
553 c = emu10k1_rename_ctls;
555 rename_ctl(card, c[0], c[1]);
557 if ((kctl = emu->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu)) == NULL)
559 if ((err = snd_ctl_add(card, kctl)))
561 if ((kctl = emu->ctl_send_volume = snd_ctl_new1(&snd_emu10k1_send_volume_control, emu)) == NULL)
563 if ((err = snd_ctl_add(card, kctl)))
565 if ((kctl = emu->ctl_attn = snd_ctl_new1(&snd_emu10k1_attn_control, emu)) == NULL)
567 if ((err = snd_ctl_add(card, kctl)))
570 /* intiailize the routing and volume table for each pcm playback stream */
571 for (pcm = 0; pcm < 32; pcm++) {
572 emu10k1_pcm_mixer_t *mix;
575 mix = &emu->pcm_mixer[pcm];
578 for (v = 0; v < 4; v++)
579 mix->send_routing[0][v] =
580 mix->send_routing[1][v] =
581 mix->send_routing[2][v] = v;
583 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
584 mix->send_volume[0][0] = mix->send_volume[0][1] =
585 mix->send_volume[1][0] = mix->send_volume[2][1] = 255;
587 mix->attn[0] = mix->attn[1] = mix->attn[2] = 0xffff;
590 if (! emu->APS) { /* FIXME: APS has these controls? */
591 /* sb live! and audigy */
592 if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL)
594 if ((err = snd_ctl_add(card, kctl)))
596 if ((kctl = ctl_find(card, SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT))) != NULL) {
597 /* already defined by ac97, remove it */
598 /* FIXME: or do we need both controls? */
599 remove_ctl(card, SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT));
601 if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_control, emu)) == NULL)
603 if ((err = snd_ctl_add(card, kctl)))
608 if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL)
610 if ((err = snd_ctl_add(card, kctl)))
612 } else if (! emu->APS) {
614 if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL)
616 if ((err = snd_ctl_add(card, kctl)))