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