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