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