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