]> git.karo-electronics.de Git - mv-sheeva.git/blob - sound/pci/oxygen/xonar_wm87x6.c
ALSA: virtuoso: add Xonar DS headphone jack detection
[mv-sheeva.git] / sound / pci / oxygen / xonar_wm87x6.c
1 /*
2  * card driver for models with WM8776/WM8766 DACs (Xonar DS)
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 speakers
31  * GPIO 8 -> enable output to speakers
32  *
33  * WM8766:
34  *
35  * input 1 <- line
36  * input 2 <- mic
37  * input 3 <- front mic
38  * input 4 <- aux
39  */
40
41 #include <linux/pci.h>
42 #include <linux/delay.h>
43 #include <sound/control.h>
44 #include <sound/core.h>
45 #include <sound/jack.h>
46 #include <sound/pcm.h>
47 #include <sound/pcm_params.h>
48 #include <sound/tlv.h>
49 #include "xonar.h"
50 #include "wm8776.h"
51 #include "wm8766.h"
52
53 #define GPIO_DS_HP_DETECT       0x0010
54 #define GPIO_DS_INPUT_ROUTE     0x0040
55 #define GPIO_DS_OUTPUT_ENABLE   0x0180
56
57 #define LC_CONTROL_LIMITER      0x40000000
58 #define LC_CONTROL_ALC          0x20000000
59
60 struct xonar_wm87x6 {
61         struct xonar_generic generic;
62         u16 wm8776_regs[0x17];
63         u16 wm8766_regs[0x10];
64         struct snd_kcontrol *line_adcmux_control;
65         struct snd_kcontrol *mic_adcmux_control;
66         struct snd_kcontrol *lc_controls[13];
67         struct snd_jack *hp_jack;
68 };
69
70 static void wm8776_write(struct oxygen *chip,
71                          unsigned int reg, unsigned int value)
72 {
73         struct xonar_wm87x6 *data = chip->model_data;
74
75         oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
76                          OXYGEN_SPI_DATA_LENGTH_2 |
77                          OXYGEN_SPI_CLOCK_160 |
78                          (1 << OXYGEN_SPI_CODEC_SHIFT) |
79                          OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
80                          (reg << 9) | value);
81         if (reg < ARRAY_SIZE(data->wm8776_regs)) {
82                 if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER)
83                         value &= ~WM8776_UPDATE;
84                 data->wm8776_regs[reg] = value;
85         }
86 }
87
88 static void wm8776_write_cached(struct oxygen *chip,
89                                 unsigned int reg, unsigned int value)
90 {
91         struct xonar_wm87x6 *data = chip->model_data;
92
93         if (reg >= ARRAY_SIZE(data->wm8776_regs) ||
94             value != data->wm8776_regs[reg])
95                 wm8776_write(chip, reg, value);
96 }
97
98 static void wm8766_write(struct oxygen *chip,
99                          unsigned int reg, unsigned int value)
100 {
101         struct xonar_wm87x6 *data = chip->model_data;
102
103         oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
104                          OXYGEN_SPI_DATA_LENGTH_2 |
105                          OXYGEN_SPI_CLOCK_160 |
106                          (0 << OXYGEN_SPI_CODEC_SHIFT) |
107                          OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
108                          (reg << 9) | value);
109         if (reg < ARRAY_SIZE(data->wm8766_regs)) {
110                 if ((reg >= WM8766_LDA1 && reg <= WM8766_RDA1) ||
111                     (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA))
112                         value &= ~WM8766_UPDATE;
113                 data->wm8766_regs[reg] = value;
114         }
115 }
116
117 static void wm8766_write_cached(struct oxygen *chip,
118                                 unsigned int reg, unsigned int value)
119 {
120         struct xonar_wm87x6 *data = chip->model_data;
121
122         if (reg >= ARRAY_SIZE(data->wm8766_regs) ||
123             value != data->wm8766_regs[reg])
124                 wm8766_write(chip, reg, value);
125 }
126
127 static void wm8776_registers_init(struct oxygen *chip)
128 {
129         struct xonar_wm87x6 *data = chip->model_data;
130
131         wm8776_write(chip, WM8776_RESET, 0);
132         wm8776_write(chip, WM8776_DACCTRL1, WM8776_DZCEN |
133                      WM8776_PL_LEFT_LEFT | WM8776_PL_RIGHT_RIGHT);
134         wm8776_write(chip, WM8776_DACMUTE, chip->dac_mute ? WM8776_DMUTE : 0);
135         wm8776_write(chip, WM8776_DACIFCTRL,
136                      WM8776_DACFMT_LJUST | WM8776_DACWL_24);
137         wm8776_write(chip, WM8776_ADCIFCTRL,
138                      data->wm8776_regs[WM8776_ADCIFCTRL]);
139         wm8776_write(chip, WM8776_MSTRCTRL, data->wm8776_regs[WM8776_MSTRCTRL]);
140         wm8776_write(chip, WM8776_PWRDOWN, data->wm8776_regs[WM8776_PWRDOWN]);
141         wm8776_write(chip, WM8776_HPLVOL, data->wm8776_regs[WM8776_HPLVOL]);
142         wm8776_write(chip, WM8776_HPRVOL, data->wm8776_regs[WM8776_HPRVOL] |
143                      WM8776_UPDATE);
144         wm8776_write(chip, WM8776_ADCLVOL, data->wm8776_regs[WM8776_ADCLVOL]);
145         wm8776_write(chip, WM8776_ADCRVOL, data->wm8776_regs[WM8776_ADCRVOL]);
146         wm8776_write(chip, WM8776_ADCMUX, data->wm8776_regs[WM8776_ADCMUX]);
147         wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0]);
148         wm8776_write(chip, WM8776_DACRVOL, chip->dac_volume[1] | WM8776_UPDATE);
149 }
150
151 static void wm8766_registers_init(struct oxygen *chip)
152 {
153         wm8766_write(chip, WM8766_RESET, 0);
154         wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24);
155         wm8766_write(chip, WM8766_DAC_CTRL2,
156                      WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
157         wm8766_write(chip, WM8766_LDA1, chip->dac_volume[2]);
158         wm8766_write(chip, WM8766_RDA1, chip->dac_volume[3]);
159         wm8766_write(chip, WM8766_LDA2, chip->dac_volume[4]);
160         wm8766_write(chip, WM8766_RDA2, chip->dac_volume[5]);
161         wm8766_write(chip, WM8766_LDA3, chip->dac_volume[6]);
162         wm8766_write(chip, WM8766_RDA3, chip->dac_volume[7] | WM8766_UPDATE);
163 }
164
165 static void wm8776_init(struct oxygen *chip)
166 {
167         struct xonar_wm87x6 *data = chip->model_data;
168
169         data->wm8776_regs[WM8776_HPLVOL] = (0x79 - 60) | WM8776_HPZCEN;
170         data->wm8776_regs[WM8776_HPRVOL] = (0x79 - 60) | WM8776_HPZCEN;
171         data->wm8776_regs[WM8776_ADCIFCTRL] =
172                 WM8776_ADCFMT_LJUST | WM8776_ADCWL_24 | WM8776_ADCMCLK;
173         data->wm8776_regs[WM8776_MSTRCTRL] =
174                 WM8776_ADCRATE_256 | WM8776_DACRATE_256;
175         data->wm8776_regs[WM8776_PWRDOWN] = WM8776_HPPD;
176         data->wm8776_regs[WM8776_ADCLVOL] = 0xa5 | WM8776_ZCA;
177         data->wm8776_regs[WM8776_ADCRVOL] = 0xa5 | WM8776_ZCA;
178         data->wm8776_regs[WM8776_ADCMUX] = 0x001;
179         wm8776_registers_init(chip);
180 }
181
182 static void xonar_ds_report_hp_jack(struct oxygen *chip)
183 {
184         struct xonar_wm87x6 *data = chip->model_data;
185         u16 bits;
186
187         bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
188         snd_jack_report(data->hp_jack,
189                         bits & GPIO_DS_HP_DETECT ? 0 : SND_JACK_HEADPHONE);
190 }
191
192 static void xonar_ds_init(struct oxygen *chip)
193 {
194         struct xonar_wm87x6 *data = chip->model_data;
195
196         data->generic.anti_pop_delay = 300;
197         data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE;
198
199         wm8776_init(chip);
200         wm8766_registers_init(chip);
201
202         oxygen_write16_masked(chip, OXYGEN_GPIO_CONTROL, GPIO_DS_INPUT_ROUTE,
203                               GPIO_DS_HP_DETECT | GPIO_DS_INPUT_ROUTE);
204         oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE);
205         oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT);
206         chip->interrupt_mask |= OXYGEN_INT_GPIO;
207
208         xonar_enable_output(chip);
209
210         snd_jack_new(chip->card, "Headphone",
211                      SND_JACK_HEADPHONE, &data->hp_jack);
212         xonar_ds_report_hp_jack(chip);
213
214         snd_component_add(chip->card, "WM8776");
215         snd_component_add(chip->card, "WM8766");
216 }
217
218 static void xonar_ds_cleanup(struct oxygen *chip)
219 {
220         xonar_disable_output(chip);
221         wm8776_write(chip, WM8776_RESET, 0);
222 }
223
224 static void xonar_ds_suspend(struct oxygen *chip)
225 {
226         xonar_ds_cleanup(chip);
227 }
228
229 static void xonar_ds_resume(struct oxygen *chip)
230 {
231         wm8776_registers_init(chip);
232         wm8766_registers_init(chip);
233         xonar_enable_output(chip);
234 }
235
236 static void wm8776_adc_hardware_filter(unsigned int channel,
237                                        struct snd_pcm_hardware *hardware)
238 {
239         if (channel == PCM_A) {
240                 hardware->rates = SNDRV_PCM_RATE_32000 |
241                                   SNDRV_PCM_RATE_44100 |
242                                   SNDRV_PCM_RATE_48000 |
243                                   SNDRV_PCM_RATE_64000 |
244                                   SNDRV_PCM_RATE_88200 |
245                                   SNDRV_PCM_RATE_96000;
246                 hardware->rate_max = 96000;
247         }
248 }
249
250 static void set_wm87x6_dac_params(struct oxygen *chip,
251                                   struct snd_pcm_hw_params *params)
252 {
253 }
254
255 static void set_wm8776_adc_params(struct oxygen *chip,
256                                   struct snd_pcm_hw_params *params)
257 {
258         u16 reg;
259
260         reg = WM8776_ADCRATE_256 | WM8776_DACRATE_256;
261         if (params_rate(params) > 48000)
262                 reg |= WM8776_ADCOSR;
263         wm8776_write_cached(chip, WM8776_MSTRCTRL, reg);
264 }
265
266 static void update_wm8776_volume(struct oxygen *chip)
267 {
268         struct xonar_wm87x6 *data = chip->model_data;
269         u8 to_change;
270
271         if (chip->dac_volume[0] == chip->dac_volume[1]) {
272                 if (chip->dac_volume[0] != data->wm8776_regs[WM8776_DACLVOL] ||
273                     chip->dac_volume[1] != data->wm8776_regs[WM8776_DACRVOL]) {
274                         wm8776_write(chip, WM8776_DACMASTER,
275                                      chip->dac_volume[0] | WM8776_UPDATE);
276                         data->wm8776_regs[WM8776_DACLVOL] = chip->dac_volume[0];
277                         data->wm8776_regs[WM8776_DACRVOL] = chip->dac_volume[0];
278                 }
279         } else {
280                 to_change = (chip->dac_volume[0] !=
281                              data->wm8776_regs[WM8776_DACLVOL]) << 0;
282                 to_change |= (chip->dac_volume[1] !=
283                               data->wm8776_regs[WM8776_DACLVOL]) << 1;
284                 if (to_change & 1)
285                         wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0] |
286                                      ((to_change & 2) ? 0 : WM8776_UPDATE));
287                 if (to_change & 2)
288                         wm8776_write(chip, WM8776_DACRVOL,
289                                      chip->dac_volume[1] | WM8776_UPDATE);
290         }
291 }
292
293 static void update_wm87x6_volume(struct oxygen *chip)
294 {
295         static const u8 wm8766_regs[6] = {
296                 WM8766_LDA1, WM8766_RDA1,
297                 WM8766_LDA2, WM8766_RDA2,
298                 WM8766_LDA3, WM8766_RDA3,
299         };
300         struct xonar_wm87x6 *data = chip->model_data;
301         unsigned int i;
302         u8 to_change;
303
304         update_wm8776_volume(chip);
305         if (chip->dac_volume[2] == chip->dac_volume[3] &&
306             chip->dac_volume[2] == chip->dac_volume[4] &&
307             chip->dac_volume[2] == chip->dac_volume[5] &&
308             chip->dac_volume[2] == chip->dac_volume[6] &&
309             chip->dac_volume[2] == chip->dac_volume[7]) {
310                 to_change = 0;
311                 for (i = 0; i < 6; ++i)
312                         if (chip->dac_volume[2] !=
313                             data->wm8766_regs[wm8766_regs[i]])
314                                 to_change = 1;
315                 if (to_change) {
316                         wm8766_write(chip, WM8766_MASTDA,
317                                      chip->dac_volume[2] | WM8766_UPDATE);
318                         for (i = 0; i < 6; ++i)
319                                 data->wm8766_regs[wm8766_regs[i]] =
320                                         chip->dac_volume[2];
321                 }
322         } else {
323                 to_change = 0;
324                 for (i = 0; i < 6; ++i)
325                         to_change |= (chip->dac_volume[2 + i] !=
326                                       data->wm8766_regs[wm8766_regs[i]]) << i;
327                 for (i = 0; i < 6; ++i)
328                         if (to_change & (1 << i))
329                                 wm8766_write(chip, wm8766_regs[i],
330                                              chip->dac_volume[2 + i] |
331                                              ((to_change & (0x3e << i))
332                                               ? 0 : WM8766_UPDATE));
333         }
334 }
335
336 static void update_wm8776_mute(struct oxygen *chip)
337 {
338         wm8776_write_cached(chip, WM8776_DACMUTE,
339                             chip->dac_mute ? WM8776_DMUTE : 0);
340 }
341
342 static void update_wm87x6_mute(struct oxygen *chip)
343 {
344         update_wm8776_mute(chip);
345         wm8766_write_cached(chip, WM8766_DAC_CTRL2, WM8766_ZCD |
346                             (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
347 }
348
349 static void xonar_ds_gpio_changed(struct oxygen *chip)
350 {
351         xonar_ds_report_hp_jack(chip);
352 }
353
354 static int wm8776_bit_switch_get(struct snd_kcontrol *ctl,
355                                  struct snd_ctl_elem_value *value)
356 {
357         struct oxygen *chip = ctl->private_data;
358         struct xonar_wm87x6 *data = chip->model_data;
359         u16 bit = ctl->private_value & 0xffff;
360         unsigned int reg_index = (ctl->private_value >> 16) & 0xff;
361         bool invert = (ctl->private_value >> 24) & 1;
362
363         value->value.integer.value[0] =
364                 ((data->wm8776_regs[reg_index] & bit) != 0) ^ invert;
365         return 0;
366 }
367
368 static int wm8776_bit_switch_put(struct snd_kcontrol *ctl,
369                                  struct snd_ctl_elem_value *value)
370 {
371         struct oxygen *chip = ctl->private_data;
372         struct xonar_wm87x6 *data = chip->model_data;
373         u16 bit = ctl->private_value & 0xffff;
374         u16 reg_value;
375         unsigned int reg_index = (ctl->private_value >> 16) & 0xff;
376         bool invert = (ctl->private_value >> 24) & 1;
377         int changed;
378
379         mutex_lock(&chip->mutex);
380         reg_value = data->wm8776_regs[reg_index] & ~bit;
381         if (value->value.integer.value[0] ^ invert)
382                 reg_value |= bit;
383         changed = reg_value != data->wm8776_regs[reg_index];
384         if (changed)
385                 wm8776_write(chip, reg_index, reg_value);
386         mutex_unlock(&chip->mutex);
387         return changed;
388 }
389
390 static int wm8776_field_enum_info(struct snd_kcontrol *ctl,
391                                   struct snd_ctl_elem_info *info)
392 {
393         static const char *const hld[16] = {
394                 "0 ms", "2.67 ms", "5.33 ms", "10.6 ms",
395                 "21.3 ms", "42.7 ms", "85.3 ms", "171 ms",
396                 "341 ms", "683 ms", "1.37 s", "2.73 s",
397                 "5.46 s", "10.9 s", "21.8 s", "43.7 s",
398         };
399         static const char *const atk_lim[11] = {
400                 "0.25 ms", "0.5 ms", "1 ms", "2 ms",
401                 "4 ms", "8 ms", "16 ms", "32 ms",
402                 "64 ms", "128 ms", "256 ms",
403         };
404         static const char *const atk_alc[11] = {
405                 "8.40 ms", "16.8 ms", "33.6 ms", "67.2 ms",
406                 "134 ms", "269 ms", "538 ms", "1.08 s",
407                 "2.15 s", "4.3 s", "8.6 s",
408         };
409         static const char *const dcy_lim[11] = {
410                 "1.2 ms", "2.4 ms", "4.8 ms", "9.6 ms",
411                 "19.2 ms", "38.4 ms", "76.8 ms", "154 ms",
412                 "307 ms", "614 ms", "1.23 s",
413         };
414         static const char *const dcy_alc[11] = {
415                 "33.5 ms", "67.0 ms", "134 ms", "268 ms",
416                 "536 ms", "1.07 s", "2.14 s", "4.29 s",
417                 "8.58 s", "17.2 s", "34.3 s",
418         };
419         static const char *const tranwin[8] = {
420                 "0 us", "62.5 us", "125 us", "250 us",
421                 "500 us", "1 ms", "2 ms", "4 ms",
422         };
423         u8 max;
424         const char *const *names;
425
426         max = (ctl->private_value >> 12) & 0xf;
427         info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
428         info->count = 1;
429         info->value.enumerated.items = max + 1;
430         if (info->value.enumerated.item > max)
431                 info->value.enumerated.item = max;
432         switch ((ctl->private_value >> 24) & 0x1f) {
433         case WM8776_ALCCTRL2:
434                 names = hld;
435                 break;
436         case WM8776_ALCCTRL3:
437                 if (((ctl->private_value >> 20) & 0xf) == 0) {
438                         if (ctl->private_value & LC_CONTROL_LIMITER)
439                                 names = atk_lim;
440                         else
441                                 names = atk_alc;
442                 } else {
443                         if (ctl->private_value & LC_CONTROL_LIMITER)
444                                 names = dcy_lim;
445                         else
446                                 names = dcy_alc;
447                 }
448                 break;
449         case WM8776_LIMITER:
450                 names = tranwin;
451                 break;
452         default:
453                 return -ENXIO;
454         }
455         strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
456         return 0;
457 }
458
459 static int wm8776_field_volume_info(struct snd_kcontrol *ctl,
460                                     struct snd_ctl_elem_info *info)
461 {
462         info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
463         info->count = 1;
464         info->value.integer.min = (ctl->private_value >> 8) & 0xf;
465         info->value.integer.max = (ctl->private_value >> 12) & 0xf;
466         return 0;
467 }
468
469 static void wm8776_field_set_from_ctl(struct snd_kcontrol *ctl)
470 {
471         struct oxygen *chip = ctl->private_data;
472         struct xonar_wm87x6 *data = chip->model_data;
473         unsigned int value, reg_index, mode;
474         u8 min, max, shift;
475         u16 mask, reg_value;
476         bool invert;
477
478         if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) ==
479             WM8776_LCSEL_LIMITER)
480                 mode = LC_CONTROL_LIMITER;
481         else
482                 mode = LC_CONTROL_ALC;
483         if (!(ctl->private_value & mode))
484                 return;
485
486         value = ctl->private_value & 0xf;
487         min = (ctl->private_value >> 8) & 0xf;
488         max = (ctl->private_value >> 12) & 0xf;
489         mask = (ctl->private_value >> 16) & 0xf;
490         shift = (ctl->private_value >> 20) & 0xf;
491         reg_index = (ctl->private_value >> 24) & 0x1f;
492         invert = (ctl->private_value >> 29) & 0x1;
493
494         if (invert)
495                 value = max - (value - min);
496         reg_value = data->wm8776_regs[reg_index];
497         reg_value &= ~(mask << shift);
498         reg_value |= value << shift;
499         wm8776_write_cached(chip, reg_index, reg_value);
500 }
501
502 static int wm8776_field_set(struct snd_kcontrol *ctl, unsigned int value)
503 {
504         struct oxygen *chip = ctl->private_data;
505         u8 min, max;
506         int changed;
507
508         min = (ctl->private_value >> 8) & 0xf;
509         max = (ctl->private_value >> 12) & 0xf;
510         if (value < min || value > max)
511                 return -EINVAL;
512         mutex_lock(&chip->mutex);
513         changed = value != (ctl->private_value & 0xf);
514         if (changed) {
515                 ctl->private_value = (ctl->private_value & ~0xf) | value;
516                 wm8776_field_set_from_ctl(ctl);
517         }
518         mutex_unlock(&chip->mutex);
519         return changed;
520 }
521
522 static int wm8776_field_enum_get(struct snd_kcontrol *ctl,
523                                  struct snd_ctl_elem_value *value)
524 {
525         value->value.enumerated.item[0] = ctl->private_value & 0xf;
526         return 0;
527 }
528
529 static int wm8776_field_volume_get(struct snd_kcontrol *ctl,
530                                    struct snd_ctl_elem_value *value)
531 {
532         value->value.integer.value[0] = ctl->private_value & 0xf;
533         return 0;
534 }
535
536 static int wm8776_field_enum_put(struct snd_kcontrol *ctl,
537                                  struct snd_ctl_elem_value *value)
538 {
539         return wm8776_field_set(ctl, value->value.enumerated.item[0]);
540 }
541
542 static int wm8776_field_volume_put(struct snd_kcontrol *ctl,
543                                    struct snd_ctl_elem_value *value)
544 {
545         return wm8776_field_set(ctl, value->value.integer.value[0]);
546 }
547
548 static int wm8776_hp_vol_info(struct snd_kcontrol *ctl,
549                               struct snd_ctl_elem_info *info)
550 {
551         info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
552         info->count = 2;
553         info->value.integer.min = 0x79 - 60;
554         info->value.integer.max = 0x7f;
555         return 0;
556 }
557
558 static int wm8776_hp_vol_get(struct snd_kcontrol *ctl,
559                              struct snd_ctl_elem_value *value)
560 {
561         struct oxygen *chip = ctl->private_data;
562         struct xonar_wm87x6 *data = chip->model_data;
563
564         mutex_lock(&chip->mutex);
565         value->value.integer.value[0] =
566                 data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK;
567         value->value.integer.value[1] =
568                 data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK;
569         mutex_unlock(&chip->mutex);
570         return 0;
571 }
572
573 static int wm8776_hp_vol_put(struct snd_kcontrol *ctl,
574                              struct snd_ctl_elem_value *value)
575 {
576         struct oxygen *chip = ctl->private_data;
577         struct xonar_wm87x6 *data = chip->model_data;
578         u8 to_update;
579
580         mutex_lock(&chip->mutex);
581         to_update = (value->value.integer.value[0] !=
582                      (data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK))
583                 << 0;
584         to_update |= (value->value.integer.value[1] !=
585                       (data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK))
586                 << 1;
587         if (value->value.integer.value[0] == value->value.integer.value[1]) {
588                 if (to_update) {
589                         wm8776_write(chip, WM8776_HPMASTER,
590                                      value->value.integer.value[0] |
591                                      WM8776_HPZCEN | WM8776_UPDATE);
592                         data->wm8776_regs[WM8776_HPLVOL] =
593                                 value->value.integer.value[0] | WM8776_HPZCEN;
594                         data->wm8776_regs[WM8776_HPRVOL] =
595                                 value->value.integer.value[0] | WM8776_HPZCEN;
596                 }
597         } else {
598                 if (to_update & 1)
599                         wm8776_write(chip, WM8776_HPLVOL,
600                                      value->value.integer.value[0] |
601                                      WM8776_HPZCEN |
602                                      ((to_update & 2) ? 0 : WM8776_UPDATE));
603                 if (to_update & 2)
604                         wm8776_write(chip, WM8776_HPRVOL,
605                                      value->value.integer.value[1] |
606                                      WM8776_HPZCEN | WM8776_UPDATE);
607         }
608         mutex_unlock(&chip->mutex);
609         return to_update != 0;
610 }
611
612 static int wm8776_input_mux_get(struct snd_kcontrol *ctl,
613                                 struct snd_ctl_elem_value *value)
614 {
615         struct oxygen *chip = ctl->private_data;
616         struct xonar_wm87x6 *data = chip->model_data;
617         unsigned int mux_bit = ctl->private_value;
618
619         value->value.integer.value[0] =
620                 !!(data->wm8776_regs[WM8776_ADCMUX] & mux_bit);
621         return 0;
622 }
623
624 static int wm8776_input_mux_put(struct snd_kcontrol *ctl,
625                                 struct snd_ctl_elem_value *value)
626 {
627         struct oxygen *chip = ctl->private_data;
628         struct xonar_wm87x6 *data = chip->model_data;
629         struct snd_kcontrol *other_ctl;
630         unsigned int mux_bit = ctl->private_value;
631         u16 reg;
632         int changed;
633
634         mutex_lock(&chip->mutex);
635         reg = data->wm8776_regs[WM8776_ADCMUX];
636         if (value->value.integer.value[0]) {
637                 reg |= mux_bit;
638                 /* line-in and mic-in are exclusive */
639                 mux_bit ^= 3;
640                 if (reg & mux_bit) {
641                         reg &= ~mux_bit;
642                         if (mux_bit == 1)
643                                 other_ctl = data->line_adcmux_control;
644                         else
645                                 other_ctl = data->mic_adcmux_control;
646                         snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
647                                        &other_ctl->id);
648                 }
649         } else
650                 reg &= ~mux_bit;
651         changed = reg != data->wm8776_regs[WM8776_ADCMUX];
652         if (changed) {
653                 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
654                                       reg & 1 ? GPIO_DS_INPUT_ROUTE : 0,
655                                       GPIO_DS_INPUT_ROUTE);
656                 wm8776_write(chip, WM8776_ADCMUX, reg);
657         }
658         mutex_unlock(&chip->mutex);
659         return changed;
660 }
661
662 static int wm8776_input_vol_info(struct snd_kcontrol *ctl,
663                                  struct snd_ctl_elem_info *info)
664 {
665         info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
666         info->count = 2;
667         info->value.integer.min = 0xa5;
668         info->value.integer.max = 0xff;
669         return 0;
670 }
671
672 static int wm8776_input_vol_get(struct snd_kcontrol *ctl,
673                                 struct snd_ctl_elem_value *value)
674 {
675         struct oxygen *chip = ctl->private_data;
676         struct xonar_wm87x6 *data = chip->model_data;
677
678         mutex_lock(&chip->mutex);
679         value->value.integer.value[0] =
680                 data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK;
681         value->value.integer.value[1] =
682                 data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK;
683         mutex_unlock(&chip->mutex);
684         return 0;
685 }
686
687 static int wm8776_input_vol_put(struct snd_kcontrol *ctl,
688                                 struct snd_ctl_elem_value *value)
689 {
690         struct oxygen *chip = ctl->private_data;
691         struct xonar_wm87x6 *data = chip->model_data;
692         int changed = 0;
693
694         mutex_lock(&chip->mutex);
695         changed = (value->value.integer.value[0] !=
696                    (data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK)) ||
697                   (value->value.integer.value[1] !=
698                    (data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK));
699         wm8776_write_cached(chip, WM8776_ADCLVOL,
700                             value->value.integer.value[0] | WM8776_ZCA);
701         wm8776_write_cached(chip, WM8776_ADCRVOL,
702                             value->value.integer.value[1] | WM8776_ZCA);
703         mutex_unlock(&chip->mutex);
704         return changed;
705 }
706
707 static int wm8776_level_control_info(struct snd_kcontrol *ctl,
708                                      struct snd_ctl_elem_info *info)
709 {
710         static const char *const names[3] = {
711                 "None", "Peak Limiter", "Automatic Level Control"
712         };
713         info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
714         info->count = 1;
715         info->value.enumerated.items = 3;
716         if (info->value.enumerated.item >= 3)
717                 info->value.enumerated.item = 2;
718         strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
719         return 0;
720 }
721
722 static int wm8776_level_control_get(struct snd_kcontrol *ctl,
723                                     struct snd_ctl_elem_value *value)
724 {
725         struct oxygen *chip = ctl->private_data;
726         struct xonar_wm87x6 *data = chip->model_data;
727
728         if (!(data->wm8776_regs[WM8776_ALCCTRL2] & WM8776_LCEN))
729                 value->value.enumerated.item[0] = 0;
730         else if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) ==
731                  WM8776_LCSEL_LIMITER)
732                 value->value.enumerated.item[0] = 1;
733         else
734                 value->value.enumerated.item[0] = 2;
735         return 0;
736 }
737
738 static void activate_control(struct oxygen *chip,
739                              struct snd_kcontrol *ctl, unsigned int mode)
740 {
741         unsigned int access;
742
743         if (ctl->private_value & mode)
744                 access = 0;
745         else
746                 access = SNDRV_CTL_ELEM_ACCESS_INACTIVE;
747         if ((ctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE) != access) {
748                 ctl->vd[0].access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
749                 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
750         }
751 }
752
753 static int wm8776_level_control_put(struct snd_kcontrol *ctl,
754                                     struct snd_ctl_elem_value *value)
755 {
756         struct oxygen *chip = ctl->private_data;
757         struct xonar_wm87x6 *data = chip->model_data;
758         unsigned int mode = 0, i;
759         u16 ctrl1, ctrl2;
760         int changed;
761
762         if (value->value.enumerated.item[0] >= 3)
763                 return -EINVAL;
764         mutex_lock(&chip->mutex);
765         changed = value->value.enumerated.item[0] != ctl->private_value;
766         if (changed) {
767                 ctl->private_value = value->value.enumerated.item[0];
768                 ctrl1 = data->wm8776_regs[WM8776_ALCCTRL1];
769                 ctrl2 = data->wm8776_regs[WM8776_ALCCTRL2];
770                 switch (value->value.enumerated.item[0]) {
771                 default:
772                         wm8776_write_cached(chip, WM8776_ALCCTRL2,
773                                             ctrl2 & ~WM8776_LCEN);
774                         break;
775                 case 1:
776                         wm8776_write_cached(chip, WM8776_ALCCTRL1,
777                                             (ctrl1 & ~WM8776_LCSEL_MASK) |
778                                             WM8776_LCSEL_LIMITER);
779                         wm8776_write_cached(chip, WM8776_ALCCTRL2,
780                                             ctrl2 | WM8776_LCEN);
781                         mode = LC_CONTROL_LIMITER;
782                         break;
783                 case 2:
784                         wm8776_write_cached(chip, WM8776_ALCCTRL1,
785                                             (ctrl1 & ~WM8776_LCSEL_MASK) |
786                                             WM8776_LCSEL_ALC_STEREO);
787                         wm8776_write_cached(chip, WM8776_ALCCTRL2,
788                                             ctrl2 | WM8776_LCEN);
789                         mode = LC_CONTROL_ALC;
790                         break;
791                 }
792                 for (i = 0; i < ARRAY_SIZE(data->lc_controls); ++i)
793                         activate_control(chip, data->lc_controls[i], mode);
794         }
795         mutex_unlock(&chip->mutex);
796         return changed;
797 }
798
799 static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
800 {
801         static const char *const names[2] = {
802                 "None", "High-pass Filter"
803         };
804
805         info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
806         info->count = 1;
807         info->value.enumerated.items = 2;
808         if (info->value.enumerated.item >= 2)
809                 info->value.enumerated.item = 1;
810         strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
811         return 0;
812 }
813
814 static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
815 {
816         struct oxygen *chip = ctl->private_data;
817         struct xonar_wm87x6 *data = chip->model_data;
818
819         value->value.enumerated.item[0] =
820                 !(data->wm8776_regs[WM8776_ADCIFCTRL] & WM8776_ADCHPD);
821         return 0;
822 }
823
824 static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
825 {
826         struct oxygen *chip = ctl->private_data;
827         struct xonar_wm87x6 *data = chip->model_data;
828         unsigned int reg;
829         int changed;
830
831         mutex_lock(&chip->mutex);
832         reg = data->wm8776_regs[WM8776_ADCIFCTRL] & ~WM8776_ADCHPD;
833         if (!value->value.enumerated.item[0])
834                 reg |= WM8776_ADCHPD;
835         changed = reg != data->wm8776_regs[WM8776_ADCIFCTRL];
836         if (changed)
837                 wm8776_write(chip, WM8776_ADCIFCTRL, reg);
838         mutex_unlock(&chip->mutex);
839         return changed;
840 }
841
842 #define WM8776_BIT_SWITCH(xname, reg, bit, invert, flags) { \
843         .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
844         .name = xname, \
845         .info = snd_ctl_boolean_mono_info, \
846         .get = wm8776_bit_switch_get, \
847         .put = wm8776_bit_switch_put, \
848         .private_value = ((reg) << 16) | (bit) | ((invert) << 24) | (flags), \
849 }
850 #define _WM8776_FIELD_CTL(xname, reg, shift, initval, min, max, mask, flags) \
851         .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
852         .name = xname, \
853         .private_value = (initval) | ((min) << 8) | ((max) << 12) | \
854         ((mask) << 16) | ((shift) << 20) | ((reg) << 24) | (flags)
855 #define WM8776_FIELD_CTL_ENUM(xname, reg, shift, init, min, max, mask, flags) {\
856         _WM8776_FIELD_CTL(xname " Capture Enum", \
857                           reg, shift, init, min, max, mask, flags), \
858         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
859                   SNDRV_CTL_ELEM_ACCESS_INACTIVE, \
860         .info = wm8776_field_enum_info, \
861         .get = wm8776_field_enum_get, \
862         .put = wm8776_field_enum_put, \
863 }
864 #define WM8776_FIELD_CTL_VOLUME(a, b, c, d, e, f, g, h, tlv_p) { \
865         _WM8776_FIELD_CTL(a " Capture Volume", b, c, d, e, f, g, h), \
866         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
867                   SNDRV_CTL_ELEM_ACCESS_INACTIVE | \
868                   SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
869         .info = wm8776_field_volume_info, \
870         .get = wm8776_field_volume_get, \
871         .put = wm8776_field_volume_put, \
872         .tlv = { .p = tlv_p }, \
873 }
874
875 static const DECLARE_TLV_DB_SCALE(wm87x6_dac_db_scale, -6000, 50, 0);
876 static const DECLARE_TLV_DB_SCALE(wm8776_adc_db_scale, -2100, 50, 0);
877 static const DECLARE_TLV_DB_SCALE(wm8776_hp_db_scale, -6000, 100, 0);
878 static const DECLARE_TLV_DB_SCALE(wm8776_lct_db_scale, -1600, 100, 0);
879 static const DECLARE_TLV_DB_SCALE(wm8776_maxgain_db_scale, 0, 400, 0);
880 static const DECLARE_TLV_DB_SCALE(wm8776_ngth_db_scale, -7800, 600, 0);
881 static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_lim_db_scale, -1200, 100, 0);
882 static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_alc_db_scale, -2100, 400, 0);
883
884 static const struct snd_kcontrol_new ds_controls[] = {
885         {
886                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
887                 .name = "Headphone Playback Volume",
888                 .info = wm8776_hp_vol_info,
889                 .get = wm8776_hp_vol_get,
890                 .put = wm8776_hp_vol_put,
891                 .tlv = { .p = wm8776_hp_db_scale },
892         },
893         WM8776_BIT_SWITCH("Headphone Playback Switch",
894                           WM8776_PWRDOWN, WM8776_HPPD, 1, 0),
895         {
896                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
897                 .name = "Input Capture Volume",
898                 .info = wm8776_input_vol_info,
899                 .get = wm8776_input_vol_get,
900                 .put = wm8776_input_vol_put,
901                 .tlv = { .p = wm8776_adc_db_scale },
902         },
903         {
904                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
905                 .name = "Line Capture Switch",
906                 .info = snd_ctl_boolean_mono_info,
907                 .get = wm8776_input_mux_get,
908                 .put = wm8776_input_mux_put,
909                 .private_value = 1 << 0,
910         },
911         {
912                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
913                 .name = "Mic Capture Switch",
914                 .info = snd_ctl_boolean_mono_info,
915                 .get = wm8776_input_mux_get,
916                 .put = wm8776_input_mux_put,
917                 .private_value = 1 << 1,
918         },
919         WM8776_BIT_SWITCH("Front Mic Capture Switch",
920                           WM8776_ADCMUX, 1 << 2, 0, 0),
921         WM8776_BIT_SWITCH("Aux Capture Switch",
922                           WM8776_ADCMUX, 1 << 3, 0, 0),
923         {
924                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
925                 .name = "ADC Filter Capture Enum",
926                 .info = hpf_info,
927                 .get = hpf_get,
928                 .put = hpf_put,
929         },
930         {
931                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
932                 .name = "Level Control Capture Enum",
933                 .info = wm8776_level_control_info,
934                 .get = wm8776_level_control_get,
935                 .put = wm8776_level_control_put,
936                 .private_value = 0,
937         },
938 };
939 static const struct snd_kcontrol_new lc_controls[] = {
940         WM8776_FIELD_CTL_VOLUME("Limiter Threshold",
941                                 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf,
942                                 LC_CONTROL_LIMITER, wm8776_lct_db_scale),
943         WM8776_FIELD_CTL_ENUM("Limiter Attack Time",
944                               WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf,
945                               LC_CONTROL_LIMITER),
946         WM8776_FIELD_CTL_ENUM("Limiter Decay Time",
947                               WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf,
948                               LC_CONTROL_LIMITER),
949         WM8776_FIELD_CTL_ENUM("Limiter Transient Window",
950                               WM8776_LIMITER, 4, 2, 0, 7, 0x7,
951                               LC_CONTROL_LIMITER),
952         WM8776_FIELD_CTL_VOLUME("Limiter Maximum Attenuation",
953                                 WM8776_LIMITER, 0, 6, 3, 12, 0xf,
954                                 LC_CONTROL_LIMITER,
955                                 wm8776_maxatten_lim_db_scale),
956         WM8776_FIELD_CTL_VOLUME("ALC Target Level",
957                                 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf,
958                                 LC_CONTROL_ALC, wm8776_lct_db_scale),
959         WM8776_FIELD_CTL_ENUM("ALC Attack Time",
960                               WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf,
961                               LC_CONTROL_ALC),
962         WM8776_FIELD_CTL_ENUM("ALC Decay Time",
963                               WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf,
964                               LC_CONTROL_ALC),
965         WM8776_FIELD_CTL_VOLUME("ALC Maximum Gain",
966                                 WM8776_ALCCTRL1, 4, 7, 1, 7, 0x7,
967                                 LC_CONTROL_ALC, wm8776_maxgain_db_scale),
968         WM8776_FIELD_CTL_VOLUME("ALC Maximum Attenuation",
969                                 WM8776_LIMITER, 0, 10, 10, 15, 0xf,
970                                 LC_CONTROL_ALC, wm8776_maxatten_alc_db_scale),
971         WM8776_FIELD_CTL_ENUM("ALC Hold Time",
972                               WM8776_ALCCTRL2, 0, 0, 0, 15, 0xf,
973                               LC_CONTROL_ALC),
974         WM8776_BIT_SWITCH("Noise Gate Capture Switch",
975                           WM8776_NOISEGATE, WM8776_NGAT, 0,
976                           LC_CONTROL_ALC),
977         WM8776_FIELD_CTL_VOLUME("Noise Gate Threshold",
978                                 WM8776_NOISEGATE, 2, 0, 0, 7, 0x7,
979                                 LC_CONTROL_ALC, wm8776_ngth_db_scale),
980 };
981
982 static int xonar_ds_control_filter(struct snd_kcontrol_new *template)
983 {
984         if (!strncmp(template->name, "CD Capture ", 11))
985                 return 1; /* no CD input */
986         return 0;
987 }
988
989 static int xonar_ds_mixer_init(struct oxygen *chip)
990 {
991         struct xonar_wm87x6 *data = chip->model_data;
992         unsigned int i;
993         struct snd_kcontrol *ctl;
994         int err;
995
996         for (i = 0; i < ARRAY_SIZE(ds_controls); ++i) {
997                 ctl = snd_ctl_new1(&ds_controls[i], chip);
998                 if (!ctl)
999                         return -ENOMEM;
1000                 err = snd_ctl_add(chip->card, ctl);
1001                 if (err < 0)
1002                         return err;
1003                 if (!strcmp(ctl->id.name, "Line Capture Switch"))
1004                         data->line_adcmux_control = ctl;
1005                 else if (!strcmp(ctl->id.name, "Mic Capture Switch"))
1006                         data->mic_adcmux_control = ctl;
1007         }
1008         if (!data->line_adcmux_control || !data->mic_adcmux_control)
1009                 return -ENXIO;
1010         BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls));
1011         for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) {
1012                 ctl = snd_ctl_new1(&lc_controls[i], chip);
1013                 if (!ctl)
1014                         return -ENOMEM;
1015                 err = snd_ctl_add(chip->card, ctl);
1016                 if (err < 0)
1017                         return err;
1018                 data->lc_controls[i] = ctl;
1019         }
1020         return 0;
1021 }
1022
1023 static const struct oxygen_model model_xonar_ds = {
1024         .shortname = "Xonar DS",
1025         .longname = "Asus Virtuoso 200",
1026         .chip = "AV200",
1027         .init = xonar_ds_init,
1028         .control_filter = xonar_ds_control_filter,
1029         .mixer_init = xonar_ds_mixer_init,
1030         .cleanup = xonar_ds_cleanup,
1031         .suspend = xonar_ds_suspend,
1032         .resume = xonar_ds_resume,
1033         .pcm_hardware_filter = wm8776_adc_hardware_filter,
1034         .get_i2s_mclk = oxygen_default_i2s_mclk,
1035         .set_dac_params = set_wm87x6_dac_params,
1036         .set_adc_params = set_wm8776_adc_params,
1037         .update_dac_volume = update_wm87x6_volume,
1038         .update_dac_mute = update_wm87x6_mute,
1039         .gpio_changed = xonar_ds_gpio_changed,
1040         .dac_tlv = wm87x6_dac_db_scale,
1041         .model_data_size = sizeof(struct xonar_wm87x6),
1042         .device_config = PLAYBACK_0_TO_I2S |
1043                          PLAYBACK_1_TO_SPDIF |
1044                          CAPTURE_0_FROM_I2S_1,
1045         .dac_channels = 8,
1046         .dac_volume_min = 255 - 2*60,
1047         .dac_volume_max = 255,
1048         .function_flags = OXYGEN_FUNCTION_SPI,
1049         .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1050         .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1051 };
1052
1053 int __devinit get_xonar_wm87x6_model(struct oxygen *chip,
1054                                      const struct pci_device_id *id)
1055 {
1056         switch (id->subdevice) {
1057         case 0x838e:
1058                 chip->model = model_xonar_ds;
1059                 break;
1060         default:
1061                 return -EINVAL;
1062         }
1063         return 0;
1064 }