ARCv2: SLC: Make sure busy bit is set properly for region ops
[linux/fpc-iii.git] / sound / pci / ice1712 / se.c
blob1c5d5b22c7a0d2ee4ccccf7e1bf6760f42ab6cca
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 <linux/delay.h>
26 #include <linux/interrupt.h>
27 #include <linux/init.h>
28 #include <linux/slab.h>
29 #include <sound/core.h>
30 #include <sound/tlv.h>
32 #include "ice1712.h"
33 #include "envy24ht.h"
34 #include "se.h"
36 struct se_spec {
37 struct {
38 unsigned char ch1, ch2;
39 } vol[8];
42 /****************************************************************************/
43 /* ONKYO WAVIO SE-200PCI */
44 /****************************************************************************/
46 * system configuration ICE_EEP2_SYSCONF=0x4b
47 * XIN1 49.152MHz
48 * not have UART
49 * one stereo ADC and a S/PDIF receiver connected
50 * four stereo DACs connected
52 * AC-Link configuration ICE_EEP2_ACLINK=0x80
53 * use I2C, not use AC97
55 * I2S converters feature ICE_EEP2_I2S=0x78
56 * I2S codec has no volume/mute control feature
57 * I2S codec supports 96KHz and 192KHz
58 * I2S codec 24bits
60 * S/PDIF configuration ICE_EEP2_SPDIF=0xc3
61 * Enable integrated S/PDIF transmitter
62 * internal S/PDIF out implemented
63 * S/PDIF is stereo
64 * External S/PDIF out implemented
67 * ** connected chips **
69 * WM8740
70 * A 2ch-DAC of main outputs.
71 * It setuped as I2S mode by wire, so no way to setup from software.
72 * The sample-rate are automatically changed.
73 * ML/I2S (28pin) --------+
74 * MC/DM1 (27pin) -- 5V |
75 * MD/DM0 (26pin) -- GND |
76 * MUTEB (25pin) -- NC |
77 * MODE (24pin) -- GND |
78 * CSBIW (23pin) --------+
79 * |
80 * RSTB (22pin) --R(1K)-+
81 * Probably it reduce the noise from the control line.
83 * WM8766
84 * A 6ch-DAC for surrounds.
85 * It's control wire was connected to GPIOxx (3-wire serial interface)
86 * ML/I2S (11pin) -- GPIO18
87 * MC/IWL (12pin) -- GPIO17
88 * MD/DM (13pin) -- GPIO16
89 * MUTE (14pin) -- GPIO01
91 * WM8776
92 * A 2ch-ADC(with 10ch-selector) plus 2ch-DAC.
93 * It's control wire was connected to SDA/SCLK (2-wire serial interface)
94 * MODE (16pin) -- R(1K) -- GND
95 * CE (17pin) -- R(1K) -- GND 2-wire mode (address=0x34)
96 * DI (18pin) -- SDA
97 * CL (19pin) -- SCLK
100 * ** output pins and device names **
102 * 7.1ch name -- output connector color -- device (-D option)
104 * FRONT 2ch -- green -- plughw:0,0
105 * CENTER(Lch) SUBWOOFER(Rch) -- black -- plughw:0,2,0
106 * SURROUND 2ch -- orange -- plughw:0,2,1
107 * SURROUND BACK 2ch -- white -- plughw:0,2,2
112 /****************************************************************************/
113 /* WM8740 interface */
114 /****************************************************************************/
116 static void se200pci_WM8740_init(struct snd_ice1712 *ice)
118 /* nothing to do */
122 static void se200pci_WM8740_set_pro_rate(struct snd_ice1712 *ice,
123 unsigned int rate)
125 /* nothing to do */
129 /****************************************************************************/
130 /* WM8766 interface */
131 /****************************************************************************/
133 static void se200pci_WM8766_write(struct snd_ice1712 *ice,
134 unsigned int addr, unsigned int data)
136 unsigned int st;
137 unsigned int bits;
138 int i;
139 const unsigned int DATA = 0x010000;
140 const unsigned int CLOCK = 0x020000;
141 const unsigned int LOAD = 0x040000;
142 const unsigned int ALL_MASK = (DATA | CLOCK | LOAD);
144 snd_ice1712_save_gpio_status(ice);
146 st = ((addr & 0x7f) << 9) | (data & 0x1ff);
147 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction | ALL_MASK);
148 snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask & ~ALL_MASK);
149 bits = snd_ice1712_gpio_read(ice) & ~ALL_MASK;
151 snd_ice1712_gpio_write(ice, bits);
152 for (i = 0; i < 16; i++) {
153 udelay(1);
154 bits &= ~CLOCK;
155 st = (st << 1);
156 if (st & 0x10000)
157 bits |= DATA;
158 else
159 bits &= ~DATA;
161 snd_ice1712_gpio_write(ice, bits);
163 udelay(1);
164 bits |= CLOCK;
165 snd_ice1712_gpio_write(ice, bits);
168 udelay(1);
169 bits |= LOAD;
170 snd_ice1712_gpio_write(ice, bits);
172 udelay(1);
173 bits |= (DATA | CLOCK);
174 snd_ice1712_gpio_write(ice, bits);
176 snd_ice1712_restore_gpio_status(ice);
179 static void se200pci_WM8766_set_volume(struct snd_ice1712 *ice, int ch,
180 unsigned int vol1, unsigned int vol2)
182 switch (ch) {
183 case 0:
184 se200pci_WM8766_write(ice, 0x000, vol1);
185 se200pci_WM8766_write(ice, 0x001, vol2 | 0x100);
186 break;
187 case 1:
188 se200pci_WM8766_write(ice, 0x004, vol1);
189 se200pci_WM8766_write(ice, 0x005, vol2 | 0x100);
190 break;
191 case 2:
192 se200pci_WM8766_write(ice, 0x006, vol1);
193 se200pci_WM8766_write(ice, 0x007, vol2 | 0x100);
194 break;
198 static void se200pci_WM8766_init(struct snd_ice1712 *ice)
200 se200pci_WM8766_write(ice, 0x1f, 0x000); /* RESET ALL */
201 udelay(10);
203 se200pci_WM8766_set_volume(ice, 0, 0, 0); /* volume L=0 R=0 */
204 se200pci_WM8766_set_volume(ice, 1, 0, 0); /* volume L=0 R=0 */
205 se200pci_WM8766_set_volume(ice, 2, 0, 0); /* volume L=0 R=0 */
207 se200pci_WM8766_write(ice, 0x03, 0x022); /* serial mode I2S-24bits */
208 se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */
209 se200pci_WM8766_write(ice, 0x12, 0x000); /* MDP=0 */
210 se200pci_WM8766_write(ice, 0x15, 0x000); /* MDP=0 */
211 se200pci_WM8766_write(ice, 0x09, 0x000); /* demp=off mute=off */
213 se200pci_WM8766_write(ice, 0x02, 0x124); /* ch-assign L=L R=R RESET */
214 se200pci_WM8766_write(ice, 0x02, 0x120); /* ch-assign L=L R=R */
217 static void se200pci_WM8766_set_pro_rate(struct snd_ice1712 *ice,
218 unsigned int rate)
220 if (rate > 96000)
221 se200pci_WM8766_write(ice, 0x0a, 0x000); /* MCLK=128fs */
222 else
223 se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */
227 /****************************************************************************/
228 /* WM8776 interface */
229 /****************************************************************************/
231 static void se200pci_WM8776_write(struct snd_ice1712 *ice,
232 unsigned int addr, unsigned int data)
234 unsigned int val;
236 val = (addr << 9) | data;
237 snd_vt1724_write_i2c(ice, 0x34, val >> 8, val & 0xff);
241 static void se200pci_WM8776_set_output_volume(struct snd_ice1712 *ice,
242 unsigned int vol1, unsigned int vol2)
244 se200pci_WM8776_write(ice, 0x03, vol1);
245 se200pci_WM8776_write(ice, 0x04, vol2 | 0x100);
248 static void se200pci_WM8776_set_input_volume(struct snd_ice1712 *ice,
249 unsigned int vol1, unsigned int vol2)
251 se200pci_WM8776_write(ice, 0x0e, vol1);
252 se200pci_WM8776_write(ice, 0x0f, vol2 | 0x100);
255 static const char * const se200pci_sel[] = {
256 "LINE-IN", "CD-IN", "MIC-IN", "ALL-MIX", NULL
259 static void se200pci_WM8776_set_input_selector(struct snd_ice1712 *ice,
260 unsigned int sel)
262 static unsigned char vals[] = {
263 /* LINE, CD, MIC, ALL, GND */
264 0x10, 0x04, 0x08, 0x1c, 0x03
266 if (sel > 4)
267 sel = 4;
268 se200pci_WM8776_write(ice, 0x15, vals[sel]);
271 static void se200pci_WM8776_set_afl(struct snd_ice1712 *ice, unsigned int afl)
273 /* AFL -- After Fader Listening */
274 if (afl)
275 se200pci_WM8776_write(ice, 0x16, 0x005);
276 else
277 se200pci_WM8776_write(ice, 0x16, 0x001);
280 static const char * const se200pci_agc[] = {
281 "Off", "LimiterMode", "ALCMode", NULL
284 static void se200pci_WM8776_set_agc(struct snd_ice1712 *ice, unsigned int agc)
286 /* AGC -- Auto Gain Control of the input */
287 switch (agc) {
288 case 0:
289 se200pci_WM8776_write(ice, 0x11, 0x000); /* Off */
290 break;
291 case 1:
292 se200pci_WM8776_write(ice, 0x10, 0x07b);
293 se200pci_WM8776_write(ice, 0x11, 0x100); /* LimiterMode */
294 break;
295 case 2:
296 se200pci_WM8776_write(ice, 0x10, 0x1fb);
297 se200pci_WM8776_write(ice, 0x11, 0x100); /* ALCMode */
298 break;
302 static void se200pci_WM8776_init(struct snd_ice1712 *ice)
304 int i;
305 static unsigned short default_values[] = {
306 0x100, 0x100, 0x100,
307 0x100, 0x100, 0x100,
308 0x000, 0x090, 0x000, 0x000,
309 0x022, 0x022, 0x022,
310 0x008, 0x0cf, 0x0cf, 0x07b, 0x000,
311 0x032, 0x000, 0x0a6, 0x001, 0x001
314 se200pci_WM8776_write(ice, 0x17, 0x000); /* reset all */
315 /* ADC and DAC interface is I2S 24bits mode */
316 /* The sample-rate are automatically changed */
317 udelay(10);
318 /* BUT my board can not do reset all, so I load all by manually. */
319 for (i = 0; i < ARRAY_SIZE(default_values); i++)
320 se200pci_WM8776_write(ice, i, default_values[i]);
322 se200pci_WM8776_set_input_selector(ice, 0);
323 se200pci_WM8776_set_afl(ice, 0);
324 se200pci_WM8776_set_agc(ice, 0);
325 se200pci_WM8776_set_input_volume(ice, 0, 0);
326 se200pci_WM8776_set_output_volume(ice, 0, 0);
328 /* head phone mute and power down */
329 se200pci_WM8776_write(ice, 0x00, 0);
330 se200pci_WM8776_write(ice, 0x01, 0);
331 se200pci_WM8776_write(ice, 0x02, 0x100);
332 se200pci_WM8776_write(ice, 0x0d, 0x080);
335 static void se200pci_WM8776_set_pro_rate(struct snd_ice1712 *ice,
336 unsigned int rate)
338 /* nothing to do */
342 /****************************************************************************/
343 /* runtime interface */
344 /****************************************************************************/
346 static void se200pci_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate)
348 se200pci_WM8740_set_pro_rate(ice, rate);
349 se200pci_WM8766_set_pro_rate(ice, rate);
350 se200pci_WM8776_set_pro_rate(ice, rate);
353 struct se200pci_control {
354 const char *name;
355 enum {
356 WM8766,
357 WM8776in,
358 WM8776out,
359 WM8776sel,
360 WM8776agc,
361 WM8776afl
362 } target;
363 enum { VOLUME1, VOLUME2, BOOLEAN, ENUM } type;
364 int ch;
365 const char * const *member;
366 const char *comment;
369 static const struct se200pci_control se200pci_cont[] = {
371 .name = "Front Playback Volume",
372 .target = WM8776out,
373 .type = VOLUME1,
374 .comment = "Front(green)"
377 .name = "Side Playback Volume",
378 .target = WM8766,
379 .type = VOLUME1,
380 .ch = 1,
381 .comment = "Surround(orange)"
384 .name = "Surround Playback Volume",
385 .target = WM8766,
386 .type = VOLUME1,
387 .ch = 2,
388 .comment = "SurroundBack(white)"
391 .name = "CLFE Playback Volume",
392 .target = WM8766,
393 .type = VOLUME1,
394 .ch = 0,
395 .comment = "Center(Lch)&SubWoofer(Rch)(black)"
398 .name = "Capture Volume",
399 .target = WM8776in,
400 .type = VOLUME2
403 .name = "Capture Select",
404 .target = WM8776sel,
405 .type = ENUM,
406 .member = se200pci_sel
409 .name = "AGC Capture Mode",
410 .target = WM8776agc,
411 .type = ENUM,
412 .member = se200pci_agc
415 .name = "AFL Bypass Playback Switch",
416 .target = WM8776afl,
417 .type = BOOLEAN
421 static int se200pci_get_enum_count(int n)
423 const char * const *member;
424 int c;
426 member = se200pci_cont[n].member;
427 if (!member)
428 return 0;
429 for (c = 0; member[c]; c++)
431 return c;
434 static int se200pci_cont_volume_info(struct snd_kcontrol *kc,
435 struct snd_ctl_elem_info *uinfo)
437 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
438 uinfo->count = 2;
439 uinfo->value.integer.min = 0; /* mute */
440 uinfo->value.integer.max = 0xff; /* 0dB */
441 return 0;
444 #define se200pci_cont_boolean_info snd_ctl_boolean_mono_info
446 static int se200pci_cont_enum_info(struct snd_kcontrol *kc,
447 struct snd_ctl_elem_info *uinfo)
449 int n, c;
451 n = kc->private_value;
452 c = se200pci_get_enum_count(n);
453 if (!c)
454 return -EINVAL;
455 return snd_ctl_enum_info(uinfo, 1, c, se200pci_cont[n].member);
458 static int se200pci_cont_volume_get(struct snd_kcontrol *kc,
459 struct snd_ctl_elem_value *uc)
461 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
462 struct se_spec *spec = ice->spec;
463 int n = kc->private_value;
464 uc->value.integer.value[0] = spec->vol[n].ch1;
465 uc->value.integer.value[1] = spec->vol[n].ch2;
466 return 0;
469 static int se200pci_cont_boolean_get(struct snd_kcontrol *kc,
470 struct snd_ctl_elem_value *uc)
472 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
473 struct se_spec *spec = ice->spec;
474 int n = kc->private_value;
475 uc->value.integer.value[0] = spec->vol[n].ch1;
476 return 0;
479 static int se200pci_cont_enum_get(struct snd_kcontrol *kc,
480 struct snd_ctl_elem_value *uc)
482 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
483 struct se_spec *spec = ice->spec;
484 int n = kc->private_value;
485 uc->value.enumerated.item[0] = spec->vol[n].ch1;
486 return 0;
489 static void se200pci_cont_update(struct snd_ice1712 *ice, int n)
491 struct se_spec *spec = ice->spec;
492 switch (se200pci_cont[n].target) {
493 case WM8766:
494 se200pci_WM8766_set_volume(ice,
495 se200pci_cont[n].ch,
496 spec->vol[n].ch1,
497 spec->vol[n].ch2);
498 break;
500 case WM8776in:
501 se200pci_WM8776_set_input_volume(ice,
502 spec->vol[n].ch1,
503 spec->vol[n].ch2);
504 break;
506 case WM8776out:
507 se200pci_WM8776_set_output_volume(ice,
508 spec->vol[n].ch1,
509 spec->vol[n].ch2);
510 break;
512 case WM8776sel:
513 se200pci_WM8776_set_input_selector(ice,
514 spec->vol[n].ch1);
515 break;
517 case WM8776agc:
518 se200pci_WM8776_set_agc(ice, spec->vol[n].ch1);
519 break;
521 case WM8776afl:
522 se200pci_WM8776_set_afl(ice, spec->vol[n].ch1);
523 break;
525 default:
526 break;
530 static int se200pci_cont_volume_put(struct snd_kcontrol *kc,
531 struct snd_ctl_elem_value *uc)
533 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
534 struct se_spec *spec = ice->spec;
535 int n = kc->private_value;
536 unsigned int vol1, vol2;
537 int changed;
539 changed = 0;
540 vol1 = uc->value.integer.value[0] & 0xff;
541 vol2 = uc->value.integer.value[1] & 0xff;
542 if (spec->vol[n].ch1 != vol1) {
543 spec->vol[n].ch1 = vol1;
544 changed = 1;
546 if (spec->vol[n].ch2 != vol2) {
547 spec->vol[n].ch2 = vol2;
548 changed = 1;
550 if (changed)
551 se200pci_cont_update(ice, n);
553 return changed;
556 static int se200pci_cont_boolean_put(struct snd_kcontrol *kc,
557 struct snd_ctl_elem_value *uc)
559 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
560 struct se_spec *spec = ice->spec;
561 int n = kc->private_value;
562 unsigned int vol1;
564 vol1 = !!uc->value.integer.value[0];
565 if (spec->vol[n].ch1 != vol1) {
566 spec->vol[n].ch1 = vol1;
567 se200pci_cont_update(ice, n);
568 return 1;
570 return 0;
573 static int se200pci_cont_enum_put(struct snd_kcontrol *kc,
574 struct snd_ctl_elem_value *uc)
576 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
577 struct se_spec *spec = ice->spec;
578 int n = kc->private_value;
579 unsigned int vol1;
581 vol1 = uc->value.enumerated.item[0];
582 if (vol1 >= se200pci_get_enum_count(n))
583 return -EINVAL;
584 if (spec->vol[n].ch1 != vol1) {
585 spec->vol[n].ch1 = vol1;
586 se200pci_cont_update(ice, n);
587 return 1;
589 return 0;
592 static const DECLARE_TLV_DB_SCALE(db_scale_gain1, -12750, 50, 1);
593 static const DECLARE_TLV_DB_SCALE(db_scale_gain2, -10350, 50, 1);
595 static int se200pci_add_controls(struct snd_ice1712 *ice)
597 int i;
598 struct snd_kcontrol_new cont;
599 int err;
601 memset(&cont, 0, sizeof(cont));
602 cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
603 for (i = 0; i < ARRAY_SIZE(se200pci_cont); i++) {
604 cont.private_value = i;
605 cont.name = se200pci_cont[i].name;
606 cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
607 cont.tlv.p = NULL;
608 switch (se200pci_cont[i].type) {
609 case VOLUME1:
610 case VOLUME2:
611 cont.info = se200pci_cont_volume_info;
612 cont.get = se200pci_cont_volume_get;
613 cont.put = se200pci_cont_volume_put;
614 cont.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
615 if (se200pci_cont[i].type == VOLUME1)
616 cont.tlv.p = db_scale_gain1;
617 else
618 cont.tlv.p = db_scale_gain2;
619 break;
620 case BOOLEAN:
621 cont.info = se200pci_cont_boolean_info;
622 cont.get = se200pci_cont_boolean_get;
623 cont.put = se200pci_cont_boolean_put;
624 break;
625 case ENUM:
626 cont.info = se200pci_cont_enum_info;
627 cont.get = se200pci_cont_enum_get;
628 cont.put = se200pci_cont_enum_put;
629 break;
630 default:
631 snd_BUG();
632 return -EINVAL;
634 err = snd_ctl_add(ice->card, snd_ctl_new1(&cont, ice));
635 if (err < 0)
636 return err;
639 return 0;
643 /****************************************************************************/
644 /* ONKYO WAVIO SE-90PCI */
645 /****************************************************************************/
647 * system configuration ICE_EEP2_SYSCONF=0x4b
648 * AC-Link configuration ICE_EEP2_ACLINK=0x80
649 * I2S converters feature ICE_EEP2_I2S=0x78
650 * S/PDIF configuration ICE_EEP2_SPDIF=0xc3
652 * ** connected chip **
654 * WM8716
655 * A 2ch-DAC of main outputs.
656 * It setuped as I2S mode by wire, so no way to setup from software.
657 * ML/I2S (28pin) -- +5V
658 * MC/DM1 (27pin) -- GND
659 * MC/DM0 (26pin) -- GND
660 * MUTEB (25pin) -- open (internal pull-up)
661 * MODE (24pin) -- GND
662 * CSBIWO (23pin) -- +5V
666 /* Nothing to do for this chip. */
669 /****************************************************************************/
670 /* probe/initialize/setup */
671 /****************************************************************************/
673 static int se_init(struct snd_ice1712 *ice)
675 struct se_spec *spec;
677 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
678 if (!spec)
679 return -ENOMEM;
680 ice->spec = spec;
682 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE90PCI) {
683 ice->num_total_dacs = 2;
684 ice->num_total_adcs = 0;
685 ice->vt1720 = 1;
686 return 0;
688 } else if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE200PCI) {
689 ice->num_total_dacs = 8;
690 ice->num_total_adcs = 2;
691 se200pci_WM8740_init(ice);
692 se200pci_WM8766_init(ice);
693 se200pci_WM8776_init(ice);
694 ice->gpio.set_pro_rate = se200pci_set_pro_rate;
695 return 0;
698 return -ENOENT;
701 static int se_add_controls(struct snd_ice1712 *ice)
703 int err;
705 err = 0;
706 /* nothing to do for VT1724_SUBDEVICE_SE90PCI */
707 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE200PCI)
708 err = se200pci_add_controls(ice);
710 return err;
714 /****************************************************************************/
715 /* entry point */
716 /****************************************************************************/
718 static unsigned char se200pci_eeprom[] = {
719 [ICE_EEP2_SYSCONF] = 0x4b, /* 49.152Hz, spdif-in/ADC, 4DACs */
720 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
721 [ICE_EEP2_I2S] = 0x78, /* 96k-ok, 24bit, 192k-ok */
722 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
724 [ICE_EEP2_GPIO_DIR] = 0x02, /* WM8766 mute 1=output */
725 [ICE_EEP2_GPIO_DIR1] = 0x00, /* not used */
726 [ICE_EEP2_GPIO_DIR2] = 0x07, /* WM8766 ML/MC/MD 1=output */
728 [ICE_EEP2_GPIO_MASK] = 0x00, /* 0=writable */
729 [ICE_EEP2_GPIO_MASK1] = 0x00, /* 0=writable */
730 [ICE_EEP2_GPIO_MASK2] = 0x00, /* 0=writable */
732 [ICE_EEP2_GPIO_STATE] = 0x00, /* WM8766 mute=0 */
733 [ICE_EEP2_GPIO_STATE1] = 0x00, /* not used */
734 [ICE_EEP2_GPIO_STATE2] = 0x07, /* WM8766 ML/MC/MD */
737 static unsigned char se90pci_eeprom[] = {
738 [ICE_EEP2_SYSCONF] = 0x4b, /* 49.152Hz, spdif-in/ADC, 4DACs */
739 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
740 [ICE_EEP2_I2S] = 0x78, /* 96k-ok, 24bit, 192k-ok */
741 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
743 /* ALL GPIO bits are in input mode */
746 struct snd_ice1712_card_info snd_vt1724_se_cards[] = {
748 .subvendor = VT1724_SUBDEVICE_SE200PCI,
749 .name = "ONKYO SE200PCI",
750 .model = "se200pci",
751 .chip_init = se_init,
752 .build_controls = se_add_controls,
753 .eeprom_size = sizeof(se200pci_eeprom),
754 .eeprom_data = se200pci_eeprom,
757 .subvendor = VT1724_SUBDEVICE_SE90PCI,
758 .name = "ONKYO SE90PCI",
759 .model = "se90pci",
760 .chip_init = se_init,
761 .build_controls = se_add_controls,
762 .eeprom_size = sizeof(se90pci_eeprom),
763 .eeprom_data = se90pci_eeprom,
765 {} /*terminator*/