0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 #include <linux/pci.h>
0052 #include <linux/delay.h>
0053 #include <sound/control.h>
0054 #include <sound/core.h>
0055 #include <sound/info.h>
0056 #include <sound/jack.h>
0057 #include <sound/pcm.h>
0058 #include <sound/pcm_params.h>
0059 #include <sound/tlv.h>
0060 #include "xonar.h"
0061 #include "wm8776.h"
0062 #include "wm8766.h"
0063
0064 #define GPIO_DS_HP_DETECT 0x0010
0065 #define GPIO_DS_INPUT_ROUTE 0x0040
0066 #define GPIO_DS_OUTPUT_FRONTLR 0x0080
0067 #define GPIO_DS_OUTPUT_ENABLE 0x0100
0068
0069 #define GPIO_SLIM_HDMI_DISABLE 0x0001
0070 #define GPIO_SLIM_OUTPUT_ENABLE 0x0002
0071 #define GPIO_SLIM_FIRMWARE_CLK 0x0040
0072 #define GPIO_SLIM_FIRMWARE_DATA 0x0080
0073
0074 #define I2C_DEVICE_WM8776 0x34
0075
0076 #define LC_CONTROL_LIMITER 0x40000000
0077 #define LC_CONTROL_ALC 0x20000000
0078
0079 struct xonar_wm87x6 {
0080 struct xonar_generic generic;
0081 u16 wm8776_regs[0x17];
0082 u16 wm8766_regs[0x10];
0083 struct snd_kcontrol *line_adcmux_control;
0084 struct snd_kcontrol *mic_adcmux_control;
0085 struct snd_kcontrol *lc_controls[13];
0086 struct snd_jack *hp_jack;
0087 struct xonar_hdmi hdmi;
0088 };
0089
0090 static void wm8776_write_spi(struct oxygen *chip,
0091 unsigned int reg, unsigned int value)
0092 {
0093 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
0094 OXYGEN_SPI_DATA_LENGTH_2 |
0095 OXYGEN_SPI_CLOCK_160 |
0096 (1 << OXYGEN_SPI_CODEC_SHIFT) |
0097 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
0098 (reg << 9) | value);
0099 }
0100
0101 static void wm8776_write_i2c(struct oxygen *chip,
0102 unsigned int reg, unsigned int value)
0103 {
0104 oxygen_write_i2c(chip, I2C_DEVICE_WM8776,
0105 (reg << 1) | (value >> 8), value);
0106 }
0107
0108 static void wm8776_write(struct oxygen *chip,
0109 unsigned int reg, unsigned int value)
0110 {
0111 struct xonar_wm87x6 *data = chip->model_data;
0112
0113 if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) ==
0114 OXYGEN_FUNCTION_SPI)
0115 wm8776_write_spi(chip, reg, value);
0116 else
0117 wm8776_write_i2c(chip, reg, value);
0118 if (reg < ARRAY_SIZE(data->wm8776_regs)) {
0119
0120 if (reg <= WM8776_DACMASTER)
0121 value &= ~WM8776_UPDATE;
0122 data->wm8776_regs[reg] = value;
0123 }
0124 }
0125
0126 static void wm8776_write_cached(struct oxygen *chip,
0127 unsigned int reg, unsigned int value)
0128 {
0129 struct xonar_wm87x6 *data = chip->model_data;
0130
0131 if (reg >= ARRAY_SIZE(data->wm8776_regs) ||
0132 value != data->wm8776_regs[reg])
0133 wm8776_write(chip, reg, value);
0134 }
0135
0136 static void wm8766_write(struct oxygen *chip,
0137 unsigned int reg, unsigned int value)
0138 {
0139 struct xonar_wm87x6 *data = chip->model_data;
0140
0141 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
0142 OXYGEN_SPI_DATA_LENGTH_2 |
0143 OXYGEN_SPI_CLOCK_160 |
0144 (0 << OXYGEN_SPI_CODEC_SHIFT) |
0145 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
0146 (reg << 9) | value);
0147 if (reg < ARRAY_SIZE(data->wm8766_regs)) {
0148
0149 if (reg <= WM8766_RDA1 ||
0150 (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA))
0151 value &= ~WM8766_UPDATE;
0152 data->wm8766_regs[reg] = value;
0153 }
0154 }
0155
0156 static void wm8766_write_cached(struct oxygen *chip,
0157 unsigned int reg, unsigned int value)
0158 {
0159 struct xonar_wm87x6 *data = chip->model_data;
0160
0161 if (reg >= ARRAY_SIZE(data->wm8766_regs) ||
0162 value != data->wm8766_regs[reg])
0163 wm8766_write(chip, reg, value);
0164 }
0165
0166 static void wm8776_registers_init(struct oxygen *chip)
0167 {
0168 struct xonar_wm87x6 *data = chip->model_data;
0169
0170 wm8776_write(chip, WM8776_RESET, 0);
0171 wm8776_write(chip, WM8776_PHASESWAP, WM8776_PH_MASK);
0172 wm8776_write(chip, WM8776_DACCTRL1, WM8776_DZCEN |
0173 WM8776_PL_LEFT_LEFT | WM8776_PL_RIGHT_RIGHT);
0174 wm8776_write(chip, WM8776_DACMUTE, chip->dac_mute ? WM8776_DMUTE : 0);
0175 wm8776_write(chip, WM8776_DACIFCTRL,
0176 WM8776_DACFMT_LJUST | WM8776_DACWL_24);
0177 wm8776_write(chip, WM8776_ADCIFCTRL,
0178 data->wm8776_regs[WM8776_ADCIFCTRL]);
0179 wm8776_write(chip, WM8776_MSTRCTRL, data->wm8776_regs[WM8776_MSTRCTRL]);
0180 wm8776_write(chip, WM8776_PWRDOWN, data->wm8776_regs[WM8776_PWRDOWN]);
0181 wm8776_write(chip, WM8776_HPLVOL, data->wm8776_regs[WM8776_HPLVOL]);
0182 wm8776_write(chip, WM8776_HPRVOL, data->wm8776_regs[WM8776_HPRVOL] |
0183 WM8776_UPDATE);
0184 wm8776_write(chip, WM8776_ADCLVOL, data->wm8776_regs[WM8776_ADCLVOL]);
0185 wm8776_write(chip, WM8776_ADCRVOL, data->wm8776_regs[WM8776_ADCRVOL]);
0186 wm8776_write(chip, WM8776_ADCMUX, data->wm8776_regs[WM8776_ADCMUX]);
0187 wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0]);
0188 wm8776_write(chip, WM8776_DACRVOL, chip->dac_volume[1] | WM8776_UPDATE);
0189 }
0190
0191 static void wm8766_registers_init(struct oxygen *chip)
0192 {
0193 struct xonar_wm87x6 *data = chip->model_data;
0194
0195 wm8766_write(chip, WM8766_RESET, 0);
0196 wm8766_write(chip, WM8766_DAC_CTRL, data->wm8766_regs[WM8766_DAC_CTRL]);
0197 wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24);
0198 wm8766_write(chip, WM8766_DAC_CTRL2,
0199 WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
0200 wm8766_write(chip, WM8766_LDA1, chip->dac_volume[2]);
0201 wm8766_write(chip, WM8766_RDA1, chip->dac_volume[3]);
0202 wm8766_write(chip, WM8766_LDA2, chip->dac_volume[4]);
0203 wm8766_write(chip, WM8766_RDA2, chip->dac_volume[5]);
0204 wm8766_write(chip, WM8766_LDA3, chip->dac_volume[6]);
0205 wm8766_write(chip, WM8766_RDA3, chip->dac_volume[7] | WM8766_UPDATE);
0206 }
0207
0208 static void wm8776_init(struct oxygen *chip)
0209 {
0210 struct xonar_wm87x6 *data = chip->model_data;
0211
0212 data->wm8776_regs[WM8776_HPLVOL] = (0x79 - 60) | WM8776_HPZCEN;
0213 data->wm8776_regs[WM8776_HPRVOL] = (0x79 - 60) | WM8776_HPZCEN;
0214 data->wm8776_regs[WM8776_ADCIFCTRL] =
0215 WM8776_ADCFMT_LJUST | WM8776_ADCWL_24 | WM8776_ADCMCLK;
0216 data->wm8776_regs[WM8776_MSTRCTRL] =
0217 WM8776_ADCRATE_256 | WM8776_DACRATE_256;
0218 data->wm8776_regs[WM8776_PWRDOWN] = WM8776_HPPD;
0219 data->wm8776_regs[WM8776_ADCLVOL] = 0xa5 | WM8776_ZCA;
0220 data->wm8776_regs[WM8776_ADCRVOL] = 0xa5 | WM8776_ZCA;
0221 data->wm8776_regs[WM8776_ADCMUX] = 0x001;
0222 wm8776_registers_init(chip);
0223 }
0224
0225 static void wm8766_init(struct oxygen *chip)
0226 {
0227 struct xonar_wm87x6 *data = chip->model_data;
0228
0229 data->wm8766_regs[WM8766_DAC_CTRL] =
0230 WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT;
0231 wm8766_registers_init(chip);
0232 }
0233
0234 static void xonar_ds_handle_hp_jack(struct oxygen *chip)
0235 {
0236 struct xonar_wm87x6 *data = chip->model_data;
0237 bool hp_plugged;
0238 unsigned int reg;
0239
0240 mutex_lock(&chip->mutex);
0241
0242 hp_plugged = !(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
0243 GPIO_DS_HP_DETECT);
0244
0245 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
0246 hp_plugged ? 0 : GPIO_DS_OUTPUT_FRONTLR,
0247 GPIO_DS_OUTPUT_FRONTLR);
0248
0249 reg = data->wm8766_regs[WM8766_DAC_CTRL] & ~WM8766_MUTEALL;
0250 if (hp_plugged)
0251 reg |= WM8766_MUTEALL;
0252 wm8766_write_cached(chip, WM8766_DAC_CTRL, reg);
0253
0254 snd_jack_report(data->hp_jack, hp_plugged ? SND_JACK_HEADPHONE : 0);
0255
0256 mutex_unlock(&chip->mutex);
0257 }
0258
0259 static void xonar_ds_init(struct oxygen *chip)
0260 {
0261 struct xonar_wm87x6 *data = chip->model_data;
0262
0263 data->generic.anti_pop_delay = 300;
0264 data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE;
0265
0266 wm8776_init(chip);
0267 wm8766_init(chip);
0268
0269 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
0270 GPIO_DS_INPUT_ROUTE | GPIO_DS_OUTPUT_FRONTLR);
0271 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
0272 GPIO_DS_HP_DETECT);
0273 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE);
0274 oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT);
0275 chip->interrupt_mask |= OXYGEN_INT_GPIO;
0276
0277 xonar_enable_output(chip);
0278
0279 snd_jack_new(chip->card, "Headphone",
0280 SND_JACK_HEADPHONE, &data->hp_jack, false, false);
0281 xonar_ds_handle_hp_jack(chip);
0282
0283 snd_component_add(chip->card, "WM8776");
0284 snd_component_add(chip->card, "WM8766");
0285 }
0286
0287 static void xonar_hdav_slim_init(struct oxygen *chip)
0288 {
0289 struct xonar_wm87x6 *data = chip->model_data;
0290
0291 data->generic.anti_pop_delay = 300;
0292 data->generic.output_enable_bit = GPIO_SLIM_OUTPUT_ENABLE;
0293
0294 wm8776_init(chip);
0295
0296 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
0297 GPIO_SLIM_HDMI_DISABLE |
0298 GPIO_SLIM_FIRMWARE_CLK |
0299 GPIO_SLIM_FIRMWARE_DATA);
0300
0301 xonar_hdmi_init(chip, &data->hdmi);
0302 xonar_enable_output(chip);
0303
0304 snd_component_add(chip->card, "WM8776");
0305 }
0306
0307 static void xonar_ds_cleanup(struct oxygen *chip)
0308 {
0309 xonar_disable_output(chip);
0310 wm8776_write(chip, WM8776_RESET, 0);
0311 }
0312
0313 static void xonar_hdav_slim_cleanup(struct oxygen *chip)
0314 {
0315 xonar_hdmi_cleanup(chip);
0316 xonar_disable_output(chip);
0317 wm8776_write(chip, WM8776_RESET, 0);
0318 msleep(2);
0319 }
0320
0321 static void xonar_ds_suspend(struct oxygen *chip)
0322 {
0323 xonar_ds_cleanup(chip);
0324 }
0325
0326 static void xonar_hdav_slim_suspend(struct oxygen *chip)
0327 {
0328 xonar_hdav_slim_cleanup(chip);
0329 }
0330
0331 static void xonar_ds_resume(struct oxygen *chip)
0332 {
0333 wm8776_registers_init(chip);
0334 wm8766_registers_init(chip);
0335 xonar_enable_output(chip);
0336 xonar_ds_handle_hp_jack(chip);
0337 }
0338
0339 static void xonar_hdav_slim_resume(struct oxygen *chip)
0340 {
0341 struct xonar_wm87x6 *data = chip->model_data;
0342
0343 wm8776_registers_init(chip);
0344 xonar_hdmi_resume(chip, &data->hdmi);
0345 xonar_enable_output(chip);
0346 }
0347
0348 static void wm8776_adc_hardware_filter(unsigned int channel,
0349 struct snd_pcm_hardware *hardware)
0350 {
0351 if (channel == PCM_A) {
0352 hardware->rates = SNDRV_PCM_RATE_32000 |
0353 SNDRV_PCM_RATE_44100 |
0354 SNDRV_PCM_RATE_48000 |
0355 SNDRV_PCM_RATE_64000 |
0356 SNDRV_PCM_RATE_88200 |
0357 SNDRV_PCM_RATE_96000;
0358 hardware->rate_max = 96000;
0359 }
0360 }
0361
0362 static void xonar_hdav_slim_hardware_filter(unsigned int channel,
0363 struct snd_pcm_hardware *hardware)
0364 {
0365 wm8776_adc_hardware_filter(channel, hardware);
0366 xonar_hdmi_pcm_hardware_filter(channel, hardware);
0367 }
0368
0369 static void set_wm87x6_dac_params(struct oxygen *chip,
0370 struct snd_pcm_hw_params *params)
0371 {
0372 }
0373
0374 static void set_wm8776_adc_params(struct oxygen *chip,
0375 struct snd_pcm_hw_params *params)
0376 {
0377 u16 reg;
0378
0379 reg = WM8776_ADCRATE_256 | WM8776_DACRATE_256;
0380 if (params_rate(params) > 48000)
0381 reg |= WM8776_ADCOSR;
0382 wm8776_write_cached(chip, WM8776_MSTRCTRL, reg);
0383 }
0384
0385 static void set_hdav_slim_dac_params(struct oxygen *chip,
0386 struct snd_pcm_hw_params *params)
0387 {
0388 struct xonar_wm87x6 *data = chip->model_data;
0389
0390 xonar_set_hdmi_params(chip, &data->hdmi, params);
0391 }
0392
0393 static void update_wm8776_volume(struct oxygen *chip)
0394 {
0395 struct xonar_wm87x6 *data = chip->model_data;
0396 u8 to_change;
0397
0398 if (chip->dac_volume[0] == chip->dac_volume[1]) {
0399 if (chip->dac_volume[0] != data->wm8776_regs[WM8776_DACLVOL] ||
0400 chip->dac_volume[1] != data->wm8776_regs[WM8776_DACRVOL]) {
0401 wm8776_write(chip, WM8776_DACMASTER,
0402 chip->dac_volume[0] | WM8776_UPDATE);
0403 data->wm8776_regs[WM8776_DACLVOL] = chip->dac_volume[0];
0404 data->wm8776_regs[WM8776_DACRVOL] = chip->dac_volume[0];
0405 }
0406 } else {
0407 to_change = (chip->dac_volume[0] !=
0408 data->wm8776_regs[WM8776_DACLVOL]) << 0;
0409 to_change |= (chip->dac_volume[1] !=
0410 data->wm8776_regs[WM8776_DACLVOL]) << 1;
0411 if (to_change & 1)
0412 wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0] |
0413 ((to_change & 2) ? 0 : WM8776_UPDATE));
0414 if (to_change & 2)
0415 wm8776_write(chip, WM8776_DACRVOL,
0416 chip->dac_volume[1] | WM8776_UPDATE);
0417 }
0418 }
0419
0420 static void update_wm87x6_volume(struct oxygen *chip)
0421 {
0422 static const u8 wm8766_regs[6] = {
0423 WM8766_LDA1, WM8766_RDA1,
0424 WM8766_LDA2, WM8766_RDA2,
0425 WM8766_LDA3, WM8766_RDA3,
0426 };
0427 struct xonar_wm87x6 *data = chip->model_data;
0428 unsigned int i;
0429 u8 to_change;
0430
0431 update_wm8776_volume(chip);
0432 if (chip->dac_volume[2] == chip->dac_volume[3] &&
0433 chip->dac_volume[2] == chip->dac_volume[4] &&
0434 chip->dac_volume[2] == chip->dac_volume[5] &&
0435 chip->dac_volume[2] == chip->dac_volume[6] &&
0436 chip->dac_volume[2] == chip->dac_volume[7]) {
0437 to_change = 0;
0438 for (i = 0; i < 6; ++i)
0439 if (chip->dac_volume[2] !=
0440 data->wm8766_regs[wm8766_regs[i]])
0441 to_change = 1;
0442 if (to_change) {
0443 wm8766_write(chip, WM8766_MASTDA,
0444 chip->dac_volume[2] | WM8766_UPDATE);
0445 for (i = 0; i < 6; ++i)
0446 data->wm8766_regs[wm8766_regs[i]] =
0447 chip->dac_volume[2];
0448 }
0449 } else {
0450 to_change = 0;
0451 for (i = 0; i < 6; ++i)
0452 to_change |= (chip->dac_volume[2 + i] !=
0453 data->wm8766_regs[wm8766_regs[i]]) << i;
0454 for (i = 0; i < 6; ++i)
0455 if (to_change & (1 << i))
0456 wm8766_write(chip, wm8766_regs[i],
0457 chip->dac_volume[2 + i] |
0458 ((to_change & (0x3e << i))
0459 ? 0 : WM8766_UPDATE));
0460 }
0461 }
0462
0463 static void update_wm8776_mute(struct oxygen *chip)
0464 {
0465 wm8776_write_cached(chip, WM8776_DACMUTE,
0466 chip->dac_mute ? WM8776_DMUTE : 0);
0467 }
0468
0469 static void update_wm87x6_mute(struct oxygen *chip)
0470 {
0471 update_wm8776_mute(chip);
0472 wm8766_write_cached(chip, WM8766_DAC_CTRL2, WM8766_ZCD |
0473 (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
0474 }
0475
0476 static void update_wm8766_center_lfe_mix(struct oxygen *chip, bool mixed)
0477 {
0478 struct xonar_wm87x6 *data = chip->model_data;
0479 unsigned int reg;
0480
0481
0482
0483
0484
0485 reg = data->wm8766_regs[WM8766_DAC_CTRL] &
0486 ~(WM8766_PL_LEFT_MASK | WM8766_PL_RIGHT_MASK);
0487 if (mixed)
0488 reg |= WM8766_PL_LEFT_LRMIX | WM8766_PL_RIGHT_LRMIX;
0489 else
0490 reg |= WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT;
0491 wm8766_write_cached(chip, WM8766_DAC_CTRL, reg);
0492 }
0493
0494 static void xonar_ds_gpio_changed(struct oxygen *chip)
0495 {
0496 xonar_ds_handle_hp_jack(chip);
0497 }
0498
0499 static int wm8776_bit_switch_get(struct snd_kcontrol *ctl,
0500 struct snd_ctl_elem_value *value)
0501 {
0502 struct oxygen *chip = ctl->private_data;
0503 struct xonar_wm87x6 *data = chip->model_data;
0504 u16 bit = ctl->private_value & 0xffff;
0505 unsigned int reg_index = (ctl->private_value >> 16) & 0xff;
0506 bool invert = (ctl->private_value >> 24) & 1;
0507
0508 value->value.integer.value[0] =
0509 ((data->wm8776_regs[reg_index] & bit) != 0) ^ invert;
0510 return 0;
0511 }
0512
0513 static int wm8776_bit_switch_put(struct snd_kcontrol *ctl,
0514 struct snd_ctl_elem_value *value)
0515 {
0516 struct oxygen *chip = ctl->private_data;
0517 struct xonar_wm87x6 *data = chip->model_data;
0518 u16 bit = ctl->private_value & 0xffff;
0519 u16 reg_value;
0520 unsigned int reg_index = (ctl->private_value >> 16) & 0xff;
0521 bool invert = (ctl->private_value >> 24) & 1;
0522 int changed;
0523
0524 mutex_lock(&chip->mutex);
0525 reg_value = data->wm8776_regs[reg_index] & ~bit;
0526 if (value->value.integer.value[0] ^ invert)
0527 reg_value |= bit;
0528 changed = reg_value != data->wm8776_regs[reg_index];
0529 if (changed)
0530 wm8776_write(chip, reg_index, reg_value);
0531 mutex_unlock(&chip->mutex);
0532 return changed;
0533 }
0534
0535 static int wm8776_field_enum_info(struct snd_kcontrol *ctl,
0536 struct snd_ctl_elem_info *info)
0537 {
0538 static const char *const hld[16] = {
0539 "0 ms", "2.67 ms", "5.33 ms", "10.6 ms",
0540 "21.3 ms", "42.7 ms", "85.3 ms", "171 ms",
0541 "341 ms", "683 ms", "1.37 s", "2.73 s",
0542 "5.46 s", "10.9 s", "21.8 s", "43.7 s",
0543 };
0544 static const char *const atk_lim[11] = {
0545 "0.25 ms", "0.5 ms", "1 ms", "2 ms",
0546 "4 ms", "8 ms", "16 ms", "32 ms",
0547 "64 ms", "128 ms", "256 ms",
0548 };
0549 static const char *const atk_alc[11] = {
0550 "8.40 ms", "16.8 ms", "33.6 ms", "67.2 ms",
0551 "134 ms", "269 ms", "538 ms", "1.08 s",
0552 "2.15 s", "4.3 s", "8.6 s",
0553 };
0554 static const char *const dcy_lim[11] = {
0555 "1.2 ms", "2.4 ms", "4.8 ms", "9.6 ms",
0556 "19.2 ms", "38.4 ms", "76.8 ms", "154 ms",
0557 "307 ms", "614 ms", "1.23 s",
0558 };
0559 static const char *const dcy_alc[11] = {
0560 "33.5 ms", "67.0 ms", "134 ms", "268 ms",
0561 "536 ms", "1.07 s", "2.14 s", "4.29 s",
0562 "8.58 s", "17.2 s", "34.3 s",
0563 };
0564 static const char *const tranwin[8] = {
0565 "0 us", "62.5 us", "125 us", "250 us",
0566 "500 us", "1 ms", "2 ms", "4 ms",
0567 };
0568 u8 max;
0569 const char *const *names;
0570
0571 max = (ctl->private_value >> 12) & 0xf;
0572 switch ((ctl->private_value >> 24) & 0x1f) {
0573 case WM8776_ALCCTRL2:
0574 names = hld;
0575 break;
0576 case WM8776_ALCCTRL3:
0577 if (((ctl->private_value >> 20) & 0xf) == 0) {
0578 if (ctl->private_value & LC_CONTROL_LIMITER)
0579 names = atk_lim;
0580 else
0581 names = atk_alc;
0582 } else {
0583 if (ctl->private_value & LC_CONTROL_LIMITER)
0584 names = dcy_lim;
0585 else
0586 names = dcy_alc;
0587 }
0588 break;
0589 case WM8776_LIMITER:
0590 names = tranwin;
0591 break;
0592 default:
0593 return -ENXIO;
0594 }
0595 return snd_ctl_enum_info(info, 1, max + 1, names);
0596 }
0597
0598 static int wm8776_field_volume_info(struct snd_kcontrol *ctl,
0599 struct snd_ctl_elem_info *info)
0600 {
0601 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0602 info->count = 1;
0603 info->value.integer.min = (ctl->private_value >> 8) & 0xf;
0604 info->value.integer.max = (ctl->private_value >> 12) & 0xf;
0605 return 0;
0606 }
0607
0608 static void wm8776_field_set_from_ctl(struct snd_kcontrol *ctl)
0609 {
0610 struct oxygen *chip = ctl->private_data;
0611 struct xonar_wm87x6 *data = chip->model_data;
0612 unsigned int value, reg_index, mode;
0613 u8 min, max, shift;
0614 u16 mask, reg_value;
0615 bool invert;
0616
0617 if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) ==
0618 WM8776_LCSEL_LIMITER)
0619 mode = LC_CONTROL_LIMITER;
0620 else
0621 mode = LC_CONTROL_ALC;
0622 if (!(ctl->private_value & mode))
0623 return;
0624
0625 value = ctl->private_value & 0xf;
0626 min = (ctl->private_value >> 8) & 0xf;
0627 max = (ctl->private_value >> 12) & 0xf;
0628 mask = (ctl->private_value >> 16) & 0xf;
0629 shift = (ctl->private_value >> 20) & 0xf;
0630 reg_index = (ctl->private_value >> 24) & 0x1f;
0631 invert = (ctl->private_value >> 29) & 0x1;
0632
0633 if (invert)
0634 value = max - (value - min);
0635 reg_value = data->wm8776_regs[reg_index];
0636 reg_value &= ~(mask << shift);
0637 reg_value |= value << shift;
0638 wm8776_write_cached(chip, reg_index, reg_value);
0639 }
0640
0641 static int wm8776_field_set(struct snd_kcontrol *ctl, unsigned int value)
0642 {
0643 struct oxygen *chip = ctl->private_data;
0644 u8 min, max;
0645 int changed;
0646
0647 min = (ctl->private_value >> 8) & 0xf;
0648 max = (ctl->private_value >> 12) & 0xf;
0649 if (value < min || value > max)
0650 return -EINVAL;
0651 mutex_lock(&chip->mutex);
0652 changed = value != (ctl->private_value & 0xf);
0653 if (changed) {
0654 ctl->private_value = (ctl->private_value & ~0xf) | value;
0655 wm8776_field_set_from_ctl(ctl);
0656 }
0657 mutex_unlock(&chip->mutex);
0658 return changed;
0659 }
0660
0661 static int wm8776_field_enum_get(struct snd_kcontrol *ctl,
0662 struct snd_ctl_elem_value *value)
0663 {
0664 value->value.enumerated.item[0] = ctl->private_value & 0xf;
0665 return 0;
0666 }
0667
0668 static int wm8776_field_volume_get(struct snd_kcontrol *ctl,
0669 struct snd_ctl_elem_value *value)
0670 {
0671 value->value.integer.value[0] = ctl->private_value & 0xf;
0672 return 0;
0673 }
0674
0675 static int wm8776_field_enum_put(struct snd_kcontrol *ctl,
0676 struct snd_ctl_elem_value *value)
0677 {
0678 return wm8776_field_set(ctl, value->value.enumerated.item[0]);
0679 }
0680
0681 static int wm8776_field_volume_put(struct snd_kcontrol *ctl,
0682 struct snd_ctl_elem_value *value)
0683 {
0684 return wm8776_field_set(ctl, value->value.integer.value[0]);
0685 }
0686
0687 static int wm8776_hp_vol_info(struct snd_kcontrol *ctl,
0688 struct snd_ctl_elem_info *info)
0689 {
0690 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0691 info->count = 2;
0692 info->value.integer.min = 0x79 - 60;
0693 info->value.integer.max = 0x7f;
0694 return 0;
0695 }
0696
0697 static int wm8776_hp_vol_get(struct snd_kcontrol *ctl,
0698 struct snd_ctl_elem_value *value)
0699 {
0700 struct oxygen *chip = ctl->private_data;
0701 struct xonar_wm87x6 *data = chip->model_data;
0702
0703 mutex_lock(&chip->mutex);
0704 value->value.integer.value[0] =
0705 data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK;
0706 value->value.integer.value[1] =
0707 data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK;
0708 mutex_unlock(&chip->mutex);
0709 return 0;
0710 }
0711
0712 static int wm8776_hp_vol_put(struct snd_kcontrol *ctl,
0713 struct snd_ctl_elem_value *value)
0714 {
0715 struct oxygen *chip = ctl->private_data;
0716 struct xonar_wm87x6 *data = chip->model_data;
0717 u8 to_update;
0718
0719 mutex_lock(&chip->mutex);
0720 to_update = (value->value.integer.value[0] !=
0721 (data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK))
0722 << 0;
0723 to_update |= (value->value.integer.value[1] !=
0724 (data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK))
0725 << 1;
0726 if (value->value.integer.value[0] == value->value.integer.value[1]) {
0727 if (to_update) {
0728 wm8776_write(chip, WM8776_HPMASTER,
0729 value->value.integer.value[0] |
0730 WM8776_HPZCEN | WM8776_UPDATE);
0731 data->wm8776_regs[WM8776_HPLVOL] =
0732 value->value.integer.value[0] | WM8776_HPZCEN;
0733 data->wm8776_regs[WM8776_HPRVOL] =
0734 value->value.integer.value[0] | WM8776_HPZCEN;
0735 }
0736 } else {
0737 if (to_update & 1)
0738 wm8776_write(chip, WM8776_HPLVOL,
0739 value->value.integer.value[0] |
0740 WM8776_HPZCEN |
0741 ((to_update & 2) ? 0 : WM8776_UPDATE));
0742 if (to_update & 2)
0743 wm8776_write(chip, WM8776_HPRVOL,
0744 value->value.integer.value[1] |
0745 WM8776_HPZCEN | WM8776_UPDATE);
0746 }
0747 mutex_unlock(&chip->mutex);
0748 return to_update != 0;
0749 }
0750
0751 static int wm8776_input_mux_get(struct snd_kcontrol *ctl,
0752 struct snd_ctl_elem_value *value)
0753 {
0754 struct oxygen *chip = ctl->private_data;
0755 struct xonar_wm87x6 *data = chip->model_data;
0756 unsigned int mux_bit = ctl->private_value;
0757
0758 value->value.integer.value[0] =
0759 !!(data->wm8776_regs[WM8776_ADCMUX] & mux_bit);
0760 return 0;
0761 }
0762
0763 static int wm8776_input_mux_put(struct snd_kcontrol *ctl,
0764 struct snd_ctl_elem_value *value)
0765 {
0766 struct oxygen *chip = ctl->private_data;
0767 struct xonar_wm87x6 *data = chip->model_data;
0768 struct snd_kcontrol *other_ctl;
0769 unsigned int mux_bit = ctl->private_value;
0770 u16 reg;
0771 int changed;
0772
0773 mutex_lock(&chip->mutex);
0774 reg = data->wm8776_regs[WM8776_ADCMUX];
0775 if (value->value.integer.value[0]) {
0776 reg |= mux_bit;
0777
0778 mux_bit ^= 3;
0779 if (reg & mux_bit) {
0780 reg &= ~mux_bit;
0781 if (mux_bit == 1)
0782 other_ctl = data->line_adcmux_control;
0783 else
0784 other_ctl = data->mic_adcmux_control;
0785 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
0786 &other_ctl->id);
0787 }
0788 } else
0789 reg &= ~mux_bit;
0790 changed = reg != data->wm8776_regs[WM8776_ADCMUX];
0791 if (changed) {
0792 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
0793 reg & 1 ? GPIO_DS_INPUT_ROUTE : 0,
0794 GPIO_DS_INPUT_ROUTE);
0795 wm8776_write(chip, WM8776_ADCMUX, reg);
0796 }
0797 mutex_unlock(&chip->mutex);
0798 return changed;
0799 }
0800
0801 static int wm8776_input_vol_info(struct snd_kcontrol *ctl,
0802 struct snd_ctl_elem_info *info)
0803 {
0804 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0805 info->count = 2;
0806 info->value.integer.min = 0xa5;
0807 info->value.integer.max = 0xff;
0808 return 0;
0809 }
0810
0811 static int wm8776_input_vol_get(struct snd_kcontrol *ctl,
0812 struct snd_ctl_elem_value *value)
0813 {
0814 struct oxygen *chip = ctl->private_data;
0815 struct xonar_wm87x6 *data = chip->model_data;
0816
0817 mutex_lock(&chip->mutex);
0818 value->value.integer.value[0] =
0819 data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK;
0820 value->value.integer.value[1] =
0821 data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK;
0822 mutex_unlock(&chip->mutex);
0823 return 0;
0824 }
0825
0826 static int wm8776_input_vol_put(struct snd_kcontrol *ctl,
0827 struct snd_ctl_elem_value *value)
0828 {
0829 struct oxygen *chip = ctl->private_data;
0830 struct xonar_wm87x6 *data = chip->model_data;
0831 int changed = 0;
0832
0833 mutex_lock(&chip->mutex);
0834 changed = (value->value.integer.value[0] !=
0835 (data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK)) ||
0836 (value->value.integer.value[1] !=
0837 (data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK));
0838 wm8776_write_cached(chip, WM8776_ADCLVOL,
0839 value->value.integer.value[0] | WM8776_ZCA);
0840 wm8776_write_cached(chip, WM8776_ADCRVOL,
0841 value->value.integer.value[1] | WM8776_ZCA);
0842 mutex_unlock(&chip->mutex);
0843 return changed;
0844 }
0845
0846 static int wm8776_level_control_info(struct snd_kcontrol *ctl,
0847 struct snd_ctl_elem_info *info)
0848 {
0849 static const char *const names[3] = {
0850 "None", "Peak Limiter", "Automatic Level Control"
0851 };
0852
0853 return snd_ctl_enum_info(info, 1, 3, names);
0854 }
0855
0856 static int wm8776_level_control_get(struct snd_kcontrol *ctl,
0857 struct snd_ctl_elem_value *value)
0858 {
0859 struct oxygen *chip = ctl->private_data;
0860 struct xonar_wm87x6 *data = chip->model_data;
0861
0862 if (!(data->wm8776_regs[WM8776_ALCCTRL2] & WM8776_LCEN))
0863 value->value.enumerated.item[0] = 0;
0864 else if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) ==
0865 WM8776_LCSEL_LIMITER)
0866 value->value.enumerated.item[0] = 1;
0867 else
0868 value->value.enumerated.item[0] = 2;
0869 return 0;
0870 }
0871
0872 static void activate_control(struct oxygen *chip,
0873 struct snd_kcontrol *ctl, unsigned int mode)
0874 {
0875 unsigned int access;
0876
0877 if (ctl->private_value & mode)
0878 access = 0;
0879 else
0880 access = SNDRV_CTL_ELEM_ACCESS_INACTIVE;
0881 if ((ctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE) != access) {
0882 ctl->vd[0].access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
0883 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
0884 }
0885 }
0886
0887 static int wm8776_level_control_put(struct snd_kcontrol *ctl,
0888 struct snd_ctl_elem_value *value)
0889 {
0890 struct oxygen *chip = ctl->private_data;
0891 struct xonar_wm87x6 *data = chip->model_data;
0892 unsigned int mode = 0, i;
0893 u16 ctrl1, ctrl2;
0894 int changed;
0895
0896 if (value->value.enumerated.item[0] >= 3)
0897 return -EINVAL;
0898 mutex_lock(&chip->mutex);
0899 changed = value->value.enumerated.item[0] != ctl->private_value;
0900 if (changed) {
0901 ctl->private_value = value->value.enumerated.item[0];
0902 ctrl1 = data->wm8776_regs[WM8776_ALCCTRL1];
0903 ctrl2 = data->wm8776_regs[WM8776_ALCCTRL2];
0904 switch (value->value.enumerated.item[0]) {
0905 default:
0906 wm8776_write_cached(chip, WM8776_ALCCTRL2,
0907 ctrl2 & ~WM8776_LCEN);
0908 break;
0909 case 1:
0910 wm8776_write_cached(chip, WM8776_ALCCTRL1,
0911 (ctrl1 & ~WM8776_LCSEL_MASK) |
0912 WM8776_LCSEL_LIMITER);
0913 wm8776_write_cached(chip, WM8776_ALCCTRL2,
0914 ctrl2 | WM8776_LCEN);
0915 mode = LC_CONTROL_LIMITER;
0916 break;
0917 case 2:
0918 wm8776_write_cached(chip, WM8776_ALCCTRL1,
0919 (ctrl1 & ~WM8776_LCSEL_MASK) |
0920 WM8776_LCSEL_ALC_STEREO);
0921 wm8776_write_cached(chip, WM8776_ALCCTRL2,
0922 ctrl2 | WM8776_LCEN);
0923 mode = LC_CONTROL_ALC;
0924 break;
0925 }
0926 for (i = 0; i < ARRAY_SIZE(data->lc_controls); ++i)
0927 activate_control(chip, data->lc_controls[i], mode);
0928 }
0929 mutex_unlock(&chip->mutex);
0930 return changed;
0931 }
0932
0933 static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
0934 {
0935 static const char *const names[2] = {
0936 "None", "High-pass Filter"
0937 };
0938
0939 return snd_ctl_enum_info(info, 1, 2, names);
0940 }
0941
0942 static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
0943 {
0944 struct oxygen *chip = ctl->private_data;
0945 struct xonar_wm87x6 *data = chip->model_data;
0946
0947 value->value.enumerated.item[0] =
0948 !(data->wm8776_regs[WM8776_ADCIFCTRL] & WM8776_ADCHPD);
0949 return 0;
0950 }
0951
0952 static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
0953 {
0954 struct oxygen *chip = ctl->private_data;
0955 struct xonar_wm87x6 *data = chip->model_data;
0956 unsigned int reg;
0957 int changed;
0958
0959 mutex_lock(&chip->mutex);
0960 reg = data->wm8776_regs[WM8776_ADCIFCTRL] & ~WM8776_ADCHPD;
0961 if (!value->value.enumerated.item[0])
0962 reg |= WM8776_ADCHPD;
0963 changed = reg != data->wm8776_regs[WM8776_ADCIFCTRL];
0964 if (changed)
0965 wm8776_write(chip, WM8776_ADCIFCTRL, reg);
0966 mutex_unlock(&chip->mutex);
0967 return changed;
0968 }
0969
0970 #define WM8776_BIT_SWITCH(xname, reg, bit, invert, flags) { \
0971 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
0972 .name = xname, \
0973 .info = snd_ctl_boolean_mono_info, \
0974 .get = wm8776_bit_switch_get, \
0975 .put = wm8776_bit_switch_put, \
0976 .private_value = ((reg) << 16) | (bit) | ((invert) << 24) | (flags), \
0977 }
0978 #define _WM8776_FIELD_CTL(xname, reg, shift, initval, min, max, mask, flags) \
0979 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
0980 .name = xname, \
0981 .private_value = (initval) | ((min) << 8) | ((max) << 12) | \
0982 ((mask) << 16) | ((shift) << 20) | ((reg) << 24) | (flags)
0983 #define WM8776_FIELD_CTL_ENUM(xname, reg, shift, init, min, max, mask, flags) {\
0984 _WM8776_FIELD_CTL(xname " Capture Enum", \
0985 reg, shift, init, min, max, mask, flags), \
0986 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
0987 SNDRV_CTL_ELEM_ACCESS_INACTIVE, \
0988 .info = wm8776_field_enum_info, \
0989 .get = wm8776_field_enum_get, \
0990 .put = wm8776_field_enum_put, \
0991 }
0992 #define WM8776_FIELD_CTL_VOLUME(a, b, c, d, e, f, g, h, tlv_p) { \
0993 _WM8776_FIELD_CTL(a " Capture Volume", b, c, d, e, f, g, h), \
0994 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
0995 SNDRV_CTL_ELEM_ACCESS_INACTIVE | \
0996 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
0997 .info = wm8776_field_volume_info, \
0998 .get = wm8776_field_volume_get, \
0999 .put = wm8776_field_volume_put, \
1000 .tlv = { .p = tlv_p }, \
1001 }
1002
1003 static const DECLARE_TLV_DB_SCALE(wm87x6_dac_db_scale, -6000, 50, 0);
1004 static const DECLARE_TLV_DB_SCALE(wm8776_adc_db_scale, -2100, 50, 0);
1005 static const DECLARE_TLV_DB_SCALE(wm8776_hp_db_scale, -6000, 100, 0);
1006 static const DECLARE_TLV_DB_SCALE(wm8776_lct_db_scale, -1600, 100, 0);
1007 static const DECLARE_TLV_DB_SCALE(wm8776_maxgain_db_scale, 0, 400, 0);
1008 static const DECLARE_TLV_DB_SCALE(wm8776_ngth_db_scale, -7800, 600, 0);
1009 static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_lim_db_scale, -1200, 100, 0);
1010 static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_alc_db_scale, -2100, 400, 0);
1011
1012 static const struct snd_kcontrol_new ds_controls[] = {
1013 {
1014 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1015 .name = "Headphone Playback Volume",
1016 .info = wm8776_hp_vol_info,
1017 .get = wm8776_hp_vol_get,
1018 .put = wm8776_hp_vol_put,
1019 .tlv = { .p = wm8776_hp_db_scale },
1020 },
1021 WM8776_BIT_SWITCH("Headphone Playback Switch",
1022 WM8776_PWRDOWN, WM8776_HPPD, 1, 0),
1023 {
1024 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1025 .name = "Input Capture Volume",
1026 .info = wm8776_input_vol_info,
1027 .get = wm8776_input_vol_get,
1028 .put = wm8776_input_vol_put,
1029 .tlv = { .p = wm8776_adc_db_scale },
1030 },
1031 {
1032 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1033 .name = "Line Capture Switch",
1034 .info = snd_ctl_boolean_mono_info,
1035 .get = wm8776_input_mux_get,
1036 .put = wm8776_input_mux_put,
1037 .private_value = 1 << 0,
1038 },
1039 {
1040 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1041 .name = "Mic Capture Switch",
1042 .info = snd_ctl_boolean_mono_info,
1043 .get = wm8776_input_mux_get,
1044 .put = wm8776_input_mux_put,
1045 .private_value = 1 << 1,
1046 },
1047 WM8776_BIT_SWITCH("Front Mic Capture Switch",
1048 WM8776_ADCMUX, 1 << 2, 0, 0),
1049 WM8776_BIT_SWITCH("Aux Capture Switch",
1050 WM8776_ADCMUX, 1 << 3, 0, 0),
1051 {
1052 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1053 .name = "ADC Filter Capture Enum",
1054 .info = hpf_info,
1055 .get = hpf_get,
1056 .put = hpf_put,
1057 },
1058 {
1059 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1060 .name = "Level Control Capture Enum",
1061 .info = wm8776_level_control_info,
1062 .get = wm8776_level_control_get,
1063 .put = wm8776_level_control_put,
1064 .private_value = 0,
1065 },
1066 };
1067 static const struct snd_kcontrol_new hdav_slim_controls[] = {
1068 {
1069 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1070 .name = "HDMI Playback Switch",
1071 .info = snd_ctl_boolean_mono_info,
1072 .get = xonar_gpio_bit_switch_get,
1073 .put = xonar_gpio_bit_switch_put,
1074 .private_value = GPIO_SLIM_HDMI_DISABLE | XONAR_GPIO_BIT_INVERT,
1075 },
1076 {
1077 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1078 .name = "Headphone Playback Volume",
1079 .info = wm8776_hp_vol_info,
1080 .get = wm8776_hp_vol_get,
1081 .put = wm8776_hp_vol_put,
1082 .tlv = { .p = wm8776_hp_db_scale },
1083 },
1084 WM8776_BIT_SWITCH("Headphone Playback Switch",
1085 WM8776_PWRDOWN, WM8776_HPPD, 1, 0),
1086 {
1087 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1088 .name = "Input Capture Volume",
1089 .info = wm8776_input_vol_info,
1090 .get = wm8776_input_vol_get,
1091 .put = wm8776_input_vol_put,
1092 .tlv = { .p = wm8776_adc_db_scale },
1093 },
1094 WM8776_BIT_SWITCH("Mic Capture Switch",
1095 WM8776_ADCMUX, 1 << 0, 0, 0),
1096 WM8776_BIT_SWITCH("Aux Capture Switch",
1097 WM8776_ADCMUX, 1 << 1, 0, 0),
1098 {
1099 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1100 .name = "ADC Filter Capture Enum",
1101 .info = hpf_info,
1102 .get = hpf_get,
1103 .put = hpf_put,
1104 },
1105 {
1106 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1107 .name = "Level Control Capture Enum",
1108 .info = wm8776_level_control_info,
1109 .get = wm8776_level_control_get,
1110 .put = wm8776_level_control_put,
1111 .private_value = 0,
1112 },
1113 };
1114 static const struct snd_kcontrol_new lc_controls[] = {
1115 WM8776_FIELD_CTL_VOLUME("Limiter Threshold",
1116 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf,
1117 LC_CONTROL_LIMITER, wm8776_lct_db_scale),
1118 WM8776_FIELD_CTL_ENUM("Limiter Attack Time",
1119 WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf,
1120 LC_CONTROL_LIMITER),
1121 WM8776_FIELD_CTL_ENUM("Limiter Decay Time",
1122 WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf,
1123 LC_CONTROL_LIMITER),
1124 WM8776_FIELD_CTL_ENUM("Limiter Transient Window",
1125 WM8776_LIMITER, 4, 2, 0, 7, 0x7,
1126 LC_CONTROL_LIMITER),
1127 WM8776_FIELD_CTL_VOLUME("Limiter Maximum Attenuation",
1128 WM8776_LIMITER, 0, 6, 3, 12, 0xf,
1129 LC_CONTROL_LIMITER,
1130 wm8776_maxatten_lim_db_scale),
1131 WM8776_FIELD_CTL_VOLUME("ALC Target Level",
1132 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf,
1133 LC_CONTROL_ALC, wm8776_lct_db_scale),
1134 WM8776_FIELD_CTL_ENUM("ALC Attack Time",
1135 WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf,
1136 LC_CONTROL_ALC),
1137 WM8776_FIELD_CTL_ENUM("ALC Decay Time",
1138 WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf,
1139 LC_CONTROL_ALC),
1140 WM8776_FIELD_CTL_VOLUME("ALC Maximum Gain",
1141 WM8776_ALCCTRL1, 4, 7, 1, 7, 0x7,
1142 LC_CONTROL_ALC, wm8776_maxgain_db_scale),
1143 WM8776_FIELD_CTL_VOLUME("ALC Maximum Attenuation",
1144 WM8776_LIMITER, 0, 10, 10, 15, 0xf,
1145 LC_CONTROL_ALC, wm8776_maxatten_alc_db_scale),
1146 WM8776_FIELD_CTL_ENUM("ALC Hold Time",
1147 WM8776_ALCCTRL2, 0, 0, 0, 15, 0xf,
1148 LC_CONTROL_ALC),
1149 WM8776_BIT_SWITCH("Noise Gate Capture Switch",
1150 WM8776_NOISEGATE, WM8776_NGAT, 0,
1151 LC_CONTROL_ALC),
1152 WM8776_FIELD_CTL_VOLUME("Noise Gate Threshold",
1153 WM8776_NOISEGATE, 2, 0, 0, 7, 0x7,
1154 LC_CONTROL_ALC, wm8776_ngth_db_scale),
1155 };
1156
1157 static int add_lc_controls(struct oxygen *chip)
1158 {
1159 struct xonar_wm87x6 *data = chip->model_data;
1160 unsigned int i;
1161 struct snd_kcontrol *ctl;
1162 int err;
1163
1164 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls));
1165 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) {
1166 ctl = snd_ctl_new1(&lc_controls[i], chip);
1167 if (!ctl)
1168 return -ENOMEM;
1169 err = snd_ctl_add(chip->card, ctl);
1170 if (err < 0)
1171 return err;
1172 data->lc_controls[i] = ctl;
1173 }
1174 return 0;
1175 }
1176
1177 static int xonar_ds_mixer_init(struct oxygen *chip)
1178 {
1179 struct xonar_wm87x6 *data = chip->model_data;
1180 unsigned int i;
1181 struct snd_kcontrol *ctl;
1182 int err;
1183
1184 for (i = 0; i < ARRAY_SIZE(ds_controls); ++i) {
1185 ctl = snd_ctl_new1(&ds_controls[i], chip);
1186 if (!ctl)
1187 return -ENOMEM;
1188 err = snd_ctl_add(chip->card, ctl);
1189 if (err < 0)
1190 return err;
1191 if (!strcmp(ctl->id.name, "Line Capture Switch"))
1192 data->line_adcmux_control = ctl;
1193 else if (!strcmp(ctl->id.name, "Mic Capture Switch"))
1194 data->mic_adcmux_control = ctl;
1195 }
1196 if (!data->line_adcmux_control || !data->mic_adcmux_control)
1197 return -ENXIO;
1198
1199 return add_lc_controls(chip);
1200 }
1201
1202 static int xonar_hdav_slim_mixer_init(struct oxygen *chip)
1203 {
1204 unsigned int i;
1205 struct snd_kcontrol *ctl;
1206 int err;
1207
1208 for (i = 0; i < ARRAY_SIZE(hdav_slim_controls); ++i) {
1209 ctl = snd_ctl_new1(&hdav_slim_controls[i], chip);
1210 if (!ctl)
1211 return -ENOMEM;
1212 err = snd_ctl_add(chip->card, ctl);
1213 if (err < 0)
1214 return err;
1215 }
1216
1217 return add_lc_controls(chip);
1218 }
1219
1220 static void dump_wm8776_registers(struct oxygen *chip,
1221 struct snd_info_buffer *buffer)
1222 {
1223 struct xonar_wm87x6 *data = chip->model_data;
1224 unsigned int i;
1225
1226 snd_iprintf(buffer, "\nWM8776:\n00:");
1227 for (i = 0; i < 0x10; ++i)
1228 snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
1229 snd_iprintf(buffer, "\n10:");
1230 for (i = 0x10; i < 0x17; ++i)
1231 snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
1232 snd_iprintf(buffer, "\n");
1233 }
1234
1235 static void dump_wm87x6_registers(struct oxygen *chip,
1236 struct snd_info_buffer *buffer)
1237 {
1238 struct xonar_wm87x6 *data = chip->model_data;
1239 unsigned int i;
1240
1241 dump_wm8776_registers(chip, buffer);
1242 snd_iprintf(buffer, "\nWM8766:\n00:");
1243 for (i = 0; i < 0x10; ++i)
1244 snd_iprintf(buffer, " %03x", data->wm8766_regs[i]);
1245 snd_iprintf(buffer, "\n");
1246 }
1247
1248 static const struct oxygen_model model_xonar_ds = {
1249 .longname = "Asus Virtuoso 66",
1250 .chip = "AV200",
1251 .init = xonar_ds_init,
1252 .mixer_init = xonar_ds_mixer_init,
1253 .cleanup = xonar_ds_cleanup,
1254 .suspend = xonar_ds_suspend,
1255 .resume = xonar_ds_resume,
1256 .pcm_hardware_filter = wm8776_adc_hardware_filter,
1257 .set_dac_params = set_wm87x6_dac_params,
1258 .set_adc_params = set_wm8776_adc_params,
1259 .update_dac_volume = update_wm87x6_volume,
1260 .update_dac_mute = update_wm87x6_mute,
1261 .update_center_lfe_mix = update_wm8766_center_lfe_mix,
1262 .gpio_changed = xonar_ds_gpio_changed,
1263 .dump_registers = dump_wm87x6_registers,
1264 .dac_tlv = wm87x6_dac_db_scale,
1265 .model_data_size = sizeof(struct xonar_wm87x6),
1266 .device_config = PLAYBACK_0_TO_I2S |
1267 PLAYBACK_1_TO_SPDIF |
1268 CAPTURE_0_FROM_I2S_1 |
1269 CAPTURE_1_FROM_SPDIF,
1270 .dac_channels_pcm = 8,
1271 .dac_channels_mixer = 8,
1272 .dac_volume_min = 255 - 2*60,
1273 .dac_volume_max = 255,
1274 .function_flags = OXYGEN_FUNCTION_SPI,
1275 .dac_mclks = OXYGEN_MCLKS(256, 256, 128),
1276 .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
1277 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1278 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1279 };
1280
1281 static const struct oxygen_model model_xonar_hdav_slim = {
1282 .shortname = "Xonar HDAV1.3 Slim",
1283 .longname = "Asus Virtuoso 200",
1284 .chip = "AV200",
1285 .init = xonar_hdav_slim_init,
1286 .mixer_init = xonar_hdav_slim_mixer_init,
1287 .cleanup = xonar_hdav_slim_cleanup,
1288 .suspend = xonar_hdav_slim_suspend,
1289 .resume = xonar_hdav_slim_resume,
1290 .pcm_hardware_filter = xonar_hdav_slim_hardware_filter,
1291 .set_dac_params = set_hdav_slim_dac_params,
1292 .set_adc_params = set_wm8776_adc_params,
1293 .update_dac_volume = update_wm8776_volume,
1294 .update_dac_mute = update_wm8776_mute,
1295 .uart_input = xonar_hdmi_uart_input,
1296 .dump_registers = dump_wm8776_registers,
1297 .dac_tlv = wm87x6_dac_db_scale,
1298 .model_data_size = sizeof(struct xonar_wm87x6),
1299 .device_config = PLAYBACK_0_TO_I2S |
1300 PLAYBACK_1_TO_SPDIF |
1301 CAPTURE_0_FROM_I2S_1 |
1302 CAPTURE_1_FROM_SPDIF,
1303 .dac_channels_pcm = 8,
1304 .dac_channels_mixer = 2,
1305 .dac_volume_min = 255 - 2*60,
1306 .dac_volume_max = 255,
1307 .function_flags = OXYGEN_FUNCTION_2WIRE,
1308 .dac_mclks = OXYGEN_MCLKS(256, 256, 128),
1309 .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
1310 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1311 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1312 };
1313
1314 int get_xonar_wm87x6_model(struct oxygen *chip,
1315 const struct pci_device_id *id)
1316 {
1317 switch (id->subdevice) {
1318 case 0x838e:
1319 chip->model = model_xonar_ds;
1320 chip->model.shortname = "Xonar DS";
1321 break;
1322 case 0x8522:
1323 chip->model = model_xonar_ds;
1324 chip->model.shortname = "Xonar DSX";
1325 break;
1326 case 0x835e:
1327 chip->model = model_xonar_hdav_slim;
1328 break;
1329 default:
1330 return -EINVAL;
1331 }
1332 return 0;
1333 }