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