root/sound/pci/ice1712/aureon.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. aureon_pca9554_write
  2. aureon_universe_inmux_info
  3. aureon_universe_inmux_get
  4. aureon_universe_inmux_put
  5. aureon_ac97_write
  6. aureon_ac97_read
  7. aureon_ac97_init
  8. aureon_ac97_vol_info
  9. aureon_ac97_vol_get
  10. aureon_ac97_vol_put
  11. aureon_ac97_mute_get
  12. aureon_ac97_mute_put
  13. aureon_ac97_micboost_get
  14. aureon_ac97_micboost_put
  15. aureon_spi_write
  16. aureon_spi_read
  17. aureon_cs8415_get
  18. aureon_cs8415_read
  19. aureon_cs8415_put
  20. wm_get
  21. wm_put_nocache
  22. wm_put
  23. aureon_ac97_mmute_get
  24. aureon_ac97_mmute_put
  25. wm_set_vol
  26. wm_pcm_mute_get
  27. wm_pcm_mute_put
  28. wm_master_vol_info
  29. wm_master_vol_get
  30. wm_master_vol_put
  31. wm_vol_info
  32. wm_vol_get
  33. wm_vol_put
  34. wm_mute_info
  35. wm_mute_get
  36. wm_mute_put
  37. wm_master_mute_get
  38. wm_master_mute_put
  39. wm_pcm_vol_info
  40. wm_pcm_vol_get
  41. wm_pcm_vol_put
  42. wm_adc_mute_get
  43. wm_adc_mute_put
  44. wm_adc_vol_info
  45. wm_adc_vol_get
  46. wm_adc_vol_put
  47. wm_adc_mux_info
  48. wm_adc_mux_get
  49. wm_adc_mux_put
  50. aureon_cs8415_mux_info
  51. aureon_cs8415_mux_get
  52. aureon_cs8415_mux_put
  53. aureon_cs8415_rate_info
  54. aureon_cs8415_rate_get
  55. aureon_cs8415_mute_get
  56. aureon_cs8415_mute_put
  57. aureon_cs8415_qsub_info
  58. aureon_cs8415_qsub_get
  59. aureon_cs8415_spdif_info
  60. aureon_cs8415_mask_get
  61. aureon_cs8415_spdif_get
  62. aureon_set_headphone_amp
  63. aureon_get_headphone_amp
  64. aureon_hpamp_get
  65. aureon_hpamp_put
  66. aureon_deemp_get
  67. aureon_deemp_put
  68. aureon_oversampling_info
  69. aureon_oversampling_get
  70. aureon_oversampling_put
  71. aureon_add_controls
  72. aureon_reset
  73. aureon_resume
  74. aureon_init

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

/* [<][>][^][v][top][bottom][index][help] */