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