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
20extern int expand_bal;	/* Balance factor for expanding (not volume!) */
21static short dmasound_alaw2dma16[] ;
22static short dmasound_ulaw2dma16[] ;
23
24static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
25			   u_char frame[], ssize_t *frameUsed,
26			   ssize_t frameLeft);
27static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
28			  u_char frame[], ssize_t *frameUsed,
29			  ssize_t frameLeft);
30static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
31			  u_char frame[], ssize_t *frameUsed,
32			  ssize_t frameLeft);
33static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
34			   u_char frame[], ssize_t *frameUsed,
35			   ssize_t frameLeft);
36static 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
40static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
41			    u_char frame[], ssize_t *frameUsed,
42			    ssize_t frameLeft);
43static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
44			   u_char frame[], ssize_t *frameUsed,
45			   ssize_t frameLeft);
46static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
47			   u_char frame[], ssize_t *frameUsed,
48			   ssize_t frameLeft);
49static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
50			    u_char frame[], ssize_t *frameUsed,
51			    ssize_t frameLeft);
52static 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
56static 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);
59static 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
65static int expand_data;	/* Data for expanding */
66
67static 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
100static 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
131static 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
162static 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
191static 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
223static 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
270static 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
315static 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
360static 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
404static 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
451static 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
486static 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
520static 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
552static 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
589static 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
638static 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
687static 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
734static 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
785TRANS 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
796TRANS 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
807TRANS 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
816TRANS 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
828static 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
865static 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};
899