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