3 * linux/drivers/sound/dmasound/dmasound_core.c
6 * OSS/Free compatible Atari TT/Falcon and Amiga DMA sound driver for
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
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
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
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
67 * - Buffer size is now a kernel runtime option
68 * - Implemented fsync() & several minor improvements
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
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
84 * - /dev/sndstat shows now the real hardware frequency
85 * - The lowpass filter is disabled by default now
87 * 1996/9/25 Geert Uytterhoeven:
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
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"
125 int dmasound_catchRadius
= 0;
126 static unsigned int numWriteBufs
= 4;
127 static unsigned int writeBufSize
= 32; /* in KB! */
129 static unsigned int numReadBufs
= 4;
130 static unsigned int readBufSize
= 32; /* in KB! */
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");
140 static int sq_unit
= -1;
141 static int mixer_unit
= -1;
142 static int state_unit
= -1;
143 static int irq_installed
= 0;
151 #ifdef HAS_8BIT_TABLES
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
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
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,
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 */
391 static long long sound_lseek(struct file
*file
, long long offset
, int orig
)
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
)
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
)
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();
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
) {
457 ct_func
= trans
->ct_ulaw
;
460 ct_func
= trans
->ct_alaw
;
463 ct_func
= trans
->ct_s8
;
466 ct_func
= trans
->ct_u8
;
469 ct_func
= trans
->ct_s16be
;
472 ct_func
= trans
->ct_u16be
;
475 ct_func
= trans
->ct_s16le
;
478 ct_func
= trans
->ct_u16le
;
483 return ct_func(userPtr
, userCount
, frame
, frameUsed
, frameLeft
);
488 * /dev/mixer abstraction
496 static int mixer_open(struct inode
*inode
, struct file
*file
)
498 dmasound
.mach
.open();
503 static int mixer_release(struct inode
*inode
, struct file
*file
)
507 dmasound
.mach
.release();
511 static int mixer_ioctl(struct inode
*inode
, struct file
*file
, u_int cmd
,
514 if (_SIOC_DIR(cmd
) & _SIOC_WRITE
)
515 mixer
.modify_counter
++;
518 return IOCTL_OUT(arg
, SOUND_VERSION
);
519 case SOUND_MIXER_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
)))
531 if (dmasound
.mach
.mixer_ioctl
)
532 return dmasound
.mach
.mixer_ioctl(cmd
, arg
);
536 static struct file_operations mixer_fops
=
542 release
: mixer_release
,
545 static void __init
mixer_init(void)
550 mixer_unit
= register_sound_mixer(&mixer_fops
, -1);
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
;
568 struct sound_queue dmasound_read_sq
;
571 static int sq_allocate_buffers(struct sound_queue
*sq
, int num
, int size
)
579 sq
->buffers
= kmalloc (num
* sizeof(char *), GFP_KERNEL
);
582 for (i
= 0; i
< num
; i
++) {
583 sq
->buffers
[i
] = dmasound
.mach
.dma_alloc(size
, GFP_KERNEL
);
584 if (!sq
->buffers
[i
]) {
586 dmasound
.mach
.dma_free(sq
->buffers
[i
], size
);
595 static void sq_release_buffers(struct sound_queue
*sq
)
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
);
609 static void sq_setup(struct sound_queue
*sq
, int max_count
, int max_active
,
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;
622 if (sq
== &write_sq
) {
624 setup_func
= dmasound
.mach
.write_sq_setup
;
627 setup_func
= dmasound
.mach
.read_sq_setup
;
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
,
641 ssize_t uWritten
= 0;
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.
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
);
668 write_sq
.rear_size
= bUsed
;
672 while (write_sq
.count
== write_sq
.max_active
) {
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
688 dest
= write_sq
.buffers
[(write_sq
.rear
+1) % write_sq
.max_count
];
690 bLeft
= write_sq
.block_size
;
691 uUsed
= sound_copy_translate(dmasound
.trans_write
, src
, uLeft
,
692 dest
, &bUsed
, bLeft
);
699 write_sq
.rear
= (write_sq
.rear
+1) % write_sq
.max_count
;
700 write_sq
.rear_size
= bUsed
;
703 } while (bUsed
); /* uUsed may have been 0 */
707 return uUsed
< 0? uUsed
: uWritten
;
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
,
728 ssize_t uRead
, bLeft
, bUsed
, uUsed
;
733 if (!read_sq
.active
&& dmasound
.mach
.record
)
734 dmasound
.mach
.record(); /* Kick off the record process. */
738 /* Move what the user requests, depending upon other options.
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
],
766 read_sq
.rear_size
+= bUsed
;
767 if (read_sq
.rear_size
>= read_sq
.block_size
) {
768 read_sq
.rear_size
= 0;
770 if (read_sq
.front
>= read_sq
.max_active
)
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
);
786 static inline void sq_wake_up(struct sound_queue
*sq
, struct file
*file
,
789 if (file
->f_mode
& mode
) {
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
)
800 if (file
->f_mode
& mode
) {
803 if (file
->f_flags
& O_NONBLOCK
)
807 SLEEP(sq
->open_queue
);
808 if (signal_pending(current
))
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
);
820 sq_setup(sq
, numbufs
, numbufs
, bufsize
);
821 sq
->open_mode
= file
->f_mode
;
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)
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
)
849 dmasound
.mach
.open();
850 if ((rc
= write_sq_open(file
)) || (rc
= read_sq_open(file
))) {
851 dmasound
.mach
.release();
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
;
861 if ((MINOR(inode
->i_rdev
) & 0x0f) == SND_DEV_AUDIO
) {
862 sound_set_speed(8000);
864 sound_set_format(AFMT_MU_LAW
);
868 if (file
->f_mode
== FMODE_READ
&& dmasound
.mach
.record
) {
869 /* Start dma'ing straight away */
870 dmasound
.mach
.record();
877 static void sq_reset(void)
882 write_sq
.front
= (write_sq
.rear
+1) % write_sq
.max_count
;
885 static int sq_fsync(struct file
*filp
, struct dentry
*dentry
)
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. */
904 write_sq
.syncing
= 0;
908 static int sq_release(struct inode
*inode
, struct file
*file
)
914 rc
= sq_fsync(file
, file
->f_dentry
);
915 dmasound
.soft
= dmasound
.dsp
;
916 dmasound
.hard
= dmasound
.dsp
;
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. */
936 static int sq_ioctl(struct inode
*inode
, struct file
*file
, u_int cmd
,
945 case SNDCTL_DSP_RESET
:
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
955 case SNDCTL_DSP_SPEED
:
956 sq_fsync(file
, file
->f_dentry
);
958 return IOCTL_OUT(arg
, sound_set_speed(data
));
959 case SNDCTL_DSP_STEREO
:
960 sq_fsync(file
, file
->f_dentry
);
962 return IOCTL_OUT(arg
, sound_set_stereo(data
));
963 case SOUND_PCM_WRITE_CHANNELS
:
964 sq_fsync(file
, file
->f_dentry
);
966 return IOCTL_OUT(arg
, sound_set_stereo(data
-1)+1);
967 case SNDCTL_DSP_SETFMT
:
968 sq_fsync(file
, file
->f_dentry
);
970 return IOCTL_OUT(arg
, sound_set_format(data
));
971 case SNDCTL_DSP_GETFMTS
:
973 if (dmasound
.trans_write
) {
974 if (dmasound
.trans_write
->ct_ulaw
)
976 if (dmasound
.trans_write
->ct_alaw
)
978 if (dmasound
.trans_write
->ct_s8
)
980 if (dmasound
.trans_write
->ct_u8
)
982 if (dmasound
.trans_write
->ct_s16be
)
984 if (dmasound
.trans_write
->ct_u16be
)
986 if (dmasound
.trans_write
->ct_s16le
)
988 if (dmasound
.trans_write
->ct_u16le
)
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
:
999 case SNDCTL_DSP_SETFRAGMENT
:
1000 if (write_sq
.count
|| write_sq
.active
|| write_sq
.syncing
)
1002 IOCTL_IN(arg
, size
);
1004 if (nbufs
< 2 || nbufs
> write_sq
.numBufs
)
1005 nbufs
= write_sq
.numBufs
;
1007 if (size
>= 8 && size
<= 29) {
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
;
1014 size
= write_sq
.bufSize
;
1015 sq_setup(&write_sq
, write_sq
.numBufs
, nbufs
, size
);
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
)))
1027 return mixer_ioctl(inode
, file
, cmd
, arg
);
1032 static struct file_operations sq_fops
=
1035 llseek
: sound_lseek
,
1039 release
: sq_release
,
1045 static void __init
sq_init(void)
1050 sq_unit
= register_sound_dsp(&sq_fops
, -1);
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
;
1082 char buf
[512]; /* state.buf should not overflow! */
1086 static int state_open(struct inode
*inode
, struct file
*file
)
1088 char *buffer
= state
.buf
;
1094 dmasound
.mach
.open();
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
) {
1104 len
+= sprintf(buffer
+len
, " (mu-law)");
1107 len
+= sprintf(buffer
+len
, " (A-law)");
1110 len
+= sprintf(buffer
+len
, " (unsigned 8 bit)");
1113 len
+= sprintf(buffer
+len
, " (signed 8 bit)");
1116 len
+= sprintf(buffer
+len
, " (signed 16 bit big)");
1119 len
+= sprintf(buffer
+len
, " (unsigned 16 bit big)");
1122 len
+= sprintf(buffer
+len
, " (signed 16 bit little)");
1125 len
+= sprintf(buffer
+len
, " (unsigned 16 bit little)");
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
);
1148 static int state_release(struct inode
*inode
, struct file
*file
)
1152 dmasound
.mach
.release();
1157 static ssize_t
state_read(struct file
*file
, char *buf
, size_t count
,
1160 int n
= state
.len
- state
.ptr
;
1165 if (copy_to_user(buf
, &state
.buf
[state
.ptr
], n
))
1171 static struct file_operations state_fops
= {
1173 llseek
: sound_lseek
,
1176 release
: state_release
,
1179 static void __init
state_init(void)
1184 state_unit
= register_sound_special(&state_fops
, SND_DEV_STATUS
);
1194 * This function is called by _one_ chipset-specific driver
1197 int __init
dmasound_init(void)
1204 /* Set up sound queue, /dev/audio and /dev/dsp. */
1206 /* Set default settings. */
1209 /* Set up /dev/sndstat. */
1212 /* Set up /dev/mixer. */
1215 if (!dmasound
.mach
.irqinit()) {
1216 printk(KERN_ERR
"DMA sound driver: Interrupt initialization failed\n");
1223 printk(KERN_INFO
"DMA sound driver installed, using %d buffers of %dk.\n",
1224 numWriteBufs
, writeBufSize
);
1231 void dmasound_deinit(void)
1233 if (irq_installed
) {
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
);
1246 unregister_sound_dsp(sq_unit
);
1251 static int __init
dmasound_setup(char *str
)
1255 str
= get_options(str
, ARRAY_SIZE(ints
), ints
);
1257 /* check the bootstrap parameter for "dmasound=" */
1261 if ((ints
[3] < 0) || (ints
[3] > MAX_CATCH_RADIUS
))
1262 printk("dmasound_setup: illegal catch radius, using default = %d\n", catchRadius
);
1264 catchRadius
= ints
[3];
1267 if (ints
[1] < MIN_BUFFERS
)
1268 printk("dmasound_setup: illegal number of buffers, using default = %d\n", numWriteBufs
);
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
);
1274 writeBufSize
= ints
[2];
1279 printk("dmasound_setup: illegal number of arguments\n");
1285 __setup("dmasound=", dmasound_setup
);
1287 #endif /* !MODULE */
1291 * Visible symbols for modules
1294 EXPORT_SYMBOL(dmasound
);
1295 EXPORT_SYMBOL(dmasound_init
);
1297 EXPORT_SYMBOL(dmasound_deinit
);
1299 EXPORT_SYMBOL(dmasound_write_sq
);
1301 EXPORT_SYMBOL(dmasound_read_sq
);
1303 EXPORT_SYMBOL(dmasound_catchRadius
);
1304 #ifdef HAS_8BIT_TABLES
1305 EXPORT_SYMBOL(dmasound_ulaw2dma8
);
1306 EXPORT_SYMBOL(dmasound_alaw2dma8
);
1308 #ifdef HAS_16BIT_TABLES
1309 EXPORT_SYMBOL(dmasound_ulaw2dma16
);
1310 EXPORT_SYMBOL(dmasound_alaw2dma16
);
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
);