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