blob: 9b5883b7957838b8a99375ff1ce432cb84abccb6 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Jaroslav Kyselac1017a42007-10-15 09:50:19 +02002 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 * 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 *
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +01008 * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
9 * Added EMU 1010 support.
10 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070011 * BUGS:
12 * --
13 *
14 * TODO:
15 * --
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 *
31 */
32
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/time.h>
34#include <linux/init.h>
35#include <sound/core.h>
36#include <sound/emu10k1.h>
James Courtier-Duttonb0dbdae2006-10-10 18:08:45 +010037#include <linux/delay.h>
James Courtier-Dutton184c1e22006-12-06 15:58:02 +000038#include <sound/tlv.h>
39
40#include "p17v.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
42#define AC97_ID_STAC9758 0x83847658
43
Takashi Iwai0cb29ea2007-01-29 15:33:49 +010044static const DECLARE_TLV_DB_SCALE(snd_audigy_db_scale2, -10350, 50, 1); /* WM8775 gain scale */
James Courtier-Dutton184c1e22006-12-06 15:58:02 +000045
Takashi Iwaieb4698f2005-11-17 14:50:13 +010046static int snd_emu10k1_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -070047{
48 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
49 uinfo->count = 1;
50 return 0;
51}
52
Takashi Iwaieb4698f2005-11-17 14:50:13 +010053static int snd_emu10k1_spdif_get(struct snd_kcontrol *kcontrol,
54 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -070055{
Takashi Iwaieb4698f2005-11-17 14:50:13 +010056 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
58 unsigned long flags;
59
James Courtier-Dutton74415a32007-11-12 14:55:19 +000060 /* Limit: emu->spdif_bits */
61 if (idx >= 3)
62 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -070063 spin_lock_irqsave(&emu->reg_lock, flags);
64 ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
65 ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
66 ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
67 ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
68 spin_unlock_irqrestore(&emu->reg_lock, flags);
69 return 0;
70}
71
Takashi Iwaieb4698f2005-11-17 14:50:13 +010072static int snd_emu10k1_spdif_get_mask(struct snd_kcontrol *kcontrol,
73 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -070074{
75 ucontrol->value.iec958.status[0] = 0xff;
76 ucontrol->value.iec958.status[1] = 0xff;
77 ucontrol->value.iec958.status[2] = 0xff;
78 ucontrol->value.iec958.status[3] = 0xff;
79 return 0;
80}
81
Pavel Hofman13d45702007-06-11 12:21:20 +020082/*
83 * Items labels in enum mixer controls assigning source data to
84 * each destination
85 */
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +010086static char *emu1010_src_texts[] = {
87 "Silence",
88 "Dock Mic A",
89 "Dock Mic B",
90 "Dock ADC1 Left",
91 "Dock ADC1 Right",
92 "Dock ADC2 Left",
93 "Dock ADC2 Right",
94 "Dock ADC3 Left",
95 "Dock ADC3 Right",
96 "0202 ADC Left",
97 "0202 ADC Right",
98 "0202 SPDIF Left",
99 "0202 SPDIF Right",
100 "ADAT 0",
101 "ADAT 1",
102 "ADAT 2",
103 "ADAT 3",
104 "ADAT 4",
105 "ADAT 5",
106 "ADAT 6",
107 "ADAT 7",
108 "DSP 0",
109 "DSP 1",
110 "DSP 2",
111 "DSP 3",
112 "DSP 4",
113 "DSP 5",
114 "DSP 6",
115 "DSP 7",
116 "DSP 8",
117 "DSP 9",
118 "DSP 10",
119 "DSP 11",
120 "DSP 12",
121 "DSP 13",
122 "DSP 14",
123 "DSP 15",
124 "DSP 16",
125 "DSP 17",
126 "DSP 18",
127 "DSP 19",
128 "DSP 20",
129 "DSP 21",
130 "DSP 22",
131 "DSP 23",
132 "DSP 24",
133 "DSP 25",
134 "DSP 26",
135 "DSP 27",
136 "DSP 28",
137 "DSP 29",
138 "DSP 30",
139 "DSP 31",
140};
141
Ctirad Fertr1c02e362007-12-13 16:27:13 +0100142/* 1616(m) cardbus */
143
144static char *emu1616_src_texts[] = {
145 "Silence",
146 "Dock Mic A",
147 "Dock Mic B",
148 "Dock ADC1 Left",
149 "Dock ADC1 Right",
150 "Dock ADC2 Left",
151 "Dock ADC2 Right",
152 "Dock SPDIF Left",
153 "Dock SPDIF Right",
154 "ADAT 0",
155 "ADAT 1",
156 "ADAT 2",
157 "ADAT 3",
158 "ADAT 4",
159 "ADAT 5",
160 "ADAT 6",
161 "ADAT 7",
162 "DSP 0",
163 "DSP 1",
164 "DSP 2",
165 "DSP 3",
166 "DSP 4",
167 "DSP 5",
168 "DSP 6",
169 "DSP 7",
170 "DSP 8",
171 "DSP 9",
172 "DSP 10",
173 "DSP 11",
174 "DSP 12",
175 "DSP 13",
176 "DSP 14",
177 "DSP 15",
178 "DSP 16",
179 "DSP 17",
180 "DSP 18",
181 "DSP 19",
182 "DSP 20",
183 "DSP 21",
184 "DSP 22",
185 "DSP 23",
186 "DSP 24",
187 "DSP 25",
188 "DSP 26",
189 "DSP 27",
190 "DSP 28",
191 "DSP 29",
192 "DSP 30",
193 "DSP 31",
194};
195
196
Pavel Hofman13d45702007-06-11 12:21:20 +0200197/*
198 * List of data sources available for each destination
199 */
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100200static unsigned int emu1010_src_regs[] = {
201 EMU_SRC_SILENCE,/* 0 */
202 EMU_SRC_DOCK_MIC_A1, /* 1 */
203 EMU_SRC_DOCK_MIC_B1, /* 2 */
204 EMU_SRC_DOCK_ADC1_LEFT1, /* 3 */
205 EMU_SRC_DOCK_ADC1_RIGHT1, /* 4 */
206 EMU_SRC_DOCK_ADC2_LEFT1, /* 5 */
207 EMU_SRC_DOCK_ADC2_RIGHT1, /* 6 */
208 EMU_SRC_DOCK_ADC3_LEFT1, /* 7 */
209 EMU_SRC_DOCK_ADC3_RIGHT1, /* 8 */
210 EMU_SRC_HAMOA_ADC_LEFT1, /* 9 */
211 EMU_SRC_HAMOA_ADC_RIGHT1, /* 10 */
212 EMU_SRC_HANA_SPDIF_LEFT1, /* 11 */
213 EMU_SRC_HANA_SPDIF_RIGHT1, /* 12 */
214 EMU_SRC_HANA_ADAT, /* 13 */
215 EMU_SRC_HANA_ADAT+1, /* 14 */
216 EMU_SRC_HANA_ADAT+2, /* 15 */
217 EMU_SRC_HANA_ADAT+3, /* 16 */
218 EMU_SRC_HANA_ADAT+4, /* 17 */
219 EMU_SRC_HANA_ADAT+5, /* 18 */
220 EMU_SRC_HANA_ADAT+6, /* 19 */
221 EMU_SRC_HANA_ADAT+7, /* 20 */
222 EMU_SRC_ALICE_EMU32A, /* 21 */
223 EMU_SRC_ALICE_EMU32A+1, /* 22 */
224 EMU_SRC_ALICE_EMU32A+2, /* 23 */
225 EMU_SRC_ALICE_EMU32A+3, /* 24 */
226 EMU_SRC_ALICE_EMU32A+4, /* 25 */
227 EMU_SRC_ALICE_EMU32A+5, /* 26 */
228 EMU_SRC_ALICE_EMU32A+6, /* 27 */
229 EMU_SRC_ALICE_EMU32A+7, /* 28 */
230 EMU_SRC_ALICE_EMU32A+8, /* 29 */
231 EMU_SRC_ALICE_EMU32A+9, /* 30 */
232 EMU_SRC_ALICE_EMU32A+0xa, /* 31 */
233 EMU_SRC_ALICE_EMU32A+0xb, /* 32 */
234 EMU_SRC_ALICE_EMU32A+0xc, /* 33 */
235 EMU_SRC_ALICE_EMU32A+0xd, /* 34 */
236 EMU_SRC_ALICE_EMU32A+0xe, /* 35 */
237 EMU_SRC_ALICE_EMU32A+0xf, /* 36 */
238 EMU_SRC_ALICE_EMU32B, /* 37 */
239 EMU_SRC_ALICE_EMU32B+1, /* 38 */
240 EMU_SRC_ALICE_EMU32B+2, /* 39 */
241 EMU_SRC_ALICE_EMU32B+3, /* 40 */
242 EMU_SRC_ALICE_EMU32B+4, /* 41 */
243 EMU_SRC_ALICE_EMU32B+5, /* 42 */
244 EMU_SRC_ALICE_EMU32B+6, /* 43 */
245 EMU_SRC_ALICE_EMU32B+7, /* 44 */
246 EMU_SRC_ALICE_EMU32B+8, /* 45 */
247 EMU_SRC_ALICE_EMU32B+9, /* 46 */
248 EMU_SRC_ALICE_EMU32B+0xa, /* 47 */
249 EMU_SRC_ALICE_EMU32B+0xb, /* 48 */
250 EMU_SRC_ALICE_EMU32B+0xc, /* 49 */
251 EMU_SRC_ALICE_EMU32B+0xd, /* 50 */
252 EMU_SRC_ALICE_EMU32B+0xe, /* 51 */
253 EMU_SRC_ALICE_EMU32B+0xf, /* 52 */
254};
255
Ctirad Fertr1c02e362007-12-13 16:27:13 +0100256/* 1616(m) cardbus */
257static unsigned int emu1616_src_regs[] = {
258 EMU_SRC_SILENCE,
259 EMU_SRC_DOCK_MIC_A1,
260 EMU_SRC_DOCK_MIC_B1,
261 EMU_SRC_DOCK_ADC1_LEFT1,
262 EMU_SRC_DOCK_ADC1_RIGHT1,
263 EMU_SRC_DOCK_ADC2_LEFT1,
264 EMU_SRC_DOCK_ADC2_RIGHT1,
265 EMU_SRC_MDOCK_SPDIF_LEFT1,
266 EMU_SRC_MDOCK_SPDIF_RIGHT1,
267 EMU_SRC_MDOCK_ADAT,
268 EMU_SRC_MDOCK_ADAT+1,
269 EMU_SRC_MDOCK_ADAT+2,
270 EMU_SRC_MDOCK_ADAT+3,
271 EMU_SRC_MDOCK_ADAT+4,
272 EMU_SRC_MDOCK_ADAT+5,
273 EMU_SRC_MDOCK_ADAT+6,
274 EMU_SRC_MDOCK_ADAT+7,
275 EMU_SRC_ALICE_EMU32A,
276 EMU_SRC_ALICE_EMU32A+1,
277 EMU_SRC_ALICE_EMU32A+2,
278 EMU_SRC_ALICE_EMU32A+3,
279 EMU_SRC_ALICE_EMU32A+4,
280 EMU_SRC_ALICE_EMU32A+5,
281 EMU_SRC_ALICE_EMU32A+6,
282 EMU_SRC_ALICE_EMU32A+7,
283 EMU_SRC_ALICE_EMU32A+8,
284 EMU_SRC_ALICE_EMU32A+9,
285 EMU_SRC_ALICE_EMU32A+0xa,
286 EMU_SRC_ALICE_EMU32A+0xb,
287 EMU_SRC_ALICE_EMU32A+0xc,
288 EMU_SRC_ALICE_EMU32A+0xd,
289 EMU_SRC_ALICE_EMU32A+0xe,
290 EMU_SRC_ALICE_EMU32A+0xf,
291 EMU_SRC_ALICE_EMU32B,
292 EMU_SRC_ALICE_EMU32B+1,
293 EMU_SRC_ALICE_EMU32B+2,
294 EMU_SRC_ALICE_EMU32B+3,
295 EMU_SRC_ALICE_EMU32B+4,
296 EMU_SRC_ALICE_EMU32B+5,
297 EMU_SRC_ALICE_EMU32B+6,
298 EMU_SRC_ALICE_EMU32B+7,
299 EMU_SRC_ALICE_EMU32B+8,
300 EMU_SRC_ALICE_EMU32B+9,
301 EMU_SRC_ALICE_EMU32B+0xa,
302 EMU_SRC_ALICE_EMU32B+0xb,
303 EMU_SRC_ALICE_EMU32B+0xc,
304 EMU_SRC_ALICE_EMU32B+0xd,
305 EMU_SRC_ALICE_EMU32B+0xe,
306 EMU_SRC_ALICE_EMU32B+0xf,
307};
308
Pavel Hofman13d45702007-06-11 12:21:20 +0200309/*
310 * Data destinations - physical EMU outputs.
311 * Each destination has an enum mixer control to choose a data source
312 */
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100313static unsigned int emu1010_output_dst[] = {
314 EMU_DST_DOCK_DAC1_LEFT1, /* 0 */
315 EMU_DST_DOCK_DAC1_RIGHT1, /* 1 */
316 EMU_DST_DOCK_DAC2_LEFT1, /* 2 */
317 EMU_DST_DOCK_DAC2_RIGHT1, /* 3 */
318 EMU_DST_DOCK_DAC3_LEFT1, /* 4 */
319 EMU_DST_DOCK_DAC3_RIGHT1, /* 5 */
320 EMU_DST_DOCK_DAC4_LEFT1, /* 6 */
321 EMU_DST_DOCK_DAC4_RIGHT1, /* 7 */
322 EMU_DST_DOCK_PHONES_LEFT1, /* 8 */
323 EMU_DST_DOCK_PHONES_RIGHT1, /* 9 */
324 EMU_DST_DOCK_SPDIF_LEFT1, /* 10 */
325 EMU_DST_DOCK_SPDIF_RIGHT1, /* 11 */
326 EMU_DST_HANA_SPDIF_LEFT1, /* 12 */
327 EMU_DST_HANA_SPDIF_RIGHT1, /* 13 */
328 EMU_DST_HAMOA_DAC_LEFT1, /* 14 */
329 EMU_DST_HAMOA_DAC_RIGHT1, /* 15 */
330 EMU_DST_HANA_ADAT, /* 16 */
331 EMU_DST_HANA_ADAT+1, /* 17 */
332 EMU_DST_HANA_ADAT+2, /* 18 */
333 EMU_DST_HANA_ADAT+3, /* 19 */
334 EMU_DST_HANA_ADAT+4, /* 20 */
335 EMU_DST_HANA_ADAT+5, /* 21 */
336 EMU_DST_HANA_ADAT+6, /* 22 */
337 EMU_DST_HANA_ADAT+7, /* 23 */
338};
339
Ctirad Fertr1c02e362007-12-13 16:27:13 +0100340/* 1616(m) cardbus */
341static unsigned int emu1616_output_dst[] = {
342 EMU_DST_DOCK_DAC1_LEFT1,
343 EMU_DST_DOCK_DAC1_RIGHT1,
344 EMU_DST_DOCK_DAC2_LEFT1,
345 EMU_DST_DOCK_DAC2_RIGHT1,
346 EMU_DST_DOCK_DAC3_LEFT1,
347 EMU_DST_DOCK_DAC3_RIGHT1,
348 EMU_DST_MDOCK_SPDIF_LEFT1,
349 EMU_DST_MDOCK_SPDIF_RIGHT1,
350 EMU_DST_MDOCK_ADAT,
351 EMU_DST_MDOCK_ADAT+1,
352 EMU_DST_MDOCK_ADAT+2,
353 EMU_DST_MDOCK_ADAT+3,
354 EMU_DST_MDOCK_ADAT+4,
355 EMU_DST_MDOCK_ADAT+5,
356 EMU_DST_MDOCK_ADAT+6,
357 EMU_DST_MDOCK_ADAT+7,
358 EMU_DST_MANA_DAC_LEFT,
359 EMU_DST_MANA_DAC_RIGHT,
360};
361
Pavel Hofman13d45702007-06-11 12:21:20 +0200362/*
363 * Data destinations - HANA outputs going to Alice2 (audigy) for
364 * capture (EMU32 + I2S links)
365 * Each destination has an enum mixer control to choose a data source
366 */
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100367static unsigned int emu1010_input_dst[] = {
368 EMU_DST_ALICE2_EMU32_0,
369 EMU_DST_ALICE2_EMU32_1,
370 EMU_DST_ALICE2_EMU32_2,
371 EMU_DST_ALICE2_EMU32_3,
372 EMU_DST_ALICE2_EMU32_4,
373 EMU_DST_ALICE2_EMU32_5,
374 EMU_DST_ALICE2_EMU32_6,
375 EMU_DST_ALICE2_EMU32_7,
376 EMU_DST_ALICE2_EMU32_8,
377 EMU_DST_ALICE2_EMU32_9,
378 EMU_DST_ALICE2_EMU32_A,
379 EMU_DST_ALICE2_EMU32_B,
380 EMU_DST_ALICE2_EMU32_C,
381 EMU_DST_ALICE2_EMU32_D,
382 EMU_DST_ALICE2_EMU32_E,
383 EMU_DST_ALICE2_EMU32_F,
384 EMU_DST_ALICE_I2S0_LEFT,
385 EMU_DST_ALICE_I2S0_RIGHT,
386 EMU_DST_ALICE_I2S1_LEFT,
387 EMU_DST_ALICE_I2S1_RIGHT,
388 EMU_DST_ALICE_I2S2_LEFT,
389 EMU_DST_ALICE_I2S2_RIGHT,
390};
391
Ctirad Fertr1c02e362007-12-13 16:27:13 +0100392static int snd_emu1010_input_output_source_info(struct snd_kcontrol *kcontrol,
393 struct snd_ctl_elem_info *uinfo)
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100394{
Ctirad Fertr1c02e362007-12-13 16:27:13 +0100395 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
396 char **items;
397
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100398 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
399 uinfo->count = 1;
Ctirad Fertr1c02e362007-12-13 16:27:13 +0100400 if (emu->card_capabilities->emu_model == 3) { /* 1616(m) cardbus */
401 uinfo->value.enumerated.items = 49;
402 items = emu1616_src_texts;
403 } else {
404 uinfo->value.enumerated.items = 53;
405 items = emu1010_src_texts;
406 }
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100407 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
Ctirad Fertr1c02e362007-12-13 16:27:13 +0100408 uinfo->value.enumerated.item =
409 uinfo->value.enumerated.items - 1;
410 strcpy(uinfo->value.enumerated.name,
411 items[uinfo->value.enumerated.item]);
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100412 return 0;
413}
414
415static int snd_emu1010_output_source_get(struct snd_kcontrol *kcontrol,
416 struct snd_ctl_elem_value *ucontrol)
417{
418 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000419 unsigned int channel;
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100420
421 channel = (kcontrol->private_value) & 0xff;
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000422 /* Limit: emu1010_output_dst, emu->emu1010.output_source */
Ctirad Fertr1c02e362007-12-13 16:27:13 +0100423 if (channel >= 24 ||
424 (emu->card_capabilities->emu_model == 3 && channel >= 18))
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000425 return -EINVAL;
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100426 ucontrol->value.enumerated.item[0] = emu->emu1010.output_source[channel];
427 return 0;
428}
429
430static int snd_emu1010_output_source_put(struct snd_kcontrol *kcontrol,
431 struct snd_ctl_elem_value *ucontrol)
432{
433 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100434 unsigned int val;
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000435 unsigned int channel;
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100436
Takashi Iwaiaa299d02007-11-15 13:16:02 +0100437 val = ucontrol->value.enumerated.item[0];
Ctirad Fertr1c02e362007-12-13 16:27:13 +0100438 if (val >= 53 ||
439 (emu->card_capabilities->emu_model == 3 && val >= 49))
Takashi Iwaiaa299d02007-11-15 13:16:02 +0100440 return -EINVAL;
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100441 channel = (kcontrol->private_value) & 0xff;
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000442 /* Limit: emu1010_output_dst, emu->emu1010.output_source */
Ctirad Fertr1c02e362007-12-13 16:27:13 +0100443 if (channel >= 24 ||
444 (emu->card_capabilities->emu_model == 3 && channel >= 18))
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000445 return -EINVAL;
Ctirad Fertr1c02e362007-12-13 16:27:13 +0100446 if (emu->emu1010.output_source[channel] == val)
447 return 0;
448 emu->emu1010.output_source[channel] = val;
449 if (emu->card_capabilities->emu_model == 3) /* 1616(m) cardbus */
450 snd_emu1010_fpga_link_dst_src_write(emu,
451 emu1616_output_dst[channel], emu1616_src_regs[val]);
452 else
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100453 snd_emu1010_fpga_link_dst_src_write(emu,
454 emu1010_output_dst[channel], emu1010_src_regs[val]);
Ctirad Fertr1c02e362007-12-13 16:27:13 +0100455 return 1;
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100456}
457
458static int snd_emu1010_input_source_get(struct snd_kcontrol *kcontrol,
459 struct snd_ctl_elem_value *ucontrol)
460{
461 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000462 unsigned int channel;
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100463
464 channel = (kcontrol->private_value) & 0xff;
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000465 /* Limit: emu1010_input_dst, emu->emu1010.input_source */
466 if (channel >= 22)
467 return -EINVAL;
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100468 ucontrol->value.enumerated.item[0] = emu->emu1010.input_source[channel];
469 return 0;
470}
471
472static int snd_emu1010_input_source_put(struct snd_kcontrol *kcontrol,
473 struct snd_ctl_elem_value *ucontrol)
474{
475 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100476 unsigned int val;
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000477 unsigned int channel;
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100478
Takashi Iwaiaa299d02007-11-15 13:16:02 +0100479 val = ucontrol->value.enumerated.item[0];
Ctirad Fertr1c02e362007-12-13 16:27:13 +0100480 if (val >= 53 ||
481 (emu->card_capabilities->emu_model == 3 && val >= 49))
Takashi Iwaiaa299d02007-11-15 13:16:02 +0100482 return -EINVAL;
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100483 channel = (kcontrol->private_value) & 0xff;
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000484 /* Limit: emu1010_input_dst, emu->emu1010.input_source */
485 if (channel >= 22)
486 return -EINVAL;
Ctirad Fertr1c02e362007-12-13 16:27:13 +0100487 if (emu->emu1010.input_source[channel] == val)
488 return 0;
489 emu->emu1010.input_source[channel] = val;
490 if (emu->card_capabilities->emu_model == 3) /* 1616(m) cardbus */
491 snd_emu1010_fpga_link_dst_src_write(emu,
492 emu1010_input_dst[channel], emu1616_src_regs[val]);
493 else
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100494 snd_emu1010_fpga_link_dst_src_write(emu,
495 emu1010_input_dst[channel], emu1010_src_regs[val]);
Ctirad Fertr1c02e362007-12-13 16:27:13 +0100496 return 1;
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100497}
498
499#define EMU1010_SOURCE_OUTPUT(xname,chid) \
500{ \
501 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
502 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
503 .info = snd_emu1010_input_output_source_info, \
504 .get = snd_emu1010_output_source_get, \
505 .put = snd_emu1010_output_source_put, \
506 .private_value = chid \
507}
508
509static struct snd_kcontrol_new snd_emu1010_output_enum_ctls[] __devinitdata = {
James Courtier-Dutton4c07c812006-11-11 10:48:58 +0000510 EMU1010_SOURCE_OUTPUT("Dock DAC1 Left Playback Enum", 0),
511 EMU1010_SOURCE_OUTPUT("Dock DAC1 Right Playback Enum", 1),
512 EMU1010_SOURCE_OUTPUT("Dock DAC2 Left Playback Enum", 2),
513 EMU1010_SOURCE_OUTPUT("Dock DAC2 Right Playback Enum", 3),
514 EMU1010_SOURCE_OUTPUT("Dock DAC3 Left Playback Enum", 4),
515 EMU1010_SOURCE_OUTPUT("Dock DAC3 Right Playback Enum", 5),
516 EMU1010_SOURCE_OUTPUT("Dock DAC4 Left Playback Enum", 6),
517 EMU1010_SOURCE_OUTPUT("Dock DAC4 Right Playback Enum", 7),
518 EMU1010_SOURCE_OUTPUT("Dock Phones Left Playback Enum", 8),
519 EMU1010_SOURCE_OUTPUT("Dock Phones Right Playback Enum", 9),
520 EMU1010_SOURCE_OUTPUT("Dock SPDIF Left Playback Enum", 0xa),
521 EMU1010_SOURCE_OUTPUT("Dock SPDIF Right Playback Enum", 0xb),
522 EMU1010_SOURCE_OUTPUT("1010 SPDIF Left Playback Enum", 0xc),
523 EMU1010_SOURCE_OUTPUT("1010 SPDIF Right Playback Enum", 0xd),
524 EMU1010_SOURCE_OUTPUT("0202 DAC Left Playback Enum", 0xe),
525 EMU1010_SOURCE_OUTPUT("0202 DAC Right Playback Enum", 0xf),
526 EMU1010_SOURCE_OUTPUT("1010 ADAT 0 Playback Enum", 0x10),
527 EMU1010_SOURCE_OUTPUT("1010 ADAT 1 Playback Enum", 0x11),
528 EMU1010_SOURCE_OUTPUT("1010 ADAT 2 Playback Enum", 0x12),
529 EMU1010_SOURCE_OUTPUT("1010 ADAT 3 Playback Enum", 0x13),
530 EMU1010_SOURCE_OUTPUT("1010 ADAT 4 Playback Enum", 0x14),
531 EMU1010_SOURCE_OUTPUT("1010 ADAT 5 Playback Enum", 0x15),
532 EMU1010_SOURCE_OUTPUT("1010 ADAT 6 Playback Enum", 0x16),
533 EMU1010_SOURCE_OUTPUT("1010 ADAT 7 Playback Enum", 0x17),
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100534};
535
Ctirad Fertr1c02e362007-12-13 16:27:13 +0100536
537/* 1616(m) cardbus */
538static struct snd_kcontrol_new snd_emu1616_output_enum_ctls[] __devinitdata = {
539 EMU1010_SOURCE_OUTPUT("Dock DAC1 Left Playback Enum", 0),
540 EMU1010_SOURCE_OUTPUT("Dock DAC1 Right Playback Enum", 1),
541 EMU1010_SOURCE_OUTPUT("Dock DAC2 Left Playback Enum", 2),
542 EMU1010_SOURCE_OUTPUT("Dock DAC2 Right Playback Enum", 3),
543 EMU1010_SOURCE_OUTPUT("Dock DAC3 Left Playback Enum", 4),
544 EMU1010_SOURCE_OUTPUT("Dock DAC3 Right Playback Enum", 5),
545 EMU1010_SOURCE_OUTPUT("Dock SPDIF Left Playback Enum", 6),
546 EMU1010_SOURCE_OUTPUT("Dock SPDIF Right Playback Enum", 7),
547 EMU1010_SOURCE_OUTPUT("Dock ADAT 0 Playback Enum", 8),
548 EMU1010_SOURCE_OUTPUT("Dock ADAT 1 Playback Enum", 9),
549 EMU1010_SOURCE_OUTPUT("Dock ADAT 2 Playback Enum", 0xa),
550 EMU1010_SOURCE_OUTPUT("Dock ADAT 3 Playback Enum", 0xb),
551 EMU1010_SOURCE_OUTPUT("Dock ADAT 4 Playback Enum", 0xc),
552 EMU1010_SOURCE_OUTPUT("Dock ADAT 5 Playback Enum", 0xd),
553 EMU1010_SOURCE_OUTPUT("Dock ADAT 6 Playback Enum", 0xe),
554 EMU1010_SOURCE_OUTPUT("Dock ADAT 7 Playback Enum", 0xf),
555 EMU1010_SOURCE_OUTPUT("Mana DAC Left Playback Enum", 0x10),
556 EMU1010_SOURCE_OUTPUT("Mana DAC Right Playback Enum", 0x11),
557};
558
559
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100560#define EMU1010_SOURCE_INPUT(xname,chid) \
561{ \
562 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
563 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
564 .info = snd_emu1010_input_output_source_info, \
565 .get = snd_emu1010_input_source_get, \
566 .put = snd_emu1010_input_source_put, \
567 .private_value = chid \
568}
569
570static struct snd_kcontrol_new snd_emu1010_input_enum_ctls[] __devinitdata = {
James Courtier-Dutton4c07c812006-11-11 10:48:58 +0000571 EMU1010_SOURCE_INPUT("DSP 0 Capture Enum", 0),
572 EMU1010_SOURCE_INPUT("DSP 1 Capture Enum", 1),
573 EMU1010_SOURCE_INPUT("DSP 2 Capture Enum", 2),
574 EMU1010_SOURCE_INPUT("DSP 3 Capture Enum", 3),
575 EMU1010_SOURCE_INPUT("DSP 4 Capture Enum", 4),
576 EMU1010_SOURCE_INPUT("DSP 5 Capture Enum", 5),
577 EMU1010_SOURCE_INPUT("DSP 6 Capture Enum", 6),
578 EMU1010_SOURCE_INPUT("DSP 7 Capture Enum", 7),
579 EMU1010_SOURCE_INPUT("DSP 8 Capture Enum", 8),
580 EMU1010_SOURCE_INPUT("DSP 9 Capture Enum", 9),
581 EMU1010_SOURCE_INPUT("DSP A Capture Enum", 0xa),
582 EMU1010_SOURCE_INPUT("DSP B Capture Enum", 0xb),
583 EMU1010_SOURCE_INPUT("DSP C Capture Enum", 0xc),
584 EMU1010_SOURCE_INPUT("DSP D Capture Enum", 0xd),
585 EMU1010_SOURCE_INPUT("DSP E Capture Enum", 0xe),
586 EMU1010_SOURCE_INPUT("DSP F Capture Enum", 0xf),
587 EMU1010_SOURCE_INPUT("DSP 10 Capture Enum", 0x10),
588 EMU1010_SOURCE_INPUT("DSP 11 Capture Enum", 0x11),
589 EMU1010_SOURCE_INPUT("DSP 12 Capture Enum", 0x12),
590 EMU1010_SOURCE_INPUT("DSP 13 Capture Enum", 0x13),
591 EMU1010_SOURCE_INPUT("DSP 14 Capture Enum", 0x14),
592 EMU1010_SOURCE_INPUT("DSP 15 Capture Enum", 0x15),
James Courtier-Dutton9148cc52006-10-09 23:08:00 +0100593};
594
595
596
Takashi Iwaia5ce8892007-07-23 15:42:26 +0200597#define snd_emu1010_adc_pads_info snd_ctl_boolean_mono_info
James Courtier-Dutton9148cc52006-10-09 23:08:00 +0100598
599static int snd_emu1010_adc_pads_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
600{
601 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
602 unsigned int mask = kcontrol->private_value & 0xff;
603 ucontrol->value.integer.value[0] = (emu->emu1010.adc_pads & mask) ? 1 : 0;
604 return 0;
605}
606
607static int snd_emu1010_adc_pads_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
608{
609 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
610 unsigned int mask = kcontrol->private_value & 0xff;
611 unsigned int val, cache;
612 val = ucontrol->value.integer.value[0];
613 cache = emu->emu1010.adc_pads;
614 if (val == 1)
615 cache = cache | mask;
616 else
617 cache = cache & ~mask;
618 if (cache != emu->emu1010.adc_pads) {
619 snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, cache );
620 emu->emu1010.adc_pads = cache;
621 }
622
623 return 0;
624}
625
626
627
628#define EMU1010_ADC_PADS(xname,chid) \
629{ \
630 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
631 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
632 .info = snd_emu1010_adc_pads_info, \
633 .get = snd_emu1010_adc_pads_get, \
634 .put = snd_emu1010_adc_pads_put, \
635 .private_value = chid \
636}
637
638static struct snd_kcontrol_new snd_emu1010_adc_pads[] __devinitdata = {
639 EMU1010_ADC_PADS("ADC1 14dB PAD Audio Dock Capture Switch", EMU_HANA_DOCK_ADC_PAD1),
640 EMU1010_ADC_PADS("ADC2 14dB PAD Audio Dock Capture Switch", EMU_HANA_DOCK_ADC_PAD2),
641 EMU1010_ADC_PADS("ADC3 14dB PAD Audio Dock Capture Switch", EMU_HANA_DOCK_ADC_PAD3),
642 EMU1010_ADC_PADS("ADC1 14dB PAD 0202 Capture Switch", EMU_HANA_0202_ADC_PAD1),
643};
644
Takashi Iwaia5ce8892007-07-23 15:42:26 +0200645#define snd_emu1010_dac_pads_info snd_ctl_boolean_mono_info
James Courtier-Dutton9148cc52006-10-09 23:08:00 +0100646
647static int snd_emu1010_dac_pads_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
648{
649 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
650 unsigned int mask = kcontrol->private_value & 0xff;
651 ucontrol->value.integer.value[0] = (emu->emu1010.dac_pads & mask) ? 1 : 0;
652 return 0;
653}
654
655static int snd_emu1010_dac_pads_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
656{
657 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
658 unsigned int mask = kcontrol->private_value & 0xff;
659 unsigned int val, cache;
660 val = ucontrol->value.integer.value[0];
661 cache = emu->emu1010.dac_pads;
662 if (val == 1)
663 cache = cache | mask;
664 else
665 cache = cache & ~mask;
666 if (cache != emu->emu1010.dac_pads) {
667 snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, cache );
668 emu->emu1010.dac_pads = cache;
669 }
670
671 return 0;
672}
673
674
675
676#define EMU1010_DAC_PADS(xname,chid) \
677{ \
678 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
679 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
680 .info = snd_emu1010_dac_pads_info, \
681 .get = snd_emu1010_dac_pads_get, \
682 .put = snd_emu1010_dac_pads_put, \
683 .private_value = chid \
684}
685
686static struct snd_kcontrol_new snd_emu1010_dac_pads[] __devinitdata = {
687 EMU1010_DAC_PADS("DAC1 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD1),
688 EMU1010_DAC_PADS("DAC2 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD2),
689 EMU1010_DAC_PADS("DAC3 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD3),
690 EMU1010_DAC_PADS("DAC4 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD4),
691 EMU1010_DAC_PADS("DAC1 0202 14dB PAD Playback Switch", EMU_HANA_0202_DAC_PAD1),
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +0100692};
693
James Courtier-Duttonb0dbdae2006-10-10 18:08:45 +0100694
695static int snd_emu1010_internal_clock_info(struct snd_kcontrol *kcontrol,
696 struct snd_ctl_elem_info *uinfo)
697{
James Courtier-Duttonedec7bb2007-07-23 20:30:22 +0100698 static char *texts[4] = {
699 "44100", "48000", "SPDIF", "ADAT"
James Courtier-Duttonb0dbdae2006-10-10 18:08:45 +0100700 };
James Courtier-Duttonedec7bb2007-07-23 20:30:22 +0100701
James Courtier-Duttonb0dbdae2006-10-10 18:08:45 +0100702 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
703 uinfo->count = 1;
James Courtier-Duttonedec7bb2007-07-23 20:30:22 +0100704 uinfo->value.enumerated.items = 4;
705 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
706 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
James Courtier-Duttonb0dbdae2006-10-10 18:08:45 +0100707 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
708 return 0;
James Courtier-Duttonedec7bb2007-07-23 20:30:22 +0100709
710
James Courtier-Duttonb0dbdae2006-10-10 18:08:45 +0100711}
712
713static int snd_emu1010_internal_clock_get(struct snd_kcontrol *kcontrol,
714 struct snd_ctl_elem_value *ucontrol)
715{
716 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
717
718 ucontrol->value.enumerated.item[0] = emu->emu1010.internal_clock;
719 return 0;
720}
721
722static int snd_emu1010_internal_clock_put(struct snd_kcontrol *kcontrol,
723 struct snd_ctl_elem_value *ucontrol)
724{
725 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
726 unsigned int val;
727 int change = 0;
728
729 val = ucontrol->value.enumerated.item[0] ;
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000730 /* Limit: uinfo->value.enumerated.items = 4; */
731 if (val >= 4)
732 return -EINVAL;
James Courtier-Duttonb0dbdae2006-10-10 18:08:45 +0100733 change = (emu->emu1010.internal_clock != val);
734 if (change) {
735 emu->emu1010.internal_clock = val;
736 switch (val) {
737 case 0:
738 /* 44100 */
739 /* Mute all */
740 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
741 /* Default fallback clock 48kHz */
742 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_44_1K );
743 /* Word Clock source, Internal 44.1kHz x1 */
744 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
745 EMU_HANA_WCLOCK_INT_44_1K | EMU_HANA_WCLOCK_1X );
746 /* Set LEDs on Audio Dock */
747 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2,
748 EMU_HANA_DOCK_LEDS_2_44K | EMU_HANA_DOCK_LEDS_2_LOCK );
749 /* Allow DLL to settle */
James Courtier-Duttone40a0b22006-10-10 18:44:29 +0100750 msleep(10);
James Courtier-Duttonb0dbdae2006-10-10 18:08:45 +0100751 /* Unmute all */
752 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
753 break;
754 case 1:
755 /* 48000 */
756 /* Mute all */
757 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
758 /* Default fallback clock 48kHz */
759 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K );
760 /* Word Clock source, Internal 48kHz x1 */
761 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
762 EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_1X );
763 /* Set LEDs on Audio Dock */
764 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2,
765 EMU_HANA_DOCK_LEDS_2_48K | EMU_HANA_DOCK_LEDS_2_LOCK );
766 /* Allow DLL to settle */
James Courtier-Duttone40a0b22006-10-10 18:44:29 +0100767 msleep(10);
James Courtier-Duttonb0dbdae2006-10-10 18:08:45 +0100768 /* Unmute all */
769 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
770 break;
James Courtier-Duttonedec7bb2007-07-23 20:30:22 +0100771
772 case 2: /* Take clock from S/PDIF IN */
773 /* Mute all */
774 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
775 /* Default fallback clock 48kHz */
776 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K );
777 /* Word Clock source, sync to S/PDIF input */
778 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
779 EMU_HANA_WCLOCK_HANA_SPDIF_IN | EMU_HANA_WCLOCK_1X );
780 /* Set LEDs on Audio Dock */
781 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2,
782 EMU_HANA_DOCK_LEDS_2_EXT | EMU_HANA_DOCK_LEDS_2_LOCK );
783 /* FIXME: We should set EMU_HANA_DOCK_LEDS_2_LOCK only when clock signal is present and valid */
784 /* Allow DLL to settle */
785 msleep(10);
786 /* Unmute all */
787 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
788 break;
789
790 case 3:
791 /* Take clock from ADAT IN */
792 /* Mute all */
793 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
794 /* Default fallback clock 48kHz */
795 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K );
796 /* Word Clock source, sync to ADAT input */
797 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
798 EMU_HANA_WCLOCK_HANA_ADAT_IN | EMU_HANA_WCLOCK_1X );
799 /* Set LEDs on Audio Dock */
800 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, EMU_HANA_DOCK_LEDS_2_EXT | EMU_HANA_DOCK_LEDS_2_LOCK );
801 /* FIXME: We should set EMU_HANA_DOCK_LEDS_2_LOCK only when clock signal is present and valid */
802 /* Allow DLL to settle */
803 msleep(10);
804 /* Unmute all */
805 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
806
807
808 break;
James Courtier-Duttonb0dbdae2006-10-10 18:08:45 +0100809 }
810 }
811 return change;
812}
813
814static struct snd_kcontrol_new snd_emu1010_internal_clock =
815{
816 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
817 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
818 .name = "Clock Internal Rate",
819 .count = 1,
820 .info = snd_emu1010_internal_clock_info,
821 .get = snd_emu1010_internal_clock_get,
822 .put = snd_emu1010_internal_clock_put
823};
824
James Courtier-Dutton184c1e22006-12-06 15:58:02 +0000825static int snd_audigy_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
826 struct snd_ctl_elem_info *uinfo)
827{
828#if 0
829 static char *texts[4] = {
830 "Unknown1", "Unknown2", "Mic", "Line"
831 };
832#endif
833 static char *texts[2] = {
834 "Mic", "Line"
835 };
836
837 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
838 uinfo->count = 1;
839 uinfo->value.enumerated.items = 2;
840 if (uinfo->value.enumerated.item > 1)
841 uinfo->value.enumerated.item = 1;
842 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
843 return 0;
844}
845
846static int snd_audigy_i2c_capture_source_get(struct snd_kcontrol *kcontrol,
847 struct snd_ctl_elem_value *ucontrol)
848{
849 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
850
851 ucontrol->value.enumerated.item[0] = emu->i2c_capture_source;
852 return 0;
853}
854
855static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
856 struct snd_ctl_elem_value *ucontrol)
857{
858 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
859 unsigned int source_id;
860 unsigned int ngain, ogain;
861 u32 gpio;
862 int change = 0;
863 unsigned long flags;
864 u32 source;
865 /* If the capture source has changed,
866 * update the capture volume from the cached value
867 * for the particular source.
868 */
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000869 source_id = ucontrol->value.enumerated.item[0];
870 /* Limit: uinfo->value.enumerated.items = 2; */
871 /* emu->i2c_capture_volume */
872 if (source_id >= 2)
873 return -EINVAL;
James Courtier-Dutton184c1e22006-12-06 15:58:02 +0000874 change = (emu->i2c_capture_source != source_id);
875 if (change) {
876 snd_emu10k1_i2c_write(emu, ADC_MUX, 0); /* Mute input */
877 spin_lock_irqsave(&emu->emu_lock, flags);
878 gpio = inl(emu->port + A_IOCFG);
879 if (source_id==0)
880 outl(gpio | 0x4, emu->port + A_IOCFG);
881 else
882 outl(gpio & ~0x4, emu->port + A_IOCFG);
883 spin_unlock_irqrestore(&emu->emu_lock, flags);
884
885 ngain = emu->i2c_capture_volume[source_id][0]; /* Left */
886 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
887 if (ngain != ogain)
888 snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff));
889 ngain = emu->i2c_capture_volume[source_id][1]; /* Right */
890 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */
891 if (ngain != ogain)
892 snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
893
894 source = 1 << (source_id + 2);
895 snd_emu10k1_i2c_write(emu, ADC_MUX, source); /* Set source */
896 emu->i2c_capture_source = source_id;
897 }
898 return change;
899}
900
901static struct snd_kcontrol_new snd_audigy_i2c_capture_source =
902{
903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
904 .name = "Capture Source",
905 .info = snd_audigy_i2c_capture_source_info,
906 .get = snd_audigy_i2c_capture_source_get,
907 .put = snd_audigy_i2c_capture_source_put
908};
909
910static int snd_audigy_i2c_volume_info(struct snd_kcontrol *kcontrol,
911 struct snd_ctl_elem_info *uinfo)
912{
913 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
914 uinfo->count = 2;
915 uinfo->value.integer.min = 0;
916 uinfo->value.integer.max = 255;
917 return 0;
918}
919
920static int snd_audigy_i2c_volume_get(struct snd_kcontrol *kcontrol,
921 struct snd_ctl_elem_value *ucontrol)
922{
923 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000924 unsigned int source_id;
James Courtier-Dutton184c1e22006-12-06 15:58:02 +0000925
926 source_id = kcontrol->private_value;
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000927 /* Limit: emu->i2c_capture_volume */
928 /* capture_source: uinfo->value.enumerated.items = 2 */
929 if (source_id >= 2)
930 return -EINVAL;
James Courtier-Dutton184c1e22006-12-06 15:58:02 +0000931
932 ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0];
933 ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1];
934 return 0;
935}
936
937static int snd_audigy_i2c_volume_put(struct snd_kcontrol *kcontrol,
938 struct snd_ctl_elem_value *ucontrol)
939{
940 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
941 unsigned int ogain;
942 unsigned int ngain;
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000943 unsigned int source_id;
James Courtier-Dutton184c1e22006-12-06 15:58:02 +0000944 int change = 0;
945
946 source_id = kcontrol->private_value;
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000947 /* Limit: emu->i2c_capture_volume */
948 /* capture_source: uinfo->value.enumerated.items = 2 */
949 if (source_id >= 2)
950 return -EINVAL;
James Courtier-Dutton184c1e22006-12-06 15:58:02 +0000951 ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
952 ngain = ucontrol->value.integer.value[0];
953 if (ngain > 0xff)
954 return 0;
955 if (ogain != ngain) {
956 if (emu->i2c_capture_source == source_id)
957 snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000958 emu->i2c_capture_volume[source_id][0] = ngain;
James Courtier-Dutton184c1e22006-12-06 15:58:02 +0000959 change = 1;
960 }
961 ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
962 ngain = ucontrol->value.integer.value[1];
963 if (ngain > 0xff)
964 return 0;
965 if (ogain != ngain) {
966 if (emu->i2c_capture_source == source_id)
967 snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
James Courtier-Dutton74415a32007-11-12 14:55:19 +0000968 emu->i2c_capture_volume[source_id][1] = ngain;
James Courtier-Dutton184c1e22006-12-06 15:58:02 +0000969 change = 1;
970 }
971
972 return change;
973}
974
975#define I2C_VOLUME(xname,chid) \
976{ \
977 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
978 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
979 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
980 .info = snd_audigy_i2c_volume_info, \
981 .get = snd_audigy_i2c_volume_get, \
982 .put = snd_audigy_i2c_volume_put, \
983 .tlv = { .p = snd_audigy_db_scale2 }, \
984 .private_value = chid \
985}
986
987
988static struct snd_kcontrol_new snd_audigy_i2c_volume_ctls[] __devinitdata = {
989 I2C_VOLUME("Mic Capture Volume", 0),
990 I2C_VOLUME("Line Capture Volume", 0)
991};
992
Takashi Iwai0af68e52005-04-11 17:03:03 +0200993#if 0
Takashi Iwaieb4698f2005-11-17 14:50:13 +0100994static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995{
996 static char *texts[] = {"44100", "48000", "96000"};
997
998 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
999 uinfo->count = 1;
1000 uinfo->value.enumerated.items = 3;
1001 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1002 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1003 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1004 return 0;
1005}
1006
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001007static int snd_audigy_spdif_output_rate_get(struct snd_kcontrol *kcontrol,
1008 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001010 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011 unsigned int tmp;
1012 unsigned long flags;
1013
1014
1015 spin_lock_irqsave(&emu->reg_lock, flags);
1016 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
1017 switch (tmp & A_SPDIF_RATE_MASK) {
1018 case A_SPDIF_44100:
1019 ucontrol->value.enumerated.item[0] = 0;
1020 break;
1021 case A_SPDIF_48000:
1022 ucontrol->value.enumerated.item[0] = 1;
1023 break;
1024 case A_SPDIF_96000:
1025 ucontrol->value.enumerated.item[0] = 2;
1026 break;
1027 default:
1028 ucontrol->value.enumerated.item[0] = 1;
1029 }
1030 spin_unlock_irqrestore(&emu->reg_lock, flags);
1031 return 0;
1032}
1033
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001034static int snd_audigy_spdif_output_rate_put(struct snd_kcontrol *kcontrol,
1035 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001037 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 int change;
1039 unsigned int reg, val, tmp;
1040 unsigned long flags;
1041
1042 switch(ucontrol->value.enumerated.item[0]) {
1043 case 0:
1044 val = A_SPDIF_44100;
1045 break;
1046 case 1:
1047 val = A_SPDIF_48000;
1048 break;
1049 case 2:
1050 val = A_SPDIF_96000;
1051 break;
1052 default:
1053 val = A_SPDIF_48000;
1054 break;
1055 }
1056
1057
1058 spin_lock_irqsave(&emu->reg_lock, flags);
1059 reg = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
1060 tmp = reg & ~A_SPDIF_RATE_MASK;
1061 tmp |= val;
1062 if ((change = (tmp != reg)))
1063 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
1064 spin_unlock_irqrestore(&emu->reg_lock, flags);
1065 return change;
1066}
1067
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001068static struct snd_kcontrol_new snd_audigy_spdif_output_rate =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069{
1070 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1071 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1072 .name = "Audigy SPDIF Output Sample Rate",
1073 .count = 1,
1074 .info = snd_audigy_spdif_output_rate_info,
1075 .get = snd_audigy_spdif_output_rate_get,
1076 .put = snd_audigy_spdif_output_rate_put
1077};
Takashi Iwai0af68e52005-04-11 17:03:03 +02001078#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001080static int snd_emu10k1_spdif_put(struct snd_kcontrol *kcontrol,
1081 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001083 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1085 int change;
1086 unsigned int val;
1087 unsigned long flags;
1088
James Courtier-Dutton74415a32007-11-12 14:55:19 +00001089 /* Limit: emu->spdif_bits */
1090 if (idx >= 3)
1091 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092 val = (ucontrol->value.iec958.status[0] << 0) |
1093 (ucontrol->value.iec958.status[1] << 8) |
1094 (ucontrol->value.iec958.status[2] << 16) |
1095 (ucontrol->value.iec958.status[3] << 24);
1096 spin_lock_irqsave(&emu->reg_lock, flags);
1097 change = val != emu->spdif_bits[idx];
1098 if (change) {
1099 snd_emu10k1_ptr_write(emu, SPCS0 + idx, 0, val);
1100 emu->spdif_bits[idx] = val;
1101 }
1102 spin_unlock_irqrestore(&emu->reg_lock, flags);
1103 return change;
1104}
1105
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001106static struct snd_kcontrol_new snd_emu10k1_spdif_mask_control =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107{
1108 .access = SNDRV_CTL_ELEM_ACCESS_READ,
Clemens Ladisch5549d542005-08-03 13:50:30 +02001109 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
Takashi Iwai7583cb52007-08-16 19:32:16 +02001111 .count = 3,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 .info = snd_emu10k1_spdif_info,
1113 .get = snd_emu10k1_spdif_get_mask
1114};
1115
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001116static struct snd_kcontrol_new snd_emu10k1_spdif_control =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117{
Clemens Ladisch5549d542005-08-03 13:50:30 +02001118 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
Takashi Iwai7583cb52007-08-16 19:32:16 +02001120 .count = 3,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 .info = snd_emu10k1_spdif_info,
1122 .get = snd_emu10k1_spdif_get,
1123 .put = snd_emu10k1_spdif_put
1124};
1125
1126
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001127static void update_emu10k1_fxrt(struct snd_emu10k1 *emu, int voice, unsigned char *route)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128{
1129 if (emu->audigy) {
1130 snd_emu10k1_ptr_write(emu, A_FXRT1, voice,
1131 snd_emu10k1_compose_audigy_fxrt1(route));
1132 snd_emu10k1_ptr_write(emu, A_FXRT2, voice,
1133 snd_emu10k1_compose_audigy_fxrt2(route));
1134 } else {
1135 snd_emu10k1_ptr_write(emu, FXRT, voice,
1136 snd_emu10k1_compose_send_routing(route));
1137 }
1138}
1139
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001140static void update_emu10k1_send_volume(struct snd_emu10k1 *emu, int voice, unsigned char *volume)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141{
1142 snd_emu10k1_ptr_write(emu, PTRX_FXSENDAMOUNT_A, voice, volume[0]);
1143 snd_emu10k1_ptr_write(emu, PTRX_FXSENDAMOUNT_B, voice, volume[1]);
1144 snd_emu10k1_ptr_write(emu, PSST_FXSENDAMOUNT_C, voice, volume[2]);
1145 snd_emu10k1_ptr_write(emu, DSL_FXSENDAMOUNT_D, voice, volume[3]);
1146 if (emu->audigy) {
1147 unsigned int val = ((unsigned int)volume[4] << 24) |
1148 ((unsigned int)volume[5] << 16) |
1149 ((unsigned int)volume[6] << 8) |
1150 (unsigned int)volume[7];
1151 snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, voice, val);
1152 }
1153}
1154
1155/* PCM stream controls */
1156
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001157static int snd_emu10k1_send_routing_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001159 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1161 uinfo->count = emu->audigy ? 3*8 : 3*4;
1162 uinfo->value.integer.min = 0;
1163 uinfo->value.integer.max = emu->audigy ? 0x3f : 0x0f;
1164 return 0;
1165}
1166
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001167static int snd_emu10k1_send_routing_get(struct snd_kcontrol *kcontrol,
1168 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169{
1170 unsigned long flags;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001171 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1172 struct snd_emu10k1_pcm_mixer *mix =
1173 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174 int voice, idx;
1175 int num_efx = emu->audigy ? 8 : 4;
1176 int mask = emu->audigy ? 0x3f : 0x0f;
1177
1178 spin_lock_irqsave(&emu->reg_lock, flags);
1179 for (voice = 0; voice < 3; voice++)
1180 for (idx = 0; idx < num_efx; idx++)
1181 ucontrol->value.integer.value[(voice * num_efx) + idx] =
1182 mix->send_routing[voice][idx] & mask;
1183 spin_unlock_irqrestore(&emu->reg_lock, flags);
1184 return 0;
1185}
1186
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001187static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol,
1188 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189{
1190 unsigned long flags;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001191 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1192 struct snd_emu10k1_pcm_mixer *mix =
1193 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194 int change = 0, voice, idx, val;
1195 int num_efx = emu->audigy ? 8 : 4;
1196 int mask = emu->audigy ? 0x3f : 0x0f;
1197
1198 spin_lock_irqsave(&emu->reg_lock, flags);
1199 for (voice = 0; voice < 3; voice++)
1200 for (idx = 0; idx < num_efx; idx++) {
1201 val = ucontrol->value.integer.value[(voice * num_efx) + idx] & mask;
1202 if (mix->send_routing[voice][idx] != val) {
1203 mix->send_routing[voice][idx] = val;
1204 change = 1;
1205 }
1206 }
1207 if (change && mix->epcm) {
1208 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
1209 update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number,
1210 &mix->send_routing[1][0]);
1211 update_emu10k1_fxrt(emu, mix->epcm->voices[1]->number,
1212 &mix->send_routing[2][0]);
1213 } else if (mix->epcm->voices[0]) {
1214 update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number,
1215 &mix->send_routing[0][0]);
1216 }
1217 }
1218 spin_unlock_irqrestore(&emu->reg_lock, flags);
1219 return change;
1220}
1221
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001222static struct snd_kcontrol_new snd_emu10k1_send_routing_control =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223{
1224 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001225 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226 .name = "EMU10K1 PCM Send Routing",
1227 .count = 32,
1228 .info = snd_emu10k1_send_routing_info,
1229 .get = snd_emu10k1_send_routing_get,
1230 .put = snd_emu10k1_send_routing_put
1231};
1232
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001233static int snd_emu10k1_send_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001235 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1237 uinfo->count = emu->audigy ? 3*8 : 3*4;
1238 uinfo->value.integer.min = 0;
1239 uinfo->value.integer.max = 255;
1240 return 0;
1241}
1242
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001243static int snd_emu10k1_send_volume_get(struct snd_kcontrol *kcontrol,
1244 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245{
1246 unsigned long flags;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001247 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1248 struct snd_emu10k1_pcm_mixer *mix =
1249 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250 int idx;
1251 int num_efx = emu->audigy ? 8 : 4;
1252
1253 spin_lock_irqsave(&emu->reg_lock, flags);
1254 for (idx = 0; idx < 3*num_efx; idx++)
1255 ucontrol->value.integer.value[idx] = mix->send_volume[idx/num_efx][idx%num_efx];
1256 spin_unlock_irqrestore(&emu->reg_lock, flags);
1257 return 0;
1258}
1259
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001260static int snd_emu10k1_send_volume_put(struct snd_kcontrol *kcontrol,
1261 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262{
1263 unsigned long flags;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001264 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1265 struct snd_emu10k1_pcm_mixer *mix =
1266 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267 int change = 0, idx, val;
1268 int num_efx = emu->audigy ? 8 : 4;
1269
1270 spin_lock_irqsave(&emu->reg_lock, flags);
1271 for (idx = 0; idx < 3*num_efx; idx++) {
1272 val = ucontrol->value.integer.value[idx] & 255;
1273 if (mix->send_volume[idx/num_efx][idx%num_efx] != val) {
1274 mix->send_volume[idx/num_efx][idx%num_efx] = val;
1275 change = 1;
1276 }
1277 }
1278 if (change && mix->epcm) {
1279 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
1280 update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number,
1281 &mix->send_volume[1][0]);
1282 update_emu10k1_send_volume(emu, mix->epcm->voices[1]->number,
1283 &mix->send_volume[2][0]);
1284 } else if (mix->epcm->voices[0]) {
1285 update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number,
1286 &mix->send_volume[0][0]);
1287 }
1288 }
1289 spin_unlock_irqrestore(&emu->reg_lock, flags);
1290 return change;
1291}
1292
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001293static struct snd_kcontrol_new snd_emu10k1_send_volume_control =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294{
1295 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001296 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297 .name = "EMU10K1 PCM Send Volume",
1298 .count = 32,
1299 .info = snd_emu10k1_send_volume_info,
1300 .get = snd_emu10k1_send_volume_get,
1301 .put = snd_emu10k1_send_volume_put
1302};
1303
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001304static int snd_emu10k1_attn_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305{
1306 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1307 uinfo->count = 3;
1308 uinfo->value.integer.min = 0;
1309 uinfo->value.integer.max = 0xffff;
1310 return 0;
1311}
1312
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001313static int snd_emu10k1_attn_get(struct snd_kcontrol *kcontrol,
1314 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001316 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1317 struct snd_emu10k1_pcm_mixer *mix =
1318 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001319 unsigned long flags;
1320 int idx;
1321
1322 spin_lock_irqsave(&emu->reg_lock, flags);
1323 for (idx = 0; idx < 3; idx++)
1324 ucontrol->value.integer.value[idx] = mix->attn[idx];
1325 spin_unlock_irqrestore(&emu->reg_lock, flags);
1326 return 0;
1327}
1328
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001329static int snd_emu10k1_attn_put(struct snd_kcontrol *kcontrol,
1330 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331{
1332 unsigned long flags;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001333 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1334 struct snd_emu10k1_pcm_mixer *mix =
1335 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336 int change = 0, idx, val;
1337
1338 spin_lock_irqsave(&emu->reg_lock, flags);
1339 for (idx = 0; idx < 3; idx++) {
1340 val = ucontrol->value.integer.value[idx] & 0xffff;
1341 if (mix->attn[idx] != val) {
1342 mix->attn[idx] = val;
1343 change = 1;
1344 }
1345 }
1346 if (change && mix->epcm) {
1347 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
1348 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[1]);
1349 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[1]->number, mix->attn[2]);
1350 } else if (mix->epcm->voices[0]) {
1351 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[0]);
1352 }
1353 }
1354 spin_unlock_irqrestore(&emu->reg_lock, flags);
1355 return change;
1356}
1357
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001358static struct snd_kcontrol_new snd_emu10k1_attn_control =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359{
1360 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001361 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362 .name = "EMU10K1 PCM Volume",
1363 .count = 32,
1364 .info = snd_emu10k1_attn_info,
1365 .get = snd_emu10k1_attn_get,
1366 .put = snd_emu10k1_attn_put
1367};
1368
1369/* Mutichannel PCM stream controls */
1370
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001371static int snd_emu10k1_efx_send_routing_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001373 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1375 uinfo->count = emu->audigy ? 8 : 4;
1376 uinfo->value.integer.min = 0;
1377 uinfo->value.integer.max = emu->audigy ? 0x3f : 0x0f;
1378 return 0;
1379}
1380
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001381static int snd_emu10k1_efx_send_routing_get(struct snd_kcontrol *kcontrol,
1382 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383{
1384 unsigned long flags;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001385 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1386 struct snd_emu10k1_pcm_mixer *mix =
1387 &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388 int idx;
1389 int num_efx = emu->audigy ? 8 : 4;
1390 int mask = emu->audigy ? 0x3f : 0x0f;
1391
1392 spin_lock_irqsave(&emu->reg_lock, flags);
1393 for (idx = 0; idx < num_efx; idx++)
1394 ucontrol->value.integer.value[idx] =
1395 mix->send_routing[0][idx] & mask;
1396 spin_unlock_irqrestore(&emu->reg_lock, flags);
1397 return 0;
1398}
1399
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001400static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol,
1401 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402{
1403 unsigned long flags;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001404 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001406 struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407 int change = 0, idx, val;
1408 int num_efx = emu->audigy ? 8 : 4;
1409 int mask = emu->audigy ? 0x3f : 0x0f;
1410
1411 spin_lock_irqsave(&emu->reg_lock, flags);
1412 for (idx = 0; idx < num_efx; idx++) {
1413 val = ucontrol->value.integer.value[idx] & mask;
1414 if (mix->send_routing[0][idx] != val) {
1415 mix->send_routing[0][idx] = val;
1416 change = 1;
1417 }
1418 }
1419
1420 if (change && mix->epcm) {
1421 if (mix->epcm->voices[ch]) {
1422 update_emu10k1_fxrt(emu, mix->epcm->voices[ch]->number,
1423 &mix->send_routing[0][0]);
1424 }
1425 }
1426 spin_unlock_irqrestore(&emu->reg_lock, flags);
1427 return change;
1428}
1429
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001430static struct snd_kcontrol_new snd_emu10k1_efx_send_routing_control =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431{
1432 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1433 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1434 .name = "Multichannel PCM Send Routing",
1435 .count = 16,
1436 .info = snd_emu10k1_efx_send_routing_info,
1437 .get = snd_emu10k1_efx_send_routing_get,
1438 .put = snd_emu10k1_efx_send_routing_put
1439};
1440
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001441static int snd_emu10k1_efx_send_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001443 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1445 uinfo->count = emu->audigy ? 8 : 4;
1446 uinfo->value.integer.min = 0;
1447 uinfo->value.integer.max = 255;
1448 return 0;
1449}
1450
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001451static int snd_emu10k1_efx_send_volume_get(struct snd_kcontrol *kcontrol,
1452 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453{
1454 unsigned long flags;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001455 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1456 struct snd_emu10k1_pcm_mixer *mix =
1457 &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458 int idx;
1459 int num_efx = emu->audigy ? 8 : 4;
1460
1461 spin_lock_irqsave(&emu->reg_lock, flags);
1462 for (idx = 0; idx < num_efx; idx++)
1463 ucontrol->value.integer.value[idx] = mix->send_volume[0][idx];
1464 spin_unlock_irqrestore(&emu->reg_lock, flags);
1465 return 0;
1466}
1467
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001468static int snd_emu10k1_efx_send_volume_put(struct snd_kcontrol *kcontrol,
1469 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470{
1471 unsigned long flags;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001472 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001474 struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 int change = 0, idx, val;
1476 int num_efx = emu->audigy ? 8 : 4;
1477
1478 spin_lock_irqsave(&emu->reg_lock, flags);
1479 for (idx = 0; idx < num_efx; idx++) {
1480 val = ucontrol->value.integer.value[idx] & 255;
1481 if (mix->send_volume[0][idx] != val) {
1482 mix->send_volume[0][idx] = val;
1483 change = 1;
1484 }
1485 }
1486 if (change && mix->epcm) {
1487 if (mix->epcm->voices[ch]) {
1488 update_emu10k1_send_volume(emu, mix->epcm->voices[ch]->number,
1489 &mix->send_volume[0][0]);
1490 }
1491 }
1492 spin_unlock_irqrestore(&emu->reg_lock, flags);
1493 return change;
1494}
1495
1496
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001497static struct snd_kcontrol_new snd_emu10k1_efx_send_volume_control =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498{
1499 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1500 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1501 .name = "Multichannel PCM Send Volume",
1502 .count = 16,
1503 .info = snd_emu10k1_efx_send_volume_info,
1504 .get = snd_emu10k1_efx_send_volume_get,
1505 .put = snd_emu10k1_efx_send_volume_put
1506};
1507
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001508static int snd_emu10k1_efx_attn_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509{
1510 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1511 uinfo->count = 1;
1512 uinfo->value.integer.min = 0;
1513 uinfo->value.integer.max = 0xffff;
1514 return 0;
1515}
1516
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001517static int snd_emu10k1_efx_attn_get(struct snd_kcontrol *kcontrol,
1518 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001520 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1521 struct snd_emu10k1_pcm_mixer *mix =
1522 &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 unsigned long flags;
1524
1525 spin_lock_irqsave(&emu->reg_lock, flags);
1526 ucontrol->value.integer.value[0] = mix->attn[0];
1527 spin_unlock_irqrestore(&emu->reg_lock, flags);
1528 return 0;
1529}
1530
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001531static int snd_emu10k1_efx_attn_put(struct snd_kcontrol *kcontrol,
1532 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533{
1534 unsigned long flags;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001535 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001537 struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538 int change = 0, val;
1539
1540 spin_lock_irqsave(&emu->reg_lock, flags);
1541 val = ucontrol->value.integer.value[0] & 0xffff;
1542 if (mix->attn[0] != val) {
1543 mix->attn[0] = val;
1544 change = 1;
1545 }
1546 if (change && mix->epcm) {
1547 if (mix->epcm->voices[ch]) {
1548 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[ch]->number, mix->attn[0]);
1549 }
1550 }
1551 spin_unlock_irqrestore(&emu->reg_lock, flags);
1552 return change;
1553}
1554
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001555static struct snd_kcontrol_new snd_emu10k1_efx_attn_control =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556{
1557 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1558 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1559 .name = "Multichannel PCM Volume",
1560 .count = 16,
1561 .info = snd_emu10k1_efx_attn_info,
1562 .get = snd_emu10k1_efx_attn_get,
1563 .put = snd_emu10k1_efx_attn_put
1564};
1565
Takashi Iwaia5ce8892007-07-23 15:42:26 +02001566#define snd_emu10k1_shared_spdif_info snd_ctl_boolean_mono_info
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001568static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol,
1569 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001571 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572
1573 if (emu->audigy)
1574 ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
1575 else
1576 ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;
1577 return 0;
1578}
1579
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001580static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
1581 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582{
1583 unsigned long flags;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001584 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585 unsigned int reg, val;
1586 int change = 0;
1587
1588 spin_lock_irqsave(&emu->reg_lock, flags);
James Courtier-Dutton184c1e22006-12-06 15:58:02 +00001589 if ( emu->card_capabilities->i2c_adc) {
1590 /* Do nothing for Audigy 2 ZS Notebook */
1591 } else if (emu->audigy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592 reg = inl(emu->port + A_IOCFG);
1593 val = ucontrol->value.integer.value[0] ? A_IOCFG_GPOUT0 : 0;
1594 change = (reg & A_IOCFG_GPOUT0) != val;
1595 if (change) {
1596 reg &= ~A_IOCFG_GPOUT0;
1597 reg |= val;
1598 outl(reg | val, emu->port + A_IOCFG);
1599 }
1600 }
1601 reg = inl(emu->port + HCFG);
1602 val = ucontrol->value.integer.value[0] ? HCFG_GPOUT0 : 0;
1603 change |= (reg & HCFG_GPOUT0) != val;
1604 if (change) {
1605 reg &= ~HCFG_GPOUT0;
1606 reg |= val;
1607 outl(reg | val, emu->port + HCFG);
1608 }
1609 spin_unlock_irqrestore(&emu->reg_lock, flags);
1610 return change;
1611}
1612
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001613static struct snd_kcontrol_new snd_emu10k1_shared_spdif __devinitdata =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614{
1615 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1616 .name = "SB Live Analog/Digital Output Jack",
1617 .info = snd_emu10k1_shared_spdif_info,
1618 .get = snd_emu10k1_shared_spdif_get,
1619 .put = snd_emu10k1_shared_spdif_put
1620};
1621
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001622static struct snd_kcontrol_new snd_audigy_shared_spdif __devinitdata =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623{
1624 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1625 .name = "Audigy Analog/Digital Output Jack",
1626 .info = snd_emu10k1_shared_spdif_info,
1627 .get = snd_emu10k1_shared_spdif_get,
1628 .put = snd_emu10k1_shared_spdif_put
1629};
1630
1631/*
1632 */
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001633static void snd_emu10k1_mixer_free_ac97(struct snd_ac97 *ac97)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001635 struct snd_emu10k1 *emu = ac97->private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 emu->ac97 = NULL;
1637}
1638
1639/*
1640 */
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001641static int remove_ctl(struct snd_card *card, const char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001643 struct snd_ctl_elem_id id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644 memset(&id, 0, sizeof(id));
1645 strcpy(id.name, name);
1646 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1647 return snd_ctl_remove_id(card, &id);
1648}
1649
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001650static struct snd_kcontrol *ctl_find(struct snd_card *card, const char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001652 struct snd_ctl_elem_id sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653 memset(&sid, 0, sizeof(sid));
1654 strcpy(sid.name, name);
1655 sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1656 return snd_ctl_find_id(card, &sid);
1657}
1658
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001659static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660{
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001661 struct snd_kcontrol *kctl = ctl_find(card, src);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 if (kctl) {
1663 strcpy(kctl->id.name, dst);
1664 return 0;
1665 }
1666 return -ENOENT;
1667}
1668
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001669int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001670 int pcm_device, int multi_device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671{
1672 int err, pcm;
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001673 struct snd_kcontrol *kctl;
1674 struct snd_card *card = emu->card;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675 char **c;
1676 static char *emu10k1_remove_ctls[] = {
1677 /* no AC97 mono, surround, center/lfe */
1678 "Master Mono Playback Switch",
1679 "Master Mono Playback Volume",
1680 "PCM Out Path & Mute",
1681 "Mono Output Select",
Takashi Iwai7eae36f2006-01-05 18:40:56 +01001682 "Front Playback Switch",
1683 "Front Playback Volume",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 "Surround Playback Switch",
1685 "Surround Playback Volume",
1686 "Center Playback Switch",
1687 "Center Playback Volume",
1688 "LFE Playback Switch",
1689 "LFE Playback Volume",
1690 NULL
1691 };
1692 static char *emu10k1_rename_ctls[] = {
1693 "Surround Digital Playback Volume", "Surround Playback Volume",
1694 "Center Digital Playback Volume", "Center Playback Volume",
1695 "LFE Digital Playback Volume", "LFE Playback Volume",
1696 NULL
1697 };
1698 static char *audigy_remove_ctls[] = {
1699 /* Master/PCM controls on ac97 of Audigy has no effect */
James Courtier-Dutton21fddde2006-04-09 17:36:39 +01001700 /* On the Audigy2 the AC97 playback is piped into
1701 * the Philips ADC for 24bit capture */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702 "PCM Playback Switch",
1703 "PCM Playback Volume",
1704 "Master Mono Playback Switch",
1705 "Master Mono Playback Volume",
1706 "Master Playback Switch",
1707 "Master Playback Volume",
1708 "PCM Out Path & Mute",
1709 "Mono Output Select",
1710 /* remove unused AC97 capture controls */
1711 "Capture Source",
1712 "Capture Switch",
1713 "Capture Volume",
1714 "Mic Select",
1715 "Video Playback Switch",
1716 "Video Playback Volume",
1717 "Mic Playback Switch",
1718 "Mic Playback Volume",
1719 NULL
1720 };
1721 static char *audigy_rename_ctls[] = {
1722 /* use conventional names */
1723 "Wave Playback Volume", "PCM Playback Volume",
1724 /* "Wave Capture Volume", "PCM Capture Volume", */
1725 "Wave Master Playback Volume", "Master Playback Volume",
1726 "AMic Playback Volume", "Mic Playback Volume",
1727 NULL
1728 };
James Courtier-Dutton184c1e22006-12-06 15:58:02 +00001729 static char *audigy_rename_ctls_i2c_adc[] = {
1730 //"Analog Mix Capture Volume","OLD Analog Mix Capture Volume",
1731 "Line Capture Volume", "Analog Mix Capture Volume",
1732 "Wave Playback Volume", "OLD PCM Playback Volume",
1733 "Wave Master Playback Volume", "Master Playback Volume",
1734 "AMic Playback Volume", "Old Mic Playback Volume",
James Courtier-Duttoneb41dab2006-12-06 20:38:45 +00001735 "CD Capture Volume", "IEC958 Optical Capture Volume",
James Courtier-Dutton184c1e22006-12-06 15:58:02 +00001736 NULL
1737 };
1738 static char *audigy_remove_ctls_i2c_adc[] = {
1739 /* On the Audigy2 ZS Notebook
1740 * Capture via WM8775 */
1741 "Mic Capture Volume",
1742 "Analog Mix Capture Volume",
1743 "Aux Capture Volume",
James Courtier-Duttoneb41dab2006-12-06 20:38:45 +00001744 "IEC958 Optical Capture Volume",
James Courtier-Dutton184c1e22006-12-06 15:58:02 +00001745 NULL
1746 };
James Courtier-Dutton21fddde2006-04-09 17:36:39 +01001747 static char *audigy_remove_ctls_1361t_adc[] = {
1748 /* On the Audigy2 the AC97 playback is piped into
1749 * the Philips ADC for 24bit capture */
1750 "PCM Playback Switch",
1751 "PCM Playback Volume",
1752 "Master Mono Playback Switch",
1753 "Master Mono Playback Volume",
1754 "Capture Source",
1755 "Capture Switch",
1756 "Capture Volume",
1757 "Mic Capture Volume",
1758 "Headphone Playback Switch",
1759 "Headphone Playback Volume",
1760 "3D Control - Center",
1761 "3D Control - Depth",
1762 "3D Control - Switch",
1763 "Line2 Playback Volume",
1764 "Line2 Capture Volume",
1765 NULL
1766 };
1767 static char *audigy_rename_ctls_1361t_adc[] = {
1768 "Master Playback Switch", "Master Capture Switch",
1769 "Master Playback Volume", "Master Capture Volume",
1770 "Wave Master Playback Volume", "Master Playback Volume",
1771 "PC Speaker Playback Switch", "PC Speaker Capture Switch",
1772 "PC Speaker Playback Volume", "PC Speaker Capture Volume",
1773 "Phone Playback Switch", "Phone Capture Switch",
1774 "Phone Playback Volume", "Phone Capture Volume",
1775 "Mic Playback Switch", "Mic Capture Switch",
1776 "Mic Playback Volume", "Mic Capture Volume",
1777 "Line Playback Switch", "Line Capture Switch",
1778 "Line Playback Volume", "Line Capture Volume",
1779 "CD Playback Switch", "CD Capture Switch",
1780 "CD Playback Volume", "CD Capture Volume",
1781 "Aux Playback Switch", "Aux Capture Switch",
1782 "Aux Playback Volume", "Aux Capture Volume",
1783 "Video Playback Switch", "Video Capture Switch",
1784 "Video Playback Volume", "Video Capture Volume",
1785
1786 NULL
1787 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788
Lee Revell2b637da2005-03-30 13:51:18 +02001789 if (emu->card_capabilities->ac97_chip) {
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001790 struct snd_ac97_bus *pbus;
1791 struct snd_ac97_template ac97;
1792 static struct snd_ac97_bus_ops ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 .write = snd_emu10k1_ac97_write,
1794 .read = snd_emu10k1_ac97_read,
1795 };
1796
Takashi Iwaib1508692005-10-04 13:49:32 +02001797 if ((err = snd_ac97_bus(emu->card, 0, &ops, NULL, &pbus)) < 0)
1798 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 pbus->no_vra = 1; /* we don't need VRA */
1800
1801 memset(&ac97, 0, sizeof(ac97));
1802 ac97.private_data = emu;
1803 ac97.private_free = snd_emu10k1_mixer_free_ac97;
1804 ac97.scaps = AC97_SCAP_NO_SPDIF;
Takashi Iwaib1508692005-10-04 13:49:32 +02001805 if ((err = snd_ac97_mixer(pbus, &ac97, &emu->ac97)) < 0) {
1806 if (emu->card_capabilities->ac97_chip == 1)
1807 return err;
1808 snd_printd(KERN_INFO "emu10k1: AC97 is optional on this board\n");
1809 snd_printd(KERN_INFO" Proceeding without ac97 mixers...\n");
1810 snd_device_free(emu->card, pbus);
1811 goto no_ac97; /* FIXME: get rid of ugly gotos.. */
1812 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 if (emu->audigy) {
1814 /* set master volume to 0 dB */
Takashi Iwai4d7d7592006-01-04 16:00:48 +01001815 snd_ac97_write_cache(emu->ac97, AC97_MASTER, 0x0000);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 /* set capture source to mic */
Takashi Iwai4d7d7592006-01-04 16:00:48 +01001817 snd_ac97_write_cache(emu->ac97, AC97_REC_SEL, 0x0000);
James Courtier-Dutton21fddde2006-04-09 17:36:39 +01001818 if (emu->card_capabilities->adc_1361t)
1819 c = audigy_remove_ctls_1361t_adc;
1820 else
1821 c = audigy_remove_ctls;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 } else {
1823 /*
1824 * Credits for cards based on STAC9758:
1825 * James Courtier-Dutton <James@superbug.demon.co.uk>
1826 * Voluspa <voluspa@comhem.se>
1827 */
1828 if (emu->ac97->id == AC97_ID_STAC9758) {
1829 emu->rear_ac97 = 1;
1830 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT);
Rolf Stefan Wilke2594d962007-02-06 19:18:14 +01001831 snd_ac97_write_cache(emu->ac97, AC97_HEADPHONE, 0x0202);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 }
1833 /* remove unused AC97 controls */
Takashi Iwai4d7d7592006-01-04 16:00:48 +01001834 snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
1835 snd_ac97_write_cache(emu->ac97, AC97_CENTER_LFE_MASTER, 0x0202);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 c = emu10k1_remove_ctls;
1837 }
1838 for (; *c; c++)
1839 remove_ctl(card, *c);
James Courtier-Dutton184c1e22006-12-06 15:58:02 +00001840 } else if (emu->card_capabilities->i2c_adc) {
1841 c = audigy_remove_ctls_i2c_adc;
1842 for (; *c; c++)
1843 remove_ctl(card, *c);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 } else {
Takashi Iwaif12aa402005-09-30 16:56:59 +02001845 no_ac97:
Lee Revell2b637da2005-03-30 13:51:18 +02001846 if (emu->card_capabilities->ecard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847 strcpy(emu->card->mixername, "EMU APS");
1848 else if (emu->audigy)
1849 strcpy(emu->card->mixername, "SB Audigy");
1850 else
1851 strcpy(emu->card->mixername, "Emu10k1");
1852 }
1853
1854 if (emu->audigy)
James Courtier-Dutton21fddde2006-04-09 17:36:39 +01001855 if (emu->card_capabilities->adc_1361t)
1856 c = audigy_rename_ctls_1361t_adc;
James Courtier-Dutton184c1e22006-12-06 15:58:02 +00001857 else if (emu->card_capabilities->i2c_adc)
1858 c = audigy_rename_ctls_i2c_adc;
James Courtier-Dutton21fddde2006-04-09 17:36:39 +01001859 else
1860 c = audigy_rename_ctls;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861 else
1862 c = emu10k1_rename_ctls;
1863 for (; *c; c += 2)
1864 rename_ctl(card, c[0], c[1]);
James Courtier-Dutton21fddde2006-04-09 17:36:39 +01001865
James Courtier-Duttone3b9bc02005-12-24 16:54:51 +01001866 if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */
1867 rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume");
1868 rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume");
1869 rename_ctl(card, "Aux2 Capture Volume", "Line3 Capture Volume");
1870 rename_ctl(card, "Mic Capture Volume", "Unknown1 Capture Volume");
1871 remove_ctl(card, "Headphone Playback Switch");
1872 remove_ctl(card, "Headphone Playback Volume");
1873 remove_ctl(card, "3D Control - Center");
1874 remove_ctl(card, "3D Control - Depth");
1875 remove_ctl(card, "3D Control - Switch");
1876 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877 if ((kctl = emu->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu)) == NULL)
1878 return -ENOMEM;
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001879 kctl->id.device = pcm_device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880 if ((err = snd_ctl_add(card, kctl)))
1881 return err;
1882 if ((kctl = emu->ctl_send_volume = snd_ctl_new1(&snd_emu10k1_send_volume_control, emu)) == NULL)
1883 return -ENOMEM;
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001884 kctl->id.device = pcm_device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885 if ((err = snd_ctl_add(card, kctl)))
1886 return err;
1887 if ((kctl = emu->ctl_attn = snd_ctl_new1(&snd_emu10k1_attn_control, emu)) == NULL)
1888 return -ENOMEM;
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001889 kctl->id.device = pcm_device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 if ((err = snd_ctl_add(card, kctl)))
1891 return err;
1892
1893 if ((kctl = emu->ctl_efx_send_routing = snd_ctl_new1(&snd_emu10k1_efx_send_routing_control, emu)) == NULL)
1894 return -ENOMEM;
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001895 kctl->id.device = multi_device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 if ((err = snd_ctl_add(card, kctl)))
1897 return err;
1898
1899 if ((kctl = emu->ctl_efx_send_volume = snd_ctl_new1(&snd_emu10k1_efx_send_volume_control, emu)) == NULL)
1900 return -ENOMEM;
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001901 kctl->id.device = multi_device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902 if ((err = snd_ctl_add(card, kctl)))
1903 return err;
1904
1905 if ((kctl = emu->ctl_efx_attn = snd_ctl_new1(&snd_emu10k1_efx_attn_control, emu)) == NULL)
1906 return -ENOMEM;
Clemens Ladisch67ed4162005-07-29 15:32:58 +02001907 kctl->id.device = multi_device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908 if ((err = snd_ctl_add(card, kctl)))
1909 return err;
1910
1911 /* initialize the routing and volume table for each pcm playback stream */
1912 for (pcm = 0; pcm < 32; pcm++) {
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001913 struct snd_emu10k1_pcm_mixer *mix;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914 int v;
1915
1916 mix = &emu->pcm_mixer[pcm];
1917 mix->epcm = NULL;
1918
1919 for (v = 0; v < 4; v++)
1920 mix->send_routing[0][v] =
1921 mix->send_routing[1][v] =
1922 mix->send_routing[2][v] = v;
1923
1924 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
1925 mix->send_volume[0][0] = mix->send_volume[0][1] =
1926 mix->send_volume[1][0] = mix->send_volume[2][1] = 255;
1927
1928 mix->attn[0] = mix->attn[1] = mix->attn[2] = 0xffff;
1929 }
1930
1931 /* initialize the routing and volume table for the multichannel playback stream */
1932 for (pcm = 0; pcm < NUM_EFX_PLAYBACK; pcm++) {
Takashi Iwaieb4698f2005-11-17 14:50:13 +01001933 struct snd_emu10k1_pcm_mixer *mix;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934 int v;
1935
1936 mix = &emu->efx_pcm_mixer[pcm];
1937 mix->epcm = NULL;
1938
1939 mix->send_routing[0][0] = pcm;
1940 mix->send_routing[0][1] = (pcm == 0) ? 1 : 0;
1941 for (v = 0; v < 2; v++)
1942 mix->send_routing[0][2+v] = 13+v;
1943 if (emu->audigy)
1944 for (v = 0; v < 4; v++)
1945 mix->send_routing[0][4+v] = 60+v;
1946
1947 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
1948 mix->send_volume[0][0] = 255;
1949
1950 mix->attn[0] = 0xffff;
1951 }
1952
Lee Revell2b637da2005-03-30 13:51:18 +02001953 if (! emu->card_capabilities->ecard) { /* FIXME: APS has these controls? */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954 /* sb live! and audigy */
1955 if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL)
1956 return -ENOMEM;
Clemens Ladisch5549d542005-08-03 13:50:30 +02001957 if (!emu->audigy)
1958 kctl->id.device = emu->pcm_efx->device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959 if ((err = snd_ctl_add(card, kctl)))
1960 return err;
1961 if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_control, emu)) == NULL)
1962 return -ENOMEM;
Clemens Ladisch5549d542005-08-03 13:50:30 +02001963 if (!emu->audigy)
1964 kctl->id.device = emu->pcm_efx->device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 if ((err = snd_ctl_add(card, kctl)))
1966 return err;
1967 }
1968
James Courtier-Dutton190d2c42007-11-04 14:08:26 +00001969 if (emu->card_capabilities->emu_model) {
James Courtier-Dutton19b99fb2005-12-04 18:03:03 +01001970 ; /* Disable the snd_audigy_spdif_shared_spdif */
1971 } else if (emu->audigy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001972 if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL)
1973 return -ENOMEM;
1974 if ((err = snd_ctl_add(card, kctl)))
1975 return err;
James Courtier-Dutton001f7582005-04-09 23:38:25 +02001976#if 0
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 if ((kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu)) == NULL)
1978 return -ENOMEM;
1979 if ((err = snd_ctl_add(card, kctl)))
1980 return err;
James Courtier-Dutton001f7582005-04-09 23:38:25 +02001981#endif
Lee Revell2b637da2005-03-30 13:51:18 +02001982 } else if (! emu->card_capabilities->ecard) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983 /* sb live! */
1984 if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL)
1985 return -ENOMEM;
1986 if ((err = snd_ctl_add(card, kctl)))
1987 return err;
1988 }
Lee Revell2b637da2005-03-30 13:51:18 +02001989 if (emu->card_capabilities->ca0151_chip) { /* P16V */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001990 if ((err = snd_p16v_mixer(emu)))
1991 return err;
1992 }
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +01001993
Ctirad Fertr1c02e362007-12-13 16:27:13 +01001994 if (emu->card_capabilities->emu_model == 3) {
1995 /* 1616(m) cardbus */
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +01001996 int i;
1997
Ctirad Fertr1c02e362007-12-13 16:27:13 +01001998 for (i = 0; i < ARRAY_SIZE(snd_emu1616_output_enum_ctls); i++) {
1999 err = snd_ctl_add(card,
2000 snd_ctl_new1(&snd_emu1616_output_enum_ctls[i],
2001 emu));
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +01002002 if (err < 0)
2003 return err;
2004 }
2005 for (i = 0; i < ARRAY_SIZE(snd_emu1010_input_enum_ctls); i++) {
Ctirad Fertr1c02e362007-12-13 16:27:13 +01002006 err = snd_ctl_add(card,
2007 snd_ctl_new1(&snd_emu1010_input_enum_ctls[i],
2008 emu));
2009 if (err < 0)
2010 return err;
2011 }
2012 for (i = 0; i < ARRAY_SIZE(snd_emu1010_adc_pads) - 2; i++) {
2013 err = snd_ctl_add(card,
2014 snd_ctl_new1(&snd_emu1010_adc_pads[i], emu));
2015 if (err < 0)
2016 return err;
2017 }
2018 for (i = 0; i < ARRAY_SIZE(snd_emu1010_dac_pads) - 2; i++) {
2019 err = snd_ctl_add(card,
2020 snd_ctl_new1(&snd_emu1010_dac_pads[i], emu));
2021 if (err < 0)
2022 return err;
2023 }
2024 err = snd_ctl_add(card,
2025 snd_ctl_new1(&snd_emu1010_internal_clock, emu));
2026 if (err < 0)
2027 return err;
2028
2029 } else {
2030 /* all other e-mu cards for now */
2031 int i;
2032
2033 for (i = 0; i < ARRAY_SIZE(snd_emu1010_output_enum_ctls); i++) {
2034 err = snd_ctl_add(card,
2035 snd_ctl_new1(&snd_emu1010_output_enum_ctls[i],
2036 emu));
2037 if (err < 0)
2038 return err;
2039 }
2040 for (i = 0; i < ARRAY_SIZE(snd_emu1010_input_enum_ctls); i++) {
2041 err = snd_ctl_add(card,
2042 snd_ctl_new1(&snd_emu1010_input_enum_ctls[i],
2043 emu));
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +01002044 if (err < 0)
2045 return err;
2046 }
James Courtier-Dutton9148cc52006-10-09 23:08:00 +01002047 for (i = 0; i < ARRAY_SIZE(snd_emu1010_adc_pads); i++) {
Ctirad Fertr1c02e362007-12-13 16:27:13 +01002048 err = snd_ctl_add(card,
2049 snd_ctl_new1(&snd_emu1010_adc_pads[i], emu));
James Courtier-Dutton9148cc52006-10-09 23:08:00 +01002050 if (err < 0)
2051 return err;
2052 }
2053 for (i = 0; i < ARRAY_SIZE(snd_emu1010_dac_pads); i++) {
Ctirad Fertr1c02e362007-12-13 16:27:13 +01002054 err = snd_ctl_add(card,
2055 snd_ctl_new1(&snd_emu1010_dac_pads[i], emu));
James Courtier-Dutton9148cc52006-10-09 23:08:00 +01002056 if (err < 0)
2057 return err;
2058 }
Ctirad Fertr1c02e362007-12-13 16:27:13 +01002059 err = snd_ctl_add(card,
2060 snd_ctl_new1(&snd_emu1010_internal_clock, emu));
James Courtier-Duttonb0dbdae2006-10-10 18:08:45 +01002061 if (err < 0)
2062 return err;
James Courtier-Dutton9f4bd5d2006-10-01 10:48:04 +01002063 }
James Courtier-Dutton184c1e22006-12-06 15:58:02 +00002064
2065 if ( emu->card_capabilities->i2c_adc) {
2066 int i;
2067
2068 err = snd_ctl_add(card, snd_ctl_new1(&snd_audigy_i2c_capture_source, emu));
2069 if (err < 0)
2070 return err;
2071
2072 for (i = 0; i < ARRAY_SIZE(snd_audigy_i2c_volume_ctls); i++) {
2073 err = snd_ctl_add(card, snd_ctl_new1(&snd_audigy_i2c_volume_ctls[i], emu));
2074 if (err < 0)
2075 return err;
2076 }
2077 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002078
2079 return 0;
2080}