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