1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45#include <asm/io.h>
46#include <linux/delay.h>
47#include <linux/interrupt.h>
48#include <linux/init.h>
49#include <linux/slab.h>
50#include <linux/mutex.h>
51
52#include <sound/core.h>
53
54#include "ice1712.h"
55#include "envy24ht.h"
56#include "phase.h"
57#include <sound/tlv.h>
58
59
60struct phase28_spec {
61 unsigned short master[2];
62 unsigned short vol[8];
63};
64
65
66#define WM_DAC_ATTEN 0x00
67#define WM_DAC_MASTER_ATTEN 0x08
68#define WM_DAC_DIG_ATTEN 0x09
69#define WM_DAC_DIG_MASTER_ATTEN 0x11
70#define WM_PHASE_SWAP 0x12
71#define WM_DAC_CTRL1 0x13
72#define WM_MUTE 0x14
73#define WM_DAC_CTRL2 0x15
74#define WM_INT_CTRL 0x16
75#define WM_MASTER 0x17
76#define WM_POWERDOWN 0x18
77#define WM_ADC_GAIN 0x19
78#define WM_ADC_MUX 0x1b
79#define WM_OUT_MUX1 0x1c
80#define WM_OUT_MUX2 0x1e
81#define WM_RESET 0x1f
82
83
84
85
86
87
88static const unsigned char wm_vol[256] = {
89 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24,
90 24, 23, 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18,
91 17, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14,
92 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11,
93 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9,
94 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
95 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5,
96 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
97 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
98 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
99 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
100 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
101};
102
103#define WM_VOL_MAX (sizeof(wm_vol) - 1)
104#define WM_VOL_MUTE 0x8000
105
106static struct snd_akm4xxx akm_phase22 __devinitdata = {
107 .type = SND_AK4524,
108 .num_dacs = 2,
109 .num_adcs = 2,
110};
111
112static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = {
113 .caddr = 2,
114 .cif = 1,
115 .data_mask = 1 << 4,
116 .clk_mask = 1 << 5,
117 .cs_mask = 1 << 10,
118 .cs_addr = 1 << 10,
119 .cs_none = 0,
120 .add_flags = 1 << 3,
121 .mask_flags = 0,
122};
123
124static int __devinit phase22_init(struct snd_ice1712 *ice)
125{
126 struct snd_akm4xxx *ak;
127 int err;
128
129
130 switch (ice->eeprom.subvendor) {
131 case VT1724_SUBDEVICE_PHASE22:
132 case VT1724_SUBDEVICE_TS22:
133 ice->num_total_dacs = 2;
134 ice->num_total_adcs = 2;
135 ice->vt1720 = 1;
136 break;
137 default:
138 snd_BUG();
139 return -EINVAL;
140 }
141
142
143 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
144 ak = ice->akm;
145 if (!ak)
146 return -ENOMEM;
147 ice->akm_codecs = 1;
148 switch (ice->eeprom.subvendor) {
149 case VT1724_SUBDEVICE_PHASE22:
150 case VT1724_SUBDEVICE_TS22:
151 err = snd_ice1712_akm4xxx_init(ak, &akm_phase22,
152 &akm_phase22_priv, ice);
153 if (err < 0)
154 return err;
155 break;
156 }
157
158 return 0;
159}
160
161static int __devinit phase22_add_controls(struct snd_ice1712 *ice)
162{
163 int err = 0;
164
165 switch (ice->eeprom.subvendor) {
166 case VT1724_SUBDEVICE_PHASE22:
167 case VT1724_SUBDEVICE_TS22:
168 err = snd_ice1712_akm4xxx_build_controls(ice);
169 if (err < 0)
170 return err;
171 }
172 return 0;
173}
174
175static unsigned char phase22_eeprom[] __devinitdata = {
176 [ICE_EEP2_SYSCONF] = 0x28,
177
178 [ICE_EEP2_ACLINK] = 0x80,
179 [ICE_EEP2_I2S] = 0xf0,
180 [ICE_EEP2_SPDIF] = 0xc3,
181 [ICE_EEP2_GPIO_DIR] = 0xff,
182 [ICE_EEP2_GPIO_DIR1] = 0xff,
183 [ICE_EEP2_GPIO_DIR2] = 0xff,
184 [ICE_EEP2_GPIO_MASK] = 0x00,
185 [ICE_EEP2_GPIO_MASK1] = 0x00,
186 [ICE_EEP2_GPIO_MASK2] = 0x00,
187 [ICE_EEP2_GPIO_STATE] = 0x00,
188 [ICE_EEP2_GPIO_STATE1] = 0x00,
189 [ICE_EEP2_GPIO_STATE2] = 0x00,
190};
191
192static unsigned char phase28_eeprom[] __devinitdata = {
193 [ICE_EEP2_SYSCONF] = 0x2b,
194
195 [ICE_EEP2_ACLINK] = 0x80,
196 [ICE_EEP2_I2S] = 0xfc,
197 [ICE_EEP2_SPDIF] = 0xc3,
198 [ICE_EEP2_GPIO_DIR] = 0xff,
199 [ICE_EEP2_GPIO_DIR1] = 0xff,
200 [ICE_EEP2_GPIO_DIR2] = 0x5f,
201 [ICE_EEP2_GPIO_MASK] = 0x00,
202 [ICE_EEP2_GPIO_MASK1] = 0x00,
203 [ICE_EEP2_GPIO_MASK2] = 0x00,
204 [ICE_EEP2_GPIO_STATE] = 0x00,
205 [ICE_EEP2_GPIO_STATE1] = 0x00,
206 [ICE_EEP2_GPIO_STATE2] = 0x00,
207};
208
209
210
211
212static void phase28_spi_write(struct snd_ice1712 *ice, unsigned int cs,
213 unsigned int data, int bits)
214{
215 unsigned int tmp;
216 int i;
217
218 tmp = snd_ice1712_gpio_read(ice);
219
220 snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RW|PHASE28_SPI_MOSI|
221 PHASE28_SPI_CLK|PHASE28_WM_CS));
222 tmp |= PHASE28_WM_RW;
223 tmp &= ~cs;
224 snd_ice1712_gpio_write(ice, tmp);
225 udelay(1);
226
227 for (i = bits - 1; i >= 0; i--) {
228 tmp &= ~PHASE28_SPI_CLK;
229 snd_ice1712_gpio_write(ice, tmp);
230 udelay(1);
231 if (data & (1 << i))
232 tmp |= PHASE28_SPI_MOSI;
233 else
234 tmp &= ~PHASE28_SPI_MOSI;
235 snd_ice1712_gpio_write(ice, tmp);
236 udelay(1);
237 tmp |= PHASE28_SPI_CLK;
238 snd_ice1712_gpio_write(ice, tmp);
239 udelay(1);
240 }
241
242 tmp &= ~PHASE28_SPI_CLK;
243 tmp |= cs;
244 snd_ice1712_gpio_write(ice, tmp);
245 udelay(1);
246 tmp |= PHASE28_SPI_CLK;
247 snd_ice1712_gpio_write(ice, tmp);
248 udelay(1);
249}
250
251
252
253
254static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
255{
256 reg <<= 1;
257 return ((unsigned short)ice->akm[0].images[reg] << 8) |
258 ice->akm[0].images[reg + 1];
259}
260
261
262
263
264static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
265{
266 phase28_spi_write(ice, PHASE28_WM_CS, (reg << 9) | (val & 0x1ff), 16);
267}
268
269
270
271
272static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
273{
274 wm_put_nocache(ice, reg, val);
275 reg <<= 1;
276 ice->akm[0].images[reg] = val >> 8;
277 ice->akm[0].images[reg + 1] = val;
278}
279
280static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index,
281 unsigned short vol, unsigned short master)
282{
283 unsigned char nvol;
284
285 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
286 nvol = 0;
287 else
288 nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) *
289 (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
290
291 wm_put(ice, index, nvol);
292 wm_put_nocache(ice, index, 0x180 | nvol);
293}
294
295
296
297
298#define wm_pcm_mute_info snd_ctl_boolean_mono_info
299
300static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol,
301 struct snd_ctl_elem_value *ucontrol)
302{
303 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
304
305 mutex_lock(&ice->gpio_mutex);
306 ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ?
307 0 : 1;
308 mutex_unlock(&ice->gpio_mutex);
309 return 0;
310}
311
312static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol,
313 struct snd_ctl_elem_value *ucontrol)
314{
315 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
316 unsigned short nval, oval;
317 int change;
318
319 snd_ice1712_save_gpio_status(ice);
320 oval = wm_get(ice, WM_MUTE);
321 nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
322 change = (nval != oval);
323 if (change)
324 wm_put(ice, WM_MUTE, nval);
325 snd_ice1712_restore_gpio_status(ice);
326
327 return change;
328}
329
330
331
332
333static int wm_master_vol_info(struct snd_kcontrol *kcontrol,
334 struct snd_ctl_elem_info *uinfo)
335{
336 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
337 uinfo->count = 2;
338 uinfo->value.integer.min = 0;
339 uinfo->value.integer.max = WM_VOL_MAX;
340 return 0;
341}
342
343static int wm_master_vol_get(struct snd_kcontrol *kcontrol,
344 struct snd_ctl_elem_value *ucontrol)
345{
346 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
347 struct phase28_spec *spec = ice->spec;
348 int i;
349 for (i = 0; i < 2; i++)
350 ucontrol->value.integer.value[i] = spec->master[i] &
351 ~WM_VOL_MUTE;
352 return 0;
353}
354
355static int wm_master_vol_put(struct snd_kcontrol *kcontrol,
356 struct snd_ctl_elem_value *ucontrol)
357{
358 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
359 struct phase28_spec *spec = ice->spec;
360 int ch, change = 0;
361
362 snd_ice1712_save_gpio_status(ice);
363 for (ch = 0; ch < 2; ch++) {
364 unsigned int vol = ucontrol->value.integer.value[ch];
365 if (vol > WM_VOL_MAX)
366 continue;
367 vol |= spec->master[ch] & WM_VOL_MUTE;
368 if (vol != spec->master[ch]) {
369 int dac;
370 spec->master[ch] = vol;
371 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
372 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
373 spec->vol[dac + ch],
374 spec->master[ch]);
375 change = 1;
376 }
377 }
378 snd_ice1712_restore_gpio_status(ice);
379 return change;
380}
381
382static int __devinit phase28_init(struct snd_ice1712 *ice)
383{
384 static const unsigned short wm_inits_phase28[] = {
385
386 0x1b, 0x044,
387 0x1c, 0x00B,
388 0x1d, 0x009,
389
390 0x18, 0x000,
391
392 0x16, 0x122,
393 0x17, 0x022,
394 0x00, 0,
395 0x01, 0,
396 0x02, 0,
397 0x03, 0,
398 0x04, 0,
399 0x05, 0,
400 0x06, 0,
401 0x07, 0,
402 0x08, 0x100,
403 0x09, 0xff,
404 0x0a, 0xff,
405 0x0b, 0xff,
406 0x0c, 0xff,
407 0x0d, 0xff,
408 0x0e, 0xff,
409 0x0f, 0xff,
410 0x10, 0xff,
411 0x11, 0x1ff,
412 0x12, 0x000,
413 0x13, 0x090,
414 0x14, 0x000,
415 0x15, 0x000,
416 0x19, 0x000,
417 0x1a, 0x000,
418 (unsigned short)-1
419 };
420
421 unsigned int tmp;
422 struct snd_akm4xxx *ak;
423 struct phase28_spec *spec;
424 const unsigned short *p;
425 int i;
426
427 ice->num_total_dacs = 8;
428 ice->num_total_adcs = 2;
429
430 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
431 if (!spec)
432 return -ENOMEM;
433 ice->spec = spec;
434
435
436 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
437 ak = ice->akm;
438 if (!ak)
439 return -ENOMEM;
440 ice->akm_codecs = 1;
441
442 snd_ice1712_gpio_set_dir(ice, 0x5fffff);
443
444
445 snd_ice1712_save_gpio_status(ice);
446 snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS|
447 PHASE28_HP_SEL));
448
449 tmp = snd_ice1712_gpio_read(ice);
450 tmp &= ~PHASE28_WM_RESET;
451 snd_ice1712_gpio_write(ice, tmp);
452 udelay(1);
453 tmp |= PHASE28_WM_CS;
454 snd_ice1712_gpio_write(ice, tmp);
455 udelay(1);
456 tmp |= PHASE28_WM_RESET;
457 snd_ice1712_gpio_write(ice, tmp);
458 udelay(1);
459
460 p = wm_inits_phase28;
461 for (; *p != (unsigned short)-1; p += 2)
462 wm_put(ice, p[0], p[1]);
463
464 snd_ice1712_restore_gpio_status(ice);
465
466 spec->master[0] = WM_VOL_MUTE;
467 spec->master[1] = WM_VOL_MUTE;
468 for (i = 0; i < ice->num_total_dacs; i++) {
469 spec->vol[i] = WM_VOL_MUTE;
470 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
471 }
472
473 return 0;
474}
475
476
477
478
479static int wm_vol_info(struct snd_kcontrol *kcontrol,
480 struct snd_ctl_elem_info *uinfo)
481{
482 int voices = kcontrol->private_value >> 8;
483 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
484 uinfo->count = voices;
485 uinfo->value.integer.min = 0;
486 uinfo->value.integer.max = 0x7F;
487 return 0;
488}
489
490static int wm_vol_get(struct snd_kcontrol *kcontrol,
491 struct snd_ctl_elem_value *ucontrol)
492{
493 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
494 struct phase28_spec *spec = ice->spec;
495 int i, ofs, voices;
496
497 voices = kcontrol->private_value >> 8;
498 ofs = kcontrol->private_value & 0xff;
499 for (i = 0; i < voices; i++)
500 ucontrol->value.integer.value[i] =
501 spec->vol[ofs+i] & ~WM_VOL_MUTE;
502 return 0;
503}
504
505static int wm_vol_put(struct snd_kcontrol *kcontrol,
506 struct snd_ctl_elem_value *ucontrol)
507{
508 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
509 struct phase28_spec *spec = ice->spec;
510 int i, idx, ofs, voices;
511 int change = 0;
512
513 voices = kcontrol->private_value >> 8;
514 ofs = kcontrol->private_value & 0xff;
515 snd_ice1712_save_gpio_status(ice);
516 for (i = 0; i < voices; i++) {
517 unsigned int vol;
518 vol = ucontrol->value.integer.value[i];
519 if (vol > 0x7f)
520 continue;
521 vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
522 if (vol != spec->vol[ofs+i]) {
523 spec->vol[ofs+i] = vol;
524 idx = WM_DAC_ATTEN + ofs + i;
525 wm_set_vol(ice, idx, spec->vol[ofs+i],
526 spec->master[i]);
527 change = 1;
528 }
529 }
530 snd_ice1712_restore_gpio_status(ice);
531 return change;
532}
533
534
535
536
537static int wm_mute_info(struct snd_kcontrol *kcontrol,
538 struct snd_ctl_elem_info *uinfo) {
539 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
540 uinfo->count = kcontrol->private_value >> 8;
541 uinfo->value.integer.min = 0;
542 uinfo->value.integer.max = 1;
543 return 0;
544}
545
546static int wm_mute_get(struct snd_kcontrol *kcontrol,
547 struct snd_ctl_elem_value *ucontrol)
548{
549 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
550 struct phase28_spec *spec = ice->spec;
551 int voices, ofs, i;
552
553 voices = kcontrol->private_value >> 8;
554 ofs = kcontrol->private_value & 0xFF;
555
556 for (i = 0; i < voices; i++)
557 ucontrol->value.integer.value[i] =
558 (spec->vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
559 return 0;
560}
561
562static int wm_mute_put(struct snd_kcontrol *kcontrol,
563 struct snd_ctl_elem_value *ucontrol)
564{
565 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
566 struct phase28_spec *spec = ice->spec;
567 int change = 0, voices, ofs, i;
568
569 voices = kcontrol->private_value >> 8;
570 ofs = kcontrol->private_value & 0xFF;
571
572 snd_ice1712_save_gpio_status(ice);
573 for (i = 0; i < voices; i++) {
574 int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
575 if (ucontrol->value.integer.value[i] != val) {
576 spec->vol[ofs + i] &= ~WM_VOL_MUTE;
577 spec->vol[ofs + i] |=
578 ucontrol->value.integer.value[i] ? 0 :
579 WM_VOL_MUTE;
580 wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
581 spec->master[i]);
582 change = 1;
583 }
584 }
585 snd_ice1712_restore_gpio_status(ice);
586
587 return change;
588}
589
590
591
592
593#define wm_master_mute_info snd_ctl_boolean_stereo_info
594
595static int wm_master_mute_get(struct snd_kcontrol *kcontrol,
596 struct snd_ctl_elem_value *ucontrol)
597{
598 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
599 struct phase28_spec *spec = ice->spec;
600
601 ucontrol->value.integer.value[0] =
602 (spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
603 ucontrol->value.integer.value[1] =
604 (spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
605 return 0;
606}
607
608static int wm_master_mute_put(struct snd_kcontrol *kcontrol,
609 struct snd_ctl_elem_value *ucontrol)
610{
611 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
612 struct phase28_spec *spec = ice->spec;
613 int change = 0, i;
614
615 snd_ice1712_save_gpio_status(ice);
616 for (i = 0; i < 2; i++) {
617 int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
618 if (ucontrol->value.integer.value[i] != val) {
619 int dac;
620 spec->master[i] &= ~WM_VOL_MUTE;
621 spec->master[i] |=
622 ucontrol->value.integer.value[i] ? 0 :
623 WM_VOL_MUTE;
624 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
625 wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
626 spec->vol[dac + i],
627 spec->master[i]);
628 change = 1;
629 }
630 }
631 snd_ice1712_restore_gpio_status(ice);
632
633 return change;
634}
635
636
637#define PCM_0dB 0xff
638#define PCM_RES 128
639#define PCM_MIN (PCM_0dB - PCM_RES)
640static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol,
641 struct snd_ctl_elem_info *uinfo)
642{
643 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
644 uinfo->count = 1;
645 uinfo->value.integer.min = 0;
646 uinfo->value.integer.max = PCM_RES;
647 return 0;
648}
649
650static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol,
651 struct snd_ctl_elem_value *ucontrol)
652{
653 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
654 unsigned short val;
655
656 mutex_lock(&ice->gpio_mutex);
657 val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
658 val = val > PCM_MIN ? (val - PCM_MIN) : 0;
659 ucontrol->value.integer.value[0] = val;
660 mutex_unlock(&ice->gpio_mutex);
661 return 0;
662}
663
664static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol,
665 struct snd_ctl_elem_value *ucontrol)
666{
667 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
668 unsigned short ovol, nvol;
669 int change = 0;
670
671 nvol = ucontrol->value.integer.value[0];
672 if (nvol > PCM_RES)
673 return -EINVAL;
674 snd_ice1712_save_gpio_status(ice);
675 nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
676 ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
677 if (ovol != nvol) {
678 wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol);
679
680 wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100);
681 change = 1;
682 }
683 snd_ice1712_restore_gpio_status(ice);
684 return change;
685}
686
687
688
689
690#define phase28_deemp_info snd_ctl_boolean_mono_info
691
692static int phase28_deemp_get(struct snd_kcontrol *kcontrol,
693 struct snd_ctl_elem_value *ucontrol)
694{
695 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
696 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) ==
697 0xf;
698 return 0;
699}
700
701static int phase28_deemp_put(struct snd_kcontrol *kcontrol,
702 struct snd_ctl_elem_value *ucontrol)
703{
704 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
705 int temp, temp2;
706 temp = wm_get(ice, WM_DAC_CTRL2);
707 temp2 = temp;
708 if (ucontrol->value.integer.value[0])
709 temp |= 0xf;
710 else
711 temp &= ~0xf;
712 if (temp != temp2) {
713 wm_put(ice, WM_DAC_CTRL2, temp);
714 return 1;
715 }
716 return 0;
717}
718
719
720
721
722static int phase28_oversampling_info(struct snd_kcontrol *k,
723 struct snd_ctl_elem_info *uinfo)
724{
725 static char *texts[2] = { "128x", "64x" };
726
727 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
728 uinfo->count = 1;
729 uinfo->value.enumerated.items = 2;
730
731 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
732 uinfo->value.enumerated.item = uinfo->value.enumerated.items -
733 1;
734 strcpy(uinfo->value.enumerated.name,
735 texts[uinfo->value.enumerated.item]);
736
737 return 0;
738}
739
740static int phase28_oversampling_get(struct snd_kcontrol *kcontrol,
741 struct snd_ctl_elem_value *ucontrol)
742{
743 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
744 ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) ==
745 0x8;
746 return 0;
747}
748
749static int phase28_oversampling_put(struct snd_kcontrol *kcontrol,
750 struct snd_ctl_elem_value *ucontrol)
751{
752 int temp, temp2;
753 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
754
755 temp = wm_get(ice, WM_MASTER);
756 temp2 = temp;
757
758 if (ucontrol->value.enumerated.item[0])
759 temp |= 0x8;
760 else
761 temp &= ~0x8;
762
763 if (temp != temp2) {
764 wm_put(ice, WM_MASTER, temp);
765 return 1;
766 }
767 return 0;
768}
769
770static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
771static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
772
773static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = {
774 {
775 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
776 .name = "Master Playback Switch",
777 .info = wm_master_mute_info,
778 .get = wm_master_mute_get,
779 .put = wm_master_mute_put
780 },
781 {
782 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
783 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
784 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
785 .name = "Master Playback Volume",
786 .info = wm_master_vol_info,
787 .get = wm_master_vol_get,
788 .put = wm_master_vol_put,
789 .tlv = { .p = db_scale_wm_dac }
790 },
791 {
792 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
793 .name = "Front Playback Switch",
794 .info = wm_mute_info,
795 .get = wm_mute_get,
796 .put = wm_mute_put,
797 .private_value = (2 << 8) | 0
798 },
799 {
800 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
801 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
802 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
803 .name = "Front Playback Volume",
804 .info = wm_vol_info,
805 .get = wm_vol_get,
806 .put = wm_vol_put,
807 .private_value = (2 << 8) | 0,
808 .tlv = { .p = db_scale_wm_dac }
809 },
810 {
811 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
812 .name = "Rear Playback Switch",
813 .info = wm_mute_info,
814 .get = wm_mute_get,
815 .put = wm_mute_put,
816 .private_value = (2 << 8) | 2
817 },
818 {
819 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
820 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
821 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
822 .name = "Rear Playback Volume",
823 .info = wm_vol_info,
824 .get = wm_vol_get,
825 .put = wm_vol_put,
826 .private_value = (2 << 8) | 2,
827 .tlv = { .p = db_scale_wm_dac }
828 },
829 {
830 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
831 .name = "Center Playback Switch",
832 .info = wm_mute_info,
833 .get = wm_mute_get,
834 .put = wm_mute_put,
835 .private_value = (1 << 8) | 4
836 },
837 {
838 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
839 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
840 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
841 .name = "Center Playback Volume",
842 .info = wm_vol_info,
843 .get = wm_vol_get,
844 .put = wm_vol_put,
845 .private_value = (1 << 8) | 4,
846 .tlv = { .p = db_scale_wm_dac }
847 },
848 {
849 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
850 .name = "LFE Playback Switch",
851 .info = wm_mute_info,
852 .get = wm_mute_get,
853 .put = wm_mute_put,
854 .private_value = (1 << 8) | 5
855 },
856 {
857 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
858 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
859 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
860 .name = "LFE Playback Volume",
861 .info = wm_vol_info,
862 .get = wm_vol_get,
863 .put = wm_vol_put,
864 .private_value = (1 << 8) | 5,
865 .tlv = { .p = db_scale_wm_dac }
866 },
867 {
868 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
869 .name = "Side Playback Switch",
870 .info = wm_mute_info,
871 .get = wm_mute_get,
872 .put = wm_mute_put,
873 .private_value = (2 << 8) | 6
874 },
875 {
876 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
877 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
878 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
879 .name = "Side Playback Volume",
880 .info = wm_vol_info,
881 .get = wm_vol_get,
882 .put = wm_vol_put,
883 .private_value = (2 << 8) | 6,
884 .tlv = { .p = db_scale_wm_dac }
885 }
886};
887
888static struct snd_kcontrol_new wm_controls[] __devinitdata = {
889 {
890 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
891 .name = "PCM Playback Switch",
892 .info = wm_pcm_mute_info,
893 .get = wm_pcm_mute_get,
894 .put = wm_pcm_mute_put
895 },
896 {
897 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
898 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
899 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
900 .name = "PCM Playback Volume",
901 .info = wm_pcm_vol_info,
902 .get = wm_pcm_vol_get,
903 .put = wm_pcm_vol_put,
904 .tlv = { .p = db_scale_wm_pcm }
905 },
906 {
907 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
908 .name = "DAC Deemphasis Switch",
909 .info = phase28_deemp_info,
910 .get = phase28_deemp_get,
911 .put = phase28_deemp_put
912 },
913 {
914 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
915 .name = "ADC Oversampling",
916 .info = phase28_oversampling_info,
917 .get = phase28_oversampling_get,
918 .put = phase28_oversampling_put
919 }
920};
921
922static int __devinit phase28_add_controls(struct snd_ice1712 *ice)
923{
924 unsigned int i, counts;
925 int err;
926
927 counts = ARRAY_SIZE(phase28_dac_controls);
928 for (i = 0; i < counts; i++) {
929 err = snd_ctl_add(ice->card,
930 snd_ctl_new1(&phase28_dac_controls[i],
931 ice));
932 if (err < 0)
933 return err;
934 }
935
936 for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
937 err = snd_ctl_add(ice->card,
938 snd_ctl_new1(&wm_controls[i], ice));
939 if (err < 0)
940 return err;
941 }
942
943 return 0;
944}
945
946struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = {
947 {
948 .subvendor = VT1724_SUBDEVICE_PHASE22,
949 .name = "Terratec PHASE 22",
950 .model = "phase22",
951 .chip_init = phase22_init,
952 .build_controls = phase22_add_controls,
953 .eeprom_size = sizeof(phase22_eeprom),
954 .eeprom_data = phase22_eeprom,
955 },
956 {
957 .subvendor = VT1724_SUBDEVICE_PHASE28,
958 .name = "Terratec PHASE 28",
959 .model = "phase28",
960 .chip_init = phase28_init,
961 .build_controls = phase28_add_controls,
962 .eeprom_size = sizeof(phase28_eeprom),
963 .eeprom_data = phase28_eeprom,
964 },
965 {
966 .subvendor = VT1724_SUBDEVICE_TS22,
967 .name = "Terrasoniq TS22 PCI",
968 .model = "TS22",
969 .chip_init = phase22_init,
970 .build_controls = phase22_add_controls,
971 .eeprom_size = sizeof(phase22_eeprom),
972 .eeprom_data = phase22_eeprom,
973 },
974 { }
975};
976