blob: 823ccfa089b27d3f1d22f4a2cdf7166e3d7169db [file] [log] [blame]
David Brazdil0f672f62019-12-10 10:32:29 +00001// SPDX-License-Identifier: GPL-2.0-only
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002/*
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
35extern void atari_microwire_cmd(int cmd);
36
37static int is_falcon;
38static int write_sq_ignore_int; /* ++TeSche: used for Falcon */
39
40static int expand_bal; /* Balance factor for expanding (not volume!) */
41static 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
71static ssize_t ata_ct_law(const u_char __user *userPtr, size_t userCount,
72 u_char frame[], ssize_t *frameUsed,
73 ssize_t frameLeft);
74static ssize_t ata_ct_s8(const u_char __user *userPtr, size_t userCount,
75 u_char frame[], ssize_t *frameUsed,
76 ssize_t frameLeft);
77static ssize_t ata_ct_u8(const u_char __user *userPtr, size_t userCount,
78 u_char frame[], ssize_t *frameUsed,
79 ssize_t frameLeft);
80static ssize_t ata_ct_s16be(const u_char __user *userPtr, size_t userCount,
81 u_char frame[], ssize_t *frameUsed,
82 ssize_t frameLeft);
83static ssize_t ata_ct_u16be(const u_char __user *userPtr, size_t userCount,
84 u_char frame[], ssize_t *frameUsed,
85 ssize_t frameLeft);
86static ssize_t ata_ct_s16le(const u_char __user *userPtr, size_t userCount,
87 u_char frame[], ssize_t *frameUsed,
88 ssize_t frameLeft);
89static ssize_t ata_ct_u16le(const u_char __user *userPtr, size_t userCount,
90 u_char frame[], ssize_t *frameUsed,
91 ssize_t frameLeft);
92static ssize_t ata_ctx_law(const u_char __user *userPtr, size_t userCount,
93 u_char frame[], ssize_t *frameUsed,
94 ssize_t frameLeft);
95static ssize_t ata_ctx_s8(const u_char __user *userPtr, size_t userCount,
96 u_char frame[], ssize_t *frameUsed,
97 ssize_t frameLeft);
98static ssize_t ata_ctx_u8(const u_char __user *userPtr, size_t userCount,
99 u_char frame[], ssize_t *frameUsed,
100 ssize_t frameLeft);
101static ssize_t ata_ctx_s16be(const u_char __user *userPtr, size_t userCount,
102 u_char frame[], ssize_t *frameUsed,
103 ssize_t frameLeft);
104static ssize_t ata_ctx_u16be(const u_char __user *userPtr, size_t userCount,
105 u_char frame[], ssize_t *frameUsed,
106 ssize_t frameLeft);
107static ssize_t ata_ctx_s16le(const u_char __user *userPtr, size_t userCount,
108 u_char frame[], ssize_t *frameUsed,
109 ssize_t frameLeft);
110static 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
118static void *AtaAlloc(unsigned int size, gfp_t flags);
119static void AtaFree(void *, unsigned int size);
120static int AtaIrqInit(void);
121#ifdef MODULE
122static void AtaIrqCleanUp(void);
123#endif /* MODULE */
124static int AtaSetBass(int bass);
125static int AtaSetTreble(int treble);
126static void TTSilence(void);
127static void TTInit(void);
128static int TTSetFormat(int format);
129static int TTSetVolume(int volume);
130static int TTSetGain(int gain);
131static void FalconSilence(void);
132static void FalconInit(void);
133static int FalconSetFormat(int format);
134static int FalconSetVolume(int volume);
135static void AtaPlayNextFrame(int index);
136static void AtaPlay(void);
137static irqreturn_t AtaInterrupt(int irq, void *dummy);
138
139/*** Mid level stuff *********************************************************/
140
141static void TTMixerInit(void);
142static void FalconMixerInit(void);
143static int AtaMixerIoctl(u_int cmd, u_long arg);
144static int TTMixerIoctl(u_int cmd, u_long arg);
145static int FalconMixerIoctl(u_int cmd, u_long arg);
146static int AtaWriteSqSetup(void);
147static int AtaSqOpen(fmode_t mode);
148static int TTStateInfo(char *buffer, size_t space);
149static int FalconStateInfo(char *buffer, size_t space);
150
151
152/*** Translations ************************************************************/
153
154
155static 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
180static 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
198static 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
233static 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
265static 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
304static 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
345static 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
385static 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
447static 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
501static 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
557static 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
613static 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
671static 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
729static 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
787static 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
794static 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
801static 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
812static 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
832static void *AtaAlloc(unsigned int size, gfp_t flags)
833{
834 return atari_stram_alloc(size, "dmasound");
835}
836
837static void AtaFree(void *obj, unsigned int size)
838{
839 atari_stram_free( obj );
840}
841
842static 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
864static 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
878static 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
886static 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
900static 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
907static 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
957static 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
990static 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
1005static 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
1019static 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
1033static 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
1113static 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
1159static 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
1169static 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
1190static 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
1262static 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. */
1326out:
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
1344static 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
1355static 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
1361static 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
1396static 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
1431static int FalconMixerIoctl(u_int cmd, u_long arg)
1432{
1433 int data;
1434 switch (cmd) {
David Brazdil0f672f62019-12-10 10:32:29 +00001435 case SOUND_MIXER_READ_RECMASK:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001436 return IOCTL_OUT(arg, SOUND_MASK_MIC);
David Brazdil0f672f62019-12-10 10:32:29 +00001437 case SOUND_MIXER_READ_DEVMASK:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001438 return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_SPEAKER);
David Brazdil0f672f62019-12-10 10:32:29 +00001439 case SOUND_MIXER_READ_STEREODEVS:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001440 return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC);
David Brazdil0f672f62019-12-10 10:32:29 +00001441 case SOUND_MIXER_READ_VOLUME:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001442 return IOCTL_OUT(arg,
1443 VOLUME_ATT_TO_VOXWARE(dmasound.volume_left) |
1444 VOLUME_ATT_TO_VOXWARE(dmasound.volume_right) << 8);
David Brazdil0f672f62019-12-10 10:32:29 +00001445 case SOUND_MIXER_READ_CAPS:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001446 return IOCTL_OUT(arg, SOUND_CAP_EXCL_INPUT);
David Brazdil0f672f62019-12-10 10:32:29 +00001447 case SOUND_MIXER_WRITE_MIC:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001448 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);
David Brazdil0f672f62019-12-10 10:32:29 +00001452 /* fall through - return set value */
1453 case SOUND_MIXER_READ_MIC:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001454 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
1461static int AtaWriteSqSetup(void)
1462{
1463 write_sq_ignore_int = 0;
1464 return 0 ;
1465}
1466
1467static int AtaSqOpen(fmode_t mode)
1468{
1469 write_sq_ignore_int = 1;
1470 return 0 ;
1471}
1472
1473static 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
1491static 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
1508static SETTINGS def_hard_falcon = {
1509 .format = AFMT_S8,
1510 .stereo = 0,
1511 .size = 8,
1512 .speed = 8195
1513} ;
1514
1515static SETTINGS def_hard_tt = {
1516 .format = AFMT_S8,
1517 .stereo = 0,
1518 .size = 8,
1519 .speed = 12517
1520} ;
1521
1522static SETTINGS def_soft = {
1523 .format = AFMT_U8,
1524 .stereo = 0,
1525 .size = 8,
1526 .speed = 8000
1527} ;
1528
1529static __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
1558static __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
1589static 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
1614static void __exit dmasound_atari_cleanup(void)
1615{
1616 dmasound_deinit();
1617}
1618
1619module_init(dmasound_atari_init);
1620module_exit(dmasound_atari_cleanup);
1621MODULE_LICENSE("GPL");