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