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

📄 azt3328.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	snd_azf3328_dbgcallenter();	*num = 1;	*den = 1024000 / seqtimer_scaling;	snd_azf3328_dbgcallleave();	return 0;}static struct snd_timer_hardware snd_azf3328_timer_hw = {	.flags = SNDRV_TIMER_HW_AUTO,	.resolution = 977, /* 1000000/1024000 = 0.9765625us */	.ticks = 1024000, /* max tick count, defined by the value register; actually it's not 1024000, but 1048576, but we don't care */	.start = snd_azf3328_timer_start,	.stop = snd_azf3328_timer_stop,	.precise_resolution = snd_azf3328_timer_precise_resolution,};static int __devinitsnd_azf3328_timer(struct snd_azf3328 *chip, int device){	struct snd_timer *timer = NULL;	struct snd_timer_id tid;	int err;	snd_azf3328_dbgcallenter();	tid.dev_class = SNDRV_TIMER_CLASS_CARD;	tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;	tid.card = chip->card->number;	tid.device = device;	tid.subdevice = 0;	snd_azf3328_timer_hw.resolution *= seqtimer_scaling;	snd_azf3328_timer_hw.ticks /= seqtimer_scaling;	if ((err = snd_timer_new(chip->card, "AZF3328", &tid, &timer)) < 0) {		goto out;	}	strcpy(timer->name, "AZF3328 timer");	timer->private_data = chip;	timer->hw = snd_azf3328_timer_hw;	chip->timer = timer;	err = 0;out:	snd_azf3328_dbgcallleave();	return err;}/******************************************************************/#if 0/* check whether a bit can be modified */static voidsnd_azf3328_test_bit(unsigned int reg, int bit){	unsigned char val, valoff, valon;	val = inb(reg);	outb(val & ~(1 << bit), reg);	valoff = inb(reg);	outb(val|(1 << bit), reg);	valon = inb(reg);		outb(val, reg);	printk(KERN_ERR "reg %04x bit %d: %02x %02x %02x\n", reg, bit, val, valoff, valon);}#endif#if DEBUG_MISCstatic voidsnd_azf3328_debug_show_ports(const struct snd_azf3328 *chip){	u16 tmp;	snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq);	snd_azf3328_dbgmisc("io2 %02x %02x %02x %02x %02x %02x\n", snd_azf3328_io2_inb(chip, 0), snd_azf3328_io2_inb(chip, 1), snd_azf3328_io2_inb(chip, 2), snd_azf3328_io2_inb(chip, 3), snd_azf3328_io2_inb(chip, 4), snd_azf3328_io2_inb(chip, 5));	for (tmp=0; tmp <= 0x01; tmp += 1)		snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp));	for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2)		snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inw(chip, tmp));	for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2)		snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n", tmp, snd_azf3328_mixer_inw(chip, tmp));}#elsestatic inline voidsnd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) {}#endifstatic int __devinitsnd_azf3328_create(struct snd_card *card,                                         struct pci_dev *pci,                                         unsigned long device_type,                                         struct snd_azf3328 ** rchip){	struct snd_azf3328 *chip;	int err;	static struct snd_device_ops ops = {		.dev_free =     snd_azf3328_dev_free,	};	u16 tmp;	*rchip = NULL;	if ((err = pci_enable_device(pci)) < 0)		return err;	chip = kzalloc(sizeof(*chip), GFP_KERNEL);	if (chip == NULL) {		err = -ENOMEM;		goto out_err;	}	spin_lock_init(&chip->reg_lock);	chip->card = card;	chip->pci = pci;	chip->irq = -1;	/* check if we can restrict PCI DMA transfers to 24 bits */	if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 ||	    pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) {		snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");		err = -ENXIO;		goto out_err;	}	if ((err = pci_request_regions(pci, "Aztech AZF3328")) < 0) {		goto out_err;	}	chip->codec_port = pci_resource_start(pci, 0);	chip->io2_port   = pci_resource_start(pci, 1);	chip->mpu_port   = pci_resource_start(pci, 2);	chip->synth_port = pci_resource_start(pci, 3);	chip->mixer_port = pci_resource_start(pci, 4);	if (request_irq(pci->irq, snd_azf3328_interrupt,			IRQF_SHARED, card->shortname, chip)) {		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);		err = -EBUSY;		goto out_err;	}	chip->irq = pci->irq;	pci_set_master(pci);	synchronize_irq(chip->irq);	snd_azf3328_debug_show_ports(chip);		if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {		goto out_err;	}	/* create mixer interface & switches */	if ((err = snd_azf3328_mixer_new(chip)) < 0)		goto out_err;#if 0	/* set very low bitrate to reduce noise and power consumption? */	snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, 5512, 8, 1);#endif	/* standard chip init stuff */	/* default IRQ init value */	tmp = DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE;	spin_lock_irq(&chip->reg_lock);	snd_azf3328_codec_outb(chip, IDX_IO_PLAY_FLAGS, tmp);	snd_azf3328_codec_outb(chip, IDX_IO_REC_FLAGS, tmp);	snd_azf3328_codec_outb(chip, IDX_IO_SOMETHING_FLAGS, tmp);	snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00); /* disable timer */	spin_unlock_irq(&chip->reg_lock);	snd_card_set_dev(card, &pci->dev);	*rchip = chip;	err = 0;	goto out;out_err:	if (chip)		snd_azf3328_free(chip);	pci_disable_device(pci);out:	return err;}static int __devinitsnd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id){	static int dev;	struct snd_card *card;	struct snd_azf3328 *chip;	struct snd_opl3 *opl3;	int err;	snd_azf3328_dbgcallenter();	if (dev >= SNDRV_CARDS)		return -ENODEV;	if (!enable[dev]) {		dev++;		return -ENOENT;	}	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0 );	if (card == NULL)		return -ENOMEM;	strcpy(card->driver, "AZF3328");	strcpy(card->shortname, "Aztech AZF3328 (PCI168)");        if ((err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip)) < 0) {		goto out_err;	}	card->private_data = chip;	if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401,				        chip->mpu_port, MPU401_INFO_INTEGRATED,					pci->irq, 0, &chip->rmidi)) < 0) {		snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port);		goto out_err;	}	if ((err = snd_azf3328_timer(chip, 0)) < 0) {		goto out_err;	}	if ((err = snd_azf3328_pcm(chip, 0)) < 0) {		goto out_err;	}	if (snd_opl3_create(card, chip->synth_port, chip->synth_port+2,			    OPL3_HW_AUTO, 1, &opl3) < 0) {		snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n",			   chip->synth_port, chip->synth_port+2 );	} else {		if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {			goto out_err;		}	}	opl3->private_data = chip;	sprintf(card->longname, "%s at 0x%lx, irq %i",		card->shortname, chip->codec_port, chip->irq);	if ((err = snd_card_register(card)) < 0) {		goto out_err;	}#ifdef MODULE	printk("azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n""azt3328: Hardware was completely undocumented, unfortunately.\n""azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n""azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",	1024000 / seqtimer_scaling, seqtimer_scaling);#endif	if (snd_azf3328_config_joystick(chip, dev) < 0)		snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,			      snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);	pci_set_drvdata(pci, card);	dev++;	err = 0;	goto out;	out_err:	snd_card_free(card);	out:	snd_azf3328_dbgcallleave();	return err;}static void __devexitsnd_azf3328_remove(struct pci_dev *pci){	snd_azf3328_dbgcallenter();	snd_card_free(pci_get_drvdata(pci));	pci_set_drvdata(pci, NULL);	snd_azf3328_dbgcallleave();}#ifdef CONFIG_PMstatic intsnd_azf3328_suspend(struct pci_dev *pci, pm_message_t state){	struct snd_card *card = pci_get_drvdata(pci);	struct snd_azf3328 *chip = card->private_data;	int reg;	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);		snd_pcm_suspend_all(chip->pcm);	for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; reg++)		chip->saved_regs_mixer[reg] = inw(chip->mixer_port + reg * 2);	/* make sure to disable master volume etc. to prevent looping sound */	snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);	snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);		for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; reg++)		chip->saved_regs_codec[reg] = inw(chip->codec_port + reg * 2);	for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++)		chip->saved_regs_io2[reg] = inw(chip->io2_port + reg * 2);	for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; reg++)		chip->saved_regs_mpu[reg] = inw(chip->mpu_port + reg * 2);	for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++)		chip->saved_regs_synth[reg] = inw(chip->synth_port + reg * 2);	pci_disable_device(pci);	pci_save_state(pci);	pci_set_power_state(pci, pci_choose_state(pci, state));	return 0;}static intsnd_azf3328_resume(struct pci_dev *pci){	struct snd_card *card = pci_get_drvdata(pci);	struct snd_azf3328 *chip = card->private_data;	int reg;	pci_set_power_state(pci, PCI_D0);	pci_restore_state(pci);	if (pci_enable_device(pci) < 0) {		printk(KERN_ERR "azt3328: pci_enable_device failed, "		       "disabling device\n");		snd_card_disconnect(card);		return -EIO;	}	pci_set_master(pci);	for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++)		outw(chip->saved_regs_io2[reg], chip->io2_port + reg * 2);	for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; reg++)		outw(chip->saved_regs_mpu[reg], chip->mpu_port + reg * 2);	for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++)		outw(chip->saved_regs_synth[reg], chip->synth_port + reg * 2);	for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; reg++)		outw(chip->saved_regs_mixer[reg], chip->mixer_port + reg * 2);	for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; reg++)		outw(chip->saved_regs_codec[reg], chip->codec_port + reg * 2);	snd_power_change_state(card, SNDRV_CTL_POWER_D0);	return 0;}#endifstatic struct pci_driver driver = {	.name = "AZF3328",	.id_table = snd_azf3328_ids,	.probe = snd_azf3328_probe,	.remove = __devexit_p(snd_azf3328_remove),#ifdef CONFIG_PM	.suspend = snd_azf3328_suspend,	.resume = snd_azf3328_resume,#endif};static int __initalsa_card_azf3328_init(void){	int err;	snd_azf3328_dbgcallenter();	err = pci_register_driver(&driver);	snd_azf3328_dbgcallleave();	return err;}static void __exitalsa_card_azf3328_exit(void){	snd_azf3328_dbgcallenter();	pci_unregister_driver(&driver);	snd_azf3328_dbgcallleave();}module_init(alsa_card_azf3328_init)module_exit(alsa_card_azf3328_exit)

⌨️ 快捷键说明

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