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