xref: /linux/sound/pci/oxygen/xonar_wm87x6.c (revision 24bce201d79807b668bf9d9e0aca801c5c0d5f78)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * card driver for models with WM8776/WM8766 DACs (Xonar DS/HDAV1.3 Slim)
4  *
5  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
6  */
7 
8 /*
9  * Xonar DS
10  * --------
11  *
12  * CMI8788:
13  *
14  *   SPI 0 -> WM8766 (surround, center/LFE, back)
15  *   SPI 1 -> WM8776 (front, input)
16  *
17  *   GPIO 4 <- headphone detect, 0 = plugged
18  *   GPIO 6 -> route input jack to mic-in (0) or line-in (1)
19  *   GPIO 7 -> enable output to front L/R speaker channels
20  *   GPIO 8 -> enable output to other speaker channels and front panel headphone
21  *
22  * WM8776:
23  *
24  *   input 1 <- line
25  *   input 2 <- mic
26  *   input 3 <- front mic
27  *   input 4 <- aux
28  */
29 
30 /*
31  * Xonar HDAV1.3 Slim
32  * ------------------
33  *
34  * CMI8788:
35  *
36  *   I²C <-> WM8776 (addr 0011010)
37  *
38  *   GPIO 0  -> disable HDMI output
39  *   GPIO 1  -> enable HP output
40  *   GPIO 6  -> firmware EEPROM I²C clock
41  *   GPIO 7 <-> firmware EEPROM I²C data
42  *
43  *   UART <-> HDMI controller
44  *
45  * WM8776:
46  *
47  *   input 1 <- mic
48  *   input 2 <- aux
49  */
50 
51 #include <linux/pci.h>
52 #include <linux/delay.h>
53 #include <sound/control.h>
54 #include <sound/core.h>
55 #include <sound/info.h>
56 #include <sound/jack.h>
57 #include <sound/pcm.h>
58 #include <sound/pcm_params.h>
59 #include <sound/tlv.h>
60 #include "xonar.h"
61 #include "wm8776.h"
62 #include "wm8766.h"
63 
64 #define GPIO_DS_HP_DETECT	0x0010
65 #define GPIO_DS_INPUT_ROUTE	0x0040
66 #define GPIO_DS_OUTPUT_FRONTLR	0x0080
67 #define GPIO_DS_OUTPUT_ENABLE	0x0100
68 
69 #define GPIO_SLIM_HDMI_DISABLE	0x0001
70 #define GPIO_SLIM_OUTPUT_ENABLE	0x0002
71 #define GPIO_SLIM_FIRMWARE_CLK	0x0040
72 #define GPIO_SLIM_FIRMWARE_DATA	0x0080
73 
74 #define I2C_DEVICE_WM8776	0x34	/* 001101, 0, /W=0 */
75 
76 #define LC_CONTROL_LIMITER	0x40000000
77 #define LC_CONTROL_ALC		0x20000000
78 
79 struct xonar_wm87x6 {
80 	struct xonar_generic generic;
81 	u16 wm8776_regs[0x17];
82 	u16 wm8766_regs[0x10];
83 	struct snd_kcontrol *line_adcmux_control;
84 	struct snd_kcontrol *mic_adcmux_control;
85 	struct snd_kcontrol *lc_controls[13];
86 	struct snd_jack *hp_jack;
87 	struct xonar_hdmi hdmi;
88 };
89 
90 static void wm8776_write_spi(struct oxygen *chip,
91 			     unsigned int reg, unsigned int value)
92 {
93 	oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
94 			 OXYGEN_SPI_DATA_LENGTH_2 |
95 			 OXYGEN_SPI_CLOCK_160 |
96 			 (1 << OXYGEN_SPI_CODEC_SHIFT) |
97 			 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
98 			 (reg << 9) | value);
99 }
100 
101 static void wm8776_write_i2c(struct oxygen *chip,
102 			     unsigned int reg, unsigned int value)
103 {
104 	oxygen_write_i2c(chip, I2C_DEVICE_WM8776,
105 			 (reg << 1) | (value >> 8), value);
106 }
107 
108 static void wm8776_write(struct oxygen *chip,
109 			 unsigned int reg, unsigned int value)
110 {
111 	struct xonar_wm87x6 *data = chip->model_data;
112 
113 	if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) ==
114 	    OXYGEN_FUNCTION_SPI)
115 		wm8776_write_spi(chip, reg, value);
116 	else
117 		wm8776_write_i2c(chip, reg, value);
118 	if (reg < ARRAY_SIZE(data->wm8776_regs)) {
119 		/* reg >= WM8776_HPLVOL is always true */
120 		if (reg <= WM8776_DACMASTER)
121 			value &= ~WM8776_UPDATE;
122 		data->wm8776_regs[reg] = value;
123 	}
124 }
125 
126 static void wm8776_write_cached(struct oxygen *chip,
127 				unsigned int reg, unsigned int value)
128 {
129 	struct xonar_wm87x6 *data = chip->model_data;
130 
131 	if (reg >= ARRAY_SIZE(data->wm8776_regs) ||
132 	    value != data->wm8776_regs[reg])
133 		wm8776_write(chip, reg, value);
134 }
135 
136 static void wm8766_write(struct oxygen *chip,
137 			 unsigned int reg, unsigned int value)
138 {
139 	struct xonar_wm87x6 *data = chip->model_data;
140 
141 	oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
142 			 OXYGEN_SPI_DATA_LENGTH_2 |
143 			 OXYGEN_SPI_CLOCK_160 |
144 			 (0 << OXYGEN_SPI_CODEC_SHIFT) |
145 			 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
146 			 (reg << 9) | value);
147 	if (reg < ARRAY_SIZE(data->wm8766_regs)) {
148 		/* reg >= WM8766_LDA1 is always true */
149 		if (reg <= WM8766_RDA1 ||
150 		    (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA))
151 			value &= ~WM8766_UPDATE;
152 		data->wm8766_regs[reg] = value;
153 	}
154 }
155 
156 static void wm8766_write_cached(struct oxygen *chip,
157 				unsigned int reg, unsigned int value)
158 {
159 	struct xonar_wm87x6 *data = chip->model_data;
160 
161 	if (reg >= ARRAY_SIZE(data->wm8766_regs) ||
162 	    value != data->wm8766_regs[reg])
163 		wm8766_write(chip, reg, value);
164 }
165 
166 static void wm8776_registers_init(struct oxygen *chip)
167 {
168 	struct xonar_wm87x6 *data = chip->model_data;
169 
170 	wm8776_write(chip, WM8776_RESET, 0);
171 	wm8776_write(chip, WM8776_PHASESWAP, WM8776_PH_MASK);
172 	wm8776_write(chip, WM8776_DACCTRL1, WM8776_DZCEN |
173 		     WM8776_PL_LEFT_LEFT | WM8776_PL_RIGHT_RIGHT);
174 	wm8776_write(chip, WM8776_DACMUTE, chip->dac_mute ? WM8776_DMUTE : 0);
175 	wm8776_write(chip, WM8776_DACIFCTRL,
176 		     WM8776_DACFMT_LJUST | WM8776_DACWL_24);
177 	wm8776_write(chip, WM8776_ADCIFCTRL,
178 		     data->wm8776_regs[WM8776_ADCIFCTRL]);
179 	wm8776_write(chip, WM8776_MSTRCTRL, data->wm8776_regs[WM8776_MSTRCTRL]);
180 	wm8776_write(chip, WM8776_PWRDOWN, data->wm8776_regs[WM8776_PWRDOWN]);
181 	wm8776_write(chip, WM8776_HPLVOL, data->wm8776_regs[WM8776_HPLVOL]);
182 	wm8776_write(chip, WM8776_HPRVOL, data->wm8776_regs[WM8776_HPRVOL] |
183 		     WM8776_UPDATE);
184 	wm8776_write(chip, WM8776_ADCLVOL, data->wm8776_regs[WM8776_ADCLVOL]);
185 	wm8776_write(chip, WM8776_ADCRVOL, data->wm8776_regs[WM8776_ADCRVOL]);
186 	wm8776_write(chip, WM8776_ADCMUX, data->wm8776_regs[WM8776_ADCMUX]);
187 	wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0]);
188 	wm8776_write(chip, WM8776_DACRVOL, chip->dac_volume[1] | WM8776_UPDATE);
189 }
190 
191 static void wm8766_registers_init(struct oxygen *chip)
192 {
193 	struct xonar_wm87x6 *data = chip->model_data;
194 
195 	wm8766_write(chip, WM8766_RESET, 0);
196 	wm8766_write(chip, WM8766_DAC_CTRL, data->wm8766_regs[WM8766_DAC_CTRL]);
197 	wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24);
198 	wm8766_write(chip, WM8766_DAC_CTRL2,
199 		     WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
200 	wm8766_write(chip, WM8766_LDA1, chip->dac_volume[2]);
201 	wm8766_write(chip, WM8766_RDA1, chip->dac_volume[3]);
202 	wm8766_write(chip, WM8766_LDA2, chip->dac_volume[4]);
203 	wm8766_write(chip, WM8766_RDA2, chip->dac_volume[5]);
204 	wm8766_write(chip, WM8766_LDA3, chip->dac_volume[6]);
205 	wm8766_write(chip, WM8766_RDA3, chip->dac_volume[7] | WM8766_UPDATE);
206 }
207 
208 static void wm8776_init(struct oxygen *chip)
209 {
210 	struct xonar_wm87x6 *data = chip->model_data;
211 
212 	data->wm8776_regs[WM8776_HPLVOL] = (0x79 - 60) | WM8776_HPZCEN;
213 	data->wm8776_regs[WM8776_HPRVOL] = (0x79 - 60) | WM8776_HPZCEN;
214 	data->wm8776_regs[WM8776_ADCIFCTRL] =
215 		WM8776_ADCFMT_LJUST | WM8776_ADCWL_24 | WM8776_ADCMCLK;
216 	data->wm8776_regs[WM8776_MSTRCTRL] =
217 		WM8776_ADCRATE_256 | WM8776_DACRATE_256;
218 	data->wm8776_regs[WM8776_PWRDOWN] = WM8776_HPPD;
219 	data->wm8776_regs[WM8776_ADCLVOL] = 0xa5 | WM8776_ZCA;
220 	data->wm8776_regs[WM8776_ADCRVOL] = 0xa5 | WM8776_ZCA;
221 	data->wm8776_regs[WM8776_ADCMUX] = 0x001;
222 	wm8776_registers_init(chip);
223 }
224 
225 static void wm8766_init(struct oxygen *chip)
226 {
227 	struct xonar_wm87x6 *data = chip->model_data;
228 
229 	data->wm8766_regs[WM8766_DAC_CTRL] =
230 		WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT;
231 	wm8766_registers_init(chip);
232 }
233 
234 static void xonar_ds_handle_hp_jack(struct oxygen *chip)
235 {
236 	struct xonar_wm87x6 *data = chip->model_data;
237 	bool hp_plugged;
238 	unsigned int reg;
239 
240 	mutex_lock(&chip->mutex);
241 
242 	hp_plugged = !(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
243 		       GPIO_DS_HP_DETECT);
244 
245 	oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
246 			      hp_plugged ? 0 : GPIO_DS_OUTPUT_FRONTLR,
247 			      GPIO_DS_OUTPUT_FRONTLR);
248 
249 	reg = data->wm8766_regs[WM8766_DAC_CTRL] & ~WM8766_MUTEALL;
250 	if (hp_plugged)
251 		reg |= WM8766_MUTEALL;
252 	wm8766_write_cached(chip, WM8766_DAC_CTRL, reg);
253 
254 	snd_jack_report(data->hp_jack, hp_plugged ? SND_JACK_HEADPHONE : 0);
255 
256 	mutex_unlock(&chip->mutex);
257 }
258 
259 static void xonar_ds_init(struct oxygen *chip)
260 {
261 	struct xonar_wm87x6 *data = chip->model_data;
262 
263 	data->generic.anti_pop_delay = 300;
264 	data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE;
265 
266 	wm8776_init(chip);
267 	wm8766_init(chip);
268 
269 	oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
270 			  GPIO_DS_INPUT_ROUTE | GPIO_DS_OUTPUT_FRONTLR);
271 	oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
272 			    GPIO_DS_HP_DETECT);
273 	oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE);
274 	oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT);
275 	chip->interrupt_mask |= OXYGEN_INT_GPIO;
276 
277 	xonar_enable_output(chip);
278 
279 	snd_jack_new(chip->card, "Headphone",
280 		     SND_JACK_HEADPHONE, &data->hp_jack, false, false);
281 	xonar_ds_handle_hp_jack(chip);
282 
283 	snd_component_add(chip->card, "WM8776");
284 	snd_component_add(chip->card, "WM8766");
285 }
286 
287 static void xonar_hdav_slim_init(struct oxygen *chip)
288 {
289 	struct xonar_wm87x6 *data = chip->model_data;
290 
291 	data->generic.anti_pop_delay = 300;
292 	data->generic.output_enable_bit = GPIO_SLIM_OUTPUT_ENABLE;
293 
294 	wm8776_init(chip);
295 
296 	oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
297 			  GPIO_SLIM_HDMI_DISABLE |
298 			  GPIO_SLIM_FIRMWARE_CLK |
299 			  GPIO_SLIM_FIRMWARE_DATA);
300 
301 	xonar_hdmi_init(chip, &data->hdmi);
302 	xonar_enable_output(chip);
303 
304 	snd_component_add(chip->card, "WM8776");
305 }
306 
307 static void xonar_ds_cleanup(struct oxygen *chip)
308 {
309 	xonar_disable_output(chip);
310 	wm8776_write(chip, WM8776_RESET, 0);
311 }
312 
313 static void xonar_hdav_slim_cleanup(struct oxygen *chip)
314 {
315 	xonar_hdmi_cleanup(chip);
316 	xonar_disable_output(chip);
317 	wm8776_write(chip, WM8776_RESET, 0);
318 	msleep(2);
319 }
320 
321 static void xonar_ds_suspend(struct oxygen *chip)
322 {
323 	xonar_ds_cleanup(chip);
324 }
325 
326 static void xonar_hdav_slim_suspend(struct oxygen *chip)
327 {
328 	xonar_hdav_slim_cleanup(chip);
329 }
330 
331 static void xonar_ds_resume(struct oxygen *chip)
332 {
333 	wm8776_registers_init(chip);
334 	wm8766_registers_init(chip);
335 	xonar_enable_output(chip);
336 	xonar_ds_handle_hp_jack(chip);
337 }
338 
339 static void xonar_hdav_slim_resume(struct oxygen *chip)
340 {
341 	struct xonar_wm87x6 *data = chip->model_data;
342 
343 	wm8776_registers_init(chip);
344 	xonar_hdmi_resume(chip, &data->hdmi);
345 	xonar_enable_output(chip);
346 }
347 
348 static void wm8776_adc_hardware_filter(unsigned int channel,
349 				       struct snd_pcm_hardware *hardware)
350 {
351 	if (channel == PCM_A) {
352 		hardware->rates = SNDRV_PCM_RATE_32000 |
353 				  SNDRV_PCM_RATE_44100 |
354 				  SNDRV_PCM_RATE_48000 |
355 				  SNDRV_PCM_RATE_64000 |
356 				  SNDRV_PCM_RATE_88200 |
357 				  SNDRV_PCM_RATE_96000;
358 		hardware->rate_max = 96000;
359 	}
360 }
361 
362 static void xonar_hdav_slim_hardware_filter(unsigned int channel,
363 					    struct snd_pcm_hardware *hardware)
364 {
365 	wm8776_adc_hardware_filter(channel, hardware);
366 	xonar_hdmi_pcm_hardware_filter(channel, hardware);
367 }
368 
369 static void set_wm87x6_dac_params(struct oxygen *chip,
370 				  struct snd_pcm_hw_params *params)
371 {
372 }
373 
374 static void set_wm8776_adc_params(struct oxygen *chip,
375 				  struct snd_pcm_hw_params *params)
376 {
377 	u16 reg;
378 
379 	reg = WM8776_ADCRATE_256 | WM8776_DACRATE_256;
380 	if (params_rate(params) > 48000)
381 		reg |= WM8776_ADCOSR;
382 	wm8776_write_cached(chip, WM8776_MSTRCTRL, reg);
383 }
384 
385 static void set_hdav_slim_dac_params(struct oxygen *chip,
386 				     struct snd_pcm_hw_params *params)
387 {
388 	struct xonar_wm87x6 *data = chip->model_data;
389 
390 	xonar_set_hdmi_params(chip, &data->hdmi, params);
391 }
392 
393 static void update_wm8776_volume(struct oxygen *chip)
394 {
395 	struct xonar_wm87x6 *data = chip->model_data;
396 	u8 to_change;
397 
398 	if (chip->dac_volume[0] == chip->dac_volume[1]) {
399 		if (chip->dac_volume[0] != data->wm8776_regs[WM8776_DACLVOL] ||
400 		    chip->dac_volume[1] != data->wm8776_regs[WM8776_DACRVOL]) {
401 			wm8776_write(chip, WM8776_DACMASTER,
402 				     chip->dac_volume[0] | WM8776_UPDATE);
403 			data->wm8776_regs[WM8776_DACLVOL] = chip->dac_volume[0];
404 			data->wm8776_regs[WM8776_DACRVOL] = chip->dac_volume[0];
405 		}
406 	} else {
407 		to_change = (chip->dac_volume[0] !=
408 			     data->wm8776_regs[WM8776_DACLVOL]) << 0;
409 		to_change |= (chip->dac_volume[1] !=
410 			      data->wm8776_regs[WM8776_DACLVOL]) << 1;
411 		if (to_change & 1)
412 			wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0] |
413 				     ((to_change & 2) ? 0 : WM8776_UPDATE));
414 		if (to_change & 2)
415 			wm8776_write(chip, WM8776_DACRVOL,
416 				     chip->dac_volume[1] | WM8776_UPDATE);
417 	}
418 }
419 
420 static void update_wm87x6_volume(struct oxygen *chip)
421 {
422 	static const u8 wm8766_regs[6] = {
423 		WM8766_LDA1, WM8766_RDA1,
424 		WM8766_LDA2, WM8766_RDA2,
425 		WM8766_LDA3, WM8766_RDA3,
426 	};
427 	struct xonar_wm87x6 *data = chip->model_data;
428 	unsigned int i;
429 	u8 to_change;
430 
431 	update_wm8776_volume(chip);
432 	if (chip->dac_volume[2] == chip->dac_volume[3] &&
433 	    chip->dac_volume[2] == chip->dac_volume[4] &&
434 	    chip->dac_volume[2] == chip->dac_volume[5] &&
435 	    chip->dac_volume[2] == chip->dac_volume[6] &&
436 	    chip->dac_volume[2] == chip->dac_volume[7]) {
437 		to_change = 0;
438 		for (i = 0; i < 6; ++i)
439 			if (chip->dac_volume[2] !=
440 			    data->wm8766_regs[wm8766_regs[i]])
441 				to_change = 1;
442 		if (to_change) {
443 			wm8766_write(chip, WM8766_MASTDA,
444 				     chip->dac_volume[2] | WM8766_UPDATE);
445 			for (i = 0; i < 6; ++i)
446 				data->wm8766_regs[wm8766_regs[i]] =
447 					chip->dac_volume[2];
448 		}
449 	} else {
450 		to_change = 0;
451 		for (i = 0; i < 6; ++i)
452 			to_change |= (chip->dac_volume[2 + i] !=
453 				      data->wm8766_regs[wm8766_regs[i]]) << i;
454 		for (i = 0; i < 6; ++i)
455 			if (to_change & (1 << i))
456 				wm8766_write(chip, wm8766_regs[i],
457 					     chip->dac_volume[2 + i] |
458 					     ((to_change & (0x3e << i))
459 					      ? 0 : WM8766_UPDATE));
460 	}
461 }
462 
463 static void update_wm8776_mute(struct oxygen *chip)
464 {
465 	wm8776_write_cached(chip, WM8776_DACMUTE,
466 			    chip->dac_mute ? WM8776_DMUTE : 0);
467 }
468 
469 static void update_wm87x6_mute(struct oxygen *chip)
470 {
471 	update_wm8776_mute(chip);
472 	wm8766_write_cached(chip, WM8766_DAC_CTRL2, WM8766_ZCD |
473 			    (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
474 }
475 
476 static void update_wm8766_center_lfe_mix(struct oxygen *chip, bool mixed)
477 {
478 	struct xonar_wm87x6 *data = chip->model_data;
479 	unsigned int reg;
480 
481 	/*
482 	 * The WM8766 can mix left and right channels, but this setting
483 	 * applies to all three stereo pairs.
484 	 */
485 	reg = data->wm8766_regs[WM8766_DAC_CTRL] &
486 		~(WM8766_PL_LEFT_MASK | WM8766_PL_RIGHT_MASK);
487 	if (mixed)
488 		reg |= WM8766_PL_LEFT_LRMIX | WM8766_PL_RIGHT_LRMIX;
489 	else
490 		reg |= WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT;
491 	wm8766_write_cached(chip, WM8766_DAC_CTRL, reg);
492 }
493 
494 static void xonar_ds_gpio_changed(struct oxygen *chip)
495 {
496 	xonar_ds_handle_hp_jack(chip);
497 }
498 
499 static int wm8776_bit_switch_get(struct snd_kcontrol *ctl,
500 				 struct snd_ctl_elem_value *value)
501 {
502 	struct oxygen *chip = ctl->private_data;
503 	struct xonar_wm87x6 *data = chip->model_data;
504 	u16 bit = ctl->private_value & 0xffff;
505 	unsigned int reg_index = (ctl->private_value >> 16) & 0xff;
506 	bool invert = (ctl->private_value >> 24) & 1;
507 
508 	value->value.integer.value[0] =
509 		((data->wm8776_regs[reg_index] & bit) != 0) ^ invert;
510 	return 0;
511 }
512 
513 static int wm8776_bit_switch_put(struct snd_kcontrol *ctl,
514 				 struct snd_ctl_elem_value *value)
515 {
516 	struct oxygen *chip = ctl->private_data;
517 	struct xonar_wm87x6 *data = chip->model_data;
518 	u16 bit = ctl->private_value & 0xffff;
519 	u16 reg_value;
520 	unsigned int reg_index = (ctl->private_value >> 16) & 0xff;
521 	bool invert = (ctl->private_value >> 24) & 1;
522 	int changed;
523 
524 	mutex_lock(&chip->mutex);
525 	reg_value = data->wm8776_regs[reg_index] & ~bit;
526 	if (value->value.integer.value[0] ^ invert)
527 		reg_value |= bit;
528 	changed = reg_value != data->wm8776_regs[reg_index];
529 	if (changed)
530 		wm8776_write(chip, reg_index, reg_value);
531 	mutex_unlock(&chip->mutex);
532 	return changed;
533 }
534 
535 static int wm8776_field_enum_info(struct snd_kcontrol *ctl,
536 				  struct snd_ctl_elem_info *info)
537 {
538 	static const char *const hld[16] = {
539 		"0 ms", "2.67 ms", "5.33 ms", "10.6 ms",
540 		"21.3 ms", "42.7 ms", "85.3 ms", "171 ms",
541 		"341 ms", "683 ms", "1.37 s", "2.73 s",
542 		"5.46 s", "10.9 s", "21.8 s", "43.7 s",
543 	};
544 	static const char *const atk_lim[11] = {
545 		"0.25 ms", "0.5 ms", "1 ms", "2 ms",
546 		"4 ms", "8 ms", "16 ms", "32 ms",
547 		"64 ms", "128 ms", "256 ms",
548 	};
549 	static const char *const atk_alc[11] = {
550 		"8.40 ms", "16.8 ms", "33.6 ms", "67.2 ms",
551 		"134 ms", "269 ms", "538 ms", "1.08 s",
552 		"2.15 s", "4.3 s", "8.6 s",
553 	};
554 	static const char *const dcy_lim[11] = {
555 		"1.2 ms", "2.4 ms", "4.8 ms", "9.6 ms",
556 		"19.2 ms", "38.4 ms", "76.8 ms", "154 ms",
557 		"307 ms", "614 ms", "1.23 s",
558 	};
559 	static const char *const dcy_alc[11] = {
560 		"33.5 ms", "67.0 ms", "134 ms", "268 ms",
561 		"536 ms", "1.07 s", "2.14 s", "4.29 s",
562 		"8.58 s", "17.2 s", "34.3 s",
563 	};
564 	static const char *const tranwin[8] = {
565 		"0 us", "62.5 us", "125 us", "250 us",
566 		"500 us", "1 ms", "2 ms", "4 ms",
567 	};
568 	u8 max;
569 	const char *const *names;
570 
571 	max = (ctl->private_value >> 12) & 0xf;
572 	switch ((ctl->private_value >> 24) & 0x1f) {
573 	case WM8776_ALCCTRL2:
574 		names = hld;
575 		break;
576 	case WM8776_ALCCTRL3:
577 		if (((ctl->private_value >> 20) & 0xf) == 0) {
578 			if (ctl->private_value & LC_CONTROL_LIMITER)
579 				names = atk_lim;
580 			else
581 				names = atk_alc;
582 		} else {
583 			if (ctl->private_value & LC_CONTROL_LIMITER)
584 				names = dcy_lim;
585 			else
586 				names = dcy_alc;
587 		}
588 		break;
589 	case WM8776_LIMITER:
590 		names = tranwin;
591 		break;
592 	default:
593 		return -ENXIO;
594 	}
595 	return snd_ctl_enum_info(info, 1, max + 1, names);
596 }
597 
598 static int wm8776_field_volume_info(struct snd_kcontrol *ctl,
599 				    struct snd_ctl_elem_info *info)
600 {
601 	info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
602 	info->count = 1;
603 	info->value.integer.min = (ctl->private_value >> 8) & 0xf;
604 	info->value.integer.max = (ctl->private_value >> 12) & 0xf;
605 	return 0;
606 }
607 
608 static void wm8776_field_set_from_ctl(struct snd_kcontrol *ctl)
609 {
610 	struct oxygen *chip = ctl->private_data;
611 	struct xonar_wm87x6 *data = chip->model_data;
612 	unsigned int value, reg_index, mode;
613 	u8 min, max, shift;
614 	u16 mask, reg_value;
615 	bool invert;
616 
617 	if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) ==
618 	    WM8776_LCSEL_LIMITER)
619 		mode = LC_CONTROL_LIMITER;
620 	else
621 		mode = LC_CONTROL_ALC;
622 	if (!(ctl->private_value & mode))
623 		return;
624 
625 	value = ctl->private_value & 0xf;
626 	min = (ctl->private_value >> 8) & 0xf;
627 	max = (ctl->private_value >> 12) & 0xf;
628 	mask = (ctl->private_value >> 16) & 0xf;
629 	shift = (ctl->private_value >> 20) & 0xf;
630 	reg_index = (ctl->private_value >> 24) & 0x1f;
631 	invert = (ctl->private_value >> 29) & 0x1;
632 
633 	if (invert)
634 		value = max - (value - min);
635 	reg_value = data->wm8776_regs[reg_index];
636 	reg_value &= ~(mask << shift);
637 	reg_value |= value << shift;
638 	wm8776_write_cached(chip, reg_index, reg_value);
639 }
640 
641 static int wm8776_field_set(struct snd_kcontrol *ctl, unsigned int value)
642 {
643 	struct oxygen *chip = ctl->private_data;
644 	u8 min, max;
645 	int changed;
646 
647 	min = (ctl->private_value >> 8) & 0xf;
648 	max = (ctl->private_value >> 12) & 0xf;
649 	if (value < min || value > max)
650 		return -EINVAL;
651 	mutex_lock(&chip->mutex);
652 	changed = value != (ctl->private_value & 0xf);
653 	if (changed) {
654 		ctl->private_value = (ctl->private_value & ~0xf) | value;
655 		wm8776_field_set_from_ctl(ctl);
656 	}
657 	mutex_unlock(&chip->mutex);
658 	return changed;
659 }
660 
661 static int wm8776_field_enum_get(struct snd_kcontrol *ctl,
662 				 struct snd_ctl_elem_value *value)
663 {
664 	value->value.enumerated.item[0] = ctl->private_value & 0xf;
665 	return 0;
666 }
667 
668 static int wm8776_field_volume_get(struct snd_kcontrol *ctl,
669 				   struct snd_ctl_elem_value *value)
670 {
671 	value->value.integer.value[0] = ctl->private_value & 0xf;
672 	return 0;
673 }
674 
675 static int wm8776_field_enum_put(struct snd_kcontrol *ctl,
676 				 struct snd_ctl_elem_value *value)
677 {
678 	return wm8776_field_set(ctl, value->value.enumerated.item[0]);
679 }
680 
681 static int wm8776_field_volume_put(struct snd_kcontrol *ctl,
682 				   struct snd_ctl_elem_value *value)
683 {
684 	return wm8776_field_set(ctl, value->value.integer.value[0]);
685 }
686 
687 static int wm8776_hp_vol_info(struct snd_kcontrol *ctl,
688 			      struct snd_ctl_elem_info *info)
689 {
690 	info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
691 	info->count = 2;
692 	info->value.integer.min = 0x79 - 60;
693 	info->value.integer.max = 0x7f;
694 	return 0;
695 }
696 
697 static int wm8776_hp_vol_get(struct snd_kcontrol *ctl,
698 			     struct snd_ctl_elem_value *value)
699 {
700 	struct oxygen *chip = ctl->private_data;
701 	struct xonar_wm87x6 *data = chip->model_data;
702 
703 	mutex_lock(&chip->mutex);
704 	value->value.integer.value[0] =
705 		data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK;
706 	value->value.integer.value[1] =
707 		data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK;
708 	mutex_unlock(&chip->mutex);
709 	return 0;
710 }
711 
712 static int wm8776_hp_vol_put(struct snd_kcontrol *ctl,
713 			     struct snd_ctl_elem_value *value)
714 {
715 	struct oxygen *chip = ctl->private_data;
716 	struct xonar_wm87x6 *data = chip->model_data;
717 	u8 to_update;
718 
719 	mutex_lock(&chip->mutex);
720 	to_update = (value->value.integer.value[0] !=
721 		     (data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK))
722 		<< 0;
723 	to_update |= (value->value.integer.value[1] !=
724 		      (data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK))
725 		<< 1;
726 	if (value->value.integer.value[0] == value->value.integer.value[1]) {
727 		if (to_update) {
728 			wm8776_write(chip, WM8776_HPMASTER,
729 				     value->value.integer.value[0] |
730 				     WM8776_HPZCEN | WM8776_UPDATE);
731 			data->wm8776_regs[WM8776_HPLVOL] =
732 				value->value.integer.value[0] | WM8776_HPZCEN;
733 			data->wm8776_regs[WM8776_HPRVOL] =
734 				value->value.integer.value[0] | WM8776_HPZCEN;
735 		}
736 	} else {
737 		if (to_update & 1)
738 			wm8776_write(chip, WM8776_HPLVOL,
739 				     value->value.integer.value[0] |
740 				     WM8776_HPZCEN |
741 				     ((to_update & 2) ? 0 : WM8776_UPDATE));
742 		if (to_update & 2)
743 			wm8776_write(chip, WM8776_HPRVOL,
744 				     value->value.integer.value[1] |
745 				     WM8776_HPZCEN | WM8776_UPDATE);
746 	}
747 	mutex_unlock(&chip->mutex);
748 	return to_update != 0;
749 }
750 
751 static int wm8776_input_mux_get(struct snd_kcontrol *ctl,
752 				struct snd_ctl_elem_value *value)
753 {
754 	struct oxygen *chip = ctl->private_data;
755 	struct xonar_wm87x6 *data = chip->model_data;
756 	unsigned int mux_bit = ctl->private_value;
757 
758 	value->value.integer.value[0] =
759 		!!(data->wm8776_regs[WM8776_ADCMUX] & mux_bit);
760 	return 0;
761 }
762 
763 static int wm8776_input_mux_put(struct snd_kcontrol *ctl,
764 				struct snd_ctl_elem_value *value)
765 {
766 	struct oxygen *chip = ctl->private_data;
767 	struct xonar_wm87x6 *data = chip->model_data;
768 	struct snd_kcontrol *other_ctl;
769 	unsigned int mux_bit = ctl->private_value;
770 	u16 reg;
771 	int changed;
772 
773 	mutex_lock(&chip->mutex);
774 	reg = data->wm8776_regs[WM8776_ADCMUX];
775 	if (value->value.integer.value[0]) {
776 		reg |= mux_bit;
777 		/* line-in and mic-in are exclusive */
778 		mux_bit ^= 3;
779 		if (reg & mux_bit) {
780 			reg &= ~mux_bit;
781 			if (mux_bit == 1)
782 				other_ctl = data->line_adcmux_control;
783 			else
784 				other_ctl = data->mic_adcmux_control;
785 			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
786 				       &other_ctl->id);
787 		}
788 	} else
789 		reg &= ~mux_bit;
790 	changed = reg != data->wm8776_regs[WM8776_ADCMUX];
791 	if (changed) {
792 		oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
793 				      reg & 1 ? GPIO_DS_INPUT_ROUTE : 0,
794 				      GPIO_DS_INPUT_ROUTE);
795 		wm8776_write(chip, WM8776_ADCMUX, reg);
796 	}
797 	mutex_unlock(&chip->mutex);
798 	return changed;
799 }
800 
801 static int wm8776_input_vol_info(struct snd_kcontrol *ctl,
802 				 struct snd_ctl_elem_info *info)
803 {
804 	info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
805 	info->count = 2;
806 	info->value.integer.min = 0xa5;
807 	info->value.integer.max = 0xff;
808 	return 0;
809 }
810 
811 static int wm8776_input_vol_get(struct snd_kcontrol *ctl,
812 				struct snd_ctl_elem_value *value)
813 {
814 	struct oxygen *chip = ctl->private_data;
815 	struct xonar_wm87x6 *data = chip->model_data;
816 
817 	mutex_lock(&chip->mutex);
818 	value->value.integer.value[0] =
819 		data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK;
820 	value->value.integer.value[1] =
821 		data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK;
822 	mutex_unlock(&chip->mutex);
823 	return 0;
824 }
825 
826 static int wm8776_input_vol_put(struct snd_kcontrol *ctl,
827 				struct snd_ctl_elem_value *value)
828 {
829 	struct oxygen *chip = ctl->private_data;
830 	struct xonar_wm87x6 *data = chip->model_data;
831 	int changed = 0;
832 
833 	mutex_lock(&chip->mutex);
834 	changed = (value->value.integer.value[0] !=
835 		   (data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK)) ||
836 		  (value->value.integer.value[1] !=
837 		   (data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK));
838 	wm8776_write_cached(chip, WM8776_ADCLVOL,
839 			    value->value.integer.value[0] | WM8776_ZCA);
840 	wm8776_write_cached(chip, WM8776_ADCRVOL,
841 			    value->value.integer.value[1] | WM8776_ZCA);
842 	mutex_unlock(&chip->mutex);
843 	return changed;
844 }
845 
846 static int wm8776_level_control_info(struct snd_kcontrol *ctl,
847 				     struct snd_ctl_elem_info *info)
848 {
849 	static const char *const names[3] = {
850 		"None", "Peak Limiter", "Automatic Level Control"
851 	};
852 
853 	return snd_ctl_enum_info(info, 1, 3, names);
854 }
855 
856 static int wm8776_level_control_get(struct snd_kcontrol *ctl,
857 				    struct snd_ctl_elem_value *value)
858 {
859 	struct oxygen *chip = ctl->private_data;
860 	struct xonar_wm87x6 *data = chip->model_data;
861 
862 	if (!(data->wm8776_regs[WM8776_ALCCTRL2] & WM8776_LCEN))
863 		value->value.enumerated.item[0] = 0;
864 	else if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) ==
865 		 WM8776_LCSEL_LIMITER)
866 		value->value.enumerated.item[0] = 1;
867 	else
868 		value->value.enumerated.item[0] = 2;
869 	return 0;
870 }
871 
872 static void activate_control(struct oxygen *chip,
873 			     struct snd_kcontrol *ctl, unsigned int mode)
874 {
875 	unsigned int access;
876 
877 	if (ctl->private_value & mode)
878 		access = 0;
879 	else
880 		access = SNDRV_CTL_ELEM_ACCESS_INACTIVE;
881 	if ((ctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE) != access) {
882 		ctl->vd[0].access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
883 		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
884 	}
885 }
886 
887 static int wm8776_level_control_put(struct snd_kcontrol *ctl,
888 				    struct snd_ctl_elem_value *value)
889 {
890 	struct oxygen *chip = ctl->private_data;
891 	struct xonar_wm87x6 *data = chip->model_data;
892 	unsigned int mode = 0, i;
893 	u16 ctrl1, ctrl2;
894 	int changed;
895 
896 	if (value->value.enumerated.item[0] >= 3)
897 		return -EINVAL;
898 	mutex_lock(&chip->mutex);
899 	changed = value->value.enumerated.item[0] != ctl->private_value;
900 	if (changed) {
901 		ctl->private_value = value->value.enumerated.item[0];
902 		ctrl1 = data->wm8776_regs[WM8776_ALCCTRL1];
903 		ctrl2 = data->wm8776_regs[WM8776_ALCCTRL2];
904 		switch (value->value.enumerated.item[0]) {
905 		default:
906 			wm8776_write_cached(chip, WM8776_ALCCTRL2,
907 					    ctrl2 & ~WM8776_LCEN);
908 			break;
909 		case 1:
910 			wm8776_write_cached(chip, WM8776_ALCCTRL1,
911 					    (ctrl1 & ~WM8776_LCSEL_MASK) |
912 					    WM8776_LCSEL_LIMITER);
913 			wm8776_write_cached(chip, WM8776_ALCCTRL2,
914 					    ctrl2 | WM8776_LCEN);
915 			mode = LC_CONTROL_LIMITER;
916 			break;
917 		case 2:
918 			wm8776_write_cached(chip, WM8776_ALCCTRL1,
919 					    (ctrl1 & ~WM8776_LCSEL_MASK) |
920 					    WM8776_LCSEL_ALC_STEREO);
921 			wm8776_write_cached(chip, WM8776_ALCCTRL2,
922 					    ctrl2 | WM8776_LCEN);
923 			mode = LC_CONTROL_ALC;
924 			break;
925 		}
926 		for (i = 0; i < ARRAY_SIZE(data->lc_controls); ++i)
927 			activate_control(chip, data->lc_controls[i], mode);
928 	}
929 	mutex_unlock(&chip->mutex);
930 	return changed;
931 }
932 
933 static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
934 {
935 	static const char *const names[2] = {
936 		"None", "High-pass Filter"
937 	};
938 
939 	return snd_ctl_enum_info(info, 1, 2, names);
940 }
941 
942 static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
943 {
944 	struct oxygen *chip = ctl->private_data;
945 	struct xonar_wm87x6 *data = chip->model_data;
946 
947 	value->value.enumerated.item[0] =
948 		!(data->wm8776_regs[WM8776_ADCIFCTRL] & WM8776_ADCHPD);
949 	return 0;
950 }
951 
952 static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
953 {
954 	struct oxygen *chip = ctl->private_data;
955 	struct xonar_wm87x6 *data = chip->model_data;
956 	unsigned int reg;
957 	int changed;
958 
959 	mutex_lock(&chip->mutex);
960 	reg = data->wm8776_regs[WM8776_ADCIFCTRL] & ~WM8776_ADCHPD;
961 	if (!value->value.enumerated.item[0])
962 		reg |= WM8776_ADCHPD;
963 	changed = reg != data->wm8776_regs[WM8776_ADCIFCTRL];
964 	if (changed)
965 		wm8776_write(chip, WM8776_ADCIFCTRL, reg);
966 	mutex_unlock(&chip->mutex);
967 	return changed;
968 }
969 
970 #define WM8776_BIT_SWITCH(xname, reg, bit, invert, flags) { \
971 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
972 	.name = xname, \
973 	.info = snd_ctl_boolean_mono_info, \
974 	.get = wm8776_bit_switch_get, \
975 	.put = wm8776_bit_switch_put, \
976 	.private_value = ((reg) << 16) | (bit) | ((invert) << 24) | (flags), \
977 }
978 #define _WM8776_FIELD_CTL(xname, reg, shift, initval, min, max, mask, flags) \
979 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
980 	.name = xname, \
981 	.private_value = (initval) | ((min) << 8) | ((max) << 12) | \
982 	((mask) << 16) | ((shift) << 20) | ((reg) << 24) | (flags)
983 #define WM8776_FIELD_CTL_ENUM(xname, reg, shift, init, min, max, mask, flags) {\
984 	_WM8776_FIELD_CTL(xname " Capture Enum", \
985 			  reg, shift, init, min, max, mask, flags), \
986 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
987 		  SNDRV_CTL_ELEM_ACCESS_INACTIVE, \
988 	.info = wm8776_field_enum_info, \
989 	.get = wm8776_field_enum_get, \
990 	.put = wm8776_field_enum_put, \
991 }
992 #define WM8776_FIELD_CTL_VOLUME(a, b, c, d, e, f, g, h, tlv_p) { \
993 	_WM8776_FIELD_CTL(a " Capture Volume", b, c, d, e, f, g, h), \
994 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
995 		  SNDRV_CTL_ELEM_ACCESS_INACTIVE | \
996 		  SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
997 	.info = wm8776_field_volume_info, \
998 	.get = wm8776_field_volume_get, \
999 	.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 }
1334