xref: /openbmc/linux/sound/pci/ca0106/ca0106_mixer.c (revision 643d1f7f)
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.18
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  *  0.0.18
43  *    Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
44  *
45  *  This code was initally based on code from ALSA's emu10k1x.c which is:
46  *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
47  *
48  *   This program is free software; you can redistribute it and/or modify
49  *   it under the terms of the GNU General Public License as published by
50  *   the Free Software Foundation; either version 2 of the License, or
51  *   (at your option) any later version.
52  *
53  *   This program is distributed in the hope that it will be useful,
54  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
55  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
56  *   GNU General Public License for more details.
57  *
58  *   You should have received a copy of the GNU General Public License
59  *   along with this program; if not, write to the Free Software
60  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
61  *
62  */
63 #include <linux/delay.h>
64 #include <linux/init.h>
65 #include <linux/interrupt.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 #include <asm/io.h>
75 
76 #include "ca0106.h"
77 
78 static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1);
79 static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1);
80 
81 #define snd_ca0106_shared_spdif_info	snd_ctl_boolean_mono_info
82 
83 static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol,
84 					struct snd_ctl_elem_value *ucontrol)
85 {
86 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
87 
88 	ucontrol->value.integer.value[0] = emu->spdif_enable;
89 	return 0;
90 }
91 
92 static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
93 					struct snd_ctl_elem_value *ucontrol)
94 {
95 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
96 	unsigned int val;
97 	int change = 0;
98 	u32 mask;
99 
100 	val = !!ucontrol->value.integer.value[0];
101 	change = (emu->spdif_enable != val);
102 	if (change) {
103 		emu->spdif_enable = val;
104 		if (val) {
105 			/* Digital */
106 			snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
107 			snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
108 			snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0,
109 				snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000);
110 			mask = inl(emu->port + GPIO) & ~0x101;
111 			outl(mask, emu->port + GPIO);
112 
113 		} else {
114 			/* Analog */
115 			snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
116 			snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
117 			snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0,
118 				snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000);
119 			mask = inl(emu->port + GPIO) | 0x101;
120 			outl(mask, emu->port + GPIO);
121 		}
122 	}
123         return change;
124 }
125 
126 static int snd_ca0106_capture_source_info(struct snd_kcontrol *kcontrol,
127 					  struct snd_ctl_elem_info *uinfo)
128 {
129 	static char *texts[6] = {
130 		"IEC958 out", "i2s mixer out", "IEC958 in", "i2s in", "AC97 in", "SRC out"
131 	};
132 
133 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
134 	uinfo->count = 1;
135 	uinfo->value.enumerated.items = 6;
136 	if (uinfo->value.enumerated.item > 5)
137                 uinfo->value.enumerated.item = 5;
138 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
139 	return 0;
140 }
141 
142 static int snd_ca0106_capture_source_get(struct snd_kcontrol *kcontrol,
143 					struct snd_ctl_elem_value *ucontrol)
144 {
145 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
146 
147 	ucontrol->value.enumerated.item[0] = emu->capture_source;
148 	return 0;
149 }
150 
151 static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
152 					struct snd_ctl_elem_value *ucontrol)
153 {
154 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
155 	unsigned int val;
156 	int change = 0;
157 	u32 mask;
158 	u32 source;
159 
160 	val = ucontrol->value.enumerated.item[0] ;
161 	if (val >= 6)
162 		return -EINVAL;
163 	change = (emu->capture_source != val);
164 	if (change) {
165 		emu->capture_source = val;
166 		source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
167 		mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
168 		snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
169 	}
170         return change;
171 }
172 
173 static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
174 					  struct snd_ctl_elem_info *uinfo)
175 {
176 	static char *texts[6] = {
177 		"Phone", "Mic", "Line in", "Aux"
178 	};
179 
180 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
181 	uinfo->count = 1;
182 	uinfo->value.enumerated.items = 4;
183 	if (uinfo->value.enumerated.item > 3)
184                 uinfo->value.enumerated.item = 3;
185 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
186 	return 0;
187 }
188 
189 static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol *kcontrol,
190 					struct snd_ctl_elem_value *ucontrol)
191 {
192 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
193 
194 	ucontrol->value.enumerated.item[0] = emu->i2c_capture_source;
195 	return 0;
196 }
197 
198 static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
199 					struct snd_ctl_elem_value *ucontrol)
200 {
201 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
202 	unsigned int source_id;
203 	unsigned int ngain, ogain;
204 	int change = 0;
205 	u32 source;
206 	/* If the capture source has changed,
207 	 * update the capture volume from the cached value
208 	 * for the particular source.
209 	 */
210 	source_id = ucontrol->value.enumerated.item[0] ;
211 	if (source_id >= 4)
212 		return -EINVAL;
213 	change = (emu->i2c_capture_source != source_id);
214 	if (change) {
215 		snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
216 		ngain = emu->i2c_capture_volume[source_id][0]; /* Left */
217 		ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
218 		if (ngain != ogain)
219 			snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff));
220 		ngain = emu->i2c_capture_volume[source_id][1]; /* Left */
221 		ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Left */
222 		if (ngain != ogain)
223 			snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
224 		source = 1 << source_id;
225 		snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
226 		emu->i2c_capture_source = source_id;
227 	}
228         return change;
229 }
230 
231 static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol *kcontrol,
232 					       struct snd_ctl_elem_info *uinfo)
233 {
234 	static char *texts[2] = { "Side out", "Line in" };
235 
236 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
237 	uinfo->count = 1;
238 	uinfo->value.enumerated.items = 2;
239 	if (uinfo->value.enumerated.item > 1)
240                 uinfo->value.enumerated.item = 1;
241 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
242 	return 0;
243 }
244 
245 static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol,
246 					       struct snd_ctl_elem_info *uinfo)
247 {
248 	static char *texts[2] = { "Line in", "Mic in" };
249 
250 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
251 	uinfo->count = 1;
252 	uinfo->value.enumerated.items = 2;
253 	if (uinfo->value.enumerated.item > 1)
254                 uinfo->value.enumerated.item = 1;
255 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
256 	return 0;
257 }
258 
259 static int snd_ca0106_capture_mic_line_in_get(struct snd_kcontrol *kcontrol,
260 					struct snd_ctl_elem_value *ucontrol)
261 {
262 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
263 
264 	ucontrol->value.enumerated.item[0] = emu->capture_mic_line_in;
265 	return 0;
266 }
267 
268 static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
269 					struct snd_ctl_elem_value *ucontrol)
270 {
271 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
272 	unsigned int val;
273 	int change = 0;
274 	u32 tmp;
275 
276 	val = ucontrol->value.enumerated.item[0] ;
277 	if (val > 1)
278 		return -EINVAL;
279 	change = (emu->capture_mic_line_in != val);
280 	if (change) {
281 		emu->capture_mic_line_in = val;
282 		if (val) {
283 			//snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
284 			tmp = inl(emu->port+GPIO) & ~0x400;
285 			tmp = tmp | 0x400;
286 			outl(tmp, emu->port+GPIO);
287 			//snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC);
288 		} else {
289 			//snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
290 			tmp = inl(emu->port+GPIO) & ~0x400;
291 			outl(tmp, emu->port+GPIO);
292 			//snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN);
293 		}
294 	}
295         return change;
296 }
297 
298 static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in __devinitdata =
299 {
300 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
301 	.name =		"Shared Mic/Line in Capture Switch",
302 	.info =		snd_ca0106_capture_mic_line_in_info,
303 	.get =		snd_ca0106_capture_mic_line_in_get,
304 	.put =		snd_ca0106_capture_mic_line_in_put
305 };
306 
307 static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out __devinitdata =
308 {
309 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
310 	.name =		"Shared Line in/Side out Capture Switch",
311 	.info =		snd_ca0106_capture_line_in_side_out_info,
312 	.get =		snd_ca0106_capture_mic_line_in_get,
313 	.put =		snd_ca0106_capture_mic_line_in_put
314 };
315 
316 
317 static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
318 				 struct snd_ctl_elem_info *uinfo)
319 {
320 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
321 	uinfo->count = 1;
322 	return 0;
323 }
324 
325 static int snd_ca0106_spdif_get(struct snd_kcontrol *kcontrol,
326                                  struct snd_ctl_elem_value *ucontrol)
327 {
328 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
329 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
330 
331 	ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
332 	ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
333 	ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
334 	ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
335         return 0;
336 }
337 
338 static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol,
339 				      struct snd_ctl_elem_value *ucontrol)
340 {
341 	ucontrol->value.iec958.status[0] = 0xff;
342 	ucontrol->value.iec958.status[1] = 0xff;
343 	ucontrol->value.iec958.status[2] = 0xff;
344 	ucontrol->value.iec958.status[3] = 0xff;
345         return 0;
346 }
347 
348 static int snd_ca0106_spdif_put(struct snd_kcontrol *kcontrol,
349                                  struct snd_ctl_elem_value *ucontrol)
350 {
351 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
352 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
353 	int change;
354 	unsigned int val;
355 
356 	val = (ucontrol->value.iec958.status[0] << 0) |
357 	      (ucontrol->value.iec958.status[1] << 8) |
358 	      (ucontrol->value.iec958.status[2] << 16) |
359 	      (ucontrol->value.iec958.status[3] << 24);
360 	change = val != emu->spdif_bits[idx];
361 	if (change) {
362 		snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, val);
363 		emu->spdif_bits[idx] = val;
364 	}
365         return change;
366 }
367 
368 static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol,
369 				  struct snd_ctl_elem_info *uinfo)
370 {
371         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
372         uinfo->count = 2;
373         uinfo->value.integer.min = 0;
374         uinfo->value.integer.max = 255;
375         return 0;
376 }
377 
378 static int snd_ca0106_volume_get(struct snd_kcontrol *kcontrol,
379 				 struct snd_ctl_elem_value *ucontrol)
380 {
381         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
382         unsigned int value;
383 	int channel_id, reg;
384 
385 	channel_id = (kcontrol->private_value >> 8) & 0xff;
386 	reg = kcontrol->private_value & 0xff;
387 
388         value = snd_ca0106_ptr_read(emu, reg, channel_id);
389         ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
390         ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
391         return 0;
392 }
393 
394 static int snd_ca0106_volume_put(struct snd_kcontrol *kcontrol,
395 				 struct snd_ctl_elem_value *ucontrol)
396 {
397         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
398         unsigned int oval, nval;
399 	int channel_id, reg;
400 
401 	channel_id = (kcontrol->private_value >> 8) & 0xff;
402 	reg = kcontrol->private_value & 0xff;
403 
404 	oval = snd_ca0106_ptr_read(emu, reg, channel_id);
405 	nval = ((0xff - ucontrol->value.integer.value[0]) << 24) |
406 		((0xff - ucontrol->value.integer.value[1]) << 16);
407         nval |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
408 		((0xff - ucontrol->value.integer.value[1]) );
409 	if (oval == nval)
410 		return 0;
411 	snd_ca0106_ptr_write(emu, reg, channel_id, nval);
412 	return 1;
413 }
414 
415 static int snd_ca0106_i2c_volume_info(struct snd_kcontrol *kcontrol,
416 				  struct snd_ctl_elem_info *uinfo)
417 {
418         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
419         uinfo->count = 2;
420         uinfo->value.integer.min = 0;
421         uinfo->value.integer.max = 255;
422         return 0;
423 }
424 
425 static int snd_ca0106_i2c_volume_get(struct snd_kcontrol *kcontrol,
426 				 struct snd_ctl_elem_value *ucontrol)
427 {
428         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
429 	int source_id;
430 
431 	source_id = kcontrol->private_value;
432 
433         ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0];
434         ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1];
435         return 0;
436 }
437 
438 static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
439 				 struct snd_ctl_elem_value *ucontrol)
440 {
441         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
442         unsigned int ogain;
443         unsigned int ngain;
444 	int source_id;
445 	int change = 0;
446 
447 	source_id = kcontrol->private_value;
448 	ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
449 	ngain = ucontrol->value.integer.value[0];
450 	if (ngain > 0xff)
451 		return -EINVAL;
452 	if (ogain != ngain) {
453 		if (emu->i2c_capture_source == source_id)
454 			snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
455 		emu->i2c_capture_volume[source_id][0] = ucontrol->value.integer.value[0];
456 		change = 1;
457 	}
458 	ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
459 	ngain = ucontrol->value.integer.value[1];
460 	if (ngain > 0xff)
461 		return -EINVAL;
462 	if (ogain != ngain) {
463 		if (emu->i2c_capture_source == source_id)
464 			snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
465 		emu->i2c_capture_volume[source_id][1] = ucontrol->value.integer.value[1];
466 		change = 1;
467 	}
468 
469 	return change;
470 }
471 
472 #define spi_mute_info	snd_ctl_boolean_mono_info
473 
474 static int spi_mute_get(struct snd_kcontrol *kcontrol,
475 			struct snd_ctl_elem_value *ucontrol)
476 {
477 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
478 	unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
479 	unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
480 
481 	ucontrol->value.integer.value[0] = !(emu->spi_dac_reg[reg] & bit);
482 	return 0;
483 }
484 
485 static int spi_mute_put(struct snd_kcontrol *kcontrol,
486 			struct snd_ctl_elem_value *ucontrol)
487 {
488 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
489 	unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
490 	unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
491 	int ret;
492 
493 	ret = emu->spi_dac_reg[reg] & bit;
494 	if (ucontrol->value.integer.value[0]) {
495 		if (!ret)	/* bit already cleared, do nothing */
496 			return 0;
497 		emu->spi_dac_reg[reg] &= ~bit;
498 	} else {
499 		if (ret)	/* bit already set, do nothing */
500 			return 0;
501 		emu->spi_dac_reg[reg] |= bit;
502 	}
503 
504 	ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]);
505 	return ret ? -EINVAL : 1;
506 }
507 
508 #define CA_VOLUME(xname,chid,reg) \
509 {								\
510 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\
511 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |		\
512 	          SNDRV_CTL_ELEM_ACCESS_TLV_READ,		\
513 	.info =	 snd_ca0106_volume_info,			\
514 	.get =   snd_ca0106_volume_get,				\
515 	.put =   snd_ca0106_volume_put,				\
516 	.tlv = { .p = snd_ca0106_db_scale1 },			\
517 	.private_value = ((chid) << 8) | (reg)			\
518 }
519 
520 static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
521 	CA_VOLUME("Analog Front Playback Volume",
522 		  CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2),
523         CA_VOLUME("Analog Rear Playback Volume",
524 		  CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2),
525 	CA_VOLUME("Analog Center/LFE Playback Volume",
526 		  CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2),
527         CA_VOLUME("Analog Side Playback Volume",
528 		  CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2),
529 
530         CA_VOLUME("IEC958 Front Playback Volume",
531 		  CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1),
532 	CA_VOLUME("IEC958 Rear Playback Volume",
533 		  CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1),
534 	CA_VOLUME("IEC958 Center/LFE Playback Volume",
535 		  CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1),
536 	CA_VOLUME("IEC958 Unknown Playback Volume",
537 		  CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1),
538 
539         CA_VOLUME("CAPTURE feedback Playback Volume",
540 		  1, CAPTURE_CONTROL),
541 
542 	{
543 		.access =	SNDRV_CTL_ELEM_ACCESS_READ,
544 		.iface =        SNDRV_CTL_ELEM_IFACE_PCM,
545 		.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
546 		.count =	4,
547 		.info =         snd_ca0106_spdif_info,
548 		.get =          snd_ca0106_spdif_get_mask
549 	},
550 	{
551 		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
552 		.name =		"IEC958 Playback Switch",
553 		.info =		snd_ca0106_shared_spdif_info,
554 		.get =		snd_ca0106_shared_spdif_get,
555 		.put =		snd_ca0106_shared_spdif_put
556 	},
557 	{
558 		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
559 		.name =		"Digital Source Capture Enum",
560 		.info =		snd_ca0106_capture_source_info,
561 		.get =		snd_ca0106_capture_source_get,
562 		.put =		snd_ca0106_capture_source_put
563 	},
564 	{
565 		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
566 		.name =		"Analog Source Capture Enum",
567 		.info =		snd_ca0106_i2c_capture_source_info,
568 		.get =		snd_ca0106_i2c_capture_source_get,
569 		.put =		snd_ca0106_i2c_capture_source_put
570 	},
571 	{
572 		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
573 		.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
574 		.count =	4,
575 		.info =         snd_ca0106_spdif_info,
576 		.get =          snd_ca0106_spdif_get,
577 		.put =          snd_ca0106_spdif_put
578 	},
579 };
580 
581 #define I2C_VOLUME(xname,chid) \
582 {								\
583 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\
584 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |		\
585 	          SNDRV_CTL_ELEM_ACCESS_TLV_READ,		\
586 	.info =  snd_ca0106_i2c_volume_info,			\
587 	.get =   snd_ca0106_i2c_volume_get,			\
588 	.put =   snd_ca0106_i2c_volume_put,			\
589 	.tlv = { .p = snd_ca0106_db_scale2 },			\
590 	.private_value = chid					\
591 }
592 
593 static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] __devinitdata = {
594         I2C_VOLUME("Phone Capture Volume", 0),
595         I2C_VOLUME("Mic Capture Volume", 1),
596         I2C_VOLUME("Line in Capture Volume", 2),
597         I2C_VOLUME("Aux Capture Volume", 3),
598 };
599 
600 #define SPI_SWITCH(xname,reg,bit) \
601 {								\
602 	.iface	= SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\
603 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,		\
604 	.info	= spi_mute_info,				\
605 	.get	= spi_mute_get,					\
606 	.put	= spi_mute_put,					\
607 	.private_value = (reg<<SPI_REG_SHIFT) | (bit)		\
608 }
609 
610 static struct snd_kcontrol_new snd_ca0106_volume_spi_dac_ctls[]
611 __devinitdata = {
612 	SPI_SWITCH("Analog Front Playback Switch",
613 		   SPI_DMUTE4_REG, SPI_DMUTE4_BIT),
614 	SPI_SWITCH("Analog Rear Playback Switch",
615 		   SPI_DMUTE0_REG, SPI_DMUTE0_BIT),
616 	SPI_SWITCH("Analog Center/LFE Playback Switch",
617 		   SPI_DMUTE2_REG, SPI_DMUTE2_BIT),
618 	SPI_SWITCH("Analog Side Playback Switch",
619 		   SPI_DMUTE1_REG, SPI_DMUTE1_BIT),
620 };
621 
622 static int __devinit remove_ctl(struct snd_card *card, const char *name)
623 {
624 	struct snd_ctl_elem_id id;
625 	memset(&id, 0, sizeof(id));
626 	strcpy(id.name, name);
627 	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
628 	return snd_ctl_remove_id(card, &id);
629 }
630 
631 static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card, const char *name)
632 {
633 	struct snd_ctl_elem_id sid;
634 	memset(&sid, 0, sizeof(sid));
635 	/* FIXME: strcpy is bad. */
636 	strcpy(sid.name, name);
637 	sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
638 	return snd_ctl_find_id(card, &sid);
639 }
640 
641 static int __devinit rename_ctl(struct snd_card *card, const char *src, const char *dst)
642 {
643 	struct snd_kcontrol *kctl = ctl_find(card, src);
644 	if (kctl) {
645 		strcpy(kctl->id.name, dst);
646 		return 0;
647 	}
648 	return -ENOENT;
649 }
650 
651 #define ADD_CTLS(emu, ctls)						\
652 	do {								\
653 		int i, err;						\
654 		for (i = 0; i < ARRAY_SIZE(ctls); i++) {		\
655 			err = snd_ctl_add(card, snd_ctl_new1(&ctls[i], emu)); \
656 			if (err < 0)					\
657 				return err;				\
658 		}							\
659 	} while (0)
660 
661 int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
662 {
663 	int err;
664         struct snd_card *card = emu->card;
665 	char **c;
666 	static char *ca0106_remove_ctls[] = {
667 		"Master Mono Playback Switch",
668 		"Master Mono Playback Volume",
669 		"3D Control - Switch",
670 		"3D Control Sigmatel - Depth",
671 		"PCM Playback Switch",
672 		"PCM Playback Volume",
673 		"CD Playback Switch",
674 		"CD Playback Volume",
675 		"Phone Playback Switch",
676 		"Phone Playback Volume",
677 		"Video Playback Switch",
678 		"Video Playback Volume",
679 		"PC Speaker Playback Switch",
680 		"PC Speaker Playback Volume",
681 		"Mono Output Select",
682 		"Capture Source",
683 		"Capture Switch",
684 		"Capture Volume",
685 		"External Amplifier",
686 		"Sigmatel 4-Speaker Stereo Playback Switch",
687 		"Sigmatel Surround Phase Inversion Playback ",
688 		NULL
689 	};
690 	static char *ca0106_rename_ctls[] = {
691 		"Master Playback Switch", "Capture Switch",
692 		"Master Playback Volume", "Capture Volume",
693 		"Line Playback Switch", "AC97 Line Capture Switch",
694 		"Line Playback Volume", "AC97 Line Capture Volume",
695 		"Aux Playback Switch", "AC97 Aux Capture Switch",
696 		"Aux Playback Volume", "AC97 Aux Capture Volume",
697 		"Mic Playback Switch", "AC97 Mic Capture Switch",
698 		"Mic Playback Volume", "AC97 Mic Capture Volume",
699 		"Mic Select", "AC97 Mic Select",
700 		"Mic Boost (+20dB)", "AC97 Mic Boost (+20dB)",
701 		NULL
702 	};
703 #if 1
704 	for (c = ca0106_remove_ctls; *c; c++)
705 		remove_ctl(card, *c);
706 	for (c = ca0106_rename_ctls; *c; c += 2)
707 		rename_ctl(card, c[0], c[1]);
708 #endif
709 
710 	ADD_CTLS(emu, snd_ca0106_volume_ctls);
711 	if (emu->details->i2c_adc == 1) {
712 		ADD_CTLS(emu, snd_ca0106_volume_i2c_adc_ctls);
713 		if (emu->details->gpio_type == 1)
714 			err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu));
715 		else  /* gpio_type == 2 */
716 			err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_line_in_side_out, emu));
717 		if (err < 0)
718 			return err;
719 	}
720 	if (emu->details->spi_dac == 1)
721 		ADD_CTLS(emu, snd_ca0106_volume_spi_dac_ctls);
722         return 0;
723 }
724 
725