Linux Audio

Check our new training course

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