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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [sound/] [oss/] [dmasound/] [dmasound_atari.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 *  linux/sound/oss/dmasound/dmasound_atari.c
3
 *
4
 *  Atari TT and Falcon DMA Sound Driver
5
 *
6
 *  See linux/sound/oss/dmasound/dmasound_core.c for copyright and credits
7
 *  prior to 28/01/2001
8
 *
9
 *  28/01/2001 [0.1] Iain Sandoe
10
 *                   - added versioning
11
 *                   - put in and populated the hardware_afmts field.
12
 *             [0.2] - put in SNDCTL_DSP_GETCAPS value.
13
 *  01/02/2001 [0.3] - put in default hard/soft settings.
14
 */
15
 
16
 
17
#include <linux/module.h>
18
#include <linux/kernel.h>
19
#include <linux/init.h>
20
#include <linux/soundcard.h>
21
#include <linux/mm.h>
22
#include <linux/spinlock.h>
23
#include <linux/interrupt.h>
24
 
25
#include <asm/uaccess.h>
26
#include <asm/atariints.h>
27
#include <asm/atari_stram.h>
28
 
29
#include "dmasound.h"
30
 
31
#define DMASOUND_ATARI_REVISION 0
32
#define DMASOUND_ATARI_EDITION 3
33
 
34
extern void atari_microwire_cmd(int cmd);
35
 
36
static int is_falcon;
37
static int write_sq_ignore_int; /* ++TeSche: used for Falcon */
38
 
39
static int expand_bal;  /* Balance factor for expanding (not volume!) */
40
static int expand_data; /* Data for expanding */
41
 
42
 
43
/*** Translations ************************************************************/
44
 
45
 
46
/* ++TeSche: radically changed for new expanding purposes...
47
 *
48
 * These two routines now deal with copying/expanding/translating the samples
49
 * from user space into our buffer at the right frequency. They take care about
50
 * how much data there's actually to read, how much buffer space there is and
51
 * to convert samples into the right frequency/encoding. They will only work on
52
 * complete samples so it may happen they leave some bytes in the input stream
53
 * if the user didn't write a multiple of the current sample size. They both
54
 * return the number of bytes they've used from both streams so you may detect
55
 * such a situation. Luckily all programs should be able to cope with that.
56
 *
57
 * I think I've optimized anything as far as one can do in plain C, all
58
 * variables should fit in registers and the loops are really short. There's
59
 * one loop for every possible situation. Writing a more generalized and thus
60
 * parameterized loop would only produce slower code. Feel free to optimize
61
 * this in assembler if you like. :)
62
 *
63
 * I think these routines belong here because they're not yet really hardware
64
 * independent, especially the fact that the Falcon can play 16bit samples
65
 * only in stereo is hardcoded in both of them!
66
 *
67
 * ++geert: split in even more functions (one per format)
68
 */
69
 
70
static ssize_t ata_ct_law(const u_char __user *userPtr, size_t userCount,
71
                          u_char frame[], ssize_t *frameUsed,
72
                          ssize_t frameLeft);
73
static ssize_t ata_ct_s8(const u_char __user *userPtr, size_t userCount,
74
                         u_char frame[], ssize_t *frameUsed,
75
                         ssize_t frameLeft);
76
static ssize_t ata_ct_u8(const u_char __user *userPtr, size_t userCount,
77
                         u_char frame[], ssize_t *frameUsed,
78
                         ssize_t frameLeft);
79
static ssize_t ata_ct_s16be(const u_char __user *userPtr, size_t userCount,
80
                            u_char frame[], ssize_t *frameUsed,
81
                            ssize_t frameLeft);
82
static ssize_t ata_ct_u16be(const u_char __user *userPtr, size_t userCount,
83
                            u_char frame[], ssize_t *frameUsed,
84
                            ssize_t frameLeft);
85
static ssize_t ata_ct_s16le(const u_char __user *userPtr, size_t userCount,
86
                            u_char frame[], ssize_t *frameUsed,
87
                            ssize_t frameLeft);
88
static ssize_t ata_ct_u16le(const u_char __user *userPtr, size_t userCount,
89
                            u_char frame[], ssize_t *frameUsed,
90
                            ssize_t frameLeft);
91
static ssize_t ata_ctx_law(const u_char __user *userPtr, size_t userCount,
92
                           u_char frame[], ssize_t *frameUsed,
93
                           ssize_t frameLeft);
94
static ssize_t ata_ctx_s8(const u_char __user *userPtr, size_t userCount,
95
                          u_char frame[], ssize_t *frameUsed,
96
                          ssize_t frameLeft);
97
static ssize_t ata_ctx_u8(const u_char __user *userPtr, size_t userCount,
98
                          u_char frame[], ssize_t *frameUsed,
99
                          ssize_t frameLeft);
100
static ssize_t ata_ctx_s16be(const u_char __user *userPtr, size_t userCount,
101
                             u_char frame[], ssize_t *frameUsed,
102
                             ssize_t frameLeft);
103
static ssize_t ata_ctx_u16be(const u_char __user *userPtr, size_t userCount,
104
                             u_char frame[], ssize_t *frameUsed,
105
                             ssize_t frameLeft);
106
static ssize_t ata_ctx_s16le(const u_char __user *userPtr, size_t userCount,
107
                             u_char frame[], ssize_t *frameUsed,
108
                             ssize_t frameLeft);
109
static ssize_t ata_ctx_u16le(const u_char __user *userPtr, size_t userCount,
110
                             u_char frame[], ssize_t *frameUsed,
111
                             ssize_t frameLeft);
112
 
113
 
114
/*** Low level stuff *********************************************************/
115
 
116
 
117
static void *AtaAlloc(unsigned int size, gfp_t flags);
118
static void AtaFree(void *, unsigned int size);
119
static int AtaIrqInit(void);
120
#ifdef MODULE
121
static void AtaIrqCleanUp(void);
122
#endif /* MODULE */
123
static int AtaSetBass(int bass);
124
static int AtaSetTreble(int treble);
125
static void TTSilence(void);
126
static void TTInit(void);
127
static int TTSetFormat(int format);
128
static int TTSetVolume(int volume);
129
static int TTSetGain(int gain);
130
static void FalconSilence(void);
131
static void FalconInit(void);
132
static int FalconSetFormat(int format);
133
static int FalconSetVolume(int volume);
134
static void AtaPlayNextFrame(int index);
135
static void AtaPlay(void);
136
static irqreturn_t AtaInterrupt(int irq, void *dummy);
137
 
138
/*** Mid level stuff *********************************************************/
139
 
140
static void TTMixerInit(void);
141
static void FalconMixerInit(void);
142
static int AtaMixerIoctl(u_int cmd, u_long arg);
143
static int TTMixerIoctl(u_int cmd, u_long arg);
144
static int FalconMixerIoctl(u_int cmd, u_long arg);
145
static int AtaWriteSqSetup(void);
146
static int AtaSqOpen(mode_t mode);
147
static int TTStateInfo(char *buffer, size_t space);
148
static int FalconStateInfo(char *buffer, size_t space);
149
 
150
 
151
/*** Translations ************************************************************/
152
 
153
 
154
static ssize_t ata_ct_law(const u_char __user *userPtr, size_t userCount,
155
                          u_char frame[], ssize_t *frameUsed,
156
                          ssize_t frameLeft)
157
{
158
        char *table = dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8
159
                                                          : dmasound_alaw2dma8;
160
        ssize_t count, used;
161
        u_char *p = &frame[*frameUsed];
162
 
163
        count = min_t(unsigned long, userCount, frameLeft);
164
        if (dmasound.soft.stereo)
165
                count &= ~1;
166
        used = count;
167
        while (count > 0) {
168
                u_char data;
169
                if (get_user(data, userPtr++))
170
                        return -EFAULT;
171
                *p++ = table[data];
172
                count--;
173
        }
174
        *frameUsed += used;
175
        return used;
176
}
177
 
178
 
179
static ssize_t ata_ct_s8(const u_char __user *userPtr, size_t userCount,
180
                         u_char frame[], ssize_t *frameUsed,
181
                         ssize_t frameLeft)
182
{
183
        ssize_t count, used;
184
        void *p = &frame[*frameUsed];
185
 
186
        count = min_t(unsigned long, userCount, frameLeft);
187
        if (dmasound.soft.stereo)
188
                count &= ~1;
189
        used = count;
190
        if (copy_from_user(p, userPtr, count))
191
                return -EFAULT;
192
        *frameUsed += used;
193
        return used;
194
}
195
 
196
 
197
static ssize_t ata_ct_u8(const u_char __user *userPtr, size_t userCount,
198
                         u_char frame[], ssize_t *frameUsed,
199
                         ssize_t frameLeft)
200
{
201
        ssize_t count, used;
202
 
203
        if (!dmasound.soft.stereo) {
204
                u_char *p = &frame[*frameUsed];
205
                count = min_t(unsigned long, userCount, frameLeft);
206
                used = count;
207
                while (count > 0) {
208
                        u_char data;
209
                        if (get_user(data, userPtr++))
210
                                return -EFAULT;
211
                        *p++ = data ^ 0x80;
212
                        count--;
213
                }
214
        } else {
215
                u_short *p = (u_short *)&frame[*frameUsed];
216
                count = min_t(unsigned long, userCount, frameLeft)>>1;
217
                used = count*2;
218
                while (count > 0) {
219
                        u_short data;
220
                        if (get_user(data, (u_short __user *)userPtr))
221
                                return -EFAULT;
222
                        userPtr += 2;
223
                        *p++ = data ^ 0x8080;
224
                        count--;
225
                }
226
        }
227
        *frameUsed += used;
228
        return used;
229
}
230
 
231
 
232
static ssize_t ata_ct_s16be(const u_char __user *userPtr, size_t userCount,
233
                            u_char frame[], ssize_t *frameUsed,
234
                            ssize_t frameLeft)
235
{
236
        ssize_t count, used;
237
 
238
        if (!dmasound.soft.stereo) {
239
                u_short *p = (u_short *)&frame[*frameUsed];
240
                count = min_t(unsigned long, userCount, frameLeft)>>1;
241
                used = count*2;
242
                while (count > 0) {
243
                        u_short data;
244
                        if (get_user(data, (u_short __user *)userPtr))
245
                                return -EFAULT;
246
                        userPtr += 2;
247
                        *p++ = data;
248
                        *p++ = data;
249
                        count--;
250
                }
251
                *frameUsed += used*2;
252
        } else {
253
                void *p = (u_short *)&frame[*frameUsed];
254
                count = min_t(unsigned long, userCount, frameLeft) & ~3;
255
                used = count;
256
                if (copy_from_user(p, userPtr, count))
257
                        return -EFAULT;
258
                *frameUsed += used;
259
        }
260
        return used;
261
}
262
 
263
 
264
static ssize_t ata_ct_u16be(const u_char __user *userPtr, size_t userCount,
265
                            u_char frame[], ssize_t *frameUsed,
266
                            ssize_t frameLeft)
267
{
268
        ssize_t count, used;
269
 
270
        if (!dmasound.soft.stereo) {
271
                u_short *p = (u_short *)&frame[*frameUsed];
272
                count = min_t(unsigned long, userCount, frameLeft)>>1;
273
                used = count*2;
274
                while (count > 0) {
275
                        u_short data;
276
                        if (get_user(data, (u_short __user *)userPtr))
277
                                return -EFAULT;
278
                        userPtr += 2;
279
                        data ^= 0x8000;
280
                        *p++ = data;
281
                        *p++ = data;
282
                        count--;
283
                }
284
                *frameUsed += used*2;
285
        } else {
286
                u_long *p = (u_long *)&frame[*frameUsed];
287
                count = min_t(unsigned long, userCount, frameLeft)>>2;
288
                used = count*4;
289
                while (count > 0) {
290
                        u_int data;
291
                        if (get_user(data, (u_int __user *)userPtr))
292
                                return -EFAULT;
293
                        userPtr += 4;
294
                        *p++ = data ^ 0x80008000;
295
                        count--;
296
                }
297
                *frameUsed += used;
298
        }
299
        return used;
300
}
301
 
302
 
303
static ssize_t ata_ct_s16le(const u_char __user *userPtr, size_t userCount,
304
                            u_char frame[], ssize_t *frameUsed,
305
                            ssize_t frameLeft)
306
{
307
        ssize_t count, used;
308
 
309
        count = frameLeft;
310
        if (!dmasound.soft.stereo) {
311
                u_short *p = (u_short *)&frame[*frameUsed];
312
                count = min_t(unsigned long, userCount, frameLeft)>>1;
313
                used = count*2;
314
                while (count > 0) {
315
                        u_short data;
316
                        if (get_user(data, (u_short __user *)userPtr))
317
                                return -EFAULT;
318
                        userPtr += 2;
319
                        data = le2be16(data);
320
                        *p++ = data;
321
                        *p++ = data;
322
                        count--;
323
                }
324
                *frameUsed += used*2;
325
        } else {
326
                u_long *p = (u_long *)&frame[*frameUsed];
327
                count = min_t(unsigned long, userCount, frameLeft)>>2;
328
                used = count*4;
329
                while (count > 0) {
330
                        u_long data;
331
                        if (get_user(data, (u_int __user *)userPtr))
332
                                return -EFAULT;
333
                        userPtr += 4;
334
                        data = le2be16dbl(data);
335
                        *p++ = data;
336
                        count--;
337
                }
338
                *frameUsed += used;
339
        }
340
        return used;
341
}
342
 
343
 
344
static ssize_t ata_ct_u16le(const u_char __user *userPtr, size_t userCount,
345
                            u_char frame[], ssize_t *frameUsed,
346
                            ssize_t frameLeft)
347
{
348
        ssize_t count, used;
349
 
350
        count = frameLeft;
351
        if (!dmasound.soft.stereo) {
352
                u_short *p = (u_short *)&frame[*frameUsed];
353
                count = min_t(unsigned long, userCount, frameLeft)>>1;
354
                used = count*2;
355
                while (count > 0) {
356
                        u_short data;
357
                        if (get_user(data, (u_short __user *)userPtr))
358
                                return -EFAULT;
359
                        userPtr += 2;
360
                        data = le2be16(data) ^ 0x8000;
361
                        *p++ = data;
362
                        *p++ = data;
363
                }
364
                *frameUsed += used*2;
365
        } else {
366
                u_long *p = (u_long *)&frame[*frameUsed];
367
                count = min_t(unsigned long, userCount, frameLeft)>>2;
368
                used = count;
369
                while (count > 0) {
370
                        u_long data;
371
                        if (get_user(data, (u_int __user *)userPtr))
372
                                return -EFAULT;
373
                        userPtr += 4;
374
                        data = le2be16dbl(data) ^ 0x80008000;
375
                        *p++ = data;
376
                        count--;
377
                }
378
                *frameUsed += used;
379
        }
380
        return used;
381
}
382
 
383
 
384
static ssize_t ata_ctx_law(const u_char __user *userPtr, size_t userCount,
385
                           u_char frame[], ssize_t *frameUsed,
386
                           ssize_t frameLeft)
387
{
388
        char *table = dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8
389
                                                          : dmasound_alaw2dma8;
390
        /* this should help gcc to stuff everything into registers */
391
        long bal = expand_bal;
392
        long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
393
        ssize_t used, usedf;
394
 
395
        used = userCount;
396
        usedf = frameLeft;
397
        if (!dmasound.soft.stereo) {
398
                u_char *p = &frame[*frameUsed];
399
                u_char data = expand_data;
400
                while (frameLeft) {
401
                        u_char c;
402
                        if (bal < 0) {
403
                                if (!userCount)
404
                                        break;
405
                                if (get_user(c, userPtr++))
406
                                        return -EFAULT;
407
                                data = table[c];
408
                                userCount--;
409
                                bal += hSpeed;
410
                        }
411
                        *p++ = data;
412
                        frameLeft--;
413
                        bal -= sSpeed;
414
                }
415
                expand_data = data;
416
        } else {
417
                u_short *p = (u_short *)&frame[*frameUsed];
418
                u_short data = expand_data;
419
                while (frameLeft >= 2) {
420
                        u_char c;
421
                        if (bal < 0) {
422
                                if (userCount < 2)
423
                                        break;
424
                                if (get_user(c, userPtr++))
425
                                        return -EFAULT;
426
                                data = table[c] << 8;
427
                                if (get_user(c, userPtr++))
428
                                        return -EFAULT;
429
                                data |= table[c];
430
                                userCount -= 2;
431
                                bal += hSpeed;
432
                        }
433
                        *p++ = data;
434
                        frameLeft -= 2;
435
                        bal -= sSpeed;
436
                }
437
                expand_data = data;
438
        }
439
        expand_bal = bal;
440
        used -= userCount;
441
        *frameUsed += usedf-frameLeft;
442
        return used;
443
}
444
 
445
 
446
static ssize_t ata_ctx_s8(const u_char __user *userPtr, size_t userCount,
447
                          u_char frame[], ssize_t *frameUsed,
448
                          ssize_t frameLeft)
449
{
450
        /* this should help gcc to stuff everything into registers */
451
        long bal = expand_bal;
452
        long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
453
        ssize_t used, usedf;
454
 
455
        used = userCount;
456
        usedf = frameLeft;
457
        if (!dmasound.soft.stereo) {
458
                u_char *p = &frame[*frameUsed];
459
                u_char data = expand_data;
460
                while (frameLeft) {
461
                        if (bal < 0) {
462
                                if (!userCount)
463
                                        break;
464
                                if (get_user(data, userPtr++))
465
                                        return -EFAULT;
466
                                userCount--;
467
                                bal += hSpeed;
468
                        }
469
                        *p++ = data;
470
                        frameLeft--;
471
                        bal -= sSpeed;
472
                }
473
                expand_data = data;
474
        } else {
475
                u_short *p = (u_short *)&frame[*frameUsed];
476
                u_short data = expand_data;
477
                while (frameLeft >= 2) {
478
                        if (bal < 0) {
479
                                if (userCount < 2)
480
                                        break;
481
                                if (get_user(data, (u_short __user *)userPtr))
482
                                        return -EFAULT;
483
                                userPtr += 2;
484
                                userCount -= 2;
485
                                bal += hSpeed;
486
                        }
487
                        *p++ = data;
488
                        frameLeft -= 2;
489
                        bal -= sSpeed;
490
                }
491
                expand_data = data;
492
        }
493
        expand_bal = bal;
494
        used -= userCount;
495
        *frameUsed += usedf-frameLeft;
496
        return used;
497
}
498
 
499
 
500
static ssize_t ata_ctx_u8(const u_char __user *userPtr, size_t userCount,
501
                          u_char frame[], ssize_t *frameUsed,
502
                          ssize_t frameLeft)
503
{
504
        /* this should help gcc to stuff everything into registers */
505
        long bal = expand_bal;
506
        long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
507
        ssize_t used, usedf;
508
 
509
        used = userCount;
510
        usedf = frameLeft;
511
        if (!dmasound.soft.stereo) {
512
                u_char *p = &frame[*frameUsed];
513
                u_char data = expand_data;
514
                while (frameLeft) {
515
                        if (bal < 0) {
516
                                if (!userCount)
517
                                        break;
518
                                if (get_user(data, userPtr++))
519
                                        return -EFAULT;
520
                                data ^= 0x80;
521
                                userCount--;
522
                                bal += hSpeed;
523
                        }
524
                        *p++ = data;
525
                        frameLeft--;
526
                        bal -= sSpeed;
527
                }
528
                expand_data = data;
529
        } else {
530
                u_short *p = (u_short *)&frame[*frameUsed];
531
                u_short data = expand_data;
532
                while (frameLeft >= 2) {
533
                        if (bal < 0) {
534
                                if (userCount < 2)
535
                                        break;
536
                                if (get_user(data, (u_short __user *)userPtr))
537
                                        return -EFAULT;
538
                                userPtr += 2;
539
                                data ^= 0x8080;
540
                                userCount -= 2;
541
                                bal += hSpeed;
542
                        }
543
                        *p++ = data;
544
                        frameLeft -= 2;
545
                        bal -= sSpeed;
546
                }
547
                expand_data = data;
548
        }
549
        expand_bal = bal;
550
        used -= userCount;
551
        *frameUsed += usedf-frameLeft;
552
        return used;
553
}
554
 
555
 
556
static ssize_t ata_ctx_s16be(const u_char __user *userPtr, size_t userCount,
557
                             u_char frame[], ssize_t *frameUsed,
558
                             ssize_t frameLeft)
559
{
560
        /* this should help gcc to stuff everything into registers */
561
        long bal = expand_bal;
562
        long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
563
        ssize_t used, usedf;
564
 
565
        used = userCount;
566
        usedf = frameLeft;
567
        if (!dmasound.soft.stereo) {
568
                u_short *p = (u_short *)&frame[*frameUsed];
569
                u_short data = expand_data;
570
                while (frameLeft >= 4) {
571
                        if (bal < 0) {
572
                                if (userCount < 2)
573
                                        break;
574
                                if (get_user(data, (u_short __user *)userPtr))
575
                                        return -EFAULT;
576
                                userPtr += 2;
577
                                userCount -= 2;
578
                                bal += hSpeed;
579
                        }
580
                        *p++ = data;
581
                        *p++ = data;
582
                        frameLeft -= 4;
583
                        bal -= sSpeed;
584
                }
585
                expand_data = data;
586
        } else {
587
                u_long *p = (u_long *)&frame[*frameUsed];
588
                u_long data = expand_data;
589
                while (frameLeft >= 4) {
590
                        if (bal < 0) {
591
                                if (userCount < 4)
592
                                        break;
593
                                if (get_user(data, (u_int __user *)userPtr))
594
                                        return -EFAULT;
595
                                userPtr += 4;
596
                                userCount -= 4;
597
                                bal += hSpeed;
598
                        }
599
                        *p++ = data;
600
                        frameLeft -= 4;
601
                        bal -= sSpeed;
602
                }
603
                expand_data = data;
604
        }
605
        expand_bal = bal;
606
        used -= userCount;
607
        *frameUsed += usedf-frameLeft;
608
        return used;
609
}
610
 
611
 
612
static ssize_t ata_ctx_u16be(const u_char __user *userPtr, size_t userCount,
613
                             u_char frame[], ssize_t *frameUsed,
614
                             ssize_t frameLeft)
615
{
616
        /* this should help gcc to stuff everything into registers */
617
        long bal = expand_bal;
618
        long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
619
        ssize_t used, usedf;
620
 
621
        used = userCount;
622
        usedf = frameLeft;
623
        if (!dmasound.soft.stereo) {
624
                u_short *p = (u_short *)&frame[*frameUsed];
625
                u_short data = expand_data;
626
                while (frameLeft >= 4) {
627
                        if (bal < 0) {
628
                                if (userCount < 2)
629
                                        break;
630
                                if (get_user(data, (u_short __user *)userPtr))
631
                                        return -EFAULT;
632
                                userPtr += 2;
633
                                data ^= 0x8000;
634
                                userCount -= 2;
635
                                bal += hSpeed;
636
                        }
637
                        *p++ = data;
638
                        *p++ = data;
639
                        frameLeft -= 4;
640
                        bal -= sSpeed;
641
                }
642
                expand_data = data;
643
        } else {
644
                u_long *p = (u_long *)&frame[*frameUsed];
645
                u_long data = expand_data;
646
                while (frameLeft >= 4) {
647
                        if (bal < 0) {
648
                                if (userCount < 4)
649
                                        break;
650
                                if (get_user(data, (u_int __user *)userPtr))
651
                                        return -EFAULT;
652
                                userPtr += 4;
653
                                data ^= 0x80008000;
654
                                userCount -= 4;
655
                                bal += hSpeed;
656
                        }
657
                        *p++ = data;
658
                        frameLeft -= 4;
659
                        bal -= sSpeed;
660
                }
661
                expand_data = data;
662
        }
663
        expand_bal = bal;
664
        used -= userCount;
665
        *frameUsed += usedf-frameLeft;
666
        return used;
667
}
668
 
669
 
670
static ssize_t ata_ctx_s16le(const u_char __user *userPtr, size_t userCount,
671
                             u_char frame[], ssize_t *frameUsed,
672
                             ssize_t frameLeft)
673
{
674
        /* this should help gcc to stuff everything into registers */
675
        long bal = expand_bal;
676
        long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
677
        ssize_t used, usedf;
678
 
679
        used = userCount;
680
        usedf = frameLeft;
681
        if (!dmasound.soft.stereo) {
682
                u_short *p = (u_short *)&frame[*frameUsed];
683
                u_short data = expand_data;
684
                while (frameLeft >= 4) {
685
                        if (bal < 0) {
686
                                if (userCount < 2)
687
                                        break;
688
                                if (get_user(data, (u_short __user *)userPtr))
689
                                        return -EFAULT;
690
                                userPtr += 2;
691
                                data = le2be16(data);
692
                                userCount -= 2;
693
                                bal += hSpeed;
694
                        }
695
                        *p++ = data;
696
                        *p++ = data;
697
                        frameLeft -= 4;
698
                        bal -= sSpeed;
699
                }
700
                expand_data = data;
701
        } else {
702
                u_long *p = (u_long *)&frame[*frameUsed];
703
                u_long data = expand_data;
704
                while (frameLeft >= 4) {
705
                        if (bal < 0) {
706
                                if (userCount < 4)
707
                                        break;
708
                                if (get_user(data, (u_int __user *)userPtr))
709
                                        return -EFAULT;
710
                                userPtr += 4;
711
                                data = le2be16dbl(data);
712
                                userCount -= 4;
713
                                bal += hSpeed;
714
                        }
715
                        *p++ = data;
716
                        frameLeft -= 4;
717
                        bal -= sSpeed;
718
                }
719
                expand_data = data;
720
        }
721
        expand_bal = bal;
722
        used -= userCount;
723
        *frameUsed += usedf-frameLeft;
724
        return used;
725
}
726
 
727
 
728
static ssize_t ata_ctx_u16le(const u_char __user *userPtr, size_t userCount,
729
                             u_char frame[], ssize_t *frameUsed,
730
                             ssize_t frameLeft)
731
{
732
        /* this should help gcc to stuff everything into registers */
733
        long bal = expand_bal;
734
        long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
735
        ssize_t used, usedf;
736
 
737
        used = userCount;
738
        usedf = frameLeft;
739
        if (!dmasound.soft.stereo) {
740
                u_short *p = (u_short *)&frame[*frameUsed];
741
                u_short data = expand_data;
742
                while (frameLeft >= 4) {
743
                        if (bal < 0) {
744
                                if (userCount < 2)
745
                                        break;
746
                                if (get_user(data, (u_short __user *)userPtr))
747
                                        return -EFAULT;
748
                                userPtr += 2;
749
                                data = le2be16(data) ^ 0x8000;
750
                                userCount -= 2;
751
                                bal += hSpeed;
752
                        }
753
                        *p++ = data;
754
                        *p++ = data;
755
                        frameLeft -= 4;
756
                        bal -= sSpeed;
757
                }
758
                expand_data = data;
759
        } else {
760
                u_long *p = (u_long *)&frame[*frameUsed];
761
                u_long data = expand_data;
762
                while (frameLeft >= 4) {
763
                        if (bal < 0) {
764
                                if (userCount < 4)
765
                                        break;
766
                                if (get_user(data, (u_int __user *)userPtr))
767
                                        return -EFAULT;
768
                                userPtr += 4;
769
                                data = le2be16dbl(data) ^ 0x80008000;
770
                                userCount -= 4;
771
                                bal += hSpeed;
772
                        }
773
                        *p++ = data;
774
                        frameLeft -= 4;
775
                        bal -= sSpeed;
776
                }
777
                expand_data = data;
778
        }
779
        expand_bal = bal;
780
        used -= userCount;
781
        *frameUsed += usedf-frameLeft;
782
        return used;
783
}
784
 
785
 
786
static TRANS transTTNormal = {
787
        .ct_ulaw        = ata_ct_law,
788
        .ct_alaw        = ata_ct_law,
789
        .ct_s8          = ata_ct_s8,
790
        .ct_u8          = ata_ct_u8,
791
};
792
 
793
static TRANS transTTExpanding = {
794
        .ct_ulaw        = ata_ctx_law,
795
        .ct_alaw        = ata_ctx_law,
796
        .ct_s8          = ata_ctx_s8,
797
        .ct_u8          = ata_ctx_u8,
798
};
799
 
800
static TRANS transFalconNormal = {
801
        .ct_ulaw        = ata_ct_law,
802
        .ct_alaw        = ata_ct_law,
803
        .ct_s8          = ata_ct_s8,
804
        .ct_u8          = ata_ct_u8,
805
        .ct_s16be       = ata_ct_s16be,
806
        .ct_u16be       = ata_ct_u16be,
807
        .ct_s16le       = ata_ct_s16le,
808
        .ct_u16le       = ata_ct_u16le
809
};
810
 
811
static TRANS transFalconExpanding = {
812
        .ct_ulaw        = ata_ctx_law,
813
        .ct_alaw        = ata_ctx_law,
814
        .ct_s8          = ata_ctx_s8,
815
        .ct_u8          = ata_ctx_u8,
816
        .ct_s16be       = ata_ctx_s16be,
817
        .ct_u16be       = ata_ctx_u16be,
818
        .ct_s16le       = ata_ctx_s16le,
819
        .ct_u16le       = ata_ctx_u16le,
820
};
821
 
822
 
823
/*** Low level stuff *********************************************************/
824
 
825
 
826
 
827
/*
828
 * Atari (TT/Falcon)
829
 */
830
 
831
static void *AtaAlloc(unsigned int size, gfp_t flags)
832
{
833
        return atari_stram_alloc(size, "dmasound");
834
}
835
 
836
static void AtaFree(void *obj, unsigned int size)
837
{
838
        atari_stram_free( obj );
839
}
840
 
841
static int __init AtaIrqInit(void)
842
{
843
        /* Set up timer A. Timer A
844
           will receive a signal upon end of playing from the sound
845
           hardware. Furthermore Timer A is able to count events
846
           and will cause an interrupt after a programmed number
847
           of events. So all we need to keep the music playing is
848
           to provide the sound hardware with new data upon
849
           an interrupt from timer A. */
850
        mfp.tim_ct_a = 0;        /* ++roman: Stop timer before programming! */
851
        mfp.tim_dt_a = 1;       /* Cause interrupt after first event. */
852
        mfp.tim_ct_a = 8;       /* Turn on event counting. */
853
        /* Register interrupt handler. */
854
        request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound",
855
                    AtaInterrupt);
856
        mfp.int_en_a |= 0x20;   /* Turn interrupt on. */
857
        mfp.int_mk_a |= 0x20;
858
        return 1;
859
}
860
 
