📄 riptide.c
字号:
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 + -