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