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>
63 #include <sound/tlv.h>
65 /* WM8770 registers */
66 #define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
67 #define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */
68 #define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */
69 #define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */
70 #define WM_PHASE_SWAP 0x12 /* DAC phase */
71 #define WM_DAC_CTRL1 0x13 /* DAC control bits */
72 #define WM_MUTE 0x14 /* mute controls */
73 #define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */
74 #define WM_INT_CTRL 0x16 /* interface control */
75 #define WM_MASTER 0x17 /* master clock and mode */
76 #define WM_POWERDOWN 0x18 /* power-down controls */
77 #define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */
78 #define WM_ADC_MUX 0x1b /* input MUX */
79 #define WM_OUT_MUX1 0x1c /* output MUX */
80 #define WM_OUT_MUX2 0x1e /* output MUX */
81 #define WM_RESET 0x1f /* software reset */
83 /* CS8415A registers */
84 #define CS8415_CTRL1 0x01
85 #define CS8415_CTRL2 0x02
86 #define CS8415_QSUB 0x14
87 #define CS8415_RATIO 0x1E
88 #define CS8415_C_BUFFER 0x20
89 #define CS8415_ID 0x7F
91 /* PCA9554 registers */
92 #define PCA9554_DEV 0x40 /* I2C device address */
93 #define PCA9554_IN 0x00 /* input port */
94 #define PCA9554_OUT 0x01 /* output port */
95 #define PCA9554_INVERT 0x02 /* input invert */
96 #define PCA9554_DIR 0x03 /* port directions */
99 * Aureon Universe additional controls using PCA9554
103 * Send data to pca9554
105 static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
110 unsigned char dev = PCA9554_DEV; /* ID 0100000, write */
111 unsigned char val = 0;
113 tmp = snd_ice1712_gpio_read(ice);
115 snd_ice1712_gpio_set_mask(ice, ~(AUREON_SPI_MOSI|AUREON_SPI_CLK|
116 AUREON_WM_RW|AUREON_WM_CS|
119 tmp |= AUREON_CS8415_CS | AUREON_WM_CS; /* disable SPI devices */
121 tmp &= ~AUREON_SPI_MOSI;
122 tmp &= ~AUREON_SPI_CLK;
123 snd_ice1712_gpio_write(ice, tmp);
127 * send i2c stop condition and start condition
128 * to obtain sane state
130 tmp |= AUREON_SPI_CLK;
131 snd_ice1712_gpio_write(ice, tmp);
133 tmp |= AUREON_SPI_MOSI;
134 snd_ice1712_gpio_write(ice, tmp);
136 tmp &= ~AUREON_SPI_MOSI;
137 snd_ice1712_gpio_write(ice, tmp);
139 tmp &= ~AUREON_SPI_CLK;
140 snd_ice1712_gpio_write(ice, tmp);
143 * send device address, command and value,
144 * skipping ack cycles inbetween
146 for (j = 0; j < 3; j++) {
148 case 0: val = dev; break;
149 case 1: val = reg; break;
150 case 2: val = data; break;
152 for (i = 7; i >= 0; i--) {
153 tmp &= ~AUREON_SPI_CLK;
154 snd_ice1712_gpio_write(ice, tmp);
157 tmp |= AUREON_SPI_MOSI;
159 tmp &= ~AUREON_SPI_MOSI;
160 snd_ice1712_gpio_write(ice, tmp);
162 tmp |= AUREON_SPI_CLK;
163 snd_ice1712_gpio_write(ice, tmp);
166 tmp &= ~AUREON_SPI_CLK;
167 snd_ice1712_gpio_write(ice, tmp);
169 tmp |= AUREON_SPI_CLK;
170 snd_ice1712_gpio_write(ice, tmp);
172 tmp &= ~AUREON_SPI_CLK;
173 snd_ice1712_gpio_write(ice, tmp);
176 tmp &= ~AUREON_SPI_CLK;
177 snd_ice1712_gpio_write(ice, tmp);
179 tmp &= ~AUREON_SPI_MOSI;
180 snd_ice1712_gpio_write(ice, tmp);
182 tmp |= AUREON_SPI_CLK;
183 snd_ice1712_gpio_write(ice, tmp);
185 tmp |= AUREON_SPI_MOSI;
186 snd_ice1712_gpio_write(ice, tmp);
190 static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,
191 struct snd_ctl_elem_info *uinfo)
193 char *texts[3] = {"Internal Aux", "Wavetable", "Rear Line-In"};
195 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
197 uinfo->value.enumerated.items = 3;
198 if(uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
199 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
200 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
204 static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol,
205 struct snd_ctl_elem_value *ucontrol)
207 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
208 ucontrol->value.integer.value[0] = ice->spec.aureon.pca9554_out;
212 static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
213 struct snd_ctl_elem_value *ucontrol)
215 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
216 unsigned char oval, nval;
219 snd_ice1712_save_gpio_status(ice);
221 oval = ice->spec.aureon.pca9554_out;
222 nval = ucontrol->value.integer.value[0];
223 if ((change = (oval != nval))) {
224 aureon_pca9554_write(ice, PCA9554_OUT, nval);
225 ice->spec.aureon.pca9554_out = nval;
227 snd_ice1712_restore_gpio_status(ice);
233 static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
238 /* Send address to XILINX chip */
239 tmp = (snd_ice1712_gpio_read(ice) & ~0xFF) | (reg & 0x7F);
240 snd_ice1712_gpio_write(ice, tmp);
242 tmp |= AUREON_AC97_ADDR;
243 snd_ice1712_gpio_write(ice, tmp);
245 tmp &= ~AUREON_AC97_ADDR;
246 snd_ice1712_gpio_write(ice, tmp);
249 /* Send low-order byte to XILINX chip */
250 tmp &= ~AUREON_AC97_DATA_MASK;
251 tmp |= val & AUREON_AC97_DATA_MASK;
252 snd_ice1712_gpio_write(ice, tmp);
254 tmp |= AUREON_AC97_DATA_LOW;
255 snd_ice1712_gpio_write(ice, tmp);
257 tmp &= ~AUREON_AC97_DATA_LOW;
258 snd_ice1712_gpio_write(ice, tmp);
261 /* Send high-order byte to XILINX chip */
262 tmp &= ~AUREON_AC97_DATA_MASK;
263 tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
265 snd_ice1712_gpio_write(ice, tmp);
267 tmp |= AUREON_AC97_DATA_HIGH;
268 snd_ice1712_gpio_write(ice, tmp);
270 tmp &= ~AUREON_AC97_DATA_HIGH;
271 snd_ice1712_gpio_write(ice, tmp);
274 /* Instruct XILINX chip to parse the data to the STAC9744 chip */
275 tmp |= AUREON_AC97_COMMIT;
276 snd_ice1712_gpio_write(ice, tmp);
278 tmp &= ~AUREON_AC97_COMMIT;
279 snd_ice1712_gpio_write(ice, tmp);
282 /* Store the data in out private buffer */
283 ice->spec.aureon.stac9744[(reg & 0x7F) >> 1] = val;
286 static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short reg)
288 return ice->spec.aureon.stac9744[(reg & 0x7F) >> 1];
292 * Initialize STAC9744 chip
294 static int aureon_ac97_init (struct snd_ice1712 *ice)
297 static const unsigned short ac97_defaults[] = {
321 tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
322 snd_ice1712_gpio_write(ice, tmp);
325 tmp &= ~AUREON_AC97_RESET;
326 snd_ice1712_gpio_write(ice, tmp);
329 tmp |= AUREON_AC97_RESET;
330 snd_ice1712_gpio_write(ice, tmp);
333 memset(&ice->spec.aureon.stac9744, 0, sizeof(ice->spec.aureon.stac9744));
334 for (i=0; ac97_defaults[i] != (unsigned short)-1; i+=2)
335 ice->spec.aureon.stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
337 aureon_ac97_write(ice, AC97_MASTER, 0x0000); // Unmute AC'97 master volume permanently - muting is done by WM8770
342 #define AUREON_AC97_STEREO 0x80
345 * AC'97 volume controls
347 static int aureon_ac97_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
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;
356 static int aureon_ac97_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
358 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
361 mutex_lock(&ice->gpio_mutex);
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);
368 mutex_unlock(&ice->gpio_mutex);
372 static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
374 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
375 unsigned short ovol, nvol;
378 snd_ice1712_save_gpio_status(ice);
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;
386 if ((change = (ovol != nvol)))
387 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
389 snd_ice1712_restore_gpio_status(ice);
395 * AC'97 mute controls
397 #define aureon_ac97_mute_info aureon_mono_bool_info
399 static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
401 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
403 mutex_lock(&ice->gpio_mutex);
405 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
407 mutex_unlock(&ice->gpio_mutex);
411 static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
413 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
414 unsigned short ovol, nvol;
417 snd_ice1712_save_gpio_status(ice);
419 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
420 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~ 0x8000);
422 if ((change = (ovol != nvol)))
423 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
425 snd_ice1712_restore_gpio_status(ice);
431 * AC'97 mute controls
433 #define aureon_ac97_micboost_info aureon_mono_bool_info
435 static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
437 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
439 mutex_lock(&ice->gpio_mutex);
441 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
443 mutex_unlock(&ice->gpio_mutex);
447 static int aureon_ac97_micboost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
449 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
450 unsigned short ovol, nvol;
453 snd_ice1712_save_gpio_status(ice);
455 ovol = aureon_ac97_read(ice, AC97_MIC);
456 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020);
458 if ((change = (ovol != nvol)))
459 aureon_ac97_write(ice, AC97_MIC, nvol);
461 snd_ice1712_restore_gpio_status(ice);
467 * write data in the SPI mode
469 static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits)
473 unsigned int mosi, clk;
475 tmp = snd_ice1712_gpio_read(ice);
477 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
478 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) {
479 snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS));
480 mosi = PRODIGY_SPI_MOSI;
481 clk = PRODIGY_SPI_CLK;
484 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
485 AUREON_WM_CS|AUREON_CS8415_CS));
486 mosi = AUREON_SPI_MOSI;
487 clk = AUREON_SPI_CLK;
493 snd_ice1712_gpio_write(ice, tmp);
496 for (i = bits - 1; i >= 0; i--) {
498 snd_ice1712_gpio_write(ice, tmp);
504 snd_ice1712_gpio_write(ice, tmp);
507 snd_ice1712_gpio_write(ice, tmp);
513 snd_ice1712_gpio_write(ice, tmp);
516 snd_ice1712_gpio_write(ice, tmp);
521 * Read data in SPI mode
523 static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits, unsigned char *buffer, int size) {
527 tmp = (snd_ice1712_gpio_read(ice) & ~AUREON_SPI_CLK) | AUREON_CS8415_CS|AUREON_WM_CS;
528 snd_ice1712_gpio_write(ice, tmp);
530 snd_ice1712_gpio_write(ice, tmp);
533 for (i=bits-1; i>=0; i--) {
535 tmp |= AUREON_SPI_MOSI;
537 tmp &= ~AUREON_SPI_MOSI;
538 snd_ice1712_gpio_write(ice, tmp);
541 tmp |= AUREON_SPI_CLK;
542 snd_ice1712_gpio_write(ice, tmp);
545 tmp &= ~AUREON_SPI_CLK;
546 snd_ice1712_gpio_write(ice, tmp);
550 for (j=0; j<size; j++) {
551 unsigned char outdata = 0;
552 for (i=7; i>=0; i--) {
553 tmp = snd_ice1712_gpio_read(ice);
555 outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0;
558 tmp |= AUREON_SPI_CLK;
559 snd_ice1712_gpio_write(ice, tmp);
562 tmp &= ~AUREON_SPI_CLK;
563 snd_ice1712_gpio_write(ice, tmp);
570 snd_ice1712_gpio_write(ice, tmp);
573 static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg) {
575 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
576 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1);
580 static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg, unsigned char *buffer, int size) {
581 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
582 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size);
585 static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg, unsigned char val) {
586 aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24);
590 * get the current register value of WM codec
592 static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
595 return ((unsigned short)ice->akm[0].images[reg] << 8) |
596 ice->akm[0].images[reg + 1];
600 * set the register value of WM codec
602 static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
604 aureon_spi_write(ice,
605 ((ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
606 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) ?
607 PRODIGY_WM_CS : AUREON_WM_CS),
608 (reg << 9) | (val & 0x1ff), 16);
612 * set the register value of WM codec and remember it
614 static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
616 wm_put_nocache(ice, reg, val);
618 ice->akm[0].images[reg] = val >> 8;
619 ice->akm[0].images[reg + 1] = val;
624 static int aureon_mono_bool_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
626 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
628 uinfo->value.integer.min = 0;
629 uinfo->value.integer.max = 1;
634 * AC'97 master playback mute controls (Mute on WM8770 chip)
636 #define aureon_ac97_mmute_info aureon_mono_bool_info
638 static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
640 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
642 mutex_lock(&ice->gpio_mutex);
644 ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
646 mutex_unlock(&ice->gpio_mutex);
650 static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
651 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
652 unsigned short ovol, nvol;
655 snd_ice1712_save_gpio_status(ice);
657 ovol = wm_get(ice, WM_OUT_MUX1);
658 nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00);
659 if ((change = (ovol != nvol)))
660 wm_put(ice, WM_OUT_MUX1, nvol);
662 snd_ice1712_restore_gpio_status(ice);
667 static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
668 static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
669 static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0);
670 static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0);
671 static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0);
674 * Logarithmic volume values for WM8770
675 * Computed as 20 * Log10(255 / x)
677 static const unsigned char wm_vol[256] = {
678 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
679 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
680 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
681 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
682 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
683 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,
684 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,
685 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,
686 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,
687 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,
688 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,
692 #define WM_VOL_MAX (sizeof(wm_vol) - 1)
693 #define WM_VOL_MUTE 0x8000
695 static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
699 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
702 nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
704 wm_put(ice, index, nvol);
705 wm_put_nocache(ice, index, 0x180 | nvol);
711 #define wm_pcm_mute_info aureon_mono_bool_info
713 static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
715 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
717 mutex_lock(&ice->gpio_mutex);
718 ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
719 mutex_unlock(&ice->gpio_mutex);
723 static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
725 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
726 unsigned short nval, oval;
729 snd_ice1712_save_gpio_status(ice);
730 oval = wm_get(ice, WM_MUTE);
731 nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
732 if ((change = (nval != oval)))
733 wm_put(ice, WM_MUTE, nval);
734 snd_ice1712_restore_gpio_status(ice);
740 * Master volume attenuation mixer control
742 static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
744 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
746 uinfo->value.integer.min = 0;
747 uinfo->value.integer.max = WM_VOL_MAX;
751 static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
753 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
756 ucontrol->value.integer.value[i] = ice->spec.aureon.master[i] & ~WM_VOL_MUTE;
760 static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
762 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
765 snd_ice1712_save_gpio_status(ice);
766 for (ch = 0; ch < 2; ch++) {
767 if (ucontrol->value.integer.value[ch] != ice->spec.aureon.master[ch]) {
769 ice->spec.aureon.master[ch] &= WM_VOL_MUTE;
770 ice->spec.aureon.master[ch] |= ucontrol->value.integer.value[ch];
771 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
772 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
773 ice->spec.aureon.vol[dac + ch],
774 ice->spec.aureon.master[ch]);
778 snd_ice1712_restore_gpio_status(ice);
783 * DAC volume attenuation mixer control
785 static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
787 int voices = kcontrol->private_value >> 8;
788 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
789 uinfo->count = voices;
790 uinfo->value.integer.min = 0; /* mute (-101dB) */
791 uinfo->value.integer.max = 0x7F; /* 0dB */
795 static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
797 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
800 voices = kcontrol->private_value >> 8;
801 ofs = kcontrol->private_value & 0xff;
802 for (i = 0; i < voices; i++)
803 ucontrol->value.integer.value[i] = ice->spec.aureon.vol[ofs+i] & ~WM_VOL_MUTE;
807 static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
809 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
810 int i, idx, ofs, voices;
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 idx = WM_DAC_ATTEN + ofs + i;
818 if (ucontrol->value.integer.value[i] != ice->spec.aureon.vol[ofs+i]) {
819 ice->spec.aureon.vol[ofs+i] &= WM_VOL_MUTE;
820 ice->spec.aureon.vol[ofs+i] |= ucontrol->value.integer.value[i];
821 wm_set_vol(ice, idx, ice->spec.aureon.vol[ofs+i],
822 ice->spec.aureon.master[i]);
826 snd_ice1712_restore_gpio_status(ice);
831 * WM8770 mute control
833 static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
834 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
835 uinfo->count = kcontrol->private_value >> 8;
836 uinfo->value.integer.min = 0;
837 uinfo->value.integer.max = 1;
841 static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
843 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
846 voices = kcontrol->private_value >> 8;
847 ofs = kcontrol->private_value & 0xFF;
849 for (i = 0; i < voices; i++)
850 ucontrol->value.integer.value[i] = (ice->spec.aureon.vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
854 static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
856 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
857 int change = 0, voices, ofs, i;
859 voices = kcontrol->private_value >> 8;
860 ofs = kcontrol->private_value & 0xFF;
862 snd_ice1712_save_gpio_status(ice);
863 for (i = 0; i < voices; i++) {
864 int val = (ice->spec.aureon.vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
865 if (ucontrol->value.integer.value[i] != val) {
866 ice->spec.aureon.vol[ofs + i] &= ~WM_VOL_MUTE;
867 ice->spec.aureon.vol[ofs + i] |=
868 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
869 wm_set_vol(ice, ofs + i, ice->spec.aureon.vol[ofs + i],
870 ice->spec.aureon.master[i]);
874 snd_ice1712_restore_gpio_status(ice);
880 * WM8770 master mute control
882 static int wm_master_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
883 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
885 uinfo->value.integer.min = 0;
886 uinfo->value.integer.max = 1;
890 static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
892 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
894 ucontrol->value.integer.value[0] = (ice->spec.aureon.master[0] & WM_VOL_MUTE) ? 0 : 1;
895 ucontrol->value.integer.value[1] = (ice->spec.aureon.master[1] & WM_VOL_MUTE) ? 0 : 1;
899 static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
901 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
904 snd_ice1712_save_gpio_status(ice);
905 for (i = 0; i < 2; i++) {
906 int val = (ice->spec.aureon.master[i] & WM_VOL_MUTE) ? 0 : 1;
907 if (ucontrol->value.integer.value[i] != val) {
909 ice->spec.aureon.master[i] &= ~WM_VOL_MUTE;
910 ice->spec.aureon.master[i] |=
911 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
912 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
913 wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
914 ice->spec.aureon.vol[dac + i],
915 ice->spec.aureon.master[i]);
919 snd_ice1712_restore_gpio_status(ice);
924 /* digital master volume */
926 #define PCM_RES 128 /* -64dB */
927 #define PCM_MIN (PCM_0dB - PCM_RES)
928 static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
930 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
932 uinfo->value.integer.min = 0; /* mute (-64dB) */
933 uinfo->value.integer.max = PCM_RES; /* 0dB */
937 static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
939 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
942 mutex_lock(&ice->gpio_mutex);
943 val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
944 val = val > PCM_MIN ? (val - PCM_MIN) : 0;
945 ucontrol->value.integer.value[0] = val;
946 mutex_unlock(&ice->gpio_mutex);
950 static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
952 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
953 unsigned short ovol, nvol;
956 snd_ice1712_save_gpio_status(ice);
957 nvol = ucontrol->value.integer.value[0];
958 nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
959 ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
961 wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
962 wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
965 snd_ice1712_restore_gpio_status(ice);
972 static int wm_adc_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
974 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
976 uinfo->value.integer.min = 0;
977 uinfo->value.integer.max = 1;
981 static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
983 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
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;
992 mutex_unlock(&ice->gpio_mutex);
996 static int wm_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
998 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
999 unsigned short new, old;
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);
1007 wm_put(ice, WM_ADC_GAIN + i, new);
1011 snd_ice1712_restore_gpio_status(ice);
1017 * ADC gain mixer control
1019 static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1021 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1023 uinfo->value.integer.min = 0; /* -12dB */
1024 uinfo->value.integer.max = 0x1f; /* 19dB */
1028 static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1030 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
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;
1040 mutex_unlock(&ice->gpio_mutex);
1044 static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1046 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1048 unsigned short ovol, nvol;
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];
1055 ovol = wm_get(ice, idx);
1056 if ((ovol & 0x1f) != nvol) {
1057 wm_put(ice, idx, nvol | (ovol & ~0x1f));
1061 snd_ice1712_restore_gpio_status(ice);
1066 * ADC input mux mixer control
1068 static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1070 static const char * const texts[] = {
1077 static const char * const universe_texts[] = {
1087 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1089 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1091 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1092 uinfo->value.enumerated.items = 8;
1093 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1094 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1095 strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]);
1098 uinfo->value.enumerated.items = 5;
1099 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1100 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1101 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1106 static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1108 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1111 mutex_lock(&ice->gpio_mutex);
1112 val = wm_get(ice, WM_ADC_MUX);
1113 ucontrol->value.enumerated.item[0] = val & 7;
1114 ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
1115 mutex_unlock(&ice->gpio_mutex);
1119 static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1121 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1122 unsigned short oval, nval;
1125 snd_ice1712_save_gpio_status(ice);
1126 oval = wm_get(ice, WM_ADC_MUX);
1127 nval = oval & ~0x77;
1128 nval |= ucontrol->value.enumerated.item[0] & 7;
1129 nval |= (ucontrol->value.enumerated.item[1] & 7) << 4;
1130 change = (oval != nval);
1132 wm_put(ice, WM_ADC_MUX, nval);
1133 snd_ice1712_restore_gpio_status(ice);
1140 static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1142 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1143 static const char * const aureon_texts[] = {
1147 static const char * const prodigy_texts[] = {
1151 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1153 uinfo->value.enumerated.items = 2;
1154 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1155 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1156 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
1157 strcpy(uinfo->value.enumerated.name, prodigy_texts[uinfo->value.enumerated.item]);
1159 strcpy(uinfo->value.enumerated.name, aureon_texts[uinfo->value.enumerated.item]);
1163 static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1165 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1167 //snd_ice1712_save_gpio_status(ice);
1168 //val = aureon_cs8415_get(ice, CS8415_CTRL2);
1169 ucontrol->value.enumerated.item[0] = ice->spec.aureon.cs8415_mux;
1170 //snd_ice1712_restore_gpio_status(ice);
1174 static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1176 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1177 unsigned short oval, nval;
1180 snd_ice1712_save_gpio_status(ice);
1181 oval = aureon_cs8415_get(ice, CS8415_CTRL2);
1182 nval = oval & ~0x07;
1183 nval |= ucontrol->value.enumerated.item[0] & 7;
1184 change = (oval != nval);
1186 aureon_cs8415_put(ice, CS8415_CTRL2, nval);
1187 snd_ice1712_restore_gpio_status(ice);
1188 ice->spec.aureon.cs8415_mux = ucontrol->value.enumerated.item[0];
1192 static int aureon_cs8415_rate_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1194 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1196 uinfo->value.integer.min = 0;
1197 uinfo->value.integer.max = 192000;
1201 static int aureon_cs8415_rate_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1203 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1204 unsigned char ratio;
1205 ratio = aureon_cs8415_get(ice, CS8415_RATIO);
1206 ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750);
1213 static int aureon_cs8415_mute_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1215 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1220 static int aureon_cs8415_mute_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1222 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1223 snd_ice1712_save_gpio_status(ice);
1224 ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1;
1225 snd_ice1712_restore_gpio_status(ice);
1229 static int aureon_cs8415_mute_put (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1231 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1232 unsigned char oval, nval;
1234 snd_ice1712_save_gpio_status(ice);
1235 oval = aureon_cs8415_get(ice, CS8415_CTRL1);
1236 if (ucontrol->value.integer.value[0])
1237 nval = oval & ~0x20;
1240 if ((change = (oval != nval)))
1241 aureon_cs8415_put(ice, CS8415_CTRL1, nval);
1242 snd_ice1712_restore_gpio_status(ice);
1247 * CS8415A Q-Sub info
1249 static int aureon_cs8415_qsub_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
1250 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1255 static int aureon_cs8415_qsub_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
1256 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1258 snd_ice1712_save_gpio_status(ice);
1259 aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
1260 snd_ice1712_restore_gpio_status(ice);
1265 static int aureon_cs8415_spdif_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
1266 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1271 static int aureon_cs8415_mask_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
1272 memset(ucontrol->value.iec958.status, 0xFF, 24);
1276 static int aureon_cs8415_spdif_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
1277 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1279 snd_ice1712_save_gpio_status(ice);
1280 aureon_cs8415_read(ice, CS8415_C_BUFFER, ucontrol->value.iec958.status, 24);
1281 snd_ice1712_restore_gpio_status(ice);
1286 * Headphone Amplifier
1288 static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
1290 unsigned int tmp, tmp2;
1292 tmp2 = tmp = snd_ice1712_gpio_read(ice);
1294 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1295 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1296 tmp |= AUREON_HP_SEL;
1298 tmp |= PRODIGY_HP_SEL;
1300 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1301 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1302 tmp &= ~ AUREON_HP_SEL;
1304 tmp &= ~ PRODIGY_HP_SEL;
1306 snd_ice1712_gpio_write(ice, tmp);
1312 static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
1314 unsigned int tmp = snd_ice1712_gpio_read(ice);
1316 return ( tmp & AUREON_HP_SEL )!= 0;
1319 #define aureon_hpamp_info aureon_mono_bool_info
1321 static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1323 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1325 ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
1330 static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1332 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1334 return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]);
1341 #define aureon_deemp_info aureon_mono_bool_info
1343 static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1345 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1346 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
1350 static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1352 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1354 temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
1355 if (ucontrol->value.integer.value[0])
1359 if (temp != temp2) {
1360 wm_put(ice, WM_DAC_CTRL2, temp);
1369 static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
1371 static const char * const texts[2] = { "128x", "64x" };
1373 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1375 uinfo->value.enumerated.items = 2;
1377 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1378 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1379 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1384 static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1386 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1387 ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
1391 static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1394 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1396 temp2 = temp = wm_get(ice, WM_MASTER);
1398 if (ucontrol->value.enumerated.item[0])
1403 if (temp != temp2) {
1404 wm_put(ice, WM_MASTER, temp);
1414 static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
1416 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1417 .name = "Master Playback Switch",
1418 .info = wm_master_mute_info,
1419 .get = wm_master_mute_get,
1420 .put = wm_master_mute_put
1423 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1424 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1425 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1426 .name = "Master Playback Volume",
1427 .info = wm_master_vol_info,
1428 .get = wm_master_vol_get,
1429 .put = wm_master_vol_put,
1430 .tlv = { .p = db_scale_wm_dac }
1433 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1434 .name = "Front Playback Switch",
1435 .info = wm_mute_info,
1438 .private_value = (2 << 8) | 0
1441 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1442 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1443 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1444 .name = "Front Playback Volume",
1445 .info = wm_vol_info,
1448 .private_value = (2 << 8) | 0,
1449 .tlv = { .p = db_scale_wm_dac }
1452 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1453 .name = "Rear Playback Switch",
1454 .info = wm_mute_info,
1457 .private_value = (2 << 8) | 2
1460 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1461 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1462 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1463 .name = "Rear Playback Volume",
1464 .info = wm_vol_info,
1467 .private_value = (2 << 8) | 2,
1468 .tlv = { .p = db_scale_wm_dac }
1471 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1472 .name = "Center Playback Switch",
1473 .info = wm_mute_info,
1476 .private_value = (1 << 8) | 4
1479 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1480 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1481 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1482 .name = "Center Playback Volume",
1483 .info = wm_vol_info,
1486 .private_value = (1 << 8) | 4,
1487 .tlv = { .p = db_scale_wm_dac }
1490 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1491 .name = "LFE Playback Switch",
1492 .info = wm_mute_info,
1495 .private_value = (1 << 8) | 5
1498 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1499 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1500 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1501 .name = "LFE Playback Volume",
1502 .info = wm_vol_info,
1505 .private_value = (1 << 8) | 5,
1506 .tlv = { .p = db_scale_wm_dac }
1509 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1510 .name = "Side Playback Switch",
1511 .info = wm_mute_info,
1514 .private_value = (2 << 8) | 6
1517 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1518 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1519 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1520 .name = "Side Playback Volume",
1521 .info = wm_vol_info,
1524 .private_value = (2 << 8) | 6,
1525 .tlv = { .p = db_scale_wm_dac }
1529 static const struct snd_kcontrol_new wm_controls[] __devinitdata = {
1531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1532 .name = "PCM Playback Switch",
1533 .info = wm_pcm_mute_info,
1534 .get = wm_pcm_mute_get,
1535 .put = wm_pcm_mute_put
1538 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1539 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1540 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1541 .name = "PCM Playback Volume",
1542 .info = wm_pcm_vol_info,
1543 .get = wm_pcm_vol_get,
1544 .put = wm_pcm_vol_put,
1545 .tlv = { .p = db_scale_wm_pcm }
1548 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1549 .name = "Capture Switch",
1550 .info = wm_adc_mute_info,
1551 .get = wm_adc_mute_get,
1552 .put = wm_adc_mute_put,
1555 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1556 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1557 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1558 .name = "Capture Volume",
1559 .info = wm_adc_vol_info,
1560 .get = wm_adc_vol_get,
1561 .put = wm_adc_vol_put,
1562 .tlv = { .p = db_scale_wm_adc }
1565 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1566 .name = "Capture Source",
1567 .info = wm_adc_mux_info,
1568 .get = wm_adc_mux_get,
1569 .put = wm_adc_mux_put,
1573 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1574 .name = "External Amplifier",
1575 .info = aureon_hpamp_info,
1576 .get = aureon_hpamp_get,
1577 .put = aureon_hpamp_put
1580 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1581 .name = "DAC Deemphasis Switch",
1582 .info = aureon_deemp_info,
1583 .get = aureon_deemp_get,
1584 .put = aureon_deemp_put
1587 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1588 .name = "ADC Oversampling",
1589 .info = aureon_oversampling_info,
1590 .get = aureon_oversampling_get,
1591 .put = aureon_oversampling_put
1595 static const struct snd_kcontrol_new ac97_controls[] __devinitdata = {
1597 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1598 .name = "AC97 Playback Switch",
1599 .info = aureon_ac97_mmute_info,
1600 .get = aureon_ac97_mmute_get,
1601 .put = aureon_ac97_mmute_put,
1602 .private_value = AC97_MASTER
1605 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1606 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1607 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1608 .name = "AC97 Playback Volume",
1609 .info = aureon_ac97_vol_info,
1610 .get = aureon_ac97_vol_get,
1611 .put = aureon_ac97_vol_put,
1612 .private_value = AC97_MASTER|AUREON_AC97_STEREO,
1613 .tlv = { .p = db_scale_ac97_master }
1616 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1617 .name = "CD Playback Switch",
1618 .info = aureon_ac97_mute_info,
1619 .get = aureon_ac97_mute_get,
1620 .put = aureon_ac97_mute_put,
1621 .private_value = AC97_CD
1624 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1625 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1626 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1627 .name = "CD Playback Volume",
1628 .info = aureon_ac97_vol_info,
1629 .get = aureon_ac97_vol_get,
1630 .put = aureon_ac97_vol_put,
1631 .private_value = AC97_CD|AUREON_AC97_STEREO,
1632 .tlv = { .p = db_scale_ac97_gain }
1635 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1636 .name = "Aux Playback Switch",
1637 .info = aureon_ac97_mute_info,
1638 .get = aureon_ac97_mute_get,
1639 .put = aureon_ac97_mute_put,
1640 .private_value = AC97_AUX,
1643 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1644 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1645 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1646 .name = "Aux Playback Volume",
1647 .info = aureon_ac97_vol_info,
1648 .get = aureon_ac97_vol_get,
1649 .put = aureon_ac97_vol_put,
1650 .private_value = AC97_AUX|AUREON_AC97_STEREO,
1651 .tlv = { .p = db_scale_ac97_gain }
1654 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1655 .name = "Line Playback Switch",
1656 .info = aureon_ac97_mute_info,
1657 .get = aureon_ac97_mute_get,
1658 .put = aureon_ac97_mute_put,
1659 .private_value = AC97_LINE
1662 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1663 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1664 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1665 .name = "Line Playback Volume",
1666 .info = aureon_ac97_vol_info,
1667 .get = aureon_ac97_vol_get,
1668 .put = aureon_ac97_vol_put,
1669 .private_value = AC97_LINE|AUREON_AC97_STEREO,
1670 .tlv = { .p = db_scale_ac97_gain }
1673 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1674 .name = "Mic Playback Switch",
1675 .info = aureon_ac97_mute_info,
1676 .get = aureon_ac97_mute_get,
1677 .put = aureon_ac97_mute_put,
1678 .private_value = AC97_MIC
1681 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1682 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1683 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1684 .name = "Mic Playback Volume",
1685 .info = aureon_ac97_vol_info,
1686 .get = aureon_ac97_vol_get,
1687 .put = aureon_ac97_vol_put,
1688 .private_value = AC97_MIC,
1689 .tlv = { .p = db_scale_ac97_gain }
1692 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1693 .name = "Mic Boost (+20dB)",
1694 .info = aureon_ac97_micboost_info,
1695 .get = aureon_ac97_micboost_get,
1696 .put = aureon_ac97_micboost_put
1700 static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
1702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1703 .name = "AC97 Playback Switch",
1704 .info = aureon_ac97_mmute_info,
1705 .get = aureon_ac97_mmute_get,
1706 .put = aureon_ac97_mmute_put,
1707 .private_value = AC97_MASTER
1710 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1711 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1712 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1713 .name = "AC97 Playback Volume",
1714 .info = aureon_ac97_vol_info,
1715 .get = aureon_ac97_vol_get,
1716 .put = aureon_ac97_vol_put,
1717 .private_value = AC97_MASTER|AUREON_AC97_STEREO,
1718 .tlv = { .p = db_scale_ac97_master }
1721 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1722 .name = "CD Playback Switch",
1723 .info = aureon_ac97_mute_info,
1724 .get = aureon_ac97_mute_get,
1725 .put = aureon_ac97_mute_put,
1726 .private_value = AC97_AUX
1729 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1730 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1731 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1732 .name = "CD Playback Volume",
1733 .info = aureon_ac97_vol_info,
1734 .get = aureon_ac97_vol_get,
1735 .put = aureon_ac97_vol_put,
1736 .private_value = AC97_AUX|AUREON_AC97_STEREO,
1737 .tlv = { .p = db_scale_ac97_gain }
1740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1741 .name = "Phono Playback Switch",
1742 .info = aureon_ac97_mute_info,
1743 .get = aureon_ac97_mute_get,
1744 .put = aureon_ac97_mute_put,
1745 .private_value = AC97_CD
1748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1749 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1750 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1751 .name = "Phono Playback Volume",
1752 .info = aureon_ac97_vol_info,
1753 .get = aureon_ac97_vol_get,
1754 .put = aureon_ac97_vol_put,
1755 .private_value = AC97_CD|AUREON_AC97_STEREO,
1756 .tlv = { .p = db_scale_ac97_gain }
1759 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1760 .name = "Line Playback Switch",
1761 .info = aureon_ac97_mute_info,
1762 .get = aureon_ac97_mute_get,
1763 .put = aureon_ac97_mute_put,
1764 .private_value = AC97_LINE
1767 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1768 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1769 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1770 .name = "Line Playback Volume",
1771 .info = aureon_ac97_vol_info,
1772 .get = aureon_ac97_vol_get,
1773 .put = aureon_ac97_vol_put,
1774 .private_value = AC97_LINE|AUREON_AC97_STEREO,
1775 .tlv = { .p = db_scale_ac97_gain }
1778 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1779 .name = "Mic Playback Switch",
1780 .info = aureon_ac97_mute_info,
1781 .get = aureon_ac97_mute_get,
1782 .put = aureon_ac97_mute_put,
1783 .private_value = AC97_MIC
1786 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1787 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1788 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1789 .name = "Mic Playback Volume",
1790 .info = aureon_ac97_vol_info,
1791 .get = aureon_ac97_vol_get,
1792 .put = aureon_ac97_vol_put,
1793 .private_value = AC97_MIC,
1794 .tlv = { .p = db_scale_ac97_gain }
1797 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1798 .name = "Mic Boost (+20dB)",
1799 .info = aureon_ac97_micboost_info,
1800 .get = aureon_ac97_micboost_get,
1801 .put = aureon_ac97_micboost_put
1804 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1805 .name = "Aux Playback Switch",
1806 .info = aureon_ac97_mute_info,
1807 .get = aureon_ac97_mute_get,
1808 .put = aureon_ac97_mute_put,
1809 .private_value = AC97_VIDEO,
1812 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1813 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1814 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1815 .name = "Aux Playback Volume",
1816 .info = aureon_ac97_vol_info,
1817 .get = aureon_ac97_vol_get,
1818 .put = aureon_ac97_vol_put,
1819 .private_value = AC97_VIDEO|AUREON_AC97_STEREO,
1820 .tlv = { .p = db_scale_ac97_gain }
1823 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1824 .name = "Aux Source",
1825 .info = aureon_universe_inmux_info,
1826 .get = aureon_universe_inmux_get,
1827 .put = aureon_universe_inmux_put
1832 static const struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
1834 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1835 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
1836 .info = aureon_cs8415_mute_info,
1837 .get = aureon_cs8415_mute_get,
1838 .put = aureon_cs8415_mute_put
1841 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1842 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Source",
1843 .info = aureon_cs8415_mux_info,
1844 .get = aureon_cs8415_mux_get,
1845 .put = aureon_cs8415_mux_put,
1848 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1849 .name = SNDRV_CTL_NAME_IEC958("Q-subcode ",CAPTURE,DEFAULT),
1850 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1851 .info = aureon_cs8415_qsub_info,
1852 .get = aureon_cs8415_qsub_get,
1855 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1856 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
1857 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1858 .info = aureon_cs8415_spdif_info,
1859 .get = aureon_cs8415_mask_get
1862 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1863 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
1864 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1865 .info = aureon_cs8415_spdif_info,
1866 .get = aureon_cs8415_spdif_get
1869 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1870 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Rate",
1871 .access =SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1872 .info = aureon_cs8415_rate_info,
1873 .get = aureon_cs8415_rate_get
1877 static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1879 unsigned int i, counts;
1882 counts = ARRAY_SIZE(aureon_dac_controls);
1883 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
1884 counts -= 2; /* no side */
1885 for (i = 0; i < counts; i++) {
1886 err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
1891 for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
1892 err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
1897 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1898 for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
1899 err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
1904 else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1905 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1906 for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
1907 err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
1913 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1914 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1916 snd_ice1712_save_gpio_status(ice);
1917 id = aureon_cs8415_get(ice, CS8415_ID);
1919 snd_printk(KERN_INFO "No CS8415 chip. Skipping CS8415 controls.\n");
1920 else if ((id & 0x0F) != 0x01)
1921 snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
1923 for (i = 0; i< ARRAY_SIZE(cs8415_controls); i++) {
1924 struct snd_kcontrol *kctl;
1925 err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
1929 kctl->id.device = ice->pcm->device;
1932 snd_ice1712_restore_gpio_status(ice);
1940 * initialize the chip
1942 static int __devinit aureon_init(struct snd_ice1712 *ice)
1944 static const unsigned short wm_inits_aureon[] = {
1945 /* These come first to reduce init pop noise */
1946 0x1b, 0x044, /* ADC Mux (AC'97 source) */
1947 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
1948 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
1950 0x18, 0x000, /* All power-up */
1952 0x16, 0x122, /* I2S, normal polarity, 24bit */
1953 0x17, 0x022, /* 256fs, slave mode */
1954 0x00, 0, /* DAC1 analog mute */
1955 0x01, 0, /* DAC2 analog mute */
1956 0x02, 0, /* DAC3 analog mute */
1957 0x03, 0, /* DAC4 analog mute */
1958 0x04, 0, /* DAC5 analog mute */
1959 0x05, 0, /* DAC6 analog mute */
1960 0x06, 0, /* DAC7 analog mute */
1961 0x07, 0, /* DAC8 analog mute */
1962 0x08, 0x100, /* master analog mute */
1963 0x09, 0xff, /* DAC1 digital full */
1964 0x0a, 0xff, /* DAC2 digital full */
1965 0x0b, 0xff, /* DAC3 digital full */
1966 0x0c, 0xff, /* DAC4 digital full */
1967 0x0d, 0xff, /* DAC5 digital full */
1968 0x0e, 0xff, /* DAC6 digital full */
1969 0x0f, 0xff, /* DAC7 digital full */
1970 0x10, 0xff, /* DAC8 digital full */
1971 0x11, 0x1ff, /* master digital full */
1972 0x12, 0x000, /* phase normal */
1973 0x13, 0x090, /* unmute DAC L/R */
1974 0x14, 0x000, /* all unmute */
1975 0x15, 0x000, /* no deemphasis, no ZFLG */
1976 0x19, 0x000, /* -12dB ADC/L */
1977 0x1a, 0x000, /* -12dB ADC/R */
1980 static const unsigned short wm_inits_prodigy[] = {
1982 /* These come first to reduce init pop noise */
1983 0x1b, 0x000, /* ADC Mux */
1984 0x1c, 0x009, /* Out Mux1 */
1985 0x1d, 0x009, /* Out Mux2 */
1987 0x18, 0x000, /* All power-up */
1989 0x16, 0x022, /* I2S, normal polarity, 24bit, high-pass on */
1990 0x17, 0x006, /* 128fs, slave mode */
1992 0x00, 0, /* DAC1 analog mute */
1993 0x01, 0, /* DAC2 analog mute */
1994 0x02, 0, /* DAC3 analog mute */
1995 0x03, 0, /* DAC4 analog mute */
1996 0x04, 0, /* DAC5 analog mute */
1997 0x05, 0, /* DAC6 analog mute */
1998 0x06, 0, /* DAC7 analog mute */
1999 0x07, 0, /* DAC8 analog mute */
2000 0x08, 0x100, /* master analog mute */
2002 0x09, 0x7f, /* DAC1 digital full */
2003 0x0a, 0x7f, /* DAC2 digital full */
2004 0x0b, 0x7f, /* DAC3 digital full */
2005 0x0c, 0x7f, /* DAC4 digital full */
2006 0x0d, 0x7f, /* DAC5 digital full */
2007 0x0e, 0x7f, /* DAC6 digital full */
2008 0x0f, 0x7f, /* DAC7 digital full */
2009 0x10, 0x7f, /* DAC8 digital full */
2010 0x11, 0x1FF, /* master digital full */
2012 0x12, 0x000, /* phase normal */
2013 0x13, 0x090, /* unmute DAC L/R */
2014 0x14, 0x000, /* all unmute */
2015 0x15, 0x000, /* no deemphasis, no ZFLG */
2017 0x19, 0x000, /* -12dB ADC/L */
2018 0x1a, 0x000, /* -12dB ADC/R */
2022 static const unsigned short cs_inits[] = {
2024 0x0180, /* no mute, OMCK output on RMCK pin */
2025 0x0201, /* S/PDIF source on RXP1 */
2026 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
2030 const unsigned short *p;
2033 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
2034 ice->num_total_dacs = 6;
2035 ice->num_total_adcs = 2;
2037 /* aureon 7.1 and prodigy 7.1 */
2038 ice->num_total_dacs = 8;
2039 ice->num_total_adcs = 2;
2042 /* to remeber the register values of CS8415 */
2043 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2046 ice->akm_codecs = 1;
2048 if ((err = aureon_ac97_init(ice)) != 0)
2051 snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
2053 /* reset the wm codec as the SPI mode */
2054 snd_ice1712_save_gpio_status(ice);
2055 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
2057 tmp = snd_ice1712_gpio_read(ice);
2058 tmp &= ~AUREON_WM_RESET;
2059 snd_ice1712_gpio_write(ice, tmp);
2061 tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
2062 snd_ice1712_gpio_write(ice, tmp);
2064 tmp |= AUREON_WM_RESET;
2065 snd_ice1712_gpio_write(ice, tmp);
2068 /* initialize WM8770 codec */
2069 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
2070 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
2071 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT)
2072 p = wm_inits_prodigy;
2074 p = wm_inits_aureon;
2075 for (; *p != (unsigned short)-1; p += 2)
2076 wm_put(ice, p[0], p[1]);
2078 /* initialize CS8415A codec */
2079 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
2080 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
2081 for (p = cs_inits; *p != (unsigned short)-1; p++)
2082 aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
2083 ice->spec.aureon.cs8415_mux = 1;
2085 aureon_set_headphone_amp(ice, 1);
2088 snd_ice1712_restore_gpio_status(ice);
2090 /* initialize PCA9554 pin directions & set default input*/
2091 aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2092 aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */
2094 ice->spec.aureon.master[0] = WM_VOL_MUTE;
2095 ice->spec.aureon.master[1] = WM_VOL_MUTE;
2096 for (i = 0; i < ice->num_total_dacs; i++) {
2097 ice->spec.aureon.vol[i] = WM_VOL_MUTE;
2098 wm_set_vol(ice, i, ice->spec.aureon.vol[i], ice->spec.aureon.master[i % 2]);
2106 * Aureon boards don't provide the EEPROM data except for the vendor IDs.
2107 * hence the driver needs to sets up it properly.
2110 static const unsigned char aureon51_eeprom[] __devinitdata = {
2111 [ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */
2112 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2113 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2114 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2115 [ICE_EEP2_GPIO_DIR] = 0xff,
2116 [ICE_EEP2_GPIO_DIR1] = 0xff,
2117 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2118 [ICE_EEP2_GPIO_MASK] = 0x00,
2119 [ICE_EEP2_GPIO_MASK1] = 0x00,
2120 [ICE_EEP2_GPIO_MASK2] = 0x00,
2121 [ICE_EEP2_GPIO_STATE] = 0x00,
2122 [ICE_EEP2_GPIO_STATE1] = 0x00,
2123 [ICE_EEP2_GPIO_STATE2] = 0x00,
2126 static const unsigned char aureon71_eeprom[] __devinitdata = {
2127 [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */
2128 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2129 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2130 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2131 [ICE_EEP2_GPIO_DIR] = 0xff,
2132 [ICE_EEP2_GPIO_DIR1] = 0xff,
2133 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2134 [ICE_EEP2_GPIO_MASK] = 0x00,
2135 [ICE_EEP2_GPIO_MASK1] = 0x00,
2136 [ICE_EEP2_GPIO_MASK2] = 0x00,
2137 [ICE_EEP2_GPIO_STATE] = 0x00,
2138 [ICE_EEP2_GPIO_STATE1] = 0x00,
2139 [ICE_EEP2_GPIO_STATE2] = 0x00,
2141 #define prodigy71_eeprom aureon71_eeprom
2143 static const unsigned char prodigy71lt_eeprom[] __devinitdata = {
2144 [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */
2145 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2146 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2147 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2148 [ICE_EEP2_GPIO_DIR] = 0xff,
2149 [ICE_EEP2_GPIO_DIR1] = 0xff,
2150 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2151 [ICE_EEP2_GPIO_MASK] = 0x00,
2152 [ICE_EEP2_GPIO_MASK1] = 0x00,
2153 [ICE_EEP2_GPIO_MASK2] = 0x00,
2154 [ICE_EEP2_GPIO_STATE] = 0x00,
2155 [ICE_EEP2_GPIO_STATE1] = 0x00,
2156 [ICE_EEP2_GPIO_STATE2] = 0x00,
2158 #define prodigy71xt_eeprom prodigy71lt_eeprom
2161 const struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
2163 .subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
2164 .name = "Terratec Aureon 5.1-Sky",
2165 .model = "aureon51",
2166 .chip_init = aureon_init,
2167 .build_controls = aureon_add_controls,
2168 .eeprom_size = sizeof(aureon51_eeprom),
2169 .eeprom_data = aureon51_eeprom,
2170 .driver = "Aureon51",
2173 .subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
2174 .name = "Terratec Aureon 7.1-Space",
2175 .model = "aureon71",
2176 .chip_init = aureon_init,
2177 .build_controls = aureon_add_controls,
2178 .eeprom_size = sizeof(aureon71_eeprom),
2179 .eeprom_data = aureon71_eeprom,
2180 .driver = "Aureon71",
2183 .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
2184 .name = "Terratec Aureon 7.1-Universe",
2185 .model = "universe",
2186 .chip_init = aureon_init,
2187 .build_controls = aureon_add_controls,
2188 .eeprom_size = sizeof(aureon71_eeprom),
2189 .eeprom_data = aureon71_eeprom,
2190 .driver = "Aureon71Univ", /* keep in 15 letters */
2193 .subvendor = VT1724_SUBDEVICE_PRODIGY71,
2194 .name = "Audiotrak Prodigy 7.1",
2195 .model = "prodigy71",
2196 .chip_init = aureon_init,
2197 .build_controls = aureon_add_controls,
2198 .eeprom_size = sizeof(prodigy71_eeprom),
2199 .eeprom_data = prodigy71_eeprom,
2200 .driver = "Prodigy71", /* should be identical with Aureon71 */
2203 .subvendor = VT1724_SUBDEVICE_PRODIGY71LT,
2204 .name = "Audiotrak Prodigy 7.1 LT",
2205 .model = "prodigy71lt",
2206 .chip_init = aureon_init,
2207 .build_controls = aureon_add_controls,
2208 .eeprom_size = sizeof(prodigy71lt_eeprom),
2209 .eeprom_data = prodigy71lt_eeprom,
2210 .driver = "Prodigy71LT",
2213 .subvendor = VT1724_SUBDEVICE_PRODIGY71XT,
2214 .name = "Audiotrak Prodigy 7.1 XT",
2215 .model = "prodigy71xt",
2216 .chip_init = aureon_init,
2217 .build_controls = aureon_add_controls,
2218 .eeprom_size = sizeof(prodigy71xt_eeprom),
2219 .eeprom_data = prodigy71xt_eeprom,
2220 .driver = "Prodigy71LT",
2222 { } /* terminator */