ALSA: virtuoso: add Xonar DS headphone jack detection
[deliverable/linux.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 }
This page took 0.070723 seconds and 5 git commands to generate.