Linux Audio

Check our new training course

Linux BSP development engineering services

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