aboutsummaryrefslogtreecommitdiffstats
path: root/sound/oss/dmasound/trans_16.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/oss/dmasound/trans_16.c')
-rw-r--r--sound/oss/dmasound/trans_16.c897
1 files changed, 897 insertions, 0 deletions
diff --git a/sound/oss/dmasound/trans_16.c b/sound/oss/dmasound/trans_16.c
new file mode 100644
index 000000000000..23562e947806
--- /dev/null
+++ b/sound/oss/dmasound/trans_16.c
@@ -0,0 +1,897 @@
1/*
2 * linux/sound/oss/dmasound/trans_16.c
3 *
4 * 16 bit translation routines. Only used by Power mac at present.
5 *
6 * See linux/sound/oss/dmasound/dmasound_core.c for copyright and
7 * history prior to 08/02/2001.
8 *
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
14 */
15
16#include <linux/soundcard.h>
17#include <asm/uaccess.h>
18#include "dmasound.h"
19
20static short dmasound_alaw2dma16[] ;
21static short dmasound_ulaw2dma16[] ;
22
23static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
24 u_char frame[], ssize_t *frameUsed,
25 ssize_t frameLeft);
26static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
27 u_char frame[], ssize_t *frameUsed,
28 ssize_t frameLeft);
29static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
30 u_char frame[], ssize_t *frameUsed,
31 ssize_t frameLeft);
32static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
33 u_char frame[], ssize_t *frameUsed,
34 ssize_t frameLeft);
35static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount,
36 u_char frame[], ssize_t *frameUsed,
37 ssize_t frameLeft);
38
39static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
40 u_char frame[], ssize_t *frameUsed,
41 ssize_t frameLeft);
42static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
43 u_char frame[], ssize_t *frameUsed,
44 ssize_t frameLeft);
45static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
46 u_char frame[], ssize_t *frameUsed,
47 ssize_t frameLeft);
48static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
49 u_char frame[], ssize_t *frameUsed,
50 ssize_t frameLeft);
51static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount,
52 u_char frame[], ssize_t *frameUsed,
53 ssize_t frameLeft);
54
55static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount,
56 u_char frame[], ssize_t *frameUsed,
57 ssize_t frameLeft);
58static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount,
59 u_char frame[], ssize_t *frameUsed,
60 ssize_t frameLeft);
61
62/*** Translations ************************************************************/
63
64static int expand_data; /* Data for expanding */
65
66static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
67 u_char frame[], ssize_t *frameUsed,
68 ssize_t frameLeft)
69{
70 short *table = dmasound.soft.format == AFMT_MU_LAW
71 ? dmasound_ulaw2dma16 : dmasound_alaw2dma16;
72 ssize_t count, used;
73 short *p = (short *) &frame[*frameUsed];
74 int val, stereo = dmasound.soft.stereo;
75
76 frameLeft >>= 2;
77 if (stereo)
78 userCount >>= 1;
79 used = count = min_t(unsigned long, userCount, frameLeft);
80 while (count > 0) {
81 u_char data;
82 if (get_user(data, userPtr++))
83 return -EFAULT;
84 val = table[data];
85 *p++ = val;
86 if (stereo) {
87 if (get_user(data, userPtr++))
88 return -EFAULT;
89 val = table[data];
90 }
91 *p++ = val;
92 count--;
93 }
94 *frameUsed += used * 4;
95 return stereo? used * 2: used;
96}
97
98
99static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
100 u_char frame[], ssize_t *frameUsed,
101 ssize_t frameLeft)
102{
103 ssize_t count, used;
104 short *p = (short *) &frame[*frameUsed];
105 int val, stereo = dmasound.soft.stereo;
106
107 frameLeft >>= 2;
108 if (stereo)
109 userCount >>= 1;
110 used = count = min_t(unsigned long, userCount, frameLeft);
111 while (count > 0) {
112 u_char data;
113 if (get_user(data, userPtr++))
114 return -EFAULT;
115 val = data << 8;
116 *p++ = val;
117 if (stereo) {
118 if (get_user(data, userPtr++))
119 return -EFAULT;
120 val = data << 8;
121 }
122 *p++ = val;
123 count--;
124 }
125 *frameUsed += used * 4;
126 return stereo? used * 2: used;
127}
128
129
130static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
131 u_char frame[], ssize_t *frameUsed,
132 ssize_t frameLeft)
133{
134 ssize_t count, used;
135 short *p = (short *) &frame[*frameUsed];
136 int val, stereo = dmasound.soft.stereo;
137
138 frameLeft >>= 2;
139 if (stereo)
140 userCount >>= 1;
141 used = count = min_t(unsigned long, userCount, frameLeft);
142 while (count > 0) {
143 u_char data;
144 if (get_user(data, userPtr++))
145 return -EFAULT;
146 val = (data ^ 0x80) << 8;
147 *p++ = val;
148 if (stereo) {
149 if (get_user(data, userPtr++))
150 return -EFAULT;
151 val = (data ^ 0x80) << 8;
152 }
153 *p++ = val;
154 count--;
155 }
156 *frameUsed += used * 4;
157 return stereo? used * 2: used;
158}
159
160
161static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
162 u_char frame[], ssize_t *frameUsed,
163 ssize_t frameLeft)
164{
165 ssize_t count, used;
166 int stereo = dmasound.soft.stereo;
167 short *fp = (short *) &frame[*frameUsed];
168
169 frameLeft >>= 2;
170 userCount >>= (stereo? 2: 1);
171 used = count = min_t(unsigned long, userCount, frameLeft);
172 if (!stereo) {
173 short __user *up = (short __user *) userPtr;
174 while (count > 0) {
175 short data;
176 if (get_user(data, up++))
177 return -EFAULT;
178 *fp++ = data;
179 *fp++ = data;
180 count--;
181 }
182 } else {
183 if (copy_from_user(fp, userPtr, count * 4))
184 return -EFAULT;
185 }
186 *frameUsed += used * 4;
187 return stereo? used * 4: used * 2;
188}
189
190static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount,
191 u_char frame[], ssize_t *frameUsed,
192 ssize_t frameLeft)
193{
194 ssize_t count, used;
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;
199
200 frameLeft >>= 2;
201 userCount >>= (stereo? 2: 1);
202 used = count = min_t(unsigned long, userCount, frameLeft);
203 while (count > 0) {
204 short data;
205 if (get_user(data, up++))
206 return -EFAULT;
207 data ^= mask;
208 *fp++ = data;
209 if (stereo) {
210 if (get_user(data, up++))
211 return -EFAULT;
212 data ^= mask;
213 }
214 *fp++ = data;
215 count--;
216 }
217 *frameUsed += used * 4;
218 return stereo? used * 4: used * 2;
219}
220
221
222static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
223 u_char frame[], ssize_t *frameUsed,
224 ssize_t frameLeft)
225{
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;
233 int utotal, ftotal;
234 int stereo = dmasound.soft.stereo;
235
236 frameLeft >>= 2;
237 if (stereo)
238 userCount >>= 1;
239 ftotal = frameLeft;
240 utotal = userCount;
241 while (frameLeft) {
242 u_char c;
243 if (bal < 0) {
244 if (userCount == 0)
245 break;
246 if (get_user(c, userPtr++))
247 return -EFAULT;
248 data = table[c];
249 if (stereo) {
250 if (get_user(c, userPtr++))
251 return -EFAULT;
252 data = (data << 16) + table[c];
253 } else
254 data = (data << 16) + data;
255 userCount--;
256 bal += hSpeed;
257 }
258 *p++ = data;
259 frameLeft--;
260 bal -= sSpeed;
261 }
262 expand_bal = bal;
263 expand_data = data;
264 *frameUsed += (ftotal - frameLeft) * 4;
265 utotal -= userCount;
266 return stereo? utotal * 2: utotal;
267}
268
269static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
270 u_char frame[], ssize_t *frameUsed,
271 ssize_t frameLeft)
272{
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;
278 int utotal, ftotal;
279
280 frameLeft >>= 2;
281 if (stereo)
282 userCount >>= 1;
283 ftotal = frameLeft;
284 utotal = userCount;
285 while (frameLeft) {
286 u_char c;
287 if (bal < 0) {
288 if (userCount == 0)
289 break;
290 if (get_user(c, userPtr++))
291 return -EFAULT;
292 data = c << 8;
293 if (stereo) {
294 if (get_user(c, userPtr++))
295 return -EFAULT;
296 data = (data << 16) + (c << 8);
297 } else
298 data = (data << 16) + data;
299 userCount--;
300 bal += hSpeed;
301 }
302 *p++ = data;
303 frameLeft--;
304 bal -= sSpeed;
305 }
306 expand_bal = bal;
307 expand_data = data;
308 *frameUsed += (ftotal - frameLeft) * 4;
309 utotal -= userCount;
310 return stereo? utotal * 2: utotal;
311}
312
313
314static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
315 u_char frame[], ssize_t *frameUsed,
316 ssize_t frameLeft)
317{
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;
323 int utotal, ftotal;
324
325 frameLeft >>= 2;
326 if (stereo)
327 userCount >>= 1;
328 ftotal = frameLeft;
329 utotal = userCount;
330 while (frameLeft) {
331 u_char c;
332 if (bal < 0) {
333 if (userCount == 0)
334 break;
335 if (get_user(c, userPtr++))
336 return -EFAULT;
337 data = (c ^ 0x80) << 8;
338 if (stereo) {
339 if (get_user(c, userPtr++))
340 return -EFAULT;
341 data = (data << 16) + ((c ^ 0x80) << 8);
342 } else
343 data = (data << 16) + data;
344 userCount--;
345 bal += hSpeed;
346 }
347 *p++ = data;
348 frameLeft--;
349 bal -= sSpeed;
350 }
351 expand_bal = bal;
352 expand_data = data;
353 *frameUsed += (ftotal - frameLeft) * 4;
354 utotal -= userCount;
355 return stereo? utotal * 2: utotal;
356}
357
358
359static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
360 u_char frame[], ssize_t *frameUsed,
361 ssize_t frameLeft)
362{
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;
369 int utotal, ftotal;
370
371 frameLeft >>= 2;
372 userCount >>= (stereo? 2: 1);
373 ftotal = frameLeft;
374 utotal = userCount;
375 while (frameLeft) {
376 unsigned short c;
377 if (bal < 0) {
378 if (userCount == 0)
379 break;
380 if (get_user(data, up++))
381 return -EFAULT;
382 if (stereo) {
383 if (get_user(c, up++))
384 return -EFAULT;
385 data = (data << 16) + c;
386 } else
387 data = (data << 16) + data;
388 userCount--;
389 bal += hSpeed;
390 }
391 *p++ = data;
392 frameLeft--;
393 bal -= sSpeed;
394 }
395 expand_bal = bal;
396 expand_data = data;
397 *frameUsed += (ftotal - frameLeft) * 4;
398 utotal -= userCount;
399 return stereo? utotal * 4: utotal * 2;
400}
401
402
403static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount,
404 u_char frame[], ssize_t *frameUsed,
405 ssize_t frameLeft)
406{
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;
414 int utotal, ftotal;
415
416 frameLeft >>= 2;
417 userCount >>= (stereo? 2: 1);
418 ftotal = frameLeft;
419 utotal = userCount;
420 while (frameLeft) {
421 unsigned short c;
422 if (bal < 0) {
423 if (userCount == 0)
424 break;
425 if (get_user(data, up++))
426 return -EFAULT;
427 data ^= mask;
428 if (stereo) {
429 if (get_user(c, up++))
430 return -EFAULT;
431 data = (data << 16) + (c ^ mask);
432 } else
433 data = (data << 16) + data;
434 userCount--;
435 bal += hSpeed;
436 }
437 *p++ = data;
438 frameLeft--;
439 bal -= sSpeed;
440 }
441 expand_bal = bal;
442 expand_data = data;
443 *frameUsed += (ftotal - frameLeft) * 4;
444 utotal -= userCount;
445 return stereo? utotal * 4: utotal * 2;
446}
447
448/* data in routines... */
449
450static ssize_t pmac_ct_s8_read(const u_char __user *userPtr, size_t userCount,
451 u_char frame[], ssize_t *frameUsed,
452 ssize_t frameLeft)
453{
454 ssize_t count, used;
455 short *p = (short *) &frame[*frameUsed];
456 int val, stereo = dmasound.soft.stereo;
457
458 frameLeft >>= 2;
459 if (stereo)
460 userCount >>= 1;
461 used = count = min_t(unsigned long, userCount, frameLeft);
462 while (count > 0) {
463 u_char data;
464
465 val = *p++;
466 val = (val * software_input_volume) >> 7;
467 data = val >> 8;
468 if (put_user(data, (u_char __user *)userPtr++))
469 return -EFAULT;
470 if (stereo) {
471 val = *p;
472 val = (val * software_input_volume) >> 7;
473 data = val >> 8;
474 if (put_user(data, (u_char __user *)userPtr++))
475 return -EFAULT;
476 }
477 p++;
478 count--;
479 }
480 *frameUsed += used * 4;
481 return stereo? used * 2: used;
482}
483
484
485static ssize_t pmac_ct_u8_read(const u_char __user *userPtr, size_t userCount,
486 u_char frame[], ssize_t *frameUsed,
487 ssize_t frameLeft)
488{
489 ssize_t count, used;
490 short *p = (short *) &frame[*frameUsed];
491 int val, stereo = dmasound.soft.stereo;
492
493 frameLeft >>= 2;
494 if (stereo)
495 userCount >>= 1;
496 used = count = min_t(unsigned long, userCount, frameLeft);
497 while (count > 0) {
498 u_char data;
499
500 val = *p++;
501 val = (val * software_input_volume) >> 7;
502 data = (val >> 8) ^ 0x80;
503 if (put_user(data, (u_char __user *)userPtr++))
504 return -EFAULT;
505 if (stereo) {
506 val = *p;
507 val = (val * software_input_volume) >> 7;
508 data = (val >> 8) ^ 0x80;
509 if (put_user(data, (u_char __user *)userPtr++))
510 return -EFAULT;
511 }
512 p++;
513 count--;
514 }
515 *frameUsed += used * 4;
516 return stereo? used * 2: used;
517}
518
519static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount,
520 u_char frame[], ssize_t *frameUsed,
521 ssize_t frameLeft)
522{
523 ssize_t count, used;
524 int stereo = dmasound.soft.stereo;
525 short *fp = (short *) &frame[*frameUsed];
526 short __user *up = (short __user *) userPtr;
527
528 frameLeft >>= 2;
529 userCount >>= (stereo? 2: 1);
530 used = count = min_t(unsigned long, userCount, frameLeft);
531 while (count > 0) {
532 short data;
533
534 data = *fp++;
535 data = (data * software_input_volume) >> 7;
536 if (put_user(data, up++))
537 return -EFAULT;
538 if (stereo) {
539 data = *fp;
540 data = (data * software_input_volume) >> 7;
541 if (put_user(data, up++))
542 return -EFAULT;
543 }
544 fp++;
545 count--;
546 }
547 *frameUsed += used * 4;
548 return stereo? used * 4: used * 2;
549}
550
551static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount,
552 u_char frame[], ssize_t *frameUsed,
553 ssize_t frameLeft)
554{
555 ssize_t count, used;
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;
560
561 frameLeft >>= 2;
562 userCount >>= (stereo? 2: 1);
563 used = count = min_t(unsigned long, userCount, frameLeft);
564 while (count > 0) {
565 int data;
566
567 data = *fp++;
568 data = (data * software_input_volume) >> 7;
569 data ^= mask;
570 if (put_user(data, up++))
571 return -EFAULT;
572 if (stereo) {
573 data = *fp;
574 data = (data * software_input_volume) >> 7;
575 data ^= mask;
576 if (put_user(data, up++))
577 return -EFAULT;
578 }
579 fp++;
580 count--;
581 }
582 *frameUsed += used * 4;
583 return stereo? used * 4: used * 2;
584}
585
586/* data in routines (reducing speed)... */
587
588static ssize_t pmac_ctx_s8_read(const u_char __user *userPtr, size_t userCount,
589 u_char frame[], ssize_t *frameUsed,
590 ssize_t frameLeft)
591{
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;
596 int utotal, ftotal;
597
598 frameLeft >>= 2;
599 if (stereo)
600 userCount >>= 1;
601 ftotal = frameLeft;
602 utotal = userCount;
603 while (frameLeft) {
604 u_char data;
605
606 if (bal<0 && userCount == 0)
607 break;
608 vall = *p++;
609 vall = (vall * software_input_volume) >> 7;
610 if (stereo) {
611 valr = *p;
612 valr = (valr * software_input_volume) >> 7;
613 }
614 p++;
615 if (bal < 0) {
616 data = vall >> 8;
617 if (put_user(data, (u_char __user *)userPtr++))
618 return -EFAULT;
619 if (stereo) {
620 data = valr >> 8;
621 if (put_user(data, (u_char __user *)userPtr++))
622 return -EFAULT;
623 }
624 userCount--;
625 bal += hSpeed;
626 }
627 frameLeft--;
628 bal -= sSpeed;
629 }
630 expand_read_bal=bal;
631 *frameUsed += (ftotal - frameLeft) * 4;
632 utotal -= userCount;
633 return stereo? utotal * 2: utotal;
634}
635
636
637static ssize_t pmac_ctx_u8_read(const u_char __user *userPtr, size_t userCount,
638 u_char frame[], ssize_t *frameUsed,
639 ssize_t frameLeft)
640{
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;
645 int utotal, ftotal;
646
647 frameLeft >>= 2;
648 if (stereo)
649 userCount >>= 1;
650 ftotal = frameLeft;
651 utotal = userCount;
652 while (frameLeft) {
653 u_char data;
654
655 if (bal<0 && userCount == 0)
656 break;
657
658 vall = *p++;
659 vall = (vall * software_input_volume) >> 7;
660 if (stereo) {
661 valr = *p;
662 valr = (valr * software_input_volume) >> 7;
663 }
664 p++;
665 if (bal < 0) {
666 data = (vall >> 8) ^ 0x80;
667 if (put_user(data, (u_char __user *)userPtr++))
668 return -EFAULT;
669 if (stereo) {
670 data = (valr >> 8) ^ 0x80;
671 if (put_user(data, (u_char __user *)userPtr++))
672 return -EFAULT;
673 }
674 userCount--;
675 bal += hSpeed;
676 }
677 frameLeft--;
678 bal -= sSpeed;
679 }
680 expand_read_bal=bal;
681 *frameUsed += (ftotal - frameLeft) * 4;
682 utotal -= userCount;
683 return stereo? utotal * 2: utotal;
684}
685
686static ssize_t pmac_ctx_s16_read(const u_char __user *userPtr, size_t userCount,
687 u_char frame[], ssize_t *frameUsed,
688 ssize_t frameLeft)
689{
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;
695 int utotal, ftotal;
696
697 frameLeft >>= 2;
698 userCount >>= (stereo? 2: 1);
699 ftotal = frameLeft;
700 utotal = userCount;
701 while (frameLeft) {
702 int datal,datar;
703
704 if (bal<0 && userCount == 0)
705 break;
706
707 datal = *fp++;
708 datal = (datal * software_input_volume) >> 7;
709 if (stereo) {
710 datar = *fp;
711 datar = (datar * software_input_volume) >> 7;
712 }
713 fp++;
714 if (bal < 0) {
715 if (put_user(datal, up++))
716 return -EFAULT;
717 if (stereo) {
718 if (put_user(datar, up++))
719 return -EFAULT;
720 }
721 userCount--;
722 bal += hSpeed;
723 }
724 frameLeft--;
725 bal -= sSpeed;
726 }
727 expand_read_bal=bal;
728 *frameUsed += (ftotal - frameLeft) * 4;
729 utotal -= userCount;
730 return stereo? utotal * 4: utotal * 2;
731}
732
733static ssize_t pmac_ctx_u16_read(const u_char __user *userPtr, size_t userCount,
734 u_char frame[], ssize_t *frameUsed,
735 ssize_t frameLeft)
736{
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;
743 int utotal, ftotal;
744
745 frameLeft >>= 2;
746 userCount >>= (stereo? 2: 1);
747 ftotal = frameLeft;
748 utotal = userCount;
749 while (frameLeft) {
750 int datal,datar;
751
752 if (bal<0 && userCount == 0)
753 break;
754
755 datal = *fp++;
756 datal = (datal * software_input_volume) >> 7;
757 datal ^= mask;
758 if (stereo) {
759 datar = *fp;
760 datar = (datar * software_input_volume) >> 7;
761 datar ^= mask;
762 }
763 fp++;
764 if (bal < 0) {
765 if (put_user(datal, up++))
766 return -EFAULT;
767 if (stereo) {
768 if (put_user(datar, up++))
769 return -EFAULT;
770 }
771 userCount--;
772 bal += hSpeed;
773 }
774 frameLeft--;
775 bal -= sSpeed;
776 }
777 expand_read_bal=bal;
778 *frameUsed += (ftotal - frameLeft) * 4;
779 utotal -= userCount;
780 return stereo? utotal * 4: utotal * 2;
781}
782
783
784TRANS transAwacsNormal = {
785 .ct_ulaw= pmac_ct_law,
786 .ct_alaw= pmac_ct_law,
787 .ct_s8= pmac_ct_s8,
788 .ct_u8= pmac_ct_u8,
789 .ct_s16be= pmac_ct_s16,
790 .ct_u16be= pmac_ct_u16,
791 .ct_s16le= pmac_ct_s16,
792 .ct_u16le= pmac_ct_u16,
793};
794
795TRANS transAwacsExpand = {
796 .ct_ulaw= pmac_ctx_law,
797 .ct_alaw= pmac_ctx_law,
798 .ct_s8= pmac_ctx_s8,
799 .ct_u8= pmac_ctx_u8,
800 .ct_s16be= pmac_ctx_s16,
801 .ct_u16be= pmac_ctx_u16,
802 .ct_s16le= pmac_ctx_s16,
803 .ct_u16le= pmac_ctx_u16,
804};
805
806TRANS 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,
813};
814
815TRANS 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,
822};
823
824/* translation tables */
825/* 16 bit mu-law */
826
827static 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,
860};
861
862/* 16 bit A-law */
863
864static 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,
897};