]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - sound/pci/emu10k1/emumixer.c
[ALSA] korg1212: fix typo
[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
38static 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
45static 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
61static 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
0af68e5e 71#if 0
1da177e4
LT
72static 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
85static 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
112static 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
146static 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};
0af68e5e 156#endif
1da177e4
LT
157
158static 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
181static snd_kcontrol_new_t snd_emu10k1_spdif_mask_control =
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
191static snd_kcontrol_new_t snd_emu10k1_spdif_control =
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
202static 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
215static 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
232static 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
242static 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
261static 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
295static snd_kcontrol_new_t snd_emu10k1_send_routing_control =
296{
297 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
67ed4161 298 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1da177e4
LT
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
306static 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
316static 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
332static 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
364static snd_kcontrol_new_t snd_emu10k1_send_volume_control =
365{
366 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
67ed4161 367 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1da177e4
LT
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
375static 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
384static 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
399static 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
427static snd_kcontrol_new_t snd_emu10k1_attn_control =
428{
429 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
67ed4161 430 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1da177e4
LT
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
440static 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
450static 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
468static 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
498static 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
509static 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
519static 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
535static 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
564static 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
575static 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
584static 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
597static 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
621static 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
632static 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
641static 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
653static 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
684static 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
693static 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 */
704static 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 */
712static 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
721static 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
730static 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
67ed4161
CL
740int __devinit snd_emu10k1_mixer(emu10k1_t *emu,
741 int pcm_device, int multi_device)
1da177e4
LT
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
2b637da5 797 if (emu->card_capabilities->ac97_chip) {
1da177e4
LT
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
f12aa40c
TI
805 if ((err = snd_ac97_bus(emu->card, 0, &ops, NULL, &pbus)) < 0) {
806 if (emu->card_capabilities->ac97_chip == 1)
807 return err;
808 snd_printd(KERN_INFO "emu10k1: AC97 is optional on this board\n");
809 snd_printd(KERN_INFO" Proceeding without ac97 mixers...\n");
810 goto no_ac97; /* FIXME: get rid of ugly gotos.. */
811 }
1da177e4
LT
812 pbus->no_vra = 1; /* we don't need VRA */
813
814 memset(&ac97, 0, sizeof(ac97));
815 ac97.private_data = emu;
816 ac97.private_free = snd_emu10k1_mixer_free_ac97;
817 ac97.scaps = AC97_SCAP_NO_SPDIF;
818 if ((err = snd_ac97_mixer(pbus, &ac97, &emu->ac97)) < 0)
819 return err;
820 if (emu->audigy) {
821 /* set master volume to 0 dB */
822 snd_ac97_write(emu->ac97, AC97_MASTER, 0x0000);
823 /* set capture source to mic */
824 snd_ac97_write(emu->ac97, AC97_REC_SEL, 0x0000);
825 c = audigy_remove_ctls;
826 } else {
827 /*
828 * Credits for cards based on STAC9758:
829 * James Courtier-Dutton <James@superbug.demon.co.uk>
830 * Voluspa <voluspa@comhem.se>
831 */
832 if (emu->ac97->id == AC97_ID_STAC9758) {
833 emu->rear_ac97 = 1;
834 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT);
835 }
836 /* remove unused AC97 controls */
837 snd_ac97_write(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
838 snd_ac97_write(emu->ac97, AC97_CENTER_LFE_MASTER, 0x0202);
839 c = emu10k1_remove_ctls;
840 }
841 for (; *c; c++)
842 remove_ctl(card, *c);
843 } else {
f12aa40c 844 no_ac97:
2b637da5 845 if (emu->card_capabilities->ecard)
1da177e4
LT
846 strcpy(emu->card->mixername, "EMU APS");
847 else if (emu->audigy)
848 strcpy(emu->card->mixername, "SB Audigy");
849 else
850 strcpy(emu->card->mixername, "Emu10k1");
851 }
852
853 if (emu->audigy)
854 c = audigy_rename_ctls;
855 else
856 c = emu10k1_rename_ctls;
857 for (; *c; c += 2)
858 rename_ctl(card, c[0], c[1]);
859
860 if ((kctl = emu->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu)) == NULL)
861 return -ENOMEM;
67ed4161 862 kctl->id.device = pcm_device;
1da177e4
LT
863 if ((err = snd_ctl_add(card, kctl)))
864 return err;
865 if ((kctl = emu->ctl_send_volume = snd_ctl_new1(&snd_emu10k1_send_volume_control, emu)) == NULL)
866 return -ENOMEM;
67ed4161 867 kctl->id.device = pcm_device;
1da177e4
LT
868 if ((err = snd_ctl_add(card, kctl)))
869 return err;
870 if ((kctl = emu->ctl_attn = snd_ctl_new1(&snd_emu10k1_attn_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
876 if ((kctl = emu->ctl_efx_send_routing = snd_ctl_new1(&snd_emu10k1_efx_send_routing_control, emu)) == NULL)
877 return -ENOMEM;
67ed4161 878 kctl->id.device = multi_device;
1da177e4
LT
879 if ((err = snd_ctl_add(card, kctl)))
880 return err;
881
882 if ((kctl = emu->ctl_efx_send_volume = snd_ctl_new1(&snd_emu10k1_efx_send_volume_control, emu)) == NULL)
883 return -ENOMEM;
67ed4161 884 kctl->id.device = multi_device;
1da177e4
LT
885 if ((err = snd_ctl_add(card, kctl)))
886 return err;
887
888 if ((kctl = emu->ctl_efx_attn = snd_ctl_new1(&snd_emu10k1_efx_attn_control, emu)) == NULL)
889 return -ENOMEM;
67ed4161 890 kctl->id.device = multi_device;
1da177e4
LT
891 if ((err = snd_ctl_add(card, kctl)))
892 return err;
893
894 /* initialize the routing and volume table for each pcm playback stream */
895 for (pcm = 0; pcm < 32; pcm++) {
896 emu10k1_pcm_mixer_t *mix;
897 int v;
898
899 mix = &emu->pcm_mixer[pcm];
900 mix->epcm = NULL;
901
902 for (v = 0; v < 4; v++)
903 mix->send_routing[0][v] =
904 mix->send_routing[1][v] =
905 mix->send_routing[2][v] = v;
906
907 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
908 mix->send_volume[0][0] = mix->send_volume[0][1] =
909 mix->send_volume[1][0] = mix->send_volume[2][1] = 255;
910
911 mix->attn[0] = mix->attn[1] = mix->attn[2] = 0xffff;
912 }
913
914 /* initialize the routing and volume table for the multichannel playback stream */
915 for (pcm = 0; pcm < NUM_EFX_PLAYBACK; pcm++) {
916 emu10k1_pcm_mixer_t *mix;
917 int v;
918
919 mix = &emu->efx_pcm_mixer[pcm];
920 mix->epcm = NULL;
921
922 mix->send_routing[0][0] = pcm;
923 mix->send_routing[0][1] = (pcm == 0) ? 1 : 0;
924 for (v = 0; v < 2; v++)
925 mix->send_routing[0][2+v] = 13+v;
926 if (emu->audigy)
927 for (v = 0; v < 4; v++)
928 mix->send_routing[0][4+v] = 60+v;
929
930 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
931 mix->send_volume[0][0] = 255;
932
933 mix->attn[0] = 0xffff;
934 }
935
2b637da5 936 if (! emu->card_capabilities->ecard) { /* FIXME: APS has these controls? */
1da177e4
LT
937 /* sb live! and audigy */
938 if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL)
939 return -ENOMEM;
5549d549
CL
940 if (!emu->audigy)
941 kctl->id.device = emu->pcm_efx->device;
1da177e4
LT
942 if ((err = snd_ctl_add(card, kctl)))
943 return err;
944 if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_control, emu)) == NULL)
945 return -ENOMEM;
5549d549
CL
946 if (!emu->audigy)
947 kctl->id.device = emu->pcm_efx->device;
1da177e4
LT
948 if ((err = snd_ctl_add(card, kctl)))
949 return err;
950 }
951
952 if (emu->audigy) {
953 if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL)
954 return -ENOMEM;
955 if ((err = snd_ctl_add(card, kctl)))
956 return err;
001f7589 957#if 0
1da177e4
LT
958 if ((kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu)) == NULL)
959 return -ENOMEM;
960 if ((err = snd_ctl_add(card, kctl)))
961 return err;
001f7589 962#endif
2b637da5 963 } else if (! emu->card_capabilities->ecard) {
1da177e4
LT
964 /* sb live! */
965 if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL)
966 return -ENOMEM;
967 if ((err = snd_ctl_add(card, kctl)))
968 return err;
969 }
2b637da5 970 if (emu->card_capabilities->ca0151_chip) { /* P16V */
1da177e4
LT
971 if ((err = snd_p16v_mixer(emu)))
972 return err;
973 }
974
975 return 0;
976}