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