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

📄 ymf_sb.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  Legacy audio driver for YMF724, 740, 744, 754 series.  Copyright 2000 Daisuke Nagano <breeze.nagano@nifty.ne.jp>  Based on the VIA 82Cxxx driver by Jeff Garzik <jgarzik@pobox.com>  And ported to 2.3.x by Jeff Garzik too :)  My it is a small world.  Distribued under the GNU PUBLIC LICENSE (GPL) Version 2.  See the "COPYING" file distributed with kernel source tree for more info.  -------------------------------------------------------------------------  It only supports SBPro compatible function of YMF7xx series s.t.    * 22.05kHz, 8-bit and stereo sample    * OPL3-compatible FM synthesizer    * MPU-401 compatible "external" MIDI interface  -------------------------------------------------------------------------  Revision history   Tue May 14 19:00:00 2000   0.0.1   * initial release   Tue May 16 19:29:29 2000   0.0.2   * add a little delays for reset devices.   * fixed addressing bug.   Sun May 21 15:14:37 2000   0.0.3   * Add 'master_vol' module parameter to change 'PCM out Vol' of AC'97.   * remove native UART401 support. External MIDI port should be supported      by sb_midi driver.   * add support for SPDIF OUT. Module parameter 'spdif_out' is now available.   Wed May 31 00:13:57 2000   0.0.4   * remove entries in Hwmcode.h. Now YMF744 / YMF754 sets instructions      in 724hwmcode.h.   * fixed wrong legacy_io setting on YMF744/YMF754 .   Thu Sep 21 05:32:51 BRT 2000 0.0.5   * got rid of attach_uart401 and attach_sbmpu     Arnaldo Carvalho de Melo <acme@conectiva.com.br> */#include <linux/module.h>#include <linux/delay.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/pci.h>#include <linux/init.h>#include <linux/ac97_codec.h>#include <asm/io.h>#include "sound_config.h"#include "sb.h"#include "724hwmcode.h"#undef YMF_DEBUG#define SUPPORT_UART401_MIDI 1/* ---------------------------------------------------------------------- */#ifndef PCI_VENDOR_ID_YAMAHA#define PCI_VENDOR_ID_YAMAHA  0x1073#endif#ifndef PCI_DEVICE_ID_YMF724#define PCI_DEVICE_ID_YMF724  0x0004#endif#ifndef PCI_DEVICE_ID_YMF740#define PCI_DEVICE_ID_YMF740  0x000A#endif#ifndef PCI_DEVICE_ID_YMF740C#define PCI_DEVICE_ID_YMF740C 0x000C#endif#ifndef PCI_DEVICE_ID_YMF724F#define PCI_DEVICE_ID_YMF724F 0x000D#endif#ifndef PCI_DEVICE_ID_YMF744#define PCI_DEVICE_ID_YMF744  0x0010#endif#ifndef PCI_DEVICE_ID_YMF754#define PCI_DEVICE_ID_YMF754  0x0012#endif/* ---------------------------------------------------------------------- */#define YMFSB_RESET_DELAY               5#define YMFSB_REGSIZE                   0x8000#define YMFSB_AC97TIMEOUT               2000#define	YMFSB_WORKBITTIMEOUT            250000#define	YMFSB_DSPLENGTH                 0x0080#define	YMFSB_CTRLLENGTH                0x3000#define YMFSB_PCIR_VENDORID             0x00#define YMFSB_PCIR_DEVICEID             0x02#define YMFSB_PCIR_CMD                  0x04#define YMFSB_PCIR_REVISIONID           0x08#define YMFSB_PCIR_BASEADDR             0x10#define YMFSB_PCIR_IRQ                  0x3c#define	YMFSB_PCIR_LEGCTRL              0x40#define	YMFSB_PCIR_ELEGCTRL             0x42#define	YMFSB_PCIR_DSXGCTRL             0x48#define YMFSB_PCIR_OPLADR               0x60#define YMFSB_PCIR_SBADR                0x62#define YMFSB_PCIR_MPUADR               0x64#define	YMFSB_INTFLAG                   0x0004#define	YMFSB_ACTIVITY                  0x0006#define	YMFSB_GLOBALCTRL                0x0008#define	YMFSB_ZVCTRL                    0x000A#define	YMFSB_TIMERCTRL                 0x0010#define	YMFSB_TIMERCOUNT                0x0012#define	YMFSB_SPDIFOUTCTRL              0x0018#define	YMFSB_SPDIFOUTSTATUS            0x001C#define	YMFSB_EEPROMCTRL                0x0020#define	YMFSB_SPDIFINCTRL               0x0034#define	YMFSB_SPDIFINSTATUS             0x0038#define	YMFSB_DSPPROGRAMDL              0x0048#define	YMFSB_DLCNTRL                   0x004C#define	YMFSB_GPIOININTFLAG             0x0050#define	YMFSB_GPIOININTENABLE           0x0052#define	YMFSB_GPIOINSTATUS              0x0054#define	YMFSB_GPIOOUTCTRL               0x0056#define	YMFSB_GPIOFUNCENABLE            0x0058#define	YMFSB_GPIOTYPECONFIG            0x005A#define	YMFSB_AC97CMDDATA               0x0060#define	YMFSB_AC97CMDADR                0x0062#define	YMFSB_PRISTATUSDATA             0x0064#define	YMFSB_PRISTATUSADR              0x0066#define	YMFSB_SECSTATUSDATA             0x0068#define	YMFSB_SECSTATUSADR              0x006A#define	YMFSB_SECCONFIG                 0x0070#define	YMFSB_LEGACYOUTVOL              0x0080#define	YMFSB_LEGACYOUTVOLL             0x0080#define	YMFSB_LEGACYOUTVOLR             0x0082#define	YMFSB_NATIVEDACOUTVOL           0x0084#define	YMFSB_NATIVEDACOUTVOLL          0x0084#define	YMFSB_NATIVEDACOUTVOLR          0x0086#define	YMFSB_SPDIFOUTVOL               0x0088#define	YMFSB_SPDIFOUTVOLL              0x0088#define	YMFSB_SPDIFOUTVOLR              0x008A#define	YMFSB_AC3OUTVOL                 0x008C#define	YMFSB_AC3OUTVOLL                0x008C#define	YMFSB_AC3OUTVOLR                0x008E#define	YMFSB_PRIADCOUTVOL              0x0090#define	YMFSB_PRIADCOUTVOLL             0x0090#define	YMFSB_PRIADCOUTVOLR             0x0092#define	YMFSB_LEGACYLOOPVOL             0x0094#define	YMFSB_LEGACYLOOPVOLL            0x0094#define	YMFSB_LEGACYLOOPVOLR            0x0096#define	YMFSB_NATIVEDACLOOPVOL          0x0098#define	YMFSB_NATIVEDACLOOPVOLL         0x0098#define	YMFSB_NATIVEDACLOOPVOLR         0x009A#define	YMFSB_SPDIFLOOPVOL              0x009C#define	YMFSB_SPDIFLOOPVOLL             0x009E#define	YMFSB_SPDIFLOOPVOLR             0x009E#define	YMFSB_AC3LOOPVOL                0x00A0#define	YMFSB_AC3LOOPVOLL               0x00A0#define	YMFSB_AC3LOOPVOLR               0x00A2#define	YMFSB_PRIADCLOOPVOL             0x00A4#define	YMFSB_PRIADCLOOPVOLL            0x00A4#define	YMFSB_PRIADCLOOPVOLR            0x00A6#define	YMFSB_NATIVEADCINVOL            0x00A8#define	YMFSB_NATIVEADCINVOLL           0x00A8#define	YMFSB_NATIVEADCINVOLR           0x00AA#define	YMFSB_NATIVEDACINVOL            0x00AC#define	YMFSB_NATIVEDACINVOLL           0x00AC#define	YMFSB_NATIVEDACINVOLR           0x00AE#define	YMFSB_BUF441OUTVOL              0x00B0#define	YMFSB_BUF441OUTVOLL             0x00B0#define	YMFSB_BUF441OUTVOLR             0x00B2#define	YMFSB_BUF441LOOPVOL             0x00B4#define	YMFSB_BUF441LOOPVOLL            0x00B4#define	YMFSB_BUF441LOOPVOLR            0x00B6#define	YMFSB_SPDIFOUTVOL2              0x00B8#define	YMFSB_SPDIFOUTVOL2L             0x00B8#define	YMFSB_SPDIFOUTVOL2R             0x00BA#define	YMFSB_SPDIFLOOPVOL2             0x00BC#define	YMFSB_SPDIFLOOPVOL2L            0x00BC#define	YMFSB_SPDIFLOOPVOL2R            0x00BE#define	YMFSB_ADCSLOTSR                 0x00C0#define	YMFSB_RECSLOTSR                 0x00C4#define	YMFSB_ADCFORMAT                 0x00C8#define	YMFSB_RECFORMAT                 0x00CC#define	YMFSB_P44SLOTSR                 0x00D0#define	YMFSB_STATUS                    0x0100#define	YMFSB_CTRLSELECT                0x0104#define	YMFSB_MODE                      0x0108#define	YMFSB_SAMPLECOUNT               0x010C#define	YMFSB_NUMOFSAMPLES              0x0110#define	YMFSB_CONFIG                    0x0114#define	YMFSB_PLAYCTRLSIZE              0x0140#define	YMFSB_RECCTRLSIZE               0x0144#define	YMFSB_EFFCTRLSIZE               0x0148#define	YMFSB_WORKSIZE                  0x014C#define	YMFSB_MAPOFREC                  0x0150#define	YMFSB_MAPOFEFFECT               0x0154#define	YMFSB_PLAYCTRLBASE              0x0158#define	YMFSB_RECCTRLBASE               0x015C#define	YMFSB_EFFCTRLBASE               0x0160#define	YMFSB_WORKBASE                  0x0164#define	YMFSB_DSPINSTRAM                0x1000#define	YMFSB_CTRLINSTRAM               0x4000/* ---------------------------------------------------------------------- */#define MAX_CARDS	4#define PFX		"ymf_sb: "#define YMFSB_VERSION	"0.0.6"#define YMFSB_CARD_NAME	"YMF7xx Legacy Audio driver " YMFSB_VERSION#ifdef SUPPORT_UART401_MIDI#if 0# define ymf7xxsb_probe_midi probe_uart401# define ymf7xxsb_unload_midi unload_uart401#else# define ymf7xxsb_probe_midi probe_sbmpu# define ymf7xxsb_unload_midi unload_sbmpu#endif#endif/* ---------------------------------------------------------------------- */static struct address_info	sb_data[MAX_CARDS];static struct address_info	opl3_data[MAX_CARDS];#ifdef SUPPORT_UART401_MIDIstatic struct address_info	mpu_data[MAX_CARDS];#endifstatic unsigned			cards = 0;static unsigned short          *ymfbase[MAX_CARDS];/* ---------------------------------------------------------------------- */#ifdef MODULE#ifdef SUPPORT_UART401_MIDIstatic int mpu_io   = 0;#endifstatic int synth_io = 0;static int io       = 0;static int dma      = 0;static int master_vol = -1;static int spdif_out = 0;#ifdef SUPPORT_UART401_MIDIMODULE_PARM(mpu_io, "i");#endifMODULE_PARM(synth_io, "i");MODULE_PARM(io,"i");MODULE_PARM(dma,"i");MODULE_PARM(master_vol,"i");MODULE_PARM(spdif_out,"i");#else#ifdef SUPPORT_UART401_MIDIstatic int mpu_io     = 0x330;#endifstatic int synth_io   = 0x388;static int io         = 0x220;static int dma        = 1;static int master_vol = 80;static int spdif_out  = 0;#endif/* ---------------------------------------------------------------------- */static int readRegWord( int adr ) {	if (ymfbase[cards]==NULL) return 0;	return readw(ymfbase[cards]+adr/2);}static void writeRegWord( int adr, int val ) {	if (ymfbase[cards]==NULL) return;	writew((unsigned short)(val&0xffff), ymfbase[cards] + adr/2);	return;}static int readRegDWord( int adr ) {	if (ymfbase[cards]==NULL) return 0;	return (readl(ymfbase[cards]+adr/2));}static void writeRegDWord( int adr, int val ) {	if (ymfbase[cards]==NULL) return;	writel((unsigned int)(val&0xffffffff), ymfbase[cards]+adr/2);	return;}/* ---------------------------------------------------------------------- */static int checkPrimaryBusy( void ){	int timeout=0;	while ( timeout++ < YMFSB_AC97TIMEOUT )	{		if ( (readRegWord(YMFSB_PRISTATUSADR) & 0x8000) == 0x0000 )			return 0;	}	return -1;}static int writeAc97( int adr, unsigned short val ){	if ( adr > 0x7f || adr < 0x00 ) return -1;	if ( checkPrimaryBusy() ) return -1;#ifdef YMF_DEBUG	printk(KERN_INFO PFX "AC97 0x%0x = 0x%0x\n",adr,val);#endif	writeRegWord( YMFSB_AC97CMDADR,  0x0000 | adr );	writeRegWord( YMFSB_AC97CMDDATA, val );	return 0;}static int __init checkCodec( struct pci_dev *pcidev ){	u8 tmp8;	pci_read_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, &tmp8);	if ( tmp8 & 0x03 ) {		pci_write_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, tmp8&0xfc);		mdelay(YMFSB_RESET_DELAY);		pci_write_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, tmp8|0x03);		mdelay(YMFSB_RESET_DELAY);		pci_write_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, tmp8&0xfc);		mdelay(YMFSB_RESET_DELAY);	}	if ( checkPrimaryBusy() ) return -1;	return 0;}static int __init setupLegacyIO( struct pci_dev *pcidev ){	int v;	int sbio=0,mpuio=0,oplio=0,dma=0;	switch(sb_data[cards].io_base) {	case 0x220:		sbio = 0;		break;	case 0x240:		sbio = 1;		break;	case 0x260:		sbio = 2;		break;	case 0x280:		sbio = 3;		break;	default:		return -1;		break;	}#ifdef YMF_DEBUG	printk(PFX "set SBPro I/O at 0x%x\n",sb_data[cards].io_base);#endif#ifdef SUPPORT_UART401_MIDI	switch(mpu_data[cards].io_base) {	case 0x330:		mpuio = 0;		break;	case 0x300:		mpuio = 1;		break;	case 0x332:		mpuio = 2;		break;	case 0x334:		mpuio = 3;		break;	default:		mpuio = 0;		break;	}# ifdef YMF_DEBUG	printk(PFX "set MPU401 I/O at 0x%x\n",mpu_data[cards].io_base);# endif#endif	switch(opl3_data[cards].io_base) {	case 0x388:		oplio = 0;		break;	case 0x398:		oplio = 1;		break;	case 0x3a0:		oplio = 2;		break;	case 0x3a8:		oplio = 3;		break;	default:		return -1;		break;	}#ifdef YMF_DEBUG	printk(PFX "set OPL3 I/O at 0x%x\n",opl3_data[cards].io_base);

⌨️ 快捷键说明

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