This source file includes following definitions.
- stac9460_put
- stac9460_get
- stac9460_2_put
- stac9460_2_get
- stac9460_dac_mute_all
- stac9460_dac_mute_get
- stac9460_dac_mute_put
- stac9460_dac_vol_info
- stac9460_dac_vol_get
- stac9460_dac_vol_put
- stac9460_adc_mute_get
- stac9460_adc_mute_put
- stac9460_adc_vol_info
- stac9460_adc_vol_get
- stac9460_adc_vol_put
- stac9460_mic_sw_info
- stac9460_mic_sw_get
- stac9460_mic_sw_put
- stac9460_set_rate_val
- wtm_add_controls
- wtm_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #include <linux/delay.h>
15 #include <linux/interrupt.h>
16 #include <linux/init.h>
17 #include <sound/core.h>
18 #include <sound/tlv.h>
19 #include <linux/slab.h>
20
21 #include "ice1712.h"
22 #include "envy24ht.h"
23 #include "wtm.h"
24 #include "stac946x.h"
25
26 struct wtm_spec {
27
28 struct mutex mute_mutex;
29 };
30
31
32
33
34
35 static inline void stac9460_put(struct snd_ice1712 *ice, int reg,
36 unsigned char val)
37 {
38 snd_vt1724_write_i2c(ice, STAC9460_I2C_ADDR, reg, val);
39 }
40
41 static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg)
42 {
43 return snd_vt1724_read_i2c(ice, STAC9460_I2C_ADDR, reg);
44 }
45
46
47
48
49 static inline void stac9460_2_put(struct snd_ice1712 *ice, int reg,
50 unsigned char val)
51 {
52 snd_vt1724_write_i2c(ice, STAC9460_2_I2C_ADDR, reg, val);
53 }
54
55 static inline unsigned char stac9460_2_get(struct snd_ice1712 *ice, int reg)
56 {
57 return snd_vt1724_read_i2c(ice, STAC9460_2_I2C_ADDR, reg);
58 }
59
60
61
62
63
64 static void stac9460_dac_mute_all(struct snd_ice1712 *ice, unsigned char mute,
65 unsigned short int *change_mask)
66 {
67 unsigned char new, old;
68 int id, idx, change;
69
70
71 for (id = 0; id < 7; id++) {
72 if (*change_mask & (0x01 << id)) {
73 if (id == 0)
74 idx = STAC946X_MASTER_VOLUME;
75 else
76 idx = STAC946X_LF_VOLUME - 1 + id;
77 old = stac9460_get(ice, idx);
78 new = (~mute << 7 & 0x80) | (old & ~0x80);
79 change = (new != old);
80 if (change) {
81 stac9460_put(ice, idx, new);
82 *change_mask = *change_mask | (0x01 << id);
83 } else {
84 *change_mask = *change_mask & ~(0x01 << id);
85 }
86 }
87 }
88
89
90 for (id = 0; id < 3; id++) {
91 if (*change_mask & (0x01 << (id + 7))) {
92 if (id == 0)
93 idx = STAC946X_MASTER_VOLUME;
94 else
95 idx = STAC946X_LF_VOLUME - 1 + id;
96 old = stac9460_2_get(ice, idx);
97 new = (~mute << 7 & 0x80) | (old & ~0x80);
98 change = (new != old);
99 if (change) {
100 stac9460_2_put(ice, idx, new);
101 *change_mask = *change_mask | (0x01 << id);
102 } else {
103 *change_mask = *change_mask & ~(0x01 << id);
104 }
105 }
106 }
107 }
108
109
110
111 #define stac9460_dac_mute_info snd_ctl_boolean_mono_info
112
113 static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol,
114 struct snd_ctl_elem_value *ucontrol)
115 {
116 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
117 struct wtm_spec *spec = ice->spec;
118 unsigned char val;
119 int idx, id;
120
121 mutex_lock(&spec->mute_mutex);
122
123 if (kcontrol->private_value) {
124 idx = STAC946X_MASTER_VOLUME;
125 id = 0;
126 } else {
127 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
128 idx = id + STAC946X_LF_VOLUME;
129 }
130 if (id < 6)
131 val = stac9460_get(ice, idx);
132 else
133 val = stac9460_2_get(ice, idx - 6);
134 ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
135
136 mutex_unlock(&spec->mute_mutex);
137 return 0;
138 }
139
140 static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol,
141 struct snd_ctl_elem_value *ucontrol)
142 {
143 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
144 unsigned char new, old;
145 int id, idx;
146 int change;
147
148 if (kcontrol->private_value) {
149 idx = STAC946X_MASTER_VOLUME;
150 old = stac9460_get(ice, idx);
151 new = (~ucontrol->value.integer.value[0] << 7 & 0x80) |
152 (old & ~0x80);
153 change = (new != old);
154 if (change) {
155 stac9460_put(ice, idx, new);
156 stac9460_2_put(ice, idx, new);
157 }
158 } else {
159 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
160 idx = id + STAC946X_LF_VOLUME;
161 if (id < 6)
162 old = stac9460_get(ice, idx);
163 else
164 old = stac9460_2_get(ice, idx - 6);
165 new = (~ucontrol->value.integer.value[0] << 7 & 0x80) |
166 (old & ~0x80);
167 change = (new != old);
168 if (change) {
169 if (id < 6)
170 stac9460_put(ice, idx, new);
171 else
172 stac9460_2_put(ice, idx - 6, new);
173 }
174 }
175 return change;
176 }
177
178
179
180
181 static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol,
182 struct snd_ctl_elem_info *uinfo)
183 {
184 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
185 uinfo->count = 1;
186 uinfo->value.integer.min = 0;
187 uinfo->value.integer.max = 0x7f;
188 return 0;
189 }
190
191 static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol,
192 struct snd_ctl_elem_value *ucontrol)
193 {
194 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
195 int idx, id;
196 unsigned char vol;
197
198 if (kcontrol->private_value) {
199 idx = STAC946X_MASTER_VOLUME;
200 id = 0;
201 } else {
202 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
203 idx = id + STAC946X_LF_VOLUME;
204 }
205 if (id < 6)
206 vol = stac9460_get(ice, idx) & 0x7f;
207 else
208 vol = stac9460_2_get(ice, idx - 6) & 0x7f;
209 ucontrol->value.integer.value[0] = 0x7f - vol;
210 return 0;
211 }
212
213 static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
214 struct snd_ctl_elem_value *ucontrol)
215 {
216 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
217 int idx, id;
218 unsigned char tmp, ovol, nvol;
219 int change;
220
221 if (kcontrol->private_value) {
222 idx = STAC946X_MASTER_VOLUME;
223 nvol = ucontrol->value.integer.value[0] & 0x7f;
224 tmp = stac9460_get(ice, idx);
225 ovol = 0x7f - (tmp & 0x7f);
226 change = (ovol != nvol);
227 if (change) {
228 stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
229 stac9460_2_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
230 }
231 } else {
232 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
233 idx = id + STAC946X_LF_VOLUME;
234 nvol = ucontrol->value.integer.value[0] & 0x7f;
235 if (id < 6)
236 tmp = stac9460_get(ice, idx);
237 else
238 tmp = stac9460_2_get(ice, idx - 6);
239 ovol = 0x7f - (tmp & 0x7f);
240 change = (ovol != nvol);
241 if (change) {
242 if (id < 6)
243 stac9460_put(ice, idx, (0x7f - nvol) |
244 (tmp & 0x80));
245 else
246 stac9460_2_put(ice, idx-6, (0x7f - nvol) |
247 (tmp & 0x80));
248 }
249 }
250 return change;
251 }
252
253
254
255
256 #define stac9460_adc_mute_info snd_ctl_boolean_stereo_info
257
258 static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol,
259 struct snd_ctl_elem_value *ucontrol)
260 {
261 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
262 unsigned char val;
263 int i, id;
264
265 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
266 if (id == 0) {
267 for (i = 0; i < 2; ++i) {
268 val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i);
269 ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
270 }
271 } else {
272 for (i = 0; i < 2; ++i) {
273 val = stac9460_2_get(ice, STAC946X_MIC_L_VOLUME + i);
274 ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
275 }
276 }
277 return 0;
278 }
279
280 static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol,
281 struct snd_ctl_elem_value *ucontrol)
282 {
283 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
284 unsigned char new, old;
285 int i, reg, id;
286 int change;
287
288 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
289 if (id == 0) {
290 for (i = 0; i < 2; ++i) {
291 reg = STAC946X_MIC_L_VOLUME + i;
292 old = stac9460_get(ice, reg);
293 new = (~ucontrol->value.integer.value[i]<<7&0x80) |
294 (old&~0x80);
295 change = (new != old);
296 if (change)
297 stac9460_put(ice, reg, new);
298 }
299 } else {
300 for (i = 0; i < 2; ++i) {
301 reg = STAC946X_MIC_L_VOLUME + i;
302 old = stac9460_2_get(ice, reg);
303 new = (~ucontrol->value.integer.value[i]<<7&0x80) |
304 (old&~0x80);
305 change = (new != old);
306 if (change)
307 stac9460_2_put(ice, reg, new);
308 }
309 }
310 return change;
311 }
312
313
314
315
316 static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol,
317 struct snd_ctl_elem_info *uinfo)
318 {
319 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
320 uinfo->count = 2;
321 uinfo->value.integer.min = 0;
322 uinfo->value.integer.max = 0x0f;
323 return 0;
324 }
325
326 static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol,
327 struct snd_ctl_elem_value *ucontrol)
328 {
329 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
330 int i, reg, id;
331 unsigned char vol;
332
333 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
334 if (id == 0) {
335 for (i = 0; i < 2; ++i) {
336 reg = STAC946X_MIC_L_VOLUME + i;
337 vol = stac9460_get(ice, reg) & 0x0f;
338 ucontrol->value.integer.value[i] = 0x0f - vol;
339 }
340 } else {
341 for (i = 0; i < 2; ++i) {
342 reg = STAC946X_MIC_L_VOLUME + i;
343 vol = stac9460_2_get(ice, reg) & 0x0f;
344 ucontrol->value.integer.value[i] = 0x0f - vol;
345 }
346 }
347 return 0;
348 }
349
350 static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
351 struct snd_ctl_elem_value *ucontrol)
352 {
353 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
354 int i, reg, id;
355 unsigned char ovol, nvol;
356 int change;
357
358 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
359 if (id == 0) {
360 for (i = 0; i < 2; ++i) {
361 reg = STAC946X_MIC_L_VOLUME + i;
362 nvol = ucontrol->value.integer.value[i] & 0x0f;
363 ovol = 0x0f - stac9460_get(ice, reg);
364 change = ((ovol & 0x0f) != nvol);
365 if (change)
366 stac9460_put(ice, reg, (0x0f - nvol) |
367 (ovol & ~0x0f));
368 }
369 } else {
370 for (i = 0; i < 2; ++i) {
371 reg = STAC946X_MIC_L_VOLUME + i;
372 nvol = ucontrol->value.integer.value[i] & 0x0f;
373 ovol = 0x0f - stac9460_2_get(ice, reg);
374 change = ((ovol & 0x0f) != nvol);
375 if (change)
376 stac9460_2_put(ice, reg, (0x0f - nvol) |
377 (ovol & ~0x0f));
378 }
379 }
380 return change;
381 }
382
383
384
385
386 static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol,
387 struct snd_ctl_elem_info *uinfo)
388 {
389 static const char * const texts[2] = { "Line In", "Mic" };
390
391 return snd_ctl_enum_info(uinfo, 1, 2, texts);
392 }
393
394
395 static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol,
396 struct snd_ctl_elem_value *ucontrol)
397 {
398 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
399 unsigned char val;
400 int id;
401
402 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
403 if (id == 0)
404 val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
405 else
406 val = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
407 ucontrol->value.enumerated.item[0] = (val >> 7) & 0x1;
408 return 0;
409 }
410
411 static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
412 struct snd_ctl_elem_value *ucontrol)
413 {
414 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
415 unsigned char new, old;
416 int change, id;
417
418 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
419 if (id == 0)
420 old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
421 else
422 old = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
423 new = (ucontrol->value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80);
424 change = (new != old);
425 if (change) {
426 if (id == 0)
427 stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new);
428 else
429 stac9460_2_put(ice, STAC946X_GENERAL_PURPOSE, new);
430 }
431 return change;
432 }
433
434
435
436
437
438 static void stac9460_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
439 {
440 unsigned char old, new;
441 unsigned short int changed;
442 struct wtm_spec *spec = ice->spec;
443
444 if (rate == 0)
445 return;
446 else if (rate <= 48000)
447 new = 0x08;
448 else if (rate <= 96000)
449 new = 0x11;
450 else
451 new = 0x12;
452
453 old = stac9460_get(ice, STAC946X_MASTER_CLOCKING);
454 if (old == new)
455 return;
456
457
458 mutex_lock(&spec->mute_mutex);
459
460 changed = 0xFFFF;
461 stac9460_dac_mute_all(ice, 0, &changed);
462
463 stac9460_put(ice, STAC946X_MASTER_CLOCKING, new);
464 stac9460_2_put(ice, STAC946X_MASTER_CLOCKING, new);
465 udelay(10);
466
467
468 stac9460_dac_mute_all(ice, 1, &changed);
469 mutex_unlock(&spec->mute_mutex);
470 }
471
472
473
474 static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0);
475 static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0);
476
477
478
479
480 static struct snd_kcontrol_new stac9640_controls[] = {
481 {
482 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
483 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
484 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
485 .name = "Master Playback Switch",
486 .info = stac9460_dac_mute_info,
487 .get = stac9460_dac_mute_get,
488 .put = stac9460_dac_mute_put,
489 .private_value = 1,
490 .tlv = { .p = db_scale_dac }
491 },
492 {
493 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
494 .name = "Master Playback Volume",
495 .info = stac9460_dac_vol_info,
496 .get = stac9460_dac_vol_get,
497 .put = stac9460_dac_vol_put,
498 .private_value = 1,
499 },
500 {
501 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
502 .name = "MIC/Line Input Enum",
503 .count = 2,
504 .info = stac9460_mic_sw_info,
505 .get = stac9460_mic_sw_get,
506 .put = stac9460_mic_sw_put,
507
508 },
509 {
510 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
511 .name = "DAC Switch",
512 .count = 8,
513 .info = stac9460_dac_mute_info,
514 .get = stac9460_dac_mute_get,
515 .put = stac9460_dac_mute_put,
516 },
517 {
518 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
519 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
520 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
521
522 .name = "DAC Volume",
523 .count = 8,
524 .info = stac9460_dac_vol_info,
525 .get = stac9460_dac_vol_get,
526 .put = stac9460_dac_vol_put,
527 .tlv = { .p = db_scale_dac }
528 },
529 {
530 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
531 .name = "ADC Switch",
532 .count = 2,
533 .info = stac9460_adc_mute_info,
534 .get = stac9460_adc_mute_get,
535 .put = stac9460_adc_mute_put,
536 },
537 {
538 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
539 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
540 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
541
542 .name = "ADC Volume",
543 .count = 2,
544 .info = stac9460_adc_vol_info,
545 .get = stac9460_adc_vol_get,
546 .put = stac9460_adc_vol_put,
547 .tlv = { .p = db_scale_adc }
548 }
549 };
550
551
552
553
554 static int wtm_add_controls(struct snd_ice1712 *ice)
555 {
556 unsigned int i;
557 int err;
558
559 for (i = 0; i < ARRAY_SIZE(stac9640_controls); i++) {
560 err = snd_ctl_add(ice->card,
561 snd_ctl_new1(&stac9640_controls[i], ice));
562 if (err < 0)
563 return err;
564 }
565 return 0;
566 }
567
568 static int wtm_init(struct snd_ice1712 *ice)
569 {
570 static unsigned short stac_inits_wtm[] = {
571 STAC946X_RESET, 0,
572 STAC946X_MASTER_CLOCKING, 0x11,
573 (unsigned short)-1
574 };
575 unsigned short *p;
576 struct wtm_spec *spec;
577
578
579 ice->num_total_dacs = 8;
580 ice->num_total_adcs = 4;
581 ice->force_rdma1 = 1;
582
583
584 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
585 if (!spec)
586 return -ENOMEM;
587 ice->spec = spec;
588 mutex_init(&spec->mute_mutex);
589
590
591
592 p = stac_inits_wtm;
593 for (; *p != (unsigned short)-1; p += 2) {
594 stac9460_put(ice, p[0], p[1]);
595 stac9460_2_put(ice, p[0], p[1]);
596 }
597 ice->gpio.set_pro_rate = stac9460_set_rate_val;
598 return 0;
599 }
600
601
602 static unsigned char wtm_eeprom[] = {
603 [ICE_EEP2_SYSCONF] = 0x67,
604
605 [ICE_EEP2_ACLINK] = 0x80,
606 [ICE_EEP2_I2S] = 0xf8,
607 [ICE_EEP2_SPDIF] = 0xc1,
608 [ICE_EEP2_GPIO_DIR] = 0x9f,
609 [ICE_EEP2_GPIO_DIR1] = 0xff,
610 [ICE_EEP2_GPIO_DIR2] = 0x7f,
611 [ICE_EEP2_GPIO_MASK] = 0x9f,
612 [ICE_EEP2_GPIO_MASK1] = 0xff,
613 [ICE_EEP2_GPIO_MASK2] = 0x7f,
614 [ICE_EEP2_GPIO_STATE] = 0x16,
615 [ICE_EEP2_GPIO_STATE1] = 0x80,
616 [ICE_EEP2_GPIO_STATE2] = 0x00,
617 };
618
619
620
621 struct snd_ice1712_card_info snd_vt1724_wtm_cards[] = {
622 {
623 .subvendor = VT1724_SUBDEVICE_WTM,
624 .name = "ESI Waveterminal 192M",
625 .model = "WT192M",
626 .chip_init = wtm_init,
627 .build_controls = wtm_add_controls,
628 .eeprom_size = sizeof(wtm_eeprom),
629 .eeprom_data = wtm_eeprom,
630 },
631 {}
632 };