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