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

📄 ali5451.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 4 页
字号:
}#define ALI5451_SPDIF(xname, xindex, value) \{ iface: SNDRV_CTL_ELEM_IFACE_MIXER, name: xname, index: xindex,\info: snd_ali5451_spdif_info, get: snd_ali5451_spdif_get, \put: snd_ali5451_spdif_put, private_value: value}static int snd_ali5451_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){        uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;        uinfo->count = 1;        uinfo->value.integer.min = 0;        uinfo->value.integer.max = 1;        return 0;}static int snd_ali5451_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	unsigned long flags;	ali_t *codec = snd_magic_cast(ali_t, kcontrol->private_data, -ENXIO);	unsigned int enable;	enable = ucontrol->value.integer.value[0] ? 1 : 0;	spin_lock_irqsave(&codec->reg_lock, flags);	switch(kcontrol->private_value) {	case 0:		enable = (codec->spdif_mask & 0x02) ? 1 : 0;		break;	case 1:		enable = ((codec->spdif_mask & 0x02) && (codec->spdif_mask & 0x04)) ? 1 : 0;		break;	case 2:		enable = (codec->spdif_mask & 0x01) ? 1 : 0;		break;	default:		break;	}	ucontrol->value.integer.value[0] = enable;	spin_unlock_irqrestore(&codec->reg_lock, flags);	return 0;}static int snd_ali5451_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	unsigned long flags;	ali_t *codec = snd_magic_cast(ali_t, kcontrol->private_data, -ENXIO);	unsigned int change = 0, enable = 0;	enable = ucontrol->value.integer.value[0] ? 1 : 0;	spin_lock_irqsave(&codec->reg_lock, flags);	switch (kcontrol->private_value) {	case 0:		change = (codec->spdif_mask & 0x02) ? 1 : 0;		change = change ^ enable;		if (change) {			if (enable) {				codec->spdif_mask |= 0x02;				snd_ali_enable_spdif_out(codec);			} else {				codec->spdif_mask &= ~(0x02);				codec->spdif_mask &= ~(0x04);				snd_ali_disable_spdif_out(codec);			}		}		break;	case 1: 		change = (codec->spdif_mask & 0x04) ? 1 : 0;		change = change ^ enable;		if (change && (codec->spdif_mask & 0x02)) {			if (enable) {				codec->spdif_mask |= 0x04;				snd_ali_enable_spdif_chnout(codec);			} else {				codec->spdif_mask &= ~(0x04);				snd_ali_disable_spdif_chnout(codec);			}		}		break;	case 2:		change = (codec->spdif_mask & 0x01) ? 1 : 0;		change = change ^ enable;		if (change) {			if (enable) {				codec->spdif_mask |= 0x01;				snd_ali_enable_spdif_in(codec);			} else {				codec->spdif_mask &= ~(0x01);				snd_ali_disable_spdif_in(codec);			}		}		break;	default:		break;	}	spin_unlock_irqrestore(&codec->reg_lock, flags);		return change;}static snd_kcontrol_new_t snd_ali5451_mixer_spdif[] __devinit = {	/* spdif aplayback switch */	ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, 0),	/* spdif out to spdif channel */	ALI5451_SPDIF("IEC958 Channel Output Switch", 0, 1),	/* spdif in from spdif channel */	ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2)};static void snd_ali_mixer_free_ac97(ac97_t *ac97){	ali_t *codec = snd_magic_cast(ali_t, ac97->private_data, return);	codec->ac97 = NULL;}static int __devinit snd_ali_mixer(ali_t * codec){	ac97_t ac97;	int err, idx;	memset(&ac97, 0, sizeof(ac97));	ac97.write = snd_ali_codec_write;	ac97.read = snd_ali_codec_read;	ac97.private_data = codec;	ac97.private_free = snd_ali_mixer_free_ac97;	if ((err = snd_ac97_mixer(codec->card, &ac97, &codec->ac97)) < 0) {		snd_printk("ali mixer creating error.\n");		return err;	}	if (codec->revision == ALI_5451_V02) {		for(idx = 0; idx < 3; idx++) {			err=snd_ctl_add(codec->card, snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec));			if (err < 0) return err;		}	}	return 0;}#ifdef CONFIG_PM#ifndef PCI_OLD_SUSPENDstatic int snd_ali_suspend(struct pci_dev *dev, u32 state)#elsestatic void snd_ali_suspend(struct pci_dev *dev)#endif{#ifndef PCI_OLD_SUSPEND	ali_t *chip = snd_magic_cast(ali_t, pci_get_drvdata(dev), return -ENXIO);#else	ali_t *chip = snd_magic_cast(ali_t, pci_get_drvdata(dev), return);#endif	ali_image_t *im;	unsigned long flags;	int i, j;	im = chip->image;	if (! im)#ifndef PCI_OLD_SUSPEND		return -ENXIO;#else		return;#endif	save_flags(flags); 	cli();		im->regs[ALI_MISCINT >> 2] = inl(ALI_REG(chip, ALI_MISCINT));	// im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START));	im->regs[ALI_STOP >> 2] = inl(ALI_REG(chip, ALI_STOP));		// disable all IRQ bits	outl(0, ALI_REG(chip, ALI_MISCINT));		for (i = 0; i < ALI_GLOBAL_REGS; i++) {			if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP))			continue;		im->regs[i] = inl(ALI_REG(chip, i*4));	}		for (i = 0; i < ALI_CHANNELS; i++) {		outb(i, ALI_REG(chip, ALI_GC_CIR));		for (j = 0; j < ALI_CHANNEL_REGS; j++) 			im->channel_regs[i][j] = inl(ALI_REG(chip, j*4 + 0xe0));	}	// stop all HW channel	outl(0xffffffff, ALI_REG(chip, ALI_STOP));	restore_flags(flags);#ifndef PCI_OLD_SUSPEND	return 0;#endif}#ifndef PCI_OLD_SUSPENDstatic int snd_ali_resume(struct pci_dev *dev)#elsestatic void snd_ali_resume(struct pci_dev *dev)#endif{#ifndef PCI_OLD_SUSPEND	ali_t *chip = snd_magic_cast(ali_t, pci_get_drvdata(dev), return -ENXIO);#else	ali_t *chip = snd_magic_cast(ali_t, pci_get_drvdata(dev), return);#endif	ali_image_t *im;	unsigned long flags;	int i, j;	im = chip->image;	if (! im)#ifndef PCI_OLD_SUSPEND		return -ENXIO;#else		return;#endif	pci_enable_device(chip->pci);	save_flags(flags); 	cli();		for (i = 0; i < ALI_CHANNELS; i++) {		outb(i, ALI_REG(chip, ALI_GC_CIR));		for (j = 0; j < ALI_CHANNEL_REGS; j++) 			outl(im->channel_regs[i][j], ALI_REG(chip, j*4 + 0xe0));	}		for (i = 0; i < ALI_GLOBAL_REGS; i++) {			if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || (i*4 == ALI_START))			continue;		outl(im->regs[i], ALI_REG(chip, i*4));	}		snd_ac97_resume(chip->ac97);		// start HW channel	outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START));	// restore IRQ enable bits	outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT));		restore_flags(flags);#ifndef PCI_OLD_SUSPEND	return 0;#endif}#endifstatic int snd_ali_free(ali_t * codec){	snd_ali_disable_address_interrupt(codec);	synchronize_irq();	if (codec->irq >=0)		free_irq(codec->irq, (void *)codec);	if (codec->res_port) {		release_resource(codec->res_port);		kfree_nocheck(codec->res_port);	}#ifdef CONFIG_PM	if (codec->image)		kfree(codec->image);#endif	snd_magic_kfree(codec);	return 0;}static int snd_ali_chip_init(ali_t *codec){	unsigned int legacy;	unsigned char temp;	struct pci_dev *pci_dev = NULL;	snd_ali_printk("chip initializing ... \n");	if (snd_ali_reset_5451(codec)) {		snd_printk("ali_chip_init: reset 5451 error.\n");		return -1;	}	if (codec->revision == ALI_5451_V02) {        	pci_dev = codec->pci_m1533;        	if (pci_dev == NULL)                	return -1;		pci_read_config_byte(pci_dev, 0x59, &temp);			pci_dev = pci_find_device(0x10b9,0x7101, pci_dev);		if (pci_dev == NULL)                	return -1;		pci_read_config_byte(pci_dev,0xb8,&temp);		temp |= 1 << 6;		pci_write_config_byte(pci_dev, 0xB8, temp);	}	pci_read_config_dword(codec->pci, 0x44, &legacy);	legacy &= 0xff00ff00;	legacy |= 0x000800aa;	pci_write_config_dword(codec->pci, 0x44, legacy);	outl(0x80000001, ALI_REG(codec, ALI_GLOBAL_CONTROL));	outl(0x00000000, ALI_REG(codec, ALI_AINTEN));	outl(0xffffffff, ALI_REG(codec, ALI_AINT));	outl(0x00000000, ALI_REG(codec, ALI_VOLUME));	outb(0x10, 	 ALI_REG(codec, ALI_MPUR2));	codec->ac97_ext_id = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_ID);	codec->ac97_ext_status = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_STATUS);	if (codec->revision == ALI_5451_V02) {		snd_ali_enable_spdif_out(codec);		codec->spdif_mask = 0x00000002;	}	snd_ali_printk("chip initialize succeed.\n");	return 0;}static int __devinit snd_ali_resources(ali_t *codec){	snd_ali_printk("resouces allocation ...\n");	if ((codec->res_port = request_region(codec->port, 0x100, "ALI 5451")) == NULL) {		snd_ali_free(codec);		snd_printk("Unalbe to request io ports.\n");		return -EBUSY;	}	if (request_irq(codec->pci->irq, snd_ali_card_interrupt, SA_INTERRUPT|SA_SHIRQ, "ALI 5451", (void *)codec)) {		snd_ali_free(codec);		snd_printk("Unable to request irq.\n");		return -EBUSY;	}	codec->irq = codec->pci->irq;	snd_ali_printk("resouces allocated.\n");	return 0;}static int snd_ali_dev_free(snd_device_t *device) {	ali_t *codec=snd_magic_cast(ali_t, device->device_data, return -ENXIO);	snd_ali_free(codec);	return 0;}static int __devinit snd_ali_create(snd_card_t * card,				 struct pci_dev *pci,				 int pcm_streams,				 ali_t ** r_ali){	ali_t *codec;	int i, err;	unsigned short cmdw = 0;	struct pci_dev *pci_dev = NULL;        static snd_device_ops_t ops = {		(snd_dev_free_t *)snd_ali_dev_free,		NULL,		NULL        };	*r_ali = NULL;	snd_ali_printk("creating ...\n");	/* enable PCI device */	if ((err = pci_enable_device(pci)) < 0)		return err;	/* check, if we can restrict PCI DMA transfers to 30 bits */	if (!pci_dma_supported(pci, 0x3fffffff)) {		snd_printk("architecture does not support 30bit PCI busmaster DMA\n");		return -ENXIO;	}	pci_set_dma_mask(pci, 0x3fffffff);	if ((codec = snd_magic_kcalloc(ali_t, 0, GFP_KERNEL)) == NULL)		return -ENOMEM;	spin_lock_init(&codec->reg_lock);	spin_lock_init(&codec->voice_alloc);	codec->card = card;	codec->pci = pci;	codec->irq = -1;	codec->port = pci_resource_start(pci, 0);	pci_read_config_byte(pci, PCI_REVISION_ID, &codec->revision);	if (pcm_streams < 1)		pcm_streams = 1;	if (pcm_streams > 32)		pcm_streams = 32;		pci_set_master(pci);	pci_read_config_word(pci, PCI_COMMAND, &cmdw);	if ((cmdw & PCI_COMMAND_IO) != PCI_COMMAND_IO) {		cmdw |= PCI_COMMAND_IO;		pci_write_config_word(pci, PCI_COMMAND, cmdw);	}	pci_set_master(pci);		if (snd_ali_resources(codec)) {		return -EBUSY;	}	synchronize_irq();	codec->synth.chmap = 0;	codec->synth.chcnt = 0;	codec->spdif_mask = 0;	codec->synth.synthcount = 0;	if (codec->revision == ALI_5451_V02)		codec->chregs.regs.ac97read = ALI_AC97_WRITE;	else		codec->chregs.regs.ac97read = ALI_AC97_READ;	codec->chregs.regs.ac97write = ALI_AC97_WRITE;	codec->chregs.regs.start  = ALI_START;	codec->chregs.regs.stop   = ALI_STOP;	codec->chregs.regs.aint   = ALI_AINT;	codec->chregs.regs.ainten = ALI_AINTEN;	codec->chregs.data.start  = 0x00;	codec->chregs.data.stop   = 0x00;	codec->chregs.data.aint   = 0x00;	codec->chregs.data.ainten = 0x00;       	pci_dev = pci_find_device(0x10b9,0x1533, pci_dev);	codec->pci_m1533 = pci_dev;       	pci_dev = pci_find_device(0x10b9,0x7101, pci_dev);	codec->pci_m7101 = pci_dev;	snd_ali_printk("snd_device_new is called.\n");	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops)) < 0) {		snd_ali_free(codec);		return err;	}	/* initialise synth voices*/	for (i = 0; i < ALI_CHANNELS; i++ ) {		codec->synth.voices[i].number = i;	}	if ((err = snd_ali_chip_init(codec)) < 0) {		snd_printk("ali create: chip init error.\n");		snd_ali_free(codec);		return err;	}#ifdef CONFIG_PM	codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL);	if (! codec->image)		snd_printk("can't allocate apm buffer\n");#endif	snd_ali_enable_address_interrupt(codec);	*r_ali = codec;	snd_ali_printk("created.\n");	return 0;}static int __devinit snd_ali_probe(struct pci_dev *pci,				   const struct pci_device_id *id){	static int dev;	snd_card_t *card;	ali_t *codec;	int err;	snd_ali_printk("probe ...\n");        if (dev >= SNDRV_CARDS)                return -ENODEV;	if (!snd_enable[dev]) {		dev++;		return -ENOENT;	}	card = snd_card_new(snd_index[dev], snd_id[dev], THIS_MODULE, 0);	if (card == NULL)		return -ENOMEM;	if ((err = snd_ali_create(card, pci, snd_pcm_channels[dev], &codec)) < 0) {		snd_card_free(card);		return err;	}	snd_ali_printk("mixer building ...\n");	if ((err = snd_ali_mixer(codec)) < 0) {		snd_card_free(card);		return err;	}		snd_ali_printk("pcm building ...\n");	if ((err = snd_ali_pcm(codec, 0, NULL)) < 0) {		snd_card_free(card);		return err;	}	strcpy(card->driver, "ALI5451");	strcpy(card->shortname, "ALI 5451");		sprintf(card->longname, "%s at 0x%lx, irq %li",		card->shortname, codec->port, codec->irq);	snd_ali_printk("register card.\n");	if ((err = snd_card_register(card)) < 0) {		snd_card_free(card);		return err;	}	pci_set_drvdata(pci, codec);	dev++;	return 0;}static void __devexit snd_ali_remove(struct pci_dev *pci){	ali_t *chip = snd_magic_cast(ali_t, pci_get_drvdata(pci), return);	if (chip)		snd_card_free(chip->card);	pci_set_drvdata(pci, NULL);}static struct pci_driver driver = {	name: "ALI 5451",	id_table: snd_ali_ids,	probe: snd_ali_probe,	remove: __devexit_p(snd_ali_remove),#ifdef CONFIG_PM	suspend: snd_ali_suspend,	resume: snd_ali_resume,#endif};                                static int __init alsa_card_ali_init(void){	int err;	if ((err = pci_module_init(&driver)) < 0) {#ifdef MODULE		printk(KERN_ERR "ALi pci audio not found or device busy.\n");#endif		return err;	}	return 0;}static void __exit alsa_card_ali_exit(void){	pci_unregister_driver(&driver);}module_init(alsa_card_ali_init)module_exit(alsa_card_ali_exit)#ifndef MODULE/* format is: snd-ali5451=snd_enable,snd_index,snd_id,snd_pcm_channels */static int __init alsa_card_ali_setup(char *str){	static unsigned __initdata nr_dev = 0;	if (nr_dev >= SNDRV_CARDS)		return 0;	(void)(get_option(&str,&snd_enable[nr_dev]) == 2 &&	       get_option(&str,&snd_index[nr_dev]) == 2 &&	       get_id(&str,&snd_id[nr_dev]) == 2 &&	       get_option(&str,&snd_pcm_channels[nr_dev]) == 2);	nr_dev++;	return 1;}__setup("snd-ali5451=", alsa_card_ali_setup);#endif /* ifndef */

⌨️ 快捷键说明

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