Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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