1 /* 2 * ALSA driver for ICEnsemble VT1724 (Envy24HT) 3 * 4 * Lowlevel functions for Ego Sys Waveterminal 192M 5 * 6 * Copyright (c) 2006 Guedez Clement <klem.dev@gmail.com> 7 * Some functions are taken from the Prodigy192 driver 8 * source 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 27 28 #include <linux/delay.h> 29 #include <linux/interrupt.h> 30 #include <linux/init.h> 31 #include <sound/core.h> 32 #include <sound/tlv.h> 33 #include <linux/slab.h> 34 35 #include "ice1712.h" 36 #include "envy24ht.h" 37 #include "wtm.h" 38 #include "stac946x.h" 39 40 struct wtm_spec { 41 /* rate change needs atomic mute/unmute of all dacs*/ 42 struct mutex mute_mutex; 43 }; 44 45 46 /* 47 * 2*ADC 6*DAC no1 ringbuffer r/w on i2c bus 48 */ 49 static inline void stac9460_put(struct snd_ice1712 *ice, int reg, 50 unsigned char val) 51 { 52 snd_vt1724_write_i2c(ice, STAC9460_I2C_ADDR, reg, val); 53 } 54 55 static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg) 56 { 57 return snd_vt1724_read_i2c(ice, STAC9460_I2C_ADDR, reg); 58 } 59 60 /* 61 * 2*ADC 2*DAC no2 ringbuffer r/w on i2c bus 62 */ 63 static inline void stac9460_2_put(struct snd_ice1712 *ice, int reg, 64 unsigned char val) 65 { 66 snd_vt1724_write_i2c(ice, STAC9460_2_I2C_ADDR, reg, val); 67 } 68 69 static inline unsigned char stac9460_2_get(struct snd_ice1712 *ice, int reg) 70 { 71 return snd_vt1724_read_i2c(ice, STAC9460_2_I2C_ADDR, reg); 72 } 73 74 75 /* 76 * DAC mute control 77 */ 78 static void stac9460_dac_mute_all(struct snd_ice1712 *ice, unsigned char mute, 79 unsigned short int *change_mask) 80 { 81 unsigned char new, old; 82 int id, idx, change; 83 84 /*stac9460 1*/ 85 for (id = 0; id < 7; id++) { 86 if (*change_mask & (0x01 << id)) { 87 if (id == 0) 88 idx = STAC946X_MASTER_VOLUME; 89 else 90 idx = STAC946X_LF_VOLUME - 1 + id; 91 old = stac9460_get(ice, idx); 92 new = (~mute << 7 & 0x80) | (old & ~0x80); 93 change = (new != old); 94 if (change) { 95 stac9460_put(ice, idx, new); 96 *change_mask = *change_mask | (0x01 << id); 97 } else { 98 *change_mask = *change_mask & ~(0x01 << id); 99 } 100 } 101 } 102 103 /*stac9460 2*/ 104 for (id = 0; id < 3; id++) { 105 if (*change_mask & (0x01 << (id + 7))) { 106 if (id == 0) 107 idx = STAC946X_MASTER_VOLUME; 108 else 109 idx = STAC946X_LF_VOLUME - 1 + id; 110 old = stac9460_2_get(ice, idx); 111 new = (~mute << 7 & 0x80) | (old & ~0x80); 112 change = (new != old); 113 if (change) { 114 stac9460_2_put(ice, idx, new); 115 *change_mask = *change_mask | (0x01 << id); 116 } else { 117 *change_mask = *change_mask & ~(0x01 << id); 118 } 119 } 120 } 121 } 122 123 124 125 #define stac9460_dac_mute_info snd_ctl_boolean_mono_info 126 127 static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, 128 struct snd_ctl_elem_value *ucontrol) 129 { 130 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 131 struct wtm_spec *spec = ice->spec; 132 unsigned char val; 133 int idx, id; 134 135 mutex_lock(&spec->mute_mutex); 136 137 if (kcontrol->private_value) { 138 idx = STAC946X_MASTER_VOLUME; 139 id = 0; 140 } else { 141 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 142 idx = id + STAC946X_LF_VOLUME; 143 } 144 if (id < 6) 145 val = stac9460_get(ice, idx); 146 else 147 val = stac9460_2_get(ice, idx - 6); 148 ucontrol->value.integer.value[0] = (~val >> 7) & 0x1; 149 150 mutex_unlock(&spec->mute_mutex); 151 return 0; 152 } 153 154 static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, 155 struct snd_ctl_elem_value *ucontrol) 156 { 157 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 158 unsigned char new, old; 159 int id, idx; 160 int change; 161 162 if (kcontrol->private_value) { 163 idx = STAC946X_MASTER_VOLUME; 164 old = stac9460_get(ice, idx); 165 new = (~ucontrol->value.integer.value[0] << 7 & 0x80) | 166 (old & ~0x80); 167 change = (new != old); 168 if (change) { 169 stac9460_put(ice, idx, new); 170 stac9460_2_put(ice, idx, new); 171 } 172 } else { 173 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 174 idx = id + STAC946X_LF_VOLUME; 175 if (id < 6) 176 old = stac9460_get(ice, idx); 177 else 178 old = stac9460_2_get(ice, idx - 6); 179 new = (~ucontrol->value.integer.value[0] << 7 & 0x80) | 180 (old & ~0x80); 181 change = (new != old); 182 if (change) { 183 if (id < 6) 184 stac9460_put(ice, idx, new); 185 else 186 stac9460_2_put(ice, idx - 6, new); 187 } 188 } 189 return change; 190 } 191 192 /* 193 * DAC volume attenuation mixer control 194 */ 195 static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol, 196 struct snd_ctl_elem_info *uinfo) 197 { 198 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 199 uinfo->count = 1; 200 uinfo->value.integer.min = 0; /* mute */ 201 uinfo->value.integer.max = 0x7f; /* 0dB */ 202 return 0; 203 } 204 205 static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol, 206 struct snd_ctl_elem_value *ucontrol) 207 { 208 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 209 int idx, id; 210 unsigned char vol; 211 212 if (kcontrol->private_value) { 213 idx = STAC946X_MASTER_VOLUME; 214 id = 0; 215 } else { 216 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 217 idx = id + STAC946X_LF_VOLUME; 218 } 219 if (id < 6) 220 vol = stac9460_get(ice, idx) & 0x7f; 221 else 222 vol = stac9460_2_get(ice, idx - 6) & 0x7f; 223 ucontrol->value.integer.value[0] = 0x7f - vol; 224 return 0; 225 } 226 227 static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, 228 struct snd_ctl_elem_value *ucontrol) 229 { 230 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 231 int idx, id; 232 unsigned char tmp, ovol, nvol; 233 int change; 234 235 if (kcontrol->private_value) { 236 idx = STAC946X_MASTER_VOLUME; 237 nvol = ucontrol->value.integer.value[0] & 0x7f; 238 tmp = stac9460_get(ice, idx); 239 ovol = 0x7f - (tmp & 0x7f); 240 change = (ovol != nvol); 241 if (change) { 242 stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); 243 stac9460_2_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); 244 } 245 } else { 246 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 247 idx = id + STAC946X_LF_VOLUME; 248 nvol = ucontrol->value.integer.value[0] & 0x7f; 249 if (id < 6) 250 tmp = stac9460_get(ice, idx); 251 else 252 tmp = stac9460_2_get(ice, idx - 6); 253 ovol = 0x7f - (tmp & 0x7f); 254 change = (ovol != nvol); 255 if (change) { 256 if (id < 6) 257 stac9460_put(ice, idx, (0x7f - nvol) | 258 (tmp & 0x80)); 259 else 260 stac9460_2_put(ice, idx-6, (0x7f - nvol) | 261 (tmp & 0x80)); 262 } 263 } 264 return change; 265 } 266 267 /* 268 * ADC mute control 269 */ 270 #define stac9460_adc_mute_info snd_ctl_boolean_stereo_info 271 272 static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol, 273 struct snd_ctl_elem_value *ucontrol) 274 { 275 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 276 unsigned char val; 277 int i, id; 278 279 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 280 if (id == 0) { 281 for (i = 0; i < 2; ++i) { 282 val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i); 283 ucontrol->value.integer.value[i] = ~val>>7 & 0x1; 284 } 285 } else { 286 for (i = 0; i < 2; ++i) { 287 val = stac9460_2_get(ice, STAC946X_MIC_L_VOLUME + i); 288 ucontrol->value.integer.value[i] = ~val>>7 & 0x1; 289 } 290 } 291 return 0; 292 } 293 294 static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol, 295 struct snd_ctl_elem_value *ucontrol) 296 { 297 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 298 unsigned char new, old; 299 int i, reg, id; 300 int change; 301 302 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 303 if (id == 0) { 304 for (i = 0; i < 2; ++i) { 305 reg = STAC946X_MIC_L_VOLUME + i; 306 old = stac9460_get(ice, reg); 307 new = (~ucontrol->value.integer.value[i]<<7&0x80) | 308 (old&~0x80); 309 change = (new != old); 310 if (change) 311 stac9460_put(ice, reg, new); 312 } 313 } else { 314 for (i = 0; i < 2; ++i) { 315 reg = STAC946X_MIC_L_VOLUME + i; 316 old = stac9460_2_get(ice, reg); 317 new = (~ucontrol->value.integer.value[i]<<7&0x80) | 318 (old&~0x80); 319 change = (new != old); 320 if (change) 321 stac9460_2_put(ice, reg, new); 322 } 323 } 324 return change; 325 } 326 327 /* 328 *ADC gain mixer control 329 */ 330 static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol, 331 struct snd_ctl_elem_info *uinfo) 332 { 333 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 334 uinfo->count = 2; 335 uinfo->value.integer.min = 0; /* 0dB */ 336 uinfo->value.integer.max = 0x0f; /* 22.5dB */ 337 return 0; 338 } 339 340 static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol, 341 struct snd_ctl_elem_value *ucontrol) 342 { 343 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 344 int i, reg, id; 345 unsigned char vol; 346 347 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 348 if (id == 0) { 349 for (i = 0; i < 2; ++i) { 350 reg = STAC946X_MIC_L_VOLUME + i; 351 vol = stac9460_get(ice, reg) & 0x0f; 352 ucontrol->value.integer.value[i] = 0x0f - vol; 353 } 354 } else { 355 for (i = 0; i < 2; ++i) { 356 reg = STAC946X_MIC_L_VOLUME + i; 357 vol = stac9460_2_get(ice, reg) & 0x0f; 358 ucontrol->value.integer.value[i] = 0x0f - vol; 359 } 360 } 361 return 0; 362 } 363 364 static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, 365 struct snd_ctl_elem_value *ucontrol) 366 { 367 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 368 int i, reg, id; 369 unsigned char ovol, nvol; 370 int change; 371 372 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 373 if (id == 0) { 374 for (i = 0; i < 2; ++i) { 375 reg = STAC946X_MIC_L_VOLUME + i; 376 nvol = ucontrol->value.integer.value[i] & 0x0f; 377 ovol = 0x0f - stac9460_get(ice, reg); 378 change = ((ovol & 0x0f) != nvol); 379 if (change) 380 stac9460_put(ice, reg, (0x0f - nvol) | 381 (ovol & ~0x0f)); 382 } 383 } else { 384 for (i = 0; i < 2; ++i) { 385 reg = STAC946X_MIC_L_VOLUME + i; 386 nvol = ucontrol->value.integer.value[i] & 0x0f; 387 ovol = 0x0f - stac9460_2_get(ice, reg); 388 change = ((ovol & 0x0f) != nvol); 389 if (change) 390 stac9460_2_put(ice, reg, (0x0f - nvol) | 391 (ovol & ~0x0f)); 392 } 393 } 394 return change; 395 } 396 397 /* 398 * MIC / LINE switch fonction 399 */ 400 static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol, 401 struct snd_ctl_elem_info *uinfo) 402 { 403 static const char * const texts[2] = { "Line In", "Mic" }; 404 405 return snd_ctl_enum_info(uinfo, 1, 2, texts); 406 } 407 408 409 static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol, 410 struct snd_ctl_elem_value *ucontrol) 411 { 412 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 413 unsigned char val; 414 int id; 415 416 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 417 if (id == 0) 418 val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); 419 else 420 val = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE); 421 ucontrol->value.enumerated.item[0] = (val >> 7) & 0x1; 422 return 0; 423 } 424 425 static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol, 426 struct snd_ctl_elem_value *ucontrol) 427 { 428 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 429 unsigned char new, old; 430 int change, id; 431 432 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 433 if (id == 0) 434 old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); 435 else 436 old = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE); 437 new = (ucontrol->value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80); 438 change = (new != old); 439 if (change) { 440 if (id == 0) 441 stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new); 442 else 443 stac9460_2_put(ice, STAC946X_GENERAL_PURPOSE, new); 444 } 445 return change; 446 } 447 448 449 /* 450 * Handler for setting correct codec rate - called when rate change is detected 451 */ 452 static void stac9460_set_rate_val(struct snd_ice1712 *ice, unsigned int rate) 453 { 454 unsigned char old, new; 455 unsigned short int changed; 456 struct wtm_spec *spec = ice->spec; 457 458 if (rate == 0) /* no hint - S/PDIF input is master, simply return */ 459 return; 460 else if (rate <= 48000) 461 new = 0x08; /* 256x, base rate mode */ 462 else if (rate <= 96000) 463 new = 0x11; /* 256x, mid rate mode */ 464 else 465 new = 0x12; /* 128x, high rate mode */ 466 467 old = stac9460_get(ice, STAC946X_MASTER_CLOCKING); 468 if (old == new) 469 return; 470 /* change detected, setting master clock, muting first */ 471 /* due to possible conflicts with mute controls - mutexing */ 472 mutex_lock(&spec->mute_mutex); 473 /* we have to remember current mute status for each DAC */ 474 changed = 0xFFFF; 475 stac9460_dac_mute_all(ice, 0, &changed); 476 /*printk(KERN_DEBUG "Rate change: %d, new MC: 0x%02x\n", rate, new);*/ 477 stac9460_put(ice, STAC946X_MASTER_CLOCKING, new); 478 stac9460_2_put(ice, STAC946X_MASTER_CLOCKING, new); 479 udelay(10); 480 /* unmuting - only originally unmuted dacs - 481 * i.e. those changed when muting */ 482 stac9460_dac_mute_all(ice, 1, &changed); 483 mutex_unlock(&spec->mute_mutex); 484 } 485 486 487 /*Limits value in dB for fader*/ 488 static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0); 489 static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); 490 491 /* 492 * Control tabs 493 */ 494 static struct snd_kcontrol_new stac9640_controls[] = { 495 { 496 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 497 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 498 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 499 .name = "Master Playback Switch", 500 .info = stac9460_dac_mute_info, 501 .get = stac9460_dac_mute_get, 502 .put = stac9460_dac_mute_put, 503 .private_value = 1, 504 .tlv = { .p = db_scale_dac } 505 }, 506 { 507 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 508 .name = "Master Playback Volume", 509 .info = stac9460_dac_vol_info, 510 .get = stac9460_dac_vol_get, 511 .put = stac9460_dac_vol_put, 512 .private_value = 1, 513 }, 514 { 515 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 516 .name = "MIC/Line Input Enum", 517 .count = 2, 518 .info = stac9460_mic_sw_info, 519 .get = stac9460_mic_sw_get, 520 .put = stac9460_mic_sw_put, 521 522 }, 523 { 524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 525 .name = "DAC Switch", 526 .count = 8, 527 .info = stac9460_dac_mute_info, 528 .get = stac9460_dac_mute_get, 529 .put = stac9460_dac_mute_put, 530 }, 531 { 532 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 533 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 534 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 535 536 .name = "DAC Volume", 537 .count = 8, 538 .info = stac9460_dac_vol_info, 539 .get = stac9460_dac_vol_get, 540 .put = stac9460_dac_vol_put, 541 .tlv = { .p = db_scale_dac } 542 }, 543 { 544 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 545 .name = "ADC Switch", 546 .count = 2, 547 .info = stac9460_adc_mute_info, 548 .get = stac9460_adc_mute_get, 549 .put = stac9460_adc_mute_put, 550 }, 551 { 552 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 553 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 554 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 555 556 .name = "ADC Volume", 557 .count = 2, 558 .info = stac9460_adc_vol_info, 559 .get = stac9460_adc_vol_get, 560 .put = stac9460_adc_vol_put, 561 .tlv = { .p = db_scale_adc } 562 } 563 }; 564 565 566 567 /*INIT*/ 568 static int wtm_add_controls(struct snd_ice1712 *ice) 569 { 570 unsigned int i; 571 int err; 572 573 for (i = 0; i < ARRAY_SIZE(stac9640_controls); i++) { 574 err = snd_ctl_add(ice->card, 575 snd_ctl_new1(&stac9640_controls[i], ice)); 576 if (err < 0) 577 return err; 578 } 579 return 0; 580 } 581 582 static int wtm_init(struct snd_ice1712 *ice) 583 { 584 static unsigned short stac_inits_wtm[] = { 585 STAC946X_RESET, 0, 586 STAC946X_MASTER_CLOCKING, 0x11, 587 (unsigned short)-1 588 }; 589 unsigned short *p; 590 struct wtm_spec *spec; 591 592 /*WTM 192M*/ 593 ice->num_total_dacs = 8; 594 ice->num_total_adcs = 4; 595 ice->force_rdma1 = 1; 596 597 /*init mutex for dac mute conflict*/ 598 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 599 if (!spec) 600 return -ENOMEM; 601 ice->spec = spec; 602 mutex_init(&spec->mute_mutex); 603 604 605 /*initialize codec*/ 606 p = stac_inits_wtm; 607 for (; *p != (unsigned short)-1; p += 2) { 608 stac9460_put(ice, p[0], p[1]); 609 stac9460_2_put(ice, p[0], p[1]); 610 } 611 ice->gpio.set_pro_rate = stac9460_set_rate_val; 612 return 0; 613 } 614 615 616 static unsigned char wtm_eeprom[] = { 617 [ICE_EEP2_SYSCONF] = 0x67, /*SYSCONF: clock 192KHz, mpu401, 618 4ADC, 8DAC */ 619 [ICE_EEP2_ACLINK] = 0x80, /* ACLINK : I2S */ 620 [ICE_EEP2_I2S] = 0xf8, /* I2S: vol; 96k, 24bit, 192k */ 621 [ICE_EEP2_SPDIF] = 0xc1, /*SPDIF: out-en, spidf ext out*/ 622 [ICE_EEP2_GPIO_DIR] = 0x9f, 623 [ICE_EEP2_GPIO_DIR1] = 0xff, 624 [ICE_EEP2_GPIO_DIR2] = 0x7f, 625 [ICE_EEP2_GPIO_MASK] = 0x9f, 626 [ICE_EEP2_GPIO_MASK1] = 0xff, 627 [ICE_EEP2_GPIO_MASK2] = 0x7f, 628 [ICE_EEP2_GPIO_STATE] = 0x16, 629 [ICE_EEP2_GPIO_STATE1] = 0x80, 630 [ICE_EEP2_GPIO_STATE2] = 0x00, 631 }; 632 633 634 /*entry point*/ 635 struct snd_ice1712_card_info snd_vt1724_wtm_cards[] = { 636 { 637 .subvendor = VT1724_SUBDEVICE_WTM, 638 .name = "ESI Waveterminal 192M", 639 .model = "WT192M", 640 .chip_init = wtm_init, 641 .build_controls = wtm_add_controls, 642 .eeprom_size = sizeof(wtm_eeprom), 643 .eeprom_data = wtm_eeprom, 644 }, 645 {} /*terminator*/ 646 }; 647