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