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