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

📄 emu10k1_main.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Copyright (c) by Jaroslav Kysela <perex@suse.cz> *                   Creative Labs, Inc. *  Routines for control of EMU10K1 chips * *  BUGS: *    -- * *  TODO: *    -- * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA * */#define __NO_VERSION__#include <sound/driver.h>#include <linux/delay.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/vmalloc.h>#include <sound/core.h>#include <sound/emu10k1.h>#if 0MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Creative Labs, Inc.");MODULE_DESCRIPTION("Routines for control of EMU10K1 chips");MODULE_LICENSE("GPL");#endif/************************************************************************* * EMU10K1 init / done *************************************************************************/void snd_emu10k1_voice_init(emu10k1_t * emu, int ch){	snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);	snd_emu10k1_ptr_write(emu, IP, ch, 0);	snd_emu10k1_ptr_write(emu, VTFT, ch, 0xffff);	snd_emu10k1_ptr_write(emu, CVCF, ch, 0xffff);	snd_emu10k1_ptr_write(emu, PTRX, ch, 0);	snd_emu10k1_ptr_write(emu, CPF, ch, 0);	snd_emu10k1_ptr_write(emu, CCR, ch, 0);	snd_emu10k1_ptr_write(emu, PSST, ch, 0);	snd_emu10k1_ptr_write(emu, DSL, ch, 0x10);	snd_emu10k1_ptr_write(emu, CCCA, ch, 0);	snd_emu10k1_ptr_write(emu, Z1, ch, 0);	snd_emu10k1_ptr_write(emu, Z2, ch, 0);	snd_emu10k1_ptr_write(emu, FXRT, ch, 0x32100000);	snd_emu10k1_ptr_write(emu, ATKHLDM, ch, 0);	snd_emu10k1_ptr_write(emu, DCYSUSM, ch, 0);	snd_emu10k1_ptr_write(emu, IFATN, ch, 0xffff);	snd_emu10k1_ptr_write(emu, PEFE, ch, 0);	snd_emu10k1_ptr_write(emu, FMMOD, ch, 0);	snd_emu10k1_ptr_write(emu, TREMFRQ, ch, 24);	/* 1 Hz */	snd_emu10k1_ptr_write(emu, FM2FRQ2, ch, 24);	/* 1 Hz */	snd_emu10k1_ptr_write(emu, TEMPENV, ch, 0);	/*** these are last so OFF prevents writing ***/	snd_emu10k1_ptr_write(emu, LFOVAL2, ch, 0);	snd_emu10k1_ptr_write(emu, LFOVAL1, ch, 0);	snd_emu10k1_ptr_write(emu, ATKHLDV, ch, 0);	snd_emu10k1_ptr_write(emu, ENVVOL, ch, 0);	snd_emu10k1_ptr_write(emu, ENVVAL, ch, 0);	/* Audigy extra stuffs */	if (emu->audigy) {		snd_emu10k1_ptr_write(emu, 0x4c, ch, 0); /* ?? */		snd_emu10k1_ptr_write(emu, 0x4d, ch, 0); /* ?? */		snd_emu10k1_ptr_write(emu, 0x4e, ch, 0); /* ?? */		snd_emu10k1_ptr_write(emu, 0x4f, ch, 0); /* ?? */		snd_emu10k1_ptr_write(emu, A_FXRT1, ch, 0x03020100);		snd_emu10k1_ptr_write(emu, A_FXRT2, ch, 0x3f3f3f3f);		snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, ch, 0);	}}static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir){	int ch, idx, err;	unsigned int silent_page;	emu->fx8010.itram_size = (16 * 1024)/2;	emu->fx8010.etram_size = 0;	/* disable audio and lock cache */	outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG);	/* reset recording buffers */	snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE);	snd_emu10k1_ptr_write(emu, MICBA, 0, 0);	snd_emu10k1_ptr_write(emu, FXBS, 0, ADCBS_BUFSIZE_NONE);	snd_emu10k1_ptr_write(emu, FXBA, 0, 0);	snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);	snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);	/* disable channel interrupt */	outl(0, emu->port + INTE);	snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);	snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);	snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);	snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);	if (emu->audigy){		snd_emu10k1_ptr_write(emu, 0x5e, 0, 0xf00); /* ?? */		snd_emu10k1_ptr_write(emu, 0x5f, 0, 0x3); /* ?? */	}	/* init envelope engine */	for (ch = 0; ch < NUM_G; ch++) {		emu->voices[ch].emu = emu;		emu->voices[ch].number = ch;		snd_emu10k1_voice_init(emu, ch);	}	/*	 *  Init to 0x02109204 :	 *  Clock accuracy    = 0     (1000ppm)	 *  Sample Rate       = 2     (48kHz)	 *  Audio Channel     = 1     (Left of 2)	 *  Source Number     = 0     (Unspecified)	 *  Generation Status = 1     (Original for Cat Code 12)	 *  Cat Code          = 12    (Digital Signal Mixer)	 *  Mode              = 0     (Mode 0)	 *  Emphasis          = 0     (None)	 *  CP                = 1     (Copyright unasserted)	 *  AN                = 0     (Audio data)	 *  P                 = 0     (Consumer)	 */	snd_emu10k1_ptr_write(emu, SPCS0, 0,			emu->spdif_bits[0] =			SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |			SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |			SPCS_GENERATIONSTATUS | 0x00001200 |			0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);	snd_emu10k1_ptr_write(emu, SPCS1, 0,			emu->spdif_bits[1] =			SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |			SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |			SPCS_GENERATIONSTATUS | 0x00001200 |			0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);	snd_emu10k1_ptr_write(emu, SPCS2, 0,			emu->spdif_bits[2] =			SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |			SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |			SPCS_GENERATIONSTATUS | 0x00001200 |			0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);	/*	 *  Clear page with silence & setup all pointers to this page	 */	memset(emu->silent_page, 0, PAGE_SIZE);	silent_page = emu->silent_page_dmaaddr << 1;	for (idx = 0; idx < MAXPAGES; idx++)		emu->ptb_pages[idx] = silent_page | idx;	snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages_dmaaddr);	snd_emu10k1_ptr_write(emu, TCB, 0, 0);	/* taken from original driver */	snd_emu10k1_ptr_write(emu, TCBS, 0, 4);	/* taken from original driver */	silent_page = (emu->silent_page_dmaaddr << 1) | MAP_PTI_MASK;	for (ch = 0; ch < NUM_G; ch++) {		snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page);		snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page);	}	/*	 *  Hokay, setup HCFG	 *   Mute Disable Audio = 0	 *   Lock Tank Memory = 1	 *   Lock Sound Memory = 0	 *   Auto Mute = 1	 */	if (emu->audigy)		outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);	else if (emu->model == 0x20 ||	    emu->model == 0xc400 ||	    (emu->model == 0x21 && emu->revision < 6))		outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG);	else		// With on-chip joystick		outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);	if (enable_ir) {	/* enable IR for SB Live */		unsigned int reg = inl(emu->port + HCFG);		outl(reg | HCFG_GPOUT2, emu->port + HCFG);		udelay(500);		outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG);		udelay(100);		outl(reg, emu->port + HCFG);	}		if (!emu->APS) {	/* enable analog output */		unsigned int reg = inl(emu->port + HCFG);		outl(reg | HCFG_GPOUT0, emu->port + HCFG);	}	/*	 *  Initialize the effect engine	 */	if ((err = snd_emu10k1_init_efx(emu)) < 0)		return err;	/*	 *  Enable the audio bit	 */	outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG);	/* Enable analog/digital outs on audigy */	if (emu->audigy)		outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);#if 0	{	unsigned int tmp;	/* FIXME: the following routine disables LiveDrive-II !! */	// TOSLink detection	emu->tos_link = 0;	tmp = inl(emu->port + HCFG);	if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {		outl(tmp|0x800, emu->port + HCFG);		udelay(50);		if (tmp != (inl(emu->port + HCFG) & ~0x800)) {			emu->tos_link = 1;			outl(tmp, emu->port + HCFG);		}	}	}#endif	snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE);	emu->reserved_page = (emu10k1_memblk_t *)snd_emu10k1_synth_alloc(emu, 4096);	if (emu->reserved_page)		emu->reserved_page->map_locked = 1;		return 0;}static int snd_emu10k1_done(emu10k1_t * emu){	int ch;	outl(0, emu->port + INTE);	/*	 *  Shutdown the chip	 */	for (ch = 0; ch < NUM_G; ch++)		snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);	for (ch = 0; ch < NUM_G; ch++) {		snd_emu10k1_ptr_write(emu, VTFT, ch, 0);		snd_emu10k1_ptr_write(emu, CVCF, ch, 0);		snd_emu10k1_ptr_write(emu, PTRX, ch, 0);		snd_emu10k1_ptr_write(emu, CPF, ch, 0);	}	/* reset recording buffers */	snd_emu10k1_ptr_write(emu, MICBS, 0, 0);	snd_emu10k1_ptr_write(emu, MICBA, 0, 0);	snd_emu10k1_ptr_write(emu, FXBS, 0, 0);	snd_emu10k1_ptr_write(emu, FXBA, 0, 0);	snd_emu10k1_ptr_write(emu, FXWC, 0, 0);	snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);	snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);	snd_emu10k1_ptr_write(emu, TCBS, 0, TCBS_BUFFSIZE_16K);	snd_emu10k1_ptr_write(emu, TCB, 0, 0);	if (emu->audigy)		snd_emu10k1_ptr_write(emu, A_DBG, 0, A_DBG_SINGLE_STEP);	else		snd_emu10k1_ptr_write(emu, DBG, 0, 0x8000);	/* disable channel interrupt */	snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);	snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);	snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);	snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);	/* remove reserved page */	if (emu->reserved_page != NULL) {		snd_emu10k1_synth_free(emu, (snd_util_memblk_t *)emu->reserved_page);		emu->reserved_page = NULL;	}	/* disable audio and lock cache */	outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG);	snd_emu10k1_ptr_write(emu, PTB, 0, 0);	snd_emu10k1_free_efx(emu);	return 0;}/************************************************************************* * ECARD functional implementation *************************************************************************//* In A1 Silicon, these bits are in the HC register */#define HOOKN_BIT		(1L << 12)#define HANDN_BIT		(1L << 11)#define PULSEN_BIT		(1L << 10)#define EC_GDI1			(1 << 13)#define EC_GDI0			(1 << 14)#define EC_NUM_CONTROL_BITS	20#define EC_AC3_DATA_SELN	0x0001L#define EC_EE_DATA_SEL		0x0002L#define EC_EE_CNTRL_SELN	0x0004L#define EC_EECLK		0x0008L#define EC_EECS			0x0010L#define EC_EESDO		0x0020L#define EC_TRIM_CSN		0x0040L#define EC_TRIM_SCLK		0x0080L#define EC_TRIM_SDATA		0x0100L#define EC_TRIM_MUTEN		0x0200L#define EC_ADCCAL		0x0400L#define EC_ADCRSTN		0x0800L#define EC_DACCAL		0x1000L#define EC_DACMUTEN		0x2000L#define EC_LEDN			0x4000L#define EC_SPDIF0_SEL_SHIFT	15#define EC_SPDIF1_SEL_SHIFT	17#define EC_SPDIF0_SEL_MASK	(0x3L << EC_SPDIF0_SEL_SHIFT)#define EC_SPDIF1_SEL_MASK	(0x7L << EC_SPDIF1_SEL_SHIFT)

⌨️ 快捷键说明

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