xref: /linux/sound/pci/ca0106/ca0106_mixer.c (revision c537b994505099b7197e7d3125b942ecbcc51eb6)
1 /*
2  *  Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
3  *  Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
4  *  Version: 0.0.17
5  *
6  *  FEATURES currently supported:
7  *    See ca0106_main.c for features.
8  *
9  *  Changelog:
10  *    Support interrupts per period.
11  *    Removed noise from Center/LFE channel when in Analog mode.
12  *    Rename and remove mixer controls.
13  *  0.0.6
14  *    Use separate card based DMA buffer for periods table list.
15  *  0.0.7
16  *    Change remove and rename ctrls into lists.
17  *  0.0.8
18  *    Try to fix capture sources.
19  *  0.0.9
20  *    Fix AC3 output.
21  *    Enable S32_LE format support.
22  *  0.0.10
23  *    Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
24  *  0.0.11
25  *    Add Model name recognition.
26  *  0.0.12
27  *    Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
28  *    Remove redundent "voice" handling.
29  *  0.0.13
30  *    Single trigger call for multi channels.
31  *  0.0.14
32  *    Set limits based on what the sound card hardware can do.
33  *    playback periods_min=2, periods_max=8
34  *    capture hw constraints require period_size = n * 64 bytes.
35  *    playback hw constraints require period_size = n * 64 bytes.
36  *  0.0.15
37  *    Separated ca0106.c into separate functional .c files.
38  *  0.0.16
39  *    Modified Copyright message.
40  *  0.0.17
41  *    Implement Mic and Line in Capture.
42  *
43  *  This code was initally based on code from ALSA's emu10k1x.c which is:
44  *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
45  *
46  *   This program is free software; you can redistribute it and/or modify
47  *   it under the terms of the GNU General Public License as published by
48  *   the Free Software Foundation; either version 2 of the License, or
49  *   (at your option) any later version.
50  *
51  *   This program is distributed in the hope that it will be useful,
52  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
53  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
54  *   GNU General Public License for more details.
55  *
56  *   You should have received a copy of the GNU General Public License
57  *   along with this program; if not, write to the Free Software
58  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
59  *
60  */
61 #include <sound/driver.h>
62 #include <linux/delay.h>
63 #include <linux/init.h>
64 #include <linux/interrupt.h>
65 #include <linux/pci.h>
66 #include <linux/slab.h>
67 #include <linux/moduleparam.h>
68 #include <sound/core.h>
69 #include <sound/initval.h>
70 #include <sound/pcm.h>
71 #include <sound/ac97_codec.h>
72 #include <sound/info.h>
73 #include <sound/tlv.h>
74 
75 #include "ca0106.h"
76 
77 static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1);
78 static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1);
79 
80 static int snd_ca0106_shared_spdif_info(struct snd_kcontrol *kcontrol,
81 					struct snd_ctl_elem_info *uinfo)
82 {
83 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
84 	uinfo->count = 1;
85 	uinfo->value.integer.min = 0;
86 	uinfo->value.integer.max = 1;
87 	return 0;
88 }
89 
90 static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol,
91 					struct snd_ctl_elem_value *ucontrol)
92 {
93 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
94 
95 	ucontrol->value.enumerated.item[0] = emu->spdif_enable;
96 	return 0;
97 }
98 
99 static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
100 					struct snd_ctl_elem_value *ucontrol)
101 {
102 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
103 	unsigned int val;
104 	int change = 0;
105 	u32 mask;
106 
107 	val = ucontrol->value.enumerated.item[0] ;
108 	change = (emu->spdif_enable != val);
109 	if (change) {
110 		emu->spdif_enable = val;
111 		if (val == 1) {
112 			/* Digital */
113 			snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
114 			snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
115 			snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0,
116 				snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000);
117 			mask = inl(emu->port + GPIO) & ~0x101;
118 			outl(mask, emu->port + GPIO);
119 
120 		} else {
121 			/* Analog */
122 			snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
123 			snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
124 			snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0,
125 				snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000);
126 			mask = inl(emu->port + GPIO) | 0x101;
127 			outl(mask, emu->port + GPIO);
128 		}
129 	}
130         return change;
131 }
132 
133 static int snd_ca0106_capture_source_info(struct snd_kcontrol *kcontrol,
134 					  struct snd_ctl_elem_info *uinfo)
135 {
136 	static char *texts[6] = {
137 		"IEC958 out", "i2s mixer out", "IEC958 in", "i2s in", "AC97 in", "SRC out"
138 	};
139 
140 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
141 	uinfo->count = 1;
142 	uinfo->value.enumerated.items = 6;
143 	if (uinfo->value.enumerated.item > 5)
144                 uinfo->value.enumerated.item = 5;
145 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
146 	return 0;
147 }
148 
149 static int snd_ca0106_capture_source_get(struct snd_kcontrol *kcontrol,
150 					struct snd_ctl_elem_value *ucontrol)
151 {
152 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
153 
154 	ucontrol->value.enumerated.item[0] = emu->capture_source;
155 	return 0;
156 }
157 
158 static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
159 					struct snd_ctl_elem_value *ucontrol)
160 {
161 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
162 	unsigned int val;
163 	int change = 0;
164 	u32 mask;
165 	u32 source;
166 
167 	val = ucontrol->value.enumerated.item[0] ;
168 	change = (emu->capture_source != val);
169 	if (change) {
170 		emu->capture_source = val;
171 		source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
172 		mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
173 		snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
174 	}
175         return change;
176 }
177 
178 static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
179 					  struct snd_ctl_elem_info *uinfo)
180 {
181 	static char *texts[6] = {
182 		"Phone", "Mic", "Line in", "Aux"
183 	};
184 
185 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
186 	uinfo->count = 1;
187 	uinfo->value.enumerated.items = 4;
188 	if (uinfo->value.enumerated.item > 3)
189                 uinfo->value.enumerated.item = 3;
190 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
191 	return 0;
192 }
193 
194 static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol *kcontrol,
195 					struct snd_ctl_elem_value *ucontrol)
196 {
197 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
198 
199 	ucontrol->value.enumerated.item[0] = emu->i2c_capture_source;
200 	return 0;
201 }
202 
203 static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
204 					struct snd_ctl_elem_value *ucontrol)
205 {
206 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
207 	unsigned int source_id;
208 	unsigned int ngain, ogain;
209 	int change = 0;
210 	u32 source;
211 	/* If the capture source has changed,
212 	 * update the capture volume from the cached value
213 	 * for the particular source.
214 	 */
215 	source_id = ucontrol->value.enumerated.item[0] ;
216 	change = (emu->i2c_capture_source != source_id);
217 	if (change) {
218 		snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
219 		ngain = emu->i2c_capture_volume[source_id][0]; /* Left */
220 		ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
221 		if (ngain != ogain)
222 			snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff));
223 		ngain = emu->i2c_capture_volume[source_id][1]; /* Left */
224 		ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Left */
225 		if (ngain != ogain)
226 			snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
227 		source = 1 << source_id;
228 		snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
229 		emu->i2c_capture_source = source_id;
230 	}
231         return change;
232 }
233 
234 static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol *kcontrol,
235 					       struct snd_ctl_elem_info *uinfo)
236 {
237 	static char *texts[2] = { "Side out", "Line in" };
238 
239 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
240 	uinfo->count = 1;
241 	uinfo->value.enumerated.items = 2;
242 	if (uinfo->value.enumerated.item > 1)
243                 uinfo->value.enumerated.item = 1;
244 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
245 	return 0;
246 }
247 
248 static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol,
249 					       struct snd_ctl_elem_info *uinfo)
250 {
251 	static char *texts[2] = { "Line in", "Mic in" };
252 
253 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
254 	uinfo->count = 1;
255 	uinfo->value.enumerated.items = 2;
256 	if (uinfo->value.enumerated.item > 1)
257                 uinfo->value.enumerated.item = 1;
258 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
259 	return 0;
260 }
261 
262 static int snd_ca0106_capture_mic_line_in_get(struct snd_kcontrol *kcontrol,
263 					struct snd_ctl_elem_value *ucontrol)
264 {
265 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
266 
267 	ucontrol->value.enumerated.item[0] = emu->capture_mic_line_in;
268 	return 0;
269 }
270 
271 static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
272 					struct snd_ctl_elem_value *ucontrol)
273 {
274 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
275 	unsigned int val;
276 	int change = 0;
277 	u32 tmp;
278 
279 	val = ucontrol->value.enumerated.item[0] ;
280 	change = (emu->capture_mic_line_in != val);
281 	if (change) {
282 		emu->capture_mic_line_in = val;
283 		if (val) {
284 			//snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
285 			tmp = inl(emu->port+GPIO) & ~0x400;
286 			tmp = tmp | 0x400;
287 			outl(tmp, emu->port+GPIO);
288 			//snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC);
289 		} else {
290 			//snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
291 			tmp = inl(emu->port+GPIO) & ~0x400;
292 			outl(tmp, emu->port+GPIO);
293 			//snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN);
294 		}
295 	}
296         return change;
297 }
298 
299 static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in __devinitdata =
300 {
301 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
302 	.name =		"Shared Mic/Line in Capture Switch",
303 	.info =		snd_ca0106_capture_mic_line_in_info,
304 	.get =		snd_ca0106_capture_mic_line_in_get,
305 	.put =		snd_ca0106_capture_mic_line_in_put
306 };
307 
308 static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out __devinitdata =
309 {
310 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
311 	.name =		"Shared Line in/Side out Capture Switch",
312 	.info =		snd_ca0106_capture_line_in_side_out_info,
313 	.get =		snd_ca0106_capture_mic_line_in_get,
314 	.put =		snd_ca0106_capture_mic_line_in_put
315 };
316 
317 
318 static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
319 				 struct snd_ctl_elem_info *uinfo)
320 {
321 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
322 	uinfo->count = 1;
323 	return 0;
324 }
325 
326 static int snd_ca0106_spdif_get(struct snd_kcontrol *kcontrol,
327                                  struct snd_ctl_elem_value *ucontrol)
328 {
329 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
330 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
331 
332 	ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
333 	ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
334 	ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
335 	ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
336         return 0;
337 }
338 
339 static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol,
340 				      struct snd_ctl_elem_value *ucontrol)
341 {
342 	ucontrol->value.iec958.status[0] = 0xff;
343 	ucontrol->value.iec958.status[1] = 0xff;
344 	ucontrol->value.iec958.status[2] = 0xff;
345 	ucontrol->value.iec958.status[3] = 0xff;
346         return 0;
347 }
348 
349 static int snd_ca0106_spdif_put(struct snd_kcontrol *kcontrol,
350                                  struct snd_ctl_elem_value *ucontrol)
351 {
352 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
353 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
354 	int change;
355 	unsigned int val;
356 
357 	val = (ucontrol->value.iec958.status[0] << 0) |
358 	      (ucontrol->value.iec958.status[1] << 8) |
359 	      (ucontrol->value.iec958.status[2] << 16) |
360 	      (ucontrol->value.iec958.status[3] << 24);
361 	change = val != emu->spdif_bits[idx];
362 	if (change) {
363 		snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, val);
364 		emu->spdif_bits[idx] = val;
365 	}
366         return change;
367 }
368 
369 static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol,
370 				  struct snd_ctl_elem_info *uinfo)
371 {
372         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
373         uinfo->count = 2;
374         uinfo->value.integer.min = 0;
375         uinfo->value.integer.max = 255;
376         return 0;
377 }
378 
379 static int snd_ca0106_volume_get(struct snd_kcontrol *kcontrol,
380 				 struct snd_ctl_elem_value *ucontrol)
381 {
382         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
383         unsigned int value;
384 	int channel_id, reg;
385 
386 	channel_id = (kcontrol->private_value >> 8) & 0xff;
387 	reg = kcontrol->private_value & 0xff;
388 
389         value = snd_ca0106_ptr_read(emu, reg, channel_id);
390         ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
391         ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
392         return 0;
393 }
394 
395 static int snd_ca0106_volume_put(struct snd_kcontrol *kcontrol,
396 				 struct snd_ctl_elem_value *ucontrol)
397 {
398         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
399         unsigned int oval, nval;
400 	int channel_id, reg;
401 
402 	channel_id = (kcontrol->private_value >> 8) & 0xff;
403 	reg = kcontrol->private_value & 0xff;
404 
405 	oval = snd_ca0106_ptr_read(emu, reg, channel_id);
406 	nval = ((0xff - ucontrol->value.integer.value[0]) << 24) |
407 		((0xff - ucontrol->value.integer.value[1]) << 16);
408         nval |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
409 		((0xff - ucontrol->value.integer.value[1]) );
410 	if (oval == nval)
411 		return 0;
412 	snd_ca0106_ptr_write(emu, reg, channel_id, nval);
413 	return 1;
414 }
415 
416 static int snd_ca0106_i2c_volume_info(struct snd_kcontrol *kcontrol,
417 				  struct snd_ctl_elem_info *uinfo)
418 {
419         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
420         uinfo->count = 2;
421         uinfo->value.integer.min = 0;
422         uinfo->value.integer.max = 255;
423         return 0;
424 }
425 
426 static int snd_ca0106_i2c_volume_get(struct snd_kcontrol *kcontrol,
427 				 struct snd_ctl_elem_value *ucontrol)
428 {
429         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
430 	int source_id;
431 
432 	source_id = kcontrol->private_value;
433 
434         ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0];
435         ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1];
436         return 0;
437 }
438 
439 static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
440 				 struct snd_ctl_elem_value *ucontrol)
441 {
442         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
443         unsigned int ogain;
444         unsigned int ngain;
445 	int source_id;
446 	int change = 0;
447 
448 	source_id = kcontrol->private_value;
449 	ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
450 	ngain = ucontrol->value.integer.value[0];
451 	if (ngain > 0xff)
452 		return 0;
453 	if (ogain != ngain) {
454 		if (emu->i2c_capture_source == source_id)
455 			snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
456 		emu->i2c_capture_volume[source_id][0] = ucontrol->value.integer.value[0];
457 		change = 1;
458 	}
459 	ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
460 	ngain = ucontrol->value.integer.value[1];
461 	if (ngain > 0xff)
462 		return 0;
463 	if (ogain != ngain) {
464 		if (emu->i2c_capture_source == source_id)
465 			snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
466 		emu->i2c_capture_volume[source_id][1] = ucontrol->value.integer.value[1];
467 		change = 1;
468 	}
469 
470 	return change;
471 }
472 
473 #define CA_VOLUME(xname,chid,reg) \
474 {								\
475 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\
476 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |		\
477 	          SNDRV_CTL_ELEM_ACCESS_TLV_READ,		\
478 	.info =	 snd_ca0106_volume_info,			\
479 	.get =   snd_ca0106_volume_get,				\
480 	.put =   snd_ca0106_volume_put,				\
481 	.tlv = { .p = snd_ca0106_db_scale1 },			\
482 	.private_value = ((chid) << 8) | (reg)			\
483 }
484 
485 static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
486 	CA_VOLUME("Analog Front Playback Volume",
487 		  CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2),
488         CA_VOLUME("Analog Rear Playback Volume",
489 		  CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2),
490 	CA_VOLUME("Analog Center/LFE Playback Volume",
491 		  CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2),
492         CA_VOLUME("Analog Side Playback Volume",
493 		  CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2),
494 
495         CA_VOLUME("IEC958 Front Playback Volume",
496 		  CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1),
497 	CA_VOLUME("IEC958 Rear Playback Volume",
498 		  CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1),
499 	CA_VOLUME("IEC958 Center/LFE Playback Volume",
500 		  CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1),
501 	CA_VOLUME("IEC958 Unknown Playback Volume",
502 		  CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1),
503 
504         CA_VOLUME("CAPTURE feedback Playback Volume",
505 		  1, CAPTURE_CONTROL),
506 
507 	{
508 		.access =	SNDRV_CTL_ELEM_ACCESS_READ,
509 		.iface =        SNDRV_CTL_ELEM_IFACE_PCM,
510 		.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
511 		.count =	4,
512 		.info =         snd_ca0106_spdif_info,
513 		.get =          snd_ca0106_spdif_get_mask
514 	},
515 	{
516 		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
517 		.name =		"IEC958 Playback Switch",
518 		.info =		snd_ca0106_shared_spdif_info,
519 		.get =		snd_ca0106_shared_spdif_get,
520 		.put =		snd_ca0106_shared_spdif_put
521 	},
522 	{
523 		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
524 		.name =		"Digital Source Capture Enum",
525 		.info =		snd_ca0106_capture_source_info,
526 		.get =		snd_ca0106_capture_source_get,
527 		.put =		snd_ca0106_capture_source_put
528 	},
529 	{
530 		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
531 		.name =		"Analog Source Capture Enum",
532 		.info =		snd_ca0106_i2c_capture_source_info,
533 		.get =		snd_ca0106_i2c_capture_source_get,
534 		.put =		snd_ca0106_i2c_capture_source_put
535 	},
536 	{
537 		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
538 		.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
539 		.count =	4,
540 		.info =         snd_ca0106_spdif_info,
541 		.get =          snd_ca0106_spdif_get,
542 		.put =          snd_ca0106_spdif_put
543 	},
544 };
545 
546 #define I2C_VOLUME(xname,chid) \
547 {								\
548 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\
549 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |		\
550 	          SNDRV_CTL_ELEM_ACCESS_TLV_READ,		\
551 	.info =  snd_ca0106_i2c_volume_info,			\
552 	.get =   snd_ca0106_i2c_volume_get,			\
553 	.put =   snd_ca0106_i2c_volume_put,			\
554 	.tlv = { .p = snd_ca0106_db_scale2 },			\
555 	.private_value = chid					\
556 }
557 
558 static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] __devinitdata = {
559         I2C_VOLUME("Phone Capture Volume", 0),
560         I2C_VOLUME("Mic Capture Volume", 1),
561         I2C_VOLUME("Line in Capture Volume", 2),
562         I2C_VOLUME("Aux Capture Volume", 3),
563 };
564 
565 static int __devinit remove_ctl(struct snd_card *card, const char *name)
566 {
567 	struct snd_ctl_elem_id id;
568 	memset(&id, 0, sizeof(id));
569 	strcpy(id.name, name);
570 	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
571 	return snd_ctl_remove_id(card, &id);
572 }
573 
574 static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card, const char *name)
575 {
576 	struct snd_ctl_elem_id sid;
577 	memset(&sid, 0, sizeof(sid));
578 	/* FIXME: strcpy is bad. */
579 	strcpy(sid.name, name);
580 	sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
581 	return snd_ctl_find_id(card, &sid);
582 }
583 
584 static int __devinit rename_ctl(struct snd_card *card, const char *src, const char *dst)
585 {
586 	struct snd_kcontrol *kctl = ctl_find(card, src);
587 	if (kctl) {
588 		strcpy(kctl->id.name, dst);
589 		return 0;
590 	}
591 	return -ENOENT;
592 }
593 
594 int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
595 {
596 	int i, err;
597         struct snd_card *card = emu->card;
598 	char **c;
599 	static char *ca0106_remove_ctls[] = {
600 		"Master Mono Playback Switch",
601 		"Master Mono Playback Volume",
602 		"3D Control - Switch",
603 		"3D Control Sigmatel - Depth",
604 		"PCM Playback Switch",
605 		"PCM Playback Volume",
606 		"CD Playback Switch",
607 		"CD Playback Volume",
608 		"Phone Playback Switch",
609 		"Phone Playback Volume",
610 		"Video Playback Switch",
611 		"Video Playback Volume",
612 		"PC Speaker Playback Switch",
613 		"PC Speaker Playback Volume",
614 		"Mono Output Select",
615 		"Capture Source",
616 		"Capture Switch",
617 		"Capture Volume",
618 		"External Amplifier",
619 		"Sigmatel 4-Speaker Stereo Playback Switch",
620 		"Sigmatel Surround Phase Inversion Playback ",
621 		NULL
622 	};
623 	static char *ca0106_rename_ctls[] = {
624 		"Master Playback Switch", "Capture Switch",
625 		"Master Playback Volume", "Capture Volume",
626 		"Line Playback Switch", "AC97 Line Capture Switch",
627 		"Line Playback Volume", "AC97 Line Capture Volume",
628 		"Aux Playback Switch", "AC97 Aux Capture Switch",
629 		"Aux Playback Volume", "AC97 Aux Capture Volume",
630 		"Mic Playback Switch", "AC97 Mic Capture Switch",
631 		"Mic Playback Volume", "AC97 Mic Capture Volume",
632 		"Mic Select", "AC97 Mic Select",
633 		"Mic Boost (+20dB)", "AC97 Mic Boost (+20dB)",
634 		NULL
635 	};
636 #if 1
637 	for (c = ca0106_remove_ctls; *c; c++)
638 		remove_ctl(card, *c);
639 	for (c = ca0106_rename_ctls; *c; c += 2)
640 		rename_ctl(card, c[0], c[1]);
641 #endif
642 
643 	for (i = 0; i < ARRAY_SIZE(snd_ca0106_volume_ctls); i++) {
644 		err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_volume_ctls[i], emu));
645 		if (err < 0)
646 			return err;
647 	}
648 	if (emu->details->i2c_adc == 1) {
649 		for (i = 0; i < ARRAY_SIZE(snd_ca0106_volume_i2c_adc_ctls); i++) {
650 			err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_volume_i2c_adc_ctls[i], emu));
651 			if (err < 0)
652 				return err;
653 		}
654 		if (emu->details->gpio_type == 1)
655 			err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu));
656 		else  /* gpio_type == 2 */
657 			err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_line_in_side_out, emu));
658 		if (err < 0)
659 			return err;
660 	}
661         return 0;
662 }
663 
664