ARCv2: SLC: Make sure busy bit is set properly for region ops
[linux/fpc-iii.git] / sound / pci / ice1712 / aureon.c
blobc9411dfff5a4deee94bad34e6da4b0b9d7ca1479
1 /*
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
23 * NOTES:
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
28 * many boards.
30 * - DAC digital volumes are not implemented in the mixer.
31 * if they show better response than DAC analog volumes, we can use them
32 * instead.
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.
49 #include <linux/delay.h>
50 #include <linux/interrupt.h>
51 #include <linux/init.h>
52 #include <linux/slab.h>
53 #include <linux/mutex.h>
55 #include <sound/core.h>
57 #include "ice1712.h"
58 #include "envy24ht.h"
59 #include "aureon.h"
60 #include <sound/tlv.h>
62 /* AC97 register cache for Aureon */
63 struct aureon_spec {
64 unsigned short stac9744[64];
65 unsigned int cs8415_mux;
66 unsigned short master[2];
67 unsigned short vol[8];
68 unsigned char pca9554_out;
71 /* WM8770 registers */
72 #define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
73 #define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */
74 #define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */
75 #define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */
76 #define WM_PHASE_SWAP 0x12 /* DAC phase */
77 #define WM_DAC_CTRL1 0x13 /* DAC control bits */
78 #define WM_MUTE 0x14 /* mute controls */
79 #define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */
80 #define WM_INT_CTRL 0x16 /* interface control */
81 #define WM_MASTER 0x17 /* master clock and mode */
82 #define WM_POWERDOWN 0x18 /* power-down controls */
83 #define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */
84 #define WM_ADC_MUX 0x1b /* input MUX */
85 #define WM_OUT_MUX1 0x1c /* output MUX */
86 #define WM_OUT_MUX2 0x1e /* output MUX */
87 #define WM_RESET 0x1f /* software reset */
89 /* CS8415A registers */
90 #define CS8415_CTRL1 0x01
91 #define CS8415_CTRL2 0x02
92 #define CS8415_QSUB 0x14
93 #define CS8415_RATIO 0x1E
94 #define CS8415_C_BUFFER 0x20
95 #define CS8415_ID 0x7F
97 /* PCA9554 registers */
98 #define PCA9554_DEV 0x40 /* I2C device address */
99 #define PCA9554_IN 0x00 /* input port */
100 #define PCA9554_OUT 0x01 /* output port */
101 #define PCA9554_INVERT 0x02 /* input invert */
102 #define PCA9554_DIR 0x03 /* port directions */
105 * Aureon Universe additional controls using PCA9554
109 * Send data to pca9554
111 static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
112 unsigned char data)
114 unsigned int tmp;
115 int i, j;
116 unsigned char dev = PCA9554_DEV; /* ID 0100000, write */
117 unsigned char val = 0;
119 tmp = snd_ice1712_gpio_read(ice);
121 snd_ice1712_gpio_set_mask(ice, ~(AUREON_SPI_MOSI|AUREON_SPI_CLK|
122 AUREON_WM_RW|AUREON_WM_CS|
123 AUREON_CS8415_CS));
124 tmp |= AUREON_WM_RW;
125 tmp |= AUREON_CS8415_CS | AUREON_WM_CS; /* disable SPI devices */
127 tmp &= ~AUREON_SPI_MOSI;
128 tmp &= ~AUREON_SPI_CLK;
129 snd_ice1712_gpio_write(ice, tmp);
130 udelay(50);
133 * send i2c stop condition and start condition
134 * to obtain sane state
136 tmp |= AUREON_SPI_CLK;
137 snd_ice1712_gpio_write(ice, tmp);
138 udelay(50);
139 tmp |= AUREON_SPI_MOSI;
140 snd_ice1712_gpio_write(ice, tmp);
141 udelay(100);
142 tmp &= ~AUREON_SPI_MOSI;
143 snd_ice1712_gpio_write(ice, tmp);
144 udelay(50);
145 tmp &= ~AUREON_SPI_CLK;
146 snd_ice1712_gpio_write(ice, tmp);
147 udelay(100);
149 * send device address, command and value,
150 * skipping ack cycles in between
152 for (j = 0; j < 3; j++) {
153 switch (j) {
154 case 0:
155 val = dev;
156 break;
157 case 1:
158 val = reg;
159 break;
160 case 2:
161 val = data;
162 break;
164 for (i = 7; i >= 0; i--) {
165 tmp &= ~AUREON_SPI_CLK;
166 snd_ice1712_gpio_write(ice, tmp);
167 udelay(40);
168 if (val & (1 << i))
169 tmp |= AUREON_SPI_MOSI;
170 else
171 tmp &= ~AUREON_SPI_MOSI;
172 snd_ice1712_gpio_write(ice, tmp);
173 udelay(40);
174 tmp |= AUREON_SPI_CLK;
175 snd_ice1712_gpio_write(ice, tmp);
176 udelay(40);
178 tmp &= ~AUREON_SPI_CLK;
179 snd_ice1712_gpio_write(ice, tmp);
180 udelay(40);
181 tmp |= AUREON_SPI_CLK;
182 snd_ice1712_gpio_write(ice, tmp);
183 udelay(40);
184 tmp &= ~AUREON_SPI_CLK;
185 snd_ice1712_gpio_write(ice, tmp);
186 udelay(40);
188 tmp &= ~AUREON_SPI_CLK;
189 snd_ice1712_gpio_write(ice, tmp);
190 udelay(40);
191 tmp &= ~AUREON_SPI_MOSI;
192 snd_ice1712_gpio_write(ice, tmp);
193 udelay(40);
194 tmp |= AUREON_SPI_CLK;
195 snd_ice1712_gpio_write(ice, tmp);
196 udelay(50);
197 tmp |= AUREON_SPI_MOSI;
198 snd_ice1712_gpio_write(ice, tmp);
199 udelay(100);
202 static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,
203 struct snd_ctl_elem_info *uinfo)
205 static const char * const texts[3] =
206 {"Internal Aux", "Wavetable", "Rear Line-In"};
208 return snd_ctl_enum_info(uinfo, 1, 3, texts);
211 static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol,
212 struct snd_ctl_elem_value *ucontrol)
214 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
215 struct aureon_spec *spec = ice->spec;
216 ucontrol->value.enumerated.item[0] = spec->pca9554_out;
217 return 0;
220 static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
221 struct snd_ctl_elem_value *ucontrol)
223 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
224 struct aureon_spec *spec = ice->spec;
225 unsigned char oval, nval;
226 int change;
228 nval = ucontrol->value.enumerated.item[0];
229 if (nval >= 3)
230 return -EINVAL;
231 snd_ice1712_save_gpio_status(ice);
232 oval = spec->pca9554_out;
233 change = (oval != nval);
234 if (change) {
235 aureon_pca9554_write(ice, PCA9554_OUT, nval);
236 spec->pca9554_out = nval;
238 snd_ice1712_restore_gpio_status(ice);
239 return change;
243 static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
244 unsigned short val)
246 struct aureon_spec *spec = ice->spec;
247 unsigned int tmp;
249 /* Send address to XILINX chip */
250 tmp = (snd_ice1712_gpio_read(ice) & ~0xFF) | (reg & 0x7F);
251 snd_ice1712_gpio_write(ice, tmp);
252 udelay(10);
253 tmp |= AUREON_AC97_ADDR;
254 snd_ice1712_gpio_write(ice, tmp);
255 udelay(10);
256 tmp &= ~AUREON_AC97_ADDR;
257 snd_ice1712_gpio_write(ice, tmp);
258 udelay(10);
260 /* Send low-order byte to XILINX chip */
261 tmp &= ~AUREON_AC97_DATA_MASK;
262 tmp |= val & AUREON_AC97_DATA_MASK;
263 snd_ice1712_gpio_write(ice, tmp);
264 udelay(10);
265 tmp |= AUREON_AC97_DATA_LOW;
266 snd_ice1712_gpio_write(ice, tmp);
267 udelay(10);
268 tmp &= ~AUREON_AC97_DATA_LOW;
269 snd_ice1712_gpio_write(ice, tmp);
270 udelay(10);
272 /* Send high-order byte to XILINX chip */
273 tmp &= ~AUREON_AC97_DATA_MASK;
274 tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
276 snd_ice1712_gpio_write(ice, tmp);
277 udelay(10);
278 tmp |= AUREON_AC97_DATA_HIGH;
279 snd_ice1712_gpio_write(ice, tmp);
280 udelay(10);
281 tmp &= ~AUREON_AC97_DATA_HIGH;
282 snd_ice1712_gpio_write(ice, tmp);
283 udelay(10);
285 /* Instruct XILINX chip to parse the data to the STAC9744 chip */
286 tmp |= AUREON_AC97_COMMIT;
287 snd_ice1712_gpio_write(ice, tmp);
288 udelay(10);
289 tmp &= ~AUREON_AC97_COMMIT;
290 snd_ice1712_gpio_write(ice, tmp);
291 udelay(10);
293 /* Store the data in out private buffer */
294 spec->stac9744[(reg & 0x7F) >> 1] = val;
297 static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short reg)
299 struct aureon_spec *spec = ice->spec;
300 return spec->stac9744[(reg & 0x7F) >> 1];
304 * Initialize STAC9744 chip
306 static int aureon_ac97_init(struct snd_ice1712 *ice)
308 struct aureon_spec *spec = ice->spec;
309 int i;
310 static const unsigned short ac97_defaults[] = {
311 0x00, 0x9640,
312 0x02, 0x8000,
313 0x04, 0x8000,
314 0x06, 0x8000,
315 0x0C, 0x8008,
316 0x0E, 0x8008,
317 0x10, 0x8808,
318 0x12, 0x8808,
319 0x14, 0x8808,
320 0x16, 0x8808,
321 0x18, 0x8808,
322 0x1C, 0x8000,
323 0x26, 0x000F,
324 0x28, 0x0201,
325 0x2C, 0xBB80,
326 0x32, 0xBB80,
327 0x7C, 0x8384,
328 0x7E, 0x7644,
329 (unsigned short)-1
331 unsigned int tmp;
333 /* Cold reset */
334 tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
335 snd_ice1712_gpio_write(ice, tmp);
336 udelay(3);
338 tmp &= ~AUREON_AC97_RESET;
339 snd_ice1712_gpio_write(ice, tmp);
340 udelay(3);
342 tmp |= AUREON_AC97_RESET;
343 snd_ice1712_gpio_write(ice, tmp);
344 udelay(3);
346 memset(&spec->stac9744, 0, sizeof(spec->stac9744));
347 for (i = 0; ac97_defaults[i] != (unsigned short)-1; i += 2)
348 spec->stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
350 /* Unmute AC'97 master volume permanently - muting is done by WM8770 */
351 aureon_ac97_write(ice, AC97_MASTER, 0x0000);
353 return 0;
356 #define AUREON_AC97_STEREO 0x80
359 * AC'97 volume controls
361 static int aureon_ac97_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
363 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
364 uinfo->count = kcontrol->private_value & AUREON_AC97_STEREO ? 2 : 1;
365 uinfo->value.integer.min = 0;
366 uinfo->value.integer.max = 31;
367 return 0;
370 static int aureon_ac97_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
372 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
373 unsigned short vol;
375 mutex_lock(&ice->gpio_mutex);
377 vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
378 ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F);
379 if (kcontrol->private_value & AUREON_AC97_STEREO)
380 ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F);
382 mutex_unlock(&ice->gpio_mutex);
383 return 0;
386 static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
388 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
389 unsigned short ovol, nvol;
390 int change;
392 snd_ice1712_save_gpio_status(ice);
394 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
395 nvol = (0x1F - ucontrol->value.integer.value[0]) & 0x001F;
396 if (kcontrol->private_value & AUREON_AC97_STEREO)
397 nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00;
398 nvol |= ovol & ~0x1F1F;
400 change = (ovol != nvol);
401 if (change)
402 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
404 snd_ice1712_restore_gpio_status(ice);
406 return change;
410 * AC'97 mute controls
412 #define aureon_ac97_mute_info snd_ctl_boolean_mono_info
414 static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
416 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
418 mutex_lock(&ice->gpio_mutex);
420 ucontrol->value.integer.value[0] = aureon_ac97_read(ice,
421 kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
423 mutex_unlock(&ice->gpio_mutex);
424 return 0;
427 static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
429 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
430 unsigned short ovol, nvol;
431 int change;
433 snd_ice1712_save_gpio_status(ice);
435 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
436 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~0x8000);
438 change = (ovol != nvol);
439 if (change)
440 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
442 snd_ice1712_restore_gpio_status(ice);
444 return change;
448 * AC'97 mute controls
450 #define aureon_ac97_micboost_info snd_ctl_boolean_mono_info
452 static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
454 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
456 mutex_lock(&ice->gpio_mutex);
458 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
460 mutex_unlock(&ice->gpio_mutex);
461 return 0;
464 static int aureon_ac97_micboost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
466 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
467 unsigned short ovol, nvol;
468 int change;
470 snd_ice1712_save_gpio_status(ice);
472 ovol = aureon_ac97_read(ice, AC97_MIC);
473 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020);
475 change = (ovol != nvol);
476 if (change)
477 aureon_ac97_write(ice, AC97_MIC, nvol);
479 snd_ice1712_restore_gpio_status(ice);
481 return change;
485 * write data in the SPI mode
487 static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits)
489 unsigned int tmp;
490 int i;
491 unsigned int mosi, clk;
493 tmp = snd_ice1712_gpio_read(ice);
495 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
496 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) {
497 snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS));
498 mosi = PRODIGY_SPI_MOSI;
499 clk = PRODIGY_SPI_CLK;
500 } else {
501 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
502 AUREON_WM_CS|AUREON_CS8415_CS));
503 mosi = AUREON_SPI_MOSI;
504 clk = AUREON_SPI_CLK;
506 tmp |= AUREON_WM_RW;
509 tmp &= ~cs;
510 snd_ice1712_gpio_write(ice, tmp);
511 udelay(1);
513 for (i = bits - 1; i >= 0; i--) {
514 tmp &= ~clk;
515 snd_ice1712_gpio_write(ice, tmp);
516 udelay(1);
517 if (data & (1 << i))
518 tmp |= mosi;
519 else
520 tmp &= ~mosi;
521 snd_ice1712_gpio_write(ice, tmp);
522 udelay(1);
523 tmp |= clk;
524 snd_ice1712_gpio_write(ice, tmp);
525 udelay(1);
528 tmp &= ~clk;
529 tmp |= cs;
530 snd_ice1712_gpio_write(ice, tmp);
531 udelay(1);
532 tmp |= clk;
533 snd_ice1712_gpio_write(ice, tmp);
534 udelay(1);
538 * Read data in SPI mode
540 static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs,
541 unsigned int data, int bits, unsigned char *buffer, int size)
543 int i, j;
544 unsigned int tmp;
546 tmp = (snd_ice1712_gpio_read(ice) & ~AUREON_SPI_CLK) | AUREON_CS8415_CS|AUREON_WM_CS;
547 snd_ice1712_gpio_write(ice, tmp);
548 tmp &= ~cs;
549 snd_ice1712_gpio_write(ice, tmp);
550 udelay(1);
552 for (i = bits-1; i >= 0; i--) {
553 if (data & (1 << i))
554 tmp |= AUREON_SPI_MOSI;
555 else
556 tmp &= ~AUREON_SPI_MOSI;
557 snd_ice1712_gpio_write(ice, tmp);
558 udelay(1);
560 tmp |= AUREON_SPI_CLK;
561 snd_ice1712_gpio_write(ice, tmp);
562 udelay(1);
564 tmp &= ~AUREON_SPI_CLK;
565 snd_ice1712_gpio_write(ice, tmp);
566 udelay(1);
569 for (j = 0; j < size; j++) {
570 unsigned char outdata = 0;
571 for (i = 7; i >= 0; i--) {
572 tmp = snd_ice1712_gpio_read(ice);
573 outdata <<= 1;
574 outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0;
575 udelay(1);
577 tmp |= AUREON_SPI_CLK;
578 snd_ice1712_gpio_write(ice, tmp);
579 udelay(1);
581 tmp &= ~AUREON_SPI_CLK;
582 snd_ice1712_gpio_write(ice, tmp);
583 udelay(1);
585 buffer[j] = outdata;
588 tmp |= cs;
589 snd_ice1712_gpio_write(ice, tmp);
592 static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg)
594 unsigned char val;
595 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
596 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1);
597 return val;
600 static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg,
601 unsigned char *buffer, int size)
603 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
604 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size);
607 static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg,
608 unsigned char val)
610 aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24);
614 * get the current register value of WM codec
616 static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
618 reg <<= 1;
619 return ((unsigned short)ice->akm[0].images[reg] << 8) |
620 ice->akm[0].images[reg + 1];
624 * set the register value of WM codec
626 static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
628 aureon_spi_write(ice,
629 ((ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
630 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) ?
631 PRODIGY_WM_CS : AUREON_WM_CS),
632 (reg << 9) | (val & 0x1ff), 16);
636 * set the register value of WM codec and remember it
638 static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
640 wm_put_nocache(ice, reg, val);
641 reg <<= 1;
642 ice->akm[0].images[reg] = val >> 8;
643 ice->akm[0].images[reg + 1] = val;
648 #define aureon_mono_bool_info snd_ctl_boolean_mono_info
651 * AC'97 master playback mute controls (Mute on WM8770 chip)
653 #define aureon_ac97_mmute_info snd_ctl_boolean_mono_info
655 static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
657 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
659 mutex_lock(&ice->gpio_mutex);
661 ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
663 mutex_unlock(&ice->gpio_mutex);
664 return 0;
667 static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
669 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
670 unsigned short ovol, nvol;
671 int change;
673 snd_ice1712_save_gpio_status(ice);
675 ovol = wm_get(ice, WM_OUT_MUX1);
676 nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00);
677 change = (ovol != nvol);
678 if (change)
679 wm_put(ice, WM_OUT_MUX1, nvol);
681 snd_ice1712_restore_gpio_status(ice);
683 return change;
686 static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -10000, 100, 1);
687 static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
688 static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0);
689 static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0);
690 static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0);
692 #define WM_VOL_MAX 100
693 #define WM_VOL_CNT 101 /* 0dB .. -100dB */
694 #define WM_VOL_MUTE 0x8000
696 static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
698 unsigned char nvol;
700 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) {
701 nvol = 0;
702 } else {
703 nvol = ((vol % WM_VOL_CNT) * (master % WM_VOL_CNT)) /
704 WM_VOL_MAX;
705 nvol += 0x1b;
708 wm_put(ice, index, nvol);
709 wm_put_nocache(ice, index, 0x180 | nvol);
713 * DAC mute control
715 #define wm_pcm_mute_info snd_ctl_boolean_mono_info
717 static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
719 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
721 mutex_lock(&ice->gpio_mutex);
722 ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
723 mutex_unlock(&ice->gpio_mutex);
724 return 0;
727 static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
729 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
730 unsigned short nval, oval;
731 int change;
733 snd_ice1712_save_gpio_status(ice);
734 oval = wm_get(ice, WM_MUTE);
735 nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
736 change = (oval != nval);
737 if (change)
738 wm_put(ice, WM_MUTE, nval);
739 snd_ice1712_restore_gpio_status(ice);
741 return change;
745 * Master volume attenuation mixer control
747 static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
749 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
750 uinfo->count = 2;
751 uinfo->value.integer.min = 0;
752 uinfo->value.integer.max = WM_VOL_MAX;
753 return 0;
756 static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
758 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
759 struct aureon_spec *spec = ice->spec;
760 int i;
761 for (i = 0; i < 2; i++)
762 ucontrol->value.integer.value[i] =
763 spec->master[i] & ~WM_VOL_MUTE;
764 return 0;
767 static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
769 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
770 struct aureon_spec *spec = ice->spec;
771 int ch, change = 0;
773 snd_ice1712_save_gpio_status(ice);
774 for (ch = 0; ch < 2; ch++) {
775 unsigned int vol = ucontrol->value.integer.value[ch];
776 if (vol > WM_VOL_MAX)
777 vol = WM_VOL_MAX;
778 vol |= spec->master[ch] & WM_VOL_MUTE;
779 if (vol != spec->master[ch]) {
780 int dac;
781 spec->master[ch] = vol;
782 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
783 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
784 spec->vol[dac + ch],
785 spec->master[ch]);
786 change = 1;
789 snd_ice1712_restore_gpio_status(ice);
790 return change;
794 * DAC volume attenuation mixer control
796 static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
798 int voices = kcontrol->private_value >> 8;
799 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
800 uinfo->count = voices;
801 uinfo->value.integer.min = 0; /* mute (-101dB) */
802 uinfo->value.integer.max = WM_VOL_MAX; /* 0dB */
803 return 0;
806 static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
808 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
809 struct aureon_spec *spec = ice->spec;
810 int i, ofs, voices;
812 voices = kcontrol->private_value >> 8;
813 ofs = kcontrol->private_value & 0xff;
814 for (i = 0; i < voices; i++)
815 ucontrol->value.integer.value[i] =
816 spec->vol[ofs+i] & ~WM_VOL_MUTE;
817 return 0;
820 static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
822 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
823 struct aureon_spec *spec = ice->spec;
824 int i, idx, ofs, voices;
825 int change = 0;
827 voices = kcontrol->private_value >> 8;
828 ofs = kcontrol->private_value & 0xff;
829 snd_ice1712_save_gpio_status(ice);
830 for (i = 0; i < voices; i++) {
831 unsigned int vol = ucontrol->value.integer.value[i];
832 if (vol > WM_VOL_MAX)
833 vol = WM_VOL_MAX;
834 vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
835 if (vol != spec->vol[ofs+i]) {
836 spec->vol[ofs+i] = vol;
837 idx = WM_DAC_ATTEN + ofs + i;
838 wm_set_vol(ice, idx, spec->vol[ofs + i],
839 spec->master[i]);
840 change = 1;
843 snd_ice1712_restore_gpio_status(ice);
844 return change;
848 * WM8770 mute control
850 static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
852 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
853 uinfo->count = kcontrol->private_value >> 8;
854 uinfo->value.integer.min = 0;
855 uinfo->value.integer.max = 1;
856 return 0;
859 static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
861 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
862 struct aureon_spec *spec = ice->spec;
863 int voices, ofs, i;
865 voices = kcontrol->private_value >> 8;
866 ofs = kcontrol->private_value & 0xFF;
868 for (i = 0; i < voices; i++)
869 ucontrol->value.integer.value[i] =
870 (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
871 return 0;
874 static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
876 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
877 struct aureon_spec *spec = ice->spec;
878 int change = 0, voices, ofs, i;
880 voices = kcontrol->private_value >> 8;
881 ofs = kcontrol->private_value & 0xFF;
883 snd_ice1712_save_gpio_status(ice);
884 for (i = 0; i < voices; i++) {
885 int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
886 if (ucontrol->value.integer.value[i] != val) {
887 spec->vol[ofs + i] &= ~WM_VOL_MUTE;
888 spec->vol[ofs + i] |=
889 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
890 wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
891 spec->master[i]);
892 change = 1;
895 snd_ice1712_restore_gpio_status(ice);
897 return change;
901 * WM8770 master mute control
903 #define wm_master_mute_info snd_ctl_boolean_stereo_info
905 static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
907 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
908 struct aureon_spec *spec = ice->spec;
910 ucontrol->value.integer.value[0] =
911 (spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
912 ucontrol->value.integer.value[1] =
913 (spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
914 return 0;
917 static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
919 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
920 struct aureon_spec *spec = ice->spec;
921 int change = 0, i;
923 snd_ice1712_save_gpio_status(ice);
924 for (i = 0; i < 2; i++) {
925 int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
926 if (ucontrol->value.integer.value[i] != val) {
927 int dac;
928 spec->master[i] &= ~WM_VOL_MUTE;
929 spec->master[i] |=
930 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
931 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
932 wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
933 spec->vol[dac + i],
934 spec->master[i]);
935 change = 1;
938 snd_ice1712_restore_gpio_status(ice);
940 return change;
943 /* digital master volume */
944 #define PCM_0dB 0xff
945 #define PCM_RES 128 /* -64dB */
946 #define PCM_MIN (PCM_0dB - PCM_RES)
947 static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
949 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
950 uinfo->count = 1;
951 uinfo->value.integer.min = 0; /* mute (-64dB) */
952 uinfo->value.integer.max = PCM_RES; /* 0dB */
953 return 0;
956 static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
958 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
959 unsigned short val;
961 mutex_lock(&ice->gpio_mutex);
962 val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
963 val = val > PCM_MIN ? (val - PCM_MIN) : 0;
964 ucontrol->value.integer.value[0] = val;
965 mutex_unlock(&ice->gpio_mutex);
966 return 0;
969 static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
971 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
972 unsigned short ovol, nvol;
973 int change = 0;
975 nvol = ucontrol->value.integer.value[0];
976 if (nvol > PCM_RES)
977 return -EINVAL;
978 snd_ice1712_save_gpio_status(ice);
979 nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
980 ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
981 if (ovol != nvol) {
982 wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
983 wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
984 change = 1;
986 snd_ice1712_restore_gpio_status(ice);
987 return change;
991 * ADC mute control
993 #define wm_adc_mute_info snd_ctl_boolean_stereo_info
995 static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
997 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
998 unsigned short val;
999 int i;
1001 mutex_lock(&ice->gpio_mutex);
1002 for (i = 0; i < 2; i++) {
1003 val = wm_get(ice, WM_ADC_GAIN + i);
1004 ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
1006 mutex_unlock(&ice->gpio_mutex);
1007 return 0;
1010 static int wm_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1012 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1013 unsigned short new, old;
1014 int i, change = 0;
1016 snd_ice1712_save_gpio_status(ice);
1017 for (i = 0; i < 2; i++) {
1018 old = wm_get(ice, WM_ADC_GAIN + i);
1019 new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
1020 if (new != old) {
1021 wm_put(ice, WM_ADC_GAIN + i, new);
1022 change = 1;
1025 snd_ice1712_restore_gpio_status(ice);
1027 return change;
1031 * ADC gain mixer control
1033 static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1035 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1036 uinfo->count = 2;
1037 uinfo->value.integer.min = 0; /* -12dB */
1038 uinfo->value.integer.max = 0x1f; /* 19dB */
1039 return 0;
1042 static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1044 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1045 int i, idx;
1046 unsigned short vol;
1048 mutex_lock(&ice->gpio_mutex);
1049 for (i = 0; i < 2; i++) {
1050 idx = WM_ADC_GAIN + i;
1051 vol = wm_get(ice, idx) & 0x1f;
1052 ucontrol->value.integer.value[i] = vol;
1054 mutex_unlock(&ice->gpio_mutex);
1055 return 0;
1058 static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1060 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1061 int i, idx;
1062 unsigned short ovol, nvol;
1063 int change = 0;
1065 snd_ice1712_save_gpio_status(ice);
1066 for (i = 0; i < 2; i++) {
1067 idx = WM_ADC_GAIN + i;
1068 nvol = ucontrol->value.integer.value[i] & 0x1f;
1069 ovol = wm_get(ice, idx);
1070 if ((ovol & 0x1f) != nvol) {
1071 wm_put(ice, idx, nvol | (ovol & ~0x1f));
1072 change = 1;
1075 snd_ice1712_restore_gpio_status(ice);
1076 return change;
1080 * ADC input mux mixer control
1082 static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1084 static const char * const texts[] = {
1085 "CD", /* AIN1 */
1086 "Aux", /* AIN2 */
1087 "Line", /* AIN3 */
1088 "Mic", /* AIN4 */
1089 "AC97" /* AIN5 */
1091 static const char * const universe_texts[] = {
1092 "Aux1", /* AIN1 */
1093 "CD", /* AIN2 */
1094 "Phono", /* AIN3 */
1095 "Line", /* AIN4 */
1096 "Aux2", /* AIN5 */
1097 "Mic", /* AIN6 */
1098 "Aux3", /* AIN7 */
1099 "AC97" /* AIN8 */
1101 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1103 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE)
1104 return snd_ctl_enum_info(uinfo, 2, 8, universe_texts);
1105 else
1106 return snd_ctl_enum_info(uinfo, 2, 5, texts);
1109 static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1111 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1112 unsigned short val;
1114 mutex_lock(&ice->gpio_mutex);
1115 val = wm_get(ice, WM_ADC_MUX);
1116 ucontrol->value.enumerated.item[0] = val & 7;
1117 ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
1118 mutex_unlock(&ice->gpio_mutex);
1119 return 0;
1122 static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1124 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1125 unsigned short oval, nval;
1126 int change;
1128 snd_ice1712_save_gpio_status(ice);
1129 oval = wm_get(ice, WM_ADC_MUX);
1130 nval = oval & ~0x77;
1131 nval |= ucontrol->value.enumerated.item[0] & 7;
1132 nval |= (ucontrol->value.enumerated.item[1] & 7) << 4;
1133 change = (oval != nval);
1134 if (change)
1135 wm_put(ice, WM_ADC_MUX, nval);
1136 snd_ice1712_restore_gpio_status(ice);
1137 return change;
1141 * CS8415 Input mux
1143 static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1145 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1146 static const char * const aureon_texts[] = {
1147 "CD", /* RXP0 */
1148 "Optical" /* RXP1 */
1150 static const char * const prodigy_texts[] = {
1151 "CD",
1152 "Coax"
1154 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
1155 return snd_ctl_enum_info(uinfo, 1, 2, prodigy_texts);
1156 else
1157 return snd_ctl_enum_info(uinfo, 1, 2, aureon_texts);
1160 static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1162 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1163 struct aureon_spec *spec = ice->spec;
1165 /* snd_ice1712_save_gpio_status(ice); */
1166 /* val = aureon_cs8415_get(ice, CS8415_CTRL2); */
1167 ucontrol->value.enumerated.item[0] = spec->cs8415_mux;
1168 /* snd_ice1712_restore_gpio_status(ice); */
1169 return 0;
1172 static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1174 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1175 struct aureon_spec *spec = ice->spec;
1176 unsigned short oval, nval;
1177 int change;
1179 snd_ice1712_save_gpio_status(ice);
1180 oval = aureon_cs8415_get(ice, CS8415_CTRL2);
1181 nval = oval & ~0x07;
1182 nval |= ucontrol->value.enumerated.item[0] & 7;
1183 change = (oval != nval);
1184 if (change)
1185 aureon_cs8415_put(ice, CS8415_CTRL2, nval);
1186 snd_ice1712_restore_gpio_status(ice);
1187 spec->cs8415_mux = ucontrol->value.enumerated.item[0];
1188 return change;
1191 static int aureon_cs8415_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1193 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1194 uinfo->count = 1;
1195 uinfo->value.integer.min = 0;
1196 uinfo->value.integer.max = 192000;
1197 return 0;
1200 static int aureon_cs8415_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1202 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1203 unsigned char ratio;
1204 ratio = aureon_cs8415_get(ice, CS8415_RATIO);
1205 ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750);
1206 return 0;
1210 * CS8415A Mute
1212 #define aureon_cs8415_mute_info snd_ctl_boolean_mono_info
1214 static int aureon_cs8415_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1216 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1217 snd_ice1712_save_gpio_status(ice);
1218 ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1;
1219 snd_ice1712_restore_gpio_status(ice);
1220 return 0;
1223 static int aureon_cs8415_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1225 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1226 unsigned char oval, nval;
1227 int change;
1228 snd_ice1712_save_gpio_status(ice);
1229 oval = aureon_cs8415_get(ice, CS8415_CTRL1);
1230 if (ucontrol->value.integer.value[0])
1231 nval = oval & ~0x20;
1232 else
1233 nval = oval | 0x20;
1234 change = (oval != nval);
1235 if (change)
1236 aureon_cs8415_put(ice, CS8415_CTRL1, nval);
1237 snd_ice1712_restore_gpio_status(ice);
1238 return change;
1242 * CS8415A Q-Sub info
1244 static int aureon_cs8415_qsub_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1246 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1247 uinfo->count = 10;
1248 return 0;
1251 static int aureon_cs8415_qsub_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1253 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1255 snd_ice1712_save_gpio_status(ice);
1256 aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
1257 snd_ice1712_restore_gpio_status(ice);
1259 return 0;
1262 static int aureon_cs8415_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1264 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1265 uinfo->count = 1;
1266 return 0;
1269 static int aureon_cs8415_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1271 memset(ucontrol->value.iec958.status, 0xFF, 24);
1272 return 0;
1275 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);
1282 return 0;
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);
1293 if (enable)
1294 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1295 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1296 tmp |= AUREON_HP_SEL;
1297 else
1298 tmp |= PRODIGY_HP_SEL;
1299 else
1300 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1301 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1302 tmp &= ~AUREON_HP_SEL;
1303 else
1304 tmp &= ~PRODIGY_HP_SEL;
1305 if (tmp != tmp2) {
1306 snd_ice1712_gpio_write(ice, tmp);
1307 return 1;
1309 return 0;
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 snd_ctl_boolean_mono_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);
1326 return 0;
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]);
1338 * Deemphasis
1341 #define aureon_deemp_info snd_ctl_boolean_mono_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;
1347 return 0;
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);
1353 int temp, temp2;
1354 temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
1355 if (ucontrol->value.integer.value[0])
1356 temp |= 0xf;
1357 else
1358 temp &= ~0xf;
1359 if (temp != temp2) {
1360 wm_put(ice, WM_DAC_CTRL2, temp);
1361 return 1;
1363 return 0;
1367 * ADC Oversampling
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 return snd_ctl_enum_info(uinfo, 1, 2, texts);
1376 static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1378 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1379 ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
1380 return 0;
1383 static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1385 int temp, temp2;
1386 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1388 temp2 = temp = wm_get(ice, WM_MASTER);
1390 if (ucontrol->value.enumerated.item[0])
1391 temp |= 0x8;
1392 else
1393 temp &= ~0x8;
1395 if (temp != temp2) {
1396 wm_put(ice, WM_MASTER, temp);
1397 return 1;
1399 return 0;
1403 * mixers
1406 static struct snd_kcontrol_new aureon_dac_controls[] = {
1408 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1409 .name = "Master Playback Switch",
1410 .info = wm_master_mute_info,
1411 .get = wm_master_mute_get,
1412 .put = wm_master_mute_put
1415 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1416 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1417 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1418 .name = "Master Playback Volume",
1419 .info = wm_master_vol_info,
1420 .get = wm_master_vol_get,
1421 .put = wm_master_vol_put,
1422 .tlv = { .p = db_scale_wm_dac }
1425 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1426 .name = "Front Playback Switch",
1427 .info = wm_mute_info,
1428 .get = wm_mute_get,
1429 .put = wm_mute_put,
1430 .private_value = (2 << 8) | 0
1433 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1434 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1435 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1436 .name = "Front Playback Volume",
1437 .info = wm_vol_info,
1438 .get = wm_vol_get,
1439 .put = wm_vol_put,
1440 .private_value = (2 << 8) | 0,
1441 .tlv = { .p = db_scale_wm_dac }
1444 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1445 .name = "Rear Playback Switch",
1446 .info = wm_mute_info,
1447 .get = wm_mute_get,
1448 .put = wm_mute_put,
1449 .private_value = (2 << 8) | 2
1452 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1453 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1454 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1455 .name = "Rear Playback Volume",
1456 .info = wm_vol_info,
1457 .get = wm_vol_get,
1458 .put = wm_vol_put,
1459 .private_value = (2 << 8) | 2,
1460 .tlv = { .p = db_scale_wm_dac }
1463 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1464 .name = "Center Playback Switch",
1465 .info = wm_mute_info,
1466 .get = wm_mute_get,
1467 .put = wm_mute_put,
1468 .private_value = (1 << 8) | 4
1471 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1472 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1473 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1474 .name = "Center Playback Volume",
1475 .info = wm_vol_info,
1476 .get = wm_vol_get,
1477 .put = wm_vol_put,
1478 .private_value = (1 << 8) | 4,
1479 .tlv = { .p = db_scale_wm_dac }
1482 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1483 .name = "LFE Playback Switch",
1484 .info = wm_mute_info,
1485 .get = wm_mute_get,
1486 .put = wm_mute_put,
1487 .private_value = (1 << 8) | 5
1490 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1491 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1492 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1493 .name = "LFE Playback Volume",
1494 .info = wm_vol_info,
1495 .get = wm_vol_get,
1496 .put = wm_vol_put,
1497 .private_value = (1 << 8) | 5,
1498 .tlv = { .p = db_scale_wm_dac }
1501 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1502 .name = "Side Playback Switch",
1503 .info = wm_mute_info,
1504 .get = wm_mute_get,
1505 .put = wm_mute_put,
1506 .private_value = (2 << 8) | 6
1509 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1510 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1511 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1512 .name = "Side Playback Volume",
1513 .info = wm_vol_info,
1514 .get = wm_vol_get,
1515 .put = wm_vol_put,
1516 .private_value = (2 << 8) | 6,
1517 .tlv = { .p = db_scale_wm_dac }
1521 static struct snd_kcontrol_new wm_controls[] = {
1523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1524 .name = "PCM Playback Switch",
1525 .info = wm_pcm_mute_info,
1526 .get = wm_pcm_mute_get,
1527 .put = wm_pcm_mute_put
1530 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1531 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1532 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1533 .name = "PCM Playback Volume",
1534 .info = wm_pcm_vol_info,
1535 .get = wm_pcm_vol_get,
1536 .put = wm_pcm_vol_put,
1537 .tlv = { .p = db_scale_wm_pcm }
1540 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1541 .name = "Capture Switch",
1542 .info = wm_adc_mute_info,
1543 .get = wm_adc_mute_get,
1544 .put = wm_adc_mute_put,
1547 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1548 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1549 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1550 .name = "Capture Volume",
1551 .info = wm_adc_vol_info,
1552 .get = wm_adc_vol_get,
1553 .put = wm_adc_vol_put,
1554 .tlv = { .p = db_scale_wm_adc }
1557 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1558 .name = "Capture Source",
1559 .info = wm_adc_mux_info,
1560 .get = wm_adc_mux_get,
1561 .put = wm_adc_mux_put,
1562 .private_value = 5
1565 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1566 .name = "External Amplifier",
1567 .info = aureon_hpamp_info,
1568 .get = aureon_hpamp_get,
1569 .put = aureon_hpamp_put
1572 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1573 .name = "DAC Deemphasis Switch",
1574 .info = aureon_deemp_info,
1575 .get = aureon_deemp_get,
1576 .put = aureon_deemp_put
1579 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1580 .name = "ADC Oversampling",
1581 .info = aureon_oversampling_info,
1582 .get = aureon_oversampling_get,
1583 .put = aureon_oversampling_put
1587 static struct snd_kcontrol_new ac97_controls[] = {
1589 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1590 .name = "AC97 Playback Switch",
1591 .info = aureon_ac97_mmute_info,
1592 .get = aureon_ac97_mmute_get,
1593 .put = aureon_ac97_mmute_put,
1594 .private_value = AC97_MASTER
1597 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1598 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1599 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1600 .name = "AC97 Playback Volume",
1601 .info = aureon_ac97_vol_info,
1602 .get = aureon_ac97_vol_get,
1603 .put = aureon_ac97_vol_put,
1604 .private_value = AC97_MASTER|AUREON_AC97_STEREO,
1605 .tlv = { .p = db_scale_ac97_master }
1608 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1609 .name = "CD Playback Switch",
1610 .info = aureon_ac97_mute_info,
1611 .get = aureon_ac97_mute_get,
1612 .put = aureon_ac97_mute_put,
1613 .private_value = AC97_CD
1616 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1617 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1618 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1619 .name = "CD Playback Volume",
1620 .info = aureon_ac97_vol_info,
1621 .get = aureon_ac97_vol_get,
1622 .put = aureon_ac97_vol_put,
1623 .private_value = AC97_CD|AUREON_AC97_STEREO,
1624 .tlv = { .p = db_scale_ac97_gain }
1627 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1628 .name = "Aux Playback Switch",
1629 .info = aureon_ac97_mute_info,
1630 .get = aureon_ac97_mute_get,
1631 .put = aureon_ac97_mute_put,
1632 .private_value = AC97_AUX,
1635 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1636 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1637 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1638 .name = "Aux Playback Volume",
1639 .info = aureon_ac97_vol_info,
1640 .get = aureon_ac97_vol_get,
1641 .put = aureon_ac97_vol_put,
1642 .private_value = AC97_AUX|AUREON_AC97_STEREO,
1643 .tlv = { .p = db_scale_ac97_gain }
1646 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1647 .name = "Line Playback Switch",
1648 .info = aureon_ac97_mute_info,
1649 .get = aureon_ac97_mute_get,
1650 .put = aureon_ac97_mute_put,
1651 .private_value = AC97_LINE
1654 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1655 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1656 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1657 .name = "Line Playback Volume",
1658 .info = aureon_ac97_vol_info,
1659 .get = aureon_ac97_vol_get,
1660 .put = aureon_ac97_vol_put,
1661 .private_value = AC97_LINE|AUREON_AC97_STEREO,
1662 .tlv = { .p = db_scale_ac97_gain }
1665 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1666 .name = "Mic Playback Switch",
1667 .info = aureon_ac97_mute_info,
1668 .get = aureon_ac97_mute_get,
1669 .put = aureon_ac97_mute_put,
1670 .private_value = AC97_MIC
1673 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1674 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1675 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1676 .name = "Mic Playback Volume",
1677 .info = aureon_ac97_vol_info,
1678 .get = aureon_ac97_vol_get,
1679 .put = aureon_ac97_vol_put,
1680 .private_value = AC97_MIC,
1681 .tlv = { .p = db_scale_ac97_gain }
1684 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1685 .name = "Mic Boost (+20dB)",
1686 .info = aureon_ac97_micboost_info,
1687 .get = aureon_ac97_micboost_get,
1688 .put = aureon_ac97_micboost_put
1692 static struct snd_kcontrol_new universe_ac97_controls[] = {
1694 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1695 .name = "AC97 Playback Switch",
1696 .info = aureon_ac97_mmute_info,
1697 .get = aureon_ac97_mmute_get,
1698 .put = aureon_ac97_mmute_put,
1699 .private_value = AC97_MASTER
1702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1703 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1704 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1705 .name = "AC97 Playback Volume",
1706 .info = aureon_ac97_vol_info,
1707 .get = aureon_ac97_vol_get,
1708 .put = aureon_ac97_vol_put,
1709 .private_value = AC97_MASTER|AUREON_AC97_STEREO,
1710 .tlv = { .p = db_scale_ac97_master }
1713 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1714 .name = "CD Playback Switch",
1715 .info = aureon_ac97_mute_info,
1716 .get = aureon_ac97_mute_get,
1717 .put = aureon_ac97_mute_put,
1718 .private_value = AC97_AUX
1721 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1722 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1723 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1724 .name = "CD Playback Volume",
1725 .info = aureon_ac97_vol_info,
1726 .get = aureon_ac97_vol_get,
1727 .put = aureon_ac97_vol_put,
1728 .private_value = AC97_AUX|AUREON_AC97_STEREO,
1729 .tlv = { .p = db_scale_ac97_gain }
1732 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1733 .name = "Phono Playback Switch",
1734 .info = aureon_ac97_mute_info,
1735 .get = aureon_ac97_mute_get,
1736 .put = aureon_ac97_mute_put,
1737 .private_value = AC97_CD
1740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1741 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1742 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1743 .name = "Phono Playback Volume",
1744 .info = aureon_ac97_vol_info,
1745 .get = aureon_ac97_vol_get,
1746 .put = aureon_ac97_vol_put,
1747 .private_value = AC97_CD|AUREON_AC97_STEREO,
1748 .tlv = { .p = db_scale_ac97_gain }
1751 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1752 .name = "Line Playback Switch",
1753 .info = aureon_ac97_mute_info,
1754 .get = aureon_ac97_mute_get,
1755 .put = aureon_ac97_mute_put,
1756 .private_value = AC97_LINE
1759 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1760 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1761 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1762 .name = "Line Playback Volume",
1763 .info = aureon_ac97_vol_info,
1764 .get = aureon_ac97_vol_get,
1765 .put = aureon_ac97_vol_put,
1766 .private_value = AC97_LINE|AUREON_AC97_STEREO,
1767 .tlv = { .p = db_scale_ac97_gain }
1770 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1771 .name = "Mic Playback Switch",
1772 .info = aureon_ac97_mute_info,
1773 .get = aureon_ac97_mute_get,
1774 .put = aureon_ac97_mute_put,
1775 .private_value = AC97_MIC
1778 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1779 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1780 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1781 .name = "Mic Playback Volume",
1782 .info = aureon_ac97_vol_info,
1783 .get = aureon_ac97_vol_get,
1784 .put = aureon_ac97_vol_put,
1785 .private_value = AC97_MIC,
1786 .tlv = { .p = db_scale_ac97_gain }
1789 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1790 .name = "Mic Boost (+20dB)",
1791 .info = aureon_ac97_micboost_info,
1792 .get = aureon_ac97_micboost_get,
1793 .put = aureon_ac97_micboost_put
1796 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1797 .name = "Aux Playback Switch",
1798 .info = aureon_ac97_mute_info,
1799 .get = aureon_ac97_mute_get,
1800 .put = aureon_ac97_mute_put,
1801 .private_value = AC97_VIDEO,
1804 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1805 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1806 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1807 .name = "Aux Playback Volume",
1808 .info = aureon_ac97_vol_info,
1809 .get = aureon_ac97_vol_get,
1810 .put = aureon_ac97_vol_put,
1811 .private_value = AC97_VIDEO|AUREON_AC97_STEREO,
1812 .tlv = { .p = db_scale_ac97_gain }
1815 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1816 .name = "Aux Source",
1817 .info = aureon_universe_inmux_info,
1818 .get = aureon_universe_inmux_get,
1819 .put = aureon_universe_inmux_put
1824 static struct snd_kcontrol_new cs8415_controls[] = {
1826 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1827 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
1828 .info = aureon_cs8415_mute_info,
1829 .get = aureon_cs8415_mute_get,
1830 .put = aureon_cs8415_mute_put
1833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1834 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Source",
1835 .info = aureon_cs8415_mux_info,
1836 .get = aureon_cs8415_mux_get,
1837 .put = aureon_cs8415_mux_put,
1840 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1841 .name = SNDRV_CTL_NAME_IEC958("Q-subcode ", CAPTURE, DEFAULT),
1842 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1843 .info = aureon_cs8415_qsub_info,
1844 .get = aureon_cs8415_qsub_get,
1847 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1848 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
1849 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1850 .info = aureon_cs8415_spdif_info,
1851 .get = aureon_cs8415_mask_get
1854 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1855 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
1856 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1857 .info = aureon_cs8415_spdif_info,
1858 .get = aureon_cs8415_spdif_get
1861 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1862 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Rate",
1863 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1864 .info = aureon_cs8415_rate_info,
1865 .get = aureon_cs8415_rate_get
1869 static int aureon_add_controls(struct snd_ice1712 *ice)
1871 unsigned int i, counts;
1872 int err;
1874 counts = ARRAY_SIZE(aureon_dac_controls);
1875 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
1876 counts -= 2; /* no side */
1877 for (i = 0; i < counts; i++) {
1878 err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
1879 if (err < 0)
1880 return err;
1883 for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
1884 err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
1885 if (err < 0)
1886 return err;
1889 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1890 for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
1891 err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
1892 if (err < 0)
1893 return err;
1895 } else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1896 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1897 for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
1898 err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
1899 if (err < 0)
1900 return err;
1904 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1905 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1906 unsigned char id;
1907 snd_ice1712_save_gpio_status(ice);
1908 id = aureon_cs8415_get(ice, CS8415_ID);
1909 if (id != 0x41)
1910 dev_info(ice->card->dev,
1911 "No CS8415 chip. Skipping CS8415 controls.\n");
1912 else if ((id & 0x0F) != 0x01)
1913 dev_info(ice->card->dev,
1914 "Detected unsupported CS8415 rev. (%c)\n",
1915 (char)((id & 0x0F) + 'A' - 1));
1916 else {
1917 for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
1918 struct snd_kcontrol *kctl;
1919 err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
1920 if (err < 0)
1921 return err;
1922 if (i > 1)
1923 kctl->id.device = ice->pcm->device;
1926 snd_ice1712_restore_gpio_status(ice);
1929 return 0;
1933 * reset the chip
1935 static int aureon_reset(struct snd_ice1712 *ice)
1937 static const unsigned short wm_inits_aureon[] = {
1938 /* These come first to reduce init pop noise */
1939 0x1b, 0x044, /* ADC Mux (AC'97 source) */
1940 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
1941 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
1943 0x18, 0x000, /* All power-up */
1945 0x16, 0x122, /* I2S, normal polarity, 24bit */
1946 0x17, 0x022, /* 256fs, slave mode */
1947 0x00, 0, /* DAC1 analog mute */
1948 0x01, 0, /* DAC2 analog mute */
1949 0x02, 0, /* DAC3 analog mute */
1950 0x03, 0, /* DAC4 analog mute */
1951 0x04, 0, /* DAC5 analog mute */
1952 0x05, 0, /* DAC6 analog mute */
1953 0x06, 0, /* DAC7 analog mute */
1954 0x07, 0, /* DAC8 analog mute */
1955 0x08, 0x100, /* master analog mute */
1956 0x09, 0xff, /* DAC1 digital full */
1957 0x0a, 0xff, /* DAC2 digital full */
1958 0x0b, 0xff, /* DAC3 digital full */
1959 0x0c, 0xff, /* DAC4 digital full */
1960 0x0d, 0xff, /* DAC5 digital full */
1961 0x0e, 0xff, /* DAC6 digital full */
1962 0x0f, 0xff, /* DAC7 digital full */
1963 0x10, 0xff, /* DAC8 digital full */
1964 0x11, 0x1ff, /* master digital full */
1965 0x12, 0x000, /* phase normal */
1966 0x13, 0x090, /* unmute DAC L/R */
1967 0x14, 0x000, /* all unmute */
1968 0x15, 0x000, /* no deemphasis, no ZFLG */
1969 0x19, 0x000, /* -12dB ADC/L */
1970 0x1a, 0x000, /* -12dB ADC/R */
1971 (unsigned short)-1
1973 static const unsigned short wm_inits_prodigy[] = {
1975 /* These come first to reduce init pop noise */
1976 0x1b, 0x000, /* ADC Mux */
1977 0x1c, 0x009, /* Out Mux1 */
1978 0x1d, 0x009, /* Out Mux2 */
1980 0x18, 0x000, /* All power-up */
1982 0x16, 0x022, /* I2S, normal polarity, 24bit, high-pass on */
1983 0x17, 0x006, /* 128fs, slave mode */
1985 0x00, 0, /* DAC1 analog mute */
1986 0x01, 0, /* DAC2 analog mute */
1987 0x02, 0, /* DAC3 analog mute */
1988 0x03, 0, /* DAC4 analog mute */
1989 0x04, 0, /* DAC5 analog mute */
1990 0x05, 0, /* DAC6 analog mute */
1991 0x06, 0, /* DAC7 analog mute */
1992 0x07, 0, /* DAC8 analog mute */
1993 0x08, 0x100, /* master analog mute */
1995 0x09, 0x7f, /* DAC1 digital full */
1996 0x0a, 0x7f, /* DAC2 digital full */
1997 0x0b, 0x7f, /* DAC3 digital full */
1998 0x0c, 0x7f, /* DAC4 digital full */
1999 0x0d, 0x7f, /* DAC5 digital full */
2000 0x0e, 0x7f, /* DAC6 digital full */
2001 0x0f, 0x7f, /* DAC7 digital full */
2002 0x10, 0x7f, /* DAC8 digital full */
2003 0x11, 0x1FF, /* master digital full */
2005 0x12, 0x000, /* phase normal */
2006 0x13, 0x090, /* unmute DAC L/R */
2007 0x14, 0x000, /* all unmute */
2008 0x15, 0x000, /* no deemphasis, no ZFLG */
2010 0x19, 0x000, /* -12dB ADC/L */
2011 0x1a, 0x000, /* -12dB ADC/R */
2012 (unsigned short)-1
2015 static const unsigned short cs_inits[] = {
2016 0x0441, /* RUN */
2017 0x0180, /* no mute, OMCK output on RMCK pin */
2018 0x0201, /* S/PDIF source on RXP1 */
2019 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
2020 (unsigned short)-1
2022 unsigned int tmp;
2023 const unsigned short *p;
2024 int err;
2025 struct aureon_spec *spec = ice->spec;
2027 err = aureon_ac97_init(ice);
2028 if (err != 0)
2029 return err;
2031 snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
2033 /* reset the wm codec as the SPI mode */
2034 snd_ice1712_save_gpio_status(ice);
2035 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
2037 tmp = snd_ice1712_gpio_read(ice);
2038 tmp &= ~AUREON_WM_RESET;
2039 snd_ice1712_gpio_write(ice, tmp);
2040 udelay(1);
2041 tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
2042 snd_ice1712_gpio_write(ice, tmp);
2043 udelay(1);
2044 tmp |= AUREON_WM_RESET;
2045 snd_ice1712_gpio_write(ice, tmp);
2046 udelay(1);
2048 /* initialize WM8770 codec */
2049 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
2050 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
2051 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT)
2052 p = wm_inits_prodigy;
2053 else
2054 p = wm_inits_aureon;
2055 for (; *p != (unsigned short)-1; p += 2)
2056 wm_put(ice, p[0], p[1]);
2058 /* initialize CS8415A codec */
2059 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
2060 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
2061 for (p = cs_inits; *p != (unsigned short)-1; p++)
2062 aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
2063 spec->cs8415_mux = 1;
2065 aureon_set_headphone_amp(ice, 1);
2068 snd_ice1712_restore_gpio_status(ice);
2070 /* initialize PCA9554 pin directions & set default input */
2071 aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2072 aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */
2073 return 0;
2077 * suspend/resume
2079 #ifdef CONFIG_PM_SLEEP
2080 static int aureon_resume(struct snd_ice1712 *ice)
2082 struct aureon_spec *spec = ice->spec;
2083 int err, i;
2085 err = aureon_reset(ice);
2086 if (err != 0)
2087 return err;
2089 /* workaround for poking volume with alsamixer after resume:
2090 * just set stored volume again */
2091 for (i = 0; i < ice->num_total_dacs; i++)
2092 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2093 return 0;
2095 #endif
2098 * initialize the chip
2100 static int aureon_init(struct snd_ice1712 *ice)
2102 struct aureon_spec *spec;
2103 int i, err;
2105 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2106 if (!spec)
2107 return -ENOMEM;
2108 ice->spec = spec;
2110 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
2111 ice->num_total_dacs = 6;
2112 ice->num_total_adcs = 2;
2113 } else {
2114 /* aureon 7.1 and prodigy 7.1 */
2115 ice->num_total_dacs = 8;
2116 ice->num_total_adcs = 2;
2119 /* to remember the register values of CS8415 */
2120 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2121 if (!ice->akm)
2122 return -ENOMEM;
2123 ice->akm_codecs = 1;
2125 err = aureon_reset(ice);
2126 if (err != 0)
2127 return err;
2129 spec->master[0] = WM_VOL_MUTE;
2130 spec->master[1] = WM_VOL_MUTE;
2131 for (i = 0; i < ice->num_total_dacs; i++) {
2132 spec->vol[i] = WM_VOL_MUTE;
2133 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2136 #ifdef CONFIG_PM_SLEEP
2137 ice->pm_resume = aureon_resume;
2138 ice->pm_suspend_enabled = 1;
2139 #endif
2141 return 0;
2146 * Aureon boards don't provide the EEPROM data except for the vendor IDs.
2147 * hence the driver needs to sets up it properly.
2150 static unsigned char aureon51_eeprom[] = {
2151 [ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */
2152 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2153 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2154 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2155 [ICE_EEP2_GPIO_DIR] = 0xff,
2156 [ICE_EEP2_GPIO_DIR1] = 0xff,
2157 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2158 [ICE_EEP2_GPIO_MASK] = 0x00,
2159 [ICE_EEP2_GPIO_MASK1] = 0x00,
2160 [ICE_EEP2_GPIO_MASK2] = 0x00,
2161 [ICE_EEP2_GPIO_STATE] = 0x00,
2162 [ICE_EEP2_GPIO_STATE1] = 0x00,
2163 [ICE_EEP2_GPIO_STATE2] = 0x00,
2166 static unsigned char aureon71_eeprom[] = {
2167 [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */
2168 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2169 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2170 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2171 [ICE_EEP2_GPIO_DIR] = 0xff,
2172 [ICE_EEP2_GPIO_DIR1] = 0xff,
2173 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2174 [ICE_EEP2_GPIO_MASK] = 0x00,
2175 [ICE_EEP2_GPIO_MASK1] = 0x00,
2176 [ICE_EEP2_GPIO_MASK2] = 0x00,
2177 [ICE_EEP2_GPIO_STATE] = 0x00,
2178 [ICE_EEP2_GPIO_STATE1] = 0x00,
2179 [ICE_EEP2_GPIO_STATE2] = 0x00,
2181 #define prodigy71_eeprom aureon71_eeprom
2183 static unsigned char aureon71_universe_eeprom[] = {
2184 [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC,
2185 * 4DACs
2187 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2188 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2189 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2190 [ICE_EEP2_GPIO_DIR] = 0xff,
2191 [ICE_EEP2_GPIO_DIR1] = 0xff,
2192 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2193 [ICE_EEP2_GPIO_MASK] = 0x00,
2194 [ICE_EEP2_GPIO_MASK1] = 0x00,
2195 [ICE_EEP2_GPIO_MASK2] = 0x00,
2196 [ICE_EEP2_GPIO_STATE] = 0x00,
2197 [ICE_EEP2_GPIO_STATE1] = 0x00,
2198 [ICE_EEP2_GPIO_STATE2] = 0x00,
2201 static unsigned char prodigy71lt_eeprom[] = {
2202 [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */
2203 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2204 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2205 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2206 [ICE_EEP2_GPIO_DIR] = 0xff,
2207 [ICE_EEP2_GPIO_DIR1] = 0xff,
2208 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2209 [ICE_EEP2_GPIO_MASK] = 0x00,
2210 [ICE_EEP2_GPIO_MASK1] = 0x00,
2211 [ICE_EEP2_GPIO_MASK2] = 0x00,
2212 [ICE_EEP2_GPIO_STATE] = 0x00,
2213 [ICE_EEP2_GPIO_STATE1] = 0x00,
2214 [ICE_EEP2_GPIO_STATE2] = 0x00,
2216 #define prodigy71xt_eeprom prodigy71lt_eeprom
2218 /* entry point */
2219 struct snd_ice1712_card_info snd_vt1724_aureon_cards[] = {
2221 .subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
2222 .name = "Terratec Aureon 5.1-Sky",
2223 .model = "aureon51",
2224 .chip_init = aureon_init,
2225 .build_controls = aureon_add_controls,
2226 .eeprom_size = sizeof(aureon51_eeprom),
2227 .eeprom_data = aureon51_eeprom,
2228 .driver = "Aureon51",
2231 .subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
2232 .name = "Terratec Aureon 7.1-Space",
2233 .model = "aureon71",
2234 .chip_init = aureon_init,
2235 .build_controls = aureon_add_controls,
2236 .eeprom_size = sizeof(aureon71_eeprom),
2237 .eeprom_data = aureon71_eeprom,
2238 .driver = "Aureon71",
2241 .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
2242 .name = "Terratec Aureon 7.1-Universe",
2243 .model = "universe",
2244 .chip_init = aureon_init,
2245 .build_controls = aureon_add_controls,
2246 .eeprom_size = sizeof(aureon71_universe_eeprom),
2247 .eeprom_data = aureon71_universe_eeprom,
2248 .driver = "Aureon71Univ", /* keep in 15 letters */
2251 .subvendor = VT1724_SUBDEVICE_PRODIGY71,
2252 .name = "Audiotrak Prodigy 7.1",
2253 .model = "prodigy71",
2254 .chip_init = aureon_init,
2255 .build_controls = aureon_add_controls,
2256 .eeprom_size = sizeof(prodigy71_eeprom),
2257 .eeprom_data = prodigy71_eeprom,
2258 .driver = "Prodigy71", /* should be identical with Aureon71 */
2261 .subvendor = VT1724_SUBDEVICE_PRODIGY71LT,
2262 .name = "Audiotrak Prodigy 7.1 LT",
2263 .model = "prodigy71lt",
2264 .chip_init = aureon_init,
2265 .build_controls = aureon_add_controls,
2266 .eeprom_size = sizeof(prodigy71lt_eeprom),
2267 .eeprom_data = prodigy71lt_eeprom,
2268 .driver = "Prodigy71LT",
2271 .subvendor = VT1724_SUBDEVICE_PRODIGY71XT,
2272 .name = "Audiotrak Prodigy 7.1 XT",
2273 .model = "prodigy71xt",
2274 .chip_init = aureon_init,
2275 .build_controls = aureon_add_controls,
2276 .eeprom_size = sizeof(prodigy71xt_eeprom),
2277 .eeprom_data = prodigy71xt_eeprom,
2278 .driver = "Prodigy71LT",
2280 { } /* terminator */