root/sound/isa/sb/emu8000.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. snd_emu8000_poke
  2. snd_emu8000_peek
  3. snd_emu8000_poke_dw
  4. snd_emu8000_peek_dw
  5. snd_emu8000_dma_chan
  6. snd_emu8000_read_wait
  7. snd_emu8000_write_wait
  8. snd_emu8000_detect
  9. init_audio
  10. init_dma
  11. send_array
  12. init_arrays
  13. size_dram
  14. snd_emu8000_init_fm
  15. snd_emu8000_init_hw
  16. snd_emu8000_update_equalizer
  17. snd_emu8000_load_chorus_fx
  18. snd_emu8000_update_chorus_mode
  19. snd_emu8000_load_reverb_fx
  20. snd_emu8000_update_reverb_mode
  21. mixer_bass_treble_info
  22. mixer_bass_treble_get
  23. mixer_bass_treble_put
  24. mixer_chorus_reverb_info
  25. mixer_chorus_reverb_get
  26. mixer_chorus_reverb_put
  27. mixer_fm_depth_info
  28. mixer_fm_depth_get
  29. mixer_fm_depth_put
  30. snd_emu8000_create_mixer
  31. snd_emu8000_free
  32. snd_emu8000_dev_free
  33. snd_emu8000_new

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

/* [<][>][^][v][top][bottom][index][help] */