⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 emu8000.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* write out a magic number */	snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE);	snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_READ);	EMU8000_SMALW_WRITE(emu, EMU8000_DRAM_OFFSET);	EMU8000_SMLD_WRITE(emu, UNIQUE_ID1);	snd_emu8000_init_fm(emu); /* This must really be here and not 2 lines back even */	while (size < EMU8000_MAX_DRAM) {		size += 512 * 1024;  /* increment 512kbytes */		/* Write a unique data on the test address.		 * if the address is out of range, the data is written on		 * 0x200000(=EMU8000_DRAM_OFFSET).  Then the id word is		 * changed by this data.		 */		/*snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE);*/		EMU8000_SMALW_WRITE(emu, EMU8000_DRAM_OFFSET + (size>>1));		EMU8000_SMLD_WRITE(emu, UNIQUE_ID2);		snd_emu8000_write_wait(emu);		/*		 * read the data on the just written DRAM address		 * if not the same then we have reached the end of ram.		 */		/*snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_READ);*/		EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET + (size>>1));		/*snd_emu8000_read_wait(emu);*/		EMU8000_SMLD_READ(emu); /* discard stale data  */		if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2)			break; /* we must have wrapped around */		snd_emu8000_read_wait(emu);		/*		 * If it is the same it could be that the address just		 * wraps back to the beginning; so check to see if the		 * initial value has been overwritten.		 */		EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET);		EMU8000_SMLD_READ(emu); /* discard stale data  */		if (EMU8000_SMLD_READ(emu) != UNIQUE_ID1)			break; /* we must have wrapped around */		snd_emu8000_read_wait(emu);	}	/* wait until FULL bit in SMAxW register is false */	for (i = 0; i < 10000; i++) {		if ((EMU8000_SMALW_READ(emu) & 0x80000000) == 0)			break;		schedule_timeout_interruptible(1);		if (signal_pending(current))			break;	}	snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_CLOSE);	snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_CLOSE);	snd_printdd("EMU8000 [0x%lx]: %d Kb on-board memory detected\n",		    emu->port1, size/1024);	emu->mem_size = size;	emu->dram_checked = 1;}/* * Initiailise the FM section.  You have to do this to use sample RAM * and therefore lose 2 voices. *//*exported*/ voidsnd_emu8000_init_fm(emu8000_t *emu){	unsigned long flags;	/* Initialize the last two channels for DRAM refresh and producing	   the reverb and chorus effects for Yamaha OPL-3 synthesizer */	/* 31: FM left channel, 0xffffe0-0xffffe8 */	EMU8000_DCYSUSV_WRITE(emu, 30, 0x80);	EMU8000_PSST_WRITE(emu, 30, 0xFFFFFFE0); /* full left */	EMU8000_CSL_WRITE(emu, 30, 0x00FFFFE8 | (emu->fm_chorus_depth << 24));	EMU8000_PTRX_WRITE(emu, 30, (emu->fm_reverb_depth << 8));	EMU8000_CPF_WRITE(emu, 30, 0);	EMU8000_CCCA_WRITE(emu, 30, 0x00FFFFE3);	/* 32: FM right channel, 0xfffff0-0xfffff8 */	EMU8000_DCYSUSV_WRITE(emu, 31, 0x80);	EMU8000_PSST_WRITE(emu, 31, 0x00FFFFF0); /* full right */	EMU8000_CSL_WRITE(emu, 31, 0x00FFFFF8 | (emu->fm_chorus_depth << 24));	EMU8000_PTRX_WRITE(emu, 31, (emu->fm_reverb_depth << 8));	EMU8000_CPF_WRITE(emu, 31, 0x8000);	EMU8000_CCCA_WRITE(emu, 31, 0x00FFFFF3);	snd_emu8000_poke((emu), EMU8000_DATA0(emu), EMU8000_CMD(1, (30)), 0);	spin_lock_irqsave(&emu->reg_lock, flags);	while (!(inw(EMU8000_PTR(emu)) & 0x1000))		;	while ((inw(EMU8000_PTR(emu)) & 0x1000))		;	spin_unlock_irqrestore(&emu->reg_lock, flags);	snd_emu8000_poke((emu), EMU8000_DATA0(emu), EMU8000_CMD(1, (30)), 0x4828);	/* this is really odd part.. */	outb(0x3C, EMU8000_PTR(emu));	outb(0, EMU8000_DATA1(emu));	/* skew volume & cutoff */	EMU8000_VTFT_WRITE(emu, 30, 0x8000FFFF);	EMU8000_VTFT_WRITE(emu, 31, 0x8000FFFF);}/* * The main initialization routine. */static void __initsnd_emu8000_init_hw(emu8000_t *emu){	int i;	emu->last_reg = 0xffff; /* reset the last register index */	/* initialize hardware configuration */	EMU8000_HWCF1_WRITE(emu, 0x0059);	EMU8000_HWCF2_WRITE(emu, 0x0020);	/* disable audio; this seems to reduce a clicking noise a bit.. */	EMU8000_HWCF3_WRITE(emu, 0);	/* initialize audio channels */	init_audio(emu);	/* initialize DMA */	init_dma(emu);	/* initialize init arrays */	init_arrays(emu);	/*	 * Initialize the FM section of the AWE32, this is needed	 * for DRAM refresh as well	 */	snd_emu8000_init_fm(emu);	/* terminate all voices */	for (i = 0; i < EMU8000_DRAM_VOICES; i++)		EMU8000_DCYSUSV_WRITE(emu, 0, 0x807F);		/* check DRAM memory size */	size_dram(emu);	/* enable audio */	EMU8000_HWCF3_WRITE(emu, 0x4);	/* set equzlier, chorus and reverb modes */	snd_emu8000_update_equalizer(emu);	snd_emu8000_update_chorus_mode(emu);	snd_emu8000_update_reverb_mode(emu);}/*---------------------------------------------------------------- * Bass/Treble Equalizer *----------------------------------------------------------------*/static unsigned short bass_parm[12][3] = {	{0xD26A, 0xD36A, 0x0000}, /* -12 dB */	{0xD25B, 0xD35B, 0x0000}, /*  -8 */	{0xD24C, 0xD34C, 0x0000}, /*  -6 */	{0xD23D, 0xD33D, 0x0000}, /*  -4 */	{0xD21F, 0xD31F, 0x0000}, /*  -2 */	{0xC208, 0xC308, 0x0001}, /*   0 (HW default) */	{0xC219, 0xC319, 0x0001}, /*  +2 */	{0xC22A, 0xC32A, 0x0001}, /*  +4 */	{0xC24C, 0xC34C, 0x0001}, /*  +6 */	{0xC26E, 0xC36E, 0x0001}, /*  +8 */	{0xC248, 0xC384, 0x0002}, /* +10 */	{0xC26A, 0xC36A, 0x0002}, /* +12 dB */};static unsigned short treble_parm[12][9] = {	{0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */	{0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},	{0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},	{0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},	{0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},	{0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002},	{0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002},	{0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002},	{0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002},	{0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */	{0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002},	{0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}  /* +12 dB */};/* * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB] *//*exported*/ voidsnd_emu8000_update_equalizer(emu8000_t *emu){	unsigned short w;	int bass = emu->bass_level;	int treble = emu->treble_level;	if (bass < 0 || bass > 11 || treble < 0 || treble > 11)		return;	EMU8000_INIT4_WRITE(emu, 0x01, bass_parm[bass][0]);	EMU8000_INIT4_WRITE(emu, 0x11, bass_parm[bass][1]);	EMU8000_INIT3_WRITE(emu, 0x11, treble_parm[treble][0]);	EMU8000_INIT3_WRITE(emu, 0x13, treble_parm[treble][1]);	EMU8000_INIT3_WRITE(emu, 0x1b, treble_parm[treble][2]);	EMU8000_INIT4_WRITE(emu, 0x07, treble_parm[treble][3]);	EMU8000_INIT4_WRITE(emu, 0x0b, treble_parm[treble][4]);	EMU8000_INIT4_WRITE(emu, 0x0d, treble_parm[treble][5]);	EMU8000_INIT4_WRITE(emu, 0x17, treble_parm[treble][6]);	EMU8000_INIT4_WRITE(emu, 0x19, treble_parm[treble][7]);	w = bass_parm[bass][2] + treble_parm[treble][8];	EMU8000_INIT4_WRITE(emu, 0x15, (unsigned short)(w + 0x0262));	EMU8000_INIT4_WRITE(emu, 0x1d, (unsigned short)(w + 0x8362));}/*---------------------------------------------------------------- * Chorus mode control *----------------------------------------------------------------*//* * chorus mode parameters */#define SNDRV_EMU8000_CHORUS_1		0#define	SNDRV_EMU8000_CHORUS_2		1#define	SNDRV_EMU8000_CHORUS_3		2#define	SNDRV_EMU8000_CHORUS_4		3#define	SNDRV_EMU8000_CHORUS_FEEDBACK	4#define	SNDRV_EMU8000_CHORUS_FLANGER	5#define	SNDRV_EMU8000_CHORUS_SHORTDELAY	6#define	SNDRV_EMU8000_CHORUS_SHORTDELAY2	7#define SNDRV_EMU8000_CHORUS_PREDEFINED	8/* user can define chorus modes up to 32 */#define SNDRV_EMU8000_CHORUS_NUMBERS	32typedef struct soundfont_chorus_fx_t {	unsigned short feedback;	/* feedback level (0xE600-0xE6FF) */	unsigned short delay_offset;	/* delay (0-0x0DA3) [1/44100 sec] */	unsigned short lfo_depth;	/* LFO depth (0xBC00-0xBCFF) */	unsigned int delay;	/* right delay (0-0xFFFFFFFF) [1/256/44100 sec] */	unsigned int lfo_freq;		/* LFO freq LFO freq (0-0xFFFFFFFF) */} soundfont_chorus_fx_t;/* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */static char chorus_defined[SNDRV_EMU8000_CHORUS_NUMBERS];static soundfont_chorus_fx_t chorus_parm[SNDRV_EMU8000_CHORUS_NUMBERS] = {	{0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */	{0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */	{0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */	{0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */	{0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */	{0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */	{0xE600, 0x0B06, 0xBC00, 0x0006E000, 0x00000083}, /* short delay */	{0xE6C0, 0x0B06, 0xBC00, 0x0006E000, 0x00000083}, /* short delay + feedback */};/*exported*/ intsnd_emu8000_load_chorus_fx(emu8000_t *emu, int mode, const void __user *buf, long len){	soundfont_chorus_fx_t rec;	if (mode < SNDRV_EMU8000_CHORUS_PREDEFINED || mode >= SNDRV_EMU8000_CHORUS_NUMBERS) {		snd_printk(KERN_WARNING "invalid chorus mode %d for uploading\n", mode);		return -EINVAL;	}	if (len < (long)sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec)))		return -EFAULT;	chorus_parm[mode] = rec;	chorus_defined[mode] = 1;	return 0;}/*exported*/ voidsnd_emu8000_update_chorus_mode(emu8000_t *emu){	int effect = emu->chorus_mode;	if (effect < 0 || effect >= SNDRV_EMU8000_CHORUS_NUMBERS ||	    (effect >= SNDRV_EMU8000_CHORUS_PREDEFINED && !chorus_defined[effect]))		return;	EMU8000_INIT3_WRITE(emu, 0x09, chorus_parm[effect].feedback);	EMU8000_INIT3_WRITE(emu, 0x0c, chorus_parm[effect].delay_offset);	EMU8000_INIT4_WRITE(emu, 0x03, chorus_parm[effect].lfo_depth);	EMU8000_HWCF4_WRITE(emu, chorus_parm[effect].delay);	EMU8000_HWCF5_WRITE(emu, chorus_parm[effect].lfo_freq);	EMU8000_HWCF6_WRITE(emu, 0x8000);	EMU8000_HWCF7_WRITE(emu, 0x0000);}/*---------------------------------------------------------------- * Reverb mode control *----------------------------------------------------------------*//* * reverb mode parameters */#define	SNDRV_EMU8000_REVERB_ROOM1	0#define SNDRV_EMU8000_REVERB_ROOM2	1#define	SNDRV_EMU8000_REVERB_ROOM3	2#define	SNDRV_EMU8000_REVERB_HALL1	3#define	SNDRV_EMU8000_REVERB_HALL2	4#define	SNDRV_EMU8000_REVERB_PLATE	5#define	SNDRV_EMU8000_REVERB_DELAY	6#define	SNDRV_EMU8000_REVERB_PANNINGDELAY 7#define SNDRV_EMU8000_REVERB_PREDEFINED	8/* user can define reverb modes up to 32 */#define SNDRV_EMU8000_REVERB_NUMBERS	32typedef struct soundfont_reverb_fx_t {	unsigned short parms[28];} soundfont_reverb_fx_t;/* reverb mode settings; write the following 28 data of 16 bit length *   on the corresponding ports in the reverb_cmds array */static char reverb_defined[SNDRV_EMU8000_CHORUS_NUMBERS];static soundfont_reverb_fx_t reverb_parm[SNDRV_EMU8000_REVERB_NUMBERS] = {{{  /* room 1 */	0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,	0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,	0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,	0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,}},{{  /* room 2 */	0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284,	0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,	0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,	0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,}},{{  /* room 3 */	0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284,	0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516,	0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B,	0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A,}},{{  /* hall 1 */	0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284,	0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,	0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A,	0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529,}},{{  /* hall 2 */	0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254,	0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3,	0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,	0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,}},{{  /* plate */	0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234,	0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548,	0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,	0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,}},{{  /* delay */	0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204,	0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,	0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,	0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,}},{{  /* panning delay */	0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204,	0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,	0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,	0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,}},};enum { DATA1, DATA2 };#define AWE_INIT1(c)	EMU8000_CMD(2,c), DATA1#define AWE_INIT2(c)	EMU8000_CMD(2,c), DATA2#define AWE_INIT3(c)	EMU8000_CMD(3,c), DATA1#define AWE_INIT4(c)	EMU8000_CMD(3,c), DATA2static struct reverb_cmd_pair {	unsigned short cmd, port;} reverb_cmds[28] = {  {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)},  {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)},  {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)},  {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)},  {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)},

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -