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