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