2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
4 * Lowlevel functions for Terratec Aureon cards
6 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * - we reuse the struct snd_akm4xxx record for storing the wm8770 codec data.
26 * both wm and akm codecs are pretty similar, so we can integrate
27 * both controls in the future, once if wm codecs are reused in
30 * - DAC digital volumes are not implemented in the mixer.
31 * if they show better response than DAC analog volumes, we can use them
34 * Lowlevel functions for AudioTrak Prodigy 7.1 (and possibly 192) cards
35 * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
37 * version 0.82: Stable / not all features work yet (no communication with AC97 secondary)
38 * added 64x/128x oversampling switch (should be 64x only for 96khz)
39 * fixed some recording labels (still need to check the rest)
40 * recording is working probably thanks to correct wm8770 initialization
42 * version 0.5: Initial release:
43 * working: analog output, mixer, headphone amplifier switch
44 * not working: prety much everything else, at least i could verify that
45 * we have no digital output, no capture, pretty bad clicks and poops
46 * on mixer switch and other coll stuff.
50 #include <sound/driver.h>
52 #include <linux/delay.h>
53 #include <linux/interrupt.h>
54 #include <linux/init.h>
55 #include <linux/slab.h>
56 #include <linux/mutex.h>
58 #include <sound/core.h>
64 /* WM8770 registers */
65 #define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
66 #define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */
67 #define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */
68 #define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */
69 #define WM_PHASE_SWAP 0x12 /* DAC phase */
70 #define WM_DAC_CTRL1 0x13 /* DAC control bits */
71 #define WM_MUTE 0x14 /* mute controls */
72 #define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */
73 #define WM_INT_CTRL 0x16 /* interface control */
74 #define WM_MASTER 0x17 /* master clock and mode */
75 #define WM_POWERDOWN 0x18 /* power-down controls */
76 #define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */
77 #define WM_ADC_MUX 0x1b /* input MUX */
78 #define WM_OUT_MUX1 0x1c /* output MUX */
79 #define WM_OUT_MUX2 0x1e /* output MUX */
80 #define WM_RESET 0x1f /* software reset */
82 /* CS8415A registers */
83 #define CS8415_CTRL1 0x01
84 #define CS8415_CTRL2 0x02
85 #define CS8415_QSUB 0x14
86 #define CS8415_RATIO 0x1E
87 #define CS8415_C_BUFFER 0x20
88 #define CS8415_ID 0x7F
90 /* PCA9554 registers */
91 #define PCA9554_DEV 0x40 /* I2C device address */
92 #define PCA9554_IN 0x00 /* input port */
93 #define PCA9554_OUT 0x01 /* output port */
94 #define PCA9554_INVERT 0x02 /* input invert */
95 #define PCA9554_DIR 0x03 /* port directions */
98 * Aureon Universe additional controls using PCA9554
102 * Send data to pca9554
104 static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
109 unsigned char dev = PCA9554_DEV; /* ID 0100000, write */
110 unsigned char val = 0;
112 tmp = snd_ice1712_gpio_read(ice);
114 snd_ice1712_gpio_set_mask(ice, ~(AUREON_SPI_MOSI|AUREON_SPI_CLK|
115 AUREON_WM_RW|AUREON_WM_CS|
118 tmp |= AUREON_CS8415_CS | AUREON_WM_CS; /* disable SPI devices */
120 tmp &= ~AUREON_SPI_MOSI;
121 tmp &= ~AUREON_SPI_CLK;
122 snd_ice1712_gpio_write(ice, tmp);
126 * send i2c stop condition and start condition
127 * to obtain sane state
129 tmp |= AUREON_SPI_CLK;
130 snd_ice1712_gpio_write(ice, tmp);
132 tmp |= AUREON_SPI_MOSI;
133 snd_ice1712_gpio_write(ice, tmp);
135 tmp &= ~AUREON_SPI_MOSI;
136 snd_ice1712_gpio_write(ice, tmp);
138 tmp &= ~AUREON_SPI_CLK;
139 snd_ice1712_gpio_write(ice, tmp);
142 * send device address, command and value,
143 * skipping ack cycles inbetween
145 for (j = 0; j < 3; j++) {
147 case 0: val = dev; break;
148 case 1: val = reg; break;
149 case 2: val = data; break;
151 for (i = 7; i >= 0; i--) {
152 tmp &= ~AUREON_SPI_CLK;
153 snd_ice1712_gpio_write(ice, tmp);
156 tmp |= AUREON_SPI_MOSI;
158 tmp &= ~AUREON_SPI_MOSI;
159 snd_ice1712_gpio_write(ice, tmp);
161 tmp |= AUREON_SPI_CLK;
162 snd_ice1712_gpio_write(ice, tmp);
165 tmp &= ~AUREON_SPI_CLK;
166 snd_ice1712_gpio_write(ice, tmp);
168 tmp |= AUREON_SPI_CLK;
169 snd_ice1712_gpio_write(ice, tmp);
171 tmp &= ~AUREON_SPI_CLK;
172 snd_ice1712_gpio_write(ice, tmp);
175 tmp &= ~AUREON_SPI_CLK;
176 snd_ice1712_gpio_write(ice, tmp);
178 tmp &= ~AUREON_SPI_MOSI;
179 snd_ice1712_gpio_write(ice, tmp);
181 tmp |= AUREON_SPI_CLK;
182 snd_ice1712_gpio_write(ice, tmp);
184 tmp |= AUREON_SPI_MOSI;
185 snd_ice1712_gpio_write(ice, tmp);
189 static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,
190 struct snd_ctl_elem_info *uinfo)
192 char *texts[3] = {"Internal Aux", "Wavetable", "Rear Line-In"};
194 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
196 uinfo->value.enumerated.items = 3;
197 if(uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
198 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
199 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
203 static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol,
204 struct snd_ctl_elem_value *ucontrol)
206 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
207 ucontrol->value.integer.value[0] = ice->spec.aureon.pca9554_out;
211 static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
212 struct snd_ctl_elem_value *ucontrol)
214 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
215 unsigned char oval, nval;
218 snd_ice1712_save_gpio_status(ice);
220 oval = ice->spec.aureon.pca9554_out;
221 nval = ucontrol->value.integer.value[0];
222 if ((change = (oval != nval))) {
223 aureon_pca9554_write(ice, PCA9554_OUT, nval);
224 ice->spec.aureon.pca9554_out = nval;
226 snd_ice1712_restore_gpio_status(ice);
232 static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
237 /* Send address to XILINX chip */
238 tmp = (snd_ice1712_gpio_read(ice) & ~0xFF) | (reg & 0x7F);
239 snd_ice1712_gpio_write(ice, tmp);
241 tmp |= AUREON_AC97_ADDR;
242 snd_ice1712_gpio_write(ice, tmp);
244 tmp &= ~AUREON_AC97_ADDR;
245 snd_ice1712_gpio_write(ice, tmp);
248 /* Send low-order byte to XILINX chip */
249 tmp &= ~AUREON_AC97_DATA_MASK;
250 tmp |= val & AUREON_AC97_DATA_MASK;
251 snd_ice1712_gpio_write(ice, tmp);
253 tmp |= AUREON_AC97_DATA_LOW;
254 snd_ice1712_gpio_write(ice, tmp);
256 tmp &= ~AUREON_AC97_DATA_LOW;
257 snd_ice1712_gpio_write(ice, tmp);
260 /* Send high-order byte to XILINX chip */
261 tmp &= ~AUREON_AC97_DATA_MASK;
262 tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
264 snd_ice1712_gpio_write(ice, tmp);
266 tmp |= AUREON_AC97_DATA_HIGH;
267 snd_ice1712_gpio_write(ice, tmp);
269 tmp &= ~AUREON_AC97_DATA_HIGH;
270 snd_ice1712_gpio_write(ice, tmp);
273 /* Instruct XILINX chip to parse the data to the STAC9744 chip */
274 tmp |= AUREON_AC97_COMMIT;
275 snd_ice1712_gpio_write(ice, tmp);
277 tmp &= ~AUREON_AC97_COMMIT;
278 snd_ice1712_gpio_write(ice, tmp);
281 /* Store the data in out private buffer */
282 ice->spec.aureon.stac9744[(reg & 0x7F) >> 1] = val;
285 static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short reg)
287 return ice->spec.aureon.stac9744[(reg & 0x7F) >> 1];
291 * Initialize STAC9744 chip
293 static int aureon_ac97_init (struct snd_ice1712 *ice)
296 static unsigned short ac97_defaults[] = {
320 tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
321 snd_ice1712_gpio_write(ice, tmp);
324 tmp &= ~AUREON_AC97_RESET;
325 snd_ice1712_gpio_write(ice, tmp);
328 tmp |= AUREON_AC97_RESET;
329 snd_ice1712_gpio_write(ice, tmp);
332 memset(&ice->spec.aureon.stac9744, 0, sizeof(ice->spec.aureon.stac9744));
333 for (i=0; ac97_defaults[i] != (unsigned short)-1; i+=2)
334 ice->spec.aureon.stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
336 aureon_ac97_write(ice, AC97_MASTER, 0x0000); // Unmute AC'97 master volume permanently - muting is done by WM8770
341 #define AUREON_AC97_STEREO 0x80
344 * AC'97 volume controls
346 static int aureon_ac97_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
348 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
349 uinfo->count = kcontrol->private_value & AUREON_AC97_STEREO ? 2 : 1;
350 uinfo->value.integer.min = 0;
351 uinfo->value.integer.max = 31;
355 static int aureon_ac97_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
357 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
360 mutex_lock(&ice->gpio_mutex);
362 vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
363 ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F);
364 if (kcontrol->private_value & AUREON_AC97_STEREO)
365 ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F);
367 mutex_unlock(&ice->gpio_mutex);
371 static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
373 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
374 unsigned short ovol, nvol;
377 snd_ice1712_save_gpio_status(ice);
379 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
380 nvol = (0x1F - ucontrol->value.integer.value[0]) & 0x001F;
381 if (kcontrol->private_value & AUREON_AC97_STEREO)
382 nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00;
383 nvol |= ovol & ~0x1F1F;
385 if ((change = (ovol != nvol)))
386 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
388 snd_ice1712_restore_gpio_status(ice);
394 * AC'97 mute controls
396 #define aureon_ac97_mute_info aureon_mono_bool_info
398 static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
400 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
402 mutex_lock(&ice->gpio_mutex);
404 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
406 mutex_unlock(&ice->gpio_mutex);
410 static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
412 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
413 unsigned short ovol, nvol;
416 snd_ice1712_save_gpio_status(ice);
418 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
419 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~ 0x8000);
421 if ((change = (ovol != nvol)))
422 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
424 snd_ice1712_restore_gpio_status(ice);
430 * AC'97 mute controls
432 #define aureon_ac97_micboost_info aureon_mono_bool_info
434 static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
436 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
438 mutex_lock(&ice->gpio_mutex);
440 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
442 mutex_unlock(&ice->gpio_mutex);
446 static int aureon_ac97_micboost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
448 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
449 unsigned short ovol, nvol;
452 snd_ice1712_save_gpio_status(ice);
454 ovol = aureon_ac97_read(ice, AC97_MIC);
455 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020);
457 if ((change = (ovol != nvol)))
458 aureon_ac97_write(ice, AC97_MIC, nvol);
460 snd_ice1712_restore_gpio_status(ice);
466 * write data in the SPI mode
468 static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits)
472 unsigned int mosi, clk;
474 tmp = snd_ice1712_gpio_read(ice);
476 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT) {
477 snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS));
478 mosi = PRODIGY_SPI_MOSI;
479 clk = PRODIGY_SPI_CLK;
482 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
483 AUREON_WM_CS|AUREON_CS8415_CS));
484 mosi = AUREON_SPI_MOSI;
485 clk = AUREON_SPI_CLK;
491 snd_ice1712_gpio_write(ice, tmp);
494 for (i = bits - 1; i >= 0; i--) {
496 snd_ice1712_gpio_write(ice, tmp);
502 snd_ice1712_gpio_write(ice, tmp);
505 snd_ice1712_gpio_write(ice, tmp);
511 snd_ice1712_gpio_write(ice, tmp);
514 snd_ice1712_gpio_write(ice, tmp);
519 * Read data in SPI mode
521 static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits, unsigned char *buffer, int size) {
525 tmp = (snd_ice1712_gpio_read(ice) & ~AUREON_SPI_CLK) | AUREON_CS8415_CS|AUREON_WM_CS;
526 snd_ice1712_gpio_write(ice, tmp);
528 snd_ice1712_gpio_write(ice, tmp);
531 for (i=bits-1; i>=0; i--) {
533 tmp |= AUREON_SPI_MOSI;
535 tmp &= ~AUREON_SPI_MOSI;
536 snd_ice1712_gpio_write(ice, tmp);
539 tmp |= AUREON_SPI_CLK;
540 snd_ice1712_gpio_write(ice, tmp);
543 tmp &= ~AUREON_SPI_CLK;
544 snd_ice1712_gpio_write(ice, tmp);
548 for (j=0; j<size; j++) {
549 unsigned char outdata = 0;
550 for (i=7; i>=0; i--) {
551 tmp = snd_ice1712_gpio_read(ice);
553 outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0;
556 tmp |= AUREON_SPI_CLK;
557 snd_ice1712_gpio_write(ice, tmp);
560 tmp &= ~AUREON_SPI_CLK;
561 snd_ice1712_gpio_write(ice, tmp);
568 snd_ice1712_gpio_write(ice, tmp);
571 static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg) {
573 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
574 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1);
578 static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg, unsigned char *buffer, int size) {
579 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
580 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size);
583 static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg, unsigned char val) {
584 aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24);
588 * get the current register value of WM codec
590 static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
593 return ((unsigned short)ice->akm[0].images[reg] << 8) |
594 ice->akm[0].images[reg + 1];
598 * set the register value of WM codec
600 static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
602 aureon_spi_write(ice,
603 (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ? PRODIGY_WM_CS : AUREON_WM_CS),
604 (reg << 9) | (val & 0x1ff), 16);
608 * set the register value of WM codec and remember it
610 static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
612 wm_put_nocache(ice, reg, val);
614 ice->akm[0].images[reg] = val >> 8;
615 ice->akm[0].images[reg + 1] = val;
620 static int aureon_mono_bool_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
622 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
624 uinfo->value.integer.min = 0;
625 uinfo->value.integer.max = 1;
630 * AC'97 master playback mute controls (Mute on WM8770 chip)
632 #define aureon_ac97_mmute_info aureon_mono_bool_info
634 static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
636 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
638 mutex_lock(&ice->gpio_mutex);
640 ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
642 mutex_unlock(&ice->gpio_mutex);
646 static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
647 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
648 unsigned short ovol, nvol;
651 snd_ice1712_save_gpio_status(ice);
653 ovol = wm_get(ice, WM_OUT_MUX1);
654 nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00);
655 if ((change = (ovol != nvol)))
656 wm_put(ice, WM_OUT_MUX1, nvol);
658 snd_ice1712_restore_gpio_status(ice);
664 * Logarithmic volume values for WM8770
665 * Computed as 20 * Log10(255 / x)
667 static unsigned char wm_vol[256] = {
668 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
669 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
670 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
671 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
672 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
673 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
674 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
675 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
676 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
677 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
678 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
682 #define WM_VOL_MAX (sizeof(wm_vol) - 1)
683 #define WM_VOL_MUTE 0x8000
685 static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
689 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
692 nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
694 wm_put(ice, index, nvol);
695 wm_put_nocache(ice, index, 0x180 | nvol);
701 #define wm_pcm_mute_info aureon_mono_bool_info
703 static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
705 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
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);
713 static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
715 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
716 unsigned short nval, oval;
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 if ((change = (nval != oval)))
723 wm_put(ice, WM_MUTE, nval);
724 snd_ice1712_restore_gpio_status(ice);
730 * Master volume attenuation mixer control
732 static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
734 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
736 uinfo->value.integer.min = 0;
737 uinfo->value.integer.max = WM_VOL_MAX;
741 static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
743 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
746 ucontrol->value.integer.value[i] = ice->spec.aureon.master[i] & ~WM_VOL_MUTE;
750 static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
752 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
755 snd_ice1712_save_gpio_status(ice);
756 for (ch = 0; ch < 2; ch++) {
757 if (ucontrol->value.integer.value[ch] != ice->spec.aureon.master[ch]) {
759 ice->spec.aureon.master[ch] &= WM_VOL_MUTE;
760 ice->spec.aureon.master[ch] |= ucontrol->value.integer.value[ch];
761 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
762 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
763 ice->spec.aureon.vol[dac + ch],
764 ice->spec.aureon.master[ch]);
768 snd_ice1712_restore_gpio_status(ice);
773 * DAC volume attenuation mixer control
775 static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
777 int voices = kcontrol->private_value >> 8;
778 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
779 uinfo->count = voices;
780 uinfo->value.integer.min = 0; /* mute (-101dB) */
781 uinfo->value.integer.max = 0x7F; /* 0dB */
785 static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
787 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
790 voices = kcontrol->private_value >> 8;
791 ofs = kcontrol->private_value & 0xff;
792 for (i = 0; i < voices; i++)
793 ucontrol->value.integer.value[i] = ice->spec.aureon.vol[ofs+i] & ~WM_VOL_MUTE;
797 static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
799 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
800 int i, idx, ofs, voices;
803 voices = kcontrol->private_value >> 8;
804 ofs = kcontrol->private_value & 0xff;
805 snd_ice1712_save_gpio_status(ice);
806 for (i = 0; i < voices; i++) {
807 idx = WM_DAC_ATTEN + ofs + i;
808 if (ucontrol->value.integer.value[i] != ice->spec.aureon.vol[ofs+i]) {
809 ice->spec.aureon.vol[ofs+i] &= WM_VOL_MUTE;
810 ice->spec.aureon.vol[ofs+i] |= ucontrol->value.integer.value[i];
811 wm_set_vol(ice, idx, ice->spec.aureon.vol[ofs+i],
812 ice->spec.aureon.master[i]);
816 snd_ice1712_restore_gpio_status(ice);
821 * WM8770 mute control
823 static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
824 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
825 uinfo->count = kcontrol->private_value >> 8;
826 uinfo->value.integer.min = 0;
827 uinfo->value.integer.max = 1;
831 static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
833 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
836 voices = kcontrol->private_value >> 8;
837 ofs = kcontrol->private_value & 0xFF;
839 for (i = 0; i < voices; i++)
840 ucontrol->value.integer.value[i] = (ice->spec.aureon.vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
844 static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
846 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
847 int change = 0, voices, ofs, i;
849 voices = kcontrol->private_value >> 8;
850 ofs = kcontrol->private_value & 0xFF;
852 snd_ice1712_save_gpio_status(ice);
853 for (i = 0; i < voices; i++) {
854 int val = (ice->spec.aureon.vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
855 if (ucontrol->value.integer.value[i] != val) {
856 ice->spec.aureon.vol[ofs + i] &= ~WM_VOL_MUTE;
857 ice->spec.aureon.vol[ofs + i] |=
858 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
859 wm_set_vol(ice, ofs + i, ice->spec.aureon.vol[ofs + i],
860 ice->spec.aureon.master[i]);
864 snd_ice1712_restore_gpio_status(ice);
870 * WM8770 master mute control
872 static int wm_master_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
873 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
875 uinfo->value.integer.min = 0;
876 uinfo->value.integer.max = 1;
880 static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
882 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
884 ucontrol->value.integer.value[0] = (ice->spec.aureon.master[0] & WM_VOL_MUTE) ? 0 : 1;
885 ucontrol->value.integer.value[1] = (ice->spec.aureon.master[1] & WM_VOL_MUTE) ? 0 : 1;
889 static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
891 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
894 snd_ice1712_save_gpio_status(ice);
895 for (i = 0; i < 2; i++) {
896 int val = (ice->spec.aureon.master[i] & WM_VOL_MUTE) ? 0 : 1;
897 if (ucontrol->value.integer.value[i] != val) {
899 ice->spec.aureon.master[i] &= ~WM_VOL_MUTE;
900 ice->spec.aureon.master[i] |=
901 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
902 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
903 wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
904 ice->spec.aureon.vol[dac + i],
905 ice->spec.aureon.master[i]);
909 snd_ice1712_restore_gpio_status(ice);
914 /* digital master volume */
916 #define PCM_RES 128 /* -64dB */
917 #define PCM_MIN (PCM_0dB - PCM_RES)
918 static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
920 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
922 uinfo->value.integer.min = 0; /* mute (-64dB) */
923 uinfo->value.integer.max = PCM_RES; /* 0dB */
927 static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
929 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
932 mutex_lock(&ice->gpio_mutex);
933 val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
934 val = val > PCM_MIN ? (val - PCM_MIN) : 0;
935 ucontrol->value.integer.value[0] = val;
936 mutex_unlock(&ice->gpio_mutex);
940 static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
942 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
943 unsigned short ovol, nvol;
946 snd_ice1712_save_gpio_status(ice);
947 nvol = ucontrol->value.integer.value[0];
948 nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
949 ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
951 wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
952 wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
955 snd_ice1712_restore_gpio_status(ice);
962 static int wm_adc_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
964 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
966 uinfo->value.integer.min = 0;
967 uinfo->value.integer.max = 1;
971 static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
973 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
977 mutex_lock(&ice->gpio_mutex);
978 for (i = 0; i < 2; i++) {
979 val = wm_get(ice, WM_ADC_GAIN + i);
980 ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
982 mutex_unlock(&ice->gpio_mutex);
986 static int wm_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
988 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
989 unsigned short new, old;
992 snd_ice1712_save_gpio_status(ice);
993 for (i = 0; i < 2; i++) {
994 old = wm_get(ice, WM_ADC_GAIN + i);
995 new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
997 wm_put(ice, WM_ADC_GAIN + i, new);
1001 snd_ice1712_restore_gpio_status(ice);
1007 * ADC gain mixer control
1009 static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1011 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1013 uinfo->value.integer.min = 0; /* -12dB */
1014 uinfo->value.integer.max = 0x1f; /* 19dB */
1018 static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1020 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1024 mutex_lock(&ice->gpio_mutex);
1025 for (i = 0; i < 2; i++) {
1026 idx = WM_ADC_GAIN + i;
1027 vol = wm_get(ice, idx) & 0x1f;
1028 ucontrol->value.integer.value[i] = vol;
1030 mutex_unlock(&ice->gpio_mutex);
1034 static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1036 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1038 unsigned short ovol, nvol;
1041 snd_ice1712_save_gpio_status(ice);
1042 for (i = 0; i < 2; i++) {
1043 idx = WM_ADC_GAIN + i;
1044 nvol = ucontrol->value.integer.value[i];
1045 ovol = wm_get(ice, idx);
1046 if ((ovol & 0x1f) != nvol) {
1047 wm_put(ice, idx, nvol | (ovol & ~0x1f));
1051 snd_ice1712_restore_gpio_status(ice);
1056 * ADC input mux mixer control
1058 static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1060 static char *texts[] = {
1067 static char *universe_texts[] = {
1077 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1079 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1081 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1082 uinfo->value.enumerated.items = 8;
1083 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1084 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1085 strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]);
1088 uinfo->value.enumerated.items = 5;
1089 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1090 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1091 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1096 static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1098 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1101 mutex_lock(&ice->gpio_mutex);
1102 val = wm_get(ice, WM_ADC_MUX);
1103 ucontrol->value.enumerated.item[0] = val & 7;
1104 ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
1105 mutex_unlock(&ice->gpio_mutex);
1109 static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1111 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1112 unsigned short oval, nval;
1115 snd_ice1712_save_gpio_status(ice);
1116 oval = wm_get(ice, WM_ADC_MUX);
1117 nval = oval & ~0x77;
1118 nval |= ucontrol->value.enumerated.item[0] & 7;
1119 nval |= (ucontrol->value.enumerated.item[1] & 7) << 4;
1120 change = (oval != nval);
1122 wm_put(ice, WM_ADC_MUX, nval);
1123 snd_ice1712_restore_gpio_status(ice);
1130 static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1132 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1133 static char *aureon_texts[] = {
1137 static char *prodigy_texts[] = {
1141 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1143 uinfo->value.enumerated.items = 2;
1144 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1145 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1146 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
1147 strcpy(uinfo->value.enumerated.name, prodigy_texts[uinfo->value.enumerated.item]);
1149 strcpy(uinfo->value.enumerated.name, aureon_texts[uinfo->value.enumerated.item]);
1153 static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1155 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1157 //snd_ice1712_save_gpio_status(ice);
1158 //val = aureon_cs8415_get(ice, CS8415_CTRL2);
1159 ucontrol->value.enumerated.item[0] = ice->spec.aureon.cs8415_mux;
1160 //snd_ice1712_restore_gpio_status(ice);
1164 static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1166 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1167 unsigned short oval, nval;
1170 snd_ice1712_save_gpio_status(ice);
1171 oval = aureon_cs8415_get(ice, CS8415_CTRL2);
1172 nval = oval & ~0x07;
1173 nval |= ucontrol->value.enumerated.item[0] & 7;
1174 change = (oval != nval);
1176 aureon_cs8415_put(ice, CS8415_CTRL2, nval);
1177 snd_ice1712_restore_gpio_status(ice);
1178 ice->spec.aureon.cs8415_mux = ucontrol->value.enumerated.item[0];
1182 static int aureon_cs8415_rate_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1184 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1186 uinfo->value.integer.min = 0;
1187 uinfo->value.integer.max = 192000;
1191 static int aureon_cs8415_rate_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1193 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1194 unsigned char ratio;
1195 ratio = aureon_cs8415_get(ice, CS8415_RATIO);
1196 ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750);
1203 static int aureon_cs8415_mute_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1205 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1210 static int aureon_cs8415_mute_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1212 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1213 snd_ice1712_save_gpio_status(ice);
1214 ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1;
1215 snd_ice1712_restore_gpio_status(ice);
1219 static int aureon_cs8415_mute_put (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1221 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1222 unsigned char oval, nval;
1224 snd_ice1712_save_gpio_status(ice);
1225 oval = aureon_cs8415_get(ice, CS8415_CTRL1);
1226 if (ucontrol->value.integer.value[0])
1227 nval = oval & ~0x20;
1230 if ((change = (oval != nval)))
1231 aureon_cs8415_put(ice, CS8415_CTRL1, nval);
1232 snd_ice1712_restore_gpio_status(ice);
1237 * CS8415A Q-Sub info
1239 static int aureon_cs8415_qsub_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
1240 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1245 static int aureon_cs8415_qsub_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
1246 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1248 snd_ice1712_save_gpio_status(ice);
1249 aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
1250 snd_ice1712_restore_gpio_status(ice);
1255 static int aureon_cs8415_spdif_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
1256 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1261 static int aureon_cs8415_mask_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
1262 memset(ucontrol->value.iec958.status, 0xFF, 24);
1266 static int aureon_cs8415_spdif_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
1267 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1269 snd_ice1712_save_gpio_status(ice);
1270 aureon_cs8415_read(ice, CS8415_C_BUFFER, ucontrol->value.iec958.status, 24);
1271 snd_ice1712_restore_gpio_status(ice);
1276 * Headphone Amplifier
1278 static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
1280 unsigned int tmp, tmp2;
1282 tmp2 = tmp = snd_ice1712_gpio_read(ice);
1284 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT)
1285 tmp |= AUREON_HP_SEL;
1287 tmp |= PRODIGY_HP_SEL;
1289 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT)
1290 tmp &= ~ AUREON_HP_SEL;
1292 tmp &= ~ PRODIGY_HP_SEL;
1294 snd_ice1712_gpio_write(ice, tmp);
1300 static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
1302 unsigned int tmp = snd_ice1712_gpio_read(ice);
1304 return ( tmp & AUREON_HP_SEL )!= 0;
1307 #define aureon_hpamp_info aureon_mono_bool_info
1309 static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1311 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1313 ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
1318 static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1320 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1322 return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]);
1329 #define aureon_deemp_info aureon_mono_bool_info
1331 static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1333 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1334 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
1338 static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1340 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1342 temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
1343 if (ucontrol->value.integer.value[0])
1347 if (temp != temp2) {
1348 wm_put(ice, WM_DAC_CTRL2, temp);
1357 static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
1359 static char *texts[2] = { "128x", "64x" };
1361 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1363 uinfo->value.enumerated.items = 2;
1365 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1366 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1367 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1372 static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1374 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1375 ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
1379 static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1382 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1384 temp2 = temp = wm_get(ice, WM_MASTER);
1386 if (ucontrol->value.enumerated.item[0])
1391 if (temp != temp2) {
1392 wm_put(ice, WM_MASTER, temp);
1402 static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
1404 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1405 .name = "Master Playback Switch",
1406 .info = wm_master_mute_info,
1407 .get = wm_master_mute_get,
1408 .put = wm_master_mute_put
1411 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1412 .name = "Master Playback Volume",
1413 .info = wm_master_vol_info,
1414 .get = wm_master_vol_get,
1415 .put = wm_master_vol_put
1418 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1419 .name = "Front Playback Switch",
1420 .info = wm_mute_info,
1423 .private_value = (2 << 8) | 0
1426 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1427 .name = "Front Playback Volume",
1428 .info = wm_vol_info,
1431 .private_value = (2 << 8) | 0
1434 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1435 .name = "Rear Playback Switch",
1436 .info = wm_mute_info,
1439 .private_value = (2 << 8) | 2
1442 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1443 .name = "Rear Playback Volume",
1444 .info = wm_vol_info,
1447 .private_value = (2 << 8) | 2
1450 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1451 .name = "Center Playback Switch",
1452 .info = wm_mute_info,
1455 .private_value = (1 << 8) | 4
1458 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1459 .name = "Center Playback Volume",
1460 .info = wm_vol_info,
1463 .private_value = (1 << 8) | 4
1466 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1467 .name = "LFE Playback Switch",
1468 .info = wm_mute_info,
1471 .private_value = (1 << 8) | 5
1474 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1475 .name = "LFE Playback Volume",
1476 .info = wm_vol_info,
1479 .private_value = (1 << 8) | 5
1482 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1483 .name = "Side Playback Switch",
1484 .info = wm_mute_info,
1487 .private_value = (2 << 8) | 6
1490 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1491 .name = "Side Playback Volume",
1492 .info = wm_vol_info,
1495 .private_value = (2 << 8) | 6
1499 static struct snd_kcontrol_new wm_controls[] __devinitdata = {
1501 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1502 .name = "PCM Playback Switch",
1503 .info = wm_pcm_mute_info,
1504 .get = wm_pcm_mute_get,
1505 .put = wm_pcm_mute_put
1508 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1509 .name = "PCM Playback Volume",
1510 .info = wm_pcm_vol_info,
1511 .get = wm_pcm_vol_get,
1512 .put = wm_pcm_vol_put
1515 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1516 .name = "Capture Switch",
1517 .info = wm_adc_mute_info,
1518 .get = wm_adc_mute_get,
1519 .put = wm_adc_mute_put,
1522 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1523 .name = "Capture Volume",
1524 .info = wm_adc_vol_info,
1525 .get = wm_adc_vol_get,
1526 .put = wm_adc_vol_put
1529 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1530 .name = "Capture Source",
1531 .info = wm_adc_mux_info,
1532 .get = wm_adc_mux_get,
1533 .put = wm_adc_mux_put,
1537 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1538 .name = "External Amplifier",
1539 .info = aureon_hpamp_info,
1540 .get = aureon_hpamp_get,
1541 .put = aureon_hpamp_put
1544 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1545 .name = "DAC Deemphasis Switch",
1546 .info = aureon_deemp_info,
1547 .get = aureon_deemp_get,
1548 .put = aureon_deemp_put
1551 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1552 .name = "ADC Oversampling",
1553 .info = aureon_oversampling_info,
1554 .get = aureon_oversampling_get,
1555 .put = aureon_oversampling_put
1559 static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
1561 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1562 .name = "AC97 Playback Switch",
1563 .info = aureon_ac97_mmute_info,
1564 .get = aureon_ac97_mmute_get,
1565 .put = aureon_ac97_mmute_put,
1566 .private_value = AC97_MASTER
1569 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1570 .name = "AC97 Playback Volume",
1571 .info = aureon_ac97_vol_info,
1572 .get = aureon_ac97_vol_get,
1573 .put = aureon_ac97_vol_put,
1574 .private_value = AC97_MASTER|AUREON_AC97_STEREO
1577 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1578 .name = "CD Playback Switch",
1579 .info = aureon_ac97_mute_info,
1580 .get = aureon_ac97_mute_get,
1581 .put = aureon_ac97_mute_put,
1582 .private_value = AC97_CD
1585 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1586 .name = "CD Playback Volume",
1587 .info = aureon_ac97_vol_info,
1588 .get = aureon_ac97_vol_get,
1589 .put = aureon_ac97_vol_put,
1590 .private_value = AC97_CD|AUREON_AC97_STEREO
1593 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1594 .name = "Aux Playback Switch",
1595 .info = aureon_ac97_mute_info,
1596 .get = aureon_ac97_mute_get,
1597 .put = aureon_ac97_mute_put,
1598 .private_value = AC97_AUX,
1601 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1602 .name = "Aux Playback Volume",
1603 .info = aureon_ac97_vol_info,
1604 .get = aureon_ac97_vol_get,
1605 .put = aureon_ac97_vol_put,
1606 .private_value = AC97_AUX|AUREON_AC97_STEREO
1609 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1610 .name = "Line Playback Switch",
1611 .info = aureon_ac97_mute_info,
1612 .get = aureon_ac97_mute_get,
1613 .put = aureon_ac97_mute_put,
1614 .private_value = AC97_LINE
1617 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1618 .name = "Line Playback Volume",
1619 .info = aureon_ac97_vol_info,
1620 .get = aureon_ac97_vol_get,
1621 .put = aureon_ac97_vol_put,
1622 .private_value = AC97_LINE|AUREON_AC97_STEREO
1625 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1626 .name = "Mic Playback Switch",
1627 .info = aureon_ac97_mute_info,
1628 .get = aureon_ac97_mute_get,
1629 .put = aureon_ac97_mute_put,
1630 .private_value = AC97_MIC
1633 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1634 .name = "Mic Playback Volume",
1635 .info = aureon_ac97_vol_info,
1636 .get = aureon_ac97_vol_get,
1637 .put = aureon_ac97_vol_put,
1638 .private_value = AC97_MIC
1641 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1642 .name = "Mic Boost (+20dB)",
1643 .info = aureon_ac97_micboost_info,
1644 .get = aureon_ac97_micboost_get,
1645 .put = aureon_ac97_micboost_put
1649 static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
1651 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1652 .name = "AC97 Playback Switch",
1653 .info = aureon_ac97_mmute_info,
1654 .get = aureon_ac97_mmute_get,
1655 .put = aureon_ac97_mmute_put,
1656 .private_value = AC97_MASTER
1659 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1660 .name = "AC97 Playback Volume",
1661 .info = aureon_ac97_vol_info,
1662 .get = aureon_ac97_vol_get,
1663 .put = aureon_ac97_vol_put,
1664 .private_value = AC97_MASTER|AUREON_AC97_STEREO
1667 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1668 .name = "CD Playback Switch",
1669 .info = aureon_ac97_mute_info,
1670 .get = aureon_ac97_mute_get,
1671 .put = aureon_ac97_mute_put,
1672 .private_value = AC97_AUX
1675 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1676 .name = "CD Playback Volume",
1677 .info = aureon_ac97_vol_info,
1678 .get = aureon_ac97_vol_get,
1679 .put = aureon_ac97_vol_put,
1680 .private_value = AC97_AUX|AUREON_AC97_STEREO
1683 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1684 .name = "Phono Playback Switch",
1685 .info = aureon_ac97_mute_info,
1686 .get = aureon_ac97_mute_get,
1687 .put = aureon_ac97_mute_put,
1688 .private_value = AC97_CD,
1691 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1692 .name = "Phono Playback Volume",
1693 .info = aureon_ac97_vol_info,
1694 .get = aureon_ac97_vol_get,
1695 .put = aureon_ac97_vol_put,
1696 .private_value = AC97_CD|AUREON_AC97_STEREO
1699 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1700 .name = "Line Playback Switch",
1701 .info = aureon_ac97_mute_info,
1702 .get = aureon_ac97_mute_get,
1703 .put = aureon_ac97_mute_put,
1704 .private_value = AC97_LINE
1707 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1708 .name = "Line Playback Volume",
1709 .info = aureon_ac97_vol_info,
1710 .get = aureon_ac97_vol_get,
1711 .put = aureon_ac97_vol_put,
1712 .private_value = AC97_LINE|AUREON_AC97_STEREO
1715 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1716 .name = "Mic Playback Switch",
1717 .info = aureon_ac97_mute_info,
1718 .get = aureon_ac97_mute_get,
1719 .put = aureon_ac97_mute_put,
1720 .private_value = AC97_MIC
1723 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1724 .name = "Mic Playback Volume",
1725 .info = aureon_ac97_vol_info,
1726 .get = aureon_ac97_vol_get,
1727 .put = aureon_ac97_vol_put,
1728 .private_value = AC97_MIC
1731 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1732 .name = "Mic Boost (+20dB)",
1733 .info = aureon_ac97_micboost_info,
1734 .get = aureon_ac97_micboost_get,
1735 .put = aureon_ac97_micboost_put
1738 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1739 .name = "Aux Playback Switch",
1740 .info = aureon_ac97_mute_info,
1741 .get = aureon_ac97_mute_get,
1742 .put = aureon_ac97_mute_put,
1743 .private_value = AC97_VIDEO,
1746 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1747 .name = "Aux Playback Volume",
1748 .info = aureon_ac97_vol_info,
1749 .get = aureon_ac97_vol_get,
1750 .put = aureon_ac97_vol_put,
1751 .private_value = AC97_VIDEO|AUREON_AC97_STEREO
1754 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1755 .name = "Aux Source",
1756 .info = aureon_universe_inmux_info,
1757 .get = aureon_universe_inmux_get,
1758 .put = aureon_universe_inmux_put
1764 static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
1766 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1767 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
1768 .info = aureon_cs8415_mute_info,
1769 .get = aureon_cs8415_mute_get,
1770 .put = aureon_cs8415_mute_put
1773 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1774 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Source",
1775 .info = aureon_cs8415_mux_info,
1776 .get = aureon_cs8415_mux_get,
1777 .put = aureon_cs8415_mux_put,
1780 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1781 .name = SNDRV_CTL_NAME_IEC958("Q-subcode ",CAPTURE,DEFAULT),
1782 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1783 .info = aureon_cs8415_qsub_info,
1784 .get = aureon_cs8415_qsub_get,
1787 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1788 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
1789 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1790 .info = aureon_cs8415_spdif_info,
1791 .get = aureon_cs8415_mask_get
1794 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1795 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
1796 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1797 .info = aureon_cs8415_spdif_info,
1798 .get = aureon_cs8415_spdif_get
1801 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1802 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Rate",
1803 .access =SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1804 .info = aureon_cs8415_rate_info,
1805 .get = aureon_cs8415_rate_get
1810 static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1812 unsigned int i, counts;
1815 counts = ARRAY_SIZE(aureon_dac_controls);
1816 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
1817 counts -= 2; /* no side */
1818 for (i = 0; i < counts; i++) {
1819 err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
1824 for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
1825 err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
1830 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1831 for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
1832 err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
1837 else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) {
1838 for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
1839 err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
1845 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) {
1847 snd_ice1712_save_gpio_status(ice);
1848 id = aureon_cs8415_get(ice, CS8415_ID);
1850 snd_printk(KERN_INFO "No CS8415 chip. Skipping CS8415 controls.\n");
1851 else if ((id & 0x0F) != 0x01)
1852 snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
1854 for (i = 0; i< ARRAY_SIZE(cs8415_controls); i++) {
1855 struct snd_kcontrol *kctl;
1856 err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
1860 kctl->id.device = ice->pcm->device;
1863 snd_ice1712_restore_gpio_status(ice);
1871 * initialize the chip
1873 static int __devinit aureon_init(struct snd_ice1712 *ice)
1875 static unsigned short wm_inits_aureon[] = {
1876 /* These come first to reduce init pop noise */
1877 0x1b, 0x044, /* ADC Mux (AC'97 source) */
1878 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
1879 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
1881 0x18, 0x000, /* All power-up */
1883 0x16, 0x122, /* I2S, normal polarity, 24bit */
1884 0x17, 0x022, /* 256fs, slave mode */
1885 0x00, 0, /* DAC1 analog mute */
1886 0x01, 0, /* DAC2 analog mute */
1887 0x02, 0, /* DAC3 analog mute */
1888 0x03, 0, /* DAC4 analog mute */
1889 0x04, 0, /* DAC5 analog mute */
1890 0x05, 0, /* DAC6 analog mute */
1891 0x06, 0, /* DAC7 analog mute */
1892 0x07, 0, /* DAC8 analog mute */
1893 0x08, 0x100, /* master analog mute */
1894 0x09, 0xff, /* DAC1 digital full */
1895 0x0a, 0xff, /* DAC2 digital full */
1896 0x0b, 0xff, /* DAC3 digital full */
1897 0x0c, 0xff, /* DAC4 digital full */
1898 0x0d, 0xff, /* DAC5 digital full */
1899 0x0e, 0xff, /* DAC6 digital full */
1900 0x0f, 0xff, /* DAC7 digital full */
1901 0x10, 0xff, /* DAC8 digital full */
1902 0x11, 0x1ff, /* master digital full */
1903 0x12, 0x000, /* phase normal */
1904 0x13, 0x090, /* unmute DAC L/R */
1905 0x14, 0x000, /* all unmute */
1906 0x15, 0x000, /* no deemphasis, no ZFLG */
1907 0x19, 0x000, /* -12dB ADC/L */
1908 0x1a, 0x000, /* -12dB ADC/R */
1911 static unsigned short wm_inits_prodigy[] = {
1913 /* These come first to reduce init pop noise */
1914 0x1b, 0x000, /* ADC Mux */
1915 0x1c, 0x009, /* Out Mux1 */
1916 0x1d, 0x009, /* Out Mux2 */
1918 0x18, 0x000, /* All power-up */
1920 0x16, 0x022, /* I2S, normal polarity, 24bit, high-pass on */
1921 0x17, 0x006, /* 128fs, slave mode */
1923 0x00, 0, /* DAC1 analog mute */
1924 0x01, 0, /* DAC2 analog mute */
1925 0x02, 0, /* DAC3 analog mute */
1926 0x03, 0, /* DAC4 analog mute */
1927 0x04, 0, /* DAC5 analog mute */
1928 0x05, 0, /* DAC6 analog mute */
1929 0x06, 0, /* DAC7 analog mute */
1930 0x07, 0, /* DAC8 analog mute */
1931 0x08, 0x100, /* master analog mute */
1933 0x09, 0x7f, /* DAC1 digital full */
1934 0x0a, 0x7f, /* DAC2 digital full */
1935 0x0b, 0x7f, /* DAC3 digital full */
1936 0x0c, 0x7f, /* DAC4 digital full */
1937 0x0d, 0x7f, /* DAC5 digital full */
1938 0x0e, 0x7f, /* DAC6 digital full */
1939 0x0f, 0x7f, /* DAC7 digital full */
1940 0x10, 0x7f, /* DAC8 digital full */
1941 0x11, 0x1FF, /* master digital full */
1943 0x12, 0x000, /* phase normal */
1944 0x13, 0x090, /* unmute DAC L/R */
1945 0x14, 0x000, /* all unmute */
1946 0x15, 0x000, /* no deemphasis, no ZFLG */
1948 0x19, 0x000, /* -12dB ADC/L */
1949 0x1a, 0x000, /* -12dB ADC/R */
1953 static unsigned short cs_inits[] = {
1955 0x0180, /* no mute, OMCK output on RMCK pin */
1956 0x0201, /* S/PDIF source on RXP1 */
1957 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
1964 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
1965 ice->num_total_dacs = 6;
1966 ice->num_total_adcs = 2;
1968 /* aureon 7.1 and prodigy 7.1 */
1969 ice->num_total_dacs = 8;
1970 ice->num_total_adcs = 2;
1973 /* to remeber the register values of CS8415 */
1974 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
1977 ice->akm_codecs = 1;
1979 if ((err = aureon_ac97_init(ice)) != 0)
1982 snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
1984 /* reset the wm codec as the SPI mode */
1985 snd_ice1712_save_gpio_status(ice);
1986 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
1988 tmp = snd_ice1712_gpio_read(ice);
1989 tmp &= ~AUREON_WM_RESET;
1990 snd_ice1712_gpio_write(ice, tmp);
1992 tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
1993 snd_ice1712_gpio_write(ice, tmp);
1995 tmp |= AUREON_WM_RESET;
1996 snd_ice1712_gpio_write(ice, tmp);
1999 /* initialize WM8770 codec */
2000 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
2001 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT)
2002 p = wm_inits_prodigy;
2004 p = wm_inits_aureon;
2005 for (; *p != (unsigned short)-1; p += 2)
2006 wm_put(ice, p[0], p[1]);
2008 /* initialize CS8415A codec */
2009 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) {
2010 for (p = cs_inits; *p != (unsigned short)-1; p++)
2011 aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
2012 ice->spec.aureon.cs8415_mux = 1;
2014 aureon_set_headphone_amp(ice, 1);
2017 snd_ice1712_restore_gpio_status(ice);
2019 /* initialize PCA9554 pin directions & set default input*/
2020 aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2021 aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */
2023 ice->spec.aureon.master[0] = WM_VOL_MUTE;
2024 ice->spec.aureon.master[1] = WM_VOL_MUTE;
2025 for (i = 0; i < ice->num_total_dacs; i++) {
2026 ice->spec.aureon.vol[i] = WM_VOL_MUTE;
2027 wm_set_vol(ice, i, ice->spec.aureon.vol[i], ice->spec.aureon.master[i % 2]);
2035 * Aureon boards don't provide the EEPROM data except for the vendor IDs.
2036 * hence the driver needs to sets up it properly.
2039 static unsigned char aureon51_eeprom[] __devinitdata = {
2040 0x0a, /* SYSCONF: clock 512, spdif-in/ADC, 3DACs */
2041 0x80, /* ACLINK: I2S */
2042 0xfc, /* I2S: vol, 96k, 24bit, 192k */
2043 0xc3, /* SPDIF: out-en, out-int, spdif-in */
2044 0xff, /* GPIO_DIR */
2045 0xff, /* GPIO_DIR1 */
2046 0x5f, /* GPIO_DIR2 */
2047 0x00, /* GPIO_MASK */
2048 0x00, /* GPIO_MASK1 */
2049 0x00, /* GPIO_MASK2 */
2050 0x00, /* GPIO_STATE */
2051 0x00, /* GPIO_STATE1 */
2052 0x00, /* GPIO_STATE2 */
2055 static unsigned char aureon71_eeprom[] __devinitdata = {
2056 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
2057 0x80, /* ACLINK: I2S */
2058 0xfc, /* I2S: vol, 96k, 24bit, 192k */
2059 0xc3, /* SPDIF: out-en, out-int, spdif-in */
2060 0xff, /* GPIO_DIR */
2061 0xff, /* GPIO_DIR1 */
2062 0x5f, /* GPIO_DIR2 */
2063 0x00, /* GPIO_MASK */
2064 0x00, /* GPIO_MASK1 */
2065 0x00, /* GPIO_MASK2 */
2066 0x00, /* GPIO_STATE */
2067 0x00, /* GPIO_STATE1 */
2068 0x00, /* GPIO_STATE2 */
2071 static unsigned char prodigy71_eeprom[] __devinitdata = {
2072 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
2073 0x80, /* ACLINK: I2S */
2074 0xfc, /* I2S: vol, 96k, 24bit, 192k */
2075 0xc3, /* SPDIF: out-en, out-int, spdif-in */
2076 0xff, /* GPIO_DIR */
2077 0xff, /* GPIO_DIR1 */
2078 0x5f, /* GPIO_DIR2 */
2079 0x00, /* GPIO_MASK */
2080 0x00, /* GPIO_MASK1 */
2081 0x00, /* GPIO_MASK2 */
2082 0x00, /* GPIO_STATE */
2083 0x00, /* GPIO_STATE1 */
2084 0x00, /* GPIO_STATE2 */
2087 static unsigned char prodigy71lt_eeprom[] __devinitdata = {
2088 0x4b, /* SYSCINF: clock 512, spdif-in/ADC, 4DACs */
2089 0x80, /* ACLINK: I2S */
2090 0xfc, /* I2S: vol, 96k, 24bit, 192k */
2091 0xc3, /* SPDIF: out-en, out-int, spdif-in */
2092 0xff, /* GPIO_DIR */
2093 0xff, /* GPIO_DIR1 */
2094 0x5f, /* GPIO_DIR2 */
2095 0x00, /* GPIO_MASK */
2096 0x00, /* GPIO_MASK1 */
2097 0x00, /* GPIO_MASK2 */
2098 0x00, /* GPIO_STATE */
2099 0x00, /* GPIO_STATE1 */
2100 0x00, /* GPIO_STATE2 */
2105 struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
2107 .subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
2108 .name = "Terratec Aureon 5.1-Sky",
2109 .model = "aureon51",
2110 .chip_init = aureon_init,
2111 .build_controls = aureon_add_controls,
2112 .eeprom_size = sizeof(aureon51_eeprom),
2113 .eeprom_data = aureon51_eeprom,
2114 .driver = "Aureon51",
2117 .subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
2118 .name = "Terratec Aureon 7.1-Space",
2119 .model = "aureon71",
2120 .chip_init = aureon_init,
2121 .build_controls = aureon_add_controls,
2122 .eeprom_size = sizeof(aureon71_eeprom),
2123 .eeprom_data = aureon71_eeprom,
2124 .driver = "Aureon71",
2127 .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
2128 .name = "Terratec Aureon 7.1-Universe",
2129 .model = "universe",
2130 .chip_init = aureon_init,
2131 .build_controls = aureon_add_controls,
2132 .eeprom_size = sizeof(aureon71_eeprom),
2133 .eeprom_data = aureon71_eeprom,
2134 .driver = "Aureon71Univ", /* keep in 15 letters */
2137 .subvendor = VT1724_SUBDEVICE_PRODIGY71,
2138 .name = "Audiotrak Prodigy 7.1",
2139 .model = "prodigy71",
2140 .chip_init = aureon_init,
2141 .build_controls = aureon_add_controls,
2142 .eeprom_size = sizeof(prodigy71_eeprom),
2143 .eeprom_data = prodigy71_eeprom,
2144 .driver = "Prodigy71", /* should be identical with Aureon71 */
2147 .subvendor = VT1724_SUBDEVICE_PRODIGY71LT,
2148 .name = "Audiotrak Prodigy 7.1 LT",
2149 .model = "prodigy71lt",
2150 .chip_init = aureon_init,
2151 .build_controls = aureon_add_controls,
2152 .eeprom_size = sizeof(prodigy71lt_eeprom),
2153 .eeprom_data = prodigy71lt_eeprom,
2154 .driver = "Prodigy71LT",
2156 { } /* terminator */