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