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 static short dmasound_alaw2dma16[] ;
21 static short dmasound_ulaw2dma16[] ;
23 static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
24 u_char frame[], ssize_t *frameUsed,
26 static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
27 u_char frame[], ssize_t *frameUsed,
29 static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
30 u_char frame[], ssize_t *frameUsed,
32 static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
33 u_char frame[], ssize_t *frameUsed,
35 static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount,
36 u_char frame[], ssize_t *frameUsed,
39 static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
40 u_char frame[], ssize_t *frameUsed,
42 static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
43 u_char frame[], ssize_t *frameUsed,
45 static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
46 u_char frame[], ssize_t *frameUsed,
48 static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
49 u_char frame[], ssize_t *frameUsed,
51 static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount,
52 u_char frame[], ssize_t *frameUsed,
55 static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount,
56 u_char frame[], ssize_t *frameUsed,
58 static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount,
59 u_char frame[], ssize_t *frameUsed,
62 /*** Translations ************************************************************/
64 static int expand_data; /* Data for expanding */
66 static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
67 u_char frame[], ssize_t *frameUsed,
70 short *table = dmasound.soft.format == AFMT_MU_LAW
71 ? dmasound_ulaw2dma16 : dmasound_alaw2dma16;
73 short *p = (short *) &frame[*frameUsed];
74 int val, stereo = dmasound.soft.stereo;
79 used = count = min_t(unsigned long, userCount, frameLeft);
82 if (get_user(data, userPtr++))
87 if (get_user(data, userPtr++))
94 *frameUsed += used * 4;
95 return stereo? used * 2: used;
99 static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
100 u_char frame[], ssize_t *frameUsed,
104 short *p = (short *) &frame[*frameUsed];
105 int val, stereo = dmasound.soft.stereo;
110 used = count = min_t(unsigned long, userCount, frameLeft);
113 if (get_user(data, userPtr++))
118 if (get_user(data, userPtr++))
125 *frameUsed += used * 4;
126 return stereo? used * 2: used;
130 static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
131 u_char frame[], ssize_t *frameUsed,
135 short *p = (short *) &frame[*frameUsed];
136 int val, stereo = dmasound.soft.stereo;
141 used = count = min_t(unsigned long, userCount, frameLeft);
144 if (get_user(data, userPtr++))
146 val = (data ^ 0x80) << 8;
149 if (get_user(data, userPtr++))
151 val = (data ^ 0x80) << 8;
156 *frameUsed += used * 4;
157 return stereo? used * 2: used;
161 static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
162 u_char frame[], ssize_t *frameUsed,
166 int stereo = dmasound.soft.stereo;
167 short *fp = (short *) &frame[*frameUsed];
170 userCount >>= (stereo? 2: 1);
171 used = count = min_t(unsigned long, userCount, frameLeft);
173 short __user *up = (short __user *) userPtr;
176 if (get_user(data, up++))
183 if (copy_from_user(fp, userPtr, count * 4))
186 *frameUsed += used * 4;
187 return stereo? used * 4: used * 2;
190 static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount,
191 u_char frame[], ssize_t *frameUsed,
195 int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
196 int stereo = dmasound.soft.stereo;
197 short *fp = (short *) &frame[*frameUsed];
198 short __user *up = (short __user *) userPtr;
201 userCount >>= (stereo? 2: 1);
202 used = count = min_t(unsigned long, userCount, frameLeft);
205 if (get_user(data, up++))
210 if (get_user(data, up++))
217 *frameUsed += used * 4;
218 return stereo? used * 4: used * 2;
222 static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
223 u_char frame[], ssize_t *frameUsed,
226 unsigned short *table = (unsigned short *)
227 (dmasound.soft.format == AFMT_MU_LAW
228 ? dmasound_ulaw2dma16 : dmasound_alaw2dma16);
229 unsigned int data = expand_data;
230 unsigned int *p = (unsigned int *) &frame[*frameUsed];
231 int bal = expand_bal;
232 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
234 int stereo = dmasound.soft.stereo;
246 if (get_user(c, userPtr++))
250 if (get_user(c, userPtr++))
252 data = (data << 16) + table[c];
254 data = (data << 16) + data;
264 *frameUsed += (ftotal - frameLeft) * 4;
266 return stereo? utotal * 2: utotal;
269 static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
270 u_char frame[], ssize_t *frameUsed,
273 unsigned int *p = (unsigned int *) &frame[*frameUsed];
274 unsigned int data = expand_data;
275 int bal = expand_bal;
276 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
277 int stereo = dmasound.soft.stereo;
290 if (get_user(c, userPtr++))
294 if (get_user(c, userPtr++))
296 data = (data << 16) + (c << 8);
298 data = (data << 16) + data;
308 *frameUsed += (ftotal - frameLeft) * 4;
310 return stereo? utotal * 2: utotal;
314 static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
315 u_char frame[], ssize_t *frameUsed,
318 unsigned int *p = (unsigned int *) &frame[*frameUsed];
319 unsigned int data = expand_data;
320 int bal = expand_bal;
321 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
322 int stereo = dmasound.soft.stereo;
335 if (get_user(c, userPtr++))
337 data = (c ^ 0x80) << 8;
339 if (get_user(c, userPtr++))
341 data = (data << 16) + ((c ^ 0x80) << 8);
343 data = (data << 16) + data;
353 *frameUsed += (ftotal - frameLeft) * 4;
355 return stereo? utotal * 2: utotal;
359 static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
360 u_char frame[], ssize_t *frameUsed,
363 unsigned int *p = (unsigned int *) &frame[*frameUsed];
364 unsigned int data = expand_data;
365 unsigned short __user *up = (unsigned short __user *) userPtr;
366 int bal = expand_bal;
367 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
368 int stereo = dmasound.soft.stereo;
372 userCount >>= (stereo? 2: 1);
380 if (get_user(data, up++))
383 if (get_user(c, up++))
385 data = (data << 16) + c;
387 data = (data << 16) + data;
397 *frameUsed += (ftotal - frameLeft) * 4;
399 return stereo? utotal * 4: utotal * 2;
403 static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount,
404 u_char frame[], ssize_t *frameUsed,
407 int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
408 unsigned int *p = (unsigned int *) &frame[*frameUsed];
409 unsigned int data = expand_data;
410 unsigned short __user *up = (unsigned short __user *) userPtr;
411 int bal = expand_bal;
412 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
413 int stereo = dmasound.soft.stereo;
417 userCount >>= (stereo? 2: 1);
425 if (get_user(data, up++))
429 if (get_user(c, up++))
431 data = (data << 16) + (c ^ mask);
433 data = (data << 16) + data;
443 *frameUsed += (ftotal - frameLeft) * 4;
445 return stereo? utotal * 4: utotal * 2;
448 /* data in routines... */
450 static ssize_t pmac_ct_s8_read(const u_char __user *userPtr, size_t userCount,
451 u_char frame[], ssize_t *frameUsed,
455 short *p = (short *) &frame[*frameUsed];
456 int val, stereo = dmasound.soft.stereo;
461 used = count = min_t(unsigned long, userCount, frameLeft);
466 val = (val * software_input_volume) >> 7;
468 if (put_user(data, (u_char __user *)userPtr++))
472 val = (val * software_input_volume) >> 7;
474 if (put_user(data, (u_char __user *)userPtr++))
480 *frameUsed += used * 4;
481 return stereo? used * 2: used;
485 static ssize_t pmac_ct_u8_read(const u_char __user *userPtr, size_t userCount,
486 u_char frame[], ssize_t *frameUsed,
490 short *p = (short *) &frame[*frameUsed];
491 int val, stereo = dmasound.soft.stereo;
496 used = count = min_t(unsigned long, userCount, frameLeft);
501 val = (val * software_input_volume) >> 7;
502 data = (val >> 8) ^ 0x80;
503 if (put_user(data, (u_char __user *)userPtr++))
507 val = (val * software_input_volume) >> 7;
508 data = (val >> 8) ^ 0x80;
509 if (put_user(data, (u_char __user *)userPtr++))
515 *frameUsed += used * 4;
516 return stereo? used * 2: used;
519 static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount,
520 u_char frame[], ssize_t *frameUsed,
524 int stereo = dmasound.soft.stereo;
525 short *fp = (short *) &frame[*frameUsed];
526 short __user *up = (short __user *) userPtr;
529 userCount >>= (stereo? 2: 1);
530 used = count = min_t(unsigned long, userCount, frameLeft);
535 data = (data * software_input_volume) >> 7;
536 if (put_user(data, up++))
540 data = (data * software_input_volume) >> 7;
541 if (put_user(data, up++))
547 *frameUsed += used * 4;
548 return stereo? used * 4: used * 2;
551 static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount,
552 u_char frame[], ssize_t *frameUsed,
556 int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
557 int stereo = dmasound.soft.stereo;
558 short *fp = (short *) &frame[*frameUsed];
559 short __user *up = (short __user *) userPtr;
562 userCount >>= (stereo? 2: 1);
563 used = count = min_t(unsigned long, userCount, frameLeft);
568 data = (data * software_input_volume) >> 7;
570 if (put_user(data, up++))
574 data = (data * software_input_volume) >> 7;
576 if (put_user(data, up++))
582 *frameUsed += used * 4;
583 return stereo? used * 4: used * 2;
586 /* data in routines (reducing speed)... */
588 static ssize_t pmac_ctx_s8_read(const u_char __user *userPtr, size_t userCount,
589 u_char frame[], ssize_t *frameUsed,
592 short *p = (short *) &frame[*frameUsed];
593 int bal = expand_read_bal;
594 int vall,valr, stereo = dmasound.soft.stereo;
595 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
606 if (bal<0 && userCount == 0)
609 vall = (vall * software_input_volume) >> 7;
612 valr = (valr * software_input_volume) >> 7;
617 if (put_user(data, (u_char __user *)userPtr++))
621 if (put_user(data, (u_char __user *)userPtr++))
631 *frameUsed += (ftotal - frameLeft) * 4;
633 return stereo? utotal * 2: utotal;
637 static ssize_t pmac_ctx_u8_read(const u_char __user *userPtr, size_t userCount,
638 u_char frame[], ssize_t *frameUsed,
641 short *p = (short *) &frame[*frameUsed];
642 int bal = expand_read_bal;
643 int vall,valr, stereo = dmasound.soft.stereo;
644 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
655 if (bal<0 && userCount == 0)
659 vall = (vall * software_input_volume) >> 7;
662 valr = (valr * software_input_volume) >> 7;
666 data = (vall >> 8) ^ 0x80;
667 if (put_user(data, (u_char __user *)userPtr++))
670 data = (valr >> 8) ^ 0x80;
671 if (put_user(data, (u_char __user *)userPtr++))
681 *frameUsed += (ftotal - frameLeft) * 4;
683 return stereo? utotal * 2: utotal;
686 static ssize_t pmac_ctx_s16_read(const u_char __user *userPtr, size_t userCount,
687 u_char frame[], ssize_t *frameUsed,
690 int bal = expand_read_bal;
691 short *fp = (short *) &frame[*frameUsed];
692 short __user *up = (short __user *) userPtr;
693 int stereo = dmasound.soft.stereo;
694 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
698 userCount >>= (stereo? 2: 1);
704 if (bal<0 && userCount == 0)
708 datal = (datal * software_input_volume) >> 7;
711 datar = (datar * software_input_volume) >> 7;
715 if (put_user(datal, up++))
718 if (put_user(datar, up++))
728 *frameUsed += (ftotal - frameLeft) * 4;
730 return stereo? utotal * 4: utotal * 2;
733 static ssize_t pmac_ctx_u16_read(const u_char __user *userPtr, size_t userCount,
734 u_char frame[], ssize_t *frameUsed,
737 int bal = expand_read_bal;
738 int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
739 short *fp = (short *) &frame[*frameUsed];
740 short __user *up = (short __user *) userPtr;
741 int stereo = dmasound.soft.stereo;
742 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
746 userCount >>= (stereo? 2: 1);
752 if (bal<0 && userCount == 0)
756 datal = (datal * software_input_volume) >> 7;
760 datar = (datar * software_input_volume) >> 7;
765 if (put_user(datal, up++))
768 if (put_user(datar, up++))
778 *frameUsed += (ftotal - frameLeft) * 4;
780 return stereo? utotal * 4: utotal * 2;
784 TRANS transAwacsNormal = {
785 .ct_ulaw= pmac_ct_law,
786 .ct_alaw= pmac_ct_law,
789 .ct_s16be= pmac_ct_s16,
790 .ct_u16be= pmac_ct_u16,
791 .ct_s16le= pmac_ct_s16,
792 .ct_u16le= pmac_ct_u16,
795 TRANS transAwacsExpand = {
796 .ct_ulaw= pmac_ctx_law,
797 .ct_alaw= pmac_ctx_law,
800 .ct_s16be= pmac_ctx_s16,
801 .ct_u16be= pmac_ctx_u16,
802 .ct_s16le= pmac_ctx_s16,
803 .ct_u16le= pmac_ctx_u16,
806 TRANS transAwacsNormalRead = {
807 .ct_s8= pmac_ct_s8_read,
808 .ct_u8= pmac_ct_u8_read,
809 .ct_s16be= pmac_ct_s16_read,
810 .ct_u16be= pmac_ct_u16_read,
811 .ct_s16le= pmac_ct_s16_read,
812 .ct_u16le= pmac_ct_u16_read,
815 TRANS transAwacsExpandRead = {
816 .ct_s8= pmac_ctx_s8_read,
817 .ct_u8= pmac_ctx_u8_read,
818 .ct_s16be= pmac_ctx_s16_read,
819 .ct_u16be= pmac_ctx_u16_read,
820 .ct_s16le= pmac_ctx_s16_read,
821 .ct_u16le= pmac_ctx_u16_read,
824 /* translation tables */
827 static short dmasound_ulaw2dma16[] = {
828 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
829 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
830 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
831 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
832 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
833 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
834 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
835 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
836 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
837 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
838 -876, -844, -812, -780, -748, -716, -684, -652,
839 -620, -588, -556, -524, -492, -460, -428, -396,
840 -372, -356, -340, -324, -308, -292, -276, -260,
841 -244, -228, -212, -196, -180, -164, -148, -132,
842 -120, -112, -104, -96, -88, -80, -72, -64,
843 -56, -48, -40, -32, -24, -16, -8, 0,
844 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
845 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
846 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
847 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
848 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
849 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
850 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
851 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
852 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
853 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
854 876, 844, 812, 780, 748, 716, 684, 652,
855 620, 588, 556, 524, 492, 460, 428, 396,
856 372, 356, 340, 324, 308, 292, 276, 260,
857 244, 228, 212, 196, 180, 164, 148, 132,
858 120, 112, 104, 96, 88, 80, 72, 64,
859 56, 48, 40, 32, 24, 16, 8, 0,
864 static short dmasound_alaw2dma16[] = {
865 -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
866 -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
867 -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
868 -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
869 -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
870 -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
871 -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
872 -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
873 -344, -328, -376, -360, -280, -264, -312, -296,
874 -472, -456, -504, -488, -408, -392, -440, -424,
875 -88, -72, -120, -104, -24, -8, -56, -40,
876 -216, -200, -248, -232, -152, -136, -184, -168,
877 -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
878 -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
879 -688, -656, -752, -720, -560, -528, -624, -592,
880 -944, -912, -1008, -976, -816, -784, -880, -848,
881 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
882 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
883 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
884 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
885 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
886 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
887 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
888 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
889 344, 328, 376, 360, 280, 264, 312, 296,
890 472, 456, 504, 488, 408, 392, 440, 424,
891 88, 72, 120, 104, 24, 8, 56, 40,
892 216, 200, 248, 232, 152, 136, 184, 168,
893 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
894 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
895 688, 656, 752, 720, 560, 528, 624, 592,
896 944, 912, 1008, 976, 816, 784, 880, 848,