xref: /openbmc/linux/sound/pci/ca0106/ca0106_mixer.c (revision ec32c0c4)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
4  *  Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
5  *  Version: 0.0.18
6  *
7  *  FEATURES currently supported:
8  *    See ca0106_main.c for features.
9  *
10  *  Changelog:
11  *    Support interrupts per period.
12  *    Removed noise from Center/LFE channel when in Analog mode.
13  *    Rename and remove mixer controls.
14  *  0.0.6
15  *    Use separate card based DMA buffer for periods table list.
16  *  0.0.7
17  *    Change remove and rename ctrls into lists.
18  *  0.0.8
19  *    Try to fix capture sources.
20  *  0.0.9
21  *    Fix AC3 output.
22  *    Enable S32_LE format support.
23  *  0.0.10
24  *    Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
25  *  0.0.11
26  *    Add Model name recognition.
27  *  0.0.12
28  *    Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
29  *    Remove redundent "voice" handling.
30  *  0.0.13
31  *    Single trigger call for multi channels.
32  *  0.0.14
33  *    Set limits based on what the sound card hardware can do.
34  *    playback periods_min=2, periods_max=8
35  *    capture hw constraints require period_size = n * 64 bytes.
36  *    playback hw constraints require period_size = n * 64 bytes.
37  *  0.0.15
38  *    Separated ca0106.c into separate functional .c files.
39  *  0.0.16
40  *    Modified Copyright message.
41  *  0.0.17
42  *    Implement Mic and Line in Capture.
43  *  0.0.18
44  *    Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
45  *
46  *  This code was initially based on code from ALSA's emu10k1x.c which is:
47  *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
48  */
49 #include <linux/delay.h>
50 #include <linux/init.h>
51 #include <linux/interrupt.h>
52 #include <linux/moduleparam.h>
53 #include <sound/core.h>
54 #include <sound/initval.h>
55 #include <sound/pcm.h>
56 #include <sound/ac97_codec.h>
57 #include <sound/info.h>
58 #include <sound/tlv.h>
59 #include <linux/io.h>
60 
61 #include "ca0106.h"
62 
63 static void ca0106_spdif_enable(struct snd_ca0106 *emu)
64 {
65 	unsigned int val;
66 
67 	if (emu->spdif_enable) {
68 		/* Digital */
69 		snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
70 		snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
71 		val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000;
72 		snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
73 		val = inl(emu->port + CA0106_GPIO) & ~0x101;
74 		outl(val, emu->port + CA0106_GPIO);
75 
76 	} else {
77 		/* Analog */
78 		snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
79 		snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
80 		val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000;
81 		snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
82 		val = inl(emu->port + CA0106_GPIO) | 0x101;
83 		outl(val, emu->port + CA0106_GPIO);
84 	}
85 }
86 
87 static void ca0106_set_capture_source(struct snd_ca0106 *emu)
88 {
89 	unsigned int val = emu->capture_source;
90 	unsigned int source, mask;
91 	source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
92 	mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
93 	snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
94 }
95 
96 static void ca0106_set_i2c_capture_source(struct snd_ca0106 *emu,
97 					  unsigned int val, int force)
98 {
99 	unsigned int ngain, ogain;
100 	u32 source;
101 
102 	snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
103 	ngain = emu->i2c_capture_volume[val][0]; /* Left */
104 	ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
105 	if (force || ngain != ogain)
106 		snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ngain & 0xff);
107 	ngain = emu->i2c_capture_volume[val][1]; /* Right */
108 	ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */
109 	if (force || ngain != ogain)
110 		snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ngain & 0xff);
111 	source = 1 << val;
112 	snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
113 	emu->i2c_capture_source = val;
114 }
115 
116 static void ca0106_set_capture_mic_line_in(struct snd_ca0106 *emu)
117 {
118 	u32 tmp;
119 
120 	if (emu->capture_mic_line_in) {
121 		/* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
122 		tmp = inl(emu->port + CA0106_GPIO) & ~0x400;
123 		tmp = tmp | 0x400;
124 		outl(tmp, emu->port + CA0106_GPIO);
125 		/* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */
126 	} else {
127 		/* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
128 		tmp = inl(emu->port + CA0106_GPIO) & ~0x400;
129 		outl(tmp, emu->port + CA0106_GPIO);
130 		/* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); */
131 	}
132 }
133 
134 static void ca0106_set_spdif_bits(struct snd_ca0106 *emu, int idx)
135 {
136 	snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, emu->spdif_str_bits[idx]);
137 }
138 
139 /*
140  */
141 static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1);
142 static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1);
143 
144 #define snd_ca0106_shared_spdif_info	snd_ctl_boolean_mono_info
145 
146 static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol,
147 					struct snd_ctl_elem_value *ucontrol)
148 {
149 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
150 
151 	ucontrol->value.integer.value[0] = emu->spdif_enable;
152 	return 0;
153 }
154 
155 static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
156 					struct snd_ctl_elem_value *ucontrol)
157 {
158 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
159 	unsigned int val;
160 	int change = 0;
161 
162 	val = !!ucontrol->value.integer.value[0];
163 	change = (emu->spdif_enable != val);
164 	if (change) {
165 		emu->spdif_enable = val;
166 		ca0106_spdif_enable(emu);
167 	}
168         return change;
169 }
170 
171 static int snd_ca0106_capture_source_info(struct snd_kcontrol *kcontrol,
172 					  struct snd_ctl_elem_info *uinfo)
173 {
174 	static const char * const texts[6] = {
175 		"IEC958 out", "i2s mixer out", "IEC958 in", "i2s in", "AC97 in", "SRC out"
176 	};
177 
178 	return snd_ctl_enum_info(uinfo, 1, 6, texts);
179 }
180 
181 static int snd_ca0106_capture_source_get(struct snd_kcontrol *kcontrol,
182 					struct snd_ctl_elem_value *ucontrol)
183 {
184 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
185 
186 	ucontrol->value.enumerated.item[0] = emu->capture_source;
187 	return 0;
188 }
189 
190 static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
191 					struct snd_ctl_elem_value *ucontrol)
192 {
193 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
194 	unsigned int val;
195 	int change = 0;
196 
197 	val = ucontrol->value.enumerated.item[0] ;
198 	if (val >= 6)
199 		return -EINVAL;
200 	change = (emu->capture_source != val);
201 	if (change) {
202 		emu->capture_source = val;
203 		ca0106_set_capture_source(emu);
204 	}
205         return change;
206 }
207 
208 static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
209 					  struct snd_ctl_elem_info *uinfo)
210 {
211 	static const char * const texts[4] = {
212 		"Phone", "Mic", "Line in", "Aux"
213 	};
214 
215 	return snd_ctl_enum_info(uinfo, 1, 4, texts);
216 }
217 
218 static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol *kcontrol,
219 					struct snd_ctl_elem_value *ucontrol)
220 {
221 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
222 
223 	ucontrol->value.enumerated.item[0] = emu->i2c_capture_source;
224 	return 0;
225 }
226 
227 static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
228 					struct snd_ctl_elem_value *ucontrol)
229 {
230 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
231 	unsigned int source_id;
232 	int change = 0;
233 	/* If the capture source has changed,
234 	 * update the capture volume from the cached value
235 	 * for the particular source.
236 	 */
237 	source_id = ucontrol->value.enumerated.item[0] ;
238 	if (source_id >= 4)
239 		return -EINVAL;
240 	change = (emu->i2c_capture_source != source_id);
241 	if (change) {
242 		ca0106_set_i2c_capture_source(emu, source_id, 0);
243 	}
244         return change;
245 }
246 
247 static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol *kcontrol,
248 					       struct snd_ctl_elem_info *uinfo)
249 {
250 	static const char * const texts[2] = { "Side out", "Line in" };
251 
252 	return snd_ctl_enum_info(uinfo, 1, 2, texts);
253 }
254 
255 static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol,
256 					       struct snd_ctl_elem_info *uinfo)
257 {
258 	static const char * const texts[2] = { "Line in", "Mic in" };
259 
260 	return snd_ctl_enum_info(uinfo, 1, 2, texts);
261 }
262 
263 static int snd_ca0106_capture_mic_line_in_get(struct snd_kcontrol *kcontrol,
264 					struct snd_ctl_elem_value *ucontrol)
265 {
266 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
267 
268 	ucontrol->value.enumerated.item[0] = emu->capture_mic_line_in;
269 	return 0;
270 }
271 
272 static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
273 					struct snd_ctl_elem_value *ucontrol)
274 {
275 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
276 	unsigned int val;
277 	int change = 0;
278 
279 	val = ucontrol->value.enumerated.item[0] ;
280 	if (val > 1)
281 		return -EINVAL;
282 	change = (emu->capture_mic_line_in != val);
283 	if (change) {
284 		emu->capture_mic_line_in = val;
285 		ca0106_set_capture_mic_line_in(emu);
286 	}
287         return change;
288 }
289 
290 static const struct snd_kcontrol_new snd_ca0106_capture_mic_line_in =
291 {
292 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
293 	.name =		"Shared Mic/Line in Capture Switch",
294 	.info =		snd_ca0106_capture_mic_line_in_info,
295 	.get =		snd_ca0106_capture_mic_line_in_get,
296 	.put =		snd_ca0106_capture_mic_line_in_put
297 };
298 
299 static const struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out =
300 {
301 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
302 	.name =		"Shared Line in/Side out Capture Switch",
303 	.info =		snd_ca0106_capture_line_in_side_out_info,
304 	.get =		snd_ca0106_capture_mic_line_in_get,
305 	.put =		snd_ca0106_capture_mic_line_in_put
306 };
307 
308 
309 static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
310 				 struct snd_ctl_elem_info *uinfo)
311 {
312 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
313 	uinfo->count = 1;
314 	return 0;
315 }
316 
317 static void decode_spdif_bits(unsigned char *status, unsigned int bits)
318 {
319 	status[0] = (bits >> 0) & 0xff;
320 	status[1] = (bits >> 8) & 0xff;
321 	status[2] = (bits >> 16) & 0xff;
322 	status[3] = (bits >> 24) & 0xff;
323 }
324 
325 static int snd_ca0106_spdif_get_default(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 	decode_spdif_bits(ucontrol->value.iec958.status,
332 			  emu->spdif_bits[idx]);
333         return 0;
334 }
335 
336 static int snd_ca0106_spdif_get_stream(struct snd_kcontrol *kcontrol,
337                                  struct snd_ctl_elem_value *ucontrol)
338 {
339 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
340 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
341 
342 	decode_spdif_bits(ucontrol->value.iec958.status,
343 			  emu->spdif_str_bits[idx]);
344         return 0;
345 }
346 
347 static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol,
348 				      struct snd_ctl_elem_value *ucontrol)
349 {
350 	ucontrol->value.iec958.status[0] = 0xff;
351 	ucontrol->value.iec958.status[1] = 0xff;
352 	ucontrol->value.iec958.status[2] = 0xff;
353 	ucontrol->value.iec958.status[3] = 0xff;
354         return 0;
355 }
356 
357 static unsigned int encode_spdif_bits(unsigned char *status)
358 {
359 	return ((unsigned int)status[0] << 0) |
360 		((unsigned int)status[1] << 8) |
361 		((unsigned int)status[2] << 16) |
362 		((unsigned int)status[3] << 24);
363 }
364 
365 static int snd_ca0106_spdif_put_default(struct snd_kcontrol *kcontrol,
366                                  struct snd_ctl_elem_value *ucontrol)
367 {
368 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
369 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
370 	unsigned int val;
371 
372 	val = encode_spdif_bits(ucontrol->value.iec958.status);
373 	if (val != emu->spdif_bits[idx]) {
374 		emu->spdif_bits[idx] = val;
375 		/* FIXME: this isn't safe, but needed to keep the compatibility
376 		 * with older alsa-lib config
377 		 */
378 		emu->spdif_str_bits[idx] = val;
379 		ca0106_set_spdif_bits(emu, idx);
380 		return 1;
381 	}
382 	return 0;
383 }
384 
385 static int snd_ca0106_spdif_put_stream(struct snd_kcontrol *kcontrol,
386                                  struct snd_ctl_elem_value *ucontrol)
387 {
388 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
389 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
390 	unsigned int val;
391 
392 	val = encode_spdif_bits(ucontrol->value.iec958.status);
393 	if (val != emu->spdif_str_bits[idx]) {
394 		emu->spdif_str_bits[idx] = val;
395 		ca0106_set_spdif_bits(emu, idx);
396 		return 1;
397 	}
398         return 0;
399 }
400 
401 static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol,
402 				  struct snd_ctl_elem_info *uinfo)
403 {
404         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
405         uinfo->count = 2;
406         uinfo->value.integer.min = 0;
407         uinfo->value.integer.max = 255;
408         return 0;
409 }
410 
411 static int snd_ca0106_volume_get(struct snd_kcontrol *kcontrol,
412 				 struct snd_ctl_elem_value *ucontrol)
413 {
414         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
415         unsigned int value;
416 	int channel_id, reg;
417 
418 	channel_id = (kcontrol->private_value >> 8) & 0xff;
419 	reg = kcontrol->private_value & 0xff;
420 
421         value = snd_ca0106_ptr_read(emu, reg, channel_id);
422         ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
423         ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
424         return 0;
425 }
426 
427 static int snd_ca0106_volume_put(struct snd_kcontrol *kcontrol,
428 				 struct snd_ctl_elem_value *ucontrol)
429 {
430         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
431         unsigned int oval, nval;
432 	int channel_id, reg;
433 
434 	channel_id = (kcontrol->private_value >> 8) & 0xff;
435 	reg = kcontrol->private_value & 0xff;
436 
437 	oval = snd_ca0106_ptr_read(emu, reg, channel_id);
438 	nval = ((0xff - ucontrol->value.integer.value[0]) << 24) |
439 		((0xff - ucontrol->value.integer.value[1]) << 16);
440         nval |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
441 		((0xff - ucontrol->value.integer.value[1]) );
442 	if (oval == nval)
443 		return 0;
444 	snd_ca0106_ptr_write(emu, reg, channel_id, nval);
445 	return 1;
446 }
447 
448 static int snd_ca0106_i2c_volume_info(struct snd_kcontrol *kcontrol,
449 				  struct snd_ctl_elem_info *uinfo)
450 {
451         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
452         uinfo->count = 2;
453         uinfo->value.integer.min = 0;
454         uinfo->value.integer.max = 255;
455         return 0;
456 }
457 
458 static int snd_ca0106_i2c_volume_get(struct snd_kcontrol *kcontrol,
459 				 struct snd_ctl_elem_value *ucontrol)
460 {
461         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
462 	int source_id;
463 
464 	source_id = kcontrol->private_value;
465 
466         ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0];
467         ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1];
468         return 0;
469 }
470 
471 static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
472 				 struct snd_ctl_elem_value *ucontrol)
473 {
474         struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
475         unsigned int ogain;
476         unsigned int ngain;
477 	int source_id;
478 	int change = 0;
479 
480 	source_id = kcontrol->private_value;
481 	ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
482 	ngain = ucontrol->value.integer.value[0];
483 	if (ngain > 0xff)
484 		return -EINVAL;
485 	if (ogain != ngain) {
486 		if (emu->i2c_capture_source == source_id)
487 			snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
488 		emu->i2c_capture_volume[source_id][0] = ucontrol->value.integer.value[0];
489 		change = 1;
490 	}
491 	ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
492 	ngain = ucontrol->value.integer.value[1];
493 	if (ngain > 0xff)
494 		return -EINVAL;
495 	if (ogain != ngain) {
496 		if (emu->i2c_capture_source == source_id)
497 			snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
498 		emu->i2c_capture_volume[source_id][1] = ucontrol->value.integer.value[1];
499 		change = 1;
500 	}
501 
502 	return change;
503 }
504 
505 #define spi_mute_info	snd_ctl_boolean_mono_info
506 
507 static int spi_mute_get(struct snd_kcontrol *kcontrol,
508 			struct snd_ctl_elem_value *ucontrol)
509 {
510 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
511 	unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
512 	unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
513 
514 	ucontrol->value.integer.value[0] = !(emu->spi_dac_reg[reg] & bit);
515 	return 0;
516 }
517 
518 static int spi_mute_put(struct snd_kcontrol *kcontrol,
519 			struct snd_ctl_elem_value *ucontrol)
520 {
521 	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
522 	unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
523 	unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
524 	int ret;
525 
526 	ret = emu->spi_dac_reg[reg] & bit;
527 	if (ucontrol->value.integer.value[0]) {
528 		if (!ret)	/* bit already cleared, do nothing */
529 			return 0;
530 		emu->spi_dac_reg[reg] &= ~bit;
531 	} else {
532 		if (ret)	/* bit already set, do nothing */
533 			return 0;
534 		emu->spi_dac_reg[reg] |= bit;
535 	}
536 
537 	ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]);
538 	return ret ? -EINVAL : 1;
539 }
540 
541 #define CA_VOLUME(xname,chid,reg) \
542 {								\
543 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\
544 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |		\
545 	          SNDRV_CTL_ELEM_ACCESS_TLV_READ,		\
546 	.info =	 snd_ca0106_volume_info,			\
547 	.get =   snd_ca0106_volume_get,				\
548 	.put =   snd_ca0106_volume_put,				\
549 	.tlv = { .p = snd_ca0106_db_scale1 },			\
550 	.private_value = ((chid) << 8) | (reg)			\
551 }
552 
553 static const struct snd_kcontrol_new snd_ca0106_volume_ctls[] = {
554 	CA_VOLUME("Analog Front Playback Volume",
555 		  CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2),
556         CA_VOLUME("Analog Rear Playback Volume",
557 		  CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2),
558 	CA_VOLUME("Analog Center/LFE Playback Volume",
559 		  CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2),
560         CA_VOLUME("Analog Side Playback Volume",
561 		  CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2),
562 
563         CA_VOLUME("IEC958 Front Playback Volume",
564 		  CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1),
565 	CA_VOLUME("IEC958 Rear Playback Volume",
566 		  CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1),
567 	CA_VOLUME("IEC958 Center/LFE Playback Volume",
568 		  CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1),
569 	CA_VOLUME("IEC958 Unknown Playback Volume",
570 		  CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1),
571 
572         CA_VOLUME("CAPTURE feedback Playback Volume",
573 		  1, CAPTURE_CONTROL),
574 
575 	{
576 		.access =	SNDRV_CTL_ELEM_ACCESS_READ,
577 		.iface =        SNDRV_CTL_ELEM_IFACE_PCM,
578 		.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
579 		.count =	4,
580 		.info =         snd_ca0106_spdif_info,
581 		.get =          snd_ca0106_spdif_get_mask
582 	},
583 	{
584 		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
585 		.name =		"IEC958 Playback Switch",
586 		.info =		snd_ca0106_shared_spdif_info,
587 		.get =		snd_ca0106_shared_spdif_get,
588 		.put =		snd_ca0106_shared_spdif_put
589 	},
590 	{
591 		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
592 		.name =		"Digital Source Capture Enum",
593 		.info =		snd_ca0106_capture_source_info,
594 		.get =		snd_ca0106_capture_source_get,
595 		.put =		snd_ca0106_capture_source_put
596 	},
597 	{
598 		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
599 		.name =		"Analog Source Capture Enum",
600 		.info =		snd_ca0106_i2c_capture_source_info,
601 		.get =		snd_ca0106_i2c_capture_source_get,
602 		.put =		snd_ca0106_i2c_capture_source_put
603 	},
604 	{
605 		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
606 		.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
607 		.count =	4,
608 		.info =         snd_ca0106_spdif_info,
609 		.get =          snd_ca0106_spdif_get_default,
610 		.put =          snd_ca0106_spdif_put_default
611 	},
612 	{
613 		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
614 		.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
615 		.count =	4,
616 		.info =         snd_ca0106_spdif_info,
617 		.get =          snd_ca0106_spdif_get_stream,
618 		.put =          snd_ca0106_spdif_put_stream
619 	},
620 };
621 
622 #define I2C_VOLUME(xname,chid) \
623 {								\
624 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\
625 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |		\
626 	          SNDRV_CTL_ELEM_ACCESS_TLV_READ,		\
627 	.info =  snd_ca0106_i2c_volume_info,			\
628 	.get =   snd_ca0106_i2c_volume_get,			\
629 	.put =   snd_ca0106_i2c_volume_put,			\
630 	.tlv = { .p = snd_ca0106_db_scale2 },			\
631 	.private_value = chid					\
632 }
633 
634 static const struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] = {
635         I2C_VOLUME("Phone Capture Volume", 0),
636         I2C_VOLUME("Mic Capture Volume", 1),
637         I2C_VOLUME("Line in Capture Volume", 2),
638         I2C_VOLUME("Aux Capture Volume", 3),
639 };
640 
641 static const int spi_dmute_reg[] = {
642 	SPI_DMUTE0_REG,
643 	SPI_DMUTE1_REG,
644 	SPI_DMUTE2_REG,
645 	0,
646 	SPI_DMUTE4_REG,
647 };
648 static const int spi_dmute_bit[] = {
649 	SPI_DMUTE0_BIT,
650 	SPI_DMUTE1_BIT,
651 	SPI_DMUTE2_BIT,
652 	0,
653 	SPI_DMUTE4_BIT,
654 };
655 
656 static struct snd_kcontrol_new
657 snd_ca0106_volume_spi_dac_ctl(const struct snd_ca0106_details *details,
658 			      int channel_id)
659 {
660 	struct snd_kcontrol_new spi_switch = {0};
661 	int reg, bit;
662 	int dac_id;
663 
664 	spi_switch.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
665 	spi_switch.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
666 	spi_switch.info = spi_mute_info;
667 	spi_switch.get = spi_mute_get;
668 	spi_switch.put = spi_mute_put;
669 
670 	switch (channel_id) {
671 	case PCM_FRONT_CHANNEL:
672 		spi_switch.name = "Analog Front Playback Switch";
673 		dac_id = (details->spi_dac & 0xf000) >> (4 * 3);
674 		break;
675 	case PCM_REAR_CHANNEL:
676 		spi_switch.name = "Analog Rear Playback Switch";
677 		dac_id = (details->spi_dac & 0x0f00) >> (4 * 2);
678 		break;
679 	case PCM_CENTER_LFE_CHANNEL:
680 		spi_switch.name = "Analog Center/LFE Playback Switch";
681 		dac_id = (details->spi_dac & 0x00f0) >> (4 * 1);
682 		break;
683 	case PCM_UNKNOWN_CHANNEL:
684 		spi_switch.name = "Analog Side Playback Switch";
685 		dac_id = (details->spi_dac & 0x000f) >> (4 * 0);
686 		break;
687 	default:
688 		/* Unused channel */
689 		spi_switch.name = NULL;
690 		dac_id = 0;
691 	}
692 	reg = spi_dmute_reg[dac_id];
693 	bit = spi_dmute_bit[dac_id];
694 
695 	spi_switch.private_value = (reg << SPI_REG_SHIFT) | bit;
696 
697 	return spi_switch;
698 }
699 
700 static int remove_ctl(struct snd_card *card, const char *name)
701 {
702 	struct snd_ctl_elem_id id;
703 	memset(&id, 0, sizeof(id));
704 	strcpy(id.name, name);
705 	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
706 	return snd_ctl_remove_id(card, &id);
707 }
708 
709 static struct snd_kcontrol *ctl_find(struct snd_card *card, const char *name)
710 {
711 	struct snd_ctl_elem_id sid;
712 	memset(&sid, 0, sizeof(sid));
713 	/* FIXME: strcpy is bad. */
714 	strcpy(sid.name, name);
715 	sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
716 	return snd_ctl_find_id(card, &sid);
717 }
718 
719 static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
720 {
721 	struct snd_kcontrol *kctl = ctl_find(card, src);
722 	if (kctl) {
723 		strcpy(kctl->id.name, dst);
724 		return 0;
725 	}
726 	return -ENOENT;
727 }
728 
729 #define ADD_CTLS(emu, ctls)						\
730 	do {								\
731 		int i, _err;						\
732 		for (i = 0; i < ARRAY_SIZE(ctls); i++) {		\
733 			_err = snd_ctl_add(card, snd_ctl_new1(&ctls[i], emu)); \
734 			if (_err < 0)					\
735 				return _err;				\
736 		}							\
737 	} while (0)
738 
739 static
740 DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale, -6375, 25, 1);
741 
742 static const char * const follower_vols[] = {
743 	"Analog Front Playback Volume",
744         "Analog Rear Playback Volume",
745 	"Analog Center/LFE Playback Volume",
746         "Analog Side Playback Volume",
747         "IEC958 Front Playback Volume",
748 	"IEC958 Rear Playback Volume",
749 	"IEC958 Center/LFE Playback Volume",
750 	"IEC958 Unknown Playback Volume",
751         "CAPTURE feedback Playback Volume",
752 	NULL
753 };
754 
755 static const char * const follower_sws[] = {
756 	"Analog Front Playback Switch",
757 	"Analog Rear Playback Switch",
758 	"Analog Center/LFE Playback Switch",
759 	"Analog Side Playback Switch",
760 	"IEC958 Playback Switch",
761 	NULL
762 };
763 
764 static void add_followers(struct snd_card *card,
765 			  struct snd_kcontrol *master, const char * const *list)
766 {
767 	for (; *list; list++) {
768 		struct snd_kcontrol *follower = ctl_find(card, *list);
769 		if (follower)
770 			snd_ctl_add_follower(master, follower);
771 	}
772 }
773 
774 int snd_ca0106_mixer(struct snd_ca0106 *emu)
775 {
776 	int err;
777         struct snd_card *card = emu->card;
778 	const char * const *c;
779 	struct snd_kcontrol *vmaster;
780 	static const char * const ca0106_remove_ctls[] = {
781 		"Master Mono Playback Switch",
782 		"Master Mono Playback Volume",
783 		"3D Control - Switch",
784 		"3D Control Sigmatel - Depth",
785 		"PCM Playback Switch",
786 		"PCM Playback Volume",
787 		"CD Playback Switch",
788 		"CD Playback Volume",
789 		"Phone Playback Switch",
790 		"Phone Playback Volume",
791 		"Video Playback Switch",
792 		"Video Playback Volume",
793 		"Beep Playback Switch",
794 		"Beep Playback Volume",
795 		"Mono Output Select",
796 		"Capture Source",
797 		"Capture Switch",
798 		"Capture Volume",
799 		"External Amplifier",
800 		"Sigmatel 4-Speaker Stereo Playback Switch",
801 		"Surround Phase Inversion Playback Switch",
802 		NULL
803 	};
804 	static const char * const ca0106_rename_ctls[] = {
805 		"Master Playback Switch", "Capture Switch",
806 		"Master Playback Volume", "Capture Volume",
807 		"Line Playback Switch", "AC97 Line Capture Switch",
808 		"Line Playback Volume", "AC97 Line Capture Volume",
809 		"Aux Playback Switch", "AC97 Aux Capture Switch",
810 		"Aux Playback Volume", "AC97 Aux Capture Volume",
811 		"Mic Playback Switch", "AC97 Mic Capture Switch",
812 		"Mic Playback Volume", "AC97 Mic Capture Volume",
813 		"Mic Select", "AC97 Mic Select",
814 		"Mic Boost (+20dB)", "AC97 Mic Boost (+20dB)",
815 		NULL
816 	};
817 #if 1
818 	for (c = ca0106_remove_ctls; *c; c++)
819 		remove_ctl(card, *c);
820 	for (c = ca0106_rename_ctls; *c; c += 2)
821 		rename_ctl(card, c[0], c[1]);
822 #endif
823 
824 	ADD_CTLS(emu, snd_ca0106_volume_ctls);
825 	if (emu->details->i2c_adc == 1) {
826 		ADD_CTLS(emu, snd_ca0106_volume_i2c_adc_ctls);
827 		if (emu->details->gpio_type == 1)
828 			err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu));
829 		else  /* gpio_type == 2 */
830 			err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_line_in_side_out, emu));
831 		if (err < 0)
832 			return err;
833 	}
834 	if (emu->details->spi_dac) {
835 		int i;
836 		for (i = 0;; i++) {
837 			struct snd_kcontrol_new ctl;
838 			ctl = snd_ca0106_volume_spi_dac_ctl(emu->details, i);
839 			if (!ctl.name)
840 				break;
841 			err = snd_ctl_add(card, snd_ctl_new1(&ctl, emu));
842 			if (err < 0)
843 				return err;
844 		}
845 	}
846 
847 	/* Create virtual master controls */
848 	vmaster = snd_ctl_make_virtual_master("Master Playback Volume",
849 					      snd_ca0106_master_db_scale);
850 	if (!vmaster)
851 		return -ENOMEM;
852 	err = snd_ctl_add(card, vmaster);
853 	if (err < 0)
854 		return err;
855 	add_followers(card, vmaster, follower_vols);
856 
857 	if (emu->details->spi_dac) {
858 		vmaster = snd_ctl_make_virtual_master("Master Playback Switch",
859 						      NULL);
860 		if (!vmaster)
861 			return -ENOMEM;
862 		err = snd_ctl_add(card, vmaster);
863 		if (err < 0)
864 			return err;
865 		add_followers(card, vmaster, follower_sws);
866 	}
867 
868 	strcpy(card->mixername, "CA0106");
869         return 0;
870 }
871 
872 #ifdef CONFIG_PM_SLEEP
873 struct ca0106_vol_tbl {
874 	unsigned int channel_id;
875 	unsigned int reg;
876 };
877 
878 static const struct ca0106_vol_tbl saved_volumes[NUM_SAVED_VOLUMES] = {
879 	{ CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2 },
880 	{ CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2 },
881 	{ CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2 },
882 	{ CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2 },
883 	{ CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1 },
884 	{ CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1 },
885 	{ CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1 },
886 	{ CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1 },
887 	{ 1, CAPTURE_CONTROL },
888 };
889 
890 void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip)
891 {
892 	int i;
893 
894 	/* save volumes */
895 	for (i = 0; i < NUM_SAVED_VOLUMES; i++)
896 		chip->saved_vol[i] =
897 			snd_ca0106_ptr_read(chip, saved_volumes[i].reg,
898 					    saved_volumes[i].channel_id);
899 }
900 
901 void snd_ca0106_mixer_resume(struct snd_ca0106  *chip)
902 {
903 	int i;
904 
905 	for (i = 0; i < NUM_SAVED_VOLUMES; i++)
906 		snd_ca0106_ptr_write(chip, saved_volumes[i].reg,
907 				     saved_volumes[i].channel_id,
908 				     chip->saved_vol[i]);
909 
910 	ca0106_spdif_enable(chip);
911 	ca0106_set_capture_source(chip);
912 	ca0106_set_i2c_capture_source(chip, chip->i2c_capture_source, 1);
913 	for (i = 0; i < 4; i++)
914 		ca0106_set_spdif_bits(chip, i);
915 	if (chip->details->i2c_adc)
916 		ca0106_set_capture_mic_line_in(chip);
917 }
918 #endif /* CONFIG_PM_SLEEP */
919