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