Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
aureon.c
Go to the documentation of this file.
1 /*
2  * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3  *
4  * Lowlevel functions for Terratec Aureon cards
5  *
6  * Copyright (c) 2003 Takashi Iwai <[email protected]>
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 <[email protected]>
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|
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 
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 {
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|
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) ?
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 {
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;
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 {
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 {
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 {
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 
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  };
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 {
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 {
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 {
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 
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 |
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 |
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 |
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 |
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 |
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 |
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  {
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 |
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 |
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  {
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 |
1630  .name = "AC97 Playback Volume",
1631  .info = aureon_ac97_vol_info,
1632  .get = aureon_ac97_vol_get,
1633  .put = aureon_ac97_vol_put,
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 |
1649  .name = "CD Playback Volume",
1650  .info = aureon_ac97_vol_info,
1651  .get = aureon_ac97_vol_get,
1652  .put = aureon_ac97_vol_put,
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 |
1668  .name = "Aux Playback Volume",
1669  .info = aureon_ac97_vol_info,
1670  .get = aureon_ac97_vol_get,
1671  .put = aureon_ac97_vol_put,
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 |
1687  .name = "Line Playback Volume",
1688  .info = aureon_ac97_vol_info,
1689  .get = aureon_ac97_vol_get,
1690  .put = aureon_ac97_vol_put,
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 |
1706  .name = "Mic Playback Volume",
1707  .info = aureon_ac97_vol_info,
1708  .get = aureon_ac97_vol_get,
1709  .put = aureon_ac97_vol_put,
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  {
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 |
1735  .name = "AC97 Playback Volume",
1736  .info = aureon_ac97_vol_info,
1737  .get = aureon_ac97_vol_get,
1738  .put = aureon_ac97_vol_put,
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 |
1754  .name = "CD Playback Volume",
1755  .info = aureon_ac97_vol_info,
1756  .get = aureon_ac97_vol_get,
1757  .put = aureon_ac97_vol_put,
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 |
1773  .name = "Phono Playback Volume",
1774  .info = aureon_ac97_vol_info,
1775  .get = aureon_ac97_vol_get,
1776  .put = aureon_ac97_vol_put,
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 |
1792  .name = "Line Playback Volume",
1793  .info = aureon_ac97_vol_info,
1794  .get = aureon_ac97_vol_get,
1795  .put = aureon_ac97_vol_put,
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 |
1811  .name = "Mic Playback Volume",
1812  .info = aureon_ac97_vol_info,
1813  .get = aureon_ac97_vol_get,
1814  .put = aureon_ac97_vol_put,
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 |
1837  .name = "Aux Playback Volume",
1838  .info = aureon_ac97_vol_info,
1839  .get = aureon_ac97_vol_get,
1840  .put = aureon_ac97_vol_put,
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  {
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),
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),
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",
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 */
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  {
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),
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),
2305  .driver = "Prodigy71LT",
2306  },
2307  { } /* terminator */
2308 };