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 /* reg >= WM8776_HPLVOL is always true */ 120 if (reg <= WM8776_DACMASTER) 121 value &= ~WM8776_UPDATE; 122 data->wm8776_regs[reg] = value; 123 } 124 } 125 126 static void wm8776_write_cached(struct oxygen *chip, 127 unsigned int reg, unsigned int value) 128 { 129 struct xonar_wm87x6 *data = chip->model_data; 130 131 if (reg >= ARRAY_SIZE(data->wm8776_regs) || 132 value != data->wm8776_regs[reg]) 133 wm8776_write(chip, reg, value); 134 } 135 136 static void wm8766_write(struct oxygen *chip, 137 unsigned int reg, unsigned int value) 138 { 139 struct xonar_wm87x6 *data = chip->model_data; 140 141 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | 142 OXYGEN_SPI_DATA_LENGTH_2 | 143 OXYGEN_SPI_CLOCK_160 | 144 (0 << OXYGEN_SPI_CODEC_SHIFT) | 145 OXYGEN_SPI_CEN_LATCH_CLOCK_LO, 146 (reg << 9) | value); 147 if (reg < ARRAY_SIZE(data->wm8766_regs)) { 148 /* reg >= WM8766_LDA1 is always true */ 149 if (reg <= WM8766_RDA1 || 150 (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA)) 151 value &= ~WM8766_UPDATE; 152 data->wm8766_regs[reg] = value; 153 } 154 } 155 156 static void wm8766_write_cached(struct oxygen *chip, 157 unsigned int reg, unsigned int value) 158 { 159 struct xonar_wm87x6 *data = chip->model_data; 160 161 if (reg >= ARRAY_SIZE(data->wm8766_regs) || 162 value != data->wm8766_regs[reg]) 163 wm8766_write(chip, reg, value); 164 } 165 166 static void wm8776_registers_init(struct oxygen *chip) 167 { 168 struct xonar_wm87x6 *data = chip->model_data; 169 170 wm8776_write(chip, WM8776_RESET, 0); 171 wm8776_write(chip, WM8776_PHASESWAP, WM8776_PH_MASK); 172 wm8776_write(chip, WM8776_DACCTRL1, WM8776_DZCEN | 173 WM8776_PL_LEFT_LEFT | WM8776_PL_RIGHT_RIGHT); 174 wm8776_write(chip, WM8776_DACMUTE, chip->dac_mute ? WM8776_DMUTE : 0); 175 wm8776_write(chip, WM8776_DACIFCTRL, 176 WM8776_DACFMT_LJUST | WM8776_DACWL_24); 177 wm8776_write(chip, WM8776_ADCIFCTRL, 178 data->wm8776_regs[WM8776_ADCIFCTRL]); 179 wm8776_write(chip, WM8776_MSTRCTRL, data->wm8776_regs[WM8776_MSTRCTRL]); 180 wm8776_write(chip, WM8776_PWRDOWN, data->wm8776_regs[WM8776_PWRDOWN]); 181 wm8776_write(chip, WM8776_HPLVOL, data->wm8776_regs[WM8776_HPLVOL]); 182 wm8776_write(chip, WM8776_HPRVOL, data->wm8776_regs[WM8776_HPRVOL] | 183 WM8776_UPDATE); 184 wm8776_write(chip, WM8776_ADCLVOL, data->wm8776_regs[WM8776_ADCLVOL]); 185 wm8776_write(chip, WM8776_ADCRVOL, data->wm8776_regs[WM8776_ADCRVOL]); 186 wm8776_write(chip, WM8776_ADCMUX, data->wm8776_regs[WM8776_ADCMUX]); 187 wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0]); 188 wm8776_write(chip, WM8776_DACRVOL, chip->dac_volume[1] | WM8776_UPDATE); 189 } 190 191 static void wm8766_registers_init(struct oxygen *chip) 192 { 193 struct xonar_wm87x6 *data = chip->model_data; 194 195 wm8766_write(chip, WM8766_RESET, 0); 196 wm8766_write(chip, WM8766_DAC_CTRL, data->wm8766_regs[WM8766_DAC_CTRL]); 197 wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24); 198 wm8766_write(chip, WM8766_DAC_CTRL2, 199 WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); 200 wm8766_write(chip, WM8766_LDA1, chip->dac_volume[2]); 201 wm8766_write(chip, WM8766_RDA1, chip->dac_volume[3]); 202 wm8766_write(chip, WM8766_LDA2, chip->dac_volume[4]); 203 wm8766_write(chip, WM8766_RDA2, chip->dac_volume[5]); 204 wm8766_write(chip, WM8766_LDA3, chip->dac_volume[6]); 205 wm8766_write(chip, WM8766_RDA3, chip->dac_volume[7] | WM8766_UPDATE); 206 } 207 208 static void wm8776_init(struct oxygen *chip) 209 { 210 struct xonar_wm87x6 *data = chip->model_data; 211 212 data->wm8776_regs[WM8776_HPLVOL] = (0x79 - 60) | WM8776_HPZCEN; 213 data->wm8776_regs[WM8776_HPRVOL] = (0x79 - 60) | WM8776_HPZCEN; 214 data->wm8776_regs[WM8776_ADCIFCTRL] = 215 WM8776_ADCFMT_LJUST | WM8776_ADCWL_24 | WM8776_ADCMCLK; 216 data->wm8776_regs[WM8776_MSTRCTRL] = 217 WM8776_ADCRATE_256 | WM8776_DACRATE_256; 218 data->wm8776_regs[WM8776_PWRDOWN] = WM8776_HPPD; 219 data->wm8776_regs[WM8776_ADCLVOL] = 0xa5 | WM8776_ZCA; 220 data->wm8776_regs[WM8776_ADCRVOL] = 0xa5 | WM8776_ZCA; 221 data->wm8776_regs[WM8776_ADCMUX] = 0x001; 222 wm8776_registers_init(chip); 223 } 224 225 static void wm8766_init(struct oxygen *chip) 226 { 227 struct xonar_wm87x6 *data = chip->model_data; 228 229 data->wm8766_regs[WM8766_DAC_CTRL] = 230 WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT; 231 wm8766_registers_init(chip); 232 } 233 234 static void xonar_ds_handle_hp_jack(struct oxygen *chip) 235 { 236 struct xonar_wm87x6 *data = chip->model_data; 237 bool hp_plugged; 238 unsigned int reg; 239 240 guard(mutex)(&chip->mutex); 241 242 hp_plugged = !(oxygen_read16(chip, OXYGEN_GPIO_DATA) & 243 GPIO_DS_HP_DETECT); 244 245 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, 246 hp_plugged ? 0 : GPIO_DS_OUTPUT_FRONTLR, 247 GPIO_DS_OUTPUT_FRONTLR); 248 249 reg = data->wm8766_regs[WM8766_DAC_CTRL] & ~WM8766_MUTEALL; 250 if (hp_plugged) 251 reg |= WM8766_MUTEALL; 252 wm8766_write_cached(chip, WM8766_DAC_CTRL, reg); 253 254 snd_jack_report(data->hp_jack, hp_plugged ? SND_JACK_HEADPHONE : 0); 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 guard(mutex)(&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 return changed; 530 } 531 532 static int wm8776_field_enum_info(struct snd_kcontrol *ctl, 533 struct snd_ctl_elem_info *info) 534 { 535 static const char *const hld[16] = { 536 "0 ms", "2.67 ms", "5.33 ms", "10.6 ms", 537 "21.3 ms", "42.7 ms", "85.3 ms", "171 ms", 538 "341 ms", "683 ms", "1.37 s", "2.73 s", 539 "5.46 s", "10.9 s", "21.8 s", "43.7 s", 540 }; 541 static const char *const atk_lim[11] = { 542 "0.25 ms", "0.5 ms", "1 ms", "2 ms", 543 "4 ms", "8 ms", "16 ms", "32 ms", 544 "64 ms", "128 ms", "256 ms", 545 }; 546 static const char *const atk_alc[11] = { 547 "8.40 ms", "16.8 ms", "33.6 ms", "67.2 ms", 548 "134 ms", "269 ms", "538 ms", "1.08 s", 549 "2.15 s", "4.3 s", "8.6 s", 550 }; 551 static const char *const dcy_lim[11] = { 552 "1.2 ms", "2.4 ms", "4.8 ms", "9.6 ms", 553 "19.2 ms", "38.4 ms", "76.8 ms", "154 ms", 554 "307 ms", "614 ms", "1.23 s", 555 }; 556 static const char *const dcy_alc[11] = { 557 "33.5 ms", "67.0 ms", "134 ms", "268 ms", 558 "536 ms", "1.07 s", "2.14 s", "4.29 s", 559 "8.58 s", "17.2 s", "34.3 s", 560 }; 561 static const char *const tranwin[8] = { 562 "0 us", "62.5 us", "125 us", "250 us", 563 "500 us", "1 ms", "2 ms", "4 ms", 564 }; 565 u8 max; 566 const char *const *names; 567 568 max = (ctl->private_value >> 12) & 0xf; 569 switch ((ctl->private_value >> 24) & 0x1f) { 570 case WM8776_ALCCTRL2: 571 names = hld; 572 break; 573 case WM8776_ALCCTRL3: 574 if (((ctl->private_value >> 20) & 0xf) == 0) { 575 if (ctl->private_value & LC_CONTROL_LIMITER) 576 names = atk_lim; 577 else 578 names = atk_alc; 579 } else { 580 if (ctl->private_value & LC_CONTROL_LIMITER) 581 names = dcy_lim; 582 else 583 names = dcy_alc; 584 } 585 break; 586 case WM8776_LIMITER: 587 names = tranwin; 588 break; 589 default: 590 return -ENXIO; 591 } 592 return snd_ctl_enum_info(info, 1, max + 1, names); 593 } 594 595 static int wm8776_field_volume_info(struct snd_kcontrol *ctl, 596 struct snd_ctl_elem_info *info) 597 { 598 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 599 info->count = 1; 600 info->value.integer.min = (ctl->private_value >> 8) & 0xf; 601 info->value.integer.max = (ctl->private_value >> 12) & 0xf; 602 return 0; 603 } 604 605 static void wm8776_field_set_from_ctl(struct snd_kcontrol *ctl) 606 { 607 struct oxygen *chip = ctl->private_data; 608 struct xonar_wm87x6 *data = chip->model_data; 609 unsigned int value, reg_index, mode; 610 u8 min, max, shift; 611 u16 mask, reg_value; 612 bool invert; 613 614 if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) == 615 WM8776_LCSEL_LIMITER) 616 mode = LC_CONTROL_LIMITER; 617 else 618 mode = LC_CONTROL_ALC; 619 if (!(ctl->private_value & mode)) 620 return; 621 622 value = ctl->private_value & 0xf; 623 min = (ctl->private_value >> 8) & 0xf; 624 max = (ctl->private_value >> 12) & 0xf; 625 mask = (ctl->private_value >> 16) & 0xf; 626 shift = (ctl->private_value >> 20) & 0xf; 627 reg_index = (ctl->private_value >> 24) & 0x1f; 628 invert = (ctl->private_value >> 29) & 0x1; 629 630 if (invert) 631 value = max - (value - min); 632 reg_value = data->wm8776_regs[reg_index]; 633 reg_value &= ~(mask << shift); 634 reg_value |= value << shift; 635 wm8776_write_cached(chip, reg_index, reg_value); 636 } 637 638 static int wm8776_field_set(struct snd_kcontrol *ctl, unsigned int value) 639 { 640 struct oxygen *chip = ctl->private_data; 641 u8 min, max; 642 int changed; 643 644 min = (ctl->private_value >> 8) & 0xf; 645 max = (ctl->private_value >> 12) & 0xf; 646 if (value < min || value > max) 647 return -EINVAL; 648 guard(mutex)(&chip->mutex); 649 changed = value != (ctl->private_value & 0xf); 650 if (changed) { 651 ctl->private_value = (ctl->private_value & ~0xf) | value; 652 wm8776_field_set_from_ctl(ctl); 653 } 654 return changed; 655 } 656 657 static int wm8776_field_enum_get(struct snd_kcontrol *ctl, 658 struct snd_ctl_elem_value *value) 659 { 660 value->value.enumerated.item[0] = ctl->private_value & 0xf; 661 return 0; 662 } 663 664 static int wm8776_field_volume_get(struct snd_kcontrol *ctl, 665 struct snd_ctl_elem_value *value) 666 { 667 value->value.integer.value[0] = ctl->private_value & 0xf; 668 return 0; 669 } 670 671 static int wm8776_field_enum_put(struct snd_kcontrol *ctl, 672 struct snd_ctl_elem_value *value) 673 { 674 return wm8776_field_set(ctl, value->value.enumerated.item[0]); 675 } 676 677 static int wm8776_field_volume_put(struct snd_kcontrol *ctl, 678 struct snd_ctl_elem_value *value) 679 { 680 return wm8776_field_set(ctl, value->value.integer.value[0]); 681 } 682 683 static int wm8776_hp_vol_info(struct snd_kcontrol *ctl, 684 struct snd_ctl_elem_info *info) 685 { 686 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 687 info->count = 2; 688 info->value.integer.min = 0x79 - 60; 689 info->value.integer.max = 0x7f; 690 return 0; 691 } 692 693 static int wm8776_hp_vol_get(struct snd_kcontrol *ctl, 694 struct snd_ctl_elem_value *value) 695 { 696 struct oxygen *chip = ctl->private_data; 697 struct xonar_wm87x6 *data = chip->model_data; 698 699 guard(mutex)(&chip->mutex); 700 value->value.integer.value[0] = 701 data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK; 702 value->value.integer.value[1] = 703 data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK; 704 return 0; 705 } 706 707 static int wm8776_hp_vol_put(struct snd_kcontrol *ctl, 708 struct snd_ctl_elem_value *value) 709 { 710 struct oxygen *chip = ctl->private_data; 711 struct xonar_wm87x6 *data = chip->model_data; 712 u8 to_update; 713 714 guard(mutex)(&chip->mutex); 715 to_update = (value->value.integer.value[0] != 716 (data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK)) 717 << 0; 718 to_update |= (value->value.integer.value[1] != 719 (data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK)) 720 << 1; 721 if (value->value.integer.value[0] == value->value.integer.value[1]) { 722 if (to_update) { 723 wm8776_write(chip, WM8776_HPMASTER, 724 value->value.integer.value[0] | 725 WM8776_HPZCEN | WM8776_UPDATE); 726 data->wm8776_regs[WM8776_HPLVOL] = 727 value->value.integer.value[0] | WM8776_HPZCEN; 728 data->wm8776_regs[WM8776_HPRVOL] = 729 value->value.integer.value[0] | WM8776_HPZCEN; 730 } 731 } else { 732 if (to_update & 1) 733 wm8776_write(chip, WM8776_HPLVOL, 734 value->value.integer.value[0] | 735 WM8776_HPZCEN | 736 ((to_update & 2) ? 0 : WM8776_UPDATE)); 737 if (to_update & 2) 738 wm8776_write(chip, WM8776_HPRVOL, 739 value->value.integer.value[1] | 740 WM8776_HPZCEN | WM8776_UPDATE); 741 } 742 return to_update != 0; 743 } 744 745 static int wm8776_input_mux_get(struct snd_kcontrol *ctl, 746 struct snd_ctl_elem_value *value) 747 { 748 struct oxygen *chip = ctl->private_data; 749 struct xonar_wm87x6 *data = chip->model_data; 750 unsigned int mux_bit = ctl->private_value; 751 752 value->value.integer.value[0] = 753 !!(data->wm8776_regs[WM8776_ADCMUX] & mux_bit); 754 return 0; 755 } 756 757 static int wm8776_input_mux_put(struct snd_kcontrol *ctl, 758 struct snd_ctl_elem_value *value) 759 { 760 struct oxygen *chip = ctl->private_data; 761 struct xonar_wm87x6 *data = chip->model_data; 762 struct snd_kcontrol *other_ctl; 763 unsigned int mux_bit = ctl->private_value; 764 u16 reg; 765 int changed; 766 767 guard(mutex)(&chip->mutex); 768 reg = data->wm8776_regs[WM8776_ADCMUX]; 769 if (value->value.integer.value[0]) { 770 reg |= mux_bit; 771 /* line-in and mic-in are exclusive */ 772 mux_bit ^= 3; 773 if (reg & mux_bit) { 774 reg &= ~mux_bit; 775 if (mux_bit == 1) 776 other_ctl = data->line_adcmux_control; 777 else 778 other_ctl = data->mic_adcmux_control; 779 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, 780 &other_ctl->id); 781 } 782 } else 783 reg &= ~mux_bit; 784 changed = reg != data->wm8776_regs[WM8776_ADCMUX]; 785 if (changed) { 786 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, 787 reg & 1 ? GPIO_DS_INPUT_ROUTE : 0, 788 GPIO_DS_INPUT_ROUTE); 789 wm8776_write(chip, WM8776_ADCMUX, reg); 790 } 791 return changed; 792 } 793 794 static int wm8776_input_vol_info(struct snd_kcontrol *ctl, 795 struct snd_ctl_elem_info *info) 796 { 797 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 798 info->count = 2; 799 info->value.integer.min = 0xa5; 800 info->value.integer.max = 0xff; 801 return 0; 802 } 803 804 static int wm8776_input_vol_get(struct snd_kcontrol *ctl, 805 struct snd_ctl_elem_value *value) 806 { 807 struct oxygen *chip = ctl->private_data; 808 struct xonar_wm87x6 *data = chip->model_data; 809 810 guard(mutex)(&chip->mutex); 811 value->value.integer.value[0] = 812 data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK; 813 value->value.integer.value[1] = 814 data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK; 815 return 0; 816 } 817 818 static int wm8776_input_vol_put(struct snd_kcontrol *ctl, 819 struct snd_ctl_elem_value *value) 820 { 821 struct oxygen *chip = ctl->private_data; 822 struct xonar_wm87x6 *data = chip->model_data; 823 int changed = 0; 824 825 guard(mutex)(&chip->mutex); 826 changed = (value->value.integer.value[0] != 827 (data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK)) || 828 (value->value.integer.value[1] != 829 (data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK)); 830 wm8776_write_cached(chip, WM8776_ADCLVOL, 831 value->value.integer.value[0] | WM8776_ZCA); 832 wm8776_write_cached(chip, WM8776_ADCRVOL, 833 value->value.integer.value[1] | WM8776_ZCA); 834 return changed; 835 } 836 837 static int wm8776_level_control_info(struct snd_kcontrol *ctl, 838 struct snd_ctl_elem_info *info) 839 { 840 static const char *const names[3] = { 841 "None", "Peak Limiter", "Automatic Level Control" 842 }; 843 844 return snd_ctl_enum_info(info, 1, 3, names); 845 } 846 847 static int wm8776_level_control_get(struct snd_kcontrol *ctl, 848 struct snd_ctl_elem_value *value) 849 { 850 struct oxygen *chip = ctl->private_data; 851 struct xonar_wm87x6 *data = chip->model_data; 852 853 if (!(data->wm8776_regs[WM8776_ALCCTRL2] & WM8776_LCEN)) 854 value->value.enumerated.item[0] = 0; 855 else if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) == 856 WM8776_LCSEL_LIMITER) 857 value->value.enumerated.item[0] = 1; 858 else 859 value->value.enumerated.item[0] = 2; 860 return 0; 861 } 862 863 static void activate_control(struct oxygen *chip, 864 struct snd_kcontrol *ctl, unsigned int mode) 865 { 866 unsigned int access; 867 868 if (ctl->private_value & mode) 869 access = 0; 870 else 871 access = SNDRV_CTL_ELEM_ACCESS_INACTIVE; 872 if ((ctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE) != access) { 873 ctl->vd[0].access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE; 874 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); 875 } 876 } 877 878 static int wm8776_level_control_put(struct snd_kcontrol *ctl, 879 struct snd_ctl_elem_value *value) 880 { 881 struct oxygen *chip = ctl->private_data; 882 struct xonar_wm87x6 *data = chip->model_data; 883 unsigned int mode = 0, i; 884 u16 ctrl1, ctrl2; 885 int changed; 886 887 if (value->value.enumerated.item[0] >= 3) 888 return -EINVAL; 889 guard(mutex)(&chip->mutex); 890 changed = value->value.enumerated.item[0] != ctl->private_value; 891 if (changed) { 892 ctl->private_value = value->value.enumerated.item[0]; 893 ctrl1 = data->wm8776_regs[WM8776_ALCCTRL1]; 894 ctrl2 = data->wm8776_regs[WM8776_ALCCTRL2]; 895 switch (value->value.enumerated.item[0]) { 896 default: 897 wm8776_write_cached(chip, WM8776_ALCCTRL2, 898 ctrl2 & ~WM8776_LCEN); 899 break; 900 case 1: 901 wm8776_write_cached(chip, WM8776_ALCCTRL1, 902 (ctrl1 & ~WM8776_LCSEL_MASK) | 903 WM8776_LCSEL_LIMITER); 904 wm8776_write_cached(chip, WM8776_ALCCTRL2, 905 ctrl2 | WM8776_LCEN); 906 mode = LC_CONTROL_LIMITER; 907 break; 908 case 2: 909 wm8776_write_cached(chip, WM8776_ALCCTRL1, 910 (ctrl1 & ~WM8776_LCSEL_MASK) | 911 WM8776_LCSEL_ALC_STEREO); 912 wm8776_write_cached(chip, WM8776_ALCCTRL2, 913 ctrl2 | WM8776_LCEN); 914 mode = LC_CONTROL_ALC; 915 break; 916 } 917 for (i = 0; i < ARRAY_SIZE(data->lc_controls); ++i) 918 activate_control(chip, data->lc_controls[i], mode); 919 } 920 return changed; 921 } 922 923 static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) 924 { 925 static const char *const names[2] = { 926 "None", "High-pass Filter" 927 }; 928 929 return snd_ctl_enum_info(info, 1, 2, names); 930 } 931 932 static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 933 { 934 struct oxygen *chip = ctl->private_data; 935 struct xonar_wm87x6 *data = chip->model_data; 936 937 value->value.enumerated.item[0] = 938 !(data->wm8776_regs[WM8776_ADCIFCTRL] & WM8776_ADCHPD); 939 return 0; 940 } 941 942 static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 943 { 944 struct oxygen *chip = ctl->private_data; 945 struct xonar_wm87x6 *data = chip->model_data; 946 unsigned int reg; 947 int changed; 948 949 guard(mutex)(&chip->mutex); 950 reg = data->wm8776_regs[WM8776_ADCIFCTRL] & ~WM8776_ADCHPD; 951 if (!value->value.enumerated.item[0]) 952 reg |= WM8776_ADCHPD; 953 changed = reg != data->wm8776_regs[WM8776_ADCIFCTRL]; 954 if (changed) 955 wm8776_write(chip, WM8776_ADCIFCTRL, reg); 956 return changed; 957 } 958 959 #define WM8776_BIT_SWITCH(xname, reg, bit, invert, flags) { \ 960 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 961 .name = xname, \ 962 .info = snd_ctl_boolean_mono_info, \ 963 .get = wm8776_bit_switch_get, \ 964 .put = wm8776_bit_switch_put, \ 965 .private_value = ((reg) << 16) | (bit) | ((invert) << 24) | (flags), \ 966 } 967 #define _WM8776_FIELD_CTL(xname, reg, shift, initval, min, max, mask, flags) \ 968 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 969 .name = xname, \ 970 .private_value = (initval) | ((min) << 8) | ((max) << 12) | \ 971 ((mask) << 16) | ((shift) << 20) | ((reg) << 24) | (flags) 972 #define WM8776_FIELD_CTL_ENUM(xname, reg, shift, init, min, max, mask, flags) {\ 973 _WM8776_FIELD_CTL(xname " Capture Enum", \ 974 reg, shift, init, min, max, mask, flags), \ 975 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 976 SNDRV_CTL_ELEM_ACCESS_INACTIVE, \ 977 .info = wm8776_field_enum_info, \ 978 .get = wm8776_field_enum_get, \ 979 .put = wm8776_field_enum_put, \ 980 } 981 #define WM8776_FIELD_CTL_VOLUME(a, b, c, d, e, f, g, h, tlv_p) { \ 982 _WM8776_FIELD_CTL(a " Capture Volume", b, c, d, e, f, g, h), \ 983 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 984 SNDRV_CTL_ELEM_ACCESS_INACTIVE | \ 985 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ 986 .info = wm8776_field_volume_info, \ 987 .get = wm8776_field_volume_get, \ 988 .put = wm8776_field_volume_put, \ 989 .tlv = { .p = tlv_p }, \ 990 } 991 992 static const DECLARE_TLV_DB_SCALE(wm87x6_dac_db_scale, -6000, 50, 0); 993 static const DECLARE_TLV_DB_SCALE(wm8776_adc_db_scale, -2100, 50, 0); 994 static const DECLARE_TLV_DB_SCALE(wm8776_hp_db_scale, -6000, 100, 0); 995 static const DECLARE_TLV_DB_SCALE(wm8776_lct_db_scale, -1600, 100, 0); 996 static const DECLARE_TLV_DB_SCALE(wm8776_maxgain_db_scale, 0, 400, 0); 997 static const DECLARE_TLV_DB_SCALE(wm8776_ngth_db_scale, -7800, 600, 0); 998 static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_lim_db_scale, -1200, 100, 0); 999 static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_alc_db_scale, -2100, 400, 0); 1000 1001 static const struct snd_kcontrol_new ds_controls[] = { 1002 { 1003 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1004 .name = "Headphone Playback Volume", 1005 .info = wm8776_hp_vol_info, 1006 .get = wm8776_hp_vol_get, 1007 .put = wm8776_hp_vol_put, 1008 .tlv = { .p = wm8776_hp_db_scale }, 1009 }, 1010 WM8776_BIT_SWITCH("Headphone Playback Switch", 1011 WM8776_PWRDOWN, WM8776_HPPD, 1, 0), 1012 { 1013 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1014 .name = "Input Capture Volume", 1015 .info = wm8776_input_vol_info, 1016 .get = wm8776_input_vol_get, 1017 .put = wm8776_input_vol_put, 1018 .tlv = { .p = wm8776_adc_db_scale }, 1019 }, 1020 { 1021 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1022 .name = "Line Capture Switch", 1023 .info = snd_ctl_boolean_mono_info, 1024 .get = wm8776_input_mux_get, 1025 .put = wm8776_input_mux_put, 1026 .private_value = 1 << 0, 1027 }, 1028 { 1029 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1030 .name = "Mic Capture Switch", 1031 .info = snd_ctl_boolean_mono_info, 1032 .get = wm8776_input_mux_get, 1033 .put = wm8776_input_mux_put, 1034 .private_value = 1 << 1, 1035 }, 1036 WM8776_BIT_SWITCH("Front Mic Capture Switch", 1037 WM8776_ADCMUX, 1 << 2, 0, 0), 1038 WM8776_BIT_SWITCH("Aux Capture Switch", 1039 WM8776_ADCMUX, 1 << 3, 0, 0), 1040 { 1041 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1042 .name = "ADC Filter Capture Enum", 1043 .info = hpf_info, 1044 .get = hpf_get, 1045 .put = hpf_put, 1046 }, 1047 { 1048 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1049 .name = "Level Control Capture Enum", 1050 .info = wm8776_level_control_info, 1051 .get = wm8776_level_control_get, 1052 .put = wm8776_level_control_put, 1053 .private_value = 0, 1054 }, 1055 }; 1056 static const struct snd_kcontrol_new hdav_slim_controls[] = { 1057 { 1058 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1059 .name = "HDMI Playback Switch", 1060 .info = snd_ctl_boolean_mono_info, 1061 .get = xonar_gpio_bit_switch_get, 1062 .put = xonar_gpio_bit_switch_put, 1063 .private_value = GPIO_SLIM_HDMI_DISABLE | XONAR_GPIO_BIT_INVERT, 1064 }, 1065 { 1066 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1067 .name = "Headphone Playback Volume", 1068 .info = wm8776_hp_vol_info, 1069 .get = wm8776_hp_vol_get, 1070 .put = wm8776_hp_vol_put, 1071 .tlv = { .p = wm8776_hp_db_scale }, 1072 }, 1073 WM8776_BIT_SWITCH("Headphone Playback Switch", 1074 WM8776_PWRDOWN, WM8776_HPPD, 1, 0), 1075 { 1076 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1077 .name = "Input Capture Volume", 1078 .info = wm8776_input_vol_info, 1079 .get = wm8776_input_vol_get, 1080 .put = wm8776_input_vol_put, 1081 .tlv = { .p = wm8776_adc_db_scale }, 1082 }, 1083 WM8776_BIT_SWITCH("Mic Capture Switch", 1084 WM8776_ADCMUX, 1 << 0, 0, 0), 1085 WM8776_BIT_SWITCH("Aux Capture Switch", 1086 WM8776_ADCMUX, 1 << 1, 0, 0), 1087 { 1088 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1089 .name = "ADC Filter Capture Enum", 1090 .info = hpf_info, 1091 .get = hpf_get, 1092 .put = hpf_put, 1093 }, 1094 { 1095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1096 .name = "Level Control Capture Enum", 1097 .info = wm8776_level_control_info, 1098 .get = wm8776_level_control_get, 1099 .put = wm8776_level_control_put, 1100 .private_value = 0, 1101 }, 1102 }; 1103 static const struct snd_kcontrol_new lc_controls[] = { 1104 WM8776_FIELD_CTL_VOLUME("Limiter Threshold", 1105 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf, 1106 LC_CONTROL_LIMITER, wm8776_lct_db_scale), 1107 WM8776_FIELD_CTL_ENUM("Limiter Attack Time", 1108 WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf, 1109 LC_CONTROL_LIMITER), 1110 WM8776_FIELD_CTL_ENUM("Limiter Decay Time", 1111 WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf, 1112 LC_CONTROL_LIMITER), 1113 WM8776_FIELD_CTL_ENUM("Limiter Transient Window", 1114 WM8776_LIMITER, 4, 2, 0, 7, 0x7, 1115 LC_CONTROL_LIMITER), 1116 WM8776_FIELD_CTL_VOLUME("Limiter Maximum Attenuation", 1117 WM8776_LIMITER, 0, 6, 3, 12, 0xf, 1118 LC_CONTROL_LIMITER, 1119 wm8776_maxatten_lim_db_scale), 1120 WM8776_FIELD_CTL_VOLUME("ALC Target Level", 1121 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf, 1122 LC_CONTROL_ALC, wm8776_lct_db_scale), 1123 WM8776_FIELD_CTL_ENUM("ALC Attack Time", 1124 WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf, 1125 LC_CONTROL_ALC), 1126 WM8776_FIELD_CTL_ENUM("ALC Decay Time", 1127 WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf, 1128 LC_CONTROL_ALC), 1129 WM8776_FIELD_CTL_VOLUME("ALC Maximum Gain", 1130 WM8776_ALCCTRL1, 4, 7, 1, 7, 0x7, 1131 LC_CONTROL_ALC, wm8776_maxgain_db_scale), 1132 WM8776_FIELD_CTL_VOLUME("ALC Maximum Attenuation", 1133 WM8776_LIMITER, 0, 10, 10, 15, 0xf, 1134 LC_CONTROL_ALC, wm8776_maxatten_alc_db_scale), 1135 WM8776_FIELD_CTL_ENUM("ALC Hold Time", 1136 WM8776_ALCCTRL2, 0, 0, 0, 15, 0xf, 1137 LC_CONTROL_ALC), 1138 WM8776_BIT_SWITCH("Noise Gate Capture Switch", 1139 WM8776_NOISEGATE, WM8776_NGAT, 0, 1140 LC_CONTROL_ALC), 1141 WM8776_FIELD_CTL_VOLUME("Noise Gate Threshold", 1142 WM8776_NOISEGATE, 2, 0, 0, 7, 0x7, 1143 LC_CONTROL_ALC, wm8776_ngth_db_scale), 1144 }; 1145 1146 static int add_lc_controls(struct oxygen *chip) 1147 { 1148 struct xonar_wm87x6 *data = chip->model_data; 1149 unsigned int i; 1150 struct snd_kcontrol *ctl; 1151 int err; 1152 1153 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls)); 1154 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) { 1155 ctl = snd_ctl_new1(&lc_controls[i], chip); 1156 if (!ctl) 1157 return -ENOMEM; 1158 err = snd_ctl_add(chip->card, ctl); 1159 if (err < 0) 1160 return err; 1161 data->lc_controls[i] = ctl; 1162 } 1163 return 0; 1164 } 1165 1166 static int xonar_ds_mixer_init(struct oxygen *chip) 1167 { 1168 struct xonar_wm87x6 *data = chip->model_data; 1169 unsigned int i; 1170 struct snd_kcontrol *ctl; 1171 int err; 1172 1173 for (i = 0; i < ARRAY_SIZE(ds_controls); ++i) { 1174 ctl = snd_ctl_new1(&ds_controls[i], chip); 1175 if (!ctl) 1176 return -ENOMEM; 1177 err = snd_ctl_add(chip->card, ctl); 1178 if (err < 0) 1179 return err; 1180 if (!strcmp(ctl->id.name, "Line Capture Switch")) 1181 data->line_adcmux_control = ctl; 1182 else if (!strcmp(ctl->id.name, "Mic Capture Switch")) 1183 data->mic_adcmux_control = ctl; 1184 } 1185 if (!data->line_adcmux_control || !data->mic_adcmux_control) 1186 return -ENXIO; 1187 1188 return add_lc_controls(chip); 1189 } 1190 1191 static int xonar_hdav_slim_mixer_init(struct oxygen *chip) 1192 { 1193 unsigned int i; 1194 struct snd_kcontrol *ctl; 1195 int err; 1196 1197 for (i = 0; i < ARRAY_SIZE(hdav_slim_controls); ++i) { 1198 ctl = snd_ctl_new1(&hdav_slim_controls[i], chip); 1199 if (!ctl) 1200 return -ENOMEM; 1201 err = snd_ctl_add(chip->card, ctl); 1202 if (err < 0) 1203 return err; 1204 } 1205 1206 return add_lc_controls(chip); 1207 } 1208 1209 static void dump_wm8776_registers(struct oxygen *chip, 1210 struct snd_info_buffer *buffer) 1211 { 1212 struct xonar_wm87x6 *data = chip->model_data; 1213 unsigned int i; 1214 1215 snd_iprintf(buffer, "\nWM8776:\n00:"); 1216 for (i = 0; i < 0x10; ++i) 1217 snd_iprintf(buffer, " %03x", data->wm8776_regs[i]); 1218 snd_iprintf(buffer, "\n10:"); 1219 for (i = 0x10; i < 0x17; ++i) 1220 snd_iprintf(buffer, " %03x", data->wm8776_regs[i]); 1221 snd_iprintf(buffer, "\n"); 1222 } 1223 1224 static void dump_wm87x6_registers(struct oxygen *chip, 1225 struct snd_info_buffer *buffer) 1226 { 1227 struct xonar_wm87x6 *data = chip->model_data; 1228 unsigned int i; 1229 1230 dump_wm8776_registers(chip, buffer); 1231 snd_iprintf(buffer, "\nWM8766:\n00:"); 1232 for (i = 0; i < 0x10; ++i) 1233 snd_iprintf(buffer, " %03x", data->wm8766_regs[i]); 1234 snd_iprintf(buffer, "\n"); 1235 } 1236 1237 static const struct oxygen_model model_xonar_ds = { 1238 .longname = "Asus Virtuoso 66", 1239 .chip = "AV200", 1240 .init = xonar_ds_init, 1241 .mixer_init = xonar_ds_mixer_init, 1242 .cleanup = xonar_ds_cleanup, 1243 .suspend = xonar_ds_suspend, 1244 .resume = xonar_ds_resume, 1245 .pcm_hardware_filter = wm8776_adc_hardware_filter, 1246 .set_dac_params = set_wm87x6_dac_params, 1247 .set_adc_params = set_wm8776_adc_params, 1248 .update_dac_volume = update_wm87x6_volume, 1249 .update_dac_mute = update_wm87x6_mute, 1250 .update_center_lfe_mix = update_wm8766_center_lfe_mix, 1251 .gpio_changed = xonar_ds_gpio_changed, 1252 .dump_registers = dump_wm87x6_registers, 1253 .dac_tlv = wm87x6_dac_db_scale, 1254 .model_data_size = sizeof(struct xonar_wm87x6), 1255 .device_config = PLAYBACK_0_TO_I2S | 1256 PLAYBACK_1_TO_SPDIF | 1257 CAPTURE_0_FROM_I2S_1 | 1258 CAPTURE_1_FROM_SPDIF, 1259 .dac_channels_pcm = 8, 1260 .dac_channels_mixer = 8, 1261 .dac_volume_min = 255 - 2*60, 1262 .dac_volume_max = 255, 1263 .function_flags = OXYGEN_FUNCTION_SPI, 1264 .dac_mclks = OXYGEN_MCLKS(256, 256, 128), 1265 .adc_mclks = OXYGEN_MCLKS(256, 256, 128), 1266 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1267 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1268 }; 1269 1270 static const struct oxygen_model model_xonar_hdav_slim = { 1271 .shortname = "Xonar HDAV1.3 Slim", 1272 .longname = "Asus Virtuoso 200", 1273 .chip = "AV200", 1274 .init = xonar_hdav_slim_init, 1275 .mixer_init = xonar_hdav_slim_mixer_init, 1276 .cleanup = xonar_hdav_slim_cleanup, 1277 .suspend = xonar_hdav_slim_suspend, 1278 .resume = xonar_hdav_slim_resume, 1279 .pcm_hardware_filter = xonar_hdav_slim_hardware_filter, 1280 .set_dac_params = set_hdav_slim_dac_params, 1281 .set_adc_params = set_wm8776_adc_params, 1282 .update_dac_volume = update_wm8776_volume, 1283 .update_dac_mute = update_wm8776_mute, 1284 .uart_input = xonar_hdmi_uart_input, 1285 .dump_registers = dump_wm8776_registers, 1286 .dac_tlv = wm87x6_dac_db_scale, 1287 .model_data_size = sizeof(struct xonar_wm87x6), 1288 .device_config = PLAYBACK_0_TO_I2S | 1289 PLAYBACK_1_TO_SPDIF | 1290 CAPTURE_0_FROM_I2S_1 | 1291 CAPTURE_1_FROM_SPDIF, 1292 .dac_channels_pcm = 8, 1293 .dac_channels_mixer = 2, 1294 .dac_volume_min = 255 - 2*60, 1295 .dac_volume_max = 255, 1296 .function_flags = OXYGEN_FUNCTION_2WIRE, 1297 .dac_mclks = OXYGEN_MCLKS(256, 256, 128), 1298 .adc_mclks = OXYGEN_MCLKS(256, 256, 128), 1299 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1300 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1301 }; 1302 1303 int get_xonar_wm87x6_model(struct oxygen *chip, 1304 const struct pci_device_id *id) 1305 { 1306 switch (id->subdevice) { 1307 case 0x838e: 1308 chip->model = model_xonar_ds; 1309 chip->model.shortname = "Xonar DS"; 1310 break; 1311 case 0x8522: 1312 chip->model = model_xonar_ds; 1313 chip->model.shortname = "Xonar DSX"; 1314 break; 1315 case 0x835e: 1316 chip->model = model_xonar_hdav_slim; 1317 break; 1318 default: 1319 return -EINVAL; 1320 } 1321 return 0; 1322 } 1323