Merge branch 'topic/ice1724-pm' into for-linus
[pandora-kernel.git] / sound / pci / ice1712 / aureon.c
1 /*
2  *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
3  *
4  *   Lowlevel functions for Terratec Aureon cards
5  *
6  *      Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
7  *
8  *   This program is free software; you can redistribute it and/or modify
9  *   it under the terms of the GNU General Public License as published by
10  *   the Free Software Foundation; either version 2 of the License, or
11  *   (at your option) any later version.
12  *
13  *   This program is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with this program; if not, write to the Free Software
20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  *
22  *
23  * NOTES:
24  *
25  * - we reuse the struct snd_akm4xxx record for storing the wm8770 codec data.
26  *   both wm and akm codecs are pretty similar, so we can integrate
27  *   both controls in the future, once if wm codecs are reused in
28  *   many boards.
29  *
30  * - DAC digital volumes are not implemented in the mixer.
31  *   if they show better response than DAC analog volumes, we can use them
32  *   instead.
33  *
34  *   Lowlevel functions for AudioTrak Prodigy 7.1 (and possibly 192) cards
35  *      Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
36  *
37  *   version 0.82: Stable / not all features work yet (no communication with AC97 secondary)
38  *       added 64x/128x oversampling switch (should be 64x only for 96khz)
39  *       fixed some recording labels (still need to check the rest)
40  *       recording is working probably thanks to correct wm8770 initialization
41  *
42  *   version 0.5: Initial release:
43  *           working: analog output, mixer, headphone amplifier switch
44  *       not working: prety much everything else, at least i could verify that
45  *                    we have no digital output, no capture, pretty bad clicks and poops
46  *                    on mixer switch and other coll stuff.
47  */
48
49 #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, -12700, 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 /*
699  * Logarithmic volume values for WM8770
700  * Computed as 20 * Log10(255 / x)
701  */
702 static const unsigned char wm_vol[256] = {
703         127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
704         23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
705         17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
706         13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
707         11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
708         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,
709         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,
710         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,
711         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,
712         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,
713         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,
714         0, 0
715 };
716
717 #define WM_VOL_MAX      (sizeof(wm_vol) - 1)
718 #define WM_VOL_MUTE     0x8000
719
720 static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
721 {
722         unsigned char nvol;
723
724         if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
725                 nvol = 0;
726         else
727                 nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
728
729         wm_put(ice, index, nvol);
730         wm_put_nocache(ice, index, 0x180 | nvol);
731 }
732
733 /*
734  * DAC mute control
735  */
736 #define wm_pcm_mute_info        snd_ctl_boolean_mono_info
737
738 static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
739 {
740         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
741
742         mutex_lock(&ice->gpio_mutex);
743         ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
744         mutex_unlock(&ice->gpio_mutex);
745         return 0;
746 }
747
748 static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
749 {
750         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
751         unsigned short nval, oval;
752         int change;
753
754         snd_ice1712_save_gpio_status(ice);
755         oval = wm_get(ice, WM_MUTE);
756         nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
757         change = (oval != nval);
758         if (change)
759                 wm_put(ice, WM_MUTE, nval);
760         snd_ice1712_restore_gpio_status(ice);
761
762         return change;
763 }
764
765 /*
766  * Master volume attenuation mixer control
767  */
768 static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
769 {
770         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
771         uinfo->count = 2;
772         uinfo->value.integer.min = 0;
773         uinfo->value.integer.max = WM_VOL_MAX;
774         return 0;
775 }
776
777 static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
778 {
779         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
780         struct aureon_spec *spec = ice->spec;
781         int i;
782         for (i = 0; i < 2; i++)
783                 ucontrol->value.integer.value[i] =
784                         spec->master[i] & ~WM_VOL_MUTE;
785         return 0;
786 }
787
788 static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
789 {
790         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
791         struct aureon_spec *spec = ice->spec;
792         int ch, change = 0;
793
794         snd_ice1712_save_gpio_status(ice);
795         for (ch = 0; ch < 2; ch++) {
796                 unsigned int vol = ucontrol->value.integer.value[ch];
797                 if (vol > WM_VOL_MAX)
798                         continue;
799                 vol |= spec->master[ch] & WM_VOL_MUTE;
800                 if (vol != spec->master[ch]) {
801                         int dac;
802                         spec->master[ch] = vol;
803                         for (dac = 0; dac < ice->num_total_dacs; dac += 2)
804                                 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
805                                            spec->vol[dac + ch],
806                                            spec->master[ch]);
807                         change = 1;
808                 }
809         }
810         snd_ice1712_restore_gpio_status(ice);
811         return change;
812 }
813
814 /*
815  * DAC volume attenuation mixer control
816  */
817 static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
818 {
819         int voices = kcontrol->private_value >> 8;
820         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
821         uinfo->count = voices;
822         uinfo->value.integer.min = 0;           /* mute (-101dB) */
823         uinfo->value.integer.max = 0x7F;        /* 0dB */
824         return 0;
825 }
826
827 static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
828 {
829         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
830         struct aureon_spec *spec = ice->spec;
831         int i, ofs, voices;
832
833         voices = kcontrol->private_value >> 8;
834         ofs = kcontrol->private_value & 0xff;
835         for (i = 0; i < voices; i++)
836                 ucontrol->value.integer.value[i] =
837                         spec->vol[ofs+i] & ~WM_VOL_MUTE;
838         return 0;
839 }
840
841 static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
842 {
843         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
844         struct aureon_spec *spec = ice->spec;
845         int i, idx, ofs, voices;
846         int change = 0;
847
848         voices = kcontrol->private_value >> 8;
849         ofs = kcontrol->private_value & 0xff;
850         snd_ice1712_save_gpio_status(ice);
851         for (i = 0; i < voices; i++) {
852                 unsigned int vol = ucontrol->value.integer.value[i];
853                 if (vol > 0x7f)
854                         continue;
855                 vol |= spec->vol[ofs+i];
856                 if (vol != spec->vol[ofs+i]) {
857                         spec->vol[ofs+i] = vol;
858                         idx  = WM_DAC_ATTEN + ofs + i;
859                         wm_set_vol(ice, idx, spec->vol[ofs + i],
860                                    spec->master[i]);
861                         change = 1;
862                 }
863         }
864         snd_ice1712_restore_gpio_status(ice);
865         return change;
866 }
867
868 /*
869  * WM8770 mute control
870  */
871 static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
872 {
873         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
874         uinfo->count = kcontrol->private_value >> 8;
875         uinfo->value.integer.min = 0;
876         uinfo->value.integer.max = 1;
877         return 0;
878 }
879
880 static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
881 {
882         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
883         struct aureon_spec *spec = ice->spec;
884         int voices, ofs, i;
885
886         voices = kcontrol->private_value >> 8;
887         ofs = kcontrol->private_value & 0xFF;
888
889         for (i = 0; i < voices; i++)
890                 ucontrol->value.integer.value[i] =
891                         (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
892         return 0;
893 }
894
895 static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
896 {
897         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
898         struct aureon_spec *spec = ice->spec;
899         int change = 0, voices, ofs, i;
900
901         voices = kcontrol->private_value >> 8;
902         ofs = kcontrol->private_value & 0xFF;
903
904         snd_ice1712_save_gpio_status(ice);
905         for (i = 0; i < voices; i++) {
906                 int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
907                 if (ucontrol->value.integer.value[i] != val) {
908                         spec->vol[ofs + i] &= ~WM_VOL_MUTE;
909                         spec->vol[ofs + i] |=
910                                 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
911                         wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
912                                    spec->master[i]);
913                         change = 1;
914                 }
915         }
916         snd_ice1712_restore_gpio_status(ice);
917
918         return change;
919 }
920
921 /*
922  * WM8770 master mute control
923  */
924 #define wm_master_mute_info             snd_ctl_boolean_stereo_info
925
926 static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
927 {
928         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
929         struct aureon_spec *spec = ice->spec;
930
931         ucontrol->value.integer.value[0] =
932                 (spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
933         ucontrol->value.integer.value[1] =
934                 (spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
935         return 0;
936 }
937
938 static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
939 {
940         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
941         struct aureon_spec *spec = ice->spec;
942         int change = 0, i;
943
944         snd_ice1712_save_gpio_status(ice);
945         for (i = 0; i < 2; i++) {
946                 int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
947                 if (ucontrol->value.integer.value[i] != val) {
948                         int dac;
949                         spec->master[i] &= ~WM_VOL_MUTE;
950                         spec->master[i] |=
951                                 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
952                         for (dac = 0; dac < ice->num_total_dacs; dac += 2)
953                                 wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
954                                            spec->vol[dac + i],
955                                            spec->master[i]);
956                         change = 1;
957                 }
958         }
959         snd_ice1712_restore_gpio_status(ice);
960
961         return change;
962 }
963
964 /* digital master volume */
965 #define PCM_0dB 0xff
966 #define PCM_RES 128     /* -64dB */
967 #define PCM_MIN (PCM_0dB - PCM_RES)
968 static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
969 {
970         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
971         uinfo->count = 1;
972         uinfo->value.integer.min = 0;           /* mute (-64dB) */
973         uinfo->value.integer.max = PCM_RES;     /* 0dB */
974         return 0;
975 }
976
977 static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
978 {
979         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
980         unsigned short val;
981
982         mutex_lock(&ice->gpio_mutex);
983         val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
984         val = val > PCM_MIN ? (val - PCM_MIN) : 0;
985         ucontrol->value.integer.value[0] = val;
986         mutex_unlock(&ice->gpio_mutex);
987         return 0;
988 }
989
990 static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
991 {
992         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
993         unsigned short ovol, nvol;
994         int change = 0;
995
996         nvol = ucontrol->value.integer.value[0];
997         if (nvol > PCM_RES)
998                 return -EINVAL;
999         snd_ice1712_save_gpio_status(ice);
1000         nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
1001         ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
1002         if (ovol != nvol) {
1003                 wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
1004                 wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
1005                 change = 1;
1006         }
1007         snd_ice1712_restore_gpio_status(ice);
1008         return change;
1009 }
1010
1011 /*
1012  * ADC mute control
1013  */
1014 #define wm_adc_mute_info                snd_ctl_boolean_stereo_info
1015
1016 static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1017 {
1018         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1019         unsigned short val;
1020         int i;
1021
1022         mutex_lock(&ice->gpio_mutex);
1023         for (i = 0; i < 2; i++) {
1024                 val = wm_get(ice, WM_ADC_GAIN + i);
1025                 ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
1026         }
1027         mutex_unlock(&ice->gpio_mutex);
1028         return 0;
1029 }
1030
1031 static int wm_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1032 {
1033         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1034         unsigned short new, old;
1035         int i, change = 0;
1036
1037         snd_ice1712_save_gpio_status(ice);
1038         for (i = 0; i < 2; i++) {
1039                 old = wm_get(ice, WM_ADC_GAIN + i);
1040                 new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
1041                 if (new != old) {
1042                         wm_put(ice, WM_ADC_GAIN + i, new);
1043                         change = 1;
1044                 }
1045         }
1046         snd_ice1712_restore_gpio_status(ice);
1047
1048         return change;
1049 }
1050
1051 /*
1052  * ADC gain mixer control
1053  */
1054 static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1055 {
1056         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1057         uinfo->count = 2;
1058         uinfo->value.integer.min = 0;           /* -12dB */
1059         uinfo->value.integer.max = 0x1f;        /* 19dB */
1060         return 0;
1061 }
1062
1063 static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1064 {
1065         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1066         int i, idx;
1067         unsigned short vol;
1068
1069         mutex_lock(&ice->gpio_mutex);
1070         for (i = 0; i < 2; i++) {
1071                 idx = WM_ADC_GAIN + i;
1072                 vol = wm_get(ice, idx) & 0x1f;
1073                 ucontrol->value.integer.value[i] = vol;
1074         }
1075         mutex_unlock(&ice->gpio_mutex);
1076         return 0;
1077 }
1078
1079 static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1080 {
1081         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1082         int i, idx;
1083         unsigned short ovol, nvol;
1084         int change = 0;
1085
1086         snd_ice1712_save_gpio_status(ice);
1087         for (i = 0; i < 2; i++) {
1088                 idx  = WM_ADC_GAIN + i;
1089                 nvol = ucontrol->value.integer.value[i] & 0x1f;
1090                 ovol = wm_get(ice, idx);
1091                 if ((ovol & 0x1f) != nvol) {
1092                         wm_put(ice, idx, nvol | (ovol & ~0x1f));
1093                         change = 1;
1094                 }
1095         }
1096         snd_ice1712_restore_gpio_status(ice);
1097         return change;
1098 }
1099
1100 /*
1101  * ADC input mux mixer control
1102  */
1103 static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1104 {
1105         static const char * const texts[] = {
1106                 "CD",           /* AIN1 */
1107                 "Aux",          /* AIN2 */
1108                 "Line",         /* AIN3 */
1109                 "Mic",          /* AIN4 */
1110                 "AC97"          /* AIN5 */
1111         };
1112         static const char * const universe_texts[] = {
1113                 "Aux1",         /* AIN1 */
1114                 "CD",           /* AIN2 */
1115                 "Phono",        /* AIN3 */
1116                 "Line",         /* AIN4 */
1117                 "Aux2",         /* AIN5 */
1118                 "Mic",          /* AIN6 */
1119                 "Aux3",         /* AIN7 */
1120                 "AC97"          /* AIN8 */
1121         };
1122         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1123
1124         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1125         uinfo->count = 2;
1126         if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1127                 uinfo->value.enumerated.items = 8;
1128                 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1129                         uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1130                 strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]);
1131         } else {
1132                 uinfo->value.enumerated.items = 5;
1133                 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1134                         uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1135                 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1136         }
1137         return 0;
1138 }
1139
1140 static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1141 {
1142         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1143         unsigned short val;
1144
1145         mutex_lock(&ice->gpio_mutex);
1146         val = wm_get(ice, WM_ADC_MUX);
1147         ucontrol->value.enumerated.item[0] = val & 7;
1148         ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
1149         mutex_unlock(&ice->gpio_mutex);
1150         return 0;
1151 }
1152
1153 static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1154 {
1155         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1156         unsigned short oval, nval;
1157         int change;
1158
1159         snd_ice1712_save_gpio_status(ice);
1160         oval = wm_get(ice, WM_ADC_MUX);
1161         nval = oval & ~0x77;
1162         nval |= ucontrol->value.enumerated.item[0] & 7;
1163         nval |= (ucontrol->value.enumerated.item[1] & 7) << 4;
1164         change = (oval != nval);
1165         if (change)
1166                 wm_put(ice, WM_ADC_MUX, nval);
1167         snd_ice1712_restore_gpio_status(ice);
1168         return change;
1169 }
1170
1171 /*
1172  * CS8415 Input mux
1173  */
1174 static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1175 {
1176         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1177         static const char * const aureon_texts[] = {
1178                 "CD",           /* RXP0 */
1179                 "Optical"       /* RXP1 */
1180         };
1181         static const char * const prodigy_texts[] = {
1182                 "CD",
1183                 "Coax"
1184         };
1185         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1186         uinfo->count = 1;
1187         uinfo->value.enumerated.items = 2;
1188         if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1189                 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1190         if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
1191                 strcpy(uinfo->value.enumerated.name, prodigy_texts[uinfo->value.enumerated.item]);
1192         else
1193                 strcpy(uinfo->value.enumerated.name, aureon_texts[uinfo->value.enumerated.item]);
1194         return 0;
1195 }
1196
1197 static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1198 {
1199         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1200         struct aureon_spec *spec = ice->spec;
1201
1202         /* snd_ice1712_save_gpio_status(ice); */
1203         /* val = aureon_cs8415_get(ice, CS8415_CTRL2); */
1204         ucontrol->value.enumerated.item[0] = spec->cs8415_mux;
1205         /* snd_ice1712_restore_gpio_status(ice); */
1206         return 0;
1207 }
1208
1209 static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1210 {
1211         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1212         struct aureon_spec *spec = ice->spec;
1213         unsigned short oval, nval;
1214         int change;
1215
1216         snd_ice1712_save_gpio_status(ice);
1217         oval = aureon_cs8415_get(ice, CS8415_CTRL2);
1218         nval = oval & ~0x07;
1219         nval |= ucontrol->value.enumerated.item[0] & 7;
1220         change = (oval != nval);
1221         if (change)
1222                 aureon_cs8415_put(ice, CS8415_CTRL2, nval);
1223         snd_ice1712_restore_gpio_status(ice);
1224         spec->cs8415_mux = ucontrol->value.enumerated.item[0];
1225         return change;
1226 }
1227
1228 static int aureon_cs8415_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1229 {
1230         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1231         uinfo->count = 1;
1232         uinfo->value.integer.min = 0;
1233         uinfo->value.integer.max = 192000;
1234         return 0;
1235 }
1236
1237 static int aureon_cs8415_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1238 {
1239         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1240         unsigned char ratio;
1241         ratio = aureon_cs8415_get(ice, CS8415_RATIO);
1242         ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750);
1243         return 0;
1244 }
1245
1246 /*
1247  * CS8415A Mute
1248  */
1249 #define aureon_cs8415_mute_info         snd_ctl_boolean_mono_info
1250
1251 static int aureon_cs8415_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1252 {
1253         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1254         snd_ice1712_save_gpio_status(ice);
1255         ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1;
1256         snd_ice1712_restore_gpio_status(ice);
1257         return 0;
1258 }
1259
1260 static int aureon_cs8415_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1261 {
1262         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1263         unsigned char oval, nval;
1264         int change;
1265         snd_ice1712_save_gpio_status(ice);
1266         oval = aureon_cs8415_get(ice, CS8415_CTRL1);
1267         if (ucontrol->value.integer.value[0])
1268                 nval = oval & ~0x20;
1269         else
1270                 nval = oval | 0x20;
1271         change = (oval != nval);
1272         if (change)
1273                 aureon_cs8415_put(ice, CS8415_CTRL1, nval);
1274         snd_ice1712_restore_gpio_status(ice);
1275         return change;
1276 }
1277
1278 /*
1279  * CS8415A Q-Sub info
1280  */
1281 static int aureon_cs8415_qsub_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1282 {
1283         uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1284         uinfo->count = 10;
1285         return 0;
1286 }
1287
1288 static int aureon_cs8415_qsub_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1289 {
1290         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1291
1292         snd_ice1712_save_gpio_status(ice);
1293         aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
1294         snd_ice1712_restore_gpio_status(ice);
1295
1296         return 0;
1297 }
1298
1299 static int aureon_cs8415_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1300 {
1301         uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1302         uinfo->count = 1;
1303         return 0;
1304 }
1305
1306 static int aureon_cs8415_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1307 {
1308         memset(ucontrol->value.iec958.status, 0xFF, 24);
1309         return 0;
1310 }
1311
1312 static int aureon_cs8415_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1313 {
1314         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1315
1316         snd_ice1712_save_gpio_status(ice);
1317         aureon_cs8415_read(ice, CS8415_C_BUFFER, ucontrol->value.iec958.status, 24);
1318         snd_ice1712_restore_gpio_status(ice);
1319         return 0;
1320 }
1321
1322 /*
1323  * Headphone Amplifier
1324  */
1325 static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
1326 {
1327         unsigned int tmp, tmp2;
1328
1329         tmp2 = tmp = snd_ice1712_gpio_read(ice);
1330         if (enable)
1331                 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1332                     ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1333                         tmp |= AUREON_HP_SEL;
1334                 else
1335                         tmp |= PRODIGY_HP_SEL;
1336         else
1337                 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1338                     ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1339                         tmp &= ~AUREON_HP_SEL;
1340                 else
1341                         tmp &= ~PRODIGY_HP_SEL;
1342         if (tmp != tmp2) {
1343                 snd_ice1712_gpio_write(ice, tmp);
1344                 return 1;
1345         }
1346         return 0;
1347 }
1348
1349 static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
1350 {
1351         unsigned int tmp = snd_ice1712_gpio_read(ice);
1352
1353         return (tmp & AUREON_HP_SEL) != 0;
1354 }
1355
1356 #define aureon_hpamp_info       snd_ctl_boolean_mono_info
1357
1358 static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1359 {
1360         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1361
1362         ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
1363         return 0;
1364 }
1365
1366
1367 static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1368 {
1369         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1370
1371         return aureon_set_headphone_amp(ice, ucontrol->value.integer.value[0]);
1372 }
1373
1374 /*
1375  * Deemphasis
1376  */
1377
1378 #define aureon_deemp_info       snd_ctl_boolean_mono_info
1379
1380 static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1381 {
1382         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1383         ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
1384         return 0;
1385 }
1386
1387 static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1388 {
1389         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1390         int temp, temp2;
1391         temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
1392         if (ucontrol->value.integer.value[0])
1393                 temp |= 0xf;
1394         else
1395                 temp &= ~0xf;
1396         if (temp != temp2) {
1397                 wm_put(ice, WM_DAC_CTRL2, temp);
1398                 return 1;
1399         }
1400         return 0;
1401 }
1402
1403 /*
1404  * ADC Oversampling
1405  */
1406 static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
1407 {
1408         static const char * const texts[2] = { "128x", "64x"    };
1409
1410         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1411         uinfo->count = 1;
1412         uinfo->value.enumerated.items = 2;
1413
1414         if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1415                 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1416         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1417
1418         return 0;
1419 }
1420
1421 static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1422 {
1423         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1424         ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
1425         return 0;
1426 }
1427
1428 static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1429 {
1430         int temp, temp2;
1431         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1432
1433         temp2 = temp = wm_get(ice, WM_MASTER);
1434
1435         if (ucontrol->value.enumerated.item[0])
1436                 temp |= 0x8;
1437         else
1438                 temp &= ~0x8;
1439
1440         if (temp != temp2) {
1441                 wm_put(ice, WM_MASTER, temp);
1442                 return 1;
1443         }
1444         return 0;
1445 }
1446
1447 /*
1448  * mixers
1449  */
1450
1451 static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
1452         {
1453                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1454                 .name = "Master Playback Switch",
1455                 .info = wm_master_mute_info,
1456                 .get = wm_master_mute_get,
1457                 .put = wm_master_mute_put
1458         },
1459         {
1460                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1461                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1462                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1463                 .name = "Master Playback Volume",
1464                 .info = wm_master_vol_info,
1465                 .get = wm_master_vol_get,
1466                 .put = wm_master_vol_put,
1467                 .tlv = { .p = db_scale_wm_dac }
1468         },
1469         {
1470                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1471                 .name = "Front Playback Switch",
1472                 .info = wm_mute_info,
1473                 .get = wm_mute_get,
1474                 .put = wm_mute_put,
1475                 .private_value = (2 << 8) | 0
1476         },
1477         {
1478                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1479                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1480                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1481                 .name = "Front Playback Volume",
1482                 .info = wm_vol_info,
1483                 .get = wm_vol_get,
1484                 .put = wm_vol_put,
1485                 .private_value = (2 << 8) | 0,
1486                 .tlv = { .p = db_scale_wm_dac }
1487         },
1488         {
1489                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1490                 .name = "Rear Playback Switch",
1491                 .info = wm_mute_info,
1492                 .get = wm_mute_get,
1493                 .put = wm_mute_put,
1494                 .private_value = (2 << 8) | 2
1495         },
1496         {
1497                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1498                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1499                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1500                 .name = "Rear Playback Volume",
1501                 .info = wm_vol_info,
1502                 .get = wm_vol_get,
1503                 .put = wm_vol_put,
1504                 .private_value = (2 << 8) | 2,
1505                 .tlv = { .p = db_scale_wm_dac }
1506         },
1507         {
1508                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1509                 .name = "Center Playback Switch",
1510                 .info = wm_mute_info,
1511                 .get = wm_mute_get,
1512                 .put = wm_mute_put,
1513                 .private_value = (1 << 8) | 4
1514         },
1515         {
1516                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1517                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1518                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1519                 .name = "Center Playback Volume",
1520                 .info = wm_vol_info,
1521                 .get = wm_vol_get,
1522                 .put = wm_vol_put,
1523                 .private_value = (1 << 8) | 4,
1524                 .tlv = { .p = db_scale_wm_dac }
1525         },
1526         {
1527                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1528                 .name = "LFE Playback Switch",
1529                 .info = wm_mute_info,
1530                 .get = wm_mute_get,
1531                 .put = wm_mute_put,
1532                 .private_value = (1 << 8) | 5
1533         },
1534         {
1535                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1536                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1537                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1538                 .name = "LFE Playback Volume",
1539                 .info = wm_vol_info,
1540                 .get = wm_vol_get,
1541                 .put = wm_vol_put,
1542                 .private_value = (1 << 8) | 5,
1543                 .tlv = { .p = db_scale_wm_dac }
1544         },
1545         {
1546                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1547                 .name = "Side Playback Switch",
1548                 .info = wm_mute_info,
1549                 .get = wm_mute_get,
1550                 .put = wm_mute_put,
1551                 .private_value = (2 << 8) | 6
1552         },
1553         {
1554                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1555                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1556                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1557                 .name = "Side Playback Volume",
1558                 .info = wm_vol_info,
1559                 .get = wm_vol_get,
1560                 .put = wm_vol_put,
1561                 .private_value = (2 << 8) | 6,
1562                 .tlv = { .p = db_scale_wm_dac }
1563         }
1564 };
1565
1566 static struct snd_kcontrol_new wm_controls[] __devinitdata = {
1567         {
1568                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1569                 .name = "PCM Playback Switch",
1570                 .info = wm_pcm_mute_info,
1571                 .get = wm_pcm_mute_get,
1572                 .put = wm_pcm_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 = "PCM Playback Volume",
1579                 .info = wm_pcm_vol_info,
1580                 .get = wm_pcm_vol_get,
1581                 .put = wm_pcm_vol_put,
1582                 .tlv = { .p = db_scale_wm_pcm }
1583         },
1584         {
1585                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1586                 .name = "Capture Switch",
1587                 .info = wm_adc_mute_info,
1588                 .get = wm_adc_mute_get,
1589                 .put = wm_adc_mute_put,
1590         },
1591         {
1592                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1593                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1594                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1595                 .name = "Capture Volume",
1596                 .info = wm_adc_vol_info,
1597                 .get = wm_adc_vol_get,
1598                 .put = wm_adc_vol_put,
1599                 .tlv = { .p = db_scale_wm_adc }
1600         },
1601         {
1602                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1603                 .name = "Capture Source",
1604                 .info = wm_adc_mux_info,
1605                 .get = wm_adc_mux_get,
1606                 .put = wm_adc_mux_put,
1607                 .private_value = 5
1608         },
1609         {
1610                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1611                 .name = "External Amplifier",
1612                 .info = aureon_hpamp_info,
1613                 .get = aureon_hpamp_get,
1614                 .put = aureon_hpamp_put
1615         },
1616         {
1617                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1618                 .name = "DAC Deemphasis Switch",
1619                 .info = aureon_deemp_info,
1620                 .get = aureon_deemp_get,
1621                 .put = aureon_deemp_put
1622         },
1623         {
1624                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1625                 .name = "ADC Oversampling",
1626                 .info = aureon_oversampling_info,
1627                 .get = aureon_oversampling_get,
1628                 .put = aureon_oversampling_put
1629         }
1630 };
1631
1632 static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
1633         {
1634                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1635                 .name = "AC97 Playback Switch",
1636                 .info = aureon_ac97_mmute_info,
1637                 .get = aureon_ac97_mmute_get,
1638                 .put = aureon_ac97_mmute_put,
1639                 .private_value = AC97_MASTER
1640         },
1641         {
1642                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1643                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1644                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1645                 .name = "AC97 Playback Volume",
1646                 .info = aureon_ac97_vol_info,
1647                 .get = aureon_ac97_vol_get,
1648                 .put = aureon_ac97_vol_put,
1649                 .private_value = AC97_MASTER|AUREON_AC97_STEREO,
1650                 .tlv = { .p = db_scale_ac97_master }
1651         },
1652         {
1653                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1654                 .name = "CD Playback Switch",
1655                 .info = aureon_ac97_mute_info,
1656                 .get = aureon_ac97_mute_get,
1657                 .put = aureon_ac97_mute_put,
1658                 .private_value = AC97_CD
1659         },
1660         {
1661                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1662                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1663                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1664                 .name = "CD Playback Volume",
1665                 .info = aureon_ac97_vol_info,
1666                 .get = aureon_ac97_vol_get,
1667                 .put = aureon_ac97_vol_put,
1668                 .private_value = AC97_CD|AUREON_AC97_STEREO,
1669                 .tlv = { .p = db_scale_ac97_gain }
1670         },
1671         {
1672                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1673                 .name = "Aux Playback Switch",
1674                 .info = aureon_ac97_mute_info,
1675                 .get = aureon_ac97_mute_get,
1676                 .put = aureon_ac97_mute_put,
1677                 .private_value = AC97_AUX,
1678         },
1679         {
1680                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1681                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1682                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1683                 .name = "Aux Playback Volume",
1684                 .info = aureon_ac97_vol_info,
1685                 .get = aureon_ac97_vol_get,
1686                 .put = aureon_ac97_vol_put,
1687                 .private_value = AC97_AUX|AUREON_AC97_STEREO,
1688                 .tlv = { .p = db_scale_ac97_gain }
1689         },
1690         {
1691                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1692                 .name = "Line Playback Switch",
1693                 .info = aureon_ac97_mute_info,
1694                 .get = aureon_ac97_mute_get,
1695                 .put = aureon_ac97_mute_put,
1696                 .private_value = AC97_LINE
1697         },
1698         {
1699                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1700                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1701                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1702                 .name = "Line Playback Volume",
1703                 .info = aureon_ac97_vol_info,
1704                 .get = aureon_ac97_vol_get,
1705                 .put = aureon_ac97_vol_put,
1706                 .private_value = AC97_LINE|AUREON_AC97_STEREO,
1707                 .tlv = { .p = db_scale_ac97_gain }
1708         },
1709         {
1710                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1711                 .name = "Mic Playback Switch",
1712                 .info = aureon_ac97_mute_info,
1713                 .get = aureon_ac97_mute_get,
1714                 .put = aureon_ac97_mute_put,
1715                 .private_value = AC97_MIC
1716         },
1717         {
1718                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1719                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1720                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1721                 .name = "Mic Playback Volume",
1722                 .info = aureon_ac97_vol_info,
1723                 .get = aureon_ac97_vol_get,
1724                 .put = aureon_ac97_vol_put,
1725                 .private_value = AC97_MIC,
1726                 .tlv = { .p = db_scale_ac97_gain }
1727         },
1728         {
1729                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1730                 .name = "Mic Boost (+20dB)",
1731                 .info = aureon_ac97_micboost_info,
1732                 .get = aureon_ac97_micboost_get,
1733                 .put = aureon_ac97_micboost_put
1734         }
1735 };
1736
1737 static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
1738         {
1739                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1740                 .name = "AC97 Playback Switch",
1741                 .info = aureon_ac97_mmute_info,
1742                 .get = aureon_ac97_mmute_get,
1743                 .put = aureon_ac97_mmute_put,
1744                 .private_value = AC97_MASTER
1745         },
1746         {
1747                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1748                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1749                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1750                 .name = "AC97 Playback Volume",
1751                 .info = aureon_ac97_vol_info,
1752                 .get = aureon_ac97_vol_get,
1753                 .put = aureon_ac97_vol_put,
1754                 .private_value = AC97_MASTER|AUREON_AC97_STEREO,
1755                 .tlv = { .p = db_scale_ac97_master }
1756         },
1757         {
1758                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1759                 .name = "CD Playback Switch",
1760                 .info = aureon_ac97_mute_info,
1761                 .get = aureon_ac97_mute_get,
1762                 .put = aureon_ac97_mute_put,
1763                 .private_value = AC97_AUX
1764         },
1765         {
1766                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1767                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1768                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1769                 .name = "CD Playback Volume",
1770                 .info = aureon_ac97_vol_info,
1771                 .get = aureon_ac97_vol_get,
1772                 .put = aureon_ac97_vol_put,
1773                 .private_value = AC97_AUX|AUREON_AC97_STEREO,
1774                 .tlv = { .p = db_scale_ac97_gain }
1775         },
1776         {
1777                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1778                 .name = "Phono Playback Switch",
1779                 .info = aureon_ac97_mute_info,
1780                 .get = aureon_ac97_mute_get,
1781                 .put = aureon_ac97_mute_put,
1782                 .private_value = AC97_CD
1783         },
1784         {
1785                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1786                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1787                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1788                 .name = "Phono Playback Volume",
1789                 .info = aureon_ac97_vol_info,
1790                 .get = aureon_ac97_vol_get,
1791                 .put = aureon_ac97_vol_put,
1792                 .private_value = AC97_CD|AUREON_AC97_STEREO,
1793                 .tlv = { .p = db_scale_ac97_gain }
1794         },
1795         {
1796                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1797                 .name = "Line Playback Switch",
1798                 .info = aureon_ac97_mute_info,
1799                 .get = aureon_ac97_mute_get,
1800                 .put = aureon_ac97_mute_put,
1801                 .private_value = AC97_LINE
1802         },
1803         {
1804                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1805                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1806                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1807                 .name = "Line Playback Volume",
1808                 .info = aureon_ac97_vol_info,
1809                 .get = aureon_ac97_vol_get,
1810                 .put = aureon_ac97_vol_put,
1811                 .private_value = AC97_LINE|AUREON_AC97_STEREO,
1812                 .tlv = { .p = db_scale_ac97_gain }
1813         },
1814         {
1815                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1816                 .name = "Mic Playback Switch",
1817                 .info = aureon_ac97_mute_info,
1818                 .get = aureon_ac97_mute_get,
1819                 .put = aureon_ac97_mute_put,
1820                 .private_value = AC97_MIC
1821         },
1822         {
1823                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1824                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1825                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1826                 .name = "Mic Playback Volume",
1827                 .info = aureon_ac97_vol_info,
1828                 .get = aureon_ac97_vol_get,
1829                 .put = aureon_ac97_vol_put,
1830                 .private_value = AC97_MIC,
1831                 .tlv = { .p = db_scale_ac97_gain }
1832         },
1833         {
1834                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1835                 .name = "Mic Boost (+20dB)",
1836                 .info = aureon_ac97_micboost_info,
1837                 .get = aureon_ac97_micboost_get,
1838                 .put = aureon_ac97_micboost_put
1839         },
1840         {
1841                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1842                 .name = "Aux Playback Switch",
1843                 .info = aureon_ac97_mute_info,
1844                 .get = aureon_ac97_mute_get,
1845                 .put = aureon_ac97_mute_put,
1846                 .private_value = AC97_VIDEO,
1847         },
1848         {
1849                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1850                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1851                                 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1852                 .name = "Aux Playback Volume",
1853                 .info = aureon_ac97_vol_info,
1854                 .get = aureon_ac97_vol_get,
1855                 .put = aureon_ac97_vol_put,
1856                 .private_value = AC97_VIDEO|AUREON_AC97_STEREO,
1857                 .tlv = { .p = db_scale_ac97_gain }
1858         },
1859         {
1860                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1861                 .name = "Aux Source",
1862                 .info = aureon_universe_inmux_info,
1863                 .get = aureon_universe_inmux_get,
1864                 .put = aureon_universe_inmux_put
1865         }
1866
1867 };
1868
1869 static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
1870         {
1871                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1872                 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
1873                 .info = aureon_cs8415_mute_info,
1874                 .get = aureon_cs8415_mute_get,
1875                 .put = aureon_cs8415_mute_put
1876         },
1877         {
1878                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1879                 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Source",
1880                 .info = aureon_cs8415_mux_info,
1881                 .get = aureon_cs8415_mux_get,
1882                 .put = aureon_cs8415_mux_put,
1883         },
1884         {
1885                 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1886                 .name = SNDRV_CTL_NAME_IEC958("Q-subcode ", CAPTURE, DEFAULT),
1887                 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1888                 .info = aureon_cs8415_qsub_info,
1889                 .get = aureon_cs8415_qsub_get,
1890         },
1891         {
1892                 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1893                 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
1894                 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1895                 .info = aureon_cs8415_spdif_info,
1896                 .get = aureon_cs8415_mask_get
1897         },
1898         {
1899                 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1900                 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
1901                 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1902                 .info = aureon_cs8415_spdif_info,
1903                 .get = aureon_cs8415_spdif_get
1904         },
1905         {
1906                 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1907                 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Rate",
1908                 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1909                 .info = aureon_cs8415_rate_info,
1910                 .get = aureon_cs8415_rate_get
1911         }
1912 };
1913
1914 static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1915 {
1916         unsigned int i, counts;
1917         int err;
1918
1919         counts = ARRAY_SIZE(aureon_dac_controls);
1920         if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
1921                 counts -= 2; /* no side */
1922         for (i = 0; i < counts; i++) {
1923                 err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
1924                 if (err < 0)
1925                         return err;
1926         }
1927
1928         for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
1929                 err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
1930                 if (err < 0)
1931                         return err;
1932         }
1933
1934         if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1935                 for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
1936                         err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
1937                         if (err < 0)
1938                                 return err;
1939                 }
1940         } else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1941                  ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1942                 for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
1943                         err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
1944                         if (err < 0)
1945                                 return err;
1946                 }
1947         }
1948
1949         if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1950             ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1951                 unsigned char id;
1952                 snd_ice1712_save_gpio_status(ice);
1953                 id = aureon_cs8415_get(ice, CS8415_ID);
1954                 if (id != 0x41)
1955                         snd_printk(KERN_INFO "No CS8415 chip. Skipping CS8415 controls.\n");
1956                 else if ((id & 0x0F) != 0x01)
1957                         snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
1958                 else {
1959                         for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
1960                                 struct snd_kcontrol *kctl;
1961                                 err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
1962                                 if (err < 0)
1963                                         return err;
1964                                 if (i > 1)
1965                                         kctl->id.device = ice->pcm->device;
1966                         }
1967                 }
1968                 snd_ice1712_restore_gpio_status(ice);
1969         }
1970
1971         return 0;
1972 }
1973
1974
1975 /*
1976  * initialize the chip
1977  */
1978 static int __devinit aureon_init(struct snd_ice1712 *ice)
1979 {
1980         static const unsigned short wm_inits_aureon[] = {
1981                 /* These come first to reduce init pop noise */
1982                 0x1b, 0x044,            /* ADC Mux (AC'97 source) */
1983                 0x1c, 0x00B,            /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
1984                 0x1d, 0x009,            /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
1985
1986                 0x18, 0x000,            /* All power-up */
1987
1988                 0x16, 0x122,            /* I2S, normal polarity, 24bit */
1989                 0x17, 0x022,            /* 256fs, slave mode */
1990                 0x00, 0,                /* DAC1 analog mute */
1991                 0x01, 0,                /* DAC2 analog mute */
1992                 0x02, 0,                /* DAC3 analog mute */
1993                 0x03, 0,                /* DAC4 analog mute */
1994                 0x04, 0,                /* DAC5 analog mute */
1995                 0x05, 0,                /* DAC6 analog mute */
1996                 0x06, 0,                /* DAC7 analog mute */
1997                 0x07, 0,                /* DAC8 analog mute */
1998                 0x08, 0x100,            /* master analog mute */
1999                 0x09, 0xff,             /* DAC1 digital full */
2000                 0x0a, 0xff,             /* DAC2 digital full */
2001                 0x0b, 0xff,             /* DAC3 digital full */
2002                 0x0c, 0xff,             /* DAC4 digital full */
2003                 0x0d, 0xff,             /* DAC5 digital full */
2004                 0x0e, 0xff,             /* DAC6 digital full */
2005                 0x0f, 0xff,             /* DAC7 digital full */
2006                 0x10, 0xff,             /* DAC8 digital full */
2007                 0x11, 0x1ff,            /* master digital full */
2008                 0x12, 0x000,            /* phase normal */
2009                 0x13, 0x090,            /* unmute DAC L/R */
2010                 0x14, 0x000,            /* all unmute */
2011                 0x15, 0x000,            /* no deemphasis, no ZFLG */
2012                 0x19, 0x000,            /* -12dB ADC/L */
2013                 0x1a, 0x000,            /* -12dB ADC/R */
2014                 (unsigned short)-1
2015         };
2016         static const unsigned short wm_inits_prodigy[] = {
2017
2018                 /* These come first to reduce init pop noise */
2019                 0x1b, 0x000,            /* ADC Mux */
2020                 0x1c, 0x009,            /* Out Mux1 */
2021                 0x1d, 0x009,            /* Out Mux2 */
2022
2023                 0x18, 0x000,            /* All power-up */
2024
2025                 0x16, 0x022,            /* I2S, normal polarity, 24bit, high-pass on */
2026                 0x17, 0x006,            /* 128fs, slave mode */
2027
2028                 0x00, 0,                /* DAC1 analog mute */
2029                 0x01, 0,                /* DAC2 analog mute */
2030                 0x02, 0,                /* DAC3 analog mute */
2031                 0x03, 0,                /* DAC4 analog mute */
2032                 0x04, 0,                /* DAC5 analog mute */
2033                 0x05, 0,                /* DAC6 analog mute */
2034                 0x06, 0,                /* DAC7 analog mute */
2035                 0x07, 0,                /* DAC8 analog mute */
2036                 0x08, 0x100,            /* master analog mute */
2037
2038                 0x09, 0x7f,             /* DAC1 digital full */
2039                 0x0a, 0x7f,             /* DAC2 digital full */
2040                 0x0b, 0x7f,             /* DAC3 digital full */
2041                 0x0c, 0x7f,             /* DAC4 digital full */
2042                 0x0d, 0x7f,             /* DAC5 digital full */
2043                 0x0e, 0x7f,             /* DAC6 digital full */
2044                 0x0f, 0x7f,             /* DAC7 digital full */
2045                 0x10, 0x7f,             /* DAC8 digital full */
2046                 0x11, 0x1FF,            /* master digital full */
2047
2048                 0x12, 0x000,            /* phase normal */
2049                 0x13, 0x090,            /* unmute DAC L/R */
2050                 0x14, 0x000,            /* all unmute */
2051                 0x15, 0x000,            /* no deemphasis, no ZFLG */
2052
2053                 0x19, 0x000,            /* -12dB ADC/L */
2054                 0x1a, 0x000,            /* -12dB ADC/R */
2055                 (unsigned short)-1
2056
2057         };
2058         static const unsigned short cs_inits[] = {
2059                 0x0441, /* RUN */
2060                 0x0180, /* no mute, OMCK output on RMCK pin */
2061                 0x0201, /* S/PDIF source on RXP1 */
2062                 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
2063                 (unsigned short)-1
2064         };
2065         struct aureon_spec *spec;
2066         unsigned int tmp;
2067         const unsigned short *p;
2068         int err, i;
2069
2070         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2071         if (!spec)
2072                 return -ENOMEM;
2073         ice->spec = spec;
2074
2075         if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
2076                 ice->num_total_dacs = 6;
2077                 ice->num_total_adcs = 2;
2078         } else {
2079                 /* aureon 7.1 and prodigy 7.1 */
2080                 ice->num_total_dacs = 8;
2081                 ice->num_total_adcs = 2;
2082         }
2083
2084         /* to remeber the register values of CS8415 */
2085         ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2086         if (!ice->akm)
2087                 return -ENOMEM;
2088         ice->akm_codecs = 1;
2089
2090         err = aureon_ac97_init(ice);
2091         if (err != 0)
2092                 return err;
2093
2094         snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
2095
2096         /* reset the wm codec as the SPI mode */
2097         snd_ice1712_save_gpio_status(ice);
2098         snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
2099
2100         tmp = snd_ice1712_gpio_read(ice);
2101         tmp &= ~AUREON_WM_RESET;
2102         snd_ice1712_gpio_write(ice, tmp);
2103         udelay(1);
2104         tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
2105         snd_ice1712_gpio_write(ice, tmp);
2106         udelay(1);
2107         tmp |= AUREON_WM_RESET;
2108         snd_ice1712_gpio_write(ice, tmp);
2109         udelay(1);
2110
2111         /* initialize WM8770 codec */
2112         if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
2113                 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
2114                 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT)
2115                 p = wm_inits_prodigy;
2116         else
2117                 p = wm_inits_aureon;
2118         for (; *p != (unsigned short)-1; p += 2)
2119                 wm_put(ice, p[0], p[1]);
2120
2121         /* initialize CS8415A codec */
2122         if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
2123             ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
2124                 for (p = cs_inits; *p != (unsigned short)-1; p++)
2125                         aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
2126                 spec->cs8415_mux = 1;
2127
2128                 aureon_set_headphone_amp(ice, 1);
2129         }
2130
2131         snd_ice1712_restore_gpio_status(ice);
2132
2133         /* initialize PCA9554 pin directions & set default input */
2134         aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2135         aureon_pca9554_write(ice, PCA9554_OUT, 0x00);   /* internal AUX */
2136
2137         spec->master[0] = WM_VOL_MUTE;
2138         spec->master[1] = WM_VOL_MUTE;
2139         for (i = 0; i < ice->num_total_dacs; i++) {
2140                 spec->vol[i] = WM_VOL_MUTE;
2141                 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2142         }
2143
2144         return 0;
2145 }
2146
2147
2148 /*
2149  * Aureon boards don't provide the EEPROM data except for the vendor IDs.
2150  * hence the driver needs to sets up it properly.
2151  */
2152
2153 static unsigned char aureon51_eeprom[] __devinitdata = {
2154         [ICE_EEP2_SYSCONF]     = 0x0a,  /* clock 512, spdif-in/ADC, 3DACs */
2155         [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
2156         [ICE_EEP2_I2S]         = 0xfc,  /* vol, 96k, 24bit, 192k */
2157         [ICE_EEP2_SPDIF]       = 0xc3,  /* out-en, out-int, spdif-in */
2158         [ICE_EEP2_GPIO_DIR]    = 0xff,
2159         [ICE_EEP2_GPIO_DIR1]   = 0xff,
2160         [ICE_EEP2_GPIO_DIR2]   = 0x5f,
2161         [ICE_EEP2_GPIO_MASK]   = 0x00,
2162         [ICE_EEP2_GPIO_MASK1]  = 0x00,
2163         [ICE_EEP2_GPIO_MASK2]  = 0x00,
2164         [ICE_EEP2_GPIO_STATE]  = 0x00,
2165         [ICE_EEP2_GPIO_STATE1] = 0x00,
2166         [ICE_EEP2_GPIO_STATE2] = 0x00,
2167 };
2168
2169 static unsigned char aureon71_eeprom[] __devinitdata = {
2170         [ICE_EEP2_SYSCONF]     = 0x0b,  /* clock 512, spdif-in/ADC, 4DACs */
2171         [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
2172         [ICE_EEP2_I2S]         = 0xfc,  /* vol, 96k, 24bit, 192k */
2173         [ICE_EEP2_SPDIF]       = 0xc3,  /* out-en, out-int, spdif-in */
2174         [ICE_EEP2_GPIO_DIR]    = 0xff,
2175         [ICE_EEP2_GPIO_DIR1]   = 0xff,
2176         [ICE_EEP2_GPIO_DIR2]   = 0x5f,
2177         [ICE_EEP2_GPIO_MASK]   = 0x00,
2178         [ICE_EEP2_GPIO_MASK1]  = 0x00,
2179         [ICE_EEP2_GPIO_MASK2]  = 0x00,
2180         [ICE_EEP2_GPIO_STATE]  = 0x00,
2181         [ICE_EEP2_GPIO_STATE1] = 0x00,
2182         [ICE_EEP2_GPIO_STATE2] = 0x00,
2183 };
2184 #define prodigy71_eeprom aureon71_eeprom
2185
2186 static unsigned char aureon71_universe_eeprom[] __devinitdata = {
2187         [ICE_EEP2_SYSCONF]     = 0x2b,  /* clock 512, mpu401, spdif-in/ADC,
2188                                          * 4DACs
2189                                          */
2190         [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
2191         [ICE_EEP2_I2S]         = 0xfc,  /* vol, 96k, 24bit, 192k */
2192         [ICE_EEP2_SPDIF]       = 0xc3,  /* out-en, out-int, spdif-in */
2193         [ICE_EEP2_GPIO_DIR]    = 0xff,
2194         [ICE_EEP2_GPIO_DIR1]   = 0xff,
2195         [ICE_EEP2_GPIO_DIR2]   = 0x5f,
2196         [ICE_EEP2_GPIO_MASK]   = 0x00,
2197         [ICE_EEP2_GPIO_MASK1]  = 0x00,
2198         [ICE_EEP2_GPIO_MASK2]  = 0x00,
2199         [ICE_EEP2_GPIO_STATE]  = 0x00,
2200         [ICE_EEP2_GPIO_STATE1] = 0x00,
2201         [ICE_EEP2_GPIO_STATE2] = 0x00,
2202 };
2203
2204 static unsigned char prodigy71lt_eeprom[] __devinitdata = {
2205         [ICE_EEP2_SYSCONF]     = 0x4b,  /* clock 384, spdif-in/ADC, 4DACs */
2206         [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
2207         [ICE_EEP2_I2S]         = 0xfc,  /* vol, 96k, 24bit, 192k */
2208         [ICE_EEP2_SPDIF]       = 0xc3,  /* out-en, out-int, spdif-in */
2209         [ICE_EEP2_GPIO_DIR]    = 0xff,
2210         [ICE_EEP2_GPIO_DIR1]   = 0xff,
2211         [ICE_EEP2_GPIO_DIR2]   = 0x5f,
2212         [ICE_EEP2_GPIO_MASK]   = 0x00,
2213         [ICE_EEP2_GPIO_MASK1]  = 0x00,
2214         [ICE_EEP2_GPIO_MASK2]  = 0x00,
2215         [ICE_EEP2_GPIO_STATE]  = 0x00,
2216         [ICE_EEP2_GPIO_STATE1] = 0x00,
2217         [ICE_EEP2_GPIO_STATE2] = 0x00,
2218 };
2219 #define prodigy71xt_eeprom prodigy71lt_eeprom
2220
2221 /* entry point */
2222 struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
2223         {
2224                 .subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
2225                 .name = "Terratec Aureon 5.1-Sky",
2226                 .model = "aureon51",
2227                 .chip_init = aureon_init,
2228                 .build_controls = aureon_add_controls,
2229                 .eeprom_size = sizeof(aureon51_eeprom),
2230                 .eeprom_data = aureon51_eeprom,
2231                 .driver = "Aureon51",
2232         },
2233         {
2234                 .subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
2235                 .name = "Terratec Aureon 7.1-Space",
2236                 .model = "aureon71",
2237                 .chip_init = aureon_init,
2238                 .build_controls = aureon_add_controls,
2239                 .eeprom_size = sizeof(aureon71_eeprom),
2240                 .eeprom_data = aureon71_eeprom,
2241                 .driver = "Aureon71",
2242         },
2243         {
2244                 .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
2245                 .name = "Terratec Aureon 7.1-Universe",
2246                 .model = "universe",
2247                 .chip_init = aureon_init,
2248                 .build_controls = aureon_add_controls,
2249                 .eeprom_size = sizeof(aureon71_universe_eeprom),
2250                 .eeprom_data = aureon71_universe_eeprom,
2251                 .driver = "Aureon71Univ", /* keep in 15 letters */
2252         },
2253         {
2254                 .subvendor = VT1724_SUBDEVICE_PRODIGY71,
2255                 .name = "Audiotrak Prodigy 7.1",
2256                 .model = "prodigy71",
2257                 .chip_init = aureon_init,
2258                 .build_controls = aureon_add_controls,
2259                 .eeprom_size = sizeof(prodigy71_eeprom),
2260                 .eeprom_data = prodigy71_eeprom,
2261                 .driver = "Prodigy71", /* should be identical with Aureon71 */
2262         },
2263         {
2264                 .subvendor = VT1724_SUBDEVICE_PRODIGY71LT,
2265                 .name = "Audiotrak Prodigy 7.1 LT",
2266                 .model = "prodigy71lt",
2267                 .chip_init = aureon_init,
2268                 .build_controls = aureon_add_controls,
2269                 .eeprom_size = sizeof(prodigy71lt_eeprom),
2270                 .eeprom_data = prodigy71lt_eeprom,
2271                 .driver = "Prodigy71LT",
2272         },
2273         {
2274                 .subvendor = VT1724_SUBDEVICE_PRODIGY71XT,
2275                 .name = "Audiotrak Prodigy 7.1 XT",
2276                 .model = "prodigy71xt",
2277                 .chip_init = aureon_init,
2278                 .build_controls = aureon_add_controls,
2279                 .eeprom_size = sizeof(prodigy71xt_eeprom),
2280                 .eeprom_data = prodigy71xt_eeprom,
2281                 .driver = "Prodigy71LT",
2282         },
2283         { } /* terminator */
2284 };