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