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