This source file includes following definitions.
- ata_ct_law
- ata_ct_s8
- ata_ct_u8
- ata_ct_s16be
- ata_ct_u16be
- ata_ct_s16le
- ata_ct_u16le
- ata_ctx_law
- ata_ctx_s8
- ata_ctx_u8
- ata_ctx_s16be
- ata_ctx_u16be
- ata_ctx_s16le
- ata_ctx_u16le
- ami_ct_law
- ami_ct_s8
- ami_ct_u8
- ami_ct_s16be
- ami_ct_u16be
- ami_ct_s16le
- ami_ct_u16le
- AtaAlloc
- AtaFree
- AtaIrqInit
- AtaSetBass
- AtaSetTreble
- TTSilence
- TTInit
- TTSetFormat
- TTSetVolume
- FalconSilence
- FalconInit
- FalconSetFormat
- FalconSetVolume
- ata_sq_play_next_frame
- AtaPlay
- ata_sq_interrupt
- AmiAlloc
- AmiFree
- AmiIrqInit
- AmiSilence
- AmiInit
- AmiSetFormat
- AmiSetVolume
- AmiSetTreble
- ami_sq_play_next_frame
- AmiPlay
- ami_sq_interrupt
- sound_silence
- sound_init
- sound_set_format
- sound_set_speed
- sound_set_stereo
- sound_set_volume
- sound_set_bass
- sound_set_treble
- sound_copy_translate
- mixer_init
- mixer_open
- mixer_release
- mixer_ioctl
- sq_init
- sq_play
- sq_write
- sq_open
- sq_reset
- sq_sync
- sq_release
- state_init
- state_open
- state_release
- state_read
- sound_open
- sound_fsync
- sound_release
- sound_lseek
- sound_read
- sound_write
- ioctl_return
- unknown_minor_dev
- sound_ioctl
- soundcard_init
- sound_setup
- dmasound_setup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 #include <linux/sched.h>
70 #include <linux/timer.h>
71 #include <linux/major.h>
72 #include <linux/config.h>
73 #include <linux/fcntl.h>
74 #include <linux/errno.h>
75 #include <linux/mm.h>
76 #include <linux/malloc.h>
77
78 #include <asm/system.h>
79 #include <asm/irq.h>
80 #include <asm/pgtable.h>
81 #include <asm/bootinfo.h>
82
83 #ifdef CONFIG_ATARI
84 #include <asm/atarihw.h>
85 #include <asm/atariints.h>
86 #endif
87 #ifdef CONFIG_AMIGA
88 #include <asm/amigahw.h>
89 #include <asm/amigaints.h>
90 #endif
91
92 #include "dmasound.h"
93 #include <linux/soundcard.h>
94
95
96 #ifdef CONFIG_ATARI
97 extern void atari_microwire_cmd(int cmd);
98 #endif
99
100 #ifdef CONFIG_AMIGA
101
102
103
104
105
106 extern volatile u_short amiga_audio_min_period;
107
108
109
110
111
112
113
114 extern u_short amiga_audio_period;
115
116
117
118
119
120
121 #define AMI_AUDIO_OFF (DMAF_AUD0 | DMAF_AUD1 | DMAF_AUD2 | DMAF_AUD3)
122 #define AMI_AUDIO_8 (DMAF_SETCLR | DMAF_MASTER | DMAF_AUD0 | DMAF_AUD1)
123 #define AMI_AUDIO_14 (AMI_AUDIO_8 | DMAF_AUD2 | DMAF_AUD3)
124
125 #endif
126
127
128
129
130
131 #define DMASND_TT 1
132 #define DMASND_FALCON 2
133 #define DMASND_AMIGA 3
134
135 #define MAX_CATCH_RADIUS 10
136 #define MIN_BUFFERS 4
137 #define MIN_BUFSIZE 4
138 #define MAX_BUFSIZE 128
139
140 static int catchRadius = 0, numBufs = 4, bufSize = 32;
141
142
143 #define arraysize(x) (sizeof(x)/sizeof(*(x)))
144 #define min(x, y) ((x) < (y) ? (x) : (y))
145 #define le2be16(x) (((x)<<8 & 0xff00) | ((x)>>8 & 0x00ff))
146 #define le2be16dbl(x) (((x)<<8 & 0xff00ff00) | ((x)>>8 & 0x00ff00ff))
147
148 #define IOCTL_IN(arg) get_user((int *)(arg))
149 #define IOCTL_OUT(arg, ret) ioctl_return((int *)arg, ret)
150
151
152
153
154
155
156
157 static char ulaw2dma8[] = {
158 -126, -122, -118, -114, -110, -106, -102, -98,
159 -94, -90, -86, -82, -78, -74, -70, -66,
160 -63, -61, -59, -57, -55, -53, -51, -49,
161 -47, -45, -43, -41, -39, -37, -35, -33,
162 -31, -30, -29, -28, -27, -26, -25, -24,
163 -23, -22, -21, -20, -19, -18, -17, -16,
164 -16, -15, -15, -14, -14, -13, -13, -12,
165 -12, -11, -11, -10, -10, -9, -9, -8,
166 -8, -8, -7, -7, -7, -7, -6, -6,
167 -6, -6, -5, -5, -5, -5, -4, -4,
168 -4, -4, -4, -4, -3, -3, -3, -3,
169 -3, -3, -3, -3, -2, -2, -2, -2,
170 -2, -2, -2, -2, -2, -2, -2, -2,
171 -1, -1, -1, -1, -1, -1, -1, -1,
172 -1, -1, -1, -1, -1, -1, -1, -1,
173 -1, -1, -1, -1, -1, -1, -1, 0,
174 125, 121, 117, 113, 109, 105, 101, 97,
175 93, 89, 85, 81, 77, 73, 69, 65,
176 62, 60, 58, 56, 54, 52, 50, 48,
177 46, 44, 42, 40, 38, 36, 34, 32,
178 30, 29, 28, 27, 26, 25, 24, 23,
179 22, 21, 20, 19, 18, 17, 16, 15,
180 15, 14, 14, 13, 13, 12, 12, 11,
181 11, 10, 10, 9, 9, 8, 8, 7,
182 7, 7, 6, 6, 6, 6, 5, 5,
183 5, 5, 4, 4, 4, 4, 3, 3,
184 3, 3, 3, 3, 2, 2, 2, 2,
185 2, 2, 2, 2, 1, 1, 1, 1,
186 1, 1, 1, 1, 1, 1, 1, 1,
187 0, 0, 0, 0, 0, 0, 0, 0,
188 0, 0, 0, 0, 0, 0, 0, 0,
189 0, 0, 0, 0, 0, 0, 0, 0
190 };
191
192
193
194 static char alaw2dma8[] = {
195 -22, -21, -24, -23, -18, -17, -20, -19,
196 -30, -29, -32, -31, -26, -25, -28, -27,
197 -11, -11, -12, -12, -9, -9, -10, -10,
198 -15, -15, -16, -16, -13, -13, -14, -14,
199 -86, -82, -94, -90, -70, -66, -78, -74,
200 -118, -114, -126, -122, -102, -98, -110, -106,
201 -43, -41, -47, -45, -35, -33, -39, -37,
202 -59, -57, -63, -61, -51, -49, -55, -53,
203 -2, -2, -2, -2, -2, -2, -2, -2,
204 -2, -2, -2, -2, -2, -2, -2, -2,
205 -1, -1, -1, -1, -1, -1, -1, -1,
206 -1, -1, -1, -1, -1, -1, -1, -1,
207 -6, -6, -6, -6, -5, -5, -5, -5,
208 -8, -8, -8, -8, -7, -7, -7, -7,
209 -3, -3, -3, -3, -3, -3, -3, -3,
210 -4, -4, -4, -4, -4, -4, -4, -4,
211 21, 20, 23, 22, 17, 16, 19, 18,
212 29, 28, 31, 30, 25, 24, 27, 26,
213 10, 10, 11, 11, 8, 8, 9, 9,
214 14, 14, 15, 15, 12, 12, 13, 13,
215 86, 82, 94, 90, 70, 66, 78, 74,
216 118, 114, 126, 122, 102, 98, 110, 106,
217 43, 41, 47, 45, 35, 33, 39, 37,
218 59, 57, 63, 61, 51, 49, 55, 53,
219 1, 1, 1, 1, 1, 1, 1, 1,
220 1, 1, 1, 1, 1, 1, 1, 1,
221 0, 0, 0, 0, 0, 0, 0, 0,
222 0, 0, 0, 0, 0, 0, 0, 0,
223 5, 5, 5, 5, 4, 4, 4, 4,
224 7, 7, 7, 7, 6, 6, 6, 6,
225 2, 2, 2, 2, 2, 2, 2, 2,
226 3, 3, 3, 3, 3, 3, 3, 3
227 };
228
229
230 #ifdef HAS_16BIT_TABLES
231
232
233
234 static char ulaw2dma16[] = {
235 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
236 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
237 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
238 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
239 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
240 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
241 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
242 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
243 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
244 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
245 -876, -844, -812, -780, -748, -716, -684, -652,
246 -620, -588, -556, -524, -492, -460, -428, -396,
247 -372, -356, -340, -324, -308, -292, -276, -260,
248 -244, -228, -212, -196, -180, -164, -148, -132,
249 -120, -112, -104, -96, -88, -80, -72, -64,
250 -56, -48, -40, -32, -24, -16, -8, 0,
251 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
252 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
253 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
254 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
255 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
256 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
257 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
258 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
259 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
260 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
261 876, 844, 812, 780, 748, 716, 684, 652,
262 620, 588, 556, 524, 492, 460, 428, 396,
263 372, 356, 340, 324, 308, 292, 276, 260,
264 244, 228, 212, 196, 180, 164, 148, 132,
265 120, 112, 104, 96, 88, 80, 72, 64,
266 56, 48, 40, 32, 24, 16, 8, 0,
267 };
268
269
270
271 static char alaw2dma16[] = {
272 -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
273 -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
274 -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
275 -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
276 -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
277 -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
278 -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
279 -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
280 -344, -328, -376, -360, -280, -264, -312, -296,
281 -472, -456, -504, -488, -408, -392, -440, -424,
282 -88, -72, -120, -104, -24, -8, -56, -40,
283 -216, -200, -248, -232, -152, -136, -184, -168,
284 -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
285 -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
286 -688, -656, -752, -720, -560, -528, -624, -592,
287 -944, -912, -1008, -976, -816, -784, -880, -848,
288 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
289 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
290 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
291 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
292 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
293 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
294 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
295 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
296 344, 328, 376, 360, 280, 264, 312, 296,
297 472, 456, 504, 488, 408, 392, 440, 424,
298 88, 72, 120, 104, 24, 8, 56, 40,
299 216, 200, 248, 232, 152, 136, 184, 168,
300 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
301 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
302 688, 656, 752, 720, 560, 528, 624, 592,
303 944, 912, 1008, 976, 816, 784, 880, 848,
304 };
305 #endif
306
307
308 #ifdef HAS_14BIT_TABLES
309
310
311
312 static char alaw2dma14l[] = {
313 33, 33, 33, 33, 33, 33, 33, 33,
314 33, 33, 33, 33, 33, 33, 33, 33,
315 33, 33, 33, 33, 33, 33, 33, 33,
316 33, 33, 33, 33, 33, 33, 33, 33,
317 1, 1, 1, 1, 1, 1, 1, 1,
318 1, 1, 1, 1, 1, 1, 1, 1,
319 49, 17, 49, 17, 49, 17, 49, 17,
320 49, 17, 49, 17, 49, 17, 49, 17,
321 41, 57, 9, 25, 41, 57, 9, 25,
322 41, 57, 9, 25, 41, 57, 9, 25,
323 37, 45, 53, 61, 5, 13, 21, 29,
324 37, 45, 53, 61, 5, 13, 21, 29,
325 35, 39, 43, 47, 51, 55, 59, 63,
326 3, 7, 11, 15, 19, 23, 27, 31,
327 34, 36, 38, 40, 42, 44, 46, 48,
328 50, 52, 54, 56, 58, 60, 62, 0,
329 31, 31, 31, 31, 31, 31, 31, 31,
330 31, 31, 31, 31, 31, 31, 31, 31,
331 31, 31, 31, 31, 31, 31, 31, 31,
332 31, 31, 31, 31, 31, 31, 31, 31,
333 63, 63, 63, 63, 63, 63, 63, 63,
334 63, 63, 63, 63, 63, 63, 63, 63,
335 15, 47, 15, 47, 15, 47, 15, 47,
336 15, 47, 15, 47, 15, 47, 15, 47,
337 23, 7, 55, 39, 23, 7, 55, 39,
338 23, 7, 55, 39, 23, 7, 55, 39,
339 27, 19, 11, 3, 59, 51, 43, 35,
340 27, 19, 11, 3, 59, 51, 43, 35,
341 29, 25, 21, 17, 13, 9, 5, 1,
342 61, 57, 53, 49, 45, 41, 37, 33,
343 30, 28, 26, 24, 22, 20, 18, 16,
344 14, 12, 10, 8, 6, 4, 2, 0
345 };
346
347
348
349 static char alaw2dma14l[] = {
350 32, 32, 32, 32, 32, 32, 32, 32,
351 32, 32, 32, 32, 32, 32, 32, 32,
352 16, 48, 16, 48, 16, 48, 16, 48,
353 16, 48, 16, 48, 16, 48, 16, 48,
354 0, 0, 0, 0, 0, 0, 0, 0,
355 0, 0, 0, 0, 0, 0, 0, 0,
356 0, 0, 0, 0, 0, 0, 0, 0,
357 0, 0, 0, 0, 0, 0, 0, 0,
358 42, 46, 34, 38, 58, 62, 50, 54,
359 10, 14, 2, 6, 26, 30, 18, 22,
360 42, 46, 34, 38, 58, 62, 50, 54,
361 10, 14, 2, 6, 26, 30, 18, 22,
362 40, 56, 8, 24, 40, 56, 8, 24,
363 40, 56, 8, 24, 40, 56, 8, 24,
364 20, 28, 4, 12, 52, 60, 36, 44,
365 20, 28, 4, 12, 52, 60, 36, 44,
366 32, 32, 32, 32, 32, 32, 32, 32,
367 32, 32, 32, 32, 32, 32, 32, 32,
368 48, 16, 48, 16, 48, 16, 48, 16,
369 48, 16, 48, 16, 48, 16, 48, 16,
370 0, 0, 0, 0, 0, 0, 0, 0,
371 0, 0, 0, 0, 0, 0, 0, 0,
372 0, 0, 0, 0, 0, 0, 0, 0,
373 0, 0, 0, 0, 0, 0, 0, 0,
374 22, 18, 30, 26, 6, 2, 14, 10,
375 54, 50, 62, 58, 38, 34, 46, 42,
376 22, 18, 30, 26, 6, 2, 14, 10,
377 54, 50, 62, 58, 38, 34, 46, 42,
378 24, 8, 56, 40, 24, 8, 56, 40,
379 24, 8, 56, 40, 24, 8, 56, 40,
380 44, 36, 60, 52, 12, 4, 28, 20,
381 44, 36, 60, 52, 12, 4, 28, 20
382 };
383 #endif
384
385
386
387
388
389 #ifdef CONFIG_ATARI
390 static long ata_ct_law(const u_char *userPtr, long userCount, u_char frame[],
391 long *frameUsed, long frameLeft);
392 static long ata_ct_s8(const u_char *userPtr, long userCount, u_char frame[],
393 long *frameUsed, long frameLeft);
394 static long ata_ct_u8(const u_char *userPtr, long userCount, u_char frame[],
395 long *frameUsed, long frameLeft);
396 static long ata_ct_s16be(const u_char *userPtr, long userCount, u_char frame[],
397 long *frameUsed, long frameLeft);
398 static long ata_ct_u16be(const u_char *userPtr, long userCount, u_char frame[],
399 long *frameUsed, long frameLeft);
400 static long ata_ct_s16le(const u_char *userPtr, long userCount, u_char frame[],
401 long *frameUsed, long frameLeft);
402 static long ata_ct_u16le(const u_char *userPtr, long userCount, u_char frame[],
403 long *frameUsed, long frameLeft);
404 static long ata_ctx_law(const u_char *userPtr, long userCount, u_char frame[],
405 long *frameUsed, long frameLeft);
406 static long ata_ctx_s8(const u_char *userPtr, long userCount, u_char frame[],
407 long *frameUsed, long frameLeft);
408 static long ata_ctx_u8(const u_char *userPtr, long userCount, u_char frame[],
409 long *frameUsed, long frameLeft);
410 static long ata_ctx_s16be(const u_char *userPtr, long userCount, u_char frame[],
411 long *frameUsed, long frameLeft);
412 static long ata_ctx_u16be(const u_char *userPtr, long userCount, u_char frame[],
413 long *frameUsed, long frameLeft);
414 static long ata_ctx_s16le(const u_char *userPtr, long userCount, u_char frame[],
415 long *frameUsed, long frameLeft);
416 static long ata_ctx_u16le(const u_char *userPtr, long userCount, u_char frame[],
417 long *frameUsed, long frameLeft);
418 #endif
419
420 #ifdef CONFIG_AMIGA
421 static long ami_ct_law(const u_char *userPtr, long userCount, u_char frame[],
422 long *frameUsed, long frameLeft);
423 static long ami_ct_s8(const u_char *userPtr, long userCount, u_char frame[],
424 long *frameUsed, long frameLeft);
425 static long ami_ct_u8(const u_char *userPtr, long userCount, u_char frame[],
426 long *frameUsed, long frameLeft);
427 static long ami_ct_s16be(const u_char *userPtr, long userCount, u_char frame[],
428 long *frameUsed, long frameLeft);
429 static long ami_ct_u16be(const u_char *userPtr, long userCount, u_char frame[],
430 long *frameUsed, long frameLeft);
431 static long ami_ct_s16le(const u_char *userPtr, long userCount, u_char frame[],
432 long *frameUsed, long frameLeft);
433 static long ami_ct_u16le(const u_char *userPtr, long userCount, u_char frame[],
434 long *frameUsed, long frameLeft);
435 #endif
436
437
438
439
440
441 typedef struct {
442 int type;
443 void *(*dma_alloc)(unsigned int, int);
444 void (*dma_free)(void *, unsigned int);
445 int (*irqinit)(void);
446 void (*init)(void);
447 void (*silence)(void);
448 int (*setFormat)(int);
449 int (*setVolume)(int);
450 int (*setBass)(int);
451 int (*setTreble)(int);
452 void (*play)(void);
453 } MACHINE;
454
455
456
457
458
459 typedef struct {
460 int format;
461 int stereo;
462 int size;
463 int speed;
464 } SETTINGS;
465
466 typedef struct {
467 long (*ct_ulaw)(const u_char *, long, u_char *, long *, long);
468 long (*ct_alaw)(const u_char *, long, u_char *, long *, long);
469 long (*ct_s8)(const u_char *, long, u_char *, long *, long);
470 long (*ct_u8)(const u_char *, long, u_char *, long *, long);
471 long (*ct_s16be)(const u_char *, long, u_char *, long *, long);
472 long (*ct_u16be)(const u_char *, long, u_char *, long *, long);
473 long (*ct_s16le)(const u_char *, long, u_char *, long *, long);
474 long (*ct_u16le)(const u_char *, long, u_char *, long *, long);
475 } TRANS;
476
477 struct sound_settings {
478 MACHINE mach;
479 SETTINGS hard;
480 SETTINGS soft;
481 SETTINGS dsp;
482 TRANS *trans;
483 int volume_left;
484 int volume_right;
485 int bass;
486 int treble;
487 int minDev;
488 #ifdef CONFIG_ATARI
489 int bal;
490 u_long data;
491 #endif
492 };
493
494 static struct sound_settings sound;
495
496
497 #ifdef CONFIG_ATARI
498 static void *AtaAlloc(unsigned int size, int flags);
499 static void AtaFree(void *, unsigned int size);
500 static int AtaIrqInit(void);
501 static int AtaSetBass(int bass);
502 static int AtaSetTreble(int treble);
503 static void TTSilence(void);
504 static void TTInit(void);
505 static int TTSetFormat(int format);
506 static int TTSetVolume(int volume);
507 static void FalconSilence(void);
508 static void FalconInit(void);
509 static int FalconSetFormat(int format);
510 static int FalconSetVolume(int volume);
511 static void ata_sq_play_next_frame(int index);
512 static void AtaPlay(void);
513 static void ata_sq_interrupt(int irq, struct pt_regs *fp, void *dummy);
514 #endif
515
516 #ifdef CONFIG_AMIGA
517 static void *AmiAlloc(unsigned int size, int flags);
518 static void AmiFree(void *, unsigned int);
519 static int AmiIrqInit(void);
520 static void AmiSilence(void);
521 static void AmiInit(void);
522 static int AmiSetFormat(int format);
523 static int AmiSetVolume(int volume);
524 static int AmiSetTreble(int treble);
525 static void ami_sq_play_next_frame(int index);
526 static void AmiPlay(void);
527 static void ami_sq_interrupt(int irq, struct pt_regs *fp, void *dummy);
528 #endif
529
530
531
532
533
534 static void sound_silence(void);
535 static void sound_init(void);
536 static int sound_set_format(int format);
537 static int sound_set_speed(int speed);
538 static int sound_set_stereo(int stereo);
539 static int sound_set_volume(int volume);
540 #ifdef CONFIG_ATARI
541 static int sound_set_bass(int bass);
542 #endif
543 static int sound_set_treble(int treble);
544 static long sound_copy_translate(const u_char *userPtr, long userCount,
545 u_char frame[], long *frameUsed,
546 long frameLeft);
547
548
549
550
551
552
553 struct sound_mixer {
554 int busy;
555 };
556
557 static struct sound_mixer mixer;
558
559 static void mixer_init(void);
560 static int mixer_open(int open_mode);
561 static int mixer_release(void);
562 static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
563 u_long arg);
564
565
566
567
568
569
570 struct sound_queue {
571 int max_count, block_size;
572 char **buffers;
573
574
575 int front, rear, count;
576 int rear_size;
577
578
579
580
581
582
583
584
585 int playing;
586 struct wait_queue *write_queue, *open_queue, *sync_queue;
587 int open_mode;
588 int busy, syncing;
589 #ifdef CONFIG_ATARI
590 int ignore_int;
591 #endif
592 #ifdef CONFIG_AMIGA
593 int block_size_half, block_size_quarter;
594 #endif
595 };
596
597 static struct sound_queue sq;
598
599 #define sq_block_address(i) (sq.buffers[i])
600 #define SIGNAL_RECEIVED (current->signal & ~current->blocked)
601 #define NON_BLOCKING(open_mode) (open_mode & O_NONBLOCK)
602 #define ONE_SECOND HZ
603 #define NO_TIME_LIMIT 0xffffffff
604 #define SLEEP(queue, time_limit) \
605 current->timeout = jiffies+(time_limit); \
606 interruptible_sleep_on(&queue);
607 #define WAKE_UP(queue) (wake_up_interruptible(&queue))
608
609 static void sq_init(int numBufs, int bufSize, char **buffers);
610 static void sq_play(void);
611 static int sq_write(const char *src, int uLeft);
612 static int sq_open(int open_mode);
613 static void sq_reset(void);
614 static int sq_sync(void);
615 static int sq_release(void);
616
617
618
619
620
621
622 struct sound_state {
623 int busy;
624 char buf[512];
625 int len, ptr;
626 };
627
628 static struct sound_state state;
629
630 static void state_init(void);
631 static int state_open(int open_mode);
632 static int state_release(void);
633 static int state_read(char *dest, int count);
634
635
636
637
638
639 static int sound_open(struct inode *inode, struct file *file);
640 static int sound_fsync(struct inode *inode, struct file *filp);
641 static void sound_release(struct inode *inode, struct file *file);
642 static int sound_lseek(struct inode *inode, struct file *file, off_t offset,
643 int orig);
644 static int sound_read(struct inode *inode, struct file *file, char *buf,
645 int count);
646 static int sound_write(struct inode *inode, struct file *file, const char *buf,
647 int count);
648 static int ioctl_return(int *addr, int value);
649 static int unknown_minor_dev(char *fname, int dev);
650 static int sound_ioctl(struct inode *inode, struct file *file, u_int cmd,
651 u_long arg);
652
653
654
655
656
657 void soundcard_init(void);
658 void dmasound_setup(char *str, int *ints);
659 void sound_setup(char *str, int *ints);
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689 #ifdef CONFIG_ATARI
690 static long ata_ct_law(const u_char *userPtr, long userCount, u_char frame[],
691 long *frameUsed, long frameLeft)
692 {
693 char *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma8 : alaw2dma8;
694 long count, used;
695 u_char *p = &frame[*frameUsed];
696
697 count = min(userCount, frameLeft);
698 if (sound.soft.stereo)
699 count &= ~1;
700 used = count;
701 while (count > 0) {
702 *p++ = table[get_user(userPtr++)];
703 count--;
704 }
705 *frameUsed += used;
706 return(used);
707 }
708
709
710 static long ata_ct_s8(const u_char *userPtr, long userCount, u_char frame[],
711 long *frameUsed, long frameLeft)
712 {
713 long count, used;
714 void *p = &frame[*frameUsed];
715
716 count = min(userCount, frameLeft);
717 if (sound.soft.stereo)
718 count &= ~1;
719 used = count;
720 memcpy_fromfs(p, userPtr, count);
721 *frameUsed += used;
722 return(used);
723 }
724
725
726 static long ata_ct_u8(const u_char *userPtr, long userCount, u_char frame[],
727 long *frameUsed, long frameLeft)
728 {
729 long count, used;
730
731 if (!sound.soft.stereo) {
732 u_char *p = &frame[*frameUsed];
733 count = min(userCount, frameLeft);
734 used = count;
735 while (count > 0) {
736 *p++ = get_user(userPtr++) ^ 0x80;
737 count--;
738 }
739 } else {
740 u_short *p = (u_short *)&frame[*frameUsed];
741 count = min(userCount, frameLeft)>>1;
742 used = count*2;
743 while (count > 0) {
744 *p++ = get_user(((u_short *)userPtr)++) ^ 0x8080;
745 count--;
746 }
747 }
748 *frameUsed += used;
749 return(used);
750 }
751
752
753 static long ata_ct_s16be(const u_char *userPtr, long userCount, u_char frame[],
754 long *frameUsed, long frameLeft)
755 {
756 long count, used;
757 u_long data;
758
759 if (!sound.soft.stereo) {
760 u_short *p = (u_short *)&frame[*frameUsed];
761 count = min(userCount, frameLeft)>>1;
762 used = count*2;
763 while (count > 0) {
764 data = get_user(((u_short *)userPtr)++);
765 *p++ = data;
766 *p++ = data;
767 count--;
768 }
769 *frameUsed += used*2;
770 } else {
771 void *p = (u_short *)&frame[*frameUsed];
772 count = min(userCount, frameLeft) & ~3;
773 used = count;
774 memcpy_fromfs(p, userPtr, count);
775 *frameUsed += used;
776 }
777 return(used);
778 }
779
780
781 static long ata_ct_u16be(const u_char *userPtr, long userCount, u_char frame[],
782 long *frameUsed, long frameLeft)
783 {
784 long count, used;
785 u_long data;
786
787 if (!sound.soft.stereo) {
788 u_short *p = (u_short *)&frame[*frameUsed];
789 count = min(userCount, frameLeft)>>1;
790 used = count*2;
791 while (count > 0) {
792 data = get_user(((u_short *)userPtr)++) ^ 0x8000;
793 *p++ = data;
794 *p++ = data;
795 count--;
796 }
797 *frameUsed += used*2;
798 } else {
799 u_long *p = (u_long *)&frame[*frameUsed];
800 count = min(userCount, frameLeft)>>2;
801 used = count*4;
802 while (count > 0) {
803 *p++ = get_user(((u_int *)userPtr)++) ^ 0x80008000;
804 count--;
805 }
806 *frameUsed += used;
807 }
808 return(used);
809 }
810
811
812 static long ata_ct_s16le(const u_char *userPtr, long userCount, u_char frame[],
813 long *frameUsed, long frameLeft)
814 {
815 long count, used;
816 u_long data;
817
818 count = frameLeft;
819 if (!sound.soft.stereo) {
820 u_short *p = (u_short *)&frame[*frameUsed];
821 count = min(userCount, frameLeft)>>1;
822 used = count*2;
823 while (count > 0) {
824 data = get_user(((u_short *)userPtr)++);
825 data = le2be16(data);
826 *p++ = data;
827 *p++ = data;
828 count--;
829 }
830 *frameUsed += used*2;
831 } else {
832 u_long *p = (u_long *)&frame[*frameUsed];
833 count = min(userCount, frameLeft)>>2;
834 used = count*4;
835 while (count > 0) {
836 data = get_user(((u_int *)userPtr)++);
837 data = le2be16dbl(data);
838 *p++ = data;
839 count--;
840 }
841 *frameUsed += used;
842 }
843 return(used);
844 }
845
846
847 static long ata_ct_u16le(const u_char *userPtr, long userCount, u_char frame[],
848 long *frameUsed, long frameLeft)
849 {
850 long count, used;
851 u_long data;
852
853 count = frameLeft;
854 if (!sound.soft.stereo) {
855 u_short *p = (u_short *)&frame[*frameUsed];
856 count = min(userCount, frameLeft)>>1;
857 used = count*2;
858 while (count > 0) {
859 data = get_user(((u_short *)userPtr)++);
860 data = le2be16(data) ^ 0x8000;
861 *p++ = data;
862 *p++ = data;
863 }
864 *frameUsed += used*2;
865 } else {
866 u_long *p = (u_long *)&frame[*frameUsed];
867 count = min(userCount, frameLeft)>>2;
868 used = count;
869 while (count > 0) {
870 data = get_user(((u_int *)userPtr)++);
871 data = le2be16dbl(data) ^ 0x80008000;
872 *p++ = data;
873 count--;
874 }
875 *frameUsed += used;
876 }
877 return(used);
878 }
879
880
881 static long ata_ctx_law(const u_char *userPtr, long userCount, u_char frame[],
882 long *frameUsed, long frameLeft)
883 {
884 char *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma8 : alaw2dma8;
885
886 u_long data = sound.data;
887 long bal = sound.bal;
888 long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
889 long used, usedf;
890
891 used = userCount;
892 usedf = frameLeft;
893 if (!sound.soft.stereo) {
894 u_char *p = &frame[*frameUsed];
895 while (frameLeft) {
896 if (bal < 0) {
897 if (!userCount)
898 break;
899 data = table[get_user(userPtr++)];
900 userCount--;
901 bal += hSpeed;
902 }
903 *p++ = data;
904 frameLeft--;
905 bal -= sSpeed;
906 }
907 } else {
908 u_short *p = (u_short *)&frame[*frameUsed];
909 while (frameLeft >= 2) {
910 if (bal < 0) {
911 if (userCount < 2)
912 break;
913 data = table[get_user(userPtr++)] << 8;
914 data |= table[get_user(userPtr++)];
915 userCount -= 2;
916 bal += hSpeed;
917 }
918 *p++ = data;
919 frameLeft -= 2;
920 bal -= sSpeed;
921 }
922 }
923 sound.bal = bal;
924 sound.data = data;
925 used -= userCount;
926 *frameUsed += usedf-frameLeft;
927 return(used);
928 }
929
930
931 static long ata_ctx_s8(const u_char *userPtr, long userCount, u_char frame[],
932 long *frameUsed, long frameLeft)
933 {
934
935 u_long data = sound.data;
936 long bal = sound.bal;
937 long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
938 long used, usedf;
939
940 used = userCount;
941 usedf = frameLeft;
942 if (!sound.soft.stereo) {
943 u_char *p = &frame[*frameUsed];
944 while (frameLeft) {
945 if (bal < 0) {
946 if (!userCount)
947 break;
948 data = get_user(userPtr++);
949 userCount--;
950 bal += hSpeed;
951 }
952 *p++ = data;
953 frameLeft--;
954 bal -= sSpeed;
955 }
956 } else {
957 u_short *p = (u_short *)&frame[*frameUsed];
958 while (frameLeft >= 2) {
959 if (bal < 0) {
960 if (userCount < 2)
961 break;
962 data = get_user(((u_short *)userPtr)++);
963 userCount -= 2;
964 bal += hSpeed;
965 }
966 *p++ = data;
967 frameLeft -= 2;
968 bal -= sSpeed;
969 }
970 }
971 sound.bal = bal;
972 sound.data = data;
973 used -= userCount;
974 *frameUsed += usedf-frameLeft;
975 return(used);
976 }
977
978
979 static long ata_ctx_u8(const u_char *userPtr, long userCount, u_char frame[],
980 long *frameUsed, long frameLeft)
981 {
982
983 u_long data = sound.data;
984 long bal = sound.bal;
985 long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
986 long used, usedf;
987
988 used = userCount;
989 usedf = frameLeft;
990 if (!sound.soft.stereo) {
991 u_char *p = &frame[*frameUsed];
992 while (frameLeft) {
993 if (bal < 0) {
994 if (!userCount)
995 break;
996 data = get_user(userPtr++) ^ 0x80;
997 userCount--;
998 bal += hSpeed;
999 }
1000 *p++ = data;
1001 frameLeft--;
1002 bal -= sSpeed;
1003 }
1004 } else {
1005 u_short *p = (u_short *)&frame[*frameUsed];
1006 while (frameLeft >= 2) {
1007 if (bal < 0) {
1008 if (userCount < 2)
1009 break;
1010 data = get_user(((u_short *)userPtr)++) ^ 0x8080;
1011 userCount -= 2;
1012 bal += hSpeed;
1013 }
1014 *p++ = data;
1015 frameLeft -= 2;
1016 bal -= sSpeed;
1017 }
1018 }
1019 sound.bal = bal;
1020 sound.data = data;
1021 used -= userCount;
1022 *frameUsed += usedf-frameLeft;
1023 return(used);
1024 }
1025
1026
1027 static long ata_ctx_s16be(const u_char *userPtr, long userCount, u_char frame[],
1028 long *frameUsed, long frameLeft)
1029 {
1030
1031 u_long data = sound.data;
1032 long bal = sound.bal;
1033 long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
1034 long used, usedf;
1035
1036 used = userCount;
1037 usedf = frameLeft;
1038 if (!sound.soft.stereo) {
1039 u_short *p = (u_short *)&frame[*frameUsed];
1040 while (frameLeft >= 4) {
1041 if (bal < 0) {
1042 if (userCount < 2)
1043 break;
1044 data = get_user(((u_short *)userPtr)++);
1045 userCount -= 2;
1046 bal += hSpeed;
1047 }
1048 *p++ = data;
1049 *p++ = data;
1050 frameLeft -= 4;
1051 bal -= sSpeed;
1052 }
1053 } else {
1054 u_long *p = (u_long *)&frame[*frameUsed];
1055 while (frameLeft >= 4) {
1056 if (bal < 0) {
1057 if (userCount < 4)
1058 break;
1059 data = get_user(((u_int *)userPtr)++);
1060 userCount -= 4;
1061 bal += hSpeed;
1062 }
1063 *p++ = data;
1064 frameLeft -= 4;
1065 bal -= sSpeed;
1066 }
1067 }
1068 sound.bal = bal;
1069 sound.data = data;
1070 used -= userCount;
1071 *frameUsed += usedf-frameLeft;
1072 return(used);
1073 }
1074
1075
1076 static long ata_ctx_u16be(const u_char *userPtr, long userCount, u_char frame[],
1077 long *frameUsed, long frameLeft)
1078 {
1079
1080 u_long data = sound.data;
1081 long bal = sound.bal;
1082 long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
1083 long used, usedf;
1084
1085 used = userCount;
1086 usedf = frameLeft;
1087 if (!sound.soft.stereo) {
1088 u_short *p = (u_short *)&frame[*frameUsed];
1089 while (frameLeft >= 4) {
1090 if (bal < 0) {
1091 if (userCount < 2)
1092 break;
1093 data = get_user(((u_short *)userPtr)++) ^ 0x8000;
1094 userCount -= 2;
1095 bal += hSpeed;
1096 }
1097 *p++ = data;
1098 *p++ = data;
1099 frameLeft -= 4;
1100 bal -= sSpeed;
1101 }
1102 } else {
1103 u_long *p = (u_long *)&frame[*frameUsed];
1104 while (frameLeft >= 4) {
1105 if (bal < 0) {
1106 if (userCount < 4)
1107 break;
1108 data = get_user(((u_int *)userPtr)++) ^ 0x80008000;
1109 userCount -= 4;
1110 bal += hSpeed;
1111 }
1112 *p++ = data;
1113 frameLeft -= 4;
1114 bal -= sSpeed;
1115 }
1116 }
1117 sound.bal = bal;
1118 sound.data = data;
1119 used -= userCount;
1120 *frameUsed += usedf-frameLeft;
1121 return(used);
1122 }
1123
1124
1125 static long ata_ctx_s16le(const u_char *userPtr, long userCount, u_char frame[],
1126 long *frameUsed, long frameLeft)
1127 {
1128
1129 u_long data = sound.data;
1130 long bal = sound.bal;
1131 long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
1132 long used, usedf;
1133
1134 used = userCount;
1135 usedf = frameLeft;
1136 if (!sound.soft.stereo) {
1137 u_short *p = (u_short *)&frame[*frameUsed];
1138 while (frameLeft >= 4) {
1139 if (bal < 0) {
1140 if (userCount < 2)
1141 break;
1142 data = get_user(((u_short *)userPtr)++);
1143 data = le2be16(data);
1144 userCount -= 2;
1145 bal += hSpeed;
1146 }
1147 *p++ = data;
1148 *p++ = data;
1149 frameLeft -= 4;
1150 bal -= sSpeed;
1151 }
1152 } else {
1153 u_long *p = (u_long *)&frame[*frameUsed];
1154 while (frameLeft >= 4) {
1155 if (bal < 0) {
1156 if (userCount < 4)
1157 break;
1158 data = get_user(((u_int *)userPtr)++);
1159 data = le2be16dbl(data);
1160 userCount -= 4;
1161 bal += hSpeed;
1162 }
1163 *p++ = data;
1164 frameLeft -= 4;
1165 bal -= sSpeed;
1166 }
1167 }
1168 sound.bal = bal;
1169 sound.data = data;
1170 used -= userCount;
1171 *frameUsed += usedf-frameLeft;
1172 return(used);
1173 }
1174
1175
1176 static long ata_ctx_u16le(const u_char *userPtr, long userCount, u_char frame[],
1177 long *frameUsed, long frameLeft)
1178 {
1179
1180 u_long data = sound.data;
1181 long bal = sound.bal;
1182 long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
1183 long used, usedf;
1184
1185 used = userCount;
1186 usedf = frameLeft;
1187 if (!sound.soft.stereo) {
1188 u_short *p = (u_short *)&frame[*frameUsed];
1189 while (frameLeft >= 4) {
1190 if (bal < 0) {
1191 if (userCount < 2)
1192 break;
1193 data = get_user(((u_short *)userPtr)++);
1194 data = le2be16(data) ^ 0x8000;
1195 userCount -= 2;
1196 bal += hSpeed;
1197 }
1198 *p++ = data;
1199 *p++ = data;
1200 frameLeft -= 4;
1201 bal -= sSpeed;
1202 }
1203 } else {
1204 u_long *p = (u_long *)&frame[*frameUsed];
1205 while (frameLeft >= 4) {
1206 if (bal < 0) {
1207 if (userCount < 4)
1208 break;
1209 data = get_user(((u_int *)userPtr)++);
1210 data = le2be16dbl(data) ^ 0x80008000;
1211 userCount -= 4;
1212 bal += hSpeed;
1213 }
1214 *p++ = data;
1215 frameLeft -= 4;
1216 bal -= sSpeed;
1217 }
1218 }
1219 sound.bal = bal;
1220 sound.data = data;
1221 used -= userCount;
1222 *frameUsed += usedf-frameLeft;
1223 return(used);
1224 }
1225 #endif
1226
1227
1228 #ifdef CONFIG_AMIGA
1229 static long ami_ct_law(const u_char *userPtr, long userCount, u_char frame[],
1230 long *frameUsed, long frameLeft)
1231 {
1232 char *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma8 : alaw2dma8;
1233 long count, used;
1234
1235 if (!sound.soft.stereo) {
1236 u_char *p = &frame[*frameUsed];
1237 count = min(userCount, frameLeft) & ~1;
1238 used = count;
1239 while (count > 0) {
1240 *p++ = table[get_user(userPtr++)];
1241 count--;
1242 }
1243 } else {
1244 u_char *left = &frame[*frameUsed>>1];
1245 u_char *right = left+sq.block_size_half;
1246 count = min(userCount, frameLeft)>>1 & ~1;
1247 used = count*2;
1248 while (count > 0) {
1249 *left++ = table[get_user(userPtr++)];
1250 *right++ = table[get_user(userPtr++)];
1251 count--;
1252 }
1253 }
1254 *frameUsed += used;
1255 return(used);
1256 }
1257
1258
1259 static long ami_ct_s8(const u_char *userPtr, long userCount, u_char frame[],
1260 long *frameUsed, long frameLeft)
1261 {
1262 long count, used;
1263
1264 if (!sound.soft.stereo) {
1265 void *p = &frame[*frameUsed];
1266 count = min(userCount, frameLeft) & ~1;
1267 used = count;
1268 memcpy_fromfs(p, userPtr, count);
1269 } else {
1270 u_char *left = &frame[*frameUsed>>1];
1271 u_char *right = left+sq.block_size_half;
1272 count = min(userCount, frameLeft)>>1 & ~1;
1273 used = count*2;
1274 while (count > 0) {
1275 *left++ = get_user(userPtr++);
1276 *right++ = get_user(userPtr++);
1277 count--;
1278 }
1279 }
1280 *frameUsed += used;
1281 return(used);
1282 }
1283
1284
1285 static long ami_ct_u8(const u_char *userPtr, long userCount, u_char frame[],
1286 long *frameUsed, long frameLeft)
1287 {
1288 long count, used;
1289
1290 if (!sound.soft.stereo) {
1291 char *p = &frame[*frameUsed];
1292 count = min(userCount, frameLeft) & ~1;
1293 used = count;
1294 while (count > 0) {
1295 *p++ = get_user(userPtr++) ^ 0x80;
1296 count--;
1297 }
1298 } else {
1299 u_char *left = &frame[*frameUsed>>1];
1300 u_char *right = left+sq.block_size_half;
1301 count = min(userCount, frameLeft)>>1 & ~1;
1302 used = count*2;
1303 while (count > 0) {
1304 *left++ = get_user(userPtr++) ^ 0x80;
1305 *right++ = get_user(userPtr++) ^ 0x80;
1306 count--;
1307 }
1308 }
1309 *frameUsed += used;
1310 return(used);
1311 }
1312
1313
1314 static long ami_ct_s16be(const u_char *userPtr, long userCount, u_char frame[],
1315 long *frameUsed, long frameLeft)
1316 {
1317 long count, used;
1318 u_long data;
1319
1320 if (!sound.soft.stereo) {
1321 u_char *high = &frame[*frameUsed>>1];
1322 u_char *low = high+sq.block_size_half;
1323 count = min(userCount, frameLeft)>>1 & ~1;
1324 used = count*2;
1325 while (count > 0) {
1326 data = get_user(((u_short *)userPtr)++);
1327 *high = data>>8;
1328 *low = (data>>2) & 0x3f;
1329 count--;
1330 }
1331 } else {
1332 u_char *lefth = &frame[*frameUsed>>2];
1333 u_char *leftl = lefth+sq.block_size_quarter;
1334 u_char *righth = lefth+sq.block_size_half;
1335 u_char *rightl = righth+sq.block_size_quarter;
1336 count = min(userCount, frameLeft)>>2 & ~1;
1337 used = count*4;
1338 while (count > 0) {
1339 data = get_user(((u_short *)userPtr)++);
1340 *lefth = data>>8;
1341 *leftl = (data>>2) & 0x3f;
1342 data = get_user(((u_short *)userPtr)++);
1343 *righth = data>>8;
1344 *rightl = (data>>2) & 0x3f;
1345 count--;
1346 }
1347 }
1348 *frameUsed += used;
1349 return(used);
1350 }
1351
1352
1353 static long ami_ct_u16be(const u_char *userPtr, long userCount, u_char frame[],
1354 long *frameUsed, long frameLeft)
1355 {
1356 long count, used;
1357 u_long data;
1358
1359 if (!sound.soft.stereo) {
1360 u_char *high = &frame[*frameUsed>>1];
1361 u_char *low = high+sq.block_size_half;
1362 count = min(userCount, frameLeft)>>1 & ~1;
1363 used = count*2;
1364 while (count > 0) {
1365 data = get_user(((u_short *)userPtr)++) ^ 0x8000;
1366 *high = data>>8;
1367 *low = (data>>2) & 0x3f;
1368 count--;
1369 }
1370 } else {
1371 u_char *lefth = &frame[*frameUsed>>2];
1372 u_char *leftl = lefth+sq.block_size_quarter;
1373 u_char *righth = lefth+sq.block_size_half;
1374 u_char *rightl = righth+sq.block_size_quarter;
1375 count = min(userCount, frameLeft)>>2 & ~1;
1376 used = count*4;
1377 while (count > 0) {
1378 data = get_user(((u_short *)userPtr)++) ^ 0x8000;
1379 *lefth = data>>8;
1380 *leftl = (data>>2) & 0x3f;
1381 data = get_user(((u_short *)userPtr)++) ^ 0x8000;
1382 *righth = data>>8;
1383 *rightl = (data>>2) & 0x3f;
1384 count--;
1385 }
1386 }
1387 *frameUsed += used;
1388 return(used);
1389 }
1390
1391
1392 static long ami_ct_s16le(const u_char *userPtr, long userCount, u_char frame[],
1393 long *frameUsed, long frameLeft)
1394 {
1395 long count, used;
1396 u_long data;
1397
1398 if (!sound.soft.stereo) {
1399 u_char *high = &frame[*frameUsed>>1];
1400 u_char *low = high+sq.block_size_half;
1401 count = min(userCount, frameLeft)>>1 & ~1;
1402 used = count*2;
1403 while (count > 0) {
1404 data = get_user(((u_short *)userPtr)++);
1405 data = le2be16(data);
1406 *high = data>>8;
1407 *low = (data>>2) & 0x3f;
1408 count--;
1409 }
1410 } else {
1411 u_char *lefth = &frame[*frameUsed>>2];
1412 u_char *leftl = lefth+sq.block_size_quarter;
1413 u_char *righth = lefth+sq.block_size_half;
1414 u_char *rightl = righth+sq.block_size_quarter;
1415 count = min(userCount, frameLeft)>>2 & ~1;
1416 used = count*4;
1417 while (count > 0) {
1418 data = get_user(((u_short *)userPtr)++);
1419 data = le2be16(data);
1420 *lefth = data>>8;
1421 *leftl = (data>>2) & 0x3f;
1422 data = get_user(((u_short *)userPtr)++);
1423 data = le2be16(data);
1424 *righth = data>>8;
1425 *rightl = (data>>2) & 0x3f;
1426 count--;
1427 }
1428 }
1429 *frameUsed += used;
1430 return(used);
1431 }
1432
1433
1434 static long ami_ct_u16le(const u_char *userPtr, long userCount, u_char frame[],
1435 long *frameUsed, long frameLeft)
1436 {
1437 long count, used;
1438 u_long data;
1439
1440 if (!sound.soft.stereo) {
1441 u_char *high = &frame[*frameUsed>>1];
1442 u_char *low = high+sq.block_size_half;
1443 count = min(userCount, frameLeft)>>1 & ~1;
1444 used = count*2;
1445 while (count > 0) {
1446 data = get_user(((u_short *)userPtr)++);
1447 data = le2be16(data) ^ 0x8000;
1448 *high = data>>8;
1449 *low = (data>>2) & 0x3f;
1450 count--;
1451 }
1452 } else {
1453 u_char *lefth = &frame[*frameUsed>>2];
1454 u_char *leftl = lefth+sq.block_size_quarter;
1455 u_char *righth = lefth+sq.block_size_half;
1456 u_char *rightl = righth+sq.block_size_quarter;
1457 count = min(userCount, frameLeft)>>2 & ~1;
1458 used = count*4;
1459 while (count > 0) {
1460 data = get_user(((u_short *)userPtr)++);
1461 data = le2be16(data) ^ 0x8000;
1462 *lefth = data>>8;
1463 *leftl = (data>>2) & 0x3f;
1464 data = get_user(((u_short *)userPtr)++);
1465 data = le2be16(data) ^ 0x8000;
1466 *righth = data>>8;
1467 *rightl = (data>>2) & 0x3f;
1468 count--;
1469 }
1470 }
1471 *frameUsed += used;
1472 return(used);
1473 }
1474 #endif
1475
1476
1477 #ifdef CONFIG_ATARI
1478 static TRANS transTTNormal = {
1479 ata_ct_law, ata_ct_law, ata_ct_s8, ata_ct_u8, NULL, NULL, NULL, NULL
1480 };
1481
1482 static TRANS transTTExpanding = {
1483 ata_ctx_law, ata_ctx_law, ata_ctx_s8, ata_ctx_u8, NULL, NULL, NULL, NULL
1484 };
1485
1486 static TRANS transFalconNormal = {
1487 ata_ct_law, ata_ct_law, ata_ct_s8, ata_ct_u8, ata_ct_s16be, ata_ct_u16be,
1488 ata_ct_s16le, ata_ct_u16le
1489 };
1490
1491 static TRANS transFalconExpanding = {
1492 ata_ctx_law, ata_ctx_law, ata_ctx_s8, ata_ctx_u8, ata_ctx_s16be,
1493 ata_ctx_u16be, ata_ctx_s16le, ata_ctx_u16le
1494 };
1495 #endif
1496
1497 #ifdef CONFIG_AMIGA
1498 static TRANS transAmiga = {
1499 ami_ct_law, ami_ct_law, ami_ct_s8, ami_ct_u8, ami_ct_s16be, ami_ct_u16be,
1500 ami_ct_s16le, ami_ct_u16le
1501 };
1502 #endif
1503
1504
1505
1506
1507
1508 #ifdef CONFIG_ATARI
1509
1510
1511
1512
1513
1514 static void *AtaAlloc(unsigned int size, int flags)
1515 {
1516 int order;
1517 unsigned int a_size;
1518 order = 0;
1519 a_size = PAGE_SIZE;
1520 while (a_size < size) {
1521 order++;
1522 a_size <<= 1;
1523 }
1524 return (void *) __get_dma_pages(flags, order);
1525 }
1526
1527 static void AtaFree(void *obj, unsigned int size)
1528 {
1529 int order;
1530 unsigned int a_size;
1531 order = 0;
1532 a_size = PAGE_SIZE;
1533 while (a_size < size) {
1534 order++;
1535 a_size <<= 1;
1536 }
1537 free_pages (obj, order);
1538 }
1539
1540 static int AtaIrqInit(void)
1541 {
1542
1543
1544
1545
1546
1547
1548
1549 mfp.tim_ct_a = 0;
1550 mfp.tim_dt_a = 1;
1551 mfp.tim_ct_a = 8;
1552
1553 add_isr(IRQ_MFP_TIMA, ata_sq_interrupt, IRQ_TYPE_SLOW, NULL, "DMA sound");
1554 mfp.int_en_a |= 0x20;
1555 mfp.int_mk_a |= 0x20;
1556 return(1);
1557 }
1558
1559
1560 #define TONE_VOXWARE_TO_DB(v) \
1561 (((v) < 0) ? -12 : ((v) > 100) ? 12 : ((v) - 50) * 6 / 25)
1562 #define TONE_DB_TO_VOXWARE(v) (((v) * 25 + ((v) > 0 ? 5 : -5)) / 6 + 50)
1563
1564
1565 static int AtaSetBass(int bass)
1566 {
1567 sound.bass = TONE_VOXWARE_TO_DB(bass);
1568 atari_microwire_cmd(MW_LM1992_BASS(sound.bass));
1569 return(TONE_DB_TO_VOXWARE(sound.bass));
1570 }
1571
1572
1573 static int AtaSetTreble(int treble)
1574 {
1575 sound.treble = TONE_VOXWARE_TO_DB(treble);
1576 atari_microwire_cmd(MW_LM1992_TREBLE(sound.treble));
1577 return(TONE_DB_TO_VOXWARE(sound.treble));
1578 }
1579
1580
1581
1582
1583
1584
1585
1586
1587 static void TTSilence(void)
1588 {
1589 tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1590 atari_microwire_cmd(MW_LM1992_PSG_HIGH);
1591 }
1592
1593
1594 static void TTInit(void)
1595 {
1596 int mode, i, idx;
1597 const int freq[4] = {50066, 25033, 12517, 6258};
1598
1599
1600
1601 idx = -1;
1602 for (i = 0; i < arraysize(freq); i++)
1603
1604
1605
1606 if ((100 * abs(sound.soft.speed - freq[i]) / freq[i]) < catchRadius)
1607 idx = i;
1608 if (idx > -1) {
1609 sound.soft.speed = freq[idx];
1610 sound.trans = &transTTNormal;
1611 } else
1612 sound.trans = &transTTExpanding;
1613
1614 TTSilence();
1615 sound.hard = sound.soft;
1616
1617 if (sound.hard.speed > 50066) {
1618
1619 sound.hard.speed = 50066;
1620 mode = DMASND_MODE_50KHZ;
1621 sound.trans = &transTTNormal;
1622 } else if (sound.hard.speed > 25033) {
1623 sound.hard.speed = 50066;
1624 mode = DMASND_MODE_50KHZ;
1625 } else if (sound.hard.speed > 12517) {
1626 sound.hard.speed = 25033;
1627 mode = DMASND_MODE_25KHZ;
1628 } else if (sound.hard.speed > 6258) {
1629 sound.hard.speed = 12517;
1630 mode = DMASND_MODE_12KHZ;
1631 } else {
1632 sound.hard.speed = 6258;
1633 mode = DMASND_MODE_6KHZ;
1634 }
1635
1636 tt_dmasnd.mode = (sound.hard.stereo ?
1637 DMASND_MODE_STEREO : DMASND_MODE_MONO) |
1638 DMASND_MODE_8BIT | mode;
1639
1640 sound.bal = -sound.soft.speed;
1641 }
1642
1643
1644 static int TTSetFormat(int format)
1645 {
1646
1647
1648 switch (format) {
1649 case AFMT_QUERY:
1650 return(sound.soft.format);
1651 case AFMT_MU_LAW:
1652 case AFMT_A_LAW:
1653 case AFMT_S8:
1654 case AFMT_U8:
1655 break;
1656 default:
1657 format = AFMT_S8;
1658 }
1659
1660 sound.soft.format = format;
1661 sound.soft.size = 8;
1662 if (sound.minDev == SND_DEV_DSP) {
1663 sound.dsp.format = format;
1664 sound.dsp.size = 8;
1665 }
1666 TTInit();
1667
1668 return(format);
1669 }
1670
1671
1672 #define VOLUME_VOXWARE_TO_DB(v) \
1673 (((v) < 0) ? -40 : ((v) > 100) ? 0 : ((v) * 2) / 5 - 40)
1674 #define VOLUME_DB_TO_VOXWARE(v) ((((v) + 40) * 5 + 1) / 2)
1675
1676
1677 static int TTSetVolume(int volume)
1678 {
1679 sound.volume_left = VOLUME_VOXWARE_TO_DB(volume & 0xff);
1680 atari_microwire_cmd(MW_LM1992_BALLEFT(sound.volume_left));
1681 sound.volume_right = VOLUME_VOXWARE_TO_DB((volume & 0xff00) >> 8);
1682 atari_microwire_cmd(MW_LM1992_BALRIGHT(sound.volume_right));
1683 return(VOLUME_DB_TO_VOXWARE(sound.volume_left) |
1684 (VOLUME_DB_TO_VOXWARE(sound.volume_right) << 8));
1685 }
1686
1687
1688
1689
1690
1691
1692
1693
1694 static void FalconSilence(void)
1695 {
1696
1697 tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1698 tt_dmasnd.mode = DMASND_MODE_50KHZ | DMASND_MODE_STEREO | DMASND_MODE_8BIT;
1699 tt_dmasnd.int_div = 0;
1700 tt_dmasnd.int_ctrl = 0x0;
1701 tt_dmasnd.cbar_src = 0x0000;
1702 tt_dmasnd.cbar_dst = 0x0000;
1703 tt_dmasnd.dac_src = 1;
1704 tt_dmasnd.adc_src = 3;
1705 }
1706
1707
1708 static void FalconInit(void)
1709 {
1710 int divider, i, idx;
1711 const int freq[8] = {49170, 32780, 24585, 19668, 16390, 12292, 9834, 8195};
1712
1713
1714
1715 idx = -1;
1716 for (i = 0; i < arraysize(freq); i++)
1717
1718
1719
1720
1721 if ((100 * abs(sound.soft.speed - freq[i]) / freq[i]) < catchRadius)
1722 idx = i;
1723 if (idx > -1) {
1724 sound.soft.speed = freq[idx];
1725 sound.trans = &transFalconNormal;
1726 } else
1727 sound.trans = &transFalconExpanding;
1728
1729 FalconSilence();
1730 sound.hard = sound.soft;
1731
1732 if (sound.hard.size == 16) {
1733
1734 sound.hard.stereo = 1;
1735 }
1736
1737 if (sound.hard.speed > 49170) {
1738
1739 sound.hard.speed = 49170;
1740 divider = 1;
1741 sound.trans = &transFalconNormal;
1742 } else if (sound.hard.speed > 32780) {
1743 sound.hard.speed = 49170;
1744 divider = 1;
1745 } else if (sound.hard.speed > 24585) {
1746 sound.hard.speed = 32780;
1747 divider = 2;
1748 } else if (sound.hard.speed > 19668) {
1749 sound.hard.speed = 24585;
1750 divider = 3;
1751 } else if (sound.hard.speed > 16390) {
1752 sound.hard.speed = 19668;
1753 divider = 4;
1754 } else if (sound.hard.speed > 12292) {
1755 sound.hard.speed = 16390;
1756 divider = 5;
1757 } else if (sound.hard.speed > 9834) {
1758 sound.hard.speed = 12292;
1759 divider = 7;
1760 } else if (sound.hard.speed > 8195) {
1761 sound.hard.speed = 9834;
1762 divider = 9;
1763 } else {
1764 sound.hard.speed = 8195;
1765 divider = 11;
1766 }
1767 tt_dmasnd.int_div = divider;
1768
1769
1770 tt_dmasnd.int_ctrl = 0x4;
1771 tt_dmasnd.track_select = 0x0;
1772 tt_dmasnd.cbar_src = 0x0001;
1773 tt_dmasnd.cbar_dst = 0x0000;
1774 tt_dmasnd.rec_track_select = 0;
1775 tt_dmasnd.dac_src = 2;
1776 tt_dmasnd.adc_src = 0;
1777
1778 tt_dmasnd.mode = (sound.hard.stereo ?
1779 DMASND_MODE_STEREO : DMASND_MODE_MONO) |
1780 ((sound.hard.size == 8) ?
1781 DMASND_MODE_8BIT : DMASND_MODE_16BIT) |
1782 DMASND_MODE_6KHZ;
1783
1784 sound.bal = -sound.soft.speed;
1785 }
1786
1787
1788 static int FalconSetFormat(int format)
1789 {
1790 int size;
1791
1792
1793 switch (format) {
1794 case AFMT_QUERY:
1795 return(sound.soft.format);
1796 case AFMT_MU_LAW:
1797 case AFMT_A_LAW:
1798 case AFMT_U8:
1799 case AFMT_S8:
1800 size = 8;
1801 break;
1802 case AFMT_S16_BE:
1803 case AFMT_U16_BE:
1804 case AFMT_S16_LE:
1805 case AFMT_U16_LE:
1806 size = 16;
1807 break;
1808 default:
1809 size = 8;
1810 format = AFMT_S8;
1811 }
1812
1813 sound.soft.format = format;
1814 sound.soft.size = size;
1815 if (sound.minDev == SND_DEV_DSP) {
1816 sound.dsp.format = format;
1817 sound.dsp.size = sound.soft.size;
1818 }
1819
1820 FalconInit();
1821
1822 return(format);
1823 }
1824
1825
1826
1827
1828
1829 #define VOLUME_VOXWARE_TO_ATT(v) \
1830 ((v) < 0 ? 15 : (v) > 100 ? 0 : 15 - (v) * 3 / 20)
1831 #define VOLUME_ATT_TO_VOXWARE(v) (100 - (v) * 20 / 3)
1832
1833
1834 static int FalconSetVolume(int volume)
1835 {
1836 sound.volume_left = VOLUME_VOXWARE_TO_ATT(volume & 0xff);
1837 sound.volume_right = VOLUME_VOXWARE_TO_ATT((volume & 0xff00) >> 8);
1838 tt_dmasnd.output_atten = sound.volume_left << 8 | sound.volume_right << 4;
1839 return(VOLUME_ATT_TO_VOXWARE(sound.volume_left) |
1840 VOLUME_ATT_TO_VOXWARE(sound.volume_right) << 8);
1841 }
1842
1843
1844 static void ata_sq_play_next_frame(int index)
1845 {
1846 char *start, *end;
1847
1848
1849
1850
1851 start = sq_block_address(sq.front);
1852 end = start+((sq.count == index) ? sq.rear_size : sq.block_size);
1853
1854 DMASNDSetEnd(VTOP(end - 1) + 1);
1855 DMASNDSetBase(VTOP(start));
1856
1857
1858 sq.front = (sq.front+1) % sq.max_count;
1859 sq.playing++;
1860 tt_dmasnd.ctrl = DMASND_CTRL_ON | DMASND_CTRL_REPEAT;
1861 }
1862
1863
1864 static void AtaPlay(void)
1865 {
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879 atari_disable_irq(IRQ_MFP_TIMA);
1880
1881 if (sq.playing == 2 ||
1882 sq.count <= 0) {
1883 atari_enable_irq(IRQ_MFP_TIMA);
1884 return;
1885 }
1886
1887 if (sq.playing == 0) {
1888
1889
1890
1891 if (sq.count == 1 && sq.rear_size < sq.block_size && !sq.syncing) {
1892
1893
1894
1895 atari_enable_irq(IRQ_MFP_TIMA);
1896 return;
1897 }
1898 ata_sq_play_next_frame(1);
1899 if (sq.count == 1) {
1900
1901 atari_enable_irq(IRQ_MFP_TIMA);
1902 return;
1903 }
1904 if (sq.count == 2 && sq.rear_size < sq.block_size && !sq.syncing) {
1905
1906
1907
1908 atari_enable_irq(IRQ_MFP_TIMA);
1909 return;
1910 }
1911 ata_sq_play_next_frame(2);
1912 } else {
1913
1914
1915
1916
1917 if (sq.count == 2 && sq.rear_size < sq.block_size && !sq.syncing) {
1918
1919
1920
1921 atari_enable_irq(IRQ_MFP_TIMA);
1922 return;
1923 }
1924 ata_sq_play_next_frame(2);
1925 }
1926 atari_enable_irq(IRQ_MFP_TIMA);
1927 }
1928
1929
1930 static void ata_sq_interrupt(int irq, struct pt_regs *fp, void *dummy)
1931 {
1932 #if 0
1933
1934 static int cnt = 0;
1935 if (sq.playing == 2)
1936 if (++cnt == 10) {
1937
1938 cnt = 0;
1939 return;
1940 }
1941 #endif
1942
1943 if (sq.ignore_int && (sound.mach.type == DMASND_FALCON)) {
1944
1945
1946
1947
1948 sq.ignore_int = 0;
1949 return;
1950 }
1951
1952 if (!sq.playing) {
1953
1954
1955
1956 WAKE_UP(sq.sync_queue);
1957 return;
1958 }
1959
1960
1961
1962
1963
1964
1965
1966
1967 sq.count--;
1968 sq.playing--;
1969
1970 if (!sq.playing) {
1971 tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1972 sq.ignore_int = 1;
1973 }
1974
1975 WAKE_UP(sq.write_queue);
1976
1977
1978
1979
1980 if ((sq.playing != 1) || (sq.count != 1))
1981
1982
1983
1984
1985
1986
1987
1988 AtaPlay();
1989
1990 if (!sq.playing) WAKE_UP(sq.sync_queue);
1991
1992
1993
1994 }
1995 #endif
1996
1997
1998 #ifdef CONFIG_AMIGA
1999
2000
2001
2002
2003
2004
2005 static void *AmiAlloc(unsigned int size, int flags)
2006 {
2007 return(amiga_chip_alloc((long)size));
2008 }
2009
2010 static void AmiFree(void *obj, unsigned int size)
2011 {
2012 amiga_chip_free (obj);
2013 }
2014
2015 static int AmiIrqInit(void)
2016 {
2017
2018 custom.dmacon = AMI_AUDIO_OFF;
2019
2020
2021 if (!add_isr(IRQ_AMIGA_AUD0, ami_sq_interrupt, 0, NULL, "DMA sound"))
2022 panic("Couldn't add audio interrupt");
2023 return(1);
2024 }
2025
2026
2027 static void AmiSilence(void)
2028 {
2029
2030 custom.dmacon = AMI_AUDIO_OFF;
2031 }
2032
2033
2034 static void AmiInit(void)
2035 {
2036 int period, i;
2037
2038 AmiSilence();
2039
2040 if (sound.soft.speed)
2041 period = amiga_colorclock/sound.soft.speed-1;
2042 else
2043 period = amiga_audio_min_period;
2044 sound.hard = sound.soft;
2045 sound.trans = &transAmiga;
2046
2047 if (period < amiga_audio_min_period) {
2048
2049 period = amiga_audio_min_period;
2050 sound.hard.speed = amiga_colorclock/(period+1);
2051 } else if (period > 65535) {
2052 period = 65535;
2053 sound.hard.speed = amiga_colorclock/(period+1);
2054 }
2055 for (i = 0; i < 4; i++)
2056 custom.aud[i].audper = period;
2057 amiga_audio_period = period;
2058 }
2059
2060
2061 static int AmiSetFormat(int format)
2062 {
2063 int size;
2064
2065
2066
2067 switch (format) {
2068 case AFMT_QUERY:
2069 return(sound.soft.format);
2070 case AFMT_MU_LAW:
2071 case AFMT_A_LAW:
2072 case AFMT_U8:
2073 case AFMT_S8:
2074 size = 8;
2075 break;
2076 case AFMT_S16_BE:
2077 case AFMT_U16_BE:
2078 case AFMT_S16_LE:
2079 case AFMT_U16_LE:
2080 size = 16;
2081 break;
2082 default:
2083 size = 8;
2084 format = AFMT_S8;
2085 }
2086
2087 sound.soft.format = format;
2088 sound.soft.size = size;
2089 if (sound.minDev == SND_DEV_DSP) {
2090 sound.dsp.format = format;
2091 sound.dsp.size = sound.soft.size;
2092 }
2093 AmiInit();
2094
2095 return(format);
2096 }
2097
2098
2099 #define VOLUME_VOXWARE_TO_AMI(v) \
2100 (((v) < 0) ? 0 : ((v) > 100) ? 64 : ((v) * 64)/100)
2101 #define VOLUME_AMI_TO_VOXWARE(v) ((v)*100/64)
2102
2103 static int AmiSetVolume(int volume)
2104 {
2105 sound.volume_left = VOLUME_VOXWARE_TO_AMI(volume & 0xff);
2106 custom.aud[0].audvol = sound.volume_left;
2107 sound.volume_right = VOLUME_VOXWARE_TO_AMI((volume & 0xff00) >> 8);
2108 custom.aud[1].audvol = sound.volume_right;
2109 return(VOLUME_AMI_TO_VOXWARE(sound.volume_left) |
2110 (VOLUME_AMI_TO_VOXWARE(sound.volume_right) << 8));
2111 }
2112
2113 static int AmiSetTreble(int treble)
2114 {
2115 sound.treble = treble;
2116 if (treble > 50)
2117 ciaa.pra |= 0x02;
2118 else
2119 ciaa.pra &= ~0x02;
2120 return(treble);
2121 }
2122
2123
2124 #define AMI_PLAY_LOADED 1
2125 #define AMI_PLAY_PLAYING 2
2126 #define AMI_PLAY_MASK 3
2127
2128
2129 static void ami_sq_play_next_frame(int index)
2130 {
2131 u_char *start, *ch0, *ch1, *ch2, *ch3;
2132 u_long size;
2133
2134
2135
2136
2137 start = sq_block_address(sq.front);
2138 size = (sq.count == index ? sq.rear_size : sq.block_size)>>1;
2139
2140 if (sound.hard.stereo) {
2141 ch0 = start;
2142 ch1 = start+sq.block_size_half;
2143 size >>= 1;
2144 } else {
2145 ch0 = start;
2146 ch1 = start;
2147 }
2148 if (sound.hard.size == 8) {
2149 custom.aud[0].audlc = (u_short *)ZTWO_PADDR(ch0);
2150 custom.aud[0].audlen = size;
2151 custom.aud[1].audlc = (u_short *)ZTWO_PADDR(ch1);
2152 custom.aud[1].audlen = size;
2153 custom.dmacon = AMI_AUDIO_8;
2154 } else {
2155 size >>= 1;
2156 custom.aud[0].audlc = (u_short *)ZTWO_PADDR(ch0);
2157 custom.aud[0].audlen = size;
2158 custom.aud[1].audlc = (u_short *)ZTWO_PADDR(ch1);
2159 custom.aud[1].audlen = size;
2160 if (sound.volume_left == 64 && sound.volume_right == 64) {
2161
2162 ch3 = ch0+sq.block_size_quarter;
2163 ch2 = ch1+sq.block_size_quarter;
2164 custom.aud[2].audlc = (u_short *)ZTWO_PADDR(ch2);
2165 custom.aud[2].audlen = size;
2166 custom.aud[3].audlc = (u_short *)ZTWO_PADDR(ch3);
2167 custom.aud[3].audlen = size;
2168 custom.dmacon = AMI_AUDIO_14;
2169 } else
2170 custom.dmacon = AMI_AUDIO_8;
2171 }
2172 sq.front = (sq.front+1) % sq.max_count;
2173 sq.playing |= AMI_PLAY_LOADED;
2174 }
2175
2176
2177 static void AmiPlay(void)
2178 {
2179 int minframes = 1;
2180
2181 custom.intena = IF_AUD0;
2182
2183 if (sq.playing & AMI_PLAY_LOADED) {
2184
2185 custom.intena = IF_SETCLR | IF_AUD0;
2186 return;
2187 }
2188
2189 if (sq.playing & AMI_PLAY_PLAYING)
2190
2191 minframes = 2;
2192
2193 if (sq.count < minframes) {
2194
2195 custom.intena = IF_SETCLR | IF_AUD0;
2196 return;
2197 }
2198
2199 if (sq.count <= minframes && sq.rear_size < sq.block_size && !sq.syncing) {
2200
2201
2202
2203 custom.intena = IF_SETCLR | IF_AUD0;
2204 return;
2205 }
2206
2207 ami_sq_play_next_frame(minframes);
2208
2209 custom.intena = IF_SETCLR | IF_AUD0;
2210 }
2211
2212
2213 static void ami_sq_interrupt(int irq, struct pt_regs *fp, void *dummy)
2214 {
2215 int minframes = 1;
2216
2217 if (!sq.playing) {
2218
2219
2220
2221 WAKE_UP(sq.sync_queue);
2222 return;
2223 }
2224
2225 if (sq.playing & AMI_PLAY_PLAYING) {
2226
2227 sq.count--;
2228 WAKE_UP(sq.write_queue);
2229 }
2230
2231 if (sq.playing & AMI_PLAY_LOADED)
2232
2233 minframes = 2;
2234
2235
2236 sq.playing = (sq.playing<<1) & AMI_PLAY_MASK;
2237
2238 if (!sq.playing)
2239
2240 custom.dmacon = AMI_AUDIO_OFF;
2241
2242 if (sq.count >= minframes)
2243
2244 AmiPlay();
2245
2246 if (!sq.playing)
2247
2248
2249 WAKE_UP(sq.sync_queue);
2250 }
2251 #endif
2252
2253
2254
2255
2256
2257 #ifdef CONFIG_ATARI
2258 static MACHINE machTT = {
2259 DMASND_TT, AtaAlloc, AtaFree, AtaIrqInit, TTInit, TTSilence, TTSetFormat,
2260 TTSetVolume, AtaSetBass, AtaSetTreble, AtaPlay
2261 };
2262
2263 static MACHINE machFalcon = {
2264 DMASND_FALCON, AtaAlloc, AtaFree, AtaIrqInit, FalconInit, FalconSilence,
2265 FalconSetFormat, FalconSetVolume, AtaSetBass, AtaSetTreble, AtaPlay
2266 };
2267 #endif
2268
2269 #ifdef CONFIG_AMIGA
2270 static MACHINE machAmiga = {
2271 DMASND_AMIGA, AmiAlloc, AmiFree, AmiIrqInit, AmiInit, AmiSilence,
2272 AmiSetFormat, AmiSetVolume, NULL, AmiSetTreble, AmiPlay
2273 };
2274 #endif
2275
2276
2277
2278
2279
2280 static void sound_silence(void)
2281 {
2282
2283 (*sound.mach.init)();
2284
2285 (*sound.mach.silence)();
2286 }
2287
2288
2289 static void sound_init(void)
2290 {
2291 (*sound.mach.init)();
2292 }
2293
2294
2295 static int sound_set_format(int format)
2296 {
2297 return(*sound.mach.setFormat)(format);
2298 }
2299
2300
2301 static int sound_set_speed(int speed)
2302 {
2303 if (speed < 0)
2304 return(sound.soft.speed);
2305
2306 sound.soft.speed = speed;
2307 (*sound.mach.init)();
2308 if (sound.minDev == SND_DEV_DSP)
2309 sound.dsp.speed = sound.soft.speed;
2310
2311 return(sound.soft.speed);
2312 }
2313
2314
2315 static int sound_set_stereo(int stereo)
2316 {
2317 if (stereo < 0)
2318 return(sound.soft.stereo);
2319
2320 stereo = !!stereo;
2321
2322 sound.soft.stereo = stereo;
2323 if (sound.minDev == SND_DEV_DSP)
2324 sound.dsp.stereo = stereo;
2325 (*sound.mach.init)();
2326
2327 return(stereo);
2328 }
2329
2330
2331 static int sound_set_volume(int volume)
2332 {
2333 return(*sound.mach.setVolume)(volume);
2334 }
2335
2336
2337 #ifdef CONFIG_ATARI
2338 static int sound_set_bass(int bass)
2339 {
2340 return(sound.mach.setBass ? (*sound.mach.setBass)(bass) : 50);
2341 }
2342 #endif
2343
2344
2345 static int sound_set_treble(int treble)
2346 {
2347 return(sound.mach.setTreble ? (*sound.mach.setTreble)(treble) : 50);
2348 }
2349
2350
2351 static long sound_copy_translate(const u_char *userPtr, long userCount,
2352 u_char frame[], long *frameUsed,
2353 long frameLeft)
2354 {
2355 long (*ct_func)(const u_char *, long, u_char *, long *, long) = NULL;
2356
2357 switch (sound.soft.format) {
2358 case AFMT_MU_LAW:
2359 ct_func = sound.trans->ct_ulaw;
2360 break;
2361 case AFMT_A_LAW:
2362 ct_func = sound.trans->ct_alaw;
2363 break;
2364 case AFMT_S8:
2365 ct_func = sound.trans->ct_s8;
2366 break;
2367 case AFMT_U8:
2368 ct_func = sound.trans->ct_u8;
2369 break;
2370 case AFMT_S16_BE:
2371 ct_func = sound.trans->ct_s16be;
2372 break;
2373 case AFMT_U16_BE:
2374 ct_func = sound.trans->ct_u16be;
2375 break;
2376 case AFMT_S16_LE:
2377 ct_func = sound.trans->ct_s16le;
2378 break;
2379 case AFMT_U16_LE:
2380 ct_func = sound.trans->ct_u16le;
2381 break;
2382 }
2383 if (ct_func)
2384 return(ct_func(userPtr, userCount, frame, frameUsed, frameLeft));
2385 else
2386 return(0);
2387 }
2388
2389
2390
2391
2392
2393
2394
2395 #define RECLEVEL_VOXWARE_TO_GAIN(v) \
2396 ((v) < 0 ? 0 : (v) > 100 ? 15 : (v) * 3 / 20)
2397 #define RECLEVEL_GAIN_TO_VOXWARE(v) (((v) * 20 + 2) / 3)
2398
2399
2400 static void mixer_init(void)
2401 {
2402 mixer.busy = 0;
2403 sound.treble = 0;
2404 sound.bass = 0;
2405 switch (sound.mach.type) {
2406 #ifdef CONFIG_ATARI
2407 case DMASND_TT:
2408 atari_microwire_cmd(MW_LM1992_VOLUME(0));
2409 sound.volume_left = 0;
2410 atari_microwire_cmd(MW_LM1992_BALLEFT(0));
2411 sound.volume_right = 0;
2412 atari_microwire_cmd(MW_LM1992_BALRIGHT(0));
2413 atari_microwire_cmd(MW_LM1992_TREBLE(0));
2414 atari_microwire_cmd(MW_LM1992_BASS(0));
2415 break;
2416 case DMASND_FALCON:
2417 sound.volume_left = (tt_dmasnd.output_atten & 0xf00) >> 8;
2418 sound.volume_right = (tt_dmasnd.output_atten & 0xf0) >> 4;
2419 break;
2420 #endif
2421 #ifdef CONFIG_AMIGA
2422 case DMASND_AMIGA:
2423 sound.volume_left = 64;
2424 sound.volume_right = 64;
2425 custom.aud[0].audvol = sound.volume_left;
2426 custom.aud[3].audvol = 1;
2427 custom.aud[1].audvol = sound.volume_right;
2428 custom.aud[2].audvol = 1;
2429 sound.treble = 50;
2430 break;
2431 #endif
2432 }
2433 }
2434
2435
2436 static int mixer_open(int open_mode)
2437 {
2438 if (mixer.busy)
2439 return(-EBUSY);
2440 mixer.busy = 1;
2441 return(0);
2442 }
2443
2444
2445 static int mixer_release(void)
2446 {
2447 mixer.busy = 0;
2448 return(0);
2449 }
2450
2451
2452 static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
2453 u_long arg)
2454 {
2455 switch (sound.mach.type) {
2456 #ifdef CONFIG_ATARI
2457 case DMASND_FALCON:
2458 switch (cmd) {
2459 case SOUND_MIXER_READ_DEVMASK:
2460 return(IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_SPEAKER));
2461 case SOUND_MIXER_READ_RECMASK:
2462 return(IOCTL_OUT(arg, SOUND_MASK_MIC));
2463 case SOUND_MIXER_READ_STEREODEVS:
2464 return(IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC));
2465 case SOUND_MIXER_READ_CAPS:
2466 return(IOCTL_OUT(arg, SOUND_CAP_EXCL_INPUT));
2467 case SOUND_MIXER_READ_VOLUME:
2468 return(IOCTL_OUT(arg,
2469 VOLUME_ATT_TO_VOXWARE(sound.volume_left) |
2470 VOLUME_ATT_TO_VOXWARE(sound.volume_right) << 8));
2471 case SOUND_MIXER_WRITE_MIC:
2472 tt_dmasnd.input_gain =
2473 RECLEVEL_VOXWARE_TO_GAIN(IOCTL_IN(arg) & 0xff) << 4 |
2474 RECLEVEL_VOXWARE_TO_GAIN(IOCTL_IN(arg) >> 8 & 0xff);
2475
2476 case SOUND_MIXER_READ_MIC:
2477 return(IOCTL_OUT(arg,
2478 RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain >> 4 & 0xf) |
2479 RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain & 0xf) << 8));
2480 case SOUND_MIXER_READ_SPEAKER:
2481 {
2482 int porta;
2483 cli();
2484 sound_ym.rd_data_reg_sel = 14;
2485 porta = sound_ym.rd_data_reg_sel;
2486 sti();
2487 return(IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
2488 }
2489 case SOUND_MIXER_WRITE_VOLUME:
2490 return(IOCTL_OUT(arg, sound_set_volume(IOCTL_IN(arg))));
2491 case SOUND_MIXER_WRITE_SPEAKER:
2492 {
2493 int porta;
2494 cli();
2495 sound_ym.rd_data_reg_sel = 14;
2496 porta = (sound_ym.rd_data_reg_sel & ~0x40) |
2497 (IOCTL_IN(arg) < 50 ? 0x40 : 0);
2498 sound_ym.wd_data = porta;
2499 sti();
2500 return(IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
2501 }
2502 }
2503 break;
2504
2505 case DMASND_TT:
2506 switch (cmd) {
2507 case SOUND_MIXER_READ_DEVMASK:
2508 return(IOCTL_OUT(arg,
2509 SOUND_MASK_VOLUME | SOUND_MASK_TREBLE | SOUND_MASK_BASS |
2510 ((boot_info.bi_atari.mch_cookie >> 16) == ATARI_MCH_TT ?
2511 SOUND_MASK_SPEAKER : 0)));
2512 case SOUND_MIXER_READ_RECMASK:
2513 return(IOCTL_OUT(arg, 0));
2514 case SOUND_MIXER_READ_STEREODEVS:
2515 return(IOCTL_OUT(arg, SOUND_MASK_VOLUME));
2516 case SOUND_MIXER_READ_VOLUME:
2517 return(IOCTL_OUT(arg,
2518 VOLUME_DB_TO_VOXWARE(sound.volume_left) |
2519 (VOLUME_DB_TO_VOXWARE(sound.volume_right) << 8)));
2520 case SOUND_MIXER_READ_BASS:
2521 return(IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(sound.bass)));
2522 case SOUND_MIXER_READ_TREBLE:
2523 return(IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(sound.treble)));
2524 case SOUND_MIXER_READ_SPEAKER:
2525 {
2526 int porta;
2527 if ((boot_info.bi_atari.mch_cookie >> 16) == ATARI_MCH_TT) {
2528 cli();
2529 sound_ym.rd_data_reg_sel = 14;
2530 porta = sound_ym.rd_data_reg_sel;
2531 sti();
2532 return(IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
2533 } else
2534 return(-EINVAL);
2535 }
2536 case SOUND_MIXER_WRITE_VOLUME:
2537 return(IOCTL_OUT(arg, sound_set_volume(IOCTL_IN(arg))));
2538 case SOUND_MIXER_WRITE_BASS:
2539 return(IOCTL_OUT(arg, sound_set_bass(IOCTL_IN(arg))));
2540 case SOUND_MIXER_WRITE_TREBLE:
2541 return(IOCTL_OUT(arg, sound_set_treble(IOCTL_IN(arg))));
2542 case SOUND_MIXER_WRITE_SPEAKER:
2543 if ((boot_info.bi_atari.mch_cookie >> 16) == ATARI_MCH_TT) {
2544 int porta;
2545 cli();
2546 sound_ym.rd_data_reg_sel = 14;
2547 porta = (sound_ym.rd_data_reg_sel & ~0x40) |
2548 (IOCTL_IN(arg) < 50 ? 0x40 : 0);
2549 sound_ym.wd_data = porta;
2550 sti();
2551 return(IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
2552 } else
2553 return(-EINVAL);
2554 }
2555 break;
2556 #endif
2557
2558 #ifdef CONFIG_AMIGA
2559 case DMASND_AMIGA:
2560 switch (cmd) {
2561 case SOUND_MIXER_READ_DEVMASK:
2562 return(IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_TREBLE));
2563 case SOUND_MIXER_READ_RECMASK:
2564 return(IOCTL_OUT(arg, 0));
2565 case SOUND_MIXER_READ_STEREODEVS:
2566 return(IOCTL_OUT(arg, SOUND_MASK_VOLUME));
2567 case SOUND_MIXER_READ_VOLUME:
2568 return(IOCTL_OUT(arg,
2569 VOLUME_AMI_TO_VOXWARE(sound.volume_left) |
2570 VOLUME_AMI_TO_VOXWARE(sound.volume_right) << 8));
2571 case SOUND_MIXER_WRITE_VOLUME:
2572 return(IOCTL_OUT(arg, sound_set_volume(IOCTL_IN(arg))));
2573 case SOUND_MIXER_READ_TREBLE:
2574 return(IOCTL_OUT(arg, sound.treble));
2575 case SOUND_MIXER_WRITE_TREBLE:
2576 return(IOCTL_OUT(arg, sound_set_treble(IOCTL_IN(arg))));
2577 }
2578 break;
2579 #endif
2580 }
2581
2582 return(-EINVAL);
2583 }
2584
2585
2586
2587
2588
2589
2590
2591
2592 static void sq_init(int numBufs, int bufSize, char **buffers)
2593 {
2594 sq.max_count = numBufs;
2595 sq.block_size = bufSize;
2596 sq.buffers = buffers;
2597
2598 sq.front = sq.count = 0;
2599 sq.rear = -1;
2600 sq.write_queue = sq.open_queue = sq.sync_queue = 0;
2601 sq.busy = 0;
2602 sq.syncing = 0;
2603
2604 sq.playing = 0;
2605
2606 #ifdef CONFIG_ATARI
2607 sq.ignore_int = 0;
2608 #endif
2609 #ifdef CONFIG_AMIGA
2610 sq.block_size_half = sq.block_size>>1;
2611 sq.block_size_quarter = sq.block_size_half>>1;
2612 #endif
2613
2614 sound_silence();
2615
2616
2617
2618
2619
2620 sound.dsp.format = AFMT_S8;
2621 sound.dsp.stereo = 0;
2622 sound.dsp.size = 8;
2623
2624
2625 switch (sound.mach.type) {
2626 #ifdef CONFIG_ATARI
2627 case DMASND_TT:
2628 sound.dsp.speed = 6258;
2629 break;
2630 case DMASND_FALCON:
2631 sound.dsp.speed = 8195;
2632 break;
2633 #endif
2634 #ifdef CONFIG_AMIGA
2635 case DMASND_AMIGA:
2636 sound.dsp.speed = 8000;
2637 break;
2638 #endif
2639 }
2640
2641
2642 sound.soft = sound.dsp;
2643 }
2644
2645
2646 static void sq_play(void)
2647 {
2648 (*sound.mach.play)();
2649 }
2650
2651
2652
2653
2654 static int sq_write(const char *src, int uLeft)
2655 {
2656 int uWritten = 0;
2657 u_char *dest;
2658 long uUsed, bUsed, bLeft;
2659
2660
2661
2662
2663
2664 if (uLeft < 1)
2665 return(0);
2666
2667
2668
2669
2670
2671
2672 if (sq.count > 0 && (bLeft = sq.block_size-sq.rear_size) > 0) {
2673 dest = sq_block_address(sq.rear);
2674 bUsed = sq.rear_size;
2675 uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft);
2676 src += uUsed;
2677 uWritten += uUsed;
2678 uLeft -= uUsed;
2679 sq.rear_size = bUsed;
2680 }
2681
2682 do {
2683 if (sq.count == sq.max_count) {
2684 sq_play();
2685 if (NON_BLOCKING(sq.open_mode))
2686 return(uWritten > 0 ? uWritten : -EAGAIN);
2687 SLEEP(sq.write_queue, ONE_SECOND);
2688 if (SIGNAL_RECEIVED)
2689 return(uWritten > 0 ? uWritten : -EINTR);
2690 }
2691
2692
2693
2694
2695
2696
2697
2698
2699 dest = sq_block_address((sq.rear+1) % sq.max_count);
2700 bUsed = 0;
2701 bLeft = sq.block_size;
2702 uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft);
2703 src += uUsed;
2704 uWritten += uUsed;
2705 uLeft -= uUsed;
2706 if (bUsed) {
2707 sq.rear = (sq.rear+1) % sq.max_count;
2708 sq.rear_size = bUsed;
2709 sq.count++;
2710 }
2711 } while (bUsed);
2712
2713 sq_play();
2714
2715 return(uWritten);
2716 }
2717
2718
2719 static int sq_open(int open_mode)
2720 {
2721 if (sq.busy) {
2722 if (NON_BLOCKING(open_mode))
2723 return(-EBUSY);
2724 while (sq.busy) {
2725 SLEEP(sq.open_queue, ONE_SECOND);
2726 if (SIGNAL_RECEIVED)
2727 return(-EINTR);
2728 }
2729 }
2730 sq.open_mode = open_mode;
2731 sq.busy = 1;
2732 #ifdef CONFIG_ATARI
2733 sq.ignore_int = 1;
2734 #endif
2735 return(0);
2736 }
2737
2738
2739 static void sq_reset(void)
2740 {
2741 sound_silence();
2742 sq.playing = 0;
2743 sq.count = 0;
2744 sq.front = (sq.rear+1) % sq.max_count;
2745 }
2746
2747
2748 static int sq_sync(void)
2749 {
2750 int rc = 0;
2751
2752 sq.syncing = 1;
2753 sq_play();
2754
2755 while (sq.playing) {
2756 SLEEP(sq.sync_queue, ONE_SECOND);
2757 if (SIGNAL_RECEIVED) {
2758
2759
2760 sq_reset();
2761 rc = -EINTR;
2762 break;
2763 }
2764 }
2765
2766 sq.syncing = 0;
2767 return(rc);
2768 }
2769
2770
2771 static int sq_release(void)
2772 {
2773 int rc = 0;
2774 if (sq.busy) {
2775 rc = sq_sync();
2776 sq.busy = 0;
2777 WAKE_UP(sq.open_queue);
2778
2779
2780
2781 }
2782 return(rc);
2783 }
2784
2785
2786
2787
2788
2789
2790
2791
2792 static void state_init(void)
2793 {
2794 state.busy = 0;
2795 }
2796
2797
2798
2799
2800 static int state_open(int open_mode)
2801 {
2802 char *buffer = state.buf, *mach = "";
2803 int len = 0;
2804
2805 if (state.busy)
2806 return(-EBUSY);
2807
2808 state.ptr = 0;
2809 state.busy = 1;
2810
2811 switch (sound.mach.type) {
2812 #ifdef CONFIG_ATARI
2813 case DMASND_TT:
2814 case DMASND_FALCON:
2815 mach = "Atari ";
2816 break;
2817 #endif
2818 #ifdef CONFIG_AMIGA
2819 case DMASND_AMIGA:
2820 mach = "Amiga ";
2821 break;
2822 #endif
2823 }
2824 len += sprintf(buffer+len, "%sDMA sound driver:\n", mach);
2825
2826 len += sprintf(buffer+len, "\tsound.format = 0x%x", sound.soft.format);
2827 switch (sound.soft.format) {
2828 case AFMT_MU_LAW:
2829 len += sprintf(buffer+len, " (mu-law)");
2830 break;
2831 case AFMT_A_LAW:
2832 len += sprintf(buffer+len, " (A-law)");
2833 break;
2834 case AFMT_U8:
2835 len += sprintf(buffer+len, " (unsigned 8 bit)");
2836 break;
2837 case AFMT_S8:
2838 len += sprintf(buffer+len, " (signed 8 bit)");
2839 break;
2840 case AFMT_S16_BE:
2841 len += sprintf(buffer+len, " (signed 16 bit big)");
2842 break;
2843 case AFMT_U16_BE:
2844 len += sprintf(buffer+len, " (unsigned 16 bit big)");
2845 break;
2846 case AFMT_S16_LE:
2847 len += sprintf(buffer+len, " (signed 16 bit little)");
2848 break;
2849 case AFMT_U16_LE:
2850 len += sprintf(buffer+len, " (unsigned 16 bit little)");
2851 break;
2852 }
2853 len += sprintf(buffer+len, "\n");
2854 len += sprintf(buffer+len, "\tsound.speed = %dHz (phys. %dHz)\n",
2855 sound.soft.speed, sound.hard.speed);
2856 len += sprintf(buffer+len, "\tsound.stereo = 0x%x (%s)\n",
2857 sound.soft.stereo, sound.soft.stereo ? "stereo" : "mono");
2858 switch (sound.mach.type) {
2859 #ifdef CONFIG_ATARI
2860 case DMASND_TT:
2861 len += sprintf(buffer+len, "\tsound.volume_left = %ddB [-40...0]\n",
2862 sound.volume_left);
2863 len += sprintf(buffer+len, "\tsound.volume_right = %ddB [-40...0]\n",
2864 sound.volume_right);
2865 len += sprintf(buffer+len, "\tsound.bass = %ddB [-12...+12]\n",
2866 sound.bass);
2867 len += sprintf(buffer+len, "\tsound.treble = %ddB [-12...+12]\n",
2868 sound.treble);
2869 break;
2870 case DMASND_FALCON:
2871 len += sprintf(buffer+len, "\tsound.volume_left = %ddB [-22.5...0]\n",
2872 sound.volume_left);
2873 len += sprintf(buffer+len, "\tsound.volume_right = %ddB [-22.5...0]\n",
2874 sound.volume_right);
2875 break;
2876 #endif
2877 #ifdef CONFIG_AMIGA
2878 case DMASND_AMIGA:
2879 len += sprintf(buffer+len, "\tsound.volume_left = %d [0...64]\n",
2880 sound.volume_left);
2881 len += sprintf(buffer+len, "\tsound.volume_right = %d [0...64]\n",
2882 sound.volume_right);
2883 break;
2884 #endif
2885 }
2886 len += sprintf(buffer+len, "\tsq.block_size = %d sq.max_count = %d\n",
2887 sq.block_size, sq.max_count);
2888 len += sprintf(buffer+len, "\tsq.count = %d sq.rear_size = %d\n", sq.count,
2889 sq.rear_size);
2890 len += sprintf(buffer+len, "\tsq.playing = %d sq.syncing = %d\n",
2891 sq.playing, sq.syncing);
2892 state.len = len;
2893 return(0);
2894 }
2895
2896
2897 static int state_release(void)
2898 {
2899 state.busy = 0;
2900 return(0);
2901 }
2902
2903
2904 static int state_read(char *dest, int count)
2905 {
2906 int n = state.len-state.ptr;
2907 if (n > count)
2908 n = count;
2909 if (n <= 0)
2910 return(0);
2911 memcpy_tofs(dest, &state.buf[state.ptr], n);
2912 state.ptr += n;
2913 return(n);
2914 }
2915
2916
2917
2918
2919
2920
2921 static int sound_open(struct inode *inode, struct file *file)
2922 {
2923 int dev = MINOR(inode->i_rdev) & 0x0f;
2924
2925 switch (dev) {
2926 case SND_DEV_STATUS:
2927 return(state_open(file->f_flags));
2928 case SND_DEV_CTL:
2929 return(mixer_open(file->f_flags));
2930 case SND_DEV_DSP:
2931 case SND_DEV_AUDIO:
2932 {
2933 int rc = sq_open(file->f_flags);
2934 if (rc == 0) {
2935 sound.minDev = dev;
2936 sound.soft = sound.dsp;
2937 sound_init();
2938 if (dev == SND_DEV_AUDIO) {
2939 sound_set_speed(8000);
2940 sound_set_stereo(0);
2941 sound_set_format(AFMT_MU_LAW);
2942 }
2943 }
2944 return(rc);
2945 }
2946 default:
2947 return(-ENXIO);
2948 }
2949 }
2950
2951
2952 static int sound_fsync(struct inode *inode, struct file *filp)
2953 {
2954 int dev = MINOR(inode->i_rdev) & 0x0f;
2955
2956 switch (dev) {
2957 case SND_DEV_STATUS:
2958 case SND_DEV_CTL:
2959 return(0);
2960 case SND_DEV_DSP:
2961 case SND_DEV_AUDIO:
2962 return(sq_sync());
2963 default:
2964 return(unknown_minor_dev("sound_fsync", dev));
2965 }
2966 }
2967
2968
2969 static void sound_release(struct inode *inode, struct file *file)
2970 {
2971 int dev = MINOR(inode->i_rdev);
2972
2973 switch (dev & 0x0f) {
2974 case SND_DEV_STATUS: state_release(); return;
2975 case SND_DEV_CTL: mixer_release(); return;
2976 case SND_DEV_DSP:
2977 case SND_DEV_AUDIO:
2978 sq_release(); sound.soft = sound.dsp; sound_silence();
2979 return;
2980 default:
2981 unknown_minor_dev("sound_release", dev);
2982 }
2983 }
2984
2985
2986 static int sound_lseek(struct inode *inode, struct file *file, off_t offset,
2987 int orig)
2988 {
2989 return(-EPERM);
2990 }
2991
2992
2993 static int sound_read(struct inode *inode, struct file *file, char *buf,
2994 int count)
2995 {
2996 int dev = MINOR(inode->i_rdev);
2997
2998 switch (dev & 0x0f) {
2999 case SND_DEV_STATUS:
3000 return(state_read(buf, count));
3001 case SND_DEV_CTL:
3002 case SND_DEV_DSP:
3003 case SND_DEV_AUDIO:
3004 return(-EPERM);
3005 default:
3006 return(unknown_minor_dev("sound_read", dev));
3007 }
3008 }
3009
3010
3011 static int sound_write(struct inode *inode, struct file *file, const char *buf,
3012 int count)
3013 {
3014 int dev = MINOR(inode->i_rdev);
3015
3016 switch (dev & 0x0f) {
3017 case SND_DEV_STATUS:
3018 case SND_DEV_CTL:
3019 return(-EPERM);
3020 case SND_DEV_DSP:
3021 case SND_DEV_AUDIO:
3022 return(sq_write(buf, count));
3023 default:
3024 return(unknown_minor_dev("sound_write", dev));
3025 }
3026 }
3027
3028
3029 static int ioctl_return(int *addr, int value)
3030 {
3031 int error;
3032
3033 if (value < 0)
3034 return(value);
3035
3036 error = verify_area(VERIFY_WRITE, addr, sizeof(int));
3037 if (error)
3038 return(error);
3039
3040 put_user(value, addr);
3041 return(0);
3042 }
3043
3044
3045 static int unknown_minor_dev(char *fname, int dev)
3046 {
3047
3048 return(-ENXIO);
3049 }
3050
3051
3052 static int sound_ioctl(struct inode *inode, struct file *file, u_int cmd,
3053 u_long arg)
3054 {
3055 int dev = MINOR(inode->i_rdev);
3056 u_long fmt;
3057
3058 switch (dev & 0x0f) {
3059 case SND_DEV_STATUS:
3060 return(-EPERM);
3061 case SND_DEV_CTL:
3062 return(mixer_ioctl(inode, file, cmd, arg));
3063 case SND_DEV_AUDIO:
3064 case SND_DEV_DSP:
3065 switch (cmd) {
3066 case SNDCTL_DSP_RESET:
3067 sq_reset();
3068 return(0);
3069 case SNDCTL_DSP_POST:
3070 case SNDCTL_DSP_SYNC:
3071 return(sound_fsync(inode, file));
3072
3073
3074
3075
3076 case SNDCTL_DSP_SPEED:
3077 sound_fsync(inode, file);
3078 return(IOCTL_OUT(arg, sound_set_speed(IOCTL_IN(arg))));
3079 case SNDCTL_DSP_STEREO:
3080 sound_fsync(inode, file);
3081 return(IOCTL_OUT(arg, sound_set_stereo(IOCTL_IN(arg))));
3082 case SOUND_PCM_WRITE_CHANNELS:
3083 sound_fsync(inode, file);
3084 return(IOCTL_OUT(arg, sound_set_stereo(IOCTL_IN(arg)-1)+1));
3085 case SNDCTL_DSP_SETFMT:
3086 sound_fsync(inode, file);
3087 return(IOCTL_OUT(arg, sound_set_format(IOCTL_IN(arg))));
3088 case SNDCTL_DSP_GETFMTS:
3089 fmt = 0;
3090 if (sound.trans) {
3091 if (sound.trans->ct_ulaw)
3092 fmt |= AFMT_MU_LAW;
3093 if (sound.trans->ct_alaw)
3094 fmt |= AFMT_A_LAW;
3095 if (sound.trans->ct_s8)
3096 fmt |= AFMT_S8;
3097 if (sound.trans->ct_u8)
3098 fmt |= AFMT_U8;
3099 if (sound.trans->ct_s16be)
3100 fmt |= AFMT_S16_BE;
3101 if (sound.trans->ct_u16be)
3102 fmt |= AFMT_U16_BE;
3103 if (sound.trans->ct_s16le)
3104 fmt |= AFMT_S16_LE;
3105 if (sound.trans->ct_u16le)
3106 fmt |= AFMT_U16_LE;
3107 }
3108 return(IOCTL_OUT(arg, fmt));
3109 case SNDCTL_DSP_GETBLKSIZE:
3110 return(IOCTL_OUT(arg, 10240));
3111 case SNDCTL_DSP_SUBDIVIDE:
3112 case SNDCTL_DSP_SETFRAGMENT:
3113 break;
3114
3115 default:
3116 return(mixer_ioctl(inode, file, cmd, arg));
3117 }
3118 break;
3119
3120 default:
3121 return(unknown_minor_dev("sound_ioctl", dev));
3122 }
3123 return(-EINVAL);
3124 }
3125
3126
3127 static struct file_operations sound_fops =
3128 {
3129 sound_lseek,
3130 sound_read,
3131 sound_write,
3132 NULL,
3133 NULL,
3134 sound_ioctl,
3135 NULL,
3136 sound_open,
3137 sound_release,
3138 sound_fsync
3139 };
3140
3141
3142
3143
3144
3145
3146 void soundcard_init(void)
3147 {
3148 int has_sound = 0;
3149 char **buffers;
3150 int i;
3151
3152 switch (boot_info.machtype) {
3153 #ifdef CONFIG_ATARI
3154 case MACH_ATARI:
3155 if (ATARIHW_PRESENT(PCM_8BIT)) {
3156 if (ATARIHW_PRESENT(CODEC))
3157 sound.mach = machFalcon;
3158 else if (ATARIHW_PRESENT(MICROWIRE))
3159 sound.mach = machTT;
3160 else
3161 break;
3162 if ((mfp.int_en_a & mfp.int_mk_a & 0x20) == 0)
3163 has_sound = 1;
3164 else
3165 printk("DMA sound driver: Timer A interrupt already in use\n");
3166 }
3167 break;
3168
3169 #endif
3170 #ifdef CONFIG_AMIGA
3171 case MACH_AMIGA:
3172 if (AMIGAHW_PRESENT(AMI_AUDIO)) {
3173 sound.mach = machAmiga;
3174 has_sound = 1;
3175 }
3176 break;
3177 #endif
3178 }
3179 if (!has_sound)
3180 return;
3181
3182
3183 buffers = kmalloc (numBufs * sizeof(char *), GFP_KERNEL);
3184 if (!buffers) {
3185 out_of_memory:
3186 printk("DMA sound driver: Not enough buffer memory, driver disabled!\n");
3187 return;
3188 }
3189 for (i = 0; i < numBufs; i++) {
3190 buffers[i] = sound.mach.dma_alloc (bufSize << 10, GFP_KERNEL);
3191 if (!buffers[i]) {
3192 while (i--)
3193 sound.mach.dma_free (buffers[i], bufSize << 10);
3194 kfree (buffers);
3195 goto out_of_memory;
3196 }
3197 }
3198
3199
3200 register_chrdev(SOUND_MAJOR, "sound", &sound_fops);
3201
3202 sq_init(numBufs, bufSize << 10, buffers);
3203
3204
3205 state_init();
3206
3207
3208 mixer_init();
3209
3210 if (!sound.mach.irqinit()) {
3211 printk("DMA sound driver: Interrupt initialization failed\n");
3212 return;
3213 }
3214
3215 printk("DMA sound driver installed, using %d buffers of %dk.\n", numBufs,
3216 bufSize);
3217
3218 return;
3219 }
3220
3221 void sound_setup(char *str, int *ints)
3222 {
3223
3224 }
3225
3226 void dmasound_setup(char *str, int *ints)
3227 {
3228
3229
3230 switch (ints[0]) {
3231 case 3:
3232 if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
3233 printk("dmasound_setup: illegal catch radius, using default = %d\n", catchRadius);
3234 else
3235 catchRadius = ints[3];
3236
3237 case 2:
3238 if (ints[1] < MIN_BUFFERS)
3239 printk("dmasound_setup: illegal number of buffers, using default = %d\n", numBufs);
3240 else
3241 numBufs = ints[1];
3242 if (ints[2] < MIN_BUFSIZE || ints[2] > MAX_BUFSIZE)
3243 printk("dmasound_setup: illegal buffer size, using default = %d\n", bufSize);
3244 else
3245 bufSize = ints[2];
3246 break;
3247 case 0:
3248 break;
3249 default:
3250 printk("dmasound_setup: illegal number of arguments\n");
3251 }
3252 }