Linux Audio

Check our new training course

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