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

📄 main.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 3 页
字号:
 /* ********************************************************************** *     main.c - Creative EMU10K1 audio driver *     Copyright 1999, 2000 Creative Labs, Inc. * ********************************************************************** * *     Date                 Author          Summary of changes *     ----                 ------          ------------------ *     October 20, 1999     Bertrand Lee    base code release *     November 2, 1999     Alan Cox        cleaned up stuff * ********************************************************************** * *     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., 675 Mass Ave, Cambridge, MA 02139, *     USA. * ********************************************************************** * *      Supported devices: *      /dev/dsp:        Standard /dev/dsp device, OSS-compatible *      /dev/dsp1:       Routes to rear speakers only	  *      /dev/mixer:      Standard /dev/mixer device, OSS-compatible *      /dev/midi:       Raw MIDI UART device, mostly OSS-compatible *	/dev/sequencer:  Sequencer Interface (requires sound.o) * *      Revision history: *      0.1 beta Initial release *      0.2 Lowered initial mixer vol. Improved on stuttering wave playback. Added MIDI UART support. *      0.3 Fixed mixer routing bug, added APS, joystick support. *      0.4 Added rear-channel, SPDIF support. *	0.5 Source cleanup, SMP fixes, multiopen support, 64 bit arch fixes, *	    moved bh's to tasklets, moved to the new PCI driver initialization style. *	0.6 Make use of pci_alloc_consistent, improve compatibility layer for 2.2 kernels, *	    code reorganization and cleanup. *	0.7 Support for the Emu-APS. Bug fixes for voice cache setup, mmaped sound + poll(). *          Support for setting external TRAM size. *      0.8 Make use of the kernel ac97 interface. Support for a dsp patch manager. *      0.9 Re-enables rear speakers volume controls *     0.10 Initializes rear speaker volume. *	    Dynamic patch storage allocation. *	    New private ioctls to change control gpr values. *	    Enable volume control interrupts. *	    By default enable dsp routes to digital out.  *     0.11 Fixed fx / 4 problem. *     0.12 Implemented mmaped for recording. *	    Fixed bug: not unreserving mmaped buffer pages. *	    IRQ handler cleanup. *     0.13 Fixed problem with dsp1 *          Simplified dsp patch writing (inside the driver) *	    Fixed several bugs found by the Stanford tools *     0.14 New control gpr to oss mixer mapping feature (Chris Purnell) *          Added AC3 Passthrough Support (Juha Yrjola) *          Added Support for 5.1 cards (digital out and the third analog out) *     0.15 Added Sequencer Support (Daniel Mack) *          Support for multichannel pcm playback (Eduard Hasenleithner) *     0.16 Mixer improvements, added old treble/bass support (Daniel Bertrand) *          Small code format cleanup. *          Deadlock bug fix for emu10k1_volxxx_irqhandler(). *     0.17 Fix for mixer SOUND_MIXER_INFO ioctl. *	    Fix for HIGHMEM machines (emu10k1 can only do 31 bit bus master)  *	    midi poll initial implementation. *	    Small mixer fixes/cleanups. *	    Improved support for 5.1 cards. *     0.18 Fix for possible leak in pci_alloc_consistent() *          Cleaned up poll() functions (audio and midi). Don't start input. *	    Restrict DMA pages used to 512Mib range. *	    New AC97_BOOST mixer ioctl. * *********************************************************************//* These are only included once per module */#include <linux/version.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/proc_fs.h>#include "hwaccess.h"#include "8010.h"#include "efxmgr.h"#include "cardwo.h"#include "cardwi.h"#include "cardmo.h"#include "cardmi.h"#include "recmgr.h"#include "ecard.h"#ifdef EMU10K1_SEQUENCER#define MIDI_SYNTH_NAME "EMU10K1 MIDI"#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT #include "../sound_config.h"#include "../midi_synth.h"/* this should be in dev_table.h */#define SNDCARD_EMU10K1 46#endif #define DRIVER_VERSION "0.18"/* the emu10k1 _seems_ to only supports 29 bit (512MiB) bit bus master */#define EMU10K1_DMA_MASK                0x1fffffff	/* DMA buffer mask for pci_alloc_consist */#ifndef PCI_VENDOR_ID_CREATIVE#define PCI_VENDOR_ID_CREATIVE 0x1102#endif#ifndef PCI_DEVICE_ID_CREATIVE_EMU10K1#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002#endif#define EMU_APS_SUBID	0x40011102 enum {	EMU10K1 = 0,};static char *card_names[] __devinitdata = {	"EMU10K1",};static struct pci_device_id emu10k1_pci_tbl[] = {	{PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_EMU10K1,	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, EMU10K1},	{0,}};MODULE_DEVICE_TABLE(pci, emu10k1_pci_tbl);/* Global var instantiation */LIST_HEAD(emu10k1_devs);extern struct file_operations emu10k1_audio_fops;extern struct file_operations emu10k1_mixer_fops;extern struct file_operations emu10k1_midi_fops;#ifdef EMU10K1_SEQUENCERstatic struct midi_operations emu10k1_midi_operations;#endifextern void emu10k1_interrupt(int, void *, struct pt_regs *s);static int __devinit emu10k1_audio_init(struct emu10k1_card *card){	card->audio_dev = register_sound_dsp(&emu10k1_audio_fops, -1);	if (card->audio_dev < 0) {		printk(KERN_ERR "emu10k1: cannot register first audio device!\n");		goto err_dev;	}	card->audio_dev1 = register_sound_dsp(&emu10k1_audio_fops, -1);	if (card->audio_dev1 < 0) {		printk(KERN_ERR "emu10k1: cannot register second audio device!\n");		goto err_dev1;	}	/* Assign default playback voice parameters */	card->mchannel_fx = 8;	/* mono voice */	card->waveout.send_a[0] = 0xff;	card->waveout.send_b[0] = 0xff;	card->waveout.send_c[0] = 0x00;	card->waveout.send_d[0] = 0x00;	card->waveout.send_routing[0] = 0x3210;	/* stereo voice */	/* left */	card->waveout.send_a[1] = 0xff;	card->waveout.send_b[1] = 0x00;	card->waveout.send_c[1] = 0x00;	card->waveout.send_d[1] = 0x00;	card->waveout.send_routing[1] = 0x3210;	/* right */	card->waveout.send_a[2] = 0x00;	card->waveout.send_b[2] = 0xff;	card->waveout.send_c[2] = 0x00;	card->waveout.send_d[2] = 0x00;	card->waveout.send_routing[2] = 0x3210;	/* Assign default recording parameters */	/* FIXME */	if(card->isaps)		card->wavein.recsrc = WAVERECORD_FX;	else		card->wavein.recsrc = WAVERECORD_AC97;	card->wavein.fxwc = 0x0003;	return 0;err_dev1:	unregister_sound_dsp(card->audio_dev);err_dev:	return -ENODEV;}static void __devinit emu10k1_audio_cleanup(struct emu10k1_card *card){	unregister_sound_dsp(card->audio_dev1);	unregister_sound_dsp(card->audio_dev);}static int __devinit emu10k1_mixer_init(struct emu10k1_card *card){	char s[32];	struct ac97_codec *codec = &card->ac97;	card->ac97.dev_mixer = register_sound_mixer(&emu10k1_mixer_fops, -1);	if (card->ac97.dev_mixer < 0) {		printk(KERN_ERR "emu10k1: cannot register mixer device\n");		return -EIO;        }	card->ac97.private_data = card;	if (!card->isaps) {		card->ac97.id = 0;		card->ac97.codec_read = emu10k1_ac97_read;        	card->ac97.codec_write = emu10k1_ac97_write;		if (ac97_probe_codec (&card->ac97) == 0) {			printk(KERN_ERR "emu10k1: unable to probe AC97 codec\n");			goto err_out;		}		/* 5.1: Enable the additional AC97 Slots and unmute extra channels on AC97 codec */		if (codec->codec_read(codec, AC97_EXTENDED_ID) & 0x0080){			printk(KERN_INFO "emu10k1: SBLive! 5.1 card detected\n"); 			sblive_writeptr(card, AC97SLOT, 0, AC97SLOT_CNTR | AC97SLOT_LFE);			codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0);		}		// Force 5bit:		    		//card->ac97.bit_resolution=5;		if (!proc_mkdir ("driver/emu10k1", 0)) {			printk(KERN_ERR "emu10k1: unable to create proc directory driver/emu10k1\n");			goto err_out;		}		sprintf(s, "driver/emu10k1/%s", card->pci_dev->slot_name);		if (!proc_mkdir (s, 0)) {			printk(KERN_ERR "emu10k1: unable to create proc directory %s\n", s);			goto err_emu10k1_proc;		}			sprintf(s, "driver/emu10k1/%s/ac97", card->pci_dev->slot_name);		if (!create_proc_read_entry (s, 0, 0, ac97_read_proc, &card->ac97)) {			printk(KERN_ERR "emu10k1: unable to create proc entry %s\n", s);			goto err_ac97_proc;		}		/* these will store the original values and never be modified */		card->ac97_supported_mixers = card->ac97.supported_mixers;		card->ac97_stereo_mixers = card->ac97.stereo_mixers;	}	return 0; err_ac97_proc:	sprintf(s, "driver/emu10k1/%s", card->pci_dev->slot_name);	remove_proc_entry(s, NULL); err_emu10k1_proc:	remove_proc_entry("driver/emu10k1", NULL); err_out:	unregister_sound_mixer (card->ac97.dev_mixer);	return -EIO;}static void __devinit emu10k1_mixer_cleanup(struct emu10k1_card *card){	char s[32];	if (!card->isaps) {		sprintf(s, "driver/emu10k1/%s/ac97", card->pci_dev->slot_name);		remove_proc_entry(s, NULL);		sprintf(s, "driver/emu10k1/%s", card->pci_dev->slot_name);		remove_proc_entry(s, NULL);		remove_proc_entry("driver/emu10k1", NULL);	}	unregister_sound_mixer (card->ac97.dev_mixer);}static int __devinit emu10k1_midi_init(struct emu10k1_card *card){	int ret;	card->midi_dev = register_sound_midi(&emu10k1_midi_fops, -1);	if (card->midi_dev < 0) {                printk(KERN_ERR "emu10k1: cannot register midi device!\n");		return -ENODEV;        }	card->mpuout = kmalloc(sizeof(struct emu10k1_mpuout), GFP_KERNEL);	if (card->mpuout == NULL) {		printk(KERN_WARNING "emu10k1: Unable to allocate emu10k1_mpuout: out of memory\n");		ret = -ENOMEM;		goto err_out1;	}	memset(card->mpuout, 0, sizeof(struct emu10k1_mpuout));	card->mpuout->intr = 1;	card->mpuout->status = FLAGS_AVAILABLE;	card->mpuout->state = CARDMIDIOUT_STATE_DEFAULT;	tasklet_init(&card->mpuout->tasklet, emu10k1_mpuout_bh, (unsigned long) card);	spin_lock_init(&card->mpuout->lock);	card->mpuin = kmalloc(sizeof(struct emu10k1_mpuin), GFP_KERNEL);	if (card->mpuin == NULL) {		printk(KERN_WARNING "emu10k1: Unable to allocate emu10k1_mpuin: out of memory\n");		ret = -ENOMEM;                goto err_out2;	}	memset(card->mpuin, 0, sizeof(struct emu10k1_mpuin));	card->mpuin->status = FLAGS_AVAILABLE;	tasklet_init(&card->mpuin->tasklet, emu10k1_mpuin_bh, (unsigned long) card->mpuin);	spin_lock_init(&card->mpuin->lock);	/* Reset the MPU port */	if (emu10k1_mpu_reset(card) < 0) {		ERROR();		ret = -EIO;		goto err_out3;	}#ifdef EMU10K1_SEQUENCER	card->seq_dev = sound_alloc_mididev();	if (card->seq_dev == -1)			printk(KERN_WARNING "emu10k1: unable to register sequencer device!");	else {			std_midi_synth.midi_dev = card->seq_dev;			midi_devs[card->seq_dev] = 					(struct midi_operations *)					kmalloc(sizeof(struct midi_operations), GFP_KERNEL);						if (midi_devs[card->seq_dev] == NULL) {				printk(KERN_ERR "emu10k1: unable to allocate memory!");				sound_unload_mididev(card->seq_dev);				card->seq_dev = -1;				return 0;			} else {				memcpy((char *)midi_devs[card->seq_dev], 					(char *)&emu10k1_midi_operations, 					sizeof(struct midi_operations));				midi_devs[card->seq_dev]->devc = card;				sequencer_init();			}	}	card->seq_mididev = 0;#endif	return 0;err_out3:	kfree(card->mpuin);err_out2:	kfree(card->mpuout);err_out1:	unregister_sound_midi(card->midi_dev);	return ret;}static void __devinit emu10k1_midi_cleanup(struct emu10k1_card *card){	tasklet_kill(&card->mpuout->tasklet);	kfree(card->mpuout);	tasklet_kill(&card->mpuin->tasklet);	kfree(card->mpuin);#ifdef EMU10K1_SEQUENCER	if (card->seq_dev > -1) {		kfree(midi_devs[card->seq_dev]);		midi_devs[card->seq_dev] = NULL;

⌨️ 快捷键说明

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