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