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