861
#ifdef MODULE
862
static void AtaIrqCleanUp(void)
863
{
864
        mfp.tim_ct_a = 0;        /* stop timer */
865
        mfp.int_en_a &= ~0x20;  /* turn interrupt off */
866
        free_irq(IRQ_MFP_TIMA, AtaInterrupt);
867
}
868
#endif /* MODULE */
869
 
870
 
871
#define TONE_VOXWARE_TO_DB(v) \
872
        (((v) < 0) ? -12 : ((v) > 100) ? 12 : ((v) - 50) * 6 / 25)
873
#define TONE_DB_TO_VOXWARE(v) (((v) * 25 + ((v) > 0 ? 5 : -5)) / 6 + 50)
874
 
875
 
876
static int AtaSetBass(int bass)
877
{
878
        dmasound.bass = TONE_VOXWARE_TO_DB(bass);
879
        atari_microwire_cmd(MW_LM1992_BASS(dmasound.bass));
880
        return TONE_DB_TO_VOXWARE(dmasound.bass);
881
}
882
 
883
 
884
static int AtaSetTreble(int treble)
885
{
886
        dmasound.treble = TONE_VOXWARE_TO_DB(treble);
887
        atari_microwire_cmd(MW_LM1992_TREBLE(dmasound.treble));
888
        return TONE_DB_TO_VOXWARE(dmasound.treble);
889
}
890
 
