Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/oss/dmasound/dmasound_atari.c
10817 views
1
/*
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(fmode_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
st_mfp.tim_ct_a = 0; /* ++roman: Stop timer before programming! */
851
st_mfp.tim_dt_a = 1; /* Cause interrupt after first event. */
852
st_mfp.tim_ct_a = 8; /* Turn on event counting. */
853
/* Register interrupt handler. */
854
if (request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound",
855
AtaInterrupt))
856
return 0;
857
st_mfp.int_en_a |= 0x20; /* Turn interrupt on. */
858
st_mfp.int_mk_a |= 0x20;
859
return 1;
860
}
861
862
#ifdef MODULE
863
static void AtaIrqCleanUp(void)
864
{
865
st_mfp.tim_ct_a = 0; /* stop timer */
866
st_mfp.int_en_a &= ~0x20; /* turn interrupt off */
867
free_irq(IRQ_MFP_TIMA, AtaInterrupt);
868
}
869
#endif /* MODULE */
870
871
872
#define TONE_VOXWARE_TO_DB(v) \
873
(((v) < 0) ? -12 : ((v) > 100) ? 12 : ((v) - 50) * 6 / 25)
874
#define TONE_DB_TO_VOXWARE(v) (((v) * 25 + ((v) > 0 ? 5 : -5)) / 6 + 50)
875
876
877
static int AtaSetBass(int bass)
878
{
879
dmasound.bass = TONE_VOXWARE_TO_DB(bass);
880
atari_microwire_cmd(MW_LM1992_BASS(dmasound.bass));
881
return TONE_DB_TO_VOXWARE(dmasound.bass);
882
}
883
884
885
static int AtaSetTreble(int treble)
886
{
887
dmasound.treble = TONE_VOXWARE_TO_DB(treble);
888
atari_microwire_cmd(MW_LM1992_TREBLE(dmasound.treble));
889
return TONE_DB_TO_VOXWARE(dmasound.treble);
890
}
891
892
893
894
/*
895
* TT
896
*/
897
898
899
static void TTSilence(void)
900
{
901
tt_dmasnd.ctrl = DMASND_CTRL_OFF;
902
atari_microwire_cmd(MW_LM1992_PSG_HIGH); /* mix in PSG signal 1:1 */
903
}
904
905
906
static void TTInit(void)
907
{
908
int mode, i, idx;
909
const int freq[4] = {50066, 25033, 12517, 6258};
910
911
/* search a frequency that fits into the allowed error range */
912
913
idx = -1;
914
for (i = 0; i < ARRAY_SIZE(freq); i++)
915
/* this isn't as much useful for a TT than for a Falcon, but
916
* then it doesn't hurt very much to implement it for a TT too.
917
*/
918
if ((100 * abs(dmasound.soft.speed - freq[i]) / freq[i]) < catchRadius)
919
idx = i;
920
if (idx > -1) {
921
dmasound.soft.speed = freq[idx];
922
dmasound.trans_write = &transTTNormal;
923
} else
924
dmasound.trans_write = &transTTExpanding;
925
926
TTSilence();
927
dmasound.hard = dmasound.soft;
928
929
if (dmasound.hard.speed > 50066) {
930
/* we would need to squeeze the sound, but we won't do that */
931
dmasound.hard.speed = 50066;
932
mode = DMASND_MODE_50KHZ;
933
dmasound.trans_write = &transTTNormal;
934
} else if (dmasound.hard.speed > 25033) {
935
dmasound.hard.speed = 50066;
936
mode = DMASND_MODE_50KHZ;
937
} else if (dmasound.hard.speed > 12517) {
938
dmasound.hard.speed = 25033;
939
mode = DMASND_MODE_25KHZ;
940
} else if (dmasound.hard.speed > 6258) {
941
dmasound.hard.speed = 12517;
942
mode = DMASND_MODE_12KHZ;
943
} else {
944
dmasound.hard.speed = 6258;
945
mode = DMASND_MODE_6KHZ;
946
}
947
948
tt_dmasnd.mode = (dmasound.hard.stereo ?
949
DMASND_MODE_STEREO : DMASND_MODE_MONO) |
950
DMASND_MODE_8BIT | mode;
951
952
expand_bal = -dmasound.soft.speed;
953
}
954
955
956
static int TTSetFormat(int format)
957
{
958
/* TT sound DMA supports only 8bit modes */
959
960
switch (format) {
961
case AFMT_QUERY:
962
return dmasound.soft.format;
963
case AFMT_MU_LAW:
964
case AFMT_A_LAW:
965
case AFMT_S8:
966
case AFMT_U8:
967
break;
968
default:
969
format = AFMT_S8;
970
}
971
972
dmasound.soft.format = format;
973
dmasound.soft.size = 8;
974
if (dmasound.minDev == SND_DEV_DSP) {
975
dmasound.dsp.format = format;
976
dmasound.dsp.size = 8;
977
}
978
TTInit();
979
980
return format;
981
}
982
983
984
#define VOLUME_VOXWARE_TO_DB(v) \
985
(((v) < 0) ? -40 : ((v) > 100) ? 0 : ((v) * 2) / 5 - 40)
986
#define VOLUME_DB_TO_VOXWARE(v) ((((v) + 40) * 5 + 1) / 2)
987
988
989
static int TTSetVolume(int volume)
990
{
991
dmasound.volume_left = VOLUME_VOXWARE_TO_DB(volume & 0xff);
992
atari_microwire_cmd(MW_LM1992_BALLEFT(dmasound.volume_left));
993
dmasound.volume_right = VOLUME_VOXWARE_TO_DB((volume & 0xff00) >> 8);
994
atari_microwire_cmd(MW_LM1992_BALRIGHT(dmasound.volume_right));
995
return VOLUME_DB_TO_VOXWARE(dmasound.volume_left) |
996
(VOLUME_DB_TO_VOXWARE(dmasound.volume_right) << 8);
997
}
998
999
1000
#define GAIN_VOXWARE_TO_DB(v) \
1001
(((v) < 0) ? -80 : ((v) > 100) ? 0 : ((v) * 4) / 5 - 80)
1002
#define GAIN_DB_TO_VOXWARE(v) ((((v) + 80) * 5 + 1) / 4)
1003
1004
static int TTSetGain(int gain)
1005
{
1006
dmasound.gain = GAIN_VOXWARE_TO_DB(gain);
1007
atari_microwire_cmd(MW_LM1992_VOLUME(dmasound.gain));
1008
return GAIN_DB_TO_VOXWARE(dmasound.gain);
1009
}
1010
1011
1012
1013
/*
1014
* Falcon
1015
*/
1016
1017
1018
static void FalconSilence(void)
1019
{
1020
/* stop playback, set sample rate 50kHz for PSG sound */
1021
tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1022
tt_dmasnd.mode = DMASND_MODE_50KHZ | DMASND_MODE_STEREO | DMASND_MODE_8BIT;
1023
tt_dmasnd.int_div = 0; /* STE compatible divider */
1024
tt_dmasnd.int_ctrl = 0x0;
1025
tt_dmasnd.cbar_src = 0x0000; /* no matrix inputs */
1026
tt_dmasnd.cbar_dst = 0x0000; /* no matrix outputs */
1027
tt_dmasnd.dac_src = 1; /* connect ADC to DAC, disconnect matrix */
1028
tt_dmasnd.adc_src = 3; /* ADC Input = PSG */
1029
}
1030
1031
1032
static void FalconInit(void)
1033
{
1034
int divider, i, idx;
1035
const int freq[8] = {49170, 32780, 24585, 19668, 16390, 12292, 9834, 8195};
1036
1037
/* search a frequency that fits into the allowed error range */
1038
1039
idx = -1;
1040
for (i = 0; i < ARRAY_SIZE(freq); i++)
1041
/* if we will tolerate 3% error 8000Hz->8195Hz (2.38%) would
1042
* be playable without expanding, but that now a kernel runtime
1043
* option
1044
*/
1045
if ((100 * abs(dmasound.soft.speed - freq[i]) / freq[i]) < catchRadius)
1046
idx = i;
1047
if (idx > -1) {
1048
dmasound.soft.speed = freq[idx];
1049
dmasound.trans_write = &transFalconNormal;
1050
} else
1051
dmasound.trans_write = &transFalconExpanding;
1052
1053
FalconSilence();
1054
dmasound.hard = dmasound.soft;
1055
1056
if (dmasound.hard.size == 16) {
1057
/* the Falcon can play 16bit samples only in stereo */
1058
dmasound.hard.stereo = 1;
1059
}
1060
1061
if (dmasound.hard.speed > 49170) {
1062
/* we would need to squeeze the sound, but we won't do that */
1063
dmasound.hard.speed = 49170;
1064
divider = 1;
1065
dmasound.trans_write = &transFalconNormal;
1066
} else if (dmasound.hard.speed > 32780) {
1067
dmasound.hard.speed = 49170;
1068
divider = 1;
1069
} else if (dmasound.hard.speed > 24585) {
1070
dmasound.hard.speed = 32780;
1071
divider = 2;
1072
} else if (dmasound.hard.speed > 19668) {
1073
dmasound.hard.speed = 24585;
1074
divider = 3;
1075
} else if (dmasound.hard.speed > 16390) {
1076
dmasound.hard.speed = 19668;
1077
divider = 4;
1078
} else if (dmasound.hard.speed > 12292) {
1079
dmasound.hard.speed = 16390;
1080
divider = 5;
1081
} else if (dmasound.hard.speed > 9834) {
1082
dmasound.hard.speed = 12292;
1083
divider = 7;
1084
} else if (dmasound.hard.speed > 8195) {
1085
dmasound.hard.speed = 9834;
1086
divider = 9;
1087
} else {
1088
dmasound.hard.speed = 8195;
1089
divider = 11;
1090
}
1091
tt_dmasnd.int_div = divider;
1092
1093
/* Setup Falcon sound DMA for playback */
1094
tt_dmasnd.int_ctrl = 0x4; /* Timer A int at play end */
1095
tt_dmasnd.track_select = 0x0; /* play 1 track, track 1 */
1096
tt_dmasnd.cbar_src = 0x0001; /* DMA(25MHz) --> DAC */
1097
tt_dmasnd.cbar_dst = 0x0000;
1098
tt_dmasnd.rec_track_select = 0;
1099
tt_dmasnd.dac_src = 2; /* connect matrix to DAC */
1100
tt_dmasnd.adc_src = 0; /* ADC Input = Mic */
1101
1102
tt_dmasnd.mode = (dmasound.hard.stereo ?
1103
DMASND_MODE_STEREO : DMASND_MODE_MONO) |
1104
((dmasound.hard.size == 8) ?
1105
DMASND_MODE_8BIT : DMASND_MODE_16BIT) |
1106
DMASND_MODE_6KHZ;
1107
1108
expand_bal = -dmasound.soft.speed;
1109
}
1110
1111
1112
static int FalconSetFormat(int format)
1113
{
1114
int size;
1115
/* Falcon sound DMA supports 8bit and 16bit modes */
1116
1117
switch (format) {
1118
case AFMT_QUERY:
1119
return dmasound.soft.format;
1120
case AFMT_MU_LAW:
1121
case AFMT_A_LAW:
1122
case AFMT_U8:
1123
case AFMT_S8:
1124
size = 8;
1125
break;
1126
case AFMT_S16_BE:
1127
case AFMT_U16_BE:
1128
case AFMT_S16_LE:
1129
case AFMT_U16_LE:
1130
size = 16;
1131
break;
1132
default: /* :-) */
1133
size = 8;
1134
format = AFMT_S8;
1135
}
1136
1137
dmasound.soft.format = format;
1138
dmasound.soft.size = size;
1139
if (dmasound.minDev == SND_DEV_DSP) {
1140
dmasound.dsp.format = format;
1141
dmasound.dsp.size = dmasound.soft.size;
1142
}
1143
1144
FalconInit();
1145
1146
return format;
1147
}
1148
1149
1150
/* This is for the Falcon output *attenuation* in 1.5dB steps,
1151
* i.e. output level from 0 to -22.5dB in -1.5dB steps.
1152
*/
1153
#define VOLUME_VOXWARE_TO_ATT(v) \
1154
((v) < 0 ? 15 : (v) > 100 ? 0 : 15 - (v) * 3 / 20)
1155
#define VOLUME_ATT_TO_VOXWARE(v) (100 - (v) * 20 / 3)
1156
1157
1158
static int FalconSetVolume(int volume)
1159
{
1160
dmasound.volume_left = VOLUME_VOXWARE_TO_ATT(volume & 0xff);
1161
dmasound.volume_right = VOLUME_VOXWARE_TO_ATT((volume & 0xff00) >> 8);
1162
tt_dmasnd.output_atten = dmasound.volume_left << 8 | dmasound.volume_right << 4;
1163
return VOLUME_ATT_TO_VOXWARE(dmasound.volume_left) |
1164
VOLUME_ATT_TO_VOXWARE(dmasound.volume_right) << 8;
1165
}
1166
1167
1168
static void AtaPlayNextFrame(int index)
1169
{
1170
char *start, *end;
1171
1172
/* used by AtaPlay() if all doubts whether there really is something
1173
* to be played are already wiped out.
1174
*/
1175
start = write_sq.buffers[write_sq.front];
1176
end = start+((write_sq.count == index) ? write_sq.rear_size
1177
: write_sq.block_size);
1178
/* end might not be a legal virtual address. */
1179
DMASNDSetEnd(virt_to_phys(end - 1) + 1);
1180
DMASNDSetBase(virt_to_phys(start));
1181
/* Since only an even number of samples per frame can
1182
be played, we might lose one byte here. (TO DO) */
1183
write_sq.front = (write_sq.front+1) % write_sq.max_count;
1184
write_sq.active++;
1185
tt_dmasnd.ctrl = DMASND_CTRL_ON | DMASND_CTRL_REPEAT;
1186
}
1187
1188
1189
static void AtaPlay(void)
1190
{
1191
/* ++TeSche: Note that write_sq.active is no longer just a flag but
1192
* holds the number of frames the DMA is currently programmed for
1193
* instead, may be 0, 1 (currently being played) or 2 (pre-programmed).
1194
*
1195
* Changes done to write_sq.count and write_sq.active are a bit more
1196
* subtle again so now I must admit I also prefer disabling the irq
1197
* here rather than considering all possible situations. But the point
1198
* is that disabling the irq doesn't have any bad influence on this
1199
* version of the driver as we benefit from having pre-programmed the
1200
* DMA wherever possible: There's no need to reload the DMA at the
1201
* exact time of an interrupt but only at some time while the
1202
* pre-programmed frame is playing!
1203
*/
1204
atari_disable_irq(IRQ_MFP_TIMA);
1205
1206
if (write_sq.active == 2 || /* DMA is 'full' */
1207
write_sq.count <= 0) { /* nothing to do */
1208
atari_enable_irq(IRQ_MFP_TIMA);
1209
return;
1210
}
1211
1212
if (write_sq.active == 0) {
1213
/* looks like there's nothing 'in' the DMA yet, so try
1214
* to put two frames into it (at least one is available).
1215
*/
1216
if (write_sq.count == 1 &&
1217
write_sq.rear_size < write_sq.block_size &&
1218
!write_sq.syncing) {
1219
/* hmmm, the only existing frame is not
1220
* yet filled and we're not syncing?
1221
*/
1222
atari_enable_irq(IRQ_MFP_TIMA);
1223
return;
1224
}
1225
AtaPlayNextFrame(1);
1226
if (write_sq.count == 1) {
1227
/* no more frames */
1228
atari_enable_irq(IRQ_MFP_TIMA);
1229
return;
1230
}
1231
if (write_sq.count == 2 &&
1232
write_sq.rear_size < write_sq.block_size &&
1233
!write_sq.syncing) {
1234
/* hmmm, there were two frames, but the second
1235
* one is not yet filled and we're not syncing?
1236
*/
1237
atari_enable_irq(IRQ_MFP_TIMA);
1238
return;
1239
}
1240
AtaPlayNextFrame(2);
1241
} else {
1242
/* there's already a frame being played so we may only stuff
1243
* one new into the DMA, but even if this may be the last
1244
* frame existing the previous one is still on write_sq.count.
1245
*/
1246
if (write_sq.count == 2 &&
1247
write_sq.rear_size < write_sq.block_size &&
1248
!write_sq.syncing) {
1249
/* hmmm, the only existing frame is not
1250
* yet filled and we're not syncing?
1251
*/
1252
atari_enable_irq(IRQ_MFP_TIMA);
1253
return;
1254
}
1255
AtaPlayNextFrame(2);
1256
}
1257
atari_enable_irq(IRQ_MFP_TIMA);
1258
}
1259
1260
1261
static irqreturn_t AtaInterrupt(int irq, void *dummy)
1262
{
1263
#if 0
1264
/* ++TeSche: if you should want to test this... */
1265
static int cnt;
1266
if (write_sq.active == 2)
1267
if (++cnt == 10) {
1268
/* simulate losing an interrupt */
1269
cnt = 0;
1270
return IRQ_HANDLED;
1271
}
1272
#endif
1273
spin_lock(&dmasound.lock);
1274
if (write_sq_ignore_int && is_falcon) {
1275
/* ++TeSche: Falcon only: ignore first irq because it comes
1276
* immediately after starting a frame. after that, irqs come
1277
* (almost) like on the TT.
1278
*/
1279
write_sq_ignore_int = 0;
1280
goto out;
1281
}
1282
1283
if (!write_sq.active) {
1284
/* playing was interrupted and sq_reset() has already cleared
1285
* the sq variables, so better don't do anything here.
1286
*/
1287
WAKE_UP(write_sq.sync_queue);
1288
goto out;
1289
}
1290
1291
/* Probably ;) one frame is finished. Well, in fact it may be that a
1292
* pre-programmed one is also finished because there has been a long
1293
* delay in interrupt delivery and we've completely lost one, but
1294
* there's no way to detect such a situation. In such a case the last
1295
* frame will be played more than once and the situation will recover
1296
* as soon as the irq gets through.
1297
*/
1298
write_sq.count--;
1299
write_sq.active--;
1300
1301
if (!write_sq.active) {
1302
tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1303
write_sq_ignore_int = 1;
1304
}
1305
1306
WAKE_UP(write_sq.action_queue);
1307
/* At least one block of the queue is free now
1308
so wake up a writing process blocked because
1309
of a full queue. */
1310
1311
if ((write_sq.active != 1) || (write_sq.count != 1))
1312
/* We must be a bit carefully here: write_sq.count indicates the
1313
* number of buffers used and not the number of frames to be
1314
* played. If write_sq.count==1 and write_sq.active==1 that
1315
* means the only remaining frame was already programmed
1316
* earlier (and is currently running) so we mustn't call
1317
* AtaPlay() here, otherwise we'll play one frame too much.
1318
*/
1319
AtaPlay();
1320
1321
if (!write_sq.active) WAKE_UP(write_sq.sync_queue);
1322
/* We are not playing after AtaPlay(), so there
1323
is nothing to play any more. Wake up a process
1324
waiting for audio output to drain. */
1325
out:
1326
spin_unlock(&dmasound.lock);
1327
return IRQ_HANDLED;
1328
}
1329
1330
1331
/*** Mid level stuff *********************************************************/
1332
1333
1334
/*
1335
* /dev/mixer abstraction
1336
*/
1337
1338
#define RECLEVEL_VOXWARE_TO_GAIN(v) \
1339
((v) < 0 ? 0 : (v) > 100 ? 15 : (v) * 3 / 20)
1340
#define RECLEVEL_GAIN_TO_VOXWARE(v) (((v) * 20 + 2) / 3)
1341
1342
1343
static void __init TTMixerInit(void)
1344
{
1345
atari_microwire_cmd(MW_LM1992_VOLUME(0));
1346
dmasound.volume_left = 0;
1347
atari_microwire_cmd(MW_LM1992_BALLEFT(0));
1348
dmasound.volume_right = 0;
1349
atari_microwire_cmd(MW_LM1992_BALRIGHT(0));
1350
atari_microwire_cmd(MW_LM1992_TREBLE(0));
1351
atari_microwire_cmd(MW_LM1992_BASS(0));
1352
}
1353
1354
static void __init FalconMixerInit(void)
1355
{
1356
dmasound.volume_left = (tt_dmasnd.output_atten & 0xf00) >> 8;
1357
dmasound.volume_right = (tt_dmasnd.output_atten & 0xf0) >> 4;
1358
}
1359
1360
static int AtaMixerIoctl(u_int cmd, u_long arg)
1361
{
1362
int data;
1363
unsigned long flags;
1364
switch (cmd) {
1365
case SOUND_MIXER_READ_SPEAKER:
1366
if (is_falcon || MACH_IS_TT) {
1367
int porta;
1368
spin_lock_irqsave(&dmasound.lock, flags);
1369
sound_ym.rd_data_reg_sel = 14;
1370
porta = sound_ym.rd_data_reg_sel;
1371
spin_unlock_irqrestore(&dmasound.lock, flags);
1372
return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
1373
}
1374
break;
1375
case SOUND_MIXER_WRITE_VOLUME:
1376
IOCTL_IN(arg, data);
1377
return IOCTL_OUT(arg, dmasound_set_volume(data));
1378
case SOUND_MIXER_WRITE_SPEAKER:
1379
if (is_falcon || MACH_IS_TT) {
1380
int porta;
1381
IOCTL_IN(arg, data);
1382
spin_lock_irqsave(&dmasound.lock, flags);
1383
sound_ym.rd_data_reg_sel = 14;
1384
porta = (sound_ym.rd_data_reg_sel & ~0x40) |
1385
(data < 50 ? 0x40 : 0);
1386
sound_ym.wd_data = porta;
1387
spin_unlock_irqrestore(&dmasound.lock, flags);
1388
return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
1389
}
1390
}
1391
return -EINVAL;
1392
}
1393
1394
1395
static int TTMixerIoctl(u_int cmd, u_long arg)
1396
{
1397
int data;
1398
switch (cmd) {
1399
case SOUND_MIXER_READ_RECMASK:
1400
return IOCTL_OUT(arg, 0);
1401
case SOUND_MIXER_READ_DEVMASK:
1402
return IOCTL_OUT(arg,
1403
SOUND_MASK_VOLUME | SOUND_MASK_TREBLE | SOUND_MASK_BASS |
1404
(MACH_IS_TT ? SOUND_MASK_SPEAKER : 0));
1405
case SOUND_MIXER_READ_STEREODEVS:
1406
return IOCTL_OUT(arg, SOUND_MASK_VOLUME);
1407
case SOUND_MIXER_READ_VOLUME:
1408
return IOCTL_OUT(arg,
1409
VOLUME_DB_TO_VOXWARE(dmasound.volume_left) |
1410
(VOLUME_DB_TO_VOXWARE(dmasound.volume_right) << 8));
1411
case SOUND_MIXER_READ_BASS:
1412
return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(dmasound.bass));
1413
case SOUND_MIXER_READ_TREBLE:
1414
return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(dmasound.treble));
1415
case SOUND_MIXER_READ_OGAIN:
1416
return IOCTL_OUT(arg, GAIN_DB_TO_VOXWARE(dmasound.gain));
1417
case SOUND_MIXER_WRITE_BASS:
1418
IOCTL_IN(arg, data);
1419
return IOCTL_OUT(arg, dmasound_set_bass(data));
1420
case SOUND_MIXER_WRITE_TREBLE:
1421
IOCTL_IN(arg, data);
1422
return IOCTL_OUT(arg, dmasound_set_treble(data));
1423
case SOUND_MIXER_WRITE_OGAIN:
1424
IOCTL_IN(arg, data);
1425
return IOCTL_OUT(arg, dmasound_set_gain(data));
1426
}
1427
return AtaMixerIoctl(cmd, arg);
1428
}
1429
1430
static int FalconMixerIoctl(u_int cmd, u_long arg)
1431
{
1432
int data;
1433
switch (cmd) {
1434
case SOUND_MIXER_READ_RECMASK:
1435
return IOCTL_OUT(arg, SOUND_MASK_MIC);
1436
case SOUND_MIXER_READ_DEVMASK:
1437
return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_SPEAKER);
1438
case SOUND_MIXER_READ_STEREODEVS:
1439
return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC);
1440
case SOUND_MIXER_READ_VOLUME:
1441
return IOCTL_OUT(arg,
1442
VOLUME_ATT_TO_VOXWARE(dmasound.volume_left) |
1443
VOLUME_ATT_TO_VOXWARE(dmasound.volume_right) << 8);
1444
case SOUND_MIXER_READ_CAPS:
1445
return IOCTL_OUT(arg, SOUND_CAP_EXCL_INPUT);
1446
case SOUND_MIXER_WRITE_MIC:
1447
IOCTL_IN(arg, data);
1448
tt_dmasnd.input_gain =
1449
RECLEVEL_VOXWARE_TO_GAIN(data & 0xff) << 4 |
1450
RECLEVEL_VOXWARE_TO_GAIN(data >> 8 & 0xff);
1451
/* fall thru, return set value */
1452
case SOUND_MIXER_READ_MIC:
1453
return IOCTL_OUT(arg,
1454
RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain >> 4 & 0xf) |
1455
RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain & 0xf) << 8);
1456
}
1457
return AtaMixerIoctl(cmd, arg);
1458
}
1459
1460
static int AtaWriteSqSetup(void)
1461
{
1462
write_sq_ignore_int = 0;
1463
return 0 ;
1464
}
1465
1466
static int AtaSqOpen(fmode_t mode)
1467
{
1468
write_sq_ignore_int = 1;
1469
return 0 ;
1470
}
1471
1472
static int TTStateInfo(char *buffer, size_t space)
1473
{
1474
int len = 0;
1475
len += sprintf(buffer+len, "\tvol left %ddB [-40... 0]\n",
1476
dmasound.volume_left);
1477
len += sprintf(buffer+len, "\tvol right %ddB [-40... 0]\n",
1478
dmasound.volume_right);
1479
len += sprintf(buffer+len, "\tbass %ddB [-12...+12]\n",
1480
dmasound.bass);
1481
len += sprintf(buffer+len, "\ttreble %ddB [-12...+12]\n",
1482
dmasound.treble);
1483
if (len >= space) {
1484
printk(KERN_ERR "dmasound_atari: overflowed state buffer alloc.\n") ;
1485
len = space ;
1486
}
1487
return len;
1488
}
1489
1490
static int FalconStateInfo(char *buffer, size_t space)
1491
{
1492
int len = 0;
1493
len += sprintf(buffer+len, "\tvol left %ddB [-22.5 ... 0]\n",
1494
dmasound.volume_left);
1495
len += sprintf(buffer+len, "\tvol right %ddB [-22.5 ... 0]\n",
1496
dmasound.volume_right);
1497
if (len >= space) {
1498
printk(KERN_ERR "dmasound_atari: overflowed state buffer alloc.\n") ;
1499
len = space ;
1500
}
1501
return len;
1502
}
1503
1504
1505
/*** Machine definitions *****************************************************/
1506
1507
static SETTINGS def_hard_falcon = {
1508
.format = AFMT_S8,
1509
.stereo = 0,
1510
.size = 8,
1511
.speed = 8195
1512
} ;
1513
1514
static SETTINGS def_hard_tt = {
1515
.format = AFMT_S8,
1516
.stereo = 0,
1517
.size = 8,
1518
.speed = 12517
1519
} ;
1520
1521
static SETTINGS def_soft = {
1522
.format = AFMT_U8,
1523
.stereo = 0,
1524
.size = 8,
1525
.speed = 8000
1526
} ;
1527
1528
static __initdata MACHINE machTT = {
1529
.name = "Atari",
1530
.name2 = "TT",
1531
.owner = THIS_MODULE,
1532
.dma_alloc = AtaAlloc,
1533
.dma_free = AtaFree,
1534
.irqinit = AtaIrqInit,
1535
#ifdef MODULE
1536
.irqcleanup = AtaIrqCleanUp,
1537
#endif /* MODULE */
1538
.init = TTInit,
1539
.silence = TTSilence,
1540
.setFormat = TTSetFormat,
1541
.setVolume = TTSetVolume,
1542
.setBass = AtaSetBass,
1543
.setTreble = AtaSetTreble,
1544
.setGain = TTSetGain,
1545
.play = AtaPlay,
1546
.mixer_init = TTMixerInit,
1547
.mixer_ioctl = TTMixerIoctl,
1548
.write_sq_setup = AtaWriteSqSetup,
1549
.sq_open = AtaSqOpen,
1550
.state_info = TTStateInfo,
1551
.min_dsp_speed = 6258,
1552
.version = ((DMASOUND_ATARI_REVISION<<8) | DMASOUND_ATARI_EDITION),
1553
.hardware_afmts = AFMT_S8, /* h'ware-supported formats *only* here */
1554
.capabilities = DSP_CAP_BATCH /* As per SNDCTL_DSP_GETCAPS */
1555
};
1556
1557
static __initdata MACHINE machFalcon = {
1558
.name = "Atari",
1559
.name2 = "FALCON",
1560
.dma_alloc = AtaAlloc,
1561
.dma_free = AtaFree,
1562
.irqinit = AtaIrqInit,
1563
#ifdef MODULE
1564
.irqcleanup = AtaIrqCleanUp,
1565
#endif /* MODULE */
1566
.init = FalconInit,
1567
.silence = FalconSilence,
1568
.setFormat = FalconSetFormat,
1569
.setVolume = FalconSetVolume,
1570
.setBass = AtaSetBass,
1571
.setTreble = AtaSetTreble,
1572
.play = AtaPlay,
1573
.mixer_init = FalconMixerInit,
1574
.mixer_ioctl = FalconMixerIoctl,
1575
.write_sq_setup = AtaWriteSqSetup,
1576
.sq_open = AtaSqOpen,
1577
.state_info = FalconStateInfo,
1578
.min_dsp_speed = 8195,
1579
.version = ((DMASOUND_ATARI_REVISION<<8) | DMASOUND_ATARI_EDITION),
1580
.hardware_afmts = (AFMT_S8 | AFMT_S16_BE), /* h'ware-supported formats *only* here */
1581
.capabilities = DSP_CAP_BATCH /* As per SNDCTL_DSP_GETCAPS */
1582
};
1583
1584
1585
/*** Config & Setup **********************************************************/
1586
1587
1588
static int __init dmasound_atari_init(void)
1589
{
1590
if (MACH_IS_ATARI && ATARIHW_PRESENT(PCM_8BIT)) {
1591
if (ATARIHW_PRESENT(CODEC)) {
1592
dmasound.mach = machFalcon;
1593
dmasound.mach.default_soft = def_soft ;
1594
dmasound.mach.default_hard = def_hard_falcon ;
1595
is_falcon = 1;
1596
} else if (ATARIHW_PRESENT(MICROWIRE)) {
1597
dmasound.mach = machTT;
1598
dmasound.mach.default_soft = def_soft ;
1599
dmasound.mach.default_hard = def_hard_tt ;
1600
is_falcon = 0;
1601
} else
1602
return -ENODEV;
1603
if ((st_mfp.int_en_a & st_mfp.int_mk_a & 0x20) == 0)
1604
return dmasound_init();
1605
else {
1606
printk("DMA sound driver: Timer A interrupt already in use\n");
1607
return -EBUSY;
1608
}
1609
}
1610
return -ENODEV;
1611
}
1612
1613
static void __exit dmasound_atari_cleanup(void)
1614
{
1615
dmasound_deinit();
1616
}
1617
1618
module_init(dmasound_atari_init);
1619
module_exit(dmasound_atari_cleanup);
1620
MODULE_LICENSE("GPL");
1621
1622