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