891
 
892
 
893
/*
894
 * TT
895
 */
896
 
897
 
898
static void TTSilence(void)
899
{
900
        tt_dmasnd.ctrl = DMASND_CTRL_OFF;
901
        atari_microwire_cmd(MW_LM1992_PSG_HIGH); /* mix in PSG signal 1:1 */
902
}
903
 
904
 
905
static void TTInit(void)
906
{
907
        int mode, i, idx;
908
        const int freq[4] = {50066, 25033, 12517, 6258};
909
 
910
        /* search a frequency that fits into the allowed error range */
911
 
912
        idx = -1;
913
        for (i = 0; i < ARRAY_SIZE(freq); i++)
914
                /* this isn't as much useful for a TT than for a Falcon, but
915
                 * then it doesn't hurt very much to implement it for a TT too.
916
                 */
917
                if ((100 * abs(dmasound.soft.speed - freq[i]) / freq[i]) < catchRadius)
918
                        idx = i;
919
        if (idx > -1) {
920
                dmasound.soft.speed = freq[idx];
921
                dmasound.trans_write = &transTTNormal;
922
        } else
923
                dmasound.trans_write = &transTTExpanding;
924
 
925
        TTSilence();
926
        dmasound.hard = dmasound.soft;
927
 
928
        if (dmasound.hard.speed > 50066) {
929
                /* we would need to squeeze the sound, but we won't do that */
930
                dmasound.hard.speed = 50066;
931
                mode = DMASND_MODE_50KHZ;
932
                dmasound.trans_write = &transTTNormal;
933
        } else if (dmasound.hard.speed > 25033) {
934
                dmasound.hard.speed = 50066;
935
                mode = DMASND_MODE_50KHZ;
936
        } else if (dmasound.hard.speed > 12517) {
937
                dmasound.hard.speed = 25033;
938
                mode = DMASND_MODE_25KHZ;
939
        } else if (dmasound.hard.speed > 6258) {
940
                dmasound.hard.speed = 12517;
941
                mode = DMASND_MODE_12KHZ;
942
        } else {
943
                dmasound.hard.speed = 6258;
944
                mode = DMASND_MODE_6KHZ;
945
        }
946
 
947
        tt_dmasnd.mode = (dmasound.hard.stereo ?
948
                          DMASND_MODE_STEREO : DMASND_MODE_MONO) |
949
                DMASND_MODE_8BIT | mode;
950
 
951
        expand_bal = -dmasound.soft.speed;
952
}
953
 
