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

📄 azt3328.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 4 页
字号:
	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,				   &snd_azf3328_hw_constraints_rates);	snd_azf3328_dbgcallleave();	return 0;}static int snd_azf3328_capture_open(snd_pcm_substream_t * substream){	azf3328_t *chip = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	snd_azf3328_dbgcallenter();	chip->capture_substream = substream;	runtime->hw = snd_azf3328_capture;	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,				   &snd_azf3328_hw_constraints_rates);	snd_azf3328_dbgcallleave();	return 0;}static int snd_azf3328_playback_close(snd_pcm_substream_t * substream){	azf3328_t *chip = snd_pcm_substream_chip(substream);	snd_azf3328_dbgcallenter();	chip->playback_substream = NULL;	snd_azf3328_dbgcallleave();	return 0;}static int snd_azf3328_capture_close(snd_pcm_substream_t * substream){	azf3328_t *chip = snd_pcm_substream_chip(substream);	snd_azf3328_dbgcallenter();	chip->capture_substream = NULL;	snd_azf3328_dbgcallleave();	return 0;}/******************************************************************/static snd_pcm_ops_t snd_azf3328_playback_ops = {	.open =		snd_azf3328_playback_open,	.close =	snd_azf3328_playback_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_azf3328_hw_params,	.hw_free =	snd_azf3328_hw_free,	.prepare =	snd_azf3328_playback_prepare,	.trigger =	snd_azf3328_playback_trigger,	.pointer =	snd_azf3328_playback_pointer};static snd_pcm_ops_t snd_azf3328_capture_ops = {	.open =		snd_azf3328_capture_open,	.close =	snd_azf3328_capture_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_azf3328_hw_params,	.hw_free =	snd_azf3328_hw_free,	.prepare =	snd_azf3328_capture_prepare,	.trigger =	snd_azf3328_capture_trigger,	.pointer =	snd_azf3328_capture_pointer};static void snd_azf3328_pcm_free(snd_pcm_t *pcm){	azf3328_t *chip = pcm->private_data;	chip->pcm = NULL;	snd_pcm_lib_preallocate_free_for_all(pcm);}static int __devinit snd_azf3328_pcm(azf3328_t *chip, int device){	snd_pcm_t *pcm;	int err;	snd_azf3328_dbgcallenter();	if ((err = snd_pcm_new(chip->card, "AZF3328 DSP", device, 1, 1, &pcm)) < 0)		return err;	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_azf3328_playback_ops);	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_azf3328_capture_ops);	pcm->private_data = chip;	pcm->private_free = snd_azf3328_pcm_free;	pcm->info_flags = 0;	strcpy(pcm->name, chip->card->shortname);	chip->pcm = pcm;	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,					      snd_dma_pci_data(chip->pci), 64*1024, 64*1024);	snd_azf3328_dbgcallleave();	return 0;}/******************************************************************/static int snd_azf3328_free(azf3328_t *chip){        if (chip->irq < 0)                goto __end_hw;	/* reset (close) mixer */	snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1); /* first mute master volume */	snd_azf3328_mixer_write(chip, IDX_MIXER_RESET, 0x0, WORD_VALUE);        /* interrupt setup - mask everything */	/* FIXME */        synchronize_irq(chip->irq);      __end_hw:#ifdef SUPPORT_JOYSTICK	if (chip->res_joystick) {		gameport_unregister_port(&chip->gameport);		/* disable gameport */		snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,				      snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);		release_resource(chip->res_joystick);		kfree_nocheck(chip->res_joystick);	}#endif        if (chip->irq >= 0)		free_irq(chip->irq, (void *)chip);	pci_release_regions(chip->pci);        kfree(chip);        return 0;}static int snd_azf3328_dev_free(snd_device_t *device){	azf3328_t *chip = device->device_data;	return snd_azf3328_free(chip);}#if 0/* check whether a bit can be modified */static void snd_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);}#endifstatic int __devinit snd_azf3328_create(snd_card_t * card,                                         struct pci_dev *pci,                                         unsigned long device_type,                                         azf3328_t ** rchip){	azf3328_t *chip;	int err;	static snd_device_ops_t ops = {		.dev_free =     snd_azf3328_dev_free,	};	u16 tmp;	*rchip = NULL;	if ((err = pci_enable_device(pci)) < 0)		return err;	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);	if (chip == NULL)		return -ENOMEM;	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, 0x00ffffff) < 0 ||	    pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {		snd_printk("architecture does not support 24bit PCI busmaster DMA\n");		return -ENXIO;	}	if ((err = pci_request_regions(pci, "Aztech AZF3328")) < 0) {		kfree(chip);		return 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, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {		snd_printk("unable to grab IRQ %d\n", pci->irq);		snd_azf3328_free(chip);		return -EBUSY;	}	chip->irq = pci->irq;	pci_set_master(pci);	synchronize_irq(chip->irq);	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_read(chip, 0), snd_azf3328_io2_read(chip, 1), snd_azf3328_io2_read(chip, 2), snd_azf3328_io2_read(chip, 3), snd_azf3328_io2_read(chip, 4), snd_azf3328_io2_read(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));	/* create mixer interface & switches */	if ((err = snd_azf3328_mixer_new(chip)) < 0)		return err;	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {		snd_azf3328_free(chip);		return 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 */	spin_lock_irq(&chip->reg_lock);	outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_PLAY_FLAGS);	outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_SOMETHING_FLAGS);	outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_REC_FLAGS);	outb(0x0, chip->codec_port + IDX_IO_IRQ63H);	spin_unlock_irq(&chip->reg_lock);	snd_card_set_dev(card, &pci->dev);	*rchip = chip;	return 0;}#ifdef SUPPORT_JOYSTICKstatic void __devinit snd_azf3328_config_joystick(azf3328_t *chip, int joystick){	unsigned char val;	if (joystick == 1) {		if ((chip->res_joystick = request_region(0x200, 8, "AZF3328 gameport")) != NULL)			chip->gameport.io = 0x200;	}	val = inb(chip->io2_port + IDX_IO2_LEGACY_ADDR);	if (chip->res_joystick)		val |= LEGACY_JOY;	else		val &= ~LEGACY_JOY;	outb(val, chip->io2_port + IDX_IO2_LEGACY_ADDR);	if (chip->res_joystick)		gameport_register_port(&chip->gameport);}#endifstatic int __devinit snd_azf3328_probe(struct pci_dev *pci,					  const struct pci_device_id *pci_id){	static int dev;	snd_card_t *card;	azf3328_t *chip;	opl3_t *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) {		snd_card_free(card);		return err;	}	if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401,				        chip->mpu_port, 1, pci->irq, 0,				        &chip->rmidi)) < 0) {		snd_printk("azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port);		snd_card_free(card);		return err;	}	if ((err = snd_azf3328_pcm(chip, 0)) < 0) {		snd_card_free(card);		return err;	}	if (snd_opl3_create(card, chip->synth_port, chip->synth_port+2,			    OPL3_HW_AUTO, 1, &opl3) < 0) {		snd_printk("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) {			snd_card_free(card);			return err;		}	}	snd_azf3328_dbgio(chip, "create");	sprintf(card->longname, "%s at 0x%lx, irq %i",		card->shortname, chip->codec_port, chip->irq);	if ((err = snd_card_register(card)) < 0) {		snd_card_free(card);		return err;	}#ifdef MODULE	printk("azt3328: Experimental driver for Aztech AZF3328-based soundcards such as PCI168.\n""azt3328: ZERO support from Aztech: you might think hard about future purchase.\n""azt3328: Feel free to contact hw7oshyuv3001@sneakemail.com for bug reports etc.!\n");#endif#ifdef SUPPORT_JOYSTICK	snd_azf3328_config_joystick(chip, joystick[dev]);#endif	pci_set_drvdata(pci, card);	dev++;	snd_azf3328_dbgcallleave();	return 0;}static void __devexit snd_azf3328_remove(struct pci_dev *pci){	snd_azf3328_dbgcallenter();	snd_card_free(pci_get_drvdata(pci));	pci_set_drvdata(pci, NULL);	snd_azf3328_dbgcallleave();}static struct pci_driver driver = {	.name = "AZF3328",	.id_table = snd_azf3328_ids,	.probe = snd_azf3328_probe,	.remove = __devexit_p(snd_azf3328_remove),};static int __init alsa_card_azf3328_init(void){	int err;	snd_azf3328_dbgcallenter();	err = pci_module_init(&driver);	snd_azf3328_dbgcallleave();	return err;}static void __exit alsa_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 + -