1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <linux/time.h>
24#include <linux/interrupt.h>
25#include <linux/init.h>
26#include <linux/mutex.h>
27
28#include <sound/core.h>
29#include "mixart.h"
30#include "mixart_core.h"
31#include "mixart_hwdep.h"
32#include <sound/control.h>
33#include <sound/tlv.h>
34#include "mixart_mixer.h"
35
36static u32 mixart_analog_level[256] = {
37 0xc2c00000,
38 0xc2bf0000,
39 0xc2be0000,
40 0xc2bd0000,
41 0xc2bc0000,
42 0xc2bb0000,
43 0xc2ba0000,
44 0xc2b90000,
45 0xc2b80000,
46 0xc2b70000,
47 0xc2b60000,
48 0xc2b50000,
49 0xc2b40000,
50 0xc2b30000,
51 0xc2b20000,
52 0xc2b10000,
53 0xc2b00000,
54 0xc2af0000,
55 0xc2ae0000,
56 0xc2ad0000,
57 0xc2ac0000,
58 0xc2ab0000,
59 0xc2aa0000,
60 0xc2a90000,
61 0xc2a80000,
62 0xc2a70000,
63 0xc2a60000,
64 0xc2a50000,
65 0xc2a40000,
66 0xc2a30000,
67 0xc2a20000,
68 0xc2a10000,
69 0xc2a00000,
70 0xc29f0000,
71 0xc29e0000,
72 0xc29d0000,
73 0xc29c0000,
74 0xc29b0000,
75 0xc29a0000,
76 0xc2990000,
77 0xc2980000,
78 0xc2970000,
79 0xc2960000,
80 0xc2950000,
81 0xc2940000,
82 0xc2930000,
83 0xc2920000,
84 0xc2910000,
85 0xc2900000,
86 0xc28f0000,
87 0xc28e0000,
88 0xc28d0000,
89 0xc28c0000,
90 0xc28b0000,
91 0xc28a0000,
92 0xc2890000,
93 0xc2880000,
94 0xc2870000,
95 0xc2860000,
96 0xc2850000,
97 0xc2840000,
98 0xc2830000,
99 0xc2820000,
100 0xc2810000,
101 0xc2800000,
102 0xc27e0000,
103 0xc27c0000,
104 0xc27a0000,
105 0xc2780000,
106 0xc2760000,
107 0xc2740000,
108 0xc2720000,
109 0xc2700000,
110 0xc26e0000,
111 0xc26c0000,
112 0xc26a0000,
113 0xc2680000,
114 0xc2660000,
115 0xc2640000,
116 0xc2620000,
117 0xc2600000,
118 0xc25e0000,
119 0xc25c0000,
120 0xc25a0000,
121 0xc2580000,
122 0xc2560000,
123 0xc2540000,
124 0xc2520000,
125 0xc2500000,
126 0xc24e0000,
127 0xc24c0000,
128 0xc24a0000,
129 0xc2480000,
130 0xc2460000,
131 0xc2440000,
132 0xc2420000,
133 0xc2400000,
134 0xc23e0000,
135 0xc23c0000,
136 0xc23a0000,
137 0xc2380000,
138 0xc2360000,
139 0xc2340000,
140 0xc2320000,
141 0xc2300000,
142 0xc22e0000,
143 0xc22c0000,
144 0xc22a0000,
145 0xc2280000,
146 0xc2260000,
147 0xc2240000,
148 0xc2220000,
149 0xc2200000,
150 0xc21e0000,
151 0xc21c0000,
152 0xc21a0000,
153 0xc2180000,
154 0xc2160000,
155 0xc2140000,
156 0xc2120000,
157 0xc2100000,
158 0xc20e0000,
159 0xc20c0000,
160 0xc20a0000,
161 0xc2080000,
162 0xc2060000,
163 0xc2040000,
164 0xc2020000,
165 0xc2000000,
166 0xc1fc0000,
167 0xc1f80000,
168 0xc1f40000,
169 0xc1f00000,
170 0xc1ec0000,
171 0xc1e80000,
172 0xc1e40000,
173 0xc1e00000,
174 0xc1dc0000,
175 0xc1d80000,
176 0xc1d40000,
177 0xc1d00000,
178 0xc1cc0000,
179 0xc1c80000,
180 0xc1c40000,
181 0xc1c00000,
182 0xc1bc0000,
183 0xc1b80000,
184 0xc1b40000,
185 0xc1b00000,
186 0xc1ac0000,
187 0xc1a80000,
188 0xc1a40000,
189 0xc1a00000,
190 0xc19c0000,
191 0xc1980000,
192 0xc1940000,
193 0xc1900000,
194 0xc18c0000,
195 0xc1880000,
196 0xc1840000,
197 0xc1800000,
198 0xc1780000,
199 0xc1700000,
200 0xc1680000,
201 0xc1600000,
202 0xc1580000,
203 0xc1500000,
204 0xc1480000,
205 0xc1400000,
206 0xc1380000,
207 0xc1300000,
208 0xc1280000,
209 0xc1200000,
210 0xc1180000,
211 0xc1100000,
212 0xc1080000,
213 0xc1000000,
214 0xc0f00000,
215 0xc0e00000,
216 0xc0d00000,
217 0xc0c00000,
218 0xc0b00000,
219 0xc0a00000,
220 0xc0900000,
221 0xc0800000,
222 0xc0600000,
223 0xc0400000,
224 0xc0200000,
225 0xc0000000,
226 0xbfc00000,
227 0xbf800000,
228 0xbf000000,
229 0x00000000,
230 0x3f000000,
231 0x3f800000,
232 0x3fc00000,
233 0x40000000,
234 0x40200000,
235 0x40400000,
236 0x40600000,
237 0x40800000,
238 0x40900000,
239 0x40a00000,
240 0x40b00000,
241 0x40c00000,
242 0x40d00000,
243 0x40e00000,
244 0x40f00000,
245 0x41000000,
246 0x41080000,
247 0x41100000,
248 0x41180000,
249 0x41200000,
250 0x41280000,
251 0x41300000,
252 0x41380000,
253 0x41400000,
254 0x41480000,
255 0x41500000,
256 0x41580000,
257 0x41600000,
258 0x41680000,
259 0x41700000,
260 0x41780000,
261 0x41800000,
262 0x41840000,
263 0x41880000,
264 0x418c0000,
265 0x41900000,
266 0x41940000,
267 0x41980000,
268 0x419c0000,
269 0x41a00000,
270 0x41a40000,
271 0x41a80000,
272 0x41ac0000,
273 0x41b00000,
274 0x41b40000,
275 0x41b80000,
276 0x41bc0000,
277 0x41c00000,
278 0x41c40000,
279 0x41c80000,
280 0x41cc0000,
281 0x41d00000,
282 0x41d40000,
283 0x41d80000,
284 0x41dc0000,
285 0x41e00000,
286 0x41e40000,
287 0x41e80000,
288 0x41ec0000,
289 0x41f00000,
290 0x41f40000,
291 0x41f80000,
292 0x41fc0000,
293};
294
295#define MIXART_ANALOG_CAPTURE_LEVEL_MIN 0
296#define MIXART_ANALOG_CAPTURE_LEVEL_MAX 255
297#define MIXART_ANALOG_CAPTURE_ZERO_LEVEL 176
298
299#define MIXART_ANALOG_PLAYBACK_LEVEL_MIN 0
300#define MIXART_ANALOG_PLAYBACK_LEVEL_MAX 192
301#define MIXART_ANALOG_PLAYBACK_ZERO_LEVEL 189
302
303static int mixart_update_analog_audio_level(struct snd_mixart* chip, int is_capture)
304{
305 int i, err;
306 struct mixart_msg request;
307 struct mixart_io_level io_level;
308 struct mixart_return_uid resp;
309
310 memset(&io_level, 0, sizeof(io_level));
311 io_level.channel = -1;
312
313 for(i=0; i<2; i++) {
314 if(is_capture) {
315 io_level.level[i].analog_level = mixart_analog_level[chip->analog_capture_volume[i]];
316 } else {
317 if(chip->analog_playback_active[i])
318 io_level.level[i].analog_level = mixart_analog_level[chip->analog_playback_volume[i]];
319 else
320 io_level.level[i].analog_level = mixart_analog_level[MIXART_ANALOG_PLAYBACK_LEVEL_MIN];
321 }
322 }
323
324 if(is_capture) request.uid = chip->uid_in_analog_physio;
325 else request.uid = chip->uid_out_analog_physio;
326 request.message_id = MSG_PHYSICALIO_SET_LEVEL;
327 request.data = &io_level;
328 request.size = sizeof(io_level);
329
330 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(resp), &resp);
331 if((err<0) || (resp.error_code)) {
332 snd_printk(KERN_DEBUG "error MSG_PHYSICALIO_SET_LEVEL card(%d) is_capture(%d) error_code(%x)\n", chip->chip_idx, is_capture, resp.error_code);
333 return -EINVAL;
334 }
335 return 0;
336}
337
338
339
340
341static int mixart_analog_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
342{
343 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
344 uinfo->count = 2;
345 if(kcontrol->private_value == 0) {
346 uinfo->value.integer.min = MIXART_ANALOG_PLAYBACK_LEVEL_MIN;
347 uinfo->value.integer.max = MIXART_ANALOG_PLAYBACK_LEVEL_MAX;
348 } else {
349 uinfo->value.integer.min = MIXART_ANALOG_CAPTURE_LEVEL_MIN;
350 uinfo->value.integer.max = MIXART_ANALOG_CAPTURE_LEVEL_MAX;
351 }
352 return 0;
353}
354
355static int mixart_analog_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
356{
357 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
358 mutex_lock(&chip->mgr->mixer_mutex);
359 if(kcontrol->private_value == 0) {
360 ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
361 ucontrol->value.integer.value[1] = chip->analog_playback_volume[1];
362 } else {
363 ucontrol->value.integer.value[0] = chip->analog_capture_volume[0];
364 ucontrol->value.integer.value[1] = chip->analog_capture_volume[1];
365 }
366 mutex_unlock(&chip->mgr->mixer_mutex);
367 return 0;
368}
369
370static int mixart_analog_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
371{
372 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
373 int changed = 0;
374 int is_capture, i;
375
376 mutex_lock(&chip->mgr->mixer_mutex);
377 is_capture = (kcontrol->private_value != 0);
378 for (i = 0; i < 2; i++) {
379 int new_volume = ucontrol->value.integer.value[i];
380 int *stored_volume = is_capture ?
381 &chip->analog_capture_volume[i] :
382 &chip->analog_playback_volume[i];
383 if (is_capture) {
384 if (new_volume < MIXART_ANALOG_CAPTURE_LEVEL_MIN ||
385 new_volume > MIXART_ANALOG_CAPTURE_LEVEL_MAX)
386 continue;
387 } else {
388 if (new_volume < MIXART_ANALOG_PLAYBACK_LEVEL_MIN ||
389 new_volume > MIXART_ANALOG_PLAYBACK_LEVEL_MAX)
390 continue;
391 }
392 if (*stored_volume != new_volume) {
393 *stored_volume = new_volume;
394 changed = 1;
395 }
396 }
397 if (changed)
398 mixart_update_analog_audio_level(chip, is_capture);
399 mutex_unlock(&chip->mgr->mixer_mutex);
400 return changed;
401}
402
403static const DECLARE_TLV_DB_SCALE(db_scale_analog, -9600, 50, 0);
404
405static struct snd_kcontrol_new mixart_control_analog_level = {
406 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
407 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
408 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
409
410 .info = mixart_analog_vol_info,
411 .get = mixart_analog_vol_get,
412 .put = mixart_analog_vol_put,
413 .tlv = { .p = db_scale_analog },
414};
415
416
417#define mixart_sw_info snd_ctl_boolean_stereo_info
418
419static int mixart_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
420{
421 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
422
423 mutex_lock(&chip->mgr->mixer_mutex);
424 ucontrol->value.integer.value[0] = chip->analog_playback_active[0];
425 ucontrol->value.integer.value[1] = chip->analog_playback_active[1];
426 mutex_unlock(&chip->mgr->mixer_mutex);
427 return 0;
428}
429
430static int mixart_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
431{
432 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
433 int i, changed = 0;
434 mutex_lock(&chip->mgr->mixer_mutex);
435 for (i = 0; i < 2; i++) {
436 if (chip->analog_playback_active[i] !=
437 ucontrol->value.integer.value[i]) {
438 chip->analog_playback_active[i] =
439 !!ucontrol->value.integer.value[i];
440 changed = 1;
441 }
442 }
443 if (changed)
444 mixart_update_analog_audio_level(chip, 0);
445 mutex_unlock(&chip->mgr->mixer_mutex);
446 return changed;
447}
448
449static struct snd_kcontrol_new mixart_control_output_switch = {
450 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
451 .name = "Master Playback Switch",
452 .info = mixart_sw_info,
453 .get = mixart_audio_sw_get,
454 .put = mixart_audio_sw_put
455};
456
457static u32 mixart_digital_level[256] = {
458 0x00000000,
459 0x366e1c7a,
460 0x367c3860,
461 0x36859525,
462 0x368d7f74,
463 0x3695e1d4,
464 0x369ec362,
465 0x36a82ba8,
466 0x36b222a0,
467 0x36bcb0c1,
468 0x36c7defd,
469 0x36d3b6d3,
470 0x36e0424e,
471 0x36ed8c14,
472 0x36fb9f6c,
473 0x37054423,
474 0x370d29a5,
475 0x371586f0,
476 0x371e631b,
477 0x3727c5ac,
478 0x3731b69a,
479 0x373c3e53,
480 0x374765c8,
481 0x3753366f,
482 0x375fba4f,
483 0x376cfc07,
484 0x377b06d5,
485 0x3784f352,
486 0x378cd40b,
487 0x37952c42,
488 0x379e030e,
489 0x37a75fef,
490 0x37b14ad5,
491 0x37bbcc2c,
492 0x37c6ecdd,
493 0x37d2b65a,
494 0x37df32a3,
495 0x37ec6c50,
496 0x37fa6e9b,
497 0x3804a2b3,
498 0x380c7ea4,
499 0x3814d1cc,
500 0x381da33c,
501 0x3826fa6f,
502 0x3830df51,
503 0x383b5a49,
504 0x3846743b,
505 0x38523692,
506 0x385eab48,
507 0x386bdcf1,
508 0x3879d6bc,
509 0x38845244,
510 0x388c2971,
511 0x3894778d,
512 0x389d43a4,
513 0x38a6952c,
514 0x38b0740f,
515 0x38bae8ac,
516 0x38c5fbe2,
517 0x38d1b717,
518 0x38de2440,
519 0x38eb4de8,
520 0x38f93f3a,
521 0x39040206,
522 0x390bd472,
523 0x39141d84,
524 0x391ce445,
525 0x39263027,
526 0x3930090d,
527 0x393a7753,
528 0x394583d2,
529 0x395137ea,
530 0x395d9d8a,
531 0x396abf37,
532 0x3978a814,
533 0x3983b1f8,
534 0x398b7fa6,
535 0x3993c3b2,
536 0x399c8521,
537 0x39a5cb5f,
538 0x39af9e4d,
539 0x39ba063f,
540 0x39c50c0b,
541 0x39d0b90a,
542 0x39dd1726,
543 0x39ea30db,
544 0x39f81149,
545 0x3a03621b,
546 0x3a0b2b0d,
547 0x3a136a16,
548 0x3a1c2636,
549 0x3a2566d5,
550 0x3a2f33cd,
551 0x3a399570,
552 0x3a44948c,
553 0x3a503a77,
554 0x3a5c9112,
555 0x3a69a2d7,
556 0x3a777ada,
557 0x3a83126f,
558 0x3a8ad6a8,
559 0x3a9310b1,
560 0x3a9bc784,
561 0x3aa50287,
562 0x3aaec98e,
563 0x3ab924e5,
564 0x3ac41d56,
565 0x3acfbc31,
566 0x3adc0b51,
567 0x3ae91528,
568 0x3af6e4c6,
569 0x3b02c2f2,
570 0x3b0a8276,
571 0x3b12b782,
572 0x3b1b690d,
573 0x3b249e76,
574 0x3b2e5f8f,
575 0x3b38b49f,
576 0x3b43a669,
577 0x3b4f3e37,
578 0x3b5b85e0,
579 0x3b6887cf,
580 0x3b764f0e,
581 0x3b8273a6,
582 0x3b8a2e77,
583 0x3b925e89,
584 0x3b9b0ace,
585 0x3ba43aa2,
586 0x3badf5d1,
587 0x3bb8449c,
588 0x3bc32fc3,
589 0x3bcec08a,
590 0x3bdb00c0,
591 0x3be7facc,
592 0x3bf5b9b0,
593 0x3c02248a,
594 0x3c09daac,
595 0x3c1205c6,
596 0x3c1aacc8,
597 0x3c23d70a,
598 0x3c2d8c52,
599 0x3c37d4dd,
600 0x3c42b965,
601 0x3c4e4329,
602 0x3c5a7bf1,
603 0x3c676e1e,
604 0x3c7524ac,
605 0x3c81d59f,
606 0x3c898712,
607 0x3c91ad39,
608 0x3c9a4efc,
609 0x3ca373af,
610 0x3cad2314,
611 0x3cb76563,
612 0x3cc24350,
613 0x3ccdc614,
614 0x3cd9f773,
615 0x3ce6e1c6,
616 0x3cf49003,
617 0x3d0186e2,
618 0x3d0933ac,
619 0x3d1154e1,
620 0x3d19f169,
621 0x3d231090,
622 0x3d2cba15,
623 0x3d36f62b,
624 0x3d41cd81,
625 0x3d4d494a,
626 0x3d597345,
627 0x3d6655c3,
628 0x3d73fbb4,
629 0x3d813856,
630 0x3d88e078,
631 0x3d90fcbf,
632 0x3d99940e,
633 0x3da2adad,
634 0x3dac5156,
635 0x3db68738,
636 0x3dc157fb,
637 0x3dcccccd,
638 0x3dd8ef67,
639 0x3de5ca15,
640 0x3df367bf,
641 0x3e00e9f9,
642 0x3e088d77,
643 0x3e10a4d3,
644 0x3e1936ec,
645 0x3e224b06,
646 0x3e2be8d7,
647 0x3e361887,
648 0x3e40e2bb,
649 0x3e4c509b,
650 0x3e586bd9,
651 0x3e653ebb,
652 0x3e72d424,
653 0x3e809bcc,
654 0x3e883aa8,
655 0x3e904d1c,
656 0x3e98da02,
657 0x3ea1e89b,
658 0x3eab8097,
659 0x3eb5aa1a,
660 0x3ec06dc3,
661 0x3ecbd4b4,
662 0x3ed7e89b,
663 0x3ee4b3b6,
664 0x3ef240e2,
665 0x3f004dce,
666 0x3f07e80b,
667 0x3f0ff59a,
668 0x3f187d50,
669 0x3f21866c,
670 0x3f2b1896,
671 0x3f353bef,
672 0x3f3ff911,
673 0x3f4b5918,
674 0x3f5765ac,
675 0x3f642905,
676 0x3f71adf9,
677 0x3f800000,
678 0x3f8795a0,
679 0x3f8f9e4d,
680 0x3f9820d7,
681 0x3fa12478,
682 0x3faab0d5,
683 0x3fb4ce08,
684 0x3fbf84a6,
685 0x3fcaddc8,
686 0x3fd6e30d,
687 0x3fe39ea9,
688 0x3ff11b6a,
689 0x3fff64c1,
690 0x40074368,
691 0x400f4735,
692 0x4017c496,
693 0x4020c2bf,
694 0x402a4952,
695 0x40346063,
696 0x403f1082,
697 0x404a62c2,
698 0x405660bd,
699 0x406314a0,
700 0x40708933,
701 0x407ec9e1,
702 0x4086f161,
703 0x408ef052,
704 0x4097688d,
705 0x40a06142,
706 0x40a9e20e,
707 0x40b3f300,
708 0x40be9ca5,
709 0x40c9e807,
710 0x40d5debc,
711 0x40e28aeb,
712 0x40eff755,
713 0x40fe2f5e,
714};
715
716#define MIXART_DIGITAL_LEVEL_MIN 0
717#define MIXART_DIGITAL_LEVEL_MAX 255
718#define MIXART_DIGITAL_ZERO_LEVEL 219
719
720
721int mixart_update_playback_stream_level(struct snd_mixart* chip, int is_aes, int idx)
722{
723 int err, i;
724 int volume[2];
725 struct mixart_msg request;
726 struct mixart_set_out_stream_level_req set_level;
727 u32 status;
728 struct mixart_pipe *pipe;
729
730 memset(&set_level, 0, sizeof(set_level));
731 set_level.nb_of_stream = 1;
732 set_level.stream_level.desc.stream_idx = idx;
733
734 if(is_aes) {
735 pipe = &chip->pipe_out_dig;
736 idx += MIXART_PLAYBACK_STREAMS;
737 } else {
738 pipe = &chip->pipe_out_ana;
739 }
740
741
742 if(pipe->status == PIPE_UNDEFINED)
743 return 0;
744
745 set_level.stream_level.desc.uid_pipe = pipe->group_uid;
746
747 for(i=0; i<2; i++) {
748 if(chip->digital_playback_active[idx][i])
749 volume[i] = chip->digital_playback_volume[idx][i];
750 else
751 volume[i] = MIXART_DIGITAL_LEVEL_MIN;
752 }
753
754 set_level.stream_level.out_level.valid_mask1 = MIXART_OUT_STREAM_SET_LEVEL_LEFT_AUDIO1 | MIXART_OUT_STREAM_SET_LEVEL_RIGHT_AUDIO2;
755 set_level.stream_level.out_level.left_to_out1_level = mixart_digital_level[volume[0]];
756 set_level.stream_level.out_level.right_to_out2_level = mixart_digital_level[volume[1]];
757
758 request.message_id = MSG_STREAM_SET_OUT_STREAM_LEVEL;
759 request.uid = (struct mixart_uid){0,0};
760 request.data = &set_level;
761 request.size = sizeof(set_level);
762
763 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(status), &status);
764 if((err<0) || status) {
765 snd_printk(KERN_DEBUG "error MSG_STREAM_SET_OUT_STREAM_LEVEL card(%d) status(%x)\n", chip->chip_idx, status);
766 return -EINVAL;
767 }
768 return 0;
769}
770
771int mixart_update_capture_stream_level(struct snd_mixart* chip, int is_aes)
772{
773 int err, i, idx;
774 struct mixart_pipe *pipe;
775 struct mixart_msg request;
776 struct mixart_set_in_audio_level_req set_level;
777 u32 status;
778
779 if(is_aes) {
780 idx = 1;
781 pipe = &chip->pipe_in_dig;
782 } else {
783 idx = 0;
784 pipe = &chip->pipe_in_ana;
785 }
786
787
788 if(pipe->status == PIPE_UNDEFINED)
789 return 0;
790
791 memset(&set_level, 0, sizeof(set_level));
792 set_level.audio_count = 2;
793 set_level.level[0].connector = pipe->uid_left_connector;
794 set_level.level[1].connector = pipe->uid_right_connector;
795
796 for(i=0; i<2; i++) {
797 set_level.level[i].valid_mask1 = MIXART_AUDIO_LEVEL_DIGITAL_MASK;
798 set_level.level[i].digital_level = mixart_digital_level[chip->digital_capture_volume[idx][i]];
799 }
800
801 request.message_id = MSG_STREAM_SET_IN_AUDIO_LEVEL;
802 request.uid = (struct mixart_uid){0,0};
803 request.data = &set_level;
804 request.size = sizeof(set_level);
805
806 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(status), &status);
807 if((err<0) || status) {
808 snd_printk(KERN_DEBUG "error MSG_STREAM_SET_IN_AUDIO_LEVEL card(%d) status(%x)\n", chip->chip_idx, status);
809 return -EINVAL;
810 }
811 return 0;
812}
813
814
815
816static int mixart_digital_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
817{
818 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
819 uinfo->count = 2;
820 uinfo->value.integer.min = MIXART_DIGITAL_LEVEL_MIN;
821 uinfo->value.integer.max = MIXART_DIGITAL_LEVEL_MAX;
822 return 0;
823}
824
825#define MIXART_VOL_REC_MASK 1
826#define MIXART_VOL_AES_MASK 2
827
828static int mixart_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
829{
830 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
831 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
832 int *stored_volume;
833 int is_capture = kcontrol->private_value & MIXART_VOL_REC_MASK;
834 int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
835 mutex_lock(&chip->mgr->mixer_mutex);
836 if(is_capture) {
837 if(is_aes) stored_volume = chip->digital_capture_volume[1];
838 else stored_volume = chip->digital_capture_volume[0];
839 } else {
840 snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
841 if(is_aes) stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx];
842 else stored_volume = chip->digital_playback_volume[idx];
843 }
844 ucontrol->value.integer.value[0] = stored_volume[0];
845 ucontrol->value.integer.value[1] = stored_volume[1];
846 mutex_unlock(&chip->mgr->mixer_mutex);
847 return 0;
848}
849
850static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
851{
852 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
853 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
854 int changed = 0;
855 int is_capture = kcontrol->private_value & MIXART_VOL_REC_MASK;
856 int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
857 int* stored_volume;
858 int i;
859 mutex_lock(&chip->mgr->mixer_mutex);
860 if (is_capture) {
861 if (is_aes)
862 stored_volume = chip->digital_capture_volume[1];
863 else
864 stored_volume = chip->digital_capture_volume[0];
865 } else {
866 snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
867 if (is_aes)
868 stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx];
869 else
870 stored_volume = chip->digital_playback_volume[idx];
871 }
872 for (i = 0; i < 2; i++) {
873 int vol = ucontrol->value.integer.value[i];
874 if (vol < MIXART_DIGITAL_LEVEL_MIN ||
875 vol > MIXART_DIGITAL_LEVEL_MAX)
876 continue;
877 if (stored_volume[i] != vol) {
878 stored_volume[i] = vol;
879 changed = 1;
880 }
881 }
882 if (changed) {
883 if (is_capture)
884 mixart_update_capture_stream_level(chip, is_aes);
885 else
886 mixart_update_playback_stream_level(chip, is_aes, idx);
887 }
888 mutex_unlock(&chip->mgr->mixer_mutex);
889 return changed;
890}
891
892static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0);
893
894static struct snd_kcontrol_new snd_mixart_pcm_vol =
895{
896 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
897 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
898 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
899
900
901 .info = mixart_digital_vol_info,
902 .get = mixart_pcm_vol_get,
903 .put = mixart_pcm_vol_put,
904 .tlv = { .p = db_scale_digital },
905};
906
907
908static int mixart_pcm_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
909{
910 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
911 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
912 snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
913 mutex_lock(&chip->mgr->mixer_mutex);
914 if(kcontrol->private_value & MIXART_VOL_AES_MASK)
915 idx += MIXART_PLAYBACK_STREAMS;
916 ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0];
917 ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1];
918 mutex_unlock(&chip->mgr->mixer_mutex);
919 return 0;
920}
921
922static int mixart_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
923{
924 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
925 int changed = 0;
926 int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
927 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
928 int i, j;
929 snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
930 mutex_lock(&chip->mgr->mixer_mutex);
931 j = idx;
932 if (is_aes)
933 j += MIXART_PLAYBACK_STREAMS;
934 for (i = 0; i < 2; i++) {
935 if (chip->digital_playback_active[j][i] !=
936 ucontrol->value.integer.value[i]) {
937 chip->digital_playback_active[j][i] =
938 !!ucontrol->value.integer.value[i];
939 changed = 1;
940 }
941 }
942 if (changed)
943 mixart_update_playback_stream_level(chip, is_aes, idx);
944 mutex_unlock(&chip->mgr->mixer_mutex);
945 return changed;
946}
947
948static struct snd_kcontrol_new mixart_control_pcm_switch = {
949 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
950
951 .count = MIXART_PLAYBACK_STREAMS,
952 .info = mixart_sw_info,
953 .get = mixart_pcm_sw_get,
954 .put = mixart_pcm_sw_put
955};
956
957static int mixart_update_monitoring(struct snd_mixart* chip, int channel)
958{
959 int err;
960 struct mixart_msg request;
961 struct mixart_set_out_audio_level audio_level;
962 u32 resp;
963
964 if(chip->pipe_out_ana.status == PIPE_UNDEFINED)
965 return -EINVAL;
966
967 if(!channel) request.uid = chip->pipe_out_ana.uid_left_connector;
968 else request.uid = chip->pipe_out_ana.uid_right_connector;
969 request.message_id = MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL;
970 request.data = &audio_level;
971 request.size = sizeof(audio_level);
972
973 memset(&audio_level, 0, sizeof(audio_level));
974 audio_level.valid_mask1 = MIXART_AUDIO_LEVEL_MONITOR_MASK | MIXART_AUDIO_LEVEL_MUTE_M1_MASK;
975 audio_level.monitor_level = mixart_digital_level[chip->monitoring_volume[channel!=0]];
976 audio_level.monitor_mute1 = !chip->monitoring_active[channel!=0];
977
978 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(resp), &resp);
979 if((err<0) || resp) {
980 snd_printk(KERN_DEBUG "error MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL card(%d) resp(%x)\n", chip->chip_idx, resp);
981 return -EINVAL;
982 }
983 return 0;
984}
985
986
987
988
989
990static int mixart_monitor_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
991{
992 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
993 mutex_lock(&chip->mgr->mixer_mutex);
994 ucontrol->value.integer.value[0] = chip->monitoring_volume[0];
995 ucontrol->value.integer.value[1] = chip->monitoring_volume[1];
996 mutex_unlock(&chip->mgr->mixer_mutex);
997 return 0;
998}
999
1000static int mixart_monitor_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1001{
1002 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
1003 int changed = 0;
1004 int i;
1005 mutex_lock(&chip->mgr->mixer_mutex);
1006 for (i = 0; i < 2; i++) {
1007 if (chip->monitoring_volume[i] !=
1008 ucontrol->value.integer.value[i]) {
1009 chip->monitoring_volume[i] =
1010 !!ucontrol->value.integer.value[i];
1011 mixart_update_monitoring(chip, i);
1012 changed = 1;
1013 }
1014 }
1015 mutex_unlock(&chip->mgr->mixer_mutex);
1016 return changed;
1017}
1018
1019static struct snd_kcontrol_new mixart_control_monitor_vol = {
1020 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1021 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1022 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1023 .name = "Monitoring Volume",
1024 .info = mixart_digital_vol_info,
1025 .get = mixart_monitor_vol_get,
1026 .put = mixart_monitor_vol_put,
1027 .tlv = { .p = db_scale_digital },
1028};
1029
1030
1031
1032
1033
1034static int mixart_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1035{
1036 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
1037 mutex_lock(&chip->mgr->mixer_mutex);
1038 ucontrol->value.integer.value[0] = chip->monitoring_active[0];
1039 ucontrol->value.integer.value[1] = chip->monitoring_active[1];
1040 mutex_unlock(&chip->mgr->mixer_mutex);
1041 return 0;
1042}
1043
1044static int mixart_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1045{
1046 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
1047 int changed = 0;
1048 int i;
1049 mutex_lock(&chip->mgr->mixer_mutex);
1050 for (i = 0; i < 2; i++) {
1051 if (chip->monitoring_active[i] !=
1052 ucontrol->value.integer.value[i]) {
1053 chip->monitoring_active[i] =
1054 !!ucontrol->value.integer.value[i];
1055 changed |= (1<<i);
1056 }
1057 }
1058 if (changed) {
1059
1060 int allocate = chip->monitoring_active[0] ||
1061 chip->monitoring_active[1];
1062 if (allocate) {
1063
1064 snd_mixart_add_ref_pipe(chip, MIXART_PCM_ANALOG, 0, 1);
1065
1066 snd_mixart_add_ref_pipe(chip, MIXART_PCM_ANALOG, 1, 1);
1067 }
1068 if (changed & 0x01)
1069 mixart_update_monitoring(chip, 0);
1070 if (changed & 0x02)
1071 mixart_update_monitoring(chip, 1);
1072 if (!allocate) {
1073
1074 snd_mixart_kill_ref_pipe(chip->mgr,
1075 &chip->pipe_in_ana, 1);
1076
1077 snd_mixart_kill_ref_pipe(chip->mgr,
1078 &chip->pipe_out_ana, 1);
1079 }
1080 }
1081
1082 mutex_unlock(&chip->mgr->mixer_mutex);
1083 return (changed != 0);
1084}
1085
1086static struct snd_kcontrol_new mixart_control_monitor_sw = {
1087 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1088 .name = "Monitoring Switch",
1089 .info = mixart_sw_info,
1090 .get = mixart_monitor_sw_get,
1091 .put = mixart_monitor_sw_put
1092};
1093
1094
1095static void mixart_reset_audio_levels(struct snd_mixart *chip)
1096{
1097
1098 mixart_update_analog_audio_level(chip, 0);
1099
1100 if(chip->chip_idx < 2) {
1101 mixart_update_analog_audio_level(chip, 1);
1102 }
1103 return;
1104}
1105
1106
1107int snd_mixart_create_mixer(struct mixart_mgr *mgr)
1108{
1109 struct snd_mixart *chip;
1110 int err, i;
1111
1112 mutex_init(&mgr->mixer_mutex);
1113
1114 for(i=0; i<mgr->num_cards; i++) {
1115 struct snd_kcontrol_new temp;
1116 chip = mgr->chip[i];
1117
1118
1119 temp = mixart_control_analog_level;
1120 temp.name = "Master Playback Volume";
1121 temp.private_value = 0;
1122 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1123 return err;
1124
1125 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_output_switch, chip))) < 0)
1126 return err;
1127
1128
1129 if(i<2) {
1130 temp = mixart_control_analog_level;
1131 temp.name = "Master Capture Volume";
1132 temp.private_value = 1;
1133 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1134 return err;
1135 }
1136
1137 temp = snd_mixart_pcm_vol;
1138 temp.name = "PCM Playback Volume";
1139 temp.count = MIXART_PLAYBACK_STREAMS;
1140 temp.private_value = 0;
1141 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1142 return err;
1143
1144 temp.name = "PCM Capture Volume";
1145 temp.count = 1;
1146 temp.private_value = MIXART_VOL_REC_MASK;
1147 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1148 return err;
1149
1150 if(mgr->board_type == MIXART_DAUGHTER_TYPE_AES) {
1151 temp.name = "AES Playback Volume";
1152 temp.count = MIXART_PLAYBACK_STREAMS;
1153 temp.private_value = MIXART_VOL_AES_MASK;
1154 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1155 return err;
1156
1157 temp.name = "AES Capture Volume";
1158 temp.count = 0;
1159 temp.private_value = MIXART_VOL_REC_MASK | MIXART_VOL_AES_MASK;
1160 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1161 return err;
1162 }
1163 temp = mixart_control_pcm_switch;
1164 temp.name = "PCM Playback Switch";
1165 temp.private_value = 0;
1166 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1167 return err;
1168
1169 if(mgr->board_type == MIXART_DAUGHTER_TYPE_AES) {
1170 temp.name = "AES Playback Switch";
1171 temp.private_value = MIXART_VOL_AES_MASK;
1172 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1173 return err;
1174 }
1175
1176
1177 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_monitor_vol, chip))) < 0)
1178 return err;
1179 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_monitor_sw, chip))) < 0)
1180 return err;
1181
1182
1183 mixart_reset_audio_levels(chip);
1184 }
1185 return 0;
1186}
1187