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