Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * card driver for models with WM8776/WM8766 DACs (Xonar DS/HDAV1.3 Slim)
0004  *
0005  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
0006  */
0007 
0008 /*
0009  * Xonar DS
0010  * --------
0011  *
0012  * CMI8788:
0013  *
0014  *   SPI 0 -> WM8766 (surround, center/LFE, back)
0015  *   SPI 1 -> WM8776 (front, input)
0016  *
0017  *   GPIO 4 <- headphone detect, 0 = plugged
0018  *   GPIO 6 -> route input jack to mic-in (0) or line-in (1)
0019  *   GPIO 7 -> enable output to front L/R speaker channels
0020  *   GPIO 8 -> enable output to other speaker channels and front panel headphone
0021  *
0022  * WM8776:
0023  *
0024  *   input 1 <- line
0025  *   input 2 <- mic
0026  *   input 3 <- front mic
0027  *   input 4 <- aux
0028  */
0029 
0030 /*
0031  * Xonar HDAV1.3 Slim
0032  * ------------------
0033  *
0034  * CMI8788:
0035  *
0036  *   I²C <-> WM8776 (addr 0011010)
0037  *
0038  *   GPIO 0  -> disable HDMI output
0039  *   GPIO 1  -> enable HP output
0040  *   GPIO 6  -> firmware EEPROM I²C clock
0041  *   GPIO 7 <-> firmware EEPROM I²C data
0042  *
0043  *   UART <-> HDMI controller
0044  *
0045  * WM8776:
0046  *
0047  *   input 1 <- mic
0048  *   input 2 <- aux
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    /* 001101, 0, /W=0 */
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         /* reg >= WM8776_HPLVOL is always true */
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         /* reg >= WM8766_LDA1 is always true */
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      * The WM8766 can mix left and right channels, but this setting
0483      * applies to all three stereo pairs.
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         /* line-in and mic-in are exclusive */
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 }