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