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