]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - sound/pci/emu10k1/emumixer.c
[ALSA] powermac - Revert the last addition for 17' powerbook
[mirror_ubuntu-bionic-kernel.git] / sound / pci / emu10k1 / emumixer.c
CommitLineData
1da177e4
LT
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
eb4698f3 38static int snd_emu10k1_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1da177e4
LT
39{
40 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
41 uinfo->count = 1;
42 return 0;
43}
44
eb4698f3
TI
45static int snd_emu10k1_spdif_get(struct snd_kcontrol *kcontrol,
46 struct snd_ctl_elem_value *ucontrol)
1da177e4 47{
eb4698f3 48 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1da177e4
LT
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
eb4698f3
TI
61static int snd_emu10k1_spdif_get_mask(struct snd_kcontrol *kcontrol,
62 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
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
0af68e5e 71#if 0
eb4698f3 72static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1da177e4
LT
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
eb4698f3
TI
85static int snd_audigy_spdif_output_rate_get(struct snd_kcontrol *kcontrol,
86 struct snd_ctl_elem_value *ucontrol)
1da177e4 87{
eb4698f3 88 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1da177e4
LT
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
eb4698f3
TI
112static int snd_audigy_spdif_output_rate_put(struct snd_kcontrol *kcontrol,
113 struct snd_ctl_elem_value *ucontrol)
1da177e4 114{
eb4698f3 115 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1da177e4
LT
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
eb4698f3 146static struct snd_kcontrol_new snd_audigy_spdif_output_rate =
1da177e4
LT
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};
0af68e5e 156#endif
1da177e4 157
eb4698f3
TI
158static int snd_emu10k1_spdif_put(struct snd_kcontrol *kcontrol,
159 struct snd_ctl_elem_value *ucontrol)
1da177e4 160{
eb4698f3 161 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1da177e4
LT
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
eb4698f3 181static struct snd_kcontrol_new snd_emu10k1_spdif_mask_control =
1da177e4
LT
182{
183 .access = SNDRV_CTL_ELEM_ACCESS_READ,
5549d549 184 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1da177e4
LT
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
eb4698f3 191static struct snd_kcontrol_new snd_emu10k1_spdif_control =
1da177e4 192{
5549d549 193 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1da177e4
LT
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
eb4698f3 202static void update_emu10k1_fxrt(struct snd_emu10k1 *emu, int voice, unsigned char *route)
1da177e4
LT
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
eb4698f3 215static void update_emu10k1_send_volume(struct snd_emu10k1 *emu, int voice, unsigned char *volume)
1da177e4
LT
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
eb4698f3 232static int snd_emu10k1_send_routing_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1da177e4 233{
eb4698f3 234 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1da177e4
LT
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
eb4698f3
TI
242static int snd_emu10k1_send_routing_get(struct snd_kcontrol *kcontrol,
243 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
244{
245 unsigned long flags;
eb4698f3
TI
246 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
247 struct snd_emu10k1_pcm_mixer *mix =
248 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
1da177e4
LT
249 int voice, idx;
250 int num_efx = emu->audigy ? 8 : 4;
251 int mask = emu->audigy ? 0x3f : 0x0f;
252
253 spin_lock_irqsave(&emu->reg_lock, flags);
254 for (voice = 0; voice < 3; voice++)
255 for (idx = 0; idx < num_efx; idx++)
256 ucontrol->value.integer.value[(voice * num_efx) + idx] =
257 mix->send_routing[voice][idx] & mask;
258 spin_unlock_irqrestore(&emu->reg_lock, flags);
259 return 0;
260}
261
eb4698f3
TI
262static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol,
263 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
264{
265 unsigned long flags;
eb4698f3
TI
266 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
267 struct snd_emu10k1_pcm_mixer *mix =
268 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
1da177e4
LT
269 int change = 0, voice, idx, val;
270 int num_efx = emu->audigy ? 8 : 4;
271 int mask = emu->audigy ? 0x3f : 0x0f;
272
273 spin_lock_irqsave(&emu->reg_lock, flags);
274 for (voice = 0; voice < 3; voice++)
275 for (idx = 0; idx < num_efx; idx++) {
276 val = ucontrol->value.integer.value[(voice * num_efx) + idx] & mask;
277 if (mix->send_routing[voice][idx] != val) {
278 mix->send_routing[voice][idx] = val;
279 change = 1;
280 }
281 }
282 if (change && mix->epcm) {
283 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
284 update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number,
285 &mix->send_routing[1][0]);
286 update_emu10k1_fxrt(emu, mix->epcm->voices[1]->number,
287 &mix->send_routing[2][0]);
288 } else if (mix->epcm->voices[0]) {
289 update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number,
290 &mix->send_routing[0][0]);
291 }
292 }
293 spin_unlock_irqrestore(&emu->reg_lock, flags);
294 return change;
295}
296
eb4698f3 297static struct snd_kcontrol_new snd_emu10k1_send_routing_control =
1da177e4
LT
298{
299 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
67ed4161 300 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1da177e4
LT
301 .name = "EMU10K1 PCM Send Routing",
302 .count = 32,
303 .info = snd_emu10k1_send_routing_info,
304 .get = snd_emu10k1_send_routing_get,
305 .put = snd_emu10k1_send_routing_put
306};
307
eb4698f3 308static int snd_emu10k1_send_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1da177e4 309{
eb4698f3 310 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1da177e4
LT
311 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
312 uinfo->count = emu->audigy ? 3*8 : 3*4;
313 uinfo->value.integer.min = 0;
314 uinfo->value.integer.max = 255;
315 return 0;
316}
317
eb4698f3
TI
318static int snd_emu10k1_send_volume_get(struct snd_kcontrol *kcontrol,
319 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
320{
321 unsigned long flags;
eb4698f3
TI
322 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
323 struct snd_emu10k1_pcm_mixer *mix =
324 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
1da177e4
LT
325 int idx;
326 int num_efx = emu->audigy ? 8 : 4;
327
328 spin_lock_irqsave(&emu->reg_lock, flags);
329 for (idx = 0; idx < 3*num_efx; idx++)
330 ucontrol->value.integer.value[idx] = mix->send_volume[idx/num_efx][idx%num_efx];
331 spin_unlock_irqrestore(&emu->reg_lock, flags);
332 return 0;
333}
334
eb4698f3
TI
335static int snd_emu10k1_send_volume_put(struct snd_kcontrol *kcontrol,
336 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
337{
338 unsigned long flags;
eb4698f3
TI
339 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
340 struct snd_emu10k1_pcm_mixer *mix =
341 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
1da177e4
LT
342 int change = 0, idx, val;
343 int num_efx = emu->audigy ? 8 : 4;
344
345 spin_lock_irqsave(&emu->reg_lock, flags);
346 for (idx = 0; idx < 3*num_efx; idx++) {
347 val = ucontrol->value.integer.value[idx] & 255;
348 if (mix->send_volume[idx/num_efx][idx%num_efx] != val) {
349 mix->send_volume[idx/num_efx][idx%num_efx] = val;
350 change = 1;
351 }
352 }
353 if (change && mix->epcm) {
354 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
355 update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number,
356 &mix->send_volume[1][0]);
357 update_emu10k1_send_volume(emu, mix->epcm->voices[1]->number,
358 &mix->send_volume[2][0]);
359 } else if (mix->epcm->voices[0]) {
360 update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number,
361 &mix->send_volume[0][0]);
362 }
363 }
364 spin_unlock_irqrestore(&emu->reg_lock, flags);
365 return change;
366}
367
eb4698f3 368static struct snd_kcontrol_new snd_emu10k1_send_volume_control =
1da177e4
LT
369{
370 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
67ed4161 371 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1da177e4
LT
372 .name = "EMU10K1 PCM Send Volume",
373 .count = 32,
374 .info = snd_emu10k1_send_volume_info,
375 .get = snd_emu10k1_send_volume_get,
376 .put = snd_emu10k1_send_volume_put
377};
378
eb4698f3 379static int snd_emu10k1_attn_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1da177e4
LT
380{
381 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
382 uinfo->count = 3;
383 uinfo->value.integer.min = 0;
384 uinfo->value.integer.max = 0xffff;
385 return 0;
386}
387
eb4698f3
TI
388static int snd_emu10k1_attn_get(struct snd_kcontrol *kcontrol,
389 struct snd_ctl_elem_value *ucontrol)
1da177e4 390{
eb4698f3
TI
391 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
392 struct snd_emu10k1_pcm_mixer *mix =
393 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
1da177e4
LT
394 unsigned long flags;
395 int idx;
396
397 spin_lock_irqsave(&emu->reg_lock, flags);
398 for (idx = 0; idx < 3; idx++)
399 ucontrol->value.integer.value[idx] = mix->attn[idx];
400 spin_unlock_irqrestore(&emu->reg_lock, flags);
401 return 0;
402}
403
eb4698f3
TI
404static int snd_emu10k1_attn_put(struct snd_kcontrol *kcontrol,
405 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
406{
407 unsigned long flags;
eb4698f3
TI
408 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
409 struct snd_emu10k1_pcm_mixer *mix =
410 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
1da177e4
LT
411 int change = 0, idx, val;
412
413 spin_lock_irqsave(&emu->reg_lock, flags);
414 for (idx = 0; idx < 3; idx++) {
415 val = ucontrol->value.integer.value[idx] & 0xffff;
416 if (mix->attn[idx] != val) {
417 mix->attn[idx] = val;
418 change = 1;
419 }
420 }
421 if (change && mix->epcm) {
422 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
423 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[1]);
424 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[1]->number, mix->attn[2]);
425 } else if (mix->epcm->voices[0]) {
426 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[0]);
427 }
428 }
429 spin_unlock_irqrestore(&emu->reg_lock, flags);
430 return change;
431}
432
eb4698f3 433static struct snd_kcontrol_new snd_emu10k1_attn_control =
1da177e4
LT
434{
435 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
67ed4161 436 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1da177e4
LT
437 .name = "EMU10K1 PCM Volume",
438 .count = 32,
439 .info = snd_emu10k1_attn_info,
440 .get = snd_emu10k1_attn_get,
441 .put = snd_emu10k1_attn_put
442};
443
444/* Mutichannel PCM stream controls */
445
eb4698f3 446static int snd_emu10k1_efx_send_routing_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1da177e4 447{
eb4698f3 448 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1da177e4
LT
449 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
450 uinfo->count = emu->audigy ? 8 : 4;
451 uinfo->value.integer.min = 0;
452 uinfo->value.integer.max = emu->audigy ? 0x3f : 0x0f;
453 return 0;
454}
455
eb4698f3
TI
456static int snd_emu10k1_efx_send_routing_get(struct snd_kcontrol *kcontrol,
457 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
458{
459 unsigned long flags;
eb4698f3
TI
460 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
461 struct snd_emu10k1_pcm_mixer *mix =
462 &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
1da177e4
LT
463 int idx;
464 int num_efx = emu->audigy ? 8 : 4;
465 int mask = emu->audigy ? 0x3f : 0x0f;
466
467 spin_lock_irqsave(&emu->reg_lock, flags);
468 for (idx = 0; idx < num_efx; idx++)
469 ucontrol->value.integer.value[idx] =
470 mix->send_routing[0][idx] & mask;
471 spin_unlock_irqrestore(&emu->reg_lock, flags);
472 return 0;
473}
474
eb4698f3
TI
475static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol,
476 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
477{
478 unsigned long flags;
eb4698f3 479 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1da177e4 480 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
eb4698f3 481 struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
1da177e4
LT
482 int change = 0, idx, val;
483 int num_efx = emu->audigy ? 8 : 4;
484 int mask = emu->audigy ? 0x3f : 0x0f;
485
486 spin_lock_irqsave(&emu->reg_lock, flags);
487 for (idx = 0; idx < num_efx; idx++) {
488 val = ucontrol->value.integer.value[idx] & mask;
489 if (mix->send_routing[0][idx] != val) {
490 mix->send_routing[0][idx] = val;
491 change = 1;
492 }
493 }
494
495 if (change && mix->epcm) {
496 if (mix->epcm->voices[ch]) {
497 update_emu10k1_fxrt(emu, mix->epcm->voices[ch]->number,
498 &mix->send_routing[0][0]);
499 }
500 }
501 spin_unlock_irqrestore(&emu->reg_lock, flags);
502 return change;
503}
504
eb4698f3 505static struct snd_kcontrol_new snd_emu10k1_efx_send_routing_control =
1da177e4
LT
506{
507 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
508 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
509 .name = "Multichannel PCM Send Routing",
510 .count = 16,
511 .info = snd_emu10k1_efx_send_routing_info,
512 .get = snd_emu10k1_efx_send_routing_get,
513 .put = snd_emu10k1_efx_send_routing_put
514};
515
eb4698f3 516static int snd_emu10k1_efx_send_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1da177e4 517{
eb4698f3 518 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1da177e4
LT
519 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
520 uinfo->count = emu->audigy ? 8 : 4;
521 uinfo->value.integer.min = 0;
522 uinfo->value.integer.max = 255;
523 return 0;
524}
525
eb4698f3
TI
526static int snd_emu10k1_efx_send_volume_get(struct snd_kcontrol *kcontrol,
527 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
528{
529 unsigned long flags;
eb4698f3
TI
530 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
531 struct snd_emu10k1_pcm_mixer *mix =
532 &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
1da177e4
LT
533 int idx;
534 int num_efx = emu->audigy ? 8 : 4;
535
536 spin_lock_irqsave(&emu->reg_lock, flags);
537 for (idx = 0; idx < num_efx; idx++)
538 ucontrol->value.integer.value[idx] = mix->send_volume[0][idx];
539 spin_unlock_irqrestore(&emu->reg_lock, flags);
540 return 0;
541}
542
eb4698f3
TI
543static int snd_emu10k1_efx_send_volume_put(struct snd_kcontrol *kcontrol,
544 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
545{
546 unsigned long flags;
eb4698f3 547 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1da177e4 548 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
eb4698f3 549 struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
1da177e4
LT
550 int change = 0, idx, val;
551 int num_efx = emu->audigy ? 8 : 4;
552
553 spin_lock_irqsave(&emu->reg_lock, flags);
554 for (idx = 0; idx < num_efx; idx++) {
555 val = ucontrol->value.integer.value[idx] & 255;
556 if (mix->send_volume[0][idx] != val) {
557 mix->send_volume[0][idx] = val;
558 change = 1;
559 }
560 }
561 if (change && mix->epcm) {
562 if (mix->epcm->voices[ch]) {
563 update_emu10k1_send_volume(emu, mix->epcm->voices[ch]->number,
564 &mix->send_volume[0][0]);
565 }
566 }
567 spin_unlock_irqrestore(&emu->reg_lock, flags);
568 return change;
569}
570
571
eb4698f3 572static struct snd_kcontrol_new snd_emu10k1_efx_send_volume_control =
1da177e4
LT
573{
574 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
575 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
576 .name = "Multichannel PCM Send Volume",
577 .count = 16,
578 .info = snd_emu10k1_efx_send_volume_info,
579 .get = snd_emu10k1_efx_send_volume_get,
580 .put = snd_emu10k1_efx_send_volume_put
581};
582
eb4698f3 583static int snd_emu10k1_efx_attn_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1da177e4
LT
584{
585 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
586 uinfo->count = 1;
587 uinfo->value.integer.min = 0;
588 uinfo->value.integer.max = 0xffff;
589 return 0;
590}
591
eb4698f3
TI
592static int snd_emu10k1_efx_attn_get(struct snd_kcontrol *kcontrol,
593 struct snd_ctl_elem_value *ucontrol)
1da177e4 594{
eb4698f3
TI
595 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
596 struct snd_emu10k1_pcm_mixer *mix =
597 &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
1da177e4
LT
598 unsigned long flags;
599
600 spin_lock_irqsave(&emu->reg_lock, flags);
601 ucontrol->value.integer.value[0] = mix->attn[0];
602 spin_unlock_irqrestore(&emu->reg_lock, flags);
603 return 0;
604}
605
eb4698f3
TI
606static int snd_emu10k1_efx_attn_put(struct snd_kcontrol *kcontrol,
607 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
608{
609 unsigned long flags;
eb4698f3 610 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1da177e4 611 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
eb4698f3 612 struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
1da177e4
LT
613 int change = 0, val;
614
615 spin_lock_irqsave(&emu->reg_lock, flags);
616 val = ucontrol->value.integer.value[0] & 0xffff;
617 if (mix->attn[0] != val) {
618 mix->attn[0] = val;
619 change = 1;
620 }
621 if (change && mix->epcm) {
622 if (mix->epcm->voices[ch]) {
623 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[ch]->number, mix->attn[0]);
624 }
625 }
626 spin_unlock_irqrestore(&emu->reg_lock, flags);
627 return change;
628}
629
eb4698f3 630static struct snd_kcontrol_new snd_emu10k1_efx_attn_control =
1da177e4
LT
631{
632 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
633 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
634 .name = "Multichannel PCM Volume",
635 .count = 16,
636 .info = snd_emu10k1_efx_attn_info,
637 .get = snd_emu10k1_efx_attn_get,
638 .put = snd_emu10k1_efx_attn_put
639};
640
eb4698f3 641static int snd_emu10k1_shared_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1da177e4
LT
642{
643 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
644 uinfo->count = 1;
645 uinfo->value.integer.min = 0;
646 uinfo->value.integer.max = 1;
647 return 0;
648}
649
eb4698f3
TI
650static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol,
651 struct snd_ctl_elem_value *ucontrol)
1da177e4 652{
eb4698f3 653 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1da177e4
LT
654
655 if (emu->audigy)
656 ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
657 else
658 ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;
659 return 0;
660}
661
eb4698f3
TI
662static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
663 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
664{
665 unsigned long flags;
eb4698f3 666 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1da177e4
LT
667 unsigned int reg, val;
668 int change = 0;
669
670 spin_lock_irqsave(&emu->reg_lock, flags);
671 if (emu->audigy) {
672 reg = inl(emu->port + A_IOCFG);
673 val = ucontrol->value.integer.value[0] ? A_IOCFG_GPOUT0 : 0;
674 change = (reg & A_IOCFG_GPOUT0) != val;
675 if (change) {
676 reg &= ~A_IOCFG_GPOUT0;
677 reg |= val;
678 outl(reg | val, emu->port + A_IOCFG);
679 }
680 }
681 reg = inl(emu->port + HCFG);
682 val = ucontrol->value.integer.value[0] ? HCFG_GPOUT0 : 0;
683 change |= (reg & HCFG_GPOUT0) != val;
684 if (change) {
685 reg &= ~HCFG_GPOUT0;
686 reg |= val;
687 outl(reg | val, emu->port + HCFG);
688 }
689 spin_unlock_irqrestore(&emu->reg_lock, flags);
690 return change;
691}
692
eb4698f3 693static struct snd_kcontrol_new snd_emu10k1_shared_spdif __devinitdata =
1da177e4
LT
694{
695 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
696 .name = "SB Live 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
eb4698f3 702static struct snd_kcontrol_new snd_audigy_shared_spdif __devinitdata =
1da177e4
LT
703{
704 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
705 .name = "Audigy Analog/Digital Output Jack",
706 .info = snd_emu10k1_shared_spdif_info,
707 .get = snd_emu10k1_shared_spdif_get,
708 .put = snd_emu10k1_shared_spdif_put
709};
710
711/*
712 */
eb4698f3 713static void snd_emu10k1_mixer_free_ac97(struct snd_ac97 *ac97)
1da177e4 714{
eb4698f3 715 struct snd_emu10k1 *emu = ac97->private_data;
1da177e4
LT
716 emu->ac97 = NULL;
717}
718
719/*
720 */
eb4698f3 721static int remove_ctl(struct snd_card *card, const char *name)
1da177e4 722{
eb4698f3 723 struct snd_ctl_elem_id id;
1da177e4
LT
724 memset(&id, 0, sizeof(id));
725 strcpy(id.name, name);
726 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
727 return snd_ctl_remove_id(card, &id);
728}
729
eb4698f3 730static struct snd_kcontrol *ctl_find(struct snd_card *card, const char *name)
1da177e4 731{
eb4698f3 732 struct snd_ctl_elem_id sid;
1da177e4
LT
733 memset(&sid, 0, sizeof(sid));
734 strcpy(sid.name, name);
735 sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
736 return snd_ctl_find_id(card, &sid);
737}
738
eb4698f3 739static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
1da177e4 740{
eb4698f3 741 struct snd_kcontrol *kctl = ctl_find(card, src);
1da177e4
LT
742 if (kctl) {
743 strcpy(kctl->id.name, dst);
744 return 0;
745 }
746 return -ENOENT;
747}
748
eb4698f3 749int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
67ed4161 750 int pcm_device, int multi_device)
1da177e4
LT
751{
752 int err, pcm;
eb4698f3
TI
753 struct snd_kcontrol *kctl;
754 struct snd_card *card = emu->card;
1da177e4
LT
755 char **c;
756 static char *emu10k1_remove_ctls[] = {
757 /* no AC97 mono, surround, center/lfe */
758 "Master Mono Playback Switch",
759 "Master Mono Playback Volume",
760 "PCM Out Path & Mute",
761 "Mono Output Select",
762 "Surround Playback Switch",
763 "Surround Playback Volume",
764 "Center Playback Switch",
765 "Center Playback Volume",
766 "LFE Playback Switch",
767 "LFE Playback Volume",
768 NULL
769 };
770 static char *emu10k1_rename_ctls[] = {
771 "Surround Digital Playback Volume", "Surround Playback Volume",
772 "Center Digital Playback Volume", "Center Playback Volume",
773 "LFE Digital Playback Volume", "LFE Playback Volume",
774 NULL
775 };
776 static char *audigy_remove_ctls[] = {
777 /* Master/PCM controls on ac97 of Audigy has no effect */
778 "PCM Playback Switch",
779 "PCM Playback Volume",
780 "Master Mono Playback Switch",
781 "Master Mono Playback Volume",
782 "Master Playback Switch",
783 "Master Playback Volume",
784 "PCM Out Path & Mute",
785 "Mono Output Select",
786 /* remove unused AC97 capture controls */
787 "Capture Source",
788 "Capture Switch",
789 "Capture Volume",
790 "Mic Select",
791 "Video Playback Switch",
792 "Video Playback Volume",
793 "Mic Playback Switch",
794 "Mic Playback Volume",
795 NULL
796 };
797 static char *audigy_rename_ctls[] = {
798 /* use conventional names */
799 "Wave Playback Volume", "PCM Playback Volume",
800 /* "Wave Capture Volume", "PCM Capture Volume", */
801 "Wave Master Playback Volume", "Master Playback Volume",
802 "AMic Playback Volume", "Mic Playback Volume",
803 NULL
804 };
805
2b637da5 806 if (emu->card_capabilities->ac97_chip) {
eb4698f3
TI
807 struct snd_ac97_bus *pbus;
808 struct snd_ac97_template ac97;
809 static struct snd_ac97_bus_ops ops = {
1da177e4
LT
810 .write = snd_emu10k1_ac97_write,
811 .read = snd_emu10k1_ac97_read,
812 };
813
b1508693
TI
814 if ((err = snd_ac97_bus(emu->card, 0, &ops, NULL, &pbus)) < 0)
815 return err;
1da177e4
LT
816 pbus->no_vra = 1; /* we don't need VRA */
817
818 memset(&ac97, 0, sizeof(ac97));
819 ac97.private_data = emu;
820 ac97.private_free = snd_emu10k1_mixer_free_ac97;
821 ac97.scaps = AC97_SCAP_NO_SPDIF;
b1508693
TI
822 if ((err = snd_ac97_mixer(pbus, &ac97, &emu->ac97)) < 0) {
823 if (emu->card_capabilities->ac97_chip == 1)
824 return err;
825 snd_printd(KERN_INFO "emu10k1: AC97 is optional on this board\n");
826 snd_printd(KERN_INFO" Proceeding without ac97 mixers...\n");
827 snd_device_free(emu->card, pbus);
828 goto no_ac97; /* FIXME: get rid of ugly gotos.. */
829 }
1da177e4
LT
830 if (emu->audigy) {
831 /* set master volume to 0 dB */
832 snd_ac97_write(emu->ac97, AC97_MASTER, 0x0000);
833 /* set capture source to mic */
834 snd_ac97_write(emu->ac97, AC97_REC_SEL, 0x0000);
835 c = audigy_remove_ctls;
836 } else {
837 /*
838 * Credits for cards based on STAC9758:
839 * James Courtier-Dutton <James@superbug.demon.co.uk>
840 * Voluspa <voluspa@comhem.se>
841 */
842 if (emu->ac97->id == AC97_ID_STAC9758) {
843 emu->rear_ac97 = 1;
844 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT);
845 }
846 /* remove unused AC97 controls */
847 snd_ac97_write(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
848 snd_ac97_write(emu->ac97, AC97_CENTER_LFE_MASTER, 0x0202);
849 c = emu10k1_remove_ctls;
850 }
851 for (; *c; c++)
852 remove_ctl(card, *c);
853 } else {
f12aa40c 854 no_ac97:
2b637da5 855 if (emu->card_capabilities->ecard)
1da177e4
LT
856 strcpy(emu->card->mixername, "EMU APS");
857 else if (emu->audigy)
858 strcpy(emu->card->mixername, "SB Audigy");
859 else
860 strcpy(emu->card->mixername, "Emu10k1");
861 }
862
863 if (emu->audigy)
864 c = audigy_rename_ctls;
865 else
866 c = emu10k1_rename_ctls;
867 for (; *c; c += 2)
868 rename_ctl(card, c[0], c[1]);
869
870 if ((kctl = emu->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu)) == NULL)
871 return -ENOMEM;
67ed4161 872 kctl->id.device = pcm_device;
1da177e4
LT
873 if ((err = snd_ctl_add(card, kctl)))
874 return err;
875 if ((kctl = emu->ctl_send_volume = snd_ctl_new1(&snd_emu10k1_send_volume_control, emu)) == NULL)
876 return -ENOMEM;
67ed4161 877 kctl->id.device = pcm_device;
1da177e4
LT
878 if ((err = snd_ctl_add(card, kctl)))
879 return err;
880 if ((kctl = emu->ctl_attn = snd_ctl_new1(&snd_emu10k1_attn_control, emu)) == NULL)
881 return -ENOMEM;
67ed4161 882 kctl->id.device = pcm_device;
1da177e4
LT
883 if ((err = snd_ctl_add(card, kctl)))
884 return err;
885
886 if ((kctl = emu->ctl_efx_send_routing = snd_ctl_new1(&snd_emu10k1_efx_send_routing_control, emu)) == NULL)
887 return -ENOMEM;
67ed4161 888 kctl->id.device = multi_device;
1da177e4
LT
889 if ((err = snd_ctl_add(card, kctl)))
890 return err;
891
892 if ((kctl = emu->ctl_efx_send_volume = snd_ctl_new1(&snd_emu10k1_efx_send_volume_control, emu)) == NULL)
893 return -ENOMEM;
67ed4161 894 kctl->id.device = multi_device;
1da177e4
LT
895 if ((err = snd_ctl_add(card, kctl)))
896 return err;
897
898 if ((kctl = emu->ctl_efx_attn = snd_ctl_new1(&snd_emu10k1_efx_attn_control, emu)) == NULL)
899 return -ENOMEM;
67ed4161 900 kctl->id.device = multi_device;
1da177e4
LT
901 if ((err = snd_ctl_add(card, kctl)))
902 return err;
903
904 /* initialize the routing and volume table for each pcm playback stream */
905 for (pcm = 0; pcm < 32; pcm++) {
eb4698f3 906 struct snd_emu10k1_pcm_mixer *mix;
1da177e4
LT
907 int v;
908
909 mix = &emu->pcm_mixer[pcm];
910 mix->epcm = NULL;
911
912 for (v = 0; v < 4; v++)
913 mix->send_routing[0][v] =
914 mix->send_routing[1][v] =
915 mix->send_routing[2][v] = v;
916
917 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
918 mix->send_volume[0][0] = mix->send_volume[0][1] =
919 mix->send_volume[1][0] = mix->send_volume[2][1] = 255;
920
921 mix->attn[0] = mix->attn[1] = mix->attn[2] = 0xffff;
922 }
923
924 /* initialize the routing and volume table for the multichannel playback stream */
925 for (pcm = 0; pcm < NUM_EFX_PLAYBACK; pcm++) {
eb4698f3 926 struct snd_emu10k1_pcm_mixer *mix;
1da177e4
LT
927 int v;
928
929 mix = &emu->efx_pcm_mixer[pcm];
930 mix->epcm = NULL;
931
932 mix->send_routing[0][0] = pcm;
933 mix->send_routing[0][1] = (pcm == 0) ? 1 : 0;
934 for (v = 0; v < 2; v++)
935 mix->send_routing[0][2+v] = 13+v;
936 if (emu->audigy)
937 for (v = 0; v < 4; v++)
938 mix->send_routing[0][4+v] = 60+v;
939
940 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
941 mix->send_volume[0][0] = 255;
942
943 mix->attn[0] = 0xffff;
944 }
945
2b637da5 946 if (! emu->card_capabilities->ecard) { /* FIXME: APS has these controls? */
1da177e4
LT
947 /* sb live! and audigy */
948 if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL)
949 return -ENOMEM;
5549d549
CL
950 if (!emu->audigy)
951 kctl->id.device = emu->pcm_efx->device;
1da177e4
LT
952 if ((err = snd_ctl_add(card, kctl)))
953 return err;
954 if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_control, emu)) == NULL)
955 return -ENOMEM;
5549d549
CL
956 if (!emu->audigy)
957 kctl->id.device = emu->pcm_efx->device;
1da177e4
LT
958 if ((err = snd_ctl_add(card, kctl)))
959 return err;
960 }
961
962 if (emu->audigy) {
963 if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL)
964 return -ENOMEM;
965 if ((err = snd_ctl_add(card, kctl)))
966 return err;
001f7589 967#if 0
1da177e4
LT
968 if ((kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu)) == NULL)
969 return -ENOMEM;
970 if ((err = snd_ctl_add(card, kctl)))
971 return err;
001f7589 972#endif
2b637da5 973 } else if (! emu->card_capabilities->ecard) {
1da177e4
LT
974 /* sb live! */
975 if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL)
976 return -ENOMEM;
977 if ((err = snd_ctl_add(card, kctl)))
978 return err;
979 }
2b637da5 980 if (emu->card_capabilities->ca0151_chip) { /* P16V */
1da177e4
LT
981 if ((err = snd_p16v_mixer(emu)))
982 return err;
983 }
984
985 return 0;
986}