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

📄 riptide.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	snd_printdd("Write AC97 reg 0x%x 0x%x\n", reg, val);	do {		SEND_SACR(cif, val, reg);		SEND_RACR(cif, reg, &rptr);	} while (rptr.retwords[1] != val && i++ < MAX_WRITE_RETRY);	if (i == MAX_WRITE_RETRY)		snd_printdd("Write AC97 reg failed\n");}static unsigned short snd_riptide_codec_read(struct snd_ac97 *ac97,					     unsigned short reg){	struct snd_riptide *chip = ac97->private_data;	struct cmdif *cif = chip->cif;	union cmdret rptr = CMDRET_ZERO;	snd_assert(cif, return 0);	if (SEND_RACR(cif, reg, &rptr) != 0)		SEND_RACR(cif, reg, &rptr);	snd_printdd("Read AC97 reg 0x%x got 0x%x\n", reg, rptr.retwords[1]);	return rptr.retwords[1];}static int snd_riptide_initialize(struct snd_riptide *chip){	struct cmdif *cif;	unsigned int device_id;	int err;	snd_assert(chip, return -EINVAL);	cif = chip->cif;	if (!cif) {		if ((cif = kzalloc(sizeof(struct cmdif), GFP_KERNEL)) == NULL)			return -ENOMEM;		cif->hwport = (struct riptideport *)chip->port;		spin_lock_init(&cif->lock);		chip->cif = cif;	}	cif->is_reset = 0;	if ((err = riptide_reset(cif, chip)) != 0)		return err;	device_id = chip->device_id;	switch (device_id) {	case 0x4310:	case 0x4320:	case 0x4330:		snd_printdd("Modem enable?\n");		SEND_SETDPLL(cif);		break;	}	snd_printdd("Enabling MPU IRQs\n");	if (chip->rmidi)		SET_EMPUIRQ(cif->hwport);	return err;}static int snd_riptide_free(struct snd_riptide *chip){	struct cmdif *cif;	snd_assert(chip, return 0);	if ((cif = chip->cif)) {		SET_GRESET(cif->hwport);		udelay(100);		UNSET_GRESET(cif->hwport);		kfree(chip->cif);	}	if (chip->irq >= 0)		free_irq(chip->irq, chip);	if (chip->fw_entry)		release_firmware(chip->fw_entry);	release_and_free_resource(chip->res_port);	kfree(chip);	return 0;}static int snd_riptide_dev_free(struct snd_device *device){	struct snd_riptide *chip = device->device_data;	return snd_riptide_free(chip);}static int __devinitsnd_riptide_create(struct snd_card *card, struct pci_dev *pci,		   struct snd_riptide **rchip){	struct snd_riptide *chip;	struct riptideport *hwport;	int err;	static struct snd_device_ops ops = {		.dev_free = snd_riptide_dev_free,	};	*rchip = NULL;	if ((err = pci_enable_device(pci)) < 0)		return err;	if (!(chip = kzalloc(sizeof(struct snd_riptide), GFP_KERNEL)))		return -ENOMEM;	spin_lock_init(&chip->lock);	chip->card = card;	chip->pci = pci;	chip->irq = -1;	chip->openstreams = 0;	chip->port = pci_resource_start(pci, 0);	chip->received_irqs = 0;	chip->handled_irqs = 0;	chip->cif = NULL;	tasklet_init(&chip->riptide_tq, riptide_handleirq, (unsigned long)chip);	if ((chip->res_port =	     request_region(chip->port, 64, "RIPTIDE")) == NULL) {		snd_printk(KERN_ERR			   "Riptide: unable to grab region 0x%lx-0x%lx\n",			   chip->port, chip->port + 64 - 1);		snd_riptide_free(chip);		return -EBUSY;	}	hwport = (struct riptideport *)chip->port;	UNSET_AIE(hwport);	if (request_irq(pci->irq, snd_riptide_interrupt, IRQF_SHARED,			"RIPTIDE", chip)) {		snd_printk(KERN_ERR "Riptide: unable to grab IRQ %d\n",			   pci->irq);		snd_riptide_free(chip);		return -EBUSY;	}	chip->irq = pci->irq;	chip->device_id = pci->device;	pci_set_master(pci);	if ((err = snd_riptide_initialize(chip)) < 0) {		snd_riptide_free(chip);		return err;	}	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {		snd_riptide_free(chip);		return err;	}	snd_card_set_dev(card, &pci->dev);	*rchip = chip;	return 0;}static voidsnd_riptide_proc_read(struct snd_info_entry *entry,		      struct snd_info_buffer *buffer){	struct snd_riptide *chip = entry->private_data;	struct pcmhw *data;	int i;	struct cmdif *cif = NULL;	unsigned char p[256];	unsigned short rval = 0, lval = 0;	unsigned int rate;	if (!chip)		return;	snd_iprintf(buffer, "%s\n\n", chip->card->longname);	snd_iprintf(buffer, "Device ID: 0x%x\nReceived IRQs: (%ld)%ld\nPorts:",		    chip->device_id, chip->handled_irqs, chip->received_irqs);	for (i = 0; i < 64; i += 4)		snd_iprintf(buffer, "%c%02x: %08x",			    (i % 16) ? ' ' : '\n', i, inl(chip->port + i));	if ((cif = chip->cif)) {		snd_iprintf(buffer,			    "\nVersion: ASIC: %d CODEC: %d AUXDSP: %d PROG: %d",			    chip->firmware.firmware.ASIC,			    chip->firmware.firmware.CODEC,			    chip->firmware.firmware.AUXDSP,			    chip->firmware.firmware.PROG);		snd_iprintf(buffer, "\nDigital mixer:");		for (i = 0; i < 12; i++) {			getmixer(cif, i, &rval, &lval);			snd_iprintf(buffer, "\n %d: %d %d", i, rval, lval);		}		snd_iprintf(buffer,			    "\nARM Commands num: %d failed: %d time: %d max: %d min: %d",			    cif->cmdcnt, cif->errcnt,			    cif->cmdtime, cif->cmdtimemax, cif->cmdtimemin);	}	snd_iprintf(buffer, "\nOpen streams %d:\n", chip->openstreams);	for (i = 0; i < PLAYBACK_SUBSTREAMS; i++) {		if (chip->playback_substream[i]		    && chip->playback_substream[i]->runtime		    && (data =			chip->playback_substream[i]->runtime->private_data)) {			snd_iprintf(buffer,				    "stream: %d mixer: %d source: %d (%d,%d)\n",				    data->id, data->mixer, data->source,				    data->intdec[0], data->intdec[1]);			if (!(getsamplerate(cif, data->intdec, &rate)))				snd_iprintf(buffer, "rate: %d\n", rate);		}	}	if (chip->capture_substream	    && chip->capture_substream->runtime	    && (data = chip->capture_substream->runtime->private_data)) {		snd_iprintf(buffer,			    "stream: %d mixer: %d source: %d (%d,%d)\n",			    data->id, data->mixer,			    data->source, data->intdec[0], data->intdec[1]);		if (!(getsamplerate(cif, data->intdec, &rate)))			snd_iprintf(buffer, "rate: %d\n", rate);	}	snd_iprintf(buffer, "Paths:\n");	i = getpaths(cif, p);	while (i--) {		snd_iprintf(buffer, "%x->%x ", p[i - 1], p[i]);		i--;	}	snd_iprintf(buffer, "\n");}static void __devinit snd_riptide_proc_init(struct snd_riptide *chip){	struct snd_info_entry *entry;	if (!snd_card_proc_new(chip->card, "riptide", &entry))		snd_info_set_text_ops(entry, chip, snd_riptide_proc_read);}static int __devinit snd_riptide_mixer(struct snd_riptide *chip){	struct snd_ac97_bus *pbus;	struct snd_ac97_template ac97;	int err = 0;	static struct snd_ac97_bus_ops ops = {		.write = snd_riptide_codec_write,		.read = snd_riptide_codec_read,	};	memset(&ac97, 0, sizeof(ac97));	ac97.private_data = chip;	ac97.scaps = AC97_SCAP_SKIP_MODEM;	if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)		return err;	chip->ac97_bus = pbus;	ac97.pci = chip->pci;	if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0)		return err;	return err;}#ifdef SUPPORT_JOYSTICKstatic int have_joystick;static struct pci_dev *riptide_gameport_pci;static struct gameport *riptide_gameport;static int __devinitsnd_riptide_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id){	static int dev;	if (dev >= SNDRV_CARDS)		return -ENODEV;	if (!enable[dev]) {		dev++;		return -ENOENT;	}	if (joystick_port[dev]) {		riptide_gameport = gameport_allocate_port();		if (riptide_gameport) {			if (!request_region			    (joystick_port[dev], 8, "Riptide gameport")) {				snd_printk(KERN_WARNING					   "Riptide: cannot grab gameport 0x%x\n",					   joystick_port[dev]);				gameport_free_port(riptide_gameport);				riptide_gameport = NULL;			} else {				riptide_gameport_pci = pci;				riptide_gameport->io = joystick_port[dev];				gameport_register_port(riptide_gameport);			}		}	}	dev++;	return 0;}static void __devexit snd_riptide_joystick_remove(struct pci_dev *pci){	if (riptide_gameport) {		if (riptide_gameport_pci == pci) {			release_region(riptide_gameport->io, 8);			riptide_gameport_pci = NULL;			gameport_unregister_port(riptide_gameport);			riptide_gameport = NULL;		}	}}#endifstatic int __devinitsnd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id){	static int dev;	struct snd_card *card;	struct snd_riptide *chip;	unsigned short addr;	int err = 0;	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;	if ((err = snd_riptide_create(card, pci, &chip)) < 0) {		snd_card_free(card);		return err;	}	card->private_data = chip;	if ((err = snd_riptide_pcm(chip, 0, NULL)) < 0) {		snd_card_free(card);		return err;	}	if ((err = snd_riptide_mixer(chip)) < 0) {		snd_card_free(card);		return err;	}	pci_write_config_word(chip->pci, PCI_EXT_Legacy_Mask, LEGACY_ENABLE_ALL			      | (opl3_port[dev] ? LEGACY_ENABLE_FM : 0)#ifdef SUPPORT_JOYSTICK			      | (joystick_port[dev] ? LEGACY_ENABLE_GAMEPORT :				 0)#endif			      | (mpu_port[dev]				 ? (LEGACY_ENABLE_MPU_INT | LEGACY_ENABLE_MPU) :				 0)			      | ((chip->irq << 4) & 0xF0));	if ((addr = mpu_port[dev]) != 0) {		pci_write_config_word(chip->pci, PCI_EXT_MPU_Base, addr);		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_RIPTIDE,					       addr, 0, chip->irq, 0,					       &chip->rmidi)) < 0)			snd_printk(KERN_WARNING				   "Riptide: Can't Allocate MPU at 0x%x\n",				   addr);		else			chip->mpuaddr = addr;	}	if ((addr = opl3_port[dev]) != 0) {		pci_write_config_word(chip->pci, PCI_EXT_FM_Base, addr);		if ((err = snd_opl3_create(card, addr, addr + 2,					   OPL3_HW_RIPTIDE, 0,					   &chip->opl3)) < 0)			snd_printk(KERN_WARNING				   "Riptide: Can't Allocate OPL3 at 0x%x\n",				   addr);		else {			chip->opladdr = addr;			if ((err =			     snd_opl3_hwdep_new(chip->opl3, 0, 1, NULL)) < 0)				snd_printk(KERN_WARNING					   "Riptide: Can't Allocate OPL3-HWDEP\n");		}	}#ifdef SUPPORT_JOYSTICK	if ((addr = joystick_port[dev]) != 0) {		pci_write_config_word(chip->pci, PCI_EXT_Game_Base, addr);		chip->gameaddr = addr;	}#endif	strcpy(card->driver, "RIPTIDE");	strcpy(card->shortname, "Riptide");#ifdef SUPPORT_JOYSTICK	snprintf(card->longname, sizeof(card->longname),		 "%s at 0x%lx, irq %i mpu 0x%x opl3 0x%x gameport 0x%x",		 card->shortname, chip->port, chip->irq, chip->mpuaddr,		 chip->opladdr, chip->gameaddr);#else	snprintf(card->longname, sizeof(card->longname),		 "%s at 0x%lx, irq %i mpu 0x%x opl3 0x%x",		 card->shortname, chip->port, chip->irq, chip->mpuaddr,		 chip->opladdr);#endif	snd_riptide_proc_init(chip);	if ((err = snd_card_register(card)) < 0) {		snd_card_free(card);		return err;	}	pci_set_drvdata(pci, card);	dev++;	return 0;}static void __devexit snd_card_riptide_remove(struct pci_dev *pci){	snd_card_free(pci_get_drvdata(pci));	pci_set_drvdata(pci, NULL);}static struct pci_driver driver = {	.name = "RIPTIDE",	.id_table = snd_riptide_ids,	.probe = snd_card_riptide_probe,	.remove = __devexit_p(snd_card_riptide_remove),#ifdef CONFIG_PM	.suspend = riptide_suspend,	.resume = riptide_resume,#endif};#ifdef SUPPORT_JOYSTICKstatic struct pci_driver joystick_driver = {	.name = "Riptide Joystick",	.id_table = snd_riptide_joystick_ids,	.probe = snd_riptide_joystick_probe,	.remove = __devexit_p(snd_riptide_joystick_remove),};#endifstatic int __init alsa_card_riptide_init(void){	int err;	if ((err = pci_register_driver(&driver)) < 0)		return err;#if defined(SUPPORT_JOYSTICK)	if (pci_register_driver(&joystick_driver) < 0) {		have_joystick = 0;		snd_printk(KERN_INFO "no joystick found\n");	} else		have_j

⌨️ 快捷键说明

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