xref: /openbmc/linux/sound/pci/ca0106/ca0106_mixer.c (revision b8bb76713ec50df2f11efee386e16f93d51e1076)
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 void ca0106_spdif_enable(struct snd_ca0106 *emu)
79 {
80 	unsigned int val;
81 
82 	if (emu->spdif_enable) {
83 		/* Digital */
84 		snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
85 		snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
86 		val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000;
87 		snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
88 		val = inl(emu->port + GPIO) & ~0x101;
89 		outl(val, emu->port + GPIO);
90 
91 	} else {
92 		/* Analog */
93 		snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
94 		snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
95 		val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000;
96 		snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
97 		val = inl(emu->port + GPIO) | 0x101;
98 		outl(val, emu->port + GPIO);
99 	}
100 }
101 
102 static void ca0106_set_capture_source(struct snd_ca0106 *emu)
103 {
104 	unsigned int val = emu->capture_source;
105 	unsigned int source, mask;
106 	source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
107 	mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
108 	snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
109 }
110 
111 static void ca0106_set_i2c_capture_source(struct snd_ca0106 *emu,
112 					  unsigned int val, int force)
113 {
114 	unsigned int ngain, ogain;
115 	u32 source;
116 
117 	snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
118 	ngain = emu->i2c_capture_volume[val][0]; /* Left */
119 	ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
120 	if (force || ngain != ogain)
121 		snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ngain & 0xff);
122 	ngain = emu->i2c_capture_volume[val][1]; /* Right */
123 	ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */
124 	if (force || ngain != ogain)
125 		snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ngain & 0xff);
126 	source = 1 << val;
127 	snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
128 	emu->i2c_capture_source = val;
129 }
130 
131 static void ca0106_set_capture_mic_line_in(struct snd_ca0106 *emu)
132 {
133 	u32 tmp;
134 
135 	if (emu->capture_mic_line_in) {
136 		/* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
137 		tmp = inl(emu->port+GPIO) & ~0x400;
138 		tmp = tmp | 0x400;
139 		outl(tmp, emu->port+GPIO);
140 		/* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */
141 	} else {
142 		/* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
143 		tmp = inl(emu->port+GPIO) & ~0x400;
144 		outl(tmp, emu->port+GPIO);
145 		/* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); */
146 	}
147 }
148 
149 static void ca0106_set_spdif_bits(struct snd_ca0106 *emu, int idx)
150 {
151 	snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, emu->spdif_str_bits[idx]);
152 }
153 
154 /*
155  */
156 static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1);
157 static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1);
158 
159 #define snd_ca0106_shared_spdif_info	snd_ctl_boolean_mono_info
160 
161 static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol,
162 					struct snd_ctl_elem_value *ucontrol)
163 {
164 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
165 
166 	ucontrol->value.integer.value[0] = emu->spdif_enable;
167 	return 0;
168 }
169 
170 static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
171 					struct snd_ctl_elem_value *ucontrol)
172 {
173 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
174 	unsigned int val;
175 	int change = 0;
176 
177 	val = !!ucontrol->value.integer.value[0];
178 	change = (emu->spdif_enable != val);
179 	if (change) {
180 		emu->spdif_enable = val;
181 		ca0106_spdif_enable(emu);
182 	}
183         return change;
184 }
185 
186 static int snd_ca0106_capture_source_info(struct snd_kcontrol *kcontrol,
187 					  struct snd_ctl_elem_info *uinfo)
188 {
189 	static char *texts[6] = {
190 		"IEC958 out", "i2s mixer out", "IEC958 in", "i2s in", "AC97 in", "SRC out"
191 	};
192 
193 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
194 	uinfo->count = 1;
195 	uinfo->value.enumerated.items = 6;
196 	if (uinfo->value.enumerated.item > 5)
197                 uinfo->value.enumerated.item = 5;
198 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
199 	return 0;
200 }
201 
202 static int snd_ca0106_capture_source_get(struct snd_kcontrol *kcontrol,
203 					struct snd_ctl_elem_value *ucontrol)
204 {
205 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
206 
207 	ucontrol->value.enumerated.item[0] = emu->capture_source;
208 	return 0;
209 }
210 
211 static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
212 					struct snd_ctl_elem_value *ucontrol)
213 {
214 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
215 	unsigned int val;
216 	int change = 0;
217 
218 	val = ucontrol->value.enumerated.item[0] ;
219 	if (val >= 6)
220 		return -EINVAL;
221 	change = (emu->capture_source != val);
222 	if (change) {
223 		emu->capture_source = val;
224 		ca0106_set_capture_source(emu);
225 	}
226         return change;
227 }
228 
229 static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
230 					  struct snd_ctl_elem_info *uinfo)
231 {
232 	static char *texts[6] = {
233 		"Phone", "Mic", "Line in", "Aux"
234 	};
235 
236 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
237 	uinfo->count = 1;
238 	uinfo->value.enumerated.items = 4;
239 	if (uinfo->value.enumerated.item > 3)
240                 uinfo->value.enumerated.item = 3;
241 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
242 	return 0;
243 }
244 
245 static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol *kcontrol,
246 					struct snd_ctl_elem_value *ucontrol)
247 {
248 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
249 
250 	ucontrol->value.enumerated.item[0] = emu->i2c_capture_source;
251 	return 0;
252 }
253 
254 static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
255 					struct snd_ctl_elem_value *ucontrol)
256 {
257 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
258 	unsigned int source_id;
259 	int change = 0;
260 	/* If the capture source has changed,
261 	 * update the capture volume from the cached value
262 	 * for the particular source.
263 	 */
264 	source_id = ucontrol->value.enumerated.item[0] ;
265 	if (source_id >= 4)
266 		return -EINVAL;
267 	change = (emu->i2c_capture_source != source_id);
268 	if (change) {
269 		ca0106_set_i2c_capture_source(emu, source_id, 0);
270 	}
271         return change;
272 }
273 
274 static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol *kcontrol,
275 					       struct snd_ctl_elem_info *uinfo)
276 {
277 	static char *texts[2] = { "Side out", "Line in" };
278 
279 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
280 	uinfo->count = 1;
281 	uinfo->value.enumerated.items = 2;
282 	if (uinfo->value.enumerated.item > 1)
283                 uinfo->value.enumerated.item = 1;
284 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
285 	return 0;
286 }
287 
288 static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol,
289 					       struct snd_ctl_elem_info *uinfo)
290 {
291 	static char *texts[2] = { "Line in", "Mic in" };
292 
293 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
294 	uinfo->count = 1;
295 	uinfo->value.enumerated.items = 2;
296 	if (uinfo->value.enumerated.item > 1)
297                 uinfo->value.enumerated.item = 1;
298 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
299 	return 0;
300 }
301 
302 static int snd_ca0106_capture_mic_line_in_get(struct snd_kcontrol *kcontrol,
303 					struct snd_ctl_elem_value *ucontrol)
304 {
305 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
306 
307 	ucontrol->value.enumerated.item[0] = emu->capture_mic_line_in;
308 	return 0;
309 }
310 
311 static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
312 					struct snd_ctl_elem_value *ucontrol)
313 {
314 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
315 	unsigned int val;
316 	int change = 0;
317 
318 	val = ucontrol->value.enumerated.item[0] ;
319 	if (val > 1)
320 		return -EINVAL;
321 	change = (emu->capture_mic_line_in != val);
322 	if (change) {
323 		emu->capture_mic_line_in = val;
324 		ca0106_set_capture_mic_line_in(emu);
325 	}
326         return change;
327 }
328 
329 static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in __devinitdata =
330 {
331 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
332 	.name =		"Shared Mic/Line in Capture Switch",
333 	.info =		snd_ca0106_capture_mic_line_in_info,
334 	.get =		snd_ca0106_capture_mic_line_in_get,
335 	.put =		snd_ca0106_capture_mic_line_in_put
336 };
337 
338 static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out __devinitdata =
339 {
340 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
341 	.name =		"Shared Line in/Side out Capture Switch",
342 	.info =		snd_ca0106_capture_line_in_side_out_info,
343 	.get =		snd_ca0106_capture_mic_line_in_get,
344 	.put =		snd_ca0106_capture_mic_line_in_put
345 };
346 
347 
348 static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
349 				 struct snd_ctl_elem_info *uinfo)
350 {
351 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
352 	uinfo->count = 1;
353 	return 0;
354 }
355 
356 static void decode_spdif_bits(unsigned char *status, unsigned int bits)
357 {
358 	status[0] = (bits >> 0) & 0xff;
359 	status[1] = (bits >> 8) & 0xff;
360 	status[2] = (bits >> 16) & 0xff;
361 	status[3] = (bits >> 24) & 0xff;
362 }
363 
364 static int snd_ca0106_spdif_get_default(struct snd_kcontrol *kcontrol,
365                                  struct snd_ctl_elem_value *ucontrol)
366 {
367 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
368 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
369 
370 	decode_spdif_bits(ucontrol->value.iec958.status,
371 			  emu->spdif_bits[idx]);
372         return 0;
373 }
374 
375 static int snd_ca0106_spdif_get_stream(struct snd_kcontrol *kcontrol,
376                                  struct snd_ctl_elem_value *ucontrol)
377 {
378 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
379 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
380 
381 	decode_spdif_bits(ucontrol->value.iec958.status,
382 			  emu->spdif_str_bits[idx]);
383         return 0;
384 }
385 
386 static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol,
387 				      struct snd_ctl_elem_value *ucontrol)
388 {
389 	ucontrol->value.iec958.status[0] = 0xff;
390 	ucontrol->value.iec958.status[1] = 0xff;
391 	ucontrol->value.iec958.status[2] = 0xff;
392 	ucontrol->value.iec958.status[3] = 0xff;
393         return 0;
394 }
395 
396 static unsigned int encode_spdif_bits(unsigned char *status)
397 {
398 	return ((unsigned int)status[0] << 0) |
399 		((unsigned int)status[1] << 8) |
400 		((unsigned int)status[2] << 16) |
401 		((unsigned int)status[3] << 24);
402 }
403 
404 static int snd_ca0106_spdif_put_default(struct snd_kcontrol *kcontrol,
405                                  struct snd_ctl_elem_value *ucontrol)
406 {
407 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
408 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
409 	unsigned int val;
410 
411 	val = encode_spdif_bits(ucontrol->value.iec958.status);
412 	if (val != emu->spdif_bits[idx]) {
413 		emu->spdif_bits[idx] = val;
414 		/* FIXME: this isn't safe, but needed to keep the compatibility
415 		 * with older alsa-lib config
416 		 */
417 		emu->spdif_str_bits[idx] = val;
418 		ca0106_set_spdif_bits(emu, idx);
419 		return 1;
420 	}
421 	return 0;
422 }
423 
424 static int snd_ca0106_spdif_put_stream(struct snd_kcontrol *kcontrol,
425                                  struct snd_ctl_elem_value *ucontrol)
426 {
427 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
428 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
429 	unsigned int val;
430 
431 	val = encode_spdif_bits(ucontrol->value.iec958.status);
432 	if (val != emu->spdif_str_bits[idx]) {
433 		emu->spdif_str_bits[idx] = val;
434 		ca0106_set_spdif_bits(emu, idx);
435 		return 1;
436 	}
437         return 0;
438 }
439 
440 static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol,
441 				  struct snd_ctl_elem_info *uinfo)
442 {
443         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
444         uinfo->count = 2;
445         uinfo->value.integer.min = 0;
446         uinfo->value.integer.max = 255;
447         return 0;
448 }
449 
450 static int snd_ca0106_volume_get(struct snd_kcontrol *kcontrol,
451 				 struct snd_ctl_elem_value *ucontrol)
452 {
453         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
454         unsigned int value;
455 	int channel_id, reg;
456 
457 	channel_id = (kcontrol->private_value >> 8) & 0xff;
458 	reg = kcontrol->private_value & 0xff;
459 
460         value = snd_ca0106_ptr_read(emu, reg, channel_id);
461         ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
462         ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
463         return 0;
464 }
465 
466 static int snd_ca0106_volume_put(struct snd_kcontrol *kcontrol,
467 				 struct snd_ctl_elem_value *ucontrol)
468 {
469         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
470         unsigned int oval, nval;
471 	int channel_id, reg;
472 
473 	channel_id = (kcontrol->private_value >> 8) & 0xff;
474 	reg = kcontrol->private_value & 0xff;
475 
476 	oval = snd_ca0106_ptr_read(emu, reg, channel_id);
477 	nval = ((0xff - ucontrol->value.integer.value[0]) << 24) |
478 		((0xff - ucontrol->value.integer.value[1]) << 16);
479         nval |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
480 		((0xff - ucontrol->value.integer.value[1]) );
481 	if (oval == nval)
482 		return 0;
483 	snd_ca0106_ptr_write(emu, reg, channel_id, nval);
484 	return 1;
485 }
486 
487 static int snd_ca0106_i2c_volume_info(struct snd_kcontrol *kcontrol,
488 				  struct snd_ctl_elem_info *uinfo)
489 {
490         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
491         uinfo->count = 2;
492         uinfo->value.integer.min = 0;
493         uinfo->value.integer.max = 255;
494         return 0;
495 }
496 
497 static int snd_ca0106_i2c_volume_get(struct snd_kcontrol *kcontrol,
498 				 struct snd_ctl_elem_value *ucontrol)
499 {
500         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
501 	int source_id;
502 
503 	source_id = kcontrol->private_value;
504 
505         ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0];
506         ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1];
507         return 0;
508 }
509 
510 static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
511 				 struct snd_ctl_elem_value *ucontrol)
512 {
513         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
514         unsigned int ogain;
515         unsigned int ngain;
516 	int source_id;
517 	int change = 0;
518 
519 	source_id = kcontrol->private_value;
520 	ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
521 	ngain = ucontrol->value.integer.value[0];
522 	if (ngain > 0xff)
523 		return -EINVAL;
524 	if (ogain != ngain) {
525 		if (emu->i2c_capture_source == source_id)
526 			snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
527 		emu->i2c_capture_volume[source_id][0] = ucontrol->value.integer.value[0];
528 		change = 1;
529 	}
530 	ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
531 	ngain = ucontrol->value.integer.value[1];
532 	if (ngain > 0xff)
533 		return -EINVAL;
534 	if (ogain != ngain) {
535 		if (emu->i2c_capture_source == source_id)
536 			snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
537 		emu->i2c_capture_volume[source_id][1] = ucontrol->value.integer.value[1];
538 		change = 1;
539 	}
540 
541 	return change;
542 }
543 
544 #define spi_mute_info	snd_ctl_boolean_mono_info
545 
546 static int spi_mute_get(struct snd_kcontrol *kcontrol,
547 			struct snd_ctl_elem_value *ucontrol)
548 {
549 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
550 	unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
551 	unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
552 
553 	ucontrol->value.integer.value[0] = !(emu->spi_dac_reg[reg] & bit);
554 	return 0;
555 }
556 
557 static int spi_mute_put(struct snd_kcontrol *kcontrol,
558 			struct snd_ctl_elem_value *ucontrol)
559 {
560 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
561 	unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
562 	unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
563 	int ret;
564 
565 	ret = emu->spi_dac_reg[reg] & bit;
566 	if (ucontrol->value.integer.value[0]) {
567 		if (!ret)	/* bit already cleared, do nothing */
568 			return 0;
569 		emu->spi_dac_reg[reg] &= ~bit;
570 	} else {
571 		if (ret)	/* bit already set, do nothing */
572 			return 0;
573 		emu->spi_dac_reg[reg] |= bit;
574 	}
575 
576 	ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]);
577 	return ret ? -EINVAL : 1;
578 }
579 
580 #define CA_VOLUME(xname,chid,reg) \
581 {								\
582 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\
583 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |		\
584 	          SNDRV_CTL_ELEM_ACCESS_TLV_READ,		\
585 	.info =	 snd_ca0106_volume_info,			\
586 	.get =   snd_ca0106_volume_get,				\
587 	.put =   snd_ca0106_volume_put,				\
588 	.tlv = { .p = snd_ca0106_db_scale1 },			\
589 	.private_value = ((chid) << 8) | (reg)			\
590 }
591 
592 static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
593 	CA_VOLUME("Analog Front Playback Volume",
594 		  CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2),
595         CA_VOLUME("Analog Rear Playback Volume",
596 		  CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2),
597 	CA_VOLUME("Analog Center/LFE Playback Volume",
598 		  CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2),
599         CA_VOLUME("Analog Side Playback Volume",
600 		  CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2),
601 
602         CA_VOLUME("IEC958 Front Playback Volume",
603 		  CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1),
604 	CA_VOLUME("IEC958 Rear Playback Volume",
605 		  CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1),
606 	CA_VOLUME("IEC958 Center/LFE Playback Volume",
607 		  CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1),
608 	CA_VOLUME("IEC958 Unknown Playback Volume",
609 		  CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1),
610 
611         CA_VOLUME("CAPTURE feedback Playback Volume",
612 		  1, CAPTURE_CONTROL),
613 
614 	{
615 		.access =	SNDRV_CTL_ELEM_ACCESS_READ,
616 		.iface =        SNDRV_CTL_ELEM_IFACE_PCM,
617 		.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
618 		.count =	4,
619 		.info =         snd_ca0106_spdif_info,
620 		.get =          snd_ca0106_spdif_get_mask
621 	},
622 	{
623 		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
624 		.name =		"IEC958 Playback Switch",
625 		.info =		snd_ca0106_shared_spdif_info,
626 		.get =		snd_ca0106_shared_spdif_get,
627 		.put =		snd_ca0106_shared_spdif_put
628 	},
629 	{
630 		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
631 		.name =		"Digital Source Capture Enum",
632 		.info =		snd_ca0106_capture_source_info,
633 		.get =		snd_ca0106_capture_source_get,
634 		.put =		snd_ca0106_capture_source_put
635 	},
636 	{
637 		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
638 		.name =		"Analog Source Capture Enum",
639 		.info =		snd_ca0106_i2c_capture_source_info,
640 		.get =		snd_ca0106_i2c_capture_source_get,
641 		.put =		snd_ca0106_i2c_capture_source_put
642 	},
643 	{
644 		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
645 		.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
646 		.count =	4,
647 		.info =         snd_ca0106_spdif_info,
648 		.get =          snd_ca0106_spdif_get_default,
649 		.put =          snd_ca0106_spdif_put_default
650 	},
651 	{
652 		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
653 		.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
654 		.count =	4,
655 		.info =         snd_ca0106_spdif_info,
656 		.get =          snd_ca0106_spdif_get_stream,
657 		.put =          snd_ca0106_spdif_put_stream
658 	},
659 };
660 
661 #define I2C_VOLUME(xname,chid) \
662 {								\
663 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\
664 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |		\
665 	          SNDRV_CTL_ELEM_ACCESS_TLV_READ,		\
666 	.info =  snd_ca0106_i2c_volume_info,			\
667 	.get =   snd_ca0106_i2c_volume_get,			\
668 	.put =   snd_ca0106_i2c_volume_put,			\
669 	.tlv = { .p = snd_ca0106_db_scale2 },			\
670 	.private_value = chid					\
671 }
672 
673 static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] __devinitdata = {
674         I2C_VOLUME("Phone Capture Volume", 0),
675         I2C_VOLUME("Mic Capture Volume", 1),
676         I2C_VOLUME("Line in Capture Volume", 2),
677         I2C_VOLUME("Aux Capture Volume", 3),
678 };
679 
680 #define SPI_SWITCH(xname,reg,bit) \
681 {								\
682 	.iface	= SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\
683 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,		\
684 	.info	= spi_mute_info,				\
685 	.get	= spi_mute_get,					\
686 	.put	= spi_mute_put,					\
687 	.private_value = (reg<<SPI_REG_SHIFT) | (bit)		\
688 }
689 
690 static struct snd_kcontrol_new snd_ca0106_volume_spi_dac_ctls[]
691 __devinitdata = {
692 	SPI_SWITCH("Analog Front Playback Switch",
693 		   SPI_DMUTE4_REG, SPI_DMUTE4_BIT),
694 	SPI_SWITCH("Analog Rear Playback Switch",
695 		   SPI_DMUTE0_REG, SPI_DMUTE0_BIT),
696 	SPI_SWITCH("Analog Center/LFE Playback Switch",
697 		   SPI_DMUTE2_REG, SPI_DMUTE2_BIT),
698 	SPI_SWITCH("Analog Side Playback Switch",
699 		   SPI_DMUTE1_REG, SPI_DMUTE1_BIT),
700 };
701 
702 static int __devinit remove_ctl(struct snd_card *card, const char *name)
703 {
704 	struct snd_ctl_elem_id id;
705 	memset(&id, 0, sizeof(id));
706 	strcpy(id.name, name);
707 	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
708 	return snd_ctl_remove_id(card, &id);
709 }
710 
711 static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card, const char *name)
712 {
713 	struct snd_ctl_elem_id sid;
714 	memset(&sid, 0, sizeof(sid));
715 	/* FIXME: strcpy is bad. */
716 	strcpy(sid.name, name);
717 	sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
718 	return snd_ctl_find_id(card, &sid);
719 }
720 
721 static int __devinit rename_ctl(struct snd_card *card, const char *src, const char *dst)
722 {
723 	struct snd_kcontrol *kctl = ctl_find(card, src);
724 	if (kctl) {
725 		strcpy(kctl->id.name, dst);
726 		return 0;
727 	}
728 	return -ENOENT;
729 }
730 
731 #define ADD_CTLS(emu, ctls)						\
732 	do {								\
733 		int i, _err;						\
734 		for (i = 0; i < ARRAY_SIZE(ctls); i++) {		\
735 			_err = snd_ctl_add(card, snd_ctl_new1(&ctls[i], emu)); \
736 			if (_err < 0)					\
737 				return _err;				\
738 		}							\
739 	} while (0)
740 
741 static __devinitdata
742 DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale, -6375, 50, 1);
743 
744 static char *slave_vols[] __devinitdata = {
745 	"Analog Front Playback Volume",
746         "Analog Rear Playback Volume",
747 	"Analog Center/LFE Playback Volume",
748         "Analog Side Playback Volume",
749         "IEC958 Front Playback Volume",
750 	"IEC958 Rear Playback Volume",
751 	"IEC958 Center/LFE Playback Volume",
752 	"IEC958 Unknown Playback Volume",
753         "CAPTURE feedback Playback Volume",
754 	NULL
755 };
756 
757 static char *slave_sws[] __devinitdata = {
758 	"Analog Front Playback Switch",
759 	"Analog Rear Playback Switch",
760 	"Analog Center/LFE Playback Switch",
761 	"Analog Side Playback Switch",
762 	"IEC958 Playback Switch",
763 	NULL
764 };
765 
766 static void __devinit add_slaves(struct snd_card *card,
767 				 struct snd_kcontrol *master, char **list)
768 {
769 	for (; *list; list++) {
770 		struct snd_kcontrol *slave = ctl_find(card, *list);
771 		if (slave)
772 			snd_ctl_add_slave(master, slave);
773 	}
774 }
775 
776 int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
777 {
778 	int err;
779         struct snd_card *card = emu->card;
780 	char **c;
781 	struct snd_kcontrol *vmaster;
782 	static char *ca0106_remove_ctls[] = {
783 		"Master Mono Playback Switch",
784 		"Master Mono Playback Volume",
785 		"3D Control - Switch",
786 		"3D Control Sigmatel - Depth",
787 		"PCM Playback Switch",
788 		"PCM Playback Volume",
789 		"CD Playback Switch",
790 		"CD Playback Volume",
791 		"Phone Playback Switch",
792 		"Phone Playback Volume",
793 		"Video Playback Switch",
794 		"Video Playback Volume",
795 		"PC Speaker Playback Switch",
796 		"PC Speaker Playback Volume",
797 		"Mono Output Select",
798 		"Capture Source",
799 		"Capture Switch",
800 		"Capture Volume",
801 		"External Amplifier",
802 		"Sigmatel 4-Speaker Stereo Playback Switch",
803 		"Sigmatel Surround Phase Inversion Playback ",
804 		NULL
805 	};
806 	static char *ca0106_rename_ctls[] = {
807 		"Master Playback Switch", "Capture Switch",
808 		"Master Playback Volume", "Capture Volume",
809 		"Line Playback Switch", "AC97 Line Capture Switch",
810 		"Line Playback Volume", "AC97 Line Capture Volume",
811 		"Aux Playback Switch", "AC97 Aux Capture Switch",
812 		"Aux Playback Volume", "AC97 Aux Capture Volume",
813 		"Mic Playback Switch", "AC97 Mic Capture Switch",
814 		"Mic Playback Volume", "AC97 Mic Capture Volume",
815 		"Mic Select", "AC97 Mic Select",
816 		"Mic Boost (+20dB)", "AC97 Mic Boost (+20dB)",
817 		NULL
818 	};
819 #if 1
820 	for (c = ca0106_remove_ctls; *c; c++)
821 		remove_ctl(card, *c);
822 	for (c = ca0106_rename_ctls; *c; c += 2)
823 		rename_ctl(card, c[0], c[1]);
824 #endif
825 
826 	ADD_CTLS(emu, snd_ca0106_volume_ctls);
827 	if (emu->details->i2c_adc == 1) {
828 		ADD_CTLS(emu, snd_ca0106_volume_i2c_adc_ctls);
829 		if (emu->details->gpio_type == 1)
830 			err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu));
831 		else  /* gpio_type == 2 */
832 			err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_line_in_side_out, emu));
833 		if (err < 0)
834 			return err;
835 	}
836 	if (emu->details->spi_dac == 1)
837 		ADD_CTLS(emu, snd_ca0106_volume_spi_dac_ctls);
838 
839 	/* Create virtual master controls */
840 	vmaster = snd_ctl_make_virtual_master("Master Playback Volume",
841 					      snd_ca0106_master_db_scale);
842 	if (!vmaster)
843 		return -ENOMEM;
844 	add_slaves(card, vmaster, slave_vols);
845 
846 	if (emu->details->spi_dac == 1) {
847 		vmaster = snd_ctl_make_virtual_master("Master Playback Switch",
848 						      NULL);
849 		if (!vmaster)
850 			return -ENOMEM;
851 		add_slaves(card, vmaster, slave_sws);
852 	}
853         return 0;
854 }
855 
856 #ifdef CONFIG_PM
857 struct ca0106_vol_tbl {
858 	unsigned int channel_id;
859 	unsigned int reg;
860 };
861 
862 static struct ca0106_vol_tbl saved_volumes[NUM_SAVED_VOLUMES] = {
863 	{ CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2 },
864 	{ CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2 },
865 	{ CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2 },
866 	{ CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2 },
867 	{ CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1 },
868 	{ CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1 },
869 	{ CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1 },
870 	{ CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1 },
871 	{ 1, CAPTURE_CONTROL },
872 };
873 
874 void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip)
875 {
876 	int i;
877 
878 	/* save volumes */
879 	for (i = 0; i < NUM_SAVED_VOLUMES; i++)
880 		chip->saved_vol[i] =
881 			snd_ca0106_ptr_read(chip, saved_volumes[i].reg,
882 					    saved_volumes[i].channel_id);
883 }
884 
885 void snd_ca0106_mixer_resume(struct snd_ca0106  *chip)
886 {
887 	int i;
888 
889 	for (i = 0; i < NUM_SAVED_VOLUMES; i++)
890 		snd_ca0106_ptr_write(chip, saved_volumes[i].reg,
891 				     saved_volumes[i].channel_id,
892 				     chip->saved_vol[i]);
893 
894 	ca0106_spdif_enable(chip);
895 	ca0106_set_capture_source(chip);
896 	ca0106_set_i2c_capture_source(chip, chip->i2c_capture_source, 1);
897 	for (i = 0; i < 4; i++)
898 		ca0106_set_spdif_bits(chip, i);
899 	if (chip->details->i2c_adc)
900 		ca0106_set_capture_mic_line_in(chip);
901 }
902 #endif /* CONFIG_PM */
903