~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/pci/ice1712/aureon.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 const 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 const 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 const 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 const 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 const 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                 snd_ice1712_restore_gpio_status(ice);
1896                 if (id != 0x41)
1897                         dev_info(ice->card->dev,
1898                                  "No CS8415 chip. Skipping CS8415 controls.\n");
1899                 else {
1900                         for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
1901                                 struct snd_kcontrol *kctl;
1902                                 kctl = snd_ctl_new1(&cs8415_controls[i], ice);
1903                                 if (i > 1)
1904                                         kctl->id.device = ice->pcm->device;
1905                                 err = snd_ctl_add(ice->card, kctl);
1906                                 if (err < 0)
1907                                         return err;
1908                         }
1909                 }
1910         }
1911 
1912         return 0;
1913 }
1914 
1915 /*
1916  * reset the chip
1917  */
1918 static int aureon_reset(struct snd_ice1712 *ice)
1919 {
1920         static const unsigned short wm_inits_aureon[] = {
1921                 /* These come first to reduce init pop noise */
1922                 0x1b, 0x044,            /* ADC Mux (AC'97 source) */
1923                 0x1c, 0x00B,            /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
1924                 0x1d, 0x009,            /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
1925 
1926                 0x18, 0x000,            /* All power-up */
1927 
1928                 0x16, 0x122,            /* I2S, normal polarity, 24bit */
1929                 0x17, 0x022,            /* 256fs, slave mode */
1930                 0x00, 0,                /* DAC1 analog mute */
1931                 0x01, 0,                /* DAC2 analog mute */
1932                 0x02, 0,                /* DAC3 analog mute */
1933                 0x03, 0,                /* DAC4 analog mute */
1934                 0x04, 0,                /* DAC5 analog mute */
1935                 0x05, 0,                /* DAC6 analog mute */
1936                 0x06, 0,                /* DAC7 analog mute */
1937                 0x07, 0,                /* DAC8 analog mute */
1938                 0x08, 0x100,            /* master analog mute */
1939                 0x09, 0xff,             /* DAC1 digital full */
1940                 0x0a, 0xff,             /* DAC2 digital full */
1941                 0x0b, 0xff,             /* DAC3 digital full */
1942                 0x0c, 0xff,             /* DAC4 digital full */
1943                 0x0d, 0xff,             /* DAC5 digital full */
1944                 0x0e, 0xff,             /* DAC6 digital full */
1945                 0x0f, 0xff,             /* DAC7 digital full */
1946                 0x10, 0xff,             /* DAC8 digital full */
1947                 0x11, 0x1ff,            /* master digital full */
1948                 0x12, 0x000,            /* phase normal */
1949                 0x13, 0x090,            /* unmute DAC L/R */
1950                 0x14, 0x000,            /* all unmute */
1951                 0x15, 0x000,            /* no deemphasis, no ZFLG */
1952                 0x19, 0x000,            /* -12dB ADC/L */
1953                 0x1a, 0x000,            /* -12dB ADC/R */
1954                 (unsigned short)-1
1955         };
1956         static const unsigned short wm_inits_prodigy[] = {
1957 
1958                 /* These come first to reduce init pop noise */
1959                 0x1b, 0x000,            /* ADC Mux */
1960                 0x1c, 0x009,            /* Out Mux1 */
1961                 0x1d, 0x009,            /* Out Mux2 */
1962 
1963                 0x18, 0x000,            /* All power-up */
1964 
1965                 0x16, 0x022,            /* I2S, normal polarity, 24bit, high-pass on */
1966                 0x17, 0x006,            /* 128fs, slave mode */
1967 
1968                 0x00, 0,                /* DAC1 analog mute */
1969                 0x01, 0,                /* DAC2 analog mute */
1970                 0x02, 0,                /* DAC3 analog mute */
1971                 0x03, 0,                /* DAC4 analog mute */
1972                 0x04, 0,                /* DAC5 analog mute */
1973                 0x05, 0,                /* DAC6 analog mute */
1974                 0x06, 0,                /* DAC7 analog mute */
1975                 0x07, 0,                /* DAC8 analog mute */
1976                 0x08, 0x100,            /* master analog mute */
1977 
1978                 0x09, 0x7f,             /* DAC1 digital full */
1979                 0x0a, 0x7f,             /* DAC2 digital full */
1980                 0x0b, 0x7f,             /* DAC3 digital full */
1981                 0x0c, 0x7f,             /* DAC4 digital full */
1982                 0x0d, 0x7f,             /* DAC5 digital full */
1983                 0x0e, 0x7f,             /* DAC6 digital full */
1984                 0x0f, 0x7f,             /* DAC7 digital full */
1985                 0x10, 0x7f,             /* DAC8 digital full */
1986                 0x11, 0x1FF,            /* master digital full */
1987 
1988                 0x12, 0x000,            /* phase normal */
1989                 0x13, 0x090,            /* unmute DAC L/R */
1990                 0x14, 0x000,            /* all unmute */
1991                 0x15, 0x000,            /* no deemphasis, no ZFLG */
1992 
1993                 0x19, 0x000,            /* -12dB ADC/L */
1994                 0x1a, 0x000,            /* -12dB ADC/R */
1995                 (unsigned short)-1
1996 
1997         };
1998         static const unsigned short cs_inits[] = {
1999                 0x0441, /* RUN */
2000                 0x0180, /* no mute, OMCK output on RMCK pin */
2001                 0x0201, /* S/PDIF source on RXP1 */
2002                 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
2003                 (unsigned short)-1
2004         };
2005         unsigned int tmp;
2006         const unsigned short *p;
2007         int err;
2008         struct aureon_spec *spec = ice->spec;
2009 
2010         err = aureon_ac97_init(ice);
2011         if (err != 0)
2012                 return err;
2013 
2014         snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
2015 
2016         /* reset the wm codec as the SPI mode */
2017         snd_ice1712_save_gpio_status(ice);
2018         snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
2019 
2020         tmp = snd_ice1712_gpio_read(ice);
2021         tmp &= ~AUREON_WM_RESET;
2022         snd_ice1712_gpio_write(ice, tmp);
2023         udelay(1);
2024         tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
2025         snd_ice1712_gpio_write(ice, tmp);
2026         udelay(1);
2027         tmp |= AUREON_WM_RESET;
2028         snd_ice1712_gpio_write(ice, tmp);
2029         udelay(1);
2030 
2031         /* initialize WM8770 codec */
2032         if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
2033                 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
2034                 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT)
2035                 p = wm_inits_prodigy;
2036         else
2037                 p = wm_inits_aureon;
2038         for (; *p != (unsigned short)-1; p += 2)
2039                 wm_put(ice, p[0], p[1]);
2040 
2041         /* initialize CS8415A codec */
2042         if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
2043             ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
2044                 for (p = cs_inits; *p != (unsigned short)-1; p++)
2045                         aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
2046                 spec->cs8415_mux = 1;
2047 
2048                 aureon_set_headphone_amp(ice, 1);
2049         }
2050 
2051         snd_ice1712_restore_gpio_status(ice);
2052 
2053         /* initialize PCA9554 pin directions & set default input */
2054         aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2055         aureon_pca9554_write(ice, PCA9554_OUT, 0x00);   /* internal AUX */
2056         return 0;
2057 }
2058 
2059 /*
2060  * suspend/resume
2061  */
2062 #ifdef CONFIG_PM_SLEEP
2063 static int aureon_resume(struct snd_ice1712 *ice)
2064 {
2065         struct aureon_spec *spec = ice->spec;
2066         int err, i;
2067 
2068         err = aureon_reset(ice);
2069         if (err != 0)
2070                 return err;
2071 
2072         /* workaround for poking volume with alsamixer after resume:
2073          * just set stored volume again */
2074         for (i = 0; i < ice->num_total_dacs; i++)
2075                 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2076         return 0;
2077 }
2078 #endif
2079 
2080 /*
2081  * initialize the chip
2082  */
2083 static int aureon_init(struct snd_ice1712 *ice)
2084 {
2085         struct aureon_spec *spec;
2086         int i, err;
2087 
2088         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2089         if (!spec)
2090                 return -ENOMEM;
2091         ice->spec = spec;
2092 
2093         if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
2094                 ice->num_total_dacs = 6;
2095                 ice->num_total_adcs = 2;
2096         } else {
2097                 /* aureon 7.1 and prodigy 7.1 */
2098                 ice->num_total_dacs = 8;
2099                 ice->num_total_adcs = 2;
2100         }
2101 
2102         /* to remember the register values of CS8415 */
2103         ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2104         if (!ice->akm)
2105                 return -ENOMEM;
2106         ice->akm_codecs = 1;
2107 
2108         err = aureon_reset(ice);
2109         if (err != 0)
2110                 return err;
2111 
2112         spec->master[0] = WM_VOL_MUTE;
2113         spec->master[1] = WM_VOL_MUTE;
2114         for (i = 0; i < ice->num_total_dacs; i++) {
2115                 spec->vol[i] = WM_VOL_MUTE;
2116                 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2117         }
2118 
2119 #ifdef CONFIG_PM_SLEEP
2120         ice->pm_resume = aureon_resume;
2121         ice->pm_suspend_enabled = 1;
2122 #endif
2123 
2124         return 0;
2125 }
2126 
2127 
2128 /*
2129  * Aureon boards don't provide the EEPROM data except for the vendor IDs.
2130  * hence the driver needs to sets up it properly.
2131  */
2132 
2133 static const unsigned char aureon51_eeprom[] = {
2134         [ICE_EEP2_SYSCONF]     = 0x0a,  /* clock 512, spdif-in/ADC, 3DACs */
2135         [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
2136         [ICE_EEP2_I2S]         = 0xfc,  /* vol, 96k, 24bit, 192k */
2137         [ICE_EEP2_SPDIF]       = 0xc3,  /* out-en, out-int, spdif-in */
2138         [ICE_EEP2_GPIO_DIR]    = 0xff,
2139         [ICE_EEP2_GPIO_DIR1]   = 0xff,
2140         [ICE_EEP2_GPIO_DIR2]   = 0x5f,
2141         [ICE_EEP2_GPIO_MASK]   = 0x00,
2142         [ICE_EEP2_GPIO_MASK1]  = 0x00,
2143         [ICE_EEP2_GPIO_MASK2]  = 0x00,
2144         [ICE_EEP2_GPIO_STATE]  = 0x00,
2145         [ICE_EEP2_GPIO_STATE1] = 0x00,
2146         [ICE_EEP2_GPIO_STATE2] = 0x00,
2147 };
2148 
2149 static const unsigned char aureon71_eeprom[] = {
2150         [ICE_EEP2_SYSCONF]     = 0x0b,  /* clock 512, spdif-in/ADC, 4DACs */
2151         [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
2152         [ICE_EEP2_I2S]         = 0xfc,  /* vol, 96k, 24bit, 192k */
2153         [ICE_EEP2_SPDIF]       = 0xc3,  /* out-en, out-int, spdif-in */
2154         [ICE_EEP2_GPIO_DIR]    = 0xff,
2155         [ICE_EEP2_GPIO_DIR1]   = 0xff,
2156         [ICE_EEP2_GPIO_DIR2]   = 0x5f,
2157         [ICE_EEP2_GPIO_MASK]   = 0x00,
2158         [ICE_EEP2_GPIO_MASK1]  = 0x00,
2159         [ICE_EEP2_GPIO_MASK2]  = 0x00,
2160         [ICE_EEP2_GPIO_STATE]  = 0x00,
2161         [ICE_EEP2_GPIO_STATE1] = 0x00,
2162         [ICE_EEP2_GPIO_STATE2] = 0x00,
2163 };
2164 #define prodigy71_eeprom aureon71_eeprom
2165 
2166 static const unsigned char aureon71_universe_eeprom[] = {
2167         [ICE_EEP2_SYSCONF]     = 0x2b,  /* clock 512, mpu401, spdif-in/ADC,
2168                                          * 4DACs
2169                                          */
2170         [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
2171         [ICE_EEP2_I2S]         = 0xfc,  /* vol, 96k, 24bit, 192k */
2172         [ICE_EEP2_SPDIF]       = 0xc3,  /* out-en, out-int, spdif-in */
2173         [ICE_EEP2_GPIO_DIR]    = 0xff,
2174         [ICE_EEP2_GPIO_DIR1]   = 0xff,
2175         [ICE_EEP2_GPIO_DIR2]   = 0x5f,
2176         [ICE_EEP2_GPIO_MASK]   = 0x00,
2177         [ICE_EEP2_GPIO_MASK1]  = 0x00,
2178         [ICE_EEP2_GPIO_MASK2]  = 0x00,
2179         [ICE_EEP2_GPIO_STATE]  = 0x00,
2180         [ICE_EEP2_GPIO_STATE1] = 0x00,
2181         [ICE_EEP2_GPIO_STATE2] = 0x00,
2182 };
2183 
2184 static const unsigned char prodigy71lt_eeprom[] = {
2185         [ICE_EEP2_SYSCONF]     = 0x4b,  /* clock 384, spdif-in/ADC, 4DACs */
2186         [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
2187         [ICE_EEP2_I2S]         = 0xfc,  /* vol, 96k, 24bit, 192k */
2188         [ICE_EEP2_SPDIF]       = 0xc3,  /* out-en, out-int, spdif-in */
2189         [ICE_EEP2_GPIO_DIR]    = 0xff,
2190         [ICE_EEP2_GPIO_DIR1]   = 0xff,
2191         [ICE_EEP2_GPIO_DIR2]   = 0x5f,
2192         [ICE_EEP2_GPIO_MASK]   = 0x00,
2193         [ICE_EEP2_GPIO_MASK1]  = 0x00,
2194         [ICE_EEP2_GPIO_MASK2]  = 0x00,
2195         [ICE_EEP2_GPIO_STATE]  = 0x00,
2196         [ICE_EEP2_GPIO_STATE1] = 0x00,
2197         [ICE_EEP2_GPIO_STATE2] = 0x00,
2198 };
2199 #define prodigy71xt_eeprom prodigy71lt_eeprom
2200 
2201 /* entry point */
2202 struct snd_ice1712_card_info snd_vt1724_aureon_cards[] = {
2203         {
2204                 .subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
2205                 .name = "Terratec Aureon 5.1-Sky",
2206                 .model = "aureon51",
2207                 .chip_init = aureon_init,
2208                 .build_controls = aureon_add_controls,
2209                 .eeprom_size = sizeof(aureon51_eeprom),
2210                 .eeprom_data = aureon51_eeprom,
2211                 .driver = "Aureon51",
2212         },
2213         {
2214                 .subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
2215                 .name = "Terratec Aureon 7.1-Space",
2216                 .model = "aureon71",
2217                 .chip_init = aureon_init,
2218                 .build_controls = aureon_add_controls,
2219                 .eeprom_size = sizeof(aureon71_eeprom),
2220                 .eeprom_data = aureon71_eeprom,
2221                 .driver = "Aureon71",
2222         },
2223         {
2224                 .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
2225                 .name = "Terratec Aureon 7.1-Universe",
2226                 .model = "universe",
2227                 .chip_init = aureon_init,
2228                 .build_controls = aureon_add_controls,
2229                 .eeprom_size = sizeof(aureon71_universe_eeprom),
2230                 .eeprom_data = aureon71_universe_eeprom,
2231                 .driver = "Aureon71Univ", /* keep in 15 letters */
2232         },
2233         {
2234                 .subvendor = VT1724_SUBDEVICE_PRODIGY71,
2235                 .name = "Audiotrak Prodigy 7.1",
2236                 .model = "prodigy71",
2237                 .chip_init = aureon_init,
2238                 .build_controls = aureon_add_controls,
2239                 .eeprom_size = sizeof(prodigy71_eeprom),
2240                 .eeprom_data = prodigy71_eeprom,
2241                 .driver = "Prodigy71", /* should be identical with Aureon71 */
2242         },
2243         {
2244                 .subvendor = VT1724_SUBDEVICE_PRODIGY71LT,
2245                 .name = "Audiotrak Prodigy 7.1 LT",
2246                 .model = "prodigy71lt",
2247                 .chip_init = aureon_init,
2248                 .build_controls = aureon_add_controls,
2249                 .eeprom_size = sizeof(prodigy71lt_eeprom),
2250                 .eeprom_data = prodigy71lt_eeprom,
2251                 .driver = "Prodigy71LT",
2252         },
2253         {
2254                 .subvendor = VT1724_SUBDEVICE_PRODIGY71XT,
2255                 .name = "Audiotrak Prodigy 7.1 XT",
2256                 .model = "prodigy71xt",
2257                 .chip_init = aureon_init,
2258                 .build_controls = aureon_add_controls,
2259                 .eeprom_size = sizeof(prodigy71xt_eeprom),
2260                 .eeprom_data = prodigy71xt_eeprom,
2261                 .driver = "Prodigy71LT",
2262         },
2263         { } /* terminator */
2264 };
2265 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php