1 /* 2 * ALSA driver for ICEnsemble VT1724 (Envy24HT) 3 * 4 * Lowlevel functions for AudioTrak Prodigy 192 cards 5 * 6 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de> 7 * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca> 8 * Copyright (c) 2004 Kouichi ONO <co2b@ceres.dti.ne.jp> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 * 24 */ 25 26 #include <sound/driver.h> 27 #include <asm/io.h> 28 #include <linux/delay.h> 29 #include <linux/interrupt.h> 30 #include <linux/init.h> 31 #include <linux/slab.h> 32 #include <sound/core.h> 33 34 #include "ice1712.h" 35 #include "envy24ht.h" 36 #include "prodigy192.h" 37 #include "stac946x.h" 38 #include <sound/tlv.h> 39 40 static inline void stac9460_put(struct snd_ice1712 *ice, int reg, unsigned char val) 41 { 42 snd_vt1724_write_i2c(ice, PRODIGY192_STAC9460_ADDR, reg, val); 43 } 44 45 static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg) 46 { 47 return snd_vt1724_read_i2c(ice, PRODIGY192_STAC9460_ADDR, reg); 48 } 49 50 /* 51 * DAC mute control 52 */ 53 static int stac9460_dac_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 54 { 55 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 56 uinfo->count = 1; 57 uinfo->value.integer.min = 0; 58 uinfo->value.integer.max = 1; 59 return 0; 60 } 61 62 static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 63 { 64 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 65 unsigned char val; 66 int idx; 67 68 if (kcontrol->private_value) 69 idx = STAC946X_MASTER_VOLUME; 70 else 71 idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME; 72 val = stac9460_get(ice, idx); 73 ucontrol->value.integer.value[0] = (~val >> 7) & 0x1; 74 return 0; 75 } 76 77 static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 78 { 79 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 80 unsigned char new, old; 81 int idx; 82 int change; 83 84 if (kcontrol->private_value) 85 idx = STAC946X_MASTER_VOLUME; 86 else 87 idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME; 88 old = stac9460_get(ice, idx); 89 new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) | (old & ~0x80); 90 change = (new != old); 91 if (change) 92 stac9460_put(ice, idx, new); 93 94 return change; 95 } 96 97 /* 98 * DAC volume attenuation mixer control 99 */ 100 static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 101 { 102 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 103 uinfo->count = 1; 104 uinfo->value.integer.min = 0; /* mute */ 105 uinfo->value.integer.max = 0x7f; /* 0dB */ 106 return 0; 107 } 108 109 static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 110 { 111 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 112 int idx; 113 unsigned char vol; 114 115 if (kcontrol->private_value) 116 idx = STAC946X_MASTER_VOLUME; 117 else 118 idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME; 119 vol = stac9460_get(ice, idx) & 0x7f; 120 ucontrol->value.integer.value[0] = 0x7f - vol; 121 122 return 0; 123 } 124 125 static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 126 { 127 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 128 int idx; 129 unsigned char tmp, ovol, nvol; 130 int change; 131 132 if (kcontrol->private_value) 133 idx = STAC946X_MASTER_VOLUME; 134 else 135 idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME; 136 nvol = ucontrol->value.integer.value[0]; 137 tmp = stac9460_get(ice, idx); 138 ovol = 0x7f - (tmp & 0x7f); 139 change = (ovol != nvol); 140 if (change) { 141 stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); 142 } 143 return change; 144 } 145 146 /* 147 * ADC mute control 148 */ 149 static int stac9460_adc_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 150 { 151 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 152 uinfo->count = 2; 153 uinfo->value.integer.min = 0; 154 uinfo->value.integer.max = 1; 155 return 0; 156 } 157 158 static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 159 { 160 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 161 unsigned char val; 162 int i; 163 164 for (i = 0; i < 2; ++i) { 165 val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i); 166 ucontrol->value.integer.value[i] = ~val>>7 & 0x1; 167 } 168 169 return 0; 170 } 171 172 static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 173 { 174 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 175 unsigned char new, old; 176 int i, reg; 177 int change; 178 179 for (i = 0; i < 2; ++i) { 180 reg = STAC946X_MIC_L_VOLUME + i; 181 old = stac9460_get(ice, reg); 182 new = (~ucontrol->value.integer.value[i]<<7&0x80) | (old&~0x80); 183 change = (new != old); 184 if (change) 185 stac9460_put(ice, reg, new); 186 } 187 188 return change; 189 } 190 191 /* 192 * ADC gain mixer control 193 */ 194 static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 195 { 196 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 197 uinfo->count = 2; 198 uinfo->value.integer.min = 0; /* 0dB */ 199 uinfo->value.integer.max = 0x0f; /* 22.5dB */ 200 return 0; 201 } 202 203 static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 204 { 205 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 206 int i, reg; 207 unsigned char vol; 208 209 for (i = 0; i < 2; ++i) { 210 reg = STAC946X_MIC_L_VOLUME + i; 211 vol = stac9460_get(ice, reg) & 0x0f; 212 ucontrol->value.integer.value[i] = 0x0f - vol; 213 } 214 215 return 0; 216 } 217 218 static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 219 { 220 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 221 int i, reg; 222 unsigned char ovol, nvol; 223 int change; 224 225 for (i = 0; i < 2; ++i) { 226 reg = STAC946X_MIC_L_VOLUME + i; 227 nvol = ucontrol->value.integer.value[i]; 228 ovol = 0x0f - stac9460_get(ice, reg); 229 change = ((ovol & 0x0f) != nvol); 230 if (change) 231 stac9460_put(ice, reg, (0x0f - nvol) | (ovol & ~0x0f)); 232 } 233 234 return change; 235 } 236 237 #if 0 238 /* 239 * Headphone Amplifier 240 */ 241 static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable) 242 { 243 unsigned int tmp, tmp2; 244 245 tmp2 = tmp = snd_ice1712_gpio_read(ice); 246 if (enable) 247 tmp |= AUREON_HP_SEL; 248 else 249 tmp &= ~ AUREON_HP_SEL; 250 if (tmp != tmp2) { 251 snd_ice1712_gpio_write(ice, tmp); 252 return 1; 253 } 254 return 0; 255 } 256 257 static int aureon_get_headphone_amp(struct snd_ice1712 *ice) 258 { 259 unsigned int tmp = snd_ice1712_gpio_read(ice); 260 261 return ( tmp & AUREON_HP_SEL )!= 0; 262 } 263 264 static int aureon_bool_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo) 265 { 266 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 267 uinfo->count = 1; 268 uinfo->value.integer.min = 0; 269 uinfo->value.integer.max = 1; 270 return 0; 271 } 272 273 static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 274 { 275 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 276 277 ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice); 278 return 0; 279 } 280 281 282 static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 283 { 284 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 285 286 return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]); 287 } 288 289 /* 290 * Deemphasis 291 */ 292 static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 293 { 294 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 295 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf; 296 return 0; 297 } 298 299 static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 300 { 301 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 302 int temp, temp2; 303 temp2 = temp = wm_get(ice, WM_DAC_CTRL2); 304 if (ucontrol->value.integer.value[0]) 305 temp |= 0xf; 306 else 307 temp &= ~0xf; 308 if (temp != temp2) { 309 wm_put(ice, WM_DAC_CTRL2, temp); 310 return 1; 311 } 312 return 0; 313 } 314 315 /* 316 * ADC Oversampling 317 */ 318 static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo) 319 { 320 static char *texts[2] = { "128x", "64x" }; 321 322 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 323 uinfo->count = 1; 324 uinfo->value.enumerated.items = 2; 325 326 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 327 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 328 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 329 330 return 0; 331 } 332 333 static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 334 { 335 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 336 ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8; 337 return 0; 338 } 339 340 static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 341 { 342 int temp, temp2; 343 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 344 345 temp2 = temp = wm_get(ice, WM_MASTER); 346 347 if (ucontrol->value.enumerated.item[0]) 348 temp |= 0x8; 349 else 350 temp &= ~0x8; 351 352 if (temp != temp2) { 353 wm_put(ice, WM_MASTER, temp); 354 return 1; 355 } 356 return 0; 357 } 358 #endif 359 360 static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0); 361 static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); 362 363 /* 364 * mixers 365 */ 366 367 static const struct snd_kcontrol_new stac_controls[] __devinitdata = { 368 { 369 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 370 .name = "Master Playback Switch", 371 .info = stac9460_dac_mute_info, 372 .get = stac9460_dac_mute_get, 373 .put = stac9460_dac_mute_put, 374 .private_value = 1, 375 .tlv = { .p = db_scale_dac } 376 }, 377 { 378 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 379 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 380 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 381 .name = "Master Playback Volume", 382 .info = stac9460_dac_vol_info, 383 .get = stac9460_dac_vol_get, 384 .put = stac9460_dac_vol_put, 385 .private_value = 1, 386 .tlv = { .p = db_scale_dac } 387 }, 388 { 389 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 390 .name = "DAC Switch", 391 .count = 6, 392 .info = stac9460_dac_mute_info, 393 .get = stac9460_dac_mute_get, 394 .put = stac9460_dac_mute_put, 395 }, 396 { 397 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 398 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 399 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 400 .name = "DAC Volume", 401 .count = 6, 402 .info = stac9460_dac_vol_info, 403 .get = stac9460_dac_vol_get, 404 .put = stac9460_dac_vol_put, 405 .tlv = { .p = db_scale_dac } 406 }, 407 { 408 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 409 .name = "ADC Switch", 410 .count = 1, 411 .info = stac9460_adc_mute_info, 412 .get = stac9460_adc_mute_get, 413 .put = stac9460_adc_mute_put, 414 415 }, 416 { 417 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 418 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 419 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 420 .name = "ADC Volume", 421 .count = 1, 422 .info = stac9460_adc_vol_info, 423 .get = stac9460_adc_vol_get, 424 .put = stac9460_adc_vol_put, 425 .tlv = { .p = db_scale_adc } 426 }, 427 #if 0 428 { 429 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 430 .name = "Capture Route", 431 .info = wm_adc_mux_info, 432 .get = wm_adc_mux_get, 433 .put = wm_adc_mux_put, 434 }, 435 { 436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 437 .name = "Headphone Amplifier Switch", 438 .info = aureon_bool_info, 439 .get = aureon_hpamp_get, 440 .put = aureon_hpamp_put 441 }, 442 { 443 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 444 .name = "DAC Deemphasis Switch", 445 .info = aureon_bool_info, 446 .get = aureon_deemp_get, 447 .put = aureon_deemp_put 448 }, 449 { 450 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 451 .name = "ADC Oversampling", 452 .info = aureon_oversampling_info, 453 .get = aureon_oversampling_get, 454 .put = aureon_oversampling_put 455 }, 456 #endif 457 }; 458 459 static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice) 460 { 461 unsigned int i; 462 int err; 463 464 for (i = 0; i < ARRAY_SIZE(stac_controls); i++) { 465 err = snd_ctl_add(ice->card, snd_ctl_new1(&stac_controls[i], ice)); 466 if (err < 0) 467 return err; 468 } 469 return 0; 470 } 471 472 473 /* 474 * initialize the chip 475 */ 476 static int __devinit prodigy192_init(struct snd_ice1712 *ice) 477 { 478 static const unsigned short stac_inits_prodigy[] = { 479 STAC946X_RESET, 0, 480 /* STAC946X_MASTER_VOLUME, 0, 481 STAC946X_LF_VOLUME, 0, 482 STAC946X_RF_VOLUME, 0, 483 STAC946X_LR_VOLUME, 0, 484 STAC946X_RR_VOLUME, 0, 485 STAC946X_CENTER_VOLUME, 0, 486 STAC946X_LFE_VOLUME, 0,*/ 487 (unsigned short)-1 488 }; 489 const unsigned short *p; 490 491 /* prodigy 192 */ 492 ice->num_total_dacs = 6; 493 ice->num_total_adcs = 2; 494 495 /* initialize codec */ 496 p = stac_inits_prodigy; 497 for (; *p != (unsigned short)-1; p += 2) 498 stac9460_put(ice, p[0], p[1]); 499 500 return 0; 501 } 502 503 504 /* 505 * Aureon boards don't provide the EEPROM data except for the vendor IDs. 506 * hence the driver needs to sets up it properly. 507 */ 508 509 static const unsigned char prodigy71_eeprom[] __devinitdata = { 510 [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC, 4DACs */ 511 [ICE_EEP2_ACLINK] = 0x80, /* I2S */ 512 [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ 513 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ 514 [ICE_EEP2_GPIO_DIR] = 0xff, 515 [ICE_EEP2_GPIO_DIR1] = 0xff, 516 [ICE_EEP2_GPIO_DIR2] = 0xbf, 517 [ICE_EEP2_GPIO_MASK] = 0x00, 518 [ICE_EEP2_GPIO_MASK1] = 0x00, 519 [ICE_EEP2_GPIO_MASK2] = 0x00, 520 [ICE_EEP2_GPIO_STATE] = 0x00, 521 [ICE_EEP2_GPIO_STATE1] = 0x00, 522 [ICE_EEP2_GPIO_STATE2] = 0x00, 523 }; 524 525 526 /* entry point */ 527 const struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = { 528 { 529 .subvendor = VT1724_SUBDEVICE_PRODIGY192VE, 530 .name = "Audiotrak Prodigy 192", 531 .model = "prodigy192", 532 .chip_init = prodigy192_init, 533 .build_controls = prodigy192_add_controls, 534 .eeprom_size = sizeof(prodigy71_eeprom), 535 .eeprom_data = prodigy71_eeprom, 536 }, 537 { } /* terminator */ 538 }; 539