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

📄 als4000.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	.period_bytes_min =	64,	.period_bytes_max =	65536,	.periods_min =		1,	.periods_max =		1024,	.fifo_size =		0};static struct snd_pcm_hardware snd_als4000_capture ={	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_MMAP_VALID),	.formats =		SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |				SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE,	/* formats */	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,	.rate_min =		4000,	.rate_max =		48000,	.channels_min =		1,	.channels_max =		2,	.buffer_bytes_max =	65536,	.period_bytes_min =	64,	.period_bytes_max =	65536,	.periods_min =		1,	.periods_max =		1024,	.fifo_size =		0};/*****************************************************************/static int snd_als4000_playback_open(struct snd_pcm_substream *substream){	struct snd_sb *chip = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	chip->playback_substream = substream;	runtime->hw = snd_als4000_playback;	return 0;}static int snd_als4000_playback_close(struct snd_pcm_substream *substream){	struct snd_sb *chip = snd_pcm_substream_chip(substream);	chip->playback_substream = NULL;	snd_pcm_lib_free_pages(substream);	return 0;}static int snd_als4000_capture_open(struct snd_pcm_substream *substream){	struct snd_sb *chip = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	chip->capture_substream = substream;	runtime->hw = snd_als4000_capture;	return 0;}static int snd_als4000_capture_close(struct snd_pcm_substream *substream){	struct snd_sb *chip = snd_pcm_substream_chip(substream);	chip->capture_substream = NULL;	snd_pcm_lib_free_pages(substream);	return 0;}/******************************************************************/static struct snd_pcm_ops snd_als4000_playback_ops = {	.open =		snd_als4000_playback_open,	.close =	snd_als4000_playback_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_als4000_hw_params,	.hw_free =	snd_als4000_hw_free,	.prepare =	snd_als4000_playback_prepare,	.trigger =	snd_als4000_playback_trigger,	.pointer =	snd_als4000_playback_pointer};static struct snd_pcm_ops snd_als4000_capture_ops = {	.open =		snd_als4000_capture_open,	.close =	snd_als4000_capture_close,	.ioctl =	snd_pcm_lib_ioctl,	.hw_params =	snd_als4000_hw_params,	.hw_free =	snd_als4000_hw_free,	.prepare =	snd_als4000_capture_prepare,	.trigger =	snd_als4000_capture_trigger,	.pointer =	snd_als4000_capture_pointer};static int __devinit snd_als4000_pcm(struct snd_sb *chip, int device){	struct snd_pcm *pcm;	int err;	if ((err = snd_pcm_new(chip->card, "ALS4000 DSP", device, 1, 1, &pcm)) < 0)		return err;	pcm->private_data = chip;	pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_als4000_playback_ops);	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_als4000_capture_ops);	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),					      64*1024, 64*1024);	chip->pcm = pcm;	return 0;}/******************************************************************/static void snd_als4000_set_addr(unsigned long gcr,					unsigned int sb,					unsigned int mpu,					unsigned int opl,					unsigned int game){	u32 confA = 0;	u32 confB = 0;	if (mpu > 0)		confB |= (mpu | 1) << 16;	if (sb > 0)		confB |= (sb | 1);	if (game > 0)		confA |= (game | 1) << 16;	if (opl > 0)			confA |= (opl | 1);	snd_als4000_gcr_write_addr(gcr, 0xa8, confA);	snd_als4000_gcr_write_addr(gcr, 0xa9, confB);}static void snd_als4000_configure(struct snd_sb *chip){	unsigned tmp;	int i;	/* do some more configuration */	spin_lock_irq(&chip->mixer_lock);	tmp = snd_sbmixer_read(chip, 0xc0);	snd_sbmixer_write(chip, 0xc0, tmp|0x80);	/* always select DMA channel 0, since we do not actually use DMA */	snd_sbmixer_write(chip, SB_DSP4_DMASETUP, SB_DMASETUP_DMA0);	snd_sbmixer_write(chip, 0xc0, tmp&0x7f);	spin_unlock_irq(&chip->mixer_lock);		spin_lock_irq(&chip->reg_lock);	/* magic number. Enables interrupts(?) */	snd_als4000_gcr_write(chip, 0x8c, 0x28000);	for(i = 0x91; i <= 0x96; ++i)		snd_als4000_gcr_write(chip, i, 0);		snd_als4000_gcr_write(chip, 0x99, snd_als4000_gcr_read(chip, 0x99));	spin_unlock_irq(&chip->reg_lock);}#ifdef SUPPORT_JOYSTICKstatic int __devinit snd_als4000_create_gameport(struct snd_card_als4000 *acard, int dev){	struct gameport *gp;	struct resource *r;	int io_port;	if (joystick_port[dev] == 0)		return -ENODEV;	if (joystick_port[dev] == 1) { /* auto-detect */		for (io_port = 0x200; io_port <= 0x218; io_port += 8) {			r = request_region(io_port, 8, "ALS4000 gameport");			if (r)				break;		}	} else {		io_port = joystick_port[dev];		r = request_region(io_port, 8, "ALS4000 gameport");	}	if (!r) {		printk(KERN_WARNING "als4000: cannot reserve joystick ports\n");		return -EBUSY;	}	acard->gameport = gp = gameport_allocate_port();	if (!gp) {		printk(KERN_ERR "als4000: cannot allocate memory for gameport\n");		release_and_free_resource(r);		return -ENOMEM;	}	gameport_set_name(gp, "ALS4000 Gameport");	gameport_set_phys(gp, "pci%s/gameport0", pci_name(acard->pci));	gameport_set_dev_parent(gp, &acard->pci->dev);	gp->io = io_port;	gameport_set_port_data(gp, r);	/* Enable legacy joystick port */	snd_als4000_set_addr(acard->gcr, 0, 0, 0, 1);	gameport_register_port(acard->gameport);	return 0;}static void snd_als4000_free_gameport(struct snd_card_als4000 *acard){	if (acard->gameport) {		struct resource *r = gameport_get_port_data(acard->gameport);		gameport_unregister_port(acard->gameport);		acard->gameport = NULL;		snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); /* disable joystick */		release_and_free_resource(r);	}}#elsestatic inline int snd_als4000_create_gameport(struct snd_card_als4000 *acard, int dev) { return -ENOSYS; }static inline void snd_als4000_free_gameport(struct snd_card_als4000 *acard) { }#endifstatic void snd_card_als4000_free( struct snd_card *card ){	struct snd_card_als4000 * acard = (struct snd_card_als4000 *)card->private_data;	/* make sure that interrupts are disabled */	snd_als4000_gcr_write_addr( acard->gcr, 0x8c, 0);	/* free resources */	snd_als4000_free_gameport(acard);	pci_release_regions(acard->pci);	pci_disable_device(acard->pci);}static int __devinit snd_card_als4000_probe(struct pci_dev *pci,					  const struct pci_device_id *pci_id){	static int dev;	struct snd_card *card;	struct snd_card_als4000 *acard;	unsigned long gcr;	struct snd_sb *chip;	struct snd_opl3 *opl3;	unsigned short word;	int err;	if (dev >= SNDRV_CARDS)		return -ENODEV;	if (!enable[dev]) {		dev++;		return -ENOENT;	}	/* enable PCI device */	if ((err = pci_enable_device(pci)) < 0) {		return err;	}	/* 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");		pci_disable_device(pci);		return -ENXIO;	}	if ((err = pci_request_regions(pci, "ALS4000")) < 0) {		pci_disable_device(pci);		return err;	}	gcr = pci_resource_start(pci, 0);	pci_read_config_word(pci, PCI_COMMAND, &word);	pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO);	pci_set_master(pci);		card = snd_card_new(index[dev], id[dev], THIS_MODULE, 			    sizeof( struct snd_card_als4000 ) );	if (card == NULL) {		pci_release_regions(pci);		pci_disable_device(pci);		return -ENOMEM;	}	acard = (struct snd_card_als4000 *)card->private_data;	acard->pci = pci;	acard->gcr = gcr;	card->private_free = snd_card_als4000_free;	/* disable all legacy ISA stuff */	snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0);	if ((err = snd_sbdsp_create(card,				    gcr + 0x10,				    pci->irq,				    snd_als4000_interrupt,				    -1,				    -1,				    SB_HW_ALS4000,				    &chip)) < 0) {		goto out_err;	}	acard->chip = chip;	chip->pci = pci;	chip->alt_port = gcr;	snd_card_set_dev(card, &pci->dev);	snd_als4000_configure(chip);	strcpy(card->driver, "ALS4000");	strcpy(card->shortname, "Avance Logic ALS4000");	sprintf(card->longname, "%s at 0x%lx, irq %i",		card->shortname, chip->alt_port, chip->irq);	if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000,				        gcr+0x30, MPU401_INFO_INTEGRATED,					pci->irq, 0, &chip->rmidi)) < 0) {		printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n", gcr+0x30);		goto out_err;	}	if ((err = snd_als4000_pcm(chip, 0)) < 0) {		goto out_err;	}	if ((err = snd_sbmixer_new(chip)) < 0) {		goto out_err;	}	    	if (snd_opl3_create(card, gcr+0x10, gcr+0x12,			    OPL3_HW_AUTO, 1, &opl3) < 0) {		printk(KERN_ERR "als4000: no OPL device at 0x%lx-0x%lx?\n",			   gcr+0x10, gcr+0x12 );	} else {		if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {			goto out_err;		}	}	snd_als4000_create_gameport(acard, dev);	if ((err = snd_card_register(card)) < 0) {		goto out_err;	}	pci_set_drvdata(pci, card);	dev++;	err = 0;	goto out;out_err:	snd_card_free(card);	out:	return err;}static void __devexit snd_card_als4000_remove(struct pci_dev *pci){	snd_card_free(pci_get_drvdata(pci));	pci_set_drvdata(pci, NULL);}#ifdef CONFIG_PMstatic int snd_als4000_suspend(struct pci_dev *pci, pm_message_t state){	struct snd_card *card = pci_get_drvdata(pci);	struct snd_card_als4000 *acard = card->private_data;	struct snd_sb *chip = acard->chip;	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);		snd_pcm_suspend_all(chip->pcm);	snd_sbmixer_suspend(chip);	pci_disable_device(pci);	pci_save_state(pci);	pci_set_power_state(pci, pci_choose_state(pci, state));	return 0;}static int snd_als4000_resume(struct pci_dev *pci){	struct snd_card *card = pci_get_drvdata(pci);	struct snd_card_als4000 *acard = card->private_data;	struct snd_sb *chip = acard->chip;	pci_set_power_state(pci, PCI_D0);	pci_restore_state(pci);	if (pci_enable_device(pci) < 0) {		printk(KERN_ERR "als4000: pci_enable_device failed, "		       "disabling device\n");		snd_card_disconnect(card);		return -EIO;	}	pci_set_master(pci);	snd_als4000_configure(chip);	snd_sbdsp_reset(chip);	snd_sbmixer_resume(chip);#ifdef SUPPORT_JOYSTICK	if (acard->gameport)		snd_als4000_set_addr(acard->gcr, 0, 0, 0, 1);#endif	snd_power_change_state(card, SNDRV_CTL_POWER_D0);	return 0;}#endifstatic struct pci_driver driver = {	.name = "ALS4000",	.id_table = snd_als4000_ids,	.probe = snd_card_als4000_probe,	.remove = __devexit_p(snd_card_als4000_remove),#ifdef CONFIG_PM	.suspend = snd_als4000_suspend,	.resume = snd_als4000_resume,#endif};static int __init alsa_card_als4000_init(void){	return pci_register_driver(&driver);}static void __exit alsa_card_als4000_exit(void){	pci_unregister_driver(&driver);}module_init(alsa_card_als4000_init)module_exit(alsa_card_als4000_exit)

⌨️ 快捷键说明

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