OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [sound/] [dmasound.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
 
2
/* linux/drivers/sound/dmasound.c */
3
 
4
/*
5
 
6
VoxWare compatible Atari TT DMA sound driver for 680x0 Linux
7
 
8
(c) 1995 by Michael Schlueter & Michael Marte
9
 
10
Michael Schlueter (michael@duck.syd.de) did the basic structure of the VFS
11
interface and the u-law to signed byte conversion.
12
 
13
Michael Marte (marte@informatik.uni-muenchen.de) did the sound queue,
14
/dev/mixer, /dev/sndstat and complemented the VFS interface. He would like
15
to thank:
16
Michael Schlueter for initial ideas and documentation on the MFP and
17
the DMA sound hardware.
18
Therapy? for their CD 'Troublegum' which really made me rock.
19
 
20
/dev/sndstat is based on code by Hannu Savolainen, the author of the
21
VoxWare family of drivers.
22
 
23
This file is subject to the terms and conditions of the GNU General Public
24
License.  See the file COPYING in the main directory of this archive
25
for more details.
26
 
27
History:
28
1995/8/25       first release
29
 
30
1995/9/02       ++roman: fixed atari_stram_alloc() call, the timer programming
31
                        and several race conditions
32
 
33
1995/9/14       ++roman: After some discussion with Michael Schlueter, revised
34
                        the interrupt disabling
35
                        Slightly speeded up U8->S8 translation by using long
36
                        operations where possible
37
                        Added 4:3 interpolation for /dev/audio
38
 
39
1995/9/20       ++TeSche: Fixed a bug in sq_write and changed /dev/audio
40
                        converting to play at 12517Hz instead of 6258Hz.
41
 
42
1995/9/23       ++TeSche: Changed sq_interrupt() and sq_play() to pre-program
43
                        the DMA for another frame while there's still one
44
                        running. This allows the IRQ response to be
45
                        arbitrarily delayed and playing will still continue.
46
 
47
1995/10/14      ++Guenther_Kelleter@ac3.maus.de, ++TeSche: better support for
48
                        Falcon audio (the Falcon doesn't raise an IRQ at the
49
                        end of a frame, but at the beginning instead!). uses
50
                        'if (codec_dma)' in lots of places to simply switch
51
                        between Falcon and TT code.
52
 
53
1995/11/06      ++TeSche: started introducing a hardware abstraction scheme
54
                        (may perhaps also serve for Amigas?), can now play
55
                        samples at almost all frequencies by means of a more
56
                        generalized expand routine, takes a good deal of care
57
                        to cut data only at sample sizes, buffer size is now
58
                        a kernel runtime option, implemented fsync() & several
59
                        minor improvements
60
                ++Guenther: useful hints and bug fixes, cross-checked it for
61
                        Falcons
62
 
63
1996/3/9        ++geert: support added for Amiga, A-law, 16-bit little endian.
64
                        Unification to drivers/sound/dmasound.c.
65
1996/4/6        ++Martin Mitchell: updated to 1.3 kernel.
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 /* CONFIG_ATARI */
87
#ifdef CONFIG_AMIGA
88
#include <asm/amigahw.h>
89
#include <asm/amigaints.h>
90
#endif /* CONFIG_AMIGA */
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 /* CONFIG_ATARI */
99
 
100
#ifdef CONFIG_AMIGA
101
   /*
102
    *   The minimum period for audio depends on total (for OCS/ECS/AGA)
103
    *   (Imported from arch/m68k/amiga/amisound.c)
104
    */
105
 
106
extern volatile u_short amiga_audio_min_period;
107
 
108
 
109
   /*
110
    *   amiga_mksound() should be able to restore the period after beeping
111
    *   (Imported from arch/m68k/amiga/amisound.c)
112
    */
113
 
114
extern u_short amiga_audio_period;
115
 
116
 
117
   /*
118
    *   Audio DMA masks
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 /* CONFIG_AMIGA */
126
 
127
 
128
/*** Some declarations *******************************************************/
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     /* Limit for Amiga */
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
/*** Some low level helpers **************************************************/
153
 
154
 
155
/* 8 bit mu-law */
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
/* 8 bit A-law */
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
/* 16 bit mu-law */
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
/* 16 bit A-law */
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 /* HAS_16BIT_TABLES */
306
 
307
 
308
#ifdef HAS_14BIT_TABLES
309
 
310
/* 14 bit mu-law (LSB) */
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
/* 14 bit A-law (LSB) */
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 /* HAS_14BIT_TABLES */
384
 
385
 
386
/*** Translations ************************************************************/
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 /* CONFIG_ATARI */
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 /* CONFIG_AMIGA */
436
 
437
 
438
/*** Machine definitions *****************************************************/
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
/*** Low level stuff *********************************************************/
457
 
458
 
459
typedef struct {
460
    int format;         /* AFMT_* */
461
    int stereo;         /* 0 = mono, 1 = stereo */
462
    int size;           /* 8/16 bit*/
463
    int speed;          /* 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;       /* machine dependent things */
479
    SETTINGS hard;      /* hardware settings */
480
    SETTINGS soft;      /* software settings */
481
    SETTINGS dsp;       /* /dev/dsp default settings */
482
    TRANS *trans;       /* supported translations */
483
    int volume_left;    /* volume (range is machine dependent) */
484
    int volume_right;
485
    int bass;           /* tone (range is machine dependent) */
486
    int treble;
487
    int minDev;         /* minor device number currently open */
488
#ifdef CONFIG_ATARI
489
    int bal;            /* balance factor for expanding (not volume!) */
490
    u_long data;        /* data for expanding */
491
#endif /* CONFIG_ATARI */
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 /* CONFIG_ATARI */
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 /* CONFIG_AMIGA */
529
 
530
 
531
/*** Mid level stuff *********************************************************/
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 /* CONFIG_ATARI */
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
 * /dev/mixer abstraction
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
 * Sound queue stuff, the heart of the driver
568
 */
569
 
570
struct sound_queue {
571
    int max_count, block_size;
572
    char **buffers;
573
 
574
    /* it shouldn't be necessary to declare any of these volatile */
575
    int front, rear, count;
576
    int rear_size;
577
    /*
578
     *  The use of the playing field depends on the hardware
579
     *
580
     *  Atari: The number of frames that are loaded/playing
581
     *
582
     *  Amiga: Bit 0 is set: a frame is loaded
583
     *         Bit 1 is set: a frame is playing
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;             /* ++TeSche: used for Falcon */
591
#endif /* CONFIG_ATARI */
592
#ifdef CONFIG_AMIGA
593
    int block_size_half, block_size_quarter;
594
#endif /* CONFIG_AMIGA */
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      /* in jiffies (100ths of a second) */
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
 * /dev/sndstat
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
/*** High level stuff ********************************************************/
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
/*** Config & Setup **********************************************************/
655
 
656
 
657
void soundcard_init(void);
658
void dmasound_setup(char *str, int *ints);
659
void sound_setup(char *str, int *ints);         /* ++Martin: stub for now */
660
 
661
 
662
/*** Translations ************************************************************/
663
 
664
 
665
/* ++TeSche: radically changed for new expanding purposes...
666
 *
667
 * These two routines now deal with copying/expanding/translating the samples
668
 * from user space into our buffer at the right frequency. They take care about
669
 * how much data there's actually to read, how much buffer space there is and
670
 * to convert samples into the right frequency/encoding. They will only work on
671
 * complete samples so it may happen they leave some bytes in the input stream
672
 * if the user didn't write a multiple of the current sample size. They both
673
 * return the number of bytes they've used from both streams so you may detect
674
 * such a situation. Luckily all programs should be able to cope with that.
675
 *
676
 * I think I've optimized anything as far as one can do in plain C, all
677
 * variables should fit in registers and the loops are really short. There's
678
 * one loop for every possible situation. Writing a more generalized and thus
679
 * parameterized loop would only produce slower code. Feel free to optimize
680
 * this in assembler if you like. :)
681
 *
682
 * I think these routines belong here because they're not yet really hardware
683
 * independent, especially the fact that the Falcon can play 16bit samples
684
 * only in stereo is hardcoded in both of them!
685
 *
686
 * ++geert: split in even more functions (one per format)
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
    /* this should help gcc to stuff everything into registers */
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
    /* this should help gcc to stuff everything into registers */
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
    /* this should help gcc to stuff everything into registers */
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
    /* this should help gcc to stuff everything into registers */
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
    /* this should help gcc to stuff everything into registers */
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
    /* this should help gcc to stuff everything into registers */
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
    /* this should help gcc to stuff everything into registers */
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 /* CONFIG_ATARI */
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 /* CONFIG_AMIGA */
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 /* CONFIG_ATARI */
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 /* CONFIG_AMIGA */
1503
 
1504
 
1505
/*** Low level stuff *********************************************************/
1506
 
1507
 
1508
#ifdef CONFIG_ATARI
1509
 
1510
/*
1511
 * Atari (TT/Falcon)
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 ((unsigned long) obj, order);
1538
}
1539
 
1540
static int AtaIrqInit(void)
1541
{
1542
    /* Set up timer A. Timer A
1543
    will receive a signal upon end of playing from the sound
1544
    hardware. Furthermore Timer A is able to count events
1545
    and will cause an interrupt after a programmed number
1546
    of events. So all we need to keep the music playing is
1547
    to provide the sound hardware with new data upon
1548
    an interrupt from timer A. */
1549
    mfp.tim_ct_a = 0;            /* ++roman: Stop timer before programming! */
1550
    mfp.tim_dt_a = 1;           /* Cause interrupt after first event. */
1551
    mfp.tim_ct_a = 8;           /* Turn on event counting. */
1552
    /* Register interrupt handler. */
1553
    add_isr(IRQ_MFP_TIMA, ata_sq_interrupt, IRQ_TYPE_SLOW, NULL, "DMA sound");
1554
    mfp.int_en_a |= 0x20;       /* Turn interrupt on. */
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
 * TT
1584
 */
1585
 
1586
 
1587
static void TTSilence(void)
1588
{
1589
    tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1590
    atari_microwire_cmd(MW_LM1992_PSG_HIGH); /* mix in PSG signal 1:1 */
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
    /* search a frequency that fits into the allowed error range */
1600
 
1601
    idx = -1;
1602
    for (i = 0; i < arraysize(freq); i++)
1603
        /* this isn't as much useful for a TT than for a Falcon, but
1604
         * then it doesn't hurt very much to implement it for a TT too.
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
        /* we would need to squeeze the sound, but we won't do that */
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
    /* TT sound DMA supports only 8bit modes */
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
 * Falcon
1691
 */
1692
 
1693
 
1694
static void FalconSilence(void)
1695
{
1696
    /* stop playback, set sample rate 50kHz for PSG sound */
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; /* STE compatible divider */
1700
    tt_dmasnd.int_ctrl = 0x0;
1701
    tt_dmasnd.cbar_src = 0x0000; /* no matrix inputs */
1702
    tt_dmasnd.cbar_dst = 0x0000; /* no matrix outputs */
1703
    tt_dmasnd.dac_src = 1; /* connect ADC to DAC, disconnect matrix */
1704
    tt_dmasnd.adc_src = 3; /* ADC Input = PSG */
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
    /* search a frequency that fits into the allowed error range */
1714
 
1715
    idx = -1;
1716
    for (i = 0; i < arraysize(freq); i++)
1717
        /* if we will tolerate 3% error 8000Hz->8195Hz (2.38%) would
1718
         * be playable without expanding, but that now a kernel runtime
1719
         * option
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
        /* the Falcon can play 16bit samples only in stereo */
1734
        sound.hard.stereo = 1;
1735
    }
1736
 
1737
    if (sound.hard.speed > 49170) {
1738
        /* we would need to squeeze the sound, but we won't do that */
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
    /* Setup Falcon sound DMA for playback */
1770
    tt_dmasnd.int_ctrl = 0x4; /* Timer A int at play end */
1771
    tt_dmasnd.track_select = 0x0; /* play 1 track, track 1 */
1772
    tt_dmasnd.cbar_src = 0x0001; /* DMA(25MHz) --> DAC */
1773
    tt_dmasnd.cbar_dst = 0x0000;
1774
    tt_dmasnd.rec_track_select = 0;
1775
    tt_dmasnd.dac_src = 2; /* connect matrix to DAC */
1776
    tt_dmasnd.adc_src = 0; /* ADC Input = Mic */
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
    /* Falcon sound DMA supports 8bit and 16bit modes */
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
/* This is for the Falcon output *attenuation* in 1.5dB steps,
1827
 * i.e. output level from 0 to -22.5dB in -1.5dB steps.
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
    /* used by AtaPlay() if all doubts whether there really is something
1849
     * to be played are already wiped out.
1850
     */
1851
    start = sq_block_address(sq.front);
1852
    end = start+((sq.count == index) ? sq.rear_size : sq.block_size);
1853
    /* end might not be a legal virtual address. */
1854
    DMASNDSetEnd(VTOP(end - 1) + 1);
1855
    DMASNDSetBase(VTOP(start));
1856
        /* Since only an even number of samples per frame can
1857
        be played, we might lose one byte here. (TO DO) */
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
    /* ++TeSche: Note that sq.playing is no longer just a flag but holds
1867
     * the number of frames the DMA is currently programmed for instead,
1868
     * may be 0, 1 (currently being played) or 2 (pre-programmed).
1869
     *
1870
     * Changes done to sq.count and sq.playing are a bit more subtle again
1871
     * so now I must admit I also prefer disabling the irq here rather
1872
     * than considering all possible situations. But the point is that
1873
     * disabling the irq doesn't have any bad influence on this version of
1874
     * the driver as we benefit from having pre-programmed the DMA
1875
     * wherever possible: There's no need to reload the DMA at the exact
1876
     * time of an interrupt but only at some time while the pre-programmed
1877
     * frame is playing!
1878
     */
1879
    atari_disable_irq(IRQ_MFP_TIMA);
1880
 
1881
    if (sq.playing == 2 ||      /* DMA is 'full' */
1882
        sq.count <= 0) { /* nothing to do */
1883
        atari_enable_irq(IRQ_MFP_TIMA);
1884
        return;
1885
    }
1886
 
1887
    if (sq.playing == 0) {
1888
        /* looks like there's nothing 'in' the DMA yet, so try
1889
         * to put two frames into it (at least one is available).
1890
         */
1891
        if (sq.count == 1 && sq.rear_size < sq.block_size && !sq.syncing) {
1892
            /* hmmm, the only existing frame is not
1893
             * yet filled and we're not syncing?
1894
             */
1895
            atari_enable_irq(IRQ_MFP_TIMA);
1896
            return;
1897
        }
1898
        ata_sq_play_next_frame(1);
1899
        if (sq.count == 1) {
1900
            /* no more frames */
1901
            atari_enable_irq(IRQ_MFP_TIMA);
1902
            return;
1903
        }
1904
        if (sq.count == 2 && sq.rear_size < sq.block_size && !sq.syncing) {
1905
            /* hmmm, there were two frames, but the second
1906
             * one is not yet filled and we're not syncing?
1907
             */
1908
            atari_enable_irq(IRQ_MFP_TIMA);
1909
            return;
1910
        }
1911
        ata_sq_play_next_frame(2);
1912
    } else {
1913
        /* there's already a frame being played so we may only stuff
1914
         * one new into the DMA, but even if this may be the last
1915
         * frame existing the previous one is still on sq.count.
1916
         */
1917
        if (sq.count == 2 && sq.rear_size < sq.block_size && !sq.syncing) {
1918
            /* hmmm, the only existing frame is not
1919
             * yet filled and we're not syncing?
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
    /* ++TeSche: if you should want to test this... */
1934
    static int cnt = 0;
1935
    if (sq.playing == 2)
1936
        if (++cnt == 10) {
1937
            /* simulate losing an interrupt */
1938
            cnt = 0;
1939
            return;
1940
        }
1941
#endif
1942
 
1943
    if (sq.ignore_int && (sound.mach.type == DMASND_FALCON)) {
1944
        /* ++TeSche: Falcon only: ignore first irq because it comes
1945
         * immediately after starting a frame. after that, irqs come
1946
         * (almost) like on the TT.
1947
         */
1948
        sq.ignore_int = 0;
1949
        return;
1950
    }
1951
 
1952
    if (!sq.playing) {
1953
        /* playing was interrupted and sq_reset() has already cleared
1954
         * the sq variables, so better don't do anything here.
1955
         */
1956
        WAKE_UP(sq.sync_queue);
1957
        return;
1958
    }
1959
 
1960
    /* Probably ;) one frame is finished. Well, in fact it may be that a
1961
     * pre-programmed one is also finished because there has been a long
1962
     * delay in interrupt delivery and we've completely lost one, but
1963
     * there's no way to detect such a situation. In such a case the last
1964
     * frame will be played more than once and the situation will recover
1965
     * as soon as the irq gets through.
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
        /* At least one block of the queue is free now
1977
        so wake up a writing process blocked because
1978
        of a full queue. */
1979
 
1980
    if ((sq.playing != 1) || (sq.count != 1))
1981
        /* We must be a bit carefully here: sq.count indicates the
1982
         * number of buffers used and not the number of frames to
1983
         * be played. If sq.count==1 and sq.playing==1 that means
1984
         * the only remaining frame was already programmed earlier
1985
         * (and is currently running) so we mustn't call AtaPlay()
1986
         * here, otherwise we'll play one frame too much.
1987
         */
1988
        AtaPlay();
1989
 
1990
    if (!sq.playing) WAKE_UP(sq.sync_queue);
1991
        /* We are not playing after AtaPlay(), so there
1992
        is nothing to play any more. Wake up a process
1993
        waiting for audio output to drain. */
1994
}
1995
#endif /* CONFIG_ATARI */
1996
 
1997
 
1998
#ifdef CONFIG_AMIGA
1999
 
2000
/*
2001
 * Amiga
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
    /* turn off DMA for audio channels */
2018
    custom.dmacon = AMI_AUDIO_OFF;
2019
 
2020
    /* Register interrupt handler. */
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
    /* turn off DMA for audio channels */
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
        /* we would need to squeeze the sound, but we won't do that */
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
    /* Amiga sound DMA supports 8bit and 16bit (pseudo 14 bit) modes */
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
    /* used by AmiPlay() if all doubts whether there really is something
2135
     * to be played are already wiped out.
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
            /* We can play pseudo 14-bit only with the maximum volume */
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
        /* There's already a frame loaded */
2185
        custom.intena = IF_SETCLR | IF_AUD0;
2186
        return;
2187
    }
2188
 
2189
    if (sq.playing & AMI_PLAY_PLAYING)
2190
        /* Increase threshold: frame 1 is already being played */
2191
        minframes = 2;
2192
 
2193
    if (sq.count < minframes) {
2194
        /* Nothing to do */
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
        /* hmmm, the only existing frame is not
2201
         * yet filled and we're not syncing?
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
        /* Playing was interrupted and sq_reset() has already cleared
2219
         * the sq variables, so better don't do anything here.
2220
         */
2221
        WAKE_UP(sq.sync_queue);
2222
        return;
2223
    }
2224
 
2225
    if (sq.playing & AMI_PLAY_PLAYING) {
2226
        /* We've just finished a frame */
2227
        sq.count--;
2228
        WAKE_UP(sq.write_queue);
2229
    }
2230
 
2231
    if (sq.playing & AMI_PLAY_LOADED)
2232
        /* Increase threshold: frame 1 is already being played */
2233
        minframes = 2;
2234
 
2235
    /* Shift the flags */
2236
    sq.playing = (sq.playing<<1) & AMI_PLAY_MASK;
2237
 
2238
    if (!sq.playing)
2239
        /* No frame is playing, disable audio DMA */
2240
        custom.dmacon = AMI_AUDIO_OFF;
2241
 
2242
    if (sq.count >= minframes)
2243
        /* Try to play the next frame */
2244
        AmiPlay();
2245
 
2246
    if (!sq.playing)
2247
        /* Nothing to play anymore.
2248
           Wake up a process waiting for audio output to drain. */
2249
        WAKE_UP(sq.sync_queue);
2250
}
2251
#endif /* CONFIG_AMIGA */
2252
 
2253
 
2254
/*** Machine definitions *****************************************************/
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 /* CONFIG_ATARI */
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 /* CONFIG_AMIGA */
2275
 
2276
 
2277
/*** Mid level stuff *********************************************************/
2278
 
2279
 
2280
static void sound_silence(void)
2281
{
2282
    /* update hardware settings one more */
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;    /* should be 0 or 1 now */
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 /* CONFIG_ATARI */
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
 * /dev/mixer abstraction
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 /* CONFIG_ATARI */
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;                   /* For pseudo 14bit */
2427
            custom.aud[1].audvol = sound.volume_right;
2428
            custom.aud[2].audvol = 1;                   /* For pseudo 14bit */
2429
            sound.treble = 50;
2430
            break;
2431
#endif /* CONFIG_AMIGA */
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
                    /* fall thru, return set value */
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 /* CONFIG_ATARI */
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 /* CONFIG_AMIGA */
2580
    }
2581
 
2582
    return(-EINVAL);
2583
}
2584
 
2585
 
2586
 
2587
/*
2588
 * Sound queue stuff, the heart of the driver
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 /* CONFIG_ATARI */
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 /* CONFIG_AMIGA */
2613
 
2614
    sound_silence();
2615
 
2616
    /* whatever you like as startup mode for /dev/dsp,
2617
     * (/dev/audio hasn't got a startup mode). note that
2618
     * once changed a new open() will *not* restore these!
2619
     */
2620
    sound.dsp.format = AFMT_S8;
2621
    sound.dsp.stereo = 0;
2622
    sound.dsp.size = 8;
2623
 
2624
    /* set minimum rate possible without expanding */
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 /* CONFIG_ATARI */
2634
#ifdef CONFIG_AMIGA
2635
        case DMASND_AMIGA:
2636
            sound.dsp.speed = 8000;
2637
            break;
2638
#endif /* CONFIG_AMIGA */
2639
    }
2640
 
2641
    /* before the first open to /dev/dsp this wouldn't be set */
2642
    sound.soft = sound.dsp;
2643
}
2644
 
2645
 
2646
static void sq_play(void)
2647
{
2648
    (*sound.mach.play)();
2649
}
2650
 
2651
 
2652
/* ++TeSche: radically changed this one too */
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
    /* ++TeSche: Is something like this necessary?
2661
     * Hey, that's an honest question! Or does any other part of the
2662
     * filesystem already checks this situation? I really don't know.
2663
     */
2664
    if (uLeft < 1)
2665
        return(0);
2666
 
2667
    /* The interrupt doesn't start to play the last, incomplete frame.
2668
     * Thus we can append to it without disabling the interrupts! (Note
2669
     * also that sq.rear isn't affected by the interrupt.)
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
        /* Here, we can avoid disabling the interrupt by first
2693
         * copying and translating the data, and then updating
2694
         * the sq variables. Until this is done, the interrupt
2695
         * won't see the new frame and we can work on it
2696
         * undisturbed.
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);   /* uUsed may have been 0 */
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 /* CONFIG_ATARI */
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();  /* there may be an incomplete frame waiting */
2754
 
2755
    while (sq.playing) {
2756
        SLEEP(sq.sync_queue, ONE_SECOND);
2757
        if (SIGNAL_RECEIVED) {
2758
            /* While waiting for audio output to drain, an interrupt occurred.
2759
               Stop audio output immediately and clear the queue. */
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
        /* Wake up a process waiting for the queue being released.
2779
           Note: There may be several processes waiting for a call to open()
2780
                 returning. */
2781
    }
2782
    return(rc);
2783
}
2784
 
2785
 
2786
 
2787
/*
2788
 * /dev/sndstat
2789
 */
2790
 
2791
 
2792
static void state_init(void)
2793
{
2794
    state.busy = 0;
2795
}
2796
 
2797
 
2798
/* state.buf should not overflow! */
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 /* CONFIG_ATARI */
2818
#ifdef CONFIG_AMIGA
2819
        case DMASND_AMIGA:
2820
            mach = "Amiga ";
2821
            break;
2822
#endif /* CONFIG_AMIGA */
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 /* CONFIG_ATARI */
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 /* CONFIG_AMIGA */
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
/*** High level stuff ********************************************************/
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
    /* printk("%s: Unknown minor device %d\n", fname, dev); */
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
                /* ++TeSche: before changing any of these it's probably wise to
3074
                 * wait until sound playing has settled down
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,                      /* select */
3134
    sound_ioctl,
3135
    NULL,
3136
    sound_open,
3137
    sound_release,
3138
    sound_fsync
3139
};
3140
 
3141
 
3142
 
3143
/*** Config & Setup **********************************************************/
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 /* CONFIG_ATARI */
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 /* CONFIG_AMIGA */
3178
    }
3179
    if (!has_sound)
3180
        return;
3181
 
3182
    /* Set up sound queue, /dev/audio and /dev/dsp. */
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
    /* Register driver with the VFS. */
3200
    register_chrdev(SOUND_MAJOR, "sound", &sound_fops);
3201
 
3202
    sq_init(numBufs, bufSize << 10, buffers);
3203
 
3204
    /* Set up /dev/sndstat. */
3205
    state_init();
3206
 
3207
    /* Set up /dev/mixer. */
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
    /* ++Martin: stub, could possibly be merged with soundcard.c et al later */
3224
}
3225
 
3226
void dmasound_setup(char *str, int *ints)
3227
{
3228
    /* check the bootstrap parameter for "dmasound=" */
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
            /* fall through */
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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.