xref: /linux/sound/pci/oxygen/xonar_wm87x6.c (revision 05a54fa773284d1a7923cdfdd8f0c8dabb98bd26)
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 	guard(mutex)(&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 
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 	guard(mutex)(&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 	return changed;
530 }
531 
532 static int wm8776_field_enum_info(struct snd_kcontrol *ctl,
533 				  struct snd_ctl_elem_info *info)
534 {
535 	static const char *const hld[16] = {
536 		"0 ms", "2.67 ms", "5.33 ms", "10.6 ms",
537 		"21.3 ms", "42.7 ms", "85.3 ms", "171 ms",
538 		"341 ms", "683 ms", "1.37 s", "2.73 s",
539 		"5.46 s", "10.9 s", "21.8 s", "43.7 s",
540 	};
541 	static const char *const atk_lim[11] = {
542 		"0.25 ms", "0.5 ms", "1 ms", "2 ms",
543 		"4 ms", "8 ms", "16 ms", "32 ms",
544 		"64 ms", "128 ms", "256 ms",
545 	};
546 	static const char *const atk_alc[11] = {
547 		"8.40 ms", "16.8 ms", "33.6 ms", "67.2 ms",
548 		"134 ms", "269 ms", "538 ms", "1.08 s",
549 		"2.15 s", "4.3 s", "8.6 s",
550 	};
551 	static const char *const dcy_lim[11] = {
552 		"1.2 ms", "2.4 ms", "4.8 ms", "9.6 ms",
553 		"19.2 ms", "38.4 ms", "76.8 ms", "154 ms",
554 		"307 ms", "614 ms", "1.23 s",
555 	};
556 	static const char *const dcy_alc[11] = {
557 		"33.5 ms", "67.0 ms", "134 ms", "268 ms",
558 		"536 ms", "1.07 s", "2.14 s", "4.29 s",
559 		"8.58 s", "17.2 s", "34.3 s",
560 	};
561 	static const char *const tranwin[8] = {
562 		"0 us", "62.5 us", "125 us", "250 us",
563 		"500 us", "1 ms", "2 ms", "4 ms",
564 	};
565 	u8 max;
566 	const char *const *names;
567 
568 	max = (ctl->private_value >> 12) & 0xf;
569 	switch ((ctl->private_value >> 24) & 0x1f) {
570 	case WM8776_ALCCTRL2:
571 		names = hld;
572 		break;
573 	case WM8776_ALCCTRL3:
574 		if (((ctl->private_value >> 20) & 0xf) == 0) {
575 			if (ctl->private_value & LC_CONTROL_LIMITER)
576 				names = atk_lim;
577 			else
578 				names = atk_alc;
579 		} else {
580 			if (ctl->private_value & LC_CONTROL_LIMITER)
581 				names = dcy_lim;
582 			else
583 				names = dcy_alc;
584 		}
585 		break;
586 	case WM8776_LIMITER:
587 		names = tranwin;
588 		break;
589 	default:
590 		return -ENXIO;
591 	}
592 	return snd_ctl_enum_info(info, 1, max + 1, names);
593 }
594 
595 static int wm8776_field_volume_info(struct snd_kcontrol *ctl,
596 				    struct snd_ctl_elem_info *info)
597 {
598 	info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
599 	info->count = 1;
600 	info->value.integer.min = (ctl->private_value >> 8) & 0xf;
601 	info->value.integer.max = (ctl->private_value >> 12) & 0xf;
602 	return 0;
603 }
604 
605 static void wm8776_field_set_from_ctl(struct snd_kcontrol *ctl)
606 {
607 	struct oxygen *chip = ctl->private_data;
608 	struct xonar_wm87x6 *data = chip->model_data;
609 	unsigned int value, reg_index, mode;
610 	u8 min, max, shift;
611 	u16 mask, reg_value;
612 	bool invert;
613 
614 	if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) ==
615 	    WM8776_LCSEL_LIMITER)
616 		mode = LC_CONTROL_LIMITER;
617 	else
618 		mode = LC_CONTROL_ALC;
619 	if (!(ctl->private_value & mode))
620 		return;
621 
622 	value = ctl->private_value & 0xf;
623 	min = (ctl->private_value >> 8) & 0xf;
624 	max = (ctl->private_value >> 12) & 0xf;
625 	mask = (ctl->private_value >> 16) & 0xf;
626 	shift = (ctl->private_value >> 20) & 0xf;
627 	reg_index = (ctl->private_value >> 24) & 0x1f;
628 	invert = (ctl->private_value >> 29) & 0x1;
629 
630 	if (invert)
631 		value = max - (value - min);
632 	reg_value = data->wm8776_regs[reg_index];
633 	reg_value &= ~(mask << shift);
634 	reg_value |= value << shift;
635 	wm8776_write_cached(chip, reg_index, reg_value);
636 }
637 
638 static int wm8776_field_set(struct snd_kcontrol *ctl, unsigned int value)
639 {
640 	struct oxygen *chip = ctl->private_data;
641 	u8 min, max;
642 	int changed;
643 
644 	min = (ctl->private_value >> 8) & 0xf;
645 	max = (ctl->private_value >> 12) & 0xf;
646 	if (value < min || value > max)
647 		return -EINVAL;
648 	guard(mutex)(&chip->mutex);
649 	changed = value != (ctl->private_value & 0xf);
650 	if (changed) {
651 		ctl->private_value = (ctl->private_value & ~0xf) | value;
652 		wm8776_field_set_from_ctl(ctl);
653 	}
654 	return changed;
655 }
656 
657 static int wm8776_field_enum_get(struct snd_kcontrol *ctl,
658 				 struct snd_ctl_elem_value *value)
659 {
660 	value->value.enumerated.item[0] = ctl->private_value & 0xf;
661 	return 0;
662 }
663 
664 static int wm8776_field_volume_get(struct snd_kcontrol *ctl,
665 				   struct snd_ctl_elem_value *value)
666 {
667 	value->value.integer.value[0] = ctl->private_value & 0xf;
668 	return 0;
669 }
670 
671 static int wm8776_field_enum_put(struct snd_kcontrol *ctl,
672 				 struct snd_ctl_elem_value *value)
673 {
674 	return wm8776_field_set(ctl, value->value.enumerated.item[0]);
675 }
676 
677 static int wm8776_field_volume_put(struct snd_kcontrol *ctl,
678 				   struct snd_ctl_elem_value *value)
679 {
680 	return wm8776_field_set(ctl, value->value.integer.value[0]);
681 }
682 
683 static int wm8776_hp_vol_info(struct snd_kcontrol *ctl,
684 			      struct snd_ctl_elem_info *info)
685 {
686 	info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
687 	info->count = 2;
688 	info->value.integer.min = 0x79 - 60;
689 	info->value.integer.max = 0x7f;
690 	return 0;
691 }
692 
693 static int wm8776_hp_vol_get(struct snd_kcontrol *ctl,
694 			     struct snd_ctl_elem_value *value)
695 {
696 	struct oxygen *chip = ctl->private_data;
697 	struct xonar_wm87x6 *data = chip->model_data;
698 
699 	guard(mutex)(&chip->mutex);
700 	value->value.integer.value[0] =
701 		data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK;
702 	value->value.integer.value[1] =
703 		data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK;
704 	return 0;
705 }
706 
707 static int wm8776_hp_vol_put(struct snd_kcontrol *ctl,
708 			     struct snd_ctl_elem_value *value)
709 {
710 	struct oxygen *chip = ctl->private_data;
711 	struct xonar_wm87x6 *data = chip->model_data;
712 	u8 to_update;
713 
714 	guard(mutex)(&chip->mutex);
715 	to_update = (value->value.integer.value[0] !=
716 		     (data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK))
717 		<< 0;
718 	to_update |= (value->value.integer.value[1] !=
719 		      (data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK))
720 		<< 1;
721 	if (value->value.integer.value[0] == value->value.integer.value[1]) {
722 		if (to_update) {
723 			wm8776_write(chip, WM8776_HPMASTER,
724 				     value->value.integer.value[0] |
725 				     WM8776_HPZCEN | WM8776_UPDATE);
726 			data->wm8776_regs[WM8776_HPLVOL] =
727 				value->value.integer.value[0] | WM8776_HPZCEN;
728 			data->wm8776_regs[WM8776_HPRVOL] =
729 				value->value.integer.value[0] | WM8776_HPZCEN;
730 		}
731 	} else {
732 		if (to_update & 1)
733 			wm8776_write(chip, WM8776_HPLVOL,
734 				     value->value.integer.value[0] |
735 				     WM8776_HPZCEN |
736 				     ((to_update & 2) ? 0 : WM8776_UPDATE));
737 		if (to_update & 2)
738 			wm8776_write(chip, WM8776_HPRVOL,
739 				     value->value.integer.value[1] |
740 				     WM8776_HPZCEN | WM8776_UPDATE);
741 	}
742 	return to_update != 0;
743 }
744 
745 static int wm8776_input_mux_get(struct snd_kcontrol *ctl,
746 				struct snd_ctl_elem_value *value)
747 {
748 	struct oxygen *chip = ctl->private_data;
749 	struct xonar_wm87x6 *data = chip->model_data;
750 	unsigned int mux_bit = ctl->private_value;
751 
752 	value->value.integer.value[0] =
753 		!!(data->wm8776_regs[WM8776_ADCMUX] & mux_bit);
754 	return 0;
755 }
756 
757 static int wm8776_input_mux_put(struct snd_kcontrol *ctl,
758 				struct snd_ctl_elem_value *value)
759 {
760 	struct oxygen *chip = ctl->private_data;
761 	struct xonar_wm87x6 *data = chip->model_data;
762 	struct snd_kcontrol *other_ctl;
763 	unsigned int mux_bit = ctl->private_value;
764 	u16 reg;
765 	int changed;
766 
767 	guard(mutex)(&chip->mutex);
768 	reg = data->wm8776_regs[WM8776_ADCMUX];
769 	if (value->value.integer.value[0]) {
770 		reg |= mux_bit;
771 		/* line-in and mic-in are exclusive */
772 		mux_bit ^= 3;
773 		if (reg & mux_bit) {
774 			reg &= ~mux_bit;
775 			if (mux_bit == 1)
776 				other_ctl = data->line_adcmux_control;
777 			else
778 				other_ctl = data->mic_adcmux_control;
779 			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
780 				       &other_ctl->id);
781 		}
782 	} else
783 		reg &= ~mux_bit;
784 	changed = reg != data->wm8776_regs[WM8776_ADCMUX];
785 	if (changed) {
786 		oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
787 				      reg & 1 ? GPIO_DS_INPUT_ROUTE : 0,
788 				      GPIO_DS_INPUT_ROUTE);
789 		wm8776_write(chip, WM8776_ADCMUX, reg);
790 	}
791 	return changed;
792 }
793 
794 static int wm8776_input_vol_info(struct snd_kcontrol *ctl,
795 				 struct snd_ctl_elem_info *info)
796 {
797 	info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
798 	info->count = 2;
799 	info->value.integer.min = 0xa5;
800 	info->value.integer.max = 0xff;
801 	return 0;
802 }
803 
804 static int wm8776_input_vol_get(struct snd_kcontrol *ctl,
805 				struct snd_ctl_elem_value *value)
806 {
807 	struct oxygen *chip = ctl->private_data;
808 	struct xonar_wm87x6 *data = chip->model_data;
809 
810 	guard(mutex)(&chip->mutex);
811 	value->value.integer.value[0] =
812 		data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK;
813 	value->value.integer.value[1] =
814 		data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK;
815 	return 0;
816 }
817 
818 static int wm8776_input_vol_put(struct snd_kcontrol *ctl,
819 				struct snd_ctl_elem_value *value)
820 {
821 	struct oxygen *chip = ctl->private_data;
822 	struct xonar_wm87x6 *data = chip->model_data;
823 	int changed = 0;
824 
825 	guard(mutex)(&chip->mutex);
826 	changed = (value->value.integer.value[0] !=
827 		   (data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK)) ||
828 		  (value->value.integer.value[1] !=
829 		   (data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK));
830 	wm8776_write_cached(chip, WM8776_ADCLVOL,
831 			    value->value.integer.value[0] | WM8776_ZCA);
832 	wm8776_write_cached(chip, WM8776_ADCRVOL,
833 			    value->value.integer.value[1] | WM8776_ZCA);
834 	return changed;
835 }
836 
837 static int wm8776_level_control_info(struct snd_kcontrol *ctl,
838 				     struct snd_ctl_elem_info *info)
839 {
840 	static const char *const names[3] = {
841 		"None", "Peak Limiter", "Automatic Level Control"
842 	};
843 
844 	return snd_ctl_enum_info(info, 1, 3, names);
845 }
846 
847 static int wm8776_level_control_get(struct snd_kcontrol *ctl,
848 				    struct snd_ctl_elem_value *value)
849 {
850 	struct oxygen *chip = ctl->private_data;
851 	struct xonar_wm87x6 *data = chip->model_data;
852 
853 	if (!(data->wm8776_regs[WM8776_ALCCTRL2] & WM8776_LCEN))
854 		value->value.enumerated.item[0] = 0;
855 	else if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) ==
856 		 WM8776_LCSEL_LIMITER)
857 		value->value.enumerated.item[0] = 1;
858 	else
859 		value->value.enumerated.item[0] = 2;
860 	return 0;
861 }
862 
863 static void activate_control(struct oxygen *chip,
864 			     struct snd_kcontrol *ctl, unsigned int mode)
865 {
866 	unsigned int access;
867 
868 	if (ctl->private_value & mode)
869 		access = 0;
870 	else
871 		access = SNDRV_CTL_ELEM_ACCESS_INACTIVE;
872 	if ((ctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE) != access) {
873 		ctl->vd[0].access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
874 		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
875 	}
876 }
877 
878 static int wm8776_level_control_put(struct snd_kcontrol *ctl,
879 				    struct snd_ctl_elem_value *value)
880 {
881 	struct oxygen *chip = ctl->private_data;
882 	struct xonar_wm87x6 *data = chip->model_data;
883 	unsigned int mode = 0, i;
884 	u16 ctrl1, ctrl2;
885 	int changed;
886 
887 	if (value->value.enumerated.item[0] >= 3)
888 		return -EINVAL;
889 	guard(mutex)(&chip->mutex);
890 	changed = value->value.enumerated.item[0] != ctl->private_value;
891 	if (changed) {
892 		ctl->private_value = value->value.enumerated.item[0];
893 		ctrl1 = data->wm8776_regs[WM8776_ALCCTRL1];
894 		ctrl2 = data->wm8776_regs[WM8776_ALCCTRL2];
895 		switch (value->value.enumerated.item[0]) {
896 		default:
897 			wm8776_write_cached(chip, WM8776_ALCCTRL2,
898 					    ctrl2 & ~WM8776_LCEN);
899 			break;
900 		case 1:
901 			wm8776_write_cached(chip, WM8776_ALCCTRL1,
902 					    (ctrl1 & ~WM8776_LCSEL_MASK) |
903 					    WM8776_LCSEL_LIMITER);
904 			wm8776_write_cached(chip, WM8776_ALCCTRL2,
905 					    ctrl2 | WM8776_LCEN);
906 			mode = LC_CONTROL_LIMITER;
907 			break;
908 		case 2:
909 			wm8776_write_cached(chip, WM8776_ALCCTRL1,
910 					    (ctrl1 & ~WM8776_LCSEL_MASK) |
911 					    WM8776_LCSEL_ALC_STEREO);
912 			wm8776_write_cached(chip, WM8776_ALCCTRL2,
913 					    ctrl2 | WM8776_LCEN);
914 			mode = LC_CONTROL_ALC;
915 			break;
916 		}
917 		for (i = 0; i < ARRAY_SIZE(data->lc_controls); ++i)
918 			activate_control(chip, data->lc_controls[i], mode);
919 	}
920 	return changed;
921 }
922 
923 static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
924 {
925 	static const char *const names[2] = {
926 		"None", "High-pass Filter"
927 	};
928 
929 	return snd_ctl_enum_info(info, 1, 2, names);
930 }
931 
932 static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
933 {
934 	struct oxygen *chip = ctl->private_data;
935 	struct xonar_wm87x6 *data = chip->model_data;
936 
937 	value->value.enumerated.item[0] =
938 		!(data->wm8776_regs[WM8776_ADCIFCTRL] & WM8776_ADCHPD);
939 	return 0;
940 }
941 
942 static int hpf_put(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 	unsigned int reg;
947 	int changed;
948 
949 	guard(mutex)(&chip->mutex);
950 	reg = data->wm8776_regs[WM8776_ADCIFCTRL] & ~WM8776_ADCHPD;
951 	if (!value->value.enumerated.item[0])
952 		reg |= WM8776_ADCHPD;
953 	changed = reg != data->wm8776_regs[WM8776_ADCIFCTRL];
954 	if (changed)
955 		wm8776_write(chip, WM8776_ADCIFCTRL, reg);
956 	return changed;
957 }
958 
959 #define WM8776_BIT_SWITCH(xname, reg, bit, invert, flags) { \
960 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
961 	.name = xname, \
962 	.info = snd_ctl_boolean_mono_info, \
963 	.get = wm8776_bit_switch_get, \
964 	.put = wm8776_bit_switch_put, \
965 	.private_value = ((reg) << 16) | (bit) | ((invert) << 24) | (flags), \
966 }
967 #define _WM8776_FIELD_CTL(xname, reg, shift, initval, min, max, mask, flags) \
968 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
969 	.name = xname, \
970 	.private_value = (initval) | ((min) << 8) | ((max) << 12) | \
971 	((mask) << 16) | ((shift) << 20) | ((reg) << 24) | (flags)
972 #define WM8776_FIELD_CTL_ENUM(xname, reg, shift, init, min, max, mask, flags) {\
973 	_WM8776_FIELD_CTL(xname " Capture Enum", \
974 			  reg, shift, init, min, max, mask, flags), \
975 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
976 		  SNDRV_CTL_ELEM_ACCESS_INACTIVE, \
977 	.info = wm8776_field_enum_info, \
978 	.get = wm8776_field_enum_get, \
979 	.put = wm8776_field_enum_put, \
980 }
981 #define WM8776_FIELD_CTL_VOLUME(a, b, c, d, e, f, g, h, tlv_p) { \
982 	_WM8776_FIELD_CTL(a " Capture Volume", b, c, d, e, f, g, h), \
983 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
984 		  SNDRV_CTL_ELEM_ACCESS_INACTIVE | \
985 		  SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
986 	.info = wm8776_field_volume_info, \
987 	.get = wm8776_field_volume_get, \
988 	.put = wm8776_field_volume_put, \
989 	.tlv = { .p = tlv_p }, \
990 }
991 
992 static const DECLARE_TLV_DB_SCALE(wm87x6_dac_db_scale, -6000, 50, 0);
993 static const DECLARE_TLV_DB_SCALE(wm8776_adc_db_scale, -2100, 50, 0);
994 static const DECLARE_TLV_DB_SCALE(wm8776_hp_db_scale, -6000, 100, 0);
995 static const DECLARE_TLV_DB_SCALE(wm8776_lct_db_scale, -1600, 100, 0);
996 static const DECLARE_TLV_DB_SCALE(wm8776_maxgain_db_scale, 0, 400, 0);
997 static const DECLARE_TLV_DB_SCALE(wm8776_ngth_db_scale, -7800, 600, 0);
998 static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_lim_db_scale, -1200, 100, 0);
999 static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_alc_db_scale, -2100, 400, 0);
1000 
1001 static const struct snd_kcontrol_new ds_controls[] = {
1002 	{
1003 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1004 		.name = "Headphone Playback Volume",
1005 		.info = wm8776_hp_vol_info,
1006 		.get = wm8776_hp_vol_get,
1007 		.put = wm8776_hp_vol_put,
1008 		.tlv = { .p = wm8776_hp_db_scale },
1009 	},
1010 	WM8776_BIT_SWITCH("Headphone Playback Switch",
1011 			  WM8776_PWRDOWN, WM8776_HPPD, 1, 0),
1012 	{
1013 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1014 		.name = "Input Capture Volume",
1015 		.info = wm8776_input_vol_info,
1016 		.get = wm8776_input_vol_get,
1017 		.put = wm8776_input_vol_put,
1018 		.tlv = { .p = wm8776_adc_db_scale },
1019 	},
1020 	{
1021 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1022 		.name = "Line Capture Switch",
1023 		.info = snd_ctl_boolean_mono_info,
1024 		.get = wm8776_input_mux_get,
1025 		.put = wm8776_input_mux_put,
1026 		.private_value = 1 << 0,
1027 	},
1028 	{
1029 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1030 		.name = "Mic Capture Switch",
1031 		.info = snd_ctl_boolean_mono_info,
1032 		.get = wm8776_input_mux_get,
1033 		.put = wm8776_input_mux_put,
1034 		.private_value = 1 << 1,
1035 	},
1036 	WM8776_BIT_SWITCH("Front Mic Capture Switch",
1037 			  WM8776_ADCMUX, 1 << 2, 0, 0),
1038 	WM8776_BIT_SWITCH("Aux Capture Switch",
1039 			  WM8776_ADCMUX, 1 << 3, 0, 0),
1040 	{
1041 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1042 		.name = "ADC Filter Capture Enum",
1043 		.info = hpf_info,
1044 		.get = hpf_get,
1045 		.put = hpf_put,
1046 	},
1047 	{
1048 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1049 		.name = "Level Control Capture Enum",
1050 		.info = wm8776_level_control_info,
1051 		.get = wm8776_level_control_get,
1052 		.put = wm8776_level_control_put,
1053 		.private_value = 0,
1054 	},
1055 };
1056 static const struct snd_kcontrol_new hdav_slim_controls[] = {
1057 	{
1058 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1059 		.name = "HDMI Playback Switch",
1060 		.info = snd_ctl_boolean_mono_info,
1061 		.get = xonar_gpio_bit_switch_get,
1062 		.put = xonar_gpio_bit_switch_put,
1063 		.private_value = GPIO_SLIM_HDMI_DISABLE | XONAR_GPIO_BIT_INVERT,
1064 	},
1065 	{
1066 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1067 		.name = "Headphone Playback Volume",
1068 		.info = wm8776_hp_vol_info,
1069 		.get = wm8776_hp_vol_get,
1070 		.put = wm8776_hp_vol_put,
1071 		.tlv = { .p = wm8776_hp_db_scale },
1072 	},
1073 	WM8776_BIT_SWITCH("Headphone Playback Switch",
1074 			  WM8776_PWRDOWN, WM8776_HPPD, 1, 0),
1075 	{
1076 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1077 		.name = "Input Capture Volume",
1078 		.info = wm8776_input_vol_info,
1079 		.get = wm8776_input_vol_get,
1080 		.put = wm8776_input_vol_put,
1081 		.tlv = { .p = wm8776_adc_db_scale },
1082 	},
1083 	WM8776_BIT_SWITCH("Mic Capture Switch",
1084 			  WM8776_ADCMUX, 1 << 0, 0, 0),
1085 	WM8776_BIT_SWITCH("Aux Capture Switch",
1086 			  WM8776_ADCMUX, 1 << 1, 0, 0),
1087 	{
1088 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1089 		.name = "ADC Filter Capture Enum",
1090 		.info = hpf_info,
1091 		.get = hpf_get,
1092 		.put = hpf_put,
1093 	},
1094 	{
1095 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1096 		.name = "Level Control Capture Enum",
1097 		.info = wm8776_level_control_info,
1098 		.get = wm8776_level_control_get,
1099 		.put = wm8776_level_control_put,
1100 		.private_value = 0,
1101 	},
1102 };
1103 static const struct snd_kcontrol_new lc_controls[] = {
1104 	WM8776_FIELD_CTL_VOLUME("Limiter Threshold",
1105 				WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf,
1106 				LC_CONTROL_LIMITER, wm8776_lct_db_scale),
1107 	WM8776_FIELD_CTL_ENUM("Limiter Attack Time",
1108 			      WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf,
1109 			      LC_CONTROL_LIMITER),
1110 	WM8776_FIELD_CTL_ENUM("Limiter Decay Time",
1111 			      WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf,
1112 			      LC_CONTROL_LIMITER),
1113 	WM8776_FIELD_CTL_ENUM("Limiter Transient Window",
1114 			      WM8776_LIMITER, 4, 2, 0, 7, 0x7,
1115 			      LC_CONTROL_LIMITER),
1116 	WM8776_FIELD_CTL_VOLUME("Limiter Maximum Attenuation",
1117 				WM8776_LIMITER, 0, 6, 3, 12, 0xf,
1118 				LC_CONTROL_LIMITER,
1119 				wm8776_maxatten_lim_db_scale),
1120 	WM8776_FIELD_CTL_VOLUME("ALC Target Level",
1121 				WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf,
1122 				LC_CONTROL_ALC, wm8776_lct_db_scale),
1123 	WM8776_FIELD_CTL_ENUM("ALC Attack Time",
1124 			      WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf,
1125 			      LC_CONTROL_ALC),
1126 	WM8776_FIELD_CTL_ENUM("ALC Decay Time",
1127 			      WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf,
1128 			      LC_CONTROL_ALC),
1129 	WM8776_FIELD_CTL_VOLUME("ALC Maximum Gain",
1130 				WM8776_ALCCTRL1, 4, 7, 1, 7, 0x7,
1131 				LC_CONTROL_ALC, wm8776_maxgain_db_scale),
1132 	WM8776_FIELD_CTL_VOLUME("ALC Maximum Attenuation",
1133 				WM8776_LIMITER, 0, 10, 10, 15, 0xf,
1134 				LC_CONTROL_ALC, wm8776_maxatten_alc_db_scale),
1135 	WM8776_FIELD_CTL_ENUM("ALC Hold Time",
1136 			      WM8776_ALCCTRL2, 0, 0, 0, 15, 0xf,
1137 			      LC_CONTROL_ALC),
1138 	WM8776_BIT_SWITCH("Noise Gate Capture Switch",
1139 			  WM8776_NOISEGATE, WM8776_NGAT, 0,
1140 			  LC_CONTROL_ALC),
1141 	WM8776_FIELD_CTL_VOLUME("Noise Gate Threshold",
1142 				WM8776_NOISEGATE, 2, 0, 0, 7, 0x7,
1143 				LC_CONTROL_ALC, wm8776_ngth_db_scale),
1144 };
1145 
1146 static int add_lc_controls(struct oxygen *chip)
1147 {
1148 	struct xonar_wm87x6 *data = chip->model_data;
1149 	unsigned int i;
1150 	struct snd_kcontrol *ctl;
1151 	int err;
1152 
1153 	BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls));
1154 	for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) {
1155 		ctl = snd_ctl_new1(&lc_controls[i], chip);
1156 		if (!ctl)
1157 			return -ENOMEM;
1158 		err = snd_ctl_add(chip->card, ctl);
1159 		if (err < 0)
1160 			return err;
1161 		data->lc_controls[i] = ctl;
1162 	}
1163 	return 0;
1164 }
1165 
1166 static int xonar_ds_mixer_init(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 	for (i = 0; i < ARRAY_SIZE(ds_controls); ++i) {
1174 		ctl = snd_ctl_new1(&ds_controls[i], chip);
1175 		if (!ctl)
1176 			return -ENOMEM;
1177 		err = snd_ctl_add(chip->card, ctl);
1178 		if (err < 0)
1179 			return err;
1180 		if (!strcmp(ctl->id.name, "Line Capture Switch"))
1181 			data->line_adcmux_control = ctl;
1182 		else if (!strcmp(ctl->id.name, "Mic Capture Switch"))
1183 			data->mic_adcmux_control = ctl;
1184 	}
1185 	if (!data->line_adcmux_control || !data->mic_adcmux_control)
1186 		return -ENXIO;
1187 
1188 	return add_lc_controls(chip);
1189 }
1190 
1191 static int xonar_hdav_slim_mixer_init(struct oxygen *chip)
1192 {
1193 	unsigned int i;
1194 	struct snd_kcontrol *ctl;
1195 	int err;
1196 
1197 	for (i = 0; i < ARRAY_SIZE(hdav_slim_controls); ++i) {
1198 		ctl = snd_ctl_new1(&hdav_slim_controls[i], chip);
1199 		if (!ctl)
1200 			return -ENOMEM;
1201 		err = snd_ctl_add(chip->card, ctl);
1202 		if (err < 0)
1203 			return err;
1204 	}
1205 
1206 	return add_lc_controls(chip);
1207 }
1208 
1209 static void dump_wm8776_registers(struct oxygen *chip,
1210 				  struct snd_info_buffer *buffer)
1211 {
1212 	struct xonar_wm87x6 *data = chip->model_data;
1213 	unsigned int i;
1214 
1215 	snd_iprintf(buffer, "\nWM8776:\n00:");
1216 	for (i = 0; i < 0x10; ++i)
1217 		snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
1218 	snd_iprintf(buffer, "\n10:");
1219 	for (i = 0x10; i < 0x17; ++i)
1220 		snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
1221 	snd_iprintf(buffer, "\n");
1222 }
1223 
1224 static void dump_wm87x6_registers(struct oxygen *chip,
1225 				  struct snd_info_buffer *buffer)
1226 {
1227 	struct xonar_wm87x6 *data = chip->model_data;
1228 	unsigned int i;
1229 
1230 	dump_wm8776_registers(chip, buffer);
1231 	snd_iprintf(buffer, "\nWM8766:\n00:");
1232 	for (i = 0; i < 0x10; ++i)
1233 		snd_iprintf(buffer, " %03x", data->wm8766_regs[i]);
1234 	snd_iprintf(buffer, "\n");
1235 }
1236 
1237 static const struct oxygen_model model_xonar_ds = {
1238 	.longname = "Asus Virtuoso 66",
1239 	.chip = "AV200",
1240 	.init = xonar_ds_init,
1241 	.mixer_init = xonar_ds_mixer_init,
1242 	.cleanup = xonar_ds_cleanup,
1243 	.suspend = xonar_ds_suspend,
1244 	.resume = xonar_ds_resume,
1245 	.pcm_hardware_filter = wm8776_adc_hardware_filter,
1246 	.set_dac_params = set_wm87x6_dac_params,
1247 	.set_adc_params = set_wm8776_adc_params,
1248 	.update_dac_volume = update_wm87x6_volume,
1249 	.update_dac_mute = update_wm87x6_mute,
1250 	.update_center_lfe_mix = update_wm8766_center_lfe_mix,
1251 	.gpio_changed = xonar_ds_gpio_changed,
1252 	.dump_registers = dump_wm87x6_registers,
1253 	.dac_tlv = wm87x6_dac_db_scale,
1254 	.model_data_size = sizeof(struct xonar_wm87x6),
1255 	.device_config = PLAYBACK_0_TO_I2S |
1256 			 PLAYBACK_1_TO_SPDIF |
1257 			 CAPTURE_0_FROM_I2S_1 |
1258 			 CAPTURE_1_FROM_SPDIF,
1259 	.dac_channels_pcm = 8,
1260 	.dac_channels_mixer = 8,
1261 	.dac_volume_min = 255 - 2*60,
1262 	.dac_volume_max = 255,
1263 	.function_flags = OXYGEN_FUNCTION_SPI,
1264 	.dac_mclks = OXYGEN_MCLKS(256, 256, 128),
1265 	.adc_mclks = OXYGEN_MCLKS(256, 256, 128),
1266 	.dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1267 	.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1268 };
1269 
1270 static const struct oxygen_model model_xonar_hdav_slim = {
1271 	.shortname = "Xonar HDAV1.3 Slim",
1272 	.longname = "Asus Virtuoso 200",
1273 	.chip = "AV200",
1274 	.init = xonar_hdav_slim_init,
1275 	.mixer_init = xonar_hdav_slim_mixer_init,
1276 	.cleanup = xonar_hdav_slim_cleanup,
1277 	.suspend = xonar_hdav_slim_suspend,
1278 	.resume = xonar_hdav_slim_resume,
1279 	.pcm_hardware_filter = xonar_hdav_slim_hardware_filter,
1280 	.set_dac_params = set_hdav_slim_dac_params,
1281 	.set_adc_params = set_wm8776_adc_params,
1282 	.update_dac_volume = update_wm8776_volume,
1283 	.update_dac_mute = update_wm8776_mute,
1284 	.uart_input = xonar_hdmi_uart_input,
1285 	.dump_registers = dump_wm8776_registers,
1286 	.dac_tlv = wm87x6_dac_db_scale,
1287 	.model_data_size = sizeof(struct xonar_wm87x6),
1288 	.device_config = PLAYBACK_0_TO_I2S |
1289 			 PLAYBACK_1_TO_SPDIF |
1290 			 CAPTURE_0_FROM_I2S_1 |
1291 			 CAPTURE_1_FROM_SPDIF,
1292 	.dac_channels_pcm = 8,
1293 	.dac_channels_mixer = 2,
1294 	.dac_volume_min = 255 - 2*60,
1295 	.dac_volume_max = 255,
1296 	.function_flags = OXYGEN_FUNCTION_2WIRE,
1297 	.dac_mclks = OXYGEN_MCLKS(256, 256, 128),
1298 	.adc_mclks = OXYGEN_MCLKS(256, 256, 128),
1299 	.dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1300 	.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1301 };
1302 
1303 int get_xonar_wm87x6_model(struct oxygen *chip,
1304 			   const struct pci_device_id *id)
1305 {
1306 	switch (id->subdevice) {
1307 	case 0x838e:
1308 		chip->model = model_xonar_ds;
1309 		chip->model.shortname = "Xonar DS";
1310 		break;
1311 	case 0x8522:
1312 		chip->model = model_xonar_ds;
1313 		chip->model.shortname = "Xonar DSX";
1314 		break;
1315 	case 0x835e:
1316 		chip->model = model_xonar_hdav_slim;
1317 		break;
1318 	default:
1319 		return -EINVAL;
1320 	}
1321 	return 0;
1322 }
1323