1/* 2 * card driver for models with WM8776/WM8766 DACs (Xonar DS) 3 * 4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 5 * 6 * 7 * This driver is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License, version 2. 9 * 10 * This driver is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this driver; if not, see <http://www.gnu.org/licenses/>. 17 */ 18 19/* 20 * Xonar DS 21 * -------- 22 * 23 * CMI8788: 24 * 25 * SPI 0 -> WM8766 (surround, center/LFE, back) 26 * SPI 1 -> WM8776 (front, input) 27 * 28 * GPIO 4 <- headphone detect 29 * GPIO 6 -> route input jack to input 1/2 (1/0) 30 * GPIO 7 -> enable output to speakers 31 * GPIO 8 -> enable output to speakers 32 */ 33 34#include <linux/pci.h> 35#include <linux/delay.h> 36#include <sound/control.h> 37#include <sound/core.h> 38#include <sound/pcm.h> 39#include <sound/pcm_params.h> 40#include <sound/tlv.h> 41#include "xonar.h" 42#include "wm8776.h" 43#include "wm8766.h" 44 45#define GPIO_DS_HP_DETECT 0x0010 46#define GPIO_DS_INPUT_ROUTE 0x0040 47#define GPIO_DS_OUTPUT_ENABLE 0x0180 48 49#define LC_CONTROL_LIMITER 0x40000000 50#define LC_CONTROL_ALC 0x20000000 51 52struct xonar_wm87x6 { 53 struct xonar_generic generic; 54 u16 wm8776_regs[0x17]; 55 u16 wm8766_regs[0x10]; 56 struct snd_kcontrol *line_adcmux_control; 57 struct snd_kcontrol *mic_adcmux_control; 58 struct snd_kcontrol *lc_controls[13]; 59}; 60 61static void wm8776_write(struct oxygen *chip, 62 unsigned int reg, unsigned int value) 63{ 64 struct xonar_wm87x6 *data = chip->model_data; 65 66 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | 67 OXYGEN_SPI_DATA_LENGTH_2 | 68 OXYGEN_SPI_CLOCK_160 | 69 (1 << OXYGEN_SPI_CODEC_SHIFT) | 70 OXYGEN_SPI_CEN_LATCH_CLOCK_LO, 71 (reg << 9) | value); 72 if (reg < ARRAY_SIZE(data->wm8776_regs)) { 73 if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER) 74 value &= ~WM8776_UPDATE; 75 data->wm8776_regs[reg] = value; 76 } 77} 78 79static void wm8776_write_cached(struct oxygen *chip, 80 unsigned int reg, unsigned int value) 81{ 82 struct xonar_wm87x6 *data = chip->model_data; 83 84 if (reg >= ARRAY_SIZE(data->wm8776_regs) || 85 value != data->wm8776_regs[reg]) 86 wm8776_write(chip, reg, value); 87} 88 89static void wm8766_write(struct oxygen *chip, 90 unsigned int reg, unsigned int value) 91{ 92 struct xonar_wm87x6 *data = chip->model_data; 93 94 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | 95 OXYGEN_SPI_DATA_LENGTH_2 | 96 OXYGEN_SPI_CLOCK_160 | 97 (0 << OXYGEN_SPI_CODEC_SHIFT) | 98 OXYGEN_SPI_CEN_LATCH_CLOCK_LO, 99 (reg << 9) | value); 100 if (reg < ARRAY_SIZE(data->wm8766_regs)) 101 data->wm8766_regs[reg] = value; 102} 103 104static void wm8766_write_cached(struct oxygen *chip, 105 unsigned int reg, unsigned int value) 106{ 107 struct xonar_wm87x6 *data = chip->model_data; 108 109 if (reg >= ARRAY_SIZE(data->wm8766_regs) || 110 value != data->wm8766_regs[reg]) { 111 if ((reg >= WM8766_LDA1 && reg <= WM8766_RDA1) || 112 (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA)) 113 value &= ~WM8766_UPDATE; 114 wm8766_write(chip, reg, value); 115 } 116} 117 118static void wm8776_registers_init(struct oxygen *chip) 119{ 120 struct xonar_wm87x6 *data = chip->model_data; 121 122 wm8776_write(chip, WM8776_RESET, 0); 123 wm8776_write(chip, WM8776_DACCTRL1, WM8776_DZCEN | 124 WM8776_PL_LEFT_LEFT | WM8776_PL_RIGHT_RIGHT); 125 wm8776_write(chip, WM8776_DACMUTE, chip->dac_mute ? WM8776_DMUTE : 0); 126 wm8776_write(chip, WM8776_DACIFCTRL, 127 WM8776_DACFMT_LJUST | WM8776_DACWL_24); 128 wm8776_write(chip, WM8776_ADCIFCTRL, 129 data->wm8776_regs[WM8776_ADCIFCTRL]); 130 wm8776_write(chip, WM8776_MSTRCTRL, data->wm8776_regs[WM8776_MSTRCTRL]); 131 wm8776_write(chip, WM8776_PWRDOWN, data->wm8776_regs[WM8776_PWRDOWN]); 132 wm8776_write(chip, WM8776_HPLVOL, data->wm8776_regs[WM8776_HPLVOL]); 133 wm8776_write(chip, WM8776_HPRVOL, data->wm8776_regs[WM8776_HPRVOL] | 134 WM8776_UPDATE); 135 wm8776_write(chip, WM8776_ADCLVOL, data->wm8776_regs[WM8776_ADCLVOL]); 136 wm8776_write(chip, WM8776_ADCRVOL, data->wm8776_regs[WM8776_ADCRVOL]); 137 wm8776_write(chip, WM8776_ADCMUX, data->wm8776_regs[WM8776_ADCMUX]); 138 wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0]); 139 wm8776_write(chip, WM8776_DACRVOL, chip->dac_volume[1] | WM8776_UPDATE); 140} 141 142static void wm8766_registers_init(struct oxygen *chip) 143{ 144 wm8766_write(chip, WM8766_RESET, 0); 145 wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24); 146 wm8766_write(chip, WM8766_DAC_CTRL2, 147 WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); 148 wm8766_write(chip, WM8766_LDA1, chip->dac_volume[2]); 149 wm8766_write(chip, WM8766_RDA1, chip->dac_volume[3]); 150 wm8766_write(chip, WM8766_LDA2, chip->dac_volume[4]); 151 wm8766_write(chip, WM8766_RDA2, chip->dac_volume[5]); 152 wm8766_write(chip, WM8766_LDA3, chip->dac_volume[6]); 153 wm8766_write(chip, WM8766_RDA3, chip->dac_volume[7] | WM8766_UPDATE); 154} 155 156static void wm8776_init(struct oxygen *chip) 157{ 158 struct xonar_wm87x6 *data = chip->model_data; 159 160 data->wm8776_regs[WM8776_HPLVOL] = (0x79 - 60) | WM8776_HPZCEN; 161 data->wm8776_regs[WM8776_HPRVOL] = (0x79 - 60) | WM8776_HPZCEN; 162 data->wm8776_regs[WM8776_ADCIFCTRL] = 163 WM8776_ADCFMT_LJUST | WM8776_ADCWL_24 | WM8776_ADCMCLK; 164 data->wm8776_regs[WM8776_MSTRCTRL] = 165 WM8776_ADCRATE_256 | WM8776_DACRATE_256; 166 data->wm8776_regs[WM8776_PWRDOWN] = WM8776_HPPD; 167 data->wm8776_regs[WM8776_ADCLVOL] = 0xa5 | WM8776_ZCA; 168 data->wm8776_regs[WM8776_ADCRVOL] = 0xa5 | WM8776_ZCA; 169 data->wm8776_regs[WM8776_ADCMUX] = 0x001; 170 wm8776_registers_init(chip); 171} 172 173static void xonar_ds_init(struct oxygen *chip) 174{ 175 struct xonar_wm87x6 *data = chip->model_data; 176 177 data->generic.anti_pop_delay = 300; 178 data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE; 179 180 wm8776_init(chip); 181 wm8766_registers_init(chip); 182 183 oxygen_write16_masked(chip, OXYGEN_GPIO_CONTROL, GPIO_DS_INPUT_ROUTE, 184 GPIO_DS_HP_DETECT | GPIO_DS_INPUT_ROUTE); 185 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE); 186 oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT); 187 chip->interrupt_mask |= OXYGEN_INT_GPIO; 188 189 xonar_enable_output(chip); 190 191 snd_component_add(chip->card, "WM8776"); 192 snd_component_add(chip->card, "WM8766"); 193} 194 195static void xonar_ds_cleanup(struct oxygen *chip) 196{ 197 xonar_disable_output(chip); 198 wm8776_write(chip, WM8776_RESET, 0); 199} 200 201static void xonar_ds_suspend(struct oxygen *chip) 202{ 203 xonar_ds_cleanup(chip); 204} 205 206static void xonar_ds_resume(struct oxygen *chip) 207{ 208 wm8776_registers_init(chip); 209 wm8766_registers_init(chip); 210 xonar_enable_output(chip); 211} 212 213static void wm8776_adc_hardware_filter(unsigned int channel, 214 struct snd_pcm_hardware *hardware) 215{ 216 if (channel == PCM_A) { 217 hardware->rates = SNDRV_PCM_RATE_32000 | 218 SNDRV_PCM_RATE_44100 | 219 SNDRV_PCM_RATE_48000 | 220 SNDRV_PCM_RATE_64000 | 221 SNDRV_PCM_RATE_88200 | 222 SNDRV_PCM_RATE_96000; 223 hardware->rate_max = 96000; 224 } 225} 226 227static void set_wm87x6_dac_params(struct oxygen *chip, 228 struct snd_pcm_hw_params *params) 229{ 230} 231 232static void set_wm8776_adc_params(struct oxygen *chip, 233 struct snd_pcm_hw_params *params) 234{ 235 u16 reg; 236 237 reg = WM8776_ADCRATE_256 | WM8776_DACRATE_256; 238 if (params_rate(params) > 48000) 239 reg |= WM8776_ADCOSR; 240 wm8776_write_cached(chip, WM8776_MSTRCTRL, reg); 241} 242 243static void update_wm8776_volume(struct oxygen *chip) 244{ 245 struct xonar_wm87x6 *data = chip->model_data; 246 u8 to_change; 247 248 if (chip->dac_volume[0] == chip->dac_volume[1]) { 249 if (chip->dac_volume[0] != data->wm8776_regs[WM8776_DACLVOL] || 250 chip->dac_volume[1] != data->wm8776_regs[WM8776_DACRVOL]) { 251 wm8776_write(chip, WM8776_DACMASTER, 252 chip->dac_volume[0] | WM8776_UPDATE); 253 data->wm8776_regs[WM8776_DACLVOL] = chip->dac_volume[0]; 254 data->wm8776_regs[WM8776_DACRVOL] = chip->dac_volume[0]; 255 } 256 } else { 257 to_change = (chip->dac_volume[0] != 258 data->wm8776_regs[WM8776_DACLVOL]) << 0; 259 to_change |= (chip->dac_volume[1] != 260 data->wm8776_regs[WM8776_DACLVOL]) << 1; 261 if (to_change & 1) 262 wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0] | 263 ((to_change & 2) ? 0 : WM8776_UPDATE)); 264 if (to_change & 2) 265 wm8776_write(chip, WM8776_DACRVOL, 266 chip->dac_volume[1] | WM8776_UPDATE); 267 } 268} 269 270static void update_wm87x6_volume(struct oxygen *chip) 271{ 272 static const u8 wm8766_regs[6] = { 273 WM8766_LDA1, WM8766_RDA1, 274 WM8766_LDA2, WM8766_RDA2, 275 WM8766_LDA3, WM8766_RDA3, 276 }; 277 struct xonar_wm87x6 *data = chip->model_data; 278 unsigned int i; 279 u8 to_change; 280 281 update_wm8776_volume(chip); 282 if (chip->dac_volume[2] == chip->dac_volume[3] && 283 chip->dac_volume[2] == chip->dac_volume[4] && 284 chip->dac_volume[2] == chip->dac_volume[5] && 285 chip->dac_volume[2] == chip->dac_volume[6] && 286 chip->dac_volume[2] == chip->dac_volume[7]) { 287 to_change = 0; 288 for (i = 0; i < 6; ++i) 289 if (chip->dac_volume[2] != 290 data->wm8766_regs[wm8766_regs[i]]) 291 to_change = 1; 292 if (to_change) { 293 wm8766_write(chip, WM8766_MASTDA, 294 chip->dac_volume[2] | WM8766_UPDATE); 295 for (i = 0; i < 6; ++i) 296 data->wm8766_regs[wm8766_regs[i]] = 297 chip->dac_volume[2]; 298 } 299 } else { 300 to_change = 0; 301 for (i = 0; i < 6; ++i) 302 to_change |= (chip->dac_volume[2 + i] != 303 data->wm8766_regs[wm8766_regs[i]]) << i; 304 for (i = 0; i < 6; ++i) 305 if (to_change & (1 << i)) 306 wm8766_write(chip, wm8766_regs[i], 307 chip->dac_volume[2 + i] | 308 ((to_change & (0x3e << i)) 309 ? 0 : WM8766_UPDATE)); 310 } 311} 312 313static void update_wm8776_mute(struct oxygen *chip) 314{ 315 wm8776_write_cached(chip, WM8776_DACMUTE, 316 chip->dac_mute ? WM8776_DMUTE : 0); 317} 318 319static void update_wm87x6_mute(struct oxygen *chip) 320{ 321 update_wm8776_mute(chip); 322 wm8766_write_cached(chip, WM8766_DAC_CTRL2, WM8766_ZCD | 323 (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); 324} 325 326static void xonar_ds_gpio_changed(struct oxygen *chip) 327{ 328 u16 bits; 329 330 bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); 331 snd_printk(KERN_INFO "HP detect: %d\n", !!(bits & GPIO_DS_HP_DETECT)); 332} 333 334static int wm8776_bit_switch_get(struct snd_kcontrol *ctl, 335 struct snd_ctl_elem_value *value) 336{ 337 struct oxygen *chip = ctl->private_data; 338 struct xonar_wm87x6 *data = chip->model_data; 339 u16 bit = ctl->private_value & 0xffff; 340 unsigned int reg_index = (ctl->private_value >> 16) & 0xff; 341 bool invert = (ctl->private_value >> 24) & 1; 342 343 value->value.integer.value[0] = 344 ((data->wm8776_regs[reg_index] & bit) != 0) ^ invert; 345 return 0; 346} 347 348static int wm8776_bit_switch_put(struct snd_kcontrol *ctl, 349 struct snd_ctl_elem_value *value) 350{ 351 struct oxygen *chip = ctl->private_data; 352 struct xonar_wm87x6 *data = chip->model_data; 353 u16 bit = ctl->private_value & 0xffff; 354 u16 reg_value; 355 unsigned int reg_index = (ctl->private_value >> 16) & 0xff; 356 bool invert = (ctl->private_value >> 24) & 1; 357 int changed; 358 359 mutex_lock(&chip->mutex); 360 reg_value = data->wm8776_regs[reg_index] & ~bit; 361 if (value->value.integer.value[0] ^ invert) 362 reg_value |= bit; 363 changed = reg_value != data->wm8776_regs[reg_index]; 364 if (changed) 365 wm8776_write(chip, reg_index, reg_value); 366 mutex_unlock(&chip->mutex); 367 return changed; 368} 369 370static int wm8776_field_enum_info(struct snd_kcontrol *ctl, 371 struct snd_ctl_elem_info *info) 372{ 373 static const char *const hld[16] = { 374 "0 ms", "2.67 ms", "5.33 ms", "10.6 ms", 375 "21.3 ms", "42.7 ms", "85.3 ms", "171 ms", 376 "341 ms", "683 ms", "1.37 s", "2.73 s", 377 "5.46 s", "10.9 s", "21.8 s", "43.7 s", 378 }; 379 static const char *const atk_lim[11] = { 380 "0.25 ms", "0.5 ms", "1 ms", "2 ms", 381 "4 ms", "8 ms", "16 ms", "32 ms", 382 "64 ms", "128 ms", "256 ms", 383 }; 384 static const char *const atk_alc[11] = { 385 "8.40 ms", "16.8 ms", "33.6 ms", "67.2 ms", 386 "134 ms", "269 ms", "538 ms", "1.08 s", 387 "2.15 s", "4.3 s", "8.6 s", 388 }; 389 static const char *const dcy_lim[11] = { 390 "1.2 ms", "2.4 ms", "4.8 ms", "9.6 ms", 391 "19.2 ms", "38.4 ms", "76.8 ms", "154 ms", 392 "307 ms", "614 ms", "1.23 s", 393 }; 394 static const char *const dcy_alc[11] = { 395 "33.5 ms", "67.0 ms", "134 ms", "268 ms", 396 "536 ms", "1.07 s", "2.14 s", "4.29 s", 397 "8.58 s", "17.2 s", "34.3 s", 398 }; 399 static const char *const tranwin[8] = { 400 "0 us", "62.5 us", "125 us", "250 us", 401 "500 us", "1 ms", "2 ms", "4 ms", 402 }; 403 u8 max; 404 const char *const *names; 405 406 max = (ctl->private_value >> 12) & 0xf; 407 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 408 info->count = 1; 409 info->value.enumerated.items = max + 1; 410 if (info->value.enumerated.item > max) 411 info->value.enumerated.item = max; 412 switch ((ctl->private_value >> 24) & 0x1f) { 413 case WM8776_ALCCTRL2: 414 names = hld; 415 break; 416 case WM8776_ALCCTRL3: 417 if (((ctl->private_value >> 20) & 0xf) == 0) { 418 if (ctl->private_value & LC_CONTROL_LIMITER) 419 names = atk_lim; 420 else 421 names = atk_alc; 422 } else { 423 if (ctl->private_value & LC_CONTROL_LIMITER) 424 names = dcy_lim; 425 else 426 names = dcy_alc; 427 } 428 break; 429 case WM8776_LIMITER: 430 names = tranwin; 431 break; 432 default: 433 return -ENXIO; 434 } 435 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); 436 return 0; 437} 438 439static int wm8776_field_volume_info(struct snd_kcontrol *ctl, 440 struct snd_ctl_elem_info *info) 441{ 442 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 443 info->count = 1; 444 info->value.integer.min = (ctl->private_value >> 8) & 0xf; 445 info->value.integer.max = (ctl->private_value >> 12) & 0xf; 446 return 0; 447} 448 449static void wm8776_field_set_from_ctl(struct snd_kcontrol *ctl) 450{ 451 struct oxygen *chip = ctl->private_data; 452 struct xonar_wm87x6 *data = chip->model_data; 453 unsigned int value, reg_index, mode; 454 u8 min, max, shift; 455 u16 mask, reg_value; 456 bool invert; 457 458 if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) == 459 WM8776_LCSEL_LIMITER) 460 mode = LC_CONTROL_LIMITER; 461 else 462 mode = LC_CONTROL_ALC; 463 if (!(ctl->private_value & mode)) 464 return; 465 466 value = ctl->private_value & 0xf; 467 min = (ctl->private_value >> 8) & 0xf; 468 max = (ctl->private_value >> 12) & 0xf; 469 mask = (ctl->private_value >> 16) & 0xf; 470 shift = (ctl->private_value >> 20) & 0xf; 471 reg_index = (ctl->private_value >> 24) & 0x1f; 472 invert = (ctl->private_value >> 29) & 0x1; 473 474 if (invert) 475 value = max - (value - min); 476 reg_value = data->wm8776_regs[reg_index]; 477 reg_value &= ~(mask << shift); 478 reg_value |= value << shift; 479 wm8776_write_cached(chip, reg_index, reg_value); 480} 481 482static int wm8776_field_set(struct snd_kcontrol *ctl, unsigned int value) 483{ 484 struct oxygen *chip = ctl->private_data; 485 u8 min, max; 486 int changed; 487 488 min = (ctl->private_value >> 8) & 0xf; 489 max = (ctl->private_value >> 12) & 0xf; 490 if (value < min || value > max) 491 return -EINVAL; 492 mutex_lock(&chip->mutex); 493 changed = value != (ctl->private_value & 0xf); 494 if (changed) { 495 ctl->private_value = (ctl->private_value & ~0xf) | value; 496 wm8776_field_set_from_ctl(ctl); 497 } 498 mutex_unlock(&chip->mutex); 499 return changed; 500} 501 502static int wm8776_field_enum_get(struct snd_kcontrol *ctl, 503 struct snd_ctl_elem_value *value) 504{ 505 value->value.enumerated.item[0] = ctl->private_value & 0xf; 506 return 0; 507} 508 509static int wm8776_field_volume_get(struct snd_kcontrol *ctl, 510 struct snd_ctl_elem_value *value) 511{ 512 value->value.integer.value[0] = ctl->private_value & 0xf; 513 return 0; 514} 515 516static int wm8776_field_enum_put(struct snd_kcontrol *ctl, 517 struct snd_ctl_elem_value *value) 518{ 519 return wm8776_field_set(ctl, value->value.enumerated.item[0]); 520} 521 522static int wm8776_field_volume_put(struct snd_kcontrol *ctl, 523 struct snd_ctl_elem_value *value) 524{ 525 return wm8776_field_set(ctl, value->value.integer.value[0]); 526} 527 528static int wm8776_hp_vol_info(struct snd_kcontrol *ctl, 529 struct snd_ctl_elem_info *info) 530{ 531 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 532 info->count = 2; 533 info->value.integer.min = 0x79 - 60; 534 info->value.integer.max = 0x7f; 535 return 0; 536} 537 538static int wm8776_hp_vol_get(struct snd_kcontrol *ctl, 539 struct snd_ctl_elem_value *value) 540{ 541 struct oxygen *chip = ctl->private_data; 542 struct xonar_wm87x6 *data = chip->model_data; 543 544 mutex_lock(&chip->mutex); 545 value->value.integer.value[0] = 546 data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK; 547 value->value.integer.value[1] = 548 data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK; 549 mutex_unlock(&chip->mutex); 550 return 0; 551} 552 553static int wm8776_hp_vol_put(struct snd_kcontrol *ctl, 554 struct snd_ctl_elem_value *value) 555{ 556 struct oxygen *chip = ctl->private_data; 557 struct xonar_wm87x6 *data = chip->model_data; 558 u8 to_update; 559 560 mutex_lock(&chip->mutex); 561 to_update = (value->value.integer.value[0] != 562 (data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK)) 563 << 0; 564 to_update |= (value->value.integer.value[1] != 565 (data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK)) 566 << 1; 567 if (value->value.integer.value[0] == value->value.integer.value[1]) { 568 if (to_update) { 569 wm8776_write(chip, WM8776_HPMASTER, 570 value->value.integer.value[0] | 571 WM8776_HPZCEN | WM8776_UPDATE); 572 data->wm8776_regs[WM8776_HPLVOL] = 573 value->value.integer.value[0] | WM8776_HPZCEN; 574 data->wm8776_regs[WM8776_HPRVOL] = 575 value->value.integer.value[0] | WM8776_HPZCEN; 576 } 577 } else { 578 if (to_update & 1) 579 wm8776_write(chip, WM8776_HPLVOL, 580 value->value.integer.value[0] | 581 WM8776_HPZCEN | 582 ((to_update & 2) ? 0 : WM8776_UPDATE)); 583 if (to_update & 2) 584 wm8776_write(chip, WM8776_HPRVOL, 585 value->value.integer.value[1] | 586 WM8776_HPZCEN | WM8776_UPDATE); 587 } 588 mutex_unlock(&chip->mutex); 589 return to_update != 0; 590} 591 592static int wm8776_input_mux_get(struct snd_kcontrol *ctl, 593 struct snd_ctl_elem_value *value) 594{ 595 struct oxygen *chip = ctl->private_data; 596 struct xonar_wm87x6 *data = chip->model_data; 597 unsigned int mux_bit = ctl->private_value; 598 599 value->value.integer.value[0] = 600 !!(data->wm8776_regs[WM8776_ADCMUX] & mux_bit); 601 return 0; 602} 603 604static int wm8776_input_mux_put(struct snd_kcontrol *ctl, 605 struct snd_ctl_elem_value *value) 606{ 607 struct oxygen *chip = ctl->private_data; 608 struct xonar_wm87x6 *data = chip->model_data; 609 struct snd_kcontrol *other_ctl; 610 unsigned int mux_bit = ctl->private_value; 611 u16 reg; 612 int changed; 613 614 mutex_lock(&chip->mutex); 615 reg = data->wm8776_regs[WM8776_ADCMUX]; 616 if (value->value.integer.value[0]) { 617 reg |= mux_bit; 618 /* line-in and mic-in are exclusive */ 619 mux_bit ^= 3; 620 if (reg & mux_bit) { 621 reg &= ~mux_bit; 622 if (mux_bit == 1) 623 other_ctl = data->line_adcmux_control; 624 else 625 other_ctl = data->mic_adcmux_control; 626 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, 627 &other_ctl->id); 628 } 629 } else 630 reg &= ~mux_bit; 631 changed = reg != data->wm8776_regs[WM8776_ADCMUX]; 632 if (changed) { 633 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, 634 reg & 1 ? GPIO_DS_INPUT_ROUTE : 0, 635 GPIO_DS_INPUT_ROUTE); 636 wm8776_write(chip, WM8776_ADCMUX, reg); 637 } 638 mutex_unlock(&chip->mutex); 639 return changed; 640} 641 642static int wm8776_input_vol_info(struct snd_kcontrol *ctl, 643 struct snd_ctl_elem_info *info) 644{ 645 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 646 info->count = 2; 647 info->value.integer.min = 0xa5; 648 info->value.integer.max = 0xff; 649 return 0; 650} 651 652static int wm8776_input_vol_get(struct snd_kcontrol *ctl, 653 struct snd_ctl_elem_value *value) 654{ 655 struct oxygen *chip = ctl->private_data; 656 struct xonar_wm87x6 *data = chip->model_data; 657 658 mutex_lock(&chip->mutex); 659 value->value.integer.value[0] = 660 data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK; 661 value->value.integer.value[1] = 662 data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK; 663 mutex_unlock(&chip->mutex); 664 return 0; 665} 666 667static int wm8776_input_vol_put(struct snd_kcontrol *ctl, 668 struct snd_ctl_elem_value *value) 669{ 670 struct oxygen *chip = ctl->private_data; 671 struct xonar_wm87x6 *data = chip->model_data; 672 int changed = 0; 673 674 mutex_lock(&chip->mutex); 675 changed = (value->value.integer.value[0] != 676 (data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK)) || 677 (value->value.integer.value[1] != 678 (data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK)); 679 wm8776_write_cached(chip, WM8776_ADCLVOL, 680 value->value.integer.value[0] | WM8776_ZCA); 681 wm8776_write_cached(chip, WM8776_ADCRVOL, 682 value->value.integer.value[1] | WM8776_ZCA); 683 mutex_unlock(&chip->mutex); 684 return changed; 685} 686 687static int wm8776_level_control_info(struct snd_kcontrol *ctl, 688 struct snd_ctl_elem_info *info) 689{ 690 static const char *const names[3] = { 691 "None", "Peak Limiter", "Automatic Level Control" 692 }; 693 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 694 info->count = 1; 695 info->value.enumerated.items = 3; 696 if (info->value.enumerated.item >= 3) 697 info->value.enumerated.item = 2; 698 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); 699 return 0; 700} 701 702static int wm8776_level_control_get(struct snd_kcontrol *ctl, 703 struct snd_ctl_elem_value *value) 704{ 705 struct oxygen *chip = ctl->private_data; 706 struct xonar_wm87x6 *data = chip->model_data; 707 708 if (!(data->wm8776_regs[WM8776_ALCCTRL2] & WM8776_LCEN)) 709 value->value.enumerated.item[0] = 0; 710 else if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) == 711 WM8776_LCSEL_LIMITER) 712 value->value.enumerated.item[0] = 1; 713 else 714 value->value.enumerated.item[0] = 2; 715 return 0; 716} 717 718static void activate_control(struct oxygen *chip, 719 struct snd_kcontrol *ctl, unsigned int mode) 720{ 721 unsigned int access; 722 723 if (ctl->private_value & mode) 724 access = 0; 725 else 726 access = SNDRV_CTL_ELEM_ACCESS_INACTIVE; 727 if ((ctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE) != access) { 728 ctl->vd[0].access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE; 729 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); 730 } 731} 732 733static int wm8776_level_control_put(struct snd_kcontrol *ctl, 734 struct snd_ctl_elem_value *value) 735{ 736 struct oxygen *chip = ctl->private_data; 737 struct xonar_wm87x6 *data = chip->model_data; 738 unsigned int mode = 0, i; 739 u16 ctrl1, ctrl2; 740 int changed; 741 742 if (value->value.enumerated.item[0] >= 3) 743 return -EINVAL; 744 mutex_lock(&chip->mutex); 745 changed = value->value.enumerated.item[0] != ctl->private_value; 746 if (changed) { 747 ctl->private_value = value->value.enumerated.item[0]; 748 ctrl1 = data->wm8776_regs[WM8776_ALCCTRL1]; 749 ctrl2 = data->wm8776_regs[WM8776_ALCCTRL2]; 750 switch (value->value.enumerated.item[0]) { 751 default: 752 wm8776_write_cached(chip, WM8776_ALCCTRL2, 753 ctrl2 & ~WM8776_LCEN); 754 break; 755 case 1: 756 wm8776_write_cached(chip, WM8776_ALCCTRL1, 757 (ctrl1 & ~WM8776_LCSEL_MASK) | 758 WM8776_LCSEL_LIMITER); 759 wm8776_write_cached(chip, WM8776_ALCCTRL2, 760 ctrl2 | WM8776_LCEN); 761 mode = LC_CONTROL_LIMITER; 762 break; 763 case 2: 764 wm8776_write_cached(chip, WM8776_ALCCTRL1, 765 (ctrl1 & ~WM8776_LCSEL_MASK) | 766 WM8776_LCSEL_ALC_STEREO); 767 wm8776_write_cached(chip, WM8776_ALCCTRL2, 768 ctrl2 | WM8776_LCEN); 769 mode = LC_CONTROL_ALC; 770 break; 771 } 772 for (i = 0; i < ARRAY_SIZE(data->lc_controls); ++i) 773 activate_control(chip, data->lc_controls[i], mode); 774 } 775 mutex_unlock(&chip->mutex); 776 return changed; 777} 778 779static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) 780{ 781 static const char *const names[2] = { 782 "None", "High-pass Filter" 783 }; 784 785 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 786 info->count = 1; 787 info->value.enumerated.items = 2; 788 if (info->value.enumerated.item >= 2) 789 info->value.enumerated.item = 1; 790 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); 791 return 0; 792} 793 794static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 795{ 796 struct oxygen *chip = ctl->private_data; 797 struct xonar_wm87x6 *data = chip->model_data; 798 799 value->value.enumerated.item[0] = 800 !(data->wm8776_regs[WM8776_ADCIFCTRL] & WM8776_ADCHPD); 801 return 0; 802} 803 804static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 805{ 806 struct oxygen *chip = ctl->private_data; 807 struct xonar_wm87x6 *data = chip->model_data; 808 unsigned int reg; 809 int changed; 810 811 mutex_lock(&chip->mutex); 812 reg = data->wm8776_regs[WM8776_ADCIFCTRL] & ~WM8776_ADCHPD; 813 if (!value->value.enumerated.item[0]) 814 reg |= WM8776_ADCHPD; 815 changed = reg != data->wm8776_regs[WM8776_ADCIFCTRL]; 816 if (changed) 817 wm8776_write(chip, WM8776_ADCIFCTRL, reg); 818 mutex_unlock(&chip->mutex); 819 return changed; 820} 821 822#define WM8776_BIT_SWITCH(xname, reg, bit, invert, flags) { \ 823 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 824 .name = xname, \ 825 .info = snd_ctl_boolean_mono_info, \ 826 .get = wm8776_bit_switch_get, \ 827 .put = wm8776_bit_switch_put, \ 828 .private_value = ((reg) << 16) | (bit) | ((invert) << 24) | (flags), \ 829} 830#define _WM8776_FIELD_CTL(xname, reg, shift, initval, min, max, mask, flags) \ 831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 832 .name = xname, \ 833 .private_value = (initval) | ((min) << 8) | ((max) << 12) | \ 834 ((mask) << 16) | ((shift) << 20) | ((reg) << 24) | (flags) 835#define WM8776_FIELD_CTL_ENUM(xname, reg, shift, init, min, max, mask, flags) {\ 836 _WM8776_FIELD_CTL(xname " Capture Enum", \ 837 reg, shift, init, min, max, mask, flags), \ 838 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 839 SNDRV_CTL_ELEM_ACCESS_INACTIVE, \ 840 .info = wm8776_field_enum_info, \ 841 .get = wm8776_field_enum_get, \ 842 .put = wm8776_field_enum_put, \ 843} 844#define WM8776_FIELD_CTL_VOLUME(a, b, c, d, e, f, g, h, tlv_p) { \ 845 _WM8776_FIELD_CTL(a " Capture Volume", b, c, d, e, f, g, h), \ 846 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 847 SNDRV_CTL_ELEM_ACCESS_INACTIVE | \ 848 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ 849 .info = wm8776_field_volume_info, \ 850 .get = wm8776_field_volume_get, \ 851 .put = wm8776_field_volume_put, \ 852 .tlv = { .p = tlv_p }, \ 853} 854 855static const DECLARE_TLV_DB_SCALE(wm87x6_dac_db_scale, -6000, 50, 0); 856static const DECLARE_TLV_DB_SCALE(wm8776_adc_db_scale, -2100, 50, 0); 857static const DECLARE_TLV_DB_SCALE(wm8776_hp_db_scale, -6000, 100, 0); 858static const DECLARE_TLV_DB_SCALE(wm8776_lct_db_scale, -1600, 100, 0); 859static const DECLARE_TLV_DB_SCALE(wm8776_maxgain_db_scale, 0, 400, 0); 860static const DECLARE_TLV_DB_SCALE(wm8776_ngth_db_scale, -7800, 600, 0); 861static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_lim_db_scale, -1200, 100, 0); 862static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_alc_db_scale, -2100, 400, 0); 863 864static const struct snd_kcontrol_new ds_controls[] = { 865 { 866 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 867 .name = "Headphone Playback Volume", 868 .info = wm8776_hp_vol_info, 869 .get = wm8776_hp_vol_get, 870 .put = wm8776_hp_vol_put, 871 .tlv = { .p = wm8776_hp_db_scale }, 872 }, 873 WM8776_BIT_SWITCH("Headphone Playback Switch", 874 WM8776_PWRDOWN, WM8776_HPPD, 1, 0), 875 { 876 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 877 .name = "Input Capture Volume", 878 .info = wm8776_input_vol_info, 879 .get = wm8776_input_vol_get, 880 .put = wm8776_input_vol_put, 881 .tlv = { .p = wm8776_adc_db_scale }, 882 }, 883 { 884 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 885 .name = "Line Capture Switch", 886 .info = snd_ctl_boolean_mono_info, 887 .get = wm8776_input_mux_get, 888 .put = wm8776_input_mux_put, 889 .private_value = 1 << 0, 890 }, 891 { 892 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 893 .name = "Mic Capture Switch", 894 .info = snd_ctl_boolean_mono_info, 895 .get = wm8776_input_mux_get, 896 .put = wm8776_input_mux_put, 897 .private_value = 1 << 1, 898 }, 899 WM8776_BIT_SWITCH("Aux", WM8776_ADCMUX, 1 << 2, 0, 0), 900 { 901 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 902 .name = "ADC Filter Capture Enum", 903 .info = hpf_info, 904 .get = hpf_get, 905 .put = hpf_put, 906 }, 907 { 908 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 909 .name = "Level Control Capture Enum", 910 .info = wm8776_level_control_info, 911 .get = wm8776_level_control_get, 912 .put = wm8776_level_control_put, 913 .private_value = 0, 914 }, 915}; 916static const struct snd_kcontrol_new lc_controls[] = { 917 WM8776_FIELD_CTL_VOLUME("Limiter Threshold", 918 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf, 919 LC_CONTROL_LIMITER, wm8776_lct_db_scale), 920 WM8776_FIELD_CTL_ENUM("Limiter Attack Time", 921 WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf, 922 LC_CONTROL_LIMITER), 923 WM8776_FIELD_CTL_ENUM("Limiter Decay Time", 924 WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf, 925 LC_CONTROL_LIMITER), 926 WM8776_FIELD_CTL_ENUM("Limiter Transient Window", 927 WM8776_LIMITER, 4, 2, 0, 7, 0x7, 928 LC_CONTROL_LIMITER), 929 WM8776_FIELD_CTL_VOLUME("Limiter Maximum Attenuation", 930 WM8776_LIMITER, 0, 6, 3, 12, 0xf, 931 LC_CONTROL_LIMITER, 932 wm8776_maxatten_lim_db_scale), 933 WM8776_FIELD_CTL_VOLUME("ALC Target Level", 934 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf, 935 LC_CONTROL_ALC, wm8776_lct_db_scale), 936 WM8776_FIELD_CTL_ENUM("ALC Attack Time", 937 WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf, 938 LC_CONTROL_ALC), 939 WM8776_FIELD_CTL_ENUM("ALC Decay Time", 940 WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf, 941 LC_CONTROL_ALC), 942 WM8776_FIELD_CTL_VOLUME("ALC Maximum Gain", 943 WM8776_ALCCTRL1, 4, 7, 1, 7, 0x7, 944 LC_CONTROL_ALC, wm8776_maxgain_db_scale), 945 WM8776_FIELD_CTL_VOLUME("ALC Maximum Attenuation", 946 WM8776_LIMITER, 0, 10, 10, 15, 0xf, 947 LC_CONTROL_ALC, wm8776_maxatten_alc_db_scale), 948 WM8776_FIELD_CTL_ENUM("ALC Hold Time", 949 WM8776_ALCCTRL2, 0, 0, 0, 15, 0xf, 950 LC_CONTROL_ALC), 951 WM8776_BIT_SWITCH("Noise Gate Capture Switch", 952 WM8776_NOISEGATE, WM8776_NGAT, 0, 953 LC_CONTROL_ALC), 954 WM8776_FIELD_CTL_VOLUME("Noise Gate Threshold", 955 WM8776_NOISEGATE, 2, 0, 0, 7, 0x7, 956 LC_CONTROL_ALC, wm8776_ngth_db_scale), 957}; 958 959static int xonar_ds_control_filter(struct snd_kcontrol_new *template) 960{ 961 if (!strncmp(template->name, "CD Capture ", 11)) 962 return 1; /* no CD input */ 963 return 0; 964} 965 966static int xonar_ds_mixer_init(struct oxygen *chip) 967{ 968 struct xonar_wm87x6 *data = chip->model_data; 969 unsigned int i; 970 struct snd_kcontrol *ctl; 971 int err; 972 973 for (i = 0; i < ARRAY_SIZE(ds_controls); ++i) { 974 ctl = snd_ctl_new1(&ds_controls[i], chip); 975 if (!ctl) 976 return -ENOMEM; 977 err = snd_ctl_add(chip->card, ctl); 978 if (err < 0) 979 return err; 980 if (!strcmp(ctl->id.name, "Line Capture Switch")) 981 data->line_adcmux_control = ctl; 982 else if (!strcmp(ctl->id.name, "Mic Capture Switch")) 983 data->mic_adcmux_control = ctl; 984 } 985 if (!data->line_adcmux_control || !data->mic_adcmux_control) 986 return -ENXIO; 987 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls)); 988 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) { 989 ctl = snd_ctl_new1(&lc_controls[i], chip); 990 if (!ctl) 991 return -ENOMEM; 992 err = snd_ctl_add(chip->card, ctl); 993 if (err < 0) 994 return err; 995 data->lc_controls[i] = ctl; 996 } 997 return 0; 998} 999 1000static const struct oxygen_model model_xonar_ds = { 1001 .shortname = "Xonar DS", 1002 .longname = "Asus Virtuoso 200", 1003 .chip = "AV200", 1004 .init = xonar_ds_init, 1005 .control_filter = xonar_ds_control_filter, 1006 .mixer_init = xonar_ds_mixer_init, 1007 .cleanup = xonar_ds_cleanup, 1008 .suspend = xonar_ds_suspend, 1009 .resume = xonar_ds_resume, 1010 .pcm_hardware_filter = wm8776_adc_hardware_filter, 1011 .get_i2s_mclk = oxygen_default_i2s_mclk, 1012 .set_dac_params = set_wm87x6_dac_params, 1013 .set_adc_params = set_wm8776_adc_params, 1014 .update_dac_volume = update_wm87x6_volume, 1015 .update_dac_mute = update_wm87x6_mute, 1016 .gpio_changed = xonar_ds_gpio_changed, 1017 .dac_tlv = wm87x6_dac_db_scale, 1018 .model_data_size = sizeof(struct xonar_wm87x6), 1019 .device_config = PLAYBACK_0_TO_I2S | 1020 PLAYBACK_1_TO_SPDIF | 1021 CAPTURE_0_FROM_I2S_1, 1022 .dac_channels = 8, 1023 .dac_volume_min = 255 - 2*60, 1024 .dac_volume_max = 255, 1025 .function_flags = OXYGEN_FUNCTION_SPI, 1026 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1027 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1028}; 1029 1030int __devinit get_xonar_wm87x6_model(struct oxygen *chip, 1031 const struct pci_device_id *id) 1032{ 1033 switch (id->subdevice) { 1034 case 0x838e: 1035 chip->model = model_xonar_ds; 1036 break; 1037 default: 1038 return -EINVAL; 1039 } 1040 return 0; 1041} 1042