954
 
955
static int TTSetFormat(int format)
956
{
957
        /* TT sound DMA supports only 8bit modes */
958
 
959
        switch (format) {
960
        case AFMT_QUERY:
961
                return dmasound.soft.format;
962
        case AFMT_MU_LAW:
963
        case AFMT_A_LAW:
964
        case AFMT_S8:
965
        case AFMT_U8:
966
                break;
967
        default:
968
                format = AFMT_S8;
969
        }
970
 
971
        dmasound.soft.format = format;
972
        dmasound.soft.size = 8;
973
        if (dmasound.minDev == SND_DEV_DSP) {
974
                dmasound.dsp.format = format;
975
                dmasound.dsp.size = 8;
976
        }
977
        TTInit();
978
 
979
        return format;
980
}
981
 
982
 
983
#define VOLUME_VOXWARE_TO_DB(v) \
984
        (((v) < 0) ? -40 : ((v) > 100) ? 0 : ((v) * 2) / 5 - 40)
985
#define VOLUME_DB_TO_VOXWARE(v) ((((v) + 40) * 5 + 1) / 2)
986
 
987
 
988
static int TTSetVolume(int volume)
989
{
990
        dmasound.volume_left = VOLUME_VOXWARE_TO_DB(volume & 0xff);
991
        atari_microwire_cmd(MW_LM1992_BALLEFT(dmasound.volume_left));
992
        dmasound.volume_right = VOLUME_VOXWARE_TO_DB((volume & 0xff00) >> 8);
993
        atari_microwire_cmd(MW_LM1992_BALRIGHT(dmasound.volume_right));
994
        return VOLUME_DB_TO_VOXWARE(dmasound.volume_left) |
995
               (VOLUME_DB_TO_VOXWARE(dmasound.volume_right) << 8);
996
}
997
 
