2 * linux/sound/oss/dmasound/trans_16.c
4 * 16 bit translation routines. Only used by Power mac at present.
6 * See linux/sound/oss/dmasound/dmasound_core.c for copyright and
7 * history prior to 08/02/2001.
9 * 08/02/2001 Iain Sandoe
10 * split from dmasound_awacs.c
11 * 11/29/2003 Renzo Davoli (King Enzo)
12 * - input resampling (for soft rate < hard rate)
13 * - software line in gain control
16 #include <linux/soundcard.h>
17 #include <asm/uaccess.h>
20 extern int expand_bal; /* Balance factor for expanding (not volume!) */
21 static short dmasound_alaw2dma16[] ;
22 static short dmasound_ulaw2dma16[] ;
24 static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
25 u_char frame[], ssize_t *frameUsed,
27 static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
28 u_char frame[], ssize_t *frameUsed,
30 static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
31 u_char frame[], ssize_t *frameUsed,
33 static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
34 u_char frame[], ssize_t *frameUsed,
36 static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount,
37 u_char frame[], ssize_t *frameUsed,
40 static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
41 u_char frame[], ssize_t *frameUsed,
43 static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
44 u_char frame[], ssize_t *frameUsed,
46 static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
47 u_char frame[], ssize_t *frameUsed,
49 static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
50 u_char frame[], ssize_t *frameUsed,
52 static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount,
53 u_char frame[], ssize_t *frameUsed,
56 static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount,
57 u_char frame[], ssize_t *frameUsed,
59 static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount,
60 u_char frame[], ssize_t *frameUsed,
63 /*** Translations ************************************************************/
65 static int expand_data; /* Data for expanding */
67 static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
68 u_char frame[], ssize_t *frameUsed,
71 short *table = dmasound.soft.format == AFMT_MU_LAW
72 ? dmasound_ulaw2dma16 : dmasound_alaw2dma16;
74 short *p = (short *) &frame[*frameUsed];
75 int val, stereo = dmasound.soft.stereo;
80 used = count = min_t(unsigned long, userCount, frameLeft);
83 if (get_user(data, userPtr++))
88 if (get_user(data, userPtr++))
95 *frameUsed += used * 4;
96 return stereo? used * 2: used;
100 static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
101 u_char frame[], ssize_t *frameUsed,
105 short *p = (short *) &frame[*frameUsed];
106 int val, stereo = dmasound.soft.stereo;
111 used = count = min_t(unsigned long, userCount, frameLeft);
114 if (get_user(data, userPtr++))
119 if (get_user(data, userPtr++))
126 *frameUsed += used * 4;
127 return stereo? used * 2: used;
131 static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
132 u_char frame[], ssize_t *frameUsed,
136 short *p = (short *) &frame[*frameUsed];
137 int val, stereo = dmasound.soft.stereo;
142 used = count = min_t(unsigned long, userCount, frameLeft);
145 if (get_user(data, userPtr++))
147 val = (data ^ 0x80) << 8;
150 if (get_user(data, userPtr++))
152 val = (data ^ 0x80) << 8;
157 *frameUsed += used * 4;
158 return stereo? used * 2: used;
162 static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
163 u_char frame[], ssize_t *frameUsed,
167 int stereo = dmasound.soft.stereo;
168 short *fp = (short *) &frame[*frameUsed];
171 userCount >>= (stereo? 2: 1);
172 used = count = min_t(unsigned long, userCount, frameLeft);
174 short __user *up = (short __user *) userPtr;
177 if (get_user(data, up++))
184 if (copy_from_user(fp, userPtr, count * 4))
187 *frameUsed += used * 4;
188 return stereo? used * 4: used * 2;
191 static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount,
192 u_char frame[], ssize_t *frameUsed,
196 int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
197 int stereo = dmasound.soft.stereo;
198 short *fp = (short *) &frame[*frameUsed];
199 short __user *up = (short __user *) userPtr;
202 userCount >>= (stereo? 2: 1);
203 used = count = min_t(unsigned long, userCount, frameLeft);
206 if (get_user(data, up++))
211 if (get_user(data, up++))
218 *frameUsed += used * 4;
219 return stereo? used * 4: used * 2;
223 static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
224 u_char frame[], ssize_t *frameUsed,
227 unsigned short *table = (unsigned short *)
228 (dmasound.soft.format == AFMT_MU_LAW
229 ? dmasound_ulaw2dma16 : dmasound_alaw2dma16);
230 unsigned int data = expand_data;
231 unsigned int *p = (unsigned int *) &frame[*frameUsed];
232 int bal = expand_bal;
233 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
235 int stereo = dmasound.soft.stereo;
247 if (get_user(c, userPtr++))
251 if (get_user(c, userPtr++))
253 data = (data << 16) + table[c];
255 data = (data << 16) + data;
265 *frameUsed += (ftotal - frameLeft) * 4;
267 return stereo? utotal * 2: utotal;
270 static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
271 u_char frame[], ssize_t *frameUsed,
274 unsigned int *p = (unsigned int *) &frame[*frameUsed];
275 unsigned int data = expand_data;
276 int bal = expand_bal;
277 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
278 int stereo = dmasound.soft.stereo;
291 if (get_user(c, userPtr++))
295 if (get_user(c, userPtr++))
297 data = (data << 16) + (c << 8);
299 data = (data << 16) + data;
309 *frameUsed += (ftotal - frameLeft) * 4;
311 return stereo? utotal * 2: utotal;
315 static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
316 u_char frame[], ssize_t *frameUsed,
319 unsigned int *p = (unsigned int *) &frame[*frameUsed];
320 unsigned int data = expand_data;
321 int bal = expand_bal;
322 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
323 int stereo = dmasound.soft.stereo;
336 if (get_user(c, userPtr++))
338 data = (c ^ 0x80) << 8;
340 if (get_user(c, userPtr++))
342 data = (data << 16) + ((c ^ 0x80) << 8);
344 data = (data << 16) + data;
354 *frameUsed += (ftotal - frameLeft) * 4;
356 return stereo? utotal * 2: utotal;
360 static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
361 u_char frame[], ssize_t *frameUsed,
364 unsigned int *p = (unsigned int *) &frame[*frameUsed];
365 unsigned int data = expand_data;
366 unsigned short __user *up = (unsigned short __user *) userPtr;
367 int bal = expand_bal;
368 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
369 int stereo = dmasound.soft.stereo;
373 userCount >>= (stereo? 2: 1);
381 if (get_user(data, up++))
384 if (get_user(c, up++))
386 data = (data << 16) + c;
388 data = (data << 16) + data;
398 *frameUsed += (ftotal - frameLeft) * 4;
400 return stereo? utotal * 4: utotal * 2;
404 static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount,
405 u_char frame[], ssize_t *frameUsed,
408 int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
409 unsigned int *p = (unsigned int *) &frame[*frameUsed];
410 unsigned int data = expand_data;
411 unsigned short __user *up = (unsigned short __user *) userPtr;
412 int bal = expand_bal;
413 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
414 int stereo = dmasound.soft.stereo;
418 userCount >>= (stereo? 2: 1);
426 if (get_user(data, up++))
430 if (get_user(c, up++))
432 data = (data << 16) + (c ^ mask);
434 data = (data << 16) + data;
444 *frameUsed += (ftotal - frameLeft) * 4;
446 return stereo? utotal * 4: utotal * 2;
449 /* data in routines... */
451 static ssize_t pmac_ct_s8_read(const u_char __user *userPtr, size_t userCount,
452 u_char frame[], ssize_t *frameUsed,
456 short *p = (short *) &frame[*frameUsed];
457 int val, stereo = dmasound.soft.stereo;
462 used = count = min_t(unsigned long, userCount, frameLeft);
467 val = (val * software_input_volume) >> 7;
469 if (put_user(data, (u_char __user *)userPtr++))
473 val = (val * software_input_volume) >> 7;
475 if (put_user(data, (u_char __user *)userPtr++))
481 *frameUsed += used * 4;
482 return stereo? used * 2: used;
486 static ssize_t pmac_ct_u8_read(const u_char __user *userPtr, size_t userCount,
487 u_char frame[], ssize_t *frameUsed,
491 short *p = (short *) &frame[*frameUsed];
492 int val, stereo = dmasound.soft.stereo;
497 used = count = min_t(unsigned long, userCount, frameLeft);
502 val = (val * software_input_volume) >> 7;
503 data = (val >> 8) ^ 0x80;
504 if (put_user(data, (u_char __user *)userPtr++))
508 val = (val * software_input_volume) >> 7;
509 data = (val >> 8) ^ 0x80;
510 if (put_user(data, (u_char __user *)userPtr++))
516 *frameUsed += used * 4;
517 return stereo? used * 2: used;
520 static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount,
521 u_char frame[], ssize_t *frameUsed,
525 int stereo = dmasound.soft.stereo;
526 short *fp = (short *) &frame[*frameUsed];
527 short __user *up = (short __user *) userPtr;
530 userCount >>= (stereo? 2: 1);
531 used = count = min_t(unsigned long, userCount, frameLeft);
536 data = (data * software_input_volume) >> 7;
537 if (put_user(data, up++))
541 data = (data * software_input_volume) >> 7;
542 if (put_user(data, up++))
548 *frameUsed += used * 4;
549 return stereo? used * 4: used * 2;
552 static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount,
553 u_char frame[], ssize_t *frameUsed,
557 int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
558 int stereo = dmasound.soft.stereo;
559 short *fp = (short *) &frame[*frameUsed];
560 short __user *up = (short __user *) userPtr;
563 userCount >>= (stereo? 2: 1);
564 used = count = min_t(unsigned long, userCount, frameLeft);
569 data = (data * software_input_volume) >> 7;
571 if (put_user(data, up++))
575 data = (data * software_input_volume) >> 7;
577 if (put_user(data, up++))
583 *frameUsed += used * 4;
584 return stereo? used * 4: used * 2;
587 /* data in routines (reducing speed)... */
589 static ssize_t pmac_ctx_s8_read(const u_char __user *userPtr, size_t userCount,
590 u_char frame[], ssize_t *frameUsed,
593 short *p = (short *) &frame[*frameUsed];
594 int bal = expand_read_bal;
595 int vall,valr, stereo = dmasound.soft.stereo;
596 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
607 if (bal<0 && userCount == 0)
610 vall = (vall * software_input_volume) >> 7;
613 valr = (valr * software_input_volume) >> 7;
618 if (put_user(data, (u_char __user *)userPtr++))
622 if (put_user(data, (u_char __user *)userPtr++))
632 *frameUsed += (ftotal - frameLeft) * 4;
634 return stereo? utotal * 2: utotal;
638 static ssize_t pmac_ctx_u8_read(const u_char __user *userPtr, size_t userCount,
639 u_char frame[], ssize_t *frameUsed,
642 short *p = (short *) &frame[*frameUsed];
643 int bal = expand_read_bal;
644 int vall,valr, stereo = dmasound.soft.stereo;
645 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
656 if (bal<0 && userCount == 0)
660 vall = (vall * software_input_volume) >> 7;
663 valr = (valr * software_input_volume) >> 7;
667 data = (vall >> 8) ^ 0x80;
668 if (put_user(data, (u_char __user *)userPtr++))
671 data = (valr >> 8) ^ 0x80;
672 if (put_user(data, (u_char __user *)userPtr++))
682 *frameUsed += (ftotal - frameLeft) * 4;
684 return stereo? utotal * 2: utotal;
687 static ssize_t pmac_ctx_s16_read(const u_char __user *userPtr, size_t userCount,
688 u_char frame[], ssize_t *frameUsed,
691 int bal = expand_read_bal;
692 short *fp = (short *) &frame[*frameUsed];
693 short __user *up = (short __user *) userPtr;
694 int stereo = dmasound.soft.stereo;
695 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
699 userCount >>= (stereo? 2: 1);
705 if (bal<0 && userCount == 0)
709 datal = (datal * software_input_volume) >> 7;
712 datar = (datar * software_input_volume) >> 7;
716 if (put_user(datal, up++))
719 if (put_user(datar, up++))
729 *frameUsed += (ftotal - frameLeft) * 4;
731 return stereo? utotal * 4: utotal * 2;
734 static ssize_t pmac_ctx_u16_read(const u_char __user *userPtr, size_t userCount,
735 u_char frame[], ssize_t *frameUsed,
738 int bal = expand_read_bal;
739 int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
740 short *fp = (short *) &frame[*frameUsed];
741 short __user *up = (short __user *) userPtr;
742 int stereo = dmasound.soft.stereo;
743 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
747 userCount >>= (stereo? 2: 1);
753 if (bal<0 && userCount == 0)
757 datal = (datal * software_input_volume) >> 7;
761 datar = (datar * software_input_volume) >> 7;
766 if (put_user(datal, up++))
769 if (put_user(datar, up++))
779 *frameUsed += (ftotal - frameLeft) * 4;
781 return stereo? utotal * 4: utotal * 2;
785 TRANS transAwacsNormal = {
786 .ct_ulaw= pmac_ct_law,
787 .ct_alaw= pmac_ct_law,
790 .ct_s16be= pmac_ct_s16,
791 .ct_u16be= pmac_ct_u16,
792 .ct_s16le= pmac_ct_s16,
793 .ct_u16le= pmac_ct_u16,
796 TRANS transAwacsExpand = {
797 .ct_ulaw= pmac_ctx_law,
798 .ct_alaw= pmac_ctx_law,
801 .ct_s16be= pmac_ctx_s16,
802 .ct_u16be= pmac_ctx_u16,
803 .ct_s16le= pmac_ctx_s16,
804 .ct_u16le= pmac_ctx_u16,
807 TRANS transAwacsNormalRead = {
808 .ct_s8= pmac_ct_s8_read,
809 .ct_u8= pmac_ct_u8_read,
810 .ct_s16be= pmac_ct_s16_read,
811 .ct_u16be= pmac_ct_u16_read,
812 .ct_s16le= pmac_ct_s16_read,
813 .ct_u16le= pmac_ct_u16_read,
816 TRANS transAwacsExpandRead = {
817 .ct_s8= pmac_ctx_s8_read,
818 .ct_u8= pmac_ctx_u8_read,
819 .ct_s16be= pmac_ctx_s16_read,
820 .ct_u16be= pmac_ctx_u16_read,
821 .ct_s16le= pmac_ctx_s16_read,
822 .ct_u16le= pmac_ctx_u16_read,
825 /* translation tables */
828 static short dmasound_ulaw2dma16[] = {
829 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
830 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
831 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
832 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
833 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
834 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
835 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
836 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
837 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
838 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
839 -876, -844, -812, -780, -748, -716, -684, -652,
840 -620, -588, -556, -524, -492, -460, -428, -396,
841 -372, -356, -340, -324, -308, -292, -276, -260,
842 -244, -228, -212, -196, -180, -164, -148, -132,
843 -120, -112, -104, -96, -88, -80, -72, -64,
844 -56, -48, -40, -32, -24, -16, -8, 0,
845 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
846 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
847 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
848 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
849 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
850 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
851 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
852 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
853 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
854 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
855 876, 844, 812, 780, 748, 716, 684, 652,
856 620, 588, 556, 524, 492, 460, 428, 396,
857 372, 356, 340, 324, 308, 292, 276, 260,
858 244, 228, 212, 196, 180, 164, 148, 132,
859 120, 112, 104, 96, 88, 80, 72, 64,
860 56, 48, 40, 32, 24, 16, 8, 0,
865 static short dmasound_alaw2dma16[] = {
866 -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
867 -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
868 -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
869 -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
870 -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
871 -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
872 -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
873 -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
874 -344, -328, -376, -360, -280, -264, -312, -296,
875 -472, -456, -504, -488, -408, -392, -440, -424,
876 -88, -72, -120, -104, -24, -8, -56, -40,
877 -216, -200, -248, -232, -152, -136, -184, -168,
878 -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
879 -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
880 -688, -656, -752, -720, -560, -528, -624, -592,
881 -944, -912, -1008, -976, -816, -784, -880, -848,
882 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
883 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
884 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
885 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
886 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
887 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
888 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
889 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
890 344, 328, 376, 360, 280, 264, 312, 296,
891 472, 456, 504, 488, 408, 392, 440, 424,
892 88, 72, 120, 104, 24, 8, 56, 40,
893 216, 200, 248, 232, 152, 136, 184, 168,
894 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
895 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
896 688, 656, 752, 720, 560, 528, 624, 592,
897 944, 912, 1008, 976, 816, 784, 880, 848,