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

📄 interwave.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  Driver for AMD InterWave soundcard *  Copyright (c) by Jaroslav Kysela <perex@suse.cz> * * *   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 * *   1999/07/22		Erik Inge Bolso <knan@mo.himolde.no> *			* mixer group handlers * */#include <sound/driver.h>#include <asm/dma.h>#include <linux/delay.h>#include <linux/init.h>#include <linux/slab.h>#ifndef LINUX_ISAPNP_H#include <linux/isapnp.h>#define isapnp_card pci_bus#define isapnp_dev pci_dev#endif#include <sound/core.h>#include <sound/gus.h>#include <sound/cs4231.h>#ifdef SNDRV_STB#include <sound/tea6330t.h>#endif#define SNDRV_LEGACY_AUTO_PROBE#define SNDRV_LEGACY_FIND_FREE_IRQ#define SNDRV_LEGACY_FIND_FREE_DMA#define SNDRV_GET_ID#include <sound/initval.h>EXPORT_NO_SYMBOLS;MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");MODULE_CLASSES("{sound}");MODULE_LICENSE("GPL");#ifndef SNDRV_STBMODULE_DESCRIPTION("AMD InterWave");MODULE_DEVICES("{{Gravis,UltraSound Plug & Play},"		"{STB,SoundRage32},"		"{MED,MED3210},"		"{Dynasonix,Dynasonix Pro},"		"{Panasonic,PCA761AW}}");#elseMODULE_DESCRIPTION("AMD InterWave STB with TEA6330T");MODULE_DEVICES("{{AMD,InterWave STB with TEA6330T}}");#endifstatic int snd_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */static char *snd_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */static int snd_enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */#ifdef __ISAPNP__static int snd_isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};#endifstatic long snd_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* 0x210,0x220,0x230,0x240,0x250,0x260 */#ifdef SNDRV_STBstatic long snd_port_tc[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* 0x350,0x360,0x370,0x380 */#endifstatic int snd_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;	/* 2,3,5,9,11,12,15 */static int snd_dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;	/* 0,1,3,5,6,7 */static int snd_dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;	/* 0,1,3,5,6,7 */static int snd_joystick_dac[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 29};				/* 0 to 31, (0.59V-4.52V or 0.389V-2.98V) */static int snd_midi[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};static int snd_pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};static int snd_effect[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};MODULE_PARM(snd_index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");MODULE_PARM_DESC(snd_index, "Index value for InterWave soundcard.");MODULE_PARM_SYNTAX(snd_index, SNDRV_INDEX_DESC);MODULE_PARM(snd_id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");MODULE_PARM_DESC(snd_id, "ID string for InterWave soundcard.");MODULE_PARM_SYNTAX(snd_id, SNDRV_ID_DESC);MODULE_PARM(snd_enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");MODULE_PARM_DESC(snd_enable, "Enable InterWave soundcard.");MODULE_PARM_SYNTAX(snd_enable, SNDRV_ENABLE_DESC);MODULE_PARM(snd_isapnp, "1-" __MODULE_STRING(SNDRV_CARDS) "i");MODULE_PARM_DESC(snd_isapnp, "ISA PnP detection for specified soundcard.");MODULE_PARM_SYNTAX(snd_isapnp, SNDRV_ISAPNP_DESC);MODULE_PARM(snd_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");MODULE_PARM_DESC(snd_port, "Port # for InterWave driver.");MODULE_PARM_SYNTAX(snd_port, SNDRV_ENABLED ",allows:{{0x210,0x260,0x10}},dialog:list");#ifdef SNDRV_STBMODULE_PARM(snd_port_tc, "1-" __MODULE_STRING(SNDRV_CARDS) "l");MODULE_PARM_DESC(snd_port_tc, "Tone control (TEA6330T - i2c bus) port # for InterWave driver.");MODULE_PARM_SYNTAX(snd_port_tc, SNDRV_ENABLED ",allows:{{0x350,0x380,0x10}},dialog:list");#endifMODULE_PARM(snd_irq, "1-" __MODULE_STRING(SNDRV_CARDS) "i");MODULE_PARM_DESC(snd_irq, "IRQ # for InterWave driver.");MODULE_PARM_SYNTAX(snd_irq, SNDRV_ENABLED ",allows:{{3},{5},{9},{11},{12},{15}},dialog:list");MODULE_PARM(snd_dma1, "1-" __MODULE_STRING(SNDRV_CARDS) "i");MODULE_PARM_DESC(snd_dma1, "DMA1 # for InterWave driver.");MODULE_PARM_SYNTAX(snd_dma1, SNDRV_DMA_DESC);MODULE_PARM(snd_dma2, "1-" __MODULE_STRING(SNDRV_CARDS) "i");MODULE_PARM_DESC(snd_dma2, "DMA2 # for InterWave driver.");MODULE_PARM_SYNTAX(snd_dma2, SNDRV_DMA_DESC);MODULE_PARM(snd_joystick_dac, "1-" __MODULE_STRING(SNDRV_CARDS) "i");MODULE_PARM_DESC(snd_joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for InterWave driver.");MODULE_PARM_SYNTAX(snd_joystic_dac, SNDRV_ENABLED ",allows:{{0,31}}");MODULE_PARM(snd_midi, "1-" __MODULE_STRING(SNDRV_CARDS) "i");MODULE_PARM_DESC(snd_midi, "MIDI UART enable for InterWave driver.");MODULE_PARM_SYNTAX(snd_midi, SNDRV_ENABLED "," SNDRV_ENABLE_DESC);MODULE_PARM(snd_pcm_channels, "1-" __MODULE_STRING(SNDRV_CARDS) "i");MODULE_PARM_DESC(snd_pcm_channels, "Reserved PCM channels for InterWave driver.");MODULE_PARM_SYNTAX(snd_pcm_channels, SNDRV_ENABLED ",allows:{{2,16}}");MODULE_PARM(snd_effect, "1-" __MODULE_STRING(SNDRV_CARDS) "i");MODULE_PARM_DESC(snd_effect, "Effects enable for InterWave driver.");MODULE_PARM_SYNTAX(snd_effect, SNDRV_ENABLED "," SNDRV_ENABLE_DESC);struct snd_interwave {	int irq;	snd_card_t *card;	snd_gus_card_t *gus;	cs4231_t *cs4231;#ifdef SNDRV_STB	struct resource *i2c_res;#endif	unsigned short gus_status_reg;	unsigned short pcm_status_reg;#ifdef __ISAPNP__	struct isapnp_dev *dev;#ifdef SNDRV_STB	struct isapnp_dev *devtc;#endif#endif};static snd_card_t *snd_interwave_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;#ifdef __ISAPNP__static struct isapnp_card *snd_interwave_isapnp_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;static const struct isapnp_card_id *snd_interwave_isapnp_id[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;#define ISAPNP_INTERWAVE(_va, _vb, _vc, _device, _audio) \	{ \		ISAPNP_CARD_ID(_va, _vb, _vc, _device), \		devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), } \	}#define ISAPNP_INTERWAVE_STB(_va, _vb, _vc, _device, _audio, _tone) \	{ \		ISAPNP_CARD_ID(_va, _vb, _vc, _device), \		devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), \			 ISAPNP_DEVICE_ID(_va, _vb, _vc, _tone), } \	}static struct isapnp_card_id snd_interwave_pnpids[] __devinitdata = {#ifndef SNDRV_STB	/* Gravis UltraSound Plug & Play */	ISAPNP_INTERWAVE('G','R','V',0x0001,0x0000),	/* STB SoundRage32 */	ISAPNP_INTERWAVE('S','T','B',0x011a,0x0010),	/* MED3210 */	ISAPNP_INTERWAVE('D','X','P',0x3201,0x0010),	/* Dynasonic Pro */	/* This device also have CDC1117:DynaSonix Pro Audio Effects Processor */	ISAPNP_INTERWAVE('C','D','C',0x1111,0x1112),	/* Panasonic PCA761AW Audio Card */	ISAPNP_INTERWAVE('A','D','V',0x55ff,0x0010),#else	/* InterWave STB with TEA6330T */	ISAPNP_INTERWAVE_STB('A','D','V',0x550a,0x0010,0x0015),#endif	{ ISAPNP_CARD_END, }};ISAPNP_CARD_TABLE(snd_interwave_pnpids);#endif /* __ISAPNP__ */#ifdef SNDRV_STBstatic void snd_interwave_i2c_setlines(snd_i2c_bus_t *bus, int ctrl, int data){	unsigned long port = bus->private_value;#if 0	printk("i2c_setlines - 0x%lx <- %i,%i\n", port, ctrl, data);#endif	outb((data << 1) | ctrl, port);	udelay(10);}static int snd_interwave_i2c_getclockline(snd_i2c_bus_t *bus){	unsigned long port = bus->private_value;	unsigned char res;	res = inb(port) & 1;#if 0	printk("i2c_getclockline - 0x%lx -> %i\n", port, res);#endif	return res;}static int snd_interwave_i2c_getdataline(snd_i2c_bus_t *bus, int ack){	unsigned long port = bus->private_value;	unsigned char res;	if (ack)		udelay(10);	res = (inb(port) & 2) >> 1;#if 0	printk("i2c_getdataline - 0x%lx -> %i\n", port, res);#endif	return res;}static snd_i2c_bit_ops_t snd_interwave_i2c_bit_ops = {	setlines: snd_interwave_i2c_setlines,	getclock: snd_interwave_i2c_getclockline,	getdata:  snd_interwave_i2c_getdataline,};static int __init snd_interwave_detect_stb(struct snd_interwave *iwcard,					   snd_gus_card_t * gus, int dev,					   snd_i2c_bus_t **rbus){	unsigned long port;	snd_i2c_bus_t *bus;	snd_card_t *card = iwcard->card;	char name[32];	int err;	*rbus = NULL;	port = snd_port_tc[dev];	if (port == SNDRV_AUTO_PORT) {		port = 0x350;		if (gus->gf1.port == 0x250) {			port = 0x360;		}		while (port <= 0x380) {			if ((iwcard->i2c_res = request_region(port, 1, "InterWave (I2C bus)")) != NULL)				break;			port += 0x10;		}		if (port > 0x380)			return -ENODEV;	} else {		if ((iwcard->i2c_res = request_region(port, 1, "InterWave (I2C bus)")) != NULL)			return -ENODEV;	}	sprintf(name, "InterWave-%i", card->number);	if ((err = snd_i2c_bus_create(card, name, NULL, &bus)) < 0)		return err;	bus->private_value = port;	bus->hw_ops.bit = &snd_interwave_i2c_bit_ops;	if ((err = snd_tea6330t_detect(bus, 0)) < 0)		return err;	*rbus = bus;	return 0;}#endifstatic int __init snd_interwave_detect(struct snd_interwave *iwcard,				       snd_gus_card_t * gus,				       int dev#ifdef SNDRV_STB				       , snd_i2c_bus_t **rbus#endif				       ){	unsigned long flags;	unsigned char rev1, rev2;	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0);	/* reset GF1 */#ifdef CONFIG_SND_DEBUG_DETECT	{		int d;		if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {			snd_printk("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);			return -ENODEV;		}	}#else	if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 0)		return -ENODEV;#endif	udelay(160);	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1);	/* release reset */	udelay(160);#ifdef CONFIG_SND_DEBUG_DETECT	{		int d;		if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {			snd_printk("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);			return -ENODEV;		}	}#else	if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 1)		return -ENODEV;#endif	spin_lock_irqsave(&gus->reg_lock, flags);	rev1 = snd_gf1_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER);	snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, ~rev1);	rev2 = snd_gf1_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER);	snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, rev1);	spin_unlock_irqrestore(&gus->reg_lock, flags);	snd_printdd("[0x%lx] InterWave check - rev1=0x%x, rev2=0x%x\n", gus->gf1.port, rev1, rev2);	if ((rev1 & 0xf0) == (rev2 & 0xf0) &&	    (rev1 & 0x0f) != (rev2 & 0x0f)) {		snd_printdd("[0x%lx] InterWave check - passed\n", gus->gf1.port);		gus->interwave = 1;		strcpy(gus->card->shortname, "AMD InterWave");		gus->revision = rev1 >> 4;#ifndef SNDRV_STB		return 0;	/* ok.. We have an InterWave board */#else		return snd_interwave_detect_stb(iwcard, gus, dev, rbus);#endif	}	snd_printdd("[0x%lx] InterWave check - failed\n", gus->gf1.port);	return -ENODEV;}static void snd_interwave_interrupt(int irq, void *dev_id, struct pt_regs *regs){	struct snd_interwave *iwcard = (struct snd_interwave *) dev_id;	int loop, max = 5;	do {		loop = 0;

⌨️ 快捷键说明

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