WIP FPC-III support
[linux/fpc-iii.git] / sound / pci / ice1712 / aureon.c
blob9a30f6d35d1358e31282002bc07d2d276b3c65e1
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
5 * Lowlevel functions for Terratec Aureon cards
7 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
9 * NOTES:
11 * - we reuse the struct snd_akm4xxx record for storing the wm8770 codec data.
12 * both wm and akm codecs are pretty similar, so we can integrate
13 * both controls in the future, once if wm codecs are reused in
14 * many boards.
16 * - DAC digital volumes are not implemented in the mixer.
17 * if they show better response than DAC analog volumes, we can use them
18 * instead.
20 * Lowlevel functions for AudioTrak Prodigy 7.1 (and possibly 192) cards
21 * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
23 * version 0.82: Stable / not all features work yet (no communication with AC97 secondary)
24 * added 64x/128x oversampling switch (should be 64x only for 96khz)
25 * fixed some recording labels (still need to check the rest)
26 * recording is working probably thanks to correct wm8770 initialization
28 * version 0.5: Initial release:
29 * working: analog output, mixer, headphone amplifier switch
30 * not working: prety much everything else, at least i could verify that
31 * we have no digital output, no capture, pretty bad clicks and poops
32 * on mixer switch and other coll stuff.
35 #include <linux/delay.h>
36 #include <linux/interrupt.h>
37 #include <linux/init.h>
38 #include <linux/slab.h>
39 #include <linux/mutex.h>
41 #include <sound/core.h>
43 #include "ice1712.h"
44 #include "envy24ht.h"
45 #include "aureon.h"
46 #include <sound/tlv.h>
48 /* AC97 register cache for Aureon */
49 struct aureon_spec {
50 unsigned short stac9744[64];
51 unsigned int cs8415_mux;
52 unsigned short master[2];
53 unsigned short vol[8];
54 unsigned char pca9554_out;
57 /* WM8770 registers */
58 #define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
59 #define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */
60 #define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */
61 #define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */
62 #define WM_PHASE_SWAP 0x12 /* DAC phase */
63 #define WM_DAC_CTRL1 0x13 /* DAC control bits */
64 #define WM_MUTE 0x14 /* mute controls */
65 #define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */
66 #define WM_INT_CTRL 0x16 /* interface control */
67 #define WM_MASTER 0x17 /* master clock and mode */
68 #define WM_POWERDOWN 0x18 /* power-down controls */
69 #define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */
70 #define WM_ADC_MUX 0x1b /* input MUX */
71 #define WM_OUT_MUX1 0x1c /* output MUX */
72 #define WM_OUT_MUX2 0x1e /* output MUX */
73 #define WM_RESET 0x1f /* software reset */
75 /* CS8415A registers */
76 #define CS8415_CTRL1 0x01
77 #define CS8415_CTRL2 0x02
78 #define CS8415_QSUB 0x14
79 #define CS8415_RATIO 0x1E
80 #define CS8415_C_BUFFER 0x20
81 #define CS8415_ID 0x7F
83 /* PCA9554 registers */
84 #define PCA9554_DEV 0x40 /* I2C device address */
85 #define PCA9554_IN 0x00 /* input port */
86 #define PCA9554_OUT 0x01 /* output port */
87 #define PCA9554_INVERT 0x02 /* input invert */
88 #define PCA9554_DIR 0x03 /* port directions */
91 * Aureon Universe additional controls using PCA9554
95 * Send data to pca9554
97 static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
98 unsigned char data)
100 unsigned int tmp;
101 int i, j;
102 unsigned char dev = PCA9554_DEV; /* ID 0100000, write */
103 unsigned char val = 0;
105 tmp = snd_ice1712_gpio_read(ice);
107 snd_ice1712_gpio_set_mask(ice, ~(AUREON_SPI_MOSI|AUREON_SPI_CLK|
108 AUREON_WM_RW|AUREON_WM_CS|
109 AUREON_CS8415_CS));
110 tmp |= AUREON_WM_RW;
111 tmp |= AUREON_CS8415_CS | AUREON_WM_CS; /* disable SPI devices */
113 tmp &= ~AUREON_SPI_MOSI;
114 tmp &= ~AUREON_SPI_CLK;
115 snd_ice1712_gpio_write(ice, tmp);
116 udelay(50);
119 * send i2c stop condition and start condition
120 * to obtain sane state
122 tmp |= AUREON_SPI_CLK;
123 snd_ice1712_gpio_write(ice, tmp);
124 udelay(50);
125 tmp |= AUREON_SPI_MOSI;
126 snd_ice1712_gpio_write(ice, tmp);
127 udelay(100);
128 tmp &= ~AUREON_SPI_MOSI;
129 snd_ice1712_gpio_write(ice, tmp);
130 udelay(50);
131 tmp &= ~AUREON_SPI_CLK;
132 snd_ice1712_gpio_write(ice, tmp);
133 udelay(100);
135 * send device address, command and value,
136 * skipping ack cycles in between
138 for (j = 0; j < 3; j++) {
139 switch (j) {
140 case 0:
141 val = dev;
142 break;
143 case 1:
144 val = reg;
145 break;
146 case 2:
147 val = data;
148 break;
150 for (i = 7; i >= 0; i--) {
151 tmp &= ~AUREON_SPI_CLK;
152 snd_ice1712_gpio_write(ice, tmp);
153 udelay(40);
154 if (val & (1 << i))
155 tmp |= AUREON_SPI_MOSI;
156 else
157 tmp &= ~AUREON_SPI_MOSI;
158 snd_ice1712_gpio_write(ice, tmp);
159 udelay(40);
160 tmp |= AUREON_SPI_CLK;
161 snd_ice1712_gpio_write(ice, tmp);
162 udelay(40);
164 tmp &= ~AUREON_SPI_CLK;
165 snd_ice1712_gpio_write(ice, tmp);
166 udelay(40);
167 tmp |= AUREON_SPI_CLK;
168 snd_ice1712_gpio_write(ice, tmp);
169 udelay(40);
170 tmp &= ~AUREON_SPI_CLK;
171 snd_ice1712_gpio_write(ice, tmp);
172 udelay(40);
174 tmp &= ~AUREON_SPI_CLK;
175 snd_ice1712_gpio_write(ice, tmp);
176 udelay(40);
177 tmp &= ~AUREON_SPI_MOSI;
178 snd_ice1712_gpio_write(ice, tmp);
179 udelay(40);
180 tmp |= AUREON_SPI_CLK;
181 snd_ice1712_gpio_write(ice, tmp);
182 udelay(50);
183 tmp |= AUREON_SPI_MOSI;
184 snd_ice1712_gpio_write(ice, tmp);
185 udelay(100);
188 static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,
189 struct snd_ctl_elem_info *uinfo)
191 static const char * const texts[3] =
192 {"Internal Aux", "Wavetable", "Rear Line-In"};
194 return snd_ctl_enum_info(uinfo, 1, 3, texts);
197 static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol,
198 struct snd_ctl_elem_value *ucontrol)
200 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
201 struct aureon_spec *spec = ice->spec;
202 ucontrol->value.enumerated.item[0] = spec->pca9554_out;
203 return 0;
206 static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
207 struct snd_ctl_elem_value *ucontrol)
209 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
210 struct aureon_spec *spec = ice->spec;
211 unsigned char oval, nval;
212 int change;
214 nval = ucontrol->value.enumerated.item[0];
215 if (nval >= 3)
216 return -EINVAL;
217 snd_ice1712_save_gpio_status(ice);
218 oval = spec->pca9554_out;
219 change = (oval != nval);
220 if (change) {
221 aureon_pca9554_write(ice, PCA9554_OUT, nval);
222 spec->pca9554_out = nval;
224 snd_ice1712_restore_gpio_status(ice);
225 return change;
229 static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
230 unsigned short val)
232 struct aureon_spec *spec = ice->spec;
233 unsigned int tmp;
235 /* Send address to XILINX chip */
236 tmp = (snd_ice1712_gpio_read(ice) & ~0xFF) | (reg & 0x7F);
237 snd_ice1712_gpio_write(ice, tmp);
238 udelay(10);
239 tmp |= AUREON_AC97_ADDR;
240 snd_ice1712_gpio_write(ice, tmp);
241 udelay(10);
242 tmp &= ~AUREON_AC97_ADDR;
243 snd_ice1712_gpio_write(ice, tmp);
244 udelay(10);
246 /* Send low-order byte to XILINX chip */
247 tmp &= ~AUREON_AC97_DATA_MASK;
248 tmp |= val & AUREON_AC97_DATA_MASK;
249 snd_ice1712_gpio_write(ice, tmp);
250 udelay(10);
251 tmp |= AUREON_AC97_DATA_LOW;
252 snd_ice1712_gpio_write(ice, tmp);
253 udelay(10);
254 tmp &= ~AUREON_AC97_DATA_LOW;
255 snd_ice1712_gpio_write(ice, tmp);
256 udelay(10);
258 /* Send high-order byte to XILINX chip */
259 tmp &= ~AUREON_AC97_DATA_MASK;
260 tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
262 snd_ice1712_gpio_write(ice, tmp);
263 udelay(10);
264 tmp |= AUREON_AC97_DATA_HIGH;
265 snd_ice1712_gpio_write(ice, tmp);
266 udelay(10);
267 tmp &= ~AUREON_AC97_DATA_HIGH;
268 snd_ice1712_gpio_write(ice, tmp);
269 udelay(10);
271 /* Instruct XILINX chip to parse the data to the STAC9744 chip */
272 tmp |= AUREON_AC97_COMMIT;
273 snd_ice1712_gpio_write(ice, tmp);
274 udelay(10);
275 tmp &= ~AUREON_AC97_COMMIT;
276 snd_ice1712_gpio_write(ice, tmp);
277 udelay(10);
279 /* Store the data in out private buffer */
280 spec->stac9744[(reg & 0x7F) >> 1] = val;
283 static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short reg)
285 struct aureon_spec *spec = ice->spec;
286 return spec->stac9744[(reg & 0x7F) >> 1];
290 * Initialize STAC9744 chip
292 static int aureon_ac97_init(struct snd_ice1712 *ice)
294 struct aureon_spec *spec = ice->spec;
295 int i;
296 static const unsigned short ac97_defaults[] = {
297 0x00, 0x9640,
298 0x02, 0x8000,
299 0x04, 0x8000,
300 0x06, 0x8000,
301 0x0C, 0x8008,
302 0x0E, 0x8008,
303 0x10, 0x8808,
304 0x12, 0x8808,
305 0x14, 0x8808,
306 0x16, 0x8808,
307 0x18, 0x8808,
308 0x1C, 0x8000,
309 0x26, 0x000F,
310 0x28, 0x0201,
311 0x2C, 0xBB80,
312 0x32, 0xBB80,
313 0x7C, 0x8384,
314 0x7E, 0x7644,
315 (unsigned short)-1
317 unsigned int tmp;
319 /* Cold reset */
320 tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
321 snd_ice1712_gpio_write(ice, tmp);
322 udelay(3);
324 tmp &= ~AUREON_AC97_RESET;
325 snd_ice1712_gpio_write(ice, tmp);
326 udelay(3);
328 tmp |= AUREON_AC97_RESET;
329 snd_ice1712_gpio_write(ice, tmp);
330 udelay(3);
332 memset(&spec->stac9744, 0, sizeof(spec->stac9744));
333 for (i = 0; ac97_defaults[i] != (unsigned short)-1; i += 2)
334 spec->stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
336 /* Unmute AC'97 master volume permanently - muting is done by WM8770 */
337 aureon_ac97_write(ice, AC97_MASTER, 0x0000);
339 return 0;
342 #define AUREON_AC97_STEREO 0x80
345 * AC'97 volume controls
347 static int aureon_ac97_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
349 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
350 uinfo->count = kcontrol->private_value & AUREON_AC97_STEREO ? 2 : 1;
351 uinfo->value.integer.min = 0;
352 uinfo->value.integer.max = 31;
353 return 0;
356 static int aureon_ac97_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
358 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
359 unsigned short vol;
361 mutex_lock(&ice->gpio_mutex);
363 vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
364 ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F);
365 if (kcontrol->private_value & AUREON_AC97_STEREO)
366 ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F);
368 mutex_unlock(&ice->gpio_mutex);
369 return 0;
372 static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
374 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
375 unsigned short ovol, nvol;
376 int change;
378 snd_ice1712_save_gpio_status(ice);
380 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
381 nvol = (0x1F - ucontrol->value.integer.value[0]) & 0x001F;
382 if (kcontrol->private_value & AUREON_AC97_STEREO)
383 nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00;
384 nvol |= ovol & ~0x1F1F;
386 change = (ovol != nvol);
387 if (change)
388 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
390 snd_ice1712_restore_gpio_status(ice);
392 return change;
396 * AC'97 mute controls
398 #define aureon_ac97_mute_info snd_ctl_boolean_mono_info
400 static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
402 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
404 mutex_lock(&ice->gpio_mutex);
406 ucontrol->value.integer.value[0] = aureon_ac97_read(ice,
407 kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
409 mutex_unlock(&ice->gpio_mutex);
410 return 0;
413 static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
415 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
416 unsigned short ovol, nvol;
417 int change;
419 snd_ice1712_save_gpio_status(ice);
421 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
422 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~0x8000);
424 change = (ovol != nvol);
425 if (change)
426 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
428 snd_ice1712_restore_gpio_status(ice);
430 return change;
434 * AC'97 mute controls
436 #define aureon_ac97_micboost_info snd_ctl_boolean_mono_info
438 static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
440 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
442 mutex_lock(&ice->gpio_mutex);
444 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
446 mutex_unlock(&ice->gpio_mutex);
447 return 0;
450 static int aureon_ac97_micboost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
452 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
453 unsigned short ovol, nvol;
454 int change;
456 snd_ice1712_save_gpio_status(ice);
458 ovol = aureon_ac97_read(ice, AC97_MIC);
459 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020);
461 change = (ovol != nvol);
462 if (change)
463 aureon_ac97_write(ice, AC97_MIC, nvol);
465 snd_ice1712_restore_gpio_status(ice);
467 return change;
471 * write data in the SPI mode
473 static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits)
475 unsigned int tmp;
476 int i;
477 unsigned int mosi, clk;
479 tmp = snd_ice1712_gpio_read(ice);
481 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
482 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) {
483 snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS));
484 mosi = PRODIGY_SPI_MOSI;
485 clk = PRODIGY_SPI_CLK;
486 } else {
487 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
488 AUREON_WM_CS|AUREON_CS8415_CS));
489 mosi = AUREON_SPI_MOSI;
490 clk = AUREON_SPI_CLK;
492 tmp |= AUREON_WM_RW;
495 tmp &= ~cs;
496 snd_ice1712_gpio_write(ice, tmp);
497 udelay(1);
499 for (i = bits - 1; i >= 0; i--) {
500 tmp &= ~clk;
501 snd_ice1712_gpio_write(ice, tmp);
502 udelay(1);
503 if (data & (1 << i))
504 tmp |= mosi;
505 else
506 tmp &= ~mosi;
507 snd_ice1712_gpio_write(ice, tmp);
508 udelay(1);
509 tmp |= clk;
510 snd_ice1712_gpio_write(ice, tmp);
511 udelay(1);
514 tmp &= ~clk;
515 tmp |= cs;
516 snd_ice1712_gpio_write(ice, tmp);
517 udelay(1);
518 tmp |= clk;
519 snd_ice1712_gpio_write(ice, tmp);
520 udelay(1);
524 * Read data in SPI mode
526 static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs,
527 unsigned int data, int bits, unsigned char *buffer, int size)
529 int i, j;
530 unsigned int tmp;
532 tmp = (snd_ice1712_gpio_read(ice) & ~AUREON_SPI_CLK) | AUREON_CS8415_CS|AUREON_WM_CS;
533 snd_ice1712_gpio_write(ice, tmp);
534 tmp &= ~cs;
535 snd_ice1712_gpio_write(ice, tmp);
536 udelay(1);
538 for (i = bits-1; i >= 0; i--) {
539 if (data & (1 << i))
540 tmp |= AUREON_SPI_MOSI;
541 else
542 tmp &= ~AUREON_SPI_MOSI;
543 snd_ice1712_gpio_write(ice, tmp);
544 udelay(1);
546 tmp |= AUREON_SPI_CLK;
547 snd_ice1712_gpio_write(ice, tmp);
548 udelay(1);
550 tmp &= ~AUREON_SPI_CLK;
551 snd_ice1712_gpio_write(ice, tmp);
552 udelay(1);
555 for (j = 0; j < size; j++) {
556 unsigned char outdata = 0;
557 for (i = 7; i >= 0; i--) {
558 tmp = snd_ice1712_gpio_read(ice);
559 outdata <<= 1;
560 outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0;
561 udelay(1);
563 tmp |= AUREON_SPI_CLK;
564 snd_ice1712_gpio_write(ice, tmp);
565 udelay(1);
567 tmp &= ~AUREON_SPI_CLK;
568 snd_ice1712_gpio_write(ice, tmp);
569 udelay(1);
571 buffer[j] = outdata;
574 tmp |= cs;
575 snd_ice1712_gpio_write(ice, tmp);
578 static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg)
580 unsigned char val;
581 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
582 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1);
583 return val;
586 static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg,
587 unsigned char *buffer, int size)
589 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
590 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size);
593 static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg,
594 unsigned char val)
596 aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24);
600 * get the current register value of WM codec
602 static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
604 reg <<= 1;
605 return ((unsigned short)ice->akm[0].images[reg] << 8) |
606 ice->akm[0].images[reg + 1];
610 * set the register value of WM codec
612 static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
614 aureon_spi_write(ice,
615 ((ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
616 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) ?
617 PRODIGY_WM_CS : AUREON_WM_CS),
618 (reg << 9) | (val & 0x1ff), 16);
622 * set the register value of WM codec and remember it
624 static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
626 wm_put_nocache(ice, reg, val);
627 reg <<= 1;
628 ice->akm[0].images[reg] = val >> 8;
629 ice->akm[0].images[reg + 1] = val;
634 #define aureon_mono_bool_info snd_ctl_boolean_mono_info
637 * AC'97 master playback mute controls (Mute on WM8770 chip)
639 #define aureon_ac97_mmute_info snd_ctl_boolean_mono_info
641 static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
643 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
645 mutex_lock(&ice->gpio_mutex);
647 ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
649 mutex_unlock(&ice->gpio_mutex);
650 return 0;
653 static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
655 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
656 unsigned short ovol, nvol;
657 int change;
659 snd_ice1712_save_gpio_status(ice);
661 ovol = wm_get(ice, WM_OUT_MUX1);
662 nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00);
663 change = (ovol != nvol);
664 if (change)
665 wm_put(ice, WM_OUT_MUX1, nvol);
667 snd_ice1712_restore_gpio_status(ice);
669 return change;
672 static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -10000, 100, 1);
673 static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
674 static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0);
675 static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0);
676 static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0);
678 #define WM_VOL_MAX 100
679 #define WM_VOL_CNT 101 /* 0dB .. -100dB */
680 #define WM_VOL_MUTE 0x8000
682 static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
684 unsigned char nvol;
686 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) {
687 nvol = 0;
688 } else {
689 nvol = ((vol % WM_VOL_CNT) * (master % WM_VOL_CNT)) /
690 WM_VOL_MAX;
691 nvol += 0x1b;
694 wm_put(ice, index, nvol);
695 wm_put_nocache(ice, index, 0x180 | nvol);
699 * DAC mute control
701 #define wm_pcm_mute_info snd_ctl_boolean_mono_info
703 static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
705 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
707 mutex_lock(&ice->gpio_mutex);
708 ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
709 mutex_unlock(&ice->gpio_mutex);
710 return 0;
713 static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
715 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
716 unsigned short nval, oval;
717 int change;
719 snd_ice1712_save_gpio_status(ice);
720 oval = wm_get(ice, WM_MUTE);
721 nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
722 change = (oval != nval);
723 if (change)
724 wm_put(ice, WM_MUTE, nval);
725 snd_ice1712_restore_gpio_status(ice);
727 return change;
731 * Master volume attenuation mixer control
733 static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
735 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
736 uinfo->count = 2;
737 uinfo->value.integer.min = 0;
738 uinfo->value.integer.max = WM_VOL_MAX;
739 return 0;
742 static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
744 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
745 struct aureon_spec *spec = ice->spec;
746 int i;
747 for (i = 0; i < 2; i++)
748 ucontrol->value.integer.value[i] =
749 spec->master[i] & ~WM_VOL_MUTE;
750 return 0;
753 static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
755 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
756 struct aureon_spec *spec = ice->spec;
757 int ch, change = 0;
759 snd_ice1712_save_gpio_status(ice);
760 for (ch = 0; ch < 2; ch++) {
761 unsigned int vol = ucontrol->value.integer.value[ch];
762 if (vol > WM_VOL_MAX)
763 vol = WM_VOL_MAX;
764 vol |= spec->master[ch] & WM_VOL_MUTE;
765 if (vol != spec->master[ch]) {
766 int dac;
767 spec->master[ch] = vol;
768 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
769 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
770 spec->vol[dac + ch],
771 spec->master[ch]);
772 change = 1;
775 snd_ice1712_restore_gpio_status(ice);
776 return change;
780 * DAC volume attenuation mixer control
782 static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
784 int voices = kcontrol->private_value >> 8;
785 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
786 uinfo->count = voices;
787 uinfo->value.integer.min = 0; /* mute (-101dB) */
788 uinfo->value.integer.max = WM_VOL_MAX; /* 0dB */
789 return 0;
792 static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
794 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
795 struct aureon_spec *spec = ice->spec;
796 int i, ofs, voices;
798 voices = kcontrol->private_value >> 8;
799 ofs = kcontrol->private_value & 0xff;
800 for (i = 0; i < voices; i++)
801 ucontrol->value.integer.value[i] =
802 spec->vol[ofs+i] & ~WM_VOL_MUTE;
803 return 0;
806 static int wm_vol_put(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, idx, ofs, voices;
811 int change = 0;
813 voices = kcontrol->private_value >> 8;
814 ofs = kcontrol->private_value & 0xff;
815 snd_ice1712_save_gpio_status(ice);
816 for (i = 0; i < voices; i++) {
817 unsigned int vol = ucontrol->value.integer.value[i];
818 if (vol > WM_VOL_MAX)
819 vol = WM_VOL_MAX;
820 vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
821 if (vol != spec->vol[ofs+i]) {
822 spec->vol[ofs+i] = vol;
823 idx = WM_DAC_ATTEN + ofs + i;
824 wm_set_vol(ice, idx, spec->vol[ofs + i],
825 spec->master[i]);
826 change = 1;
829 snd_ice1712_restore_gpio_status(ice);
830 return change;
834 * WM8770 mute control
836 static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
838 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
839 uinfo->count = kcontrol->private_value >> 8;
840 uinfo->value.integer.min = 0;
841 uinfo->value.integer.max = 1;
842 return 0;
845 static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
847 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
848 struct aureon_spec *spec = ice->spec;
849 int voices, ofs, i;
851 voices = kcontrol->private_value >> 8;
852 ofs = kcontrol->private_value & 0xFF;
854 for (i = 0; i < voices; i++)
855 ucontrol->value.integer.value[i] =
856 (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
857 return 0;
860 static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
862 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
863 struct aureon_spec *spec = ice->spec;
864 int change = 0, voices, ofs, i;
866 voices = kcontrol->private_value >> 8;
867 ofs = kcontrol->private_value & 0xFF;
869 snd_ice1712_save_gpio_status(ice);
870 for (i = 0; i < voices; i++) {
871 int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
872 if (ucontrol->value.integer.value[i] != val) {
873 spec->vol[ofs + i] &= ~WM_VOL_MUTE;
874 spec->vol[ofs + i] |=
875 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
876 wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
877 spec->master[i]);
878 change = 1;
881 snd_ice1712_restore_gpio_status(ice);
883 return change;
887 * WM8770 master mute control
889 #define wm_master_mute_info snd_ctl_boolean_stereo_info
891 static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
893 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
894 struct aureon_spec *spec = ice->spec;
896 ucontrol->value.integer.value[0] =
897 (spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
898 ucontrol->value.integer.value[1] =
899 (spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
900 return 0;
903 static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
905 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
906 struct aureon_spec *spec = ice->spec;
907 int change = 0, i;
909 snd_ice1712_save_gpio_status(ice);
910 for (i = 0; i < 2; i++) {
911 int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
912 if (ucontrol->value.integer.value[i] != val) {
913 int dac;
914 spec->master[i] &= ~WM_VOL_MUTE;
915 spec->master[i] |=
916 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
917 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
918 wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
919 spec->vol[dac + i],
920 spec->master[i]);
921 change = 1;
924 snd_ice1712_restore_gpio_status(ice);
926 return change;
929 /* digital master volume */
930 #define PCM_0dB 0xff
931 #define PCM_RES 128 /* -64dB */
932 #define PCM_MIN (PCM_0dB - PCM_RES)
933 static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
935 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
936 uinfo->count = 1;
937 uinfo->value.integer.min = 0; /* mute (-64dB) */
938 uinfo->value.integer.max = PCM_RES; /* 0dB */
939 return 0;
942 static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
944 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
945 unsigned short val;
947 mutex_lock(&ice->gpio_mutex);
948 val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
949 val = val > PCM_MIN ? (val - PCM_MIN) : 0;
950 ucontrol->value.integer.value[0] = val;
951 mutex_unlock(&ice->gpio_mutex);
952 return 0;
955 static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
957 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
958 unsigned short ovol, nvol;
959 int change = 0;
961 nvol = ucontrol->value.integer.value[0];
962 if (nvol > PCM_RES)
963 return -EINVAL;
964 snd_ice1712_save_gpio_status(ice);
965 nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
966 ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
967 if (ovol != nvol) {
968 wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
969 wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
970 change = 1;
972 snd_ice1712_restore_gpio_status(ice);
973 return change;
977 * ADC mute control
979 #define wm_adc_mute_info snd_ctl_boolean_stereo_info
981 static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
983 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
984 unsigned short val;
985 int i;
987 mutex_lock(&ice->gpio_mutex);
988 for (i = 0; i < 2; i++) {
989 val = wm_get(ice, WM_ADC_GAIN + i);
990 ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
992 mutex_unlock(&ice->gpio_mutex);
993 return 0;
996 static int wm_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
998 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
999 unsigned short new, old;
1000 int i, change = 0;
1002 snd_ice1712_save_gpio_status(ice);
1003 for (i = 0; i < 2; i++) {
1004 old = wm_get(ice, WM_ADC_GAIN + i);
1005 new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
1006 if (new != old) {
1007 wm_put(ice, WM_ADC_GAIN + i, new);
1008 change = 1;
1011 snd_ice1712_restore_gpio_status(ice);
1013 return change;
1017 * ADC gain mixer control
1019 static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1021 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1022 uinfo->count = 2;
1023 uinfo->value.integer.min = 0; /* -12dB */
1024 uinfo->value.integer.max = 0x1f; /* 19dB */
1025 return 0;
1028 static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1030 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1031 int i, idx;
1032 unsigned short vol;
1034 mutex_lock(&ice->gpio_mutex);
1035 for (i = 0; i < 2; i++) {
1036 idx = WM_ADC_GAIN + i;
1037 vol = wm_get(ice, idx) & 0x1f;
1038 ucontrol->value.integer.value[i] = vol;
1040 mutex_unlock(&ice->gpio_mutex);
1041 return 0;
1044 static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1046 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1047 int i, idx;
1048 unsigned short ovol, nvol;
1049 int change = 0;
1051 snd_ice1712_save_gpio_status(ice);
1052 for (i = 0; i < 2; i++) {
1053 idx = WM_ADC_GAIN + i;
1054 nvol = ucontrol->value.integer.value[i] & 0x1f;
1055 ovol = wm_get(ice, idx);
1056 if ((ovol & 0x1f) != nvol) {
1057 wm_put(ice, idx, nvol | (ovol & ~0x1f));
1058 change = 1;
1061 snd_ice1712_restore_gpio_status(ice);
1062 return change;
1066 * ADC input mux mixer control
1068 static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1070 static const char * const texts[] = {
1071 "CD", /* AIN1 */
1072 "Aux", /* AIN2 */
1073 "Line", /* AIN3 */
1074 "Mic", /* AIN4 */
1075 "AC97" /* AIN5 */
1077 static const char * const universe_texts[] = {
1078 "Aux1", /* AIN1 */
1079 "CD", /* AIN2 */
1080 "Phono", /* AIN3 */
1081 "Line", /* AIN4 */
1082 "Aux2", /* AIN5 */
1083 "Mic", /* AIN6 */
1084 "Aux3", /* AIN7 */
1085 "AC97" /* AIN8 */
1087 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1089 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE)
1090 return snd_ctl_enum_info(uinfo, 2, 8, universe_texts);
1091 else
1092 return snd_ctl_enum_info(uinfo, 2, 5, texts);
1095 static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1097 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1098 unsigned short val;
1100 mutex_lock(&ice->gpio_mutex);
1101 val = wm_get(ice, WM_ADC_MUX);
1102 ucontrol->value.enumerated.item[0] = val & 7;
1103 ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
1104 mutex_unlock(&ice->gpio_mutex);
1105 return 0;
1108 static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1110 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1111 unsigned short oval, nval;
1112 int change;
1114 snd_ice1712_save_gpio_status(ice);
1115 oval = wm_get(ice, WM_ADC_MUX);
1116 nval = oval & ~0x77;
1117 nval |= ucontrol->value.enumerated.item[0] & 7;
1118 nval |= (ucontrol->value.enumerated.item[1] & 7) << 4;
1119 change = (oval != nval);
1120 if (change)
1121 wm_put(ice, WM_ADC_MUX, nval);
1122 snd_ice1712_restore_gpio_status(ice);
1123 return change;
1127 * CS8415 Input mux
1129 static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1131 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1132 static const char * const aureon_texts[] = {
1133 "CD", /* RXP0 */
1134 "Optical" /* RXP1 */
1136 static const char * const prodigy_texts[] = {
1137 "CD",
1138 "Coax"
1140 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
1141 return snd_ctl_enum_info(uinfo, 1, 2, prodigy_texts);
1142 else
1143 return snd_ctl_enum_info(uinfo, 1, 2, aureon_texts);
1146 static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1148 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1149 struct aureon_spec *spec = ice->spec;
1151 /* snd_ice1712_save_gpio_status(ice); */
1152 /* val = aureon_cs8415_get(ice, CS8415_CTRL2); */
1153 ucontrol->value.enumerated.item[0] = spec->cs8415_mux;
1154 /* snd_ice1712_restore_gpio_status(ice); */
1155 return 0;
1158 static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1160 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1161 struct aureon_spec *spec = ice->spec;
1162 unsigned short oval, nval;
1163 int change;
1165 snd_ice1712_save_gpio_status(ice);
1166 oval = aureon_cs8415_get(ice, CS8415_CTRL2);
1167 nval = oval & ~0x07;
1168 nval |= ucontrol->value.enumerated.item[0] & 7;
1169 change = (oval != nval);
1170 if (change)
1171 aureon_cs8415_put(ice, CS8415_CTRL2, nval);
1172 snd_ice1712_restore_gpio_status(ice);
1173 spec->cs8415_mux = ucontrol->value.enumerated.item[0];
1174 return change;
1177 static int aureon_cs8415_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1179 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1180 uinfo->count = 1;
1181 uinfo->value.integer.min = 0;
1182 uinfo->value.integer.max = 192000;
1183 return 0;
1186 static int aureon_cs8415_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1188 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1189 unsigned char ratio;
1190 ratio = aureon_cs8415_get(ice, CS8415_RATIO);
1191 ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750);
1192 return 0;
1196 * CS8415A Mute
1198 #define aureon_cs8415_mute_info snd_ctl_boolean_mono_info
1200 static int aureon_cs8415_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1202 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1203 snd_ice1712_save_gpio_status(ice);
1204 ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1;
1205 snd_ice1712_restore_gpio_status(ice);
1206 return 0;
1209 static int aureon_cs8415_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1211 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1212 unsigned char oval, nval;
1213 int change;
1214 snd_ice1712_save_gpio_status(ice);
1215 oval = aureon_cs8415_get(ice, CS8415_CTRL1);
1216 if (ucontrol->value.integer.value[0])
1217 nval = oval & ~0x20;
1218 else
1219 nval = oval | 0x20;
1220 change = (oval != nval);
1221 if (change)
1222 aureon_cs8415_put(ice, CS8415_CTRL1, nval);
1223 snd_ice1712_restore_gpio_status(ice);
1224 return change;
1228 * CS8415A Q-Sub info
1230 static int aureon_cs8415_qsub_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1232 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1233 uinfo->count = 10;
1234 return 0;
1237 static int aureon_cs8415_qsub_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1239 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1241 snd_ice1712_save_gpio_status(ice);
1242 aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
1243 snd_ice1712_restore_gpio_status(ice);
1245 return 0;
1248 static int aureon_cs8415_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1250 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1251 uinfo->count = 1;
1252 return 0;
1255 static int aureon_cs8415_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1257 memset(ucontrol->value.iec958.status, 0xFF, 24);
1258 return 0;
1261 static int aureon_cs8415_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1263 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1265 snd_ice1712_save_gpio_status(ice);
1266 aureon_cs8415_read(ice, CS8415_C_BUFFER, ucontrol->value.iec958.status, 24);
1267 snd_ice1712_restore_gpio_status(ice);
1268 return 0;
1272 * Headphone Amplifier
1274 static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
1276 unsigned int tmp, tmp2;
1278 tmp2 = tmp = snd_ice1712_gpio_read(ice);
1279 if (enable)
1280 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1281 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1282 tmp |= AUREON_HP_SEL;
1283 else
1284 tmp |= PRODIGY_HP_SEL;
1285 else
1286 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1287 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1288 tmp &= ~AUREON_HP_SEL;
1289 else
1290 tmp &= ~PRODIGY_HP_SEL;
1291 if (tmp != tmp2) {
1292 snd_ice1712_gpio_write(ice, tmp);
1293 return 1;
1295 return 0;
1298 static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
1300 unsigned int tmp = snd_ice1712_gpio_read(ice);
1302 return (tmp & AUREON_HP_SEL) != 0;
1305 #define aureon_hpamp_info snd_ctl_boolean_mono_info
1307 static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1309 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1311 ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
1312 return 0;
1316 static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1318 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1320 return aureon_set_headphone_amp(ice, ucontrol->value.integer.value[0]);
1324 * Deemphasis
1327 #define aureon_deemp_info snd_ctl_boolean_mono_info
1329 static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1331 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1332 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
1333 return 0;
1336 static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1338 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1339 int temp, temp2;
1340 temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
1341 if (ucontrol->value.integer.value[0])
1342 temp |= 0xf;
1343 else
1344 temp &= ~0xf;
1345 if (temp != temp2) {
1346 wm_put(ice, WM_DAC_CTRL2, temp);
1347 return 1;
1349 return 0;
1353 * ADC Oversampling
1355 static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
1357 static const char * const texts[2] = { "128x", "64x" };
1359 return snd_ctl_enum_info(uinfo, 1, 2, texts);
1362 static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1364 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1365 ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
1366 return 0;
1369 static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1371 int temp, temp2;
1372 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1374 temp2 = temp = wm_get(ice, WM_MASTER);
1376 if (ucontrol->value.enumerated.item[0])
1377 temp |= 0x8;
1378 else
1379 temp &= ~0x8;
1381 if (temp != temp2) {
1382 wm_put(ice, WM_MASTER, temp);
1383 return 1;
1385 return 0;
1389 * mixers
1392 static const struct snd_kcontrol_new aureon_dac_controls[] = {
1394 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1395 .name = "Master Playback Switch",
1396 .info = wm_master_mute_info,
1397 .get = wm_master_mute_get,
1398 .put = wm_master_mute_put
1401 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1402 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1403 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1404 .name = "Master Playback Volume",
1405 .info = wm_master_vol_info,
1406 .get = wm_master_vol_get,
1407 .put = wm_master_vol_put,
1408 .tlv = { .p = db_scale_wm_dac }
1411 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1412 .name = "Front Playback Switch",
1413 .info = wm_mute_info,
1414 .get = wm_mute_get,
1415 .put = wm_mute_put,
1416 .private_value = (2 << 8) | 0
1419 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1420 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1421 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1422 .name = "Front Playback Volume",
1423 .info = wm_vol_info,
1424 .get = wm_vol_get,
1425 .put = wm_vol_put,
1426 .private_value = (2 << 8) | 0,
1427 .tlv = { .p = db_scale_wm_dac }
1430 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1431 .name = "Rear Playback Switch",
1432 .info = wm_mute_info,
1433 .get = wm_mute_get,
1434 .put = wm_mute_put,
1435 .private_value = (2 << 8) | 2
1438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1439 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1440 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1441 .name = "Rear Playback Volume",
1442 .info = wm_vol_info,
1443 .get = wm_vol_get,
1444 .put = wm_vol_put,
1445 .private_value = (2 << 8) | 2,
1446 .tlv = { .p = db_scale_wm_dac }
1449 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1450 .name = "Center Playback Switch",
1451 .info = wm_mute_info,
1452 .get = wm_mute_get,
1453 .put = wm_mute_put,
1454 .private_value = (1 << 8) | 4
1457 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1458 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1459 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1460 .name = "Center Playback Volume",
1461 .info = wm_vol_info,
1462 .get = wm_vol_get,
1463 .put = wm_vol_put,
1464 .private_value = (1 << 8) | 4,
1465 .tlv = { .p = db_scale_wm_dac }
1468 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1469 .name = "LFE Playback Switch",
1470 .info = wm_mute_info,
1471 .get = wm_mute_get,
1472 .put = wm_mute_put,
1473 .private_value = (1 << 8) | 5
1476 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1477 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1478 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1479 .name = "LFE Playback Volume",
1480 .info = wm_vol_info,
1481 .get = wm_vol_get,
1482 .put = wm_vol_put,
1483 .private_value = (1 << 8) | 5,
1484 .tlv = { .p = db_scale_wm_dac }
1487 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1488 .name = "Side Playback Switch",
1489 .info = wm_mute_info,
1490 .get = wm_mute_get,
1491 .put = wm_mute_put,
1492 .private_value = (2 << 8) | 6
1495 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1496 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1497 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1498 .name = "Side Playback Volume",
1499 .info = wm_vol_info,
1500 .get = wm_vol_get,
1501 .put = wm_vol_put,
1502 .private_value = (2 << 8) | 6,
1503 .tlv = { .p = db_scale_wm_dac }
1507 static const struct snd_kcontrol_new wm_controls[] = {
1509 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1510 .name = "PCM Playback Switch",
1511 .info = wm_pcm_mute_info,
1512 .get = wm_pcm_mute_get,
1513 .put = wm_pcm_mute_put
1516 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1517 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1518 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1519 .name = "PCM Playback Volume",
1520 .info = wm_pcm_vol_info,
1521 .get = wm_pcm_vol_get,
1522 .put = wm_pcm_vol_put,
1523 .tlv = { .p = db_scale_wm_pcm }
1526 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1527 .name = "Capture Switch",
1528 .info = wm_adc_mute_info,
1529 .get = wm_adc_mute_get,
1530 .put = wm_adc_mute_put,
1533 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1534 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1535 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1536 .name = "Capture Volume",
1537 .info = wm_adc_vol_info,
1538 .get = wm_adc_vol_get,
1539 .put = wm_adc_vol_put,
1540 .tlv = { .p = db_scale_wm_adc }
1543 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1544 .name = "Capture Source",
1545 .info = wm_adc_mux_info,
1546 .get = wm_adc_mux_get,
1547 .put = wm_adc_mux_put,
1548 .private_value = 5
1551 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1552 .name = "External Amplifier",
1553 .info = aureon_hpamp_info,
1554 .get = aureon_hpamp_get,
1555 .put = aureon_hpamp_put
1558 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1559 .name = "DAC Deemphasis Switch",
1560 .info = aureon_deemp_info,
1561 .get = aureon_deemp_get,
1562 .put = aureon_deemp_put
1565 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1566 .name = "ADC Oversampling",
1567 .info = aureon_oversampling_info,
1568 .get = aureon_oversampling_get,
1569 .put = aureon_oversampling_put
1573 static const struct snd_kcontrol_new ac97_controls[] = {
1575 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1576 .name = "AC97 Playback Switch",
1577 .info = aureon_ac97_mmute_info,
1578 .get = aureon_ac97_mmute_get,
1579 .put = aureon_ac97_mmute_put,
1580 .private_value = AC97_MASTER
1583 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1584 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1585 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1586 .name = "AC97 Playback Volume",
1587 .info = aureon_ac97_vol_info,
1588 .get = aureon_ac97_vol_get,
1589 .put = aureon_ac97_vol_put,
1590 .private_value = AC97_MASTER|AUREON_AC97_STEREO,
1591 .tlv = { .p = db_scale_ac97_master }
1594 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1595 .name = "CD Playback Switch",
1596 .info = aureon_ac97_mute_info,
1597 .get = aureon_ac97_mute_get,
1598 .put = aureon_ac97_mute_put,
1599 .private_value = AC97_CD
1602 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1603 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1604 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1605 .name = "CD Playback Volume",
1606 .info = aureon_ac97_vol_info,
1607 .get = aureon_ac97_vol_get,
1608 .put = aureon_ac97_vol_put,
1609 .private_value = AC97_CD|AUREON_AC97_STEREO,
1610 .tlv = { .p = db_scale_ac97_gain }
1613 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1614 .name = "Aux Playback Switch",
1615 .info = aureon_ac97_mute_info,
1616 .get = aureon_ac97_mute_get,
1617 .put = aureon_ac97_mute_put,
1618 .private_value = AC97_AUX,
1621 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1622 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1623 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1624 .name = "Aux Playback Volume",
1625 .info = aureon_ac97_vol_info,
1626 .get = aureon_ac97_vol_get,
1627 .put = aureon_ac97_vol_put,
1628 .private_value = AC97_AUX|AUREON_AC97_STEREO,
1629 .tlv = { .p = db_scale_ac97_gain }
1632 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1633 .name = "Line Playback Switch",
1634 .info = aureon_ac97_mute_info,
1635 .get = aureon_ac97_mute_get,
1636 .put = aureon_ac97_mute_put,
1637 .private_value = AC97_LINE
1640 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1641 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1642 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1643 .name = "Line Playback Volume",
1644 .info = aureon_ac97_vol_info,
1645 .get = aureon_ac97_vol_get,
1646 .put = aureon_ac97_vol_put,
1647 .private_value = AC97_LINE|AUREON_AC97_STEREO,
1648 .tlv = { .p = db_scale_ac97_gain }
1651 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1652 .name = "Mic Playback Switch",
1653 .info = aureon_ac97_mute_info,
1654 .get = aureon_ac97_mute_get,
1655 .put = aureon_ac97_mute_put,
1656 .private_value = AC97_MIC
1659 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1660 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1661 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1662 .name = "Mic Playback Volume",
1663 .info = aureon_ac97_vol_info,
1664 .get = aureon_ac97_vol_get,
1665 .put = aureon_ac97_vol_put,
1666 .private_value = AC97_MIC,
1667 .tlv = { .p = db_scale_ac97_gain }
1670 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1671 .name = "Mic Boost (+20dB)",
1672 .info = aureon_ac97_micboost_info,
1673 .get = aureon_ac97_micboost_get,
1674 .put = aureon_ac97_micboost_put
1678 static const struct snd_kcontrol_new universe_ac97_controls[] = {
1680 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1681 .name = "AC97 Playback Switch",
1682 .info = aureon_ac97_mmute_info,
1683 .get = aureon_ac97_mmute_get,
1684 .put = aureon_ac97_mmute_put,
1685 .private_value = AC97_MASTER
1688 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1689 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1690 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1691 .name = "AC97 Playback Volume",
1692 .info = aureon_ac97_vol_info,
1693 .get = aureon_ac97_vol_get,
1694 .put = aureon_ac97_vol_put,
1695 .private_value = AC97_MASTER|AUREON_AC97_STEREO,
1696 .tlv = { .p = db_scale_ac97_master }
1699 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1700 .name = "CD Playback Switch",
1701 .info = aureon_ac97_mute_info,
1702 .get = aureon_ac97_mute_get,
1703 .put = aureon_ac97_mute_put,
1704 .private_value = AC97_AUX
1707 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1708 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1709 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1710 .name = "CD Playback Volume",
1711 .info = aureon_ac97_vol_info,
1712 .get = aureon_ac97_vol_get,
1713 .put = aureon_ac97_vol_put,
1714 .private_value = AC97_AUX|AUREON_AC97_STEREO,
1715 .tlv = { .p = db_scale_ac97_gain }
1718 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1719 .name = "Phono Playback Switch",
1720 .info = aureon_ac97_mute_info,
1721 .get = aureon_ac97_mute_get,
1722 .put = aureon_ac97_mute_put,
1723 .private_value = AC97_CD
1726 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1727 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1728 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1729 .name = "Phono Playback Volume",
1730 .info = aureon_ac97_vol_info,
1731 .get = aureon_ac97_vol_get,
1732 .put = aureon_ac97_vol_put,
1733 .private_value = AC97_CD|AUREON_AC97_STEREO,
1734 .tlv = { .p = db_scale_ac97_gain }
1737 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1738 .name = "Line Playback Switch",
1739 .info = aureon_ac97_mute_info,
1740 .get = aureon_ac97_mute_get,
1741 .put = aureon_ac97_mute_put,
1742 .private_value = AC97_LINE
1745 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1746 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1747 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1748 .name = "Line Playback Volume",
1749 .info = aureon_ac97_vol_info,
1750 .get = aureon_ac97_vol_get,
1751 .put = aureon_ac97_vol_put,
1752 .private_value = AC97_LINE|AUREON_AC97_STEREO,
1753 .tlv = { .p = db_scale_ac97_gain }
1756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1757 .name = "Mic Playback Switch",
1758 .info = aureon_ac97_mute_info,
1759 .get = aureon_ac97_mute_get,
1760 .put = aureon_ac97_mute_put,
1761 .private_value = AC97_MIC
1764 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1765 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1766 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1767 .name = "Mic Playback Volume",
1768 .info = aureon_ac97_vol_info,
1769 .get = aureon_ac97_vol_get,
1770 .put = aureon_ac97_vol_put,
1771 .private_value = AC97_MIC,
1772 .tlv = { .p = db_scale_ac97_gain }
1775 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1776 .name = "Mic Boost (+20dB)",
1777 .info = aureon_ac97_micboost_info,
1778 .get = aureon_ac97_micboost_get,
1779 .put = aureon_ac97_micboost_put
1782 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1783 .name = "Aux Playback Switch",
1784 .info = aureon_ac97_mute_info,
1785 .get = aureon_ac97_mute_get,
1786 .put = aureon_ac97_mute_put,
1787 .private_value = AC97_VIDEO,
1790 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1791 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1792 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1793 .name = "Aux Playback Volume",
1794 .info = aureon_ac97_vol_info,
1795 .get = aureon_ac97_vol_get,
1796 .put = aureon_ac97_vol_put,
1797 .private_value = AC97_VIDEO|AUREON_AC97_STEREO,
1798 .tlv = { .p = db_scale_ac97_gain }
1801 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1802 .name = "Aux Source",
1803 .info = aureon_universe_inmux_info,
1804 .get = aureon_universe_inmux_get,
1805 .put = aureon_universe_inmux_put
1810 static const struct snd_kcontrol_new cs8415_controls[] = {
1812 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1813 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
1814 .info = aureon_cs8415_mute_info,
1815 .get = aureon_cs8415_mute_get,
1816 .put = aureon_cs8415_mute_put
1819 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1820 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Source",
1821 .info = aureon_cs8415_mux_info,
1822 .get = aureon_cs8415_mux_get,
1823 .put = aureon_cs8415_mux_put,
1826 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1827 .name = SNDRV_CTL_NAME_IEC958("Q-subcode ", CAPTURE, DEFAULT),
1828 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1829 .info = aureon_cs8415_qsub_info,
1830 .get = aureon_cs8415_qsub_get,
1833 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1834 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
1835 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1836 .info = aureon_cs8415_spdif_info,
1837 .get = aureon_cs8415_mask_get
1840 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1841 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
1842 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1843 .info = aureon_cs8415_spdif_info,
1844 .get = aureon_cs8415_spdif_get
1847 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1848 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Rate",
1849 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1850 .info = aureon_cs8415_rate_info,
1851 .get = aureon_cs8415_rate_get
1855 static int aureon_add_controls(struct snd_ice1712 *ice)
1857 unsigned int i, counts;
1858 int err;
1860 counts = ARRAY_SIZE(aureon_dac_controls);
1861 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
1862 counts -= 2; /* no side */
1863 for (i = 0; i < counts; i++) {
1864 err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
1865 if (err < 0)
1866 return err;
1869 for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
1870 err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
1871 if (err < 0)
1872 return err;
1875 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1876 for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
1877 err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
1878 if (err < 0)
1879 return err;
1881 } else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1882 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1883 for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
1884 err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
1885 if (err < 0)
1886 return err;
1890 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1891 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1892 unsigned char id;
1893 snd_ice1712_save_gpio_status(ice);
1894 id = aureon_cs8415_get(ice, CS8415_ID);
1895 if (id != 0x41)
1896 dev_info(ice->card->dev,
1897 "No CS8415 chip. Skipping CS8415 controls.\n");
1898 else if ((id & 0x0F) != 0x01)
1899 dev_info(ice->card->dev,
1900 "Detected unsupported CS8415 rev. (%c)\n",
1901 (char)((id & 0x0F) + 'A' - 1));
1902 else {
1903 for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
1904 struct snd_kcontrol *kctl;
1905 err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
1906 if (err < 0)
1907 return err;
1908 if (i > 1)
1909 kctl->id.device = ice->pcm->device;
1912 snd_ice1712_restore_gpio_status(ice);
1915 return 0;
1919 * reset the chip
1921 static int aureon_reset(struct snd_ice1712 *ice)
1923 static const unsigned short wm_inits_aureon[] = {
1924 /* These come first to reduce init pop noise */
1925 0x1b, 0x044, /* ADC Mux (AC'97 source) */
1926 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
1927 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
1929 0x18, 0x000, /* All power-up */
1931 0x16, 0x122, /* I2S, normal polarity, 24bit */
1932 0x17, 0x022, /* 256fs, slave mode */
1933 0x00, 0, /* DAC1 analog mute */
1934 0x01, 0, /* DAC2 analog mute */
1935 0x02, 0, /* DAC3 analog mute */
1936 0x03, 0, /* DAC4 analog mute */
1937 0x04, 0, /* DAC5 analog mute */
1938 0x05, 0, /* DAC6 analog mute */
1939 0x06, 0, /* DAC7 analog mute */
1940 0x07, 0, /* DAC8 analog mute */
1941 0x08, 0x100, /* master analog mute */
1942 0x09, 0xff, /* DAC1 digital full */
1943 0x0a, 0xff, /* DAC2 digital full */
1944 0x0b, 0xff, /* DAC3 digital full */
1945 0x0c, 0xff, /* DAC4 digital full */
1946 0x0d, 0xff, /* DAC5 digital full */
1947 0x0e, 0xff, /* DAC6 digital full */
1948 0x0f, 0xff, /* DAC7 digital full */
1949 0x10, 0xff, /* DAC8 digital full */
1950 0x11, 0x1ff, /* master digital full */
1951 0x12, 0x000, /* phase normal */
1952 0x13, 0x090, /* unmute DAC L/R */
1953 0x14, 0x000, /* all unmute */
1954 0x15, 0x000, /* no deemphasis, no ZFLG */
1955 0x19, 0x000, /* -12dB ADC/L */
1956 0x1a, 0x000, /* -12dB ADC/R */
1957 (unsigned short)-1
1959 static const unsigned short wm_inits_prodigy[] = {
1961 /* These come first to reduce init pop noise */
1962 0x1b, 0x000, /* ADC Mux */
1963 0x1c, 0x009, /* Out Mux1 */
1964 0x1d, 0x009, /* Out Mux2 */
1966 0x18, 0x000, /* All power-up */
1968 0x16, 0x022, /* I2S, normal polarity, 24bit, high-pass on */
1969 0x17, 0x006, /* 128fs, slave mode */
1971 0x00, 0, /* DAC1 analog mute */
1972 0x01, 0, /* DAC2 analog mute */
1973 0x02, 0, /* DAC3 analog mute */
1974 0x03, 0, /* DAC4 analog mute */
1975 0x04, 0, /* DAC5 analog mute */
1976 0x05, 0, /* DAC6 analog mute */
1977 0x06, 0, /* DAC7 analog mute */
1978 0x07, 0, /* DAC8 analog mute */
1979 0x08, 0x100, /* master analog mute */
1981 0x09, 0x7f, /* DAC1 digital full */
1982 0x0a, 0x7f, /* DAC2 digital full */
1983 0x0b, 0x7f, /* DAC3 digital full */
1984 0x0c, 0x7f, /* DAC4 digital full */
1985 0x0d, 0x7f, /* DAC5 digital full */
1986 0x0e, 0x7f, /* DAC6 digital full */
1987 0x0f, 0x7f, /* DAC7 digital full */
1988 0x10, 0x7f, /* DAC8 digital full */
1989 0x11, 0x1FF, /* master digital full */
1991 0x12, 0x000, /* phase normal */
1992 0x13, 0x090, /* unmute DAC L/R */
1993 0x14, 0x000, /* all unmute */
1994 0x15, 0x000, /* no deemphasis, no ZFLG */
1996 0x19, 0x000, /* -12dB ADC/L */
1997 0x1a, 0x000, /* -12dB ADC/R */
1998 (unsigned short)-1
2001 static const unsigned short cs_inits[] = {
2002 0x0441, /* RUN */
2003 0x0180, /* no mute, OMCK output on RMCK pin */
2004 0x0201, /* S/PDIF source on RXP1 */
2005 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
2006 (unsigned short)-1
2008 unsigned int tmp;
2009 const unsigned short *p;
2010 int err;
2011 struct aureon_spec *spec = ice->spec;
2013 err = aureon_ac97_init(ice);
2014 if (err != 0)
2015 return err;
2017 snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
2019 /* reset the wm codec as the SPI mode */
2020 snd_ice1712_save_gpio_status(ice);
2021 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
2023 tmp = snd_ice1712_gpio_read(ice);
2024 tmp &= ~AUREON_WM_RESET;
2025 snd_ice1712_gpio_write(ice, tmp);
2026 udelay(1);
2027 tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
2028 snd_ice1712_gpio_write(ice, tmp);
2029 udelay(1);
2030 tmp |= AUREON_WM_RESET;
2031 snd_ice1712_gpio_write(ice, tmp);
2032 udelay(1);
2034 /* initialize WM8770 codec */
2035 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
2036 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
2037 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT)
2038 p = wm_inits_prodigy;
2039 else
2040 p = wm_inits_aureon;
2041 for (; *p != (unsigned short)-1; p += 2)
2042 wm_put(ice, p[0], p[1]);
2044 /* initialize CS8415A codec */
2045 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
2046 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
2047 for (p = cs_inits; *p != (unsigned short)-1; p++)
2048 aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
2049 spec->cs8415_mux = 1;
2051 aureon_set_headphone_amp(ice, 1);
2054 snd_ice1712_restore_gpio_status(ice);
2056 /* initialize PCA9554 pin directions & set default input */
2057 aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2058 aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */
2059 return 0;
2063 * suspend/resume
2065 #ifdef CONFIG_PM_SLEEP
2066 static int aureon_resume(struct snd_ice1712 *ice)
2068 struct aureon_spec *spec = ice->spec;
2069 int err, i;
2071 err = aureon_reset(ice);
2072 if (err != 0)
2073 return err;
2075 /* workaround for poking volume with alsamixer after resume:
2076 * just set stored volume again */
2077 for (i = 0; i < ice->num_total_dacs; i++)
2078 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2079 return 0;
2081 #endif
2084 * initialize the chip
2086 static int aureon_init(struct snd_ice1712 *ice)
2088 struct aureon_spec *spec;
2089 int i, err;
2091 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2092 if (!spec)
2093 return -ENOMEM;
2094 ice->spec = spec;
2096 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
2097 ice->num_total_dacs = 6;
2098 ice->num_total_adcs = 2;
2099 } else {
2100 /* aureon 7.1 and prodigy 7.1 */
2101 ice->num_total_dacs = 8;
2102 ice->num_total_adcs = 2;
2105 /* to remember the register values of CS8415 */
2106 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2107 if (!ice->akm)
2108 return -ENOMEM;
2109 ice->akm_codecs = 1;
2111 err = aureon_reset(ice);
2112 if (err != 0)
2113 return err;
2115 spec->master[0] = WM_VOL_MUTE;
2116 spec->master[1] = WM_VOL_MUTE;
2117 for (i = 0; i < ice->num_total_dacs; i++) {
2118 spec->vol[i] = WM_VOL_MUTE;
2119 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2122 #ifdef CONFIG_PM_SLEEP
2123 ice->pm_resume = aureon_resume;
2124 ice->pm_suspend_enabled = 1;
2125 #endif
2127 return 0;
2132 * Aureon boards don't provide the EEPROM data except for the vendor IDs.
2133 * hence the driver needs to sets up it properly.
2136 static const unsigned char aureon51_eeprom[] = {
2137 [ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */
2138 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2139 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2140 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2141 [ICE_EEP2_GPIO_DIR] = 0xff,
2142 [ICE_EEP2_GPIO_DIR1] = 0xff,
2143 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2144 [ICE_EEP2_GPIO_MASK] = 0x00,
2145 [ICE_EEP2_GPIO_MASK1] = 0x00,
2146 [ICE_EEP2_GPIO_MASK2] = 0x00,
2147 [ICE_EEP2_GPIO_STATE] = 0x00,
2148 [ICE_EEP2_GPIO_STATE1] = 0x00,
2149 [ICE_EEP2_GPIO_STATE2] = 0x00,
2152 static const unsigned char aureon71_eeprom[] = {
2153 [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */
2154 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2155 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2156 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2157 [ICE_EEP2_GPIO_DIR] = 0xff,
2158 [ICE_EEP2_GPIO_DIR1] = 0xff,
2159 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2160 [ICE_EEP2_GPIO_MASK] = 0x00,
2161 [ICE_EEP2_GPIO_MASK1] = 0x00,
2162 [ICE_EEP2_GPIO_MASK2] = 0x00,
2163 [ICE_EEP2_GPIO_STATE] = 0x00,
2164 [ICE_EEP2_GPIO_STATE1] = 0x00,
2165 [ICE_EEP2_GPIO_STATE2] = 0x00,
2167 #define prodigy71_eeprom aureon71_eeprom
2169 static const unsigned char aureon71_universe_eeprom[] = {
2170 [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC,
2171 * 4DACs
2173 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2174 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2175 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2176 [ICE_EEP2_GPIO_DIR] = 0xff,
2177 [ICE_EEP2_GPIO_DIR1] = 0xff,
2178 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2179 [ICE_EEP2_GPIO_MASK] = 0x00,
2180 [ICE_EEP2_GPIO_MASK1] = 0x00,
2181 [ICE_EEP2_GPIO_MASK2] = 0x00,
2182 [ICE_EEP2_GPIO_STATE] = 0x00,
2183 [ICE_EEP2_GPIO_STATE1] = 0x00,
2184 [ICE_EEP2_GPIO_STATE2] = 0x00,
2187 static const unsigned char prodigy71lt_eeprom[] = {
2188 [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */
2189 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2190 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2191 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2192 [ICE_EEP2_GPIO_DIR] = 0xff,
2193 [ICE_EEP2_GPIO_DIR1] = 0xff,
2194 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2195 [ICE_EEP2_GPIO_MASK] = 0x00,
2196 [ICE_EEP2_GPIO_MASK1] = 0x00,
2197 [ICE_EEP2_GPIO_MASK2] = 0x00,
2198 [ICE_EEP2_GPIO_STATE] = 0x00,
2199 [ICE_EEP2_GPIO_STATE1] = 0x00,
2200 [ICE_EEP2_GPIO_STATE2] = 0x00,
2202 #define prodigy71xt_eeprom prodigy71lt_eeprom
2204 /* entry point */
2205 struct snd_ice1712_card_info snd_vt1724_aureon_cards[] = {
2207 .subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
2208 .name = "Terratec Aureon 5.1-Sky",
2209 .model = "aureon51",
2210 .chip_init = aureon_init,
2211 .build_controls = aureon_add_controls,
2212 .eeprom_size = sizeof(aureon51_eeprom),
2213 .eeprom_data = aureon51_eeprom,
2214 .driver = "Aureon51",
2217 .subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
2218 .name = "Terratec Aureon 7.1-Space",
2219 .model = "aureon71",
2220 .chip_init = aureon_init,
2221 .build_controls = aureon_add_controls,
2222 .eeprom_size = sizeof(aureon71_eeprom),
2223 .eeprom_data = aureon71_eeprom,
2224 .driver = "Aureon71",
2227 .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
2228 .name = "Terratec Aureon 7.1-Universe",
2229 .model = "universe",
2230 .chip_init = aureon_init,
2231 .build_controls = aureon_add_controls,
2232 .eeprom_size = sizeof(aureon71_universe_eeprom),
2233 .eeprom_data = aureon71_universe_eeprom,
2234 .driver = "Aureon71Univ", /* keep in 15 letters */
2237 .subvendor = VT1724_SUBDEVICE_PRODIGY71,
2238 .name = "Audiotrak Prodigy 7.1",
2239 .model = "prodigy71",
2240 .chip_init = aureon_init,
2241 .build_controls = aureon_add_controls,
2242 .eeprom_size = sizeof(prodigy71_eeprom),
2243 .eeprom_data = prodigy71_eeprom,
2244 .driver = "Prodigy71", /* should be identical with Aureon71 */
2247 .subvendor = VT1724_SUBDEVICE_PRODIGY71LT,
2248 .name = "Audiotrak Prodigy 7.1 LT",
2249 .model = "prodigy71lt",
2250 .chip_init = aureon_init,
2251 .build_controls = aureon_add_controls,
2252 .eeprom_size = sizeof(prodigy71lt_eeprom),
2253 .eeprom_data = prodigy71lt_eeprom,
2254 .driver = "Prodigy71LT",
2257 .subvendor = VT1724_SUBDEVICE_PRODIGY71XT,
2258 .name = "Audiotrak Prodigy 7.1 XT",
2259 .model = "prodigy71xt",
2260 .chip_init = aureon_init,
2261 .build_controls = aureon_add_controls,
2262 .eeprom_size = sizeof(prodigy71xt_eeprom),
2263 .eeprom_data = prodigy71xt_eeprom,
2264 .driver = "Prodigy71LT",
2266 { } /* terminator */