998
 
999
#define GAIN_VOXWARE_TO_DB(v) \
1000
        (((v) < 0) ? -80 : ((v) > 100) ? 0 : ((v) * 4) / 5 - 80)
1001
#define GAIN_DB_TO_VOXWARE(v) ((((v) + 80) * 5 + 1) / 4)
1002
 
1003
static int TTSetGain(int gain)
1004
{
1005
        dmasound.gain = GAIN_VOXWARE_TO_DB(gain);
1006
        atari_microwire_cmd(MW_LM1992_VOLUME(dmasound.gain));
1007
        return GAIN_DB_TO_VOXWARE(dmasound.gain);
1008
}
1009
 
1010
 
1011
 
1012
/*
1013
 * Falcon
1014
 */
1015
 
1016
 
1017
static void FalconSilence(void)
1018
{
1019
        /* stop playback, set sample rate 50kHz for PSG sound */
1020
        tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1021
        tt_dmasnd.mode = DMASND_MODE_50KHZ | DMASND_MODE_STEREO | DMASND_MODE_8BIT;
1022
        tt_dmasnd.int_div = 0; /* STE compatible divider */
1023
        tt_dmasnd.int_ctrl = 0x0;
1024
        tt_dmasnd.cbar_src = 0x0000; /* no matrix inputs */
1025
        tt_dmasnd.cbar_dst = 0x0000; /* no matrix outputs */
1026
        tt_dmasnd.dac_src = 1; /* connect ADC to DAC, disconnect matrix */
1027
        tt_dmasnd.adc_src = 3; /* ADC Input = PSG */
1028
}
1029
 
1030
 
1031
static void FalconInit(void)
1032
{
1033
        int divider, i, idx;
1034
        const int freq[8] = {49170, 32780, 24585, 19668, 16390, 12292, 9834, 8195};
1035
 
1036
        /* search a frequency that fits into the allowed error range */
1037
 
1038
        idx = -1;
1039
        for (i = 0; i < ARRAY_SIZE(freq); i++)
1040
                /* if we will tolerate 3% error 8000Hz->8195Hz (2.38%) would
1041
                 * be playable without expanding, but that now a kernel runtime
1042
                 * option
1043
                 */
1044
                if ((100 * abs(dmasound.soft.speed - freq[i]) / freq[i]) < catchRadius)
1045
                        idx = i;
1046
        if (idx > -1) {
1047
                dmasound.soft.speed = freq[idx];
1048
                dmasound.trans_write = &transFalconNormal;
1049
        } else
1050
                dmasound.trans_write = &transFalconExpanding;
1051
 
1052
        FalconSilence();
1053
        dmasound.hard = dmasound.soft;
1054
 
1055
        if (dmasound.hard.size == 16) {
1056
                /* the Falcon can play 16bit samples only in stereo */
1057
                dmasound.hard.stereo = 1;
1058
        }
1059
 
1060
        if (dmasound.hard.speed > 49170) {
1061
                /* we would need to squeeze the sound, but we won't do that */
1062
                dmasound.hard.speed = 49170;
1063
                divider = 1;
1064
                dmasound.trans_write = &transFalconNormal;
1065
        } else if (dmasound.hard.speed > 32780) {
1066
                dmasound.hard.speed = 49170;
1067
                divider = 1;
1068
        } else if (dmasound.hard.speed > 24585) {
1069
                dmasound.hard.speed = 32780;
1070
                divider = 2;
1071
        } else if (dmasound.hard.speed > 19668) {
1072
                dmasound.hard.speed = 24585;
1073
                divider = 3;
1074
        } else if (dmasound.hard.speed > 16390) {
1075
                dmasound.hard.speed = 19668;
1076
                divider = 4;
1077
        } else if (dmasound.hard.speed > 12292) {
1078
                dmasound.hard.speed = 16390;
1079
                divider = 5;
1080
        } else if (dmasound.hard.speed > 9834) {
1081
                dmasound.hard.speed = 12292;
1082
                divider = 7;
1083
        } else if (dmasound.hard.speed > 8195) {
1084
                dmasound.hard.speed = 9834;
1085
                divider = 9;
1086
        } else {
1087
                dmasound.hard.speed = 8195;
1088
                divider = 11;
1089
        }
1090
        tt_dmasnd.int_div = divider;
1091
 
1092
        /* Setup Falcon sound DMA for playback */
1093
        tt_dmasnd.int_ctrl = 0x4; /* Timer A int at play end */
1094
        tt_dmasnd.track_select = 0x0; /* play 1 track, track 1 */
1095
        tt_dmasnd.cbar_src = 0x0001; /* DMA(25MHz) --> DAC */
1096
        tt_dmasnd.cbar_dst = 0x0000;
1097
        tt_dmasnd.rec_track_select = 0;
1098
        tt_dmasnd.dac_src = 2; /* connect matrix to DAC */
1099
        tt_dmasnd.adc_src = 0; /* ADC Input = Mic */
1100
 
1101
        tt_dmasnd.mode = (dmasound.hard.stereo ?
1102
                          DMASND_MODE_STEREO : DMASND_MODE_MONO) |
1103
                ((dmasound.hard.size == 8) ?
1104
                 DMASND_MODE_8BIT : DMASND_MODE_16BIT) |
1105
                DMASND_MODE_6KHZ;
1106
 
1107
        expand_bal = -dmasound.soft.speed;
1108
}
1109
 
