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