xref: /openbmc/linux/sound/pci/ice1712/aureon.c (revision ecba1060)
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 inbetween
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, -12700, 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 /*
699  * Logarithmic volume values for WM8770
700  * Computed as 20 * Log10(255 / x)
701  */
702 static const unsigned char wm_vol[256] = {
703 	127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
704 	23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
705 	17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
706 	13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
707 	11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
708 	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
709 	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
710 	5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
711 	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
712 	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
713 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
714 	0, 0
715 };
716 
717 #define WM_VOL_MAX	(sizeof(wm_vol) - 1)
718 #define WM_VOL_MUTE	0x8000
719 
720 static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
721 {
722 	unsigned char nvol;
723 
724 	if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
725 		nvol = 0;
726 	else
727 		nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
728 
729 	wm_put(ice, index, nvol);
730 	wm_put_nocache(ice, index, 0x180 | nvol);
731 }
732 
733 /*
734  * DAC mute control
735  */
736 #define wm_pcm_mute_info	snd_ctl_boolean_mono_info
737 
738 static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
739 {
740 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
741 
742 	mutex_lock(&ice->gpio_mutex);
743 	ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
744 	mutex_unlock(&ice->gpio_mutex);
745 	return 0;
746 }
747 
748 static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
749 {
750 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
751 	unsigned short nval, oval;
752 	int change;
753 
754 	snd_ice1712_save_gpio_status(ice);
755 	oval = wm_get(ice, WM_MUTE);
756 	nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
757 	change = (oval != nval);
758 	if (change)
759 		wm_put(ice, WM_MUTE, nval);
760 	snd_ice1712_restore_gpio_status(ice);
761 
762 	return change;
763 }
764 
765 /*
766  * Master volume attenuation mixer control
767  */
768 static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
769 {
770 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
771 	uinfo->count = 2;
772 	uinfo->value.integer.min = 0;
773 	uinfo->value.integer.max = WM_VOL_MAX;
774 	return 0;
775 }
776 
777 static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
778 {
779 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
780 	struct aureon_spec *spec = ice->spec;
781 	int i;
782 	for (i = 0; i < 2; i++)
783 		ucontrol->value.integer.value[i] =
784 			spec->master[i] & ~WM_VOL_MUTE;
785 	return 0;
786 }
787 
788 static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
789 {
790 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
791 	struct aureon_spec *spec = ice->spec;
792 	int ch, change = 0;
793 
794 	snd_ice1712_save_gpio_status(ice);
795 	for (ch = 0; ch < 2; ch++) {
796 		unsigned int vol = ucontrol->value.integer.value[ch];
797 		if (vol > WM_VOL_MAX)
798 			continue;
799 		vol |= spec->master[ch] & WM_VOL_MUTE;
800 		if (vol != spec->master[ch]) {
801 			int dac;
802 			spec->master[ch] = vol;
803 			for (dac = 0; dac < ice->num_total_dacs; dac += 2)
804 				wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
805 					   spec->vol[dac + ch],
806 					   spec->master[ch]);
807 			change = 1;
808 		}
809 	}
810 	snd_ice1712_restore_gpio_status(ice);
811 	return change;
812 }
813 
814 /*
815  * DAC volume attenuation mixer control
816  */
817 static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
818 {
819 	int voices = kcontrol->private_value >> 8;
820 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
821 	uinfo->count = voices;
822 	uinfo->value.integer.min = 0;		/* mute (-101dB) */
823 	uinfo->value.integer.max = 0x7F;	/* 0dB */
824 	return 0;
825 }
826 
827 static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
828 {
829 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
830 	struct aureon_spec *spec = ice->spec;
831 	int i, ofs, voices;
832 
833 	voices = kcontrol->private_value >> 8;
834 	ofs = kcontrol->private_value & 0xff;
835 	for (i = 0; i < voices; i++)
836 		ucontrol->value.integer.value[i] =
837 			spec->vol[ofs+i] & ~WM_VOL_MUTE;
838 	return 0;
839 }
840 
841 static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
842 {
843 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
844 	struct aureon_spec *spec = ice->spec;
845 	int i, idx, ofs, voices;
846 	int change = 0;
847 
848 	voices = kcontrol->private_value >> 8;
849 	ofs = kcontrol->private_value & 0xff;
850 	snd_ice1712_save_gpio_status(ice);
851 	for (i = 0; i < voices; i++) {
852 		unsigned int vol = ucontrol->value.integer.value[i];
853 		if (vol > 0x7f)
854 			continue;
855 		vol |= spec->vol[ofs+i];
856 		if (vol != spec->vol[ofs+i]) {
857 			spec->vol[ofs+i] = vol;
858 			idx  = WM_DAC_ATTEN + ofs + i;
859 			wm_set_vol(ice, idx, spec->vol[ofs + i],
860 				   spec->master[i]);
861 			change = 1;
862 		}
863 	}
864 	snd_ice1712_restore_gpio_status(ice);
865 	return change;
866 }
867 
868 /*
869  * WM8770 mute control
870  */
871 static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
872 {
873 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
874 	uinfo->count = kcontrol->private_value >> 8;
875 	uinfo->value.integer.min = 0;
876 	uinfo->value.integer.max = 1;
877 	return 0;
878 }
879 
880 static int wm_mute_get(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 voices, ofs, i;
885 
886 	voices = kcontrol->private_value >> 8;
887 	ofs = kcontrol->private_value & 0xFF;
888 
889 	for (i = 0; i < voices; i++)
890 		ucontrol->value.integer.value[i] =
891 			(spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
892 	return 0;
893 }
894 
895 static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
896 {
897 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
898 	struct aureon_spec *spec = ice->spec;
899 	int change = 0, voices, ofs, i;
900 
901 	voices = kcontrol->private_value >> 8;
902 	ofs = kcontrol->private_value & 0xFF;
903 
904 	snd_ice1712_save_gpio_status(ice);
905 	for (i = 0; i < voices; i++) {
906 		int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
907 		if (ucontrol->value.integer.value[i] != val) {
908 			spec->vol[ofs + i] &= ~WM_VOL_MUTE;
909 			spec->vol[ofs + i] |=
910 				ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
911 			wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
912 				   spec->master[i]);
913 			change = 1;
914 		}
915 	}
916 	snd_ice1712_restore_gpio_status(ice);
917 
918 	return change;
919 }
920 
921 /*
922  * WM8770 master mute control
923  */
924 #define wm_master_mute_info		snd_ctl_boolean_stereo_info
925 
926 static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
927 {
928 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
929 	struct aureon_spec *spec = ice->spec;
930 
931 	ucontrol->value.integer.value[0] =
932 		(spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
933 	ucontrol->value.integer.value[1] =
934 		(spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
935 	return 0;
936 }
937 
938 static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
939 {
940 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
941 	struct aureon_spec *spec = ice->spec;
942 	int change = 0, i;
943 
944 	snd_ice1712_save_gpio_status(ice);
945 	for (i = 0; i < 2; i++) {
946 		int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
947 		if (ucontrol->value.integer.value[i] != val) {
948 			int dac;
949 			spec->master[i] &= ~WM_VOL_MUTE;
950 			spec->master[i] |=
951 				ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
952 			for (dac = 0; dac < ice->num_total_dacs; dac += 2)
953 				wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
954 					   spec->vol[dac + i],
955 					   spec->master[i]);
956 			change = 1;
957 		}
958 	}
959 	snd_ice1712_restore_gpio_status(ice);
960 
961 	return change;
962 }
963 
964 /* digital master volume */
965 #define PCM_0dB 0xff
966 #define PCM_RES 128	/* -64dB */
967 #define PCM_MIN (PCM_0dB - PCM_RES)
968 static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
969 {
970 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
971 	uinfo->count = 1;
972 	uinfo->value.integer.min = 0;		/* mute (-64dB) */
973 	uinfo->value.integer.max = PCM_RES;	/* 0dB */
974 	return 0;
975 }
976 
977 static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
978 {
979 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
980 	unsigned short val;
981 
982 	mutex_lock(&ice->gpio_mutex);
983 	val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
984 	val = val > PCM_MIN ? (val - PCM_MIN) : 0;
985 	ucontrol->value.integer.value[0] = val;
986 	mutex_unlock(&ice->gpio_mutex);
987 	return 0;
988 }
989 
990 static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
991 {
992 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
993 	unsigned short ovol, nvol;
994 	int change = 0;
995 
996 	nvol = ucontrol->value.integer.value[0];
997 	if (nvol > PCM_RES)
998 		return -EINVAL;
999 	snd_ice1712_save_gpio_status(ice);
1000 	nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
1001 	ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
1002 	if (ovol != nvol) {
1003 		wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
1004 		wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
1005 		change = 1;
1006 	}
1007 	snd_ice1712_restore_gpio_status(ice);
1008 	return change;
1009 }
1010 
1011 /*
1012  * ADC mute control
1013  */
1014 #define wm_adc_mute_info		snd_ctl_boolean_stereo_info
1015 
1016 static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1017 {
1018 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1019 	unsigned short val;
1020 	int i;
1021 
1022 	mutex_lock(&ice->gpio_mutex);
1023 	for (i = 0; i < 2; i++) {
1024 		val = wm_get(ice, WM_ADC_GAIN + i);
1025 		ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
1026 	}
1027 	mutex_unlock(&ice->gpio_mutex);
1028 	return 0;
1029 }
1030 
1031 static int wm_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1032 {
1033 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1034 	unsigned short new, old;
1035 	int i, change = 0;
1036 
1037 	snd_ice1712_save_gpio_status(ice);
1038 	for (i = 0; i < 2; i++) {
1039 		old = wm_get(ice, WM_ADC_GAIN + i);
1040 		new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
1041 		if (new != old) {
1042 			wm_put(ice, WM_ADC_GAIN + i, new);
1043 			change = 1;
1044 		}
1045 	}
1046 	snd_ice1712_restore_gpio_status(ice);
1047 
1048 	return change;
1049 }
1050 
1051 /*
1052  * ADC gain mixer control
1053  */
1054 static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1055 {
1056 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1057 	uinfo->count = 2;
1058 	uinfo->value.integer.min = 0;		/* -12dB */
1059 	uinfo->value.integer.max = 0x1f;	/* 19dB */
1060 	return 0;
1061 }
1062 
1063 static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1064 {
1065 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1066 	int i, idx;
1067 	unsigned short vol;
1068 
1069 	mutex_lock(&ice->gpio_mutex);
1070 	for (i = 0; i < 2; i++) {
1071 		idx = WM_ADC_GAIN + i;
1072 		vol = wm_get(ice, idx) & 0x1f;
1073 		ucontrol->value.integer.value[i] = vol;
1074 	}
1075 	mutex_unlock(&ice->gpio_mutex);
1076 	return 0;
1077 }
1078 
1079 static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1080 {
1081 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1082 	int i, idx;
1083 	unsigned short ovol, nvol;
1084 	int change = 0;
1085 
1086 	snd_ice1712_save_gpio_status(ice);
1087 	for (i = 0; i < 2; i++) {
1088 		idx  = WM_ADC_GAIN + i;
1089 		nvol = ucontrol->value.integer.value[i] & 0x1f;
1090 		ovol = wm_get(ice, idx);
1091 		if ((ovol & 0x1f) != nvol) {
1092 			wm_put(ice, idx, nvol | (ovol & ~0x1f));
1093 			change = 1;
1094 		}
1095 	}
1096 	snd_ice1712_restore_gpio_status(ice);
1097 	return change;
1098 }
1099 
1100 /*
1101  * ADC input mux mixer control
1102  */
1103 static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1104 {
1105 	static const char * const texts[] = {
1106 		"CD",		/* AIN1 */
1107 		"Aux",		/* AIN2 */
1108 		"Line",		/* AIN3 */
1109 		"Mic",		/* AIN4 */
1110 		"AC97"		/* AIN5 */
1111 	};
1112 	static const char * const universe_texts[] = {
1113 		"Aux1",		/* AIN1 */
1114 		"CD",		/* AIN2 */
1115 		"Phono",	/* AIN3 */
1116 		"Line",		/* AIN4 */
1117 		"Aux2",		/* AIN5 */
1118 		"Mic",		/* AIN6 */
1119 		"Aux3",		/* AIN7 */
1120 		"AC97"		/* AIN8 */
1121 	};
1122 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1123 
1124 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1125 	uinfo->count = 2;
1126 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1127 		uinfo->value.enumerated.items = 8;
1128 		if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1129 			uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1130 		strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]);
1131 	} else {
1132 		uinfo->value.enumerated.items = 5;
1133 		if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1134 			uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1135 		strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1136 	}
1137 	return 0;
1138 }
1139 
1140 static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1141 {
1142 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1143 	unsigned short val;
1144 
1145 	mutex_lock(&ice->gpio_mutex);
1146 	val = wm_get(ice, WM_ADC_MUX);
1147 	ucontrol->value.enumerated.item[0] = val & 7;
1148 	ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
1149 	mutex_unlock(&ice->gpio_mutex);
1150 	return 0;
1151 }
1152 
1153 static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1154 {
1155 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1156 	unsigned short oval, nval;
1157 	int change;
1158 
1159 	snd_ice1712_save_gpio_status(ice);
1160 	oval = wm_get(ice, WM_ADC_MUX);
1161 	nval = oval & ~0x77;
1162 	nval |= ucontrol->value.enumerated.item[0] & 7;
1163 	nval |= (ucontrol->value.enumerated.item[1] & 7) << 4;
1164 	change = (oval != nval);
1165 	if (change)
1166 		wm_put(ice, WM_ADC_MUX, nval);
1167 	snd_ice1712_restore_gpio_status(ice);
1168 	return change;
1169 }
1170 
1171 /*
1172  * CS8415 Input mux
1173  */
1174 static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1175 {
1176 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1177 	static const char * const aureon_texts[] = {
1178 		"CD",		/* RXP0 */
1179 		"Optical"	/* RXP1 */
1180 	};
1181 	static const char * const prodigy_texts[] = {
1182 		"CD",
1183 		"Coax"
1184 	};
1185 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1186 	uinfo->count = 1;
1187 	uinfo->value.enumerated.items = 2;
1188 	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1189 		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1190 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
1191 		strcpy(uinfo->value.enumerated.name, prodigy_texts[uinfo->value.enumerated.item]);
1192 	else
1193 		strcpy(uinfo->value.enumerated.name, aureon_texts[uinfo->value.enumerated.item]);
1194 	return 0;
1195 }
1196 
1197 static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1198 {
1199 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1200 	struct aureon_spec *spec = ice->spec;
1201 
1202 	/* snd_ice1712_save_gpio_status(ice); */
1203 	/* val = aureon_cs8415_get(ice, CS8415_CTRL2); */
1204 	ucontrol->value.enumerated.item[0] = spec->cs8415_mux;
1205 	/* snd_ice1712_restore_gpio_status(ice); */
1206 	return 0;
1207 }
1208 
1209 static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1210 {
1211 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1212 	struct aureon_spec *spec = ice->spec;
1213 	unsigned short oval, nval;
1214 	int change;
1215 
1216 	snd_ice1712_save_gpio_status(ice);
1217 	oval = aureon_cs8415_get(ice, CS8415_CTRL2);
1218 	nval = oval & ~0x07;
1219 	nval |= ucontrol->value.enumerated.item[0] & 7;
1220 	change = (oval != nval);
1221 	if (change)
1222 		aureon_cs8415_put(ice, CS8415_CTRL2, nval);
1223 	snd_ice1712_restore_gpio_status(ice);
1224 	spec->cs8415_mux = ucontrol->value.enumerated.item[0];
1225 	return change;
1226 }
1227 
1228 static int aureon_cs8415_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1229 {
1230 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1231 	uinfo->count = 1;
1232 	uinfo->value.integer.min = 0;
1233 	uinfo->value.integer.max = 192000;
1234 	return 0;
1235 }
1236 
1237 static int aureon_cs8415_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1238 {
1239 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1240 	unsigned char ratio;
1241 	ratio = aureon_cs8415_get(ice, CS8415_RATIO);
1242 	ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750);
1243 	return 0;
1244 }
1245 
1246 /*
1247  * CS8415A Mute
1248  */
1249 #define aureon_cs8415_mute_info		snd_ctl_boolean_mono_info
1250 
1251 static int aureon_cs8415_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1252 {
1253 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1254 	snd_ice1712_save_gpio_status(ice);
1255 	ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1;
1256 	snd_ice1712_restore_gpio_status(ice);
1257 	return 0;
1258 }
1259 
1260 static int aureon_cs8415_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1261 {
1262 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1263 	unsigned char oval, nval;
1264 	int change;
1265 	snd_ice1712_save_gpio_status(ice);
1266 	oval = aureon_cs8415_get(ice, CS8415_CTRL1);
1267 	if (ucontrol->value.integer.value[0])
1268 		nval = oval & ~0x20;
1269 	else
1270 		nval = oval | 0x20;
1271 	change = (oval != nval);
1272 	if (change)
1273 		aureon_cs8415_put(ice, CS8415_CTRL1, nval);
1274 	snd_ice1712_restore_gpio_status(ice);
1275 	return change;
1276 }
1277 
1278 /*
1279  * CS8415A Q-Sub info
1280  */
1281 static int aureon_cs8415_qsub_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1282 {
1283 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1284 	uinfo->count = 10;
1285 	return 0;
1286 }
1287 
1288 static int aureon_cs8415_qsub_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1289 {
1290 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1291 
1292 	snd_ice1712_save_gpio_status(ice);
1293 	aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
1294 	snd_ice1712_restore_gpio_status(ice);
1295 
1296 	return 0;
1297 }
1298 
1299 static int aureon_cs8415_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1300 {
1301 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1302 	uinfo->count = 1;
1303 	return 0;
1304 }
1305 
1306 static int aureon_cs8415_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1307 {
1308 	memset(ucontrol->value.iec958.status, 0xFF, 24);
1309 	return 0;
1310 }
1311 
1312 static int aureon_cs8415_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1313 {
1314 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1315 
1316 	snd_ice1712_save_gpio_status(ice);
1317 	aureon_cs8415_read(ice, CS8415_C_BUFFER, ucontrol->value.iec958.status, 24);
1318 	snd_ice1712_restore_gpio_status(ice);
1319 	return 0;
1320 }
1321 
1322 /*
1323  * Headphone Amplifier
1324  */
1325 static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
1326 {
1327 	unsigned int tmp, tmp2;
1328 
1329 	tmp2 = tmp = snd_ice1712_gpio_read(ice);
1330 	if (enable)
1331 		if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1332 		    ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1333 			tmp |= AUREON_HP_SEL;
1334 		else
1335 			tmp |= PRODIGY_HP_SEL;
1336 	else
1337 		if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1338 		    ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1339 			tmp &= ~AUREON_HP_SEL;
1340 		else
1341 			tmp &= ~PRODIGY_HP_SEL;
1342 	if (tmp != tmp2) {
1343 		snd_ice1712_gpio_write(ice, tmp);
1344 		return 1;
1345 	}
1346 	return 0;
1347 }
1348 
1349 static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
1350 {
1351 	unsigned int tmp = snd_ice1712_gpio_read(ice);
1352 
1353 	return (tmp & AUREON_HP_SEL) != 0;
1354 }
1355 
1356 #define aureon_hpamp_info	snd_ctl_boolean_mono_info
1357 
1358 static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1359 {
1360 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1361 
1362 	ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
1363 	return 0;
1364 }
1365 
1366 
1367 static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1368 {
1369 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1370 
1371 	return aureon_set_headphone_amp(ice, ucontrol->value.integer.value[0]);
1372 }
1373 
1374 /*
1375  * Deemphasis
1376  */
1377 
1378 #define aureon_deemp_info	snd_ctl_boolean_mono_info
1379 
1380 static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1381 {
1382 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1383 	ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
1384 	return 0;
1385 }
1386 
1387 static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1388 {
1389 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1390 	int temp, temp2;
1391 	temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
1392 	if (ucontrol->value.integer.value[0])
1393 		temp |= 0xf;
1394 	else
1395 		temp &= ~0xf;
1396 	if (temp != temp2) {
1397 		wm_put(ice, WM_DAC_CTRL2, temp);
1398 		return 1;
1399 	}
1400 	return 0;
1401 }
1402 
1403 /*
1404  * ADC Oversampling
1405  */
1406 static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
1407 {
1408 	static const char * const texts[2] = { "128x", "64x"	};
1409 
1410 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1411 	uinfo->count = 1;
1412 	uinfo->value.enumerated.items = 2;
1413 
1414 	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1415 		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1416 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1417 
1418 	return 0;
1419 }
1420 
1421 static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1422 {
1423 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1424 	ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
1425 	return 0;
1426 }
1427 
1428 static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1429 {
1430 	int temp, temp2;
1431 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1432 
1433 	temp2 = temp = wm_get(ice, WM_MASTER);
1434 
1435 	if (ucontrol->value.enumerated.item[0])
1436 		temp |= 0x8;
1437 	else
1438 		temp &= ~0x8;
1439 
1440 	if (temp != temp2) {
1441 		wm_put(ice, WM_MASTER, temp);
1442 		return 1;
1443 	}
1444 	return 0;
1445 }
1446 
1447 /*
1448  * mixers
1449  */
1450 
1451 static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
1452 	{
1453 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1454 		.name = "Master Playback Switch",
1455 		.info = wm_master_mute_info,
1456 		.get = wm_master_mute_get,
1457 		.put = wm_master_mute_put
1458 	},
1459 	{
1460 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1461 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1462 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1463 		.name = "Master Playback Volume",
1464 		.info = wm_master_vol_info,
1465 		.get = wm_master_vol_get,
1466 		.put = wm_master_vol_put,
1467 		.tlv = { .p = db_scale_wm_dac }
1468 	},
1469 	{
1470 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1471 		.name = "Front Playback Switch",
1472 		.info = wm_mute_info,
1473 		.get = wm_mute_get,
1474 		.put = wm_mute_put,
1475 		.private_value = (2 << 8) | 0
1476 	},
1477 	{
1478 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1479 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1480 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1481 		.name = "Front Playback Volume",
1482 		.info = wm_vol_info,
1483 		.get = wm_vol_get,
1484 		.put = wm_vol_put,
1485 		.private_value = (2 << 8) | 0,
1486 		.tlv = { .p = db_scale_wm_dac }
1487 	},
1488 	{
1489 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1490 		.name = "Rear Playback Switch",
1491 		.info = wm_mute_info,
1492 		.get = wm_mute_get,
1493 		.put = wm_mute_put,
1494 		.private_value = (2 << 8) | 2
1495 	},
1496 	{
1497 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1498 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1499 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1500 		.name = "Rear Playback Volume",
1501 		.info = wm_vol_info,
1502 		.get = wm_vol_get,
1503 		.put = wm_vol_put,
1504 		.private_value = (2 << 8) | 2,
1505 		.tlv = { .p = db_scale_wm_dac }
1506 	},
1507 	{
1508 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1509 		.name = "Center Playback Switch",
1510 		.info = wm_mute_info,
1511 		.get = wm_mute_get,
1512 		.put = wm_mute_put,
1513 		.private_value = (1 << 8) | 4
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 = "Center Playback Volume",
1520 		.info = wm_vol_info,
1521 		.get = wm_vol_get,
1522 		.put = wm_vol_put,
1523 		.private_value = (1 << 8) | 4,
1524 		.tlv = { .p = db_scale_wm_dac }
1525 	},
1526 	{
1527 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1528 		.name = "LFE Playback Switch",
1529 		.info = wm_mute_info,
1530 		.get = wm_mute_get,
1531 		.put = wm_mute_put,
1532 		.private_value = (1 << 8) | 5
1533 	},
1534 	{
1535 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1536 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1537 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1538 		.name = "LFE Playback Volume",
1539 		.info = wm_vol_info,
1540 		.get = wm_vol_get,
1541 		.put = wm_vol_put,
1542 		.private_value = (1 << 8) | 5,
1543 		.tlv = { .p = db_scale_wm_dac }
1544 	},
1545 	{
1546 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1547 		.name = "Side Playback Switch",
1548 		.info = wm_mute_info,
1549 		.get = wm_mute_get,
1550 		.put = wm_mute_put,
1551 		.private_value = (2 << 8) | 6
1552 	},
1553 	{
1554 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1555 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1556 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1557 		.name = "Side Playback Volume",
1558 		.info = wm_vol_info,
1559 		.get = wm_vol_get,
1560 		.put = wm_vol_put,
1561 		.private_value = (2 << 8) | 6,
1562 		.tlv = { .p = db_scale_wm_dac }
1563 	}
1564 };
1565 
1566 static struct snd_kcontrol_new wm_controls[] __devinitdata = {
1567 	{
1568 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1569 		.name = "PCM Playback Switch",
1570 		.info = wm_pcm_mute_info,
1571 		.get = wm_pcm_mute_get,
1572 		.put = wm_pcm_mute_put
1573 	},
1574 	{
1575 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1576 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1577 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1578 		.name = "PCM Playback Volume",
1579 		.info = wm_pcm_vol_info,
1580 		.get = wm_pcm_vol_get,
1581 		.put = wm_pcm_vol_put,
1582 		.tlv = { .p = db_scale_wm_pcm }
1583 	},
1584 	{
1585 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1586 		.name = "Capture Switch",
1587 		.info = wm_adc_mute_info,
1588 		.get = wm_adc_mute_get,
1589 		.put = wm_adc_mute_put,
1590 	},
1591 	{
1592 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1593 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1594 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1595 		.name = "Capture Volume",
1596 		.info = wm_adc_vol_info,
1597 		.get = wm_adc_vol_get,
1598 		.put = wm_adc_vol_put,
1599 		.tlv = { .p = db_scale_wm_adc }
1600 	},
1601 	{
1602 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1603 		.name = "Capture Source",
1604 		.info = wm_adc_mux_info,
1605 		.get = wm_adc_mux_get,
1606 		.put = wm_adc_mux_put,
1607 		.private_value = 5
1608 	},
1609 	{
1610 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1611 		.name = "External Amplifier",
1612 		.info = aureon_hpamp_info,
1613 		.get = aureon_hpamp_get,
1614 		.put = aureon_hpamp_put
1615 	},
1616 	{
1617 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1618 		.name = "DAC Deemphasis Switch",
1619 		.info = aureon_deemp_info,
1620 		.get = aureon_deemp_get,
1621 		.put = aureon_deemp_put
1622 	},
1623 	{
1624 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1625 		.name = "ADC Oversampling",
1626 		.info = aureon_oversampling_info,
1627 		.get = aureon_oversampling_get,
1628 		.put = aureon_oversampling_put
1629 	}
1630 };
1631 
1632 static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
1633 	{
1634 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1635 		.name = "AC97 Playback Switch",
1636 		.info = aureon_ac97_mmute_info,
1637 		.get = aureon_ac97_mmute_get,
1638 		.put = aureon_ac97_mmute_put,
1639 		.private_value = AC97_MASTER
1640 	},
1641 	{
1642 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1643 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1644 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1645 		.name = "AC97 Playback Volume",
1646 		.info = aureon_ac97_vol_info,
1647 		.get = aureon_ac97_vol_get,
1648 		.put = aureon_ac97_vol_put,
1649 		.private_value = AC97_MASTER|AUREON_AC97_STEREO,
1650 		.tlv = { .p = db_scale_ac97_master }
1651 	},
1652 	{
1653 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1654 		.name = "CD Playback Switch",
1655 		.info = aureon_ac97_mute_info,
1656 		.get = aureon_ac97_mute_get,
1657 		.put = aureon_ac97_mute_put,
1658 		.private_value = AC97_CD
1659 	},
1660 	{
1661 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1662 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1663 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1664 		.name = "CD Playback Volume",
1665 		.info = aureon_ac97_vol_info,
1666 		.get = aureon_ac97_vol_get,
1667 		.put = aureon_ac97_vol_put,
1668 		.private_value = AC97_CD|AUREON_AC97_STEREO,
1669 		.tlv = { .p = db_scale_ac97_gain }
1670 	},
1671 	{
1672 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1673 		.name = "Aux Playback Switch",
1674 		.info = aureon_ac97_mute_info,
1675 		.get = aureon_ac97_mute_get,
1676 		.put = aureon_ac97_mute_put,
1677 		.private_value = AC97_AUX,
1678 	},
1679 	{
1680 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1681 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1682 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1683 		.name = "Aux Playback Volume",
1684 		.info = aureon_ac97_vol_info,
1685 		.get = aureon_ac97_vol_get,
1686 		.put = aureon_ac97_vol_put,
1687 		.private_value = AC97_AUX|AUREON_AC97_STEREO,
1688 		.tlv = { .p = db_scale_ac97_gain }
1689 	},
1690 	{
1691 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1692 		.name = "Line Playback Switch",
1693 		.info = aureon_ac97_mute_info,
1694 		.get = aureon_ac97_mute_get,
1695 		.put = aureon_ac97_mute_put,
1696 		.private_value = AC97_LINE
1697 	},
1698 	{
1699 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1700 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1701 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1702 		.name = "Line Playback Volume",
1703 		.info = aureon_ac97_vol_info,
1704 		.get = aureon_ac97_vol_get,
1705 		.put = aureon_ac97_vol_put,
1706 		.private_value = AC97_LINE|AUREON_AC97_STEREO,
1707 		.tlv = { .p = db_scale_ac97_gain }
1708 	},
1709 	{
1710 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1711 		.name = "Mic Playback Switch",
1712 		.info = aureon_ac97_mute_info,
1713 		.get = aureon_ac97_mute_get,
1714 		.put = aureon_ac97_mute_put,
1715 		.private_value = AC97_MIC
1716 	},
1717 	{
1718 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1719 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1720 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1721 		.name = "Mic Playback Volume",
1722 		.info = aureon_ac97_vol_info,
1723 		.get = aureon_ac97_vol_get,
1724 		.put = aureon_ac97_vol_put,
1725 		.private_value = AC97_MIC,
1726 		.tlv = { .p = db_scale_ac97_gain }
1727 	},
1728 	{
1729 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1730 		.name = "Mic Boost (+20dB)",
1731 		.info = aureon_ac97_micboost_info,
1732 		.get = aureon_ac97_micboost_get,
1733 		.put = aureon_ac97_micboost_put
1734 	}
1735 };
1736 
1737 static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
1738 	{
1739 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1740 		.name = "AC97 Playback Switch",
1741 		.info = aureon_ac97_mmute_info,
1742 		.get = aureon_ac97_mmute_get,
1743 		.put = aureon_ac97_mmute_put,
1744 		.private_value = AC97_MASTER
1745 	},
1746 	{
1747 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1748 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1749 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1750 		.name = "AC97 Playback Volume",
1751 		.info = aureon_ac97_vol_info,
1752 		.get = aureon_ac97_vol_get,
1753 		.put = aureon_ac97_vol_put,
1754 		.private_value = AC97_MASTER|AUREON_AC97_STEREO,
1755 		.tlv = { .p = db_scale_ac97_master }
1756 	},
1757 	{
1758 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1759 		.name = "CD Playback Switch",
1760 		.info = aureon_ac97_mute_info,
1761 		.get = aureon_ac97_mute_get,
1762 		.put = aureon_ac97_mute_put,
1763 		.private_value = AC97_AUX
1764 	},
1765 	{
1766 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1767 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1768 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1769 		.name = "CD Playback Volume",
1770 		.info = aureon_ac97_vol_info,
1771 		.get = aureon_ac97_vol_get,
1772 		.put = aureon_ac97_vol_put,
1773 		.private_value = AC97_AUX|AUREON_AC97_STEREO,
1774 		.tlv = { .p = db_scale_ac97_gain }
1775 	},
1776 	{
1777 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1778 		.name = "Phono Playback Switch",
1779 		.info = aureon_ac97_mute_info,
1780 		.get = aureon_ac97_mute_get,
1781 		.put = aureon_ac97_mute_put,
1782 		.private_value = AC97_CD
1783 	},
1784 	{
1785 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1786 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1787 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1788 		.name = "Phono Playback Volume",
1789 		.info = aureon_ac97_vol_info,
1790 		.get = aureon_ac97_vol_get,
1791 		.put = aureon_ac97_vol_put,
1792 		.private_value = AC97_CD|AUREON_AC97_STEREO,
1793 		.tlv = { .p = db_scale_ac97_gain }
1794 	},
1795 	{
1796 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1797 		.name = "Line Playback Switch",
1798 		.info = aureon_ac97_mute_info,
1799 		.get = aureon_ac97_mute_get,
1800 		.put = aureon_ac97_mute_put,
1801 		.private_value = AC97_LINE
1802 	},
1803 	{
1804 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1805 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1806 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1807 		.name = "Line Playback Volume",
1808 		.info = aureon_ac97_vol_info,
1809 		.get = aureon_ac97_vol_get,
1810 		.put = aureon_ac97_vol_put,
1811 		.private_value = AC97_LINE|AUREON_AC97_STEREO,
1812 		.tlv = { .p = db_scale_ac97_gain }
1813 	},
1814 	{
1815 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1816 		.name = "Mic Playback Switch",
1817 		.info = aureon_ac97_mute_info,
1818 		.get = aureon_ac97_mute_get,
1819 		.put = aureon_ac97_mute_put,
1820 		.private_value = AC97_MIC
1821 	},
1822 	{
1823 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1824 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1825 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1826 		.name = "Mic Playback Volume",
1827 		.info = aureon_ac97_vol_info,
1828 		.get = aureon_ac97_vol_get,
1829 		.put = aureon_ac97_vol_put,
1830 		.private_value = AC97_MIC,
1831 		.tlv = { .p = db_scale_ac97_gain }
1832 	},
1833 	{
1834 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1835 		.name = "Mic Boost (+20dB)",
1836 		.info = aureon_ac97_micboost_info,
1837 		.get = aureon_ac97_micboost_get,
1838 		.put = aureon_ac97_micboost_put
1839 	},
1840 	{
1841 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1842 		.name = "Aux Playback Switch",
1843 		.info = aureon_ac97_mute_info,
1844 		.get = aureon_ac97_mute_get,
1845 		.put = aureon_ac97_mute_put,
1846 		.private_value = AC97_VIDEO,
1847 	},
1848 	{
1849 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1850 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1851 				SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1852 		.name = "Aux Playback Volume",
1853 		.info = aureon_ac97_vol_info,
1854 		.get = aureon_ac97_vol_get,
1855 		.put = aureon_ac97_vol_put,
1856 		.private_value = AC97_VIDEO|AUREON_AC97_STEREO,
1857 		.tlv = { .p = db_scale_ac97_gain }
1858 	},
1859 	{
1860 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1861 		.name = "Aux Source",
1862 		.info = aureon_universe_inmux_info,
1863 		.get = aureon_universe_inmux_get,
1864 		.put = aureon_universe_inmux_put
1865 	}
1866 
1867 };
1868 
1869 static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
1870 	{
1871 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1872 		.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
1873 		.info = aureon_cs8415_mute_info,
1874 		.get = aureon_cs8415_mute_get,
1875 		.put = aureon_cs8415_mute_put
1876 	},
1877 	{
1878 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1879 		.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Source",
1880 		.info = aureon_cs8415_mux_info,
1881 		.get = aureon_cs8415_mux_get,
1882 		.put = aureon_cs8415_mux_put,
1883 	},
1884 	{
1885 		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
1886 		.name = SNDRV_CTL_NAME_IEC958("Q-subcode ", CAPTURE, DEFAULT),
1887 		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1888 		.info = aureon_cs8415_qsub_info,
1889 		.get = aureon_cs8415_qsub_get,
1890 	},
1891 	{
1892 		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
1893 		.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
1894 		.access = SNDRV_CTL_ELEM_ACCESS_READ,
1895 		.info = aureon_cs8415_spdif_info,
1896 		.get = aureon_cs8415_mask_get
1897 	},
1898 	{
1899 		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
1900 		.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
1901 		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1902 		.info = aureon_cs8415_spdif_info,
1903 		.get = aureon_cs8415_spdif_get
1904 	},
1905 	{
1906 		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
1907 		.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Rate",
1908 		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1909 		.info = aureon_cs8415_rate_info,
1910 		.get = aureon_cs8415_rate_get
1911 	}
1912 };
1913 
1914 static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1915 {
1916 	unsigned int i, counts;
1917 	int err;
1918 
1919 	counts = ARRAY_SIZE(aureon_dac_controls);
1920 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
1921 		counts -= 2; /* no side */
1922 	for (i = 0; i < counts; i++) {
1923 		err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
1924 		if (err < 0)
1925 			return err;
1926 	}
1927 
1928 	for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
1929 		err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
1930 		if (err < 0)
1931 			return err;
1932 	}
1933 
1934 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1935 		for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
1936 			err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
1937 			if (err < 0)
1938 				return err;
1939 		}
1940 	} else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1941 		 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1942 		for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
1943 			err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
1944 			if (err < 0)
1945 				return err;
1946 		}
1947 	}
1948 
1949 	if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1950 	    ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1951 		unsigned char id;
1952 		snd_ice1712_save_gpio_status(ice);
1953 		id = aureon_cs8415_get(ice, CS8415_ID);
1954 		if (id != 0x41)
1955 			snd_printk(KERN_INFO "No CS8415 chip. Skipping CS8415 controls.\n");
1956 		else if ((id & 0x0F) != 0x01)
1957 			snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
1958 		else {
1959 			for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
1960 				struct snd_kcontrol *kctl;
1961 				err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
1962 				if (err < 0)
1963 					return err;
1964 				if (i > 1)
1965 					kctl->id.device = ice->pcm->device;
1966 			}
1967 		}
1968 		snd_ice1712_restore_gpio_status(ice);
1969 	}
1970 
1971 	return 0;
1972 }
1973 
1974 
1975 /*
1976  * initialize the chip
1977  */
1978 static int __devinit aureon_init(struct snd_ice1712 *ice)
1979 {
1980 	static const unsigned short wm_inits_aureon[] = {
1981 		/* These come first to reduce init pop noise */
1982 		0x1b, 0x044,		/* ADC Mux (AC'97 source) */
1983 		0x1c, 0x00B,		/* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
1984 		0x1d, 0x009,		/* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
1985 
1986 		0x18, 0x000,		/* All power-up */
1987 
1988 		0x16, 0x122,		/* I2S, normal polarity, 24bit */
1989 		0x17, 0x022,		/* 256fs, slave mode */
1990 		0x00, 0,		/* DAC1 analog mute */
1991 		0x01, 0,		/* DAC2 analog mute */
1992 		0x02, 0,		/* DAC3 analog mute */
1993 		0x03, 0,		/* DAC4 analog mute */
1994 		0x04, 0,		/* DAC5 analog mute */
1995 		0x05, 0,		/* DAC6 analog mute */
1996 		0x06, 0,		/* DAC7 analog mute */
1997 		0x07, 0,		/* DAC8 analog mute */
1998 		0x08, 0x100,		/* master analog mute */
1999 		0x09, 0xff,		/* DAC1 digital full */
2000 		0x0a, 0xff,		/* DAC2 digital full */
2001 		0x0b, 0xff,		/* DAC3 digital full */
2002 		0x0c, 0xff,		/* DAC4 digital full */
2003 		0x0d, 0xff,		/* DAC5 digital full */
2004 		0x0e, 0xff,		/* DAC6 digital full */
2005 		0x0f, 0xff,		/* DAC7 digital full */
2006 		0x10, 0xff,		/* DAC8 digital full */
2007 		0x11, 0x1ff,		/* master digital full */
2008 		0x12, 0x000,		/* phase normal */
2009 		0x13, 0x090,		/* unmute DAC L/R */
2010 		0x14, 0x000,		/* all unmute */
2011 		0x15, 0x000,		/* no deemphasis, no ZFLG */
2012 		0x19, 0x000,		/* -12dB ADC/L */
2013 		0x1a, 0x000,		/* -12dB ADC/R */
2014 		(unsigned short)-1
2015 	};
2016 	static const unsigned short wm_inits_prodigy[] = {
2017 
2018 		/* These come first to reduce init pop noise */
2019 		0x1b, 0x000,		/* ADC Mux */
2020 		0x1c, 0x009,		/* Out Mux1 */
2021 		0x1d, 0x009,		/* Out Mux2 */
2022 
2023 		0x18, 0x000,		/* All power-up */
2024 
2025 		0x16, 0x022,		/* I2S, normal polarity, 24bit, high-pass on */
2026 		0x17, 0x006,		/* 128fs, slave mode */
2027 
2028 		0x00, 0,		/* DAC1 analog mute */
2029 		0x01, 0,		/* DAC2 analog mute */
2030 		0x02, 0,		/* DAC3 analog mute */
2031 		0x03, 0,		/* DAC4 analog mute */
2032 		0x04, 0,		/* DAC5 analog mute */
2033 		0x05, 0,		/* DAC6 analog mute */
2034 		0x06, 0,		/* DAC7 analog mute */
2035 		0x07, 0,		/* DAC8 analog mute */
2036 		0x08, 0x100,		/* master analog mute */
2037 
2038 		0x09, 0x7f,		/* DAC1 digital full */
2039 		0x0a, 0x7f,		/* DAC2 digital full */
2040 		0x0b, 0x7f,		/* DAC3 digital full */
2041 		0x0c, 0x7f,		/* DAC4 digital full */
2042 		0x0d, 0x7f,		/* DAC5 digital full */
2043 		0x0e, 0x7f,		/* DAC6 digital full */
2044 		0x0f, 0x7f,		/* DAC7 digital full */
2045 		0x10, 0x7f,		/* DAC8 digital full */
2046 		0x11, 0x1FF,		/* master digital full */
2047 
2048 		0x12, 0x000,		/* phase normal */
2049 		0x13, 0x090,		/* unmute DAC L/R */
2050 		0x14, 0x000,		/* all unmute */
2051 		0x15, 0x000,		/* no deemphasis, no ZFLG */
2052 
2053 		0x19, 0x000,		/* -12dB ADC/L */
2054 		0x1a, 0x000,		/* -12dB ADC/R */
2055 		(unsigned short)-1
2056 
2057 	};
2058 	static const unsigned short cs_inits[] = {
2059 		0x0441, /* RUN */
2060 		0x0180, /* no mute, OMCK output on RMCK pin */
2061 		0x0201, /* S/PDIF source on RXP1 */
2062 		0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
2063 		(unsigned short)-1
2064 	};
2065 	struct aureon_spec *spec;
2066 	unsigned int tmp;
2067 	const unsigned short *p;
2068 	int err, i;
2069 
2070 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2071 	if (!spec)
2072 		return -ENOMEM;
2073 	ice->spec = spec;
2074 
2075 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
2076 		ice->num_total_dacs = 6;
2077 		ice->num_total_adcs = 2;
2078 	} else {
2079 		/* aureon 7.1 and prodigy 7.1 */
2080 		ice->num_total_dacs = 8;
2081 		ice->num_total_adcs = 2;
2082 	}
2083 
2084 	/* to remeber the register values of CS8415 */
2085 	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2086 	if (!ice->akm)
2087 		return -ENOMEM;
2088 	ice->akm_codecs = 1;
2089 
2090 	err = aureon_ac97_init(ice);
2091 	if (err != 0)
2092 		return err;
2093 
2094 	snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
2095 
2096 	/* reset the wm codec as the SPI mode */
2097 	snd_ice1712_save_gpio_status(ice);
2098 	snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
2099 
2100 	tmp = snd_ice1712_gpio_read(ice);
2101 	tmp &= ~AUREON_WM_RESET;
2102 	snd_ice1712_gpio_write(ice, tmp);
2103 	udelay(1);
2104 	tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
2105 	snd_ice1712_gpio_write(ice, tmp);
2106 	udelay(1);
2107 	tmp |= AUREON_WM_RESET;
2108 	snd_ice1712_gpio_write(ice, tmp);
2109 	udelay(1);
2110 
2111 	/* initialize WM8770 codec */
2112 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
2113 		ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
2114 		ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT)
2115 		p = wm_inits_prodigy;
2116 	else
2117 		p = wm_inits_aureon;
2118 	for (; *p != (unsigned short)-1; p += 2)
2119 		wm_put(ice, p[0], p[1]);
2120 
2121 	/* initialize CS8415A codec */
2122 	if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
2123 	    ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
2124 		for (p = cs_inits; *p != (unsigned short)-1; p++)
2125 			aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
2126 		spec->cs8415_mux = 1;
2127 
2128 		aureon_set_headphone_amp(ice, 1);
2129 	}
2130 
2131 	snd_ice1712_restore_gpio_status(ice);
2132 
2133 	/* initialize PCA9554 pin directions & set default input */
2134 	aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2135 	aureon_pca9554_write(ice, PCA9554_OUT, 0x00);   /* internal AUX */
2136 
2137 	spec->master[0] = WM_VOL_MUTE;
2138 	spec->master[1] = WM_VOL_MUTE;
2139 	for (i = 0; i < ice->num_total_dacs; i++) {
2140 		spec->vol[i] = WM_VOL_MUTE;
2141 		wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2142 	}
2143 
2144 	return 0;
2145 }
2146 
2147 
2148 /*
2149  * Aureon boards don't provide the EEPROM data except for the vendor IDs.
2150  * hence the driver needs to sets up it properly.
2151  */
2152 
2153 static unsigned char aureon51_eeprom[] __devinitdata = {
2154 	[ICE_EEP2_SYSCONF]     = 0x0a,	/* clock 512, spdif-in/ADC, 3DACs */
2155 	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
2156 	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */
2157 	[ICE_EEP2_SPDIF]       = 0xc3,	/* out-en, out-int, spdif-in */
2158 	[ICE_EEP2_GPIO_DIR]    = 0xff,
2159 	[ICE_EEP2_GPIO_DIR1]   = 0xff,
2160 	[ICE_EEP2_GPIO_DIR2]   = 0x5f,
2161 	[ICE_EEP2_GPIO_MASK]   = 0x00,
2162 	[ICE_EEP2_GPIO_MASK1]  = 0x00,
2163 	[ICE_EEP2_GPIO_MASK2]  = 0x00,
2164 	[ICE_EEP2_GPIO_STATE]  = 0x00,
2165 	[ICE_EEP2_GPIO_STATE1] = 0x00,
2166 	[ICE_EEP2_GPIO_STATE2] = 0x00,
2167 };
2168 
2169 static unsigned char aureon71_eeprom[] __devinitdata = {
2170 	[ICE_EEP2_SYSCONF]     = 0x0b,	/* clock 512, spdif-in/ADC, 4DACs */
2171 	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
2172 	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */
2173 	[ICE_EEP2_SPDIF]       = 0xc3,	/* out-en, out-int, spdif-in */
2174 	[ICE_EEP2_GPIO_DIR]    = 0xff,
2175 	[ICE_EEP2_GPIO_DIR1]   = 0xff,
2176 	[ICE_EEP2_GPIO_DIR2]   = 0x5f,
2177 	[ICE_EEP2_GPIO_MASK]   = 0x00,
2178 	[ICE_EEP2_GPIO_MASK1]  = 0x00,
2179 	[ICE_EEP2_GPIO_MASK2]  = 0x00,
2180 	[ICE_EEP2_GPIO_STATE]  = 0x00,
2181 	[ICE_EEP2_GPIO_STATE1] = 0x00,
2182 	[ICE_EEP2_GPIO_STATE2] = 0x00,
2183 };
2184 #define prodigy71_eeprom aureon71_eeprom
2185 
2186 static unsigned char aureon71_universe_eeprom[] __devinitdata = {
2187 	[ICE_EEP2_SYSCONF]     = 0x2b,	/* clock 512, mpu401, spdif-in/ADC,
2188 					 * 4DACs
2189 					 */
2190 	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
2191 	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */
2192 	[ICE_EEP2_SPDIF]       = 0xc3,	/* out-en, out-int, spdif-in */
2193 	[ICE_EEP2_GPIO_DIR]    = 0xff,
2194 	[ICE_EEP2_GPIO_DIR1]   = 0xff,
2195 	[ICE_EEP2_GPIO_DIR2]   = 0x5f,
2196 	[ICE_EEP2_GPIO_MASK]   = 0x00,
2197 	[ICE_EEP2_GPIO_MASK1]  = 0x00,
2198 	[ICE_EEP2_GPIO_MASK2]  = 0x00,
2199 	[ICE_EEP2_GPIO_STATE]  = 0x00,
2200 	[ICE_EEP2_GPIO_STATE1] = 0x00,
2201 	[ICE_EEP2_GPIO_STATE2] = 0x00,
2202 };
2203 
2204 static unsigned char prodigy71lt_eeprom[] __devinitdata = {
2205 	[ICE_EEP2_SYSCONF]     = 0x4b,	/* clock 384, spdif-in/ADC, 4DACs */
2206 	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
2207 	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */
2208 	[ICE_EEP2_SPDIF]       = 0xc3,	/* out-en, out-int, spdif-in */
2209 	[ICE_EEP2_GPIO_DIR]    = 0xff,
2210 	[ICE_EEP2_GPIO_DIR1]   = 0xff,
2211 	[ICE_EEP2_GPIO_DIR2]   = 0x5f,
2212 	[ICE_EEP2_GPIO_MASK]   = 0x00,
2213 	[ICE_EEP2_GPIO_MASK1]  = 0x00,
2214 	[ICE_EEP2_GPIO_MASK2]  = 0x00,
2215 	[ICE_EEP2_GPIO_STATE]  = 0x00,
2216 	[ICE_EEP2_GPIO_STATE1] = 0x00,
2217 	[ICE_EEP2_GPIO_STATE2] = 0x00,
2218 };
2219 #define prodigy71xt_eeprom prodigy71lt_eeprom
2220 
2221 /* entry point */
2222 struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
2223 	{
2224 		.subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
2225 		.name = "Terratec Aureon 5.1-Sky",
2226 		.model = "aureon51",
2227 		.chip_init = aureon_init,
2228 		.build_controls = aureon_add_controls,
2229 		.eeprom_size = sizeof(aureon51_eeprom),
2230 		.eeprom_data = aureon51_eeprom,
2231 		.driver = "Aureon51",
2232 	},
2233 	{
2234 		.subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
2235 		.name = "Terratec Aureon 7.1-Space",
2236 		.model = "aureon71",
2237 		.chip_init = aureon_init,
2238 		.build_controls = aureon_add_controls,
2239 		.eeprom_size = sizeof(aureon71_eeprom),
2240 		.eeprom_data = aureon71_eeprom,
2241 		.driver = "Aureon71",
2242 	},
2243 	{
2244 		.subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
2245 		.name = "Terratec Aureon 7.1-Universe",
2246 		.model = "universe",
2247 		.chip_init = aureon_init,
2248 		.build_controls = aureon_add_controls,
2249 		.eeprom_size = sizeof(aureon71_universe_eeprom),
2250 		.eeprom_data = aureon71_universe_eeprom,
2251 		.driver = "Aureon71Univ", /* keep in 15 letters */
2252 	},
2253 	{
2254 		.subvendor = VT1724_SUBDEVICE_PRODIGY71,
2255 		.name = "Audiotrak Prodigy 7.1",
2256 		.model = "prodigy71",
2257 		.chip_init = aureon_init,
2258 		.build_controls = aureon_add_controls,
2259 		.eeprom_size = sizeof(prodigy71_eeprom),
2260 		.eeprom_data = prodigy71_eeprom,
2261 		.driver = "Prodigy71", /* should be identical with Aureon71 */
2262 	},
2263 	{
2264 		.subvendor = VT1724_SUBDEVICE_PRODIGY71LT,
2265 		.name = "Audiotrak Prodigy 7.1 LT",
2266 		.model = "prodigy71lt",
2267 		.chip_init = aureon_init,
2268 		.build_controls = aureon_add_controls,
2269 		.eeprom_size = sizeof(prodigy71lt_eeprom),
2270 		.eeprom_data = prodigy71lt_eeprom,
2271 		.driver = "Prodigy71LT",
2272 	},
2273 	{
2274 		.subvendor = VT1724_SUBDEVICE_PRODIGY71XT,
2275 		.name = "Audiotrak Prodigy 7.1 XT",
2276 		.model = "prodigy71xt",
2277 		.chip_init = aureon_init,
2278 		.build_controls = aureon_add_controls,
2279 		.eeprom_size = sizeof(prodigy71xt_eeprom),
2280 		.eeprom_data = prodigy71xt_eeprom,
2281 		.driver = "Prodigy71LT",
2282 	},
2283 	{ } /* terminator */
2284 };
2285