- pre2
[davej-history.git] / drivers / sound / dmasound / dmasound_core.c
blob21f54bdb1192aec070e6c405482e9702a916bca0
2 /*
3 * linux/drivers/sound/dmasound/dmasound_core.c
6 * OSS/Free compatible Atari TT/Falcon and Amiga DMA sound driver for
7 * Linux/m68k
8 * Extended to support Power Macintosh for Linux/ppc by Paul Mackerras
10 * (c) 1995 by Michael Schlueter & Michael Marte
12 * Michael Schlueter (michael@duck.syd.de) did the basic structure of the VFS
13 * interface and the u-law to signed byte conversion.
15 * Michael Marte (marte@informatik.uni-muenchen.de) did the sound queue,
16 * /dev/mixer, /dev/sndstat and complemented the VFS interface. He would like
17 * to thank:
18 * - Michael Schlueter for initial ideas and documentation on the MFP and
19 * the DMA sound hardware.
20 * - Therapy? for their CD 'Troublegum' which really made me rock.
22 * /dev/sndstat is based on code by Hannu Savolainen, the author of the
23 * VoxWare family of drivers.
25 * This file is subject to the terms and conditions of the GNU General Public
26 * License. See the file COPYING in the main directory of this archive
27 * for more details.
29 * History:
31 * 1995/8/25 First release
33 * 1995/9/02 Roman Hodek:
34 * - Fixed atari_stram_alloc() call, the timer
35 * programming and several race conditions
36 * 1995/9/14 Roman Hodek:
37 * - After some discussion with Michael Schlueter,
38 * revised the interrupt disabling
39 * - Slightly speeded up U8->S8 translation by using
40 * long operations where possible
41 * - Added 4:3 interpolation for /dev/audio
43 * 1995/9/20 Torsten Scherer:
44 * - Fixed a bug in sq_write and changed /dev/audio
45 * converting to play at 12517Hz instead of 6258Hz.
47 * 1995/9/23 Torsten Scherer:
48 * - Changed sq_interrupt() and sq_play() to pre-program
49 * the DMA for another frame while there's still one
50 * running. This allows the IRQ response to be
51 * arbitrarily delayed and playing will still continue.
53 * 1995/10/14 Guenther Kelleter, Torsten Scherer:
54 * - Better support for Falcon audio (the Falcon doesn't
55 * raise an IRQ at the end of a frame, but at the
56 * beginning instead!). uses 'if (codec_dma)' in lots
57 * of places to simply switch between Falcon and TT
58 * code.
60 * 1995/11/06 Torsten Scherer:
61 * - Started introducing a hardware abstraction scheme
62 * (may perhaps also serve for Amigas?)
63 * - Can now play samples at almost all frequencies by
64 * means of a more generalized expand routine
65 * - Takes a good deal of care to cut data only at
66 * sample sizes
67 * - Buffer size is now a kernel runtime option
68 * - Implemented fsync() & several minor improvements
69 * Guenther Kelleter:
70 * - Useful hints and bug fixes
71 * - Cross-checked it for Falcons
73 * 1996/3/9 Geert Uytterhoeven:
74 * - Support added for Amiga, A-law, 16-bit little
75 * endian.
76 * - Unification to drivers/sound/dmasound.c.
78 * 1996/4/6 Martin Mitchell:
79 * - Updated to 1.3 kernel.
81 * 1996/6/13 Topi Kanerva:
82 * - Fixed things that were broken (mainly the amiga
83 * 14-bit routines)
84 * - /dev/sndstat shows now the real hardware frequency
85 * - The lowpass filter is disabled by default now
87 * 1996/9/25 Geert Uytterhoeven:
88 * - Modularization
90 * 1998/6/10 Andreas Schwab:
91 * - Converted to use sound_core
93 * 1999/12/28 Richard Zidlicky:
94 * - Added support for Q40
96 * 2000/2/27 Geert Uytterhoeven:
97 * - Clean up and split the code into 4 parts:
98 * o dmasound_core: machine-independent code
99 * o dmasound_atari: Atari TT and Falcon support
100 * o dmasound_awacs: Apple PowerMac support
101 * o dmasound_paula: Amiga support
103 * 2000/3/25 Geert Uytterhoeven:
104 * - Integration of dmasound_q40
105 * - Small clean ups
109 #include <linux/module.h>
110 #include <linux/malloc.h>
111 #include <linux/sound.h>
112 #include <linux/init.h>
113 #include <linux/soundcard.h>
114 #include <linux/smp_lock.h>
116 #include <asm/uaccess.h>
118 #include "dmasound.h"
122 * Declarations
125 int dmasound_catchRadius = 0;
126 static unsigned int numWriteBufs = 4;
127 static unsigned int writeBufSize = 32; /* in KB! */
128 #ifdef HAS_RECORD
129 static unsigned int numReadBufs = 4;
130 static unsigned int readBufSize = 32; /* in KB! */
131 #endif
133 MODULE_PARM(dmasound_catchRadius, "i");
134 MODULE_PARM(numWriteBufs, "i");
135 MODULE_PARM(writeBufSize, "i");
136 MODULE_PARM(numReadBufs, "i");
137 MODULE_PARM(readBufSize, "i");
139 #ifdef MODULE
140 static int sq_unit = -1;
141 static int mixer_unit = -1;
142 static int state_unit = -1;
143 static int irq_installed = 0;
144 #endif /* MODULE */
148 * Conversion tables
151 #ifdef HAS_8BIT_TABLES
152 /* 8 bit mu-law */
154 char dmasound_ulaw2dma8[] = {
155 -126, -122, -118, -114, -110, -106, -102, -98,
156 -94, -90, -86, -82, -78, -74, -70, -66,
157 -63, -61, -59, -57, -55, -53, -51, -49,
158 -47, -45, -43, -41, -39, -37, -35, -33,
159 -31, -30, -29, -28, -27, -26, -25, -24,
160 -23, -22, -21, -20, -19, -18, -17, -16,
161 -16, -15, -15, -14, -14, -13, -13, -12,
162 -12, -11, -11, -10, -10, -9, -9, -8,
163 -8, -8, -7, -7, -7, -7, -6, -6,
164 -6, -6, -5, -5, -5, -5, -4, -4,
165 -4, -4, -4, -4, -3, -3, -3, -3,
166 -3, -3, -3, -3, -2, -2, -2, -2,
167 -2, -2, -2, -2, -2, -2, -2, -2,
168 -1, -1, -1, -1, -1, -1, -1, -1,
169 -1, -1, -1, -1, -1, -1, -1, -1,
170 -1, -1, -1, -1, -1, -1, -1, 0,
171 125, 121, 117, 113, 109, 105, 101, 97,
172 93, 89, 85, 81, 77, 73, 69, 65,
173 62, 60, 58, 56, 54, 52, 50, 48,
174 46, 44, 42, 40, 38, 36, 34, 32,
175 30, 29, 28, 27, 26, 25, 24, 23,
176 22, 21, 20, 19, 18, 17, 16, 15,
177 15, 14, 14, 13, 13, 12, 12, 11,
178 11, 10, 10, 9, 9, 8, 8, 7,
179 7, 7, 6, 6, 6, 6, 5, 5,
180 5, 5, 4, 4, 4, 4, 3, 3,
181 3, 3, 3, 3, 2, 2, 2, 2,
182 2, 2, 2, 2, 1, 1, 1, 1,
183 1, 1, 1, 1, 1, 1, 1, 1,
184 0, 0, 0, 0, 0, 0, 0, 0,
185 0, 0, 0, 0, 0, 0, 0, 0,
186 0, 0, 0, 0, 0, 0, 0, 0
189 /* 8 bit A-law */
191 char dmasound_alaw2dma8[] = {
192 -22, -21, -24, -23, -18, -17, -20, -19,
193 -30, -29, -32, -31, -26, -25, -28, -27,
194 -11, -11, -12, -12, -9, -9, -10, -10,
195 -15, -15, -16, -16, -13, -13, -14, -14,
196 -86, -82, -94, -90, -70, -66, -78, -74,
197 -118, -114, -126, -122, -102, -98, -110, -106,
198 -43, -41, -47, -45, -35, -33, -39, -37,
199 -59, -57, -63, -61, -51, -49, -55, -53,
200 -2, -2, -2, -2, -2, -2, -2, -2,
201 -2, -2, -2, -2, -2, -2, -2, -2,
202 -1, -1, -1, -1, -1, -1, -1, -1,
203 -1, -1, -1, -1, -1, -1, -1, -1,
204 -6, -6, -6, -6, -5, -5, -5, -5,
205 -8, -8, -8, -8, -7, -7, -7, -7,
206 -3, -3, -3, -3, -3, -3, -3, -3,
207 -4, -4, -4, -4, -4, -4, -4, -4,
208 21, 20, 23, 22, 17, 16, 19, 18,
209 29, 28, 31, 30, 25, 24, 27, 26,
210 10, 10, 11, 11, 8, 8, 9, 9,
211 14, 14, 15, 15, 12, 12, 13, 13,
212 86, 82, 94, 90, 70, 66, 78, 74,
213 118, 114, 126, 122, 102, 98, 110, 106,
214 43, 41, 47, 45, 35, 33, 39, 37,
215 59, 57, 63, 61, 51, 49, 55, 53,
216 1, 1, 1, 1, 1, 1, 1, 1,
217 1, 1, 1, 1, 1, 1, 1, 1,
218 0, 0, 0, 0, 0, 0, 0, 0,
219 0, 0, 0, 0, 0, 0, 0, 0,
220 5, 5, 5, 5, 4, 4, 4, 4,
221 7, 7, 7, 7, 6, 6, 6, 6,
222 2, 2, 2, 2, 2, 2, 2, 2,
223 3, 3, 3, 3, 3, 3, 3, 3
225 #endif /* HAS_8BIT_TABLES */
227 #ifdef HAS_16BIT_TABLES
229 /* 16 bit mu-law */
231 short dmasound_ulaw2dma16[] = {
232 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
233 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
234 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
235 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
236 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
237 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
238 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
239 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
240 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
241 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
242 -876, -844, -812, -780, -748, -716, -684, -652,
243 -620, -588, -556, -524, -492, -460, -428, -396,
244 -372, -356, -340, -324, -308, -292, -276, -260,
245 -244, -228, -212, -196, -180, -164, -148, -132,
246 -120, -112, -104, -96, -88, -80, -72, -64,
247 -56, -48, -40, -32, -24, -16, -8, 0,
248 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
249 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
250 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
251 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
252 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
253 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
254 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
255 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
256 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
257 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
258 876, 844, 812, 780, 748, 716, 684, 652,
259 620, 588, 556, 524, 492, 460, 428, 396,
260 372, 356, 340, 324, 308, 292, 276, 260,
261 244, 228, 212, 196, 180, 164, 148, 132,
262 120, 112, 104, 96, 88, 80, 72, 64,
263 56, 48, 40, 32, 24, 16, 8, 0,
266 /* 16 bit A-law */
268 short dmasound_alaw2dma16[] = {
269 -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
270 -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
271 -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
272 -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
273 -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
274 -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
275 -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
276 -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
277 -344, -328, -376, -360, -280, -264, -312, -296,
278 -472, -456, -504, -488, -408, -392, -440, -424,
279 -88, -72, -120, -104, -24, -8, -56, -40,
280 -216, -200, -248, -232, -152, -136, -184, -168,
281 -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
282 -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
283 -688, -656, -752, -720, -560, -528, -624, -592,
284 -944, -912, -1008, -976, -816, -784, -880, -848,
285 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
286 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
287 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
288 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
289 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
290 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
291 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
292 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
293 344, 328, 376, 360, 280, 264, 312, 296,
294 472, 456, 504, 488, 408, 392, 440, 424,
295 88, 72, 120, 104, 24, 8, 56, 40,
296 216, 200, 248, 232, 152, 136, 184, 168,
297 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
298 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
299 688, 656, 752, 720, 560, 528, 624, 592,
300 944, 912, 1008, 976, 816, 784, 880, 848,
302 #endif /* HAS_16BIT_TABLES */
305 #ifdef HAS_14BIT_TABLES
308 * Unused for now. Where are the MSB parts anyway??
311 /* 14 bit mu-law (LSB) */
313 char dmasound_ulaw2dma14l[] = {
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 33, 33, 33, 33, 33, 33, 33, 33,
318 1, 1, 1, 1, 1, 1, 1, 1,
319 1, 1, 1, 1, 1, 1, 1, 1,
320 49, 17, 49, 17, 49, 17, 49, 17,
321 49, 17, 49, 17, 49, 17, 49, 17,
322 41, 57, 9, 25, 41, 57, 9, 25,
323 41, 57, 9, 25, 41, 57, 9, 25,
324 37, 45, 53, 61, 5, 13, 21, 29,
325 37, 45, 53, 61, 5, 13, 21, 29,
326 35, 39, 43, 47, 51, 55, 59, 63,
327 3, 7, 11, 15, 19, 23, 27, 31,
328 34, 36, 38, 40, 42, 44, 46, 48,
329 50, 52, 54, 56, 58, 60, 62, 0,
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 31, 31, 31, 31, 31, 31, 31, 31,
334 63, 63, 63, 63, 63, 63, 63, 63,
335 63, 63, 63, 63, 63, 63, 63, 63,
336 15, 47, 15, 47, 15, 47, 15, 47,
337 15, 47, 15, 47, 15, 47, 15, 47,
338 23, 7, 55, 39, 23, 7, 55, 39,
339 23, 7, 55, 39, 23, 7, 55, 39,
340 27, 19, 11, 3, 59, 51, 43, 35,
341 27, 19, 11, 3, 59, 51, 43, 35,
342 29, 25, 21, 17, 13, 9, 5, 1,
343 61, 57, 53, 49, 45, 41, 37, 33,
344 30, 28, 26, 24, 22, 20, 18, 16,
345 14, 12, 10, 8, 6, 4, 2, 0
348 /* 14 bit A-law (LSB) */
350 char dmasound_alaw2dma14l[] = {
351 32, 32, 32, 32, 32, 32, 32, 32,
352 32, 32, 32, 32, 32, 32, 32, 32,
353 16, 48, 16, 48, 16, 48, 16, 48,
354 16, 48, 16, 48, 16, 48, 16, 48,
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 0, 0, 0, 0, 0, 0, 0, 0,
359 42, 46, 34, 38, 58, 62, 50, 54,
360 10, 14, 2, 6, 26, 30, 18, 22,
361 42, 46, 34, 38, 58, 62, 50, 54,
362 10, 14, 2, 6, 26, 30, 18, 22,
363 40, 56, 8, 24, 40, 56, 8, 24,
364 40, 56, 8, 24, 40, 56, 8, 24,
365 20, 28, 4, 12, 52, 60, 36, 44,
366 20, 28, 4, 12, 52, 60, 36, 44,
367 32, 32, 32, 32, 32, 32, 32, 32,
368 32, 32, 32, 32, 32, 32, 32, 32,
369 48, 16, 48, 16, 48, 16, 48, 16,
370 48, 16, 48, 16, 48, 16, 48, 16,
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 0, 0, 0, 0, 0, 0, 0, 0,
375 22, 18, 30, 26, 6, 2, 14, 10,
376 54, 50, 62, 58, 38, 34, 46, 42,
377 22, 18, 30, 26, 6, 2, 14, 10,
378 54, 50, 62, 58, 38, 34, 46, 42,
379 24, 8, 56, 40, 24, 8, 56, 40,
380 24, 8, 56, 40, 24, 8, 56, 40,
381 44, 36, 60, 52, 12, 4, 28, 20,
382 44, 36, 60, 52, 12, 4, 28, 20
384 #endif /* HAS_14BIT_TABLES */
388 * Common stuff
391 static long long sound_lseek(struct file *file, long long offset, int orig)
393 return -ESPIPE;
398 * Mid level stuff
401 struct sound_settings dmasound;
403 static inline void sound_silence(void)
405 /* update hardware settings one more */
406 dmasound.mach.init();
408 dmasound.mach.silence();
411 static inline void sound_init(void)
413 dmasound.mach.init();
416 static inline int sound_set_format(int format)
418 return dmasound.mach.setFormat(format);
421 static int sound_set_speed(int speed)
423 if (speed < 0)
424 return dmasound.soft.speed;
426 dmasound.soft.speed = speed;
427 dmasound.mach.init();
428 if (dmasound.minDev == SND_DEV_DSP)
429 dmasound.dsp.speed = dmasound.soft.speed;
431 return dmasound.soft.speed;
434 static int sound_set_stereo(int stereo)
436 if (stereo < 0)
437 return dmasound.soft.stereo;
439 stereo = !!stereo; /* should be 0 or 1 now */
441 dmasound.soft.stereo = stereo;
442 if (dmasound.minDev == SND_DEV_DSP)
443 dmasound.dsp.stereo = stereo;
444 dmasound.mach.init();
446 return stereo;
449 static ssize_t sound_copy_translate(TRANS *trans, const u_char *userPtr,
450 size_t userCount, u_char frame[],
451 ssize_t *frameUsed, ssize_t frameLeft)
453 ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
455 switch (dmasound.soft.format) {
456 case AFMT_MU_LAW:
457 ct_func = trans->ct_ulaw;
458 break;
459 case AFMT_A_LAW:
460 ct_func = trans->ct_alaw;
461 break;
462 case AFMT_S8:
463 ct_func = trans->ct_s8;
464 break;
465 case AFMT_U8:
466 ct_func = trans->ct_u8;
467 break;
468 case AFMT_S16_BE:
469 ct_func = trans->ct_s16be;
470 break;
471 case AFMT_U16_BE:
472 ct_func = trans->ct_u16be;
473 break;
474 case AFMT_S16_LE:
475 ct_func = trans->ct_s16le;
476 break;
477 case AFMT_U16_LE:
478 ct_func = trans->ct_u16le;
479 break;
480 default:
481 return 0;
483 return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
488 * /dev/mixer abstraction
491 static struct {
492 int busy;
493 int modify_counter;
494 } mixer;
496 static int mixer_open(struct inode *inode, struct file *file)
498 dmasound.mach.open();
499 mixer.busy = 1;
500 return 0;
503 static int mixer_release(struct inode *inode, struct file *file)
505 lock_kernel();
506 mixer.busy = 0;
507 dmasound.mach.release();
508 unlock_kernel();
509 return 0;
511 static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
512 u_long arg)
514 if (_SIOC_DIR(cmd) & _SIOC_WRITE)
515 mixer.modify_counter++;
516 switch (cmd) {
517 case OSS_GETVERSION:
518 return IOCTL_OUT(arg, SOUND_VERSION);
519 case SOUND_MIXER_INFO:
521 mixer_info info;
522 strncpy(info.id, dmasound.mach.name2, sizeof(info.id));
523 strncpy(info.name, dmasound.mach.name2, sizeof(info.name));
524 info.name[sizeof(info.name)-1] = 0;
525 info.modify_counter = mixer.modify_counter;
526 if (copy_to_user((int *)arg, &info, sizeof(info)))
527 return -EFAULT;
528 return 0;
531 if (dmasound.mach.mixer_ioctl)
532 return dmasound.mach.mixer_ioctl(cmd, arg);
533 return -EINVAL;
536 static struct file_operations mixer_fops =
538 owner: THIS_MODULE,
539 llseek: sound_lseek,
540 ioctl: mixer_ioctl,
541 open: mixer_open,
542 release: mixer_release,
545 static void __init mixer_init(void)
547 #ifndef MODULE
548 int mixer_unit;
549 #endif
550 mixer_unit = register_sound_mixer(&mixer_fops, -1);
551 if (mixer_unit < 0)
552 return;
554 mixer.busy = 0;
555 dmasound.treble = 0;
556 dmasound.bass = 0;
557 if (dmasound.mach.mixer_init)
558 dmasound.mach.mixer_init();
563 * Sound queue stuff, the heart of the driver
566 struct sound_queue dmasound_write_sq;
567 #ifdef HAS_RECORD
568 struct sound_queue dmasound_read_sq;
569 #endif
571 static int sq_allocate_buffers(struct sound_queue *sq, int num, int size)
573 int i;
575 if (sq->buffers)
576 return 0;
577 sq->numBufs = num;
578 sq->bufSize = size;
579 sq->buffers = kmalloc (num * sizeof(char *), GFP_KERNEL);
580 if (!sq->buffers)
581 return -ENOMEM;
582 for (i = 0; i < num; i++) {
583 sq->buffers[i] = dmasound.mach.dma_alloc(size, GFP_KERNEL);
584 if (!sq->buffers[i]) {
585 while (i--)
586 dmasound.mach.dma_free(sq->buffers[i], size);
587 kfree(sq->buffers);
588 sq->buffers = 0;
589 return -ENOMEM;
592 return 0;
595 static void sq_release_buffers(struct sound_queue *sq)
597 int i;
599 if (sq->buffers) {
600 if (sq != &write_sq && dmasound.mach.abort_read)
601 dmasound.mach.abort_read();
602 for (i = 0; i < sq->numBufs; i++)
603 dmasound.mach.dma_free(sq->buffers[i], sq->bufSize);
604 kfree(sq->buffers);
605 sq->buffers = NULL;
609 static void sq_setup(struct sound_queue *sq, int max_count, int max_active,
610 int block_size)
612 void (*setup_func)(void);
614 sq->max_count = max_count;
615 sq->max_active = max_active;
616 sq->block_size = block_size;
618 sq->front = sq->count = sq->rear_size = 0;
619 sq->syncing = 0;
620 sq->active = 0;
622 if (sq == &write_sq) {
623 sq->rear = -1;
624 setup_func = dmasound.mach.write_sq_setup;
625 } else {
626 sq->rear = 0;
627 setup_func = dmasound.mach.read_sq_setup;
629 if (setup_func)
630 setup_func();
633 static inline void sq_play(void)
635 dmasound.mach.play();
638 static ssize_t sq_write(struct file *file, const char *src, size_t uLeft,
639 loff_t *ppos)
641 ssize_t uWritten = 0;
642 u_char *dest;
643 ssize_t uUsed, bUsed, bLeft;
645 /* ++TeSche: Is something like this necessary?
646 * Hey, that's an honest question! Or does any other part of the
647 * filesystem already checks this situation? I really don't know.
649 if (uLeft == 0)
650 return 0;
652 /* The interrupt doesn't start to play the last, incomplete frame.
653 * Thus we can append to it without disabling the interrupts! (Note
654 * also that write_sq.rear isn't affected by the interrupt.)
657 if (write_sq.count > 0 &&
658 (bLeft = write_sq.block_size-write_sq.rear_size) > 0) {
659 dest = write_sq.buffers[write_sq.rear];
660 bUsed = write_sq.rear_size;
661 uUsed = sound_copy_translate(dmasound.trans_write, src, uLeft,
662 dest, &bUsed, bLeft);
663 if (uUsed <= 0)
664 return uUsed;
665 src += uUsed;
666 uWritten += uUsed;
667 uLeft -= uUsed;
668 write_sq.rear_size = bUsed;
671 do {
672 while (write_sq.count == write_sq.max_active) {
673 sq_play();
674 if (write_sq.open_mode & O_NONBLOCK)
675 return uWritten > 0 ? uWritten : -EAGAIN;
676 SLEEP(write_sq.action_queue);
677 if (signal_pending(current))
678 return uWritten > 0 ? uWritten : -EINTR;
681 /* Here, we can avoid disabling the interrupt by first
682 * copying and translating the data, and then updating
683 * the write_sq variables. Until this is done, the interrupt
684 * won't see the new frame and we can work on it
685 * undisturbed.
688 dest = write_sq.buffers[(write_sq.rear+1) % write_sq.max_count];
689 bUsed = 0;
690 bLeft = write_sq.block_size;
691 uUsed = sound_copy_translate(dmasound.trans_write, src, uLeft,
692 dest, &bUsed, bLeft);
693 if (uUsed <= 0)
694 break;
695 src += uUsed;
696 uWritten += uUsed;
697 uLeft -= uUsed;
698 if (bUsed) {
699 write_sq.rear = (write_sq.rear+1) % write_sq.max_count;
700 write_sq.rear_size = bUsed;
701 write_sq.count++;
703 } while (bUsed); /* uUsed may have been 0 */
705 sq_play();
707 return uUsed < 0? uUsed: uWritten;
710 #ifdef HAS_RECORD
712 * Here is how the values are used for reading.
713 * The value 'active' simply indicates the DMA is running. This is done
714 * so the driver semantics are DMA starts when the first read is posted.
715 * The value 'front' indicates the buffer we should next send to the user.
716 * The value 'rear' indicates the buffer the DMA is currently filling.
717 * When 'front' == 'rear' the buffer "ring" is empty (we always have an
718 * empty available). The 'rear_size' is used to track partial offsets
719 * into the current buffer. Right now, I just keep the DMA running. If
720 * the reader can't keep up, the interrupt tosses the oldest buffer. We
721 * could also shut down the DMA in this case.
724 static ssize_t sq_read(struct file *file, char *dst, size_t uLeft,
725 loff_t *ppos)
728 ssize_t uRead, bLeft, bUsed, uUsed;
730 if (uLeft == 0)
731 return 0;
733 if (!read_sq.active && dmasound.mach.record)
734 dmasound.mach.record(); /* Kick off the record process. */
736 uRead = 0;
738 /* Move what the user requests, depending upon other options.
740 while (uLeft > 0) {
742 /* When front == rear, the DMA is not done yet.
744 while (read_sq.front == read_sq.rear) {
745 if (read_sq.open_mode & O_NONBLOCK) {
746 return uRead > 0 ? uRead : -EAGAIN;
748 SLEEP(read_sq.action_queue);
749 if (signal_pending(current))
750 return uRead > 0 ? uRead : -EINTR;
753 /* The amount we move is either what is left in the
754 * current buffer or what the user wants.
756 bLeft = read_sq.block_size - read_sq.rear_size;
757 bUsed = read_sq.rear_size;
758 uUsed = sound_copy_translate(dmasound.trans_read, dst, uLeft,
759 read_sq.buffers[read_sq.front],
760 &bUsed, bLeft);
761 if (uUsed <= 0)
762 return uUsed;
763 dst += uUsed;
764 uRead += uUsed;
765 uLeft -= uUsed;
766 read_sq.rear_size += bUsed;
767 if (read_sq.rear_size >= read_sq.block_size) {
768 read_sq.rear_size = 0;
769 read_sq.front++;
770 if (read_sq.front >= read_sq.max_active)
771 read_sq.front = 0;
774 return uRead;
776 #endif /* HAS_RECORD */
778 static inline void sq_init_waitqueue(struct sound_queue *sq)
780 init_waitqueue_head(&sq->action_queue);
781 init_waitqueue_head(&sq->open_queue);
782 init_waitqueue_head(&sq->sync_queue);
783 sq->busy = 0;
786 static inline void sq_wake_up(struct sound_queue *sq, struct file *file,
787 mode_t mode)
789 if (file->f_mode & mode) {
790 sq->busy = 0;
791 WAKE_UP(sq->open_queue);
795 static int sq_open2(struct sound_queue *sq, struct file *file, mode_t mode,
796 int numbufs, int bufsize)
798 int rc = 0;
800 if (file->f_mode & mode) {
801 if (sq->busy) {
802 rc = -EBUSY;
803 if (file->f_flags & O_NONBLOCK)
804 return rc;
805 rc = -EINTR;
806 while (sq->busy) {
807 SLEEP(sq->open_queue);
808 if (signal_pending(current))
809 return rc;
811 rc = 0;
813 sq->busy = 1; /* Let's play spot-the-race-condition */
815 if (sq_allocate_buffers(sq, numbufs, bufsize)) {
816 sq_wake_up(sq, file, mode);
817 return rc;
820 sq_setup(sq, numbufs, numbufs, bufsize);
821 sq->open_mode = file->f_mode;
823 return rc;
826 #define write_sq_init_waitqueue() sq_init_waitqueue(&write_sq)
827 #define write_sq_wake_up(file) sq_wake_up(&write_sq, file, FMODE_WRITE)
828 #define write_sq_release_buffers() sq_release_buffers(&write_sq)
829 #define write_sq_open(file) \
830 sq_open2(&write_sq, file, FMODE_WRITE, numWriteBufs, writeBufSize << 10)
832 #ifdef HAS_RECORD
833 #define read_sq_init_waitqueue() sq_init_waitqueue(&read_sq)
834 #define read_sq_wake_up(file) sq_wake_up(&read_sq, file, FMODE_READ)
835 #define read_sq_release_buffers() sq_release_buffers(&read_sq)
836 #define read_sq_open(file) \
837 sq_open2(&read_sq, file, FMODE_READ, numReadBufs, readBufSize << 10)
838 #else /* !HAS_RECORD */
839 #define read_sq_init_waitqueue() do {} while (0)
840 #define read_sq_wake_up(file) do {} while (0)
841 #define read_sq_release_buffers() do {} while (0)
842 #define read_sq_open(file) (0)
843 #endif /* !HAS_RECORD */
845 static int sq_open(struct inode *inode, struct file *file)
847 int rc;
849 dmasound.mach.open();
850 if ((rc = write_sq_open(file)) || (rc = read_sq_open(file))) {
851 dmasound.mach.release();
852 return rc;
855 if (dmasound.mach.sq_open)
856 dmasound.mach.sq_open();
857 dmasound.minDev = MINOR(inode->i_rdev) & 0x0f;
858 dmasound.soft = dmasound.dsp;
859 dmasound.hard = dmasound.dsp;
860 sound_init();
861 if ((MINOR(inode->i_rdev) & 0x0f) == SND_DEV_AUDIO) {
862 sound_set_speed(8000);
863 sound_set_stereo(0);
864 sound_set_format(AFMT_MU_LAW);
867 #if 0
868 if (file->f_mode == FMODE_READ && dmasound.mach.record) {
869 /* Start dma'ing straight away */
870 dmasound.mach.record();
872 #endif
874 return 0;
877 static void sq_reset(void)
879 sound_silence();
880 write_sq.active = 0;
881 write_sq.count = 0;
882 write_sq.front = (write_sq.rear+1) % write_sq.max_count;
885 static int sq_fsync(struct file *filp, struct dentry *dentry)
887 int rc = 0;
889 write_sq.syncing = 1;
890 sq_play(); /* there may be an incomplete frame waiting */
892 while (write_sq.active) {
893 SLEEP(write_sq.sync_queue);
894 if (signal_pending(current)) {
895 /* While waiting for audio output to drain, an
896 * interrupt occurred. Stop audio output immediately
897 * and clear the queue. */
898 sq_reset();
899 rc = -EINTR;
900 break;
904 write_sq.syncing = 0;
905 return rc;
908 static int sq_release(struct inode *inode, struct file *file)
910 int rc = 0;
912 lock_kernel();
913 if (write_sq.busy)
914 rc = sq_fsync(file, file->f_dentry);
915 dmasound.soft = dmasound.dsp;
916 dmasound.hard = dmasound.dsp;
917 sound_silence();
919 write_sq_release_buffers();
920 read_sq_release_buffers();
921 dmasound.mach.release();
923 /* There is probably a DOS atack here. They change the mode flag. */
924 /* XXX add check here */
925 read_sq_wake_up(file);
926 write_sq_wake_up(file);
928 /* Wake up a process waiting for the queue being released.
929 * Note: There may be several processes waiting for a call
930 * to open() returning. */
931 unlock_kernel();
933 return rc;
936 static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
937 u_long arg)
939 u_long fmt;
940 int data;
941 int size, nbufs;
942 audio_buf_info info;
944 switch (cmd) {
945 case SNDCTL_DSP_RESET:
946 sq_reset();
947 return 0;
948 case SNDCTL_DSP_POST:
949 case SNDCTL_DSP_SYNC:
950 return sq_fsync(file, file->f_dentry);
952 /* ++TeSche: before changing any of these it's
953 * probably wise to wait until sound playing has
954 * settled down. */
955 case SNDCTL_DSP_SPEED:
956 sq_fsync(file, file->f_dentry);
957 IOCTL_IN(arg, data);
958 return IOCTL_OUT(arg, sound_set_speed(data));
959 case SNDCTL_DSP_STEREO:
960 sq_fsync(file, file->f_dentry);
961 IOCTL_IN(arg, data);
962 return IOCTL_OUT(arg, sound_set_stereo(data));
963 case SOUND_PCM_WRITE_CHANNELS:
964 sq_fsync(file, file->f_dentry);
965 IOCTL_IN(arg, data);
966 return IOCTL_OUT(arg, sound_set_stereo(data-1)+1);
967 case SNDCTL_DSP_SETFMT:
968 sq_fsync(file, file->f_dentry);
969 IOCTL_IN(arg, data);
970 return IOCTL_OUT(arg, sound_set_format(data));
971 case SNDCTL_DSP_GETFMTS:
972 fmt = 0;
973 if (dmasound.trans_write) {
974 if (dmasound.trans_write->ct_ulaw)
975 fmt |= AFMT_MU_LAW;
976 if (dmasound.trans_write->ct_alaw)
977 fmt |= AFMT_A_LAW;
978 if (dmasound.trans_write->ct_s8)
979 fmt |= AFMT_S8;
980 if (dmasound.trans_write->ct_u8)
981 fmt |= AFMT_U8;
982 if (dmasound.trans_write->ct_s16be)
983 fmt |= AFMT_S16_BE;
984 if (dmasound.trans_write->ct_u16be)
985 fmt |= AFMT_U16_BE;
986 if (dmasound.trans_write->ct_s16le)
987 fmt |= AFMT_S16_LE;
988 if (dmasound.trans_write->ct_u16le)
989 fmt |= AFMT_U16_LE;
991 return IOCTL_OUT(arg, fmt);
992 case SNDCTL_DSP_GETBLKSIZE:
993 size = write_sq.block_size
994 * dmasound.soft.size * (dmasound.soft.stereo + 1)
995 / (dmasound.hard.size * (dmasound.hard.stereo + 1));
996 return IOCTL_OUT(arg, size);
997 case SNDCTL_DSP_SUBDIVIDE:
998 break;
999 case SNDCTL_DSP_SETFRAGMENT:
1000 if (write_sq.count || write_sq.active || write_sq.syncing)
1001 return -EINVAL;
1002 IOCTL_IN(arg, size);
1003 nbufs = size >> 16;
1004 if (nbufs < 2 || nbufs > write_sq.numBufs)
1005 nbufs = write_sq.numBufs;
1006 size &= 0xffff;
1007 if (size >= 8 && size <= 29) {
1008 size = 1 << size;
1009 size *= dmasound.hard.size * (dmasound.hard.stereo + 1);
1010 size /= dmasound.soft.size * (dmasound.soft.stereo + 1);
1011 if (size > write_sq.bufSize)
1012 size = write_sq.bufSize;
1013 } else
1014 size = write_sq.bufSize;
1015 sq_setup(&write_sq, write_sq.numBufs, nbufs, size);
1016 return 0;
1017 case SNDCTL_DSP_GETOSPACE:
1018 info.fragments = write_sq.max_active - write_sq.count;
1019 info.fragstotal = write_sq.max_active;
1020 info.fragsize = write_sq.block_size;
1021 info.bytes = info.fragments * info.fragsize;
1022 if (copy_to_user((void *)arg, &info, sizeof(info)))
1023 return -EFAULT;
1024 return 0;
1026 default:
1027 return mixer_ioctl(inode, file, cmd, arg);
1029 return -EINVAL;
1032 static struct file_operations sq_fops =
1034 owner: THIS_MODULE,
1035 llseek: sound_lseek,
1036 write: sq_write,
1037 ioctl: sq_ioctl,
1038 open: sq_open,
1039 release: sq_release,
1040 #ifdef HAS_RECORD
1041 read: sq_read,
1042 #endif
1045 static void __init sq_init(void)
1047 #ifndef MODULE
1048 int sq_unit;
1049 #endif
1050 sq_unit = register_sound_dsp(&sq_fops, -1);
1051 if (sq_unit < 0)
1052 return;
1054 write_sq_init_waitqueue();
1055 read_sq_init_waitqueue();
1057 /* whatever you like as startup mode for /dev/dsp,
1058 * (/dev/audio hasn't got a startup mode). note that
1059 * once changed a new open() will *not* restore these!
1061 dmasound.dsp.format = AFMT_U8;
1062 dmasound.dsp.stereo = 0;
1063 dmasound.dsp.size = 8;
1065 /* set minimum rate possible without expanding */
1066 dmasound.dsp.speed = dmasound.mach.min_dsp_speed;
1068 /* before the first open to /dev/dsp this wouldn't be set */
1069 dmasound.soft = dmasound.dsp;
1070 dmasound.hard = dmasound.dsp;
1072 sound_silence();
1077 * /dev/sndstat
1080 static struct {
1081 int busy;
1082 char buf[512]; /* state.buf should not overflow! */
1083 int len, ptr;
1084 } state;
1086 static int state_open(struct inode *inode, struct file *file)
1088 char *buffer = state.buf;
1089 int len = 0;
1091 if (state.busy)
1092 return -EBUSY;
1094 dmasound.mach.open();
1095 state.ptr = 0;
1096 state.busy = 1;
1098 len += sprintf(buffer+len, "%sDMA sound driver:\n", dmasound.mach.name);
1100 len += sprintf(buffer+len, "\tsound.format = 0x%x",
1101 dmasound.soft.format);
1102 switch (dmasound.soft.format) {
1103 case AFMT_MU_LAW:
1104 len += sprintf(buffer+len, " (mu-law)");
1105 break;
1106 case AFMT_A_LAW:
1107 len += sprintf(buffer+len, " (A-law)");
1108 break;
1109 case AFMT_U8:
1110 len += sprintf(buffer+len, " (unsigned 8 bit)");
1111 break;
1112 case AFMT_S8:
1113 len += sprintf(buffer+len, " (signed 8 bit)");
1114 break;
1115 case AFMT_S16_BE:
1116 len += sprintf(buffer+len, " (signed 16 bit big)");
1117 break;
1118 case AFMT_U16_BE:
1119 len += sprintf(buffer+len, " (unsigned 16 bit big)");
1120 break;
1121 case AFMT_S16_LE:
1122 len += sprintf(buffer+len, " (signed 16 bit little)");
1123 break;
1124 case AFMT_U16_LE:
1125 len += sprintf(buffer+len, " (unsigned 16 bit little)");
1126 break;
1128 len += sprintf(buffer+len, "\n");
1129 len += sprintf(buffer+len, "\tsound.speed = %dHz (phys. %dHz)\n",
1130 dmasound.soft.speed, dmasound.hard.speed);
1131 len += sprintf(buffer+len, "\tsound.stereo = 0x%x (%s)\n",
1132 dmasound.soft.stereo,
1133 dmasound.soft.stereo ? "stereo" : "mono");
1134 if (dmasound.mach.state_info)
1135 len += dmasound.mach.state_info(buffer);
1136 len += sprintf(buffer+len, "\tsq.block_size = %d sq.max_count = %d"
1137 " sq.max_active = %d\n",
1138 write_sq.block_size, write_sq.max_count,
1139 write_sq.max_active);
1140 len += sprintf(buffer+len, "\tsq.count = %d sq.rear_size = %d\n",
1141 write_sq.count, write_sq.rear_size);
1142 len += sprintf(buffer+len, "\tsq.active = %d sq.syncing = %d\n",
1143 write_sq.active, write_sq.syncing);
1144 state.len = len;
1145 return 0;
1148 static int state_release(struct inode *inode, struct file *file)
1150 lock_kernel();
1151 state.busy = 0;
1152 dmasound.mach.release();
1153 unlock_kernel();
1154 return 0;
1157 static ssize_t state_read(struct file *file, char *buf, size_t count,
1158 loff_t *ppos)
1160 int n = state.len - state.ptr;
1161 if (n > count)
1162 n = count;
1163 if (n <= 0)
1164 return 0;
1165 if (copy_to_user(buf, &state.buf[state.ptr], n))
1166 return -EFAULT;
1167 state.ptr += n;
1168 return n;
1171 static struct file_operations state_fops = {
1172 owner: THIS_MODULE,
1173 llseek: sound_lseek,
1174 read: state_read,
1175 open: state_open,
1176 release: state_release,
1179 static void __init state_init(void)
1181 #ifndef MODULE
1182 int state_unit;
1183 #endif
1184 state_unit = register_sound_special(&state_fops, SND_DEV_STATUS);
1185 if (state_unit < 0)
1186 return;
1187 state.busy = 0;
1192 * Config & Setup
1194 * This function is called by _one_ chipset-specific driver
1197 int __init dmasound_init(void)
1199 #ifdef MODULE
1200 if (irq_installed)
1201 return -EBUSY;
1202 #endif
1204 /* Set up sound queue, /dev/audio and /dev/dsp. */
1206 /* Set default settings. */
1207 sq_init();
1209 /* Set up /dev/sndstat. */
1210 state_init();
1212 /* Set up /dev/mixer. */
1213 mixer_init();
1215 if (!dmasound.mach.irqinit()) {
1216 printk(KERN_ERR "DMA sound driver: Interrupt initialization failed\n");
1217 return -ENODEV;
1219 #ifdef MODULE
1220 irq_installed = 1;
1221 #endif
1223 printk(KERN_INFO "DMA sound driver installed, using %d buffers of %dk.\n",
1224 numWriteBufs, writeBufSize);
1226 return 0;
1229 #ifdef MODULE
1231 void dmasound_deinit(void)
1233 if (irq_installed) {
1234 sound_silence();
1235 dmasound.mach.irqcleanup();
1238 write_sq_release_buffers();
1239 read_sq_release_buffers();
1241 if (mixer_unit >= 0)
1242 unregister_sound_mixer(mixer_unit);
1243 if (state_unit >= 0)
1244 unregister_sound_special(state_unit);
1245 if (sq_unit >= 0)
1246 unregister_sound_dsp(sq_unit);
1249 #else /* !MODULE */
1251 static int __init dmasound_setup(char *str)
1253 int ints[6];
1255 str = get_options(str, ARRAY_SIZE(ints), ints);
1257 /* check the bootstrap parameter for "dmasound=" */
1259 switch (ints[0]) {
1260 case 3:
1261 if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
1262 printk("dmasound_setup: illegal catch radius, using default = %d\n", catchRadius);
1263 else
1264 catchRadius = ints[3];
1265 /* fall through */
1266 case 2:
1267 if (ints[1] < MIN_BUFFERS)
1268 printk("dmasound_setup: illegal number of buffers, using default = %d\n", numWriteBufs);
1269 else
1270 numWriteBufs = ints[1];
1271 if (ints[2] < MIN_BUFSIZE || ints[2] > MAX_BUFSIZE)
1272 printk("dmasound_setup: illegal buffer size, using default = %dK\n", writeBufSize);
1273 else
1274 writeBufSize = ints[2];
1275 break;
1276 case 0:
1277 break;
1278 default:
1279 printk("dmasound_setup: illegal number of arguments\n");
1280 return 0;
1282 return 1;
1285 __setup("dmasound=", dmasound_setup);
1287 #endif /* !MODULE */
1291 * Visible symbols for modules
1294 EXPORT_SYMBOL(dmasound);
1295 EXPORT_SYMBOL(dmasound_init);
1296 #ifdef MODULE
1297 EXPORT_SYMBOL(dmasound_deinit);
1298 #endif
1299 EXPORT_SYMBOL(dmasound_write_sq);
1300 #ifdef HAS_RECORD
1301 EXPORT_SYMBOL(dmasound_read_sq);
1302 #endif
1303 EXPORT_SYMBOL(dmasound_catchRadius);
1304 #ifdef HAS_8BIT_TABLES
1305 EXPORT_SYMBOL(dmasound_ulaw2dma8);
1306 EXPORT_SYMBOL(dmasound_alaw2dma8);
1307 #endif
1308 #ifdef HAS_16BIT_TABLES
1309 EXPORT_SYMBOL(dmasound_ulaw2dma16);
1310 EXPORT_SYMBOL(dmasound_alaw2dma16);
1311 #endif
1312 #ifdef HAS_14BIT_TABLES
1313 EXPORT_SYMBOL(dmasound_ulaw2dma14l);
1314 EXPORT_SYMBOL(dmasound_ulaw2dma14h);
1315 EXPORT_SYMBOL(dmasound_alaw2dma14l);
1316 EXPORT_SYMBOL(dmasound_alaw2dma14h);
1317 #endif