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 akm4xxx_t 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 * - writing over SPI is implemented but reading is not yet.
31 * the SPDIF-in channel status, etc. can be read from CS chip.
33 * - DAC digital volumes are not implemented in the mixer.
34 * if they show better response than DAC analog volumes, we can use them
37 * - Aureon boards are equipped with AC97 codec, too. it's used to do
38 * the analog mixing but not easily controllable (it's not connected
39 * directly from envy24ht chip). so let's leave it as it is.
42 * Lowlevel functions for AudioTrak Prodigy 7.1 (and possibly 192) cards
43 * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
45 * version 0.82: Stable / not all features work yet (no communication with AC97 secondary)
46 * added 64x/128x oversampling switch (should be 64x only for 96khz)
47 * fixed some recording labels (still need to check the rest)
48 * recording is working probably thanks to correct wm8770 initialization
50 * version 0.5: Initial release:
51 * working: analog output, mixer, headphone amplifier switch
52 * not working: prety much everything else, at least i could verify that
53 * we have no digital output, no capture, pretty bad clicks and poops
54 * on mixer switch and other coll stuff.
56 * - Prodigy boards are equipped with AC97 STAC9744 chip , too. it's used to do
57 * the analog mixing but not easily controllable (it's not connected
58 * directly from envy24ht chip). so let's leave it as it is.
62 #include <sound/driver.h>
64 #include <linux/delay.h>
65 #include <linux/interrupt.h>
66 #include <linux/init.h>
67 #include <linux/slab.h>
68 #include <sound/core.h>
74 /* WM8770 registers */
75 #define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
76 #define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */
77 #define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */
78 #define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */
79 #define WM_PHASE_SWAP 0x12 /* DAC phase */
80 #define WM_DAC_CTRL1 0x13 /* DAC control bits */
81 #define WM_MUTE 0x14 /* mute controls */
82 #define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */
83 #define WM_INT_CTRL 0x16 /* interface control */
84 #define WM_MASTER 0x17 /* master clock and mode */
85 #define WM_POWERDOWN 0x18 /* power-down controls */
86 #define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */
87 #define WM_ADC_MUX 0x1b /* input MUX */
88 #define WM_OUT_MUX1 0x1c /* output MUX */
89 #define WM_OUT_MUX2 0x1e /* output MUX */
90 #define WM_RESET 0x1f /* software reset */
92 static void aureon_ac97_write(ice1712_t *ice, unsigned short reg, unsigned short val) {
95 /* Send address to XILINX chip */
96 tmp = (snd_ice1712_gpio_read(ice) & ~0xFF) | (reg & 0x7F);
97 snd_ice1712_gpio_write(ice, tmp);
99 tmp |= AUREON_AC97_ADDR;
100 snd_ice1712_gpio_write(ice, tmp);
102 tmp &= ~AUREON_AC97_ADDR;
103 snd_ice1712_gpio_write(ice, tmp);
106 /* Send low-order byte to XILINX chip */
107 tmp &= ~AUREON_AC97_DATA_MASK;
108 tmp |= val & AUREON_AC97_DATA_MASK;
109 snd_ice1712_gpio_write(ice, tmp);
111 tmp |= AUREON_AC97_DATA_LOW;
112 snd_ice1712_gpio_write(ice, tmp);
114 tmp &= ~AUREON_AC97_DATA_LOW;
115 snd_ice1712_gpio_write(ice, tmp);
118 /* Send high-order byte to XILINX chip */
119 tmp &= ~AUREON_AC97_DATA_MASK;
120 tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
122 snd_ice1712_gpio_write(ice, tmp);
124 tmp |= AUREON_AC97_DATA_HIGH;
125 snd_ice1712_gpio_write(ice, tmp);
127 tmp &= ~AUREON_AC97_DATA_HIGH;
128 snd_ice1712_gpio_write(ice, tmp);
131 /* Instruct XILINX chip to parse the data to the STAC9744 chip */
132 tmp |= AUREON_AC97_COMMIT;
133 snd_ice1712_gpio_write(ice, tmp);
135 tmp &= ~AUREON_AC97_COMMIT;
136 snd_ice1712_gpio_write(ice, tmp);
139 /* Store the data in out private buffer */
140 ice->spec.aureon.stac9744[(reg & 0x7F) >> 1] = val;
143 static unsigned short aureon_ac97_read(ice1712_t *ice, unsigned short reg)
145 return ice->spec.aureon.stac9744[(reg & 0x7F) >> 1];
149 * Initialize STAC9744 chip
151 static int aureon_ac97_init (ice1712_t *ice) {
153 static unsigned short ac97_defaults[] = {
177 tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
178 snd_ice1712_gpio_write(ice, tmp);
181 tmp &= ~AUREON_AC97_RESET;
182 snd_ice1712_gpio_write(ice, tmp);
185 tmp |= AUREON_AC97_RESET;
186 snd_ice1712_gpio_write(ice, tmp);
189 memset(&ice->spec.aureon.stac9744, 0, sizeof(ice->spec.aureon.stac9744));
190 for (i=0; ac97_defaults[i] != (unsigned short)-1; i+=2)
191 ice->spec.aureon.stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
193 aureon_ac97_write(ice, AC97_MASTER, 0x0000); // Unmute AC'97 master volume permanently - muting is done by WM8770
198 #define AUREON_AC97_STEREO 0x80
201 * AC'97 volume controls
203 static int aureon_ac97_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
205 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
206 uinfo->count = kcontrol->private_value & AUREON_AC97_STEREO ? 2 : 1;
207 uinfo->value.integer.min = 0;
208 uinfo->value.integer.max = 31;
212 static int aureon_ac97_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
214 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
217 down(&ice->gpio_mutex);
219 vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
220 ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F);
221 if (kcontrol->private_value & AUREON_AC97_STEREO)
222 ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F);
224 up(&ice->gpio_mutex);
228 static int aureon_ac97_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
230 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
231 unsigned short ovol, nvol;
234 snd_ice1712_save_gpio_status(ice);
236 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
237 nvol = (0x1F - ucontrol->value.integer.value[0]) & 0x001F;
238 if (kcontrol->private_value & AUREON_AC97_STEREO)
239 nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00;
240 nvol |= ovol & ~0x1F1F;
242 if ((change = (ovol != nvol)))
243 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
245 snd_ice1712_restore_gpio_status(ice);
251 * AC'97 mute controls
253 #define aureon_ac97_mute_info aureon_mono_bool_info
255 static int aureon_ac97_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
257 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
259 down(&ice->gpio_mutex);
261 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
263 up(&ice->gpio_mutex);
267 static int aureon_ac97_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
269 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
270 unsigned short ovol, nvol;
273 snd_ice1712_save_gpio_status(ice);
275 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
276 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~ 0x8000);
278 if ((change = (ovol != nvol)))
279 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
281 snd_ice1712_restore_gpio_status(ice);
287 * AC'97 mute controls
289 #define aureon_ac97_micboost_info aureon_mono_bool_info
291 static int aureon_ac97_micboost_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
293 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
295 down(&ice->gpio_mutex);
297 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
299 up(&ice->gpio_mutex);
303 static int aureon_ac97_micboost_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
305 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
306 unsigned short ovol, nvol;
309 snd_ice1712_save_gpio_status(ice);
311 ovol = aureon_ac97_read(ice, AC97_MIC);
312 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020);
314 if ((change = (ovol != nvol)))
315 aureon_ac97_write(ice, AC97_MIC, nvol);
317 snd_ice1712_restore_gpio_status(ice);
323 * write data in the SPI mode
325 static void aureon_spi_write(ice1712_t *ice, unsigned int cs, unsigned int data, int bits)
331 tmp = snd_ice1712_gpio_read(ice);
333 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
334 cscs = PRODIGY_CS8415_CS;
336 cscs = AUREON_CS8415_CS;
338 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_WM_DATA|AUREON_WM_CLK|
342 snd_ice1712_gpio_write(ice, tmp);
345 for (i = bits - 1; i >= 0; i--) {
346 tmp &= ~AUREON_WM_CLK;
347 snd_ice1712_gpio_write(ice, tmp);
350 tmp |= AUREON_WM_DATA;
352 tmp &= ~AUREON_WM_DATA;
353 snd_ice1712_gpio_write(ice, tmp);
355 tmp |= AUREON_WM_CLK;
356 snd_ice1712_gpio_write(ice, tmp);
360 tmp &= ~AUREON_WM_CLK;
362 snd_ice1712_gpio_write(ice, tmp);
364 tmp |= AUREON_WM_CLK;
365 snd_ice1712_gpio_write(ice, tmp);
371 * get the current register value of WM codec
373 static unsigned short wm_get(ice1712_t *ice, int reg)
376 return ((unsigned short)ice->akm[0].images[reg] << 8) |
377 ice->akm[0].images[reg + 1];
381 * set the register value of WM codec
383 static void wm_put_nocache(ice1712_t *ice, int reg, unsigned short val)
385 aureon_spi_write(ice, AUREON_WM_CS, (reg << 9) | (val & 0x1ff), 16);
389 * set the register value of WM codec and remember it
391 static void wm_put(ice1712_t *ice, int reg, unsigned short val)
393 wm_put_nocache(ice, reg, val);
395 ice->akm[0].images[reg] = val >> 8;
396 ice->akm[0].images[reg + 1] = val;
401 static int aureon_mono_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
403 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
405 uinfo->value.integer.min = 0;
406 uinfo->value.integer.max = 1;
411 * AC'97 master playback mute controls (Mute on WM8770 chip)
413 #define aureon_ac97_mmute_info aureon_mono_bool_info
415 static int aureon_ac97_mmute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
417 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
419 down(&ice->gpio_mutex);
421 ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
423 up(&ice->gpio_mutex);
427 static int aureon_ac97_mmute_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
428 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
429 unsigned short ovol, nvol;
432 snd_ice1712_save_gpio_status(ice);
434 ovol = wm_get(ice, WM_OUT_MUX1);
435 nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00);
436 if ((change = (ovol != nvol)))
437 wm_put(ice, WM_OUT_MUX1, nvol);
439 snd_ice1712_restore_gpio_status(ice);
445 * Logarithmic volume values for WM8770
446 * Computed as 20 * Log10(255 / x)
448 static unsigned char wm_vol[256] = {
449 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
450 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
451 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
452 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
453 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
454 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,
455 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,
456 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,
457 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,
458 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,
459 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,
463 #define WM_VOL_MAX (sizeof(wm_vol) - 1)
464 #define WM_VOL_MUTE 0x8000
466 static void wm_set_vol(ice1712_t *ice, unsigned int index, unsigned short vol, unsigned short master)
470 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
473 nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
475 wm_put(ice, index, nvol);
476 wm_put_nocache(ice, index, 0x180 | nvol);
482 #define wm_pcm_mute_info aureon_mono_bool_info
484 static int wm_pcm_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
486 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
488 down(&ice->gpio_mutex);
489 ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
490 up(&ice->gpio_mutex);
494 static int wm_pcm_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
496 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
497 unsigned short nval, oval;
500 snd_ice1712_save_gpio_status(ice);
501 oval = wm_get(ice, WM_MUTE);
502 nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
503 if ((change = (nval != oval)))
504 wm_put(ice, WM_MUTE, nval);
505 snd_ice1712_restore_gpio_status(ice);
511 * Master volume attenuation mixer control
513 static int wm_master_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
515 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
517 uinfo->value.integer.min = 0;
518 uinfo->value.integer.max = WM_VOL_MAX;
522 static int wm_master_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
524 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
527 ucontrol->value.integer.value[i] = ice->spec.aureon.master[i] & ~WM_VOL_MUTE;
531 static int wm_master_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
533 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
536 snd_ice1712_save_gpio_status(ice);
537 for (ch = 0; ch < 2; ch++) {
538 if (ucontrol->value.integer.value[ch] != ice->spec.aureon.master[ch]) {
540 ice->spec.aureon.master[ch] &= WM_VOL_MUTE;
541 ice->spec.aureon.master[ch] |= ucontrol->value.integer.value[ch];
542 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
543 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
544 ice->spec.aureon.vol[dac + ch],
545 ice->spec.aureon.master[ch]);
549 snd_ice1712_restore_gpio_status(ice);
554 * DAC volume attenuation mixer control
556 static int wm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
558 int voices = kcontrol->private_value >> 8;
559 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
560 uinfo->count = voices;
561 uinfo->value.integer.min = 0; /* mute (-101dB) */
562 uinfo->value.integer.max = 0x7F; /* 0dB */
566 static int wm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
568 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
571 voices = kcontrol->private_value >> 8;
572 ofs = kcontrol->private_value & 0xff;
573 for (i = 0; i < voices; i++)
574 ucontrol->value.integer.value[i] = ice->spec.aureon.vol[ofs+i] & ~WM_VOL_MUTE;
578 static int wm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
580 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
581 int i, idx, ofs, voices;
584 voices = kcontrol->private_value >> 8;
585 ofs = kcontrol->private_value & 0xff;
586 snd_ice1712_save_gpio_status(ice);
587 for (i = 0; i < voices; i++) {
588 idx = WM_DAC_ATTEN + ofs + i;
589 if (ucontrol->value.integer.value[i] != ice->spec.aureon.vol[ofs+i]) {
590 ice->spec.aureon.vol[ofs+i] &= WM_VOL_MUTE;
591 ice->spec.aureon.vol[ofs+i] |= ucontrol->value.integer.value[i];
592 wm_set_vol(ice, idx, ice->spec.aureon.vol[ofs+i],
593 ice->spec.aureon.master[i]);
597 snd_ice1712_restore_gpio_status(ice);
602 * WM8770 mute control
604 static int wm_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
605 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
606 uinfo->count = kcontrol->private_value >> 8;
607 uinfo->value.integer.min = 0;
608 uinfo->value.integer.max = 1;
612 static int wm_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
614 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
617 voices = kcontrol->private_value >> 8;
618 ofs = kcontrol->private_value & 0xFF;
620 for (i = 0; i < voices; i++)
621 ucontrol->value.integer.value[i] = (ice->spec.aureon.vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
625 static int wm_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
627 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
628 int change = 0, voices, ofs, i;
630 voices = kcontrol->private_value >> 8;
631 ofs = kcontrol->private_value & 0xFF;
633 snd_ice1712_save_gpio_status(ice);
634 for (i = 0; i < voices; i++) {
635 int val = (ice->spec.aureon.vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
636 if (ucontrol->value.integer.value[i] != val) {
637 ice->spec.aureon.vol[ofs + i] &= ~WM_VOL_MUTE;
638 ice->spec.aureon.vol[ofs + i] |=
639 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
640 wm_set_vol(ice, ofs + i, ice->spec.aureon.vol[ofs + i],
641 ice->spec.aureon.master[i]);
645 snd_ice1712_restore_gpio_status(ice);
651 * WM8770 master mute control
653 static int wm_master_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
654 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
656 uinfo->value.integer.min = 0;
657 uinfo->value.integer.max = 1;
661 static int wm_master_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
663 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
665 ucontrol->value.integer.value[0] = (ice->spec.aureon.master[0] & WM_VOL_MUTE) ? 0 : 1;
666 ucontrol->value.integer.value[1] = (ice->spec.aureon.master[1] & WM_VOL_MUTE) ? 0 : 1;
670 static int wm_master_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
672 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
675 snd_ice1712_save_gpio_status(ice);
676 for (i = 0; i < 2; i++) {
677 int val = (ice->spec.aureon.master[i] & WM_VOL_MUTE) ? 0 : 1;
678 if (ucontrol->value.integer.value[i] != val) {
680 ice->spec.aureon.master[i] &= ~WM_VOL_MUTE;
681 ice->spec.aureon.master[i] |=
682 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
683 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
684 wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
685 ice->spec.aureon.vol[dac + i],
686 ice->spec.aureon.master[i]);
690 snd_ice1712_restore_gpio_status(ice);
695 /* digital master volume */
697 #define PCM_RES 128 /* -64dB */
698 #define PCM_MIN (PCM_0dB - PCM_RES)
699 static int wm_pcm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
701 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
703 uinfo->value.integer.min = 0; /* mute (-64dB) */
704 uinfo->value.integer.max = PCM_RES; /* 0dB */
708 static int wm_pcm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
710 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
713 down(&ice->gpio_mutex);
714 val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
715 val = val > PCM_MIN ? (val - PCM_MIN) : 0;
716 ucontrol->value.integer.value[0] = val;
717 up(&ice->gpio_mutex);
721 static int wm_pcm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
723 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
724 unsigned short ovol, nvol;
727 snd_ice1712_save_gpio_status(ice);
728 nvol = ucontrol->value.integer.value[0];
729 nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
730 ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
732 wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
733 wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
736 snd_ice1712_restore_gpio_status(ice);
743 static int wm_adc_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
745 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
747 uinfo->value.integer.min = 0;
748 uinfo->value.integer.max = 1;
752 static int wm_adc_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
754 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
758 down(&ice->gpio_mutex);
759 for (i = 0; i < 2; i++) {
760 val = wm_get(ice, WM_ADC_GAIN + i);
761 ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
763 up(&ice->gpio_mutex);
767 static int wm_adc_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
769 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
770 unsigned short new, old;
773 snd_ice1712_save_gpio_status(ice);
774 for (i = 0; i < 2; i++) {
775 old = wm_get(ice, WM_ADC_GAIN + i);
776 new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
778 wm_put(ice, WM_ADC_GAIN + i, new);
782 snd_ice1712_restore_gpio_status(ice);
788 * ADC gain mixer control
790 static int wm_adc_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
792 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
794 uinfo->value.integer.min = 0; /* -12dB */
795 uinfo->value.integer.max = 0x1f; /* 19dB */
799 static int wm_adc_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
801 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
805 down(&ice->gpio_mutex);
806 for (i = 0; i < 2; i++) {
807 idx = WM_ADC_GAIN + i;
808 vol = wm_get(ice, idx) & 0x1f;
809 ucontrol->value.integer.value[i] = vol;
811 up(&ice->gpio_mutex);
815 static int wm_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
817 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
819 unsigned short ovol, nvol;
822 snd_ice1712_save_gpio_status(ice);
823 for (i = 0; i < 2; i++) {
824 idx = WM_ADC_GAIN + i;
825 nvol = ucontrol->value.integer.value[i];
826 ovol = wm_get(ice, idx);
827 if ((ovol & 0x1f) != nvol) {
828 wm_put(ice, idx, nvol | (ovol & ~0x1f));
832 snd_ice1712_restore_gpio_status(ice);
837 * ADC input mux mixer control
839 static int wm_adc_mux_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
841 static char *texts[] = {
848 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
850 uinfo->value.enumerated.items = 5;
851 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
852 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
853 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
857 static int wm_adc_mux_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
859 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
862 down(&ice->gpio_mutex);
863 val = wm_get(ice, WM_ADC_MUX);
864 ucontrol->value.integer.value[0] = val & 7;
865 ucontrol->value.integer.value[1] = (val >> 4) & 7;
866 up(&ice->gpio_mutex);
870 static int wm_adc_mux_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
872 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
873 unsigned short oval, nval;
876 snd_ice1712_save_gpio_status(ice);
877 oval = wm_get(ice, WM_ADC_MUX);
879 nval |= ucontrol->value.integer.value[0] & 7;
880 nval |= (ucontrol->value.integer.value[1] & 7) << 4;
881 change = (oval != nval);
883 wm_put(ice, WM_ADC_MUX, nval);
884 snd_ice1712_restore_gpio_status(ice);
889 * Headphone Amplifier
891 static int aureon_set_headphone_amp(ice1712_t *ice, int enable)
893 unsigned int tmp, tmp2;
895 tmp2 = tmp = snd_ice1712_gpio_read(ice);
897 tmp |= AUREON_HP_SEL;
899 tmp &= ~ AUREON_HP_SEL;
901 snd_ice1712_gpio_write(ice, tmp);
907 static int aureon_get_headphone_amp(ice1712_t *ice)
909 unsigned int tmp = snd_ice1712_gpio_read(ice);
911 return ( tmp & AUREON_HP_SEL )!= 0;
914 #define aureon_hpamp_info aureon_mono_bool_info
916 static int aureon_hpamp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
918 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
920 ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
925 static int aureon_hpamp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
927 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
929 return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]);
936 #define aureon_deemp_info aureon_mono_bool_info
938 static int aureon_deemp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
940 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
941 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
945 static int aureon_deemp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
947 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
949 temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
950 if (ucontrol->value.integer.value[0])
955 wm_put(ice, WM_DAC_CTRL2, temp);
964 static int aureon_oversampling_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
966 static char *texts[2] = { "128x", "64x" };
968 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
970 uinfo->value.enumerated.items = 2;
972 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
973 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
974 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
979 static int aureon_oversampling_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
981 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
982 ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
986 static int aureon_oversampling_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
989 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
991 temp2 = temp = wm_get(ice, WM_MASTER);
993 if (ucontrol->value.enumerated.item[0])
999 wm_put(ice, WM_MASTER, temp);
1009 static snd_kcontrol_new_t aureon_dac_controls[] __devinitdata = {
1011 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1012 .name = "Master Playback Switch",
1013 .info = wm_master_mute_info,
1014 .get = wm_master_mute_get,
1015 .put = wm_master_mute_put
1018 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1019 .name = "Master Playback Volume",
1020 .info = wm_master_vol_info,
1021 .get = wm_master_vol_get,
1022 .put = wm_master_vol_put
1025 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1026 .name = "Front Playback Switch",
1027 .info = wm_mute_info,
1030 .private_value = (2 << 8) | 0
1033 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1034 .name = "Front Playback Volume",
1035 .info = wm_vol_info,
1038 .private_value = (2 << 8) | 0
1041 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1042 .name = "Rear Playback Switch",
1043 .info = wm_mute_info,
1046 .private_value = (2 << 8) | 2
1049 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1050 .name = "Rear Playback Volume",
1051 .info = wm_vol_info,
1054 .private_value = (2 << 8) | 2
1057 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1058 .name = "Center Playback Switch",
1059 .info = wm_mute_info,
1062 .private_value = (1 << 8) | 4
1065 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1066 .name = "Center Playback Volume",
1067 .info = wm_vol_info,
1070 .private_value = (1 << 8) | 4
1073 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1074 .name = "LFE Playback Switch",
1075 .info = wm_mute_info,
1078 .private_value = (1 << 8) | 5
1081 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1082 .name = "LFE Playback Volume",
1083 .info = wm_vol_info,
1086 .private_value = (1 << 8) | 5
1089 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1090 .name = "Side Playback Switch",
1091 .info = wm_mute_info,
1094 .private_value = (2 << 8) | 6
1097 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1098 .name = "Side Playback Volume",
1099 .info = wm_vol_info,
1102 .private_value = (2 << 8) | 6
1106 static snd_kcontrol_new_t wm_controls[] __devinitdata = {
1108 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1109 .name = "PCM Playback Switch",
1110 .info = wm_pcm_mute_info,
1111 .get = wm_pcm_mute_get,
1112 .put = wm_pcm_mute_put
1115 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1116 .name = "PCM Playback Volume",
1117 .info = wm_pcm_vol_info,
1118 .get = wm_pcm_vol_get,
1119 .put = wm_pcm_vol_put
1122 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1123 .name = "Capture Switch",
1124 .info = wm_adc_mute_info,
1125 .get = wm_adc_mute_get,
1126 .put = wm_adc_mute_put,
1129 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1130 .name = "Capture Volume",
1131 .info = wm_adc_vol_info,
1132 .get = wm_adc_vol_get,
1133 .put = wm_adc_vol_put
1136 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1137 .name = "Capture Source",
1138 .info = wm_adc_mux_info,
1139 .get = wm_adc_mux_get,
1140 .put = wm_adc_mux_put,
1144 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1145 .name = "Headphone Amplifier Switch",
1146 .info = aureon_hpamp_info,
1147 .get = aureon_hpamp_get,
1148 .put = aureon_hpamp_put
1151 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1152 .name = "DAC Deemphasis Switch",
1153 .info = aureon_deemp_info,
1154 .get = aureon_deemp_get,
1155 .put = aureon_deemp_put
1158 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1159 .name = "ADC Oversampling",
1160 .info = aureon_oversampling_info,
1161 .get = aureon_oversampling_get,
1162 .put = aureon_oversampling_put
1166 static snd_kcontrol_new_t ac97_controls[] __devinitdata = {
1168 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1169 .name = "AC97 Playback Switch",
1170 .info = aureon_ac97_mmute_info,
1171 .get = aureon_ac97_mmute_get,
1172 .put = aureon_ac97_mmute_put,
1173 .private_value = AC97_MASTER
1176 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1177 .name = "AC97 Playback Volume",
1178 .info = aureon_ac97_vol_info,
1179 .get = aureon_ac97_vol_get,
1180 .put = aureon_ac97_vol_put,
1181 .private_value = AC97_MASTER|AUREON_AC97_STEREO
1184 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1185 .name = "CD Playback Switch",
1186 .info = aureon_ac97_mute_info,
1187 .get = aureon_ac97_mute_get,
1188 .put = aureon_ac97_mute_put,
1189 .private_value = AC97_CD
1192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1193 .name = "CD Playback Volume",
1194 .info = aureon_ac97_vol_info,
1195 .get = aureon_ac97_vol_get,
1196 .put = aureon_ac97_vol_put,
1197 .private_value = AC97_CD|AUREON_AC97_STEREO
1200 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1201 .name = "Aux Playback Switch",
1202 .info = aureon_ac97_mute_info,
1203 .get = aureon_ac97_mute_get,
1204 .put = aureon_ac97_mute_put,
1205 .private_value = AC97_AUX,
1208 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1209 .name = "Aux Playback Volume",
1210 .info = aureon_ac97_vol_info,
1211 .get = aureon_ac97_vol_get,
1212 .put = aureon_ac97_vol_put,
1213 .private_value = AC97_AUX|AUREON_AC97_STEREO
1216 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1217 .name = "Line Playback Switch",
1218 .info = aureon_ac97_mute_info,
1219 .get = aureon_ac97_mute_get,
1220 .put = aureon_ac97_mute_put,
1221 .private_value = AC97_LINE
1224 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1225 .name = "Line Playback Volume",
1226 .info = aureon_ac97_vol_info,
1227 .get = aureon_ac97_vol_get,
1228 .put = aureon_ac97_vol_put,
1229 .private_value = AC97_LINE|AUREON_AC97_STEREO
1232 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1233 .name = "Mic Playback Switch",
1234 .info = aureon_ac97_mute_info,
1235 .get = aureon_ac97_mute_get,
1236 .put = aureon_ac97_mute_put,
1237 .private_value = AC97_MIC
1240 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1241 .name = "Mic Playback Volume",
1242 .info = aureon_ac97_vol_info,
1243 .get = aureon_ac97_vol_get,
1244 .put = aureon_ac97_vol_put,
1245 .private_value = AC97_MIC
1248 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1249 .name = "Mic Boost",
1250 .info = aureon_ac97_micboost_info,
1251 .get = aureon_ac97_micboost_get,
1252 .put = aureon_ac97_micboost_put
1256 static int __devinit aureon_add_controls(ice1712_t *ice)
1258 unsigned int i, counts;
1261 counts = ARRAY_SIZE(aureon_dac_controls);
1262 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
1263 counts -= 2; /* no side */
1264 for (i = 0; i < counts; i++) {
1265 err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
1270 for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
1271 err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
1276 for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
1277 err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
1287 * initialize the chip
1289 static int __devinit aureon_init(ice1712_t *ice)
1291 static unsigned short wm_inits_aureon[] = {
1292 /* These come first to reduce init pop noise */
1293 0x1b, 0x005, /* ADC Mux (AC'97 source) */
1294 0x1c, 0x00B, /* Out Mux1 (VOUT1 = ADC+AUX, VOUT2 = ADC) */
1295 0x1d, 0x009, /* Out Mux2 (VOUT2 = ADC, VOUT3 = ADC) */
1297 0x18, 0x000, /* All power-up */
1299 0x16, 0x122, /* I2S, normal polarity, 24bit */
1300 0x17, 0x022, /* 256fs, slave mode */
1301 0x00, 0, /* DAC1 analog mute */
1302 0x01, 0, /* DAC2 analog mute */
1303 0x02, 0, /* DAC3 analog mute */
1304 0x03, 0, /* DAC4 analog mute */
1305 0x04, 0, /* DAC5 analog mute */
1306 0x05, 0, /* DAC6 analog mute */
1307 0x06, 0, /* DAC7 analog mute */
1308 0x07, 0, /* DAC8 analog mute */
1309 0x08, 0x100, /* master analog mute */
1310 0x09, 0xff, /* DAC1 digital full */
1311 0x0a, 0xff, /* DAC2 digital full */
1312 0x0b, 0xff, /* DAC3 digital full */
1313 0x0c, 0xff, /* DAC4 digital full */
1314 0x0d, 0xff, /* DAC5 digital full */
1315 0x0e, 0xff, /* DAC6 digital full */
1316 0x0f, 0xff, /* DAC7 digital full */
1317 0x10, 0xff, /* DAC8 digital full */
1318 0x11, 0x1ff, /* master digital full */
1319 0x12, 0x000, /* phase normal */
1320 0x13, 0x090, /* unmute DAC L/R */
1321 0x14, 0x000, /* all unmute */
1322 0x15, 0x000, /* no deemphasis, no ZFLG */
1323 0x19, 0x000, /* -12dB ADC/L */
1324 0x1a, 0x000, /* -12dB ADC/R */
1327 static unsigned short wm_inits_prodigy[] = {
1329 /* These come first to reduce init pop noise */
1330 0x1b, 0x000, /* ADC Mux */
1331 0x1c, 0x009, /* Out Mux1 */
1332 0x1d, 0x009, /* Out Mux2 */
1334 0x18, 0x000, /* All power-up */
1336 0x16, 0x022, /* I2S, normal polarity, 24bit, high-pass on */
1337 0x17, 0x006, /* 128fs, slave mode */
1339 0x00, 0, /* DAC1 analog mute */
1340 0x01, 0, /* DAC2 analog mute */
1341 0x02, 0, /* DAC3 analog mute */
1342 0x03, 0, /* DAC4 analog mute */
1343 0x04, 0, /* DAC5 analog mute */
1344 0x05, 0, /* DAC6 analog mute */
1345 0x06, 0, /* DAC7 analog mute */
1346 0x07, 0, /* DAC8 analog mute */
1347 0x08, 0x100, /* master analog mute */
1349 0x09, 0x7f, /* DAC1 digital full */
1350 0x0a, 0x7f, /* DAC2 digital full */
1351 0x0b, 0x7f, /* DAC3 digital full */
1352 0x0c, 0x7f, /* DAC4 digital full */
1353 0x0d, 0x7f, /* DAC5 digital full */
1354 0x0e, 0x7f, /* DAC6 digital full */
1355 0x0f, 0x7f, /* DAC7 digital full */
1356 0x10, 0x7f, /* DAC8 digital full */
1357 0x11, 0x1FF, /* master digital full */
1359 0x12, 0x000, /* phase normal */
1360 0x13, 0x090, /* unmute DAC L/R */
1361 0x14, 0x000, /* all unmute */
1362 0x15, 0x000, /* no deemphasis, no ZFLG */
1364 0x19, 0x000, /* -12dB ADC/L */
1365 0x1a, 0x000, /* -12dB ADC/R */
1369 static unsigned short cs_inits[] = {
1371 0x0180, /* no mute, OMCK output on RMCK pin */
1372 0x0201, /* S/PDIF source on RXP1 */
1373 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
1381 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
1382 ice->num_total_dacs = 6;
1383 ice->num_total_adcs = 2;
1385 /* aureon 7.1 and prodigy 7.1 */
1386 ice->num_total_dacs = 8;
1387 ice->num_total_adcs = 2;
1390 /* to remeber the register values of CS8415 */
1391 ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
1394 ice->akm_codecs = 1;
1396 if ((err = aureon_ac97_init(ice)) != 0)
1399 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
1400 cscs = PRODIGY_CS8415_CS;
1402 cscs = AUREON_CS8415_CS;
1404 snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
1406 /* reset the wm codec as the SPI mode */
1407 snd_ice1712_save_gpio_status(ice);
1408 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|
1409 cscs|AUREON_HP_SEL));
1411 tmp = snd_ice1712_gpio_read(ice);
1412 tmp &= ~AUREON_WM_RESET;
1413 snd_ice1712_gpio_write(ice, tmp);
1415 tmp |= AUREON_WM_CS | cscs;
1416 snd_ice1712_gpio_write(ice, tmp);
1418 tmp |= AUREON_WM_RESET;
1419 snd_ice1712_gpio_write(ice, tmp);
1422 /* initialize WM8770 codec */
1423 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
1424 p = wm_inits_prodigy;
1426 p = wm_inits_aureon;
1427 for (; *p != (unsigned short)-1; p += 2)
1428 wm_put(ice, p[0], p[1]);
1430 /* initialize CS8415A codec */
1431 for (p = cs_inits; *p != (unsigned short)-1; p++)
1432 aureon_spi_write(ice, cscs,
1435 aureon_set_headphone_amp(ice, 1);
1437 snd_ice1712_restore_gpio_status(ice);
1439 ice->spec.aureon.master[0] = WM_VOL_MUTE;
1440 ice->spec.aureon.master[1] = WM_VOL_MUTE;
1441 for (i = 0; i < ice->num_total_dacs; i++) {
1442 ice->spec.aureon.vol[i] = WM_VOL_MUTE;
1443 wm_set_vol(ice, i, ice->spec.aureon.vol[i], ice->spec.aureon.master[i % 2]);
1451 * Aureon boards don't provide the EEPROM data except for the vendor IDs.
1452 * hence the driver needs to sets up it properly.
1455 static unsigned char aureon51_eeprom[] __devinitdata = {
1456 0x0a, /* SYSCONF: clock 512, spdif-in/ADC, 3DACs */
1457 0x80, /* ACLINK: I2S */
1458 0xfc, /* I2S: vol, 96k, 24bit, 192k */
1459 0xc3, /* SPDIF: out-en, out-int, spdif-in */
1460 0xff, /* GPIO_DIR */
1461 0xff, /* GPIO_DIR1 */
1462 0x5f, /* GPIO_DIR2 */
1463 0x00, /* GPIO_MASK */
1464 0x00, /* GPIO_MASK1 */
1465 0x00, /* GPIO_MASK2 */
1466 0x00, /* GPIO_STATE */
1467 0x00, /* GPIO_STATE1 */
1468 0x00, /* GPIO_STATE2 */
1471 static unsigned char aureon71_eeprom[] __devinitdata = {
1472 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
1473 0x80, /* ACLINK: I2S */
1474 0xfc, /* I2S: vol, 96k, 24bit, 192k */
1475 0xc3, /* SPDIF: out-en, out-int, spdif-in */
1476 0xff, /* GPIO_DIR */
1477 0xff, /* GPIO_DIR1 */
1478 0x5f, /* GPIO_DIR2 */
1479 0x00, /* GPIO_MASK */
1480 0x00, /* GPIO_MASK1 */
1481 0x00, /* GPIO_MASK2 */
1482 0x00, /* GPIO_STATE */
1483 0x00, /* GPIO_STATE1 */
1484 0x00, /* GPIO_STATE2 */
1487 static unsigned char prodigy71_eeprom[] __devinitdata = {
1488 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
1489 0x80, /* ACLINK: I2S */
1490 0xfc, /* I2S: vol, 96k, 24bit, 192k */
1491 0xc3, /* SPDIF: out-en, out-int, spdif-in */
1492 0xff, /* GPIO_DIR */
1493 0xff, /* GPIO_DIR1 */
1494 0x5f, /* GPIO_DIR2 */
1495 0x00, /* GPIO_MASK */
1496 0x00, /* GPIO_MASK1 */
1497 0x00, /* GPIO_MASK2 */
1498 0x00, /* GPIO_STATE */
1499 0x00, /* GPIO_STATE1 */
1500 0x00, /* GPIO_STATE2 */
1504 struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
1506 .subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
1507 .name = "Terratec Aureon 5.1-Sky",
1508 .model = "aureon51",
1509 .chip_init = aureon_init,
1510 .build_controls = aureon_add_controls,
1511 .eeprom_size = sizeof(aureon51_eeprom),
1512 .eeprom_data = aureon51_eeprom,
1513 .driver = "Aureon51",
1516 .subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
1517 .name = "Terratec Aureon 7.1-Space",
1518 .model = "aureon71",
1519 .chip_init = aureon_init,
1520 .build_controls = aureon_add_controls,
1521 .eeprom_size = sizeof(aureon71_eeprom),
1522 .eeprom_data = aureon71_eeprom,
1523 .driver = "Aureon71",
1526 .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
1527 .name = "Terratec Aureon 7.1-Universe",
1528 /* model not needed - identical with 7.1-Space */
1529 .chip_init = aureon_init,
1530 .build_controls = aureon_add_controls,
1531 .eeprom_size = sizeof(aureon71_eeprom),
1532 .eeprom_data = aureon71_eeprom,
1533 .driver = "Aureon71",
1536 .subvendor = VT1724_SUBDEVICE_PRODIGY71,
1537 .name = "Audiotrak Prodigy 7.1",
1538 .model = "prodigy71",
1539 .chip_init = aureon_init,
1540 .build_controls = aureon_add_controls,
1541 .eeprom_size = sizeof(prodigy71_eeprom),
1542 .eeprom_data = prodigy71_eeprom,
1543 .driver = "Prodigy71", /* should be identical with Aureon71 */
1545 { } /* terminator */