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.h> 25 #include <linux/slab.h> 26 #include <linux/ioport.h> 27 #include <linux/export.h> 28 #include <linux/delay.h> 29 #include <sound/core.h> 30 #include <sound/emu8000.h> 31 #include <sound/emu8000_reg.h> 32 #include <asm/io.h> 33 #include <asm/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 */ 48 void 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 */ 61 unsigned 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 */ 76 void 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 */ 90 unsigned 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 110 snd_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 */ 134 static void 135 snd_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 */ 146 static void 147 snd_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 */ 159 static int 160 snd_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 */ 185 static void 186 init_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 */ 226 static void 227 init_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 */ 238 static 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 260 static 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 282 static 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 304 static 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 */ 330 static void 331 send_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 */ 352 static void 353 init_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 */ 378 static void 379 size_dram(struct snd_emu8000 *emu) 380 { 381 int i, size, detected_size; 382 383 if (emu->dram_checked) 384 return; 385 386 size = 0; 387 detected_size = 0; 388 389 /* write out a magic number */ 390 snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE); 391 snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_READ); 392 EMU8000_SMALW_WRITE(emu, EMU8000_DRAM_OFFSET); 393 EMU8000_SMLD_WRITE(emu, UNIQUE_ID1); 394 snd_emu8000_init_fm(emu); /* This must really be here and not 2 lines back even */ 395 396 while (size < EMU8000_MAX_DRAM) { 397 398 size += 512 * 1024; /* increment 512kbytes */ 399 400 /* Write a unique data on the test address. 401 * if the address is out of range, the data is written on 402 * 0x200000(=EMU8000_DRAM_OFFSET). Then the id word is 403 * changed by this data. 404 */ 405 /*snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE);*/ 406 EMU8000_SMALW_WRITE(emu, EMU8000_DRAM_OFFSET + (size>>1)); 407 EMU8000_SMLD_WRITE(emu, UNIQUE_ID2); 408 snd_emu8000_write_wait(emu); 409 410 /* 411 * read the data on the just written DRAM address 412 * if not the same then we have reached the end of ram. 413 */ 414 /*snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_READ);*/ 415 EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET + (size>>1)); 416 /*snd_emu8000_read_wait(emu);*/ 417 EMU8000_SMLD_READ(emu); /* discard stale data */ 418 if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2) 419 break; /* no memory at this address */ 420 snd_emu8000_read_wait(emu); 421 422 /* 423 * If it is the same it could be that the address just 424 * wraps back to the beginning; so check to see if the 425 * initial value has been overwritten. 426 */ 427 EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET); 428 EMU8000_SMLD_READ(emu); /* discard stale data */ 429 if (EMU8000_SMLD_READ(emu) != UNIQUE_ID1) 430 break; /* we must have wrapped around */ 431 snd_emu8000_read_wait(emu); 432 433 /* Otherwise, it's valid memory. */ 434 detected_size = size + 512 * 1024; 435 } 436 437 /* Distinguish 512 KiB from 0. */ 438 if (detected_size == 0) { 439 snd_emu8000_read_wait(emu); 440 EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET); 441 EMU8000_SMLD_READ(emu); /* discard stale data */ 442 if (EMU8000_SMLD_READ(emu) == UNIQUE_ID1) 443 detected_size = 512 * 1024; 444 } 445 446 /* wait until FULL bit in SMAxW register is false */ 447 for (i = 0; i < 10000; i++) { 448 if ((EMU8000_SMALW_READ(emu) & 0x80000000) == 0) 449 break; 450 schedule_timeout_interruptible(1); 451 if (signal_pending(current)) 452 break; 453 } 454 snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_CLOSE); 455 snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_CLOSE); 456 457 snd_printdd("EMU8000 [0x%lx]: %d Kb on-board memory detected\n", 458 emu->port1, detected_size/1024); 459 460 emu->mem_size = detected_size; 461 emu->dram_checked = 1; 462 } 463 464 465 /* 466 * Initiailise the FM section. You have to do this to use sample RAM 467 * and therefore lose 2 voices. 468 */ 469 /*exported*/ void 470 snd_emu8000_init_fm(struct snd_emu8000 *emu) 471 { 472 unsigned long flags; 473 474 /* Initialize the last two channels for DRAM refresh and producing 475 the reverb and chorus effects for Yamaha OPL-3 synthesizer */ 476 477 /* 31: FM left channel, 0xffffe0-0xffffe8 */ 478 EMU8000_DCYSUSV_WRITE(emu, 30, 0x80); 479 EMU8000_PSST_WRITE(emu, 30, 0xFFFFFFE0); /* full left */ 480 EMU8000_CSL_WRITE(emu, 30, 0x00FFFFE8 | (emu->fm_chorus_depth << 24)); 481 EMU8000_PTRX_WRITE(emu, 30, (emu->fm_reverb_depth << 8)); 482 EMU8000_CPF_WRITE(emu, 30, 0); 483 EMU8000_CCCA_WRITE(emu, 30, 0x00FFFFE3); 484 485 /* 32: FM right channel, 0xfffff0-0xfffff8 */ 486 EMU8000_DCYSUSV_WRITE(emu, 31, 0x80); 487 EMU8000_PSST_WRITE(emu, 31, 0x00FFFFF0); /* full right */ 488 EMU8000_CSL_WRITE(emu, 31, 0x00FFFFF8 | (emu->fm_chorus_depth << 24)); 489 EMU8000_PTRX_WRITE(emu, 31, (emu->fm_reverb_depth << 8)); 490 EMU8000_CPF_WRITE(emu, 31, 0x8000); 491 EMU8000_CCCA_WRITE(emu, 31, 0x00FFFFF3); 492 493 snd_emu8000_poke((emu), EMU8000_DATA0(emu), EMU8000_CMD(1, (30)), 0); 494 495 spin_lock_irqsave(&emu->reg_lock, flags); 496 while (!(inw(EMU8000_PTR(emu)) & 0x1000)) 497 ; 498 while ((inw(EMU8000_PTR(emu)) & 0x1000)) 499 ; 500 spin_unlock_irqrestore(&emu->reg_lock, flags); 501 snd_emu8000_poke((emu), EMU8000_DATA0(emu), EMU8000_CMD(1, (30)), 0x4828); 502 /* this is really odd part.. */ 503 outb(0x3C, EMU8000_PTR(emu)); 504 outb(0, EMU8000_DATA1(emu)); 505 506 /* skew volume & cutoff */ 507 EMU8000_VTFT_WRITE(emu, 30, 0x8000FFFF); 508 EMU8000_VTFT_WRITE(emu, 31, 0x8000FFFF); 509 } 510 511 512 /* 513 * The main initialization routine. 514 */ 515 static void 516 snd_emu8000_init_hw(struct snd_emu8000 *emu) 517 { 518 int i; 519 520 emu->last_reg = 0xffff; /* reset the last register index */ 521 522 /* initialize hardware configuration */ 523 EMU8000_HWCF1_WRITE(emu, 0x0059); 524 EMU8000_HWCF2_WRITE(emu, 0x0020); 525 526 /* disable audio; this seems to reduce a clicking noise a bit.. */ 527 EMU8000_HWCF3_WRITE(emu, 0); 528 529 /* initialize audio channels */ 530 init_audio(emu); 531 532 /* initialize DMA */ 533 init_dma(emu); 534 535 /* initialize init arrays */ 536 init_arrays(emu); 537 538 /* 539 * Initialize the FM section of the AWE32, this is needed 540 * for DRAM refresh as well 541 */ 542 snd_emu8000_init_fm(emu); 543 544 /* terminate all voices */ 545 for (i = 0; i < EMU8000_DRAM_VOICES; i++) 546 EMU8000_DCYSUSV_WRITE(emu, 0, 0x807F); 547 548 /* check DRAM memory size */ 549 size_dram(emu); 550 551 /* enable audio */ 552 EMU8000_HWCF3_WRITE(emu, 0x4); 553 554 /* set equzlier, chorus and reverb modes */ 555 snd_emu8000_update_equalizer(emu); 556 snd_emu8000_update_chorus_mode(emu); 557 snd_emu8000_update_reverb_mode(emu); 558 } 559 560 561 /*---------------------------------------------------------------- 562 * Bass/Treble Equalizer 563 *----------------------------------------------------------------*/ 564 565 static unsigned short bass_parm[12][3] = { 566 {0xD26A, 0xD36A, 0x0000}, /* -12 dB */ 567 {0xD25B, 0xD35B, 0x0000}, /* -8 */ 568 {0xD24C, 0xD34C, 0x0000}, /* -6 */ 569 {0xD23D, 0xD33D, 0x0000}, /* -4 */ 570 {0xD21F, 0xD31F, 0x0000}, /* -2 */ 571 {0xC208, 0xC308, 0x0001}, /* 0 (HW default) */ 572 {0xC219, 0xC319, 0x0001}, /* +2 */ 573 {0xC22A, 0xC32A, 0x0001}, /* +4 */ 574 {0xC24C, 0xC34C, 0x0001}, /* +6 */ 575 {0xC26E, 0xC36E, 0x0001}, /* +8 */ 576 {0xC248, 0xC384, 0x0002}, /* +10 */ 577 {0xC26A, 0xC36A, 0x0002}, /* +12 dB */ 578 }; 579 580 static unsigned short treble_parm[12][9] = { 581 {0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */ 582 {0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, 583 {0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, 584 {0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, 585 {0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, 586 {0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002}, 587 {0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002}, 588 {0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002}, 589 {0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002}, 590 {0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */ 591 {0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, 592 {0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002} /* +12 dB */ 593 }; 594 595 596 /* 597 * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB] 598 */ 599 /*exported*/ void 600 snd_emu8000_update_equalizer(struct snd_emu8000 *emu) 601 { 602 unsigned short w; 603 int bass = emu->bass_level; 604 int treble = emu->treble_level; 605 606 if (bass < 0 || bass > 11 || treble < 0 || treble > 11) 607 return; 608 EMU8000_INIT4_WRITE(emu, 0x01, bass_parm[bass][0]); 609 EMU8000_INIT4_WRITE(emu, 0x11, bass_parm[bass][1]); 610 EMU8000_INIT3_WRITE(emu, 0x11, treble_parm[treble][0]); 611 EMU8000_INIT3_WRITE(emu, 0x13, treble_parm[treble][1]); 612 EMU8000_INIT3_WRITE(emu, 0x1b, treble_parm[treble][2]); 613 EMU8000_INIT4_WRITE(emu, 0x07, treble_parm[treble][3]); 614 EMU8000_INIT4_WRITE(emu, 0x0b, treble_parm[treble][4]); 615 EMU8000_INIT4_WRITE(emu, 0x0d, treble_parm[treble][5]); 616 EMU8000_INIT4_WRITE(emu, 0x17, treble_parm[treble][6]); 617 EMU8000_INIT4_WRITE(emu, 0x19, treble_parm[treble][7]); 618 w = bass_parm[bass][2] + treble_parm[treble][8]; 619 EMU8000_INIT4_WRITE(emu, 0x15, (unsigned short)(w + 0x0262)); 620 EMU8000_INIT4_WRITE(emu, 0x1d, (unsigned short)(w + 0x8362)); 621 } 622 623 624 /*---------------------------------------------------------------- 625 * Chorus mode control 626 *----------------------------------------------------------------*/ 627 628 /* 629 * chorus mode parameters 630 */ 631 #define SNDRV_EMU8000_CHORUS_1 0 632 #define SNDRV_EMU8000_CHORUS_2 1 633 #define SNDRV_EMU8000_CHORUS_3 2 634 #define SNDRV_EMU8000_CHORUS_4 3 635 #define SNDRV_EMU8000_CHORUS_FEEDBACK 4 636 #define SNDRV_EMU8000_CHORUS_FLANGER 5 637 #define SNDRV_EMU8000_CHORUS_SHORTDELAY 6 638 #define SNDRV_EMU8000_CHORUS_SHORTDELAY2 7 639 #define SNDRV_EMU8000_CHORUS_PREDEFINED 8 640 /* user can define chorus modes up to 32 */ 641 #define SNDRV_EMU8000_CHORUS_NUMBERS 32 642 643 struct soundfont_chorus_fx { 644 unsigned short feedback; /* feedback level (0xE600-0xE6FF) */ 645 unsigned short delay_offset; /* delay (0-0x0DA3) [1/44100 sec] */ 646 unsigned short lfo_depth; /* LFO depth (0xBC00-0xBCFF) */ 647 unsigned int delay; /* right delay (0-0xFFFFFFFF) [1/256/44100 sec] */ 648 unsigned int lfo_freq; /* LFO freq LFO freq (0-0xFFFFFFFF) */ 649 }; 650 651 /* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */ 652 static char chorus_defined[SNDRV_EMU8000_CHORUS_NUMBERS]; 653 static struct soundfont_chorus_fx chorus_parm[SNDRV_EMU8000_CHORUS_NUMBERS] = { 654 {0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */ 655 {0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */ 656 {0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */ 657 {0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */ 658 {0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */ 659 {0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */ 660 {0xE600, 0x0B06, 0xBC00, 0x0006E000, 0x00000083}, /* short delay */ 661 {0xE6C0, 0x0B06, 0xBC00, 0x0006E000, 0x00000083}, /* short delay + feedback */ 662 }; 663 664 /*exported*/ int 665 snd_emu8000_load_chorus_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len) 666 { 667 struct soundfont_chorus_fx rec; 668 if (mode < SNDRV_EMU8000_CHORUS_PREDEFINED || mode >= SNDRV_EMU8000_CHORUS_NUMBERS) { 669 snd_printk(KERN_WARNING "invalid chorus mode %d for uploading\n", mode); 670 return -EINVAL; 671 } 672 if (len < (long)sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec))) 673 return -EFAULT; 674 chorus_parm[mode] = rec; 675 chorus_defined[mode] = 1; 676 return 0; 677 } 678 679 /*exported*/ void 680 snd_emu8000_update_chorus_mode(struct snd_emu8000 *emu) 681 { 682 int effect = emu->chorus_mode; 683 if (effect < 0 || effect >= SNDRV_EMU8000_CHORUS_NUMBERS || 684 (effect >= SNDRV_EMU8000_CHORUS_PREDEFINED && !chorus_defined[effect])) 685 return; 686 EMU8000_INIT3_WRITE(emu, 0x09, chorus_parm[effect].feedback); 687 EMU8000_INIT3_WRITE(emu, 0x0c, chorus_parm[effect].delay_offset); 688 EMU8000_INIT4_WRITE(emu, 0x03, chorus_parm[effect].lfo_depth); 689 EMU8000_HWCF4_WRITE(emu, chorus_parm[effect].delay); 690 EMU8000_HWCF5_WRITE(emu, chorus_parm[effect].lfo_freq); 691 EMU8000_HWCF6_WRITE(emu, 0x8000); 692 EMU8000_HWCF7_WRITE(emu, 0x0000); 693 } 694 695 /*---------------------------------------------------------------- 696 * Reverb mode control 697 *----------------------------------------------------------------*/ 698 699 /* 700 * reverb mode parameters 701 */ 702 #define SNDRV_EMU8000_REVERB_ROOM1 0 703 #define SNDRV_EMU8000_REVERB_ROOM2 1 704 #define SNDRV_EMU8000_REVERB_ROOM3 2 705 #define SNDRV_EMU8000_REVERB_HALL1 3 706 #define SNDRV_EMU8000_REVERB_HALL2 4 707 #define SNDRV_EMU8000_REVERB_PLATE 5 708 #define SNDRV_EMU8000_REVERB_DELAY 6 709 #define SNDRV_EMU8000_REVERB_PANNINGDELAY 7 710 #define SNDRV_EMU8000_REVERB_PREDEFINED 8 711 /* user can define reverb modes up to 32 */ 712 #define SNDRV_EMU8000_REVERB_NUMBERS 32 713 714 struct soundfont_reverb_fx { 715 unsigned short parms[28]; 716 }; 717 718 /* reverb mode settings; write the following 28 data of 16 bit length 719 * on the corresponding ports in the reverb_cmds array 720 */ 721 static char reverb_defined[SNDRV_EMU8000_CHORUS_NUMBERS]; 722 static struct soundfont_reverb_fx reverb_parm[SNDRV_EMU8000_REVERB_NUMBERS] = { 723 {{ /* room 1 */ 724 0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4, 725 0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516, 726 0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429, 727 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528, 728 }}, 729 {{ /* room 2 */ 730 0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284, 731 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548, 732 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429, 733 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528, 734 }}, 735 {{ /* room 3 */ 736 0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284, 737 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516, 738 0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B, 739 0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A, 740 }}, 741 {{ /* hall 1 */ 742 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284, 743 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548, 744 0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A, 745 0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529, 746 }}, 747 {{ /* hall 2 */ 748 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254, 749 0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3, 750 0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429, 751 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528, 752 }}, 753 {{ /* plate */ 754 0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234, 755 0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548, 756 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429, 757 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528, 758 }}, 759 {{ /* delay */ 760 0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204, 761 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500, 762 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 763 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 764 }}, 765 {{ /* panning delay */ 766 0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204, 767 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500, 768 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 769 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 770 }}, 771 }; 772 773 enum { DATA1, DATA2 }; 774 #define AWE_INIT1(c) EMU8000_CMD(2,c), DATA1 775 #define AWE_INIT2(c) EMU8000_CMD(2,c), DATA2 776 #define AWE_INIT3(c) EMU8000_CMD(3,c), DATA1 777 #define AWE_INIT4(c) EMU8000_CMD(3,c), DATA2 778 779 static struct reverb_cmd_pair { 780 unsigned short cmd, port; 781 } reverb_cmds[28] = { 782 {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)}, 783 {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)}, 784 {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)}, 785 {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)}, 786 {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)}, 787 {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)}, 788 {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)}, 789 }; 790 791 /*exported*/ int 792 snd_emu8000_load_reverb_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len) 793 { 794 struct soundfont_reverb_fx rec; 795 796 if (mode < SNDRV_EMU8000_REVERB_PREDEFINED || mode >= SNDRV_EMU8000_REVERB_NUMBERS) { 797 snd_printk(KERN_WARNING "invalid reverb mode %d for uploading\n", mode); 798 return -EINVAL; 799 } 800 if (len < (long)sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec))) 801 return -EFAULT; 802 reverb_parm[mode] = rec; 803 reverb_defined[mode] = 1; 804 return 0; 805 } 806 807 /*exported*/ void 808 snd_emu8000_update_reverb_mode(struct snd_emu8000 *emu) 809 { 810 int effect = emu->reverb_mode; 811 int i; 812 813 if (effect < 0 || effect >= SNDRV_EMU8000_REVERB_NUMBERS || 814 (effect >= SNDRV_EMU8000_REVERB_PREDEFINED && !reverb_defined[effect])) 815 return; 816 for (i = 0; i < 28; i++) { 817 int port; 818 if (reverb_cmds[i].port == DATA1) 819 port = EMU8000_DATA1(emu); 820 else 821 port = EMU8000_DATA2(emu); 822 snd_emu8000_poke(emu, port, reverb_cmds[i].cmd, reverb_parm[effect].parms[i]); 823 } 824 } 825 826 827 /*---------------------------------------------------------------- 828 * mixer interface 829 *----------------------------------------------------------------*/ 830 831 /* 832 * bass/treble 833 */ 834 static int mixer_bass_treble_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 835 { 836 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 837 uinfo->count = 1; 838 uinfo->value.integer.min = 0; 839 uinfo->value.integer.max = 11; 840 return 0; 841 } 842 843 static int mixer_bass_treble_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 844 { 845 struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol); 846 847 ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->treble_level : emu->bass_level; 848 return 0; 849 } 850 851 static int mixer_bass_treble_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 852 { 853 struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol); 854 unsigned long flags; 855 int change; 856 unsigned short val1; 857 858 val1 = ucontrol->value.integer.value[0] % 12; 859 spin_lock_irqsave(&emu->control_lock, flags); 860 if (kcontrol->private_value) { 861 change = val1 != emu->treble_level; 862 emu->treble_level = val1; 863 } else { 864 change = val1 != emu->bass_level; 865 emu->bass_level = val1; 866 } 867 spin_unlock_irqrestore(&emu->control_lock, flags); 868 snd_emu8000_update_equalizer(emu); 869 return change; 870 } 871 872 static struct snd_kcontrol_new mixer_bass_control = 873 { 874 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 875 .name = "Synth Tone Control - Bass", 876 .info = mixer_bass_treble_info, 877 .get = mixer_bass_treble_get, 878 .put = mixer_bass_treble_put, 879 .private_value = 0, 880 }; 881 882 static struct snd_kcontrol_new mixer_treble_control = 883 { 884 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 885 .name = "Synth Tone Control - Treble", 886 .info = mixer_bass_treble_info, 887 .get = mixer_bass_treble_get, 888 .put = mixer_bass_treble_put, 889 .private_value = 1, 890 }; 891 892 /* 893 * chorus/reverb mode 894 */ 895 static int mixer_chorus_reverb_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 896 { 897 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 898 uinfo->count = 1; 899 uinfo->value.integer.min = 0; 900 uinfo->value.integer.max = kcontrol->private_value ? (SNDRV_EMU8000_CHORUS_NUMBERS-1) : (SNDRV_EMU8000_REVERB_NUMBERS-1); 901 return 0; 902 } 903 904 static int mixer_chorus_reverb_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 905 { 906 struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol); 907 908 ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->chorus_mode : emu->reverb_mode; 909 return 0; 910 } 911 912 static int mixer_chorus_reverb_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 913 { 914 struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol); 915 unsigned long flags; 916 int change; 917 unsigned short val1; 918 919 spin_lock_irqsave(&emu->control_lock, flags); 920 if (kcontrol->private_value) { 921 val1 = ucontrol->value.integer.value[0] % SNDRV_EMU8000_CHORUS_NUMBERS; 922 change = val1 != emu->chorus_mode; 923 emu->chorus_mode = val1; 924 } else { 925 val1 = ucontrol->value.integer.value[0] % SNDRV_EMU8000_REVERB_NUMBERS; 926 change = val1 != emu->reverb_mode; 927 emu->reverb_mode = val1; 928 } 929 spin_unlock_irqrestore(&emu->control_lock, flags); 930 if (change) { 931 if (kcontrol->private_value) 932 snd_emu8000_update_chorus_mode(emu); 933 else 934 snd_emu8000_update_reverb_mode(emu); 935 } 936 return change; 937 } 938 939 static struct snd_kcontrol_new mixer_chorus_mode_control = 940 { 941 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 942 .name = "Chorus Mode", 943 .info = mixer_chorus_reverb_info, 944 .get = mixer_chorus_reverb_get, 945 .put = mixer_chorus_reverb_put, 946 .private_value = 1, 947 }; 948 949 static struct snd_kcontrol_new mixer_reverb_mode_control = 950 { 951 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 952 .name = "Reverb Mode", 953 .info = mixer_chorus_reverb_info, 954 .get = mixer_chorus_reverb_get, 955 .put = mixer_chorus_reverb_put, 956 .private_value = 0, 957 }; 958 959 /* 960 * FM OPL3 chorus/reverb depth 961 */ 962 static int mixer_fm_depth_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 963 { 964 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 965 uinfo->count = 1; 966 uinfo->value.integer.min = 0; 967 uinfo->value.integer.max = 255; 968 return 0; 969 } 970 971 static int mixer_fm_depth_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 972 { 973 struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol); 974 975 ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->fm_chorus_depth : emu->fm_reverb_depth; 976 return 0; 977 } 978 979 static int mixer_fm_depth_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 980 { 981 struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol); 982 unsigned long flags; 983 int change; 984 unsigned short val1; 985 986 val1 = ucontrol->value.integer.value[0] % 256; 987 spin_lock_irqsave(&emu->control_lock, flags); 988 if (kcontrol->private_value) { 989 change = val1 != emu->fm_chorus_depth; 990 emu->fm_chorus_depth = val1; 991 } else { 992 change = val1 != emu->fm_reverb_depth; 993 emu->fm_reverb_depth = val1; 994 } 995 spin_unlock_irqrestore(&emu->control_lock, flags); 996 if (change) 997 snd_emu8000_init_fm(emu); 998 return change; 999 } 1000 1001 static struct snd_kcontrol_new mixer_fm_chorus_depth_control = 1002 { 1003 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1004 .name = "FM Chorus Depth", 1005 .info = mixer_fm_depth_info, 1006 .get = mixer_fm_depth_get, 1007 .put = mixer_fm_depth_put, 1008 .private_value = 1, 1009 }; 1010 1011 static struct snd_kcontrol_new mixer_fm_reverb_depth_control = 1012 { 1013 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1014 .name = "FM Reverb Depth", 1015 .info = mixer_fm_depth_info, 1016 .get = mixer_fm_depth_get, 1017 .put = mixer_fm_depth_put, 1018 .private_value = 0, 1019 }; 1020 1021 1022 static struct snd_kcontrol_new *mixer_defs[EMU8000_NUM_CONTROLS] = { 1023 &mixer_bass_control, 1024 &mixer_treble_control, 1025 &mixer_chorus_mode_control, 1026 &mixer_reverb_mode_control, 1027 &mixer_fm_chorus_depth_control, 1028 &mixer_fm_reverb_depth_control, 1029 }; 1030 1031 /* 1032 * create and attach mixer elements for WaveTable treble/bass controls 1033 */ 1034 static int 1035 snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu) 1036 { 1037 int i, err = 0; 1038 1039 if (snd_BUG_ON(!emu || !card)) 1040 return -EINVAL; 1041 1042 spin_lock_init(&emu->control_lock); 1043 1044 memset(emu->controls, 0, sizeof(emu->controls)); 1045 for (i = 0; i < EMU8000_NUM_CONTROLS; i++) { 1046 if ((err = snd_ctl_add(card, emu->controls[i] = snd_ctl_new1(mixer_defs[i], emu))) < 0) 1047 goto __error; 1048 } 1049 return 0; 1050 1051 __error: 1052 for (i = 0; i < EMU8000_NUM_CONTROLS; i++) { 1053 down_write(&card->controls_rwsem); 1054 if (emu->controls[i]) 1055 snd_ctl_remove(card, emu->controls[i]); 1056 up_write(&card->controls_rwsem); 1057 } 1058 return err; 1059 } 1060 1061 1062 /* 1063 * free resources 1064 */ 1065 static int snd_emu8000_free(struct snd_emu8000 *hw) 1066 { 1067 release_and_free_resource(hw->res_port1); 1068 release_and_free_resource(hw->res_port2); 1069 release_and_free_resource(hw->res_port3); 1070 kfree(hw); 1071 return 0; 1072 } 1073 1074 /* 1075 */ 1076 static int snd_emu8000_dev_free(struct snd_device *device) 1077 { 1078 struct snd_emu8000 *hw = device->device_data; 1079 return snd_emu8000_free(hw); 1080 } 1081 1082 /* 1083 * initialize and register emu8000 synth device. 1084 */ 1085 int 1086 snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports, 1087 struct snd_seq_device **awe_ret) 1088 { 1089 struct snd_seq_device *awe; 1090 struct snd_emu8000 *hw; 1091 int err; 1092 static struct snd_device_ops ops = { 1093 .dev_free = snd_emu8000_dev_free, 1094 }; 1095 1096 if (awe_ret) 1097 *awe_ret = NULL; 1098 1099 if (seq_ports <= 0) 1100 return 0; 1101 1102 hw = kzalloc(sizeof(*hw), GFP_KERNEL); 1103 if (hw == NULL) 1104 return -ENOMEM; 1105 spin_lock_init(&hw->reg_lock); 1106 hw->index = index; 1107 hw->port1 = port; 1108 hw->port2 = port + 0x400; 1109 hw->port3 = port + 0x800; 1110 if (!(hw->res_port1 = request_region(hw->port1, 4, "Emu8000-1")) || 1111 !(hw->res_port2 = request_region(hw->port2, 4, "Emu8000-2")) || 1112 !(hw->res_port3 = request_region(hw->port3, 4, "Emu8000-3"))) { 1113 snd_printk(KERN_ERR "sbawe: can't grab ports 0x%lx, 0x%lx, 0x%lx\n", hw->port1, hw->port2, hw->port3); 1114 snd_emu8000_free(hw); 1115 return -EBUSY; 1116 } 1117 hw->mem_size = 0; 1118 hw->card = card; 1119 hw->seq_ports = seq_ports; 1120 hw->bass_level = 5; 1121 hw->treble_level = 9; 1122 hw->chorus_mode = 2; 1123 hw->reverb_mode = 4; 1124 hw->fm_chorus_depth = 0; 1125 hw->fm_reverb_depth = 0; 1126 1127 if (snd_emu8000_detect(hw) < 0) { 1128 snd_emu8000_free(hw); 1129 return -ENODEV; 1130 } 1131 1132 snd_emu8000_init_hw(hw); 1133 if ((err = snd_emu8000_create_mixer(card, hw)) < 0) { 1134 snd_emu8000_free(hw); 1135 return err; 1136 } 1137 1138 if ((err = snd_device_new(card, SNDRV_DEV_CODEC, hw, &ops)) < 0) { 1139 snd_emu8000_free(hw); 1140 return err; 1141 } 1142 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) 1143 if (snd_seq_device_new(card, index, SNDRV_SEQ_DEV_ID_EMU8000, 1144 sizeof(struct snd_emu8000*), &awe) >= 0) { 1145 strcpy(awe->name, "EMU-8000"); 1146 *(struct snd_emu8000 **)SNDRV_SEQ_DEVICE_ARGPTR(awe) = hw; 1147 } 1148 #else 1149 awe = NULL; 1150 #endif 1151 if (awe_ret) 1152 *awe_ret = awe; 1153 1154 return 0; 1155 } 1156 1157 1158 /* 1159 * exported stuff 1160 */ 1161 1162 EXPORT_SYMBOL(snd_emu8000_poke); 1163 EXPORT_SYMBOL(snd_emu8000_peek); 1164 EXPORT_SYMBOL(snd_emu8000_poke_dw); 1165 EXPORT_SYMBOL(snd_emu8000_peek_dw); 1166 EXPORT_SYMBOL(snd_emu8000_dma_chan); 1167 EXPORT_SYMBOL(snd_emu8000_init_fm); 1168 EXPORT_SYMBOL(snd_emu8000_load_chorus_fx); 1169 EXPORT_SYMBOL(snd_emu8000_load_reverb_fx); 1170 EXPORT_SYMBOL(snd_emu8000_update_chorus_mode); 1171 EXPORT_SYMBOL(snd_emu8000_update_reverb_mode); 1172 EXPORT_SYMBOL(snd_emu8000_update_equalizer); 1173