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