1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
4 *
5 *   Lowlevel functions for Terratec Aureon cards
6 *
7 *	Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
8 *
9 * NOTES:
10 *
11 * - we reuse the struct snd_akm4xxx record for storing the wm8770 codec data.
12 *   both wm and akm codecs are pretty similar, so we can integrate
13 *   both controls in the future, once if wm codecs are reused in
14 *   many boards.
15 *
16 * - DAC digital volumes are not implemented in the mixer.
17 *   if they show better response than DAC analog volumes, we can use them
18 *   instead.
19 *
20 *   Lowlevel functions for AudioTrak Prodigy 7.1 (and possibly 192) cards
21 *      Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
22 *
23 *   version 0.82: Stable / not all features work yet (no communication with AC97 secondary)
24 *       added 64x/128x oversampling switch (should be 64x only for 96khz)
25 *       fixed some recording labels (still need to check the rest)
26 *       recording is working probably thanks to correct wm8770 initialization
27 *
28 *   version 0.5: Initial release:
29 *           working: analog output, mixer, headphone amplifier switch
30 *       not working: prety much everything else, at least i could verify that
31 *                    we have no digital output, no capture, pretty bad clicks and poops
32 *                    on mixer switch and other coll stuff.
33 */
34
35#include <linux/delay.h>
36#include <linux/interrupt.h>
37#include <linux/init.h>
38#include <linux/slab.h>
39#include <linux/mutex.h>
40
41#include <sound/core.h>
42
43#include "ice1712.h"
44#include "envy24ht.h"
45#include "aureon.h"
46#include <sound/tlv.h>
47
48/* AC97 register cache for Aureon */
49struct aureon_spec {
50	unsigned short stac9744[64];
51	unsigned int cs8415_mux;
52	unsigned short master[2];
53	unsigned short vol[8];
54	unsigned char pca9554_out;
55};
56
57/* WM8770 registers */
58#define WM_DAC_ATTEN		0x00	/* DAC1-8 analog attenuation */
59#define WM_DAC_MASTER_ATTEN	0x08	/* DAC master analog attenuation */
60#define WM_DAC_DIG_ATTEN	0x09	/* DAC1-8 digital attenuation */
61#define WM_DAC_DIG_MASTER_ATTEN	0x11	/* DAC master digital attenuation */
62#define WM_PHASE_SWAP		0x12	/* DAC phase */
63#define WM_DAC_CTRL1		0x13	/* DAC control bits */
64#define WM_MUTE			0x14	/* mute controls */
65#define WM_DAC_CTRL2		0x15	/* de-emphasis and zefo-flag */
66#define WM_INT_CTRL		0x16	/* interface control */
67#define WM_MASTER		0x17	/* master clock and mode */
68#define WM_POWERDOWN		0x18	/* power-down controls */
69#define WM_ADC_GAIN		0x19	/* ADC gain L(19)/R(1a) */
70#define WM_ADC_MUX		0x1b	/* input MUX */
71#define WM_OUT_MUX1		0x1c	/* output MUX */
72#define WM_OUT_MUX2		0x1e	/* output MUX */
73#define WM_RESET		0x1f	/* software reset */
74
75/* CS8415A registers */
76#define CS8415_CTRL1	0x01
77#define CS8415_CTRL2	0x02
78#define CS8415_QSUB		0x14
79#define CS8415_RATIO	0x1E
80#define CS8415_C_BUFFER	0x20
81#define CS8415_ID		0x7F
82
83/* PCA9554 registers */
84#define PCA9554_DEV     0x40            /* I2C device address */
85#define PCA9554_IN      0x00            /* input port */
86#define PCA9554_OUT     0x01            /* output port */
87#define PCA9554_INVERT  0x02            /* input invert */
88#define PCA9554_DIR     0x03            /* port directions */
89
90/*
91 * Aureon Universe additional controls using PCA9554
92 */
93
94/*
95 * Send data to pca9554
96 */
97static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
98				 unsigned char data)
99{
100	unsigned int tmp;
101	int i, j;
102	unsigned char dev = PCA9554_DEV;  /* ID 0100000, write */
103	unsigned char val = 0;
104
105	tmp = snd_ice1712_gpio_read(ice);
106
107	snd_ice1712_gpio_set_mask(ice, ~(AUREON_SPI_MOSI|AUREON_SPI_CLK|
108					 AUREON_WM_RW|AUREON_WM_CS|
109					 AUREON_CS8415_CS));
110	tmp |= AUREON_WM_RW;
111	tmp |= AUREON_CS8415_CS | AUREON_WM_CS; /* disable SPI devices */
112
113	tmp &= ~AUREON_SPI_MOSI;
114	tmp &= ~AUREON_SPI_CLK;
115	snd_ice1712_gpio_write(ice, tmp);
116	udelay(50);
117
118	/*
119	 * send i2c stop condition and start condition
120	 * to obtain sane state
121	 */
122	tmp |= AUREON_SPI_CLK;
123	snd_ice1712_gpio_write(ice, tmp);
124	udelay(50);
125	tmp |= AUREON_SPI_MOSI;
126	snd_ice1712_gpio_write(ice, tmp);
127	udelay(100);
128	tmp &= ~AUREON_SPI_MOSI;
129	snd_ice1712_gpio_write(ice, tmp);
130	udelay(50);
131	tmp &= ~AUREON_SPI_CLK;
132	snd_ice1712_gpio_write(ice, tmp);
133	udelay(100);
134	/*
135	 * send device address, command and value,
136	 * skipping ack cycles in between
137	 */
138	for (j = 0; j < 3; j++) {
139		switch (j) {
140		case 0:
141			val = dev;
142			break;
143		case 1:
144			val = reg;
145			break;
146		case 2:
147			val = data;
148			break;
149		}
150		for (i = 7; i >= 0; i--) {
151			tmp &= ~AUREON_SPI_CLK;
152			snd_ice1712_gpio_write(ice, tmp);
153			udelay(40);
154			if (val & (1 << i))
155				tmp |= AUREON_SPI_MOSI;
156			else
157				tmp &= ~AUREON_SPI_MOSI;
158			snd_ice1712_gpio_write(ice, tmp);
159			udelay(40);
160			tmp |= AUREON_SPI_CLK;
161			snd_ice1712_gpio_write(ice, tmp);
162			udelay(40);
163		}
164		tmp &= ~AUREON_SPI_CLK;
165		snd_ice1712_gpio_write(ice, tmp);
166		udelay(40);
167		tmp |= AUREON_SPI_CLK;
168		snd_ice1712_gpio_write(ice, tmp);
169		udelay(40);
170		tmp &= ~AUREON_SPI_CLK;
171		snd_ice1712_gpio_write(ice, tmp);
172		udelay(40);
173	}
174	tmp &= ~AUREON_SPI_CLK;
175	snd_ice1712_gpio_write(ice, tmp);
176	udelay(40);
177	tmp &= ~AUREON_SPI_MOSI;
178	snd_ice1712_gpio_write(ice, tmp);
179	udelay(40);
180	tmp |= AUREON_SPI_CLK;
181	snd_ice1712_gpio_write(ice, tmp);
182	udelay(50);
183	tmp |= AUREON_SPI_MOSI;
184	snd_ice1712_gpio_write(ice, tmp);
185	udelay(100);
186}
187
188static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,
189				      struct snd_ctl_elem_info *uinfo)
190{
191	static const char * const texts[3] =
192		{"Internal Aux", "Wavetable", "Rear Line-In"};
193
194	return snd_ctl_enum_info(uinfo, 1, 3, texts);
195}
196
197static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol,
198				     struct snd_ctl_elem_value *ucontrol)
199{
200	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
201	struct aureon_spec *spec = ice->spec;
202	ucontrol->value.enumerated.item[0] = spec->pca9554_out;
203	return 0;
204}
205
206static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
207				     struct snd_ctl_elem_value *ucontrol)
208{
209	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
210	struct aureon_spec *spec = ice->spec;
211	unsigned char oval, nval;
212	int change;
213
214	nval = ucontrol->value.enumerated.item[0];
215	if (nval >= 3)
216		return -EINVAL;
217	snd_ice1712_save_gpio_status(ice);
218	oval = spec->pca9554_out;
219	change = (oval != nval);
220	if (change) {
221		aureon_pca9554_write(ice, PCA9554_OUT, nval);
222		spec->pca9554_out = nval;
223	}
224	snd_ice1712_restore_gpio_status(ice);
225	return change;
226}
227
228
229static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
230			      unsigned short val)
231{
232	struct aureon_spec *spec = ice->spec;
233	unsigned int tmp;
234
235	/* Send address to XILINX chip */
236	tmp = (snd_ice1712_gpio_read(ice) & ~0xFF) | (reg & 0x7F);
237	snd_ice1712_gpio_write(ice, tmp);
238	udelay(10);
239	tmp |= AUREON_AC97_ADDR;
240	snd_ice1712_gpio_write(ice, tmp);
241	udelay(10);
242	tmp &= ~AUREON_AC97_ADDR;
243	snd_ice1712_gpio_write(ice, tmp);
244	udelay(10);
245
246	/* Send low-order byte to XILINX chip */
247	tmp &= ~AUREON_AC97_DATA_MASK;
248	tmp |= val & AUREON_AC97_DATA_MASK;
249	snd_ice1712_gpio_write(ice, tmp);
250	udelay(10);
251	tmp |= AUREON_AC97_DATA_LOW;
252	snd_ice1712_gpio_write(ice, tmp);
253	udelay(10);
254	tmp &= ~AUREON_AC97_DATA_LOW;
255	snd_ice1712_gpio_write(ice, tmp);
256	udelay(10);
257
258	/* Send high-order byte to XILINX chip */
259	tmp &= ~AUREON_AC97_DATA_MASK;
260	tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
261
262	snd_ice1712_gpio_write(ice, tmp);
263	udelay(10);
264	tmp |= AUREON_AC97_DATA_HIGH;
265	snd_ice1712_gpio_write(ice, tmp);
266	udelay(10);
267	tmp &= ~AUREON_AC97_DATA_HIGH;
268	snd_ice1712_gpio_write(ice, tmp);
269	udelay(10);
270
271	/* Instruct XILINX chip to parse the data to the STAC9744 chip */
272	tmp |= AUREON_AC97_COMMIT;
273	snd_ice1712_gpio_write(ice, tmp);
274	udelay(10);
275	tmp &= ~AUREON_AC97_COMMIT;
276	snd_ice1712_gpio_write(ice, tmp);
277	udelay(10);
278
279	/* Store the data in out private buffer */
280	spec->stac9744[(reg & 0x7F) >> 1] = val;
281}
282
283static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short reg)
284{
285	struct aureon_spec *spec = ice->spec;
286	return spec->stac9744[(reg & 0x7F) >> 1];
287}
288
289/*
290 * Initialize STAC9744 chip
291 */
292static int aureon_ac97_init(struct snd_ice1712 *ice)
293{
294	struct aureon_spec *spec = ice->spec;
295	int i;
296	static const unsigned short ac97_defaults[] = {
297		0x00, 0x9640,
298		0x02, 0x8000,
299		0x04, 0x8000,
300		0x06, 0x8000,
301		0x0C, 0x8008,
302		0x0E, 0x8008,
303		0x10, 0x8808,
304		0x12, 0x8808,
305		0x14, 0x8808,
306		0x16, 0x8808,
307		0x18, 0x8808,
308		0x1C, 0x8000,
309		0x26, 0x000F,
310		0x28, 0x0201,
311		0x2C, 0xBB80,
312		0x32, 0xBB80,
313		0x7C, 0x8384,
314		0x7E, 0x7644,
315		(unsigned short)-1
316	};
317	unsigned int tmp;
318
319	/* Cold reset */
320	tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
321	snd_ice1712_gpio_write(ice, tmp);
322	udelay(3);
323
324	tmp &= ~AUREON_AC97_RESET;
325	snd_ice1712_gpio_write(ice, tmp);
326	udelay(3);
327
328	tmp |= AUREON_AC97_RESET;
329	snd_ice1712_gpio_write(ice, tmp);
330	udelay(3);
331
332	memset(&spec->stac9744, 0, sizeof(spec->stac9744));
333	for (i = 0; ac97_defaults[i] != (unsigned short)-1; i += 2)
334		spec->stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
335
336	/* Unmute AC'97 master volume permanently - muting is done by WM8770 */
337	aureon_ac97_write(ice, AC97_MASTER, 0x0000);
338
339	return 0;
340}
341
342#define AUREON_AC97_STEREO	0x80
343
344/*
345 * AC'97 volume controls
346 */
347static int aureon_ac97_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
348{
349	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
350	uinfo->count = kcontrol->private_value & AUREON_AC97_STEREO ? 2 : 1;
351	uinfo->value.integer.min = 0;
352	uinfo->value.integer.max = 31;
353	return 0;
354}
355
356static int aureon_ac97_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
357{
358	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
359	unsigned short vol;
360
361	mutex_lock(&ice->gpio_mutex);
362
363	vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
364	ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F);
365	if (kcontrol->private_value & AUREON_AC97_STEREO)
366		ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F);
367
368	mutex_unlock(&ice->gpio_mutex);
369	return 0;
370}
371
372static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
373{
374	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
375	unsigned short ovol, nvol;
376	int change;
377
378	snd_ice1712_save_gpio_status(ice);
379
380	ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
381	nvol = (0x1F - ucontrol->value.integer.value[0]) & 0x001F;
382	if (kcontrol->private_value & AUREON_AC97_STEREO)
383		nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00;
384	nvol |= ovol & ~0x1F1F;
385
386	change = (ovol != nvol);
387	if (change)
388		aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
389
390	snd_ice1712_restore_gpio_status(ice);
391
392	return change;
393}
394
395/*
396 * AC'97 mute controls
397 */
398#define aureon_ac97_mute_info	snd_ctl_boolean_mono_info
399
400static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
401{
402	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
403
404	mutex_lock(&ice->gpio_mutex);
405
406	ucontrol->value.integer.value[0] = aureon_ac97_read(ice,
407			kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
408
409	mutex_unlock(&ice->gpio_mutex);
410	return 0;
411}
412
413static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
414{
415	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
416	unsigned short ovol, nvol;
417	int change;
418
419	snd_ice1712_save_gpio_status(ice);
420
421	ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
422	nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~0x8000);
423
424	change = (ovol != nvol);
425	if (change)
426		aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
427
428	snd_ice1712_restore_gpio_status(ice);
429
430	return change;
431}
432
433/*
434 * AC'97 mute controls
435 */
436#define aureon_ac97_micboost_info	snd_ctl_boolean_mono_info
437
438static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
439{
440	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
441
442	mutex_lock(&ice->gpio_mutex);
443
444	ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
445
446	mutex_unlock(&ice->gpio_mutex);
447	return 0;
448}
449
450static int aureon_ac97_micboost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
451{
452	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
453	unsigned short ovol, nvol;
454	int change;
455
456	snd_ice1712_save_gpio_status(ice);
457
458	ovol = aureon_ac97_read(ice, AC97_MIC);
459	nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020);
460
461	change = (ovol != nvol);
462	if (change)
463		aureon_ac97_write(ice, AC97_MIC, nvol);
464
465	snd_ice1712_restore_gpio_status(ice);
466
467	return change;
468}
469
470/*
471 * write data in the SPI mode
472 */
473static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits)
474{
475	unsigned int tmp;
476	int i;
477	unsigned int mosi, clk;
478
479	tmp = snd_ice1712_gpio_read(ice);
480
481	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
482	    ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) {
483		snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS));
484		mosi = PRODIGY_SPI_MOSI;
485		clk = PRODIGY_SPI_CLK;
486	} else {
487		snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
488						 AUREON_WM_CS|AUREON_CS8415_CS));
489		mosi = AUREON_SPI_MOSI;
490		clk = AUREON_SPI_CLK;
491
492		tmp |= AUREON_WM_RW;
493	}
494
495	tmp &= ~cs;
496	snd_ice1712_gpio_write(ice, tmp);
497	udelay(1);
498
499	for (i = bits - 1; i >= 0; i--) {
500		tmp &= ~clk;
501		snd_ice1712_gpio_write(ice, tmp);
502		udelay(1);
503		if (data & (1 << i))
504			tmp |= mosi;
505		else
506			tmp &= ~mosi;
507		snd_ice1712_gpio_write(ice, tmp);
508		udelay(1);
509		tmp |= clk;
510		snd_ice1712_gpio_write(ice, tmp);
511		udelay(1);
512	}
513
514	tmp &= ~clk;
515	tmp |= cs;
516	snd_ice1712_gpio_write(ice, tmp);
517	udelay(1);
518	tmp |= clk;
519	snd_ice1712_gpio_write(ice, tmp);
520	udelay(1);
521}
522
523/*
524 * Read data in SPI mode
525 */
526static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs,
527		unsigned int data, int bits, unsigned char *buffer, int size)
528{
529	int i, j;
530	unsigned int tmp;
531
532	tmp = (snd_ice1712_gpio_read(ice) & ~AUREON_SPI_CLK) | AUREON_CS8415_CS|AUREON_WM_CS;
533	snd_ice1712_gpio_write(ice, tmp);
534	tmp &= ~cs;
535	snd_ice1712_gpio_write(ice, tmp);
536	udelay(1);
537
538	for (i = bits-1; i >= 0; i--) {
539		if (data & (1 << i))
540			tmp |= AUREON_SPI_MOSI;
541		else
542			tmp &= ~AUREON_SPI_MOSI;
543		snd_ice1712_gpio_write(ice, tmp);
544		udelay(1);
545
546		tmp |= AUREON_SPI_CLK;
547		snd_ice1712_gpio_write(ice, tmp);
548		udelay(1);
549
550		tmp &= ~AUREON_SPI_CLK;
551		snd_ice1712_gpio_write(ice, tmp);
552		udelay(1);
553	}
554
555	for (j = 0; j < size; j++) {
556		unsigned char outdata = 0;
557		for (i = 7; i >= 0; i--) {
558			tmp = snd_ice1712_gpio_read(ice);
559			outdata <<= 1;
560			outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0;
561			udelay(1);
562
563			tmp |= AUREON_SPI_CLK;
564			snd_ice1712_gpio_write(ice, tmp);
565			udelay(1);
566
567			tmp &= ~AUREON_SPI_CLK;
568			snd_ice1712_gpio_write(ice, tmp);
569			udelay(1);
570		}
571		buffer[j] = outdata;
572	}
573
574	tmp |= cs;
575	snd_ice1712_gpio_write(ice, tmp);
576}
577
578static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg)
579{
580	unsigned char val;
581	aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
582	aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1);
583	return val;
584}
585
586static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg,
587				unsigned char *buffer, int size)
588{
589	aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
590	aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size);
591}
592
593static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg,
594						unsigned char val)
595{
596	aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24);
597}
598
599/*
600 * get the current register value of WM codec
601 */
602static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
603{
604	reg <<= 1;
605	return ((unsigned short)ice->akm[0].images[reg] << 8) |
606		ice->akm[0].images[reg + 1];
607}
608
609/*
610 * set the register value of WM codec
611 */
612static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
613{
614	aureon_spi_write(ice,
615			 ((ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
616			   ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) ?
617			 PRODIGY_WM_CS : AUREON_WM_CS),
618			(reg << 9) | (val & 0x1ff), 16);
619}
620
621/*
622 * set the register value of WM codec and remember it
623 */
624static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
625{
626	wm_put_nocache(ice, reg, val);
627	reg <<= 1;
628	ice->akm[0].images[reg] = val >> 8;
629	ice->akm[0].images[reg + 1] = val;
630}
631
632/*
633 */
634#define aureon_mono_bool_info		snd_ctl_boolean_mono_info
635
636/*
637 * AC'97 master playback mute controls (Mute on WM8770 chip)
638 */
639#define aureon_ac97_mmute_info		snd_ctl_boolean_mono_info
640
641static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
642{
643	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
644
645	mutex_lock(&ice->gpio_mutex);
646
647	ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
648
649	mutex_unlock(&ice->gpio_mutex);
650	return 0;
651}
652
653static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
654{
655	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
656	unsigned short ovol, nvol;
657	int change;
658
659	snd_ice1712_save_gpio_status(ice);
660
661	ovol = wm_get(ice, WM_OUT_MUX1);
662	nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00);
663	change = (ovol != nvol);
664	if (change)
665		wm_put(ice, WM_OUT_MUX1, nvol);
666
667	snd_ice1712_restore_gpio_status(ice);
668
669	return change;
670}
671
672static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -10000, 100, 1);
673static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
674static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0);
675static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0);
676static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0);
677
678#define WM_VOL_MAX	100
679#define WM_VOL_CNT	101	/* 0dB .. -100dB */
680#define WM_VOL_MUTE	0x8000
681
682static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
683{
684	unsigned char nvol;
685
686	if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) {
687		nvol = 0;
688	} else {
689		nvol = ((vol % WM_VOL_CNT) * (master % WM_VOL_CNT)) /
690								WM_VOL_MAX;
691		nvol += 0x1b;
692	}
693
694	wm_put(ice, index, nvol);
695	wm_put_nocache(ice, index, 0x180 | nvol);
696}
697
698/*
699 * DAC mute control
700 */
701#define wm_pcm_mute_info	snd_ctl_boolean_mono_info
702
703static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
704{
705	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
706
707	mutex_lock(&ice->gpio_mutex);
708	ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
709	mutex_unlock(&ice->gpio_mutex);
710	return 0;
711}
712
713static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
714{
715	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
716	unsigned short nval, oval;
717	int change;
718
719	snd_ice1712_save_gpio_status(ice);
720	oval = wm_get(ice, WM_MUTE);
721	nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
722	change = (oval != nval);
723	if (change)
724		wm_put(ice, WM_MUTE, nval);
725	snd_ice1712_restore_gpio_status(ice);
726
727	return change;
728}
729
730/*
731 * Master volume attenuation mixer control
732 */
733static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
734{
735	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
736	uinfo->count = 2;
737	uinfo->value.integer.min = 0;
738	uinfo->value.integer.max = WM_VOL_MAX;
739	return 0;
740}
741
742static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
743{
744	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
745	struct aureon_spec *spec = ice->spec;
746	int i;
747	for (i = 0; i < 2; i++)
748		ucontrol->value.integer.value[i] =
749			spec->master[i] & ~WM_VOL_MUTE;
750	return 0;
751}
752
753static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
754{
755	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
756	struct aureon_spec *spec = ice->spec;
757	int ch, change = 0;
758
759	snd_ice1712_save_gpio_status(ice);
760	for (ch = 0; ch < 2; ch++) {
761		unsigned int vol = ucontrol->value.integer.value[ch];
762		if (vol > WM_VOL_MAX)
763			vol = WM_VOL_MAX;
764		vol |= spec->master[ch] & WM_VOL_MUTE;
765		if (vol != spec->master[ch]) {
766			int dac;
767			spec->master[ch] = vol;
768			for (dac = 0; dac < ice->num_total_dacs; dac += 2)
769				wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
770					   spec->vol[dac + ch],
771					   spec->master[ch]);
772			change = 1;
773		}
774	}
775	snd_ice1712_restore_gpio_status(ice);
776	return change;
777}
778
779/*
780 * DAC volume attenuation mixer control
781 */
782static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
783{
784	int voices = kcontrol->private_value >> 8;
785	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
786	uinfo->count = voices;
787	uinfo->value.integer.min = 0;		/* mute (-101dB) */
788	uinfo->value.integer.max = WM_VOL_MAX;	/* 0dB */
789	return 0;
790}
791
792static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
793{
794	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
795	struct aureon_spec *spec = ice->spec;
796	int i, ofs, voices;
797
798	voices = kcontrol->private_value >> 8;
799	ofs = kcontrol->private_value & 0xff;
800	for (i = 0; i < voices; i++)
801		ucontrol->value.integer.value[i] =
802			spec->vol[ofs+i] & ~WM_VOL_MUTE;
803	return 0;
804}
805
806static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
807{
808	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
809	struct aureon_spec *spec = ice->spec;
810	int i, idx, ofs, voices;
811	int change = 0;
812
813	voices = kcontrol->private_value >> 8;
814	ofs = kcontrol->private_value & 0xff;
815	snd_ice1712_save_gpio_status(ice);
816	for (i = 0; i < voices; i++) {
817		unsigned int vol = ucontrol->value.integer.value[i];
818		if (vol > WM_VOL_MAX)
819			vol = WM_VOL_MAX;
820		vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
821		if (vol != spec->vol[ofs+i]) {
822			spec->vol[ofs+i] = vol;
823			idx  = WM_DAC_ATTEN + ofs + i;
824			wm_set_vol(ice, idx, spec->vol[ofs + i],
825				   spec->master[i]);
826			change = 1;
827		}
828	}
829	snd_ice1712_restore_gpio_status(ice);
830	return change;
831}
832
833/*
834 * WM8770 mute control
835 */
836static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
837{
838	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
839	uinfo->count = kcontrol->private_value >> 8;
840	uinfo->value.integer.min = 0;
841	uinfo->value.integer.max = 1;
842	return 0;
843}
844
845static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
846{
847	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
848	struct aureon_spec *spec = ice->spec;
849	int voices, ofs, i;
850
851	voices = kcontrol->private_value >> 8;
852	ofs = kcontrol->private_value & 0xFF;
853
854	for (i = 0; i < voices; i++)
855		ucontrol->value.integer.value[i] =
856			(spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
857	return 0;
858}
859
860static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
861{
862	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
863	struct aureon_spec *spec = ice->spec;
864	int change = 0, voices, ofs, i;
865
866	voices = kcontrol->private_value >> 8;
867	ofs = kcontrol->private_value & 0xFF;
868
869	snd_ice1712_save_gpio_status(ice);
870	for (i = 0; i < voices; i++) {
871		int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
872		if (ucontrol->value.integer.value[i] != val) {
873			spec->vol[ofs + i] &= ~WM_VOL_MUTE;
874			spec->vol[ofs + i] |=
875				ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
876			wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
877				   spec->master[i]);
878			change = 1;
879		}
880	}
881	snd_ice1712_restore_gpio_status(ice);
882
883	return change;
884}
885
886/*
887 * WM8770 master mute control
888 */
889#define wm_master_mute_info		snd_ctl_boolean_stereo_info
890
891static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
892{
893	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
894	struct aureon_spec *spec = ice->spec;
895
896	ucontrol->value.integer.value[0] =
897		(spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
898	ucontrol->value.integer.value[1] =
899		(spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
900	return 0;
901}
902
903static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
904{
905	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
906	struct aureon_spec *spec = ice->spec;
907	int change = 0, i;
908
909	snd_ice1712_save_gpio_status(ice);
910	for (i = 0; i < 2; i++) {
911		int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
912		if (ucontrol->value.integer.value[i] != val) {
913			int dac;
914			spec->master[i] &= ~WM_VOL_MUTE;
915			spec->master[i] |=
916				ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
917			for (dac = 0; dac < ice->num_total_dacs; dac += 2)
918				wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
919					   spec->vol[dac + i],
920					   spec->master[i]);
921			change = 1;
922		}
923	}
924	snd_ice1712_restore_gpio_status(ice);
925
926	return change;
927}
928
929/* digital master volume */
930#define PCM_0dB 0xff
931#define PCM_RES 128	/* -64dB */
932#define PCM_MIN (PCM_0dB - PCM_RES)
933static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
934{
935	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
936	uinfo->count = 1;
937	uinfo->value.integer.min = 0;		/* mute (-64dB) */
938	uinfo->value.integer.max = PCM_RES;	/* 0dB */
939	return 0;
940}
941
942static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
943{
944	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
945	unsigned short val;
946
947	mutex_lock(&ice->gpio_mutex);
948	val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
949	val = val > PCM_MIN ? (val - PCM_MIN) : 0;
950	ucontrol->value.integer.value[0] = val;
951	mutex_unlock(&ice->gpio_mutex);
952	return 0;
953}
954
955static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
956{
957	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
958	unsigned short ovol, nvol;
959	int change = 0;
960
961	nvol = ucontrol->value.integer.value[0];
962	if (nvol > PCM_RES)
963		return -EINVAL;
964	snd_ice1712_save_gpio_status(ice);
965	nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
966	ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
967	if (ovol != nvol) {
968		wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
969		wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
970		change = 1;
971	}
972	snd_ice1712_restore_gpio_status(ice);
973	return change;
974}
975
976/*
977 * ADC mute control
978 */
979#define wm_adc_mute_info		snd_ctl_boolean_stereo_info
980
981static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
982{
983	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
984	unsigned short val;
985	int i;
986
987	mutex_lock(&ice->gpio_mutex);
988	for (i = 0; i < 2; i++) {
989		val = wm_get(ice, WM_ADC_GAIN + i);
990		ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
991	}
992	mutex_unlock(&ice->gpio_mutex);
993	return 0;
994}
995
996static int wm_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
997{
998	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
999	unsigned short new, old;
1000	int i, change = 0;
1001
1002	snd_ice1712_save_gpio_status(ice);
1003	for (i = 0; i < 2; i++) {
1004		old = wm_get(ice, WM_ADC_GAIN + i);
1005		new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
1006		if (new != old) {
1007			wm_put(ice, WM_ADC_GAIN + i, new);
1008			change = 1;
1009		}
1010	}
1011	snd_ice1712_restore_gpio_status(ice);
1012
1013	return change;
1014}
1015
1016/*
1017 * ADC gain mixer control
1018 */
1019static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1020{
1021	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1022	uinfo->count = 2;
1023	uinfo->value.integer.min = 0;		/* -12dB */
1024	uinfo->value.integer.max = 0x1f;	/* 19dB */
1025	return 0;
1026}
1027
1028static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1029{
1030	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1031	int i, idx;
1032	unsigned short vol;
1033
1034	mutex_lock(&ice->gpio_mutex);
1035	for (i = 0; i < 2; i++) {
1036		idx = WM_ADC_GAIN + i;
1037		vol = wm_get(ice, idx) & 0x1f;
1038		ucontrol->value.integer.value[i] = vol;
1039	}
1040	mutex_unlock(&ice->gpio_mutex);
1041	return 0;
1042}
1043
1044static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1045{
1046	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1047	int i, idx;
1048	unsigned short ovol, nvol;
1049	int change = 0;
1050
1051	snd_ice1712_save_gpio_status(ice);
1052	for (i = 0; i < 2; i++) {
1053		idx  = WM_ADC_GAIN + i;
1054		nvol = ucontrol->value.integer.value[i] & 0x1f;
1055		ovol = wm_get(ice, idx);
1056		if ((ovol & 0x1f) != nvol) {
1057			wm_put(ice, idx, nvol | (ovol & ~0x1f));
1058			change = 1;
1059		}
1060	}
1061	snd_ice1712_restore_gpio_status(ice);
1062	return change;
1063}
1064
1065/*
1066 * ADC input mux mixer control
1067 */
1068static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1069{
1070	static const char * const texts[] = {
1071		"CD",		/* AIN1 */
1072		"Aux",		/* AIN2 */
1073		"Line",		/* AIN3 */
1074		"Mic",		/* AIN4 */
1075		"AC97"		/* AIN5 */
1076	};
1077	static const char * const universe_texts[] = {
1078		"Aux1",		/* AIN1 */
1079		"CD",		/* AIN2 */
1080		"Phono",	/* AIN3 */
1081		"Line",		/* AIN4 */
1082		"Aux2",		/* AIN5 */
1083		"Mic",		/* AIN6 */
1084		"Aux3",		/* AIN7 */
1085		"AC97"		/* AIN8 */
1086	};
1087	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1088
1089	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE)
1090		return snd_ctl_enum_info(uinfo, 2, 8, universe_texts);
1091	else
1092		return snd_ctl_enum_info(uinfo, 2, 5, texts);
1093}
1094
1095static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1096{
1097	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1098	unsigned short val;
1099
1100	mutex_lock(&ice->gpio_mutex);
1101	val = wm_get(ice, WM_ADC_MUX);
1102	ucontrol->value.enumerated.item[0] = val & 7;
1103	ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
1104	mutex_unlock(&ice->gpio_mutex);
1105	return 0;
1106}
1107
1108static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1109{
1110	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1111	unsigned short oval, nval;
1112	int change;
1113
1114	snd_ice1712_save_gpio_status(ice);
1115	oval = wm_get(ice, WM_ADC_MUX);
1116	nval = oval & ~0x77;
1117	nval |= ucontrol->value.enumerated.item[0] & 7;
1118	nval |= (ucontrol->value.enumerated.item[1] & 7) << 4;
1119	change = (oval != nval);
1120	if (change)
1121		wm_put(ice, WM_ADC_MUX, nval);
1122	snd_ice1712_restore_gpio_status(ice);
1123	return change;
1124}
1125
1126/*
1127 * CS8415 Input mux
1128 */
1129static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1130{
1131	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1132	static const char * const aureon_texts[] = {
1133		"CD",		/* RXP0 */
1134		"Optical"	/* RXP1 */
1135	};
1136	static const char * const prodigy_texts[] = {
1137		"CD",
1138		"Coax"
1139	};
1140	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
1141		return snd_ctl_enum_info(uinfo, 1, 2, prodigy_texts);
1142	else
1143		return snd_ctl_enum_info(uinfo, 1, 2, aureon_texts);
1144}
1145
1146static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1147{
1148	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1149	struct aureon_spec *spec = ice->spec;
1150
1151	/* snd_ice1712_save_gpio_status(ice); */
1152	/* val = aureon_cs8415_get(ice, CS8415_CTRL2); */
1153	ucontrol->value.enumerated.item[0] = spec->cs8415_mux;
1154	/* snd_ice1712_restore_gpio_status(ice); */
1155	return 0;
1156}
1157
1158static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1159{
1160	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1161	struct aureon_spec *spec = ice->spec;
1162	unsigned short oval, nval;
1163	int change;
1164
1165	snd_ice1712_save_gpio_status(ice);
1166	oval = aureon_cs8415_get(ice, CS8415_CTRL2);
1167	nval = oval & ~0x07;
1168	nval |= ucontrol->value.enumerated.item[0] & 7;
1169	change = (oval != nval);
1170	if (change)
1171		aureon_cs8415_put(ice, CS8415_CTRL2, nval);
1172	snd_ice1712_restore_gpio_status(ice);
1173	spec->cs8415_mux = ucontrol->value.enumerated.item[0];
1174	return change;
1175}
1176
1177static int aureon_cs8415_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1178{
1179	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1180	uinfo->count = 1;
1181	uinfo->value.integer.min = 0;
1182	uinfo->value.integer.max = 192000;
1183	return 0;
1184}
1185
1186static int aureon_cs8415_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1187{
1188	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1189	unsigned char ratio;
1190	ratio = aureon_cs8415_get(ice, CS8415_RATIO);
1191	ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750);
1192	return 0;
1193}
1194
1195/*
1196 * CS8415A Mute
1197 */
1198#define aureon_cs8415_mute_info		snd_ctl_boolean_mono_info
1199
1200static int aureon_cs8415_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1201{
1202	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1203	snd_ice1712_save_gpio_status(ice);
1204	ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1;
1205	snd_ice1712_restore_gpio_status(ice);
1206	return 0;
1207}
1208
1209static int aureon_cs8415_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1210{
1211	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1212	unsigned char oval, nval;
1213	int change;
1214	snd_ice1712_save_gpio_status(ice);
1215	oval = aureon_cs8415_get(ice, CS8415_CTRL1);
1216	if (ucontrol->value.integer.value[0])
1217		nval = oval & ~0x20;
1218	else
1219		nval = oval | 0x20;
1220	change = (oval != nval);
1221	if (change)
1222		aureon_cs8415_put(ice, CS8415_CTRL1, nval);
1223	snd_ice1712_restore_gpio_status(ice);
1224	return change;
1225}
1226
1227/*
1228 * CS8415A Q-Sub info
1229 */
1230static int aureon_cs8415_qsub_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1231{
1232	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1233	uinfo->count = 10;
1234	return 0;
1235}
1236
1237static int aureon_cs8415_qsub_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1238{
1239	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1240
1241	snd_ice1712_save_gpio_status(ice);
1242	aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
1243	snd_ice1712_restore_gpio_status(ice);
1244
1245	return 0;
1246}
1247
1248static int aureon_cs8415_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1249{
1250	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1251	uinfo->count = 1;
1252	return 0;
1253}
1254
1255static int aureon_cs8415_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1256{
1257	memset(ucontrol->value.iec958.status, 0xFF, 24);
1258	return 0;
1259}
1260
1261static int aureon_cs8415_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1262{
1263	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1264
1265	snd_ice1712_save_gpio_status(ice);
1266	aureon_cs8415_read(ice, CS8415_C_BUFFER, ucontrol->value.iec958.status, 24);
1267	snd_ice1712_restore_gpio_status(ice);
1268	return 0;
1269}
1270
1271/*
1272 * Headphone Amplifier
1273 */
1274static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
1275{
1276	unsigned int tmp, tmp2;
1277
1278	tmp2 = tmp = snd_ice1712_gpio_read(ice);
1279	if (enable)
1280		if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1281		    ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1282			tmp |= AUREON_HP_SEL;
1283		else
1284			tmp |= PRODIGY_HP_SEL;
1285	else
1286		if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1287		    ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1288			tmp &= ~AUREON_HP_SEL;
1289		else
1290			tmp &= ~PRODIGY_HP_SEL;
1291	if (tmp != tmp2) {
1292		snd_ice1712_gpio_write(ice, tmp);
1293		return 1;
1294	}
1295	return 0;
1296}
1297
1298static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
1299{
1300	unsigned int tmp = snd_ice1712_gpio_read(ice);
1301
1302	return (tmp & AUREON_HP_SEL) != 0;
1303}
1304
1305#define aureon_hpamp_info	snd_ctl_boolean_mono_info
1306
1307static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1308{
1309	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1310
1311	ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
1312	return 0;
1313}
1314
1315
1316static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1317{
1318	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1319
1320	return aureon_set_headphone_amp(ice, ucontrol->value.integer.value[0]);
1321}
1322
1323/*
1324 * Deemphasis
1325 */
1326
1327#define aureon_deemp_info	snd_ctl_boolean_mono_info
1328
1329static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1330{
1331	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1332	ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
1333	return 0;
1334}
1335
1336static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1337{
1338	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1339	int temp, temp2;
1340	temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
1341	if (ucontrol->value.integer.value[0])
1342		temp |= 0xf;
1343	else
1344		temp &= ~0xf;
1345	if (temp != temp2) {
1346		wm_put(ice, WM_DAC_CTRL2, temp);
1347		return 1;
1348	}
1349	return 0;
1350}
1351
1352/*
1353 * ADC Oversampling
1354 */
1355static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
1356{
1357	static const char * const texts[2] = { "128x", "64x"	};
1358
1359	return snd_ctl_enum_info(uinfo, 1, 2, texts);
1360}
1361
1362static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1363{
1364	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1365	ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
1366	return 0;
1367}
1368
1369static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1370{
1371	int temp, temp2;
1372	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1373
1374	temp2 = temp = wm_get(ice, WM_MASTER);
1375
1376	if (ucontrol->value.enumerated.item[0])
1377		temp |= 0x8;
1378	else
1379		temp &= ~0x8;
1380
1381	if (temp != temp2) {
1382		wm_put(ice, WM_MASTER, temp);
1383		return 1;
1384	}
1385	return 0;
1386}
1387
1388/*
1389 * mixers
1390 */
1391
1392static const struct snd_kcontrol_new aureon_dac_controls[] = {
1393	{
1394		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1395		.name = "Master Playback Switch",
1396		.info = wm_master_mute_info,
1397		.get = wm_master_mute_get,
1398		.put = wm_master_mute_put
1399	},
1400	{
1401		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1402		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1403				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1404		.name = "Master Playback Volume",
1405		.info = wm_master_vol_info,
1406		.get = wm_master_vol_get,
1407		.put = wm_master_vol_put,
1408		.tlv = { .p = db_scale_wm_dac }
1409	},
1410	{
1411		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1412		.name = "Front Playback Switch",
1413		.info = wm_mute_info,
1414		.get = wm_mute_get,
1415		.put = wm_mute_put,
1416		.private_value = (2 << 8) | 0
1417	},
1418	{
1419		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1420		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1421				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1422		.name = "Front Playback Volume",
1423		.info = wm_vol_info,
1424		.get = wm_vol_get,
1425		.put = wm_vol_put,
1426		.private_value = (2 << 8) | 0,
1427		.tlv = { .p = db_scale_wm_dac }
1428	},
1429	{
1430		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1431		.name = "Rear Playback Switch",
1432		.info = wm_mute_info,
1433		.get = wm_mute_get,
1434		.put = wm_mute_put,
1435		.private_value = (2 << 8) | 2
1436	},
1437	{
1438		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1439		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1440				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1441		.name = "Rear Playback Volume",
1442		.info = wm_vol_info,
1443		.get = wm_vol_get,
1444		.put = wm_vol_put,
1445		.private_value = (2 << 8) | 2,
1446		.tlv = { .p = db_scale_wm_dac }
1447	},
1448	{
1449		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1450		.name = "Center Playback Switch",
1451		.info = wm_mute_info,
1452		.get = wm_mute_get,
1453		.put = wm_mute_put,
1454		.private_value = (1 << 8) | 4
1455	},
1456	{
1457		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1458		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1459				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1460		.name = "Center Playback Volume",
1461		.info = wm_vol_info,
1462		.get = wm_vol_get,
1463		.put = wm_vol_put,
1464		.private_value = (1 << 8) | 4,
1465		.tlv = { .p = db_scale_wm_dac }
1466	},
1467	{
1468		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1469		.name = "LFE Playback Switch",
1470		.info = wm_mute_info,
1471		.get = wm_mute_get,
1472		.put = wm_mute_put,
1473		.private_value = (1 << 8) | 5
1474	},
1475	{
1476		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1477		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1478				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1479		.name = "LFE Playback Volume",
1480		.info = wm_vol_info,
1481		.get = wm_vol_get,
1482		.put = wm_vol_put,
1483		.private_value = (1 << 8) | 5,
1484		.tlv = { .p = db_scale_wm_dac }
1485	},
1486	{
1487		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1488		.name = "Side Playback Switch",
1489		.info = wm_mute_info,
1490		.get = wm_mute_get,
1491		.put = wm_mute_put,
1492		.private_value = (2 << 8) | 6
1493	},
1494	{
1495		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1496		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1497				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1498		.name = "Side Playback Volume",
1499		.info = wm_vol_info,
1500		.get = wm_vol_get,
1501		.put = wm_vol_put,
1502		.private_value = (2 << 8) | 6,
1503		.tlv = { .p = db_scale_wm_dac }
1504	}
1505};
1506
1507static const struct snd_kcontrol_new wm_controls[] = {
1508	{
1509		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1510		.name = "PCM Playback Switch",
1511		.info = wm_pcm_mute_info,
1512		.get = wm_pcm_mute_get,
1513		.put = wm_pcm_mute_put
1514	},
1515	{
1516		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1517		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1518				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1519		.name = "PCM Playback Volume",
1520		.info = wm_pcm_vol_info,
1521		.get = wm_pcm_vol_get,
1522		.put = wm_pcm_vol_put,
1523		.tlv = { .p = db_scale_wm_pcm }
1524	},
1525	{
1526		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1527		.name = "Capture Switch",
1528		.info = wm_adc_mute_info,
1529		.get = wm_adc_mute_get,
1530		.put = wm_adc_mute_put,
1531	},
1532	{
1533		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1534		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1535				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1536		.name = "Capture Volume",
1537		.info = wm_adc_vol_info,
1538		.get = wm_adc_vol_get,
1539		.put = wm_adc_vol_put,
1540		.tlv = { .p = db_scale_wm_adc }
1541	},
1542	{
1543		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1544		.name = "Capture Source",
1545		.info = wm_adc_mux_info,
1546		.get = wm_adc_mux_get,
1547		.put = wm_adc_mux_put,
1548		.private_value = 5
1549	},
1550	{
1551		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1552		.name = "External Amplifier",
1553		.info = aureon_hpamp_info,
1554		.get = aureon_hpamp_get,
1555		.put = aureon_hpamp_put
1556	},
1557	{
1558		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1559		.name = "DAC Deemphasis Switch",
1560		.info = aureon_deemp_info,
1561		.get = aureon_deemp_get,
1562		.put = aureon_deemp_put
1563	},
1564	{
1565		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1566		.name = "ADC Oversampling",
1567		.info = aureon_oversampling_info,
1568		.get = aureon_oversampling_get,
1569		.put = aureon_oversampling_put
1570	}
1571};
1572
1573static const struct snd_kcontrol_new ac97_controls[] = {
1574	{
1575		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1576		.name = "AC97 Playback Switch",
1577		.info = aureon_ac97_mmute_info,
1578		.get = aureon_ac97_mmute_get,
1579		.put = aureon_ac97_mmute_put,
1580		.private_value = AC97_MASTER
1581	},
1582	{
1583		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1584		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1585				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1586		.name = "AC97 Playback Volume",
1587		.info = aureon_ac97_vol_info,
1588		.get = aureon_ac97_vol_get,
1589		.put = aureon_ac97_vol_put,
1590		.private_value = AC97_MASTER|AUREON_AC97_STEREO,
1591		.tlv = { .p = db_scale_ac97_master }
1592	},
1593	{
1594		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1595		.name = "CD Playback Switch",
1596		.info = aureon_ac97_mute_info,
1597		.get = aureon_ac97_mute_get,
1598		.put = aureon_ac97_mute_put,
1599		.private_value = AC97_CD
1600	},
1601	{
1602		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1603		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1604				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1605		.name = "CD Playback Volume",
1606		.info = aureon_ac97_vol_info,
1607		.get = aureon_ac97_vol_get,
1608		.put = aureon_ac97_vol_put,
1609		.private_value = AC97_CD|AUREON_AC97_STEREO,
1610		.tlv = { .p = db_scale_ac97_gain }
1611	},
1612	{
1613		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1614		.name = "Aux Playback Switch",
1615		.info = aureon_ac97_mute_info,
1616		.get = aureon_ac97_mute_get,
1617		.put = aureon_ac97_mute_put,
1618		.private_value = AC97_AUX,
1619	},
1620	{
1621		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1622		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1623				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1624		.name = "Aux Playback Volume",
1625		.info = aureon_ac97_vol_info,
1626		.get = aureon_ac97_vol_get,
1627		.put = aureon_ac97_vol_put,
1628		.private_value = AC97_AUX|AUREON_AC97_STEREO,
1629		.tlv = { .p = db_scale_ac97_gain }
1630	},
1631	{
1632		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1633		.name = "Line Playback Switch",
1634		.info = aureon_ac97_mute_info,
1635		.get = aureon_ac97_mute_get,
1636		.put = aureon_ac97_mute_put,
1637		.private_value = AC97_LINE
1638	},
1639	{
1640		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1641		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1642				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1643		.name = "Line Playback Volume",
1644		.info = aureon_ac97_vol_info,
1645		.get = aureon_ac97_vol_get,
1646		.put = aureon_ac97_vol_put,
1647		.private_value = AC97_LINE|AUREON_AC97_STEREO,
1648		.tlv = { .p = db_scale_ac97_gain }
1649	},
1650	{
1651		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1652		.name = "Mic Playback Switch",
1653		.info = aureon_ac97_mute_info,
1654		.get = aureon_ac97_mute_get,
1655		.put = aureon_ac97_mute_put,
1656		.private_value = AC97_MIC
1657	},
1658	{
1659		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1660		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1661				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1662		.name = "Mic Playback Volume",
1663		.info = aureon_ac97_vol_info,
1664		.get = aureon_ac97_vol_get,
1665		.put = aureon_ac97_vol_put,
1666		.private_value = AC97_MIC,
1667		.tlv = { .p = db_scale_ac97_gain }
1668	},
1669	{
1670		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1671		.name = "Mic Boost (+20dB)",
1672		.info = aureon_ac97_micboost_info,
1673		.get = aureon_ac97_micboost_get,
1674		.put = aureon_ac97_micboost_put
1675	}
1676};
1677
1678static const struct snd_kcontrol_new universe_ac97_controls[] = {
1679	{
1680		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1681		.name = "AC97 Playback Switch",
1682		.info = aureon_ac97_mmute_info,
1683		.get = aureon_ac97_mmute_get,
1684		.put = aureon_ac97_mmute_put,
1685		.private_value = AC97_MASTER
1686	},
1687	{
1688		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1689		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1690				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1691		.name = "AC97 Playback Volume",
1692		.info = aureon_ac97_vol_info,
1693		.get = aureon_ac97_vol_get,
1694		.put = aureon_ac97_vol_put,
1695		.private_value = AC97_MASTER|AUREON_AC97_STEREO,
1696		.tlv = { .p = db_scale_ac97_master }
1697	},
1698	{
1699		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1700		.name = "CD Playback Switch",
1701		.info = aureon_ac97_mute_info,
1702		.get = aureon_ac97_mute_get,
1703		.put = aureon_ac97_mute_put,
1704		.private_value = AC97_AUX
1705	},
1706	{
1707		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1708		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1709				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1710		.name = "CD Playback Volume",
1711		.info = aureon_ac97_vol_info,
1712		.get = aureon_ac97_vol_get,
1713		.put = aureon_ac97_vol_put,
1714		.private_value = AC97_AUX|AUREON_AC97_STEREO,
1715		.tlv = { .p = db_scale_ac97_gain }
1716	},
1717	{
1718		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1719		.name = "Phono Playback Switch",
1720		.info = aureon_ac97_mute_info,
1721		.get = aureon_ac97_mute_get,
1722		.put = aureon_ac97_mute_put,
1723		.private_value = AC97_CD
1724	},
1725	{
1726		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1727		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1728				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1729		.name = "Phono Playback Volume",
1730		.info = aureon_ac97_vol_info,
1731		.get = aureon_ac97_vol_get,
1732		.put = aureon_ac97_vol_put,
1733		.private_value = AC97_CD|AUREON_AC97_STEREO,
1734		.tlv = { .p = db_scale_ac97_gain }
1735	},
1736	{
1737		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1738		.name = "Line Playback Switch",
1739		.info = aureon_ac97_mute_info,
1740		.get = aureon_ac97_mute_get,
1741		.put = aureon_ac97_mute_put,
1742		.private_value = AC97_LINE
1743	},
1744	{
1745		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1746		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1747				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1748		.name = "Line Playback Volume",
1749		.info = aureon_ac97_vol_info,
1750		.get = aureon_ac97_vol_get,
1751		.put = aureon_ac97_vol_put,
1752		.private_value = AC97_LINE|AUREON_AC97_STEREO,
1753		.tlv = { .p = db_scale_ac97_gain }
1754	},
1755	{
1756		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1757		.name = "Mic Playback Switch",
1758		.info = aureon_ac97_mute_info,
1759		.get = aureon_ac97_mute_get,
1760		.put = aureon_ac97_mute_put,
1761		.private_value = AC97_MIC
1762	},
1763	{
1764		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1765		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1766				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1767		.name = "Mic Playback Volume",
1768		.info = aureon_ac97_vol_info,
1769		.get = aureon_ac97_vol_get,
1770		.put = aureon_ac97_vol_put,
1771		.private_value = AC97_MIC,
1772		.tlv = { .p = db_scale_ac97_gain }
1773	},
1774	{
1775		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1776		.name = "Mic Boost (+20dB)",
1777		.info = aureon_ac97_micboost_info,
1778		.get = aureon_ac97_micboost_get,
1779		.put = aureon_ac97_micboost_put
1780	},
1781	{
1782		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1783		.name = "Aux Playback Switch",
1784		.info = aureon_ac97_mute_info,
1785		.get = aureon_ac97_mute_get,
1786		.put = aureon_ac97_mute_put,
1787		.private_value = AC97_VIDEO,
1788	},
1789	{
1790		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1791		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1792				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1793		.name = "Aux Playback Volume",
1794		.info = aureon_ac97_vol_info,
1795		.get = aureon_ac97_vol_get,
1796		.put = aureon_ac97_vol_put,
1797		.private_value = AC97_VIDEO|AUREON_AC97_STEREO,
1798		.tlv = { .p = db_scale_ac97_gain }
1799	},
1800	{
1801		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1802		.name = "Aux Source",
1803		.info = aureon_universe_inmux_info,
1804		.get = aureon_universe_inmux_get,
1805		.put = aureon_universe_inmux_put
1806	}
1807
1808};
1809
1810static const struct snd_kcontrol_new cs8415_controls[] = {
1811	{
1812		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1813		.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
1814		.info = aureon_cs8415_mute_info,
1815		.get = aureon_cs8415_mute_get,
1816		.put = aureon_cs8415_mute_put
1817	},
1818	{
1819		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1820		.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Source",
1821		.info = aureon_cs8415_mux_info,
1822		.get = aureon_cs8415_mux_get,
1823		.put = aureon_cs8415_mux_put,
1824	},
1825	{
1826		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
1827		.name = SNDRV_CTL_NAME_IEC958("Q-subcode ", CAPTURE, DEFAULT),
1828		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1829		.info = aureon_cs8415_qsub_info,
1830		.get = aureon_cs8415_qsub_get,
1831	},
1832	{
1833		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
1834		.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
1835		.access = SNDRV_CTL_ELEM_ACCESS_READ,
1836		.info = aureon_cs8415_spdif_info,
1837		.get = aureon_cs8415_mask_get
1838	},
1839	{
1840		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
1841		.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
1842		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1843		.info = aureon_cs8415_spdif_info,
1844		.get = aureon_cs8415_spdif_get
1845	},
1846	{
1847		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
1848		.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Rate",
1849		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1850		.info = aureon_cs8415_rate_info,
1851		.get = aureon_cs8415_rate_get
1852	}
1853};
1854
1855static int aureon_add_controls(struct snd_ice1712 *ice)
1856{
1857	unsigned int i, counts;
1858	int err;
1859
1860	counts = ARRAY_SIZE(aureon_dac_controls);
1861	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
1862		counts -= 2; /* no side */
1863	for (i = 0; i < counts; i++) {
1864		err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
1865		if (err < 0)
1866			return err;
1867	}
1868
1869	for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
1870		err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
1871		if (err < 0)
1872			return err;
1873	}
1874
1875	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1876		for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
1877			err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
1878			if (err < 0)
1879				return err;
1880		}
1881	} else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1882		 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1883		for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
1884			err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
1885			if (err < 0)
1886				return err;
1887		}
1888	}
1889
1890	if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1891	    ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1892		unsigned char id;
1893		snd_ice1712_save_gpio_status(ice);
1894		id = aureon_cs8415_get(ice, CS8415_ID);
1895		snd_ice1712_restore_gpio_status(ice);
1896		if (id != 0x41)
1897			dev_info(ice->card->dev,
1898				 "No CS8415 chip. Skipping CS8415 controls.\n");
1899		else if ((id & 0x0F) != 0x01)
1900			dev_info(ice->card->dev,
1901				 "Detected unsupported CS8415 rev. (%c)\n",
1902				 (char)((id & 0x0F) + 'A' - 1));
1903		else {
1904			for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
1905				struct snd_kcontrol *kctl;
1906				err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
1907				if (err < 0)
1908					return err;
1909				if (i > 1)
1910					kctl->id.device = ice->pcm->device;
1911			}
1912		}
1913	}
1914
1915	return 0;
1916}
1917
1918/*
1919 * reset the chip
1920 */
1921static int aureon_reset(struct snd_ice1712 *ice)
1922{
1923	static const unsigned short wm_inits_aureon[] = {
1924		/* These come first to reduce init pop noise */
1925		0x1b, 0x044,		/* ADC Mux (AC'97 source) */
1926		0x1c, 0x00B,		/* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
1927		0x1d, 0x009,		/* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
1928
1929		0x18, 0x000,		/* All power-up */
1930
1931		0x16, 0x122,		/* I2S, normal polarity, 24bit */
1932		0x17, 0x022,		/* 256fs, slave mode */
1933		0x00, 0,		/* DAC1 analog mute */
1934		0x01, 0,		/* DAC2 analog mute */
1935		0x02, 0,		/* DAC3 analog mute */
1936		0x03, 0,		/* DAC4 analog mute */
1937		0x04, 0,		/* DAC5 analog mute */
1938		0x05, 0,		/* DAC6 analog mute */
1939		0x06, 0,		/* DAC7 analog mute */
1940		0x07, 0,		/* DAC8 analog mute */
1941		0x08, 0x100,		/* master analog mute */
1942		0x09, 0xff,		/* DAC1 digital full */
1943		0x0a, 0xff,		/* DAC2 digital full */
1944		0x0b, 0xff,		/* DAC3 digital full */
1945		0x0c, 0xff,		/* DAC4 digital full */
1946		0x0d, 0xff,		/* DAC5 digital full */
1947		0x0e, 0xff,		/* DAC6 digital full */
1948		0x0f, 0xff,		/* DAC7 digital full */
1949		0x10, 0xff,		/* DAC8 digital full */
1950		0x11, 0x1ff,		/* master digital full */
1951		0x12, 0x000,		/* phase normal */
1952		0x13, 0x090,		/* unmute DAC L/R */
1953		0x14, 0x000,		/* all unmute */
1954		0x15, 0x000,		/* no deemphasis, no ZFLG */
1955		0x19, 0x000,		/* -12dB ADC/L */
1956		0x1a, 0x000,		/* -12dB ADC/R */
1957		(unsigned short)-1
1958	};
1959	static const unsigned short wm_inits_prodigy[] = {
1960
1961		/* These come first to reduce init pop noise */
1962		0x1b, 0x000,		/* ADC Mux */
1963		0x1c, 0x009,		/* Out Mux1 */
1964		0x1d, 0x009,		/* Out Mux2 */
1965
1966		0x18, 0x000,		/* All power-up */
1967
1968		0x16, 0x022,		/* I2S, normal polarity, 24bit, high-pass on */
1969		0x17, 0x006,		/* 128fs, slave mode */
1970
1971		0x00, 0,		/* DAC1 analog mute */
1972		0x01, 0,		/* DAC2 analog mute */
1973		0x02, 0,		/* DAC3 analog mute */
1974		0x03, 0,		/* DAC4 analog mute */
1975		0x04, 0,		/* DAC5 analog mute */
1976		0x05, 0,		/* DAC6 analog mute */
1977		0x06, 0,		/* DAC7 analog mute */
1978		0x07, 0,		/* DAC8 analog mute */
1979		0x08, 0x100,		/* master analog mute */
1980
1981		0x09, 0x7f,		/* DAC1 digital full */
1982		0x0a, 0x7f,		/* DAC2 digital full */
1983		0x0b, 0x7f,		/* DAC3 digital full */
1984		0x0c, 0x7f,		/* DAC4 digital full */
1985		0x0d, 0x7f,		/* DAC5 digital full */
1986		0x0e, 0x7f,		/* DAC6 digital full */
1987		0x0f, 0x7f,		/* DAC7 digital full */
1988		0x10, 0x7f,		/* DAC8 digital full */
1989		0x11, 0x1FF,		/* master digital full */
1990
1991		0x12, 0x000,		/* phase normal */
1992		0x13, 0x090,		/* unmute DAC L/R */
1993		0x14, 0x000,		/* all unmute */
1994		0x15, 0x000,		/* no deemphasis, no ZFLG */
1995
1996		0x19, 0x000,		/* -12dB ADC/L */
1997		0x1a, 0x000,		/* -12dB ADC/R */
1998		(unsigned short)-1
1999
2000	};
2001	static const unsigned short cs_inits[] = {
2002		0x0441, /* RUN */
2003		0x0180, /* no mute, OMCK output on RMCK pin */
2004		0x0201, /* S/PDIF source on RXP1 */
2005		0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
2006		(unsigned short)-1
2007	};
2008	unsigned int tmp;
2009	const unsigned short *p;
2010	int err;
2011	struct aureon_spec *spec = ice->spec;
2012
2013	err = aureon_ac97_init(ice);
2014	if (err != 0)
2015		return err;
2016
2017	snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
2018
2019	/* reset the wm codec as the SPI mode */
2020	snd_ice1712_save_gpio_status(ice);
2021	snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
2022
2023	tmp = snd_ice1712_gpio_read(ice);
2024	tmp &= ~AUREON_WM_RESET;
2025	snd_ice1712_gpio_write(ice, tmp);
2026	udelay(1);
2027	tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
2028	snd_ice1712_gpio_write(ice, tmp);
2029	udelay(1);
2030	tmp |= AUREON_WM_RESET;
2031	snd_ice1712_gpio_write(ice, tmp);
2032	udelay(1);
2033
2034	/* initialize WM8770 codec */
2035	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
2036		ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
2037		ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT)
2038		p = wm_inits_prodigy;
2039	else
2040		p = wm_inits_aureon;
2041	for (; *p != (unsigned short)-1; p += 2)
2042		wm_put(ice, p[0], p[1]);
2043
2044	/* initialize CS8415A codec */
2045	if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
2046	    ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
2047		for (p = cs_inits; *p != (unsigned short)-1; p++)
2048			aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
2049		spec->cs8415_mux = 1;
2050
2051		aureon_set_headphone_amp(ice, 1);
2052	}
2053
2054	snd_ice1712_restore_gpio_status(ice);
2055
2056	/* initialize PCA9554 pin directions & set default input */
2057	aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2058	aureon_pca9554_write(ice, PCA9554_OUT, 0x00);   /* internal AUX */
2059	return 0;
2060}
2061
2062/*
2063 * suspend/resume
2064 */
2065#ifdef CONFIG_PM_SLEEP
2066static int aureon_resume(struct snd_ice1712 *ice)
2067{
2068	struct aureon_spec *spec = ice->spec;
2069	int err, i;
2070
2071	err = aureon_reset(ice);
2072	if (err != 0)
2073		return err;
2074
2075	/* workaround for poking volume with alsamixer after resume:
2076	 * just set stored volume again */
2077	for (i = 0; i < ice->num_total_dacs; i++)
2078		wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2079	return 0;
2080}
2081#endif
2082
2083/*
2084 * initialize the chip
2085 */
2086static int aureon_init(struct snd_ice1712 *ice)
2087{
2088	struct aureon_spec *spec;
2089	int i, err;
2090
2091	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2092	if (!spec)
2093		return -ENOMEM;
2094	ice->spec = spec;
2095
2096	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
2097		ice->num_total_dacs = 6;
2098		ice->num_total_adcs = 2;
2099	} else {
2100		/* aureon 7.1 and prodigy 7.1 */
2101		ice->num_total_dacs = 8;
2102		ice->num_total_adcs = 2;
2103	}
2104
2105	/* to remember the register values of CS8415 */
2106	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2107	if (!ice->akm)
2108		return -ENOMEM;
2109	ice->akm_codecs = 1;
2110
2111	err = aureon_reset(ice);
2112	if (err != 0)
2113		return err;
2114
2115	spec->master[0] = WM_VOL_MUTE;
2116	spec->master[1] = WM_VOL_MUTE;
2117	for (i = 0; i < ice->num_total_dacs; i++) {
2118		spec->vol[i] = WM_VOL_MUTE;
2119		wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2120	}
2121
2122#ifdef CONFIG_PM_SLEEP
2123	ice->pm_resume = aureon_resume;
2124	ice->pm_suspend_enabled = 1;
2125#endif
2126
2127	return 0;
2128}
2129
2130
2131/*
2132 * Aureon boards don't provide the EEPROM data except for the vendor IDs.
2133 * hence the driver needs to sets up it properly.
2134 */
2135
2136static const unsigned char aureon51_eeprom[] = {
2137	[ICE_EEP2_SYSCONF]     = 0x0a,	/* clock 512, spdif-in/ADC, 3DACs */
2138	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
2139	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */
2140	[ICE_EEP2_SPDIF]       = 0xc3,	/* out-en, out-int, spdif-in */
2141	[ICE_EEP2_GPIO_DIR]    = 0xff,
2142	[ICE_EEP2_GPIO_DIR1]   = 0xff,
2143	[ICE_EEP2_GPIO_DIR2]   = 0x5f,
2144	[ICE_EEP2_GPIO_MASK]   = 0x00,
2145	[ICE_EEP2_GPIO_MASK1]  = 0x00,
2146	[ICE_EEP2_GPIO_MASK2]  = 0x00,
2147	[ICE_EEP2_GPIO_STATE]  = 0x00,
2148	[ICE_EEP2_GPIO_STATE1] = 0x00,
2149	[ICE_EEP2_GPIO_STATE2] = 0x00,
2150};
2151
2152static const unsigned char aureon71_eeprom[] = {
2153	[ICE_EEP2_SYSCONF]     = 0x0b,	/* clock 512, spdif-in/ADC, 4DACs */
2154	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
2155	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */
2156	[ICE_EEP2_SPDIF]       = 0xc3,	/* out-en, out-int, spdif-in */
2157	[ICE_EEP2_GPIO_DIR]    = 0xff,
2158	[ICE_EEP2_GPIO_DIR1]   = 0xff,
2159	[ICE_EEP2_GPIO_DIR2]   = 0x5f,
2160	[ICE_EEP2_GPIO_MASK]   = 0x00,
2161	[ICE_EEP2_GPIO_MASK1]  = 0x00,
2162	[ICE_EEP2_GPIO_MASK2]  = 0x00,
2163	[ICE_EEP2_GPIO_STATE]  = 0x00,
2164	[ICE_EEP2_GPIO_STATE1] = 0x00,
2165	[ICE_EEP2_GPIO_STATE2] = 0x00,
2166};
2167#define prodigy71_eeprom aureon71_eeprom
2168
2169static const unsigned char aureon71_universe_eeprom[] = {
2170	[ICE_EEP2_SYSCONF]     = 0x2b,	/* clock 512, mpu401, spdif-in/ADC,
2171					 * 4DACs
2172					 */
2173	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
2174	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */
2175	[ICE_EEP2_SPDIF]       = 0xc3,	/* out-en, out-int, spdif-in */
2176	[ICE_EEP2_GPIO_DIR]    = 0xff,
2177	[ICE_EEP2_GPIO_DIR1]   = 0xff,
2178	[ICE_EEP2_GPIO_DIR2]   = 0x5f,
2179	[ICE_EEP2_GPIO_MASK]   = 0x00,
2180	[ICE_EEP2_GPIO_MASK1]  = 0x00,
2181	[ICE_EEP2_GPIO_MASK2]  = 0x00,
2182	[ICE_EEP2_GPIO_STATE]  = 0x00,
2183	[ICE_EEP2_GPIO_STATE1] = 0x00,
2184	[ICE_EEP2_GPIO_STATE2] = 0x00,
2185};
2186
2187static const unsigned char prodigy71lt_eeprom[] = {
2188	[ICE_EEP2_SYSCONF]     = 0x4b,	/* clock 384, spdif-in/ADC, 4DACs */
2189	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
2190	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */
2191	[ICE_EEP2_SPDIF]       = 0xc3,	/* out-en, out-int, spdif-in */
2192	[ICE_EEP2_GPIO_DIR]    = 0xff,
2193	[ICE_EEP2_GPIO_DIR1]   = 0xff,
2194	[ICE_EEP2_GPIO_DIR2]   = 0x5f,
2195	[ICE_EEP2_GPIO_MASK]   = 0x00,
2196	[ICE_EEP2_GPIO_MASK1]  = 0x00,
2197	[ICE_EEP2_GPIO_MASK2]  = 0x00,
2198	[ICE_EEP2_GPIO_STATE]  = 0x00,
2199	[ICE_EEP2_GPIO_STATE1] = 0x00,
2200	[ICE_EEP2_GPIO_STATE2] = 0x00,
2201};
2202#define prodigy71xt_eeprom prodigy71lt_eeprom
2203
2204/* entry point */
2205struct snd_ice1712_card_info snd_vt1724_aureon_cards[] = {
2206	{
2207		.subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
2208		.name = "Terratec Aureon 5.1-Sky",
2209		.model = "aureon51",
2210		.chip_init = aureon_init,
2211		.build_controls = aureon_add_controls,
2212		.eeprom_size = sizeof(aureon51_eeprom),
2213		.eeprom_data = aureon51_eeprom,
2214		.driver = "Aureon51",
2215	},
2216	{
2217		.subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
2218		.name = "Terratec Aureon 7.1-Space",
2219		.model = "aureon71",
2220		.chip_init = aureon_init,
2221		.build_controls = aureon_add_controls,
2222		.eeprom_size = sizeof(aureon71_eeprom),
2223		.eeprom_data = aureon71_eeprom,
2224		.driver = "Aureon71",
2225	},
2226	{
2227		.subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
2228		.name = "Terratec Aureon 7.1-Universe",
2229		.model = "universe",
2230		.chip_init = aureon_init,
2231		.build_controls = aureon_add_controls,
2232		.eeprom_size = sizeof(aureon71_universe_eeprom),
2233		.eeprom_data = aureon71_universe_eeprom,
2234		.driver = "Aureon71Univ", /* keep in 15 letters */
2235	},
2236	{
2237		.subvendor = VT1724_SUBDEVICE_PRODIGY71,
2238		.name = "Audiotrak Prodigy 7.1",
2239		.model = "prodigy71",
2240		.chip_init = aureon_init,
2241		.build_controls = aureon_add_controls,
2242		.eeprom_size = sizeof(prodigy71_eeprom),
2243		.eeprom_data = prodigy71_eeprom,
2244		.driver = "Prodigy71", /* should be identical with Aureon71 */
2245	},
2246	{
2247		.subvendor = VT1724_SUBDEVICE_PRODIGY71LT,
2248		.name = "Audiotrak Prodigy 7.1 LT",
2249		.model = "prodigy71lt",
2250		.chip_init = aureon_init,
2251		.build_controls = aureon_add_controls,
2252		.eeprom_size = sizeof(prodigy71lt_eeprom),
2253		.eeprom_data = prodigy71lt_eeprom,
2254		.driver = "Prodigy71LT",
2255	},
2256	{
2257		.subvendor = VT1724_SUBDEVICE_PRODIGY71XT,
2258		.name = "Audiotrak Prodigy 7.1 XT",
2259		.model = "prodigy71xt",
2260		.chip_init = aureon_init,
2261		.build_controls = aureon_add_controls,
2262		.eeprom_size = sizeof(prodigy71xt_eeprom),
2263		.eeprom_data = prodigy71xt_eeprom,
2264		.driver = "Prodigy71LT",
2265	},
2266	{ } /* terminator */
2267};
2268