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