Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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