xref: /linux/sound/pci/ice1712/aureon.c (revision 6e8331ac6973435b1e7604c30f2ad394035b46e1)
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 		if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT)
1285 			tmp |= AUREON_HP_SEL;
1286 		else
1287 			tmp |= PRODIGY_HP_SEL;
1288 	else
1289 		if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT)
1290 			tmp &= ~ AUREON_HP_SEL;
1291 		else
1292 			tmp &= ~ PRODIGY_HP_SEL;
1293 	if (tmp != tmp2) {
1294 		snd_ice1712_gpio_write(ice, tmp);
1295 		return 1;
1296 	}
1297 	return 0;
1298 }
1299 
1300 static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
1301 {
1302 	unsigned int tmp = snd_ice1712_gpio_read(ice);
1303 
1304 	return ( tmp & AUREON_HP_SEL )!= 0;
1305 }
1306 
1307 #define aureon_hpamp_info	aureon_mono_bool_info
1308 
1309 static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1310 {
1311 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1312 
1313 	ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
1314 	return 0;
1315 }
1316 
1317 
1318 static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1319 {
1320 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1321 
1322 	return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]);
1323 }
1324 
1325 /*
1326  * Deemphasis
1327  */
1328 
1329 #define aureon_deemp_info	aureon_mono_bool_info
1330 
1331 static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1332 {
1333 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1334 	ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
1335 	return 0;
1336 }
1337 
1338 static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1339 {
1340 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1341 	int temp, temp2;
1342 	temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
1343 	if (ucontrol->value.integer.value[0])
1344 		temp |= 0xf;
1345 	else
1346 		temp &= ~0xf;
1347 	if (temp != temp2) {
1348 		wm_put(ice, WM_DAC_CTRL2, temp);
1349 		return 1;
1350 	}
1351 	return 0;
1352 }
1353 
1354 /*
1355  * ADC Oversampling
1356  */
1357 static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
1358 {
1359 	static char *texts[2] = { "128x", "64x"	};
1360 
1361 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1362 	uinfo->count = 1;
1363 	uinfo->value.enumerated.items = 2;
1364 
1365 	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1366 		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1367 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1368 
1369         return 0;
1370 }
1371 
1372 static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1373 {
1374 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1375 	ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
1376 	return 0;
1377 }
1378 
1379 static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1380 {
1381 	int temp, temp2;
1382 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1383 
1384 	temp2 = temp = wm_get(ice, WM_MASTER);
1385 
1386 	if (ucontrol->value.enumerated.item[0])
1387 		temp |= 0x8;
1388 	else
1389 		temp &= ~0x8;
1390 
1391 	if (temp != temp2) {
1392 		wm_put(ice, WM_MASTER, temp);
1393 		return 1;
1394 	}
1395 	return 0;
1396 }
1397 
1398 /*
1399  * mixers
1400  */
1401 
1402 static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
1403 	{
1404 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1405 		.name = "Master Playback Switch",
1406 		.info = wm_master_mute_info,
1407 		.get = wm_master_mute_get,
1408 		.put = wm_master_mute_put
1409 	},
1410 	{
1411 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1412 		.name = "Master Playback Volume",
1413 		.info = wm_master_vol_info,
1414 		.get = wm_master_vol_get,
1415 		.put = wm_master_vol_put
1416 	},
1417 	{
1418 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1419 		.name = "Front Playback Switch",
1420 		.info = wm_mute_info,
1421 		.get = wm_mute_get,
1422 		.put = wm_mute_put,
1423 		.private_value = (2 << 8) | 0
1424 	},
1425 	{
1426 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1427 		.name = "Front Playback Volume",
1428 		.info = wm_vol_info,
1429 		.get = wm_vol_get,
1430 		.put = wm_vol_put,
1431 		.private_value = (2 << 8) | 0
1432 	},
1433 	{
1434 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1435 		.name = "Rear Playback Switch",
1436 		.info = wm_mute_info,
1437 		.get = wm_mute_get,
1438 		.put = wm_mute_put,
1439 		.private_value = (2 << 8) | 2
1440 	},
1441 	{
1442 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1443 		.name = "Rear Playback Volume",
1444 		.info = wm_vol_info,
1445 		.get = wm_vol_get,
1446 		.put = wm_vol_put,
1447 		.private_value = (2 << 8) | 2
1448 	},
1449 	{
1450 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1451 		.name = "Center Playback Switch",
1452 		.info = wm_mute_info,
1453 		.get = wm_mute_get,
1454 		.put = wm_mute_put,
1455 		.private_value = (1 << 8) | 4
1456 	},
1457 	{
1458 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1459 		.name = "Center Playback Volume",
1460 		.info = wm_vol_info,
1461 		.get = wm_vol_get,
1462 		.put = wm_vol_put,
1463 		.private_value = (1 << 8) | 4
1464 	},
1465 	{
1466 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1467 		.name = "LFE Playback Switch",
1468 		.info = wm_mute_info,
1469 		.get = wm_mute_get,
1470 		.put = wm_mute_put,
1471 		.private_value = (1 << 8) | 5
1472 	},
1473 	{
1474 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1475 		.name = "LFE Playback Volume",
1476 		.info = wm_vol_info,
1477 		.get = wm_vol_get,
1478 		.put = wm_vol_put,
1479 		.private_value = (1 << 8) | 5
1480 	},
1481 	{
1482 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1483 		.name = "Side Playback Switch",
1484 		.info = wm_mute_info,
1485 		.get = wm_mute_get,
1486 		.put = wm_mute_put,
1487 		.private_value = (2 << 8) | 6
1488 	},
1489 	{
1490 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1491 		.name = "Side Playback Volume",
1492 		.info = wm_vol_info,
1493 		.get = wm_vol_get,
1494 		.put = wm_vol_put,
1495 		.private_value = (2 << 8) | 6
1496 	}
1497 };
1498 
1499 static struct snd_kcontrol_new wm_controls[] __devinitdata = {
1500  	{
1501  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1502 		.name = "PCM Playback Switch",
1503 		.info = wm_pcm_mute_info,
1504 		.get = wm_pcm_mute_get,
1505 		.put = wm_pcm_mute_put
1506  	},
1507  	{
1508  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1509 		.name = "PCM Playback Volume",
1510 		.info = wm_pcm_vol_info,
1511 		.get = wm_pcm_vol_get,
1512 		.put = wm_pcm_vol_put
1513  	},
1514 	{
1515 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1516 		.name = "Capture Switch",
1517 		.info = wm_adc_mute_info,
1518 		.get = wm_adc_mute_get,
1519 		.put = wm_adc_mute_put,
1520 	},
1521 	{
1522 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1523 		.name = "Capture Volume",
1524 		.info = wm_adc_vol_info,
1525 		.get = wm_adc_vol_get,
1526 		.put = wm_adc_vol_put
1527 	},
1528 	{
1529 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1530 		.name = "Capture Source",
1531 		.info = wm_adc_mux_info,
1532 		.get = wm_adc_mux_get,
1533 		.put = wm_adc_mux_put,
1534 		.private_value = 5
1535 	},
1536 	{
1537 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1538 		.name = "External Amplifier",
1539 		.info = aureon_hpamp_info,
1540 		.get = aureon_hpamp_get,
1541 		.put = aureon_hpamp_put
1542 	},
1543 	{
1544 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1545 		.name = "DAC Deemphasis Switch",
1546 		.info = aureon_deemp_info,
1547 		.get = aureon_deemp_get,
1548 		.put = aureon_deemp_put
1549 	},
1550 	{
1551 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1552 		.name = "ADC Oversampling",
1553 		.info = aureon_oversampling_info,
1554 		.get = aureon_oversampling_get,
1555 		.put = aureon_oversampling_put
1556 	}
1557 };
1558 
1559 static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
1560  	{
1561  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1562 		.name = "AC97 Playback Switch",
1563 		.info = aureon_ac97_mmute_info,
1564 		.get = aureon_ac97_mmute_get,
1565 		.put = aureon_ac97_mmute_put,
1566 		.private_value = AC97_MASTER
1567  	},
1568  	{
1569  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1570  		.name = "AC97 Playback Volume",
1571  		.info = aureon_ac97_vol_info,
1572  		.get = aureon_ac97_vol_get,
1573  		.put = aureon_ac97_vol_put,
1574  		.private_value = AC97_MASTER|AUREON_AC97_STEREO
1575  	},
1576  	{
1577  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1578  		.name = "CD Playback Switch",
1579  		.info = aureon_ac97_mute_info,
1580  		.get = aureon_ac97_mute_get,
1581  		.put = aureon_ac97_mute_put,
1582  		.private_value = AC97_CD
1583  	},
1584  	{
1585  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1586  		.name = "CD Playback Volume",
1587  		.info = aureon_ac97_vol_info,
1588  		.get = aureon_ac97_vol_get,
1589  		.put = aureon_ac97_vol_put,
1590  		.private_value = AC97_CD|AUREON_AC97_STEREO
1591  	},
1592  	{
1593  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1594  		.name = "Aux Playback Switch",
1595  		.info = aureon_ac97_mute_info,
1596  		.get = aureon_ac97_mute_get,
1597  		.put = aureon_ac97_mute_put,
1598  		.private_value = AC97_AUX,
1599  	},
1600  	{
1601  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1602  		.name = "Aux Playback Volume",
1603  		.info = aureon_ac97_vol_info,
1604  		.get = aureon_ac97_vol_get,
1605  		.put = aureon_ac97_vol_put,
1606  		.private_value = AC97_AUX|AUREON_AC97_STEREO
1607  	},
1608  	{
1609  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1610  		.name = "Line Playback Switch",
1611  		.info = aureon_ac97_mute_info,
1612  		.get = aureon_ac97_mute_get,
1613  		.put = aureon_ac97_mute_put,
1614  		.private_value = AC97_LINE
1615  	},
1616  	{
1617  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1618  		.name = "Line Playback Volume",
1619  		.info = aureon_ac97_vol_info,
1620  		.get = aureon_ac97_vol_get,
1621  		.put = aureon_ac97_vol_put,
1622  		.private_value = AC97_LINE|AUREON_AC97_STEREO
1623  	},
1624  	{
1625  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1626  		.name = "Mic Playback Switch",
1627  		.info = aureon_ac97_mute_info,
1628  		.get = aureon_ac97_mute_get,
1629  		.put = aureon_ac97_mute_put,
1630  		.private_value = AC97_MIC
1631  	},
1632  	{
1633  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1634  		.name = "Mic Playback Volume",
1635  		.info = aureon_ac97_vol_info,
1636  		.get = aureon_ac97_vol_get,
1637  		.put = aureon_ac97_vol_put,
1638  		.private_value = AC97_MIC
1639  	},
1640  	{
1641  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1642  		.name = "Mic Boost (+20dB)",
1643  		.info = aureon_ac97_micboost_info,
1644  		.get = aureon_ac97_micboost_get,
1645  		.put = aureon_ac97_micboost_put
1646  	}
1647 };
1648 
1649 static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
1650  	{
1651  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1652 		.name = "AC97 Playback Switch",
1653 		.info = aureon_ac97_mmute_info,
1654 		.get = aureon_ac97_mmute_get,
1655 		.put = aureon_ac97_mmute_put,
1656 		.private_value = AC97_MASTER
1657  	},
1658  	{
1659  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1660  		.name = "AC97 Playback Volume",
1661  		.info = aureon_ac97_vol_info,
1662  		.get = aureon_ac97_vol_get,
1663  		.put = aureon_ac97_vol_put,
1664  		.private_value = AC97_MASTER|AUREON_AC97_STEREO
1665  	},
1666  	{
1667  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1668  		.name = "CD Playback Switch",
1669  		.info = aureon_ac97_mute_info,
1670  		.get = aureon_ac97_mute_get,
1671  		.put = aureon_ac97_mute_put,
1672  		.private_value = AC97_AUX
1673  	},
1674  	{
1675  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1676  		.name = "CD Playback Volume",
1677  		.info = aureon_ac97_vol_info,
1678  		.get = aureon_ac97_vol_get,
1679  		.put = aureon_ac97_vol_put,
1680  		.private_value = AC97_AUX|AUREON_AC97_STEREO
1681  	},
1682  	{
1683  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1684  		.name = "Phono Playback Switch",
1685  		.info = aureon_ac97_mute_info,
1686  		.get = aureon_ac97_mute_get,
1687  		.put = aureon_ac97_mute_put,
1688  		.private_value = AC97_CD,
1689  	},
1690  	{
1691  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1692  		.name = "Phono Playback Volume",
1693  		.info = aureon_ac97_vol_info,
1694  		.get = aureon_ac97_vol_get,
1695  		.put = aureon_ac97_vol_put,
1696  		.private_value = AC97_CD|AUREON_AC97_STEREO
1697  	},
1698  	{
1699  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1700  		.name = "Line Playback Switch",
1701  		.info = aureon_ac97_mute_info,
1702  		.get = aureon_ac97_mute_get,
1703  		.put = aureon_ac97_mute_put,
1704  		.private_value = AC97_LINE
1705  	},
1706  	{
1707  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1708  		.name = "Line Playback Volume",
1709  		.info = aureon_ac97_vol_info,
1710  		.get = aureon_ac97_vol_get,
1711  		.put = aureon_ac97_vol_put,
1712  		.private_value = AC97_LINE|AUREON_AC97_STEREO
1713  	},
1714  	{
1715  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1716  		.name = "Mic Playback Switch",
1717  		.info = aureon_ac97_mute_info,
1718  		.get = aureon_ac97_mute_get,
1719  		.put = aureon_ac97_mute_put,
1720  		.private_value = AC97_MIC
1721  	},
1722  	{
1723  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1724  		.name = "Mic Playback Volume",
1725  		.info = aureon_ac97_vol_info,
1726  		.get = aureon_ac97_vol_get,
1727  		.put = aureon_ac97_vol_put,
1728  		.private_value = AC97_MIC
1729  	},
1730  	{
1731  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1732  		.name = "Mic Boost (+20dB)",
1733  		.info = aureon_ac97_micboost_info,
1734  		.get = aureon_ac97_micboost_get,
1735  		.put = aureon_ac97_micboost_put
1736  	},
1737  	{
1738  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1739  		.name = "Aux Playback Switch",
1740  		.info = aureon_ac97_mute_info,
1741  		.get = aureon_ac97_mute_get,
1742  		.put = aureon_ac97_mute_put,
1743  		.private_value = AC97_VIDEO,
1744  	},
1745  	{
1746  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1747  		.name = "Aux Playback Volume",
1748  		.info = aureon_ac97_vol_info,
1749  		.get = aureon_ac97_vol_get,
1750  		.put = aureon_ac97_vol_put,
1751  		.private_value = AC97_VIDEO|AUREON_AC97_STEREO
1752  	},
1753 	{
1754 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1755 		.name = "Aux Source",
1756 		.info = aureon_universe_inmux_info,
1757 		.get = aureon_universe_inmux_get,
1758 		.put = aureon_universe_inmux_put
1759 	}
1760 
1761 };
1762 
1763 
1764 static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
1765 	{
1766 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1767 		.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
1768 		.info = aureon_cs8415_mute_info,
1769 		.get = aureon_cs8415_mute_get,
1770 		.put = aureon_cs8415_mute_put
1771 	},
1772  	{
1773  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1774 		.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Source",
1775 		.info = aureon_cs8415_mux_info,
1776 		.get = aureon_cs8415_mux_get,
1777 		.put = aureon_cs8415_mux_put,
1778 	},
1779 	{
1780 		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
1781 		.name = SNDRV_CTL_NAME_IEC958("Q-subcode ",CAPTURE,DEFAULT),
1782 		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1783 		.info = aureon_cs8415_qsub_info,
1784 		.get = aureon_cs8415_qsub_get,
1785 	},
1786 	{
1787 		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
1788 		.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
1789 		.access = SNDRV_CTL_ELEM_ACCESS_READ,
1790 		.info = aureon_cs8415_spdif_info,
1791 		.get = aureon_cs8415_mask_get
1792 	},
1793 	{
1794 		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
1795 		.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
1796 		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1797 		.info = aureon_cs8415_spdif_info,
1798 		.get = aureon_cs8415_spdif_get
1799 	},
1800 	{
1801 		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
1802 		.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Rate",
1803 		.access =SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1804 		.info = aureon_cs8415_rate_info,
1805 		.get = aureon_cs8415_rate_get
1806 	}
1807 };
1808 
1809 
1810 static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1811 {
1812 	unsigned int i, counts;
1813 	int err;
1814 
1815 	counts = ARRAY_SIZE(aureon_dac_controls);
1816 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
1817 		counts -= 2; /* no side */
1818 	for (i = 0; i < counts; i++) {
1819 		err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
1820 		if (err < 0)
1821 			return err;
1822 	}
1823 
1824 	for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
1825 		err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
1826 		if (err < 0)
1827 			return err;
1828 	}
1829 
1830 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1831 		for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
1832 			err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
1833 			if (err < 0)
1834 				return err;
1835 		}
1836 	}
1837 	else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) {
1838 		for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
1839 			err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
1840 			if (err < 0)
1841 				return err;
1842 		}
1843 	}
1844 
1845 	if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) {
1846 		unsigned char id;
1847 		snd_ice1712_save_gpio_status(ice);
1848 		id = aureon_cs8415_get(ice, CS8415_ID);
1849 		if (id != 0x41)
1850 			snd_printk(KERN_INFO "No CS8415 chip. Skipping CS8415 controls.\n");
1851 		else if ((id & 0x0F) != 0x01)
1852 			snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
1853 		else {
1854 			for (i = 0; i< ARRAY_SIZE(cs8415_controls); i++) {
1855 				struct snd_kcontrol *kctl;
1856 				err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
1857 				if (err < 0)
1858 					return err;
1859 				if (i > 1)
1860 					kctl->id.device = ice->pcm->device;
1861 			}
1862 		}
1863 		snd_ice1712_restore_gpio_status(ice);
1864 	}
1865 
1866 	return 0;
1867 }
1868 
1869 
1870 /*
1871  * initialize the chip
1872  */
1873 static int __devinit aureon_init(struct snd_ice1712 *ice)
1874 {
1875 	static unsigned short wm_inits_aureon[] = {
1876 		/* These come first to reduce init pop noise */
1877 		0x1b, 0x044,		/* ADC Mux (AC'97 source) */
1878 		0x1c, 0x00B,		/* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
1879 		0x1d, 0x009,		/* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
1880 
1881 		0x18, 0x000,		/* All power-up */
1882 
1883 		0x16, 0x122,		/* I2S, normal polarity, 24bit */
1884 		0x17, 0x022,		/* 256fs, slave mode */
1885 		0x00, 0,		/* DAC1 analog mute */
1886 		0x01, 0,		/* DAC2 analog mute */
1887 		0x02, 0,		/* DAC3 analog mute */
1888 		0x03, 0,		/* DAC4 analog mute */
1889 		0x04, 0,		/* DAC5 analog mute */
1890 		0x05, 0,		/* DAC6 analog mute */
1891 		0x06, 0,		/* DAC7 analog mute */
1892 		0x07, 0,		/* DAC8 analog mute */
1893 		0x08, 0x100,		/* master analog mute */
1894 		0x09, 0xff,		/* DAC1 digital full */
1895 		0x0a, 0xff,		/* DAC2 digital full */
1896 		0x0b, 0xff,		/* DAC3 digital full */
1897 		0x0c, 0xff,		/* DAC4 digital full */
1898 		0x0d, 0xff,		/* DAC5 digital full */
1899 		0x0e, 0xff,		/* DAC6 digital full */
1900 		0x0f, 0xff,		/* DAC7 digital full */
1901 		0x10, 0xff,		/* DAC8 digital full */
1902 		0x11, 0x1ff,		/* master digital full */
1903 		0x12, 0x000,		/* phase normal */
1904 		0x13, 0x090,		/* unmute DAC L/R */
1905 		0x14, 0x000,		/* all unmute */
1906 		0x15, 0x000,		/* no deemphasis, no ZFLG */
1907 		0x19, 0x000,		/* -12dB ADC/L */
1908 		0x1a, 0x000,		/* -12dB ADC/R */
1909 		(unsigned short)-1
1910 	};
1911 	static unsigned short wm_inits_prodigy[] = {
1912 
1913 		/* These come first to reduce init pop noise */
1914 		0x1b, 0x000,		/* ADC Mux */
1915 		0x1c, 0x009,		/* Out Mux1 */
1916 		0x1d, 0x009,		/* Out Mux2 */
1917 
1918 		0x18, 0x000,		/* All power-up */
1919 
1920 		0x16, 0x022,		/* I2S, normal polarity, 24bit, high-pass on */
1921 		0x17, 0x006,		/* 128fs, slave mode */
1922 
1923 		0x00, 0,		/* DAC1 analog mute */
1924 		0x01, 0,		/* DAC2 analog mute */
1925 		0x02, 0,		/* DAC3 analog mute */
1926 		0x03, 0,		/* DAC4 analog mute */
1927 		0x04, 0,		/* DAC5 analog mute */
1928 		0x05, 0,		/* DAC6 analog mute */
1929 		0x06, 0,		/* DAC7 analog mute */
1930 		0x07, 0,		/* DAC8 analog mute */
1931 		0x08, 0x100,		/* master analog mute */
1932 
1933 		0x09, 0x7f,		/* DAC1 digital full */
1934 		0x0a, 0x7f,		/* DAC2 digital full */
1935 		0x0b, 0x7f,		/* DAC3 digital full */
1936 		0x0c, 0x7f,		/* DAC4 digital full */
1937 		0x0d, 0x7f,		/* DAC5 digital full */
1938 		0x0e, 0x7f,		/* DAC6 digital full */
1939 		0x0f, 0x7f,		/* DAC7 digital full */
1940 		0x10, 0x7f,		/* DAC8 digital full */
1941 		0x11, 0x1FF,		/* master digital full */
1942 
1943 		0x12, 0x000,		/* phase normal */
1944 		0x13, 0x090,		/* unmute DAC L/R */
1945 		0x14, 0x000,		/* all unmute */
1946 		0x15, 0x000,		/* no deemphasis, no ZFLG */
1947 
1948 		0x19, 0x000,		/* -12dB ADC/L */
1949 		0x1a, 0x000,		/* -12dB ADC/R */
1950 		(unsigned short)-1
1951 
1952 	};
1953 	static unsigned short cs_inits[] = {
1954 		0x0441, /* RUN */
1955 		0x0180, /* no mute, OMCK output on RMCK pin */
1956 		0x0201, /* S/PDIF source on RXP1 */
1957 		0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
1958 		(unsigned short)-1
1959 	};
1960 	unsigned int tmp;
1961 	unsigned short *p;
1962 	int err, i;
1963 
1964 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
1965 		ice->num_total_dacs = 6;
1966 		ice->num_total_adcs = 2;
1967 	} else {
1968 		/* aureon 7.1 and prodigy 7.1 */
1969 		ice->num_total_dacs = 8;
1970 		ice->num_total_adcs = 2;
1971 	}
1972 
1973 	/* to remeber the register values of CS8415 */
1974 	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
1975 	if (! ice->akm)
1976 		return -ENOMEM;
1977 	ice->akm_codecs = 1;
1978 
1979 	if ((err = aureon_ac97_init(ice)) != 0)
1980 		return err;
1981 
1982 	snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
1983 
1984 	/* reset the wm codec as the SPI mode */
1985 	snd_ice1712_save_gpio_status(ice);
1986 	snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
1987 
1988 	tmp = snd_ice1712_gpio_read(ice);
1989 	tmp &= ~AUREON_WM_RESET;
1990 	snd_ice1712_gpio_write(ice, tmp);
1991 	udelay(1);
1992 	tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
1993 	snd_ice1712_gpio_write(ice, tmp);
1994 	udelay(1);
1995 	tmp |= AUREON_WM_RESET;
1996 	snd_ice1712_gpio_write(ice, tmp);
1997 	udelay(1);
1998 
1999 	/* initialize WM8770 codec */
2000 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
2001 		ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT)
2002 		p = wm_inits_prodigy;
2003 	else
2004 		p = wm_inits_aureon;
2005 	for (; *p != (unsigned short)-1; p += 2)
2006 		wm_put(ice, p[0], p[1]);
2007 
2008 	/* initialize CS8415A codec */
2009 	if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) {
2010 		for (p = cs_inits; *p != (unsigned short)-1; p++)
2011 			aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
2012 		ice->spec.aureon.cs8415_mux = 1;
2013 
2014 		aureon_set_headphone_amp(ice, 1);
2015 	}
2016 
2017 	snd_ice1712_restore_gpio_status(ice);
2018 
2019         /* initialize PCA9554 pin directions & set default input*/
2020 	aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2021 	aureon_pca9554_write(ice, PCA9554_OUT, 0x00);   /* internal AUX */
2022 
2023 	ice->spec.aureon.master[0] = WM_VOL_MUTE;
2024 	ice->spec.aureon.master[1] = WM_VOL_MUTE;
2025 	for (i = 0; i < ice->num_total_dacs; i++) {
2026 		ice->spec.aureon.vol[i] = WM_VOL_MUTE;
2027 		wm_set_vol(ice, i, ice->spec.aureon.vol[i], ice->spec.aureon.master[i % 2]);
2028 	}
2029 
2030 	return 0;
2031 }
2032 
2033 
2034 /*
2035  * Aureon boards don't provide the EEPROM data except for the vendor IDs.
2036  * hence the driver needs to sets up it properly.
2037  */
2038 
2039 static unsigned char aureon51_eeprom[] __devinitdata = {
2040 	0x0a,	/* SYSCONF: clock 512, spdif-in/ADC, 3DACs */
2041 	0x80,	/* ACLINK: I2S */
2042 	0xfc,	/* I2S: vol, 96k, 24bit, 192k */
2043 	0xc3,	/* SPDIF: out-en, out-int, spdif-in */
2044 	0xff,	/* GPIO_DIR */
2045 	0xff,	/* GPIO_DIR1 */
2046 	0x5f,	/* GPIO_DIR2 */
2047 	0x00,	/* GPIO_MASK */
2048 	0x00,	/* GPIO_MASK1 */
2049 	0x00,	/* GPIO_MASK2 */
2050 	0x00,	/* GPIO_STATE */
2051 	0x00,	/* GPIO_STATE1 */
2052 	0x00,	/* GPIO_STATE2 */
2053 };
2054 
2055 static unsigned char aureon71_eeprom[] __devinitdata = {
2056 	0x0b,	/* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
2057 	0x80,	/* ACLINK: I2S */
2058 	0xfc,	/* I2S: vol, 96k, 24bit, 192k */
2059 	0xc3,	/* SPDIF: out-en, out-int, spdif-in */
2060 	0xff,	/* GPIO_DIR */
2061 	0xff,	/* GPIO_DIR1 */
2062 	0x5f,	/* GPIO_DIR2 */
2063 	0x00,	/* GPIO_MASK */
2064 	0x00,	/* GPIO_MASK1 */
2065 	0x00,	/* GPIO_MASK2 */
2066 	0x00,	/* GPIO_STATE */
2067 	0x00,	/* GPIO_STATE1 */
2068 	0x00,	/* GPIO_STATE2 */
2069 };
2070 
2071 static unsigned char prodigy71_eeprom[] __devinitdata = {
2072 	0x0b,	/* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
2073 	0x80,	/* ACLINK: I2S */
2074 	0xfc,	/* I2S: vol, 96k, 24bit, 192k */
2075 	0xc3,	/* SPDIF: out-en, out-int, spdif-in */
2076 	0xff,	/* GPIO_DIR */
2077 	0xff,	/* GPIO_DIR1 */
2078 	0x5f,	/* GPIO_DIR2 */
2079 	0x00,	/* GPIO_MASK */
2080 	0x00,	/* GPIO_MASK1 */
2081 	0x00,	/* GPIO_MASK2 */
2082 	0x00,	/* GPIO_STATE */
2083 	0x00,	/* GPIO_STATE1 */
2084 	0x00,	/* GPIO_STATE2 */
2085 };
2086 
2087 static unsigned char prodigy71lt_eeprom[] __devinitdata = {
2088 	0x4b,	/* SYSCINF: clock 512, spdif-in/ADC, 4DACs */
2089 	0x80,	/* ACLINK: I2S */
2090 	0xfc,	/* I2S: vol, 96k, 24bit, 192k */
2091 	0xc3,	/* SPDIF: out-en, out-int, spdif-in */
2092 	0xff,	/* GPIO_DIR */
2093 	0xff,	/* GPIO_DIR1 */
2094 	0x5f,	/* GPIO_DIR2 */
2095 	0x00,	/* GPIO_MASK */
2096 	0x00,	/* GPIO_MASK1 */
2097 	0x00,	/* GPIO_MASK2 */
2098 	0x00,	/* GPIO_STATE */
2099 	0x00,	/* GPIO_STATE1 */
2100 	0x00,	/* GPIO_STATE2 */
2101 };
2102 
2103 
2104 /* entry point */
2105 struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
2106 	{
2107 		.subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
2108 		.name = "Terratec Aureon 5.1-Sky",
2109 		.model = "aureon51",
2110 		.chip_init = aureon_init,
2111 		.build_controls = aureon_add_controls,
2112 		.eeprom_size = sizeof(aureon51_eeprom),
2113 		.eeprom_data = aureon51_eeprom,
2114 		.driver = "Aureon51",
2115 	},
2116 	{
2117 		.subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
2118 		.name = "Terratec Aureon 7.1-Space",
2119 		.model = "aureon71",
2120 		.chip_init = aureon_init,
2121 		.build_controls = aureon_add_controls,
2122 		.eeprom_size = sizeof(aureon71_eeprom),
2123 		.eeprom_data = aureon71_eeprom,
2124 		.driver = "Aureon71",
2125 	},
2126  	{
2127  		.subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
2128  		.name = "Terratec Aureon 7.1-Universe",
2129 		.model = "universe",
2130  		.chip_init = aureon_init,
2131  		.build_controls = aureon_add_controls,
2132  		.eeprom_size = sizeof(aureon71_eeprom),
2133  		.eeprom_data = aureon71_eeprom,
2134 		.driver = "Aureon71Univ", /* keep in 15 letters */
2135 	},
2136 	{
2137 		.subvendor = VT1724_SUBDEVICE_PRODIGY71,
2138 		.name = "Audiotrak Prodigy 7.1",
2139 		.model = "prodigy71",
2140 		.chip_init = aureon_init,
2141 		.build_controls = aureon_add_controls,
2142 		.eeprom_size = sizeof(prodigy71_eeprom),
2143 		.eeprom_data = prodigy71_eeprom,
2144 		.driver = "Prodigy71", /* should be identical with Aureon71 */
2145 	},
2146 	{
2147 		.subvendor = VT1724_SUBDEVICE_PRODIGY71LT,
2148 		.name = "Audiotrak Prodigy 7.1 LT",
2149 		.model = "prodigy71lt",
2150 		.chip_init = aureon_init,
2151 		.build_controls = aureon_add_controls,
2152 		.eeprom_size = sizeof(prodigy71lt_eeprom),
2153 		.eeprom_data = prodigy71lt_eeprom,
2154 		.driver = "Prodigy71LT",
2155 	},
2156 	{ } /* terminator */
2157 };
2158