~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/pci/ice1712/aureon.c

Version: ~ [ linux-5.9 ] ~ [ linux-5.8.14 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.70 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.150 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.200 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.238 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.238 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp