linux/sound/isa/sb/emu8000.c
<<
>>
Prefs
   1/*
   2 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
   3 *     and (c) 1999 Steve Ratcliffe <steve@parabola.demon.co.uk>
   4 *  Copyright (C) 1999-2000 Takashi Iwai <tiwai@suse.de>
   5 *
   6 *  Routines for control of EMU8000 chip
   7 *
   8 *   This program is free software; you can redistribute it and/or modify
   9 *   it under the terms of the GNU General Public License as published by
  10 *   the Free Software Foundation; either version 2 of the License, or
  11 *   (at your option) any later version.
  12 *
  13 *   This program is distributed in the hope that it will be useful,
  14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 *   GNU General Public License for more details.
  17 *
  18 *   You should have received a copy of the GNU General Public License
  19 *   along with this program; if not, write to the Free Software
  20 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  21 */
  22
  23#include <linux/wait.h>
  24#include <linux/sched/signal.h>
  25#include <linux/slab.h>
  26#include <linux/ioport.h>
  27#include <linux/export.h>
  28#include <linux/delay.h>
  29#include <linux/io.h>
  30#include <sound/core.h>
  31#include <sound/emu8000.h>
  32#include <sound/emu8000_reg.h>
  33#include <linux/uaccess.h>
  34#include <linux/init.h>
  35#include <sound/control.h>
  36#include <sound/initval.h>
  37
  38/*
  39 * emu8000 register controls
  40 */
  41
  42/*
  43 * The following routines read and write registers on the emu8000.  They
  44 * should always be called via the EMU8000*READ/WRITE macros and never
  45 * directly.  The macros handle the port number and command word.
  46 */
  47/* Write a word */
  48void snd_emu8000_poke(struct snd_emu8000 *emu, unsigned int port, unsigned int reg, unsigned int val)
  49{
  50        unsigned long flags;
  51        spin_lock_irqsave(&emu->reg_lock, flags);
  52        if (reg != emu->last_reg) {
  53                outw((unsigned short)reg, EMU8000_PTR(emu)); /* Set register */
  54                emu->last_reg = reg;
  55        }
  56        outw((unsigned short)val, port); /* Send data */
  57        spin_unlock_irqrestore(&emu->reg_lock, flags);
  58}
  59
  60/* Read a word */
  61unsigned short snd_emu8000_peek(struct snd_emu8000 *emu, unsigned int port, unsigned int reg)
  62{
  63        unsigned short res;
  64        unsigned long flags;
  65        spin_lock_irqsave(&emu->reg_lock, flags);
  66        if (reg != emu->last_reg) {
  67                outw((unsigned short)reg, EMU8000_PTR(emu)); /* Set register */
  68                emu->last_reg = reg;
  69        }
  70        res = inw(port);        /* Read data */
  71        spin_unlock_irqrestore(&emu->reg_lock, flags);
  72        return res;
  73}
  74
  75/* Write a double word */
  76void snd_emu8000_poke_dw(struct snd_emu8000 *emu, unsigned int port, unsigned int reg, unsigned int val)
  77{
  78        unsigned long flags;
  79        spin_lock_irqsave(&emu->reg_lock, flags);
  80        if (reg != emu->last_reg) {
  81                outw((unsigned short)reg, EMU8000_PTR(emu)); /* Set register */
  82                emu->last_reg = reg;
  83        }
  84        outw((unsigned short)val, port); /* Send low word of data */
  85        outw((unsigned short)(val>>16), port+2); /* Send high word of data */
  86        spin_unlock_irqrestore(&emu->reg_lock, flags);
  87}
  88
  89/* Read a double word */
  90unsigned int snd_emu8000_peek_dw(struct snd_emu8000 *emu, unsigned int port, unsigned int reg)
  91{
  92        unsigned short low;
  93        unsigned int res;
  94        unsigned long flags;
  95        spin_lock_irqsave(&emu->reg_lock, flags);
  96        if (reg != emu->last_reg) {
  97                outw((unsigned short)reg, EMU8000_PTR(emu)); /* Set register */
  98                emu->last_reg = reg;
  99        }
 100        low = inw(port);        /* Read low word of data */
 101        res = low + (inw(port+2) << 16);
 102        spin_unlock_irqrestore(&emu->reg_lock, flags);
 103        return res;
 104}
 105
 106/*
 107 * Set up / close a channel to be used for DMA.
 108 */
 109/*exported*/ void
 110snd_emu8000_dma_chan(struct snd_emu8000 *emu, int ch, int mode)
 111{
 112        unsigned right_bit = (mode & EMU8000_RAM_RIGHT) ? 0x01000000 : 0;
 113        mode &= EMU8000_RAM_MODE_MASK;
 114        if (mode == EMU8000_RAM_CLOSE) {
 115                EMU8000_CCCA_WRITE(emu, ch, 0);
 116                EMU8000_DCYSUSV_WRITE(emu, ch, 0x807F);
 117                return;
 118        }
 119        EMU8000_DCYSUSV_WRITE(emu, ch, 0x80);
 120        EMU8000_VTFT_WRITE(emu, ch, 0);
 121        EMU8000_CVCF_WRITE(emu, ch, 0);
 122        EMU8000_PTRX_WRITE(emu, ch, 0x40000000);
 123        EMU8000_CPF_WRITE(emu, ch, 0x40000000);
 124        EMU8000_PSST_WRITE(emu, ch, 0);
 125        EMU8000_CSL_WRITE(emu, ch, 0);
 126        if (mode == EMU8000_RAM_WRITE) /* DMA write */
 127                EMU8000_CCCA_WRITE(emu, ch, 0x06000000 | right_bit);
 128        else       /* DMA read */
 129                EMU8000_CCCA_WRITE(emu, ch, 0x04000000 | right_bit);
 130}
 131
 132/*
 133 */
 134static void
 135snd_emu8000_read_wait(struct snd_emu8000 *emu)
 136{
 137        while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) {
 138                schedule_timeout_interruptible(1);
 139                if (signal_pending(current))
 140                        break;
 141        }
 142}
 143
 144/*
 145 */
 146static void
 147snd_emu8000_write_wait(struct snd_emu8000 *emu)
 148{
 149        while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
 150                schedule_timeout_interruptible(1);
 151                if (signal_pending(current))
 152                        break;
 153        }
 154}
 155
 156/*
 157 * detect a card at the given port
 158 */
 159static int
 160snd_emu8000_detect(struct snd_emu8000 *emu)
 161{
 162        /* Initialise */
 163        EMU8000_HWCF1_WRITE(emu, 0x0059);
 164        EMU8000_HWCF2_WRITE(emu, 0x0020);
 165        EMU8000_HWCF3_WRITE(emu, 0x0000);
 166        /* Check for a recognisable emu8000 */
 167        /*
 168        if ((EMU8000_U1_READ(emu) & 0x000f) != 0x000c)
 169                return -ENODEV;
 170                */
 171        if ((EMU8000_HWCF1_READ(emu) & 0x007e) != 0x0058)
 172                return -ENODEV;
 173        if ((EMU8000_HWCF2_READ(emu) & 0x0003) != 0x0003)
 174                return -ENODEV;
 175
 176        snd_printdd("EMU8000 [0x%lx]: Synth chip found\n",
 177                    emu->port1);
 178        return 0;
 179}
 180
 181
 182/*
 183 * intiailize audio channels
 184 */
 185static void
 186init_audio(struct snd_emu8000 *emu)
 187{
 188        int ch;
 189
 190        /* turn off envelope engines */
 191        for (ch = 0; ch < EMU8000_CHANNELS; ch++)
 192                EMU8000_DCYSUSV_WRITE(emu, ch, 0x80);
 193  
 194        /* reset all other parameters to zero */
 195        for (ch = 0; ch < EMU8000_CHANNELS; ch++) {
 196                EMU8000_ENVVOL_WRITE(emu, ch, 0);
 197                EMU8000_ENVVAL_WRITE(emu, ch, 0);
 198                EMU8000_DCYSUS_WRITE(emu, ch, 0);
 199                EMU8000_ATKHLDV_WRITE(emu, ch, 0);
 200                EMU8000_LFO1VAL_WRITE(emu, ch, 0);
 201                EMU8000_ATKHLD_WRITE(emu, ch, 0);
 202                EMU8000_LFO2VAL_WRITE(emu, ch, 0);
 203                EMU8000_IP_WRITE(emu, ch, 0);
 204                EMU8000_IFATN_WRITE(emu, ch, 0);
 205                EMU8000_PEFE_WRITE(emu, ch, 0);
 206                EMU8000_FMMOD_WRITE(emu, ch, 0);
 207                EMU8000_TREMFRQ_WRITE(emu, ch, 0);
 208                EMU8000_FM2FRQ2_WRITE(emu, ch, 0);
 209                EMU8000_PTRX_WRITE(emu, ch, 0);
 210                EMU8000_VTFT_WRITE(emu, ch, 0);
 211                EMU8000_PSST_WRITE(emu, ch, 0);
 212                EMU8000_CSL_WRITE(emu, ch, 0);
 213                EMU8000_CCCA_WRITE(emu, ch, 0);
 214        }
 215
 216        for (ch = 0; ch < EMU8000_CHANNELS; ch++) {
 217                EMU8000_CPF_WRITE(emu, ch, 0);
 218                EMU8000_CVCF_WRITE(emu, ch, 0);
 219        }
 220}
 221
 222
 223/*
 224 * initialize DMA address
 225 */
 226static void
 227init_dma(struct snd_emu8000 *emu)
 228{
 229        EMU8000_SMALR_WRITE(emu, 0);
 230        EMU8000_SMARR_WRITE(emu, 0);
 231        EMU8000_SMALW_WRITE(emu, 0);
 232        EMU8000_SMARW_WRITE(emu, 0);
 233}
 234
 235/*
 236 * initialization arrays; from ADIP
 237 */
 238static unsigned short init1[128] = {
 239        0x03ff, 0x0030,  0x07ff, 0x0130, 0x0bff, 0x0230,  0x0fff, 0x0330,
 240        0x13ff, 0x0430,  0x17ff, 0x0530, 0x1bff, 0x0630,  0x1fff, 0x0730,
 241        0x23ff, 0x0830,  0x27ff, 0x0930, 0x2bff, 0x0a30,  0x2fff, 0x0b30,
 242        0x33ff, 0x0c30,  0x37ff, 0x0d30, 0x3bff, 0x0e30,  0x3fff, 0x0f30,
 243
 244        0x43ff, 0x0030,  0x47ff, 0x0130, 0x4bff, 0x0230,  0x4fff, 0x0330,
 245        0x53ff, 0x0430,  0x57ff, 0x0530, 0x5bff, 0x0630,  0x5fff, 0x0730,
 246        0x63ff, 0x0830,  0x67ff, 0x0930, 0x6bff, 0x0a30,  0x6fff, 0x0b30,
 247        0x73ff, 0x0c30,  0x77ff, 0x0d30, 0x7bff, 0x0e30,  0x7fff, 0x0f30,
 248
 249        0x83ff, 0x0030,  0x87ff, 0x0130, 0x8bff, 0x0230,  0x8fff, 0x0330,
 250        0x93ff, 0x0430,  0x97ff, 0x0530, 0x9bff, 0x0630,  0x9fff, 0x0730,
 251        0xa3ff, 0x0830,  0xa7ff, 0x0930, 0xabff, 0x0a30,  0xafff, 0x0b30,
 252        0xb3ff, 0x0c30,  0xb7ff, 0x0d30, 0xbbff, 0x0e30,  0xbfff, 0x0f30,
 253
 254        0xc3ff, 0x0030,  0xc7ff, 0x0130, 0xcbff, 0x0230,  0xcfff, 0x0330,
 255        0xd3ff, 0x0430,  0xd7ff, 0x0530, 0xdbff, 0x0630,  0xdfff, 0x0730,
 256        0xe3ff, 0x0830,  0xe7ff, 0x0930, 0xebff, 0x0a30,  0xefff, 0x0b30,
 257        0xf3ff, 0x0c30,  0xf7ff, 0x0d30, 0xfbff, 0x0e30,  0xffff, 0x0f30,
 258};
 259
 260static unsigned short init2[128] = {
 261        0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330,
 262        0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730,
 263        0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30,
 264        0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30,
 265
 266        0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330,
 267        0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730,
 268        0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30,
 269        0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30,
 270
 271        0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330,
 272        0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730,
 273        0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30,
 274        0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30,
 275
 276        0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330,
 277        0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730,
 278        0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30,
 279        0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30,
 280};
 281
 282static unsigned short init3[128] = {
 283        0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
 284        0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254,
 285        0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234,
 286        0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224,
 287
 288        0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254,
 289        0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264,
 290        0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294,
 291        0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3,
 292
 293        0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287,
 294        0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7,
 295        0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386,
 296        0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55,
 297
 298        0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308,
 299        0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F,
 300        0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319,
 301        0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570,
 302};
 303
 304static unsigned short init4[128] = {
 305        0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
 306        0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254,
 307        0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234,
 308        0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224,
 309
 310        0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254,
 311        0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264,
 312        0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294,
 313        0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3,
 314
 315        0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287,
 316        0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7,
 317        0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386,
 318        0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55,
 319
 320        0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308,
 321        0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F,
 322        0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319,
 323        0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570,
 324};
 325
 326/* send an initialization array
 327 * Taken from the oss driver, not obvious from the doc how this
 328 * is meant to work
 329 */
 330static void
 331send_array(struct snd_emu8000 *emu, unsigned short *data, int size)
 332{
 333        int i;
 334        unsigned short *p;
 335
 336        p = data;
 337        for (i = 0; i < size; i++, p++)
 338                EMU8000_INIT1_WRITE(emu, i, *p);
 339        for (i = 0; i < size; i++, p++)
 340                EMU8000_INIT2_WRITE(emu, i, *p);
 341        for (i = 0; i < size; i++, p++)
 342                EMU8000_INIT3_WRITE(emu, i, *p);
 343        for (i = 0; i < size; i++, p++)
 344                EMU8000_INIT4_WRITE(emu, i, *p);
 345}
 346
 347
 348/*
 349 * Send initialization arrays to start up, this just follows the
 350 * initialisation sequence in the adip.
 351 */
 352static void
 353init_arrays(struct snd_emu8000 *emu)
 354{
 355        send_array(emu, init1, ARRAY_SIZE(init1)/4);
 356
 357        msleep((1024 * 1000) / 44100); /* wait for 1024 clocks */
 358        send_array(emu, init2, ARRAY_SIZE(init2)/4);
 359        send_array(emu, init3, ARRAY_SIZE(init3)/4);
 360
 361        EMU8000_HWCF4_WRITE(emu, 0);
 362        EMU8000_HWCF5_WRITE(emu, 0x83);
 363        EMU8000_HWCF6_WRITE(emu, 0x8000);
 364
 365        send_array(emu, init4, ARRAY_SIZE(init4)/4);
 366}
 367
 368
 369#define UNIQUE_ID1      0xa5b9
 370#define UNIQUE_ID2      0x9d53
 371
 372/*
 373 * Size the onboard memory.
 374 * This is written so as not to need arbitrary delays after the write. It
 375 * seems that the only way to do this is to use the one channel and keep
 376 * reallocating between read and write.
 377 */
 378static void
 379size_dram(struct snd_emu8000 *emu)
 380{
 381        int i, size;
 382
 383        if (emu->dram_checked)
 384                return;
 385
 386        size = 0;
 387
 388        /* write out a magic number */
 389        snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE);
 390        snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_READ);
 391        EMU8000_SMALW_WRITE(emu, EMU8000_DRAM_OFFSET);
 392        EMU8000_SMLD_WRITE(emu, UNIQUE_ID1);
 393        snd_emu8000_init_fm(emu); /* This must really be here and not 2 lines back even */
 394        snd_emu8000_write_wait(emu);
 395
 396        /*
 397         * Detect first 512 KiB.  If a write succeeds at the beginning of a
 398         * 512 KiB page we assume that the whole page is there.
 399         */
 400        EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET);
 401        EMU8000_SMLD_READ(emu); /* discard stale data  */
 402        if (EMU8000_SMLD_READ(emu) != UNIQUE_ID1)
 403                goto skip_detect;   /* No RAM */
 404        snd_emu8000_read_wait(emu);
 405
 406        for (size = 512 * 1024; size < EMU8000_MAX_DRAM; size += 512 * 1024) {
 407
 408                /* Write a unique data on the test address.
 409                 * if the address is out of range, the data is written on
 410                 * 0x200000(=EMU8000_DRAM_OFFSET).  Then the id word is
 411                 * changed by this data.
 412                 */
 413                /*snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE);*/
 414                EMU8000_SMALW_WRITE(emu, EMU8000_DRAM_OFFSET + (size>>1));
 415                EMU8000_SMLD_WRITE(emu, UNIQUE_ID2);
 416                snd_emu8000_write_wait(emu);
 417
 418                /*
 419                 * read the data on the just written DRAM address
 420                 * if not the same then we have reached the end of ram.
 421                 */
 422                /*snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_READ);*/
 423                EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET + (size>>1));
 424                /*snd_emu8000_read_wait(emu);*/
 425                EMU8000_SMLD_READ(emu); /* discard stale data  */
 426                if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2)
 427                        break; /* no memory at this address */
 428                snd_emu8000_read_wait(emu);
 429
 430                /*
 431                 * If it is the same it could be that the address just
 432                 * wraps back to the beginning; so check to see if the
 433                 * initial value has been overwritten.
 434                 */
 435                EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET);
 436                EMU8000_SMLD_READ(emu); /* discard stale data  */
 437                if (EMU8000_SMLD_READ(emu) != UNIQUE_ID1)
 438                        break; /* we must have wrapped around */
 439                snd_emu8000_read_wait(emu);
 440
 441                /* Otherwise, it's valid memory. */
 442        }
 443
 444skip_detect:
 445        /* wait until FULL bit in SMAxW register is false */
 446        for (i = 0; i < 10000; i++) {
 447                if ((EMU8000_SMALW_READ(emu) & 0x80000000) == 0)
 448                        break;
 449                schedule_timeout_interruptible(1);
 450                if (signal_pending(current))
 451                        break;
 452        }
 453        snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_CLOSE);
 454        snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_CLOSE);
 455
 456        pr_info("EMU8000 [0x%lx]: %d KiB on-board DRAM detected\n",
 457                    emu->port1, size/1024);
 458
 459        emu->mem_size = size;
 460        emu->dram_checked = 1;
 461}
 462
 463
 464/*
 465 * Initiailise the FM section.  You have to do this to use sample RAM
 466 * and therefore lose 2 voices.
 467 */
 468/*exported*/ void
 469snd_emu8000_init_fm(struct snd_emu8000 *emu)
 470{
 471        unsigned long flags;
 472
 473        /* Initialize the last two channels for DRAM refresh and producing
 474           the reverb and chorus effects for Yamaha OPL-3 synthesizer */
 475
 476        /* 31: FM left channel, 0xffffe0-0xffffe8 */
 477        EMU8000_DCYSUSV_WRITE(emu, 30, 0x80);
 478        EMU8000_PSST_WRITE(emu, 30, 0xFFFFFFE0); /* full left */
 479        EMU8000_CSL_WRITE(emu, 30, 0x00FFFFE8 | (emu->fm_chorus_depth << 24));
 480        EMU8000_PTRX_WRITE(emu, 30, (emu->fm_reverb_depth << 8));
 481        EMU8000_CPF_WRITE(emu, 30, 0);
 482        EMU8000_CCCA_WRITE(emu, 30, 0x00FFFFE3);
 483
 484        /* 32: FM right channel, 0xfffff0-0xfffff8 */
 485        EMU8000_DCYSUSV_WRITE(emu, 31, 0x80);
 486        EMU8000_PSST_WRITE(emu, 31, 0x00FFFFF0); /* full right */
 487        EMU8000_CSL_WRITE(emu, 31, 0x00FFFFF8 | (emu->fm_chorus_depth << 24));
 488        EMU8000_PTRX_WRITE(emu, 31, (emu->fm_reverb_depth << 8));
 489        EMU8000_CPF_WRITE(emu, 31, 0x8000);
 490        EMU8000_CCCA_WRITE(emu, 31, 0x00FFFFF3);
 491
 492        snd_emu8000_poke((emu), EMU8000_DATA0(emu), EMU8000_CMD(1, (30)), 0);
 493
 494        spin_lock_irqsave(&emu->reg_lock, flags);
 495        while (!(inw(EMU8000_PTR(emu)) & 0x1000))
 496                ;
 497        while ((inw(EMU8000_PTR(emu)) & 0x1000))
 498                ;
 499        spin_unlock_irqrestore(&emu->reg_lock, flags);
 500        snd_emu8000_poke((emu), EMU8000_DATA0(emu), EMU8000_CMD(1, (30)), 0x4828);
 501        /* this is really odd part.. */
 502        outb(0x3C, EMU8000_PTR(emu));
 503        outb(0, EMU8000_DATA1(emu));
 504
 505        /* skew volume & cutoff */
 506        EMU8000_VTFT_WRITE(emu, 30, 0x8000FFFF);
 507        EMU8000_VTFT_WRITE(emu, 31, 0x8000FFFF);
 508}
 509
 510
 511/*
 512 * The main initialization routine.
 513 */
 514static void
 515snd_emu8000_init_hw(struct snd_emu8000 *emu)
 516{
 517        int i;
 518
 519        emu->last_reg = 0xffff; /* reset the last register index */
 520
 521        /* initialize hardware configuration */
 522        EMU8000_HWCF1_WRITE(emu, 0x0059);
 523        EMU8000_HWCF2_WRITE(emu, 0x0020);
 524
 525        /* disable audio; this seems to reduce a clicking noise a bit.. */
 526        EMU8000_HWCF3_WRITE(emu, 0);
 527
 528        /* initialize audio channels */
 529        init_audio(emu);
 530
 531        /* initialize DMA */
 532        init_dma(emu);
 533
 534        /* initialize init arrays */
 535        init_arrays(emu);
 536
 537        /*
 538         * Initialize the FM section of the AWE32, this is needed
 539         * for DRAM refresh as well
 540         */
 541        snd_emu8000_init_fm(emu);
 542
 543        /* terminate all voices */
 544        for (i = 0; i < EMU8000_DRAM_VOICES; i++)
 545                EMU8000_DCYSUSV_WRITE(emu, 0, 0x807F);
 546        
 547        /* check DRAM memory size */
 548        size_dram(emu);
 549
 550        /* enable audio */
 551        EMU8000_HWCF3_WRITE(emu, 0x4);
 552
 553        /* set equzlier, chorus and reverb modes */
 554        snd_emu8000_update_equalizer(emu);
 555        snd_emu8000_update_chorus_mode(emu);
 556        snd_emu8000_update_reverb_mode(emu);
 557}
 558
 559
 560/*----------------------------------------------------------------
 561 * Bass/Treble Equalizer
 562 *----------------------------------------------------------------*/
 563
 564static unsigned short bass_parm[12][3] = {
 565        {0xD26A, 0xD36A, 0x0000}, /* -12 dB */
 566        {0xD25B, 0xD35B, 0x0000}, /*  -8 */
 567        {0xD24C, 0xD34C, 0x0000}, /*  -6 */
 568        {0xD23D, 0xD33D, 0x0000}, /*  -4 */
 569        {0xD21F, 0xD31F, 0x0000}, /*  -2 */
 570        {0xC208, 0xC308, 0x0001}, /*   0 (HW default) */
 571        {0xC219, 0xC319, 0x0001}, /*  +2 */
 572        {0xC22A, 0xC32A, 0x0001}, /*  +4 */
 573        {0xC24C, 0xC34C, 0x0001}, /*  +6 */
 574        {0xC26E, 0xC36E, 0x0001}, /*  +8 */
 575        {0xC248, 0xC384, 0x0002}, /* +10 */
 576        {0xC26A, 0xC36A, 0x0002}, /* +12 dB */
 577};
 578
 579static unsigned short treble_parm[12][9] = {
 580        {0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */
 581        {0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
 582        {0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
 583        {0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
 584        {0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
 585        {0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002},
 586        {0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002},
 587        {0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002},
 588        {0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002},
 589        {0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */
 590        {0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002},
 591        {0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}  /* +12 dB */
 592};
 593
 594
 595/*
 596 * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB]
 597 */
 598/*exported*/ void
 599snd_emu8000_update_equalizer(struct snd_emu8000 *emu)
 600{
 601        unsigned short w;
 602        int bass = emu->bass_level;
 603        int treble = emu->treble_level;
 604
 605        if (bass < 0 || bass > 11 || treble < 0 || treble > 11)
 606                return;
 607        EMU8000_INIT4_WRITE(emu, 0x01, bass_parm[bass][0]);
 608        EMU8000_INIT4_WRITE(emu, 0x11, bass_parm[bass][1]);
 609        EMU8000_INIT3_WRITE(emu, 0x11, treble_parm[treble][0]);
 610        EMU8000_INIT3_WRITE(emu, 0x13, treble_parm[treble][1]);
 611        EMU8000_INIT3_WRITE(emu, 0x1b, treble_parm[treble][2]);
 612        EMU8000_INIT4_WRITE(emu, 0x07, treble_parm[treble][3]);
 613        EMU8000_INIT4_WRITE(emu, 0x0b, treble_parm[treble][4]);
 614        EMU8000_INIT4_WRITE(emu, 0x0d, treble_parm[treble][5]);
 615        EMU8000_INIT4_WRITE(emu, 0x17, treble_parm[treble][6]);
 616        EMU8000_INIT4_WRITE(emu, 0x19, treble_parm[treble][7]);
 617        w = bass_parm[bass][2] + treble_parm[treble][8];
 618        EMU8000_INIT4_WRITE(emu, 0x15, (unsigned short)(w + 0x0262));
 619        EMU8000_INIT4_WRITE(emu, 0x1d, (unsigned short)(w + 0x8362));
 620}
 621
 622
 623/*----------------------------------------------------------------
 624 * Chorus mode control
 625 *----------------------------------------------------------------*/
 626
 627/*
 628 * chorus mode parameters
 629 */
 630#define SNDRV_EMU8000_CHORUS_1          0
 631#define SNDRV_EMU8000_CHORUS_2          1
 632#define SNDRV_EMU8000_CHORUS_3          2
 633#define SNDRV_EMU8000_CHORUS_4          3
 634#define SNDRV_EMU8000_CHORUS_FEEDBACK   4
 635#define SNDRV_EMU8000_CHORUS_FLANGER    5
 636#define SNDRV_EMU8000_CHORUS_SHORTDELAY 6
 637#define SNDRV_EMU8000_CHORUS_SHORTDELAY2        7
 638#define SNDRV_EMU8000_CHORUS_PREDEFINED 8
 639/* user can define chorus modes up to 32 */
 640#define SNDRV_EMU8000_CHORUS_NUMBERS    32
 641
 642struct soundfont_chorus_fx {
 643        unsigned short feedback;        /* feedback level (0xE600-0xE6FF) */
 644        unsigned short delay_offset;    /* delay (0-0x0DA3) [1/44100 sec] */
 645        unsigned short lfo_depth;       /* LFO depth (0xBC00-0xBCFF) */
 646        unsigned int delay;     /* right delay (0-0xFFFFFFFF) [1/256/44100 sec] */
 647        unsigned int lfo_freq;          /* LFO freq LFO freq (0-0xFFFFFFFF) */
 648};
 649
 650/* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */
 651static char chorus_defined[SNDRV_EMU8000_CHORUS_NUMBERS];
 652static struct soundfont_chorus_fx chorus_parm[SNDRV_EMU8000_CHORUS_NUMBERS] = {
 653        {0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */
 654        {0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */
 655        {0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */
 656        {0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */
 657        {0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */
 658        {0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */
 659        {0xE600, 0x0B06, 0xBC00, 0x0006E000, 0x00000083}, /* short delay */
 660        {0xE6C0, 0x0B06, 0xBC00, 0x0006E000, 0x00000083}, /* short delay + feedback */
 661};
 662
 663/*exported*/ int
 664snd_emu8000_load_chorus_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len)
 665{
 666        struct soundfont_chorus_fx rec;
 667        if (mode < SNDRV_EMU8000_CHORUS_PREDEFINED || mode >= SNDRV_EMU8000_CHORUS_NUMBERS) {
 668                snd_printk(KERN_WARNING "invalid chorus mode %d for uploading\n", mode);
 669                return -EINVAL;
 670        }
 671        if (len < (long)sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec)))
 672                return -EFAULT;
 673        chorus_parm[mode] = rec;
 674        chorus_defined[mode] = 1;
 675        return 0;
 676}
 677
 678/*exported*/ void
 679snd_emu8000_update_chorus_mode(struct snd_emu8000 *emu)
 680{
 681        int effect = emu->chorus_mode;
 682        if (effect < 0 || effect >= SNDRV_EMU8000_CHORUS_NUMBERS ||
 683            (effect >= SNDRV_EMU8000_CHORUS_PREDEFINED && !chorus_defined[effect]))
 684                return;
 685        EMU8000_INIT3_WRITE(emu, 0x09, chorus_parm[effect].feedback);
 686        EMU8000_INIT3_WRITE(emu, 0x0c, chorus_parm[effect].delay_offset);
 687        EMU8000_INIT4_WRITE(emu, 0x03, chorus_parm[effect].lfo_depth);
 688        EMU8000_HWCF4_WRITE(emu, chorus_parm[effect].delay);
 689        EMU8000_HWCF5_WRITE(emu, chorus_parm[effect].lfo_freq);
 690        EMU8000_HWCF6_WRITE(emu, 0x8000);
 691        EMU8000_HWCF7_WRITE(emu, 0x0000);
 692}
 693
 694/*----------------------------------------------------------------
 695 * Reverb mode control
 696 *----------------------------------------------------------------*/
 697
 698/*
 699 * reverb mode parameters
 700 */
 701#define SNDRV_EMU8000_REVERB_ROOM1      0
 702#define SNDRV_EMU8000_REVERB_ROOM2      1
 703#define SNDRV_EMU8000_REVERB_ROOM3      2
 704#define SNDRV_EMU8000_REVERB_HALL1      3
 705#define SNDRV_EMU8000_REVERB_HALL2      4
 706#define SNDRV_EMU8000_REVERB_PLATE      5
 707#define SNDRV_EMU8000_REVERB_DELAY      6
 708#define SNDRV_EMU8000_REVERB_PANNINGDELAY 7
 709#define SNDRV_EMU8000_REVERB_PREDEFINED 8
 710/* user can define reverb modes up to 32 */
 711#define SNDRV_EMU8000_REVERB_NUMBERS    32
 712
 713struct soundfont_reverb_fx {
 714        unsigned short parms[28];
 715};
 716
 717/* reverb mode settings; write the following 28 data of 16 bit length
 718 *   on the corresponding ports in the reverb_cmds array
 719 */
 720static char reverb_defined[SNDRV_EMU8000_CHORUS_NUMBERS];
 721static struct soundfont_reverb_fx reverb_parm[SNDRV_EMU8000_REVERB_NUMBERS] = {
 722{{  /* room 1 */
 723        0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,
 724        0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,
 725        0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
 726        0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
 727}},
 728{{  /* room 2 */
 729        0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284,
 730        0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
 731        0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
 732        0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
 733}},
 734{{  /* room 3 */
 735        0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284,
 736        0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516,
 737        0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B,
 738        0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A,
 739}},
 740{{  /* hall 1 */
 741        0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284,
 742        0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
 743        0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A,
 744        0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529,
 745}},
 746{{  /* hall 2 */
 747        0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254,
 748        0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3,
 749        0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
 750        0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
 751}},
 752{{  /* plate */
 753        0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234,
 754        0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548,
 755        0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
 756        0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
 757}},
 758{{  /* delay */
 759        0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204,
 760        0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
 761        0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
 762        0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
 763}},
 764{{  /* panning delay */
 765        0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204,
 766        0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
 767        0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
 768        0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
 769}},
 770};
 771
 772enum { DATA1, DATA2 };
 773#define AWE_INIT1(c)    EMU8000_CMD(2,c), DATA1
 774#define AWE_INIT2(c)    EMU8000_CMD(2,c), DATA2
 775#define AWE_INIT3(c)    EMU8000_CMD(3,c), DATA1
 776#define AWE_INIT4(c)    EMU8000_CMD(3,c), DATA2
 777
 778static struct reverb_cmd_pair {
 779        unsigned short cmd, port;
 780} reverb_cmds[28] = {
 781  {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)},
 782  {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)},
 783  {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)},
 784  {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)},
 785  {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)},
 786  {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)},
 787  {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)},
 788};
 789
 790/*exported*/ int
 791snd_emu8000_load_reverb_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len)
 792{
 793        struct soundfont_reverb_fx rec;
 794
 795        if (mode < SNDRV_EMU8000_REVERB_PREDEFINED || mode >= SNDRV_EMU8000_REVERB_NUMBERS) {
 796                snd_printk(KERN_WARNING "invalid reverb mode %d for uploading\n", mode);
 797                return -EINVAL;
 798        }
 799        if (len < (long)sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec)))
 800                return -EFAULT;
 801        reverb_parm[mode] = rec;
 802        reverb_defined[mode] = 1;
 803        return 0;
 804}
 805
 806/*exported*/ void
 807snd_emu8000_update_reverb_mode(struct snd_emu8000 *emu)
 808{
 809        int effect = emu->reverb_mode;
 810        int i;
 811
 812        if (effect < 0 || effect >= SNDRV_EMU8000_REVERB_NUMBERS ||
 813            (effect >= SNDRV_EMU8000_REVERB_PREDEFINED && !reverb_defined[effect]))
 814                return;
 815        for (i = 0; i < 28; i++) {
 816                int port;
 817                if (reverb_cmds[i].port == DATA1)
 818                        port = EMU8000_DATA1(emu);
 819                else
 820                        port = EMU8000_DATA2(emu);
 821                snd_emu8000_poke(emu, port, reverb_cmds[i].cmd, reverb_parm[effect].parms[i]);
 822        }
 823}
 824
 825
 826/*----------------------------------------------------------------
 827 * mixer interface
 828 *----------------------------------------------------------------*/
 829
 830/*
 831 * bass/treble
 832 */
 833static int mixer_bass_treble_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 834{
 835        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 836        uinfo->count = 1;
 837        uinfo->value.integer.min = 0;
 838        uinfo->value.integer.max = 11;
 839        return 0;
 840}
 841
 842static int mixer_bass_treble_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 843{
 844        struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
 845        
 846        ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->treble_level : emu->bass_level;
 847        return 0;
 848}
 849
 850static int mixer_bass_treble_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 851{
 852        struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
 853        unsigned long flags;
 854        int change;
 855        unsigned short val1;
 856        
 857        val1 = ucontrol->value.integer.value[0] % 12;
 858        spin_lock_irqsave(&emu->control_lock, flags);
 859        if (kcontrol->private_value) {
 860                change = val1 != emu->treble_level;
 861                emu->treble_level = val1;
 862        } else {
 863                change = val1 != emu->bass_level;
 864                emu->bass_level = val1;
 865        }
 866        spin_unlock_irqrestore(&emu->control_lock, flags);
 867        snd_emu8000_update_equalizer(emu);
 868        return change;
 869}
 870
 871static struct snd_kcontrol_new mixer_bass_control =
 872{
 873        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 874        .name = "Synth Tone Control - Bass",
 875        .info = mixer_bass_treble_info,
 876        .get = mixer_bass_treble_get,
 877        .put = mixer_bass_treble_put,
 878        .private_value = 0,
 879};
 880
 881static struct snd_kcontrol_new mixer_treble_control =
 882{
 883        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 884        .name = "Synth Tone Control - Treble",
 885        .info = mixer_bass_treble_info,
 886        .get = mixer_bass_treble_get,
 887        .put = mixer_bass_treble_put,
 888        .private_value = 1,
 889};
 890
 891/*
 892 * chorus/reverb mode
 893 */
 894static int mixer_chorus_reverb_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 895{
 896        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 897        uinfo->count = 1;
 898        uinfo->value.integer.min = 0;
 899        uinfo->value.integer.max = kcontrol->private_value ? (SNDRV_EMU8000_CHORUS_NUMBERS-1) : (SNDRV_EMU8000_REVERB_NUMBERS-1);
 900        return 0;
 901}
 902
 903static int mixer_chorus_reverb_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 904{
 905        struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
 906        
 907        ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->chorus_mode : emu->reverb_mode;
 908        return 0;
 909}
 910
 911static int mixer_chorus_reverb_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 912{
 913        struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
 914        unsigned long flags;
 915        int change;
 916        unsigned short val1;
 917        
 918        spin_lock_irqsave(&emu->control_lock, flags);
 919        if (kcontrol->private_value) {
 920                val1 = ucontrol->value.integer.value[0] % SNDRV_EMU8000_CHORUS_NUMBERS;
 921                change = val1 != emu->chorus_mode;
 922                emu->chorus_mode = val1;
 923        } else {
 924                val1 = ucontrol->value.integer.value[0] % SNDRV_EMU8000_REVERB_NUMBERS;
 925                change = val1 != emu->reverb_mode;
 926                emu->reverb_mode = val1;
 927        }
 928        spin_unlock_irqrestore(&emu->control_lock, flags);
 929        if (change) {
 930                if (kcontrol->private_value)
 931                        snd_emu8000_update_chorus_mode(emu);
 932                else
 933                        snd_emu8000_update_reverb_mode(emu);
 934        }
 935        return change;
 936}
 937
 938static struct snd_kcontrol_new mixer_chorus_mode_control =
 939{
 940        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 941        .name = "Chorus Mode",
 942        .info = mixer_chorus_reverb_info,
 943        .get = mixer_chorus_reverb_get,
 944        .put = mixer_chorus_reverb_put,
 945        .private_value = 1,
 946};
 947
 948static struct snd_kcontrol_new mixer_reverb_mode_control =
 949{
 950        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 951        .name = "Reverb Mode",
 952        .info = mixer_chorus_reverb_info,
 953        .get = mixer_chorus_reverb_get,
 954        .put = mixer_chorus_reverb_put,
 955        .private_value = 0,
 956};
 957
 958/*
 959 * FM OPL3 chorus/reverb depth
 960 */
 961static int mixer_fm_depth_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 962{
 963        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 964        uinfo->count = 1;
 965        uinfo->value.integer.min = 0;
 966        uinfo->value.integer.max = 255;
 967        return 0;
 968}
 969
 970static int mixer_fm_depth_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 971{
 972        struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
 973        
 974        ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->fm_chorus_depth : emu->fm_reverb_depth;
 975        return 0;
 976}
 977
 978static int mixer_fm_depth_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 979{
 980        struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
 981        unsigned long flags;
 982        int change;
 983        unsigned short val1;
 984        
 985        val1 = ucontrol->value.integer.value[0] % 256;
 986        spin_lock_irqsave(&emu->control_lock, flags);
 987        if (kcontrol->private_value) {
 988                change = val1 != emu->fm_chorus_depth;
 989                emu->fm_chorus_depth = val1;
 990        } else {
 991                change = val1 != emu->fm_reverb_depth;
 992                emu->fm_reverb_depth = val1;
 993        }
 994        spin_unlock_irqrestore(&emu->control_lock, flags);
 995        if (change)
 996                snd_emu8000_init_fm(emu);
 997        return change;
 998}
 999
