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