1 // SPDX-License-Identifier: GPL-2.0-only
3 * linux/sound/oss/dmasound/dmasound_atari.c
5 * Atari TT and Falcon DMA Sound Driver
7 * See linux/sound/oss/dmasound/dmasound_core.c for copyright and credits
10 * 28/01/2001 [0.1] Iain Sandoe
12 * - put in and populated the hardware_afmts field.
13 * [0.2] - put in SNDCTL_DSP_GETCAPS value.
14 * 01/02/2001 [0.3] - put in default hard/soft settings.
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21 #include <linux/soundcard.h>
23 #include <linux/spinlock.h>
24 #include <linux/interrupt.h>
26 #include <linux/uaccess.h>
27 #include <asm/atariints.h>
28 #include <asm/atari_stram.h>
32 #define DMASOUND_ATARI_REVISION 0
33 #define DMASOUND_ATARI_EDITION 3
35 extern void atari_microwire_cmd(int cmd
);
38 static int write_sq_ignore_int
; /* ++TeSche: used for Falcon */
40 static int expand_bal
; /* Balance factor for expanding (not volume!) */
41 static int expand_data
; /* Data for expanding */
44 /*** Translations ************************************************************/
47 /* ++TeSche: radically changed for new expanding purposes...
49 * These two routines now deal with copying/expanding/translating the samples
50 * from user space into our buffer at the right frequency. They take care about
51 * how much data there's actually to read, how much buffer space there is and
52 * to convert samples into the right frequency/encoding. They will only work on
53 * complete samples so it may happen they leave some bytes in the input stream
54 * if the user didn't write a multiple of the current sample size. They both
55 * return the number of bytes they've used from both streams so you may detect
56 * such a situation. Luckily all programs should be able to cope with that.
58 * I think I've optimized anything as far as one can do in plain C, all
59 * variables should fit in registers and the loops are really short. There's
60 * one loop for every possible situation. Writing a more generalized and thus
61 * parameterized loop would only produce slower code. Feel free to optimize
62 * this in assembler if you like. :)
64 * I think these routines belong here because they're not yet really hardware
65 * independent, especially the fact that the Falcon can play 16bit samples
66 * only in stereo is hardcoded in both of them!
68 * ++geert: split in even more functions (one per format)
71 static ssize_t
ata_ct_law(const u_char __user
*userPtr
, size_t userCount
,
72 u_char frame
[], ssize_t
*frameUsed
,
74 static ssize_t
ata_ct_s8(const u_char __user
*userPtr
, size_t userCount
,
75 u_char frame
[], ssize_t
*frameUsed
,
77 static ssize_t
ata_ct_u8(const u_char __user
*userPtr
, size_t userCount
,
78 u_char frame
[], ssize_t
*frameUsed
,
80 static ssize_t
ata_ct_s16be(const u_char __user
*userPtr
, size_t userCount
,
81 u_char frame
[], ssize_t
*frameUsed
,
83 static ssize_t
ata_ct_u16be(const u_char __user
*userPtr
, size_t userCount
,
84 u_char frame
[], ssize_t
*frameUsed
,
86 static ssize_t
ata_ct_s16le(const u_char __user
*userPtr
, size_t userCount
,
87 u_char frame
[], ssize_t
*frameUsed
,
89 static ssize_t
ata_ct_u16le(const u_char __user
*userPtr
, size_t userCount
,
90 u_char frame
[], ssize_t
*frameUsed
,
92 static ssize_t
ata_ctx_law(const u_char __user
*userPtr
, size_t userCount
,
93 u_char frame
[], ssize_t
*frameUsed
,
95 static ssize_t
ata_ctx_s8(const u_char __user
*userPtr
, size_t userCount
,
96 u_char frame
[], ssize_t
*frameUsed
,
98 static ssize_t
ata_ctx_u8(const u_char __user
*userPtr
, size_t userCount
,
99 u_char frame
[], ssize_t
*frameUsed
,
101 static ssize_t
ata_ctx_s16be(const u_char __user
*userPtr
, size_t userCount
,
102 u_char frame
[], ssize_t
*frameUsed
,
104 static ssize_t
ata_ctx_u16be(const u_char __user
*userPtr
, size_t userCount
,
105 u_char frame
[], ssize_t
*frameUsed
,
107 static ssize_t
ata_ctx_s16le(const u_char __user
*userPtr
, size_t userCount
,
108 u_char frame
[], ssize_t
*frameUsed
,
110 static ssize_t
ata_ctx_u16le(const u_char __user
*userPtr
, size_t userCount
,
111 u_char frame
[], ssize_t
*frameUsed
,
115 /*** Low level stuff *********************************************************/
118 static void *AtaAlloc(unsigned int size
, gfp_t flags
);
119 static void AtaFree(void *, unsigned int size
);
120 static int AtaIrqInit(void);
122 static void AtaIrqCleanUp(void);
124 static int AtaSetBass(int bass
);
125 static int AtaSetTreble(int treble
);
126 static void TTSilence(void);
127 static void TTInit(void);
128 static int TTSetFormat(int format
);
129 static int TTSetVolume(int volume
);
130 static int TTSetGain(int gain
);
131 static void FalconSilence(void);
132 static void FalconInit(void);
133 static int FalconSetFormat(int format
);
134 static int FalconSetVolume(int volume
);
135 static void AtaPlayNextFrame(int index
);
136 static void AtaPlay(void);
137 static irqreturn_t
AtaInterrupt(int irq
, void *dummy
);
139 /*** Mid level stuff *********************************************************/
141 static void TTMixerInit(void);
142 static void FalconMixerInit(void);
143 static int AtaMixerIoctl(u_int cmd
, u_long arg
);
144 static int TTMixerIoctl(u_int cmd
, u_long arg
);
145 static int FalconMixerIoctl(u_int cmd
, u_long arg
);
146 static int AtaWriteSqSetup(void);
147 static int AtaSqOpen(fmode_t mode
);
148 static int TTStateInfo(char *buffer
, size_t space
);
149 static int FalconStateInfo(char *buffer
, size_t space
);
152 /*** Translations ************************************************************/
155 static ssize_t
ata_ct_law(const u_char __user
*userPtr
, size_t userCount
,
156 u_char frame
[], ssize_t
*frameUsed
,
159 char *table
= dmasound
.soft
.format
== AFMT_MU_LAW
? dmasound_ulaw2dma8
160 : dmasound_alaw2dma8
;
162 u_char
*p
= &frame
[*frameUsed
];
164 count
= min_t(unsigned long, userCount
, frameLeft
);
165 if (dmasound
.soft
.stereo
)
170 if (get_user(data
, userPtr
++))
180 static ssize_t
ata_ct_s8(const u_char __user
*userPtr
, size_t userCount
,
181 u_char frame
[], ssize_t
*frameUsed
,
185 void *p
= &frame
[*frameUsed
];
187 count
= min_t(unsigned long, userCount
, frameLeft
);
188 if (dmasound
.soft
.stereo
)
191 if (copy_from_user(p
, userPtr
, count
))
198 static ssize_t
ata_ct_u8(const u_char __user
*userPtr
, size_t userCount
,
199 u_char frame
[], ssize_t
*frameUsed
,
204 if (!dmasound
.soft
.stereo
) {
205 u_char
*p
= &frame
[*frameUsed
];
206 count
= min_t(unsigned long, userCount
, frameLeft
);
210 if (get_user(data
, userPtr
++))
216 u_short
*p
= (u_short
*)&frame
[*frameUsed
];
217 count
= min_t(unsigned long, userCount
, frameLeft
)>>1;
221 if (get_user(data
, (u_short __user
*)userPtr
))
224 *p
++ = data
^ 0x8080;
233 static ssize_t
ata_ct_s16be(const u_char __user
*userPtr
, size_t userCount
,
234 u_char frame
[], ssize_t
*frameUsed
,
239 if (!dmasound
.soft
.stereo
) {
240 u_short
*p
= (u_short
*)&frame
[*frameUsed
];
241 count
= min_t(unsigned long, userCount
, frameLeft
)>>1;
245 if (get_user(data
, (u_short __user
*)userPtr
))
252 *frameUsed
+= used
*2;
254 void *p
= (u_short
*)&frame
[*frameUsed
];
255 count
= min_t(unsigned long, userCount
, frameLeft
) & ~3;
257 if (copy_from_user(p
, userPtr
, count
))
265 static ssize_t
ata_ct_u16be(const u_char __user
*userPtr
, size_t userCount
,
266 u_char frame
[], ssize_t
*frameUsed
,
271 if (!dmasound
.soft
.stereo
) {
272 u_short
*p
= (u_short
*)&frame
[*frameUsed
];
273 count
= min_t(unsigned long, userCount
, frameLeft
)>>1;
277 if (get_user(data
, (u_short __user
*)userPtr
))
285 *frameUsed
+= used
*2;
287 u_long
*p
= (u_long
*)&frame
[*frameUsed
];
288 count
= min_t(unsigned long, userCount
, frameLeft
)>>2;
292 if (get_user(data
, (u_int __user
*)userPtr
))
295 *p
++ = data
^ 0x80008000;
304 static ssize_t
ata_ct_s16le(const u_char __user
*userPtr
, size_t userCount
,
305 u_char frame
[], ssize_t
*frameUsed
,
311 if (!dmasound
.soft
.stereo
) {
312 u_short
*p
= (u_short
*)&frame
[*frameUsed
];
313 count
= min_t(unsigned long, userCount
, frameLeft
)>>1;
317 if (get_user(data
, (u_short __user
*)userPtr
))
320 data
= le2be16(data
);
325 *frameUsed
+= used
*2;
327 u_long
*p
= (u_long
*)&frame
[*frameUsed
];
328 count
= min_t(unsigned long, userCount
, frameLeft
)>>2;
332 if (get_user(data
, (u_int __user
*)userPtr
))
335 data
= le2be16dbl(data
);
345 static ssize_t
ata_ct_u16le(const u_char __user
*userPtr
, size_t userCount
,
346 u_char frame
[], ssize_t
*frameUsed
,
352 if (!dmasound
.soft
.stereo
) {
353 u_short
*p
= (u_short
*)&frame
[*frameUsed
];
354 count
= min_t(unsigned long, userCount
, frameLeft
)>>1;
358 if (get_user(data
, (u_short __user
*)userPtr
))
361 data
= le2be16(data
) ^ 0x8000;
365 *frameUsed
+= used
*2;
367 u_long
*p
= (u_long
*)&frame
[*frameUsed
];
368 count
= min_t(unsigned long, userCount
, frameLeft
)>>2;
372 if (get_user(data
, (u_int __user
*)userPtr
))
375 data
= le2be16dbl(data
) ^ 0x80008000;
385 static ssize_t
ata_ctx_law(const u_char __user
*userPtr
, size_t userCount
,
386 u_char frame
[], ssize_t
*frameUsed
,
389 char *table
= dmasound
.soft
.format
== AFMT_MU_LAW
? dmasound_ulaw2dma8
390 : dmasound_alaw2dma8
;
391 /* this should help gcc to stuff everything into registers */
392 long bal
= expand_bal
;
393 long hSpeed
= dmasound
.hard
.speed
, sSpeed
= dmasound
.soft
.speed
;
398 if (!dmasound
.soft
.stereo
) {
399 u_char
*p
= &frame
[*frameUsed
];
400 u_char data
= expand_data
;
406 if (get_user(c
, userPtr
++))
418 u_short
*p
= (u_short
*)&frame
[*frameUsed
];
419 u_short data
= expand_data
;
420 while (frameLeft
>= 2) {
425 if (get_user(c
, userPtr
++))
427 data
= table
[c
] << 8;
428 if (get_user(c
, userPtr
++))
442 *frameUsed
+= usedf
-frameLeft
;
447 static ssize_t
ata_ctx_s8(const u_char __user
*userPtr
, size_t userCount
,
448 u_char frame
[], ssize_t
*frameUsed
,
451 /* this should help gcc to stuff everything into registers */
452 long bal
= expand_bal
;
453 long hSpeed
= dmasound
.hard
.speed
, sSpeed
= dmasound
.soft
.speed
;
458 if (!dmasound
.soft
.stereo
) {
459 u_char
*p
= &frame
[*frameUsed
];
460 u_char data
= expand_data
;
465 if (get_user(data
, userPtr
++))
476 u_short
*p
= (u_short
*)&frame
[*frameUsed
];
477 u_short data
= expand_data
;
478 while (frameLeft
>= 2) {
482 if (get_user(data
, (u_short __user
*)userPtr
))
496 *frameUsed
+= usedf
-frameLeft
;
501 static ssize_t
ata_ctx_u8(const u_char __user
*userPtr
, size_t userCount
,
502 u_char frame
[], ssize_t
*frameUsed
,
505 /* this should help gcc to stuff everything into registers */
506 long bal
= expand_bal
;
507 long hSpeed
= dmasound
.hard
.speed
, sSpeed
= dmasound
.soft
.speed
;
512 if (!dmasound
.soft
.stereo
) {
513 u_char
*p
= &frame
[*frameUsed
];
514 u_char data
= expand_data
;
519 if (get_user(data
, userPtr
++))
531 u_short
*p
= (u_short
*)&frame
[*frameUsed
];
532 u_short data
= expand_data
;
533 while (frameLeft
>= 2) {
537 if (get_user(data
, (u_short __user
*)userPtr
))
552 *frameUsed
+= usedf
-frameLeft
;
557 static ssize_t
ata_ctx_s16be(const u_char __user
*userPtr
, size_t userCount
,
558 u_char frame
[], ssize_t
*frameUsed
,
561 /* this should help gcc to stuff everything into registers */
562 long bal
= expand_bal
;
563 long hSpeed
= dmasound
.hard
.speed
, sSpeed
= dmasound
.soft
.speed
;
568 if (!dmasound
.soft
.stereo
) {
569 u_short
*p
= (u_short
*)&frame
[*frameUsed
];
570 u_short data
= expand_data
;
571 while (frameLeft
>= 4) {
575 if (get_user(data
, (u_short __user
*)userPtr
))
588 u_long
*p
= (u_long
*)&frame
[*frameUsed
];
589 u_long data
= expand_data
;
590 while (frameLeft
>= 4) {
594 if (get_user(data
, (u_int __user
*)userPtr
))
608 *frameUsed
+= usedf
-frameLeft
;
613 static ssize_t
ata_ctx_u16be(const u_char __user
*userPtr
, size_t userCount
,
614 u_char frame
[], ssize_t
*frameUsed
,
617 /* this should help gcc to stuff everything into registers */
618 long bal
= expand_bal
;
619 long hSpeed
= dmasound
.hard
.speed
, sSpeed
= dmasound
.soft
.speed
;
624 if (!dmasound
.soft
.stereo
) {
625 u_short
*p
= (u_short
*)&frame
[*frameUsed
];
626 u_short data
= expand_data
;
627 while (frameLeft
>= 4) {
631 if (get_user(data
, (u_short __user
*)userPtr
))
645 u_long
*p
= (u_long
*)&frame
[*frameUsed
];
646 u_long data
= expand_data
;
647 while (frameLeft
>= 4) {
651 if (get_user(data
, (u_int __user
*)userPtr
))
666 *frameUsed
+= usedf
-frameLeft
;
671 static ssize_t
ata_ctx_s16le(const u_char __user
*userPtr
, size_t userCount
,
672 u_char frame
[], ssize_t
*frameUsed
,
675 /* this should help gcc to stuff everything into registers */
676 long bal
= expand_bal
;
677 long hSpeed
= dmasound
.hard
.speed
, sSpeed
= dmasound
.soft
.speed
;
682 if (!dmasound
.soft
.stereo
) {
683 u_short
*p
= (u_short
*)&frame
[*frameUsed
];
684 u_short data
= expand_data
;
685 while (frameLeft
>= 4) {
689 if (get_user(data
, (u_short __user
*)userPtr
))
692 data
= le2be16(data
);
703 u_long
*p
= (u_long
*)&frame
[*frameUsed
];
704 u_long data
= expand_data
;
705 while (frameLeft
>= 4) {
709 if (get_user(data
, (u_int __user
*)userPtr
))
712 data
= le2be16dbl(data
);
724 *frameUsed
+= usedf
-frameLeft
;
729 static ssize_t
ata_ctx_u16le(const u_char __user
*userPtr
, size_t userCount
,
730 u_char frame
[], ssize_t
*frameUsed
,
733 /* this should help gcc to stuff everything into registers */
734 long bal
= expand_bal
;
735 long hSpeed
= dmasound
.hard
.speed
, sSpeed
= dmasound
.soft
.speed
;
740 if (!dmasound
.soft
.stereo
) {
741 u_short
*p
= (u_short
*)&frame
[*frameUsed
];
742 u_short data
= expand_data
;
743 while (frameLeft
>= 4) {
747 if (get_user(data
, (u_short __user
*)userPtr
))
750 data
= le2be16(data
) ^ 0x8000;
761 u_long
*p
= (u_long
*)&frame
[*frameUsed
];
762 u_long data
= expand_data
;
763 while (frameLeft
>= 4) {
767 if (get_user(data
, (u_int __user
*)userPtr
))
770 data
= le2be16dbl(data
) ^ 0x80008000;
782 *frameUsed
+= usedf
-frameLeft
;
787 static TRANS transTTNormal
= {
788 .ct_ulaw
= ata_ct_law
,
789 .ct_alaw
= ata_ct_law
,
794 static TRANS transTTExpanding
= {
795 .ct_ulaw
= ata_ctx_law
,
796 .ct_alaw
= ata_ctx_law
,
801 static TRANS transFalconNormal
= {
802 .ct_ulaw
= ata_ct_law
,
803 .ct_alaw
= ata_ct_law
,
806 .ct_s16be
= ata_ct_s16be
,
807 .ct_u16be
= ata_ct_u16be
,
808 .ct_s16le
= ata_ct_s16le
,
809 .ct_u16le
= ata_ct_u16le
812 static TRANS transFalconExpanding
= {
813 .ct_ulaw
= ata_ctx_law
,
814 .ct_alaw
= ata_ctx_law
,
817 .ct_s16be
= ata_ctx_s16be
,
818 .ct_u16be
= ata_ctx_u16be
,
819 .ct_s16le
= ata_ctx_s16le
,
820 .ct_u16le
= ata_ctx_u16le
,
824 /*** Low level stuff *********************************************************/
832 static void *AtaAlloc(unsigned int size
, gfp_t flags
)
834 return atari_stram_alloc(size
, "dmasound");
837 static void AtaFree(void *obj
, unsigned int size
)
839 atari_stram_free( obj
);
842 static int __init
AtaIrqInit(void)
844 /* Set up timer A. Timer A
845 will receive a signal upon end of playing from the sound
846 hardware. Furthermore Timer A is able to count events
847 and will cause an interrupt after a programmed number
848 of events. So all we need to keep the music playing is
849 to provide the sound hardware with new data upon
850 an interrupt from timer A. */
851 st_mfp
.tim_ct_a
= 0; /* ++roman: Stop timer before programming! */
852 st_mfp
.tim_dt_a
= 1; /* Cause interrupt after first event. */
853 st_mfp
.tim_ct_a
= 8; /* Turn on event counting. */
854 /* Register interrupt handler. */
855 if (request_irq(IRQ_MFP_TIMA
, AtaInterrupt
, 0, "DMA sound",
858 st_mfp
.int_en_a
|= 0x20; /* Turn interrupt on. */
859 st_mfp
.int_mk_a
|= 0x20;
864 static void AtaIrqCleanUp(void)
866 st_mfp
.tim_ct_a
= 0; /* stop timer */
867 st_mfp
.int_en_a
&= ~0x20; /* turn interrupt off */
868 free_irq(IRQ_MFP_TIMA
, AtaInterrupt
);
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)
878 static int AtaSetBass(int bass
)
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
);
886 static int AtaSetTreble(int treble
)
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
);
900 static void TTSilence(void)
902 tt_dmasnd
.ctrl
= DMASND_CTRL_OFF
;
903 atari_microwire_cmd(MW_LM1992_PSG_HIGH
); /* mix in PSG signal 1:1 */
907 static void TTInit(void)
910 const int freq
[4] = {50066, 25033, 12517, 6258};
912 /* search a frequency that fits into the allowed error range */
915 for (i
= 0; i
< ARRAY_SIZE(freq
); i
++)
916 /* this isn't as much useful for a TT than for a Falcon, but
917 * then it doesn't hurt very much to implement it for a TT too.
919 if ((100 * abs(dmasound
.soft
.speed
- freq
[i
]) / freq
[i
]) < catchRadius
)
922 dmasound
.soft
.speed
= freq
[idx
];
923 dmasound
.trans_write
= &transTTNormal
;
925 dmasound
.trans_write
= &transTTExpanding
;
928 dmasound
.hard
= dmasound
.soft
;
930 if (dmasound
.hard
.speed
> 50066) {
931 /* we would need to squeeze the sound, but we won't do that */
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
;
945 dmasound
.hard
.speed
= 6258;
946 mode
= DMASND_MODE_6KHZ
;
949 tt_dmasnd
.mode
= (dmasound
.hard
.stereo
?
950 DMASND_MODE_STEREO
: DMASND_MODE_MONO
) |
951 DMASND_MODE_8BIT
| mode
;
953 expand_bal
= -dmasound
.soft
.speed
;
957 static int TTSetFormat(int format
)
959 /* TT sound DMA supports only 8bit modes */
963 return dmasound
.soft
.format
;
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;
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)
990 static int TTSetVolume(int volume
)
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);
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)
1005 static int TTSetGain(int gain
)
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
);
1019 static void FalconSilence(void)
1021 /* stop playback, set sample rate 50kHz for PSG sound */
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; /* STE compatible divider */
1025 tt_dmasnd
.int_ctrl
= 0x0;
1026 tt_dmasnd
.cbar_src
= 0x0000; /* no matrix inputs */
1027 tt_dmasnd
.cbar_dst
= 0x0000; /* no matrix outputs */
1028 tt_dmasnd
.dac_src
= 1; /* connect ADC to DAC, disconnect matrix */
1029 tt_dmasnd
.adc_src
= 3; /* ADC Input = PSG */
1033 static void FalconInit(void)
1035 int divider
, i
, idx
;
1036 const int freq
[8] = {49170, 32780, 24585, 19668, 16390, 12292, 9834, 8195};
1038 /* search a frequency that fits into the allowed error range */
1041 for (i
= 0; i
< ARRAY_SIZE(freq
); i
++)
1042 /* if we will tolerate 3% error 8000Hz->8195Hz (2.38%) would
1043 * be playable without expanding, but that now a kernel runtime
1046 if ((100 * abs(dmasound
.soft
.speed
- freq
[i
]) / freq
[i
]) < catchRadius
)
1049 dmasound
.soft
.speed
= freq
[idx
];
1050 dmasound
.trans_write
= &transFalconNormal
;
1052 dmasound
.trans_write
= &transFalconExpanding
;
1055 dmasound
.hard
= dmasound
.soft
;
1057 if (dmasound
.hard
.size
== 16) {
1058 /* the Falcon can play 16bit samples only in stereo */
1059 dmasound
.hard
.stereo
= 1;
1062 if (dmasound
.hard
.speed
> 49170) {
1063 /* we would need to squeeze the sound, but we won't do that */
1064 dmasound
.hard
.speed
= 49170;
1066 dmasound
.trans_write
= &transFalconNormal
;
1067 } else if (dmasound
.hard
.speed
> 32780) {
1068 dmasound
.hard
.speed
= 49170;
1070 } else if (dmasound
.hard
.speed
> 24585) {
1071 dmasound
.hard
.speed
= 32780;
1073 } else if (dmasound
.hard
.speed
> 19668) {
1074 dmasound
.hard
.speed
= 24585;
1076 } else if (dmasound
.hard
.speed
> 16390) {
1077 dmasound
.hard
.speed
= 19668;
1079 } else if (dmasound
.hard
.speed
> 12292) {
1080 dmasound
.hard
.speed
= 16390;
1082 } else if (dmasound
.hard
.speed
> 9834) {
1083 dmasound
.hard
.speed
= 12292;
1085 } else if (dmasound
.hard
.speed
> 8195) {
1086 dmasound
.hard
.speed
= 9834;
1089 dmasound
.hard
.speed
= 8195;
1092 tt_dmasnd
.int_div
= divider
;
1094 /* Setup Falcon sound DMA for playback */
1095 tt_dmasnd
.int_ctrl
= 0x4; /* Timer A int at play end */
1096 tt_dmasnd
.track_select
= 0x0; /* play 1 track, track 1 */
1097 tt_dmasnd
.cbar_src
= 0x0001; /* DMA(25MHz) --> DAC */
1098 tt_dmasnd
.cbar_dst
= 0x0000;
1099 tt_dmasnd
.rec_track_select
= 0;
1100 tt_dmasnd
.dac_src
= 2; /* connect matrix to DAC */
1101 tt_dmasnd
.adc_src
= 0; /* ADC Input = Mic */
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
) |
1109 expand_bal
= -dmasound
.soft
.speed
;
1113 static int FalconSetFormat(int format
)
1116 /* Falcon sound DMA supports 8bit and 16bit modes */
1120 return dmasound
.soft
.format
;
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
;
1151 /* This is for the Falcon output *attenuation* in 1.5dB steps,
1152 * i.e. output level from 0 to -22.5dB in -1.5dB steps.
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)
1159 static int FalconSetVolume(int volume
)
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;
1169 static void AtaPlayNextFrame(int index
)
1173 /* used by AtaPlay() if all doubts whether there really is something
1174 * to be played are already wiped out.
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 /* end might not be a legal virtual address. */
1180 DMASNDSetEnd(virt_to_phys(end
- 1) + 1);
1181 DMASNDSetBase(virt_to_phys(start
));
1182 /* Since only an even number of samples per frame can
1183 be played, we might lose one byte here. (TO DO) */
1184 write_sq
.front
= (write_sq
.front
+1) % write_sq
.max_count
;
1186 tt_dmasnd
.ctrl
= DMASND_CTRL_ON
| DMASND_CTRL_REPEAT
;
1190 static void AtaPlay(void)
1192 /* ++TeSche: Note that write_sq.active is no longer just a flag but
1193 * holds the number of frames the DMA is currently programmed for
1194 * instead, may be 0, 1 (currently being played) or 2 (pre-programmed).
1196 * Changes done to write_sq.count and write_sq.active are a bit more
1197 * subtle again so now I must admit I also prefer disabling the irq
1198 * here rather than considering all possible situations. But the point
1199 * is that disabling the irq doesn't have any bad influence on this
1200 * version of the driver as we benefit from having pre-programmed the
1201 * DMA wherever possible: There's no need to reload the DMA at the
1202 * exact time of an interrupt but only at some time while the
1203 * pre-programmed frame is playing!
1205 atari_disable_irq(IRQ_MFP_TIMA
);
1207 if (write_sq
.active
== 2 || /* DMA is 'full' */
1208 write_sq
.count
<= 0) { /* nothing to do */
1209 atari_enable_irq(IRQ_MFP_TIMA
);
1213 if (write_sq
.active
== 0) {
1214 /* looks like there's nothing 'in' the DMA yet, so try
1215 * to put two frames into it (at least one is available).
1217 if (write_sq
.count
== 1 &&
1218 write_sq
.rear_size
< write_sq
.block_size
&&
1219 !write_sq
.syncing
) {
1220 /* hmmm, the only existing frame is not
1221 * yet filled and we're not syncing?
1223 atari_enable_irq(IRQ_MFP_TIMA
);
1226 AtaPlayNextFrame(1);
1227 if (write_sq
.count
== 1) {
1228 /* no more frames */
1229 atari_enable_irq(IRQ_MFP_TIMA
);
1232 if (write_sq
.count
== 2 &&
1233 write_sq
.rear_size
< write_sq
.block_size
&&
1234 !write_sq
.syncing
) {
1235 /* hmmm, there were two frames, but the second
1236 * one is not yet filled and we're not syncing?
1238 atari_enable_irq(IRQ_MFP_TIMA
);
1241 AtaPlayNextFrame(2);
1243 /* there's already a frame being played so we may only stuff
1244 * one new into the DMA, but even if this may be the last
1245 * frame existing the previous one is still on write_sq.count.
1247 if (write_sq
.count
== 2 &&
1248 write_sq
.rear_size
< write_sq
.block_size
&&
1249 !write_sq
.syncing
) {
1250 /* hmmm, the only existing frame is not
1251 * yet filled and we're not syncing?
1253 atari_enable_irq(IRQ_MFP_TIMA
);
1256 AtaPlayNextFrame(2);
1258 atari_enable_irq(IRQ_MFP_TIMA
);
1262 static irqreturn_t
AtaInterrupt(int irq
, void *dummy
)
1265 /* ++TeSche: if you should want to test this... */
1267 if (write_sq
.active
== 2)
1269 /* simulate losing an interrupt */
1274 spin_lock(&dmasound
.lock
);
1275 if (write_sq_ignore_int
&& is_falcon
) {
1276 /* ++TeSche: Falcon only: ignore first irq because it comes
1277 * immediately after starting a frame. after that, irqs come
1278 * (almost) like on the TT.
1280 write_sq_ignore_int
= 0;
1284 if (!write_sq
.active
) {
1285 /* playing was interrupted and sq_reset() has already cleared
1286 * the sq variables, so better don't do anything here.
1288 WAKE_UP(write_sq
.sync_queue
);
1292 /* Probably ;) one frame is finished. Well, in fact it may be that a
1293 * pre-programmed one is also finished because there has been a long
1294 * delay in interrupt delivery and we've completely lost one, but
1295 * there's no way to detect such a situation. In such a case the last
1296 * frame will be played more than once and the situation will recover
1297 * as soon as the irq gets through.
1302 if (!write_sq
.active
) {
1303 tt_dmasnd
.ctrl
= DMASND_CTRL_OFF
;
1304 write_sq_ignore_int
= 1;
1307 WAKE_UP(write_sq
.action_queue
);
1308 /* At least one block of the queue is free now
1309 so wake up a writing process blocked because
1312 if ((write_sq
.active
!= 1) || (write_sq
.count
!= 1))
1313 /* We must be a bit carefully here: write_sq.count indicates the
1314 * number of buffers used and not the number of frames to be
1315 * played. If write_sq.count==1 and write_sq.active==1 that
1316 * means the only remaining frame was already programmed
1317 * earlier (and is currently running) so we mustn't call
1318 * AtaPlay() here, otherwise we'll play one frame too much.
1322 if (!write_sq
.active
) WAKE_UP(write_sq
.sync_queue
);
1323 /* We are not playing after AtaPlay(), so there
1324 is nothing to play any more. Wake up a process
1325 waiting for audio output to drain. */
1327 spin_unlock(&dmasound
.lock
);
1332 /*** Mid level stuff *********************************************************/
1336 * /dev/mixer abstraction
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)
1344 static void __init
TTMixerInit(void)
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));
1355 static void __init
FalconMixerInit(void)
1357 dmasound
.volume_left
= (tt_dmasnd
.output_atten
& 0xf00) >> 8;
1358 dmasound
.volume_right
= (tt_dmasnd
.output_atten
& 0xf0) >> 4;
1361 static int AtaMixerIoctl(u_int cmd
, u_long arg
)
1364 unsigned long flags
;
1366 case SOUND_MIXER_READ_SPEAKER
:
1367 if (is_falcon
|| MACH_IS_TT
) {
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);
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
) {
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);
1396 static int TTMixerIoctl(u_int cmd
, u_long arg
)
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
));
1428 return AtaMixerIoctl(cmd
, arg
);
1431 static int FalconMixerIoctl(u_int cmd
, u_long arg
)
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
; /* return set value */
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);
1458 return AtaMixerIoctl(cmd
, arg
);
1461 static int AtaWriteSqSetup(void)
1463 write_sq_ignore_int
= 0;
1467 static int AtaSqOpen(fmode_t mode
)
1469 write_sq_ignore_int
= 1;
1473 static int TTStateInfo(char *buffer
, size_t space
)
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",
1482 len
+= sprintf(buffer
+len
, "\ttreble %ddB [-12...+12]\n",
1485 printk(KERN_ERR
"dmasound_atari: overflowed state buffer alloc.\n") ;
1491 static int FalconStateInfo(char *buffer
, size_t space
)
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
);
1499 printk(KERN_ERR
"dmasound_atari: overflowed state buffer alloc.\n") ;
1506 /*** Machine definitions *****************************************************/
1508 static SETTINGS def_hard_falcon
= {
1515 static SETTINGS def_hard_tt
= {
1522 static SETTINGS def_soft
= {
1529 static __initdata MACHINE machTT
= {
1532 .owner
= THIS_MODULE
,
1533 .dma_alloc
= AtaAlloc
,
1534 .dma_free
= AtaFree
,
1535 .irqinit
= AtaIrqInit
,
1537 .irqcleanup
= AtaIrqCleanUp
,
1540 .silence
= TTSilence
,
1541 .setFormat
= TTSetFormat
,
1542 .setVolume
= TTSetVolume
,
1543 .setBass
= AtaSetBass
,
1544 .setTreble
= AtaSetTreble
,
1545 .setGain
= TTSetGain
,
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
, /* h'ware-supported formats *only* here */
1555 .capabilities
= DSP_CAP_BATCH
/* As per SNDCTL_DSP_GETCAPS */
1558 static __initdata MACHINE machFalcon
= {
1561 .dma_alloc
= AtaAlloc
,
1562 .dma_free
= AtaFree
,
1563 .irqinit
= AtaIrqInit
,
1565 .irqcleanup
= AtaIrqCleanUp
,
1568 .silence
= FalconSilence
,
1569 .setFormat
= FalconSetFormat
,
1570 .setVolume
= FalconSetVolume
,
1571 .setBass
= AtaSetBass
,
1572 .setTreble
= AtaSetTreble
,
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
), /* h'ware-supported formats *only* here */
1582 .capabilities
= DSP_CAP_BATCH
/* As per SNDCTL_DSP_GETCAPS */
1586 /*** Config & Setup **********************************************************/
1589 static int __init
dmasound_atari_init(void)
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
;
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
;
1604 if ((st_mfp
.int_en_a
& st_mfp
.int_mk_a
& 0x20) == 0)
1605 return dmasound_init();
1607 printk("DMA sound driver: Timer A interrupt already in use\n");
1614 static void __exit
dmasound_atari_cleanup(void)
1619 module_init(dmasound_atari_init
);
1620 module_exit(dmasound_atari_cleanup
);
1621 MODULE_LICENSE("GPL");