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 dev_dbg(chip->card->dev,
333 "error MSG_PHYSICALIO_SET_LEVEL card(%d) is_capture(%d) error_code(%x)\n",
334 chip->chip_idx, is_capture, resp.error_code);
335 return -EINVAL;
336 }
337 return 0;
338}
339
340
341
342
343static int mixart_analog_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
344{
345 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
346 uinfo->count = 2;
347 if(kcontrol->private_value == 0) {
348 uinfo->value.integer.min = MIXART_ANALOG_PLAYBACK_LEVEL_MIN;
349 uinfo->value.integer.max = MIXART_ANALOG_PLAYBACK_LEVEL_MAX;
350 } else {
351 uinfo->value.integer.min = MIXART_ANALOG_CAPTURE_LEVEL_MIN;
352 uinfo->value.integer.max = MIXART_ANALOG_CAPTURE_LEVEL_MAX;
353 }
354 return 0;
355}
356
357static int mixart_analog_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
358{
359 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
360 mutex_lock(&chip->mgr->mixer_mutex);
361 if(kcontrol->private_value == 0) {
362 ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
363 ucontrol->value.integer.value[1] = chip->analog_playback_volume[1];
364 } else {
365 ucontrol->value.integer.value[0] = chip->analog_capture_volume[0];
366 ucontrol->value.integer.value[1] = chip->analog_capture_volume[1];
367 }
368 mutex_unlock(&chip->mgr->mixer_mutex);
369 return 0;
370}
371
372static int mixart_analog_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
373{
374 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
375 int changed = 0;
376 int is_capture, i;
377
378 mutex_lock(&chip->mgr->mixer_mutex);
379 is_capture = (kcontrol->private_value != 0);
380 for (i = 0; i < 2; i++) {
381 int new_volume = ucontrol->value.integer.value[i];
382 int *stored_volume = is_capture ?
383 &chip->analog_capture_volume[i] :
384 &chip->analog_playback_volume[i];
385 if (is_capture) {
386 if (new_volume < MIXART_ANALOG_CAPTURE_LEVEL_MIN ||
387 new_volume > MIXART_ANALOG_CAPTURE_LEVEL_MAX)
388 continue;
389 } else {
390 if (new_volume < MIXART_ANALOG_PLAYBACK_LEVEL_MIN ||
391 new_volume > MIXART_ANALOG_PLAYBACK_LEVEL_MAX)
392 continue;
393 }
394 if (*stored_volume != new_volume) {
395 *stored_volume = new_volume;
396 changed = 1;
397 }
398 }
399 if (changed)
400 mixart_update_analog_audio_level(chip, is_capture);
401 mutex_unlock(&chip->mgr->mixer_mutex);
402 return changed;
403}
404
405static const DECLARE_TLV_DB_SCALE(db_scale_analog, -9600, 50, 0);
406
407static const struct snd_kcontrol_new mixart_control_analog_level = {
408 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
409 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
410 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
411
412 .info = mixart_analog_vol_info,
413 .get = mixart_analog_vol_get,
414 .put = mixart_analog_vol_put,
415 .tlv = { .p = db_scale_analog },
416};
417
418
419#define mixart_sw_info snd_ctl_boolean_stereo_info
420
421static int mixart_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
422{
423 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
424
425 mutex_lock(&chip->mgr->mixer_mutex);
426 ucontrol->value.integer.value[0] = chip->analog_playback_active[0];
427 ucontrol->value.integer.value[1] = chip->analog_playback_active[1];
428 mutex_unlock(&chip->mgr->mixer_mutex);
429 return 0;
430}
431
432static int mixart_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
433{
434 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
435 int i, changed = 0;
436 mutex_lock(&chip->mgr->mixer_mutex);
437 for (i = 0; i < 2; i++) {
438 if (chip->analog_playback_active[i] !=
439 ucontrol->value.integer.value[i]) {
440 chip->analog_playback_active[i] =
441 !!ucontrol->value.integer.value[i];
442 changed = 1;
443 }
444 }
445 if (changed)
446 mixart_update_analog_audio_level(chip, 0);
447 mutex_unlock(&chip->mgr->mixer_mutex);
448 return changed;
449}
450
451static const struct snd_kcontrol_new mixart_control_output_switch = {
452 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
453 .name = "Master Playback Switch",
454 .info = mixart_sw_info,
455 .get = mixart_audio_sw_get,
456 .put = mixart_audio_sw_put
457};
458
459static u32 mixart_digital_level[256] = {
460 0x00000000,
461 0x366e1c7a,
462 0x367c3860,
463 0x36859525,
464 0x368d7f74,
465 0x3695e1d4,
466 0x369ec362,
467 0x36a82ba8,
468 0x36b222a0,
469 0x36bcb0c1,
470 0x36c7defd,
471 0x36d3b6d3,
472 0x36e0424e,
473 0x36ed8c14,
474 0x36fb9f6c,
475 0x37054423,
476 0x370d29a5,
477 0x371586f0,
478 0x371e631b,
479 0x3727c5ac,
480 0x3731b69a,
481 0x373c3e53,
482 0x374765c8,
483 0x3753366f,
484 0x375fba4f,
485 0x376cfc07,
486 0x377b06d5,
487 0x3784f352,
488 0x378cd40b,
489 0x37952c42,
490 0x379e030e,
491 0x37a75fef,
492 0x37b14ad5,
493 0x37bbcc2c,
494 0x37c6ecdd,
495 0x37d2b65a,
496 0x37df32a3,
497 0x37ec6c50,
498 0x37fa6e9b,
499 0x3804a2b3,
500 0x380c7ea4,
501 0x3814d1cc,
502 0x381da33c,
503 0x3826fa6f,
504 0x3830df51,
505 0x383b5a49,
506 0x3846743b,
507 0x38523692,
508 0x385eab48,
509 0x386bdcf1,
510 0x3879d6bc,
511 0x38845244,
512 0x388c2971,
513 0x3894778d,
514 0x389d43a4,
515 0x38a6952c,
516 0x38b0740f,
517 0x38bae8ac,
518 0x38c5fbe2,
519 0x38d1b717,
520 0x38de2440,
521 0x38eb4de8,
522 0x38f93f3a,
523 0x39040206,
524 0x390bd472,
525 0x39141d84,
526 0x391ce445,
527 0x39263027,
528 0x3930090d,
529 0x393a7753,
530 0x394583d2,
531 0x395137ea,
532 0x395d9d8a,
533 0x396abf37,
534 0x3978a814,
535 0x3983b1f8,
536 0x398b7fa6,
537 0x3993c3b2,
538 0x399c8521,
539 0x39a5cb5f,
540 0x39af9e4d,
541 0x39ba063f,
542 0x39c50c0b,
543 0x39d0b90a,
544 0x39dd1726,
545 0x39ea30db,
546 0x39f81149,
547 0x3a03621b,
548 0x3a0b2b0d,
549 0x3a136a16,
550 0x3a1c2636,
551 0x3a2566d5,
552 0x3a2f33cd,
553 0x3a399570,
554 0x3a44948c,
555 0x3a503a77,
556 0x3a5c9112,
557 0x3a69a2d7,
558 0x3a777ada,
559 0x3a83126f,
560 0x3a8ad6a8,
561 0x3a9310b1,
562 0x3a9bc784,
563 0x3aa50287,
564 0x3aaec98e,
565 0x3ab924e5,
566 0x3ac41d56,
567 0x3acfbc31,
568 0x3adc0b51,
569 0x3ae91528,
570 0x3af6e4c6,
571 0x3b02c2f2,
572 0x3b0a8276,
573 0x3b12b782,
574 0x3b1b690d,
575 0x3b249e76,
576 0x3b2e5f8f,
577 0x3b38b49f,
578 0x3b43a669,
579 0x3b4f3e37,
580 0x3b5b85e0,
581 0x3b6887cf,
582 0x3b764f0e,
583 0x3b8273a6,
584 0x3b8a2e77,
585 0x3b925e89,
586 0x3b9b0ace,
587 0x3ba43aa2,
588 0x3badf5d1,
589 0x3bb8449c,
590 0x3bc32fc3,
591 0x3bcec08a,
592 0x3bdb00c0,
593 0x3be7facc,
594 0x3bf5b9b0,
595 0x3c02248a,
596 0x3c09daac,
597 0x3c1205c6,
598 0x3c1aacc8,
599 0x3c23d70a,
600 0x3c2d8c52,
601 0x3c37d4dd,
602 0x3c42b965,
603 0x3c4e4329,
604 0x3c5a7bf1,
605 0x3c676e1e,
606 0x3c7524ac,
607 0x3c81d59f,
608 0x3c898712,
609 0x3c91ad39,
610 0x3c9a4efc,
611 0x3ca373af,
612 0x3cad2314,
613 0x3cb76563,
614 0x3cc24350,
615 0x3ccdc614,
616 0x3cd9f773,
617 0x3ce6e1c6,
618 0x3cf49003,
619 0x3d0186e2,
620 0x3d0933ac,
621 0x3d1154e1,
622 0x3d19f169,
623 0x3d231090,
624 0x3d2cba15,
625 0x3d36f62b,
626 0x3d41cd81,
627 0x3d4d494a,
628 0x3d597345,
629 0x3d6655c3,
630 0x3d73fbb4,
631 0x3d813856,
632 0x3d88e078,
633 0x3d90fcbf,
634 0x3d99940e,
635 0x3da2adad,
636 0x3dac5156,
637 0x3db68738,
638 0x3dc157fb,
639 0x3dcccccd,
640 0x3dd8ef67,
641 0x3de5ca15,
642 0x3df367bf,
643 0x3e00e9f9,
644 0x3e088d77,
645 0x3e10a4d3,
646 0x3e1936ec,
647 0x3e224b06,
648 0x3e2be8d7,
649 0x3e361887,
650 0x3e40e2bb,
651 0x3e4c509b,
652 0x3e586bd9,
653 0x3e653ebb,
654 0x3e72d424,
655 0x3e809bcc,
656 0x3e883aa8,
657 0x3e904d1c,
658 0x3e98da02,
659 0x3ea1e89b,
660 0x3eab8097,
661 0x3eb5aa1a,
662 0x3ec06dc3,
663 0x3ecbd4b4,
664 0x3ed7e89b,
665 0x3ee4b3b6,
666 0x3ef240e2,
667 0x3f004dce,
668 0x3f07e80b,
669 0x3f0ff59a,
670 0x3f187d50,
671 0x3f21866c,
672 0x3f2b1896,
673 0x3f353bef,
674 0x3f3ff911,
675 0x3f4b5918,
676 0x3f5765ac,
677 0x3f642905,
678 0x3f71adf9,
679 0x3f800000,
680 0x3f8795a0,
681 0x3f8f9e4d,
682 0x3f9820d7,
683 0x3fa12478,
684 0x3faab0d5,
685 0x3fb4ce08,
686 0x3fbf84a6,
687 0x3fcaddc8,
688 0x3fd6e30d,
689 0x3fe39ea9,
690 0x3ff11b6a,
691 0x3fff64c1,
692 0x40074368,
693 0x400f4735,
694 0x4017c496,
695 0x4020c2bf,
696 0x402a4952,
697 0x40346063,
698 0x403f1082,
699 0x404a62c2,
700 0x405660bd,
701 0x406314a0,
702 0x40708933,
703 0x407ec9e1,
704 0x4086f161,
705 0x408ef052,
706 0x4097688d,
707 0x40a06142,
708 0x40a9e20e,
709 0x40b3f300,
710 0x40be9ca5,
711 0x40c9e807,
712 0x40d5debc,
713 0x40e28aeb,
714 0x40eff755,
715 0x40fe2f5e,
716};
717
718#define MIXART_DIGITAL_LEVEL_MIN 0
719#define MIXART_DIGITAL_LEVEL_MAX 255
720#define MIXART_DIGITAL_ZERO_LEVEL 219
721
722
723int mixart_update_playback_stream_level(struct snd_mixart* chip, int is_aes, int idx)
724{
725 int err, i;
726 int volume[2];
727 struct mixart_msg request;
728 struct mixart_set_out_stream_level_req set_level;
729 u32 status = 0;
730 struct mixart_pipe *pipe;
731
732 memset(&set_level, 0, sizeof(set_level));
733 set_level.nb_of_stream = 1;
734 set_level.stream_level.desc.stream_idx = idx;
735
736 if(is_aes) {
737 pipe = &chip->pipe_out_dig;
738 idx += MIXART_PLAYBACK_STREAMS;
739 } else {
740 pipe = &chip->pipe_out_ana;
741 }
742
743
744 if(pipe->status == PIPE_UNDEFINED)
745 return 0;
746
747 set_level.stream_level.desc.uid_pipe = pipe->group_uid;
748
749 for(i=0; i<2; i++) {
750 if(chip->digital_playback_active[idx][i])
751 volume[i] = chip->digital_playback_volume[idx][i];
752 else
753 volume[i] = MIXART_DIGITAL_LEVEL_MIN;
754 }
755
756 set_level.stream_level.out_level.valid_mask1 = MIXART_OUT_STREAM_SET_LEVEL_LEFT_AUDIO1 | MIXART_OUT_STREAM_SET_LEVEL_RIGHT_AUDIO2;
757 set_level.stream_level.out_level.left_to_out1_level = mixart_digital_level[volume[0]];
758 set_level.stream_level.out_level.right_to_out2_level = mixart_digital_level[volume[1]];
759
760 request.message_id = MSG_STREAM_SET_OUT_STREAM_LEVEL;
761 request.uid = (struct mixart_uid){0,0};
762 request.data = &set_level;
763 request.size = sizeof(set_level);
764
765 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(status), &status);
766 if((err<0) || status) {
767 dev_dbg(chip->card->dev,
768 "error MSG_STREAM_SET_OUT_STREAM_LEVEL card(%d) status(%x)\n",
769 chip->chip_idx, status);
770 return -EINVAL;
771 }
772 return 0;
773}
774
775int mixart_update_capture_stream_level(struct snd_mixart* chip, int is_aes)
776{
777 int err, i, idx;
778 struct mixart_pipe *pipe;
779 struct mixart_msg request;
780 struct mixart_set_in_audio_level_req set_level;
781 u32 status = 0;
782
783 if(is_aes) {
784 idx = 1;
785 pipe = &chip->pipe_in_dig;
786 } else {
787 idx = 0;
788 pipe = &chip->pipe_in_ana;
789 }
790
791
792 if(pipe->status == PIPE_UNDEFINED)
793 return 0;
794
795 memset(&set_level, 0, sizeof(set_level));
796 set_level.audio_count = 2;
797 set_level.level[0].connector = pipe->uid_left_connector;
798 set_level.level[1].connector = pipe->uid_right_connector;
799
800 for(i=0; i<2; i++) {
801 set_level.level[i].valid_mask1 = MIXART_AUDIO_LEVEL_DIGITAL_MASK;
802 set_level.level[i].digital_level = mixart_digital_level[chip->digital_capture_volume[idx][i]];
803 }
804
805 request.message_id = MSG_STREAM_SET_IN_AUDIO_LEVEL;
806 request.uid = (struct mixart_uid){0,0};
807 request.data = &set_level;
808 request.size = sizeof(set_level);
809
810 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(status), &status);
811 if((err<0) || status) {
812 dev_dbg(chip->card->dev,
813 "error MSG_STREAM_SET_IN_AUDIO_LEVEL card(%d) status(%x)\n",
814 chip->chip_idx, status);
815 return -EINVAL;
816 }
817 return 0;
818}
819
820
821
822static int mixart_digital_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
823{
824 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
825 uinfo->count = 2;
826 uinfo->value.integer.min = MIXART_DIGITAL_LEVEL_MIN;
827 uinfo->value.integer.max = MIXART_DIGITAL_LEVEL_MAX;
828 return 0;
829}
830
831#define MIXART_VOL_REC_MASK 1
832#define MIXART_VOL_AES_MASK 2
833
834static int mixart_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
835{
836 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
837 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
838 int *stored_volume;
839 int is_capture = kcontrol->private_value & MIXART_VOL_REC_MASK;
840 int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
841 mutex_lock(&chip->mgr->mixer_mutex);
842 if(is_capture) {
843 if(is_aes) stored_volume = chip->digital_capture_volume[1];
844 else stored_volume = chip->digital_capture_volume[0];
845 } else {
846 snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
847 if(is_aes) stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx];
848 else stored_volume = chip->digital_playback_volume[idx];
849 }
850 ucontrol->value.integer.value[0] = stored_volume[0];
851 ucontrol->value.integer.value[1] = stored_volume[1];
852 mutex_unlock(&chip->mgr->mixer_mutex);
853 return 0;
854}
855
856static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
857{
858 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
859 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
860 int changed = 0;
861 int is_capture = kcontrol->private_value & MIXART_VOL_REC_MASK;
862 int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
863 int* stored_volume;
864 int i;
865 mutex_lock(&chip->mgr->mixer_mutex);
866 if (is_capture) {
867 if (is_aes)
868 stored_volume = chip->digital_capture_volume[1];
869 else
870 stored_volume = chip->digital_capture_volume[0];
871 } else {
872 snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
873 if (is_aes)
874 stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx];
875 else
876 stored_volume = chip->digital_playback_volume[idx];
877 }
878 for (i = 0; i < 2; i++) {
879 int vol = ucontrol->value.integer.value[i];
880 if (vol < MIXART_DIGITAL_LEVEL_MIN ||
881 vol > MIXART_DIGITAL_LEVEL_MAX)
882 continue;
883 if (stored_volume[i] != vol) {
884 stored_volume[i] = vol;
885 changed = 1;
886 }
887 }
888 if (changed) {
889 if (is_capture)
890 mixart_update_capture_stream_level(chip, is_aes);
891 else
892 mixart_update_playback_stream_level(chip, is_aes, idx);
893 }
894 mutex_unlock(&chip->mgr->mixer_mutex);
895 return changed;
896}
897
898static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0);
899
900static const struct snd_kcontrol_new snd_mixart_pcm_vol =
901{
902 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
903 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
904 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
905
906
907 .info = mixart_digital_vol_info,
908 .get = mixart_pcm_vol_get,
909 .put = mixart_pcm_vol_put,
910 .tlv = { .p = db_scale_digital },
911};
912
913
914static int mixart_pcm_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
915{
916 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
917 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
918 snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
919 mutex_lock(&chip->mgr->mixer_mutex);
920 if(kcontrol->private_value & MIXART_VOL_AES_MASK)
921 idx += MIXART_PLAYBACK_STREAMS;
922 ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0];
923 ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1];
924 mutex_unlock(&chip->mgr->mixer_mutex);
925 return 0;
926}
927
928static int mixart_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
929{
930 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
931 int changed = 0;
932 int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
933 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
934 int i, j;
935 snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
936 mutex_lock(&chip->mgr->mixer_mutex);
937 j = idx;
938 if (is_aes)
939 j += MIXART_PLAYBACK_STREAMS;
940 for (i = 0; i < 2; i++) {
941 if (chip->digital_playback_active[j][i] !=
942 ucontrol->value.integer.value[i]) {
943 chip->digital_playback_active[j][i] =
944 !!ucontrol->value.integer.value[i];
945 changed = 1;
946 }
947 }
948 if (changed)
949 mixart_update_playback_stream_level(chip, is_aes, idx);
950 mutex_unlock(&chip->mgr->mixer_mutex);
951 return changed;
952}
953
954static const struct snd_kcontrol_new mixart_control_pcm_switch = {
955 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
956
957 .count = MIXART_PLAYBACK_STREAMS,
958 .info = mixart_sw_info,
959 .get = mixart_pcm_sw_get,
960 .put = mixart_pcm_sw_put
961};
962
963static int mixart_update_monitoring(struct snd_mixart* chip, int channel)
964{
965 int err;
966 struct mixart_msg request;
967 struct mixart_set_out_audio_level audio_level;
968 u32 resp = 0;
969
970 if(chip->pipe_out_ana.status == PIPE_UNDEFINED)
971 return -EINVAL;
972
973 if(!channel) request.uid = chip->pipe_out_ana.uid_left_connector;
974 else request.uid = chip->pipe_out_ana.uid_right_connector;
975 request.message_id = MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL;
976 request.data = &audio_level;
977 request.size = sizeof(audio_level);
978
979 memset(&audio_level, 0, sizeof(audio_level));
980 audio_level.valid_mask1 = MIXART_AUDIO_LEVEL_MONITOR_MASK | MIXART_AUDIO_LEVEL_MUTE_M1_MASK;
981 audio_level.monitor_level = mixart_digital_level[chip->monitoring_volume[channel!=0]];
982 audio_level.monitor_mute1 = !chip->monitoring_active[channel!=0];
983
984 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(resp), &resp);
985 if((err<0) || resp) {
986 dev_dbg(chip->card->dev,
987 "error MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL card(%d) resp(%x)\n",
988 chip->chip_idx, resp);
989 return -EINVAL;
990 }
991 return 0;
992}
993
994
995
996
997
998static int mixart_monitor_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
999{
1000 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
1001 mutex_lock(&chip->mgr->mixer_mutex);
1002 ucontrol->value.integer.value[0] = chip->monitoring_volume[0];
1003 ucontrol->value.integer.value[1] = chip->monitoring_volume[1];
1004 mutex_unlock(&chip->mgr->mixer_mutex);
1005 return 0;
1006}
1007
1008static int mixart_monitor_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1009{
1010 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
1011 int changed = 0;
1012 int i;
1013 mutex_lock(&chip->mgr->mixer_mutex);
1014 for (i = 0; i < 2; i++) {
1015 if (chip->monitoring_volume[i] !=
1016 ucontrol->value.integer.value[i]) {
1017 chip->monitoring_volume[i] =
1018 !!ucontrol->value.integer.value[i];
1019 mixart_update_monitoring(chip, i);
1020 changed = 1;
1021 }
1022 }
1023 mutex_unlock(&chip->mgr->mixer_mutex);
1024 return changed;
1025}
1026
1027static const struct snd_kcontrol_new mixart_control_monitor_vol = {
1028 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1029 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1030 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1031 .name = "Monitoring Volume",
1032 .info = mixart_digital_vol_info,
1033 .get = mixart_monitor_vol_get,
1034 .put = mixart_monitor_vol_put,
1035 .tlv = { .p = db_scale_digital },
1036};
1037
1038
1039
1040
1041
1042static int mixart_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1043{
1044 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
1045 mutex_lock(&chip->mgr->mixer_mutex);
1046 ucontrol->value.integer.value[0] = chip->monitoring_active[0];
1047 ucontrol->value.integer.value[1] = chip->monitoring_active[1];
1048 mutex_unlock(&chip->mgr->mixer_mutex);
1049 return 0;
1050}
1051
1052static int mixart_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1053{
1054 struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
1055 int changed = 0;
1056 int i;
1057 mutex_lock(&chip->mgr->mixer_mutex);
1058 for (i = 0; i < 2; i++) {
1059 if (chip->monitoring_active[i] !=
1060 ucontrol->value.integer.value[i]) {
1061 chip->monitoring_active[i] =
1062 !!ucontrol->value.integer.value[i];
1063 changed |= (1<<i);
1064 }
1065 }
1066 if (changed) {
1067
1068 int allocate = chip->monitoring_active[0] ||
1069 chip->monitoring_active[1];
1070 if (allocate) {
1071
1072 snd_mixart_add_ref_pipe(chip, MIXART_PCM_ANALOG, 0, 1);
1073
1074 snd_mixart_add_ref_pipe(chip, MIXART_PCM_ANALOG, 1, 1);
1075 }
1076 if (changed & 0x01)
1077 mixart_update_monitoring(chip, 0);
1078 if (changed & 0x02)
1079 mixart_update_monitoring(chip, 1);
1080 if (!allocate) {
1081
1082 snd_mixart_kill_ref_pipe(chip->mgr,
1083 &chip->pipe_in_ana, 1);
1084
1085 snd_mixart_kill_ref_pipe(chip->mgr,
1086 &chip->pipe_out_ana, 1);
1087 }
1088 }
1089
1090 mutex_unlock(&chip->mgr->mixer_mutex);
1091 return (changed != 0);
1092}
1093
1094static const struct snd_kcontrol_new mixart_control_monitor_sw = {
1095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1096 .name = "Monitoring Switch",
1097 .info = mixart_sw_info,
1098 .get = mixart_monitor_sw_get,
1099 .put = mixart_monitor_sw_put
1100};
1101
1102
1103static void mixart_reset_audio_levels(struct snd_mixart *chip)
1104{
1105
1106 mixart_update_analog_audio_level(chip, 0);
1107
1108 if(chip->chip_idx < 2) {
1109 mixart_update_analog_audio_level(chip, 1);
1110 }
1111 return;
1112}
1113
1114
1115int snd_mixart_create_mixer(struct mixart_mgr *mgr)
1116{
1117 struct snd_mixart *chip;
1118 int err, i;
1119
1120 mutex_init(&mgr->mixer_mutex);
1121
1122 for(i=0; i<mgr->num_cards; i++) {
1123 struct snd_kcontrol_new temp;
1124 chip = mgr->chip[i];
1125
1126
1127 temp = mixart_control_analog_level;
1128 temp.name = "Master Playback Volume";
1129 temp.private_value = 0;
1130 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1131 return err;
1132
1133 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_output_switch, chip))) < 0)
1134 return err;
1135
1136
1137 if(i<2) {
1138 temp = mixart_control_analog_level;
1139 temp.name = "Master Capture Volume";
1140 temp.private_value = 1;
1141 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1142 return err;
1143 }
1144
1145 temp = snd_mixart_pcm_vol;
1146 temp.name = "PCM Playback Volume";
1147 temp.count = MIXART_PLAYBACK_STREAMS;
1148 temp.private_value = 0;
1149 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1150 return err;
1151
1152 temp.name = "PCM Capture Volume";
1153 temp.count = 1;
1154 temp.private_value = MIXART_VOL_REC_MASK;
1155 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1156 return err;
1157
1158 if(mgr->board_type == MIXART_DAUGHTER_TYPE_AES) {
1159 temp.name = "AES Playback Volume";
1160 temp.count = MIXART_PLAYBACK_STREAMS;
1161 temp.private_value = MIXART_VOL_AES_MASK;
1162 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1163 return err;
1164
1165 temp.name = "AES Capture Volume";
1166 temp.count = 0;
1167 temp.private_value = MIXART_VOL_REC_MASK | MIXART_VOL_AES_MASK;
1168 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1169 return err;
1170 }
1171 temp = mixart_control_pcm_switch;
1172 temp.name = "PCM Playback Switch";
1173 temp.private_value = 0;
1174 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1175 return err;
1176
1177 if(mgr->board_type == MIXART_DAUGHTER_TYPE_AES) {
1178 temp.name = "AES Playback Switch";
1179 temp.private_value = MIXART_VOL_AES_MASK;
1180 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
1181 return err;
1182 }
1183
1184
1185 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_monitor_vol, chip))) < 0)
1186 return err;
1187 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_monitor_sw, chip))) < 0)
1188 return err;
1189
1190
1191 mixart_reset_audio_levels(chip);
1192 }
1193 return 0;
1194}
1195