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