1000static struct snd_kcontrol_new mixer_fm_chorus_depth_control =
1001{
1002        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1003        .name = "FM Chorus Depth",
1004        .info = mixer_fm_depth_info,
1005        .get = mixer_fm_depth_get,
1006        .put = mixer_fm_depth_put,
1007        .private_value = 1,
1008};
1009
1010static struct snd_kcontrol_new mixer_fm_reverb_depth_control =
1011{
1012        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1013        .name = "FM Reverb Depth",
1014        .info = mixer_fm_depth_info,
1015        .get = mixer_fm_depth_get,
1016        .put = mixer_fm_depth_put,
1017        .private_value = 0,
1018};
1019
1020
1021static struct snd_kcontrol_new *mixer_defs[EMU8000_NUM_CONTROLS] = {
1022        &mixer_bass_control,
1023        &mixer_treble_control,
1024        &mixer_chorus_mode_control,
1025        &mixer_reverb_mode_control,
1026        &mixer_fm_chorus_depth_control,
1027        &mixer_fm_reverb_depth_control,
1028};
1029
1030/*
1031 * create and attach mixer elements for WaveTable treble/bass controls
1032 */
1033static int
1034snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu)
1035{
1036        int i, err = 0;
1037
1038        if (snd_BUG_ON(!emu || !card))
1039                return -EINVAL;
1040
1041        spin_lock_init(&emu->control_lock);
1042
1043        memset(emu->controls, 0, sizeof(emu->controls));
1044        for (i = 0; i < EMU8000_NUM_CONTROLS; i++) {
1045                if ((err = snd_ctl_add(card, emu->controls[i] = snd_ctl_new1(mixer_defs[i], emu))) < 0)
1046                        goto __error;
1047        }
1048        return 0;
1049
1050__error:
1051        for (i = 0; i < EMU8000_NUM_CONTROLS; i++) {
1052                down_write(&card->controls_rwsem);
1053                if (emu->controls[i])
1054                        snd_ctl_remove(card, emu->controls[i]);
1055                up_write(&card->controls_rwsem);
1056        }
1057        return err;
1058}
1059
1060
1061/*
1062 * free resources
1063 */
1064static int snd_emu8000_free(struct snd_emu8000 *hw)
1065{
1066        release_and_free_resource(hw->res_port1);
1067        release_and_free_resource(hw->res_port2);
1068        release_and_free_resource(hw->res_port3);
1069        kfree(hw);
1070        return 0;
1071}
1072
1073/*
1074 */
1075static int snd_emu8000_dev_free(struct snd_device *device)
1076{
1077        struct snd_emu8000 *hw = device->device_data;
1078        return snd_emu8000_free(hw);
1079}
1080
1081/*
1082 * initialize and register emu8000 synth device.
1083 */
1084int
1085snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports,
1086                struct snd_seq_device **awe_ret)
1087{
1088        struct snd_seq_device *awe;
1089        struct snd_emu8000 *hw;
1090        int err;
1091        static struct snd_device_ops ops = {
1092                .dev_free = snd_emu8000_dev_free,
1093        };
1094
1095        if (awe_ret)
1096                *awe_ret = NULL;
1097
1098        if (seq_ports <= 0)
1099                return 0;
1100
1101        hw = kzalloc(sizeof(*hw), GFP_KERNEL);
1102        if (hw == NULL)
1103                return -ENOMEM;
1104        spin_lock_init(&hw->reg_lock);
1105        hw->index = index;
1106        hw->port1 = port;
1107        hw->port2 = port + 0x400;
1108        hw->port3 = port + 0x800;
1109        if (!(hw->res_port1 = request_region(hw->port1, 4, "Emu8000-1")) ||
1110            !(hw->res_port2 = request_region(hw->port2, 4, "Emu8000-2")) ||
1111            !(hw->res_port3 = request_region(hw->port3, 4, "Emu8000-3"))) {
1112                snd_printk(KERN_ERR "sbawe: can't grab ports 0x%lx, 0x%lx, 0x%lx\n", hw->port1, hw->port2, hw->port3);
1113                snd_emu8000_free(hw);
1114                return -EBUSY;
1115        }
1116        hw->mem_size = 0;
1117        hw->card = card;
1118        hw->seq_ports = seq_ports;
1119        hw->bass_level = 5;
1120        hw->treble_level = 9;
1121        hw->chorus_mode = 2;
1122        hw->reverb_mode = 4;
1123        hw->fm_chorus_depth = 0;
1124        hw->fm_reverb_depth = 0;
1125
1126        if (snd_emu8000_detect(hw) < 0) {
1127                snd_emu8000_free(hw);
1128                return -ENODEV;
1129        }
1130
1131        snd_emu8000_init_hw(hw);
1132        if ((err = snd_emu8000_create_mixer(card, hw)) < 0) {
1133                snd_emu8000_free(hw);
1134                return err;
1135        }
1136        
1137        if ((err = snd_device_new(card, SNDRV_DEV_CODEC, hw, &ops)) < 0) {
1138                snd_emu8000_free(hw);
1139                return err;
1140        }
1141#if IS_ENABLED(CONFIG_SND_SEQUENCER)
1142        if (snd_seq_device_new(card, index, SNDRV_SEQ_DEV_ID_EMU8000,
1143                               sizeof(struct snd_emu8000*), &awe) >= 0) {
1144                strcpy(awe->name, "EMU-8000");
1145                *(struct snd_emu8000 **)SNDRV_SEQ_DEVICE_ARGPTR(awe) = hw;
1146        }
1147#else
1148        awe = NULL;
1149#endif
1150        if (awe_ret)
1151                *awe_ret = awe;
1152
1153        return 0;
1154}
1155
1156
1157/*
1158 * exported stuff
1159 */
1160
1161EXPORT_SYMBOL(snd_emu8000_poke);
1162EXPORT_SYMBOL(snd_emu8000_peek);
1163EXPORT_SYMBOL(snd_emu8000_poke_dw);
1164EXPORT_SYMBOL(snd_emu8000_peek_dw);
1165EXPORT_SYMBOL(snd_emu8000_dma_chan);
1166EXPORT_SYMBOL(snd_emu8000_init_fm);
1167EXPORT_SYMBOL(snd_emu8000_load_chorus_fx);
1168EXPORT_SYMBOL(snd_emu8000_load_reverb_fx);
1169EXPORT_SYMBOL(snd_emu8000_update_chorus_mode);
1170EXPORT_SYMBOL(snd_emu8000_update_reverb_mode);
1171EXPORT_SYMBOL(snd_emu8000_update_equalizer);
1172