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