]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - sound/pci/ice1712/aureon.c
Merge branch 'for-2.6.25' of git://git.secretlab.ca/git/linux-2.6-mpc52xx into for...
[mirror_ubuntu-zesty-kernel.git] / sound / pci / ice1712 / aureon.c
1 /*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3 *
4 * Lowlevel functions for Terratec Aureon cards
5 *
6 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
7 *
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.
12 *
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.
17 *
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
21 *
22 *
23 * NOTES:
24 *
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.
29 *
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.
33 *
34 * Lowlevel functions for AudioTrak Prodigy 7.1 (and possibly 192) cards
35 * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
36 *
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
41 *
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.
47 *
48 */
49
50 #include <asm/io.h>
51 #include <linux/delay.h>
52 #include <linux/interrupt.h>
53 #include <linux/init.h>
54 #include <linux/slab.h>
55 #include <linux/mutex.h>
56
57 #include <sound/core.h>
58
59 #include "ice1712.h"
60 #include "envy24ht.h"
61 #include "aureon.h"
62 #include <sound/tlv.h>
63
64 /* AC97 register cache for Aureon */
65 struct aureon_spec {
66 unsigned short stac9744[64];
67 unsigned int cs8415_mux;
68 unsigned short master[2];
69 unsigned short vol[8];
70 unsigned char pca9554_out;
71 };
72
73 /* WM8770 registers */
74 #define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
75 #define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */
76 #define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */
77 #define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */
78 #define WM_PHASE_SWAP 0x12 /* DAC phase */
79 #define WM_DAC_CTRL1 0x13 /* DAC control bits */
80 #define WM_MUTE 0x14 /* mute controls */
81 #define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */
82 #define WM_INT_CTRL 0x16 /* interface control */
83 #define WM_MASTER 0x17 /* master clock and mode */
84 #define WM_POWERDOWN 0x18 /* power-down controls */
85 #define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */
86 #define WM_ADC_MUX 0x1b /* input MUX */
87 #define WM_OUT_MUX1 0x1c /* output MUX */
88 #define WM_OUT_MUX2 0x1e /* output MUX */
89 #define WM_RESET 0x1f /* software reset */
90
91 /* CS8415A registers */
92 #define CS8415_CTRL1 0x01
93 #define CS8415_CTRL2 0x02
94 #define CS8415_QSUB 0x14
95 #define CS8415_RATIO 0x1E
96 #define CS8415_C_BUFFER 0x20
97 #define CS8415_ID 0x7F
98
99 /* PCA9554 registers */
100 #define PCA9554_DEV 0x40 /* I2C device address */
101 #define PCA9554_IN 0x00 /* input port */
102 #define PCA9554_OUT 0x01 /* output port */
103 #define PCA9554_INVERT 0x02 /* input invert */
104 #define PCA9554_DIR 0x03 /* port directions */
105
106 /*
107 * Aureon Universe additional controls using PCA9554
108 */
109
110 /*
111 * Send data to pca9554
112 */
113 static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
114 unsigned char data)
115 {
116 unsigned int tmp;
117 int i, j;
118 unsigned char dev = PCA9554_DEV; /* ID 0100000, write */
119 unsigned char val = 0;
120
121 tmp = snd_ice1712_gpio_read(ice);
122
123 snd_ice1712_gpio_set_mask(ice, ~(AUREON_SPI_MOSI|AUREON_SPI_CLK|
124 AUREON_WM_RW|AUREON_WM_CS|
125 AUREON_CS8415_CS));
126 tmp |= AUREON_WM_RW;
127 tmp |= AUREON_CS8415_CS | AUREON_WM_CS; /* disable SPI devices */
128
129 tmp &= ~AUREON_SPI_MOSI;
130 tmp &= ~AUREON_SPI_CLK;
131 snd_ice1712_gpio_write(ice, tmp);
132 udelay(50);
133
134 /*
135 * send i2c stop condition and start condition
136 * to obtain sane state
137 */
138 tmp |= AUREON_SPI_CLK;
139 snd_ice1712_gpio_write(ice, tmp);
140 udelay(50);
141 tmp |= AUREON_SPI_MOSI;
142 snd_ice1712_gpio_write(ice, tmp);
143 udelay(100);
144 tmp &= ~AUREON_SPI_MOSI;
145 snd_ice1712_gpio_write(ice, tmp);
146 udelay(50);
147 tmp &= ~AUREON_SPI_CLK;
148 snd_ice1712_gpio_write(ice, tmp);
149 udelay(100);
150 /*
151 * send device address, command and value,
152 * skipping ack cycles inbetween
153 */
154 for (j = 0; j < 3; j++) {
155 switch(j) {
156 case 0: val = dev; break;
157 case 1: val = reg; break;
158 case 2: val = data; break;
159 }
160 for (i = 7; i >= 0; i--) {
161 tmp &= ~AUREON_SPI_CLK;
162 snd_ice1712_gpio_write(ice, tmp);
163 udelay(40);
164 if (val & (1 << i))
165 tmp |= AUREON_SPI_MOSI;
166 else
167 tmp &= ~AUREON_SPI_MOSI;
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);
173 }
174 tmp &= ~AUREON_SPI_CLK;
175 snd_ice1712_gpio_write(ice, tmp);
176 udelay(40);
177 tmp |= AUREON_SPI_CLK;
178 snd_ice1712_gpio_write(ice, tmp);
179 udelay(40);
180 tmp &= ~AUREON_SPI_CLK;
181 snd_ice1712_gpio_write(ice, tmp);
182 udelay(40);
183 }
184 tmp &= ~AUREON_SPI_CLK;
185 snd_ice1712_gpio_write(ice, tmp);
186 udelay(40);
187 tmp &= ~AUREON_SPI_MOSI;
188 snd_ice1712_gpio_write(ice, tmp);
189 udelay(40);
190 tmp |= AUREON_SPI_CLK;
191 snd_ice1712_gpio_write(ice, tmp);
192 udelay(50);
193 tmp |= AUREON_SPI_MOSI;
194 snd_ice1712_gpio_write(ice, tmp);
195 udelay(100);
196 }
197
198 static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,
199 struct snd_ctl_elem_info *uinfo)
200 {
201 char *texts[3] = {"Internal Aux", "Wavetable", "Rear Line-In"};
202
203 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
204 uinfo->count = 1;
205 uinfo->value.enumerated.items = 3;
206 if(uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
207 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
208 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
209 return 0;
210 }
211
212 static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol,
213 struct snd_ctl_elem_value *ucontrol)
214 {
215 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
216 struct aureon_spec *spec = ice->spec;
217 ucontrol->value.enumerated.item[0] = spec->pca9554_out;
218 return 0;
219 }
220
221 static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
222 struct snd_ctl_elem_value *ucontrol)
223 {
224 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
225 struct aureon_spec *spec = ice->spec;
226 unsigned char oval, nval;
227 int change;
228
229 nval = ucontrol->value.enumerated.item[0];
230 if (nval >= 3)
231 return -EINVAL;
232 snd_ice1712_save_gpio_status(ice);
233 oval = spec->pca9554_out;
234 if ((change = (oval != nval))) {
235 aureon_pca9554_write(ice, PCA9554_OUT, nval);
236 spec->pca9554_out = nval;
237 }
238 snd_ice1712_restore_gpio_status(ice);
239
240 return change;
241 }
242
243
244 static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
245 unsigned short val)
246 {
247 struct aureon_spec *spec = ice->spec;
248 unsigned int tmp;
249
250 /* Send address to XILINX chip */
251 tmp = (snd_ice1712_gpio_read(ice) & ~0xFF) | (reg & 0x7F);
252 snd_ice1712_gpio_write(ice, tmp);
253 udelay(10);
254 tmp |= AUREON_AC97_ADDR;
255 snd_ice1712_gpio_write(ice, tmp);
256 udelay(10);
257 tmp &= ~AUREON_AC97_ADDR;
258 snd_ice1712_gpio_write(ice, tmp);
259 udelay(10);
260
261 /* Send low-order byte to XILINX chip */
262 tmp &= ~AUREON_AC97_DATA_MASK;
263 tmp |= val & AUREON_AC97_DATA_MASK;
264 snd_ice1712_gpio_write(ice, tmp);
265 udelay(10);
266 tmp |= AUREON_AC97_DATA_LOW;
267 snd_ice1712_gpio_write(ice, tmp);
268 udelay(10);
269 tmp &= ~AUREON_AC97_DATA_LOW;
270 snd_ice1712_gpio_write(ice, tmp);
271 udelay(10);
272
273 /* Send high-order byte to XILINX chip */
274 tmp &= ~AUREON_AC97_DATA_MASK;
275 tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
276
277 snd_ice1712_gpio_write(ice, tmp);
278 udelay(10);
279 tmp |= AUREON_AC97_DATA_HIGH;
280 snd_ice1712_gpio_write(ice, tmp);
281 udelay(10);
282 tmp &= ~AUREON_AC97_DATA_HIGH;
283 snd_ice1712_gpio_write(ice, tmp);
284 udelay(10);
285
286 /* Instruct XILINX chip to parse the data to the STAC9744 chip */
287 tmp |= AUREON_AC97_COMMIT;
288 snd_ice1712_gpio_write(ice, tmp);
289 udelay(10);
290 tmp &= ~AUREON_AC97_COMMIT;
291 snd_ice1712_gpio_write(ice, tmp);
292 udelay(10);
293
294 /* Store the data in out private buffer */
295 spec->stac9744[(reg & 0x7F) >> 1] = val;
296 }
297
298 static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short reg)
299 {
300 struct aureon_spec *spec = ice->spec;
301 return spec->stac9744[(reg & 0x7F) >> 1];
302 }
303
304 /*
305 * Initialize STAC9744 chip
306 */
307 static int aureon_ac97_init (struct snd_ice1712 *ice)
308 {
309 struct aureon_spec *spec = ice->spec;
310 int i;
311 static const unsigned short ac97_defaults[] = {
312 0x00, 0x9640,
313 0x02, 0x8000,
314 0x04, 0x8000,
315 0x06, 0x8000,
316 0x0C, 0x8008,
317 0x0E, 0x8008,
318 0x10, 0x8808,
319 0x12, 0x8808,
320 0x14, 0x8808,
321 0x16, 0x8808,
322 0x18, 0x8808,
323 0x1C, 0x8000,
324 0x26, 0x000F,
325 0x28, 0x0201,
326 0x2C, 0xBB80,
327 0x32, 0xBB80,
328 0x7C, 0x8384,
329 0x7E, 0x7644,
330 (unsigned short)-1
331 };
332 unsigned int tmp;
333
334 /* Cold reset */
335 tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
336 snd_ice1712_gpio_write(ice, tmp);
337 udelay(3);
338
339 tmp &= ~AUREON_AC97_RESET;
340 snd_ice1712_gpio_write(ice, tmp);
341 udelay(3);
342
343 tmp |= AUREON_AC97_RESET;
344 snd_ice1712_gpio_write(ice, tmp);
345 udelay(3);
346
347 memset(&spec->stac9744, 0, sizeof(spec->stac9744));
348 for (i=0; ac97_defaults[i] != (unsigned short)-1; i+=2)
349 spec->stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
350
351 aureon_ac97_write(ice, AC97_MASTER, 0x0000); // Unmute AC'97 master volume permanently - muting is done by WM8770
352
353 return 0;
354 }
355
356 #define AUREON_AC97_STEREO 0x80
357
358 /*
359 * AC'97 volume controls
360 */
361 static int aureon_ac97_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
362 {
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;
368 }
369
370 static int aureon_ac97_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
371 {
372 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
373 unsigned short vol;
374
375 mutex_lock(&ice->gpio_mutex);
376
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);
381
382 mutex_unlock(&ice->gpio_mutex);
383 return 0;
384 }
385
386 static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
387 {
388 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
389 unsigned short ovol, nvol;
390 int change;
391
392 snd_ice1712_save_gpio_status(ice);
393
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;
399
400 if ((change = (ovol != nvol)))
401 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
402
403 snd_ice1712_restore_gpio_status(ice);
404
405 return change;
406 }
407
408 /*
409 * AC'97 mute controls
410 */
411 #define aureon_ac97_mute_info snd_ctl_boolean_mono_info
412
413 static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
414 {
415 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
416
417 mutex_lock(&ice->gpio_mutex);
418
419 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
420
421 mutex_unlock(&ice->gpio_mutex);
422 return 0;
423 }
424
425 static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
426 {
427 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
428 unsigned short ovol, nvol;
429 int change;
430
431 snd_ice1712_save_gpio_status(ice);
432
433 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
434 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~ 0x8000);
435
436 if ((change = (ovol != nvol)))
437 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
438
439 snd_ice1712_restore_gpio_status(ice);
440
441 return change;
442 }
443
444 /*
445 * AC'97 mute controls
446 */
447 #define aureon_ac97_micboost_info snd_ctl_boolean_mono_info
448
449 static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
450 {
451 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
452
453 mutex_lock(&ice->gpio_mutex);
454
455 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
456
457 mutex_unlock(&ice->gpio_mutex);
458 return 0;
459 }
460
461 static int aureon_ac97_micboost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
462 {
463 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
464 unsigned short ovol, nvol;
465 int change;
466
467 snd_ice1712_save_gpio_status(ice);
468
469 ovol = aureon_ac97_read(ice, AC97_MIC);
470 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020);
471
472 if ((change = (ovol != nvol)))
473 aureon_ac97_write(ice, AC97_MIC, nvol);
474
475 snd_ice1712_restore_gpio_status(ice);
476
477 return change;
478 }
479
480 /*
481 * write data in the SPI mode
482 */
483 static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits)
484 {
485 unsigned int tmp;
486 int i;
487 unsigned int mosi, clk;
488
489 tmp = snd_ice1712_gpio_read(ice);
490
491 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
492 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) {
493 snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS));
494 mosi = PRODIGY_SPI_MOSI;
495 clk = PRODIGY_SPI_CLK;
496 }
497 else {
498 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
499 AUREON_WM_CS|AUREON_CS8415_CS));
500 mosi = AUREON_SPI_MOSI;
501 clk = AUREON_SPI_CLK;
502
503 tmp |= AUREON_WM_RW;
504 }
505
506 tmp &= ~cs;
507 snd_ice1712_gpio_write(ice, tmp);
508 udelay(1);
509
510 for (i = bits - 1; i >= 0; i--) {
511 tmp &= ~clk;
512 snd_ice1712_gpio_write(ice, tmp);
513 udelay(1);
514 if (data & (1 << i))
515 tmp |= mosi;
516 else
517 tmp &= ~mosi;
518 snd_ice1712_gpio_write(ice, tmp);
519 udelay(1);
520 tmp |= clk;
521 snd_ice1712_gpio_write(ice, tmp);
522 udelay(1);
523 }
524
525 tmp &= ~clk;
526 tmp |= cs;
527 snd_ice1712_gpio_write(ice, tmp);
528 udelay(1);
529 tmp |= clk;
530 snd_ice1712_gpio_write(ice, tmp);
531 udelay(1);
532 }
533
534 /*
535 * Read data in SPI mode
536 */
537 static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits, unsigned char *buffer, int size) {
538 int i, j;
539 unsigned int tmp;
540
541 tmp = (snd_ice1712_gpio_read(ice) & ~AUREON_SPI_CLK) | AUREON_CS8415_CS|AUREON_WM_CS;
542 snd_ice1712_gpio_write(ice, tmp);
543 tmp &= ~cs;
544 snd_ice1712_gpio_write(ice, tmp);
545 udelay(1);
546
547 for (i=bits-1; i>=0; i--) {
548 if (data & (1 << i))
549 tmp |= AUREON_SPI_MOSI;
550 else
551 tmp &= ~AUREON_SPI_MOSI;
552 snd_ice1712_gpio_write(ice, tmp);
553 udelay(1);
554
555 tmp |= AUREON_SPI_CLK;
556 snd_ice1712_gpio_write(ice, tmp);
557 udelay(1);
558
559 tmp &= ~AUREON_SPI_CLK;
560 snd_ice1712_gpio_write(ice, tmp);
561 udelay(1);
562 }
563
564 for (j=0; j<size; j++) {
565 unsigned char outdata = 0;
566 for (i=7; i>=0; i--) {
567 tmp = snd_ice1712_gpio_read(ice);
568 outdata <<= 1;
569 outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0;
570 udelay(1);
571
572 tmp |= AUREON_SPI_CLK;
573 snd_ice1712_gpio_write(ice, tmp);
574 udelay(1);
575
576 tmp &= ~AUREON_SPI_CLK;
577 snd_ice1712_gpio_write(ice, tmp);
578 udelay(1);
579 }
580 buffer[j] = outdata;
581 }
582
583 tmp |= cs;
584 snd_ice1712_gpio_write(ice, tmp);
585 }
586
587 static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg) {
588 unsigned char val;
589 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
590 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1);
591 return val;
592 }
593
594 static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg, unsigned char *buffer, int size) {
595 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
596 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size);
597 }
598
599 static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg, unsigned char val) {
600 aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24);
601 }
602
603 /*
604 * get the current register value of WM codec
605 */
606 static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
607 {
608 reg <<= 1;
609 return ((unsigned short)ice->akm[0].images[reg] << 8) |
610 ice->akm[0].images[reg + 1];
611 }
612
613 /*
614 * set the register value of WM codec
615 */
616 static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
617 {
618 aureon_spi_write(ice,
619 ((ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
620 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) ?
621 PRODIGY_WM_CS : AUREON_WM_CS),
622 (reg << 9) | (val & 0x1ff), 16);
623 }
624
625 /*
626 * set the register value of WM codec and remember it
627 */
628 static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
629 {
630 wm_put_nocache(ice, reg, val);
631 reg <<= 1;
632 ice->akm[0].images[reg] = val >> 8;
633 ice->akm[0].images[reg + 1] = val;
634 }
635
636 /*
637 */
638 #define aureon_mono_bool_info snd_ctl_boolean_mono_info
639
640 /*
641 * AC'97 master playback mute controls (Mute on WM8770 chip)
642 */
643 #define aureon_ac97_mmute_info snd_ctl_boolean_mono_info
644
645 static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
646 {
647 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
648
649 mutex_lock(&ice->gpio_mutex);
650
651 ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
652
653 mutex_unlock(&ice->gpio_mutex);
654 return 0;
655 }
656
657 static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
658 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
659 unsigned short ovol, nvol;
660 int change;
661
662 snd_ice1712_save_gpio_status(ice);
663
664 ovol = wm_get(ice, WM_OUT_MUX1);
665 nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00);
666 if ((change = (ovol != nvol)))
667 wm_put(ice, WM_OUT_MUX1, nvol);
668
669 snd_ice1712_restore_gpio_status(ice);
670
671 return change;
672 }
673
674 static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
675 static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
676 static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0);
677 static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0);
678 static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0);
679
680 /*
681 * Logarithmic volume values for WM8770
682 * Computed as 20 * Log10(255 / x)
683 */
684 static const unsigned char wm_vol[256] = {
685 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
686 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
687 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
688 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
689 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
690 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
691 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
692 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
693 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
694 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
695 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
696 0, 0
697 };
698
699 #define WM_VOL_MAX (sizeof(wm_vol) - 1)
700 #define WM_VOL_MUTE 0x8000
701
702 static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
703 {
704 unsigned char nvol;
705
706 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
707 nvol = 0;
708 else
709 nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
710
711 wm_put(ice, index, nvol);
712 wm_put_nocache(ice, index, 0x180 | nvol);
713 }
714
715 /*
716 * DAC mute control
717 */
718 #define wm_pcm_mute_info snd_ctl_boolean_mono_info
719
720 static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
721 {
722 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
723
724 mutex_lock(&ice->gpio_mutex);
725 ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
726 mutex_unlock(&ice->gpio_mutex);
727 return 0;
728 }
729
730 static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
731 {
732 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
733 unsigned short nval, oval;
734 int change;
735
736 snd_ice1712_save_gpio_status(ice);
737 oval = wm_get(ice, WM_MUTE);
738 nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
739 if ((change = (nval != oval)))
740 wm_put(ice, WM_MUTE, nval);
741 snd_ice1712_restore_gpio_status(ice);
742
743 return change;
744 }
745
746 /*
747 * Master volume attenuation mixer control
748 */
749 static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
750 {
751 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
752 uinfo->count = 2;
753 uinfo->value.integer.min = 0;
754 uinfo->value.integer.max = WM_VOL_MAX;
755 return 0;
756 }
757
758 static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
759 {
760 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
761 struct aureon_spec *spec = ice->spec;
762 int i;
763 for (i=0; i<2; i++)
764 ucontrol->value.integer.value[i] =
765 spec->master[i] & ~WM_VOL_MUTE;
766 return 0;
767 }
768
769 static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
770 {
771 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
772 struct aureon_spec *spec = ice->spec;
773 int ch, change = 0;
774
775 snd_ice1712_save_gpio_status(ice);
776 for (ch = 0; ch < 2; ch++) {
777 unsigned int vol = ucontrol->value.integer.value[ch];
778 if (vol > WM_VOL_MAX)
779 continue;
780 vol |= spec->master[ch] & WM_VOL_MUTE;
781 if (vol != spec->master[ch]) {
782 int dac;
783 spec->master[ch] = vol;
784 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
785 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
786 spec->vol[dac + ch],
787 spec->master[ch]);
788 change = 1;
789 }
790 }
791 snd_ice1712_restore_gpio_status(ice);
792 return change;
793 }
794
795 /*
796 * DAC volume attenuation mixer control
797 */
798 static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
799 {
800 int voices = kcontrol->private_value >> 8;
801 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
802 uinfo->count = voices;
803 uinfo->value.integer.min = 0; /* mute (-101dB) */
804 uinfo->value.integer.max = 0x7F; /* 0dB */
805 return 0;
806 }
807
808 static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
809 {
810 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
811 struct aureon_spec *spec = ice->spec;
812 int i, ofs, voices;
813
814 voices = kcontrol->private_value >> 8;
815 ofs = kcontrol->private_value & 0xff;
816 for (i = 0; i < voices; i++)
817 ucontrol->value.integer.value[i] =
818 spec->vol[ofs+i] & ~WM_VOL_MUTE;
819 return 0;
820 }
821
822 static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
823 {
824 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
825 struct aureon_spec *spec = ice->spec;
826 int i, idx, ofs, voices;
827 int change = 0;
828
829 voices = kcontrol->private_value >> 8;
830 ofs = kcontrol->private_value & 0xff;
831 snd_ice1712_save_gpio_status(ice);
832 for (i = 0; i < voices; i++) {
833 unsigned int vol = ucontrol->value.integer.value[i];
834 if (vol > 0x7f)
835 continue;
836 vol |= spec->vol[ofs+i];
837 if (vol != spec->vol[ofs+i]) {
838 spec->vol[ofs+i] = vol;
839 idx = WM_DAC_ATTEN + ofs + i;
840 wm_set_vol(ice, idx, spec->vol[ofs + i],
841 spec->master[i]);
842 change = 1;
843 }
844 }
845 snd_ice1712_restore_gpio_status(ice);
846 return change;
847 }
848
849 /*
850 * WM8770 mute control
851 */
852 static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
853 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
854 uinfo->count = kcontrol->private_value >> 8;
855 uinfo->value.integer.min = 0;
856 uinfo->value.integer.max = 1;
857 return 0;
858 }
859
860 static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
861 {
862 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
863 struct aureon_spec *spec = ice->spec;
864 int voices, ofs, i;
865
866 voices = kcontrol->private_value >> 8;
867 ofs = kcontrol->private_value & 0xFF;
868
869 for (i = 0; i < voices; i++)
870 ucontrol->value.integer.value[i] =
871 (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
872 return 0;
873 }
874
875 static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
876 {
877 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
878 struct aureon_spec *spec = ice->spec;
879 int change = 0, voices, ofs, i;
880
881 voices = kcontrol->private_value >> 8;
882 ofs = kcontrol->private_value & 0xFF;
883
884 snd_ice1712_save_gpio_status(ice);
885 for (i = 0; i < voices; i++) {
886 int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
887 if (ucontrol->value.integer.value[i] != val) {
888 spec->vol[ofs + i] &= ~WM_VOL_MUTE;
889 spec->vol[ofs + i] |=
890 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
891 wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
892 spec->master[i]);
893 change = 1;
894 }
895 }
896 snd_ice1712_restore_gpio_status(ice);
897
898 return change;
899 }
900
901 /*
902 * WM8770 master mute control
903 */
904 #define wm_master_mute_info snd_ctl_boolean_stereo_info
905
906 static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
907 {
908 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
909 struct aureon_spec *spec = ice->spec;
910
911 ucontrol->value.integer.value[0] =
912 (spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
913 ucontrol->value.integer.value[1] =
914 (spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
915 return 0;
916 }
917
918 static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
919 {
920 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
921 struct aureon_spec *spec = ice->spec;
922 int change = 0, i;
923
924 snd_ice1712_save_gpio_status(ice);
925 for (i = 0; i < 2; i++) {
926 int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
927 if (ucontrol->value.integer.value[i] != val) {
928 int dac;
929 spec->master[i] &= ~WM_VOL_MUTE;
930 spec->master[i] |=
931 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
932 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
933 wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
934 spec->vol[dac + i],
935 spec->master[i]);
936 change = 1;
937 }
938 }
939 snd_ice1712_restore_gpio_status(ice);
940
941 return change;
942 }
943
944 /* digital master volume */
945 #define PCM_0dB 0xff
946 #define PCM_RES 128 /* -64dB */
947 #define PCM_MIN (PCM_0dB - PCM_RES)
948 static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
949 {
950 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
951 uinfo->count = 1;
952 uinfo->value.integer.min = 0; /* mute (-64dB) */
953 uinfo->value.integer.max = PCM_RES; /* 0dB */
954 return 0;
955 }
956
957 static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
958 {
959 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
960 unsigned short val;
961
962 mutex_lock(&ice->gpio_mutex);
963 val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
964 val = val > PCM_MIN ? (val - PCM_MIN) : 0;
965 ucontrol->value.integer.value[0] = val;
966 mutex_unlock(&ice->gpio_mutex);
967 return 0;
968 }
969
970 static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
971 {
972 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
973 unsigned short ovol, nvol;
974 int change = 0;
975
976 nvol = ucontrol->value.integer.value[0];
977 if (nvol > PCM_RES)
978 return -EINVAL;
979 snd_ice1712_save_gpio_status(ice);
980 nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
981 ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
982 if (ovol != nvol) {
983 wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
984 wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
985 change = 1;
986 }
987 snd_ice1712_restore_gpio_status(ice);
988 return change;
989 }
990
991 /*
992 * ADC mute control
993 */
994 #define wm_adc_mute_info snd_ctl_boolean_stereo_info
995
996 static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
997 {
998 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
999 unsigned short val;
1000 int i;
1001
1002 mutex_lock(&ice->gpio_mutex);
1003 for (i = 0; i < 2; i++) {
1004 val = wm_get(ice, WM_ADC_GAIN + i);
1005 ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
1006 }
1007 mutex_unlock(&ice->gpio_mutex);
1008 return 0;
1009 }
1010
1011 static int wm_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1012 {
1013 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1014 unsigned short new, old;
1015 int i, change = 0;
1016
1017 snd_ice1712_save_gpio_status(ice);
1018 for (i = 0; i < 2; i++) {
1019 old = wm_get(ice, WM_ADC_GAIN + i);
1020 new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
1021 if (new != old) {
1022 wm_put(ice, WM_ADC_GAIN + i, new);
1023 change = 1;
1024 }
1025 }
1026 snd_ice1712_restore_gpio_status(ice);
1027
1028 return change;
1029 }
1030
1031 /*
1032 * ADC gain mixer control
1033 */
1034 static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1035 {
1036 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1037 uinfo->count = 2;
1038 uinfo->value.integer.min = 0; /* -12dB */
1039 uinfo->value.integer.max = 0x1f; /* 19dB */
1040 return 0;
1041 }
1042
1043 static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1044 {
1045 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1046 int i, idx;
1047 unsigned short vol;
1048
1049 mutex_lock(&ice->gpio_mutex);
1050 for (i = 0; i < 2; i++) {
1051 idx = WM_ADC_GAIN + i;
1052 vol = wm_get(ice, idx) & 0x1f;
1053 ucontrol->value.integer.value[i] = vol;
1054 }
1055 mutex_unlock(&ice->gpio_mutex);
1056 return 0;
1057 }
1058
1059 static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1060 {
1061 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1062 int i, idx;
1063 unsigned short ovol, nvol;
1064 int change = 0;
1065
1066 snd_ice1712_save_gpio_status(ice);
1067 for (i = 0; i < 2; i++) {
1068 idx = WM_ADC_GAIN + i;
1069 nvol = ucontrol->value.integer.value[i] & 0x1f;
1070 ovol = wm_get(ice, idx);
1071 if ((ovol & 0x1f) != nvol) {
1072 wm_put(ice, idx, nvol | (ovol & ~0x1f));
1073 change = 1;
1074 }
1075 }
1076 snd_ice1712_restore_gpio_status(ice);
1077 return change;
1078 }
1079
1080 /*
1081 * ADC input mux mixer control
1082 */
1083 static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1084 {
1085 static const char * const texts[] = {
1086 "CD", //AIN1
1087 "Aux", //AIN2
1088 "Line", //AIN3
1089 "Mic", //AIN4
1090 "AC97" //AIN5
1091 };
1092 static const char * const universe_texts[] = {
1093 "Aux1", //AIN1
1094 "CD", //AIN2
1095 "Phono", //AIN3
1096 "Line", //AIN4
1097 "Aux2", //AIN5
1098 "Mic", //AIN6
1099 "Aux3", //AIN7
1100 "AC97" //AIN8
1101 };
1102 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1103
1104 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1105 uinfo->count = 2;
1106 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1107 uinfo->value.enumerated.items = 8;
1108 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1109 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1110 strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]);
1111 }
1112 else {
1113 uinfo->value.enumerated.items = 5;
1114 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1115 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1116 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1117 }
1118 return 0;
1119 }
1120
1121 static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1122 {
1123 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1124 unsigned short val;
1125
1126 mutex_lock(&ice->gpio_mutex);
1127 val = wm_get(ice, WM_ADC_MUX);
1128 ucontrol->value.enumerated.item[0] = val & 7;
1129 ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
1130 mutex_unlock(&ice->gpio_mutex);
1131 return 0;
1132 }
1133
1134 static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1135 {
1136 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1137 unsigned short oval, nval;
1138 int change;
1139
1140 snd_ice1712_save_gpio_status(ice);
1141 oval = wm_get(ice, WM_ADC_MUX);
1142 nval = oval & ~0x77;
1143 nval |= ucontrol->value.enumerated.item[0] & 7;
1144 nval |= (ucontrol->value.enumerated.item[1] & 7) << 4;
1145 change = (oval != nval);
1146 if (change)
1147 wm_put(ice, WM_ADC_MUX, nval);
1148 snd_ice1712_restore_gpio_status(ice);
1149 return change;
1150 }
1151
1152 /*
1153 * CS8415 Input mux
1154 */
1155 static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1156 {
1157 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1158 static const char * const aureon_texts[] = {
1159 "CD", //RXP0
1160 "Optical" //RXP1
1161 };
1162 static const char * const prodigy_texts[] = {
1163 "CD",
1164 "Coax"
1165 };
1166 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1167 uinfo->count = 1;
1168 uinfo->value.enumerated.items = 2;
1169 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1170 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1171 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
1172 strcpy(uinfo->value.enumerated.name, prodigy_texts[uinfo->value.enumerated.item]);
1173 else
1174 strcpy(uinfo->value.enumerated.name, aureon_texts[uinfo->value.enumerated.item]);
1175 return 0;
1176 }
1177
1178 static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1179 {
1180 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1181 struct aureon_spec *spec = ice->spec;
1182
1183 //snd_ice1712_save_gpio_status(ice);
1184 //val = aureon_cs8415_get(ice, CS8415_CTRL2);
1185 ucontrol->value.enumerated.item[0] = spec->cs8415_mux;
1186 //snd_ice1712_restore_gpio_status(ice);
1187 return 0;
1188 }
1189
1190 static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1191 {
1192 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1193 struct aureon_spec *spec = ice->spec;
1194 unsigned short oval, nval;
1195 int change;
1196
1197 snd_ice1712_save_gpio_status(ice);
1198 oval = aureon_cs8415_get(ice, CS8415_CTRL2);
1199 nval = oval & ~0x07;
1200 nval |= ucontrol->value.enumerated.item[0] & 7;
1201 change = (oval != nval);
1202 if (change)
1203 aureon_cs8415_put(ice, CS8415_CTRL2, nval);
1204 snd_ice1712_restore_gpio_status(ice);
1205 spec->cs8415_mux = ucontrol->value.enumerated.item[0];
1206 return change;
1207 }
1208
1209 static int aureon_cs8415_rate_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1210 {
1211 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1212 uinfo->count = 1;
1213 uinfo->value.integer.min = 0;
1214 uinfo->value.integer.max = 192000;
1215 return 0;
1216 }
1217
1218 static int aureon_cs8415_rate_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1219 {
1220 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1221 unsigned char ratio;
1222 ratio = aureon_cs8415_get(ice, CS8415_RATIO);
1223 ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750);
1224 return 0;
1225 }
1226
1227 /*
1228 * CS8415A Mute
1229 */
1230 #define aureon_cs8415_mute_info snd_ctl_boolean_mono_info
1231
1232 static int aureon_cs8415_mute_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1233 {
1234 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1235 snd_ice1712_save_gpio_status(ice);
1236 ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1;
1237 snd_ice1712_restore_gpio_status(ice);
1238 return 0;
1239 }
1240
1241 static int aureon_cs8415_mute_put (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1242 {
1243 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1244 unsigned char oval, nval;
1245 int change;
1246 snd_ice1712_save_gpio_status(ice);
1247 oval = aureon_cs8415_get(ice, CS8415_CTRL1);
1248 if (ucontrol->value.integer.value[0])
1249 nval = oval & ~0x20;
1250 else
1251 nval = oval | 0x20;
1252 if ((change = (oval != nval)))
1253 aureon_cs8415_put(ice, CS8415_CTRL1, nval);
1254 snd_ice1712_restore_gpio_status(ice);
1255 return change;
1256 }
1257
1258 /*
1259 * CS8415A Q-Sub info
1260 */
1261 static int aureon_cs8415_qsub_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
1262 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1263 uinfo->count = 10;
1264 return 0;
1265 }
1266
1267 static int aureon_cs8415_qsub_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
1268 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1269
1270 snd_ice1712_save_gpio_status(ice);
1271 aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
1272 snd_ice1712_restore_gpio_status(ice);
1273
1274 return 0;
1275 }
1276
1277 static int aureon_cs8415_spdif_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
1278 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1279 uinfo->count = 1;
1280 return 0;
1281 }
1282
1283 static int aureon_cs8415_mask_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
1284 memset(ucontrol->value.iec958.status, 0xFF, 24);
1285 return 0;
1286 }
1287
1288 static int aureon_cs8415_spdif_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
1289 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1290
1291 snd_ice1712_save_gpio_status(ice);
1292 aureon_cs8415_read(ice, CS8415_C_BUFFER, ucontrol->value.iec958.status, 24);
1293 snd_ice1712_restore_gpio_status(ice);
1294 return 0;
1295 }
1296
1297 /*
1298 * Headphone Amplifier
1299 */
1300 static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
1301 {
1302 unsigned int tmp, tmp2;
1303
1304 tmp2 = tmp = snd_ice1712_gpio_read(ice);
1305 if (enable)
1306 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1307 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1308 tmp |= AUREON_HP_SEL;
1309 else
1310 tmp |= PRODIGY_HP_SEL;
1311 else
1312 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1313 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1314 tmp &= ~ AUREON_HP_SEL;
1315 else
1316 tmp &= ~ PRODIGY_HP_SEL;
1317 if (tmp != tmp2) {
1318 snd_ice1712_gpio_write(ice, tmp);
1319 return 1;
1320 }
1321 return 0;
1322 }
1323
1324 static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
1325 {
1326 unsigned int tmp = snd_ice1712_gpio_read(ice);
1327
1328 return ( tmp & AUREON_HP_SEL )!= 0;
1329 }
1330
1331 #define aureon_hpamp_info snd_ctl_boolean_mono_info
1332
1333 static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1334 {
1335 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1336
1337 ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
1338 return 0;
1339 }
1340
1341
1342 static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1343 {
1344 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1345
1346 return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]);
1347 }
1348
1349 /*
1350 * Deemphasis
1351 */
1352
1353 #define aureon_deemp_info snd_ctl_boolean_mono_info
1354
1355 static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1356 {
1357 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1358 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
1359 return 0;
1360 }
1361
1362 static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1363 {
1364 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1365 int temp, temp2;
1366 temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
1367 if (ucontrol->value.integer.value[0])
1368 temp |= 0xf;
1369 else
1370 temp &= ~0xf;
1371 if (temp != temp2) {
1372 wm_put(ice, WM_DAC_CTRL2, temp);
1373 return 1;
1374 }
1375 return 0;
1376 }
1377
1378 /*
1379 * ADC Oversampling
1380 */
1381 static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
1382 {
1383 static const char * const texts[2] = { "128x", "64x" };
1384
1385 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1386 uinfo->count = 1;
1387 uinfo->value.enumerated.items = 2;
1388
1389 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1390 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1391 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1392
1393 return 0;
1394 }
1395
1396 static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1397 {
1398 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1399 ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
1400 return 0;
1401 }
1402
1403 static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1404 {
1405 int temp, temp2;
1406 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1407
1408 temp2 = temp = wm_get(ice, WM_MASTER);
1409
1410 if (ucontrol->value.enumerated.item[0])
1411 temp |= 0x8;
1412 else
1413 temp &= ~0x8;
1414
1415 if (temp != temp2) {
1416 wm_put(ice, WM_MASTER, temp);
1417 return 1;
1418 }
1419 return 0;
1420 }
1421
1422 /*
1423 * mixers
1424 */
1425
1426 static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
1427 {
1428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1429 .name = "Master Playback Switch",
1430 .info = wm_master_mute_info,
1431 .get = wm_master_mute_get,
1432 .put = wm_master_mute_put
1433 },
1434 {
1435 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1436 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1437 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1438 .name = "Master Playback Volume",
1439 .info = wm_master_vol_info,
1440 .get = wm_master_vol_get,
1441 .put = wm_master_vol_put,
1442 .tlv = { .p = db_scale_wm_dac }
1443 },
1444 {
1445 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1446 .name = "Front Playback Switch",
1447 .info = wm_mute_info,
1448 .get = wm_mute_get,
1449 .put = wm_mute_put,
1450 .private_value = (2 << 8) | 0
1451 },
1452 {
1453 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1454 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1455 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1456 .name = "Front Playback Volume",
1457 .info = wm_vol_info,
1458 .get = wm_vol_get,
1459 .put = wm_vol_put,
1460 .private_value = (2 << 8) | 0,
1461 .tlv = { .p = db_scale_wm_dac }
1462 },
1463 {
1464 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1465 .name = "Rear Playback Switch",
1466 .info = wm_mute_info,
1467 .get = wm_mute_get,
1468 .put = wm_mute_put,
1469 .private_value = (2 << 8) | 2
1470 },
1471 {
1472 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1473 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1474 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1475 .name = "Rear Playback Volume",
1476 .info = wm_vol_info,
1477 .get = wm_vol_get,
1478 .put = wm_vol_put,
1479 .private_value = (2 << 8) | 2,
1480 .tlv = { .p = db_scale_wm_dac }
1481 },
1482 {
1483 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1484 .name = "Center Playback Switch",
1485 .info = wm_mute_info,
1486 .get = wm_mute_get,
1487 .put = wm_mute_put,
1488 .private_value = (1 << 8) | 4
1489 },
1490 {
1491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1492 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1493 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1494 .name = "Center Playback Volume",
1495 .info = wm_vol_info,
1496 .get = wm_vol_get,
1497 .put = wm_vol_put,
1498 .private_value = (1 << 8) | 4,
1499 .tlv = { .p = db_scale_wm_dac }
1500 },
1501 {
1502 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1503 .name = "LFE Playback Switch",
1504 .info = wm_mute_info,
1505 .get = wm_mute_get,
1506 .put = wm_mute_put,
1507 .private_value = (1 << 8) | 5
1508 },
1509 {
1510 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1511 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1512 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1513 .name = "LFE Playback Volume",
1514 .info = wm_vol_info,
1515 .get = wm_vol_get,
1516 .put = wm_vol_put,
1517 .private_value = (1 << 8) | 5,
1518 .tlv = { .p = db_scale_wm_dac }
1519 },
1520 {
1521 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1522 .name = "Side Playback Switch",
1523 .info = wm_mute_info,
1524 .get = wm_mute_get,
1525 .put = wm_mute_put,
1526 .private_value = (2 << 8) | 6
1527 },
1528 {
1529 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1530 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1531 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1532 .name = "Side Playback Volume",
1533 .info = wm_vol_info,
1534 .get = wm_vol_get,
1535 .put = wm_vol_put,
1536 .private_value = (2 << 8) | 6,
1537 .tlv = { .p = db_scale_wm_dac }
1538 }
1539 };
1540
1541 static struct snd_kcontrol_new wm_controls[] __devinitdata = {
1542 {
1543 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1544 .name = "PCM Playback Switch",
1545 .info = wm_pcm_mute_info,
1546 .get = wm_pcm_mute_get,
1547 .put = wm_pcm_mute_put
1548 },
1549 {
1550 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1551 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1552 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1553 .name = "PCM Playback Volume",
1554 .info = wm_pcm_vol_info,
1555 .get = wm_pcm_vol_get,
1556 .put = wm_pcm_vol_put,
1557 .tlv = { .p = db_scale_wm_pcm }
1558 },
1559 {
1560 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1561 .name = "Capture Switch",
1562 .info = wm_adc_mute_info,
1563 .get = wm_adc_mute_get,
1564 .put = wm_adc_mute_put,
1565 },
1566 {
1567 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1568 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1569 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1570 .name = "Capture Volume",
1571 .info = wm_adc_vol_info,
1572 .get = wm_adc_vol_get,
1573 .put = wm_adc_vol_put,
1574 .tlv = { .p = db_scale_wm_adc }
1575 },
1576 {
1577 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1578 .name = "Capture Source",
1579 .info = wm_adc_mux_info,
1580 .get = wm_adc_mux_get,
1581 .put = wm_adc_mux_put,
1582 .private_value = 5
1583 },
1584 {
1585 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1586 .name = "External Amplifier",
1587 .info = aureon_hpamp_info,
1588 .get = aureon_hpamp_get,
1589 .put = aureon_hpamp_put
1590 },
1591 {
1592 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1593 .name = "DAC Deemphasis Switch",
1594 .info = aureon_deemp_info,
1595 .get = aureon_deemp_get,
1596 .put = aureon_deemp_put
1597 },
1598 {
1599 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1600 .name = "ADC Oversampling",
1601 .info = aureon_oversampling_info,
1602 .get = aureon_oversampling_get,
1603 .put = aureon_oversampling_put
1604 }
1605 };
1606
1607 static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
1608 {
1609 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1610 .name = "AC97 Playback Switch",
1611 .info = aureon_ac97_mmute_info,
1612 .get = aureon_ac97_mmute_get,
1613 .put = aureon_ac97_mmute_put,
1614 .private_value = AC97_MASTER
1615 },
1616 {
1617 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1618 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1619 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1620 .name = "AC97 Playback Volume",
1621 .info = aureon_ac97_vol_info,
1622 .get = aureon_ac97_vol_get,
1623 .put = aureon_ac97_vol_put,
1624 .private_value = AC97_MASTER|AUREON_AC97_STEREO,
1625 .tlv = { .p = db_scale_ac97_master }
1626 },
1627 {
1628 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1629 .name = "CD Playback Switch",
1630 .info = aureon_ac97_mute_info,
1631 .get = aureon_ac97_mute_get,
1632 .put = aureon_ac97_mute_put,
1633 .private_value = AC97_CD
1634 },
1635 {
1636 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1637 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1638 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1639 .name = "CD Playback Volume",
1640 .info = aureon_ac97_vol_info,
1641 .get = aureon_ac97_vol_get,
1642 .put = aureon_ac97_vol_put,
1643 .private_value = AC97_CD|AUREON_AC97_STEREO,
1644 .tlv = { .p = db_scale_ac97_gain }
1645 },
1646 {
1647 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1648 .name = "Aux Playback Switch",
1649 .info = aureon_ac97_mute_info,
1650 .get = aureon_ac97_mute_get,
1651 .put = aureon_ac97_mute_put,
1652 .private_value = AC97_AUX,
1653 },
1654 {
1655 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1656 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1657 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1658 .name = "Aux Playback Volume",
1659 .info = aureon_ac97_vol_info,
1660 .get = aureon_ac97_vol_get,
1661 .put = aureon_ac97_vol_put,
1662 .private_value = AC97_AUX|AUREON_AC97_STEREO,
1663 .tlv = { .p = db_scale_ac97_gain }
1664 },
1665 {
1666 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1667 .name = "Line Playback Switch",
1668 .info = aureon_ac97_mute_info,
1669 .get = aureon_ac97_mute_get,
1670 .put = aureon_ac97_mute_put,
1671 .private_value = AC97_LINE
1672 },
1673 {
1674 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1675 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1676 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1677 .name = "Line Playback Volume",
1678 .info = aureon_ac97_vol_info,
1679 .get = aureon_ac97_vol_get,
1680 .put = aureon_ac97_vol_put,
1681 .private_value = AC97_LINE|AUREON_AC97_STEREO,
1682 .tlv = { .p = db_scale_ac97_gain }
1683 },
1684 {
1685 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1686 .name = "Mic Playback Switch",
1687 .info = aureon_ac97_mute_info,
1688 .get = aureon_ac97_mute_get,
1689 .put = aureon_ac97_mute_put,
1690 .private_value = AC97_MIC
1691 },
1692 {
1693 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1694 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1695 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1696 .name = "Mic Playback Volume",
1697 .info = aureon_ac97_vol_info,
1698 .get = aureon_ac97_vol_get,
1699 .put = aureon_ac97_vol_put,
1700 .private_value = AC97_MIC,
1701 .tlv = { .p = db_scale_ac97_gain }
1702 },
1703 {
1704 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1705 .name = "Mic Boost (+20dB)",
1706 .info = aureon_ac97_micboost_info,
1707 .get = aureon_ac97_micboost_get,
1708 .put = aureon_ac97_micboost_put
1709 }
1710 };
1711
1712 static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
1713 {
1714 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1715 .name = "AC97 Playback Switch",
1716 .info = aureon_ac97_mmute_info,
1717 .get = aureon_ac97_mmute_get,
1718 .put = aureon_ac97_mmute_put,
1719 .private_value = AC97_MASTER
1720 },
1721 {
1722 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1723 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1724 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1725 .name = "AC97 Playback Volume",
1726 .info = aureon_ac97_vol_info,
1727 .get = aureon_ac97_vol_get,
1728 .put = aureon_ac97_vol_put,
1729 .private_value = AC97_MASTER|AUREON_AC97_STEREO,
1730 .tlv = { .p = db_scale_ac97_master }
1731 },
1732 {
1733 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1734 .name = "CD Playback Switch",
1735 .info = aureon_ac97_mute_info,
1736 .get = aureon_ac97_mute_get,
1737 .put = aureon_ac97_mute_put,
1738 .private_value = AC97_AUX
1739 },
1740 {
1741 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1742 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1743 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1744 .name = "CD Playback Volume",
1745 .info = aureon_ac97_vol_info,
1746 .get = aureon_ac97_vol_get,
1747 .put = aureon_ac97_vol_put,
1748 .private_value = AC97_AUX|AUREON_AC97_STEREO,
1749 .tlv = { .p = db_scale_ac97_gain }
1750 },
1751 {
1752 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1753 .name = "Phono Playback Switch",
1754 .info = aureon_ac97_mute_info,
1755 .get = aureon_ac97_mute_get,
1756 .put = aureon_ac97_mute_put,
1757 .private_value = AC97_CD
1758 },
1759 {
1760 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1761 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1762 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1763 .name = "Phono Playback Volume",
1764 .info = aureon_ac97_vol_info,
1765 .get = aureon_ac97_vol_get,
1766 .put = aureon_ac97_vol_put,
1767 .private_value = AC97_CD|AUREON_AC97_STEREO,
1768 .tlv = { .p = db_scale_ac97_gain }
1769 },
1770 {
1771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1772 .name = "Line Playback Switch",
1773 .info = aureon_ac97_mute_info,
1774 .get = aureon_ac97_mute_get,
1775 .put = aureon_ac97_mute_put,
1776 .private_value = AC97_LINE
1777 },
1778 {
1779 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1780 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1781 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1782 .name = "Line Playback Volume",
1783 .info = aureon_ac97_vol_info,
1784 .get = aureon_ac97_vol_get,
1785 .put = aureon_ac97_vol_put,
1786 .private_value = AC97_LINE|AUREON_AC97_STEREO,
1787 .tlv = { .p = db_scale_ac97_gain }
1788 },
1789 {
1790 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1791 .name = "Mic Playback Switch",
1792 .info = aureon_ac97_mute_info,
1793 .get = aureon_ac97_mute_get,
1794 .put = aureon_ac97_mute_put,
1795 .private_value = AC97_MIC
1796 },
1797 {
1798 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1799 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1800 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1801 .name = "Mic Playback Volume",
1802 .info = aureon_ac97_vol_info,
1803 .get = aureon_ac97_vol_get,
1804 .put = aureon_ac97_vol_put,
1805 .private_value = AC97_MIC,
1806 .tlv = { .p = db_scale_ac97_gain }
1807 },
1808 {
1809 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1810 .name = "Mic Boost (+20dB)",
1811 .info = aureon_ac97_micboost_info,
1812 .get = aureon_ac97_micboost_get,
1813 .put = aureon_ac97_micboost_put
1814 },
1815 {
1816 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1817 .name = "Aux Playback Switch",
1818 .info = aureon_ac97_mute_info,
1819 .get = aureon_ac97_mute_get,
1820 .put = aureon_ac97_mute_put,
1821 .private_value = AC97_VIDEO,
1822 },
1823 {
1824 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1825 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1826 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1827 .name = "Aux Playback Volume",
1828 .info = aureon_ac97_vol_info,
1829 .get = aureon_ac97_vol_get,
1830 .put = aureon_ac97_vol_put,
1831 .private_value = AC97_VIDEO|AUREON_AC97_STEREO,
1832 .tlv = { .p = db_scale_ac97_gain }
1833 },
1834 {
1835 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1836 .name = "Aux Source",
1837 .info = aureon_universe_inmux_info,
1838 .get = aureon_universe_inmux_get,
1839 .put = aureon_universe_inmux_put
1840 }
1841
1842 };
1843
1844 static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
1845 {
1846 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1847 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
1848 .info = aureon_cs8415_mute_info,
1849 .get = aureon_cs8415_mute_get,
1850 .put = aureon_cs8415_mute_put
1851 },
1852 {
1853 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1854 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Source",
1855 .info = aureon_cs8415_mux_info,
1856 .get = aureon_cs8415_mux_get,
1857 .put = aureon_cs8415_mux_put,
1858 },
1859 {
1860 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1861 .name = SNDRV_CTL_NAME_IEC958("Q-subcode ",CAPTURE,DEFAULT),
1862 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1863 .info = aureon_cs8415_qsub_info,
1864 .get = aureon_cs8415_qsub_get,
1865 },
1866 {
1867 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1868 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
1869 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1870 .info = aureon_cs8415_spdif_info,
1871 .get = aureon_cs8415_mask_get
1872 },
1873 {
1874 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1875 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
1876 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1877 .info = aureon_cs8415_spdif_info,
1878 .get = aureon_cs8415_spdif_get
1879 },
1880 {
1881 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1882 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Rate",
1883 .access =SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1884 .info = aureon_cs8415_rate_info,
1885 .get = aureon_cs8415_rate_get
1886 }
1887 };
1888
1889 static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1890 {
1891 unsigned int i, counts;
1892 int err;
1893
1894 counts = ARRAY_SIZE(aureon_dac_controls);
1895 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
1896 counts -= 2; /* no side */
1897 for (i = 0; i < counts; i++) {
1898 err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
1899 if (err < 0)
1900 return err;
1901 }
1902
1903 for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
1904 err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
1905 if (err < 0)
1906 return err;
1907 }
1908
1909 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1910 for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
1911 err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
1912 if (err < 0)
1913 return err;
1914 }
1915 }
1916 else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1917 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1918 for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
1919 err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
1920 if (err < 0)
1921 return err;
1922 }
1923 }
1924
1925 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1926 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1927 unsigned char id;
1928 snd_ice1712_save_gpio_status(ice);
1929 id = aureon_cs8415_get(ice, CS8415_ID);
1930 if (id != 0x41)
1931 snd_printk(KERN_INFO "No CS8415 chip. Skipping CS8415 controls.\n");
1932 else if ((id & 0x0F) != 0x01)
1933 snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
1934 else {
1935 for (i = 0; i< ARRAY_SIZE(cs8415_controls); i++) {
1936 struct snd_kcontrol *kctl;
1937 err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
1938 if (err < 0)
1939 return err;
1940 if (i > 1)
1941 kctl->id.device = ice->pcm->device;
1942 }
1943 }
1944 snd_ice1712_restore_gpio_status(ice);
1945 }
1946
1947 return 0;
1948 }
1949
1950
1951 /*
1952 * initialize the chip
1953 */
1954 static int __devinit aureon_init(struct snd_ice1712 *ice)
1955 {
1956 static const unsigned short wm_inits_aureon[] = {
1957 /* These come first to reduce init pop noise */
1958 0x1b, 0x044, /* ADC Mux (AC'97 source) */
1959 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
1960 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
1961
1962 0x18, 0x000, /* All power-up */
1963
1964 0x16, 0x122, /* I2S, normal polarity, 24bit */
1965 0x17, 0x022, /* 256fs, slave mode */
1966 0x00, 0, /* DAC1 analog mute */
1967 0x01, 0, /* DAC2 analog mute */
1968 0x02, 0, /* DAC3 analog mute */
1969 0x03, 0, /* DAC4 analog mute */
1970 0x04, 0, /* DAC5 analog mute */
1971 0x05, 0, /* DAC6 analog mute */
1972 0x06, 0, /* DAC7 analog mute */
1973 0x07, 0, /* DAC8 analog mute */
1974 0x08, 0x100, /* master analog mute */
1975 0x09, 0xff, /* DAC1 digital full */
1976 0x0a, 0xff, /* DAC2 digital full */
1977 0x0b, 0xff, /* DAC3 digital full */
1978 0x0c, 0xff, /* DAC4 digital full */
1979 0x0d, 0xff, /* DAC5 digital full */
1980 0x0e, 0xff, /* DAC6 digital full */
1981 0x0f, 0xff, /* DAC7 digital full */
1982 0x10, 0xff, /* DAC8 digital full */
1983 0x11, 0x1ff, /* master digital full */
1984 0x12, 0x000, /* phase normal */
1985 0x13, 0x090, /* unmute DAC L/R */
1986 0x14, 0x000, /* all unmute */
1987 0x15, 0x000, /* no deemphasis, no ZFLG */
1988 0x19, 0x000, /* -12dB ADC/L */
1989 0x1a, 0x000, /* -12dB ADC/R */
1990 (unsigned short)-1
1991 };
1992 static const unsigned short wm_inits_prodigy[] = {
1993
1994 /* These come first to reduce init pop noise */
1995 0x1b, 0x000, /* ADC Mux */
1996 0x1c, 0x009, /* Out Mux1 */
1997 0x1d, 0x009, /* Out Mux2 */
1998
1999 0x18, 0x000, /* All power-up */
2000
2001 0x16, 0x022, /* I2S, normal polarity, 24bit, high-pass on */
2002 0x17, 0x006, /* 128fs, slave mode */
2003
2004 0x00, 0, /* DAC1 analog mute */
2005 0x01, 0, /* DAC2 analog mute */
2006 0x02, 0, /* DAC3 analog mute */
2007 0x03, 0, /* DAC4 analog mute */
2008 0x04, 0, /* DAC5 analog mute */
2009 0x05, 0, /* DAC6 analog mute */
2010 0x06, 0, /* DAC7 analog mute */
2011 0x07, 0, /* DAC8 analog mute */
2012 0x08, 0x100, /* master analog mute */
2013
2014 0x09, 0x7f, /* DAC1 digital full */
2015 0x0a, 0x7f, /* DAC2 digital full */
2016 0x0b, 0x7f, /* DAC3 digital full */
2017 0x0c, 0x7f, /* DAC4 digital full */
2018 0x0d, 0x7f, /* DAC5 digital full */
2019 0x0e, 0x7f, /* DAC6 digital full */
2020 0x0f, 0x7f, /* DAC7 digital full */
2021 0x10, 0x7f, /* DAC8 digital full */
2022 0x11, 0x1FF, /* master digital full */
2023
2024 0x12, 0x000, /* phase normal */
2025 0x13, 0x090, /* unmute DAC L/R */
2026 0x14, 0x000, /* all unmute */
2027 0x15, 0x000, /* no deemphasis, no ZFLG */
2028
2029 0x19, 0x000, /* -12dB ADC/L */
2030 0x1a, 0x000, /* -12dB ADC/R */
2031 (unsigned short)-1
2032
2033 };
2034 static const unsigned short cs_inits[] = {
2035 0x0441, /* RUN */
2036 0x0180, /* no mute, OMCK output on RMCK pin */
2037 0x0201, /* S/PDIF source on RXP1 */
2038 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
2039 (unsigned short)-1
2040 };
2041 struct aureon_spec *spec;
2042 unsigned int tmp;
2043 const unsigned short *p;
2044 int err, i;
2045
2046 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2047 if (!spec)
2048 return -ENOMEM;
2049 ice->spec = spec;
2050
2051 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
2052 ice->num_total_dacs = 6;
2053 ice->num_total_adcs = 2;
2054 } else {
2055 /* aureon 7.1 and prodigy 7.1 */
2056 ice->num_total_dacs = 8;
2057 ice->num_total_adcs = 2;
2058 }
2059
2060 /* to remeber the register values of CS8415 */
2061 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2062 if (! ice->akm)
2063 return -ENOMEM;
2064 ice->akm_codecs = 1;
2065
2066 if ((err = aureon_ac97_init(ice)) != 0)
2067 return err;
2068
2069 snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
2070
2071 /* reset the wm codec as the SPI mode */
2072 snd_ice1712_save_gpio_status(ice);
2073 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
2074
2075 tmp = snd_ice1712_gpio_read(ice);
2076 tmp &= ~AUREON_WM_RESET;
2077 snd_ice1712_gpio_write(ice, tmp);
2078 udelay(1);
2079 tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
2080 snd_ice1712_gpio_write(ice, tmp);
2081 udelay(1);
2082 tmp |= AUREON_WM_RESET;
2083 snd_ice1712_gpio_write(ice, tmp);
2084 udelay(1);
2085
2086 /* initialize WM8770 codec */
2087 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
2088 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
2089 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT)
2090 p = wm_inits_prodigy;
2091 else
2092 p = wm_inits_aureon;
2093 for (; *p != (unsigned short)-1; p += 2)
2094 wm_put(ice, p[0], p[1]);
2095
2096 /* initialize CS8415A codec */
2097 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
2098 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
2099 for (p = cs_inits; *p != (unsigned short)-1; p++)
2100 aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
2101 spec->cs8415_mux = 1;
2102
2103 aureon_set_headphone_amp(ice, 1);
2104 }
2105
2106 snd_ice1712_restore_gpio_status(ice);
2107
2108 /* initialize PCA9554 pin directions & set default input*/
2109 aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2110 aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */
2111
2112 spec->master[0] = WM_VOL_MUTE;
2113 spec->master[1] = WM_VOL_MUTE;
2114 for (i = 0; i < ice->num_total_dacs; i++) {
2115 spec->vol[i] = WM_VOL_MUTE;
2116 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2117 }
2118
2119 return 0;
2120 }
2121
2122
2123 /*
2124 * Aureon boards don't provide the EEPROM data except for the vendor IDs.
2125 * hence the driver needs to sets up it properly.
2126 */
2127
2128 static unsigned char aureon51_eeprom[] __devinitdata = {
2129 [ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */
2130 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2131 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2132 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2133 [ICE_EEP2_GPIO_DIR] = 0xff,
2134 [ICE_EEP2_GPIO_DIR1] = 0xff,
2135 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2136 [ICE_EEP2_GPIO_MASK] = 0x00,
2137 [ICE_EEP2_GPIO_MASK1] = 0x00,
2138 [ICE_EEP2_GPIO_MASK2] = 0x00,
2139 [ICE_EEP2_GPIO_STATE] = 0x00,
2140 [ICE_EEP2_GPIO_STATE1] = 0x00,
2141 [ICE_EEP2_GPIO_STATE2] = 0x00,
2142 };
2143
2144 static unsigned char aureon71_eeprom[] __devinitdata = {
2145 [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */
2146 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2147 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2148 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2149 [ICE_EEP2_GPIO_DIR] = 0xff,
2150 [ICE_EEP2_GPIO_DIR1] = 0xff,
2151 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2152 [ICE_EEP2_GPIO_MASK] = 0x00,
2153 [ICE_EEP2_GPIO_MASK1] = 0x00,
2154 [ICE_EEP2_GPIO_MASK2] = 0x00,
2155 [ICE_EEP2_GPIO_STATE] = 0x00,
2156 [ICE_EEP2_GPIO_STATE1] = 0x00,
2157 [ICE_EEP2_GPIO_STATE2] = 0x00,
2158 };
2159 #define prodigy71_eeprom aureon71_eeprom
2160
2161 static unsigned char prodigy71lt_eeprom[] __devinitdata = {
2162 [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */
2163 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2164 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2165 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2166 [ICE_EEP2_GPIO_DIR] = 0xff,
2167 [ICE_EEP2_GPIO_DIR1] = 0xff,
2168 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2169 [ICE_EEP2_GPIO_MASK] = 0x00,
2170 [ICE_EEP2_GPIO_MASK1] = 0x00,
2171 [ICE_EEP2_GPIO_MASK2] = 0x00,
2172 [ICE_EEP2_GPIO_STATE] = 0x00,
2173 [ICE_EEP2_GPIO_STATE1] = 0x00,
2174 [ICE_EEP2_GPIO_STATE2] = 0x00,
2175 };
2176 #define prodigy71xt_eeprom prodigy71lt_eeprom
2177
2178 /* entry point */
2179 struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
2180 {
2181 .subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
2182 .name = "Terratec Aureon 5.1-Sky",
2183 .model = "aureon51",
2184 .chip_init = aureon_init,
2185 .build_controls = aureon_add_controls,
2186 .eeprom_size = sizeof(aureon51_eeprom),
2187 .eeprom_data = aureon51_eeprom,
2188 .driver = "Aureon51",
2189 },
2190 {
2191 .subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
2192 .name = "Terratec Aureon 7.1-Space",
2193 .model = "aureon71",
2194 .chip_init = aureon_init,
2195 .build_controls = aureon_add_controls,
2196 .eeprom_size = sizeof(aureon71_eeprom),
2197 .eeprom_data = aureon71_eeprom,
2198 .driver = "Aureon71",
2199 },
2200 {
2201 .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
2202 .name = "Terratec Aureon 7.1-Universe",
2203 .model = "universe",
2204 .chip_init = aureon_init,
2205 .build_controls = aureon_add_controls,
2206 .eeprom_size = sizeof(aureon71_eeprom),
2207 .eeprom_data = aureon71_eeprom,
2208 .driver = "Aureon71Univ", /* keep in 15 letters */
2209 },
2210 {
2211 .subvendor = VT1724_SUBDEVICE_PRODIGY71,
2212 .name = "Audiotrak Prodigy 7.1",
2213 .model = "prodigy71",
2214 .chip_init = aureon_init,
2215 .build_controls = aureon_add_controls,
2216 .eeprom_size = sizeof(prodigy71_eeprom),
2217 .eeprom_data = prodigy71_eeprom,
2218 .driver = "Prodigy71", /* should be identical with Aureon71 */
2219 },
2220 {
2221 .subvendor = VT1724_SUBDEVICE_PRODIGY71LT,
2222 .name = "Audiotrak Prodigy 7.1 LT",
2223 .model = "prodigy71lt",
2224 .chip_init = aureon_init,
2225 .build_controls = aureon_add_controls,
2226 .eeprom_size = sizeof(prodigy71lt_eeprom),
2227 .eeprom_data = prodigy71lt_eeprom,
2228 .driver = "Prodigy71LT",
2229 },
2230 {
2231 .subvendor = VT1724_SUBDEVICE_PRODIGY71XT,
2232 .name = "Audiotrak Prodigy 7.1 XT",
2233 .model = "prodigy71xt",
2234 .chip_init = aureon_init,
2235 .build_controls = aureon_add_controls,
2236 .eeprom_size = sizeof(prodigy71xt_eeprom),
2237 .eeprom_data = prodigy71xt_eeprom,
2238 .driver = "Prodigy71LT",
2239 },
2240 { } /* terminator */
2241 };