1110
 
1111
static int FalconSetFormat(int format)
1112
{
1113
        int size;
1114
        /* Falcon sound DMA supports 8bit and 16bit modes */
1115
 
1116
        switch (format) {
1117
        case AFMT_QUERY:
1118
                return dmasound.soft.format;
1119
        case AFMT_MU_LAW:
1120
        case AFMT_A_LAW:
1121
        case AFMT_U8:
1122
        case AFMT_S8:
1123
                size = 8;
1124
                break;
1125
        case AFMT_S16_BE:
1126
        case AFMT_U16_BE:
1127
        case AFMT_S16_LE:
1128
        case AFMT_U16_LE:
1129
                size = 16;
1130
                break;
1131
        default: /* :-) */
1132
                size = 8;
1133
                format = AFMT_S8;
1134
        }
1135
 
1136
        dmasound.soft.format = format;
1137
        dmasound.soft.size = size;
1138
        if (dmasound.minDev == SND_DEV_DSP) {
1139
                dmasound.dsp.format = format;
1140
                dmasound.dsp.size = dmasound.soft.size;
1141
        }
1142
 
1143
        FalconInit();
1144
 
1145
        return format;
1146
}
1147
 
1148
 
1149
/* This is for the Falcon output *attenuation* in 1.5dB steps,
1150
 * i.e. output level from 0 to -22.5dB in -1.5dB steps.
1151
 */
1152
#define VOLUME_VOXWARE_TO_ATT(v) \
1153
        ((v) < 0 ? 15 : (v) > 100 ? 0 : 15 - (v) * 3 / 20)
1154
#define VOLUME_ATT_TO_VOXWARE(v) (100 - (v) * 20 / 3)
1155
 
1156
 
1157
static int FalconSetVolume(int volume)
1158
{
1159
        dmasound.volume_left = VOLUME_VOXWARE_TO_ATT(volume & 0xff);
1160
        dmasound.volume_right = VOLUME_VOXWARE_TO_ATT((volume & 0xff00) >> 8);
1161
        tt_dmasnd.output_atten = dmasound.volume_left << 8 | dmasound.volume_right << 4;
1162
        return VOLUME_ATT_TO_VOXWARE(dmasound.volume_left) |
1163
               VOLUME_ATT_TO_VOXWARE(dmasound.volume_right) << 8;
1164
}
1165
 
1166
 
1167
static void AtaPlayNextFrame(int index)
1168
{
1169
        char *start, *end;
1170
 
1171
        /* used by AtaPlay() if all doubts whether there really is something
1172
         * to be played are already wiped out.
1173
         */
1174
        start = write_sq.buffers[write_sq.front];
1175
        end = start+((write_sq.count == index) ? write_sq.rear_size
1176
                                               : write_sq.block_size);
1177
        /* end might not be a legal virtual address. */
1178
        DMASNDSetEnd(virt_to_phys(end - 1) + 1);
1179
        DMASNDSetBase(virt_to_phys(start));
1180
        /* Since only an even number of samples per frame can
1181
           be played, we might lose one byte here. (TO DO) */
1182
        write_sq.front = (write_sq.front+1) % write_sq.max_count;
1183
        write_sq.active++;
1184
        tt_dmasnd.ctrl = DMASND_CTRL_ON | DMASND_CTRL_REPEAT;
1185
}
1186
 
1187
 
1188
static void AtaPlay(void)
1189
{
1190
        /* ++TeSche: Note that write_sq.active is no longer just a flag but
1191
         * holds the number of frames the DMA is currently programmed for
1192
         * instead, may be 0, 1 (currently being played) or 2 (pre-programmed).
1193
         *
1194
         * Changes done to write_sq.count and write_sq.active are a bit more
1195
         * subtle again so now I must admit I also prefer disabling the irq
1196
         * here rather than considering all possible situations. But the point
1197
         * is that disabling the irq doesn't have any bad influence on this
1198
         * version of the driver as we benefit from having pre-programmed the
1199
         * DMA wherever possible: There's no need to reload the DMA at the
1200
         * exact time of an interrupt but only at some time while the
1201
         * pre-programmed frame is playing!
1202
         */
1203
        atari_disable_irq(IRQ_MFP_TIMA);
1204
 
1205
        if (write_sq.active == 2 ||     /* DMA is 'full' */
1206
            write_sq.count <= 0) {       /* nothing to do */
1207
                atari_enable_irq(IRQ_MFP_TIMA);
1208
                return;
1209
        }
1210
 
1211
        if (write_sq.active == 0) {
1212
                /* looks like there's nothing 'in' the DMA yet, so try
1213
                 * to put two frames into it (at least one is available).
1214
                 */
1215
                if (write_sq.count == 1 &&
1216
                    write_sq.rear_size < write_sq.block_size &&
1217
                    !write_sq.syncing) {
1218
                        /* hmmm, the only existing frame is not
1219
                         * yet filled and we're not syncing?
1220
                         */
1221
                        atari_enable_irq(IRQ_MFP_TIMA);
1222
                        return;
1223
                }
1224
                AtaPlayNextFrame(1);
1225
                if (write_sq.count == 1) {
1226
                        /* no more frames */
1227
                        atari_enable_irq(IRQ_MFP_TIMA);
1228
                        return;
1229
                }
1230
                if (write_sq.count == 2 &&
1231
                    write_sq.rear_size < write_sq.block_size &&
1232
                    !write_sq.syncing) {
1233
                        /* hmmm, there were two frames, but the second
1234
                         * one is not yet filled and we're not syncing?
1235
                         */
1236
                        atari_enable_irq(IRQ_MFP_TIMA);
1237
                        return;
1238
                }
1239
                AtaPlayNextFrame(2);
1240
        } else {
1241
                /* there's already a frame being played so we may only stuff
1242
                 * one new into the DMA, but even if this may be the last
1243
                 * frame existing the previous one is still on write_sq.count.
1244
                 */
1245
                if (write_sq.count == 2 &&
1246
                    write_sq.rear_size < write_sq.block_size &&
1247
                    !write_sq.syncing) {
1248
                        /* hmmm, the only existing frame is not
1249
                         * yet filled and we're not syncing?
1250
                         */
1251
                        atari_enable_irq(IRQ_MFP_TIMA);
1252
                        return;
1253
                }
1254
                AtaPlayNextFrame(2);
1255
        }
1256
        atari_enable_irq(IRQ_MFP_TIMA);
1257
}
1258
 
1259
 
