1 /* 2 * ALSA driver for ICEnsemble VT1724 (Envy24HT) 3 * 4 * Lowlevel functions for ONKYO WAVIO SE-90PCI and SE-200PCI 5 * 6 * Copyright (c) 2007 Shin-ya Okada sh_okada(at)d4.dion.ne.jp 7 * (at) -> @ 8 * 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. 13 * 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. 18 * 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 22 * 23 */ 24 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> 31 32 #include "ice1712.h" 33 #include "envy24ht.h" 34 #include "se.h" 35 36 struct se_spec { 37 struct { 38 unsigned char ch1, ch2; 39 } vol[8]; 40 }; 41 42 /****************************************************************************/ 43 /* ONKYO WAVIO SE-200PCI */ 44 /****************************************************************************/ 45 /* 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 51 * 52 * AC-Link configuration ICE_EEP2_ACLINK=0x80 53 * use I2C, not use AC97 54 * 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 59 * 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 65 * 66 * 67 * ** connected chips ** 68 * 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. 82 * 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 90 * 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 98 * 99 * 100 * ** output pins and device names ** 101 * 102 * 7.1ch name -- output connector color -- device (-D option) 103 * 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 108 * 109 */ 110 111 112 /****************************************************************************/ 113 /* WM8740 interface */ 114 /****************************************************************************/ 115 116 static void se200pci_WM8740_init(struct snd_ice1712 *ice) 117 { 118 /* nothing to do */ 119 } 120 121 122 static void se200pci_WM8740_set_pro_rate(struct snd_ice1712 *ice, 123 unsigned int rate) 124 { 125 /* nothing to do */ 126 } 127 128 129 /****************************************************************************/ 130 /* WM8766 interface */ 131 /****************************************************************************/ 132 133 static void se200pci_WM8766_write(struct snd_ice1712 *ice, 134 unsigned int addr, unsigned int data) 135 { 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); 143 144 snd_ice1712_save_gpio_status(ice); 145 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; 150 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; 160 161 snd_ice1712_gpio_write(ice, bits); 162 163 udelay(1); 164 bits |= CLOCK; 165 snd_ice1712_gpio_write(ice, bits); 166 } 167 168 udelay(1); 169 bits |= LOAD; 170 snd_ice1712_gpio_write(ice, bits); 171 172 udelay(1); 173 bits |= (DATA | CLOCK); 174 snd_ice1712_gpio_write(ice, bits); 175 176 snd_ice1712_restore_gpio_status(ice); 177 } 178 179 static void se200pci_WM8766_set_volume(struct snd_ice1712 *ice, int ch, 180 unsigned int vol1, unsigned int vol2) 181 { 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; 195 } 196 } 197 198 static void se200pci_WM8766_init(struct snd_ice1712 *ice) 199 { 200 se200pci_WM8766_write(ice, 0x1f, 0x000); /* RESET ALL */ 201 udelay(10); 202 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 */ 206 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 */ 212 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 */ 215 } 216 217 static void se200pci_WM8766_set_pro_rate(struct snd_ice1712 *ice, 218 unsigned int rate) 219 { 220 if (rate > 96000) 221 se200pci_WM8766_write(ice, 0x0a, 0x000); /* MCLK=128fs */ 222 else 223 se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */ 224 } 225 226 227 /****************************************************************************/ 228 /* WM8776 interface */ 229 /****************************************************************************/ 230 231 static void se200pci_WM8776_write(struct snd_ice1712 *ice, 232 unsigned int addr, unsigned int data) 233 { 234 unsigned int val; 235 236 val = (addr << 9) | data; 237 snd_vt1724_write_i2c(ice, 0x34, val >> 8, val & 0xff); 238 } 239 240 241 static void se200pci_WM8776_set_output_volume(struct snd_ice1712 *ice, 242 unsigned int vol1, unsigned int vol2) 243 { 244 se200pci_WM8776_write(ice, 0x03, vol1); 245 se200pci_WM8776_write(ice, 0x04, vol2 | 0x100); 246 } 247 248 static void se200pci_WM8776_set_input_volume(struct snd_ice1712 *ice, 249 unsigned int vol1, unsigned int vol2) 250 { 251 se200pci_WM8776_write(ice, 0x0e, vol1); 252 se200pci_WM8776_write(ice, 0x0f, vol2 | 0x100); 253 } 254 255 static const char * const se200pci_sel[] = { 256 "LINE-IN", "CD-IN", "MIC-IN", "ALL-MIX", NULL 257 }; 258 259 static void se200pci_WM8776_set_input_selector(struct snd_ice1712 *ice, 260 unsigned int sel) 261 { 262 static unsigned char vals[] = { 263 /* LINE, CD, MIC, ALL, GND */ 264 0x10, 0x04, 0x08, 0x1c, 0x03 265 }; 266 if (sel > 4) 267 sel = 4; 268 se200pci_WM8776_write(ice, 0x15, vals[sel]); 269 } 270 271 static void se200pci_WM8776_set_afl(struct snd_ice1712 *ice, unsigned int afl) 272 { 273 /* AFL -- After Fader Listening */ 274 if (afl) 275 se200pci_WM8776_write(ice, 0x16, 0x005); 276 else 277 se200pci_WM8776_write(ice, 0x16, 0x001); 278 } 279 280 static const char * const se200pci_agc[] = { 281 "Off", "LimiterMode", "ALCMode", NULL 282 }; 283 284 static void se200pci_WM8776_set_agc(struct snd_ice1712 *ice, unsigned int agc) 285 { 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; 299 } 300 } 301 302 static void se200pci_WM8776_init(struct snd_ice1712 *ice) 303 { 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 312 }; 313 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]); 321 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); 327 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); 333 } 334 335 static void se200pci_WM8776_set_pro_rate(struct snd_ice1712 *ice, 336 unsigned int rate) 337 { 338 /* nothing to do */ 339 } 340 341 342 /****************************************************************************/ 343 /* runtime interface */ 344 /****************************************************************************/ 345 346 static void se200pci_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate) 347 { 348 se200pci_WM8740_set_pro_rate(ice, rate); 349 se200pci_WM8766_set_pro_rate(ice, rate); 350 se200pci_WM8776_set_pro_rate(ice, rate); 351 } 352 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; 367 }; 368 369 static const struct se200pci_control se200pci_cont[] = { 370 { 371 .name = "Front Playback Volume", 372 .target = WM8776out, 373 .type = VOLUME1, 374 .comment = "Front(green)" 375 }, 376 { 377 .name = "Side Playback Volume", 378 .target = WM8766, 379 .type = VOLUME1, 380 .ch = 1, 381 .comment = "Surround(orange)" 382 }, 383 { 384 .name = "Surround Playback Volume", 385 .target = WM8766, 386 .type = VOLUME1, 387 .ch = 2, 388 .comment = "SurroundBack(white)" 389 }, 390 { 391 .name = "CLFE Playback Volume", 392 .target = WM8766, 393 .type = VOLUME1, 394 .ch = 0, 395 .comment = "Center(Lch)&SubWoofer(Rch)(black)" 396 }, 397 { 398 .name = "Capture Volume", 399 .target = WM8776in, 400 .type = VOLUME2 401 }, 402 { 403 .name = "Capture Select", 404 .target = WM8776sel, 405 .type = ENUM, 406 .member = se200pci_sel 407 }, 408 { 409 .name = "AGC Capture Mode", 410 .target = WM8776agc, 411 .type = ENUM, 412 .member = se200pci_agc 413 }, 414 { 415 .name = "AFL Bypass Playback Switch", 416 .target = WM8776afl, 417 .type = BOOLEAN 418 } 419 }; 420 421 static int se200pci_get_enum_count(int n) 422 { 423 const char * const *member; 424 int c; 425 426 member = se200pci_cont[n].member; 427 if (!member) 428 return 0; 429 for (c = 0; member[c]; c++) 430 ; 431 return c; 432 } 433 434 static int se200pci_cont_volume_info(struct snd_kcontrol *kc, 435 struct snd_ctl_elem_info *uinfo) 436 { 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; 442 } 443 444 #define se200pci_cont_boolean_info snd_ctl_boolean_mono_info 445 446 static int se200pci_cont_enum_info(struct snd_kcontrol *kc, 447 struct snd_ctl_elem_info *uinfo) 448 { 449 int n, c; 450 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); 456 } 457 458 static int se200pci_cont_volume_get(struct snd_kcontrol *kc, 459 struct snd_ctl_elem_value *uc) 460 { 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; 467 } 468 469 static int se200pci_cont_boolean_get(struct snd_kcontrol *kc, 470 struct snd_ctl_elem_value *uc) 471 { 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; 477 } 478 479 static int se200pci_cont_enum_get(struct snd_kcontrol *kc, 480 struct snd_ctl_elem_value *uc) 481 { 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; 487 } 488 489 static void se200pci_cont_update(struct snd_ice1712 *ice, int n) 490 { 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; 499 500 case WM8776in: 501 se200pci_WM8776_set_input_volume(ice, 502 spec->vol[n].ch1, 503 spec->vol[n].ch2); 504 break; 505 506 case WM8776out: 507 se200pci_WM8776_set_output_volume(ice, 508 spec->vol[n].ch1, 509 spec->vol[n].ch2); 510 break; 511 512 case WM8776sel: 513 se200pci_WM8776_set_input_selector(ice, 514 spec->vol[n].ch1); 515 break; 516 517 case WM8776agc: 518 se200pci_WM8776_set_agc(ice, spec->vol[n].ch1); 519 break; 520 521 case WM8776afl: 522 se200pci_WM8776_set_afl(ice, spec->vol[n].ch1); 523 break; 524 525 default: 526 break; 527 } 528 } 529 530 static int se200pci_cont_volume_put(struct snd_kcontrol *kc, 531 struct snd_ctl_elem_value *uc) 532 { 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; 538 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; 545 } 546 if (spec->vol[n].ch2 != vol2) { 547 spec->vol[n].ch2 = vol2; 548 changed = 1; 549 } 550 if (changed) 551 se200pci_cont_update(ice, n); 552 553 return changed; 554 } 555 556 static int se200pci_cont_boolean_put(struct snd_kcontrol *kc, 557 struct snd_ctl_elem_value *uc) 558 { 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; 563 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; 569 } 570 return 0; 571 } 572 573 static int se200pci_cont_enum_put(struct snd_kcontrol *kc, 574 struct snd_ctl_elem_value *uc) 575 { 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; 580 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; 588 } 589 return 0; 590 } 591 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); 594 595 static int se200pci_add_controls(struct snd_ice1712 *ice) 596 { 597 int i; 598 struct snd_kcontrol_new cont; 599 int err; 600 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; 633 } 634 err = snd_ctl_add(ice->card, snd_ctl_new1(&cont, ice)); 635 if (err < 0) 636 return err; 637 } 638 639 return 0; 640 } 641 642 643 /****************************************************************************/ 644 /* ONKYO WAVIO SE-90PCI */ 645 /****************************************************************************/ 646 /* 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 651 * 652 * ** connected chip ** 653 * 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 663 * 664 */ 665 666 /* Nothing to do for this chip. */ 667 668 669 /****************************************************************************/ 670 /* probe/initialize/setup */ 671 /****************************************************************************/ 672 673 static int se_init(struct snd_ice1712 *ice) 674 { 675 struct se_spec *spec; 676 677 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 678 if (!spec) 679 return -ENOMEM; 680 ice->spec = spec; 681 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; 687 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; 696 } 697 698 return -ENOENT; 699 } 700 701 static int se_add_controls(struct snd_ice1712 *ice) 702 { 703 int err; 704 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); 709 710 return err; 711 } 712 713 714 /****************************************************************************/ 715 /* entry point */ 716 /****************************************************************************/ 717 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 */ 723 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 */ 727 728 [ICE_EEP2_GPIO_MASK] = 0x00, /* 0=writable */ 729 [ICE_EEP2_GPIO_MASK1] = 0x00, /* 0=writable */ 730 [ICE_EEP2_GPIO_MASK2] = 0x00, /* 0=writable */ 731 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 */ 735 }; 736 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 */ 742 743 /* ALL GPIO bits are in input mode */ 744 }; 745 746 struct snd_ice1712_card_info snd_vt1724_se_cards[] = { 747 { 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, 755 }, 756 { 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, 764 }, 765 {} /*terminator*/ 766 }; 767