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