1260
static irqreturn_t AtaInterrupt(int irq, void *dummy)
1261
{
1262
#if 0
1263
        /* ++TeSche: if you should want to test this... */
1264
        static int cnt;
1265
        if (write_sq.active == 2)
1266
                if (++cnt == 10) {
1267
                        /* simulate losing an interrupt */
1268
                        cnt = 0;
1269
                        return IRQ_HANDLED;
1270
                }
1271
#endif
1272
        spin_lock(&dmasound.lock);
1273
        if (write_sq_ignore_int && is_falcon) {
1274
                /* ++TeSche: Falcon only: ignore first irq because it comes
1275
                 * immediately after starting a frame. after that, irqs come
1276
                 * (almost) like on the TT.
1277
                 */
1278
                write_sq_ignore_int = 0;
1279
                return IRQ_HANDLED;
1280
        }
1281
 
1282
        if (!write_sq.active) {
1283
                /* playing was interrupted and sq_reset() has already cleared
1284
                 * the sq variables, so better don't do anything here.
1285
                 */
1286
                WAKE_UP(write_sq.sync_queue);
1287
                return IRQ_HANDLED;
1288
        }
1289
 
1290
        /* Probably ;) one frame is finished. Well, in fact it may be that a
1291
         * pre-programmed one is also finished because there has been a long
1292
         * delay in interrupt delivery and we've completely lost one, but
1293
         * there's no way to detect such a situation. In such a case the last
1294
         * frame will be played more than once and the situation will recover
1295
         * as soon as the irq gets through.
1296
         */
1297
        write_sq.count--;
1298
        write_sq.active--;
1299
 
1300
        if (!write_sq.active) {
1301
                tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1302
                write_sq_ignore_int = 1;
1303
        }
1304
 
1305
        WAKE_UP(write_sq.action_queue);
1306
        /* At least one block of the queue is free now
1307
           so wake up a writing process blocked because
1308
           of a full queue. */
1309
 
1310
        if ((write_sq.active != 1) || (write_sq.count != 1))
1311
                /* We must be a bit carefully here: write_sq.count indicates the
1312
                 * number of buffers used and not the number of frames to be
1313
                 * played. If write_sq.count==1 and write_sq.active==1 that
1314
                 * means the only remaining frame was already programmed
1315
                 * earlier (and is currently running) so we mustn't call
1316
                 * AtaPlay() here, otherwise we'll play one frame too much.
1317
                 */
1318
                AtaPlay();
1319
 
1320
        if (!write_sq.active) WAKE_UP(write_sq.sync_queue);
1321
        /* We are not playing after AtaPlay(), so there
1322
           is nothing to play any more. Wake up a process
1323
           waiting for audio output to drain. */
1324
        spin_unlock(&dmasound.lock);
1325
        return IRQ_HANDLED;
1326
}
1327
 
1328
 
1329
/*** Mid level stuff *********************************************************/
1330
 
1331
 
1332
/*
1333
 * /dev/mixer abstraction
1334
 */
1335
 
1336
#define RECLEVEL_VOXWARE_TO_GAIN(v)     \
1337
        ((v) < 0 ? 0 : (v) > 100 ? 15 : (v) * 3 / 20)
1338
#define RECLEVEL_GAIN_TO_VOXWARE(v)     (((v) * 20 + 2) / 3)
1339
 
1340
 
1341
static void __init TTMixerInit(void)
1342
{
1343
        atari_microwire_cmd(MW_LM1992_VOLUME(0));
1344
        dmasound.volume_left = 0;
1345
        atari_microwire_cmd(MW_LM1992_BALLEFT(0));
1346
        dmasound.volume_right = 0;
1347
        atari_microwire_cmd(MW_LM1992_BALRIGHT(0));
1348
        atari_microwire_cmd(MW_LM1992_TREBLE(0));
1349
        atari_microwire_cmd(MW_LM1992_BASS(0));
1350
}
1351
 
1352
static void __init FalconMixerInit(void)
1353
{
1354
        dmasound.volume_left = (tt_dmasnd.output_atten & 0xf00) >> 8;
1355
        dmasound.volume_right = (tt_dmasnd.output_atten & 0xf0) >> 4;
1356
}
1357
 
1358
static int AtaMixerIoctl(u_int cmd, u_long arg)
1359
{
1360
        int data;
1361
        unsigned long flags;
1362
        switch (cmd) {
1363
            case SOUND_MIXER_READ_SPEAKER:
1364
                    if (is_falcon || MACH_IS_TT) {
1365
                            int porta;
1366
                            spin_lock_irqsave(&dmasound.lock, flags);
1367
                            sound_ym.rd_data_reg_sel = 14;
1368
                            porta = sound_ym.rd_data_reg_sel;
1369
                            spin_unlock_irqrestore(&dmasound.lock, flags);
1370
                            return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
1371
                    }
1372
                    break;
1373
            case SOUND_MIXER_WRITE_VOLUME:
1374
                    IOCTL_IN(arg, data);
1375
                    return IOCTL_OUT(arg, dmasound_set_volume(data));
1376
            case SOUND_MIXER_WRITE_SPEAKER:
1377
                    if (is_falcon || MACH_IS_TT) {
1378
                            int porta;
1379
                            IOCTL_IN(arg, data);
1380
                            spin_lock_irqsave(&dmasound.lock, flags);
1381
                            sound_ym.rd_data_reg_sel = 14;
1382
                            porta = (sound_ym.rd_data_reg_sel & ~0x40) |
1383
                                    (data < 50 ? 0x40 : 0);
1384
                            sound_ym.wd_data = porta;
1385
                            spin_unlock_irqrestore(&dmasound.lock, flags);
1386
                            return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
1387
                    }
1388
        }
1389
        return -EINVAL;
1390
}
1391
 
1392
 
1393
static int TTMixerIoctl(u_int cmd, u_long arg)
1394
{
1395
        int data;
1396
        switch (cmd) {
1397
            case SOUND_MIXER_READ_RECMASK:
1398
                return IOCTL_OUT(arg, 0);
1399
            case SOUND_MIXER_READ_DEVMASK:
1400
                return IOCTL_OUT(arg,
1401
                                 SOUND_MASK_VOLUME | SOUND_MASK_TREBLE | SOUND_MASK_BASS |
1402
                                 (MACH_IS_TT ? SOUND_MASK_SPEAKER : 0));
1403
            case SOUND_MIXER_READ_STEREODEVS:
1404
                return IOCTL_OUT(arg, SOUND_MASK_VOLUME);
1405
            case SOUND_MIXER_READ_VOLUME:
1406
                return IOCTL_OUT(arg,
1407
                                 VOLUME_DB_TO_VOXWARE(dmasound.volume_left) |
1408
                                 (VOLUME_DB_TO_VOXWARE(dmasound.volume_right) << 8));
1409
            case SOUND_MIXER_READ_BASS:
1410
                return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(dmasound.bass));
1411
            case SOUND_MIXER_READ_TREBLE:
1412
                return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(dmasound.treble));
1413
            case SOUND_MIXER_READ_OGAIN:
1414
                return IOCTL_OUT(arg, GAIN_DB_TO_VOXWARE(dmasound.gain));
1415
            case SOUND_MIXER_WRITE_BASS:
1416
                IOCTL_IN(arg, data);
1417
                return IOCTL_OUT(arg, dmasound_set_bass(data));
1418
            case SOUND_MIXER_WRITE_TREBLE:
1419
                IOCTL_IN(arg, data);
1420
                return IOCTL_OUT(arg, dmasound_set_treble(data));
1421
            case SOUND_MIXER_WRITE_OGAIN:
1422
                IOCTL_IN(arg, data);
1423
                return IOCTL_OUT(arg, dmasound_set_gain(data));
1424
        }
1425
        return AtaMixerIoctl(cmd, arg);
1426
}
1427
 
1428
static int FalconMixerIoctl(u_int cmd, u_long arg)
1429
{
1430
        int data;
1431
        switch (cmd) {
1432
            case SOUND_MIXER_READ_RECMASK:
1433
                return IOCTL_OUT(arg, SOUND_MASK_MIC);
1434
            case SOUND_MIXER_READ_DEVMASK:
1435
                return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_SPEAKER);
1436
            case SOUND_MIXER_READ_STEREODEVS:
1437
                return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC);
