Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / sound / oss / dmasound / trans_16.c
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
20 static short dmasound_alaw2dma16[] ;
21 static short dmasound_ulaw2dma16[] ;
22
23 static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
24                            u_char frame[], ssize_t *frameUsed,
25                            ssize_t frameLeft);
26 static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
27                           u_char frame[], ssize_t *frameUsed,
28                           ssize_t frameLeft);
29 static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
30                           u_char frame[], ssize_t *frameUsed,
31                           ssize_t frameLeft);
32 static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
33                            u_char frame[], ssize_t *frameUsed,
34                            ssize_t frameLeft);
35 static 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
39 static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
40                             u_char frame[], ssize_t *frameUsed,
41                             ssize_t frameLeft);
42 static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
43                            u_char frame[], ssize_t *frameUsed,
44                            ssize_t frameLeft);
45 static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
46                            u_char frame[], ssize_t *frameUsed,
47                            ssize_t frameLeft);
48 static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
49                             u_char frame[], ssize_t *frameUsed,
50                             ssize_t frameLeft);
51 static 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
55 static 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);
58 static 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
64 static int expand_data; /* Data for expanding */
65
66 static 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
99 static 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
130 static 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
161 static 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
190 static 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
222 static 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
269 static 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
314 static 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
359 static 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
403 static 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
450 static 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
485 static 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
519 static 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
551 static 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
588 static 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
637 static 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
686 static 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
733 static 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
784 TRANS 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
795 TRANS 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
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,
813 };
814
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,
822 };
823
824 /* translation tables */
825 /* 16 bit mu-law */
826
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,
860 };
861
862 /* 16 bit A-law */
863
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,
897 };