diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /sound/oss/dmasound/trans_16.c |
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'sound/oss/dmasound/trans_16.c')
-rw-r--r-- | sound/oss/dmasound/trans_16.c | 897 |
1 files changed, 897 insertions, 0 deletions
diff --git a/sound/oss/dmasound/trans_16.c b/sound/oss/dmasound/trans_16.c new file mode 100644 index 00000000000..23562e94780 --- /dev/null +++ b/sound/oss/dmasound/trans_16.c | |||
@@ -0,0 +1,897 @@ | |||
1 | /* | ||
2 | * linux/sound/oss/dmasound/trans_16.c | ||
3 | * | ||
4 | * 16 bit translation routines. Only used by Power mac at present. | ||
5 | * | ||
6 | * See linux/sound/oss/dmasound/dmasound_core.c for copyright and | ||
7 | * history prior to 08/02/2001. | ||
8 | * | ||
9 | * 08/02/2001 Iain Sandoe | ||
10 | * split from dmasound_awacs.c | ||
11 | * 11/29/2003 Renzo Davoli (King Enzo) | ||
12 | * - input resampling (for soft rate < hard rate) | ||
13 | * - software line in gain control | ||
14 | */ | ||
15 | |||
16 | #include <linux/soundcard.h> | ||
17 | #include <asm/uaccess.h> | ||
18 | #include "dmasound.h" | ||
19 | |||
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 | }; | ||