1438
            case SOUND_MIXER_READ_VOLUME:
1439
                return IOCTL_OUT(arg,
1440
                        VOLUME_ATT_TO_VOXWARE(dmasound.volume_left) |
1441
                        VOLUME_ATT_TO_VOXWARE(dmasound.volume_right) << 8);
1442
            case SOUND_MIXER_READ_CAPS:
1443
                return IOCTL_OUT(arg, SOUND_CAP_EXCL_INPUT);
1444
            case SOUND_MIXER_WRITE_MIC:
1445
                IOCTL_IN(arg, data);
1446
                tt_dmasnd.input_gain =
1447
                        RECLEVEL_VOXWARE_TO_GAIN(data & 0xff) << 4 |
1448
                        RECLEVEL_VOXWARE_TO_GAIN(data >> 8 & 0xff);
1449
                /* fall thru, return set value */
1450
            case SOUND_MIXER_READ_MIC:
1451
                return IOCTL_OUT(arg,
1452
                        RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain >> 4 & 0xf) |
1453
                        RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain & 0xf) << 8);
1454
        }
1455
        return AtaMixerIoctl(cmd, arg);
1456
}
1457
 
1458
static int AtaWriteSqSetup(void)
1459
{
1460
        write_sq_ignore_int = 0;
1461
        return 0 ;
1462
}
1463
 
1464
static int AtaSqOpen(mode_t mode)
1465
{
1466
        write_sq_ignore_int = 1;
1467
        return 0 ;
1468
}
1469
 
1470
static int TTStateInfo(char *buffer, size_t space)
1471
{
1472
        int len = 0;
1473
        len += sprintf(buffer+len, "\tvol left  %ddB [-40...  0]\n",
1474
                       dmasound.volume_left);
1475
        len += sprintf(buffer+len, "\tvol right %ddB [-40...  0]\n",
1476
                       dmasound.volume_right);
1477
        len += sprintf(buffer+len, "\tbass      %ddB [-12...+12]\n",
1478
                       dmasound.bass);
1479
        len += sprintf(buffer+len, "\ttreble    %ddB [-12...+12]\n",
1480
                       dmasound.treble);
1481
        if (len >= space) {
1482
                printk(KERN_ERR "dmasound_atari: overflowed state buffer alloc.\n") ;
1483
                len = space ;
1484
        }
1485
        return len;
1486
}
1487
 
1488
static int FalconStateInfo(char *buffer, size_t space)
1489
{
1490
        int len = 0;
1491
        len += sprintf(buffer+len, "\tvol left  %ddB [-22.5 ... 0]\n",
1492
                       dmasound.volume_left);
1493
        len += sprintf(buffer+len, "\tvol right %ddB [-22.5 ... 0]\n",
1494
                       dmasound.volume_right);
1495
        if (len >= space) {
1496
                printk(KERN_ERR "dmasound_atari: overflowed state buffer alloc.\n") ;
1497
                len = space ;
1498
        }
1499
        return len;
1500
}
1501
 
1502
 
1503
/*** Machine definitions *****************************************************/
1504
 
1505
static SETTINGS def_hard_falcon = {
1506
        .format         = AFMT_S8,
1507
        .stereo         = 0,
1508
        .size           = 8,
1509
        .speed          = 8195
1510
} ;
1511
 
1512
static SETTINGS def_hard_tt = {
1513
        .format = AFMT_S8,
1514
        .stereo = 0,
1515
        .size   = 8,
1516
        .speed  = 12517
1517
} ;
1518
 
1519
static SETTINGS def_soft = {
1520
        .format = AFMT_U8,
1521
        .stereo = 0,
1522
        .size   = 8,
1523
        .speed  = 8000
1524
} ;
1525
 
1526
static MACHINE machTT = {
1527
        .name           = "Atari",
1528
        .name2          = "TT",
1529
        .owner          = THIS_MODULE,
1530
        .dma_alloc      = AtaAlloc,
1531
        .dma_free       = AtaFree,
1532
        .irqinit        = AtaIrqInit,
1533
#ifdef MODULE
1534
        .irqcleanup     = AtaIrqCleanUp,
1535
#endif /* MODULE */
1536
        .init           = TTInit,
1537
        .silence        = TTSilence,
1538
        .setFormat      = TTSetFormat,
1539
        .setVolume      = TTSetVolume,
1540
        .setBass        = AtaSetBass,
1541
        .setTreble      = AtaSetTreble,
1542
        .setGain        = TTSetGain,
1543
        .play           = AtaPlay,
1544
        .mixer_init     = TTMixerInit,
1545
        .mixer_ioctl    = TTMixerIoctl,
1546
        .write_sq_setup = AtaWriteSqSetup,
1547
        .sq_open        = AtaSqOpen,
1548
        .state_info     = TTStateInfo,
1549
        .min_dsp_speed  = 6258,
1550
        .version        = ((DMASOUND_ATARI_REVISION<<8) | DMASOUND_ATARI_EDITION),
1551
        .hardware_afmts = AFMT_S8,  /* h'ware-supported formats *only* here */
1552
        .capabilities   =  DSP_CAP_BATCH        /* As per SNDCTL_DSP_GETCAPS */
1553
};
1554
 
1555
static MACHINE machFalcon = {
1556
        .name           = "Atari",
1557
        .name2          = "FALCON",
1558
        .dma_alloc      = AtaAlloc,
1559
        .dma_free       = AtaFree,
1560
        .irqinit        = AtaIrqInit,
1561
#ifdef MODULE
1562
        .irqcleanup     = AtaIrqCleanUp,
1563
#endif /* MODULE */
1564
        .init           = FalconInit,
1565
        .silence        = FalconSilence,
1566
        .setFormat      = FalconSetFormat,
1567
        .setVolume      = FalconSetVolume,
1568
        .setBass        = AtaSetBass,
1569
        .setTreble      = AtaSetTreble,
1570
        .play           = AtaPlay,
1571
        .mixer_init     = FalconMixerInit,
1572
        .mixer_ioctl    = FalconMixerIoctl,
1573
        .write_sq_setup = AtaWriteSqSetup,
1574
        .sq_open        = AtaSqOpen,
1575
        .state_info     = FalconStateInfo,
1576
        .min_dsp_speed  = 8195,
1577
        .version        = ((DMASOUND_ATARI_REVISION<<8) | DMASOUND_ATARI_EDITION),
1578
        .hardware_afmts = (AFMT_S8 | AFMT_S16_BE), /* h'ware-supported formats *only* here */
1579
        .capabilities   =  DSP_CAP_BATCH        /* As per SNDCTL_DSP_GETCAPS */
1580
};
1581
 
1582
 
1583
/*** Config & Setup **********************************************************/
1584
 
1585
 
1586
static int __init dmasound_atari_init(void)
1587
{
1588
        if (MACH_IS_ATARI && ATARIHW_PRESENT(PCM_8BIT)) {
1589
            if (ATARIHW_PRESENT(CODEC)) {
1590
                dmasound.mach = machFalcon;
1591
                dmasound.mach.default_soft = def_soft ;
1592
                dmasound.mach.default_hard = def_hard_falcon ;
1593
                is_falcon = 1;
1594
            } else if (ATARIHW_PRESENT(MICROWIRE)) {
1595
                dmasound.mach = machTT;
1596
                dmasound.mach.default_soft = def_soft ;
1597
                dmasound.mach.default_hard = def_hard_tt ;
1598
                is_falcon = 0;
1599
            } else
1600
                return -ENODEV;
1601
            if ((mfp.int_en_a & mfp.int_mk_a & 0x20) == 0)
1602
                return dmasound_init();
1603
            else {
1604
                printk("DMA sound driver: Timer A interrupt already in use\n");
1605
                return -EBUSY;
1606
            }
1607
        }
1608
        return -ENODEV;
1609
}
1610
 
1611
static void __exit dmasound_atari_cleanup(void)
1612
{
1613
        dmasound_deinit();
1614
}
1615
 
1616
module_init(dmasound_atari_init);
1617
module_exit(dmasound_atari_cleanup);
1618
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

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