root/drivers/sound/dmasound.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ata_ct_law
  2. ata_ct_s8
  3. ata_ct_u8
  4. ata_ct_s16be
  5. ata_ct_u16be
  6. ata_ct_s16le
  7. ata_ct_u16le
  8. ata_ctx_law
  9. ata_ctx_s8
  10. ata_ctx_u8
  11. ata_ctx_s16be
  12. ata_ctx_u16be
  13. ata_ctx_s16le
  14. ata_ctx_u16le
  15. ami_ct_law
  16. ami_ct_s8
  17. ami_ct_u8
  18. ami_ct_s16be
  19. ami_ct_u16be
  20. ami_ct_s16le
  21. ami_ct_u16le
  22. AtaAlloc
  23. AtaFree
  24. AtaIrqInit
  25. AtaSetBass
  26. AtaSetTreble
  27. TTSilence
  28. TTInit
  29. TTSetFormat
  30. TTSetVolume
  31. FalconSilence
  32. FalconInit
  33. FalconSetFormat
  34. FalconSetVolume
  35. ata_sq_play_next_frame
  36. AtaPlay
  37. ata_sq_interrupt
  38. AmiAlloc
  39. AmiFree
  40. AmiIrqInit
  41. AmiSilence
  42. AmiInit
  43. AmiSetFormat
  44. AmiSetVolume
  45. AmiSetTreble
  46. ami_sq_play_next_frame
  47. AmiPlay
  48. ami_sq_interrupt
  49. sound_silence
  50. sound_init
  51. sound_set_format
  52. sound_set_speed
  53. sound_set_stereo
  54. sound_set_volume
  55. sound_set_bass
  56. sound_set_treble
  57. sound_copy_translate
  58. mixer_init
  59. mixer_open
  60. mixer_release
  61. mixer_ioctl
  62. sq_init
  63. sq_play
  64. sq_write
  65. sq_open
  66. sq_reset
  67. sq_sync
  68. sq_release
  69. state_init
  70. state_open
  71. state_release
  72. state_read
  73. sound_open
  74. sound_fsync
  75. sound_release
  76. sound_lseek
  77. sound_read
  78. sound_write
  79. ioctl_return
  80. unknown_minor_dev
  81. sound_ioctl
  82. soundcard_init
  83. sound_setup
  84. dmasound_setup

   1 
   2 /* linux/drivers/sound/dmasound.c */
   3 
   4 /*
   5 
   6 VoxWare compatible Atari TT DMA sound driver for 680x0 Linux
   7 
   8 (c) 1995 by Michael Schlueter & Michael Marte
   9 
  10 Michael Schlueter (michael@duck.syd.de) did the basic structure of the VFS
  11 interface and the u-law to signed byte conversion.
  12 
  13 Michael Marte (marte@informatik.uni-muenchen.de) did the sound queue,
  14 /dev/mixer, /dev/sndstat and complemented the VFS interface. He would like
  15 to thank:
  16 Michael Schlueter for initial ideas and documentation on the MFP and
  17 the DMA sound hardware.
  18 Therapy? for their CD 'Troublegum' which really made me rock.
  19 
  20 /dev/sndstat is based on code by Hannu Savolainen, the author of the
  21 VoxWare family of drivers.
  22 
  23 This file is subject to the terms and conditions of the GNU General Public
  24 License.  See the file README.legal in the main directory of this archive
  25 for more details.
  26 
  27 History:
  28 1995/8/25       first release
  29 
  30 1995/9/02       ++roman: fixed atari_stram_alloc() call, the timer programming
  31                         and several race conditions
  32 
  33 1995/9/14       ++roman: After some discussion with Michael Schlueter, revised
  34                         the interrupt disabling
  35                         Slightly speeded up U8->S8 translation by using long
  36                         operations where possible
  37                         Added 4:3 interpolation for /dev/audio
  38 
  39 1995/9/20       ++TeSche: Fixed a bug in sq_write and changed /dev/audio
  40                         converting to play at 12517Hz instead of 6258Hz.
  41 
  42 1995/9/23       ++TeSche: Changed sq_interrupt() and sq_play() to pre-program
  43                         the DMA for another frame while there's still one
  44                         running. This allows the IRQ response to be
  45                         arbitrarily delayed and playing will still continue.
  46 
  47 1995/10/14      ++Guenther_Kelleter@ac3.maus.de, ++TeSche: better support for
  48                         Falcon audio (the Falcon doesn't raise an IRQ at the
  49                         end of a frame, but at the beginning instead!). uses
  50                         'if (codec_dma)' in lots of places to simply switch
  51                         between Falcon and TT code.
  52 
  53 1995/11/06      ++TeSche: started introducing a hardware abstraction scheme
  54                         (may perhaps also serve for Amigas?), can now play
  55                         samples at almost all frequencies by means of a more
  56                         generalized expand routine, takes a good deal of care
  57                         to cut data only at sample sizes, buffer size is now
  58                         a kernel runtime option, implemented fsync() & several
  59                         minor improvements
  60                 ++Guenther: useful hints and bugfixes, cross-checked it for
  61                         Falcons
  62 
  63 1996/3/9        ++geert: support added for Amiga, A-law, 16-bit little endian.
  64                         Unification to drivers/sound/dmasound.c.
  65 1996/4/6        ++Martin Mitchell: updated to 1.3 kernel.
  66 */
  67 
  68 
  69 #include <linux/sched.h>
  70 #include <linux/timer.h>
  71 #include <linux/major.h>
  72 #include <linux/config.h>
  73 #include <linux/fcntl.h>
  74 #include <linux/errno.h>
  75 #include <linux/mm.h>
  76 #include <linux/malloc.h>
  77 
  78 #include <asm/system.h>
  79 #include <asm/irq.h>
  80 #include <asm/pgtable.h>
  81 #include <asm/bootinfo.h>
  82 
  83 #ifdef CONFIG_ATARI
  84 #include <asm/atarihw.h>
  85 #include <asm/atariints.h>
  86 #endif /* CONFIG_ATARI */
  87 #ifdef CONFIG_AMIGA
  88 #include <asm/amigahw.h>
  89 #include <asm/amigaints.h>
  90 #endif /* CONFIG_AMIGA */
  91 
  92 #include "dmasound.h"
  93 #include <linux/soundcard.h>
  94 
  95 
  96 #ifdef CONFIG_ATARI
  97 extern void atari_microwire_cmd(int cmd);
  98 #endif /* CONFIG_ATARI */
  99 
 100 #ifdef CONFIG_AMIGA
 101    /*
 102     *   The minimum period for audio depends on htotal (for OCS/ECS/AGA)
 103     *   (Imported from arch/m68k/amiga/amisound.c)
 104     */
 105 
 106 extern volatile u_short amiga_audio_min_period;
 107 
 108 
 109    /*
 110     *   amiga_mksound() should be able to restore the period after beeping
 111     *   (Imported from arch/m68k/amiga/amisound.c)
 112     */
 113 
 114 extern u_short amiga_audio_period;
 115 
 116 
 117    /*
 118     *   Audio DMA masks
 119     */
 120 
 121 #define AMI_AUDIO_OFF   (DMAF_AUD0 | DMAF_AUD1 | DMAF_AUD2 | DMAF_AUD3)
 122 #define AMI_AUDIO_8     (DMAF_SETCLR | DMAF_MASTER | DMAF_AUD0 | DMAF_AUD1)
 123 #define AMI_AUDIO_14    (AMI_AUDIO_8 | DMAF_AUD2 | DMAF_AUD3)
 124 
 125 #endif /* CONFIG_AMIGA */
 126 
 127 
 128 /*** Some declarations *******************************************************/
 129 
 130 
 131 #define DMASND_TT               1
 132 #define DMASND_FALCON           2
 133 #define DMASND_AMIGA            3
 134 
 135 #define MAX_CATCH_RADIUS        10
 136 #define MIN_BUFFERS             4
 137 #define MIN_BUFSIZE             4
 138 #define MAX_BUFSIZE             128     /* Limit for Amiga */
 139 
 140 static int catchRadius = 0, numBufs = 4, bufSize = 32;
 141 
 142 
 143 #define arraysize(x)    (sizeof(x)/sizeof(*(x)))
 144 #define min(x, y)       ((x) < (y) ? (x) : (y))
 145 #define le2be16(x)      (((x)<<8 & 0xff00) | ((x)>>8 & 0x00ff))
 146 #define le2be16dbl(x)   (((x)<<8 & 0xff00ff00) | ((x)>>8 & 0x00ff00ff))
 147 
 148 #define IOCTL_IN(arg)           get_user((int *)(arg))
 149 #define IOCTL_OUT(arg, ret)     ioctl_return((int *)arg, ret)
 150 
 151 
 152 /*** Some low level helpers **************************************************/
 153 
 154 
 155 /* 8 bit mu-law */
 156 
 157 static char ulaw2dma8[] = {
 158     -126,   -122,   -118,   -114,   -110,   -106,   -102,    -98,
 159      -94,    -90,    -86,    -82,    -78,    -74,    -70,    -66,
 160      -63,    -61,    -59,    -57,    -55,    -53,    -51,    -49,
 161      -47,    -45,    -43,    -41,    -39,    -37,    -35,    -33,
 162      -31,    -30,    -29,    -28,    -27,    -26,    -25,    -24,
 163      -23,    -22,    -21,    -20,    -19,    -18,    -17,    -16,
 164      -16,    -15,    -15,    -14,    -14,    -13,    -13,    -12,
 165      -12,    -11,    -11,    -10,    -10,     -9,     -9,     -8,
 166       -8,     -8,     -7,     -7,     -7,     -7,     -6,     -6,
 167       -6,     -6,     -5,     -5,     -5,     -5,     -4,     -4,
 168       -4,     -4,     -4,     -4,     -3,     -3,     -3,     -3,
 169       -3,     -3,     -3,     -3,     -2,     -2,     -2,     -2,
 170       -2,     -2,     -2,     -2,     -2,     -2,     -2,     -2,
 171       -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
 172       -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
 173       -1,     -1,     -1,     -1,     -1,     -1,     -1,      0,
 174      125,    121,    117,    113,    109,    105,    101,     97,
 175       93,     89,     85,     81,     77,     73,     69,     65,
 176       62,     60,     58,     56,     54,     52,     50,     48,
 177       46,     44,     42,     40,     38,     36,     34,     32,
 178       30,     29,     28,     27,     26,     25,     24,     23,
 179       22,     21,     20,     19,     18,     17,     16,     15,
 180       15,     14,     14,     13,     13,     12,     12,     11,
 181       11,     10,     10,      9,      9,      8,      8,      7,
 182        7,      7,      6,      6,      6,      6,      5,      5,
 183        5,      5,      4,      4,      4,      4,      3,      3,
 184        3,      3,      3,      3,      2,      2,      2,      2,
 185        2,      2,      2,      2,      1,      1,      1,      1,
 186        1,      1,      1,      1,      1,      1,      1,      1,
 187        0,      0,      0,      0,      0,      0,      0,      0,
 188        0,      0,      0,      0,      0,      0,      0,      0,
 189        0,      0,      0,      0,      0,      0,      0,      0
 190 };
 191 
 192 /* 8 bit A-law */
 193 
 194 static char alaw2dma8[] = {
 195      -22,    -21,    -24,    -23,    -18,    -17,    -20,    -19,
 196      -30,    -29,    -32,    -31,    -26,    -25,    -28,    -27,
 197      -11,    -11,    -12,    -12,     -9,     -9,    -10,    -10,
 198      -15,    -15,    -16,    -16,    -13,    -13,    -14,    -14,
 199      -86,    -82,    -94,    -90,    -70,    -66,    -78,    -74,
 200     -118,   -114,   -126,   -122,   -102,    -98,   -110,   -106,
 201      -43,    -41,    -47,    -45,    -35,    -33,    -39,    -37,
 202      -59,    -57,    -63,    -61,    -51,    -49,    -55,    -53,
 203       -2,     -2,     -2,     -2,     -2,     -2,     -2,     -2,
 204       -2,     -2,     -2,     -2,     -2,     -2,     -2,     -2,
 205       -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
 206       -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
 207       -6,     -6,     -6,     -6,     -5,     -5,     -5,     -5,
 208       -8,     -8,     -8,     -8,     -7,     -7,     -7,     -7,
 209       -3,     -3,     -3,     -3,     -3,     -3,     -3,     -3,
 210       -4,     -4,     -4,     -4,     -4,     -4,     -4,     -4,
 211       21,     20,     23,     22,     17,     16,     19,     18,
 212       29,     28,     31,     30,     25,     24,     27,     26,
 213       10,     10,     11,     11,      8,      8,      9,      9,
 214       14,     14,     15,     15,     12,     12,     13,     13,
 215       86,     82,     94,     90,     70,     66,     78,     74,
 216      118,    114,    126,    122,    102,     98,    110,    106,
 217       43,     41,     47,     45,     35,     33,     39,     37,
 218       59,     57,     63,     61,     51,     49,     55,     53,
 219        1,      1,      1,      1,      1,      1,      1,      1,
 220        1,      1,      1,      1,      1,      1,      1,      1,
 221        0,      0,      0,      0,      0,      0,      0,      0,
 222        0,      0,      0,      0,      0,      0,      0,      0,
 223        5,      5,      5,      5,      4,      4,      4,      4,
 224        7,      7,      7,      7,      6,      6,      6,      6,
 225        2,      2,      2,      2,      2,      2,      2,      2,
 226        3,      3,      3,      3,      3,      3,      3,      3
 227 };
 228 
 229 
 230 #ifdef HAS_16BIT_TABLES
 231 
 232 /* 16 bit mu-law */
 233 
 234 static char ulaw2dma16[] = {
 235     -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
 236     -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
 237     -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
 238     -11900, -11388, -10876, -10364,  -9852,  -9340,  -8828,  -8316,
 239      -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
 240      -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
 241      -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
 242      -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
 243      -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
 244      -1372,  -1308,  -1244,  -1180,  -1116,  -1052,   -988,   -924,
 245       -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
 246       -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
 247       -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
 248       -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
 249       -120,   -112,   -104,    -96,    -88,    -80,    -72,    -64,
 250        -56,    -48,    -40,    -32,    -24,    -16,     -8,      0,
 251      32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
 252      23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
 253      15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
 254      11900,  11388,  10876,  10364,   9852,   9340,   8828,   8316,
 255       7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
 256       5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
 257       3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
 258       2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
 259       1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
 260       1372,   1308,   1244,   1180,   1116,   1052,    988,    924,
 261        876,    844,    812,    780,    748,    716,    684,    652,
 262        620,    588,    556,    524,    492,    460,    428,    396,
 263        372,    356,    340,    324,    308,    292,    276,    260,
 264        244,    228,    212,    196,    180,    164,    148,    132,
 265        120,    112,    104,     96,     88,     80,     72,     64,
 266         56,     48,     40,     32,     24,     16,      8,      0,
 267 };
 268 
 269 /* 16 bit A-law */
 270 
 271 static char alaw2dma16[] = {
 272      -5504,  -5248,  -6016,  -5760,  -4480,  -4224,  -4992,  -4736,
 273      -7552,  -7296,  -8064,  -7808,  -6528,  -6272,  -7040,  -6784,
 274      -2752,  -2624,  -3008,  -2880,  -2240,  -2112,  -2496,  -2368,
 275      -3776,  -3648,  -4032,  -3904,  -3264,  -3136,  -3520,  -3392,
 276     -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
 277     -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
 278     -11008, -10496, -12032, -11520,  -8960,  -8448,  -9984,  -9472,
 279     -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
 280       -344,   -328,   -376,   -360,   -280,   -264,   -312,   -296,
 281       -472,   -456,   -504,   -488,   -408,   -392,   -440,   -424,
 282        -88,    -72,   -120,   -104,    -24,     -8,    -56,    -40,
 283       -216,   -200,   -248,   -232,   -152,   -136,   -184,   -168,
 284      -1376,  -1312,  -1504,  -1440,  -1120,  -1056,  -1248,  -1184,
 285      -1888,  -1824,  -2016,  -1952,  -1632,  -1568,  -1760,  -1696,
 286       -688,   -656,   -752,   -720,   -560,   -528,   -624,   -592,
 287       -944,   -912,  -1008,   -976,   -816,   -784,   -880,   -848,
 288       5504,   5248,   6016,   5760,   4480,   4224,   4992,   4736,
 289       7552,   7296,   8064,   7808,   6528,   6272,   7040,   6784,
 290       2752,   2624,   3008,   2880,   2240,   2112,   2496,   2368,
 291       3776,   3648,   4032,   3904,   3264,   3136,   3520,   3392,
 292      22016,  20992,  24064,  23040,  17920,  16896,  19968,  18944,
 293      30208,  29184,  32256,  31232,  26112,  25088,  28160,  27136,
 294      11008,  10496,  12032,  11520,   8960,   8448,   9984,   9472,
 295      15104,  14592,  16128,  15616,  13056,  12544,  14080,  13568,
 296        344,    328,    376,    360,    280,    264,    312,    296,
 297        472,    456,    504,    488,    408,    392,    440,    424,
 298         88,     72,    120,    104,     24,      8,     56,     40,
 299        216,    200,    248,    232,    152,    136,    184,    168,
 300       1376,   1312,   1504,   1440,   1120,   1056,   1248,   1184,
 301       1888,   1824,   2016,   1952,   1632,   1568,   1760,   1696,
 302        688,    656,    752,    720,    560,    528,    624,    592,
 303        944,    912,   1008,    976,    816,    784,    880,    848,
 304 };
 305 #endif /* HAS_16BIT_TABLES */
 306 
 307 
 308 #ifdef HAS_14BIT_TABLES
 309 
 310 /* 14 bit mu-law (lsb) */
 311 
 312 static char alaw2dma14l[] = {
 313         33,     33,     33,     33,     33,     33,     33,     33,
 314         33,     33,     33,     33,     33,     33,     33,     33,
 315         33,     33,     33,     33,     33,     33,     33,     33,
 316         33,     33,     33,     33,     33,     33,     33,     33,
 317          1,      1,      1,      1,      1,      1,      1,      1,
 318          1,      1,      1,      1,      1,      1,      1,      1,
 319         49,     17,     49,     17,     49,     17,     49,     17,
 320         49,     17,     49,     17,     49,     17,     49,     17,
 321         41,     57,      9,     25,     41,     57,      9,     25,
 322         41,     57,      9,     25,     41,     57,      9,     25,
 323         37,     45,     53,     61,      5,     13,     21,     29,
 324         37,     45,     53,     61,      5,     13,     21,     29,
 325         35,     39,     43,     47,     51,     55,     59,     63,
 326          3,      7,     11,     15,     19,     23,     27,     31,
 327         34,     36,     38,     40,     42,     44,     46,     48,
 328         50,     52,     54,     56,     58,     60,     62,      0,
 329         31,     31,     31,     31,     31,     31,     31,     31,
 330         31,     31,     31,     31,     31,     31,     31,     31,
 331         31,     31,     31,     31,     31,     31,     31,     31,
 332         31,     31,     31,     31,     31,     31,     31,     31,
 333         63,     63,     63,     63,     63,     63,     63,     63,
 334         63,     63,     63,     63,     63,     63,     63,     63,
 335         15,     47,     15,     47,     15,     47,     15,     47,
 336         15,     47,     15,     47,     15,     47,     15,     47,
 337         23,      7,     55,     39,     23,      7,     55,     39,
 338         23,      7,     55,     39,     23,      7,     55,     39,
 339         27,     19,     11,      3,     59,     51,     43,     35,
 340         27,     19,     11,      3,     59,     51,     43,     35,
 341         29,     25,     21,     17,     13,      9,      5,      1,
 342         61,     57,     53,     49,     45,     41,     37,     33,
 343         30,     28,     26,     24,     22,     20,     18,     16,
 344         14,     12,     10,      8,      6,      4,      2,      0
 345 };
 346 
 347 /* 14 bit A-law (lsb) */
 348 
 349 static char alaw2dma14l[] = {
 350         32,     32,     32,     32,     32,     32,     32,     32,
 351         32,     32,     32,     32,     32,     32,     32,     32,
 352         16,     48,     16,     48,     16,     48,     16,     48,
 353         16,     48,     16,     48,     16,     48,     16,     48,
 354          0,      0,      0,      0,      0,      0,      0,      0,
 355          0,      0,      0,      0,      0,      0,      0,      0,
 356          0,      0,      0,      0,      0,      0,      0,      0,
 357          0,      0,      0,      0,      0,      0,      0,      0,
 358         42,     46,     34,     38,     58,     62,     50,     54,
 359         10,     14,      2,      6,     26,     30,     18,     22,
 360         42,     46,     34,     38,     58,     62,     50,     54,
 361         10,     14,      2,      6,     26,     30,     18,     22,
 362         40,     56,      8,     24,     40,     56,      8,     24,
 363         40,     56,      8,     24,     40,     56,      8,     24,
 364         20,     28,      4,     12,     52,     60,     36,     44,
 365         20,     28,      4,     12,     52,     60,     36,     44,
 366         32,     32,     32,     32,     32,     32,     32,     32,
 367         32,     32,     32,     32,     32,     32,     32,     32,
 368         48,     16,     48,     16,     48,     16,     48,     16,
 369         48,     16,     48,     16,     48,     16,     48,     16,
 370          0,      0,      0,      0,      0,      0,      0,      0,
 371          0,      0,      0,      0,      0,      0,      0,      0,
 372          0,      0,      0,      0,      0,      0,      0,      0,
 373          0,      0,      0,      0,      0,      0,      0,      0,
 374         22,     18,     30,     26,      6,      2,     14,     10,
 375         54,     50,     62,     58,     38,     34,     46,     42,
 376         22,     18,     30,     26,      6,      2,     14,     10,
 377         54,     50,     62,     58,     38,     34,     46,     42,
 378         24,      8,     56,     40,     24,      8,     56,     40,
 379         24,      8,     56,     40,     24,      8,     56,     40,
 380         44,     36,     60,     52,     12,      4,     28,     20,
 381         44,     36,     60,     52,     12,      4,     28,     20
 382 };
 383 #endif /* HAS_14BIT_TABLES */
 384 
 385 
 386 /*** Translations ************************************************************/
 387 
 388 
 389 #ifdef CONFIG_ATARI
 390 static long ata_ct_law(const u_char *userPtr, long userCount, u_char frame[],
 391                        long *frameUsed, long frameLeft);
 392 static long ata_ct_s8(const u_char *userPtr, long userCount, u_char frame[],
 393                       long *frameUsed, long frameLeft);
 394 static long ata_ct_u8(const u_char *userPtr, long userCount, u_char frame[],
 395                       long *frameUsed, long frameLeft);
 396 static long ata_ct_s16be(const u_char *userPtr, long userCount, u_char frame[],
 397                          long *frameUsed, long frameLeft);
 398 static long ata_ct_u16be(const u_char *userPtr, long userCount, u_char frame[],
 399                          long *frameUsed, long frameLeft);
 400 static long ata_ct_s16le(const u_char *userPtr, long userCount, u_char frame[],
 401                          long *frameUsed, long frameLeft);
 402 static long ata_ct_u16le(const u_char *userPtr, long userCount, u_char frame[],
 403                          long *frameUsed, long frameLeft);
 404 static long ata_ctx_law(const u_char *userPtr, long userCount, u_char frame[],
 405                         long *frameUsed, long frameLeft);
 406 static long ata_ctx_s8(const u_char *userPtr, long userCount, u_char frame[],
 407                        long *frameUsed, long frameLeft);
 408 static long ata_ctx_u8(const u_char *userPtr, long userCount, u_char frame[],
 409                         long *frameUsed, long frameLeft);
 410 static long ata_ctx_s16be(const u_char *userPtr, long userCount, u_char frame[],
 411                           long *frameUsed, long frameLeft);
 412 static long ata_ctx_u16be(const u_char *userPtr, long userCount, u_char frame[],
 413                           long *frameUsed, long frameLeft);
 414 static long ata_ctx_s16le(const u_char *userPtr, long userCount, u_char frame[],
 415                           long *frameUsed, long frameLeft);
 416 static long ata_ctx_u16le(const u_char *userPtr, long userCount, u_char frame[],
 417                           long *frameUsed, long frameLeft);
 418 #endif /* CONFIG_ATARI */
 419 
 420 #ifdef CONFIG_AMIGA
 421 static long ami_ct_law(const u_char *userPtr, long userCount, u_char frame[],
 422                        long *frameUsed, long frameLeft);
 423 static long ami_ct_s8(const u_char *userPtr, long userCount, u_char frame[],
 424                       long *frameUsed, long frameLeft);
 425 static long ami_ct_u8(const u_char *userPtr, long userCount, u_char frame[],
 426                       long *frameUsed, long frameLeft);
 427 static long ami_ct_s16be(const u_char *userPtr, long userCount, u_char frame[],
 428                          long *frameUsed, long frameLeft);
 429 static long ami_ct_u16be(const u_char *userPtr, long userCount, u_char frame[],
 430                          long *frameUsed, long frameLeft);
 431 static long ami_ct_s16le(const u_char *userPtr, long userCount, u_char frame[],
 432                          long *frameUsed, long frameLeft);
 433 static long ami_ct_u16le(const u_char *userPtr, long userCount, u_char frame[],
 434                          long *frameUsed, long frameLeft);
 435 #endif /* CONFIG_AMIGA */
 436 
 437 
 438 /*** Machine definitions *****************************************************/
 439 
 440 
 441 typedef struct {
 442     int type;
 443     void *(*dma_alloc)(unsigned int, int);
 444     void (*dma_free)(void *, unsigned int);
 445     int (*irqinit)(void);
 446     void (*init)(void);
 447     void (*silence)(void);
 448     int (*setFormat)(int);
 449     int (*setVolume)(int);
 450     int (*setBass)(int);
 451     int (*setTreble)(int);
 452     void (*play)(void);
 453 } MACHINE;
 454 
 455 
 456 /*** Low level stuff *********************************************************/
 457 
 458 
 459 typedef struct {
 460     int format;         /* AFMT_* */
 461     int stereo;         /* 0 = mono, 1 = stereo */
 462     int size;           /* 8/16 bit*/
 463     int speed;          /* speed */
 464 } SETTINGS;
 465 
 466 typedef struct {
 467     long (*ct_ulaw)(const u_char *, long, u_char *, long *, long);
 468     long (*ct_alaw)(const u_char *, long, u_char *, long *, long);
 469     long (*ct_s8)(const u_char *, long, u_char *, long *, long);
 470     long (*ct_u8)(const u_char *, long, u_char *, long *, long);
 471     long (*ct_s16be)(const u_char *, long, u_char *, long *, long);
 472     long (*ct_u16be)(const u_char *, long, u_char *, long *, long);
 473     long (*ct_s16le)(const u_char *, long, u_char *, long *, long);
 474     long (*ct_u16le)(const u_char *, long, u_char *, long *, long);
 475 } TRANS;
 476 
 477 struct sound_settings {
 478     MACHINE mach;       /* machine dependend things */
 479     SETTINGS hard;      /* hardware settings */
 480     SETTINGS soft;      /* software settings */
 481     SETTINGS dsp;       /* /dev/dsp default settings */
 482     TRANS *trans;       /* supported translations */
 483     int volume_left;    /* volume (range is machine dependent) */
 484     int volume_right;
 485     int bass;           /* tone (range is machine dependent) */
 486     int treble;
 487     int minDev;         /* minor device number currently open */
 488 #ifdef CONFIG_ATARI
 489     int bal;            /* balance factor for expanding (not volume!) */
 490     u_long data;        /* data for expanding */
 491 #endif /* CONFIG_ATARI */
 492 };
 493 
 494 static struct sound_settings sound;
 495 
 496 
 497 #ifdef CONFIG_ATARI
 498 static void *AtaAlloc(unsigned int size, int flags);
 499 static void AtaFree(void *, unsigned int size);
 500 static int AtaIrqInit(void);
 501 static int AtaSetBass(int bass);
 502 static int AtaSetTreble(int treble);
 503 static void TTSilence(void);
 504 static void TTInit(void);
 505 static int TTSetFormat(int format);
 506 static int TTSetVolume(int volume);
 507 static void FalconSilence(void);
 508 static void FalconInit(void);
 509 static int FalconSetFormat(int format);
 510 static int FalconSetVolume(int volume);
 511 static void ata_sq_play_next_frame(int index);
 512 static void AtaPlay(void);
 513 static void ata_sq_interrupt(int irq, struct pt_regs *fp, void *dummy);
 514 #endif /* CONFIG_ATARI */
 515 
 516 #ifdef CONFIG_AMIGA
 517 static void *AmiAlloc(unsigned int size, int flags);
 518 static void AmiFree(void *, unsigned int);
 519 static int AmiIrqInit(void);
 520 static void AmiSilence(void);
 521 static void AmiInit(void);
 522 static int AmiSetFormat(int format);
 523 static int AmiSetVolume(int volume);
 524 static int AmiSetTreble(int treble);
 525 static void ami_sq_play_next_frame(int index);
 526 static void AmiPlay(void);
 527 static void ami_sq_interrupt(int irq, struct pt_regs *fp, void *dummy);
 528 #endif /* CONFIG_AMIGA */
 529 
 530 
 531 /*** Mid level stuff *********************************************************/
 532 
 533 
 534 static void sound_silence(void);
 535 static void sound_init(void);
 536 static int sound_set_format(int format);
 537 static int sound_set_speed(int speed);
 538 static int sound_set_stereo(int stereo);
 539 static int sound_set_volume(int volume);
 540 #ifdef CONFIG_ATARI
 541 static int sound_set_bass(int bass);
 542 #endif /* CONFIG_ATARI */
 543 static int sound_set_treble(int treble);
 544 static long sound_copy_translate(const u_char *userPtr, long userCount,
 545                                  u_char frame[], long *frameUsed,
 546                                  long frameLeft);
 547 
 548 
 549 /*
 550  * /dev/mixer abstraction
 551  */
 552 
 553 struct sound_mixer {
 554     int busy;
 555 };
 556 
 557 static struct sound_mixer mixer;
 558 
 559 static void mixer_init(void);
 560 static int mixer_open(int open_mode);
 561 static int mixer_release(void);
 562 static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
 563                        u_long arg);
 564 
 565 
 566 /*
 567  * Sound queue stuff, the heart of the driver
 568  */
 569 
 570 struct sound_queue {
 571     int max_count, block_size;
 572     char **buffers;
 573 
 574     /* it shouldn't be necessary to declare any of these volatile */
 575     int front, rear, count;
 576     int rear_size;
 577     /*
 578      *  The use of the playing field depends on the hardware
 579      *
 580      *  Atari: The number of frames that are loaded/playing
 581      *
 582      *  Amiga: Bit 0 is set: a frame is loaded
 583      *         Bit 1 is set: a frame is playing
 584      */
 585     int playing;
 586     struct wait_queue *write_queue, *open_queue, *sync_queue;
 587     int open_mode;
 588     int busy, syncing;
 589 #ifdef CONFIG_ATARI
 590     int ignore_int;             /* ++TeSche: used for Falcon */
 591 #endif /* CONFIG_ATARI */
 592 #ifdef CONFIG_AMIGA
 593     int block_size_half, block_size_quarter;
 594 #endif /* CONFIG_AMIGA */
 595 };
 596 
 597 static struct sound_queue sq;
 598 
 599 #define sq_block_address(i)     (sq.buffers[i])
 600 #define SIGNAL_RECEIVED (current->signal & ~current->blocked)
 601 #define NON_BLOCKING(open_mode) (open_mode & O_NONBLOCK)
 602 #define ONE_SECOND      HZ      /* in jiffies (100ths of a second) */
 603 #define NO_TIME_LIMIT   0xffffffff
 604 #define SLEEP(queue, time_limit) \
 605         current->timeout = jiffies+(time_limit); \
 606         interruptible_sleep_on(&queue);
 607 #define WAKE_UP(queue)  (wake_up_interruptible(&queue))
 608 
 609 static void sq_init(int numBufs, int bufSize, char **buffers);
 610 static void sq_play(void);
 611 static int sq_write(const char *src, int uLeft);
 612 static int sq_open(int open_mode);
 613 static void sq_reset(void);
 614 static int sq_sync(void);
 615 static int sq_release(void);
 616 
 617 
 618 /*
 619  * /dev/sndstat
 620  */
 621 
 622 struct sound_state {
 623     int busy;
 624     char buf[512];
 625     int len, ptr;
 626 };
 627 
 628 static struct sound_state state;
 629 
 630 static void state_init(void);
 631 static int state_open(int open_mode);
 632 static int state_release(void);
 633 static int state_read(char *dest, int count);
 634 
 635 
 636 /*** High level stuff ********************************************************/
 637 
 638 
 639 static int sound_open(struct inode *inode, struct file *file);
 640 static int sound_fsync(struct inode *inode, struct file *filp);
 641 static void sound_release(struct inode *inode, struct file *file);
 642 static int sound_lseek(struct inode *inode, struct file *file, off_t offset,
 643                        int orig);
 644 static int sound_read(struct inode *inode, struct file *file, char *buf,
 645                       int count);
 646 static int sound_write(struct inode *inode, struct file *file, const char *buf,
 647                        int count);
 648 static int ioctl_return(int *addr, int value);
 649 static int unknown_minor_dev(char *fname, int dev);
 650 static int sound_ioctl(struct inode *inode, struct file *file, u_int cmd,
 651                        u_long arg);
 652 
 653 
 654 /*** Config & Setup **********************************************************/
 655 
 656 
 657 void soundcard_init(void);
 658 void dmasound_setup(char *str, int *ints);
 659 void sound_setup(char *str, int *ints);         /* ++Martin: stub for now */
 660 
 661 
 662 /*** Translations ************************************************************/
 663 
 664 
 665 /* ++TeSche: radically changed for new expanding purposes...
 666  *
 667  * These two routines now deal with copying/expanding/translating the samples
 668  * from user space into our buffer at the right frequency. They take care about
 669  * how much data there's actually to read, how much buffer space there is and
 670  * to convert samples into the right frequency/encoding. They will only work on
 671  * complete samples so it may happen they leave some bytes in the input stream
 672  * if the user didn't write a multiple of the current sample size. They both
 673  * return the number of bytes they've used from both streams so you may detect
 674  * such a situation. Luckily all programs should be able to cope with that.
 675  *
 676  * I think I've optimized anything as far as one can do in plain C, all
 677  * variables should fit in registers and the loops are really short. There's
 678  * one loop for every possible situation. Writing a more generalized and thus
 679  * parametrized loop would only produce slower code. Feel free to optimize
 680  * this in assembler if you like. :)
 681  *
 682  * I think these routines belong here because they're not yet really hardware
 683  * independend, especially the fact that the Falcon can play 16bit samples
 684  * only in stereo is hardcoded in both of them!
 685  *
 686  * ++geert: split in even more functions (one per format)
 687  */
 688 
 689 #ifdef CONFIG_ATARI
 690 static long ata_ct_law(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
 691                        long *frameUsed, long frameLeft)
 692 {
 693     char *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma8 : alaw2dma8;
 694     long count, used;
 695     u_char *p = &frame[*frameUsed];
 696 
 697     count = min(userCount, frameLeft);
 698     if (sound.soft.stereo)
 699         count &= ~1;
 700     used = count;
 701     while (count > 0) {
 702         *p++ = table[get_user(userPtr++)];
 703         count--;
 704     }
 705     *frameUsed += used;
 706     return(used);
 707 }
 708 
 709 
 710 static long ata_ct_s8(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
 711                       long *frameUsed, long frameLeft)
 712 {
 713     long count, used;
 714     void *p = &frame[*frameUsed];
 715 
 716     count = min(userCount, frameLeft);
 717     if (sound.soft.stereo)
 718         count &= ~1;
 719     used = count;
 720     memcpy_fromfs(p, userPtr, count);
 721     *frameUsed += used;
 722     return(used);
 723 }
 724 
 725 
 726 static long ata_ct_u8(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
 727                       long *frameUsed, long frameLeft)
 728 {
 729     long count, used;
 730 
 731     if (!sound.soft.stereo) {
 732         u_char *p = &frame[*frameUsed];
 733         count = min(userCount, frameLeft);
 734         used = count;
 735         while (count > 0) {
 736             *p++ = get_user(userPtr++) ^ 0x80;
 737             count--;
 738         }
 739     } else {
 740         u_short *p = (u_short *)&frame[*frameUsed];
 741         count = min(userCount, frameLeft)>>1;
 742         used = count*2;
 743         while (count > 0) {
 744             *p++ = get_user(((u_short *)userPtr)++) ^ 0x8080;
 745             count--;
 746         }
 747     }
 748     *frameUsed += used;
 749     return(used);
 750 }
 751 
 752 
 753 static long ata_ct_s16be(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
 754                          long *frameUsed, long frameLeft)
 755 {
 756     long count, used;
 757     u_long data;
 758 
 759     if (!sound.soft.stereo) {
 760         u_short *p = (u_short *)&frame[*frameUsed];
 761         count = min(userCount, frameLeft)>>1;
 762         used = count*2;
 763         while (count > 0) {
 764             data = get_user(((u_short *)userPtr)++);
 765             *p++ = data;
 766             *p++ = data;
 767             count--;
 768         }
 769         *frameUsed += used*2;
 770     } else {
 771         void *p = (u_short *)&frame[*frameUsed];
 772         count = min(userCount, frameLeft) & ~3;
 773         used = count;
 774         memcpy_fromfs(p, userPtr, count);
 775         *frameUsed += used;
 776     }
 777     return(used);
 778 }
 779 
 780 
 781 static long ata_ct_u16be(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
 782                          long *frameUsed, long frameLeft)
 783 {
 784     long count, used;
 785     u_long data;
 786 
 787     if (!sound.soft.stereo) {
 788         u_short *p = (u_short *)&frame[*frameUsed];
 789         count = min(userCount, frameLeft)>>1;
 790         used = count*2;
 791         while (count > 0) {
 792             data = get_user(((u_short *)userPtr)++) ^ 0x8000;
 793             *p++ = data;
 794             *p++ = data;
 795             count--;
 796         }
 797         *frameUsed += used*2;
 798     } else {
 799         u_long *p = (u_long *)&frame[*frameUsed];
 800         count = min(userCount, frameLeft)>>2;
 801         used = count*4;
 802         while (count > 0) {
 803             *p++ = get_user(((u_int *)userPtr)++) ^ 0x80008000;
 804             count--;
 805         }
 806         *frameUsed += used;
 807     }
 808     return(used);
 809 }
 810 
 811 
 812 static long ata_ct_s16le(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
 813                          long *frameUsed, long frameLeft)
 814 {
 815     long count, used;
 816     u_long data;
 817 
 818     count = frameLeft;
 819     if (!sound.soft.stereo) {
 820         u_short *p = (u_short *)&frame[*frameUsed];
 821         count = min(userCount, frameLeft)>>1;
 822         used = count*2;
 823         while (count > 0) {
 824             data = get_user(((u_short *)userPtr)++);
 825             data = le2be16(data);
 826             *p++ = data;
 827             *p++ = data;
 828             count--;
 829         }
 830         *frameUsed += used*2;
 831     } else {
 832         u_long *p = (u_long *)&frame[*frameUsed];
 833         count = min(userCount, frameLeft)>>2;
 834         used = count*4;
 835         while (count > 0) {
 836             data = get_user(((u_int *)userPtr)++);
 837             data = le2be16dbl(data);
 838             *p++ = data;
 839             count--;
 840         }
 841         *frameUsed += used;
 842     }
 843     return(used);
 844 }
 845 
 846 
 847 static long ata_ct_u16le(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
 848                          long *frameUsed, long frameLeft)
 849 {
 850     long count, used;
 851     u_long data;
 852 
 853     count = frameLeft;
 854     if (!sound.soft.stereo) {
 855         u_short *p = (u_short *)&frame[*frameUsed];
 856         count = min(userCount, frameLeft)>>1;
 857         used = count*2;
 858         while (count > 0) {
 859             data = get_user(((u_short *)userPtr)++);
 860             data = le2be16(data) ^ 0x8000;
 861             *p++ = data;
 862             *p++ = data;
 863         }
 864         *frameUsed += used*2;
 865     } else {
 866         u_long *p = (u_long *)&frame[*frameUsed];
 867         count = min(userCount, frameLeft)>>2;
 868         used = count;
 869         while (count > 0) {
 870             data = get_user(((u_int *)userPtr)++);
 871             data = le2be16dbl(data) ^ 0x80008000;
 872             *p++ = data;
 873             count--;
 874         }
 875         *frameUsed += used;
 876     }
 877     return(used);
 878 }
 879 
 880 
 881 static long ata_ctx_law(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
 882                         long *frameUsed, long frameLeft)
 883 {
 884     char *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma8 : alaw2dma8;
 885     /* this should help gcc to stuff everything into registers */
 886     u_long data = sound.data;
 887     long bal = sound.bal;
 888     long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
 889     long used, usedf;
 890 
 891     used = userCount;
 892     usedf = frameLeft;
 893     if (!sound.soft.stereo) {
 894         u_char *p = &frame[*frameUsed];
 895         while (frameLeft) {
 896             if (bal < 0) {
 897                 if (!userCount)
 898                     break;
 899                 data = table[get_user(userPtr++)];
 900                 userCount--;
 901                 bal += hSpeed;
 902             }
 903             *p++ = data;
 904             frameLeft--;
 905             bal -= sSpeed;
 906         }
 907     } else {
 908         u_short *p = (u_short *)&frame[*frameUsed];
 909         while (frameLeft >= 2) {
 910             if (bal < 0) {
 911                 if (userCount < 2)
 912                     break;
 913                 data = table[get_user(userPtr++)] << 8;
 914                 data |= table[get_user(userPtr++)];
 915                 userCount -= 2;
 916                 bal += hSpeed;
 917             }
 918             *p++ = data;
 919             frameLeft -= 2;
 920             bal -= sSpeed;
 921         }
 922     }
 923     sound.bal = bal;
 924     sound.data = data;
 925     used -= userCount;
 926     *frameUsed += usedf-frameLeft;
 927     return(used);
 928 }
 929 
 930 
 931 static long ata_ctx_s8(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
 932                        long *frameUsed, long frameLeft)
 933 {
 934     /* this should help gcc to stuff everything into registers */
 935     u_long data = sound.data;
 936     long bal = sound.bal;
 937     long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
 938     long used, usedf;
 939 
 940     used = userCount;
 941     usedf = frameLeft;
 942     if (!sound.soft.stereo) {
 943         u_char *p = &frame[*frameUsed];
 944         while (frameLeft) {
 945             if (bal < 0) {
 946                 if (!userCount)
 947                     break;
 948                 data = get_user(userPtr++);
 949                 userCount--;
 950                 bal += hSpeed;
 951             }
 952             *p++ = data;
 953             frameLeft--;
 954             bal -= sSpeed;
 955         }
 956     } else {
 957         u_short *p = (u_short *)&frame[*frameUsed];
 958         while (frameLeft >= 2) {
 959             if (bal < 0) {
 960                 if (userCount < 2)
 961                     break;
 962                 data = get_user(((u_short *)userPtr)++);
 963                 userCount -= 2;
 964                 bal += hSpeed;
 965             }
 966             *p++ = data;
 967             frameLeft -= 2;
 968             bal -= sSpeed;
 969         }
 970     }
 971     sound.bal = bal;
 972     sound.data = data;
 973     used -= userCount;
 974     *frameUsed += usedf-frameLeft;
 975     return(used);
 976 }
 977 
 978 
 979 static long ata_ctx_u8(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
 980                        long *frameUsed, long frameLeft)
 981 {
 982     /* this should help gcc to stuff everything into registers */
 983     u_long data = sound.data;
 984     long bal = sound.bal;
 985     long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
 986     long used, usedf;
 987 
 988     used = userCount;
 989     usedf = frameLeft;
 990     if (!sound.soft.stereo) {
 991         u_char *p = &frame[*frameUsed];
 992         while (frameLeft) {
 993             if (bal < 0) {
 994                 if (!userCount)
 995                     break;
 996                 data = get_user(userPtr++) ^ 0x80;
 997                 userCount--;
 998                 bal += hSpeed;
 999             }
1000             *p++ = data;
1001             frameLeft--;
1002             bal -= sSpeed;
1003         }
1004     } else {
1005         u_short *p = (u_short *)&frame[*frameUsed];
1006         while (frameLeft >= 2) {
1007             if (bal < 0) {
1008                 if (userCount < 2)
1009                     break;
1010                 data = get_user(((u_short *)userPtr)++) ^ 0x8080;
1011                 userCount -= 2;
1012                 bal += hSpeed;
1013             }
1014             *p++ = data;
1015             frameLeft -= 2;
1016             bal -= sSpeed;
1017         }
1018     }
1019     sound.bal = bal;
1020     sound.data = data;
1021     used -= userCount;
1022     *frameUsed += usedf-frameLeft;
1023     return(used);
1024 }
1025 
1026 
1027 static long ata_ctx_s16be(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
1028                           long *frameUsed, long frameLeft)
1029 {
1030     /* this should help gcc to stuff everything into registers */
1031     u_long data = sound.data;
1032     long bal = sound.bal;
1033     long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
1034     long used, usedf;
1035 
1036     used = userCount;
1037     usedf = frameLeft;
1038     if (!sound.soft.stereo) {
1039         u_short *p = (u_short *)&frame[*frameUsed];
1040         while (frameLeft >= 4) {
1041             if (bal < 0) {
1042                 if (userCount < 2)
1043                     break;
1044                 data = get_user(((u_short *)userPtr)++);
1045                 userCount -= 2;
1046                 bal += hSpeed;
1047             }
1048             *p++ = data;
1049             *p++ = data;
1050             frameLeft -= 4;
1051             bal -= sSpeed;
1052         }
1053     } else {
1054         u_long *p = (u_long *)&frame[*frameUsed];
1055         while (frameLeft >= 4) {
1056             if (bal < 0) {
1057                 if (userCount < 4)
1058                     break;
1059                 data = get_user(((u_int *)userPtr)++);
1060                 userCount -= 4;
1061                 bal += hSpeed;
1062             }
1063             *p++ = data;
1064             frameLeft -= 4;
1065             bal -= sSpeed;
1066         }
1067     }
1068     sound.bal = bal;
1069     sound.data = data;
1070     used -= userCount;
1071     *frameUsed += usedf-frameLeft;
1072     return(used);
1073 }
1074 
1075 
1076 static long ata_ctx_u16be(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
1077                           long *frameUsed, long frameLeft)
1078 {
1079     /* this should help gcc to stuff everything into registers */
1080     u_long data = sound.data;
1081     long bal = sound.bal;
1082     long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
1083     long used, usedf;
1084 
1085     used = userCount;
1086     usedf = frameLeft;
1087     if (!sound.soft.stereo) {
1088         u_short *p = (u_short *)&frame[*frameUsed];
1089         while (frameLeft >= 4) {
1090             if (bal < 0) {
1091                 if (userCount < 2)
1092                     break;
1093                 data = get_user(((u_short *)userPtr)++) ^ 0x8000;
1094                 userCount -= 2;
1095                 bal += hSpeed;
1096             }
1097             *p++ = data;
1098             *p++ = data;
1099             frameLeft -= 4;
1100             bal -= sSpeed;
1101         }
1102     } else {
1103         u_long *p = (u_long *)&frame[*frameUsed];
1104         while (frameLeft >= 4) {
1105             if (bal < 0) {
1106                 if (userCount < 4)
1107                     break;
1108                 data = get_user(((u_int *)userPtr)++) ^ 0x80008000;
1109                 userCount -= 4;
1110                 bal += hSpeed;
1111             }
1112             *p++ = data;
1113             frameLeft -= 4;
1114             bal -= sSpeed;
1115         }
1116     }
1117     sound.bal = bal;
1118     sound.data = data;
1119     used -= userCount;
1120     *frameUsed += usedf-frameLeft;
1121     return(used);
1122 }
1123 
1124 
1125 static long ata_ctx_s16le(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
1126                           long *frameUsed, long frameLeft)
1127 {
1128     /* this should help gcc to stuff everything into registers */
1129     u_long data = sound.data;
1130     long bal = sound.bal;
1131     long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
1132     long used, usedf;
1133 
1134     used = userCount;
1135     usedf = frameLeft;
1136     if (!sound.soft.stereo) {
1137         u_short *p = (u_short *)&frame[*frameUsed];
1138         while (frameLeft >= 4) {
1139             if (bal < 0) {
1140                 if (userCount < 2)
1141                     break;
1142                 data = get_user(((u_short *)userPtr)++);
1143                 data = le2be16(data);
1144                 userCount -= 2;
1145                 bal += hSpeed;
1146             }
1147             *p++ = data;
1148             *p++ = data;
1149             frameLeft -= 4;
1150             bal -= sSpeed;
1151         }
1152     } else {
1153         u_long *p = (u_long *)&frame[*frameUsed];
1154         while (frameLeft >= 4) {
1155             if (bal < 0) {
1156                 if (userCount < 4)
1157                     break;
1158                 data = get_user(((u_int *)userPtr)++);
1159                 data = le2be16dbl(data);
1160                 userCount -= 4;
1161                 bal += hSpeed;
1162             }
1163             *p++ = data;
1164             frameLeft -= 4;
1165             bal -= sSpeed;
1166         }
1167     }
1168     sound.bal = bal;
1169     sound.data = data;
1170     used -= userCount;
1171     *frameUsed += usedf-frameLeft;
1172     return(used);
1173 }
1174 
1175 
1176 static long ata_ctx_u16le(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
1177                           long *frameUsed, long frameLeft)
1178 {
1179     /* this should help gcc to stuff everything into registers */
1180     u_long data = sound.data;
1181     long bal = sound.bal;
1182     long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
1183     long used, usedf;
1184 
1185     used = userCount;
1186     usedf = frameLeft;
1187     if (!sound.soft.stereo) {
1188         u_short *p = (u_short *)&frame[*frameUsed];
1189         while (frameLeft >= 4) {
1190             if (bal < 0) {
1191                 if (userCount < 2)
1192                     break;
1193                 data = get_user(((u_short *)userPtr)++);
1194                 data = le2be16(data) ^ 0x8000;
1195                 userCount -= 2;
1196                 bal += hSpeed;
1197             }
1198             *p++ = data;
1199             *p++ = data;
1200             frameLeft -= 4;
1201             bal -= sSpeed;
1202         }
1203     } else {
1204         u_long *p = (u_long *)&frame[*frameUsed];
1205         while (frameLeft >= 4) {
1206             if (bal < 0) {
1207                 if (userCount < 4)
1208                     break;
1209                 data = get_user(((u_int *)userPtr)++);
1210                 data = le2be16dbl(data) ^ 0x80008000;
1211                 userCount -= 4;
1212                 bal += hSpeed;
1213             }
1214             *p++ = data;
1215             frameLeft -= 4;
1216             bal -= sSpeed;
1217         }
1218     }
1219     sound.bal = bal;
1220     sound.data = data;
1221     used -= userCount;
1222     *frameUsed += usedf-frameLeft;
1223     return(used);
1224 }
1225 #endif /* CONFIG_ATARI */
1226 
1227 
1228 #ifdef CONFIG_AMIGA
1229 static long ami_ct_law(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
1230                        long *frameUsed, long frameLeft)
1231 {
1232     char *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma8 : alaw2dma8;
1233     long count, used;
1234 
1235     if (!sound.soft.stereo) {
1236         u_char *p = &frame[*frameUsed];
1237         count = min(userCount, frameLeft) & ~1;
1238         used = count;
1239         while (count > 0) {
1240             *p++ = table[get_user(userPtr++)];
1241             count--;
1242         }
1243     } else {
1244         u_char *left = &frame[*frameUsed>>1];
1245         u_char *right = left+sq.block_size_half;
1246         count = min(userCount, frameLeft)>>1 & ~1;
1247         used = count*2;
1248         while (count > 0) {
1249             *left++ = table[get_user(userPtr++)];
1250             *right++ = table[get_user(userPtr++)];
1251             count--;
1252         }
1253     }
1254     *frameUsed += used;
1255     return(used);
1256 }
1257 
1258 
1259 static long ami_ct_s8(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
1260                       long *frameUsed, long frameLeft)
1261 {
1262     long count, used;
1263 
1264     if (!sound.soft.stereo) {
1265         void *p = &frame[*frameUsed];
1266         count = min(userCount, frameLeft) & ~1;
1267         used = count;
1268         memcpy_fromfs(p, userPtr, count);
1269     } else {
1270         u_char *left = &frame[*frameUsed>>1];
1271         u_char *right = left+sq.block_size_half;
1272         count = min(userCount, frameLeft)>>1 & ~1;
1273         used = count*2;
1274         while (count > 0) {
1275             *left++ = get_user(userPtr++);
1276             *right++ = get_user(userPtr++);
1277             count--;
1278         }
1279     }
1280     *frameUsed += used;
1281     return(used);
1282 }
1283 
1284 
1285 static long ami_ct_u8(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
1286                       long *frameUsed, long frameLeft)
1287 {
1288     long count, used;
1289 
1290     if (!sound.soft.stereo) {
1291         char *p = &frame[*frameUsed];
1292         count = min(userCount, frameLeft) & ~1;
1293         used = count;
1294         while (count > 0) {
1295             *p++ = get_user(userPtr++) ^ 0x80;
1296             count--;
1297         }
1298     } else {
1299         u_char *left = &frame[*frameUsed>>1];
1300         u_char *right = left+sq.block_size_half;
1301         count = min(userCount, frameLeft)>>1 & ~1;
1302         used = count*2;
1303         while (count > 0) {
1304             *left++ = get_user(userPtr++) ^ 0x80;
1305             *right++ = get_user(userPtr++) ^ 0x80;
1306             count--;
1307         }
1308     }
1309     *frameUsed += used;
1310     return(used);
1311 }
1312 
1313 
1314 static long ami_ct_s16be(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
1315                          long *frameUsed, long frameLeft)
1316 {
1317     long count, used;
1318     u_long data;
1319 
1320     if (!sound.soft.stereo) {
1321         u_char *high = &frame[*frameUsed>>1];
1322         u_char *low = high+sq.block_size_half;
1323         count = min(userCount, frameLeft)>>1 & ~1;
1324         used = count*2;
1325         while (count > 0) {
1326             data = get_user(((u_short *)userPtr)++);
1327             *high = data>>8;
1328             *low = (data>>2) & 0x3f;
1329             count--;
1330         }
1331     } else {
1332         u_char *lefth = &frame[*frameUsed>>2];
1333         u_char *leftl = lefth+sq.block_size_quarter;
1334         u_char *righth = lefth+sq.block_size_half;
1335         u_char *rightl = righth+sq.block_size_quarter;
1336         count = min(userCount, frameLeft)>>2 & ~1;
1337         used = count*4;
1338         while (count > 0) {
1339             data = get_user(((u_short *)userPtr)++);
1340             *lefth = data>>8;
1341             *leftl = (data>>2) & 0x3f;
1342             data = get_user(((u_short *)userPtr)++);
1343             *righth = data>>8;
1344             *rightl = (data>>2) & 0x3f;
1345             count--;
1346         }
1347     }
1348     *frameUsed += used;
1349     return(used);
1350 }
1351 
1352 
1353 static long ami_ct_u16be(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
1354                          long *frameUsed, long frameLeft)
1355 {
1356     long count, used;
1357     u_long data;
1358 
1359     if (!sound.soft.stereo) {
1360         u_char *high = &frame[*frameUsed>>1];
1361         u_char *low = high+sq.block_size_half;
1362         count = min(userCount, frameLeft)>>1 & ~1;
1363         used = count*2;
1364         while (count > 0) {
1365             data = get_user(((u_short *)userPtr)++) ^ 0x8000;
1366             *high = data>>8;
1367             *low = (data>>2) & 0x3f;
1368             count--;
1369         }
1370     } else {
1371         u_char *lefth = &frame[*frameUsed>>2];
1372         u_char *leftl = lefth+sq.block_size_quarter;
1373         u_char *righth = lefth+sq.block_size_half;
1374         u_char *rightl = righth+sq.block_size_quarter;
1375         count = min(userCount, frameLeft)>>2 & ~1;
1376         used = count*4;
1377         while (count > 0) {
1378             data = get_user(((u_short *)userPtr)++) ^ 0x8000;
1379             *lefth = data>>8;
1380             *leftl = (data>>2) & 0x3f;
1381             data = get_user(((u_short *)userPtr)++) ^ 0x8000;
1382             *righth = data>>8;
1383             *rightl = (data>>2) & 0x3f;
1384             count--;
1385         }
1386     }
1387     *frameUsed += used;
1388     return(used);
1389 }
1390 
1391 
1392 static long ami_ct_s16le(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
1393                          long *frameUsed, long frameLeft)
1394 {
1395     long count, used;
1396     u_long data;
1397 
1398     if (!sound.soft.stereo) {
1399         u_char *high = &frame[*frameUsed>>1];
1400         u_char *low = high+sq.block_size_half;
1401         count = min(userCount, frameLeft)>>1 & ~1;
1402         used = count*2;
1403         while (count > 0) {
1404             data = get_user(((u_short *)userPtr)++);
1405             data = le2be16(data);
1406             *high = data>>8;
1407             *low = (data>>2) & 0x3f;
1408             count--;
1409         }
1410     } else {
1411         u_char *lefth = &frame[*frameUsed>>2];
1412         u_char *leftl = lefth+sq.block_size_quarter;
1413         u_char *righth = lefth+sq.block_size_half;
1414         u_char *rightl = righth+sq.block_size_quarter;
1415         count = min(userCount, frameLeft)>>2 & ~1;
1416         used = count*4;
1417         while (count > 0) {
1418             data = get_user(((u_short *)userPtr)++);
1419             data = le2be16(data);
1420             *lefth = data>>8;
1421             *leftl = (data>>2) & 0x3f;
1422             data = get_user(((u_short *)userPtr)++);
1423             data = le2be16(data);
1424             *righth = data>>8;
1425             *rightl = (data>>2) & 0x3f;
1426             count--;
1427         }
1428     }
1429     *frameUsed += used;
1430     return(used);
1431 }
1432 
1433 
1434 static long ami_ct_u16le(const u_char *userPtr, long userCount, u_char frame[],
     /* [previous][next][first][last][top][bottom][index][help] */
1435                          long *frameUsed, long frameLeft)
1436 {
1437     long count, used;
1438     u_long data;
1439 
1440     if (!sound.soft.stereo) {
1441         u_char *high = &frame[*frameUsed>>1];
1442         u_char *low = high+sq.block_size_half;
1443         count = min(userCount, frameLeft)>>1 & ~1;
1444         used = count*2;
1445         while (count > 0) {
1446             data = get_user(((u_short *)userPtr)++);
1447             data = le2be16(data) ^ 0x8000;
1448             *high = data>>8;
1449             *low = (data>>2) & 0x3f;
1450             count--;
1451         }
1452     } else {
1453         u_char *lefth = &frame[*frameUsed>>2];
1454         u_char *leftl = lefth+sq.block_size_quarter;
1455         u_char *righth = lefth+sq.block_size_half;
1456         u_char *rightl = righth+sq.block_size_quarter;
1457         count = min(userCount, frameLeft)>>2 & ~1;
1458         used = count*4;
1459         while (count > 0) {
1460             data = get_user(((u_short *)userPtr)++);
1461             data = le2be16(data) ^ 0x8000;
1462             *lefth = data>>8;
1463             *leftl = (data>>2) & 0x3f;
1464             data = get_user(((u_short *)userPtr)++);
1465             data = le2be16(data) ^ 0x8000;
1466             *righth = data>>8;
1467             *rightl = (data>>2) & 0x3f;
1468             count--;
1469         }
1470     }
1471     *frameUsed += used;
1472     return(used);
1473 }
1474 #endif /* CONFIG_AMIGA */
1475 
1476 
1477 #ifdef CONFIG_ATARI
1478 static TRANS transTTNormal = {
1479     ata_ct_law, ata_ct_law, ata_ct_s8, ata_ct_u8, NULL, NULL, NULL, NULL
1480 };
1481 
1482 static TRANS transTTExpanding = {
1483     ata_ctx_law, ata_ctx_law, ata_ctx_s8, ata_ctx_u8, NULL, NULL, NULL, NULL
1484 };
1485 
1486 static TRANS transFalconNormal = {
1487     ata_ct_law, ata_ct_law, ata_ct_s8, ata_ct_u8, ata_ct_s16be, ata_ct_u16be,
1488     ata_ct_s16le, ata_ct_u16le
1489 };
1490 
1491 static TRANS transFalconExpanding = {
1492     ata_ctx_law, ata_ctx_law, ata_ctx_s8, ata_ctx_u8, ata_ctx_s16be,
1493     ata_ctx_u16be, ata_ctx_s16le, ata_ctx_u16le
1494 };
1495 #endif /* CONFIG_ATARI */
1496 
1497 #ifdef CONFIG_AMIGA
1498 static TRANS transAmiga = {
1499     ami_ct_law, ami_ct_law, ami_ct_s8, ami_ct_u8, ami_ct_s16be, ami_ct_u16be,
1500     ami_ct_s16le, ami_ct_u16le
1501 };
1502 #endif /* CONFIG_AMIGA */
1503 
1504 
1505 /*** Low level stuff *********************************************************/
1506 
1507 
1508 #ifdef CONFIG_ATARI
1509 
1510 /*
1511  * Atari (TT/Falcon)
1512  */
1513 
1514 static void *AtaAlloc(unsigned int size, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
1515 {
1516     int order;
1517     unsigned int a_size;
1518     order = 0;
1519     a_size = PAGE_SIZE;
1520     while (a_size < size) {
1521         order++;
1522         a_size <<= 1;
1523     }
1524     return (void *) __get_dma_pages(flags, order);
1525 }
1526 
1527 static void AtaFree(void *obj, unsigned int size)
     /* [previous][next][first][last][top][bottom][index][help] */
1528 {
1529     int order;
1530     unsigned int a_size;
1531     order = 0;
1532     a_size = PAGE_SIZE;
1533     while (a_size < size) {
1534         order++;
1535         a_size <<= 1;
1536     }
1537     free_pages (obj, order);
1538 }
1539 
1540 static int AtaIrqInit(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1541 {
1542     /* Set up timer A. Timer A
1543     will receive a signal upon end of playing from the sound
1544     hardware. Furthermore Timer A is able to count events
1545     and will cause an interrupt after a programmed number
1546     of events. So all we need to keep the music playing is
1547     to provide the sound hardware with new data upon
1548     an interrupt from timer A. */
1549     mfp.tim_ct_a = 0;           /* ++roman: Stop timer before programming! */
1550     mfp.tim_dt_a = 1;           /* Cause interrupt after first event. */
1551     mfp.tim_ct_a = 8;           /* Turn on event counting. */
1552     /* Register interrupt handler. */
1553     add_isr(IRQ_MFP_TIMA, ata_sq_interrupt, IRQ_TYPE_SLOW, NULL, "DMA sound");
1554     mfp.int_en_a |= 0x20;       /* Turn interrupt on. */
1555     mfp.int_mk_a |= 0x20;
1556     return(1);
1557 }
1558 
1559 
1560 #define TONE_VOXWARE_TO_DB(v) \
1561         (((v) < 0) ? -12 : ((v) > 100) ? 12 : ((v) - 50) * 6 / 25)
1562 #define TONE_DB_TO_VOXWARE(v) (((v) * 25 + ((v) > 0 ? 5 : -5)) / 6 + 50)
1563 
1564 
1565 static int AtaSetBass(int bass)
     /* [previous][next][first][last][top][bottom][index][help] */
1566 {
1567     sound.bass = TONE_VOXWARE_TO_DB(bass);
1568     atari_microwire_cmd(MW_LM1992_BASS(sound.bass));
1569     return(TONE_DB_TO_VOXWARE(sound.bass));
1570 }
1571 
1572 
1573 static int AtaSetTreble(int treble)
     /* [previous][next][first][last][top][bottom][index][help] */
1574 {
1575     sound.treble = TONE_VOXWARE_TO_DB(treble);
1576     atari_microwire_cmd(MW_LM1992_TREBLE(sound.treble));
1577     return(TONE_DB_TO_VOXWARE(sound.treble));
1578 }
1579 
1580 
1581 
1582 /*
1583  * TT
1584  */
1585 
1586 
1587 static void TTSilence(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1588 {
1589     tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1590     atari_microwire_cmd(MW_LM1992_PSG_HIGH); /* mix in PSG signal 1:1 */
1591 }
1592 
1593 
1594 static void TTInit(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1595 {
1596     int mode, i, idx;
1597     const int freq[4] = {50066, 25033, 12517, 6258};
1598 
1599     /* search a frequency that fits into the allowed error range */
1600 
1601     idx = -1;
1602     for (i = 0; i < arraysize(freq); i++)
1603         /* this isn't as much useful for a TT than for a Falcon, but
1604          * then it doesn't hurt very much to implement it for a TT too.
1605          */
1606         if ((100 * abs(sound.soft.speed - freq[i]) / freq[i]) < catchRadius)
1607             idx = i;
1608     if (idx > -1) {
1609         sound.soft.speed = freq[idx];
1610         sound.trans = &transTTNormal;
1611     } else
1612         sound.trans = &transTTExpanding;
1613 
1614     TTSilence();
1615     sound.hard = sound.soft;
1616 
1617     if (sound.hard.speed > 50066) {
1618         /* we would need to squeeze the sound, but we won't do that */
1619         sound.hard.speed = 50066;
1620         mode = DMASND_MODE_50KHZ;
1621         sound.trans = &transTTNormal;
1622     } else if (sound.hard.speed > 25033) {
1623         sound.hard.speed = 50066;
1624         mode = DMASND_MODE_50KHZ;
1625     } else if (sound.hard.speed > 12517) {
1626         sound.hard.speed = 25033;
1627         mode = DMASND_MODE_25KHZ;
1628     } else if (sound.hard.speed > 6258) {
1629         sound.hard.speed = 12517;
1630         mode = DMASND_MODE_12KHZ;
1631     } else {
1632         sound.hard.speed = 6258;
1633         mode = DMASND_MODE_6KHZ;
1634     }
1635 
1636     tt_dmasnd.mode = (sound.hard.stereo ?
1637                       DMASND_MODE_STEREO : DMASND_MODE_MONO) |
1638                      DMASND_MODE_8BIT | mode;
1639 
1640     sound.bal = -sound.soft.speed;
1641 }
1642 
1643 
1644 static int TTSetFormat(int format)
     /* [previous][next][first][last][top][bottom][index][help] */
1645 {
1646     /* TT sound DMA supports only 8bit modes */
1647 
1648     switch (format) {
1649         case AFMT_QUERY:
1650             return(sound.soft.format);
1651         case AFMT_MU_LAW:
1652         case AFMT_A_LAW:
1653         case AFMT_S8:
1654         case AFMT_U8:
1655             break;
1656         default:
1657             format = AFMT_S8;
1658     }
1659 
1660     sound.soft.format = format;
1661     sound.soft.size = 8;
1662     if (sound.minDev == SND_DEV_DSP) {
1663         sound.dsp.format = format;
1664         sound.dsp.size = 8;
1665     }
1666     TTInit();
1667 
1668     return(format);
1669 }
1670 
1671 
1672 #define VOLUME_VOXWARE_TO_DB(v) \
1673         (((v) < 0) ? -40 : ((v) > 100) ? 0 : ((v) * 2) / 5 - 40)
1674 #define VOLUME_DB_TO_VOXWARE(v) ((((v) + 40) * 5 + 1) / 2)
1675 
1676 
1677 static int TTSetVolume(int volume)
     /* [previous][next][first][last][top][bottom][index][help] */
1678 {
1679     sound.volume_left = VOLUME_VOXWARE_TO_DB(volume & 0xff);
1680     atari_microwire_cmd(MW_LM1992_BALLEFT(sound.volume_left));
1681     sound.volume_right = VOLUME_VOXWARE_TO_DB((volume & 0xff00) >> 8);
1682     atari_microwire_cmd(MW_LM1992_BALRIGHT(sound.volume_right));
1683     return(VOLUME_DB_TO_VOXWARE(sound.volume_left) |
1684            (VOLUME_DB_TO_VOXWARE(sound.volume_right) << 8));
1685 }
1686 
1687 
1688 
1689 /*
1690  * Falcon
1691  */
1692 
1693 
1694 static void FalconSilence(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1695 {
1696     /* stop playback, set sample rate 50kHz for PSG sound */
1697     tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1698     tt_dmasnd.mode = DMASND_MODE_50KHZ | DMASND_MODE_STEREO | DMASND_MODE_8BIT;
1699     tt_dmasnd.int_div = 0; /* STE compatible divider */
1700     tt_dmasnd.int_ctrl = 0x0;
1701     tt_dmasnd.cbar_src = 0x0000; /* no matrix inputs */
1702     tt_dmasnd.cbar_dst = 0x0000; /* no matrix outputs */
1703     tt_dmasnd.dac_src = 1; /* connect ADC to DAC, disconnect matrix */
1704     tt_dmasnd.adc_src = 3; /* ADC Input = PSG */
1705 }
1706 
1707 
1708 static void FalconInit(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1709 {
1710     int divider, i, idx;
1711     const int freq[8] = {49170, 32780, 24585, 19668, 16390, 12292, 9834, 8195};
1712 
1713     /* search a frequency that fits into the allowed error range */
1714 
1715     idx = -1;
1716     for (i = 0; i < arraysize(freq); i++)
1717         /* if we will tolerate 3% error 8000Hz->8195Hz (2.38%) would
1718          * be playable without expanding, but that now a kernel runtime
1719          * option
1720          */
1721         if ((100 * abs(sound.soft.speed - freq[i]) / freq[i]) < catchRadius)
1722             idx = i;
1723     if (idx > -1) {
1724         sound.soft.speed = freq[idx];
1725         sound.trans = &transFalconNormal;
1726     } else
1727         sound.trans = &transFalconExpanding;
1728 
1729     FalconSilence();
1730     sound.hard = sound.soft;
1731 
1732     if (sound.hard.size == 16) {
1733         /* the Falcon can play 16bit samples only in stereo */
1734         sound.hard.stereo = 1;
1735     }
1736 
1737     if (sound.hard.speed > 49170) {
1738         /* we would need to squeeze the sound, but we won't do that */
1739         sound.hard.speed = 49170;
1740         divider = 1;
1741         sound.trans = &transFalconNormal;
1742     } else if (sound.hard.speed > 32780) {
1743         sound.hard.speed = 49170;
1744         divider = 1;
1745     } else if (sound.hard.speed > 24585) {
1746         sound.hard.speed = 32780;
1747         divider = 2;
1748     } else if (sound.hard.speed > 19668) {
1749         sound.hard.speed = 24585;
1750         divider = 3;
1751     } else if (sound.hard.speed > 16390) {
1752         sound.hard.speed = 19668;
1753         divider = 4;
1754     } else if (sound.hard.speed > 12292) {
1755         sound.hard.speed = 16390;
1756         divider = 5;
1757     } else if (sound.hard.speed > 9834) {
1758         sound.hard.speed = 12292;
1759         divider = 7;
1760     } else if (sound.hard.speed > 8195) {
1761         sound.hard.speed = 9834;
1762         divider = 9;
1763     } else {
1764         sound.hard.speed = 8195;
1765         divider = 11;
1766     }
1767     tt_dmasnd.int_div = divider;
1768 
1769     /* Setup Falcon sound DMA for playback */
1770     tt_dmasnd.int_ctrl = 0x4; /* Timer A int at play end */
1771     tt_dmasnd.track_select = 0x0; /* play 1 track, track 1 */
1772     tt_dmasnd.cbar_src = 0x0001; /* DMA(25MHz) --> DAC */
1773     tt_dmasnd.cbar_dst = 0x0000;
1774     tt_dmasnd.rec_track_select = 0;
1775     tt_dmasnd.dac_src = 2; /* connect matrix to DAC */
1776     tt_dmasnd.adc_src = 0; /* ADC Input = Mic */
1777 
1778     tt_dmasnd.mode = (sound.hard.stereo ?
1779                       DMASND_MODE_STEREO : DMASND_MODE_MONO) |
1780                      ((sound.hard.size == 8) ?
1781                        DMASND_MODE_8BIT : DMASND_MODE_16BIT) |
1782                      DMASND_MODE_6KHZ;
1783 
1784     sound.bal = -sound.soft.speed;
1785 }
1786 
1787 
1788 static int FalconSetFormat(int format)
     /* [previous][next][first][last][top][bottom][index][help] */
1789 {
1790     int size;
1791     /* Falcon sound DMA supports 8bit and 16bit modes */
1792 
1793     switch (format) {
1794         case AFMT_QUERY:
1795             return(sound.soft.format);
1796         case AFMT_MU_LAW:
1797         case AFMT_A_LAW:
1798         case AFMT_U8:
1799         case AFMT_S8:
1800             size = 8;
1801             break;
1802         case AFMT_S16_BE:
1803         case AFMT_U16_BE:
1804         case AFMT_S16_LE:
1805         case AFMT_U16_LE:
1806             size = 16;
1807             break;
1808         default: /* :-) */
1809             size = 8;
1810             format = AFMT_S8;
1811     }
1812 
1813     sound.soft.format = format;
1814     sound.soft.size = size;
1815     if (sound.minDev == SND_DEV_DSP) {
1816         sound.dsp.format = format;
1817         sound.dsp.size = sound.soft.size;
1818     }
1819 
1820     FalconInit();
1821 
1822     return(format);
1823 }
1824 
1825 
1826 /* This is for the Falcon output *attenuation* in 1.5dB steps,
1827  * i.e. output level from 0 to -22.5dB in -1.5dB steps.
1828  */
1829 #define VOLUME_VOXWARE_TO_ATT(v) \
1830         ((v) < 0 ? 15 : (v) > 100 ? 0 : 15 - (v) * 3 / 20)
1831 #define VOLUME_ATT_TO_VOXWARE(v) (100 - (v) * 20 / 3)
1832 
1833 
1834 static int FalconSetVolume(int volume)
     /* [previous][next][first][last][top][bottom][index][help] */
1835 {
1836     sound.volume_left = VOLUME_VOXWARE_TO_ATT(volume & 0xff);
1837     sound.volume_right = VOLUME_VOXWARE_TO_ATT((volume & 0xff00) >> 8);
1838     tt_dmasnd.output_atten = sound.volume_left << 8 | sound.volume_right << 4;
1839     return(VOLUME_ATT_TO_VOXWARE(sound.volume_left) |
1840            VOLUME_ATT_TO_VOXWARE(sound.volume_right) << 8);
1841 }
1842 
1843 
1844 static void ata_sq_play_next_frame(int index)
     /* [previous][next][first][last][top][bottom][index][help] */
1845 {
1846     char *start, *end;
1847 
1848     /* used by AtaPlay() if all doubts whether there really is something
1849      * to be played are already wiped out.
1850      */
1851     start = sq_block_address(sq.front);
1852     end = start+((sq.count == index) ? sq.rear_size : sq.block_size);
1853     /* end might not be a legal virtual address. */
1854     DMASNDSetEnd(VTOP(end - 1) + 1);
1855     DMASNDSetBase(VTOP(start));
1856         /* Since only an even number of samples per frame can
1857         be played, we might lose one byte here. (TO DO) */
1858     sq.front = (sq.front+1) % sq.max_count;
1859     sq.playing++;
1860     tt_dmasnd.ctrl = DMASND_CTRL_ON | DMASND_CTRL_REPEAT;
1861 }
1862 
1863 
1864 static void AtaPlay(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1865 {
1866     /* ++TeSche: Note that sq.playing is no longer just a flag but holds
1867      * the number of frames the DMA is currently programmed for instead,
1868      * may be 0, 1 (currently being played) or 2 (pre-programmed).
1869      *
1870      * Changes done to sq.count and sq.playing are a bit more subtle again
1871      * so now I must admit I also prefer disabling the irq here rather
1872      * than considering all possible situations. But the point is that
1873      * disabling the irq doesn't have any bad influence on this version of
1874      * the driver as we benefit from having pre-programmed the DMA
1875      * whereever possible: There's no need to reload the DMA at the exact
1876      * time of an interrupt but only at some time while the pre-programmed
1877      * frame is playing!
1878      */
1879     atari_disable_irq(IRQ_MFP_TIMA);
1880 
1881     if (sq.playing == 2 ||      /* DMA is 'full' */
1882         sq.count <= 0) {        /* nothing to do */
1883         atari_enable_irq(IRQ_MFP_TIMA);
1884         return;
1885     }
1886 
1887     if (sq.playing == 0) {
1888         /* looks like there's nothing 'in' the DMA yet, so try
1889          * to put two frames into it (at least one is available).
1890          */
1891         if (sq.count == 1 && sq.rear_size < sq.block_size && !sq.syncing) {
1892             /* hmmm, the only existing frame is not
1893              * yet filled and we're not syncing?
1894              */
1895             atari_enable_irq(IRQ_MFP_TIMA);
1896             return;
1897         }
1898         ata_sq_play_next_frame(1);
1899         if (sq.count == 1) {
1900             /* no more frames */
1901             atari_enable_irq(IRQ_MFP_TIMA);
1902             return;
1903         }
1904         if (sq.count == 2 && sq.rear_size < sq.block_size && !sq.syncing) {
1905             /* hmmm, there were two frames, but the second
1906              * one is not yet filled and we're not syncing?
1907              */
1908             atari_enable_irq(IRQ_MFP_TIMA);
1909             return;
1910         }
1911         ata_sq_play_next_frame(2);
1912     } else {
1913         /* there's already a frame being played so we may only stuff
1914          * one new into the DMA, but even if this may be the last
1915          * frame existing the previous one is still on sq.count.
1916          */
1917         if (sq.count == 2 && sq.rear_size < sq.block_size && !sq.syncing) {
1918             /* hmmm, the only existing frame is not
1919              * yet filled and we're not syncing?
1920              */
1921             atari_enable_irq(IRQ_MFP_TIMA);
1922             return;
1923         }
1924         ata_sq_play_next_frame(2);
1925     }
1926     atari_enable_irq(IRQ_MFP_TIMA);
1927 }
1928 
1929 
1930 static void ata_sq_interrupt(int irq, struct pt_regs *fp, void *dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
1931 {
1932 #if 0
1933     /* ++TeSche: if you should want to test this... */
1934     static int cnt = 0;
1935     if (sq.playing == 2)
1936         if (++cnt == 10) {
1937             /* simulate losing an interrupt */
1938             cnt = 0;
1939             return;
1940         }
1941 #endif
1942 
1943     if (sq.ignore_int && (sound.mach.type == DMASND_FALCON)) {
1944         /* ++TeSche: Falcon only: ignore first irq because it comes
1945          * immediately after starting a frame. after that, irqs come
1946          * (almost) like on the TT.
1947          */
1948         sq.ignore_int = 0;
1949         return;
1950     }
1951 
1952     if (!sq.playing) {
1953         /* playing was interrupted and sq_reset() has already cleared
1954          * the sq variables, so better don't do anything here.
1955          */
1956         WAKE_UP(sq.sync_queue);
1957         return;
1958     }
1959 
1960     /* Probably ;) one frame is finished. Well, in fact it may be that a
1961      * pre-programmed one is also finished because there has been a long
1962      * delay in interrupt delivery and we've completely lost one, but
1963      * there's no way to detect such a situation. In such a case the last
1964      * frame will be played more than once and the situation will recover
1965      * as soon as the irq gets through.
1966      */
1967     sq.count--;
1968     sq.playing--;
1969 
1970     if (!sq.playing) {
1971         tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1972         sq.ignore_int = 1;
1973     }
1974 
1975     WAKE_UP(sq.write_queue);
1976         /* At least one block of the queue is free now
1977         so wake up a writing process blocked because
1978         of a full queue. */
1979 
1980     if ((sq.playing != 1) || (sq.count != 1))
1981         /* We must be a bit carefully here: sq.count indicates the
1982          * number of buffers used and not the number of frames to
1983          * be played. If sq.count==1 and sq.playing==1 that means
1984          * the only remaining frame was already programmed earlier
1985          * (and is currently running) so we mustn't call AtaPlay()
1986          * here, otherwise we'll play one frame too much.
1987          */
1988         AtaPlay();
1989 
1990     if (!sq.playing) WAKE_UP(sq.sync_queue);
1991         /* We are not playing after AtaPlay(), so there
1992         is nothing to play any more. Wake up a process
1993         waiting for audio output to drain. */
1994 }
1995 #endif /* CONFIG_ATARI */
1996 
1997 
1998 #ifdef CONFIG_AMIGA
1999 
2000 /*
2001  * Amiga
2002  */
2003 
2004 
2005 static void *AmiAlloc(unsigned int size, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
2006 {
2007     return(amiga_chip_alloc((long)size));
2008 }
2009 
2010 static void AmiFree(void *obj, unsigned int size)
     /* [previous][next][first][last][top][bottom][index][help] */
2011 {
2012     amiga_chip_free (obj);
2013 }
2014 
2015 static int AmiIrqInit(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2016 {
2017     /* turn off DMA for audio channels */
2018     custom.dmacon = AMI_AUDIO_OFF;
2019 
2020     /* Register interrupt handler. */
2021     if (!add_isr(IRQ_AMIGA_AUD0, ami_sq_interrupt, 0, NULL, "DMA sound"))
2022         panic("Couldn't add audio interrupt");
2023     return(1);
2024 }
2025 
2026 
2027 static void AmiSilence(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2028 {
2029     /* turn off DMA for audio channels */
2030     custom.dmacon = AMI_AUDIO_OFF;
2031 }
2032 
2033 
2034 static void AmiInit(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2035 {
2036     int period, i;
2037 
2038     AmiSilence();
2039 
2040     if (sound.soft.speed)
2041         period = amiga_colorclock/sound.soft.speed-1;
2042     else
2043         period = amiga_audio_min_period;
2044     sound.hard = sound.soft;
2045     sound.trans = &transAmiga;
2046 
2047     if (period < amiga_audio_min_period) {
2048         /* we would need to squeeze the sound, but we won't do that */
2049         period = amiga_audio_min_period;
2050         sound.hard.speed = amiga_colorclock/(period+1);
2051     } else if (period > 65535) {
2052         period = 65535;
2053         sound.hard.speed = amiga_colorclock/(period+1);
2054     }
2055     for (i = 0; i < 4; i++)
2056         custom.aud[i].audper = period;
2057     amiga_audio_period = period;
2058 }
2059 
2060 
2061 static int AmiSetFormat(int format)
     /* [previous][next][first][last][top][bottom][index][help] */
2062 {
2063     int size;
2064 
2065     /* Amiga sound DMA supports 8bit and 16bit (pseudo 14 bit) modes */
2066 
2067     switch (format) {
2068         case AFMT_QUERY:
2069             return(sound.soft.format);
2070         case AFMT_MU_LAW:
2071         case AFMT_A_LAW:
2072         case AFMT_U8:
2073         case AFMT_S8:
2074             size = 8;
2075             break;
2076         case AFMT_S16_BE:
2077         case AFMT_U16_BE:
2078         case AFMT_S16_LE:
2079         case AFMT_U16_LE:
2080             size = 16;
2081             break;
2082         default: /* :-) */
2083             size = 8;
2084             format = AFMT_S8;
2085     }
2086 
2087     sound.soft.format = format;
2088     sound.soft.size = size;
2089     if (sound.minDev == SND_DEV_DSP) {
2090         sound.dsp.format = format;
2091         sound.dsp.size = sound.soft.size;
2092     }
2093     AmiInit();
2094 
2095     return(format);
2096 }
2097 
2098 
2099 #define VOLUME_VOXWARE_TO_AMI(v) \
2100         (((v) < 0) ? 0 : ((v) > 100) ? 64 : ((v) * 64)/100)
2101 #define VOLUME_AMI_TO_VOXWARE(v) ((v)*100/64)
2102 
2103 static int AmiSetVolume(int volume)
     /* [previous][next][first][last][top][bottom][index][help] */
2104 {
2105     sound.volume_left = VOLUME_VOXWARE_TO_AMI(volume & 0xff);
2106     custom.aud[0].audvol = sound.volume_left;
2107     sound.volume_right = VOLUME_VOXWARE_TO_AMI((volume & 0xff00) >> 8);
2108     custom.aud[1].audvol = sound.volume_right;
2109     return(VOLUME_AMI_TO_VOXWARE(sound.volume_left) |
2110            (VOLUME_AMI_TO_VOXWARE(sound.volume_right) << 8));
2111 }
2112 
2113 static int AmiSetTreble(int treble)
     /* [previous][next][first][last][top][bottom][index][help] */
2114 {
2115     sound.treble = treble;
2116     if (treble > 50)
2117         ciaa.pra |= 0x02;
2118     else
2119         ciaa.pra &= ~0x02;
2120     return(treble);
2121 }
2122 
2123 
2124 #define AMI_PLAY_LOADED         1
2125 #define AMI_PLAY_PLAYING        2
2126 #define AMI_PLAY_MASK           3
2127 
2128 
2129 static void ami_sq_play_next_frame(int index)
     /* [previous][next][first][last][top][bottom][index][help] */
2130 {
2131     u_char *start, *ch0, *ch1, *ch2, *ch3;
2132     u_long size;
2133 
2134     /* used by AmiPlay() if all doubts whether there really is something
2135      * to be played are already wiped out.
2136      */
2137     start = sq_block_address(sq.front);
2138     size = (sq.count == index ? sq.rear_size : sq.block_size)>>1;
2139 
2140     if (sound.hard.stereo) {
2141         ch0 = start;
2142         ch1 = start+sq.block_size_half;
2143         size >>= 1;
2144     } else {
2145         ch0 = start;
2146         ch1 = start;
2147     }
2148     if (sound.hard.size == 8) {
2149         custom.aud[0].audlc = (u_short *)ZTWO_PADDR(ch0);
2150         custom.aud[0].audlen = size;
2151         custom.aud[1].audlc = (u_short *)ZTWO_PADDR(ch1);
2152         custom.aud[1].audlen = size;
2153         custom.dmacon = AMI_AUDIO_8;
2154     } else {
2155         size >>= 1;
2156         custom.aud[0].audlc = (u_short *)ZTWO_PADDR(ch0);
2157         custom.aud[0].audlen = size;
2158         custom.aud[1].audlc = (u_short *)ZTWO_PADDR(ch1);
2159         custom.aud[1].audlen = size;
2160         if (sound.volume_left == 64 && sound.volume_right == 64) {
2161             /* We can play pseudo 14-bit only with the maximum volume */
2162             ch3 = ch0+sq.block_size_quarter;
2163             ch2 = ch1+sq.block_size_quarter;
2164             custom.aud[2].audlc = (u_short *)ZTWO_PADDR(ch2);
2165             custom.aud[2].audlen = size;
2166             custom.aud[3].audlc = (u_short *)ZTWO_PADDR(ch3);
2167             custom.aud[3].audlen = size;
2168             custom.dmacon = AMI_AUDIO_14;
2169         } else
2170             custom.dmacon = AMI_AUDIO_8;
2171     }
2172     sq.front = (sq.front+1) % sq.max_count;
2173     sq.playing |= AMI_PLAY_LOADED;
2174 }
2175 
2176 
2177 static void AmiPlay(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2178 {
2179     int minframes = 1;
2180 
2181     custom.intena = IF_AUD0;
2182 
2183     if (sq.playing & AMI_PLAY_LOADED) {
2184         /* There's already a frame loaded */
2185         custom.intena = IF_SETCLR | IF_AUD0;
2186         return;
2187     }
2188 
2189     if (sq.playing & AMI_PLAY_PLAYING)
2190         /* Increase threshold: frame 1 is already being played */
2191         minframes = 2;
2192 
2193     if (sq.count < minframes) {
2194         /* Nothing to do */
2195         custom.intena = IF_SETCLR | IF_AUD0;
2196         return;
2197     }
2198 
2199     if (sq.count <= minframes && sq.rear_size < sq.block_size && !sq.syncing) {
2200         /* hmmm, the only existing frame is not
2201          * yet filled and we're not syncing?
2202          */
2203         custom.intena = IF_SETCLR | IF_AUD0;
2204         return;
2205     }
2206 
2207     ami_sq_play_next_frame(minframes);
2208 
2209     custom.intena = IF_SETCLR | IF_AUD0;
2210 }
2211 
2212 
2213 static void ami_sq_interrupt(int irq, struct pt_regs *fp, void *dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
2214 {
2215     int minframes = 1;
2216 
2217     if (!sq.playing) {
2218         /* Playing was interrupted and sq_reset() has already cleared
2219          * the sq variables, so better don't do anything here.
2220          */
2221         WAKE_UP(sq.sync_queue);
2222         return;
2223     }
2224 
2225     if (sq.playing & AMI_PLAY_PLAYING) {
2226         /* We've just finished a frame */
2227         sq.count--;
2228         WAKE_UP(sq.write_queue);
2229     }
2230 
2231     if (sq.playing & AMI_PLAY_LOADED)
2232         /* Increase threshold: frame 1 is already being played */
2233         minframes = 2;
2234 
2235     /* Shift the flags */
2236     sq.playing = (sq.playing<<1) & AMI_PLAY_MASK;
2237 
2238     if (!sq.playing)
2239         /* No frame is playing, disable audio DMA */
2240         custom.dmacon = AMI_AUDIO_OFF;
2241 
2242     if (sq.count >= minframes)
2243         /* Try to play the next frame */
2244         AmiPlay();
2245 
2246     if (!sq.playing)
2247         /* Nothing to play anymore.
2248            Wake up a process waiting for audio output to drain. */
2249         WAKE_UP(sq.sync_queue);
2250 }
2251 #endif /* CONFIG_AMIGA */
2252 
2253 
2254 /*** Machine definitions *****************************************************/
2255 
2256 
2257 #ifdef CONFIG_ATARI
2258 static MACHINE machTT = {
2259     DMASND_TT, AtaAlloc, AtaFree, AtaIrqInit, TTInit, TTSilence, TTSetFormat,
2260     TTSetVolume, AtaSetBass, AtaSetTreble, AtaPlay
2261 };
2262 
2263 static MACHINE machFalcon = {
2264     DMASND_FALCON, AtaAlloc, AtaFree, AtaIrqInit, FalconInit, FalconSilence,
2265     FalconSetFormat, FalconSetVolume, AtaSetBass, AtaSetTreble, AtaPlay
2266 };
2267 #endif /* CONFIG_ATARI */
2268 
2269 #ifdef CONFIG_AMIGA
2270 static MACHINE machAmiga = {
2271     DMASND_AMIGA, AmiAlloc, AmiFree, AmiIrqInit, AmiInit, AmiSilence,
2272     AmiSetFormat, AmiSetVolume, NULL, AmiSetTreble, AmiPlay
2273 };
2274 #endif /* CONFIG_AMIGA */
2275 
2276 
2277 /*** Mid level stuff *********************************************************/
2278 
2279 
2280 static void sound_silence(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2281 {
2282     /* update hardware settings one more */
2283     (*sound.mach.init)();
2284 
2285     (*sound.mach.silence)();
2286 }
2287 
2288 
2289 static void sound_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2290 {
2291     (*sound.mach.init)();
2292 }
2293 
2294 
2295 static int sound_set_format(int format)
     /* [previous][next][first][last][top][bottom][index][help] */
2296 {
2297     return(*sound.mach.setFormat)(format);
2298 }
2299 
2300 
2301 static int sound_set_speed(int speed)
     /* [previous][next][first][last][top][bottom][index][help] */
2302 {
2303     if (speed < 0)
2304         return(sound.soft.speed);
2305 
2306     sound.soft.speed = speed;
2307     (*sound.mach.init)();
2308     if (sound.minDev == SND_DEV_DSP)
2309         sound.dsp.speed = sound.soft.speed;
2310 
2311     return(sound.soft.speed);
2312 }
2313 
2314 
2315 static int sound_set_stereo(int stereo)
     /* [previous][next][first][last][top][bottom][index][help] */
2316 {
2317     if (stereo < 0)
2318         return(sound.soft.stereo);
2319 
2320     stereo = !!stereo;    /* should be 0 or 1 now */
2321 
2322     sound.soft.stereo = stereo;
2323     if (sound.minDev == SND_DEV_DSP)
2324         sound.dsp.stereo = stereo;
2325     (*sound.mach.init)();
2326 
2327     return(stereo);
2328 }
2329 
2330 
2331 static int sound_set_volume(int volume)
     /* [previous][next][first][last][top][bottom][index][help] */
2332 {
2333     return(*sound.mach.setVolume)(volume);
2334 }
2335 
2336 
2337 #ifdef CONFIG_ATARI
2338 static int sound_set_bass(int bass)
     /* [previous][next][first][last][top][bottom][index][help] */
2339 {
2340     return(sound.mach.setBass ? (*sound.mach.setBass)(bass) : 50);
2341 }
2342 #endif /* CONFIG_ATARI */
2343 
2344 
2345 static int sound_set_treble(int treble)
     /* [previous][next][first][last][top][bottom][index][help] */
2346 {
2347     return(sound.mach.setTreble ? (*sound.mach.setTreble)(treble) : 50);
2348 }
2349 
2350 
2351 static long sound_copy_translate(const u_char *userPtr, long userCount,
     /* [previous][next][first][last][top][bottom][index][help] */
2352                                  u_char frame[], long *frameUsed,
2353                                  long frameLeft)
2354 {
2355     long (*ct_func)(const u_char *, long, u_char *, long *, long) = NULL;
2356 
2357     switch (sound.soft.format) {
2358         case AFMT_MU_LAW:
2359             ct_func = sound.trans->ct_ulaw;
2360             break;
2361         case AFMT_A_LAW:
2362             ct_func = sound.trans->ct_alaw;
2363             break;
2364         case AFMT_S8:
2365             ct_func = sound.trans->ct_s8;
2366             break;
2367         case AFMT_U8:
2368             ct_func = sound.trans->ct_u8;
2369             break;
2370         case AFMT_S16_BE:
2371             ct_func = sound.trans->ct_s16be;
2372             break;
2373         case AFMT_U16_BE:
2374             ct_func = sound.trans->ct_u16be;
2375             break;
2376         case AFMT_S16_LE:
2377             ct_func = sound.trans->ct_s16le;
2378             break;
2379         case AFMT_U16_LE:
2380             ct_func = sound.trans->ct_u16le;
2381             break;
2382     }
2383     if (ct_func)
2384         return(ct_func(userPtr, userCount, frame, frameUsed, frameLeft));
2385     else
2386         return(0);
2387 }
2388 
2389 
2390 /*
2391  * /dev/mixer abstraction
2392  */
2393 
2394 
2395 #define RECLEVEL_VOXWARE_TO_GAIN(v) \
2396         ((v) < 0 ? 0 : (v) > 100 ? 15 : (v) * 3 / 20)
2397 #define RECLEVEL_GAIN_TO_VOXWARE(v) (((v) * 20 + 2) / 3)
2398 
2399 
2400 static void mixer_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2401 {
2402     mixer.busy = 0;
2403     sound.treble = 0;
2404     sound.bass = 0;
2405     switch (sound.mach.type) {
2406 #ifdef CONFIG_ATARI
2407         case DMASND_TT:
2408             atari_microwire_cmd(MW_LM1992_VOLUME(0));
2409             sound.volume_left = 0;
2410             atari_microwire_cmd(MW_LM1992_BALLEFT(0));
2411             sound.volume_right = 0;
2412             atari_microwire_cmd(MW_LM1992_BALRIGHT(0));
2413             atari_microwire_cmd(MW_LM1992_TREBLE(0));
2414             atari_microwire_cmd(MW_LM1992_BASS(0));
2415             break;
2416         case DMASND_FALCON:
2417             sound.volume_left = (tt_dmasnd.output_atten & 0xf00) >> 8;
2418             sound.volume_right = (tt_dmasnd.output_atten & 0xf0) >> 4;
2419             break;
2420 #endif /* CONFIG_ATARI */
2421 #ifdef CONFIG_AMIGA
2422         case DMASND_AMIGA:
2423             sound.volume_left = 64;
2424             sound.volume_right = 64;
2425             custom.aud[0].audvol = sound.volume_left;
2426             custom.aud[3].audvol = 1;                   /* For pseudo 14bit */
2427             custom.aud[1].audvol = sound.volume_right;
2428             custom.aud[2].audvol = 1;                   /* For pseudo 14bit */
2429             sound.treble = 50;
2430             break;
2431 #endif /* CONFIG_AMIGA */
2432     }
2433 }
2434 
2435 
2436 static int mixer_open(int open_mode)
     /* [previous][next][first][last][top][bottom][index][help] */
2437 {
2438     if (mixer.busy)
2439         return(-EBUSY);
2440     mixer.busy = 1;
2441     return(0);
2442 }
2443 
2444 
2445 static int mixer_release(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2446 {
2447     mixer.busy = 0;
2448     return(0);
2449 }
2450 
2451 
2452 static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
     /* [previous][next][first][last][top][bottom][index][help] */
2453                        u_long arg)
2454 {
2455     switch (sound.mach.type) {
2456 #ifdef CONFIG_ATARI
2457         case DMASND_FALCON:
2458             switch (cmd) {
2459                 case SOUND_MIXER_READ_DEVMASK:
2460                     return(IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_SPEAKER));
2461                 case SOUND_MIXER_READ_RECMASK:
2462                     return(IOCTL_OUT(arg, SOUND_MASK_MIC));
2463                 case SOUND_MIXER_READ_STEREODEVS:
2464                     return(IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC));
2465                 case SOUND_MIXER_READ_CAPS:
2466                     return(IOCTL_OUT(arg, SOUND_CAP_EXCL_INPUT));
2467                 case SOUND_MIXER_READ_VOLUME:
2468                     return(IOCTL_OUT(arg,
2469                         VOLUME_ATT_TO_VOXWARE(sound.volume_left) |
2470                         VOLUME_ATT_TO_VOXWARE(sound.volume_right) << 8));
2471                 case SOUND_MIXER_WRITE_MIC:
2472                     tt_dmasnd.input_gain =
2473                         RECLEVEL_VOXWARE_TO_GAIN(IOCTL_IN(arg) & 0xff) << 4 |
2474                         RECLEVEL_VOXWARE_TO_GAIN(IOCTL_IN(arg) >> 8 & 0xff);
2475                     /* fall thru, return set value */
2476                 case SOUND_MIXER_READ_MIC:
2477                     return(IOCTL_OUT(arg,
2478                         RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain >> 4 & 0xf) |
2479                         RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain & 0xf) << 8));
2480                 case SOUND_MIXER_READ_SPEAKER:
2481                     {
2482                         int porta;
2483                         cli();
2484                         sound_ym.rd_data_reg_sel = 14;
2485                         porta = sound_ym.rd_data_reg_sel;
2486                         sti();
2487                         return(IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
2488                     }
2489                 case SOUND_MIXER_WRITE_VOLUME:
2490                     return(IOCTL_OUT(arg, sound_set_volume(IOCTL_IN(arg))));
2491                 case SOUND_MIXER_WRITE_SPEAKER:
2492                     {
2493                         int porta;
2494                         cli();
2495                         sound_ym.rd_data_reg_sel = 14;
2496                         porta = (sound_ym.rd_data_reg_sel & ~0x40) |
2497                                 (IOCTL_IN(arg) < 50 ? 0x40 : 0);
2498                         sound_ym.wd_data = porta;
2499                         sti();
2500                         return(IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
2501                     }
2502             }
2503             break;
2504 
2505         case DMASND_TT:
2506             switch (cmd) {
2507                 case SOUND_MIXER_READ_DEVMASK:
2508                     return(IOCTL_OUT(arg,
2509                         SOUND_MASK_VOLUME | SOUND_MASK_TREBLE | SOUND_MASK_BASS |
2510                         ((boot_info.bi_atari.mch_cookie >> 16) == ATARI_MCH_TT ?
2511                             SOUND_MASK_SPEAKER : 0)));
2512                 case SOUND_MIXER_READ_RECMASK:
2513                     return(IOCTL_OUT(arg, 0));
2514                 case SOUND_MIXER_READ_STEREODEVS:
2515                     return(IOCTL_OUT(arg, SOUND_MASK_VOLUME));
2516                 case SOUND_MIXER_READ_VOLUME:
2517                     return(IOCTL_OUT(arg,
2518                         VOLUME_DB_TO_VOXWARE(sound.volume_left) |
2519                         (VOLUME_DB_TO_VOXWARE(sound.volume_right) << 8)));
2520                 case SOUND_MIXER_READ_BASS:
2521                     return(IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(sound.bass)));
2522                 case SOUND_MIXER_READ_TREBLE:
2523                     return(IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(sound.treble)));
2524                 case SOUND_MIXER_READ_SPEAKER:
2525                     {
2526                         int porta;
2527                         if ((boot_info.bi_atari.mch_cookie >> 16) == ATARI_MCH_TT) {
2528                             cli();
2529                             sound_ym.rd_data_reg_sel = 14;
2530                             porta = sound_ym.rd_data_reg_sel;
2531                             sti();
2532                             return(IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
2533                         } else
2534                             return(-EINVAL);
2535                     }
2536                 case SOUND_MIXER_WRITE_VOLUME:
2537                     return(IOCTL_OUT(arg, sound_set_volume(IOCTL_IN(arg))));
2538                 case SOUND_MIXER_WRITE_BASS:
2539                     return(IOCTL_OUT(arg, sound_set_bass(IOCTL_IN(arg))));
2540                 case SOUND_MIXER_WRITE_TREBLE:
2541                     return(IOCTL_OUT(arg, sound_set_treble(IOCTL_IN(arg))));
2542                 case SOUND_MIXER_WRITE_SPEAKER:
2543                     if ((boot_info.bi_atari.mch_cookie >> 16) == ATARI_MCH_TT) {
2544                         int porta;
2545                         cli();
2546                         sound_ym.rd_data_reg_sel = 14;
2547                         porta = (sound_ym.rd_data_reg_sel & ~0x40) |
2548                                 (IOCTL_IN(arg) < 50 ? 0x40 : 0);
2549                         sound_ym.wd_data = porta;
2550                         sti();
2551                         return(IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
2552                     } else
2553                         return(-EINVAL);
2554             }
2555             break;
2556 #endif /* CONFIG_ATARI */
2557 
2558 #ifdef CONFIG_AMIGA
2559         case DMASND_AMIGA:
2560             switch (cmd) {
2561                 case SOUND_MIXER_READ_DEVMASK:
2562                     return(IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_TREBLE));
2563                 case SOUND_MIXER_READ_RECMASK:
2564                     return(IOCTL_OUT(arg, 0));
2565                 case SOUND_MIXER_READ_STEREODEVS:
2566                     return(IOCTL_OUT(arg, SOUND_MASK_VOLUME));
2567                 case SOUND_MIXER_READ_VOLUME:
2568                     return(IOCTL_OUT(arg,
2569                         VOLUME_AMI_TO_VOXWARE(sound.volume_left) |
2570                         VOLUME_AMI_TO_VOXWARE(sound.volume_right) << 8));
2571                 case SOUND_MIXER_WRITE_VOLUME:
2572                     return(IOCTL_OUT(arg, sound_set_volume(IOCTL_IN(arg))));
2573                 case SOUND_MIXER_READ_TREBLE:
2574                     return(IOCTL_OUT(arg, sound.treble));
2575                 case SOUND_MIXER_WRITE_TREBLE:
2576                     return(IOCTL_OUT(arg, sound_set_treble(IOCTL_IN(arg))));
2577             }
2578             break;
2579 #endif /* CONFIG_AMIGA */
2580     }
2581 
2582     return(-EINVAL);
2583 }
2584 
2585 
2586 
2587 /*
2588  * Sound queue stuff, the heart of the driver
2589  */
2590 
2591 
2592 static void sq_init(int numBufs, int bufSize, char **buffers)
     /* [previous][next][first][last][top][bottom][index][help] */
2593 {
2594     sq.max_count = numBufs;
2595     sq.block_size = bufSize;
2596     sq.buffers = buffers;
2597 
2598     sq.front = sq.count = 0;
2599     sq.rear = -1;
2600     sq.write_queue = sq.open_queue = sq.sync_queue = 0;
2601     sq.busy = 0;
2602     sq.syncing = 0;
2603 
2604     sq.playing = 0;
2605 
2606 #ifdef CONFIG_ATARI
2607     sq.ignore_int = 0;
2608 #endif /* CONFIG_ATARI */
2609 #ifdef CONFIG_AMIGA
2610     sq.block_size_half = sq.block_size>>1;
2611     sq.block_size_quarter = sq.block_size_half>>1;
2612 #endif /* CONFIG_AMIGA */
2613 
2614     sound_silence();
2615 
2616     /* whatever you like as startup mode for /dev/dsp,
2617      * (/dev/audio hasn't got a startup mode). note that
2618      * once changed a new open() will *not* restore these!
2619      */
2620     sound.dsp.format = AFMT_S8;
2621     sound.dsp.stereo = 0;
2622     sound.dsp.size = 8;
2623 
2624     /* set minimum rate possible without expanding */
2625     switch (sound.mach.type) {
2626 #ifdef CONFIG_ATARI
2627         case DMASND_TT:
2628             sound.dsp.speed = 6258;
2629             break;
2630         case DMASND_FALCON:
2631             sound.dsp.speed = 8195;
2632             break;
2633 #endif /* CONFIG_ATARI */
2634 #ifdef CONFIG_AMIGA
2635         case DMASND_AMIGA:
2636             sound.dsp.speed = 8000;
2637             break;
2638 #endif /* CONFIG_AMIGA */
2639     }
2640 
2641     /* before the first open to /dev/dsp this wouldn't be set */
2642     sound.soft = sound.dsp;
2643 }
2644 
2645 
2646 static void sq_play(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2647 {
2648     (*sound.mach.play)();
2649 }
2650 
2651 
2652 /* ++TeSche: radically changed this one too */
2653 
2654 static int sq_write(const char *src, int uLeft)
     /* [previous][next][first][last][top][bottom][index][help] */
2655 {
2656     int uWritten = 0;
2657     u_char *dest;
2658     long uUsed, bUsed, bLeft;
2659 
2660     /* ++TeSche: Is something like this necessary?
2661      * Hey, that's an honest question! Or does any other part of the
2662      * filesystem already checks this situation? I really don't know.
2663      */
2664     if (uLeft < 1)
2665         return(0);
2666 
2667     /* The interrupt doesn't start to play the last, incomplete frame.
2668      * Thus we can append to it without disabling the interrupts! (Note
2669      * also that sq.rear isn't affected by the interrupt.)
2670      */
2671 
2672     if (sq.count > 0 && (bLeft = sq.block_size-sq.rear_size) > 0) {
2673         dest = sq_block_address(sq.rear);
2674         bUsed = sq.rear_size;
2675         uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft);
2676         src += uUsed;
2677         uWritten += uUsed;
2678         uLeft -= uUsed;
2679         sq.rear_size = bUsed;
2680     }
2681 
2682     do {
2683         if (sq.count == sq.max_count) {
2684             sq_play();
2685             if (NON_BLOCKING(sq.open_mode))
2686                 return(uWritten > 0 ? uWritten : -EAGAIN);
2687             SLEEP(sq.write_queue, ONE_SECOND);
2688             if (SIGNAL_RECEIVED)
2689                 return(uWritten > 0 ? uWritten : -EINTR);
2690         }
2691 
2692         /* Here, we can avoid disabling the interrupt by first
2693          * copying and translating the data, and then updating
2694          * the sq variables. Until this is done, the interrupt
2695          * won't see the new frame and we can work on it
2696          * undisturbed.
2697          */
2698 
2699         dest = sq_block_address((sq.rear+1) % sq.max_count);
2700         bUsed = 0;
2701         bLeft = sq.block_size;
2702         uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft);
2703         src += uUsed;
2704         uWritten += uUsed;
2705         uLeft -= uUsed;
2706         if (bUsed) {
2707             sq.rear = (sq.rear+1) % sq.max_count;
2708             sq.rear_size = bUsed;
2709             sq.count++;
2710         }
2711     } while (bUsed);   /* uUsed may have been 0 */
2712 
2713     sq_play();
2714 
2715     return(uWritten);
2716 }
2717 
2718 
2719 static int sq_open(int open_mode)
     /* [previous][next][first][last][top][bottom][index][help] */
2720 {
2721     if (sq.busy) {
2722         if (NON_BLOCKING(open_mode))
2723             return(-EBUSY);
2724         while (sq.busy) {
2725             SLEEP(sq.open_queue, ONE_SECOND);
2726             if (SIGNAL_RECEIVED)
2727                 return(-EINTR);
2728         }
2729     }
2730     sq.open_mode = open_mode;
2731     sq.busy = 1;
2732 #ifdef CONFIG_ATARI
2733     sq.ignore_int = 1;
2734 #endif /* CONFIG_ATARI */
2735     return(0);
2736 }
2737 
2738 
2739 static void sq_reset(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2740 {
2741     sound_silence();
2742     sq.playing = 0;
2743     sq.count = 0;
2744     sq.front = (sq.rear+1) % sq.max_count;
2745 }
2746 
2747 
2748 static int sq_sync(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2749 {
2750     int rc = 0;
2751 
2752     sq.syncing = 1;
2753     sq_play();  /* there may be an incomplete frame waiting */
2754 
2755     while (sq.playing) {
2756         SLEEP(sq.sync_queue, ONE_SECOND);
2757         if (SIGNAL_RECEIVED) {
2758             /* While waiting for audio output to drain, an interrupt occured.
2759                Stop audio output immediately and clear the queue. */
2760             sq_reset();
2761             rc = -EINTR;
2762             break;
2763         }
2764     }
2765 
2766     sq.syncing = 0;
2767     return(rc);
2768 }
2769 
2770 
2771 static int sq_release(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2772 {
2773     int rc = 0;
2774     if (sq.busy) {
2775         rc = sq_sync();
2776         sq.busy = 0;
2777         WAKE_UP(sq.open_queue);
2778         /* Wake up a process waiting for the queue beeing released.
2779            Note: There may be several processes waiting for a call to open()
2780                  returning. */
2781     }
2782     return(rc);
2783 }
2784 
2785 
2786 
2787 /*
2788  * /dev/sndstat
2789  */
2790 
2791 
2792 static void state_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2793 {
2794     state.busy = 0;
2795 }
2796 
2797 
2798 /* state.buf should not overflow! */
2799 
2800 static int state_open(int open_mode)
     /* [previous][next][first][last][top][bottom][index][help] */
2801 {
2802     char *buffer = state.buf, *mach = "";
2803     int len = 0;
2804 
2805     if (state.busy)
2806         return(-EBUSY);
2807 
2808     state.ptr = 0;
2809     state.busy = 1;
2810 
2811     switch (sound.mach.type) {
2812 #ifdef CONFIG_ATARI
2813         case DMASND_TT:
2814         case DMASND_FALCON:
2815             mach = "Atari ";
2816             break;
2817 #endif /* CONFIG_ATARI */
2818 #ifdef CONFIG_AMIGA
2819         case DMASND_AMIGA:
2820             mach = "Amiga ";
2821             break;
2822 #endif /* CONFIG_AMIGA */
2823     }
2824     len += sprintf(buffer+len, "%sDMA sound driver:\n", mach);
2825 
2826     len += sprintf(buffer+len, "\tsound.format = 0x%x", sound.soft.format);
2827     switch (sound.soft.format) {
2828         case AFMT_MU_LAW:
2829             len += sprintf(buffer+len, " (mu-law)");
2830             break;
2831         case AFMT_A_LAW:
2832             len += sprintf(buffer+len, " (A-law)");
2833             break;
2834         case AFMT_U8:
2835             len += sprintf(buffer+len, " (unsigned 8 bit)");
2836             break;
2837         case AFMT_S8:
2838             len += sprintf(buffer+len, " (signed 8 bit)");
2839             break;
2840         case AFMT_S16_BE:
2841             len += sprintf(buffer+len, " (signed 16 bit big)");
2842             break;
2843         case AFMT_U16_BE:
2844             len += sprintf(buffer+len, " (unsigned 16 bit big)");
2845             break;
2846         case AFMT_S16_LE:
2847             len += sprintf(buffer+len, " (signed 16 bit little)");
2848             break;
2849         case AFMT_U16_LE:
2850             len += sprintf(buffer+len, " (unsigned 16 bit little)");
2851             break;
2852     }
2853     len += sprintf(buffer+len, "\n");
2854     len += sprintf(buffer+len, "\tsound.speed = %dHz (phys. %dHz)\n",
2855                    sound.soft.speed, sound.hard.speed);
2856     len += sprintf(buffer+len, "\tsound.stereo = 0x%x (%s)\n",
2857                    sound.soft.stereo, sound.soft.stereo ? "stereo" : "mono");
2858     switch (sound.mach.type) {
2859 #ifdef CONFIG_ATARI
2860         case DMASND_TT:
2861             len += sprintf(buffer+len, "\tsound.volume_left = %ddB [-40...0]\n",
2862                            sound.volume_left);
2863             len += sprintf(buffer+len, "\tsound.volume_right = %ddB [-40...0]\n",
2864                            sound.volume_right);
2865             len += sprintf(buffer+len, "\tsound.bass = %ddB [-12...+12]\n",
2866                            sound.bass);
2867             len += sprintf(buffer+len, "\tsound.treble = %ddB [-12...+12]\n",
2868                            sound.treble);
2869             break;
2870         case DMASND_FALCON:
2871             len += sprintf(buffer+len, "\tsound.volume_left = %ddB [-22.5...0]\n",
2872                            sound.volume_left);
2873             len += sprintf(buffer+len, "\tsound.volume_right = %ddB [-22.5...0]\n",
2874                            sound.volume_right);
2875             break;
2876 #endif /* CONFIG_ATARI */
2877 #ifdef CONFIG_AMIGA
2878         case DMASND_AMIGA:
2879             len += sprintf(buffer+len, "\tsound.volume_left = %d [0...64]\n",
2880                            sound.volume_left);
2881             len += sprintf(buffer+len, "\tsound.volume_right = %d [0...64]\n",
2882                            sound.volume_right);
2883             break;
2884 #endif /* CONFIG_AMIGA */
2885     }
2886     len += sprintf(buffer+len, "\tsq.block_size = %d sq.max_count = %d\n",
2887                    sq.block_size, sq.max_count);
2888     len += sprintf(buffer+len, "\tsq.count = %d sq.rear_size = %d\n", sq.count,
2889                    sq.rear_size);
2890     len += sprintf(buffer+len, "\tsq.playing = %d sq.syncing = %d\n",
2891                    sq.playing, sq.syncing);
2892     state.len = len;
2893     return(0);
2894 }
2895 
2896 
2897 static int state_release(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2898 {
2899     state.busy = 0;
2900     return(0);
2901 }
2902 
2903 
2904 static int state_read(char *dest, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
2905 {
2906     int n = state.len-state.ptr;
2907     if (n > count)
2908         n = count;
2909     if (n <= 0)
2910         return(0);
2911     memcpy_tofs(dest, &state.buf[state.ptr], n);
2912     state.ptr += n;
2913     return(n);
2914 }
2915 
2916 
2917 
2918 /*** High level stuff ********************************************************/
2919 
2920 
2921 static int sound_open(struct inode *inode, struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
2922 {
2923     int dev = MINOR(inode->i_rdev) & 0x0f;
2924 
2925     switch (dev) {
2926         case SND_DEV_STATUS:
2927             return(state_open(file->f_flags));
2928         case SND_DEV_CTL:
2929             return(mixer_open(file->f_flags));
2930         case SND_DEV_DSP:
2931         case SND_DEV_AUDIO:
2932             {
2933                 int rc = sq_open(file->f_flags);
2934                 if (rc == 0) {
2935                     sound.minDev = dev;
2936                     sound.soft = sound.dsp;
2937                     sound_init();
2938                     if (dev == SND_DEV_AUDIO) {
2939                         sound_set_speed(8000);
2940                         sound_set_stereo(0);
2941                         sound_set_format(AFMT_MU_LAW);
2942                     }
2943                 }
2944                 return(rc);
2945             }
2946         default:
2947             return(-ENXIO);
2948     }
2949 }
2950 
2951 
2952 static int sound_fsync(struct inode *inode, struct file *filp)
     /* [previous][next][first][last][top][bottom][index][help] */
2953 {
2954     int dev = MINOR(inode->i_rdev) & 0x0f;
2955 
2956     switch (dev) {
2957         case SND_DEV_STATUS:
2958         case SND_DEV_CTL:
2959             return(0);
2960         case SND_DEV_DSP:
2961         case SND_DEV_AUDIO:
2962             return(sq_sync());
2963         default:
2964             return(unknown_minor_dev("sound_fsync", dev));
2965     }
2966 }
2967 
2968 
2969 static void sound_release(struct inode *inode, struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
2970 {
2971     int dev = MINOR(inode->i_rdev);
2972 
2973     switch (dev & 0x0f) {
2974         case SND_DEV_STATUS: state_release(); return;
2975         case SND_DEV_CTL: mixer_release(); return;
2976         case SND_DEV_DSP:
2977         case SND_DEV_AUDIO:
2978             sq_release(); sound.soft = sound.dsp; sound_silence();
2979             return;
2980         default:
2981             unknown_minor_dev("sound_release", dev);
2982     }
2983 }
2984 
2985 
2986 static int sound_lseek(struct inode *inode, struct file *file, off_t offset,
     /* [previous][next][first][last][top][bottom][index][help] */
2987                        int orig)
2988 {
2989     return(-EPERM);
2990 }
2991 
2992 
2993 static int sound_read(struct inode *inode, struct file *file, char *buf,
     /* [previous][next][first][last][top][bottom][index][help] */
2994                       int count)
2995 {
2996     int dev = MINOR(inode->i_rdev);
2997 
2998     switch (dev & 0x0f) {
2999         case SND_DEV_STATUS:
3000             return(state_read(buf, count));
3001         case SND_DEV_CTL:
3002         case SND_DEV_DSP:
3003         case SND_DEV_AUDIO:
3004             return(-EPERM);
3005         default:
3006             return(unknown_minor_dev("sound_read", dev));
3007     }
3008 }
3009 
3010 
3011 static int sound_write(struct inode *inode, struct file *file, const char *buf,
     /* [previous][next][first][last][top][bottom][index][help] */
3012                        int count)
3013 {
3014     int dev = MINOR(inode->i_rdev);
3015 
3016     switch (dev & 0x0f) {
3017         case SND_DEV_STATUS:
3018         case SND_DEV_CTL:
3019             return(-EPERM);
3020         case SND_DEV_DSP:
3021         case SND_DEV_AUDIO:
3022             return(sq_write(buf, count));
3023         default:
3024             return(unknown_minor_dev("sound_write", dev));
3025     }
3026 }
3027 
3028 
3029 static int ioctl_return(int *addr, int value)
     /* [previous][next][first][last][top][bottom][index][help] */
3030 {
3031     int error;
3032 
3033     if (value < 0)
3034         return(value);
3035 
3036     error = verify_area(VERIFY_WRITE, addr, sizeof(int));
3037     if (error)
3038         return(error);
3039 
3040     put_user(value, addr);
3041     return(0);
3042 }
3043 
3044 
3045 static int unknown_minor_dev(char *fname, int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
3046 {
3047     /* printk("%s: Unknown minor device %d\n", fname, dev); */
3048     return(-ENXIO);
3049 }
3050 
3051 
3052 static int sound_ioctl(struct inode *inode, struct file *file, u_int cmd,
     /* [previous][next][first][last][top][bottom][index][help] */
3053                        u_long arg)
3054 {
3055     int dev = MINOR(inode->i_rdev);
3056     u_long fmt;
3057 
3058     switch (dev & 0x0f) {
3059         case SND_DEV_STATUS:
3060             return(-EPERM);
3061         case SND_DEV_CTL:
3062             return(mixer_ioctl(inode, file, cmd, arg));
3063         case SND_DEV_AUDIO:
3064         case SND_DEV_DSP:
3065             switch (cmd) {
3066                 case SNDCTL_DSP_RESET:
3067                     sq_reset();
3068                     return(0);
3069                 case SNDCTL_DSP_POST:
3070                 case SNDCTL_DSP_SYNC:
3071                     return(sound_fsync(inode, file));
3072 
3073                 /* ++TeSche: before changing any of these it's probably wise to
3074                  * wait until sound playing has settled down
3075                  */
3076                 case SNDCTL_DSP_SPEED:
3077                     sound_fsync(inode, file);
3078                     return(IOCTL_OUT(arg, sound_set_speed(IOCTL_IN(arg))));
3079                 case SNDCTL_DSP_STEREO:
3080                     sound_fsync(inode, file);
3081                     return(IOCTL_OUT(arg, sound_set_stereo(IOCTL_IN(arg))));
3082                 case SOUND_PCM_WRITE_CHANNELS:
3083                     sound_fsync(inode, file);
3084                     return(IOCTL_OUT(arg, sound_set_stereo(IOCTL_IN(arg)-1)+1));
3085                 case SNDCTL_DSP_SETFMT:
3086                     sound_fsync(inode, file);
3087                     return(IOCTL_OUT(arg, sound_set_format(IOCTL_IN(arg))));
3088                 case SNDCTL_DSP_GETFMTS:
3089                     fmt = 0;
3090                     if (sound.trans) {
3091                         if (sound.trans->ct_ulaw)
3092                             fmt |= AFMT_MU_LAW;
3093                         if (sound.trans->ct_alaw)
3094                             fmt |= AFMT_A_LAW;
3095                         if (sound.trans->ct_s8)
3096                             fmt |= AFMT_S8;
3097                         if (sound.trans->ct_u8)
3098                             fmt |= AFMT_U8;
3099                         if (sound.trans->ct_s16be)
3100                             fmt |= AFMT_S16_BE;
3101                         if (sound.trans->ct_u16be)
3102                             fmt |= AFMT_U16_BE;
3103                         if (sound.trans->ct_s16le)
3104                             fmt |= AFMT_S16_LE;
3105                         if (sound.trans->ct_u16le)
3106                             fmt |= AFMT_U16_LE;
3107                     }
3108                     return(IOCTL_OUT(arg, fmt));
3109                 case SNDCTL_DSP_GETBLKSIZE:
3110                     return(IOCTL_OUT(arg, 10240));
3111                 case SNDCTL_DSP_SUBDIVIDE:
3112                 case SNDCTL_DSP_SETFRAGMENT:
3113                     break;
3114 
3115                 default:
3116                     return(mixer_ioctl(inode, file, cmd, arg));
3117             }
3118             break;
3119 
3120         default:
3121             return(unknown_minor_dev("sound_ioctl", dev));
3122     }
3123     return(-EINVAL);
3124 }
3125 
3126 
3127 static struct file_operations sound_fops =
3128 {
3129     sound_lseek,
3130     sound_read,
3131     sound_write,
3132     NULL,
3133     NULL,                      /* select */
3134     sound_ioctl,
3135     NULL,
3136     sound_open,
3137     sound_release,
3138     sound_fsync
3139 };
3140 
3141 
3142 
3143 /*** Config & Setup **********************************************************/
3144 
3145 
3146 void soundcard_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
3147 {
3148     int has_sound = 0;
3149     char **buffers;
3150     int i;
3151 
3152     switch (boot_info.machtype) {
3153 #ifdef CONFIG_ATARI
3154         case MACH_ATARI:
3155             if (ATARIHW_PRESENT(PCM_8BIT)) {
3156                 if (ATARIHW_PRESENT(CODEC))
3157                     sound.mach = machFalcon;
3158                 else if (ATARIHW_PRESENT(MICROWIRE))
3159                     sound.mach = machTT;
3160                 else
3161                     break;
3162                 if ((mfp.int_en_a & mfp.int_mk_a & 0x20) == 0)
3163                     has_sound = 1;
3164                 else
3165                     printk("DMA sound driver: Timer A interrupt already in use\n");
3166             }
3167             break;
3168 
3169 #endif /* CONFIG_ATARI */
3170 #ifdef CONFIG_AMIGA
3171         case MACH_AMIGA:
3172             if (AMIGAHW_PRESENT(AMI_AUDIO)) {
3173                 sound.mach = machAmiga;
3174                 has_sound = 1;
3175             }
3176             break;
3177 #endif /* CONFIG_AMIGA */
3178     }
3179     if (!has_sound)
3180         return;
3181 
3182     /* Set up sound queue, /dev/audio and /dev/dsp. */
3183     buffers = kmalloc (numBufs * sizeof(char *), GFP_KERNEL);
3184     if (!buffers) {
3185     out_of_memory:
3186         printk("DMA sound driver: Not enough buffer memory, driver disabled!\n");
3187         return;
3188     }
3189     for (i = 0; i < numBufs; i++) {
3190         buffers[i] = sound.mach.dma_alloc (bufSize << 10, GFP_KERNEL);
3191         if (!buffers[i]) {
3192             while (i--)
3193                 sound.mach.dma_free (buffers[i], bufSize << 10);
3194             kfree (buffers);
3195             goto out_of_memory;
3196         }
3197     }
3198 
3199     /* Register driver with the VFS. */
3200     register_chrdev(SOUND_MAJOR, "sound", &sound_fops);
3201 
3202     sq_init(numBufs, bufSize << 10, buffers);
3203 
3204     /* Set up /dev/sndstat. */
3205     state_init();
3206 
3207     /* Set up /dev/mixer. */
3208     mixer_init();
3209 
3210     if (!sound.mach.irqinit()) {
3211         printk("DMA sound driver: Interrupt initialization failed\n");
3212         return;
3213     }
3214 
3215     printk("DMA sound driver installed, using %d buffers of %dk.\n", numBufs,
3216            bufSize);
3217 
3218     return;
3219 }
3220 
3221 void sound_setup(char *str, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
3222 {
3223     /* ++Martin: stub, could possibly be merged with soundcard.c et al later */
3224 }
3225 
3226 void dmasound_setup(char *str, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
3227 {
3228     /* check the bootstrap parameter for "dmasound=" */
3229 
3230     switch (ints[0]) {
3231         case 3:
3232             if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
3233                 printk("dmasound_setup: illegal catch radius, using default = %d\n", catchRadius);
3234             else
3235                 catchRadius = ints[3];
3236             /* fall through */
3237         case 2:
3238             if (ints[1] < MIN_BUFFERS)
3239                 printk("dmasound_setup: illegal number of buffers, using default = %d\n", numBufs);
3240             else
3241                 numBufs = ints[1];
3242             if (ints[2] < MIN_BUFSIZE || ints[2] > MAX_BUFSIZE)
3243                 printk("dmasound_setup: illegal buffer size, using default = %d\n", bufSize);
3244             else
3245                 bufSize = ints[2];
3246             break;
3247         case 0:
3248             break;
3249         default:
3250             printk("dmasound_setup: illegal number of arguments\n");
3251     }
3252 }

/* [previous][next][first][last][top][bottom][index][help] */