1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * card driver for models with WM8776/WM8766 DACs (Xonar DS/HDAV1.3 Slim) 4 * 5 * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 6 */ 7 8 /* 9 * Xonar DS 10 * -------- 11 * 12 * CMI8788: 13 * 14 * SPI 0 -> WM8766 (surround, center/LFE, back) 15 * SPI 1 -> WM8776 (front, input) 16 * 17 * GPIO 4 <- headphone detect, 0 = plugged 18 * GPIO 6 -> route input jack to mic-in (0) or line-in (1) 19 * GPIO 7 -> enable output to front L/R speaker channels 20 * GPIO 8 -> enable output to other speaker channels and front panel headphone 21 * 22 * WM8776: 23 * 24 * input 1 <- line 25 * input 2 <- mic 26 * input 3 <- front mic 27 * input 4 <- aux 28 */ 29 30 /* 31 * Xonar HDAV1.3 Slim 32 * ------------------ 33 * 34 * CMI8788: 35 * 36 * I²C <-> WM8776 (addr 0011010) 37 * 38 * GPIO 0 -> disable HDMI output 39 * GPIO 1 -> enable HP output 40 * GPIO 6 -> firmware EEPROM I²C clock 41 * GPIO 7 <-> firmware EEPROM I²C data 42 * 43 * UART <-> HDMI controller 44 * 45 * WM8776: 46 * 47 * input 1 <- mic 48 * input 2 <- aux 49 */ 50 51 #include <linux/pci.h> 52 #include <linux/delay.h> 53 #include <sound/control.h> 54 #include <sound/core.h> 55 #include <sound/info.h> 56 #include <sound/jack.h> 57 #include <sound/pcm.h> 58 #include <sound/pcm_params.h> 59 #include <sound/tlv.h> 60 #include "xonar.h" 61 #include "wm8776.h" 62 #include "wm8766.h" 63 64 #define GPIO_DS_HP_DETECT 0x0010 65 #define GPIO_DS_INPUT_ROUTE 0x0040 66 #define GPIO_DS_OUTPUT_FRONTLR 0x0080 67 #define GPIO_DS_OUTPUT_ENABLE 0x0100 68 69 #define GPIO_SLIM_HDMI_DISABLE 0x0001 70 #define GPIO_SLIM_OUTPUT_ENABLE 0x0002 71 #define GPIO_SLIM_FIRMWARE_CLK 0x0040 72 #define GPIO_SLIM_FIRMWARE_DATA 0x0080 73 74 #define I2C_DEVICE_WM8776 0x34 /* 001101, 0, /W=0 */ 75 76 #define LC_CONTROL_LIMITER 0x40000000 77 #define LC_CONTROL_ALC 0x20000000 78 79 struct xonar_wm87x6 { 80 struct xonar_generic generic; 81 u16 wm8776_regs[0x17]; 82 u16 wm8766_regs[0x10]; 83 struct snd_kcontrol *line_adcmux_control; 84 struct snd_kcontrol *mic_adcmux_control; 85 struct snd_kcontrol *lc_controls[13]; 86 struct snd_jack *hp_jack; 87 struct xonar_hdmi hdmi; 88 }; 89 90 static void wm8776_write_spi(struct oxygen *chip, 91 unsigned int reg, unsigned int value) 92 { 93 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | 94 OXYGEN_SPI_DATA_LENGTH_2 | 95 OXYGEN_SPI_CLOCK_160 | 96 (1 << OXYGEN_SPI_CODEC_SHIFT) | 97 OXYGEN_SPI_CEN_LATCH_CLOCK_LO, 98 (reg << 9) | value); 99 } 100 101 static void wm8776_write_i2c(struct oxygen *chip, 102 unsigned int reg, unsigned int value) 103 { 104 oxygen_write_i2c(chip, I2C_DEVICE_WM8776, 105 (reg << 1) | (value >> 8), value); 106 } 107 108 static void wm8776_write(struct oxygen *chip, 109 unsigned int reg, unsigned int value) 110 { 111 struct xonar_wm87x6 *data = chip->model_data; 112 113 if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) == 114 OXYGEN_FUNCTION_SPI) 115 wm8776_write_spi(chip, reg, value); 116 else 117 wm8776_write_i2c(chip, reg, value); 118 if (reg < ARRAY_SIZE(data->wm8776_regs)) { 119 if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER) 120 value &= ~WM8776_UPDATE; 121 data->wm8776_regs[reg] = value; 122 } 123 } 124 125 static void wm8776_write_cached(struct oxygen *chip, 126 unsigned int reg, unsigned int value) 127 { 128 struct xonar_wm87x6 *data = chip->model_data; 129 130 if (reg >= ARRAY_SIZE(data->wm8776_regs) || 131 value != data->wm8776_regs[reg]) 132 wm8776_write(chip, reg, value); 133 } 134 135 static void wm8766_write(struct oxygen *chip, 136 unsigned int reg, unsigned int value) 137 { 138 struct xonar_wm87x6 *data = chip->model_data; 139 140 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | 141 OXYGEN_SPI_DATA_LENGTH_2 | 142 OXYGEN_SPI_CLOCK_160 | 143 (0 << OXYGEN_SPI_CODEC_SHIFT) | 144 OXYGEN_SPI_CEN_LATCH_CLOCK_LO, 145 (reg << 9) | value); 146 if (reg < ARRAY_SIZE(data->wm8766_regs)) { 147 if ((reg >= WM8766_LDA1 && reg <= WM8766_RDA1) || 148 (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA)) 149 value &= ~WM8766_UPDATE; 150 data->wm8766_regs[reg] = value; 151 } 152 } 153 154 static void wm8766_write_cached(struct oxygen *chip, 155 unsigned int reg, unsigned int value) 156 { 157 struct xonar_wm87x6 *data = chip->model_data; 158 159 if (reg >= ARRAY_SIZE(data->wm8766_regs) || 160 value != data->wm8766_regs[reg]) 161 wm8766_write(chip, reg, value); 162 } 163 164 static void wm8776_registers_init(struct oxygen *chip) 165 { 166 struct xonar_wm87x6 *data = chip->model_data; 167 168 wm8776_write(chip, WM8776_RESET, 0); 169 wm8776_write(chip, WM8776_PHASESWAP, WM8776_PH_MASK); 170 wm8776_write(chip, WM8776_DACCTRL1, WM8776_DZCEN | 171 WM8776_PL_LEFT_LEFT | WM8776_PL_RIGHT_RIGHT); 172 wm8776_write(chip, WM8776_DACMUTE, chip->dac_mute ? WM8776_DMUTE : 0); 173 wm8776_write(chip, WM8776_DACIFCTRL, 174 WM8776_DACFMT_LJUST | WM8776_DACWL_24); 175 wm8776_write(chip, WM8776_ADCIFCTRL, 176 data->wm8776_regs[WM8776_ADCIFCTRL]); 177 wm8776_write(chip, WM8776_MSTRCTRL, data->wm8776_regs[WM8776_MSTRCTRL]); 178 wm8776_write(chip, WM8776_PWRDOWN, data->wm8776_regs[WM8776_PWRDOWN]); 179 wm8776_write(chip, WM8776_HPLVOL, data->wm8776_regs[WM8776_HPLVOL]); 180 wm8776_write(chip, WM8776_HPRVOL, data->wm8776_regs[WM8776_HPRVOL] | 181 WM8776_UPDATE); 182 wm8776_write(chip, WM8776_ADCLVOL, data->wm8776_regs[WM8776_ADCLVOL]); 183 wm8776_write(chip, WM8776_ADCRVOL, data->wm8776_regs[WM8776_ADCRVOL]); 184 wm8776_write(chip, WM8776_ADCMUX, data->wm8776_regs[WM8776_ADCMUX]); 185 wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0]); 186 wm8776_write(chip, WM8776_DACRVOL, chip->dac_volume[1] | WM8776_UPDATE); 187 } 188 189 static void wm8766_registers_init(struct oxygen *chip) 190 { 191 struct xonar_wm87x6 *data = chip->model_data; 192 193 wm8766_write(chip, WM8766_RESET, 0); 194 wm8766_write(chip, WM8766_DAC_CTRL, data->wm8766_regs[WM8766_DAC_CTRL]); 195 wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24); 196 wm8766_write(chip, WM8766_DAC_CTRL2, 197 WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); 198 wm8766_write(chip, WM8766_LDA1, chip->dac_volume[2]); 199 wm8766_write(chip, WM8766_RDA1, chip->dac_volume[3]); 200 wm8766_write(chip, WM8766_LDA2, chip->dac_volume[4]); 201 wm8766_write(chip, WM8766_RDA2, chip->dac_volume[5]); 202 wm8766_write(chip, WM8766_LDA3, chip->dac_volume[6]); 203 wm8766_write(chip, WM8766_RDA3, chip->dac_volume[7] | WM8766_UPDATE); 204 } 205 206 static void wm8776_init(struct oxygen *chip) 207 { 208 struct xonar_wm87x6 *data = chip->model_data; 209 210 data->wm8776_regs[WM8776_HPLVOL] = (0x79 - 60) | WM8776_HPZCEN; 211 data->wm8776_regs[WM8776_HPRVOL] = (0x79 - 60) | WM8776_HPZCEN; 212 data->wm8776_regs[WM8776_ADCIFCTRL] = 213 WM8776_ADCFMT_LJUST | WM8776_ADCWL_24 | WM8776_ADCMCLK; 214 data->wm8776_regs[WM8776_MSTRCTRL] = 215 WM8776_ADCRATE_256 | WM8776_DACRATE_256; 216 data->wm8776_regs[WM8776_PWRDOWN] = WM8776_HPPD; 217 data->wm8776_regs[WM8776_ADCLVOL] = 0xa5 | WM8776_ZCA; 218 data->wm8776_regs[WM8776_ADCRVOL] = 0xa5 | WM8776_ZCA; 219 data->wm8776_regs[WM8776_ADCMUX] = 0x001; 220 wm8776_registers_init(chip); 221 } 222 223 static void wm8766_init(struct oxygen *chip) 224 { 225 struct xonar_wm87x6 *data = chip->model_data; 226 227 data->wm8766_regs[WM8766_DAC_CTRL] = 228 WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT; 229 wm8766_registers_init(chip); 230 } 231 232 static void xonar_ds_handle_hp_jack(struct oxygen *chip) 233 { 234 struct xonar_wm87x6 *data = chip->model_data; 235 bool hp_plugged; 236 unsigned int reg; 237 238 mutex_lock(&chip->mutex); 239 240 hp_plugged = !(oxygen_read16(chip, OXYGEN_GPIO_DATA) & 241 GPIO_DS_HP_DETECT); 242 243 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, 244 hp_plugged ? 0 : GPIO_DS_OUTPUT_FRONTLR, 245 GPIO_DS_OUTPUT_FRONTLR); 246 247 reg = data->wm8766_regs[WM8766_DAC_CTRL] & ~WM8766_MUTEALL; 248 if (hp_plugged) 249 reg |= WM8766_MUTEALL; 250 wm8766_write_cached(chip, WM8766_DAC_CTRL, reg); 251 252 snd_jack_report(data->hp_jack, hp_plugged ? SND_JACK_HEADPHONE : 0); 253 254 mutex_unlock(&chip->mutex); 255 } 256 257 static void xonar_ds_init(struct oxygen *chip) 258 { 259 struct xonar_wm87x6 *data = chip->model_data; 260 261 data->generic.anti_pop_delay = 300; 262 data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE; 263 264 wm8776_init(chip); 265 wm8766_init(chip); 266 267 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 268 GPIO_DS_INPUT_ROUTE | GPIO_DS_OUTPUT_FRONTLR); 269 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, 270 GPIO_DS_HP_DETECT); 271 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE); 272 oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT); 273 chip->interrupt_mask |= OXYGEN_INT_GPIO; 274 275 xonar_enable_output(chip); 276 277 snd_jack_new(chip->card, "Headphone", 278 SND_JACK_HEADPHONE, &data->hp_jack, false, false); 279 xonar_ds_handle_hp_jack(chip); 280 281 snd_component_add(chip->card, "WM8776"); 282 snd_component_add(chip->card, "WM8766"); 283 } 284 285 static void xonar_hdav_slim_init(struct oxygen *chip) 286 { 287 struct xonar_wm87x6 *data = chip->model_data; 288 289 data->generic.anti_pop_delay = 300; 290 data->generic.output_enable_bit = GPIO_SLIM_OUTPUT_ENABLE; 291 292 wm8776_init(chip); 293 294 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 295 GPIO_SLIM_HDMI_DISABLE | 296 GPIO_SLIM_FIRMWARE_CLK | 297 GPIO_SLIM_FIRMWARE_DATA); 298 299 xonar_hdmi_init(chip, &data->hdmi); 300 xonar_enable_output(chip); 301 302 snd_component_add(chip->card, "WM8776"); 303 } 304 305 static void xonar_ds_cleanup(struct oxygen *chip) 306 { 307 xonar_disable_output(chip); 308 wm8776_write(chip, WM8776_RESET, 0); 309 } 310 311 static void xonar_hdav_slim_cleanup(struct oxygen *chip) 312 { 313 xonar_hdmi_cleanup(chip); 314 xonar_disable_output(chip); 315 wm8776_write(chip, WM8776_RESET, 0); 316 msleep(2); 317 } 318 319 static void xonar_ds_suspend(struct oxygen *chip) 320 { 321 xonar_ds_cleanup(chip); 322 } 323 324 static void xonar_hdav_slim_suspend(struct oxygen *chip) 325 { 326 xonar_hdav_slim_cleanup(chip); 327 } 328 329 static void xonar_ds_resume(struct oxygen *chip) 330 { 331 wm8776_registers_init(chip); 332 wm8766_registers_init(chip); 333 xonar_enable_output(chip); 334 xonar_ds_handle_hp_jack(chip); 335 } 336 337 static void xonar_hdav_slim_resume(struct oxygen *chip) 338 { 339 struct xonar_wm87x6 *data = chip->model_data; 340 341 wm8776_registers_init(chip); 342 xonar_hdmi_resume(chip, &data->hdmi); 343 xonar_enable_output(chip); 344 } 345 346 static void wm8776_adc_hardware_filter(unsigned int channel, 347 struct snd_pcm_hardware *hardware) 348 { 349 if (channel == PCM_A) { 350 hardware->rates = SNDRV_PCM_RATE_32000 | 351 SNDRV_PCM_RATE_44100 | 352 SNDRV_PCM_RATE_48000 | 353 SNDRV_PCM_RATE_64000 | 354 SNDRV_PCM_RATE_88200 | 355 SNDRV_PCM_RATE_96000; 356 hardware->rate_max = 96000; 357 } 358 } 359 360 static void xonar_hdav_slim_hardware_filter(unsigned int channel, 361 struct snd_pcm_hardware *hardware) 362 { 363 wm8776_adc_hardware_filter(channel, hardware); 364 xonar_hdmi_pcm_hardware_filter(channel, hardware); 365 } 366 367 static void set_wm87x6_dac_params(struct oxygen *chip, 368 struct snd_pcm_hw_params *params) 369 { 370 } 371 372 static void set_wm8776_adc_params(struct oxygen *chip, 373 struct snd_pcm_hw_params *params) 374 { 375 u16 reg; 376 377 reg = WM8776_ADCRATE_256 | WM8776_DACRATE_256; 378 if (params_rate(params) > 48000) 379 reg |= WM8776_ADCOSR; 380 wm8776_write_cached(chip, WM8776_MSTRCTRL, reg); 381 } 382 383 static void set_hdav_slim_dac_params(struct oxygen *chip, 384 struct snd_pcm_hw_params *params) 385 { 386 struct xonar_wm87x6 *data = chip->model_data; 387 388 xonar_set_hdmi_params(chip, &data->hdmi, params); 389 } 390 391 static void update_wm8776_volume(struct oxygen *chip) 392 { 393 struct xonar_wm87x6 *data = chip->model_data; 394 u8 to_change; 395 396 if (chip->dac_volume[0] == chip->dac_volume[1]) { 397 if (chip->dac_volume[0] != data->wm8776_regs[WM8776_DACLVOL] || 398 chip->dac_volume[1] != data->wm8776_regs[WM8776_DACRVOL]) { 399 wm8776_write(chip, WM8776_DACMASTER, 400 chip->dac_volume[0] | WM8776_UPDATE); 401 data->wm8776_regs[WM8776_DACLVOL] = chip->dac_volume[0]; 402 data->wm8776_regs[WM8776_DACRVOL] = chip->dac_volume[0]; 403 } 404 } else { 405 to_change = (chip->dac_volume[0] != 406 data->wm8776_regs[WM8776_DACLVOL]) << 0; 407 to_change |= (chip->dac_volume[1] != 408 data->wm8776_regs[WM8776_DACLVOL]) << 1; 409 if (to_change & 1) 410 wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0] | 411 ((to_change & 2) ? 0 : WM8776_UPDATE)); 412 if (to_change & 2) 413 wm8776_write(chip, WM8776_DACRVOL, 414 chip->dac_volume[1] | WM8776_UPDATE); 415 } 416 } 417 418 static void update_wm87x6_volume(struct oxygen *chip) 419 { 420 static const u8 wm8766_regs[6] = { 421 WM8766_LDA1, WM8766_RDA1, 422 WM8766_LDA2, WM8766_RDA2, 423 WM8766_LDA3, WM8766_RDA3, 424 }; 425 struct xonar_wm87x6 *data = chip->model_data; 426 unsigned int i; 427 u8 to_change; 428 429 update_wm8776_volume(chip); 430 if (chip->dac_volume[2] == chip->dac_volume[3] && 431 chip->dac_volume[2] == chip->dac_volume[4] && 432 chip->dac_volume[2] == chip->dac_volume[5] && 433 chip->dac_volume[2] == chip->dac_volume[6] && 434 chip->dac_volume[2] == chip->dac_volume[7]) { 435 to_change = 0; 436 for (i = 0; i < 6; ++i) 437 if (chip->dac_volume[2] != 438 data->wm8766_regs[wm8766_regs[i]]) 439 to_change = 1; 440 if (to_change) { 441 wm8766_write(chip, WM8766_MASTDA, 442 chip->dac_volume[2] | WM8766_UPDATE); 443 for (i = 0; i < 6; ++i) 444 data->wm8766_regs[wm8766_regs[i]] = 445 chip->dac_volume[2]; 446 } 447 } else { 448 to_change = 0; 449 for (i = 0; i < 6; ++i) 450 to_change |= (chip->dac_volume[2 + i] != 451 data->wm8766_regs[wm8766_regs[i]]) << i; 452 for (i = 0; i < 6; ++i) 453 if (to_change & (1 << i)) 454 wm8766_write(chip, wm8766_regs[i], 455 chip->dac_volume[2 + i] | 456 ((to_change & (0x3e << i)) 457 ? 0 : WM8766_UPDATE)); 458 } 459 } 460 461 static void update_wm8776_mute(struct oxygen *chip) 462 { 463 wm8776_write_cached(chip, WM8776_DACMUTE, 464 chip->dac_mute ? WM8776_DMUTE : 0); 465 } 466 467 static void update_wm87x6_mute(struct oxygen *chip) 468 { 469 update_wm8776_mute(chip); 470 wm8766_write_cached(chip, WM8766_DAC_CTRL2, WM8766_ZCD | 471 (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); 472 } 473 474 static void update_wm8766_center_lfe_mix(struct oxygen *chip, bool mixed) 475 { 476 struct xonar_wm87x6 *data = chip->model_data; 477 unsigned int reg; 478 479 /* 480 * The WM8766 can mix left and right channels, but this setting 481 * applies to all three stereo pairs. 482 */ 483 reg = data->wm8766_regs[WM8766_DAC_CTRL] & 484 ~(WM8766_PL_LEFT_MASK | WM8766_PL_RIGHT_MASK); 485 if (mixed) 486 reg |= WM8766_PL_LEFT_LRMIX | WM8766_PL_RIGHT_LRMIX; 487 else 488 reg |= WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT; 489 wm8766_write_cached(chip, WM8766_DAC_CTRL, reg); 490 } 491 492 static void xonar_ds_gpio_changed(struct oxygen *chip) 493 { 494 xonar_ds_handle_hp_jack(chip); 495 } 496 497 static int wm8776_bit_switch_get(struct snd_kcontrol *ctl, 498 struct snd_ctl_elem_value *value) 499 { 500 struct oxygen *chip = ctl->private_data; 501 struct xonar_wm87x6 *data = chip->model_data; 502 u16 bit = ctl->private_value & 0xffff; 503 unsigned int reg_index = (ctl->private_value >> 16) & 0xff; 504 bool invert = (ctl->private_value >> 24) & 1; 505 506 value->value.integer.value[0] = 507 ((data->wm8776_regs[reg_index] & bit) != 0) ^ invert; 508 return 0; 509 } 510 511 static int wm8776_bit_switch_put(struct snd_kcontrol *ctl, 512 struct snd_ctl_elem_value *value) 513 { 514 struct oxygen *chip = ctl->private_data; 515 struct xonar_wm87x6 *data = chip->model_data; 516 u16 bit = ctl->private_value & 0xffff; 517 u16 reg_value; 518 unsigned int reg_index = (ctl->private_value >> 16) & 0xff; 519 bool invert = (ctl->private_value >> 24) & 1; 520 int changed; 521 522 mutex_lock(&chip->mutex); 523 reg_value = data->wm8776_regs[reg_index] & ~bit; 524 if (value->value.integer.value[0] ^ invert) 525 reg_value |= bit; 526 changed = reg_value != data->wm8776_regs[reg_index]; 527 if (changed) 528 wm8776_write(chip, reg_index, reg_value); 529 mutex_unlock(&chip->mutex); 530 return changed; 531 } 532 533 static int wm8776_field_enum_info(struct snd_kcontrol *ctl, 534 struct snd_ctl_elem_info *info) 535 { 536 static const char *const hld[16] = { 537 "0 ms", "2.67 ms", "5.33 ms", "10.6 ms", 538 "21.3 ms", "42.7 ms", "85.3 ms", "171 ms", 539 "341 ms", "683 ms", "1.37 s", "2.73 s", 540 "5.46 s", "10.9 s", "21.8 s", "43.7 s", 541 }; 542 static const char *const atk_lim[11] = { 543 "0.25 ms", "0.5 ms", "1 ms", "2 ms", 544 "4 ms", "8 ms", "16 ms", "32 ms", 545 "64 ms", "128 ms", "256 ms", 546 }; 547 static const char *const atk_alc[11] = { 548 "8.40 ms", "16.8 ms", "33.6 ms", "67.2 ms", 549 "134 ms", "269 ms", "538 ms", "1.08 s", 550 "2.15 s", "4.3 s", "8.6 s", 551 }; 552 static const char *const dcy_lim[11] = { 553 "1.2 ms", "2.4 ms", "4.8 ms", "9.6 ms", 554 "19.2 ms", "38.4 ms", "76.8 ms", "154 ms", 555 "307 ms", "614 ms", "1.23 s", 556 }; 557 static const char *const dcy_alc[11] = { 558 "33.5 ms", "67.0 ms", "134 ms", "268 ms", 559 "536 ms", "1.07 s", "2.14 s", "4.29 s", 560 "8.58 s", "17.2 s", "34.3 s", 561 }; 562 static const char *const tranwin[8] = { 563 "0 us", "62.5 us", "125 us", "250 us", 564 "500 us", "1 ms", "2 ms", "4 ms", 565 }; 566 u8 max; 567 const char *const *names; 568 569 max = (ctl->private_value >> 12) & 0xf; 570 switch ((ctl->private_value >> 24) & 0x1f) { 571 case WM8776_ALCCTRL2: 572 names = hld; 573 break; 574 case WM8776_ALCCTRL3: 575 if (((ctl->private_value >> 20) & 0xf) == 0) { 576 if (ctl->private_value & LC_CONTROL_LIMITER) 577 names = atk_lim; 578 else 579 names = atk_alc; 580 } else { 581 if (ctl->private_value & LC_CONTROL_LIMITER) 582 names = dcy_lim; 583 else 584 names = dcy_alc; 585 } 586 break; 587 case WM8776_LIMITER: 588 names = tranwin; 589 break; 590 default: 591 return -ENXIO; 592 } 593 return snd_ctl_enum_info(info, 1, max + 1, names); 594 } 595 596 static int wm8776_field_volume_info(struct snd_kcontrol *ctl, 597 struct snd_ctl_elem_info *info) 598 { 599 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 600 info->count = 1; 601 info->value.integer.min = (ctl->private_value >> 8) & 0xf; 602 info->value.integer.max = (ctl->private_value >> 12) & 0xf; 603 return 0; 604 } 605 606 static void wm8776_field_set_from_ctl(struct snd_kcontrol *ctl) 607 { 608 struct oxygen *chip = ctl->private_data; 609 struct xonar_wm87x6 *data = chip->model_data; 610 unsigned int value, reg_index, mode; 611 u8 min, max, shift; 612 u16 mask, reg_value; 613 bool invert; 614 615 if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) == 616 WM8776_LCSEL_LIMITER) 617 mode = LC_CONTROL_LIMITER; 618 else 619 mode = LC_CONTROL_ALC; 620 if (!(ctl->private_value & mode)) 621 return; 622 623 value = ctl->private_value & 0xf; 624 min = (ctl->private_value >> 8) & 0xf; 625 max = (ctl->private_value >> 12) & 0xf; 626 mask = (ctl->private_value >> 16) & 0xf; 627 shift = (ctl->private_value >> 20) & 0xf; 628 reg_index = (ctl->private_value >> 24) & 0x1f; 629 invert = (ctl->private_value >> 29) & 0x1; 630 631 if (invert) 632 value = max - (value - min); 633 reg_value = data->wm8776_regs[reg_index]; 634 reg_value &= ~(mask << shift); 635 reg_value |= value << shift; 636 wm8776_write_cached(chip, reg_index, reg_value); 637 } 638 639 static int wm8776_field_set(struct snd_kcontrol *ctl, unsigned int value) 640 { 641 struct oxygen *chip = ctl->private_data; 642 u8 min, max; 643 int changed; 644 645 min = (ctl->private_value >> 8) & 0xf; 646 max = (ctl->private_value >> 12) & 0xf; 647 if (value < min || value > max) 648 return -EINVAL; 649 mutex_lock(&chip->mutex); 650 changed = value != (ctl->private_value & 0xf); 651 if (changed) { 652 ctl->private_value = (ctl->private_value & ~0xf) | value; 653 wm8776_field_set_from_ctl(ctl); 654 } 655 mutex_unlock(&chip->mutex); 656 return changed; 657 } 658 659 static int wm8776_field_enum_get(struct snd_kcontrol *ctl, 660 struct snd_ctl_elem_value *value) 661 { 662 value->value.enumerated.item[0] = ctl->private_value & 0xf; 663 return 0; 664 } 665 666 static int wm8776_field_volume_get(struct snd_kcontrol *ctl, 667 struct snd_ctl_elem_value *value) 668 { 669 value->value.integer.value[0] = ctl->private_value & 0xf; 670 return 0; 671 } 672 673 static int wm8776_field_enum_put(struct snd_kcontrol *ctl, 674 struct snd_ctl_elem_value *value) 675 { 676 return wm8776_field_set(ctl, value->value.enumerated.item[0]); 677 } 678 679 static int wm8776_field_volume_put(struct snd_kcontrol *ctl, 680 struct snd_ctl_elem_value *value) 681 { 682 return wm8776_field_set(ctl, value->value.integer.value[0]); 683 } 684 685 static int wm8776_hp_vol_info(struct snd_kcontrol *ctl, 686 struct snd_ctl_elem_info *info) 687 { 688 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 689 info->count = 2; 690 info->value.integer.min = 0x79 - 60; 691 info->value.integer.max = 0x7f; 692 return 0; 693 } 694 695 static int wm8776_hp_vol_get(struct snd_kcontrol *ctl, 696 struct snd_ctl_elem_value *value) 697 { 698 struct oxygen *chip = ctl->private_data; 699 struct xonar_wm87x6 *data = chip->model_data; 700 701 mutex_lock(&chip->mutex); 702 value->value.integer.value[0] = 703 data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK; 704 value->value.integer.value[1] = 705 data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK; 706 mutex_unlock(&chip->mutex); 707 return 0; 708 } 709 710 static int wm8776_hp_vol_put(struct snd_kcontrol *ctl, 711 struct snd_ctl_elem_value *value) 712 { 713 struct oxygen *chip = ctl->private_data; 714 struct xonar_wm87x6 *data = chip->model_data; 715 u8 to_update; 716 717 mutex_lock(&chip->mutex); 718 to_update = (value->value.integer.value[0] != 719 (data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK)) 720 << 0; 721 to_update |= (value->value.integer.value[1] != 722 (data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK)) 723 << 1; 724 if (value->value.integer.value[0] == value->value.integer.value[1]) { 725 if (to_update) { 726 wm8776_write(chip, WM8776_HPMASTER, 727 value->value.integer.value[0] | 728 WM8776_HPZCEN | WM8776_UPDATE); 729 data->wm8776_regs[WM8776_HPLVOL] = 730 value->value.integer.value[0] | WM8776_HPZCEN; 731 data->wm8776_regs[WM8776_HPRVOL] = 732 value->value.integer.value[0] | WM8776_HPZCEN; 733 } 734 } else { 735 if (to_update & 1) 736 wm8776_write(chip, WM8776_HPLVOL, 737 value->value.integer.value[0] | 738 WM8776_HPZCEN | 739 ((to_update & 2) ? 0 : WM8776_UPDATE)); 740 if (to_update & 2) 741 wm8776_write(chip, WM8776_HPRVOL, 742 value->value.integer.value[1] | 743 WM8776_HPZCEN | WM8776_UPDATE); 744 } 745 mutex_unlock(&chip->mutex); 746 return to_update != 0; 747 } 748 749 static int wm8776_input_mux_get(struct snd_kcontrol *ctl, 750 struct snd_ctl_elem_value *value) 751 { 752 struct oxygen *chip = ctl->private_data; 753 struct xonar_wm87x6 *data = chip->model_data; 754 unsigned int mux_bit = ctl->private_value; 755 756 value->value.integer.value[0] = 757 !!(data->wm8776_regs[WM8776_ADCMUX] & mux_bit); 758 return 0; 759 } 760 761 static int wm8776_input_mux_put(struct snd_kcontrol *ctl, 762 struct snd_ctl_elem_value *value) 763 { 764 struct oxygen *chip = ctl->private_data; 765 struct xonar_wm87x6 *data = chip->model_data; 766 struct snd_kcontrol *other_ctl; 767 unsigned int mux_bit = ctl->private_value; 768 u16 reg; 769 int changed; 770 771 mutex_lock(&chip->mutex); 772 reg = data->wm8776_regs[WM8776_ADCMUX]; 773 if (value->value.integer.value[0]) { 774 reg |= mux_bit; 775 /* line-in and mic-in are exclusive */ 776 mux_bit ^= 3; 777 if (reg & mux_bit) { 778 reg &= ~mux_bit; 779 if (mux_bit == 1) 780 other_ctl = data->line_adcmux_control; 781 else 782 other_ctl = data->mic_adcmux_control; 783 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, 784 &other_ctl->id); 785 } 786 } else 787 reg &= ~mux_bit; 788 changed = reg != data->wm8776_regs[WM8776_ADCMUX]; 789 if (changed) { 790 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, 791 reg & 1 ? GPIO_DS_INPUT_ROUTE : 0, 792 GPIO_DS_INPUT_ROUTE); 793 wm8776_write(chip, WM8776_ADCMUX, reg); 794 } 795 mutex_unlock(&chip->mutex); 796 return changed; 797 } 798 799 static int wm8776_input_vol_info(struct snd_kcontrol *ctl, 800 struct snd_ctl_elem_info *info) 801 { 802 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 803 info->count = 2; 804 info->value.integer.min = 0xa5; 805 info->value.integer.max = 0xff; 806 return 0; 807 } 808 809 static int wm8776_input_vol_get(struct snd_kcontrol *ctl, 810 struct snd_ctl_elem_value *value) 811 { 812 struct oxygen *chip = ctl->private_data; 813 struct xonar_wm87x6 *data = chip->model_data; 814 815 mutex_lock(&chip->mutex); 816 value->value.integer.value[0] = 817 data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK; 818 value->value.integer.value[1] = 819 data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK; 820 mutex_unlock(&chip->mutex); 821 return 0; 822 } 823 824 static int wm8776_input_vol_put(struct snd_kcontrol *ctl, 825 struct snd_ctl_elem_value *value) 826 { 827 struct oxygen *chip = ctl->private_data; 828 struct xonar_wm87x6 *data = chip->model_data; 829 int changed = 0; 830 831 mutex_lock(&chip->mutex); 832 changed = (value->value.integer.value[0] != 833 (data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK)) || 834 (value->value.integer.value[1] != 835 (data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK)); 836 wm8776_write_cached(chip, WM8776_ADCLVOL, 837 value->value.integer.value[0] | WM8776_ZCA); 838 wm8776_write_cached(chip, WM8776_ADCRVOL, 839 value->value.integer.value[1] | WM8776_ZCA); 840 mutex_unlock(&chip->mutex); 841 return changed; 842 } 843 844 static int wm8776_level_control_info(struct snd_kcontrol *ctl, 845 struct snd_ctl_elem_info *info) 846 { 847 static const char *const names[3] = { 848 "None", "Peak Limiter", "Automatic Level Control" 849 }; 850 851 return snd_ctl_enum_info(info, 1, 3, names); 852 } 853 854 static int wm8776_level_control_get(struct snd_kcontrol *ctl, 855 struct snd_ctl_elem_value *value) 856 { 857 struct oxygen *chip = ctl->private_data; 858 struct xonar_wm87x6 *data = chip->model_data; 859 860 if (!(data->wm8776_regs[WM8776_ALCCTRL2] & WM8776_LCEN)) 861 value->value.enumerated.item[0] = 0; 862 else if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) == 863 WM8776_LCSEL_LIMITER) 864 value->value.enumerated.item[0] = 1; 865 else 866 value->value.enumerated.item[0] = 2; 867 return 0; 868 } 869 870 static void activate_control(struct oxygen *chip, 871 struct snd_kcontrol *ctl, unsigned int mode) 872 { 873 unsigned int access; 874 875 if (ctl->private_value & mode) 876 access = 0; 877 else 878 access = SNDRV_CTL_ELEM_ACCESS_INACTIVE; 879 if ((ctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE) != access) { 880 ctl->vd[0].access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE; 881 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); 882 } 883 } 884 885 static int wm8776_level_control_put(struct snd_kcontrol *ctl, 886 struct snd_ctl_elem_value *value) 887 { 888 struct oxygen *chip = ctl->private_data; 889 struct xonar_wm87x6 *data = chip->model_data; 890 unsigned int mode = 0, i; 891 u16 ctrl1, ctrl2; 892 int changed; 893 894 if (value->value.enumerated.item[0] >= 3) 895 return -EINVAL; 896 mutex_lock(&chip->mutex); 897 changed = value->value.enumerated.item[0] != ctl->private_value; 898 if (changed) { 899 ctl->private_value = value->value.enumerated.item[0]; 900 ctrl1 = data->wm8776_regs[WM8776_ALCCTRL1]; 901 ctrl2 = data->wm8776_regs[WM8776_ALCCTRL2]; 902 switch (value->value.enumerated.item[0]) { 903 default: 904 wm8776_write_cached(chip, WM8776_ALCCTRL2, 905 ctrl2 & ~WM8776_LCEN); 906 break; 907 case 1: 908 wm8776_write_cached(chip, WM8776_ALCCTRL1, 909 (ctrl1 & ~WM8776_LCSEL_MASK) | 910 WM8776_LCSEL_LIMITER); 911 wm8776_write_cached(chip, WM8776_ALCCTRL2, 912 ctrl2 | WM8776_LCEN); 913 mode = LC_CONTROL_LIMITER; 914 break; 915 case 2: 916 wm8776_write_cached(chip, WM8776_ALCCTRL1, 917 (ctrl1 & ~WM8776_LCSEL_MASK) | 918 WM8776_LCSEL_ALC_STEREO); 919 wm8776_write_cached(chip, WM8776_ALCCTRL2, 920 ctrl2 | WM8776_LCEN); 921 mode = LC_CONTROL_ALC; 922 break; 923 } 924 for (i = 0; i < ARRAY_SIZE(data->lc_controls); ++i) 925 activate_control(chip, data->lc_controls[i], mode); 926 } 927 mutex_unlock(&chip->mutex); 928 return changed; 929 } 930 931 static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) 932 { 933 static const char *const names[2] = { 934 "None", "High-pass Filter" 935 }; 936 937 return snd_ctl_enum_info(info, 1, 2, names); 938 } 939 940 static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 941 { 942 struct oxygen *chip = ctl->private_data; 943 struct xonar_wm87x6 *data = chip->model_data; 944 945 value->value.enumerated.item[0] = 946 !(data->wm8776_regs[WM8776_ADCIFCTRL] & WM8776_ADCHPD); 947 return 0; 948 } 949 950 static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 951 { 952 struct oxygen *chip = ctl->private_data; 953 struct xonar_wm87x6 *data = chip->model_data; 954 unsigned int reg; 955 int changed; 956 957 mutex_lock(&chip->mutex); 958 reg = data->wm8776_regs[WM8776_ADCIFCTRL] & ~WM8776_ADCHPD; 959 if (!value->value.enumerated.item[0]) 960 reg |= WM8776_ADCHPD; 961 changed = reg != data->wm8776_regs[WM8776_ADCIFCTRL]; 962 if (changed) 963 wm8776_write(chip, WM8776_ADCIFCTRL, reg); 964 mutex_unlock(&chip->mutex); 965 return changed; 966 } 967 968 #define WM8776_BIT_SWITCH(xname, reg, bit, invert, flags) { \ 969 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 970 .name = xname, \ 971 .info = snd_ctl_boolean_mono_info, \ 972 .get = wm8776_bit_switch_get, \ 973 .put = wm8776_bit_switch_put, \ 974 .private_value = ((reg) << 16) | (bit) | ((invert) << 24) | (flags), \ 975 } 976 #define _WM8776_FIELD_CTL(xname, reg, shift, initval, min, max, mask, flags) \ 977 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 978 .name = xname, \ 979 .private_value = (initval) | ((min) << 8) | ((max) << 12) | \ 980 ((mask) << 16) | ((shift) << 20) | ((reg) << 24) | (flags) 981 #define WM8776_FIELD_CTL_ENUM(xname, reg, shift, init, min, max, mask, flags) {\ 982 _WM8776_FIELD_CTL(xname " Capture Enum", \ 983 reg, shift, init, min, max, mask, flags), \ 984 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 985 SNDRV_CTL_ELEM_ACCESS_INACTIVE, \ 986 .info = wm8776_field_enum_info, \ 987 .get = wm8776_field_enum_get, \ 988 .put = wm8776_field_enum_put, \ 989 } 990 #define WM8776_FIELD_CTL_VOLUME(a, b, c, d, e, f, g, h, tlv_p) { \ 991 _WM8776_FIELD_CTL(a " Capture Volume", b, c, d, e, f, g, h), \ 992 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 993 SNDRV_CTL_ELEM_ACCESS_INACTIVE | \ 994 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ 995 .info = wm8776_field_volume_info, \ 996 .get = wm8776_field_volume_get, \ 997 .put = wm8776_field_volume_put, \ 998 .tlv = { .p = tlv_p }, \ 999 } 1000 1001 static const DECLARE_TLV_DB_SCALE(wm87x6_dac_db_scale, -6000, 50, 0); 1002 static const DECLARE_TLV_DB_SCALE(wm8776_adc_db_scale, -2100, 50, 0); 1003 static const DECLARE_TLV_DB_SCALE(wm8776_hp_db_scale, -6000, 100, 0); 1004 static const DECLARE_TLV_DB_SCALE(wm8776_lct_db_scale, -1600, 100, 0); 1005 static const DECLARE_TLV_DB_SCALE(wm8776_maxgain_db_scale, 0, 400, 0); 1006 static const DECLARE_TLV_DB_SCALE(wm8776_ngth_db_scale, -7800, 600, 0); 1007 static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_lim_db_scale, -1200, 100, 0); 1008 static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_alc_db_scale, -2100, 400, 0); 1009 1010 static const struct snd_kcontrol_new ds_controls[] = { 1011 { 1012 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1013 .name = "Headphone Playback Volume", 1014 .info = wm8776_hp_vol_info, 1015 .get = wm8776_hp_vol_get, 1016 .put = wm8776_hp_vol_put, 1017 .tlv = { .p = wm8776_hp_db_scale }, 1018 }, 1019 WM8776_BIT_SWITCH("Headphone Playback Switch", 1020 WM8776_PWRDOWN, WM8776_HPPD, 1, 0), 1021 { 1022 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1023 .name = "Input Capture Volume", 1024 .info = wm8776_input_vol_info, 1025 .get = wm8776_input_vol_get, 1026 .put = wm8776_input_vol_put, 1027 .tlv = { .p = wm8776_adc_db_scale }, 1028 }, 1029 { 1030 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1031 .name = "Line Capture Switch", 1032 .info = snd_ctl_boolean_mono_info, 1033 .get = wm8776_input_mux_get, 1034 .put = wm8776_input_mux_put, 1035 .private_value = 1 << 0, 1036 }, 1037 { 1038 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1039 .name = "Mic Capture Switch", 1040 .info = snd_ctl_boolean_mono_info, 1041 .get = wm8776_input_mux_get, 1042 .put = wm8776_input_mux_put, 1043 .private_value = 1 << 1, 1044 }, 1045 WM8776_BIT_SWITCH("Front Mic Capture Switch", 1046 WM8776_ADCMUX, 1 << 2, 0, 0), 1047 WM8776_BIT_SWITCH("Aux Capture Switch", 1048 WM8776_ADCMUX, 1 << 3, 0, 0), 1049 { 1050 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1051 .name = "ADC Filter Capture Enum", 1052 .info = hpf_info, 1053 .get = hpf_get, 1054 .put = hpf_put, 1055 }, 1056 { 1057 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1058 .name = "Level Control Capture Enum", 1059 .info = wm8776_level_control_info, 1060 .get = wm8776_level_control_get, 1061 .put = wm8776_level_control_put, 1062 .private_value = 0, 1063 }, 1064 }; 1065 static const struct snd_kcontrol_new hdav_slim_controls[] = { 1066 { 1067 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1068 .name = "HDMI Playback Switch", 1069 .info = snd_ctl_boolean_mono_info, 1070 .get = xonar_gpio_bit_switch_get, 1071 .put = xonar_gpio_bit_switch_put, 1072 .private_value = GPIO_SLIM_HDMI_DISABLE | XONAR_GPIO_BIT_INVERT, 1073 }, 1074 { 1075 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1076 .name = "Headphone Playback Volume", 1077 .info = wm8776_hp_vol_info, 1078 .get = wm8776_hp_vol_get, 1079 .put = wm8776_hp_vol_put, 1080 .tlv = { .p = wm8776_hp_db_scale }, 1081 }, 1082 WM8776_BIT_SWITCH("Headphone Playback Switch", 1083 WM8776_PWRDOWN, WM8776_HPPD, 1, 0), 1084 { 1085 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1086 .name = "Input Capture Volume", 1087 .info = wm8776_input_vol_info, 1088 .get = wm8776_input_vol_get, 1089 .put = wm8776_input_vol_put, 1090 .tlv = { .p = wm8776_adc_db_scale }, 1091 }, 1092 WM8776_BIT_SWITCH("Mic Capture Switch", 1093 WM8776_ADCMUX, 1 << 0, 0, 0), 1094 WM8776_BIT_SWITCH("Aux Capture Switch", 1095 WM8776_ADCMUX, 1 << 1, 0, 0), 1096 { 1097 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1098 .name = "ADC Filter Capture Enum", 1099 .info = hpf_info, 1100 .get = hpf_get, 1101 .put = hpf_put, 1102 }, 1103 { 1104 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1105 .name = "Level Control Capture Enum", 1106 .info = wm8776_level_control_info, 1107 .get = wm8776_level_control_get, 1108 .put = wm8776_level_control_put, 1109 .private_value = 0, 1110 }, 1111 }; 1112 static const struct snd_kcontrol_new lc_controls[] = { 1113 WM8776_FIELD_CTL_VOLUME("Limiter Threshold", 1114 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf, 1115 LC_CONTROL_LIMITER, wm8776_lct_db_scale), 1116 WM8776_FIELD_CTL_ENUM("Limiter Attack Time", 1117 WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf, 1118 LC_CONTROL_LIMITER), 1119 WM8776_FIELD_CTL_ENUM("Limiter Decay Time", 1120 WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf, 1121 LC_CONTROL_LIMITER), 1122 WM8776_FIELD_CTL_ENUM("Limiter Transient Window", 1123 WM8776_LIMITER, 4, 2, 0, 7, 0x7, 1124 LC_CONTROL_LIMITER), 1125 WM8776_FIELD_CTL_VOLUME("Limiter Maximum Attenuation", 1126 WM8776_LIMITER, 0, 6, 3, 12, 0xf, 1127 LC_CONTROL_LIMITER, 1128 wm8776_maxatten_lim_db_scale), 1129 WM8776_FIELD_CTL_VOLUME("ALC Target Level", 1130 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf, 1131 LC_CONTROL_ALC, wm8776_lct_db_scale), 1132 WM8776_FIELD_CTL_ENUM("ALC Attack Time", 1133 WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf, 1134 LC_CONTROL_ALC), 1135 WM8776_FIELD_CTL_ENUM("ALC Decay Time", 1136 WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf, 1137 LC_CONTROL_ALC), 1138 WM8776_FIELD_CTL_VOLUME("ALC Maximum Gain", 1139 WM8776_ALCCTRL1, 4, 7, 1, 7, 0x7, 1140 LC_CONTROL_ALC, wm8776_maxgain_db_scale), 1141 WM8776_FIELD_CTL_VOLUME("ALC Maximum Attenuation", 1142 WM8776_LIMITER, 0, 10, 10, 15, 0xf, 1143 LC_CONTROL_ALC, wm8776_maxatten_alc_db_scale), 1144 WM8776_FIELD_CTL_ENUM("ALC Hold Time", 1145 WM8776_ALCCTRL2, 0, 0, 0, 15, 0xf, 1146 LC_CONTROL_ALC), 1147 WM8776_BIT_SWITCH("Noise Gate Capture Switch", 1148 WM8776_NOISEGATE, WM8776_NGAT, 0, 1149 LC_CONTROL_ALC), 1150 WM8776_FIELD_CTL_VOLUME("Noise Gate Threshold", 1151 WM8776_NOISEGATE, 2, 0, 0, 7, 0x7, 1152 LC_CONTROL_ALC, wm8776_ngth_db_scale), 1153 }; 1154 1155 static int add_lc_controls(struct oxygen *chip) 1156 { 1157 struct xonar_wm87x6 *data = chip->model_data; 1158 unsigned int i; 1159 struct snd_kcontrol *ctl; 1160 int err; 1161 1162 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls)); 1163 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) { 1164 ctl = snd_ctl_new1(&lc_controls[i], chip); 1165 if (!ctl) 1166 return -ENOMEM; 1167 err = snd_ctl_add(chip->card, ctl); 1168 if (err < 0) 1169 return err; 1170 data->lc_controls[i] = ctl; 1171 } 1172 return 0; 1173 } 1174 1175 static int xonar_ds_mixer_init(struct oxygen *chip) 1176 { 1177 struct xonar_wm87x6 *data = chip->model_data; 1178 unsigned int i; 1179 struct snd_kcontrol *ctl; 1180 int err; 1181 1182 for (i = 0; i < ARRAY_SIZE(ds_controls); ++i) { 1183 ctl = snd_ctl_new1(&ds_controls[i], chip); 1184 if (!ctl) 1185 return -ENOMEM; 1186 err = snd_ctl_add(chip->card, ctl); 1187 if (err < 0) 1188 return err; 1189 if (!strcmp(ctl->id.name, "Line Capture Switch")) 1190 data->line_adcmux_control = ctl; 1191 else if (!strcmp(ctl->id.name, "Mic Capture Switch")) 1192 data->mic_adcmux_control = ctl; 1193 } 1194 if (!data->line_adcmux_control || !data->mic_adcmux_control) 1195 return -ENXIO; 1196 1197 return add_lc_controls(chip); 1198 } 1199 1200 static int xonar_hdav_slim_mixer_init(struct oxygen *chip) 1201 { 1202 unsigned int i; 1203 struct snd_kcontrol *ctl; 1204 int err; 1205 1206 for (i = 0; i < ARRAY_SIZE(hdav_slim_controls); ++i) { 1207 ctl = snd_ctl_new1(&hdav_slim_controls[i], chip); 1208 if (!ctl) 1209 return -ENOMEM; 1210 err = snd_ctl_add(chip->card, ctl); 1211 if (err < 0) 1212 return err; 1213 } 1214 1215 return add_lc_controls(chip); 1216 } 1217 1218 static void dump_wm8776_registers(struct oxygen *chip, 1219 struct snd_info_buffer *buffer) 1220 { 1221 struct xonar_wm87x6 *data = chip->model_data; 1222 unsigned int i; 1223 1224 snd_iprintf(buffer, "\nWM8776:\n00:"); 1225 for (i = 0; i < 0x10; ++i) 1226 snd_iprintf(buffer, " %03x", data->wm8776_regs[i]); 1227 snd_iprintf(buffer, "\n10:"); 1228 for (i = 0x10; i < 0x17; ++i) 1229 snd_iprintf(buffer, " %03x", data->wm8776_regs[i]); 1230 snd_iprintf(buffer, "\n"); 1231 } 1232 1233 static void dump_wm87x6_registers(struct oxygen *chip, 1234 struct snd_info_buffer *buffer) 1235 { 1236 struct xonar_wm87x6 *data = chip->model_data; 1237 unsigned int i; 1238 1239 dump_wm8776_registers(chip, buffer); 1240 snd_iprintf(buffer, "\nWM8766:\n00:"); 1241 for (i = 0; i < 0x10; ++i) 1242 snd_iprintf(buffer, " %03x", data->wm8766_regs[i]); 1243 snd_iprintf(buffer, "\n"); 1244 } 1245 1246 static const struct oxygen_model model_xonar_ds = { 1247 .longname = "Asus Virtuoso 66", 1248 .chip = "AV200", 1249 .init = xonar_ds_init, 1250 .mixer_init = xonar_ds_mixer_init, 1251 .cleanup = xonar_ds_cleanup, 1252 .suspend = xonar_ds_suspend, 1253 .resume = xonar_ds_resume, 1254 .pcm_hardware_filter = wm8776_adc_hardware_filter, 1255 .set_dac_params = set_wm87x6_dac_params, 1256 .set_adc_params = set_wm8776_adc_params, 1257 .update_dac_volume = update_wm87x6_volume, 1258 .update_dac_mute = update_wm87x6_mute, 1259 .update_center_lfe_mix = update_wm8766_center_lfe_mix, 1260 .gpio_changed = xonar_ds_gpio_changed, 1261 .dump_registers = dump_wm87x6_registers, 1262 .dac_tlv = wm87x6_dac_db_scale, 1263 .model_data_size = sizeof(struct xonar_wm87x6), 1264 .device_config = PLAYBACK_0_TO_I2S | 1265 PLAYBACK_1_TO_SPDIF | 1266 CAPTURE_0_FROM_I2S_1 | 1267 CAPTURE_1_FROM_SPDIF, 1268 .dac_channels_pcm = 8, 1269 .dac_channels_mixer = 8, 1270 .dac_volume_min = 255 - 2*60, 1271 .dac_volume_max = 255, 1272 .function_flags = OXYGEN_FUNCTION_SPI, 1273 .dac_mclks = OXYGEN_MCLKS(256, 256, 128), 1274 .adc_mclks = OXYGEN_MCLKS(256, 256, 128), 1275 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1276 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1277 }; 1278 1279 static const struct oxygen_model model_xonar_hdav_slim = { 1280 .shortname = "Xonar HDAV1.3 Slim", 1281 .longname = "Asus Virtuoso 200", 1282 .chip = "AV200", 1283 .init = xonar_hdav_slim_init, 1284 .mixer_init = xonar_hdav_slim_mixer_init, 1285 .cleanup = xonar_hdav_slim_cleanup, 1286 .suspend = xonar_hdav_slim_suspend, 1287 .resume = xonar_hdav_slim_resume, 1288 .pcm_hardware_filter = xonar_hdav_slim_hardware_filter, 1289 .set_dac_params = set_hdav_slim_dac_params, 1290 .set_adc_params = set_wm8776_adc_params, 1291 .update_dac_volume = update_wm8776_volume, 1292 .update_dac_mute = update_wm8776_mute, 1293 .uart_input = xonar_hdmi_uart_input, 1294 .dump_registers = dump_wm8776_registers, 1295 .dac_tlv = wm87x6_dac_db_scale, 1296 .model_data_size = sizeof(struct xonar_wm87x6), 1297 .device_config = PLAYBACK_0_TO_I2S | 1298 PLAYBACK_1_TO_SPDIF | 1299 CAPTURE_0_FROM_I2S_1 | 1300 CAPTURE_1_FROM_SPDIF, 1301 .dac_channels_pcm = 8, 1302 .dac_channels_mixer = 2, 1303 .dac_volume_min = 255 - 2*60, 1304 .dac_volume_max = 255, 1305 .function_flags = OXYGEN_FUNCTION_2WIRE, 1306 .dac_mclks = OXYGEN_MCLKS(256, 256, 128), 1307 .adc_mclks = OXYGEN_MCLKS(256, 256, 128), 1308 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1309 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1310 }; 1311 1312 int get_xonar_wm87x6_model(struct oxygen *chip, 1313 const struct pci_device_id *id) 1314 { 1315 switch (id->subdevice) { 1316 case 0x838e: 1317 chip->model = model_xonar_ds; 1318 chip->model.shortname = "Xonar DS"; 1319 break; 1320 case 0x8522: 1321 chip->model = model_xonar_ds; 1322 chip->model.shortname = "Xonar DSX"; 1323 break; 1324 case 0x835e: 1325 chip->model = model_xonar_hdav_slim; 1326 break; 1327 default: 1328 return -EINVAL; 1329 } 1330 return 0; 1331 } 1332