File: /usr/src/linux/drivers/sound/dmasound/dmasound_atari.c
1
2 /*
3 * linux/drivers/sound/dmasound/dmasound_atari.c
4 *
5 * Atari TT and Falcon DMA Sound Driver
6 *
7 * See linux/drivers/sound/dmasound/dmasound_core.c for copyright and credits
8 */
9
10
11 #include <linux/module.h>
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <linux/soundcard.h>
15 #include <linux/mm.h>
16
17 #include <asm/pgalloc.h>
18 #include <asm/uaccess.h>
19 #include <asm/atariints.h>
20 #include <asm/atari_stram.h>
21
22 #include "dmasound.h"
23
24
25 extern void atari_microwire_cmd(int cmd);
26
27
28 static int is_falcon;
29 static int write_sq_ignore_int = 0; /* ++TeSche: used for Falcon */
30
31 static int expand_bal; /* Balance factor for expanding (not volume!) */
32 static int expand_data; /* Data for expanding */
33
34
35 /*** Translations ************************************************************/
36
37
38 /* ++TeSche: radically changed for new expanding purposes...
39 *
40 * These two routines now deal with copying/expanding/translating the samples
41 * from user space into our buffer at the right frequency. They take care about
42 * how much data there's actually to read, how much buffer space there is and
43 * to convert samples into the right frequency/encoding. They will only work on
44 * complete samples so it may happen they leave some bytes in the input stream
45 * if the user didn't write a multiple of the current sample size. They both
46 * return the number of bytes they've used from both streams so you may detect
47 * such a situation. Luckily all programs should be able to cope with that.
48 *
49 * I think I've optimized anything as far as one can do in plain C, all
50 * variables should fit in registers and the loops are really short. There's
51 * one loop for every possible situation. Writing a more generalized and thus
52 * parameterized loop would only produce slower code. Feel free to optimize
53 * this in assembler if you like. :)
54 *
55 * I think these routines belong here because they're not yet really hardware
56 * independent, especially the fact that the Falcon can play 16bit samples
57 * only in stereo is hardcoded in both of them!
58 *
59 * ++geert: split in even more functions (one per format)
60 */
61
62 static ssize_t ata_ct_law(const u_char *userPtr, size_t userCount,
63 u_char frame[], ssize_t *frameUsed,
64 ssize_t frameLeft);
65 static ssize_t ata_ct_s8(const u_char *userPtr, size_t userCount,
66 u_char frame[], ssize_t *frameUsed,
67 ssize_t frameLeft);
68 static ssize_t ata_ct_u8(const u_char *userPtr, size_t userCount,
69 u_char frame[], ssize_t *frameUsed,
70 ssize_t frameLeft);
71 static ssize_t ata_ct_s16be(const u_char *userPtr, size_t userCount,
72 u_char frame[], ssize_t *frameUsed,
73 ssize_t frameLeft);
74 static ssize_t ata_ct_u16be(const u_char *userPtr, size_t userCount,
75 u_char frame[], ssize_t *frameUsed,
76 ssize_t frameLeft);
77 static ssize_t ata_ct_s16le(const u_char *userPtr, size_t userCount,
78 u_char frame[], ssize_t *frameUsed,
79 ssize_t frameLeft);
80 static ssize_t ata_ct_u16le(const u_char *userPtr, size_t userCount,
81 u_char frame[], ssize_t *frameUsed,
82 ssize_t frameLeft);
83 static ssize_t ata_ctx_law(const u_char *userPtr, size_t userCount,
84 u_char frame[], ssize_t *frameUsed,
85 ssize_t frameLeft);
86 static ssize_t ata_ctx_s8(const u_char *userPtr, size_t userCount,
87 u_char frame[], ssize_t *frameUsed,
88 ssize_t frameLeft);
89 static ssize_t ata_ctx_u8(const u_char *userPtr, size_t userCount,
90 u_char frame[], ssize_t *frameUsed,
91 ssize_t frameLeft);
92 static ssize_t ata_ctx_s16be(const u_char *userPtr, size_t userCount,
93 u_char frame[], ssize_t *frameUsed,
94 ssize_t frameLeft);
95 static ssize_t ata_ctx_u16be(const u_char *userPtr, size_t userCount,
96 u_char frame[], ssize_t *frameUsed,
97 ssize_t frameLeft);
98 static ssize_t ata_ctx_s16le(const u_char *userPtr, size_t userCount,
99 u_char frame[], ssize_t *frameUsed,
100 ssize_t frameLeft);
101 static ssize_t ata_ctx_u16le(const u_char *userPtr, size_t userCount,
102 u_char frame[], ssize_t *frameUsed,
103 ssize_t frameLeft);
104
105
106 /*** Low level stuff *********************************************************/
107
108
109 static void AtaOpen(void);
110 static void AtaRelease(void);
111 static void *AtaAlloc(unsigned int size, int flags);
112 static void AtaFree(void *, unsigned int size);
113 static int AtaIrqInit(void);
114 #ifdef MODULE
115 static void AtaIrqCleanUp(void);
116 #endif /* MODULE */
117 static int AtaSetBass(int bass);
118 static int AtaSetTreble(int treble);
119 static void TTSilence(void);
120 static void TTInit(void);
121 static int TTSetFormat(int format);
122 static int TTSetVolume(int volume);
123 static int TTSetGain(int gain);
124 static void FalconSilence(void);
125 static void FalconInit(void);
126 static int FalconSetFormat(int format);
127 static int FalconSetVolume(int volume);
128 static void AtaPlayNextFrame(int index);
129 static void AtaPlay(void);
130 static void AtaInterrupt(int irq, void *dummy, struct pt_regs *fp);
131
132 /*** Mid level stuff *********************************************************/
133
134 static void TTMixerInit(void);
135 static void FalconMixerInit(void);
136 static int AtaMixerIoctl(u_int cmd, u_long arg);
137 static int TTMixerIoctl(u_int cmd, u_long arg);
138 static int FalconMixerIoctl(u_int cmd, u_long arg);
139 static void AtaWriteSqSetup(void);
140 static void AtaSqOpen(void);
141 static int TTStateInfo(char *buffer);
142 static int FalconStateInfo(char *buffer);
143
144
145 /*** Translations ************************************************************/
146
147
148 static ssize_t ata_ct_law(const u_char *userPtr, size_t userCount,
149 u_char frame[], ssize_t *frameUsed,
150 ssize_t frameLeft)
151 {
152 char *table = dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8
153 : dmasound_alaw2dma8;
154 ssize_t count, used;
155 u_char *p = &frame[*frameUsed];
156
157 count = min_t(unsigned long, userCount, frameLeft);
158 if (dmasound.soft.stereo)
159 count &= ~1;
160 used = count;
161 while (count > 0) {
162 u_char data;
163 if (get_user(data, userPtr++))
164 return -EFAULT;
165 *p++ = table[data];
166 count--;
167 }
168 *frameUsed += used;
169 return used;
170 }
171
172
173 static ssize_t ata_ct_s8(const u_char *userPtr, size_t userCount,
174 u_char frame[], ssize_t *frameUsed,
175 ssize_t frameLeft)
176 {
177 ssize_t count, used;
178 void *p = &frame[*frameUsed];
179
180 count = min_t(unsigned long, userCount, frameLeft);
181 if (dmasound.soft.stereo)
182 count &= ~1;
183 used = count;
184 if (copy_from_user(p, userPtr, count))
185 return -EFAULT;
186 *frameUsed += used;
187 return used;
188 }
189
190
191 static ssize_t ata_ct_u8(const u_char *userPtr, size_t userCount,
192 u_char frame[], ssize_t *frameUsed,
193 ssize_t frameLeft)
194 {
195 ssize_t count, used;
196
197 if (!dmasound.soft.stereo) {
198 u_char *p = &frame[*frameUsed];
199 count = min_t(unsigned long, userCount, frameLeft);
200 used = count;
201 while (count > 0) {
202 u_char data;
203 if (get_user(data, userPtr++))
204 return -EFAULT;
205 *p++ = data ^ 0x80;
206 count--;
207 }
208 } else {
209 u_short *p = (u_short *)&frame[*frameUsed];
210 count = min_t(unsigned long, userCount, frameLeft)>>1;
211 used = count*2;
212 while (count > 0) {
213 u_short data;
214 if (get_user(data, ((u_short *)userPtr)++))
215 return -EFAULT;
216 *p++ = data ^ 0x8080;
217 count--;
218 }
219 }
220 *frameUsed += used;
221 return used;
222 }
223
224
225 static ssize_t ata_ct_s16be(const u_char *userPtr, size_t userCount,
226 u_char frame[], ssize_t *frameUsed,
227 ssize_t frameLeft)
228 {
229 ssize_t count, used;
230
231 if (!dmasound.soft.stereo) {
232 u_short *p = (u_short *)&frame[*frameUsed];
233 count = min_t(unsigned long, userCount, frameLeft)>>1;
234 used = count*2;
235 while (count > 0) {
236 u_short data;
237 if (get_user(data, ((u_short *)userPtr)++))
238 return -EFAULT;
239 *p++ = data;
240 *p++ = data;
241 count--;
242 }
243 *frameUsed += used*2;
244 } else {
245 void *p = (u_short *)&frame[*frameUsed];
246 count = min_t(unsigned long, userCount, frameLeft) & ~3;
247 used = count;
248 if (copy_from_user(p, userPtr, count))
249 return -EFAULT;
250 *frameUsed += used;
251 }
252 return used;
253 }
254
255
256 static ssize_t ata_ct_u16be(const u_char *userPtr, size_t userCount,
257 u_char frame[], ssize_t *frameUsed,
258 ssize_t frameLeft)
259 {
260 ssize_t count, used;
261
262 if (!dmasound.soft.stereo) {
263 u_short *p = (u_short *)&frame[*frameUsed];
264 count = min_t(unsigned long, userCount, frameLeft)>>1;
265 used = count*2;
266 while (count > 0) {
267 u_short data;
268 if (get_user(data, ((u_short *)userPtr)++))
269 return -EFAULT;
270 data ^= 0x8000;
271 *p++ = data;
272 *p++ = data;
273 count--;
274 }
275 *frameUsed += used*2;
276 } else {
277 u_long *p = (u_long *)&frame[*frameUsed];
278 count = min_t(unsigned long, userCount, frameLeft)>>2;
279 used = count*4;
280 while (count > 0) {
281 u_long data;
282 if (get_user(data, ((u_int *)userPtr)++))
283 return -EFAULT;
284 *p++ = data ^ 0x80008000;
285 count--;
286 }
287 *frameUsed += used;
288 }
289 return used;
290 }
291
292
293 static ssize_t ata_ct_s16le(const u_char *userPtr, size_t userCount,
294 u_char frame[], ssize_t *frameUsed,
295 ssize_t frameLeft)
296 {
297 ssize_t count, used;
298
299 count = frameLeft;
300 if (!dmasound.soft.stereo) {
301 u_short *p = (u_short *)&frame[*frameUsed];
302 count = min_t(unsigned long, userCount, frameLeft)>>1;
303 used = count*2;
304 while (count > 0) {
305 u_short data;
306 if (get_user(data, ((u_short *)userPtr)++))
307 return -EFAULT;
308 data = le2be16(data);
309 *p++ = data;
310 *p++ = data;
311 count--;
312 }
313 *frameUsed += used*2;
314 } else {
315 u_long *p = (u_long *)&frame[*frameUsed];
316 count = min_t(unsigned long, userCount, frameLeft)>>2;
317 used = count*4;
318 while (count > 0) {
319 u_long data;
320 if (get_user(data, ((u_int *)userPtr)++))
321 return -EFAULT;
322 data = le2be16dbl(data);
323 *p++ = data;
324 count--;
325 }
326 *frameUsed += used;
327 }
328 return used;
329 }
330
331
332 static ssize_t ata_ct_u16le(const u_char *userPtr, size_t userCount,
333 u_char frame[], ssize_t *frameUsed,
334 ssize_t frameLeft)
335 {
336 ssize_t count, used;
337
338 count = frameLeft;
339 if (!dmasound.soft.stereo) {
340 u_short *p = (u_short *)&frame[*frameUsed];
341 count = min_t(unsigned long, userCount, frameLeft)>>1;
342 used = count*2;
343 while (count > 0) {
344 u_short data;
345 if (get_user(data, ((u_short *)userPtr)++))
346 return -EFAULT;
347 data = le2be16(data) ^ 0x8000;
348 *p++ = data;
349 *p++ = data;
350 }
351 *frameUsed += used*2;
352 } else {
353 u_long *p = (u_long *)&frame[*frameUsed];
354 count = min_t(unsigned long, userCount, frameLeft)>>2;
355 used = count;
356 while (count > 0) {
357 u_long data;
358 if (get_user(data, ((u_int *)userPtr)++))
359 return -EFAULT;
360 data = le2be16dbl(data) ^ 0x80008000;
361 *p++ = data;
362 count--;
363 }
364 *frameUsed += used;
365 }
366 return used;
367 }
368
369
370 static ssize_t ata_ctx_law(const u_char *userPtr, size_t userCount,
371 u_char frame[], ssize_t *frameUsed,
372 ssize_t frameLeft)
373 {
374 char *table = dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8
375 : dmasound_alaw2dma8;
376 /* this should help gcc to stuff everything into registers */
377 long bal = expand_bal;
378 long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
379 ssize_t used, usedf;
380
381 used = userCount;
382 usedf = frameLeft;
383 if (!dmasound.soft.stereo) {
384 u_char *p = &frame[*frameUsed];
385 u_char data = expand_data;
386 while (frameLeft) {
387 u_char c;
388 if (bal < 0) {
389 if (!userCount)
390 break;
391 if (get_user(c, userPtr++))
392 return -EFAULT;
393 data = table[c];
394 userCount--;
395 bal += hSpeed;
396 }
397 *p++ = data;
398 frameLeft--;
399 bal -= sSpeed;
400 }
401 expand_data = data;
402 } else {
403 u_short *p = (u_short *)&frame[*frameUsed];
404 u_short data = expand_data;
405 while (frameLeft >= 2) {
406 u_char c;
407 if (bal < 0) {
408 if (userCount < 2)
409 break;
410 if (get_user(c, userPtr++))
411 return -EFAULT;
412 data = table[c] << 8;
413 if (get_user(c, userPtr++))
414 return -EFAULT;
415 data |= table[c];
416 userCount -= 2;
417 bal += hSpeed;
418 }
419 *p++ = data;
420 frameLeft -= 2;
421 bal -= sSpeed;
422 }
423 expand_data = data;
424 }
425 expand_bal = bal;
426 used -= userCount;
427 *frameUsed += usedf-frameLeft;
428 return used;
429 }
430
431
432 static ssize_t ata_ctx_s8(const u_char *userPtr, size_t userCount,
433 u_char frame[], ssize_t *frameUsed,
434 ssize_t frameLeft)
435 {
436 /* this should help gcc to stuff everything into registers */
437 long bal = expand_bal;
438 long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
439 ssize_t used, usedf;
440
441 used = userCount;
442 usedf = frameLeft;
443 if (!dmasound.soft.stereo) {
444 u_char *p = &frame[*frameUsed];
445 u_char data = expand_data;
446 while (frameLeft) {
447 if (bal < 0) {
448 if (!userCount)
449 break;
450 if (get_user(data, userPtr++))
451 return -EFAULT;
452 userCount--;
453 bal += hSpeed;
454 }
455 *p++ = data;
456 frameLeft--;
457 bal -= sSpeed;
458 }
459 expand_data = data;
460 } else {
461 u_short *p = (u_short *)&frame[*frameUsed];
462 u_short data = expand_data;
463 while (frameLeft >= 2) {
464 if (bal < 0) {
465 if (userCount < 2)
466 break;
467 if (get_user(data, ((u_short *)userPtr)++))
468 return -EFAULT;
469 userCount -= 2;
470 bal += hSpeed;
471 }
472 *p++ = data;
473 frameLeft -= 2;
474 bal -= sSpeed;
475 }
476 expand_data = data;
477 }
478 expand_bal = bal;
479 used -= userCount;
480 *frameUsed += usedf-frameLeft;
481 return used;
482 }
483
484
485 static ssize_t ata_ctx_u8(const u_char *userPtr, size_t userCount,
486 u_char frame[], ssize_t *frameUsed,
487 ssize_t frameLeft)
488 {
489 /* this should help gcc to stuff everything into registers */
490 long bal = expand_bal;
491 long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
492 ssize_t used, usedf;
493
494 used = userCount;
495 usedf = frameLeft;
496 if (!dmasound.soft.stereo) {
497 u_char *p = &frame[*frameUsed];
498 u_char data = expand_data;
499 while (frameLeft) {
500 if (bal < 0) {
501 if (!userCount)
502 break;
503 if (get_user(data, userPtr++))
504 return -EFAULT;
505 data ^= 0x80;
506 userCount--;
507 bal += hSpeed;
508 }
509 *p++ = data;
510 frameLeft--;
511 bal -= sSpeed;
512 }
513 expand_data = data;
514 } else {
515 u_short *p = (u_short *)&frame[*frameUsed];
516 u_short data = expand_data;
517 while (frameLeft >= 2) {
518 if (bal < 0) {
519 if (userCount < 2)
520 break;
521 if (get_user(data, ((u_short *)userPtr)++))
522 return -EFAULT;
523 data ^= 0x8080;
524 userCount -= 2;
525 bal += hSpeed;
526 }
527 *p++ = data;
528 frameLeft -= 2;
529 bal -= sSpeed;
530 }
531 expand_data = data;
532 }
533 expand_bal = bal;
534 used -= userCount;
535 *frameUsed += usedf-frameLeft;
536 return used;
537 }
538
539
540 static ssize_t ata_ctx_s16be(const u_char *userPtr, size_t userCount,
541 u_char frame[], ssize_t *frameUsed,
542 ssize_t frameLeft)
543 {
544 /* this should help gcc to stuff everything into registers */
545 long bal = expand_bal;
546 long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
547 ssize_t used, usedf;
548
549 used = userCount;
550 usedf = frameLeft;
551 if (!dmasound.soft.stereo) {
552 u_short *p = (u_short *)&frame[*frameUsed];
553 u_short data = expand_data;
554 while (frameLeft >= 4) {
555 if (bal < 0) {
556 if (userCount < 2)
557 break;
558 if (get_user(data, ((u_short *)userPtr)++))
559 return -EFAULT;
560 userCount -= 2;
561 bal += hSpeed;
562 }
563 *p++ = data;
564 *p++ = data;
565 frameLeft -= 4;
566 bal -= sSpeed;
567 }
568 expand_data = data;
569 } else {
570 u_long *p = (u_long *)&frame[*frameUsed];
571 u_long data = expand_data;
572 while (frameLeft >= 4) {
573 if (bal < 0) {
574 if (userCount < 4)
575 break;
576 if (get_user(data, ((u_int *)userPtr)++))
577 return -EFAULT;
578 userCount -= 4;
579 bal += hSpeed;
580 }
581 *p++ = data;
582 frameLeft -= 4;
583 bal -= sSpeed;
584 }
585 expand_data = data;
586 }
587 expand_bal = bal;
588 used -= userCount;
589 *frameUsed += usedf-frameLeft;
590 return used;
591 }
592
593
594 static ssize_t ata_ctx_u16be(const u_char *userPtr, size_t userCount,
595 u_char frame[], ssize_t *frameUsed,
596 ssize_t frameLeft)
597 {
598 /* this should help gcc to stuff everything into registers */
599 long bal = expand_bal;
600 long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
601 ssize_t used, usedf;
602
603 used = userCount;
604 usedf = frameLeft;
605 if (!dmasound.soft.stereo) {
606 u_short *p = (u_short *)&frame[*frameUsed];
607 u_short data = expand_data;
608 while (frameLeft >= 4) {
609 if (bal < 0) {
610 if (userCount < 2)
611 break;
612 if (get_user(data, ((u_short *)userPtr)++))
613 return -EFAULT;
614 data ^= 0x8000;
615 userCount -= 2;
616 bal += hSpeed;
617 }
618 *p++ = data;
619 *p++ = data;
620 frameLeft -= 4;
621 bal -= sSpeed;
622 }
623 expand_data = data;
624 } else {
625 u_long *p = (u_long *)&frame[*frameUsed];
626 u_long data = expand_data;
627 while (frameLeft >= 4) {
628 if (bal < 0) {
629 if (userCount < 4)
630 break;
631 if (get_user(data, ((u_int *)userPtr)++))
632 return -EFAULT;
633 data ^= 0x80008000;
634 userCount -= 4;
635 bal += hSpeed;
636 }
637 *p++ = data;
638 frameLeft -= 4;
639 bal -= sSpeed;
640 }
641 expand_data = data;
642 }
643 expand_bal = bal;
644 used -= userCount;
645 *frameUsed += usedf-frameLeft;
646 return used;
647 }
648
649
650 static ssize_t ata_ctx_s16le(const u_char *userPtr, size_t userCount,
651 u_char frame[], ssize_t *frameUsed,
652 ssize_t frameLeft)
653 {
654 /* this should help gcc to stuff everything into registers */
655 long bal = expand_bal;
656 long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
657 ssize_t used, usedf;
658
659 used = userCount;
660 usedf = frameLeft;
661 if (!dmasound.soft.stereo) {
662 u_short *p = (u_short *)&frame[*frameUsed];
663 u_short data = expand_data;
664 while (frameLeft >= 4) {
665 if (bal < 0) {
666 if (userCount < 2)
667 break;
668 if (get_user(data, ((u_short *)userPtr)++))
669 return -EFAULT;
670 data = le2be16(data);
671 userCount -= 2;
672 bal += hSpeed;
673 }
674 *p++ = data;
675 *p++ = data;
676 frameLeft -= 4;
677 bal -= sSpeed;
678 }
679 expand_data = data;
680 } else {
681 u_long *p = (u_long *)&frame[*frameUsed];
682 u_long data = expand_data;
683 while (frameLeft >= 4) {
684 if (bal < 0) {
685 if (userCount < 4)
686 break;
687 if (get_user(data, ((u_int *)userPtr)++))
688 return -EFAULT;
689 data = le2be16dbl(data);
690 userCount -= 4;
691 bal += hSpeed;
692 }
693 *p++ = data;
694 frameLeft -= 4;
695 bal -= sSpeed;
696 }
697 expand_data = data;
698 }
699 expand_bal = bal;
700 used -= userCount;
701 *frameUsed += usedf-frameLeft;
702 return used;
703 }
704
705
706 static ssize_t ata_ctx_u16le(const u_char *userPtr, size_t userCount,
707 u_char frame[], ssize_t *frameUsed,
708 ssize_t frameLeft)
709 {
710 /* this should help gcc to stuff everything into registers */
711 long bal = expand_bal;
712 long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
713 ssize_t used, usedf;
714
715 used = userCount;
716 usedf = frameLeft;
717 if (!dmasound.soft.stereo) {
718 u_short *p = (u_short *)&frame[*frameUsed];
719 u_short data = expand_data;
720 while (frameLeft >= 4) {
721 if (bal < 0) {
722 if (userCount < 2)
723 break;
724 if (get_user(data, ((u_short *)userPtr)++))
725 return -EFAULT;
726 data = le2be16(data) ^ 0x8000;
727 userCount -= 2;
728 bal += hSpeed;
729 }
730 *p++ = data;
731 *p++ = data;
732 frameLeft -= 4;
733 bal -= sSpeed;
734 }
735 expand_data = data;
736 } else {
737 u_long *p = (u_long *)&frame[*frameUsed];
738 u_long data = expand_data;
739 while (frameLeft >= 4) {
740 if (bal < 0) {
741 if (userCount < 4)
742 break;
743 if (get_user(data, ((u_int *)userPtr)++))
744 return -EFAULT;
745 data = le2be16dbl(data) ^ 0x80008000;
746 userCount -= 4;
747 bal += hSpeed;
748 }
749 *p++ = data;
750 frameLeft -= 4;
751 bal -= sSpeed;
752 }
753 expand_data = data;
754 }
755 expand_bal = bal;
756 used -= userCount;
757 *frameUsed += usedf-frameLeft;
758 return used;
759 }
760
761
762 static TRANS transTTNormal = {
763 ct_ulaw: ata_ct_law,
764 ct_alaw: ata_ct_law,
765 ct_s8: ata_ct_s8,
766 ct_u8: ata_ct_u8,
767 };
768
769 static TRANS transTTExpanding = {
770 ct_ulaw: ata_ctx_law,
771 ct_alaw: ata_ctx_law,
772 ct_s8: ata_ctx_s8,
773 ct_u8: ata_ctx_u8,
774 };
775
776 static TRANS transFalconNormal = {
777 ct_ulaw: ata_ct_law,
778 ct_alaw: ata_ct_law,
779 ct_s8: ata_ct_s8,
780 ct_u8: ata_ct_u8,
781 ct_s16be: ata_ct_s16be,
782 ct_u16be: ata_ct_u16be,
783 ct_s16le: ata_ct_s16le,
784 ct_u16le: ata_ct_u16le
785 };
786
787 static TRANS transFalconExpanding = {
788 ct_ulaw: ata_ctx_law,
789 ct_alaw: ata_ctx_law,
790 ct_s8: ata_ctx_s8,
791 ct_u8: ata_ctx_u8,
792 ct_s16be: ata_ctx_s16be,
793 ct_u16be: ata_ctx_u16be,
794 ct_s16le: ata_ctx_s16le,
795 ct_u16le: ata_ctx_u16le,
796 };
797
798
799 /*** Low level stuff *********************************************************/
800
801
802
803 /*
804 * Atari (TT/Falcon)
805 */
806
807 static void AtaOpen(void)
808 {
809 MOD_INC_USE_COUNT;
810 }
811
812 static void AtaRelease(void)
813 {
814 MOD_DEC_USE_COUNT;
815 }
816
817 static void *AtaAlloc(unsigned int size, int flags)
818 {
819 return atari_stram_alloc(size, "dmasound");
820 }
821
822 static void AtaFree(void *obj, unsigned int size)
823 {
824 atari_stram_free( obj );
825 }
826
827 static int __init AtaIrqInit(void)
828 {
829 /* Set up timer A. Timer A
830 will receive a signal upon end of playing from the sound
831 hardware. Furthermore Timer A is able to count events
832 and will cause an interrupt after a programmed number
833 of events. So all we need to keep the music playing is
834 to provide the sound hardware with new data upon
835 an interrupt from timer A. */
836 mfp.tim_ct_a = 0; /* ++roman: Stop timer before programming! */
837 mfp.tim_dt_a = 1; /* Cause interrupt after first event. */
838 mfp.tim_ct_a = 8; /* Turn on event counting. */
839 /* Register interrupt handler. */
840 request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound",
841 AtaInterrupt);
842 mfp.int_en_a |= 0x20; /* Turn interrupt on. */
843 mfp.int_mk_a |= 0x20;
844 return 1;
845 }
846
847 #ifdef MODULE
848 static void AtaIrqCleanUp(void)
849 {
850 mfp.tim_ct_a = 0; /* stop timer */
851 mfp.int_en_a &= ~0x20; /* turn interrupt off */
852 free_irq(IRQ_MFP_TIMA, AtaInterrupt);
853 }
854 #endif /* MODULE */
855
856
857 #define TONE_VOXWARE_TO_DB(v) \
858 (((v) < 0) ? -12 : ((v) > 100) ? 12 : ((v) - 50) * 6 / 25)
859 #define TONE_DB_TO_VOXWARE(v) (((v) * 25 + ((v) > 0 ? 5 : -5)) / 6 + 50)
860
861
862 static int AtaSetBass(int bass)
863 {
864 dmasound.bass = TONE_VOXWARE_TO_DB(bass);
865 atari_microwire_cmd(MW_LM1992_BASS(dmasound.bass));
866 return TONE_DB_TO_VOXWARE(dmasound.bass);
867 }
868
869
870 static int AtaSetTreble(int treble)
871 {
872 dmasound.treble = TONE_VOXWARE_TO_DB(treble);
873 atari_microwire_cmd(MW_LM1992_TREBLE(dmasound.treble));
874 return TONE_DB_TO_VOXWARE(dmasound.treble);
875 }
876
877
878
879 /*
880 * TT
881 */
882
883
884 static void TTSilence(void)
885 {
886 tt_dmasnd.ctrl = DMASND_CTRL_OFF;
887 atari_microwire_cmd(MW_LM1992_PSG_HIGH); /* mix in PSG signal 1:1 */
888 }
889
890
891 static void TTInit(void)
892 {
893 int mode, i, idx;
894 const int freq[4] = {50066, 25033, 12517, 6258};
895
896 /* search a frequency that fits into the allowed error range */
897
898 idx = -1;
899 for (i = 0; i < ARRAY_SIZE(freq); i++)
900 /* this isn't as much useful for a TT than for a Falcon, but
901 * then it doesn't hurt very much to implement it for a TT too.
902 */
903 if ((100 * abs(dmasound.soft.speed - freq[i]) / freq[i]) < catchRadius)
904 idx = i;
905 if (idx > -1) {
906 dmasound.soft.speed = freq[idx];
907 dmasound.trans_write = &transTTNormal;
908 } else
909 dmasound.trans_write = &transTTExpanding;
910
911 TTSilence();
912 dmasound.hard = dmasound.soft;
913
914 if (dmasound.hard.speed > 50066) {
915 /* we would need to squeeze the sound, but we won't do that */
916 dmasound.hard.speed = 50066;
917 mode = DMASND_MODE_50KHZ;
918 dmasound.trans_write = &transTTNormal;
919 } else if (dmasound.hard.speed > 25033) {
920 dmasound.hard.speed = 50066;
921 mode = DMASND_MODE_50KHZ;
922 } else if (dmasound.hard.speed > 12517) {
923 dmasound.hard.speed = 25033;
924 mode = DMASND_MODE_25KHZ;
925 } else if (dmasound.hard.speed > 6258) {
926 dmasound.hard.speed = 12517;
927 mode = DMASND_MODE_12KHZ;
928 } else {
929 dmasound.hard.speed = 6258;
930 mode = DMASND_MODE_6KHZ;
931 }
932
933 tt_dmasnd.mode = (dmasound.hard.stereo ?
934 DMASND_MODE_STEREO : DMASND_MODE_MONO) |
935 DMASND_MODE_8BIT | mode;
936
937 expand_bal = -dmasound.soft.speed;
938 }
939
940
941 static int TTSetFormat(int format)
942 {
943 /* TT sound DMA supports only 8bit modes */
944
945 switch (format) {
946 case AFMT_QUERY:
947 return dmasound.soft.format;
948 case AFMT_MU_LAW:
949 case AFMT_A_LAW:
950 case AFMT_S8:
951 case AFMT_U8:
952 break;
953 default:
954 format = AFMT_S8;
955 }
956
957 dmasound.soft.format = format;
958 dmasound.soft.size = 8;
959 if (dmasound.minDev == SND_DEV_DSP) {
960 dmasound.dsp.format = format;
961 dmasound.dsp.size = 8;
962 }
963 TTInit();
964
965 return format;
966 }
967
968
969 #define VOLUME_VOXWARE_TO_DB(v) \
970 (((v) < 0) ? -40 : ((v) > 100) ? 0 : ((v) * 2) / 5 - 40)
971 #define VOLUME_DB_TO_VOXWARE(v) ((((v) + 40) * 5 + 1) / 2)
972
973
974 static int TTSetVolume(int volume)
975 {
976 dmasound.volume_left = VOLUME_VOXWARE_TO_DB(volume & 0xff);
977 atari_microwire_cmd(MW_LM1992_BALLEFT(dmasound.volume_left));
978 dmasound.volume_right = VOLUME_VOXWARE_TO_DB((volume & 0xff00) >> 8);
979 atari_microwire_cmd(MW_LM1992_BALRIGHT(dmasound.volume_right));
980 return VOLUME_DB_TO_VOXWARE(dmasound.volume_left) |
981 (VOLUME_DB_TO_VOXWARE(dmasound.volume_right) << 8);
982 }
983
984
985 #define GAIN_VOXWARE_TO_DB(v) \
986 (((v) < 0) ? -80 : ((v) > 100) ? 0 : ((v) * 4) / 5 - 80)
987 #define GAIN_DB_TO_VOXWARE(v) ((((v) + 80) * 5 + 1) / 4)
988
989 static int TTSetGain(int gain)
990 {
991 dmasound.gain = GAIN_VOXWARE_TO_DB(gain);
992 atari_microwire_cmd(MW_LM1992_VOLUME(dmasound.gain));
993 return GAIN_DB_TO_VOXWARE(dmasound.gain);
994 }
995
996
997
998 /*
999 * Falcon
1000 */
1001
1002
1003 static void FalconSilence(void)
1004 {
1005 /* stop playback, set sample rate 50kHz for PSG sound */
1006 tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1007 tt_dmasnd.mode = DMASND_MODE_50KHZ | DMASND_MODE_STEREO | DMASND_MODE_8BIT;
1008 tt_dmasnd.int_div = 0; /* STE compatible divider */
1009 tt_dmasnd.int_ctrl = 0x0;
1010 tt_dmasnd.cbar_src = 0x0000; /* no matrix inputs */
1011 tt_dmasnd.cbar_dst = 0x0000; /* no matrix outputs */
1012 tt_dmasnd.dac_src = 1; /* connect ADC to DAC, disconnect matrix */
1013 tt_dmasnd.adc_src = 3; /* ADC Input = PSG */
1014 }
1015
1016
1017 static void FalconInit(void)
1018 {
1019 int divider, i, idx;
1020 const int freq[8] = {49170, 32780, 24585, 19668, 16390, 12292, 9834, 8195};
1021
1022 /* search a frequency that fits into the allowed error range */
1023
1024 idx = -1;
1025 for (i = 0; i < ARRAY_SIZE(freq); i++)
1026 /* if we will tolerate 3% error 8000Hz->8195Hz (2.38%) would
1027 * be playable without expanding, but that now a kernel runtime
1028 * option
1029 */
1030 if ((100 * abs(dmasound.soft.speed - freq[i]) / freq[i]) < catchRadius)
1031 idx = i;
1032 if (idx > -1) {
1033 dmasound.soft.speed = freq[idx];
1034 dmasound.trans_write = &transFalconNormal;
1035 } else
1036 dmasound.trans_write = &transFalconExpanding;
1037
1038 FalconSilence();
1039 dmasound.hard = dmasound.soft;
1040
1041 if (dmasound.hard.size == 16) {
1042 /* the Falcon can play 16bit samples only in stereo */
1043 dmasound.hard.stereo = 1;
1044 }
1045
1046 if (dmasound.hard.speed > 49170) {
1047 /* we would need to squeeze the sound, but we won't do that */
1048 dmasound.hard.speed = 49170;
1049 divider = 1;
1050 dmasound.trans_write = &transFalconNormal;
1051 } else if (dmasound.hard.speed > 32780) {
1052 dmasound.hard.speed = 49170;
1053 divider = 1;
1054 } else if (dmasound.hard.speed > 24585) {
1055 dmasound.hard.speed = 32780;
1056 divider = 2;
1057 } else if (dmasound.hard.speed > 19668) {
1058 dmasound.hard.speed = 24585;
1059 divider = 3;
1060 } else if (dmasound.hard.speed > 16390) {
1061 dmasound.hard.speed = 19668;
1062 divider = 4;
1063 } else if (dmasound.hard.speed > 12292) {
1064 dmasound.hard.speed = 16390;
1065 divider = 5;
1066 } else if (dmasound.hard.speed > 9834) {
1067 dmasound.hard.speed = 12292;
1068 divider = 7;
1069 } else if (dmasound.hard.speed > 8195) {
1070 dmasound.hard.speed = 9834;
1071 divider = 9;
1072 } else {
1073 dmasound.hard.speed = 8195;
1074 divider = 11;
1075 }
1076 tt_dmasnd.int_div = divider;
1077
1078 /* Setup Falcon sound DMA for playback */
1079 tt_dmasnd.int_ctrl = 0x4; /* Timer A int at play end */
1080 tt_dmasnd.track_select = 0x0; /* play 1 track, track 1 */
1081 tt_dmasnd.cbar_src = 0x0001; /* DMA(25MHz) --> DAC */
1082 tt_dmasnd.cbar_dst = 0x0000;
1083 tt_dmasnd.rec_track_select = 0;
1084 tt_dmasnd.dac_src = 2; /* connect matrix to DAC */
1085 tt_dmasnd.adc_src = 0; /* ADC Input = Mic */
1086
1087 tt_dmasnd.mode = (dmasound.hard.stereo ?
1088 DMASND_MODE_STEREO : DMASND_MODE_MONO) |
1089 ((dmasound.hard.size == 8) ?
1090 DMASND_MODE_8BIT : DMASND_MODE_16BIT) |
1091 DMASND_MODE_6KHZ;
1092
1093 expand_bal = -dmasound.soft.speed;
1094 }
1095
1096
1097 static int FalconSetFormat(int format)
1098 {
1099 int size;
1100 /* Falcon sound DMA supports 8bit and 16bit modes */
1101
1102 switch (format) {
1103 case AFMT_QUERY:
1104 return dmasound.soft.format;
1105 case AFMT_MU_LAW:
1106 case AFMT_A_LAW:
1107 case AFMT_U8:
1108 case AFMT_S8:
1109 size = 8;
1110 break;
1111 case AFMT_S16_BE:
1112 case AFMT_U16_BE:
1113 case AFMT_S16_LE:
1114 case AFMT_U16_LE:
1115 size = 16;
1116 break;
1117 default: /* :-) */
1118 size = 8;
1119 format = AFMT_S8;
1120 }
1121
1122 dmasound.soft.format = format;
1123 dmasound.soft.size = size;
1124 if (dmasound.minDev == SND_DEV_DSP) {
1125 dmasound.dsp.format = format;
1126 dmasound.dsp.size = dmasound.soft.size;
1127 }
1128
1129 FalconInit();
1130
1131 return format;
1132 }
1133
1134
1135 /* This is for the Falcon output *attenuation* in 1.5dB steps,
1136 * i.e. output level from 0 to -22.5dB in -1.5dB steps.
1137 */
1138 #define VOLUME_VOXWARE_TO_ATT(v) \
1139 ((v) < 0 ? 15 : (v) > 100 ? 0 : 15 - (v) * 3 / 20)
1140 #define VOLUME_ATT_TO_VOXWARE(v) (100 - (v) * 20 / 3)
1141
1142
1143 static int FalconSetVolume(int volume)
1144 {
1145 dmasound.volume_left = VOLUME_VOXWARE_TO_ATT(volume & 0xff);
1146 dmasound.volume_right = VOLUME_VOXWARE_TO_ATT((volume & 0xff00) >> 8);
1147 tt_dmasnd.output_atten = dmasound.volume_left << 8 | dmasound.volume_right << 4;
1148 return VOLUME_ATT_TO_VOXWARE(dmasound.volume_left) |
1149 VOLUME_ATT_TO_VOXWARE(dmasound.volume_right) << 8;
1150 }
1151
1152
1153 static void AtaPlayNextFrame(int index)
1154 {
1155 char *start, *end;
1156
1157 /* used by AtaPlay() if all doubts whether there really is something
1158 * to be played are already wiped out.
1159 */
1160 start = write_sq.buffers[write_sq.front];
1161 end = start+((write_sq.count == index) ? write_sq.rear_size
1162 : write_sq.block_size);
1163 /* end might not be a legal virtual address. */
1164 DMASNDSetEnd(virt_to_phys(end - 1) + 1);
1165 DMASNDSetBase(virt_to_phys(start));
1166 /* Since only an even number of samples per frame can
1167 be played, we might lose one byte here. (TO DO) */
1168 write_sq.front = (write_sq.front+1) % write_sq.max_count;
1169 write_sq.active++;
1170 tt_dmasnd.ctrl = DMASND_CTRL_ON | DMASND_CTRL_REPEAT;
1171 }
1172
1173
1174 static void AtaPlay(void)
1175 {
1176 /* ++TeSche: Note that write_sq.active is no longer just a flag but
1177 * holds the number of frames the DMA is currently programmed for
1178 * instead, may be 0, 1 (currently being played) or 2 (pre-programmed).
1179 *
1180 * Changes done to write_sq.count and write_sq.active are a bit more
1181 * subtle again so now I must admit I also prefer disabling the irq
1182 * here rather than considering all possible situations. But the point
1183 * is that disabling the irq doesn't have any bad influence on this
1184 * version of the driver as we benefit from having pre-programmed the
1185 * DMA wherever possible: There's no need to reload the DMA at the
1186 * exact time of an interrupt but only at some time while the
1187 * pre-programmed frame is playing!
1188 */
1189 atari_disable_irq(IRQ_MFP_TIMA);
1190
1191 if (write_sq.active == 2 || /* DMA is 'full' */
1192 write_sq.count <= 0) { /* nothing to do */
1193 atari_enable_irq(IRQ_MFP_TIMA);
1194 return;
1195 }
1196
1197 if (write_sq.active == 0) {
1198 /* looks like there's nothing 'in' the DMA yet, so try
1199 * to put two frames into it (at least one is available).
1200 */
1201 if (write_sq.count == 1 &&
1202 write_sq.rear_size < write_sq.block_size &&
1203 !write_sq.syncing) {
1204 /* hmmm, the only existing frame is not
1205 * yet filled and we're not syncing?
1206 */
1207 atari_enable_irq(IRQ_MFP_TIMA);
1208 return;
1209 }
1210 AtaPlayNextFrame(1);
1211 if (write_sq.count == 1) {
1212 /* no more frames */
1213 atari_enable_irq(IRQ_MFP_TIMA);
1214 return;
1215 }
1216 if (write_sq.count == 2 &&
1217 write_sq.rear_size < write_sq.block_size &&
1218 !write_sq.syncing) {
1219 /* hmmm, there were two frames, but the second
1220 * one is not yet filled and we're not syncing?
1221 */
1222 atari_enable_irq(IRQ_MFP_TIMA);
1223 return;
1224 }
1225 AtaPlayNextFrame(2);
1226 } else {
1227 /* there's already a frame being played so we may only stuff
1228 * one new into the DMA, but even if this may be the last
1229 * frame existing the previous one is still on write_sq.count.
1230 */
1231 if (write_sq.count == 2 &&
1232 write_sq.rear_size < write_sq.block_size &&
1233 !write_sq.syncing) {
1234 /* hmmm, the only existing frame is not
1235 * yet filled and we're not syncing?
1236 */
1237 atari_enable_irq(IRQ_MFP_TIMA);
1238 return;
1239 }
1240 AtaPlayNextFrame(2);
1241 }
1242 atari_enable_irq(IRQ_MFP_TIMA);
1243 }
1244
1245
1246 static void AtaInterrupt(int irq, void *dummy, struct pt_regs *fp)
1247 {
1248 #if 0
1249 /* ++TeSche: if you should want to test this... */
1250 static int cnt = 0;
1251 if (write_sq.active == 2)
1252 if (++cnt == 10) {
1253 /* simulate losing an interrupt */
1254 cnt = 0;
1255 return;
1256 }
1257 #endif
1258
1259 if (write_sq_ignore_int && is_falcon) {
1260 /* ++TeSche: Falcon only: ignore first irq because it comes
1261 * immediately after starting a frame. after that, irqs come
1262 * (almost) like on the TT.
1263 */
1264 write_sq_ignore_int = 0;
1265 return;
1266 }
1267
1268 if (!write_sq.active) {
1269 /* playing was interrupted and sq_reset() has already cleared
1270 * the sq variables, so better don't do anything here.
1271 */
1272 WAKE_UP(write_sq.sync_queue);
1273 return;
1274 }
1275
1276 /* Probably ;) one frame is finished. Well, in fact it may be that a
1277 * pre-programmed one is also finished because there has been a long
1278 * delay in interrupt delivery and we've completely lost one, but
1279 * there's no way to detect such a situation. In such a case the last
1280 * frame will be played more than once and the situation will recover
1281 * as soon as the irq gets through.
1282 */
1283 write_sq.count--;
1284 write_sq.active--;
1285
1286 if (!write_sq.active) {
1287 tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1288 write_sq_ignore_int = 1;
1289 }
1290
1291 WAKE_UP(write_sq.action_queue);
1292 /* At least one block of the queue is free now
1293 so wake up a writing process blocked because
1294 of a full queue. */
1295
1296 if ((write_sq.active != 1) || (write_sq.count != 1))
1297 /* We must be a bit carefully here: write_sq.count indicates the
1298 * number of buffers used and not the number of frames to be
1299 * played. If write_sq.count==1 and write_sq.active==1 that
1300 * means the only remaining frame was already programmed
1301 * earlier (and is currently running) so we mustn't call
1302 * AtaPlay() here, otherwise we'll play one frame too much.
1303 */
1304 AtaPlay();
1305
1306 if (!write_sq.active) WAKE_UP(write_sq.sync_queue);
1307 /* We are not playing after AtaPlay(), so there
1308 is nothing to play any more. Wake up a process
1309 waiting for audio output to drain. */
1310 }
1311
1312
1313 /*** Mid level stuff *********************************************************/
1314
1315
1316 /*
1317 * /dev/mixer abstraction
1318 */
1319
1320 #define RECLEVEL_VOXWARE_TO_GAIN(v) \
1321 ((v) < 0 ? 0 : (v) > 100 ? 15 : (v) * 3 / 20)
1322 #define RECLEVEL_GAIN_TO_VOXWARE(v) (((v) * 20 + 2) / 3)
1323
1324
1325 static void __init TTMixerInit(void)
1326 {
1327 atari_microwire_cmd(MW_LM1992_VOLUME(0));
1328 dmasound.volume_left = 0;
1329 atari_microwire_cmd(MW_LM1992_BALLEFT(0));
1330 dmasound.volume_right = 0;
1331 atari_microwire_cmd(MW_LM1992_BALRIGHT(0));
1332 atari_microwire_cmd(MW_LM1992_TREBLE(0));
1333 atari_microwire_cmd(MW_LM1992_BASS(0));
1334 }
1335
1336 static void __init FalconMixerInit(void)
1337 {
1338 dmasound.volume_left = (tt_dmasnd.output_atten & 0xf00) >> 8;
1339 dmasound.volume_right = (tt_dmasnd.output_atten & 0xf0) >> 4;
1340 }
1341
1342 static int AtaMixerIoctl(u_int cmd, u_long arg)
1343 {
1344 int data;
1345 switch (cmd) {
1346 case SOUND_MIXER_READ_SPEAKER:
1347 if (is_falcon || MACH_IS_TT) {
1348 int porta;
1349 cli();
1350 sound_ym.rd_data_reg_sel = 14;
1351 porta = sound_ym.rd_data_reg_sel;
1352 sti();
1353 return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
1354 }
1355 break;
1356 case SOUND_MIXER_WRITE_VOLUME:
1357 IOCTL_IN(arg, data);
1358 return IOCTL_OUT(arg, dmasound_set_volume(data));
1359 case SOUND_MIXER_WRITE_SPEAKER:
1360 if (is_falcon || MACH_IS_TT) {
1361 int porta;
1362 IOCTL_IN(arg, data);
1363 cli();
1364 sound_ym.rd_data_reg_sel = 14;
1365 porta = (sound_ym.rd_data_reg_sel & ~0x40) |
1366 (data < 50 ? 0x40 : 0);
1367 sound_ym.wd_data = porta;
1368 sti();
1369 return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
1370 }
1371 }
1372 return -EINVAL;
1373 }
1374
1375
1376 static int TTMixerIoctl(u_int cmd, u_long arg)
1377 {
1378 int data;
1379 switch (cmd) {
1380 case SOUND_MIXER_READ_RECMASK:
1381 return IOCTL_OUT(arg, 0);
1382 case SOUND_MIXER_READ_DEVMASK:
1383 return IOCTL_OUT(arg,
1384 SOUND_MASK_VOLUME | SOUND_MASK_TREBLE | SOUND_MASK_BASS |
1385 (MACH_IS_TT ? SOUND_MASK_SPEAKER : 0));
1386 case SOUND_MIXER_READ_STEREODEVS:
1387 return IOCTL_OUT(arg, SOUND_MASK_VOLUME);
1388 case SOUND_MIXER_READ_VOLUME:
1389 return IOCTL_OUT(arg,
1390 VOLUME_DB_TO_VOXWARE(dmasound.volume_left) |
1391 (VOLUME_DB_TO_VOXWARE(dmasound.volume_right) << 8));
1392 case SOUND_MIXER_READ_BASS:
1393 return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(dmasound.bass));
1394 case SOUND_MIXER_READ_TREBLE:
1395 return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(dmasound.treble));
1396 case SOUND_MIXER_READ_OGAIN:
1397 return IOCTL_OUT(arg, GAIN_DB_TO_VOXWARE(dmasound.gain));
1398 case SOUND_MIXER_WRITE_BASS:
1399 IOCTL_IN(arg, data);
1400 return IOCTL_OUT(arg, dmasound_set_bass(data));
1401 case SOUND_MIXER_WRITE_TREBLE:
1402 IOCTL_IN(arg, data);
1403 return IOCTL_OUT(arg, dmasound_set_treble(data));
1404 case SOUND_MIXER_WRITE_OGAIN:
1405 IOCTL_IN(arg, data);
1406 return IOCTL_OUT(arg, dmasound_set_gain(data));
1407 }
1408 return AtaMixerIoctl(cmd, arg);
1409 }
1410
1411 static int FalconMixerIoctl(u_int cmd, u_long arg)
1412 {
1413 int data;
1414 switch (cmd) {
1415 case SOUND_MIXER_READ_RECMASK:
1416 return IOCTL_OUT(arg, SOUND_MASK_MIC);
1417 case SOUND_MIXER_READ_DEVMASK:
1418 return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_SPEAKER);
1419 case SOUND_MIXER_READ_STEREODEVS:
1420 return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC);
1421 case SOUND_MIXER_READ_VOLUME:
1422 return IOCTL_OUT(arg,
1423 VOLUME_ATT_TO_VOXWARE(dmasound.volume_left) |
1424 VOLUME_ATT_TO_VOXWARE(dmasound.volume_right) << 8);
1425 case SOUND_MIXER_READ_CAPS:
1426 return IOCTL_OUT(arg, SOUND_CAP_EXCL_INPUT);
1427 case SOUND_MIXER_WRITE_MIC:
1428 IOCTL_IN(arg, data);
1429 tt_dmasnd.input_gain =
1430 RECLEVEL_VOXWARE_TO_GAIN(data & 0xff) << 4 |
1431 RECLEVEL_VOXWARE_TO_GAIN(data >> 8 & 0xff);
1432 /* fall thru, return set value */
1433 case SOUND_MIXER_READ_MIC:
1434 return IOCTL_OUT(arg,
1435 RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain >> 4 & 0xf) |
1436 RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain & 0xf) << 8);
1437 }
1438 return AtaMixerIoctl(cmd, arg);
1439 }
1440
1441 static void AtaWriteSqSetup(void)
1442 {
1443 write_sq_ignore_int = 0;
1444 }
1445
1446 static void AtaSqOpen(void)
1447 {
1448 write_sq_ignore_int = 1;
1449 }
1450
1451 static int TTStateInfo(char *buffer)
1452 {
1453 int len = 0;
1454 len += sprintf(buffer+len, "\tsound.volume_left = %ddB [-40...0]\n",
1455 dmasound.volume_left);
1456 len += sprintf(buffer+len, "\tsound.volume_right = %ddB [-40...0]\n",
1457 dmasound.volume_right);
1458 len += sprintf(buffer+len, "\tsound.bass = %ddB [-12...+12]\n",
1459 dmasound.bass);
1460 len += sprintf(buffer+len, "\tsound.treble = %ddB [-12...+12]\n",
1461 dmasound.treble);
1462 return len;
1463 }
1464
1465 static int FalconStateInfo(char *buffer)
1466 {
1467 int len = 0;
1468 len += sprintf(buffer+len, "\tsound.volume_left = %ddB [-22.5...0]\n",
1469 dmasound.volume_left);
1470 len += sprintf(buffer+len, "\tsound.volume_right = %ddB [-22.5...0]\n",
1471 dmasound.volume_right);
1472 return len;
1473 }
1474
1475
1476 /*** Machine definitions *****************************************************/
1477
1478
1479 static MACHINE machTT = {
1480 name: "Atari",
1481 name2: "TT",
1482 open: AtaOpen,
1483 release: AtaRelease,
1484 dma_alloc: AtaAlloc,
1485 dma_free: AtaFree,
1486 irqinit: AtaIrqInit,
1487 #ifdef MODULE
1488 irqcleanup: AtaIrqCleanUp,
1489 #endif /* MODULE */
1490 init: TTInit,
1491 silence: TTSilence,
1492 setFormat: TTSetFormat,
1493 setVolume: TTSetVolume,
1494 setBass: AtaSetBass,
1495 setTreble: AtaSetTreble,
1496 setGain: TTSetGain,
1497 play: AtaPlay,
1498 mixer_init: TTMixerInit,
1499 mixer_ioctl: TTMixerIoctl,
1500 write_sq_setup: AtaWriteSqSetup,
1501 sq_open: AtaSqOpen,
1502 state_info: TTStateInfo,
1503 min_dsp_speed: 6258,
1504 };
1505
1506 static MACHINE machFalcon = {
1507 name: "Atari",
1508 name2: "FALCON",
1509 dma_alloc: AtaAlloc,
1510 dma_free: AtaFree,
1511 irqinit: AtaIrqInit,
1512 #ifdef MODULE
1513 irqcleanup: AtaIrqCleanUp,
1514 #endif /* MODULE */
1515 init: FalconInit,
1516 silence: FalconSilence,
1517 setFormat: FalconSetFormat,
1518 setVolume: FalconSetVolume,
1519 setBass: AtaSetBass,
1520 setTreble: AtaSetTreble,
1521 play: AtaPlay,
1522 mixer_init: FalconMixerInit,
1523 mixer_ioctl: FalconMixerIoctl,
1524 write_sq_setup: AtaWriteSqSetup,
1525 sq_open: AtaSqOpen,
1526 state_info: FalconStateInfo,
1527 min_dsp_speed: 8195,
1528 };
1529
1530
1531 /*** Config & Setup **********************************************************/
1532
1533
1534 static int __init dmasound_atari_init(void)
1535 {
1536 if (MACH_IS_ATARI && ATARIHW_PRESENT(PCM_8BIT)) {
1537 if (ATARIHW_PRESENT(CODEC)) {
1538 dmasound.mach = machFalcon;
1539 is_falcon = 1;
1540 } else if (ATARIHW_PRESENT(MICROWIRE)) {
1541 dmasound.mach = machTT;
1542 is_falcon = 0;
1543 } else
1544 return -ENODEV;
1545 if ((mfp.int_en_a & mfp.int_mk_a & 0x20) == 0)
1546 return dmasound_init();
1547 else {
1548 printk("DMA sound driver: Timer A interrupt already in use\n");
1549 return -EBUSY;
1550 }
1551 }
1552 return -ENODEV;
1553 }
1554
1555 static void __exit dmasound_atari_cleanup(void)
1556 {
1557 dmasound_deinit();
1558 }
1559
1560 module_init(dmasound_atari_init);
1561 module_exit(dmasound_atari_cleanup);
1562