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

📄 ymfpci_main.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 4 页
字号:
static int snd_ymfpci_joystick_addr_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;        uinfo->count = 1;        uinfo->value.enumerated.items = 4;	if (uinfo->value.enumerated.item >= 4)		uinfo->value.enumerated.item = 3;	sprintf(uinfo->value.enumerated.name, "port 0x%x", ymfpci_joystick_ports[uinfo->value.enumerated.item]);        return 0;}static int snd_ymfpci_joystick_addr_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);	ucontrol->value.integer.value[0] = chip->joystick_port;	return 0;}static int snd_ymfpci_joystick_addr_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);	if (ucontrol->value.integer.value[0] != chip->joystick_port) {		snd_assert(ucontrol->value.integer.value[0] >= 0 && ucontrol->value.integer.value[0] < 4, return -EINVAL);		chip->joystick_port = ucontrol->value.integer.value[0];		setup_joystick_base(chip);		return 1;	}	return 0;}static snd_kcontrol_new_t snd_ymfpci_control_joystick __devinitdata = {	name: "Joystick",	iface: SNDRV_CTL_ELEM_IFACE_CARD,	info: snd_ymfpci_joystick_info,	get: snd_ymfpci_joystick_get,	put: snd_ymfpci_joystick_put,};static snd_kcontrol_new_t snd_ymfpci_control_joystick_addr __devinitdata = {	name: "Joystick Address",	iface: SNDRV_CTL_ELEM_IFACE_CARD,	info: snd_ymfpci_joystick_addr_info,	get: snd_ymfpci_joystick_addr_get,	put: snd_ymfpci_joystick_addr_put,};int __devinit snd_ymfpci_joystick(ymfpci_t *chip){	int err;	chip->joystick_port = 0; /* default */	if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_control_joystick, chip))) < 0)		return err;	if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_control_joystick_addr, chip))) < 0)		return err;	return 0;}/* *  proc interface */static void snd_ymfpci_proc_read(snd_info_entry_t *entry, 				 snd_info_buffer_t * buffer){	// ymfpci_t *chip = snd_magic_cast(ymfpci_t, private_data, return);		snd_iprintf(buffer, "YMFPCI\n\n");}static int __devinit snd_ymfpci_proc_init(snd_card_t * card, ymfpci_t *chip){	snd_info_entry_t *entry;		entry = snd_info_create_card_entry(card, "ymfpci", card->proc_root);	if (entry) {		entry->content = SNDRV_INFO_CONTENT_TEXT;		entry->private_data = chip;		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;		entry->c.text.read_size = 4096;		entry->c.text.read = snd_ymfpci_proc_read;		if (snd_info_register(entry) < 0) {			snd_info_unregister(entry);			entry = NULL;		}	}	chip->proc_entry = entry;	return 0;}static int snd_ymfpci_proc_done(ymfpci_t *chip){	if (chip->proc_entry)		snd_info_unregister((snd_info_entry_t *) chip->proc_entry);	return 0;}/* *  initialization routines */static void snd_ymfpci_aclink_reset(struct pci_dev * pci){	u8 cmd;	pci_read_config_byte(pci, PCIR_DSXG_CTRL, &cmd);#if 0 // force to reset	if (cmd & 0x03) {#endif		pci_write_config_byte(pci, PCIR_DSXG_CTRL, cmd & 0xfc);		pci_write_config_byte(pci, PCIR_DSXG_CTRL, cmd | 0x03);		pci_write_config_byte(pci, PCIR_DSXG_CTRL, cmd & 0xfc);		pci_write_config_word(pci, PCIR_DSXG_PWRCTRL1, 0);		pci_write_config_word(pci, PCIR_DSXG_PWRCTRL2, 0);#if 0	}#endif}static void snd_ymfpci_enable_dsp(ymfpci_t *chip){	snd_ymfpci_writel(chip, YDSXGR_CONFIG, 0x00000001);}static void snd_ymfpci_disable_dsp(ymfpci_t *chip){	u32 val;	int timeout = 1000;	val = snd_ymfpci_readl(chip, YDSXGR_CONFIG);	if (val)		snd_ymfpci_writel(chip, YDSXGR_CONFIG, 0x00000000);	while (timeout-- > 0) {		val = snd_ymfpci_readl(chip, YDSXGR_STATUS);		if ((val & 0x00000002) == 0)			break;	}}#include "ymfpci_image.h"static void snd_ymfpci_download_image(ymfpci_t *chip){	int i;	u16 ctrl;	unsigned long *inst;	snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x00000000);	snd_ymfpci_disable_dsp(chip);	snd_ymfpci_writel(chip, YDSXGR_MODE, 0x00010000);	snd_ymfpci_writel(chip, YDSXGR_MODE, 0x00000000);	snd_ymfpci_writel(chip, YDSXGR_MAPOFREC, 0x00000000);	snd_ymfpci_writel(chip, YDSXGR_MAPOFEFFECT, 0x00000000);	snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, 0x00000000);	snd_ymfpci_writel(chip, YDSXGR_RECCTRLBASE, 0x00000000);	snd_ymfpci_writel(chip, YDSXGR_EFFCTRLBASE, 0x00000000);	ctrl = snd_ymfpci_readw(chip, YDSXGR_GLOBALCTRL);	snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);	/* setup DSP instruction code */	for (i = 0; i < YDSXG_DSPLENGTH / 4; i++)		snd_ymfpci_writel(chip, YDSXGR_DSPINSTRAM + (i << 2), DspInst[i]);	/* setup control instruction code */	switch (chip->device_id) {	case PCI_DEVICE_ID_YAMAHA_724F:	case PCI_DEVICE_ID_YAMAHA_740C:	case PCI_DEVICE_ID_YAMAHA_744:	case PCI_DEVICE_ID_YAMAHA_754:		inst = CntrlInst1E;		break;	default:		inst = CntrlInst;		break;	}	for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++)		snd_ymfpci_writel(chip, YDSXGR_CTRLINSTRAM + (i << 2), inst[i]);	snd_ymfpci_enable_dsp(chip);}static int __devinit snd_ymfpci_memalloc(ymfpci_t *chip){	long size, playback_ctrl_size;	int voice, bank, reg;	u8 *ptr;	dma_addr_t ptr_addr;	playback_ctrl_size = 4 + 4 * YDSXG_PLAYBACK_VOICES;	chip->bank_size_playback = snd_ymfpci_readl(chip, YDSXGR_PLAYCTRLSIZE) << 2;	chip->bank_size_capture = snd_ymfpci_readl(chip, YDSXGR_RECCTRLSIZE) << 2;	chip->bank_size_effect = snd_ymfpci_readl(chip, YDSXGR_EFFCTRLSIZE) << 2;	chip->work_size = YDSXG_DEFAULT_WORK_SIZE;		size = ((playback_ctrl_size + 0x00ff) & ~0x00ff) +	       ((chip->bank_size_playback * 2 * YDSXG_PLAYBACK_VOICES + 0x00ff) & ~0x00ff) +	       ((chip->bank_size_capture * 2 * YDSXG_CAPTURE_VOICES + 0x00ff) & ~0x00ff) +	       ((chip->bank_size_effect * 2 * YDSXG_EFFECT_VOICES + 0x00ff) & ~0x00ff) +	       chip->work_size;	/* work_ptr must be aligned to 256 bytes, but it's already	   covered with the kernel page allocation mechanism */	if ((ptr = snd_malloc_pci_pages(chip->pci, size, &ptr_addr)) == NULL)		return -ENOMEM;	memset(ptr, 0, size);	/* for sure */	chip->work_ptr = ptr;	chip->work_ptr_addr = ptr_addr;	chip->work_ptr_size = size;	chip->bank_base_playback = ptr;	chip->bank_base_playback_addr = ptr_addr;	chip->ctrl_playback = (u32 *)ptr;	chip->ctrl_playback[0] = cpu_to_le32(YDSXG_PLAYBACK_VOICES);	ptr += (playback_ctrl_size + 0x00ff) & ~0x00ff;	ptr_addr += (playback_ctrl_size + 0x00ff) & ~0x00ff;	for (voice = 0; voice < YDSXG_PLAYBACK_VOICES; voice++) {		chip->voices[voice].number = voice;		chip->voices[voice].bank = (snd_ymfpci_playback_bank_t *)ptr;		chip->voices[voice].bank_addr = ptr_addr;		for (bank = 0; bank < 2; bank++) {			chip->bank_playback[voice][bank] = (snd_ymfpci_playback_bank_t *)ptr;			ptr += chip->bank_size_playback;			ptr_addr += chip->bank_size_playback;		}	}	ptr = (char *)(((unsigned long)ptr + 0x00ff) & ~0x00ff);	ptr_addr = (ptr_addr + 0x00ff) & ~0x00ff;	chip->bank_base_capture = ptr;	chip->bank_base_capture_addr = ptr_addr;	for (voice = 0; voice < YDSXG_CAPTURE_VOICES; voice++)		for (bank = 0; bank < 2; bank++) {			chip->bank_capture[voice][bank] = (snd_ymfpci_capture_bank_t *)ptr;			ptr += chip->bank_size_capture;			ptr_addr += chip->bank_size_capture;		}	ptr = (char *)(((unsigned long)ptr + 0x00ff) & ~0x00ff);	ptr_addr = (ptr_addr + 0x00ff) & ~0x00ff;	chip->bank_base_effect = ptr;	chip->bank_base_effect_addr = ptr_addr;	for (voice = 0; voice < YDSXG_EFFECT_VOICES; voice++)		for (bank = 0; bank < 2; bank++) {			chip->bank_effect[voice][bank] = (snd_ymfpci_effect_bank_t *)ptr;			ptr += chip->bank_size_effect;			ptr_addr += chip->bank_size_effect;		}	ptr = (char *)(((unsigned long)ptr + 0x00ff) & ~0x00ff);	ptr_addr = (ptr_addr + 0x00ff) & ~0x00ff;	chip->work_base = ptr;	chip->work_base_addr = ptr_addr;		snd_assert(ptr + chip->work_size == chip->work_ptr + chip->work_ptr_size, );	snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, chip->bank_base_playback_addr);	snd_ymfpci_writel(chip, YDSXGR_RECCTRLBASE, chip->bank_base_capture_addr);	snd_ymfpci_writel(chip, YDSXGR_EFFCTRLBASE, chip->bank_base_effect_addr);	snd_ymfpci_writel(chip, YDSXGR_WORKBASE, chip->work_base_addr);	snd_ymfpci_writel(chip, YDSXGR_WORKSIZE, chip->work_size >> 2);	/* S/PDIF output initialization */	chip->spdif_bits = chip->spdif_pcm_bits = SNDRV_PCM_DEFAULT_CON_SPDIF & 0xffff;	snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTCTRL, 0);	snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_bits);	/* S/PDIF input initialization */	snd_ymfpci_writew(chip, YDSXGR_SPDIFINCTRL, 0);	/* digital mixer setup */	for (reg = 0x80; reg < 0xc0; reg += 4)		snd_ymfpci_writel(chip, reg, 0);	snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x3fff3fff);	snd_ymfpci_writel(chip, YDSXGR_ZVOUTVOL, 0x3fff3fff);	snd_ymfpci_writel(chip, YDSXGR_SPDIFOUTVOL, 0x3fff3fff);	snd_ymfpci_writel(chip, YDSXGR_NATIVEADCINVOL, 0x3fff3fff);	snd_ymfpci_writel(chip, YDSXGR_NATIVEDACINVOL, 0x3fff3fff);	snd_ymfpci_writel(chip, YDSXGR_PRIADCLOOPVOL, 0x3fff3fff);		return 0;}static int snd_ymfpci_free(ymfpci_t *chip){	u16 ctrl;	snd_assert(chip != NULL, return -EINVAL);	snd_ymfpci_proc_done(chip);	if (chip->res_reg_area) {	/* don't touch busy hardware */		snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);		snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);		snd_ymfpci_writel(chip, YDSXGR_STATUS, ~0);		snd_ymfpci_disable_dsp(chip);		snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, 0);		snd_ymfpci_writel(chip, YDSXGR_RECCTRLBASE, 0);		snd_ymfpci_writel(chip, YDSXGR_EFFCTRLBASE, 0);		snd_ymfpci_writel(chip, YDSXGR_WORKBASE, 0);		snd_ymfpci_writel(chip, YDSXGR_WORKSIZE, 0);		ctrl = snd_ymfpci_readw(chip, YDSXGR_GLOBALCTRL);		snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);	}	/* Set PCI device to D3 state */	// pci_set_power_state(chip->pci, 3);#ifdef CONFIG_PM	if (chip->saved_regs)		kfree(chip->saved_regs);#endif	if (chip->reg_area_virt)		iounmap((void *)chip->reg_area_virt);	if (chip->work_ptr)		snd_free_pci_pages(chip->pci, chip->work_ptr_size, chip->work_ptr, chip->work_ptr_addr);		if (chip->irq >= 0)		free_irq(chip->irq, (void *)chip);	if (chip->res_reg_area) {		release_resource(chip->res_reg_area);		kfree_nocheck(chip->res_reg_area);	}	pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl);		snd_magic_kfree(chip);	return 0;}static int snd_ymfpci_dev_free(snd_device_t *device){	ymfpci_t *chip = snd_magic_cast(ymfpci_t, device->device_data, return -ENXIO);	return snd_ymfpci_free(chip);}#ifdef CONFIG_PMstatic int saved_regs_index[] = {	/* spdif */	YDSXGR_SPDIFOUTCTRL,	YDSXGR_SPDIFOUTSTATUS,	YDSXGR_SPDIFINCTRL,	/* volumes */	YDSXGR_PRIADCLOOPVOL,	YDSXGR_NATIVEDACINVOL,	YDSXGR_NATIVEDACOUTVOL,	// YDSXGR_BUF441OUTVOL,	YDSXGR_NATIVEADCINVOL,	YDSXGR_SPDIFLOOPVOL,	YDSXGR_SPDIFOUTVOL,	YDSXGR_ZVOUTVOL,	/* address bases */	YDSXGR_PLAYCTRLBASE,	YDSXGR_RECCTRLBASE,	YDSXGR_EFFCTRLBASE,	YDSXGR_WORKBASE,	/* capture set up */	YDSXGR_MAPOFREC,	YDSXGR_RECFORMAT,	YDSXGR_RECSLOTSR,	YDSXGR_ADCFORMAT,	YDSXGR_ADCSLOTSR,};#define YDSXGR_NUM_SAVED_REGS	(sizeof(saved_regs_index)/sizeof(saved_regs_index[0]))void snd_ymfpci_suspend(ymfpci_t *chip){	snd_card_t *card = chip->card;	int i;		snd_power_lock(card);	if (card->power_state == SNDRV_CTL_POWER_D3hot)		goto __skip;	snd_pcm_suspend_all(chip->pcm);	snd_pcm_suspend_all(chip->pcm2);	snd_pcm_suspend_all(chip->pcm_spdif);	snd_pcm_suspend_all(chip->pcm_4ch);	for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++)		chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]);	chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE);	snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);	snd_ymfpci_disable_dsp(chip);	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);      __skip:      	snd_power_unlock(card);}void snd_ymfpci_resume(ymfpci_t *chip){	snd_card_t *card = chip->card;	int i;	snd_power_lock(card);	if (card->power_state == SNDRV_CTL_POWER_D0)		goto __skip;	pci_enable_device(chip->pci);	pci_set_master(chip->pci);	snd_ymfpci_aclink_reset(chip->pci);	snd_ymfpci_codec_ready(chip, 0, 0);	snd_ymfpci_download_image(chip);	udelay(100);	for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++)		snd_ymfpci_writel(chip, saved_regs_index[i], chip->saved_regs[i]);	snd_ac97_resume(chip->ac97);	/* start hw again */	if (chip->start_count > 0) {		spin_lock(&chip->reg_lock);		snd_ymfpci_writel(chip, YDSXGR_MODE, chip->saved_ydsxgr_mode);		chip->active_bank = snd_ymfpci_readl(chip, YDSXGR_CTRLSELECT);		spin_unlock(&chip->reg_lock);	}	snd_power_change_state(card, SNDRV_CTL_POWER_D0);      __skip:      	snd_power_unlock(card);}static int snd_ymfpci_set_power_state(snd_card_t *card, unsigned int power_state){	ymfpci_t *chip = snd_magic_cast(ymfpci_t, card->power_state_private_data, return -ENXIO);	switch (power_state) {	case SNDRV_CTL_POWER_D0:	case SNDRV_CTL_POWER_D1:	case SNDRV_CTL_POWER_D2:		snd_ymfpci_resume(chip);		break;	case SNDRV_CTL_POWER_D3hot:	case SNDRV_CTL_POWER_D3cold:		snd_ymfpci_suspend(chip);		break;	default:		return -EINVAL;	}	return 0;}#endif /* CONFIG_PM */int __devinit snd_ymfpci_create(snd_card_t * card,				struct pci_dev * pci,				unsigned short old_legacy_ctrl,				ymfpci_t ** rchip){	ymfpci_t *chip;	int err;	static snd_device_ops_t ops = {		dev_free:	snd_ymfpci_dev_free,	};		*rchip = NULL;	/* enable PCI device */	if ((err = pci_enable_device(pci)) < 0)		return err;	chip = snd_magic_kcalloc(ymfpci_t, 0, GFP_KERNEL);	if (chip == NULL)		return -ENOMEM;	chip->old_legacy_ctrl = old_legacy_ctrl;	spin_lock_init(&chip->reg_lock);	spin_lock_init(&chip->voice_lock);	init_waitqueue_head(&chip->interrupt_sleep);	atomic_set(&chip->interrupt_sleep_count, 0);	chip->card = card;	chip->pci = pci;	chip->irq = -1;	chip->device_id = pci->device;	pci_read_config_byte(pci, PCI_REVISION_ID, (u8 *)&chip->rev);	chip->reg_area_phys = pci_resource_start(pci, 0);	chip->reg_area_virt = (unsigned long)ioremap_nocache(chip->reg_area_phys, 0x8000);	pci_set_master(pci);	if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) {		snd_ymfpci_free(chip);		snd_printk("unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1);		return -EBUSY;	}	if (request_irq(pci->irq, snd_ymfpci_interrupt, SA_INTERRUPT|SA_SHIRQ, "YMFPCI", (void *) chip)) {		snd_ymfpci_free(chip);		snd_printk("unable to grab IRQ %d\n", pci->irq);		return -EBUSY;	}	chip->irq = pci->irq;	snd_ymfpci_aclink_reset(pci);	if (snd_ymfpci_codec_ready(chip, 0, 1) < 0) {		snd_ymfpci_free(chip);		return -EIO;	}	snd_ymfpci_download_image(chip);	udelay(100); /* seems we need a delay after downloading image.. */	if (snd_ymfpci_memalloc(chip) < 0) {		snd_ymfpci_free(chip);		return -EIO;	}#ifdef CONFIG_PM	chip->saved_regs = kmalloc(YDSXGR_NUM_SAVED_REGS * sizeof(u32), GFP_KERNEL);	if (chip->saved_regs == NULL) {		snd_ymfpci_free(chip);		return -ENOMEM;	}	card->set_power_state = snd_ymfpci_set_power_state;	card->power_state_private_data = chip;#endif	snd_ymfpci_proc_init(card, chip);	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {		snd_ymfpci_free(chip);		return err;	}	*rchip = chip;	return 0;}

⌨️ 快捷键说明

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