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