On Tue, Nov 06, 2007 at 02:33:53AM -0800, akpm@linux-foundation.org wrote:
[mmotm.git] / sound / pci / ice1712 / se.c
blob69673b95869da9bfd855aa4aa05acdf24f4c6835
1 /*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
4 * Lowlevel functions for ONKYO WAVIO SE-90PCI and SE-200PCI
6 * Copyright (c) 2007 Shin-ya Okada sh_okada(at)d4.dion.ne.jp
7 * (at) -> @
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
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/tlv.h>
33 #include "ice1712.h"
34 #include "envy24ht.h"
35 #include "se.h"
37 struct se_spec {
38 struct {
39 unsigned char ch1, ch2;
40 } vol[8];
43 /****************************************************************************/
44 /* ONKYO WAVIO SE-200PCI */
45 /****************************************************************************/
47 * system configuration ICE_EEP2_SYSCONF=0x4b
48 * XIN1 49.152MHz
49 * not have UART
50 * one stereo ADC and a S/PDIF receiver connected
51 * four stereo DACs connected
53 * AC-Link configuration ICE_EEP2_ACLINK=0x80
54 * use I2C, not use AC97
56 * I2S converters feature ICE_EEP2_I2S=0x78
57 * I2S codec has no volume/mute control feature
58 * I2S codec supports 96KHz and 192KHz
59 * I2S codec 24bits
61 * S/PDIF configuration ICE_EEP2_SPDIF=0xc3
62 * Enable integrated S/PDIF transmitter
63 * internal S/PDIF out implemented
64 * S/PDIF is stereo
65 * External S/PDIF out implemented
68 * ** connected chips **
70 * WM8740
71 * A 2ch-DAC of main outputs.
72 * It setuped as I2S mode by wire, so no way to setup from software.
73 * The sample-rate are automatically changed.
74 * ML/I2S (28pin) --------+
75 * MC/DM1 (27pin) -- 5V |
76 * MD/DM0 (26pin) -- GND |
77 * MUTEB (25pin) -- NC |
78 * MODE (24pin) -- GND |
79 * CSBIW (23pin) --------+
80 * |
81 * RSTB (22pin) --R(1K)-+
82 * Probably it reduce the noise from the control line.
84 * WM8766
85 * A 6ch-DAC for surrounds.
86 * It's control wire was connected to GPIOxx (3-wire serial interface)
87 * ML/I2S (11pin) -- GPIO18
88 * MC/IWL (12pin) -- GPIO17
89 * MD/DM (13pin) -- GPIO16
90 * MUTE (14pin) -- GPIO01
92 * WM8776
93 * A 2ch-ADC(with 10ch-selector) plus 2ch-DAC.
94 * It's control wire was connected to SDA/SCLK (2-wire serial interface)
95 * MODE (16pin) -- R(1K) -- GND
96 * CE (17pin) -- R(1K) -- GND 2-wire mode (address=0x34)
97 * DI (18pin) -- SDA
98 * CL (19pin) -- SCLK
101 * ** output pins and device names **
103 * 7.1ch name -- output connector color -- device (-D option)
105 * FRONT 2ch -- green -- plughw:0,0
106 * CENTER(Lch) SUBWOOFER(Rch) -- black -- plughw:0,2,0
107 * SURROUND 2ch -- orange -- plughw:0,2,1
108 * SURROUND BACK 2ch -- white -- plughw:0,2,2
113 /****************************************************************************/
114 /* WM8740 interface */
115 /****************************************************************************/
117 static void __devinit se200pci_WM8740_init(struct snd_ice1712 *ice)
119 /* nothing to do */
123 static void se200pci_WM8740_set_pro_rate(struct snd_ice1712 *ice,
124 unsigned int rate)
126 /* nothing to do */
130 /****************************************************************************/
131 /* WM8766 interface */
132 /****************************************************************************/
134 static void se200pci_WM8766_write(struct snd_ice1712 *ice,
135 unsigned int addr, unsigned int data)
137 unsigned int st;
138 unsigned int bits;
139 int i;
140 const unsigned int DATA = 0x010000;
141 const unsigned int CLOCK = 0x020000;
142 const unsigned int LOAD = 0x040000;
143 const unsigned int ALL_MASK = (DATA | CLOCK | LOAD);
145 snd_ice1712_save_gpio_status(ice);
147 st = ((addr & 0x7f) << 9) | (data & 0x1ff);
148 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction | ALL_MASK);
149 snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask & ~ALL_MASK);
150 bits = snd_ice1712_gpio_read(ice) & ~ALL_MASK;
152 snd_ice1712_gpio_write(ice, bits);
153 for (i = 0; i < 16; i++) {
154 udelay(1);
155 bits &= ~CLOCK;
156 st = (st << 1);
157 if (st & 0x10000)
158 bits |= DATA;
159 else
160 bits &= ~DATA;
162 snd_ice1712_gpio_write(ice, bits);
164 udelay(1);
165 bits |= CLOCK;
166 snd_ice1712_gpio_write(ice, bits);
169 udelay(1);
170 bits |= LOAD;
171 snd_ice1712_gpio_write(ice, bits);
173 udelay(1);
174 bits |= (DATA | CLOCK);
175 snd_ice1712_gpio_write(ice, bits);
177 snd_ice1712_restore_gpio_status(ice);
180 static void se200pci_WM8766_set_volume(struct snd_ice1712 *ice, int ch,
181 unsigned int vol1, unsigned int vol2)
183 switch (ch) {
184 case 0:
185 se200pci_WM8766_write(ice, 0x000, vol1);
186 se200pci_WM8766_write(ice, 0x001, vol2 | 0x100);
187 break;
188 case 1:
189 se200pci_WM8766_write(ice, 0x004, vol1);
190 se200pci_WM8766_write(ice, 0x005, vol2 | 0x100);
191 break;
192 case 2:
193 se200pci_WM8766_write(ice, 0x006, vol1);
194 se200pci_WM8766_write(ice, 0x007, vol2 | 0x100);
195 break;
199 static void __devinit se200pci_WM8766_init(struct snd_ice1712 *ice)
201 se200pci_WM8766_write(ice, 0x1f, 0x000); /* RESET ALL */
202 udelay(10);
204 se200pci_WM8766_set_volume(ice, 0, 0, 0); /* volume L=0 R=0 */
205 se200pci_WM8766_set_volume(ice, 1, 0, 0); /* volume L=0 R=0 */
206 se200pci_WM8766_set_volume(ice, 2, 0, 0); /* volume L=0 R=0 */
208 se200pci_WM8766_write(ice, 0x03, 0x022); /* serial mode I2S-24bits */
209 se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */
210 se200pci_WM8766_write(ice, 0x12, 0x000); /* MDP=0 */
211 se200pci_WM8766_write(ice, 0x15, 0x000); /* MDP=0 */
212 se200pci_WM8766_write(ice, 0x09, 0x000); /* demp=off mute=off */
214 se200pci_WM8766_write(ice, 0x02, 0x124); /* ch-assign L=L R=R RESET */
215 se200pci_WM8766_write(ice, 0x02, 0x120); /* ch-assign L=L R=R */
218 static void se200pci_WM8766_set_pro_rate(struct snd_ice1712 *ice,
219 unsigned int rate)
221 if (rate > 96000)
222 se200pci_WM8766_write(ice, 0x0a, 0x000); /* MCLK=128fs */
223 else
224 se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */
228 /****************************************************************************/
229 /* WM8776 interface */
230 /****************************************************************************/
232 static void se200pci_WM8776_write(struct snd_ice1712 *ice,
233 unsigned int addr, unsigned int data)
235 unsigned int val;
237 val = (addr << 9) | data;
238 snd_vt1724_write_i2c(ice, 0x34, val >> 8, val & 0xff);
242 static void se200pci_WM8776_set_output_volume(struct snd_ice1712 *ice,
243 unsigned int vol1, unsigned int vol2)
245 se200pci_WM8776_write(ice, 0x03, vol1);
246 se200pci_WM8776_write(ice, 0x04, vol2 | 0x100);
249 static void se200pci_WM8776_set_input_volume(struct snd_ice1712 *ice,
250 unsigned int vol1, unsigned int vol2)
252 se200pci_WM8776_write(ice, 0x0e, vol1);
253 se200pci_WM8776_write(ice, 0x0f, vol2 | 0x100);
256 static const char *se200pci_sel[] = {
257 "LINE-IN", "CD-IN", "MIC-IN", "ALL-MIX", NULL
260 static void se200pci_WM8776_set_input_selector(struct snd_ice1712 *ice,
261 unsigned int sel)
263 static unsigned char vals[] = {
264 /* LINE, CD, MIC, ALL, GND */
265 0x10, 0x04, 0x08, 0x1c, 0x03
267 if (sel > 4)
268 sel = 4;
269 se200pci_WM8776_write(ice, 0x15, vals[sel]);
272 static void se200pci_WM8776_set_afl(struct snd_ice1712 *ice, unsigned int afl)
274 /* AFL -- After Fader Listening */
275 if (afl)
276 se200pci_WM8776_write(ice, 0x16, 0x005);
277 else
278 se200pci_WM8776_write(ice, 0x16, 0x001);
281 static const char *se200pci_agc[] = {
282 "Off", "LimiterMode", "ALCMode", NULL
285 static void se200pci_WM8776_set_agc(struct snd_ice1712 *ice, unsigned int agc)
287 /* AGC -- Auto Gain Control of the input */
288 switch (agc) {
289 case 0:
290 se200pci_WM8776_write(ice, 0x11, 0x000); /* Off */
291 break;
292 case 1:
293 se200pci_WM8776_write(ice, 0x10, 0x07b);
294 se200pci_WM8776_write(ice, 0x11, 0x100); /* LimiterMode */
295 break;
296 case 2:
297 se200pci_WM8776_write(ice, 0x10, 0x1fb);
298 se200pci_WM8776_write(ice, 0x11, 0x100); /* ALCMode */
299 break;
303 static void __devinit se200pci_WM8776_init(struct snd_ice1712 *ice)
305 int i;
306 static unsigned short __devinitdata default_values[] = {
307 0x100, 0x100, 0x100,
308 0x100, 0x100, 0x100,
309 0x000, 0x090, 0x000, 0x000,
310 0x022, 0x022, 0x022,
311 0x008, 0x0cf, 0x0cf, 0x07b, 0x000,
312 0x032, 0x000, 0x0a6, 0x001, 0x001
315 se200pci_WM8776_write(ice, 0x17, 0x000); /* reset all */
316 /* ADC and DAC interface is I2S 24bits mode */
317 /* The sample-rate are automatically changed */
318 udelay(10);
319 /* BUT my board can not do reset all, so I load all by manually. */
320 for (i = 0; i < ARRAY_SIZE(default_values); i++)
321 se200pci_WM8776_write(ice, i, default_values[i]);
323 se200pci_WM8776_set_input_selector(ice, 0);
324 se200pci_WM8776_set_afl(ice, 0);
325 se200pci_WM8776_set_agc(ice, 0);
326 se200pci_WM8776_set_input_volume(ice, 0, 0);
327 se200pci_WM8776_set_output_volume(ice, 0, 0);
329 /* head phone mute and power down */
330 se200pci_WM8776_write(ice, 0x00, 0);
331 se200pci_WM8776_write(ice, 0x01, 0);
332 se200pci_WM8776_write(ice, 0x02, 0x100);
333 se200pci_WM8776_write(ice, 0x0d, 0x080);
336 static void se200pci_WM8776_set_pro_rate(struct snd_ice1712 *ice,
337 unsigned int rate)
339 /* nothing to do */
343 /****************************************************************************/
344 /* runtime interface */
345 /****************************************************************************/
347 static void se200pci_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate)
349 se200pci_WM8740_set_pro_rate(ice, rate);
350 se200pci_WM8766_set_pro_rate(ice, rate);
351 se200pci_WM8776_set_pro_rate(ice, rate);
354 struct se200pci_control {
355 char *name;
356 enum {
357 WM8766,
358 WM8776in,
359 WM8776out,
360 WM8776sel,
361 WM8776agc,
362 WM8776afl
363 } target;
364 enum { VOLUME1, VOLUME2, BOOLEAN, ENUM } type;
365 int ch;
366 const char **member;
367 const char *comment;
370 static const struct se200pci_control se200pci_cont[] = {
372 .name = "Front Playback Volume",
373 .target = WM8776out,
374 .type = VOLUME1,
375 .comment = "Front(green)"
378 .name = "Side Playback Volume",
379 .target = WM8766,
380 .type = VOLUME1,
381 .ch = 1,
382 .comment = "Surround(orange)"
385 .name = "Surround Playback Volume",
386 .target = WM8766,
387 .type = VOLUME1,
388 .ch = 2,
389 .comment = "SurroundBack(white)"
392 .name = "CLFE Playback Volume",
393 .target = WM8766,
394 .type = VOLUME1,
395 .ch = 0,
396 .comment = "Center(Lch)&SubWoofer(Rch)(black)"
399 .name = "Capture Volume",
400 .target = WM8776in,
401 .type = VOLUME2
404 .name = "Capture Select",
405 .target = WM8776sel,
406 .type = ENUM,
407 .member = se200pci_sel
410 .name = "AGC Capture Mode",
411 .target = WM8776agc,
412 .type = ENUM,
413 .member = se200pci_agc
416 .name = "AFL Bypass Playback Switch",
417 .target = WM8776afl,
418 .type = BOOLEAN
422 static int se200pci_get_enum_count(int n)
424 const char **member;
425 int c;
427 member = se200pci_cont[n].member;
428 if (!member)
429 return 0;
430 for (c = 0; member[c]; c++)
432 return c;
435 static int se200pci_cont_volume_info(struct snd_kcontrol *kc,
436 struct snd_ctl_elem_info *uinfo)
438 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
439 uinfo->count = 2;
440 uinfo->value.integer.min = 0; /* mute */
441 uinfo->value.integer.max = 0xff; /* 0dB */
442 return 0;
445 #define se200pci_cont_boolean_info snd_ctl_boolean_mono_info
447 static int se200pci_cont_enum_info(struct snd_kcontrol *kc,
448 struct snd_ctl_elem_info *uinfo)
450 int n, c;
452 n = kc->private_value;
453 c = se200pci_get_enum_count(n);
454 if (!c)
455 return -EINVAL;
456 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
457 uinfo->count = 1;
458 uinfo->value.enumerated.items = c;
459 if (uinfo->value.enumerated.item >= c)
460 uinfo->value.enumerated.item = c - 1;
461 strcpy(uinfo->value.enumerated.name,
462 se200pci_cont[n].member[uinfo->value.enumerated.item]);
463 return 0;
466 static int se200pci_cont_volume_get(struct snd_kcontrol *kc,
467 struct snd_ctl_elem_value *uc)
469 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
470 struct se_spec *spec = ice->spec;
471 int n = kc->private_value;
472 uc->value.integer.value[0] = spec->vol[n].ch1;
473 uc->value.integer.value[1] = spec->vol[n].ch2;
474 return 0;
477 static int se200pci_cont_boolean_get(struct snd_kcontrol *kc,
478 struct snd_ctl_elem_value *uc)
480 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
481 struct se_spec *spec = ice->spec;
482 int n = kc->private_value;
483 uc->value.integer.value[0] = spec->vol[n].ch1;
484 return 0;
487 static int se200pci_cont_enum_get(struct snd_kcontrol *kc,
488 struct snd_ctl_elem_value *uc)
490 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
491 struct se_spec *spec = ice->spec;
492 int n = kc->private_value;
493 uc->value.enumerated.item[0] = spec->vol[n].ch1;
494 return 0;
497 static void se200pci_cont_update(struct snd_ice1712 *ice, int n)
499 struct se_spec *spec = ice->spec;
500 switch (se200pci_cont[n].target) {
501 case WM8766:
502 se200pci_WM8766_set_volume(ice,
503 se200pci_cont[n].ch,
504 spec->vol[n].ch1,
505 spec->vol[n].ch2);
506 break;
508 case WM8776in:
509 se200pci_WM8776_set_input_volume(ice,
510 spec->vol[n].ch1,
511 spec->vol[n].ch2);
512 break;
514 case WM8776out:
515 se200pci_WM8776_set_output_volume(ice,
516 spec->vol[n].ch1,
517 spec->vol[n].ch2);
518 break;
520 case WM8776sel:
521 se200pci_WM8776_set_input_selector(ice,
522 spec->vol[n].ch1);
523 break;
525 case WM8776agc:
526 se200pci_WM8776_set_agc(ice, spec->vol[n].ch1);
527 break;
529 case WM8776afl:
530 se200pci_WM8776_set_afl(ice, spec->vol[n].ch1);
531 break;
533 default:
534 break;
538 static int se200pci_cont_volume_put(struct snd_kcontrol *kc,
539 struct snd_ctl_elem_value *uc)
541 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
542 struct se_spec *spec = ice->spec;
543 int n = kc->private_value;
544 unsigned int vol1, vol2;
545 int changed;
547 changed = 0;
548 vol1 = uc->value.integer.value[0] & 0xff;
549 vol2 = uc->value.integer.value[1] & 0xff;
550 if (spec->vol[n].ch1 != vol1) {
551 spec->vol[n].ch1 = vol1;
552 changed = 1;
554 if (spec->vol[n].ch2 != vol2) {
555 spec->vol[n].ch2 = vol2;
556 changed = 1;
558 if (changed)
559 se200pci_cont_update(ice, n);
561 return changed;
564 static int se200pci_cont_boolean_put(struct snd_kcontrol *kc,
565 struct snd_ctl_elem_value *uc)
567 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
568 struct se_spec *spec = ice->spec;
569 int n = kc->private_value;
570 unsigned int vol1;
572 vol1 = !!uc->value.integer.value[0];
573 if (spec->vol[n].ch1 != vol1) {
574 spec->vol[n].ch1 = vol1;
575 se200pci_cont_update(ice, n);
576 return 1;
578 return 0;
581 static int se200pci_cont_enum_put(struct snd_kcontrol *kc,
582 struct snd_ctl_elem_value *uc)
584 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
585 struct se_spec *spec = ice->spec;
586 int n = kc->private_value;
587 unsigned int vol1;
589 vol1 = uc->value.enumerated.item[0];
590 if (vol1 >= se200pci_get_enum_count(n))
591 return -EINVAL;
592 if (spec->vol[n].ch1 != vol1) {
593 spec->vol[n].ch1 = vol1;
594 se200pci_cont_update(ice, n);
595 return 1;
597 return 0;
600 static const DECLARE_TLV_DB_SCALE(db_scale_gain1, -12750, 50, 1);
601 static const DECLARE_TLV_DB_SCALE(db_scale_gain2, -10350, 50, 1);
603 static int __devinit se200pci_add_controls(struct snd_ice1712 *ice)
605 int i;
606 struct snd_kcontrol_new cont;
607 int err;
609 memset(&cont, 0, sizeof(cont));
610 cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
611 for (i = 0; i < ARRAY_SIZE(se200pci_cont); i++) {
612 cont.private_value = i;
613 cont.name = se200pci_cont[i].name;
614 cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
615 cont.tlv.p = NULL;
616 switch (se200pci_cont[i].type) {
617 case VOLUME1:
618 case VOLUME2:
619 cont.info = se200pci_cont_volume_info;
620 cont.get = se200pci_cont_volume_get;
621 cont.put = se200pci_cont_volume_put;
622 cont.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
623 if (se200pci_cont[i].type == VOLUME1)
624 cont.tlv.p = db_scale_gain1;
625 else
626 cont.tlv.p = db_scale_gain2;
627 break;
628 case BOOLEAN:
629 cont.info = se200pci_cont_boolean_info;
630 cont.get = se200pci_cont_boolean_get;
631 cont.put = se200pci_cont_boolean_put;
632 break;
633 case ENUM:
634 cont.info = se200pci_cont_enum_info;
635 cont.get = se200pci_cont_enum_get;
636 cont.put = se200pci_cont_enum_put;
637 break;
638 default:
639 snd_BUG();
640 return -EINVAL;
642 err = snd_ctl_add(ice->card, snd_ctl_new1(&cont, ice));
643 if (err < 0)
644 return err;
647 return 0;
651 /****************************************************************************/
652 /* ONKYO WAVIO SE-90PCI */
653 /****************************************************************************/
655 * system configuration ICE_EEP2_SYSCONF=0x4b
656 * AC-Link configuration ICE_EEP2_ACLINK=0x80
657 * I2S converters feature ICE_EEP2_I2S=0x78
658 * S/PDIF configuration ICE_EEP2_SPDIF=0xc3
660 * ** connected chip **
662 * WM8716
663 * A 2ch-DAC of main outputs.
664 * It setuped as I2S mode by wire, so no way to setup from software.
665 * ML/I2S (28pin) -- +5V
666 * MC/DM1 (27pin) -- GND
667 * MC/DM0 (26pin) -- GND
668 * MUTEB (25pin) -- open (internal pull-up)
669 * MODE (24pin) -- GND
670 * CSBIWO (23pin) -- +5V
674 /* Nothing to do for this chip. */
677 /****************************************************************************/
678 /* probe/initialize/setup */
679 /****************************************************************************/
681 static int __devinit se_init(struct snd_ice1712 *ice)
683 struct se_spec *spec;
685 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
686 if (!spec)
687 return -ENOMEM;
688 ice->spec = spec;
690 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE90PCI) {
691 ice->num_total_dacs = 2;
692 ice->num_total_adcs = 0;
693 ice->vt1720 = 1;
694 return 0;
696 } else if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE200PCI) {
697 ice->num_total_dacs = 8;
698 ice->num_total_adcs = 2;
699 se200pci_WM8740_init(ice);
700 se200pci_WM8766_init(ice);
701 se200pci_WM8776_init(ice);
702 ice->gpio.set_pro_rate = se200pci_set_pro_rate;
703 return 0;
706 return -ENOENT;
709 static int __devinit se_add_controls(struct snd_ice1712 *ice)
711 int err;
713 err = 0;
714 /* nothing to do for VT1724_SUBDEVICE_SE90PCI */
715 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE200PCI)
716 err = se200pci_add_controls(ice);
718 return err;
722 /****************************************************************************/
723 /* entry point */
724 /****************************************************************************/
726 static unsigned char se200pci_eeprom[] __devinitdata = {
727 [ICE_EEP2_SYSCONF] = 0x4b, /* 49.152Hz, spdif-in/ADC, 4DACs */
728 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
729 [ICE_EEP2_I2S] = 0x78, /* 96k-ok, 24bit, 192k-ok */
730 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
732 [ICE_EEP2_GPIO_DIR] = 0x02, /* WM8766 mute 1=output */
733 [ICE_EEP2_GPIO_DIR1] = 0x00, /* not used */
734 [ICE_EEP2_GPIO_DIR2] = 0x07, /* WM8766 ML/MC/MD 1=output */
736 [ICE_EEP2_GPIO_MASK] = 0x00, /* 0=writable */
737 [ICE_EEP2_GPIO_MASK1] = 0x00, /* 0=writable */
738 [ICE_EEP2_GPIO_MASK2] = 0x00, /* 0=writable */
740 [ICE_EEP2_GPIO_STATE] = 0x00, /* WM8766 mute=0 */
741 [ICE_EEP2_GPIO_STATE1] = 0x00, /* not used */
742 [ICE_EEP2_GPIO_STATE2] = 0x07, /* WM8766 ML/MC/MD */
745 static unsigned char se90pci_eeprom[] __devinitdata = {
746 [ICE_EEP2_SYSCONF] = 0x4b, /* 49.152Hz, spdif-in/ADC, 4DACs */
747 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
748 [ICE_EEP2_I2S] = 0x78, /* 96k-ok, 24bit, 192k-ok */
749 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
751 /* ALL GPIO bits are in input mode */
754 struct snd_ice1712_card_info snd_vt1724_se_cards[] __devinitdata = {
756 .subvendor = VT1724_SUBDEVICE_SE200PCI,
757 .name = "ONKYO SE200PCI",
758 .model = "se200pci",
759 .chip_init = se_init,
760 .build_controls = se_add_controls,
761 .eeprom_size = sizeof(se200pci_eeprom),
762 .eeprom_data = se200pci_eeprom,
765 .subvendor = VT1724_SUBDEVICE_SE90PCI,
766 .name = "ONKYO SE90PCI",
767 .model = "se90pci",
768 .chip_init = se_init,
769 .build_controls = se_add_controls,
770 .eeprom_size = sizeof(se90pci_eeprom),
771 .eeprom_data = se90pci_eeprom,
773 {} /*terminator*/