| Linux kernel & device driver programming |
| [ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] |
1 /* 1
2 * ALSA driver for ICEnsemble ICE1724 (Envy2
3 *
4 * Lowlevel functions for Terratec PHASE 22
5 *
6 * Copyright (c) 2005 Misha Zhilin <misha
7 *
8 * This program is free software; you can re
9 * it under the terms of the GNU General Pub
10 * the Free Software Foundation; either vers
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope t
14 * but WITHOUT ANY WARRANTY; without even th
15 * MERCHANTABILITY or FITNESS FOR A PARTICUL
16 * GNU General Public License for more detai
17 *
18 * You should have received a copy of the GN
19 * along with this program; if not, write to
20 * Foundation, Inc., 59 Temple Place, Suite
21 *
22 */
23
24 /* PHASE 22 overview:
25 * Audio controller: VIA Envy24HT-S (slightl
26 * Analog chip: AK4524 (partially via Philip
27 * Digital receiver: CS8414-CS (supported in
28 * PHASE 22 revision 2.0 and Terr
29 * (support status unknown, pleas
30 *
31 * Envy connects to AK4524
32 * - CS directly from GPIO 10
33 * - CCLK via 74HCT125's gate #4 from GPI
34 * - CDTI via 74HCT125's gate #2 from GPI
35 * CDTI may be completely blocked
36 * controlled by GPIO 3
37 */
38
39 /* PHASE 28 overview:
40 * Audio controller: VIA Envy24HT (full untr
41 * Analog chip: WM8770 (8 channel 192k DAC,
42 * Digital receiver: CS8414-CS (supported in
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 /* AC97 register cache for Phase28 */
60 struct phase28_spec {
61 unsigned short master[2];
62 unsigned short vol[8];
63 };
64
65 /* WM8770 registers */
66 #define WM_DAC_ATTEN 0x00 /* DAC
67 #define WM_DAC_MASTER_ATTEN 0x08 /* DAC
68 #define WM_DAC_DIG_ATTEN 0x09 /* DAC
69 #define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC
70 #define WM_PHASE_SWAP 0x12 /* DAC
71 #define WM_DAC_CTRL1 0x13 /* DAC
72 #define WM_MUTE 0x14 /* mut
73 #define WM_DAC_CTRL2 0x15 /* de-
74 #define WM_INT_CTRL 0x16 /* int
75 #define WM_MASTER 0x17 /* mas
76 #define WM_POWERDOWN 0x18 /* pow
77 #define WM_ADC_GAIN 0x19 /* ADC
78 #define WM_ADC_MUX 0x1b /* inp
79 #define WM_OUT_MUX1 0x1c /* out
80 #define WM_OUT_MUX2 0x1e /* out
81 #define WM_RESET 0x1f /* sof
82
83
84 /*
85 * Logarithmic volume values for WM8770
86 * Computed as 20 * Log10(255 / x)
87 */
88 static const unsigned char wm_vol[256] = {
89 127, 48, 42, 39, 36, 34, 33, 31, 30, 2
90 24, 23, 23, 22, 22, 21, 21, 21, 20, 20
91 17, 17, 17, 17, 16, 16, 16, 16, 15, 15
92 14, 13, 13, 13, 13, 13, 13, 13, 12, 12
93 11, 11, 11, 11, 11, 11, 10, 10, 10, 10
94 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8,
95 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6,
96 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
97 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3,
98 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2,
99 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
100 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
101 };
102
103 #define WM_VOL_MAX (sizeof(wm_vol) - 1)
104 #define WM_VOL_MUTE 0x8000
105
106 static struct snd_akm4xxx akm_phase22 __devini
107 .type = SND_AK4524,
108 .num_dacs = 2,
109 .num_adcs = 2,
110 };
111
112 static struct snd_ak4xxx_private akm_phase22_p
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
124 static int __devinit phase22_init(struct snd_i
125 {
126 struct snd_akm4xxx *ak;
127 int err;
128
129 /* Configure DAC/ADC description for g
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; /* Envy24HT-S
136 break;
137 default:
138 snd_BUG();
139 return -EINVAL;
140 }
141
142 /* Initialize analog chips */
143 ice->akm = kzalloc(sizeof(struct snd_a
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
152
153 if (err < 0)
154 return err;
155 break;
156 }
157
158 return 0;
159 }
160
161 static int __devinit phase22_add_controls(stru
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_buil
169 if (err < 0)
170 return err;
171 }
172 return 0;
173 }
174
175 static unsigned char phase22_eeprom[] __devini
176 [ICE_EEP2_SYSCONF] = 0x28, /* clo
177 spdif-
178 [ICE_EEP2_ACLINK] = 0x80, /* I2S
179 [ICE_EEP2_I2S] = 0xf0, /* vol
180 [ICE_EEP2_SPDIF] = 0xc3, /* out
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
192 static unsigned char phase28_eeprom[] __devini
193 [ICE_EEP2_SYSCONF] = 0x2b, /* clo
194 spdif-
195 [ICE_EEP2_ACLINK] = 0x80, /* I2S
196 [ICE_EEP2_I2S] = 0xfc, /* vol
197 [ICE_EEP2_SPDIF] = 0xc3, /* out
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 * write data in the SPI mode
211 */
212 static void phase28_spi_write(struct snd_ice17
213 unsigned int d
214 {
215 unsigned int tmp;
216 int i;
217
218 tmp = snd_ice1712_gpio_read(ice);
219
220 snd_ice1712_gpio_set_mask(ice, ~(PHASE
221 PHASE2
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, tm
230 udelay(1);
231 if (data & (1 << i))
232 tmp |= PHASE28_SPI_MOS
233 else
234 tmp &= ~PHASE28_SPI_MO
235 snd_ice1712_gpio_write(ice, tm
236 udelay(1);
237 tmp |= PHASE28_SPI_CLK;
238 snd_ice1712_gpio_write(ice, tm
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 * get the current register value of WM codec
253 */
254 static unsigned short wm_get(struct snd_ice171
255 {
256 reg <<= 1;
257 return ((unsigned short)ice->akm[0].im
258 ice->akm[0].images[reg + 1];
259 }
260
261 /*
262 * set the register value of WM codec
263 */
264 static void wm_put_nocache(struct snd_ice1712
265 {
266 phase28_spi_write(ice, PHASE28_WM_CS,
267 }
268
269 /*
270 * set the register value of WM codec and reme
271 */
272 static void wm_put(struct snd_ice1712 *ice, in
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
280 static void wm_set_vol(struct snd_ice1712 *ice
281 unsigned short vol, un
282 {
283 unsigned char nvol;
284
285 if ((master & WM_VOL_MUTE) || (vol & W
286 nvol = 0;
287 else
288 nvol = 127 - wm_vol[(((vol & ~
289 (master & ~WM_VOL_MUTE
290
291 wm_put(ice, index, nvol);
292 wm_put_nocache(ice, index, 0x180 | nvo
293 }
294
295 /*
296 * DAC mute control
297 */
298 #define wm_pcm_mute_info snd_ctl_boolea
299
300 static int wm_pcm_mute_get(struct snd_kcontrol
301 struct snd_ctl
302 {
303 struct snd_ice1712 *ice = snd_kcontrol
304
305 mutex_lock(&ice->gpio_mutex);
306 ucontrol->value.integer.value[0] = (wm
307
308 mutex_unlock(&ice->gpio_mutex);
309 return 0;
310 }
311
312 static int wm_pcm_mute_put(struct snd_kcontrol
313 struct snd_ctl
314 {
315 struct snd_ice1712 *ice = snd_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->val
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 * Master volume attenuation mixer control
332 */
333 static int wm_master_vol_info(struct snd_kcont
334 struct snd_ctl
335 {
336 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTE
337 uinfo->count = 2;
338 uinfo->value.integer.min = 0;
339 uinfo->value.integer.max = WM_VOL_MAX;
340 return 0;
341 }
342
343 static int wm_master_vol_get(struct snd_kcontr
344 struct snd_ctl
345 {
346 struct snd_ice1712 *ice = snd_kcontrol
347 struct phase28_spec *spec = ice->spec;
348 int i;
349 for (i = 0; i < 2; i++)
350 ucontrol->value.integer.value[
351
352 return 0;
353 }
354
355 static int wm_master_vol_put(struct snd_kcontr
356 struct snd_ctl
357 {
358 struct snd_ice1712 *ice = snd_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->v
365 if (vol > WM_VOL_MAX)
366 continue;
367 vol |= spec->master[ch] & WM_V
368 if (vol != spec->master[ch]) {
369 int dac;
370 spec->master[ch] = vol
371 for (dac = 0; dac < ic
372 wm_set_vol(ice
373 spe
374 spe
375 change = 1;
376 }
377 }
378 snd_ice1712_restore_gpio_status(ice);
379 return change;
380 }
381
382 static int __devinit phase28_init(struct snd_i
383 {
384 static const unsigned short wm_inits_p
385 /* These come first to reduce
386 0x1b, 0x044, /* ADC Mux (AC
387 0x1c, 0x00B, /* Out Mux1 (V
388 0x1d, 0x009, /* Out Mux2 (V
389
390 0x18, 0x000, /* All power-u
391
392 0x16, 0x122, /* I2S, normal
393 0x17, 0x022, /* 256fs, slav
394 0x00, 0, /* DAC1 analog
395 0x01, 0, /* DAC2 analog
396 0x02, 0, /* DAC3 analog
397 0x03, 0, /* DAC4 analog
398 0x04, 0, /* DAC5 analog
399 0x05, 0, /* DAC6 analog
400 0x06, 0, /* DAC7 analog
401 0x07, 0, /* DAC8 analog
402 0x08, 0x100, /* master anal
403 0x09, 0xff, /* DAC1 digita
404 0x0a, 0xff, /* DAC2 digita
405 0x0b, 0xff, /* DAC3 digita
406 0x0c, 0xff, /* DAC4 digita
407 0x0d, 0xff, /* DAC5 digita
408 0x0e, 0xff, /* DAC6 digita
409 0x0f, 0xff, /* DAC7 digita
410 0x10, 0xff, /* DAC8 digita
411 0x11, 0x1ff, /* master digi
412 0x12, 0x000, /* phase norma
413 0x13, 0x090, /* unmute DAC
414 0x14, 0x000, /* all unmute
415 0x15, 0x000, /* no deemphas
416 0x19, 0x000, /* -12dB ADC/L
417 0x1a, 0x000, /* -12dB ADC/R
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_KERN
431 if (!spec)
432 return -ENOMEM;
433 ice->spec = spec;
434
435 /* Initialize analog chips */
436 ice->akm = kzalloc(sizeof(struct snd_a
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 /* reset the wm codec as the SPI mode
445 snd_ice1712_save_gpio_status(ice);
446 snd_ice1712_gpio_set_mask(ice, ~(PHASE
447 PHASE2
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 +=
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
471 }
472
473 return 0;
474 }
475
476 /*
477 * DAC volume attenuation mixer control
478 */
479 static int wm_vol_info(struct snd_kcontrol *kc
480 struct snd_ctl_elem_in
481 {
482 int voices = kcontrol->private_value >
483 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTE
484 uinfo->count = voices;
485 uinfo->value.integer.min = 0;
486 uinfo->value.integer.max = 0x7F;
487 return 0;
488 }
489
490 static int wm_vol_get(struct snd_kcontrol *kco
491 struct snd_ctl_elem_va
492 {
493 struct snd_ice1712 *ice = snd_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[
501 spec->vol[ofs+i] & ~WM
502 return 0;
503 }
504
505 static int wm_vol_put(struct snd_kcontrol *kco
506 struct snd_ctl_elem_va
507 {
508 struct snd_ice1712 *ice = snd_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.
519 if (vol > 0x7f)
520 continue;
521 vol |= spec->vol[ofs+i] & WM_V
522 if (vol != spec->vol[ofs+i]) {
523 spec->vol[ofs+i] = vol
524 idx = WM_DAC_ATTEN +
525 wm_set_vol(ice, idx, s
526 spec->maste
527 change = 1;
528 }
529 }
530 snd_ice1712_restore_gpio_status(ice);
531 return change;
532 }
533
534 /*
535 * WM8770 mute control
536 */
537 static int wm_mute_info(struct snd_kcontrol *k
538 struct snd_ctl_elem_in
539 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOL
540 uinfo->count = kcontrol->private_value
541 uinfo->value.integer.min = 0;
542 uinfo->value.integer.max = 1;
543 return 0;
544 }
545
546 static int wm_mute_get(struct snd_kcontrol *kc
547 struct snd_ctl_elem_va
548 {
549 struct snd_ice1712 *ice = snd_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[
558 (spec->vol[ofs+i] & WM
559 return 0;
560 }
561
562 static int wm_mute_put(struct snd_kcontrol *kc
563 struct snd_ctl_elem_va
564 {
565 struct snd_ice1712 *ice = snd_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]
575 if (ucontrol->value.integer.va
576 spec->vol[ofs + i] &=
577 spec->vol[ofs + i] |=
578 ucontrol->valu
579 WM_VOL_MUTE;
580 wm_set_vol(ice, ofs +
581 spec->
582 change = 1;
583 }
584 }
585 snd_ice1712_restore_gpio_status(ice);
586
587 return change;
588 }
589
590 /*
591 * WM8770 master mute control
592 */
593 #define wm_master_mute_info snd_ct
594
595 static int wm_master_mute_get(struct snd_kcont
596 struct snd_ctl
597 {
598 struct snd_ice1712 *ice = snd_kcontrol
599 struct phase28_spec *spec = ice->spec;
600
601 ucontrol->value.integer.value[0] =
602 (spec->master[0] & WM_VOL_MUTE
603 ucontrol->value.integer.value[1] =
604 (spec->master[1] & WM_VOL_MUTE
605 return 0;
606 }
607
608 static int wm_master_mute_put(struct snd_kcont
609 struct snd_ctl
610 {
611 struct snd_ice1712 *ice = snd_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] & W
618 if (ucontrol->value.integer.va
619 int dac;
620 spec->master[i] &= ~WM
621 spec->master[i] |=
622 ucontrol->valu
623 WM_VOL_MUTE;
624 for (dac = 0; dac < ic
625 wm_set_vol(ice
626
627
628 change = 1;
629 }
630 }
631 snd_ice1712_restore_gpio_status(ice);
632
633 return change;
634 }
635
636 /* digital master volume */
637 #define PCM_0dB 0xff
638 #define PCM_RES 128 /* -64dB */
639 #define PCM_MIN (PCM_0dB - PCM_RES)
640 static int wm_pcm_vol_info(struct snd_kcontrol
641 struct snd_ctl
642 {
643 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTE
644 uinfo->count = 1;
645 uinfo->value.integer.min = 0;
646 uinfo->value.integer.max = PCM_RES;
647 return 0;
648 }
649
650 static int wm_pcm_vol_get(struct snd_kcontrol
651 struct snd_ctl
652 {
653 struct snd_ice1712 *ice = snd_kcontrol
654 unsigned short val;
655
656 mutex_lock(&ice->gpio_mutex);
657 val = wm_get(ice, WM_DAC_DIG_MASTER_AT
658 val = val > PCM_MIN ? (val - PCM_MIN)
659 ucontrol->value.integer.value[0] = val
660 mutex_unlock(&ice->gpio_mutex);
661 return 0;
662 }
663
664 static int wm_pcm_vol_put(struct snd_kcontrol
665 struct snd_ctl
666 {
667 struct snd_ice1712 *ice = snd_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) &
676 ovol = wm_get(ice, WM_DAC_DIG_MASTER_A
677 if (ovol != nvol) {
678 wm_put(ice, WM_DAC_DIG_MASTER_
679 /* update */
680 wm_put_nocache(ice, WM_DAC_DIG
681 change = 1;
682 }
683 snd_ice1712_restore_gpio_status(ice);
684 return change;
685 }
686
687 /*
688 * Deemphasis
689 */
690 #define phase28_deemp_info snd_ctl_boolea
691
692 static int phase28_deemp_get(struct snd_kcontr
693 struct snd_ctl
694 {
695 struct snd_ice1712 *ice = snd_kcontrol
696 ucontrol->value.integer.value[0] = (wm
697
698 return 0;
699 }
700
701 static int phase28_deemp_put(struct snd_kcontr
702 struct snd_ctl
703 {
704 struct snd_ice1712 *ice = snd_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 * ADC Oversampling
721 */
722 static int phase28_oversampling_info(struct sn
723 struct
724 {
725 static char *texts[2] = { "128x", "64x
726
727 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUM
728 uinfo->count = 1;
729 uinfo->value.enumerated.items = 2;
730
731 if (uinfo->value.enumerated.item >= ui
732 uinfo->value.enumerated.item =
733
734 strcpy(uinfo->value.enumerated.name,
735 texts[uinfo->value.enumerated.
736
737 return 0;
738 }
739
740 static int phase28_oversampling_get(struct snd
741 struct
742 {
743 struct snd_ice1712 *ice = snd_kcontrol
744 ucontrol->value.enumerated.item[0] = (
745
746 return 0;
747 }
748
749 static int phase28_oversampling_put(struct snd
750 struct
751 {
752 int temp, temp2;
753 struct snd_ice1712 *ice = snd_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
770 static const DECLARE_TLV_DB_SCALE(db_scale_wm_
771 static const DECLARE_TLV_DB_SCALE(db_scale_wm_
772
773 static struct snd_kcontrol_new phase28_dac_con
774 {
775 .iface = SNDRV_CTL_ELEM_IFACE_
776 .name = "Master Playback Switc
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_
783 .access = (SNDRV_CTL_ELEM_ACCE
784 SNDRV_CTL_ELEM_ACCE
785 .name = "Master Playback Volum
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_
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_
801 .access = (SNDRV_CTL_ELEM_ACCE
802 SNDRV_CTL_ELEM_ACCE
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_
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_
820 .access = (SNDRV_CTL_ELEM_ACCE
821 SNDRV_CTL_ELEM_ACCE
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_
831 .name = "Center Playback Switc
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_
839 .access = (SNDRV_CTL_ELEM_ACCE
840 SNDRV_CTL_ELEM_ACCE
841 .name = "Center Playback Volum
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_
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_
858 .access = (SNDRV_CTL_ELEM_ACCE
859 SNDRV_CTL_ELEM_ACCE
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_
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_
877 .access = (SNDRV_CTL_ELEM_ACCE
878 SNDRV_CTL_ELEM_ACCE
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
888 static struct snd_kcontrol_new wm_controls[] _
889 {
890 .iface = SNDRV_CTL_ELEM_IFACE_
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_
898 .access = (SNDRV_CTL_ELEM_ACCE
899 SNDRV_CTL_ELEM_ACCE
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_
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_
915 .name = "ADC Oversampling",
916 .info = phase28_oversampling_i
917 .get = phase28_oversampling_ge
918 .put = phase28_oversampling_pu
919 }
920 };
921
922 static int __devinit phase28_add_controls(stru
923 {
924 unsigned int i, counts;
925 int err;
926
927 counts = ARRAY_SIZE(phase28_dac_contro
928 for (i = 0; i < counts; i++) {
929 err = snd_ctl_add(ice->card,
930 snd_ct
931
932 if (err < 0)
933 return err;
934 }
935
936 for (i = 0; i < ARRAY_SIZE(wm_controls
937 err = snd_ctl_add(ice->card,
938 snd_ct
939 if (err < 0)
940 return err;
941 }
942
943 return 0;
944 }
945
946 struct snd_ice1712_card_info snd_vt1724_phase_
947 {
948 .subvendor = VT1724_SUBDEVICE_
949 .name = "Terratec PHASE 22",
950 .model = "phase22",
951 .chip_init = phase22_init,
952 .build_controls = phase22_add_
953 .eeprom_size = sizeof(phase22_
954 .eeprom_data = phase22_eeprom,
955 },
956 {
957 .subvendor = VT1724_SUBDEVICE_
958 .name = "Terratec PHASE 28",
959 .model = "phase28",
960 .chip_init = phase28_init,
961 .build_controls = phase28_add_
962 .eeprom_size = sizeof(phase28_
963 .eeprom_data = phase28_eeprom,
964 },
965 {
966 .subvendor = VT1724_SUBDEVICE_
967 .name = "Terrasoniq TS22 PCI",
968 .model = "TS22",
969 .chip_init = phase22_init,
970 .build_controls = phase22_add_
971 .eeprom_size = sizeof(phase22_
972 .eeprom_data = phase22_eeprom,
973 },
974 { } /* terminator */
975 };
976
| This page was automatically generated by the LXR engine. |