2 * card driver for models with WM8776/WM8766 DACs (Xonar DS)
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
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.
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.
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/>.
25 * SPI 0 -> WM8766 (surround, center/LFE, back)
26 * SPI 1 -> WM8776 (front, input)
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
37 * input 3 <- front mic
41 #include <linux/pci.h>
42 #include <linux/delay.h>
43 #include <sound/control.h>
44 #include <sound/core.h>
45 #include <sound/info.h>
46 #include <sound/jack.h>
47 #include <sound/pcm.h>
48 #include <sound/pcm_params.h>
49 #include <sound/tlv.h>
54 #define GPIO_DS_HP_DETECT 0x0010
55 #define GPIO_DS_INPUT_ROUTE 0x0040
56 #define GPIO_DS_OUTPUT_FRONTLR 0x0080
57 #define GPIO_DS_OUTPUT_ENABLE 0x0100
59 #define LC_CONTROL_LIMITER 0x40000000
60 #define LC_CONTROL_ALC 0x20000000
63 struct xonar_generic generic;
64 u16 wm8776_regs[0x17];
65 u16 wm8766_regs[0x10];
66 struct snd_kcontrol *line_adcmux_control;
67 struct snd_kcontrol *mic_adcmux_control;
68 struct snd_kcontrol *lc_controls[13];
69 struct snd_jack *hp_jack;
72 static void wm8776_write(struct oxygen *chip,
73 unsigned int reg, unsigned int value)
75 struct xonar_wm87x6 *data = chip->model_data;
77 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
78 OXYGEN_SPI_DATA_LENGTH_2 |
79 OXYGEN_SPI_CLOCK_160 |
80 (1 << OXYGEN_SPI_CODEC_SHIFT) |
81 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
83 if (reg < ARRAY_SIZE(data->wm8776_regs)) {
84 if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER)
85 value &= ~WM8776_UPDATE;
86 data->wm8776_regs[reg] = value;
90 static void wm8776_write_cached(struct oxygen *chip,
91 unsigned int reg, unsigned int value)
93 struct xonar_wm87x6 *data = chip->model_data;
95 if (reg >= ARRAY_SIZE(data->wm8776_regs) ||
96 value != data->wm8776_regs[reg])
97 wm8776_write(chip, reg, value);
100 static void wm8766_write(struct oxygen *chip,
101 unsigned int reg, unsigned int value)
103 struct xonar_wm87x6 *data = chip->model_data;
105 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
106 OXYGEN_SPI_DATA_LENGTH_2 |
107 OXYGEN_SPI_CLOCK_160 |
108 (0 << OXYGEN_SPI_CODEC_SHIFT) |
109 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
111 if (reg < ARRAY_SIZE(data->wm8766_regs)) {
112 if ((reg >= WM8766_LDA1 && reg <= WM8766_RDA1) ||
113 (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA))
114 value &= ~WM8766_UPDATE;
115 data->wm8766_regs[reg] = value;
119 static void wm8766_write_cached(struct oxygen *chip,
120 unsigned int reg, unsigned int value)
122 struct xonar_wm87x6 *data = chip->model_data;
124 if (reg >= ARRAY_SIZE(data->wm8766_regs) ||
125 value != data->wm8766_regs[reg])
126 wm8766_write(chip, reg, value);
129 static void wm8776_registers_init(struct oxygen *chip)
131 struct xonar_wm87x6 *data = chip->model_data;
133 wm8776_write(chip, WM8776_RESET, 0);
134 wm8776_write(chip, WM8776_DACCTRL1, WM8776_DZCEN |
135 WM8776_PL_LEFT_LEFT | WM8776_PL_RIGHT_RIGHT);
136 wm8776_write(chip, WM8776_DACMUTE, chip->dac_mute ? WM8776_DMUTE : 0);
137 wm8776_write(chip, WM8776_DACIFCTRL,
138 WM8776_DACFMT_LJUST | WM8776_DACWL_24);
139 wm8776_write(chip, WM8776_ADCIFCTRL,
140 data->wm8776_regs[WM8776_ADCIFCTRL]);
141 wm8776_write(chip, WM8776_MSTRCTRL, data->wm8776_regs[WM8776_MSTRCTRL]);
142 wm8776_write(chip, WM8776_PWRDOWN, data->wm8776_regs[WM8776_PWRDOWN]);
143 wm8776_write(chip, WM8776_HPLVOL, data->wm8776_regs[WM8776_HPLVOL]);
144 wm8776_write(chip, WM8776_HPRVOL, data->wm8776_regs[WM8776_HPRVOL] |
146 wm8776_write(chip, WM8776_ADCLVOL, data->wm8776_regs[WM8776_ADCLVOL]);
147 wm8776_write(chip, WM8776_ADCRVOL, data->wm8776_regs[WM8776_ADCRVOL]);
148 wm8776_write(chip, WM8776_ADCMUX, data->wm8776_regs[WM8776_ADCMUX]);
149 wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0]);
150 wm8776_write(chip, WM8776_DACRVOL, chip->dac_volume[1] | WM8776_UPDATE);
153 static void wm8766_registers_init(struct oxygen *chip)
155 struct xonar_wm87x6 *data = chip->model_data;
157 wm8766_write(chip, WM8766_RESET, 0);
158 wm8766_write(chip, WM8766_DAC_CTRL, data->wm8766_regs[WM8766_DAC_CTRL]);
159 wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24);
160 wm8766_write(chip, WM8766_DAC_CTRL2,
161 WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
162 wm8766_write(chip, WM8766_LDA1, chip->dac_volume[2]);
163 wm8766_write(chip, WM8766_RDA1, chip->dac_volume[3]);
164 wm8766_write(chip, WM8766_LDA2, chip->dac_volume[4]);
165 wm8766_write(chip, WM8766_RDA2, chip->dac_volume[5]);
166 wm8766_write(chip, WM8766_LDA3, chip->dac_volume[6]);
167 wm8766_write(chip, WM8766_RDA3, chip->dac_volume[7] | WM8766_UPDATE);
170 static void wm8776_init(struct oxygen *chip)
172 struct xonar_wm87x6 *data = chip->model_data;
174 data->wm8776_regs[WM8776_HPLVOL] = (0x79 - 60) | WM8776_HPZCEN;
175 data->wm8776_regs[WM8776_HPRVOL] = (0x79 - 60) | WM8776_HPZCEN;
176 data->wm8776_regs[WM8776_ADCIFCTRL] =
177 WM8776_ADCFMT_LJUST | WM8776_ADCWL_24 | WM8776_ADCMCLK;
178 data->wm8776_regs[WM8776_MSTRCTRL] =
179 WM8776_ADCRATE_256 | WM8776_DACRATE_256;
180 data->wm8776_regs[WM8776_PWRDOWN] = WM8776_HPPD;
181 data->wm8776_regs[WM8776_ADCLVOL] = 0xa5 | WM8776_ZCA;
182 data->wm8776_regs[WM8776_ADCRVOL] = 0xa5 | WM8776_ZCA;
183 data->wm8776_regs[WM8776_ADCMUX] = 0x001;
184 wm8776_registers_init(chip);
187 static void wm8766_init(struct oxygen *chip)
189 struct xonar_wm87x6 *data = chip->model_data;
191 data->wm8766_regs[WM8766_DAC_CTRL] =
192 WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT;
193 wm8766_registers_init(chip);
196 static void xonar_ds_handle_hp_jack(struct oxygen *chip)
198 struct xonar_wm87x6 *data = chip->model_data;
202 mutex_lock(&chip->mutex);
204 hp_plugged = !(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
207 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
208 hp_plugged ? 0 : GPIO_DS_OUTPUT_FRONTLR,
209 GPIO_DS_OUTPUT_FRONTLR);
211 reg = data->wm8766_regs[WM8766_DAC_CTRL] & ~WM8766_MUTEALL;
213 reg |= WM8766_MUTEALL;
214 wm8766_write_cached(chip, WM8766_DAC_CTRL, reg);
216 snd_jack_report(data->hp_jack, hp_plugged ? SND_JACK_HEADPHONE : 0);
218 mutex_unlock(&chip->mutex);
221 static void xonar_ds_init(struct oxygen *chip)
223 struct xonar_wm87x6 *data = chip->model_data;
225 data->generic.anti_pop_delay = 300;
226 data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE;
231 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
232 GPIO_DS_INPUT_ROUTE | GPIO_DS_OUTPUT_FRONTLR);
233 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
235 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE);
236 oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT);
237 chip->interrupt_mask |= OXYGEN_INT_GPIO;
239 xonar_enable_output(chip);
241 snd_jack_new(chip->card, "Headphone",
242 SND_JACK_HEADPHONE, &data->hp_jack);
243 xonar_ds_handle_hp_jack(chip);
245 snd_component_add(chip->card, "WM8776");
246 snd_component_add(chip->card, "WM8766");
249 static void xonar_ds_cleanup(struct oxygen *chip)
251 xonar_disable_output(chip);
252 wm8776_write(chip, WM8776_RESET, 0);
255 static void xonar_ds_suspend(struct oxygen *chip)
257 xonar_ds_cleanup(chip);
260 static void xonar_ds_resume(struct oxygen *chip)
262 wm8776_registers_init(chip);
263 wm8766_registers_init(chip);
264 xonar_enable_output(chip);
265 xonar_ds_handle_hp_jack(chip);
268 static void wm8776_adc_hardware_filter(unsigned int channel,
269 struct snd_pcm_hardware *hardware)
271 if (channel == PCM_A) {
272 hardware->rates = SNDRV_PCM_RATE_32000 |
273 SNDRV_PCM_RATE_44100 |
274 SNDRV_PCM_RATE_48000 |
275 SNDRV_PCM_RATE_64000 |
276 SNDRV_PCM_RATE_88200 |
277 SNDRV_PCM_RATE_96000;
278 hardware->rate_max = 96000;
282 static void set_wm87x6_dac_params(struct oxygen *chip,
283 struct snd_pcm_hw_params *params)
287 static void set_wm8776_adc_params(struct oxygen *chip,
288 struct snd_pcm_hw_params *params)
292 reg = WM8776_ADCRATE_256 | WM8776_DACRATE_256;
293 if (params_rate(params) > 48000)
294 reg |= WM8776_ADCOSR;
295 wm8776_write_cached(chip, WM8776_MSTRCTRL, reg);
298 static void update_wm8776_volume(struct oxygen *chip)
300 struct xonar_wm87x6 *data = chip->model_data;
303 if (chip->dac_volume[0] == chip->dac_volume[1]) {
304 if (chip->dac_volume[0] != data->wm8776_regs[WM8776_DACLVOL] ||
305 chip->dac_volume[1] != data->wm8776_regs[WM8776_DACRVOL]) {
306 wm8776_write(chip, WM8776_DACMASTER,
307 chip->dac_volume[0] | WM8776_UPDATE);
308 data->wm8776_regs[WM8776_DACLVOL] = chip->dac_volume[0];
309 data->wm8776_regs[WM8776_DACRVOL] = chip->dac_volume[0];
312 to_change = (chip->dac_volume[0] !=
313 data->wm8776_regs[WM8776_DACLVOL]) << 0;
314 to_change |= (chip->dac_volume[1] !=
315 data->wm8776_regs[WM8776_DACLVOL]) << 1;
317 wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0] |
318 ((to_change & 2) ? 0 : WM8776_UPDATE));
320 wm8776_write(chip, WM8776_DACRVOL,
321 chip->dac_volume[1] | WM8776_UPDATE);
325 static void update_wm87x6_volume(struct oxygen *chip)
327 static const u8 wm8766_regs[6] = {
328 WM8766_LDA1, WM8766_RDA1,
329 WM8766_LDA2, WM8766_RDA2,
330 WM8766_LDA3, WM8766_RDA3,
332 struct xonar_wm87x6 *data = chip->model_data;
336 update_wm8776_volume(chip);
337 if (chip->dac_volume[2] == chip->dac_volume[3] &&
338 chip->dac_volume[2] == chip->dac_volume[4] &&
339 chip->dac_volume[2] == chip->dac_volume[5] &&
340 chip->dac_volume[2] == chip->dac_volume[6] &&
341 chip->dac_volume[2] == chip->dac_volume[7]) {
343 for (i = 0; i < 6; ++i)
344 if (chip->dac_volume[2] !=
345 data->wm8766_regs[wm8766_regs[i]])
348 wm8766_write(chip, WM8766_MASTDA,
349 chip->dac_volume[2] | WM8766_UPDATE);
350 for (i = 0; i < 6; ++i)
351 data->wm8766_regs[wm8766_regs[i]] =
356 for (i = 0; i < 6; ++i)
357 to_change |= (chip->dac_volume[2 + i] !=
358 data->wm8766_regs[wm8766_regs[i]]) << i;
359 for (i = 0; i < 6; ++i)
360 if (to_change & (1 << i))
361 wm8766_write(chip, wm8766_regs[i],
362 chip->dac_volume[2 + i] |
363 ((to_change & (0x3e << i))
364 ? 0 : WM8766_UPDATE));
368 static void update_wm8776_mute(struct oxygen *chip)
370 wm8776_write_cached(chip, WM8776_DACMUTE,
371 chip->dac_mute ? WM8776_DMUTE : 0);
374 static void update_wm87x6_mute(struct oxygen *chip)
376 update_wm8776_mute(chip);
377 wm8766_write_cached(chip, WM8766_DAC_CTRL2, WM8766_ZCD |
378 (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
381 static void update_wm8766_center_lfe_mix(struct oxygen *chip, bool mixed)
383 struct xonar_wm87x6 *data = chip->model_data;
387 * The WM8766 can mix left and right channels, but this setting
388 * applies to all three stereo pairs.
390 reg = data->wm8766_regs[WM8766_DAC_CTRL] &
391 ~(WM8766_PL_LEFT_MASK | WM8766_PL_RIGHT_MASK);
393 reg |= WM8766_PL_LEFT_LRMIX | WM8766_PL_RIGHT_LRMIX;
395 reg |= WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT;
396 wm8766_write_cached(chip, WM8766_DAC_CTRL, reg);
399 static void xonar_ds_gpio_changed(struct oxygen *chip)
401 xonar_ds_handle_hp_jack(chip);
404 static int wm8776_bit_switch_get(struct snd_kcontrol *ctl,
405 struct snd_ctl_elem_value *value)
407 struct oxygen *chip = ctl->private_data;
408 struct xonar_wm87x6 *data = chip->model_data;
409 u16 bit = ctl->private_value & 0xffff;
410 unsigned int reg_index = (ctl->private_value >> 16) & 0xff;
411 bool invert = (ctl->private_value >> 24) & 1;
413 value->value.integer.value[0] =
414 ((data->wm8776_regs[reg_index] & bit) != 0) ^ invert;
418 static int wm8776_bit_switch_put(struct snd_kcontrol *ctl,
419 struct snd_ctl_elem_value *value)
421 struct oxygen *chip = ctl->private_data;
422 struct xonar_wm87x6 *data = chip->model_data;
423 u16 bit = ctl->private_value & 0xffff;
425 unsigned int reg_index = (ctl->private_value >> 16) & 0xff;
426 bool invert = (ctl->private_value >> 24) & 1;
429 mutex_lock(&chip->mutex);
430 reg_value = data->wm8776_regs[reg_index] & ~bit;
431 if (value->value.integer.value[0] ^ invert)
433 changed = reg_value != data->wm8776_regs[reg_index];
435 wm8776_write(chip, reg_index, reg_value);
436 mutex_unlock(&chip->mutex);
440 static int wm8776_field_enum_info(struct snd_kcontrol *ctl,
441 struct snd_ctl_elem_info *info)
443 static const char *const hld[16] = {
444 "0 ms", "2.67 ms", "5.33 ms", "10.6 ms",
445 "21.3 ms", "42.7 ms", "85.3 ms", "171 ms",
446 "341 ms", "683 ms", "1.37 s", "2.73 s",
447 "5.46 s", "10.9 s", "21.8 s", "43.7 s",
449 static const char *const atk_lim[11] = {
450 "0.25 ms", "0.5 ms", "1 ms", "2 ms",
451 "4 ms", "8 ms", "16 ms", "32 ms",
452 "64 ms", "128 ms", "256 ms",
454 static const char *const atk_alc[11] = {
455 "8.40 ms", "16.8 ms", "33.6 ms", "67.2 ms",
456 "134 ms", "269 ms", "538 ms", "1.08 s",
457 "2.15 s", "4.3 s", "8.6 s",
459 static const char *const dcy_lim[11] = {
460 "1.2 ms", "2.4 ms", "4.8 ms", "9.6 ms",
461 "19.2 ms", "38.4 ms", "76.8 ms", "154 ms",
462 "307 ms", "614 ms", "1.23 s",
464 static const char *const dcy_alc[11] = {
465 "33.5 ms", "67.0 ms", "134 ms", "268 ms",
466 "536 ms", "1.07 s", "2.14 s", "4.29 s",
467 "8.58 s", "17.2 s", "34.3 s",
469 static const char *const tranwin[8] = {
470 "0 us", "62.5 us", "125 us", "250 us",
471 "500 us", "1 ms", "2 ms", "4 ms",
474 const char *const *names;
476 max = (ctl->private_value >> 12) & 0xf;
477 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
479 info->value.enumerated.items = max + 1;
480 if (info->value.enumerated.item > max)
481 info->value.enumerated.item = max;
482 switch ((ctl->private_value >> 24) & 0x1f) {
483 case WM8776_ALCCTRL2:
486 case WM8776_ALCCTRL3:
487 if (((ctl->private_value >> 20) & 0xf) == 0) {
488 if (ctl->private_value & LC_CONTROL_LIMITER)
493 if (ctl->private_value & LC_CONTROL_LIMITER)
505 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
509 static int wm8776_field_volume_info(struct snd_kcontrol *ctl,
510 struct snd_ctl_elem_info *info)
512 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
514 info->value.integer.min = (ctl->private_value >> 8) & 0xf;
515 info->value.integer.max = (ctl->private_value >> 12) & 0xf;
519 static void wm8776_field_set_from_ctl(struct snd_kcontrol *ctl)
521 struct oxygen *chip = ctl->private_data;
522 struct xonar_wm87x6 *data = chip->model_data;
523 unsigned int value, reg_index, mode;
528 if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) ==
529 WM8776_LCSEL_LIMITER)
530 mode = LC_CONTROL_LIMITER;
532 mode = LC_CONTROL_ALC;
533 if (!(ctl->private_value & mode))
536 value = ctl->private_value & 0xf;
537 min = (ctl->private_value >> 8) & 0xf;
538 max = (ctl->private_value >> 12) & 0xf;
539 mask = (ctl->private_value >> 16) & 0xf;
540 shift = (ctl->private_value >> 20) & 0xf;
541 reg_index = (ctl->private_value >> 24) & 0x1f;
542 invert = (ctl->private_value >> 29) & 0x1;
545 value = max - (value - min);
546 reg_value = data->wm8776_regs[reg_index];
547 reg_value &= ~(mask << shift);
548 reg_value |= value << shift;
549 wm8776_write_cached(chip, reg_index, reg_value);
552 static int wm8776_field_set(struct snd_kcontrol *ctl, unsigned int value)
554 struct oxygen *chip = ctl->private_data;
558 min = (ctl->private_value >> 8) & 0xf;
559 max = (ctl->private_value >> 12) & 0xf;
560 if (value < min || value > max)
562 mutex_lock(&chip->mutex);
563 changed = value != (ctl->private_value & 0xf);
565 ctl->private_value = (ctl->private_value & ~0xf) | value;
566 wm8776_field_set_from_ctl(ctl);
568 mutex_unlock(&chip->mutex);
572 static int wm8776_field_enum_get(struct snd_kcontrol *ctl,
573 struct snd_ctl_elem_value *value)
575 value->value.enumerated.item[0] = ctl->private_value & 0xf;
579 static int wm8776_field_volume_get(struct snd_kcontrol *ctl,
580 struct snd_ctl_elem_value *value)
582 value->value.integer.value[0] = ctl->private_value & 0xf;
586 static int wm8776_field_enum_put(struct snd_kcontrol *ctl,
587 struct snd_ctl_elem_value *value)
589 return wm8776_field_set(ctl, value->value.enumerated.item[0]);
592 static int wm8776_field_volume_put(struct snd_kcontrol *ctl,
593 struct snd_ctl_elem_value *value)
595 return wm8776_field_set(ctl, value->value.integer.value[0]);
598 static int wm8776_hp_vol_info(struct snd_kcontrol *ctl,
599 struct snd_ctl_elem_info *info)
601 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
603 info->value.integer.min = 0x79 - 60;
604 info->value.integer.max = 0x7f;
608 static int wm8776_hp_vol_get(struct snd_kcontrol *ctl,
609 struct snd_ctl_elem_value *value)
611 struct oxygen *chip = ctl->private_data;
612 struct xonar_wm87x6 *data = chip->model_data;
614 mutex_lock(&chip->mutex);
615 value->value.integer.value[0] =
616 data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK;
617 value->value.integer.value[1] =
618 data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK;
619 mutex_unlock(&chip->mutex);
623 static int wm8776_hp_vol_put(struct snd_kcontrol *ctl,
624 struct snd_ctl_elem_value *value)
626 struct oxygen *chip = ctl->private_data;
627 struct xonar_wm87x6 *data = chip->model_data;
630 mutex_lock(&chip->mutex);
631 to_update = (value->value.integer.value[0] !=
632 (data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK))
634 to_update |= (value->value.integer.value[1] !=
635 (data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK))
637 if (value->value.integer.value[0] == value->value.integer.value[1]) {
639 wm8776_write(chip, WM8776_HPMASTER,
640 value->value.integer.value[0] |
641 WM8776_HPZCEN | WM8776_UPDATE);
642 data->wm8776_regs[WM8776_HPLVOL] =
643 value->value.integer.value[0] | WM8776_HPZCEN;
644 data->wm8776_regs[WM8776_HPRVOL] =
645 value->value.integer.value[0] | WM8776_HPZCEN;
649 wm8776_write(chip, WM8776_HPLVOL,
650 value->value.integer.value[0] |
652 ((to_update & 2) ? 0 : WM8776_UPDATE));
654 wm8776_write(chip, WM8776_HPRVOL,
655 value->value.integer.value[1] |
656 WM8776_HPZCEN | WM8776_UPDATE);
658 mutex_unlock(&chip->mutex);
659 return to_update != 0;
662 static int wm8776_input_mux_get(struct snd_kcontrol *ctl,
663 struct snd_ctl_elem_value *value)
665 struct oxygen *chip = ctl->private_data;
666 struct xonar_wm87x6 *data = chip->model_data;
667 unsigned int mux_bit = ctl->private_value;
669 value->value.integer.value[0] =
670 !!(data->wm8776_regs[WM8776_ADCMUX] & mux_bit);
674 static int wm8776_input_mux_put(struct snd_kcontrol *ctl,
675 struct snd_ctl_elem_value *value)
677 struct oxygen *chip = ctl->private_data;
678 struct xonar_wm87x6 *data = chip->model_data;
679 struct snd_kcontrol *other_ctl;
680 unsigned int mux_bit = ctl->private_value;
684 mutex_lock(&chip->mutex);
685 reg = data->wm8776_regs[WM8776_ADCMUX];
686 if (value->value.integer.value[0]) {
688 /* line-in and mic-in are exclusive */
693 other_ctl = data->line_adcmux_control;
695 other_ctl = data->mic_adcmux_control;
696 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
701 changed = reg != data->wm8776_regs[WM8776_ADCMUX];
703 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
704 reg & 1 ? GPIO_DS_INPUT_ROUTE : 0,
705 GPIO_DS_INPUT_ROUTE);
706 wm8776_write(chip, WM8776_ADCMUX, reg);
708 mutex_unlock(&chip->mutex);
712 static int wm8776_input_vol_info(struct snd_kcontrol *ctl,
713 struct snd_ctl_elem_info *info)
715 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
717 info->value.integer.min = 0xa5;
718 info->value.integer.max = 0xff;
722 static int wm8776_input_vol_get(struct snd_kcontrol *ctl,
723 struct snd_ctl_elem_value *value)
725 struct oxygen *chip = ctl->private_data;
726 struct xonar_wm87x6 *data = chip->model_data;
728 mutex_lock(&chip->mutex);
729 value->value.integer.value[0] =
730 data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK;
731 value->value.integer.value[1] =
732 data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK;
733 mutex_unlock(&chip->mutex);
737 static int wm8776_input_vol_put(struct snd_kcontrol *ctl,
738 struct snd_ctl_elem_value *value)
740 struct oxygen *chip = ctl->private_data;
741 struct xonar_wm87x6 *data = chip->model_data;
744 mutex_lock(&chip->mutex);
745 changed = (value->value.integer.value[0] !=
746 (data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK)) ||
747 (value->value.integer.value[1] !=
748 (data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK));
749 wm8776_write_cached(chip, WM8776_ADCLVOL,
750 value->value.integer.value[0] | WM8776_ZCA);
751 wm8776_write_cached(chip, WM8776_ADCRVOL,
752 value->value.integer.value[1] | WM8776_ZCA);
753 mutex_unlock(&chip->mutex);
757 static int wm8776_level_control_info(struct snd_kcontrol *ctl,
758 struct snd_ctl_elem_info *info)
760 static const char *const names[3] = {
761 "None", "Peak Limiter", "Automatic Level Control"
763 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
765 info->value.enumerated.items = 3;
766 if (info->value.enumerated.item >= 3)
767 info->value.enumerated.item = 2;
768 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
772 static int wm8776_level_control_get(struct snd_kcontrol *ctl,
773 struct snd_ctl_elem_value *value)
775 struct oxygen *chip = ctl->private_data;
776 struct xonar_wm87x6 *data = chip->model_data;
778 if (!(data->wm8776_regs[WM8776_ALCCTRL2] & WM8776_LCEN))
779 value->value.enumerated.item[0] = 0;
780 else if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) ==
781 WM8776_LCSEL_LIMITER)
782 value->value.enumerated.item[0] = 1;
784 value->value.enumerated.item[0] = 2;
788 static void activate_control(struct oxygen *chip,
789 struct snd_kcontrol *ctl, unsigned int mode)
793 if (ctl->private_value & mode)
796 access = SNDRV_CTL_ELEM_ACCESS_INACTIVE;
797 if ((ctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE) != access) {
798 ctl->vd[0].access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
799 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
803 static int wm8776_level_control_put(struct snd_kcontrol *ctl,
804 struct snd_ctl_elem_value *value)
806 struct oxygen *chip = ctl->private_data;
807 struct xonar_wm87x6 *data = chip->model_data;
808 unsigned int mode = 0, i;
812 if (value->value.enumerated.item[0] >= 3)
814 mutex_lock(&chip->mutex);
815 changed = value->value.enumerated.item[0] != ctl->private_value;
817 ctl->private_value = value->value.enumerated.item[0];
818 ctrl1 = data->wm8776_regs[WM8776_ALCCTRL1];
819 ctrl2 = data->wm8776_regs[WM8776_ALCCTRL2];
820 switch (value->value.enumerated.item[0]) {
822 wm8776_write_cached(chip, WM8776_ALCCTRL2,
823 ctrl2 & ~WM8776_LCEN);
826 wm8776_write_cached(chip, WM8776_ALCCTRL1,
827 (ctrl1 & ~WM8776_LCSEL_MASK) |
828 WM8776_LCSEL_LIMITER);
829 wm8776_write_cached(chip, WM8776_ALCCTRL2,
830 ctrl2 | WM8776_LCEN);
831 mode = LC_CONTROL_LIMITER;
834 wm8776_write_cached(chip, WM8776_ALCCTRL1,
835 (ctrl1 & ~WM8776_LCSEL_MASK) |
836 WM8776_LCSEL_ALC_STEREO);
837 wm8776_write_cached(chip, WM8776_ALCCTRL2,
838 ctrl2 | WM8776_LCEN);
839 mode = LC_CONTROL_ALC;
842 for (i = 0; i < ARRAY_SIZE(data->lc_controls); ++i)
843 activate_control(chip, data->lc_controls[i], mode);
845 mutex_unlock(&chip->mutex);
849 static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
851 static const char *const names[2] = {
852 "None", "High-pass Filter"
855 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
857 info->value.enumerated.items = 2;
858 if (info->value.enumerated.item >= 2)
859 info->value.enumerated.item = 1;
860 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
864 static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
866 struct oxygen *chip = ctl->private_data;
867 struct xonar_wm87x6 *data = chip->model_data;
869 value->value.enumerated.item[0] =
870 !(data->wm8776_regs[WM8776_ADCIFCTRL] & WM8776_ADCHPD);
874 static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
876 struct oxygen *chip = ctl->private_data;
877 struct xonar_wm87x6 *data = chip->model_data;
881 mutex_lock(&chip->mutex);
882 reg = data->wm8776_regs[WM8776_ADCIFCTRL] & ~WM8776_ADCHPD;
883 if (!value->value.enumerated.item[0])
884 reg |= WM8776_ADCHPD;
885 changed = reg != data->wm8776_regs[WM8776_ADCIFCTRL];
887 wm8776_write(chip, WM8776_ADCIFCTRL, reg);
888 mutex_unlock(&chip->mutex);
892 #define WM8776_BIT_SWITCH(xname, reg, bit, invert, flags) { \
893 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
895 .info = snd_ctl_boolean_mono_info, \
896 .get = wm8776_bit_switch_get, \
897 .put = wm8776_bit_switch_put, \
898 .private_value = ((reg) << 16) | (bit) | ((invert) << 24) | (flags), \
900 #define _WM8776_FIELD_CTL(xname, reg, shift, initval, min, max, mask, flags) \
901 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
903 .private_value = (initval) | ((min) << 8) | ((max) << 12) | \
904 ((mask) << 16) | ((shift) << 20) | ((reg) << 24) | (flags)
905 #define WM8776_FIELD_CTL_ENUM(xname, reg, shift, init, min, max, mask, flags) {\
906 _WM8776_FIELD_CTL(xname " Capture Enum", \
907 reg, shift, init, min, max, mask, flags), \
908 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
909 SNDRV_CTL_ELEM_ACCESS_INACTIVE, \
910 .info = wm8776_field_enum_info, \
911 .get = wm8776_field_enum_get, \
912 .put = wm8776_field_enum_put, \
914 #define WM8776_FIELD_CTL_VOLUME(a, b, c, d, e, f, g, h, tlv_p) { \
915 _WM8776_FIELD_CTL(a " Capture Volume", b, c, d, e, f, g, h), \
916 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
917 SNDRV_CTL_ELEM_ACCESS_INACTIVE | \
918 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
919 .info = wm8776_field_volume_info, \
920 .get = wm8776_field_volume_get, \
921 .put = wm8776_field_volume_put, \
922 .tlv = { .p = tlv_p }, \
925 static const DECLARE_TLV_DB_SCALE(wm87x6_dac_db_scale, -6000, 50, 0);
926 static const DECLARE_TLV_DB_SCALE(wm8776_adc_db_scale, -2100, 50, 0);
927 static const DECLARE_TLV_DB_SCALE(wm8776_hp_db_scale, -6000, 100, 0);
928 static const DECLARE_TLV_DB_SCALE(wm8776_lct_db_scale, -1600, 100, 0);
929 static const DECLARE_TLV_DB_SCALE(wm8776_maxgain_db_scale, 0, 400, 0);
930 static const DECLARE_TLV_DB_SCALE(wm8776_ngth_db_scale, -7800, 600, 0);
931 static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_lim_db_scale, -1200, 100, 0);
932 static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_alc_db_scale, -2100, 400, 0);
934 static const struct snd_kcontrol_new ds_controls[] = {
936 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
937 .name = "Headphone Playback Volume",
938 .info = wm8776_hp_vol_info,
939 .get = wm8776_hp_vol_get,
940 .put = wm8776_hp_vol_put,
941 .tlv = { .p = wm8776_hp_db_scale },
943 WM8776_BIT_SWITCH("Headphone Playback Switch",
944 WM8776_PWRDOWN, WM8776_HPPD, 1, 0),
946 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
947 .name = "Input Capture Volume",
948 .info = wm8776_input_vol_info,
949 .get = wm8776_input_vol_get,
950 .put = wm8776_input_vol_put,
951 .tlv = { .p = wm8776_adc_db_scale },
954 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
955 .name = "Line Capture Switch",
956 .info = snd_ctl_boolean_mono_info,
957 .get = wm8776_input_mux_get,
958 .put = wm8776_input_mux_put,
959 .private_value = 1 << 0,
962 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
963 .name = "Mic Capture Switch",
964 .info = snd_ctl_boolean_mono_info,
965 .get = wm8776_input_mux_get,
966 .put = wm8776_input_mux_put,
967 .private_value = 1 << 1,
969 WM8776_BIT_SWITCH("Front Mic Capture Switch",
970 WM8776_ADCMUX, 1 << 2, 0, 0),
971 WM8776_BIT_SWITCH("Aux Capture Switch",
972 WM8776_ADCMUX, 1 << 3, 0, 0),
974 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
975 .name = "ADC Filter Capture Enum",
981 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
982 .name = "Level Control Capture Enum",
983 .info = wm8776_level_control_info,
984 .get = wm8776_level_control_get,
985 .put = wm8776_level_control_put,
989 static const struct snd_kcontrol_new lc_controls[] = {
990 WM8776_FIELD_CTL_VOLUME("Limiter Threshold",
991 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf,
992 LC_CONTROL_LIMITER, wm8776_lct_db_scale),
993 WM8776_FIELD_CTL_ENUM("Limiter Attack Time",
994 WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf,
996 WM8776_FIELD_CTL_ENUM("Limiter Decay Time",
997 WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf,
999 WM8776_FIELD_CTL_ENUM("Limiter Transient Window",
1000 WM8776_LIMITER, 4, 2, 0, 7, 0x7,
1001 LC_CONTROL_LIMITER),
1002 WM8776_FIELD_CTL_VOLUME("Limiter Maximum Attenuation",
1003 WM8776_LIMITER, 0, 6, 3, 12, 0xf,
1005 wm8776_maxatten_lim_db_scale),
1006 WM8776_FIELD_CTL_VOLUME("ALC Target Level",
1007 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf,
1008 LC_CONTROL_ALC, wm8776_lct_db_scale),
1009 WM8776_FIELD_CTL_ENUM("ALC Attack Time",
1010 WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf,
1012 WM8776_FIELD_CTL_ENUM("ALC Decay Time",
1013 WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf,
1015 WM8776_FIELD_CTL_VOLUME("ALC Maximum Gain",
1016 WM8776_ALCCTRL1, 4, 7, 1, 7, 0x7,
1017 LC_CONTROL_ALC, wm8776_maxgain_db_scale),
1018 WM8776_FIELD_CTL_VOLUME("ALC Maximum Attenuation",
1019 WM8776_LIMITER, 0, 10, 10, 15, 0xf,
1020 LC_CONTROL_ALC, wm8776_maxatten_alc_db_scale),
1021 WM8776_FIELD_CTL_ENUM("ALC Hold Time",
1022 WM8776_ALCCTRL2, 0, 0, 0, 15, 0xf,
1024 WM8776_BIT_SWITCH("Noise Gate Capture Switch",
1025 WM8776_NOISEGATE, WM8776_NGAT, 0,
1027 WM8776_FIELD_CTL_VOLUME("Noise Gate Threshold",
1028 WM8776_NOISEGATE, 2, 0, 0, 7, 0x7,
1029 LC_CONTROL_ALC, wm8776_ngth_db_scale),
1032 static int xonar_ds_mixer_init(struct oxygen *chip)
1034 struct xonar_wm87x6 *data = chip->model_data;
1036 struct snd_kcontrol *ctl;
1039 for (i = 0; i < ARRAY_SIZE(ds_controls); ++i) {
1040 ctl = snd_ctl_new1(&ds_controls[i], chip);
1043 err = snd_ctl_add(chip->card, ctl);
1046 if (!strcmp(ctl->id.name, "Line Capture Switch"))
1047 data->line_adcmux_control = ctl;
1048 else if (!strcmp(ctl->id.name, "Mic Capture Switch"))
1049 data->mic_adcmux_control = ctl;
1051 if (!data->line_adcmux_control || !data->mic_adcmux_control)
1053 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls));
1054 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) {
1055 ctl = snd_ctl_new1(&lc_controls[i], chip);
1058 err = snd_ctl_add(chip->card, ctl);
1061 data->lc_controls[i] = ctl;
1066 static void dump_wm8776_registers(struct oxygen *chip,
1067 struct snd_info_buffer *buffer)
1069 struct xonar_wm87x6 *data = chip->model_data;
1072 snd_iprintf(buffer, "\nWM8776:\n00:");
1073 for (i = 0; i < 0x10; ++i)
1074 snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
1075 snd_iprintf(buffer, "\n10:");
1076 for (i = 0x10; i < 0x17; ++i)
1077 snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
1078 snd_iprintf(buffer, "\n");
1081 static void dump_wm87x6_registers(struct oxygen *chip,
1082 struct snd_info_buffer *buffer)
1084 struct xonar_wm87x6 *data = chip->model_data;
1087 dump_wm8776_registers(chip, buffer);
1088 snd_iprintf(buffer, "\nWM8766:\n00:");
1089 for (i = 0; i < 0x10; ++i)
1090 snd_iprintf(buffer, " %03x", data->wm8766_regs[i]);
1091 snd_iprintf(buffer, "\n");
1094 static const struct oxygen_model model_xonar_ds = {
1095 .shortname = "Xonar DS",
1096 .longname = "Asus Virtuoso 66",
1098 .init = xonar_ds_init,
1099 .mixer_init = xonar_ds_mixer_init,
1100 .cleanup = xonar_ds_cleanup,
1101 .suspend = xonar_ds_suspend,
1102 .resume = xonar_ds_resume,
1103 .pcm_hardware_filter = wm8776_adc_hardware_filter,
1104 .get_i2s_mclk = oxygen_default_i2s_mclk,
1105 .set_dac_params = set_wm87x6_dac_params,
1106 .set_adc_params = set_wm8776_adc_params,
1107 .update_dac_volume = update_wm87x6_volume,
1108 .update_dac_mute = update_wm87x6_mute,
1109 .update_center_lfe_mix = update_wm8766_center_lfe_mix,
1110 .gpio_changed = xonar_ds_gpio_changed,
1111 .dump_registers = dump_wm87x6_registers,
1112 .dac_tlv = wm87x6_dac_db_scale,
1113 .model_data_size = sizeof(struct xonar_wm87x6),
1114 .device_config = PLAYBACK_0_TO_I2S |
1115 PLAYBACK_1_TO_SPDIF |
1116 CAPTURE_0_FROM_I2S_1,
1118 .dac_volume_min = 255 - 2*60,
1119 .dac_volume_max = 255,
1120 .function_flags = OXYGEN_FUNCTION_SPI,
1121 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1122 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1125 int __devinit get_xonar_wm87x6_model(struct oxygen *chip,
1126 const struct pci_device_id *id)
1128 switch (id->subdevice) {
1130 chip->model = model_xonar_ds;