Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  linux/sound/oss/dmasound/dmasound_atari.c
0004  *
0005  *  Atari TT and Falcon DMA Sound Driver
0006  *
0007  *  See linux/sound/oss/dmasound/dmasound_core.c for copyright and credits
0008  *  prior to 28/01/2001
0009  *
0010  *  28/01/2001 [0.1] Iain Sandoe
0011  *           - added versioning
0012  *           - put in and populated the hardware_afmts field.
0013  *             [0.2] - put in SNDCTL_DSP_GETCAPS value.
0014  *  01/02/2001 [0.3] - put in default hard/soft settings.
0015  */
0016 
0017 
0018 #include <linux/module.h>
0019 #include <linux/kernel.h>
0020 #include <linux/init.h>
0021 #include <linux/soundcard.h>
0022 #include <linux/mm.h>
0023 #include <linux/spinlock.h>
0024 #include <linux/interrupt.h>
0025 
0026 #include <linux/uaccess.h>
0027 #include <asm/atariints.h>
0028 #include <asm/atari_stram.h>
0029 
0030 #include "dmasound.h"
0031 
0032 #define DMASOUND_ATARI_REVISION 0
0033 #define DMASOUND_ATARI_EDITION 3
0034 
0035 extern void atari_microwire_cmd(int cmd);
0036 
0037 static int is_falcon;
0038 static int write_sq_ignore_int; /* ++TeSche: used for Falcon */
0039 
0040 static int expand_bal;  /* Balance factor for expanding (not volume!) */
0041 static int expand_data; /* Data for expanding */
0042 
0043 
0044 /*** Translations ************************************************************/
0045 
0046 
0047 /* ++TeSche: radically changed for new expanding purposes...
0048  *
0049  * These two routines now deal with copying/expanding/translating the samples
0050  * from user space into our buffer at the right frequency. They take care about
0051  * how much data there's actually to read, how much buffer space there is and
0052  * to convert samples into the right frequency/encoding. They will only work on
0053  * complete samples so it may happen they leave some bytes in the input stream
0054  * if the user didn't write a multiple of the current sample size. They both
0055  * return the number of bytes they've used from both streams so you may detect
0056  * such a situation. Luckily all programs should be able to cope with that.
0057  *
0058  * I think I've optimized anything as far as one can do in plain C, all
0059  * variables should fit in registers and the loops are really short. There's
0060  * one loop for every possible situation. Writing a more generalized and thus
0061  * parameterized loop would only produce slower code. Feel free to optimize
0062  * this in assembler if you like. :)
0063  *
0064  * I think these routines belong here because they're not yet really hardware
0065  * independent, especially the fact that the Falcon can play 16bit samples
0066  * only in stereo is hardcoded in both of them!
0067  *
0068  * ++geert: split in even more functions (one per format)
0069  */
0070 
0071 static ssize_t ata_ct_law(const u_char __user *userPtr, size_t userCount,
0072               u_char frame[], ssize_t *frameUsed,
0073               ssize_t frameLeft);
0074 static ssize_t ata_ct_s8(const u_char __user *userPtr, size_t userCount,
0075              u_char frame[], ssize_t *frameUsed,
0076              ssize_t frameLeft);
0077 static ssize_t ata_ct_u8(const u_char __user *userPtr, size_t userCount,
0078              u_char frame[], ssize_t *frameUsed,
0079              ssize_t frameLeft);
0080 static ssize_t ata_ct_s16be(const u_char __user *userPtr, size_t userCount,
0081                 u_char frame[], ssize_t *frameUsed,
0082                 ssize_t frameLeft);
0083 static ssize_t ata_ct_u16be(const u_char __user *userPtr, size_t userCount,
0084                 u_char frame[], ssize_t *frameUsed,
0085                 ssize_t frameLeft);
0086 static ssize_t ata_ct_s16le(const u_char __user *userPtr, size_t userCount,
0087                 u_char frame[], ssize_t *frameUsed,
0088                 ssize_t frameLeft);
0089 static ssize_t ata_ct_u16le(const u_char __user *userPtr, size_t userCount,
0090                 u_char frame[], ssize_t *frameUsed,
0091                 ssize_t frameLeft);
0092 static ssize_t ata_ctx_law(const u_char __user *userPtr, size_t userCount,
0093                u_char frame[], ssize_t *frameUsed,
0094                ssize_t frameLeft);
0095 static ssize_t ata_ctx_s8(const u_char __user *userPtr, size_t userCount,
0096               u_char frame[], ssize_t *frameUsed,
0097               ssize_t frameLeft);
0098 static ssize_t ata_ctx_u8(const u_char __user *userPtr, size_t userCount,
0099               u_char frame[], ssize_t *frameUsed,
0100               ssize_t frameLeft);
0101 static ssize_t ata_ctx_s16be(const u_char __user *userPtr, size_t userCount,
0102                  u_char frame[], ssize_t *frameUsed,
0103                  ssize_t frameLeft);
0104 static ssize_t ata_ctx_u16be(const u_char __user *userPtr, size_t userCount,
0105                  u_char frame[], ssize_t *frameUsed,
0106                  ssize_t frameLeft);
0107 static ssize_t ata_ctx_s16le(const u_char __user *userPtr, size_t userCount,
0108                  u_char frame[], ssize_t *frameUsed,
0109                  ssize_t frameLeft);
0110 static ssize_t ata_ctx_u16le(const u_char __user *userPtr, size_t userCount,
0111                  u_char frame[], ssize_t *frameUsed,
0112                  ssize_t frameLeft);
0113 
0114 
0115 /*** Low level stuff *********************************************************/
0116 
0117 
0118 static void *AtaAlloc(unsigned int size, gfp_t flags);
0119 static void AtaFree(void *, unsigned int size);
0120 static int AtaIrqInit(void);
0121 #ifdef MODULE
0122 static void AtaIrqCleanUp(void);
0123 #endif /* MODULE */
0124 static int AtaSetBass(int bass);
0125 static int AtaSetTreble(int treble);
0126 static void TTSilence(void);
0127 static void TTInit(void);
0128 static int TTSetFormat(int format);
0129 static int TTSetVolume(int volume);
0130 static int TTSetGain(int gain);
0131 static void FalconSilence(void);
0132 static void FalconInit(void);
0133 static int FalconSetFormat(int format);
0134 static int FalconSetVolume(int volume);
0135 static void AtaPlayNextFrame(int index);
0136 static void AtaPlay(void);
0137 static irqreturn_t AtaInterrupt(int irq, void *dummy);
0138 
0139 /*** Mid level stuff *********************************************************/
0140 
0141 static void TTMixerInit(void);
0142 static void FalconMixerInit(void);
0143 static int AtaMixerIoctl(u_int cmd, u_long arg);
0144 static int TTMixerIoctl(u_int cmd, u_long arg);
0145 static int FalconMixerIoctl(u_int cmd, u_long arg);
0146 static int AtaWriteSqSetup(void);
0147 static int AtaSqOpen(fmode_t mode);
0148 static int TTStateInfo(char *buffer, size_t space);
0149 static int FalconStateInfo(char *buffer, size_t space);
0150 
0151 
0152 /*** Translations ************************************************************/
0153 
0154 
0155 static ssize_t ata_ct_law(const u_char __user *userPtr, size_t userCount,
0156               u_char frame[], ssize_t *frameUsed,
0157               ssize_t frameLeft)
0158 {
0159     char *table = dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8
0160                               : dmasound_alaw2dma8;
0161     ssize_t count, used;
0162     u_char *p = &frame[*frameUsed];
0163 
0164     count = min_t(unsigned long, userCount, frameLeft);
0165     if (dmasound.soft.stereo)
0166         count &= ~1;
0167     used = count;
0168     while (count > 0) {
0169         u_char data;
0170         if (get_user(data, userPtr++))
0171             return -EFAULT;
0172         *p++ = table[data];
0173         count--;
0174     }
0175     *frameUsed += used;
0176     return used;
0177 }
0178 
0179 
0180 static ssize_t ata_ct_s8(const u_char __user *userPtr, size_t userCount,
0181              u_char frame[], ssize_t *frameUsed,
0182              ssize_t frameLeft)
0183 {
0184     ssize_t count, used;
0185     void *p = &frame[*frameUsed];
0186 
0187     count = min_t(unsigned long, userCount, frameLeft);
0188     if (dmasound.soft.stereo)
0189         count &= ~1;
0190     used = count;
0191     if (copy_from_user(p, userPtr, count))
0192         return -EFAULT;
0193     *frameUsed += used;
0194     return used;
0195 }
0196 
0197 
0198 static ssize_t ata_ct_u8(const u_char __user *userPtr, size_t userCount,
0199              u_char frame[], ssize_t *frameUsed,
0200              ssize_t frameLeft)
0201 {
0202     ssize_t count, used;
0203 
0204     if (!dmasound.soft.stereo) {
0205         u_char *p = &frame[*frameUsed];
0206         count = min_t(unsigned long, userCount, frameLeft);
0207         used = count;
0208         while (count > 0) {
0209             u_char data;
0210             if (get_user(data, userPtr++))
0211                 return -EFAULT;
0212             *p++ = data ^ 0x80;
0213             count--;
0214         }
0215     } else {
0216         u_short *p = (u_short *)&frame[*frameUsed];
0217         count = min_t(unsigned long, userCount, frameLeft)>>1;
0218         used = count*2;
0219         while (count > 0) {
0220             u_short data;
0221             if (get_user(data, (u_short __user *)userPtr))
0222                 return -EFAULT;
0223             userPtr += 2;
0224             *p++ = data ^ 0x8080;
0225             count--;
0226         }
0227     }
0228     *frameUsed += used;
0229     return used;
0230 }
0231 
0232 
0233 static ssize_t ata_ct_s16be(const u_char __user *userPtr, size_t userCount,
0234                 u_char frame[], ssize_t *frameUsed,
0235                 ssize_t frameLeft)
0236 {
0237     ssize_t count, used;
0238 
0239     if (!dmasound.soft.stereo) {
0240         u_short *p = (u_short *)&frame[*frameUsed];
0241         count = min_t(unsigned long, userCount, frameLeft)>>1;
0242         used = count*2;
0243         while (count > 0) {
0244             u_short data;
0245             if (get_user(data, (u_short __user *)userPtr))
0246                 return -EFAULT;
0247             userPtr += 2;
0248             *p++ = data;
0249             *p++ = data;
0250             count--;
0251         }
0252         *frameUsed += used*2;
0253     } else {
0254         void *p = (u_short *)&frame[*frameUsed];
0255         count = min_t(unsigned long, userCount, frameLeft) & ~3;
0256         used = count;
0257         if (copy_from_user(p, userPtr, count))
0258             return -EFAULT;
0259         *frameUsed += used;
0260     }
0261     return used;
0262 }
0263 
0264 
0265 static ssize_t ata_ct_u16be(const u_char __user *userPtr, size_t userCount,
0266                 u_char frame[], ssize_t *frameUsed,
0267                 ssize_t frameLeft)
0268 {
0269     ssize_t count, used;
0270 
0271     if (!dmasound.soft.stereo) {
0272         u_short *p = (u_short *)&frame[*frameUsed];
0273         count = min_t(unsigned long, userCount, frameLeft)>>1;
0274         used = count*2;
0275         while (count > 0) {
0276             u_short data;
0277             if (get_user(data, (u_short __user *)userPtr))
0278                 return -EFAULT;
0279             userPtr += 2;
0280             data ^= 0x8000;
0281             *p++ = data;
0282             *p++ = data;
0283             count--;
0284         }
0285         *frameUsed += used*2;
0286     } else {
0287         u_long *p = (u_long *)&frame[*frameUsed];
0288         count = min_t(unsigned long, userCount, frameLeft)>>2;
0289         used = count*4;
0290         while (count > 0) {
0291             u_int data;
0292             if (get_user(data, (u_int __user *)userPtr))
0293                 return -EFAULT;
0294             userPtr += 4;
0295             *p++ = data ^ 0x80008000;
0296             count--;
0297         }
0298         *frameUsed += used;
0299     }
0300     return used;
0301 }
0302 
0303 
0304 static ssize_t ata_ct_s16le(const u_char __user *userPtr, size_t userCount,
0305                 u_char frame[], ssize_t *frameUsed,
0306                 ssize_t frameLeft)
0307 {
0308     ssize_t count, used;
0309 
0310     count = frameLeft;
0311     if (!dmasound.soft.stereo) {
0312         u_short *p = (u_short *)&frame[*frameUsed];
0313         count = min_t(unsigned long, userCount, frameLeft)>>1;
0314         used = count*2;
0315         while (count > 0) {
0316             u_short data;
0317             if (get_user(data, (u_short __user *)userPtr))
0318                 return -EFAULT;
0319             userPtr += 2;
0320             data = le2be16(data);
0321             *p++ = data;
0322             *p++ = data;
0323             count--;
0324         }
0325         *frameUsed += used*2;
0326     } else {
0327         u_long *p = (u_long *)&frame[*frameUsed];
0328         count = min_t(unsigned long, userCount, frameLeft)>>2;
0329         used = count*4;
0330         while (count > 0) {
0331             u_long data;
0332             if (get_user(data, (u_int __user *)userPtr))
0333                 return -EFAULT;
0334             userPtr += 4;
0335             data = le2be16dbl(data);
0336             *p++ = data;
0337             count--;
0338         }
0339         *frameUsed += used;
0340     }
0341     return used;
0342 }
0343 
0344 
0345 static ssize_t ata_ct_u16le(const u_char __user *userPtr, size_t userCount,
0346                 u_char frame[], ssize_t *frameUsed,
0347                 ssize_t frameLeft)
0348 {
0349     ssize_t count, used;
0350 
0351     count = frameLeft;
0352     if (!dmasound.soft.stereo) {
0353         u_short *p = (u_short *)&frame[*frameUsed];
0354         count = min_t(unsigned long, userCount, frameLeft)>>1;
0355         used = count*2;
0356         while (count > 0) {
0357             u_short data;
0358             if (get_user(data, (u_short __user *)userPtr))
0359                 return -EFAULT;
0360             userPtr += 2;
0361             data = le2be16(data) ^ 0x8000;
0362             *p++ = data;
0363             *p++ = data;
0364         }
0365         *frameUsed += used*2;
0366     } else {
0367         u_long *p = (u_long *)&frame[*frameUsed];
0368         count = min_t(unsigned long, userCount, frameLeft)>>2;
0369         used = count;
0370         while (count > 0) {
0371             u_long data;
0372             if (get_user(data, (u_int __user *)userPtr))
0373                 return -EFAULT;
0374             userPtr += 4;
0375             data = le2be16dbl(data) ^ 0x80008000;
0376             *p++ = data;
0377             count--;
0378         }
0379         *frameUsed += used;
0380     }
0381     return used;
0382 }
0383 
0384 
0385 static ssize_t ata_ctx_law(const u_char __user *userPtr, size_t userCount,
0386                u_char frame[], ssize_t *frameUsed,
0387                ssize_t frameLeft)
0388 {
0389     char *table = dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8
0390                               : dmasound_alaw2dma8;
0391     /* this should help gcc to stuff everything into registers */
0392     long bal = expand_bal;
0393     long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
0394     ssize_t used, usedf;
0395 
0396     used = userCount;
0397     usedf = frameLeft;
0398     if (!dmasound.soft.stereo) {
0399         u_char *p = &frame[*frameUsed];
0400         u_char data = expand_data;
0401         while (frameLeft) {
0402             u_char c;
0403             if (bal < 0) {
0404                 if (!userCount)
0405                     break;
0406                 if (get_user(c, userPtr++))
0407                     return -EFAULT;
0408                 data = table[c];
0409                 userCount--;
0410                 bal += hSpeed;
0411             }
0412             *p++ = data;
0413             frameLeft--;
0414             bal -= sSpeed;
0415         }
0416         expand_data = data;
0417     } else {
0418         u_short *p = (u_short *)&frame[*frameUsed];
0419         u_short data = expand_data;
0420         while (frameLeft >= 2) {
0421             u_char c;
0422             if (bal < 0) {
0423                 if (userCount < 2)
0424                     break;
0425                 if (get_user(c, userPtr++))
0426                     return -EFAULT;
0427                 data = table[c] << 8;
0428                 if (get_user(c, userPtr++))
0429                     return -EFAULT;
0430                 data |= table[c];
0431                 userCount -= 2;
0432                 bal += hSpeed;
0433             }
0434             *p++ = data;
0435             frameLeft -= 2;
0436             bal -= sSpeed;
0437         }
0438         expand_data = data;
0439     }
0440     expand_bal = bal;
0441     used -= userCount;
0442     *frameUsed += usedf-frameLeft;
0443     return used;
0444 }
0445 
0446 
0447 static ssize_t ata_ctx_s8(const u_char __user *userPtr, size_t userCount,
0448               u_char frame[], ssize_t *frameUsed,
0449               ssize_t frameLeft)
0450 {
0451     /* this should help gcc to stuff everything into registers */
0452     long bal = expand_bal;
0453     long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
0454     ssize_t used, usedf;
0455 
0456     used = userCount;
0457     usedf = frameLeft;
0458     if (!dmasound.soft.stereo) {
0459         u_char *p = &frame[*frameUsed];
0460         u_char data = expand_data;
0461         while (frameLeft) {
0462             if (bal < 0) {
0463                 if (!userCount)
0464                     break;
0465                 if (get_user(data, userPtr++))
0466                     return -EFAULT;
0467                 userCount--;
0468                 bal += hSpeed;
0469             }
0470             *p++ = data;
0471             frameLeft--;
0472             bal -= sSpeed;
0473         }
0474         expand_data = data;
0475     } else {
0476         u_short *p = (u_short *)&frame[*frameUsed];
0477         u_short data = expand_data;
0478         while (frameLeft >= 2) {
0479             if (bal < 0) {
0480                 if (userCount < 2)
0481                     break;
0482                 if (get_user(data, (u_short __user *)userPtr))
0483                     return -EFAULT;
0484                 userPtr += 2;
0485                 userCount -= 2;
0486                 bal += hSpeed;
0487             }
0488             *p++ = data;
0489             frameLeft -= 2;
0490             bal -= sSpeed;
0491         }
0492         expand_data = data;
0493     }
0494     expand_bal = bal;
0495     used -= userCount;
0496     *frameUsed += usedf-frameLeft;
0497     return used;
0498 }
0499 
0500 
0501 static ssize_t ata_ctx_u8(const u_char __user *userPtr, size_t userCount,
0502               u_char frame[], ssize_t *frameUsed,
0503               ssize_t frameLeft)
0504 {
0505     /* this should help gcc to stuff everything into registers */
0506     long bal = expand_bal;
0507     long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
0508     ssize_t used, usedf;
0509 
0510     used = userCount;
0511     usedf = frameLeft;
0512     if (!dmasound.soft.stereo) {
0513         u_char *p = &frame[*frameUsed];
0514         u_char data = expand_data;
0515         while (frameLeft) {
0516             if (bal < 0) {
0517                 if (!userCount)
0518                     break;
0519                 if (get_user(data, userPtr++))
0520                     return -EFAULT;
0521                 data ^= 0x80;
0522                 userCount--;
0523                 bal += hSpeed;
0524             }
0525             *p++ = data;
0526             frameLeft--;
0527             bal -= sSpeed;
0528         }
0529         expand_data = data;
0530     } else {
0531         u_short *p = (u_short *)&frame[*frameUsed];
0532         u_short data = expand_data;
0533         while (frameLeft >= 2) {
0534             if (bal < 0) {
0535                 if (userCount < 2)
0536                     break;
0537                 if (get_user(data, (u_short __user *)userPtr))
0538                     return -EFAULT;
0539                 userPtr += 2;
0540                 data ^= 0x8080;
0541                 userCount -= 2;
0542                 bal += hSpeed;
0543             }
0544             *p++ = data;
0545             frameLeft -= 2;
0546             bal -= sSpeed;
0547         }
0548         expand_data = data;
0549     }
0550     expand_bal = bal;
0551     used -= userCount;
0552     *frameUsed += usedf-frameLeft;
0553     return used;
0554 }
0555 
0556 
0557 static ssize_t ata_ctx_s16be(const u_char __user *userPtr, size_t userCount,
0558                  u_char frame[], ssize_t *frameUsed,
0559                  ssize_t frameLeft)
0560 {
0561     /* this should help gcc to stuff everything into registers */
0562     long bal = expand_bal;
0563     long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
0564     ssize_t used, usedf;
0565 
0566     used = userCount;
0567     usedf = frameLeft;
0568     if (!dmasound.soft.stereo) {
0569         u_short *p = (u_short *)&frame[*frameUsed];
0570         u_short data = expand_data;
0571         while (frameLeft >= 4) {
0572             if (bal < 0) {
0573                 if (userCount < 2)
0574                     break;
0575                 if (get_user(data, (u_short __user *)userPtr))
0576                     return -EFAULT;
0577                 userPtr += 2;
0578                 userCount -= 2;
0579                 bal += hSpeed;
0580             }
0581             *p++ = data;
0582             *p++ = data;
0583             frameLeft -= 4;
0584             bal -= sSpeed;
0585         }
0586         expand_data = data;
0587     } else {
0588         u_long *p = (u_long *)&frame[*frameUsed];
0589         u_long data = expand_data;
0590         while (frameLeft >= 4) {
0591             if (bal < 0) {
0592                 if (userCount < 4)
0593                     break;
0594                 if (get_user(data, (u_int __user *)userPtr))
0595                     return -EFAULT;
0596                 userPtr += 4;
0597                 userCount -= 4;
0598                 bal += hSpeed;
0599             }
0600             *p++ = data;
0601             frameLeft -= 4;
0602             bal -= sSpeed;
0603         }
0604         expand_data = data;
0605     }
0606     expand_bal = bal;
0607     used -= userCount;
0608     *frameUsed += usedf-frameLeft;
0609     return used;
0610 }
0611 
0612 
0613 static ssize_t ata_ctx_u16be(const u_char __user *userPtr, size_t userCount,
0614                  u_char frame[], ssize_t *frameUsed,
0615                  ssize_t frameLeft)
0616 {
0617     /* this should help gcc to stuff everything into registers */
0618     long bal = expand_bal;
0619     long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
0620     ssize_t used, usedf;
0621 
0622     used = userCount;
0623     usedf = frameLeft;
0624     if (!dmasound.soft.stereo) {
0625         u_short *p = (u_short *)&frame[*frameUsed];
0626         u_short data = expand_data;
0627         while (frameLeft >= 4) {
0628             if (bal < 0) {
0629                 if (userCount < 2)
0630                     break;
0631                 if (get_user(data, (u_short __user *)userPtr))
0632                     return -EFAULT;
0633                 userPtr += 2;
0634                 data ^= 0x8000;
0635                 userCount -= 2;
0636                 bal += hSpeed;
0637             }
0638             *p++ = data;
0639             *p++ = data;
0640             frameLeft -= 4;
0641             bal -= sSpeed;
0642         }
0643         expand_data = data;
0644     } else {
0645         u_long *p = (u_long *)&frame[*frameUsed];
0646         u_long data = expand_data;
0647         while (frameLeft >= 4) {
0648             if (bal < 0) {
0649                 if (userCount < 4)
0650                     break;
0651                 if (get_user(data, (u_int __user *)userPtr))
0652                     return -EFAULT;
0653                 userPtr += 4;
0654                 data ^= 0x80008000;
0655                 userCount -= 4;
0656                 bal += hSpeed;
0657             }
0658             *p++ = data;
0659             frameLeft -= 4;
0660             bal -= sSpeed;
0661         }
0662         expand_data = data;
0663     }
0664     expand_bal = bal;
0665     used -= userCount;
0666     *frameUsed += usedf-frameLeft;
0667     return used;
0668 }
0669 
0670 
0671 static ssize_t ata_ctx_s16le(const u_char __user *userPtr, size_t userCount,
0672                  u_char frame[], ssize_t *frameUsed,
0673                  ssize_t frameLeft)
0674 {
0675     /* this should help gcc to stuff everything into registers */
0676     long bal = expand_bal;
0677     long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
0678     ssize_t used, usedf;
0679 
0680     used = userCount;
0681     usedf = frameLeft;
0682     if (!dmasound.soft.stereo) {
0683         u_short *p = (u_short *)&frame[*frameUsed];
0684         u_short data = expand_data;
0685         while (frameLeft >= 4) {
0686             if (bal < 0) {
0687                 if (userCount < 2)
0688                     break;
0689                 if (get_user(data, (u_short __user *)userPtr))
0690                     return -EFAULT;
0691                 userPtr += 2;
0692                 data = le2be16(data);
0693                 userCount -= 2;
0694                 bal += hSpeed;
0695             }
0696             *p++ = data;
0697             *p++ = data;
0698             frameLeft -= 4;
0699             bal -= sSpeed;
0700         }
0701         expand_data = data;
0702     } else {
0703         u_long *p = (u_long *)&frame[*frameUsed];
0704         u_long data = expand_data;
0705         while (frameLeft >= 4) {
0706             if (bal < 0) {
0707                 if (userCount < 4)
0708                     break;
0709                 if (get_user(data, (u_int __user *)userPtr))
0710                     return -EFAULT;
0711                 userPtr += 4;
0712                 data = le2be16dbl(data);
0713                 userCount -= 4;
0714                 bal += hSpeed;
0715             }
0716             *p++ = data;
0717             frameLeft -= 4;
0718             bal -= sSpeed;
0719         }
0720         expand_data = data;
0721     }
0722     expand_bal = bal;
0723     used -= userCount;
0724     *frameUsed += usedf-frameLeft;
0725     return used;
0726 }
0727 
0728 
0729 static ssize_t ata_ctx_u16le(const u_char __user *userPtr, size_t userCount,
0730                  u_char frame[], ssize_t *frameUsed,
0731                  ssize_t frameLeft)
0732 {
0733     /* this should help gcc to stuff everything into registers */
0734     long bal = expand_bal;
0735     long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
0736     ssize_t used, usedf;
0737 
0738     used = userCount;
0739     usedf = frameLeft;
0740     if (!dmasound.soft.stereo) {
0741         u_short *p = (u_short *)&frame[*frameUsed];
0742         u_short data = expand_data;
0743         while (frameLeft >= 4) {
0744             if (bal < 0) {
0745                 if (userCount < 2)
0746                     break;
0747                 if (get_user(data, (u_short __user *)userPtr))
0748                     return -EFAULT;
0749                 userPtr += 2;
0750                 data = le2be16(data) ^ 0x8000;
0751                 userCount -= 2;
0752                 bal += hSpeed;
0753             }
0754             *p++ = data;
0755             *p++ = data;
0756             frameLeft -= 4;
0757             bal -= sSpeed;
0758         }
0759         expand_data = data;
0760     } else {
0761         u_long *p = (u_long *)&frame[*frameUsed];
0762         u_long data = expand_data;
0763         while (frameLeft >= 4) {
0764             if (bal < 0) {
0765                 if (userCount < 4)
0766                     break;
0767                 if (get_user(data, (u_int __user *)userPtr))
0768                     return -EFAULT;
0769                 userPtr += 4;
0770                 data = le2be16dbl(data) ^ 0x80008000;
0771                 userCount -= 4;
0772                 bal += hSpeed;
0773             }
0774             *p++ = data;
0775             frameLeft -= 4;
0776             bal -= sSpeed;
0777         }
0778         expand_data = data;
0779     }
0780     expand_bal = bal;
0781     used -= userCount;
0782     *frameUsed += usedf-frameLeft;
0783     return used;
0784 }
0785 
0786 
0787 static TRANS transTTNormal = {
0788     .ct_ulaw    = ata_ct_law,
0789     .ct_alaw    = ata_ct_law,
0790     .ct_s8      = ata_ct_s8,
0791     .ct_u8      = ata_ct_u8,
0792 };
0793 
0794 static TRANS transTTExpanding = {
0795     .ct_ulaw    = ata_ctx_law,
0796     .ct_alaw    = ata_ctx_law,
0797     .ct_s8      = ata_ctx_s8,
0798     .ct_u8      = ata_ctx_u8,
0799 };
0800 
0801 static TRANS transFalconNormal = {
0802     .ct_ulaw    = ata_ct_law,
0803     .ct_alaw    = ata_ct_law,
0804     .ct_s8      = ata_ct_s8,
0805     .ct_u8      = ata_ct_u8,
0806     .ct_s16be   = ata_ct_s16be,
0807     .ct_u16be   = ata_ct_u16be,
0808     .ct_s16le   = ata_ct_s16le,
0809     .ct_u16le   = ata_ct_u16le
0810 };
0811 
0812 static TRANS transFalconExpanding = {
0813     .ct_ulaw    = ata_ctx_law,
0814     .ct_alaw    = ata_ctx_law,
0815     .ct_s8      = ata_ctx_s8,
0816     .ct_u8      = ata_ctx_u8,
0817     .ct_s16be   = ata_ctx_s16be,
0818     .ct_u16be   = ata_ctx_u16be,
0819     .ct_s16le   = ata_ctx_s16le,
0820     .ct_u16le   = ata_ctx_u16le,
0821 };
0822 
0823 
0824 /*** Low level stuff *********************************************************/
0825 
0826 
0827 
0828 /*
0829  * Atari (TT/Falcon)
0830  */
0831 
0832 static void *AtaAlloc(unsigned int size, gfp_t flags)
0833 {
0834     return atari_stram_alloc(size, "dmasound");
0835 }
0836 
0837 static void AtaFree(void *obj, unsigned int size)
0838 {
0839     atari_stram_free( obj );
0840 }
0841 
0842 static int __init AtaIrqInit(void)
0843 {
0844     /* Set up timer A. Timer A
0845        will receive a signal upon end of playing from the sound
0846        hardware. Furthermore Timer A is able to count events
0847        and will cause an interrupt after a programmed number
0848        of events. So all we need to keep the music playing is
0849        to provide the sound hardware with new data upon
0850        an interrupt from timer A. */
0851     st_mfp.tim_ct_a = 0;    /* ++roman: Stop timer before programming! */
0852     st_mfp.tim_dt_a = 1;    /* Cause interrupt after first event. */
0853     st_mfp.tim_ct_a = 8;    /* Turn on event counting. */
0854     /* Register interrupt handler. */
0855     if (request_irq(IRQ_MFP_TIMA, AtaInterrupt, 0, "DMA sound",
0856             AtaInterrupt))
0857         return 0;
0858     st_mfp.int_en_a |= 0x20;    /* Turn interrupt on. */
0859     st_mfp.int_mk_a |= 0x20;
0860     return 1;
0861 }
0862 
0863 #ifdef MODULE
0864 static void AtaIrqCleanUp(void)
0865 {
0866     st_mfp.tim_ct_a = 0;        /* stop timer */
0867     st_mfp.int_en_a &= ~0x20;   /* turn interrupt off */
0868     free_irq(IRQ_MFP_TIMA, AtaInterrupt);
0869 }
0870 #endif /* MODULE */
0871 
0872 
0873 #define TONE_VOXWARE_TO_DB(v) \
0874     (((v) < 0) ? -12 : ((v) > 100) ? 12 : ((v) - 50) * 6 / 25)
0875 #define TONE_DB_TO_VOXWARE(v) (((v) * 25 + ((v) > 0 ? 5 : -5)) / 6 + 50)
0876 
0877 
0878 static int AtaSetBass(int bass)
0879 {
0880     dmasound.bass = TONE_VOXWARE_TO_DB(bass);
0881     atari_microwire_cmd(MW_LM1992_BASS(dmasound.bass));
0882     return TONE_DB_TO_VOXWARE(dmasound.bass);
0883 }
0884 
0885 
0886 static int AtaSetTreble(int treble)
0887 {
0888     dmasound.treble = TONE_VOXWARE_TO_DB(treble);
0889     atari_microwire_cmd(MW_LM1992_TREBLE(dmasound.treble));
0890     return TONE_DB_TO_VOXWARE(dmasound.treble);
0891 }
0892 
0893 
0894 
0895 /*
0896  * TT
0897  */
0898 
0899 
0900 static void TTSilence(void)
0901 {
0902     tt_dmasnd.ctrl = DMASND_CTRL_OFF;
0903     atari_microwire_cmd(MW_LM1992_PSG_HIGH); /* mix in PSG signal 1:1 */
0904 }
0905 
0906 
0907 static void TTInit(void)
0908 {
0909     int mode, i, idx;
0910     const int freq[4] = {50066, 25033, 12517, 6258};
0911 
0912     /* search a frequency that fits into the allowed error range */
0913 
0914     idx = -1;
0915     for (i = 0; i < ARRAY_SIZE(freq); i++)
0916         /* this isn't as much useful for a TT than for a Falcon, but
0917          * then it doesn't hurt very much to implement it for a TT too.
0918          */
0919         if ((100 * abs(dmasound.soft.speed - freq[i]) / freq[i]) < catchRadius)
0920             idx = i;
0921     if (idx > -1) {
0922         dmasound.soft.speed = freq[idx];
0923         dmasound.trans_write = &transTTNormal;
0924     } else
0925         dmasound.trans_write = &transTTExpanding;
0926 
0927     TTSilence();
0928     dmasound.hard = dmasound.soft;
0929 
0930     if (dmasound.hard.speed > 50066) {
0931         /* we would need to squeeze the sound, but we won't do that */
0932         dmasound.hard.speed = 50066;
0933         mode = DMASND_MODE_50KHZ;
0934         dmasound.trans_write = &transTTNormal;
0935     } else if (dmasound.hard.speed > 25033) {
0936         dmasound.hard.speed = 50066;
0937         mode = DMASND_MODE_50KHZ;
0938     } else if (dmasound.hard.speed > 12517) {
0939         dmasound.hard.speed = 25033;
0940         mode = DMASND_MODE_25KHZ;
0941     } else if (dmasound.hard.speed > 6258) {
0942         dmasound.hard.speed = 12517;
0943         mode = DMASND_MODE_12KHZ;
0944     } else {
0945         dmasound.hard.speed = 6258;
0946         mode = DMASND_MODE_6KHZ;
0947     }
0948 
0949     tt_dmasnd.mode = (dmasound.hard.stereo ?
0950               DMASND_MODE_STEREO : DMASND_MODE_MONO) |
0951         DMASND_MODE_8BIT | mode;
0952 
0953     expand_bal = -dmasound.soft.speed;
0954 }
0955 
0956 
0957 static int TTSetFormat(int format)
0958 {
0959     /* TT sound DMA supports only 8bit modes */
0960 
0961     switch (format) {
0962     case AFMT_QUERY:
0963         return dmasound.soft.format;
0964     case AFMT_MU_LAW:
0965     case AFMT_A_LAW:
0966     case AFMT_S8:
0967     case AFMT_U8:
0968         break;
0969     default:
0970         format = AFMT_S8;
0971     }
0972 
0973     dmasound.soft.format = format;
0974     dmasound.soft.size = 8;
0975     if (dmasound.minDev == SND_DEV_DSP) {
0976         dmasound.dsp.format = format;
0977         dmasound.dsp.size = 8;
0978     }
0979     TTInit();
0980 
0981     return format;
0982 }
0983 
0984 
0985 #define VOLUME_VOXWARE_TO_DB(v) \
0986     (((v) < 0) ? -40 : ((v) > 100) ? 0 : ((v) * 2) / 5 - 40)
0987 #define VOLUME_DB_TO_VOXWARE(v) ((((v) + 40) * 5 + 1) / 2)
0988 
0989 
0990 static int TTSetVolume(int volume)
0991 {
0992     dmasound.volume_left = VOLUME_VOXWARE_TO_DB(volume & 0xff);
0993     atari_microwire_cmd(MW_LM1992_BALLEFT(dmasound.volume_left));
0994     dmasound.volume_right = VOLUME_VOXWARE_TO_DB((volume & 0xff00) >> 8);
0995     atari_microwire_cmd(MW_LM1992_BALRIGHT(dmasound.volume_right));
0996     return VOLUME_DB_TO_VOXWARE(dmasound.volume_left) |
0997            (VOLUME_DB_TO_VOXWARE(dmasound.volume_right) << 8);
0998 }
0999 
1000 
1001 #define GAIN_VOXWARE_TO_DB(v) \
1002     (((v) < 0) ? -80 : ((v) > 100) ? 0 : ((v) * 4) / 5 - 80)
1003 #define GAIN_DB_TO_VOXWARE(v) ((((v) + 80) * 5 + 1) / 4)
1004 
1005 static int TTSetGain(int gain)
1006 {
1007     dmasound.gain = GAIN_VOXWARE_TO_DB(gain);
1008     atari_microwire_cmd(MW_LM1992_VOLUME(dmasound.gain));
1009     return GAIN_DB_TO_VOXWARE(dmasound.gain);
1010 }
1011 
1012 
1013 
1014 /*
1015  * Falcon
1016  */
1017 
1018 
1019 static void FalconSilence(void)
1020 {
1021     /* stop playback, set sample rate 50kHz for PSG sound */
1022     tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1023     tt_dmasnd.mode = DMASND_MODE_50KHZ | DMASND_MODE_STEREO | DMASND_MODE_8BIT;
1024     tt_dmasnd.int_div = 0; /* STE compatible divider */
1025     tt_dmasnd.int_ctrl = 0x0;
1026     tt_dmasnd.cbar_src = 0x0000; /* no matrix inputs */
1027     tt_dmasnd.cbar_dst = 0x0000; /* no matrix outputs */
1028     tt_dmasnd.dac_src = 1; /* connect ADC to DAC, disconnect matrix */
1029     tt_dmasnd.adc_src = 3; /* ADC Input = PSG */
1030 }
1031 
1032 
1033 static void FalconInit(void)
1034 {
1035     int divider, i, idx;
1036     const int freq[8] = {49170, 32780, 24585, 19668, 16390, 12292, 9834, 8195};
1037 
1038     /* search a frequency that fits into the allowed error range */
1039 
1040     idx = -1;
1041     for (i = 0; i < ARRAY_SIZE(freq); i++)
1042         /* if we will tolerate 3% error 8000Hz->8195Hz (2.38%) would
1043          * be playable without expanding, but that now a kernel runtime
1044          * option
1045          */
1046         if ((100 * abs(dmasound.soft.speed - freq[i]) / freq[i]) < catchRadius)
1047             idx = i;
1048     if (idx > -1) {
1049         dmasound.soft.speed = freq[idx];
1050         dmasound.trans_write = &transFalconNormal;
1051     } else
1052         dmasound.trans_write = &transFalconExpanding;
1053 
1054     FalconSilence();
1055     dmasound.hard = dmasound.soft;
1056 
1057     if (dmasound.hard.size == 16) {
1058         /* the Falcon can play 16bit samples only in stereo */
1059         dmasound.hard.stereo = 1;
1060     }
1061 
1062     if (dmasound.hard.speed > 49170) {
1063         /* we would need to squeeze the sound, but we won't do that */
1064         dmasound.hard.speed = 49170;
1065         divider = 1;
1066         dmasound.trans_write = &transFalconNormal;
1067     } else if (dmasound.hard.speed > 32780) {
1068         dmasound.hard.speed = 49170;
1069         divider = 1;
1070     } else if (dmasound.hard.speed > 24585) {
1071         dmasound.hard.speed = 32780;
1072         divider = 2;
1073     } else if (dmasound.hard.speed > 19668) {
1074         dmasound.hard.speed = 24585;
1075         divider = 3;
1076     } else if (dmasound.hard.speed > 16390) {
1077         dmasound.hard.speed = 19668;
1078         divider = 4;
1079     } else if (dmasound.hard.speed > 12292) {
1080         dmasound.hard.speed = 16390;
1081         divider = 5;
1082     } else if (dmasound.hard.speed > 9834) {
1083         dmasound.hard.speed = 12292;
1084         divider = 7;
1085     } else if (dmasound.hard.speed > 8195) {
1086         dmasound.hard.speed = 9834;
1087         divider = 9;
1088     } else {
1089         dmasound.hard.speed = 8195;
1090         divider = 11;
1091     }
1092     tt_dmasnd.int_div = divider;
1093 
1094     /* Setup Falcon sound DMA for playback */
1095     tt_dmasnd.int_ctrl = 0x4; /* Timer A int at play end */
1096     tt_dmasnd.track_select = 0x0; /* play 1 track, track 1 */
1097     tt_dmasnd.cbar_src = 0x0001; /* DMA(25MHz) --> DAC */
1098     tt_dmasnd.cbar_dst = 0x0000;
1099     tt_dmasnd.rec_track_select = 0;
1100     tt_dmasnd.dac_src = 2; /* connect matrix to DAC */
1101     tt_dmasnd.adc_src = 0; /* ADC Input = Mic */
1102 
1103     tt_dmasnd.mode = (dmasound.hard.stereo ?
1104               DMASND_MODE_STEREO : DMASND_MODE_MONO) |
1105         ((dmasound.hard.size == 8) ?
1106          DMASND_MODE_8BIT : DMASND_MODE_16BIT) |
1107         DMASND_MODE_6KHZ;
1108 
1109     expand_bal = -dmasound.soft.speed;
1110 }
1111 
1112 
1113 static int FalconSetFormat(int format)
1114 {
1115     int size;
1116     /* Falcon sound DMA supports 8bit and 16bit modes */
1117 
1118     switch (format) {
1119     case AFMT_QUERY:
1120         return dmasound.soft.format;
1121     case AFMT_MU_LAW:
1122     case AFMT_A_LAW:
1123     case AFMT_U8:
1124     case AFMT_S8:
1125         size = 8;
1126         break;
1127     case AFMT_S16_BE:
1128     case AFMT_U16_BE:
1129     case AFMT_S16_LE:
1130     case AFMT_U16_LE:
1131         size = 16;
1132         break;
1133     default: /* :-) */
1134         size = 8;
1135         format = AFMT_S8;
1136     }
1137 
1138     dmasound.soft.format = format;
1139     dmasound.soft.size = size;
1140     if (dmasound.minDev == SND_DEV_DSP) {
1141         dmasound.dsp.format = format;
1142         dmasound.dsp.size = dmasound.soft.size;
1143     }
1144 
1145     FalconInit();
1146 
1147     return format;
1148 }
1149 
1150 
1151 /* This is for the Falcon output *attenuation* in 1.5dB steps,
1152  * i.e. output level from 0 to -22.5dB in -1.5dB steps.
1153  */
1154 #define VOLUME_VOXWARE_TO_ATT(v) \
1155     ((v) < 0 ? 15 : (v) > 100 ? 0 : 15 - (v) * 3 / 20)
1156 #define VOLUME_ATT_TO_VOXWARE(v) (100 - (v) * 20 / 3)
1157 
1158 
1159 static int FalconSetVolume(int volume)
1160 {
1161     dmasound.volume_left = VOLUME_VOXWARE_TO_ATT(volume & 0xff);
1162     dmasound.volume_right = VOLUME_VOXWARE_TO_ATT((volume & 0xff00) >> 8);
1163     tt_dmasnd.output_atten = dmasound.volume_left << 8 | dmasound.volume_right << 4;
1164     return VOLUME_ATT_TO_VOXWARE(dmasound.volume_left) |
1165            VOLUME_ATT_TO_VOXWARE(dmasound.volume_right) << 8;
1166 }
1167 
1168 
1169 static void AtaPlayNextFrame(int index)
1170 {
1171     char *start, *end;
1172 
1173     /* used by AtaPlay() if all doubts whether there really is something
1174      * to be played are already wiped out.
1175      */
1176     start = write_sq.buffers[write_sq.front];
1177     end = start+((write_sq.count == index) ? write_sq.rear_size
1178                            : write_sq.block_size);
1179     /* end might not be a legal virtual address. */
1180     DMASNDSetEnd(virt_to_phys(end - 1) + 1);
1181     DMASNDSetBase(virt_to_phys(start));
1182     /* Since only an even number of samples per frame can
1183        be played, we might lose one byte here. (TO DO) */
1184     write_sq.front = (write_sq.front+1) % write_sq.max_count;
1185     write_sq.active++;
1186     tt_dmasnd.ctrl = DMASND_CTRL_ON | DMASND_CTRL_REPEAT;
1187 }
1188 
1189 
1190 static void AtaPlay(void)
1191 {
1192     /* ++TeSche: Note that write_sq.active is no longer just a flag but
1193      * holds the number of frames the DMA is currently programmed for
1194      * instead, may be 0, 1 (currently being played) or 2 (pre-programmed).
1195      *
1196      * Changes done to write_sq.count and write_sq.active are a bit more
1197      * subtle again so now I must admit I also prefer disabling the irq
1198      * here rather than considering all possible situations. But the point
1199      * is that disabling the irq doesn't have any bad influence on this
1200      * version of the driver as we benefit from having pre-programmed the
1201      * DMA wherever possible: There's no need to reload the DMA at the
1202      * exact time of an interrupt but only at some time while the
1203      * pre-programmed frame is playing!
1204      */
1205     atari_disable_irq(IRQ_MFP_TIMA);
1206 
1207     if (write_sq.active == 2 || /* DMA is 'full' */
1208         write_sq.count <= 0) {  /* nothing to do */
1209         atari_enable_irq(IRQ_MFP_TIMA);
1210         return;
1211     }
1212 
1213     if (write_sq.active == 0) {
1214         /* looks like there's nothing 'in' the DMA yet, so try
1215          * to put two frames into it (at least one is available).
1216          */
1217         if (write_sq.count == 1 &&
1218             write_sq.rear_size < write_sq.block_size &&
1219             !write_sq.syncing) {
1220             /* hmmm, the only existing frame is not
1221              * yet filled and we're not syncing?
1222              */
1223             atari_enable_irq(IRQ_MFP_TIMA);
1224             return;
1225         }
1226         AtaPlayNextFrame(1);
1227         if (write_sq.count == 1) {
1228             /* no more frames */
1229             atari_enable_irq(IRQ_MFP_TIMA);
1230             return;
1231         }
1232         if (write_sq.count == 2 &&
1233             write_sq.rear_size < write_sq.block_size &&
1234             !write_sq.syncing) {
1235             /* hmmm, there were two frames, but the second
1236              * one is not yet filled and we're not syncing?
1237              */
1238             atari_enable_irq(IRQ_MFP_TIMA);
1239             return;
1240         }
1241         AtaPlayNextFrame(2);
1242     } else {
1243         /* there's already a frame being played so we may only stuff
1244          * one new into the DMA, but even if this may be the last
1245          * frame existing the previous one is still on write_sq.count.
1246          */
1247         if (write_sq.count == 2 &&
1248             write_sq.rear_size < write_sq.block_size &&
1249             !write_sq.syncing) {
1250             /* hmmm, the only existing frame is not
1251              * yet filled and we're not syncing?
1252              */
1253             atari_enable_irq(IRQ_MFP_TIMA);
1254             return;
1255         }
1256         AtaPlayNextFrame(2);
1257     }
1258     atari_enable_irq(IRQ_MFP_TIMA);
1259 }
1260 
1261 
1262 static irqreturn_t AtaInterrupt(int irq, void *dummy)
1263 {
1264 #if 0
1265     /* ++TeSche: if you should want to test this... */
1266     static int cnt;
1267     if (write_sq.active == 2)
1268         if (++cnt == 10) {
1269             /* simulate losing an interrupt */
1270             cnt = 0;
1271             return IRQ_HANDLED;
1272         }
1273 #endif
1274     spin_lock(&dmasound.lock);
1275     if (write_sq_ignore_int && is_falcon) {
1276         /* ++TeSche: Falcon only: ignore first irq because it comes
1277          * immediately after starting a frame. after that, irqs come
1278          * (almost) like on the TT.
1279          */
1280         write_sq_ignore_int = 0;
1281         goto out;
1282     }
1283 
1284     if (!write_sq.active) {
1285         /* playing was interrupted and sq_reset() has already cleared
1286          * the sq variables, so better don't do anything here.
1287          */
1288         WAKE_UP(write_sq.sync_queue);
1289         goto out;
1290     }
1291 
1292     /* Probably ;) one frame is finished. Well, in fact it may be that a
1293      * pre-programmed one is also finished because there has been a long
1294      * delay in interrupt delivery and we've completely lost one, but
1295      * there's no way to detect such a situation. In such a case the last
1296      * frame will be played more than once and the situation will recover
1297      * as soon as the irq gets through.
1298      */
1299     write_sq.count--;
1300     write_sq.active--;
1301 
1302     if (!write_sq.active) {
1303         tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1304         write_sq_ignore_int = 1;
1305     }
1306 
1307     WAKE_UP(write_sq.action_queue);
1308     /* At least one block of the queue is free now
1309        so wake up a writing process blocked because
1310        of a full queue. */
1311 
1312     if ((write_sq.active != 1) || (write_sq.count != 1))
1313         /* We must be a bit carefully here: write_sq.count indicates the
1314          * number of buffers used and not the number of frames to be
1315          * played. If write_sq.count==1 and write_sq.active==1 that
1316          * means the only remaining frame was already programmed
1317          * earlier (and is currently running) so we mustn't call
1318          * AtaPlay() here, otherwise we'll play one frame too much.
1319          */
1320         AtaPlay();
1321 
1322     if (!write_sq.active) WAKE_UP(write_sq.sync_queue);
1323     /* We are not playing after AtaPlay(), so there
1324        is nothing to play any more. Wake up a process
1325        waiting for audio output to drain. */
1326 out:
1327     spin_unlock(&dmasound.lock);
1328     return IRQ_HANDLED;
1329 }
1330 
1331 
1332 /*** Mid level stuff *********************************************************/
1333 
1334 
1335 /*
1336  * /dev/mixer abstraction
1337  */
1338 
1339 #define RECLEVEL_VOXWARE_TO_GAIN(v) \
1340     ((v) < 0 ? 0 : (v) > 100 ? 15 : (v) * 3 / 20)
1341 #define RECLEVEL_GAIN_TO_VOXWARE(v) (((v) * 20 + 2) / 3)
1342 
1343 
1344 static void __init TTMixerInit(void)
1345 {
1346     atari_microwire_cmd(MW_LM1992_VOLUME(0));
1347     dmasound.volume_left = 0;
1348     atari_microwire_cmd(MW_LM1992_BALLEFT(0));
1349     dmasound.volume_right = 0;
1350     atari_microwire_cmd(MW_LM1992_BALRIGHT(0));
1351     atari_microwire_cmd(MW_LM1992_TREBLE(0));
1352     atari_microwire_cmd(MW_LM1992_BASS(0));
1353 }
1354 
1355 static void __init FalconMixerInit(void)
1356 {
1357     dmasound.volume_left = (tt_dmasnd.output_atten & 0xf00) >> 8;
1358     dmasound.volume_right = (tt_dmasnd.output_atten & 0xf0) >> 4;
1359 }
1360 
1361 static int AtaMixerIoctl(u_int cmd, u_long arg)
1362 {
1363     int data;
1364     unsigned long flags;
1365     switch (cmd) {
1366         case SOUND_MIXER_READ_SPEAKER:
1367             if (is_falcon || MACH_IS_TT) {
1368                 int porta;
1369                 spin_lock_irqsave(&dmasound.lock, flags);
1370                 sound_ym.rd_data_reg_sel = 14;
1371                 porta = sound_ym.rd_data_reg_sel;
1372                 spin_unlock_irqrestore(&dmasound.lock, flags);
1373                 return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
1374             }
1375             break;
1376         case SOUND_MIXER_WRITE_VOLUME:
1377             IOCTL_IN(arg, data);
1378             return IOCTL_OUT(arg, dmasound_set_volume(data));
1379         case SOUND_MIXER_WRITE_SPEAKER:
1380             if (is_falcon || MACH_IS_TT) {
1381                 int porta;
1382                 IOCTL_IN(arg, data);
1383                 spin_lock_irqsave(&dmasound.lock, flags);
1384                 sound_ym.rd_data_reg_sel = 14;
1385                 porta = (sound_ym.rd_data_reg_sel & ~0x40) |
1386                     (data < 50 ? 0x40 : 0);
1387                 sound_ym.wd_data = porta;
1388                 spin_unlock_irqrestore(&dmasound.lock, flags);
1389                 return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
1390             }
1391     }
1392     return -EINVAL;
1393 }
1394 
1395 
1396 static int TTMixerIoctl(u_int cmd, u_long arg)
1397 {
1398     int data;
1399     switch (cmd) {
1400         case SOUND_MIXER_READ_RECMASK:
1401         return IOCTL_OUT(arg, 0);
1402         case SOUND_MIXER_READ_DEVMASK:
1403         return IOCTL_OUT(arg,
1404                  SOUND_MASK_VOLUME | SOUND_MASK_TREBLE | SOUND_MASK_BASS |
1405                  (MACH_IS_TT ? SOUND_MASK_SPEAKER : 0));
1406         case SOUND_MIXER_READ_STEREODEVS:
1407         return IOCTL_OUT(arg, SOUND_MASK_VOLUME);
1408         case SOUND_MIXER_READ_VOLUME:
1409         return IOCTL_OUT(arg,
1410                  VOLUME_DB_TO_VOXWARE(dmasound.volume_left) |
1411                  (VOLUME_DB_TO_VOXWARE(dmasound.volume_right) << 8));
1412         case SOUND_MIXER_READ_BASS:
1413         return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(dmasound.bass));
1414         case SOUND_MIXER_READ_TREBLE:
1415         return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(dmasound.treble));
1416         case SOUND_MIXER_READ_OGAIN:
1417         return IOCTL_OUT(arg, GAIN_DB_TO_VOXWARE(dmasound.gain));
1418         case SOUND_MIXER_WRITE_BASS:
1419         IOCTL_IN(arg, data);
1420         return IOCTL_OUT(arg, dmasound_set_bass(data));
1421         case SOUND_MIXER_WRITE_TREBLE:
1422         IOCTL_IN(arg, data);
1423         return IOCTL_OUT(arg, dmasound_set_treble(data));
1424         case SOUND_MIXER_WRITE_OGAIN:
1425         IOCTL_IN(arg, data);
1426         return IOCTL_OUT(arg, dmasound_set_gain(data));
1427     }
1428     return AtaMixerIoctl(cmd, arg);
1429 }
1430 
1431 static int FalconMixerIoctl(u_int cmd, u_long arg)
1432 {
1433     int data;
1434     switch (cmd) {
1435     case SOUND_MIXER_READ_RECMASK:
1436         return IOCTL_OUT(arg, SOUND_MASK_MIC);
1437     case SOUND_MIXER_READ_DEVMASK:
1438         return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_SPEAKER);
1439     case SOUND_MIXER_READ_STEREODEVS:
1440         return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC);
1441     case SOUND_MIXER_READ_VOLUME:
1442         return IOCTL_OUT(arg,
1443             VOLUME_ATT_TO_VOXWARE(dmasound.volume_left) |
1444             VOLUME_ATT_TO_VOXWARE(dmasound.volume_right) << 8);
1445     case SOUND_MIXER_READ_CAPS:
1446         return IOCTL_OUT(arg, SOUND_CAP_EXCL_INPUT);
1447     case SOUND_MIXER_WRITE_MIC:
1448         IOCTL_IN(arg, data);
1449         tt_dmasnd.input_gain =
1450             RECLEVEL_VOXWARE_TO_GAIN(data & 0xff) << 4 |
1451             RECLEVEL_VOXWARE_TO_GAIN(data >> 8 & 0xff);
1452         fallthrough;    /* return set value */
1453     case SOUND_MIXER_READ_MIC:
1454         return IOCTL_OUT(arg,
1455             RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain >> 4 & 0xf) |
1456             RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain & 0xf) << 8);
1457     }
1458     return AtaMixerIoctl(cmd, arg);
1459 }
1460 
1461 static int AtaWriteSqSetup(void)
1462 {
1463     write_sq_ignore_int = 0;
1464     return 0 ;
1465 }
1466 
1467 static int AtaSqOpen(fmode_t mode)
1468 {
1469     write_sq_ignore_int = 1;
1470     return 0 ;
1471 }
1472 
1473 static int TTStateInfo(char *buffer, size_t space)
1474 {
1475     int len = 0;
1476     len += sprintf(buffer+len, "\tvol left  %ddB [-40...  0]\n",
1477                dmasound.volume_left);
1478     len += sprintf(buffer+len, "\tvol right %ddB [-40...  0]\n",
1479                dmasound.volume_right);
1480     len += sprintf(buffer+len, "\tbass      %ddB [-12...+12]\n",
1481                dmasound.bass);
1482     len += sprintf(buffer+len, "\ttreble    %ddB [-12...+12]\n",
1483                dmasound.treble);
1484     if (len >= space) {
1485         printk(KERN_ERR "dmasound_atari: overflowed state buffer alloc.\n") ;
1486         len = space ;
1487     }
1488     return len;
1489 }
1490 
1491 static int FalconStateInfo(char *buffer, size_t space)
1492 {
1493     int len = 0;
1494     len += sprintf(buffer+len, "\tvol left  %ddB [-22.5 ... 0]\n",
1495                dmasound.volume_left);
1496     len += sprintf(buffer+len, "\tvol right %ddB [-22.5 ... 0]\n",
1497                dmasound.volume_right);
1498     if (len >= space) {
1499         printk(KERN_ERR "dmasound_atari: overflowed state buffer alloc.\n") ;
1500         len = space ;
1501     }
1502     return len;
1503 }
1504 
1505 
1506 /*** Machine definitions *****************************************************/
1507 
1508 static SETTINGS def_hard_falcon = {
1509     .format     = AFMT_S8,
1510     .stereo     = 0,
1511     .size       = 8,
1512     .speed      = 8195
1513 } ;
1514 
1515 static SETTINGS def_hard_tt = {
1516     .format = AFMT_S8,
1517     .stereo = 0,
1518     .size   = 8,
1519     .speed  = 12517
1520 } ;
1521 
1522 static SETTINGS def_soft = {
1523     .format = AFMT_U8,
1524     .stereo = 0,
1525     .size   = 8,
1526     .speed  = 8000
1527 } ;
1528 
1529 static __initdata MACHINE machTT = {
1530     .name       = "Atari",
1531     .name2      = "TT",
1532     .owner      = THIS_MODULE,
1533     .dma_alloc  = AtaAlloc,
1534     .dma_free   = AtaFree,
1535     .irqinit    = AtaIrqInit,
1536 #ifdef MODULE
1537     .irqcleanup = AtaIrqCleanUp,
1538 #endif /* MODULE */
1539     .init       = TTInit,
1540     .silence    = TTSilence,
1541     .setFormat  = TTSetFormat,
1542     .setVolume  = TTSetVolume,
1543     .setBass    = AtaSetBass,
1544     .setTreble  = AtaSetTreble,
1545     .setGain    = TTSetGain,
1546     .play       = AtaPlay,
1547     .mixer_init = TTMixerInit,
1548     .mixer_ioctl    = TTMixerIoctl,
1549     .write_sq_setup = AtaWriteSqSetup,
1550     .sq_open    = AtaSqOpen,
1551     .state_info = TTStateInfo,
1552     .min_dsp_speed  = 6258,
1553     .version    = ((DMASOUND_ATARI_REVISION<<8) | DMASOUND_ATARI_EDITION),
1554     .hardware_afmts = AFMT_S8,  /* h'ware-supported formats *only* here */
1555     .capabilities   =  DSP_CAP_BATCH    /* As per SNDCTL_DSP_GETCAPS */
1556 };
1557 
1558 static __initdata MACHINE machFalcon = {
1559     .name       = "Atari",
1560     .name2      = "FALCON",
1561     .dma_alloc  = AtaAlloc,
1562     .dma_free   = AtaFree,
1563     .irqinit    = AtaIrqInit,
1564 #ifdef MODULE
1565     .irqcleanup = AtaIrqCleanUp,
1566 #endif /* MODULE */
1567     .init       = FalconInit,
1568     .silence    = FalconSilence,
1569     .setFormat  = FalconSetFormat,
1570     .setVolume  = FalconSetVolume,
1571     .setBass    = AtaSetBass,
1572     .setTreble  = AtaSetTreble,
1573     .play       = AtaPlay,
1574     .mixer_init = FalconMixerInit,
1575     .mixer_ioctl    = FalconMixerIoctl,
1576     .write_sq_setup = AtaWriteSqSetup,
1577     .sq_open    = AtaSqOpen,
1578     .state_info = FalconStateInfo,
1579     .min_dsp_speed  = 8195,
1580     .version    = ((DMASOUND_ATARI_REVISION<<8) | DMASOUND_ATARI_EDITION),
1581     .hardware_afmts = (AFMT_S8 | AFMT_S16_BE), /* h'ware-supported formats *only* here */
1582     .capabilities   =  DSP_CAP_BATCH    /* As per SNDCTL_DSP_GETCAPS */
1583 };
1584 
1585 
1586 /*** Config & Setup **********************************************************/
1587 
1588 
1589 static int __init dmasound_atari_init(void)
1590 {
1591     if (MACH_IS_ATARI && ATARIHW_PRESENT(PCM_8BIT)) {
1592         if (ATARIHW_PRESENT(CODEC)) {
1593         dmasound.mach = machFalcon;
1594         dmasound.mach.default_soft = def_soft ;
1595         dmasound.mach.default_hard = def_hard_falcon ;
1596         is_falcon = 1;
1597         } else if (ATARIHW_PRESENT(MICROWIRE)) {
1598         dmasound.mach = machTT;
1599         dmasound.mach.default_soft = def_soft ;
1600         dmasound.mach.default_hard = def_hard_tt ;
1601         is_falcon = 0;
1602         } else
1603         return -ENODEV;
1604         if ((st_mfp.int_en_a & st_mfp.int_mk_a & 0x20) == 0)
1605         return dmasound_init();
1606         else {
1607         printk("DMA sound driver: Timer A interrupt already in use\n");
1608         return -EBUSY;
1609         }
1610     }
1611     return -ENODEV;
1612 }
1613 
1614 static void __exit dmasound_atari_cleanup(void)
1615 {
1616     dmasound_deinit();
1617 }
1618 
1619 module_init(dmasound_atari_init);
1620 module_exit(dmasound_atari_cleanup);
1621 MODULE_LICENSE("GPL");