This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / sound / pci / ice1712 / pontis.c
1 /*
2  *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
3  *
4  *   Lowlevel functions for Pontis MS300
5  *
6  *      Copyright (c) 2004 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
24 #include <sound/driver.h>
25 #include <asm/io.h>
26 #include <linux/delay.h>
27 #include <linux/interrupt.h>
28 #include <linux/init.h>
29 #include <linux/slab.h>
30 #include <sound/core.h>
31 #include <sound/info.h>
32
33 #include "ice1712.h"
34 #include "envy24ht.h"
35 #include "pontis.h"
36
37 /* I2C addresses */
38 #define WM_DEV          0x34
39 #define CS_DEV          0x20
40
41 /* WM8776 registers */
42 #define WM_HP_ATTEN_L           0x00    /* headphone left attenuation */
43 #define WM_HP_ATTEN_R           0x01    /* headphone left attenuation */
44 #define WM_HP_MASTER            0x02    /* headphone master (both channels), override LLR */
45 #define WM_DAC_ATTEN_L          0x03    /* digital left attenuation */
46 #define WM_DAC_ATTEN_R          0x04
47 #define WM_DAC_MASTER           0x05
48 #define WM_PHASE_SWAP           0x06    /* DAC phase swap */
49 #define WM_DAC_CTRL1            0x07
50 #define WM_DAC_MUTE             0x08
51 #define WM_DAC_CTRL2            0x09
52 #define WM_DAC_INT              0x0a
53 #define WM_ADC_INT              0x0b
54 #define WM_MASTER_CTRL          0x0c
55 #define WM_POWERDOWN            0x0d
56 #define WM_ADC_ATTEN_L          0x0e
57 #define WM_ADC_ATTEN_R          0x0f
58 #define WM_ALC_CTRL1            0x10
59 #define WM_ALC_CTRL2            0x11
60 #define WM_ALC_CTRL3            0x12
61 #define WM_NOISE_GATE           0x13
62 #define WM_LIMITER              0x14
63 #define WM_ADC_MUX              0x15
64 #define WM_OUT_MUX              0x16
65 #define WM_RESET                0x17
66
67 /*
68  * GPIO
69  */
70 #define PONTIS_CS_CS            (1<<4)  /* CS */
71 #define PONTIS_CS_CLK           (1<<5)  /* CLK */
72 #define PONTIS_CS_RDATA         (1<<6)  /* CS8416 -> VT1720 */
73 #define PONTIS_CS_WDATA         (1<<7)  /* VT1720 -> CS8416 */
74
75
76 /*
77  * get the current register value of WM codec
78  */
79 static unsigned short wm_get(ice1712_t *ice, int reg)
80 {
81         reg <<= 1;
82         return ((unsigned short)ice->akm[0].images[reg] << 8) |
83                 ice->akm[0].images[reg + 1];
84 }
85
86 /*
87  * set the register value of WM codec and remember it
88  */
89 static void wm_put_nocache(ice1712_t *ice, int reg, unsigned short val)
90 {
91         unsigned short cval;
92         cval = (reg << 9) | val;
93         snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
94 }
95
96 static void wm_put(ice1712_t *ice, int reg, unsigned short val)
97 {
98         wm_put_nocache(ice, reg, val);
99         reg <<= 1;
100         ice->akm[0].images[reg] = val >> 8;
101         ice->akm[0].images[reg + 1] = val;
102 }
103
104 /*
105  * DAC volume attenuation mixer control (-64dB to 0dB)
106  */
107
108 #define DAC_0dB 0xff
109 #define DAC_RES 128
110 #define DAC_MIN (DAC_0dB - DAC_RES)
111
112 static int wm_dac_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
113 {
114         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
115         uinfo->count = 2;
116         uinfo->value.integer.min = 0;   /* mute */
117         uinfo->value.integer.max = DAC_RES;     /* 0dB, 0.5dB step */
118         return 0;
119 }
120
121 static int wm_dac_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
122 {
123         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
124         unsigned short val;
125         int i;
126
127         down(&ice->gpio_mutex);
128         for (i = 0; i < 2; i++) {
129                 val = wm_get(ice, WM_DAC_ATTEN_L + i) & 0xff;
130                 val = val > DAC_MIN ? (val - DAC_MIN) : 0;
131                 ucontrol->value.integer.value[i] = val;
132         }
133         up(&ice->gpio_mutex);
134         return 0;
135 }
136
137 static int wm_dac_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
138 {
139         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
140         unsigned short oval, nval;
141         int i, idx, change = 0;
142
143         down(&ice->gpio_mutex);
144         for (i = 0; i < 2; i++) {
145                 nval = ucontrol->value.integer.value[i];
146                 nval = (nval ? (nval + DAC_MIN) : 0) & 0xff;
147                 idx = WM_DAC_ATTEN_L + i;
148                 oval = wm_get(ice, idx) & 0xff;
149                 if (oval != nval) {
150                         wm_put(ice, idx, nval);
151                         wm_put_nocache(ice, idx, nval | 0x100);
152                         change = 1;
153                 }
154         }
155         up(&ice->gpio_mutex);
156         return change;
157 }
158
159 /*
160  * ADC gain mixer control (-64dB to 0dB)
161  */
162
163 #define ADC_0dB 0xcf
164 #define ADC_RES 128
165 #define ADC_MIN (ADC_0dB - ADC_RES)
166
167 static int wm_adc_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
168 {
169         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
170         uinfo->count = 2;
171         uinfo->value.integer.min = 0;   /* mute (-64dB) */
172         uinfo->value.integer.max = ADC_RES;     /* 0dB, 0.5dB step */
173         return 0;
174 }
175
176 static int wm_adc_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
177 {
178         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
179         unsigned short val;
180         int i;
181
182         down(&ice->gpio_mutex);
183         for (i = 0; i < 2; i++) {
184                 val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff;
185                 val = val > ADC_MIN ? (val - ADC_MIN) : 0;
186                 ucontrol->value.integer.value[i] = val;
187         }
188         up(&ice->gpio_mutex);
189         return 0;
190 }
191
192 static int wm_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
193 {
194         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
195         unsigned short ovol, nvol;
196         int i, idx, change = 0;
197
198         down(&ice->gpio_mutex);
199         for (i = 0; i < 2; i++) {
200                 nvol = ucontrol->value.integer.value[i];
201                 nvol = nvol ? (nvol + ADC_MIN) : 0;
202                 idx  = WM_ADC_ATTEN_L + i;
203                 ovol = wm_get(ice, idx) & 0xff;
204                 if (ovol != nvol) {
205                         wm_put(ice, idx, nvol);
206                         change = 1;
207                 }
208         }
209         up(&ice->gpio_mutex);
210         return change;
211 }
212
213 /*
214  * ADC input mux mixer control
215  */
216 static int wm_adc_mux_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
217 {
218         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
219         uinfo->count = 1;
220         uinfo->value.integer.min = 0;
221         uinfo->value.integer.max = 1;
222         return 0;
223 }
224
225 static int wm_adc_mux_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
226 {
227         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
228         int bit = kcontrol->private_value;
229
230         down(&ice->gpio_mutex);
231         ucontrol->value.integer.value[0] = (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
232         up(&ice->gpio_mutex);
233         return 0;
234 }
235
236 static int wm_adc_mux_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
237 {
238         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
239         int bit = kcontrol->private_value;
240         unsigned short oval, nval;
241         int change;
242
243         down(&ice->gpio_mutex);
244         nval = oval = wm_get(ice, WM_ADC_MUX);
245         if (ucontrol->value.integer.value[0])
246                 nval |= (1 << bit);
247         else
248                 nval &= ~(1 << bit);
249         change = nval != oval;
250         if (change) {
251                 wm_put(ice, WM_ADC_MUX, nval);
252         }
253         up(&ice->gpio_mutex);
254         return 0;
255 }
256
257 /*
258  * Analog bypass (In -> Out)
259  */
260 static int wm_bypass_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
261 {
262         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
263         uinfo->count = 1;
264         uinfo->value.integer.min = 0;
265         uinfo->value.integer.max = 1;
266         return 0;
267 }
268
269 static int wm_bypass_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
270 {
271         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
272
273         down(&ice->gpio_mutex);
274         ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
275         up(&ice->gpio_mutex);
276         return 0;
277 }
278
279 static int wm_bypass_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
280 {
281         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
282         unsigned short val, oval;
283         int change = 0;
284
285         down(&ice->gpio_mutex);
286         val = oval = wm_get(ice, WM_OUT_MUX);
287         if (ucontrol->value.integer.value[0])
288                 val |= 0x04;
289         else
290                 val &= ~0x04;
291         if (val != oval) {
292                 wm_put(ice, WM_OUT_MUX, val);
293                 change = 1;
294         }
295         up(&ice->gpio_mutex);
296         return change;
297 }
298
299 /*
300  * Left/Right swap
301  */
302 static int wm_chswap_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
303 {
304         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
305         uinfo->count = 1;
306         uinfo->value.integer.min = 0;
307         uinfo->value.integer.max = 1;
308         return 0;
309 }
310
311 static int wm_chswap_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
312 {
313         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
314
315         down(&ice->gpio_mutex);
316         ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90;
317         up(&ice->gpio_mutex);
318         return 0;
319 }
320
321 static int wm_chswap_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
322 {
323         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
324         unsigned short val, oval;
325         int change = 0;
326
327         down(&ice->gpio_mutex);
328         oval = wm_get(ice, WM_DAC_CTRL1);
329         val = oval & 0x0f;
330         if (ucontrol->value.integer.value[0])
331                 val |= 0x60;
332         else
333                 val |= 0x90;
334         if (val != oval) {
335                 wm_put(ice, WM_DAC_CTRL1, val);
336                 wm_put_nocache(ice, WM_DAC_CTRL1, val);
337                 change = 1;
338         }
339         up(&ice->gpio_mutex);
340         return change;
341 }
342
343 /*
344  * write data in the SPI mode
345  */
346 static void set_gpio_bit(ice1712_t *ice, unsigned int bit, int val)
347 {
348         unsigned int tmp = snd_ice1712_gpio_read(ice);
349         if (val)
350                 tmp |= bit;
351         else
352                 tmp &= ~bit;
353         snd_ice1712_gpio_write(ice, tmp);
354 }
355
356 static void spi_send_byte(ice1712_t *ice, unsigned char data)
357 {
358         int i;
359         for (i = 0; i < 8; i++) {
360                 set_gpio_bit(ice, PONTIS_CS_CLK, 0);
361                 udelay(1);
362                 set_gpio_bit(ice, PONTIS_CS_WDATA, data & 0x80);
363                 udelay(1);
364                 set_gpio_bit(ice, PONTIS_CS_CLK, 1);
365                 udelay(1);
366                 data <<= 1;
367         }
368 }
369
370 static unsigned int spi_read_byte(ice1712_t *ice)
371 {
372         int i;
373         unsigned int val = 0;
374
375         for (i = 0; i < 8; i++) {
376                 val <<= 1;
377                 set_gpio_bit(ice, PONTIS_CS_CLK, 0);
378                 udelay(1);
379                 if (snd_ice1712_gpio_read(ice) & PONTIS_CS_RDATA)
380                         val |= 1;
381                 udelay(1);
382                 set_gpio_bit(ice, PONTIS_CS_CLK, 1);
383                 udelay(1);
384         }
385         return val;
386 }
387
388
389 static void spi_write(ice1712_t *ice, unsigned int dev, unsigned int reg, unsigned int data)
390 {
391         snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK);
392         snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK));
393         set_gpio_bit(ice, PONTIS_CS_CS, 0);
394         spi_send_byte(ice, dev & ~1); /* WRITE */
395         spi_send_byte(ice, reg); /* MAP */
396         spi_send_byte(ice, data); /* DATA */
397         /* trigger */
398         set_gpio_bit(ice, PONTIS_CS_CS, 1);
399         udelay(1);
400         /* restore */
401         snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
402         snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
403 }
404
405 static unsigned int spi_read(ice1712_t *ice, unsigned int dev, unsigned int reg)
406 {
407         unsigned int val;
408         snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK);
409         snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK));
410         set_gpio_bit(ice, PONTIS_CS_CS, 0);
411         spi_send_byte(ice, dev & ~1); /* WRITE */
412         spi_send_byte(ice, reg); /* MAP */
413         /* trigger */
414         set_gpio_bit(ice, PONTIS_CS_CS, 1);
415         udelay(1);
416         set_gpio_bit(ice, PONTIS_CS_CS, 0);
417         spi_send_byte(ice, dev | 1); /* READ */
418         val = spi_read_byte(ice);
419         /* trigger */
420         set_gpio_bit(ice, PONTIS_CS_CS, 1);
421         udelay(1);
422         /* restore */
423         snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
424         snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
425         return val;
426 }
427
428
429 /*
430  * SPDIF input source
431  */
432 static int cs_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
433 {
434         static char *texts[] = {
435                 "Coax",         /* RXP0 */
436                 "Optical",      /* RXP1 */
437                 "CD",           /* RXP2 */
438         };
439         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
440         uinfo->count = 1;
441         uinfo->value.enumerated.items = 3;
442         if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
443                 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
444         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
445         return 0;
446 }
447
448 static int cs_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
449 {
450         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
451
452         down(&ice->gpio_mutex);
453         ucontrol->value.enumerated.item[0] = ice->gpio.saved[0];
454         up(&ice->gpio_mutex);
455         return 0;
456 }
457
458 static int cs_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
459 {
460         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
461         unsigned char val;
462         int change = 0;
463
464         down(&ice->gpio_mutex);
465         if (ucontrol->value.enumerated.item[0] != ice->gpio.saved[0]) {
466                 ice->gpio.saved[0] = ucontrol->value.enumerated.item[0] & 3;
467                 val = 0x80 | (ice->gpio.saved[0] << 3);
468                 spi_write(ice, CS_DEV, 0x04, val);
469                 change = 1;
470         }
471         up(&ice->gpio_mutex);
472         return 0;
473 }
474
475
476 /*
477  * GPIO controls
478  */
479 static int pontis_gpio_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
480 {
481         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
482         uinfo->count = 1;
483         uinfo->value.integer.min = 0;
484         uinfo->value.integer.max = 0xffff; /* 16bit */
485         return 0;
486 }
487
488 static int pontis_gpio_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
489 {
490         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
491         down(&ice->gpio_mutex);
492         /* 4-7 reserved */
493         ucontrol->value.integer.value[0] = (~ice->gpio.write_mask & 0xffff) | 0x00f0;
494         up(&ice->gpio_mutex);
495         return 0;
496 }
497         
498 static int pontis_gpio_mask_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
499 {
500         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
501         unsigned int val;
502         int changed;
503         down(&ice->gpio_mutex);
504         /* 4-7 reserved */
505         val = (~ucontrol->value.integer.value[0] & 0xffff) | 0x00f0;
506         changed = val != ice->gpio.write_mask;
507         ice->gpio.write_mask = val;
508         up(&ice->gpio_mutex);
509         return changed;
510 }
511
512 static int pontis_gpio_dir_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
513 {
514         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
515         down(&ice->gpio_mutex);
516         /* 4-7 reserved */
517         ucontrol->value.integer.value[0] = ice->gpio.direction & 0xff0f;
518         up(&ice->gpio_mutex);
519         return 0;
520 }
521         
522 static int pontis_gpio_dir_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
523 {
524         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
525         unsigned int val;
526         int changed;
527         down(&ice->gpio_mutex);
528         /* 4-7 reserved */
529         val = ucontrol->value.integer.value[0] & 0xff0f;
530         changed = (val != ice->gpio.direction);
531         ice->gpio.direction = val;
532         up(&ice->gpio_mutex);
533         return changed;
534 }
535
536 static int pontis_gpio_data_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
537 {
538         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
539         down(&ice->gpio_mutex);
540         snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
541         snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
542         ucontrol->value.integer.value[0] = snd_ice1712_gpio_read(ice) & 0xffff;
543         up(&ice->gpio_mutex);
544         return 0;
545 }
546
547 static int pontis_gpio_data_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
548 {
549         ice1712_t *ice = snd_kcontrol_chip(kcontrol);
550         unsigned int val, nval;
551         int changed = 0;
552         down(&ice->gpio_mutex);
553         snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
554         snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
555         val = snd_ice1712_gpio_read(ice) & 0xffff;
556         nval = ucontrol->value.integer.value[0] & 0xffff;
557         if (val != nval) {
558                 snd_ice1712_gpio_write(ice, nval);
559                 changed = 1;
560         }
561         up(&ice->gpio_mutex);
562         return changed;
563 }
564
565 /*
566  * mixers
567  */
568
569 static snd_kcontrol_new_t pontis_controls[] __devinitdata = {
570         {
571                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
572                 .name = "PCM Playback Volume",
573                 .info = wm_dac_vol_info,
574                 .get = wm_dac_vol_get,
575                 .put = wm_dac_vol_put,
576         },
577         {
578                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
579                 .name = "Capture Volume",
580                 .info = wm_adc_vol_info,
581                 .get = wm_adc_vol_get,
582                 .put = wm_adc_vol_put,
583         },
584         {
585                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
586                 .name = "CD Capture Switch",
587                 .info = wm_adc_mux_info,
588                 .get = wm_adc_mux_get,
589                 .put = wm_adc_mux_put,
590                 .private_value = 0,
591         },
592         {
593                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
594                 .name = "Line Capture Switch",
595                 .info = wm_adc_mux_info,
596                 .get = wm_adc_mux_get,
597                 .put = wm_adc_mux_put,
598                 .private_value = 1,
599         },
600         {
601                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
602                 .name = "Analog Bypass Switch",
603                 .info = wm_bypass_info,
604                 .get = wm_bypass_get,
605                 .put = wm_bypass_put,
606         },
607         {
608                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
609                 .name = "Swap Output Channels",
610                 .info = wm_chswap_info,
611                 .get = wm_chswap_get,
612                 .put = wm_chswap_put,
613         },
614         {
615                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
616                 .name = "IEC958 Input Source",
617                 .info = cs_source_info,
618                 .get = cs_source_get,
619                 .put = cs_source_put,
620         },
621         /* FIXME: which interface? */
622         {
623                 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
624                 .name = "GPIO Mask",
625                 .info = pontis_gpio_mask_info,
626                 .get = pontis_gpio_mask_get,
627                 .put = pontis_gpio_mask_put,
628         },
629         {
630                 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
631                 .name = "GPIO Direction",
632                 .info = pontis_gpio_mask_info,
633                 .get = pontis_gpio_dir_get,
634                 .put = pontis_gpio_dir_put,
635         },
636         {
637                 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
638                 .name = "GPIO Data",
639                 .info = pontis_gpio_mask_info,
640                 .get = pontis_gpio_data_get,
641                 .put = pontis_gpio_data_put,
642         },
643 };
644
645
646 /*
647  * WM codec registers
648  */
649 static void wm_proc_regs_write(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
650 {
651         ice1712_t *ice = (ice1712_t *)entry->private_data;
652         char line[64];
653         unsigned int reg, val;
654         down(&ice->gpio_mutex);
655         while (!snd_info_get_line(buffer, line, sizeof(line))) {
656                 if (sscanf(line, "%x %x", &reg, &val) != 2)
657                         continue;
658                 if (reg <= 0x17 && val <= 0xffff)
659                         wm_put(ice, reg, val);
660         }
661         up(&ice->gpio_mutex);
662 }
663
664 static void wm_proc_regs_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
665 {
666         ice1712_t *ice = (ice1712_t *)entry->private_data;
667         int reg, val;
668
669         down(&ice->gpio_mutex);
670         for (reg = 0; reg <= 0x17; reg++) {
671                 val = wm_get(ice, reg);
672                 snd_iprintf(buffer, "%02x = %04x\n", reg, val);
673         }
674         up(&ice->gpio_mutex);
675 }
676
677 static void wm_proc_init(ice1712_t *ice)
678 {
679         snd_info_entry_t *entry;
680         if (! snd_card_proc_new(ice->card, "wm_codec", &entry)) {
681                 snd_info_set_text_ops(entry, ice, 1024, wm_proc_regs_read);
682                 entry->mode |= S_IWUSR;
683                 entry->c.text.write_size = 1024;
684                 entry->c.text.write = wm_proc_regs_write;
685         }
686 }
687
688 static void cs_proc_regs_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
689 {
690         ice1712_t *ice = (ice1712_t *)entry->private_data;
691         int reg, val;
692
693         down(&ice->gpio_mutex);
694         for (reg = 0; reg <= 0x26; reg++) {
695                 val = spi_read(ice, CS_DEV, reg);
696                 snd_iprintf(buffer, "%02x = %02x\n", reg, val);
697         }
698         val = spi_read(ice, CS_DEV, 0x7f);
699         snd_iprintf(buffer, "%02x = %02x\n", 0x7f, val);
700         up(&ice->gpio_mutex);
701 }
702
703 static void cs_proc_init(ice1712_t *ice)
704 {
705         snd_info_entry_t *entry;
706         if (! snd_card_proc_new(ice->card, "cs_codec", &entry)) {
707                 snd_info_set_text_ops(entry, ice, 1024, cs_proc_regs_read);
708         }
709 }
710
711
712 static int __devinit pontis_add_controls(ice1712_t *ice)
713 {
714         unsigned int i;
715         int err;
716
717         for (i = 0; i < ARRAY_SIZE(pontis_controls); i++) {
718                 err = snd_ctl_add(ice->card, snd_ctl_new1(&pontis_controls[i], ice));
719                 if (err < 0)
720                         return err;
721         }
722
723         wm_proc_init(ice);
724         cs_proc_init(ice);
725
726         return 0;
727 }
728
729
730 /*
731  * initialize the chip
732  */
733 static int __devinit pontis_init(ice1712_t *ice)
734 {
735         static unsigned short wm_inits[] = {
736                 /* These come first to reduce init pop noise */
737                 WM_ADC_MUX,     0x00c0, /* ADC mute */
738                 WM_DAC_MUTE,    0x0001, /* DAC softmute */
739                 WM_DAC_CTRL1,   0x0000, /* DAC mute */
740
741                 WM_POWERDOWN,   0x0008, /* All power-up except HP */
742                 WM_RESET,       0x0000, /* reset */
743         };
744         static unsigned short wm_inits2[] = {
745                 WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */
746                 WM_DAC_INT,     0x0022, /* I2S, normal polarity, 24bit */
747                 WM_ADC_INT,     0x0022, /* I2S, normal polarity, 24bit */
748                 WM_DAC_CTRL1,   0x0090, /* DAC L/R */
749                 WM_OUT_MUX,     0x0001, /* OUT DAC */
750                 WM_HP_ATTEN_L,  0x0179, /* HP 0dB */
751                 WM_HP_ATTEN_R,  0x0179, /* HP 0dB */
752                 WM_DAC_ATTEN_L, 0x0000, /* DAC 0dB */
753                 WM_DAC_ATTEN_L, 0x0100, /* DAC 0dB */
754                 WM_DAC_ATTEN_R, 0x0000, /* DAC 0dB */
755                 WM_DAC_ATTEN_R, 0x0100, /* DAC 0dB */
756                 // WM_DAC_MASTER,       0x0100, /* DAC master muted */
757                 WM_PHASE_SWAP,  0x0000, /* phase normal */
758                 WM_DAC_CTRL2,   0x0000, /* no deemphasis, no ZFLG */
759                 WM_ADC_ATTEN_L, 0x0000, /* ADC muted */
760                 WM_ADC_ATTEN_R, 0x0000, /* ADC muted */
761 #if 0
762                 WM_ALC_CTRL1,   0x007b, /* */
763                 WM_ALC_CTRL2,   0x0000, /* */
764                 WM_ALC_CTRL3,   0x0000, /* */
765                 WM_NOISE_GATE,  0x0000, /* */
766 #endif
767                 WM_DAC_MUTE,    0x0000, /* DAC unmute */
768                 WM_ADC_MUX,     0x0003, /* ADC unmute, both CD/Line On */
769         };
770         static unsigned char cs_inits[] = {
771                 0x04,   0x80,   /* RUN, RXP0 */
772                 0x05,   0x05,   /* slave, 24bit */
773                 0x01,   0x00,
774                 0x02,   0x00,
775                 0x03,   0x00,
776         };
777         unsigned int i;
778
779         ice->vt1720 = 1;
780         ice->num_total_dacs = 2;
781         ice->num_total_adcs = 2;
782
783         /* to remeber the register values */
784         ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
785         if (! ice->akm)
786                 return -ENOMEM;
787         ice->akm_codecs = 1;
788
789         /* HACK - use this as the SPDIF source.
790          * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
791          */
792         ice->gpio.saved[0] = 0;
793
794         /* initialize WM8776 codec */
795         for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
796                 wm_put(ice, wm_inits[i], wm_inits[i+1]);
797         set_current_state(TASK_UNINTERRUPTIBLE);
798         schedule_timeout(1);
799         for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
800                 wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
801
802         /* initialize CS8416 codec */
803         /* assert PRST#; MT05 bit 7 */
804         outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
805         mdelay(5);
806         /* deassert PRST# */
807         outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
808
809         for (i = 0; i < ARRAY_SIZE(cs_inits); i += 2)
810                 spi_write(ice, CS_DEV, cs_inits[i], cs_inits[i+1]);
811
812         return 0;
813 }
814
815
816 /*
817  * Pontis boards don't provide the EEPROM data at all.
818  * hence the driver needs to sets up it properly.
819  */
820
821 static unsigned char pontis_eeprom[] __devinitdata = {
822         0x08,   /* SYSCONF: clock 256, mpu401, spdif-in/ADC, 1DAC */
823         0x80,   /* ACLINK: I2S */
824         0xf8,   /* I2S: vol, 96k, 24bit, 192k */
825         0xc3,   /* SPDIF: out-en, out-int, spdif-in */
826         0x07,   /* GPIO_DIR */
827         0x00,   /* GPIO_DIR1 */
828         0x00,   /* GPIO_DIR2 (ignored) */
829         0x0f,   /* GPIO_MASK (4-7 reserved for CS8416) */
830         0xff,   /* GPIO_MASK1 */
831         0x00,   /* GPIO_MASK2 (ignored) */
832         0x06,   /* GPIO_STATE (0-low, 1-high, 2-high) */
833         0x00,   /* GPIO_STATE1 */
834         0x00,   /* GPIO_STATE2 (ignored) */
835 };
836
837 /* entry point */
838 struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = {
839         {
840                 .subvendor = VT1720_SUBDEVICE_PONTIS_MS300,
841                 .name = "Pontis MS300",
842                 .model = "ms300",
843                 .chip_init = pontis_init,
844                 .build_controls = pontis_add_controls,
845                 .eeprom_size = sizeof(pontis_eeprom),
846                 .eeprom_data = pontis_eeprom,
847         },
848         { } /* terminator */
849 };