📄 sb16.c
字号:
static void snd_sb16_free(snd_card_t *card){ struct snd_sb16 *acard = (struct snd_sb16 *)card->private_data; if (acard == NULL) return; if (acard->fm_res) { release_resource(acard->fm_res); kfree_nocheck(acard->fm_res); }#ifdef __ISAPNP__ snd_sb16_deactivate(acard);#endif}static int __init snd_sb16_probe(int dev){ static int possible_irqs[] = {5, 9, 10, 7, -1}; static int possible_dmas8[] = {1, 3, 0, -1}; static int possible_dmas16[] = {5, 6, 7, -1}; int irq, dma8, dma16; sb_t *chip; snd_card_t *card; struct snd_sb16 *acard; opl3_t *opl3; snd_hwdep_t *synth = NULL;#ifdef CONFIG_SND_SB16_CSP snd_hwdep_t *csp = NULL;#endif unsigned long flags; int err; card = snd_card_new(snd_index[dev], snd_id[dev], THIS_MODULE, sizeof(struct snd_sb16)); if (card == NULL) return -ENOMEM; acard = (struct snd_sb16 *) card->private_data; card->private_free = snd_sb16_free;#ifdef __ISAPNP__ if (snd_isapnp[dev] && snd_sb16_isapnp(dev, acard) < 0) { snd_card_free(card); return -EBUSY; }#endif irq = snd_irq[dev]; dma8 = snd_dma8[dev]; dma16 = snd_dma16[dev];#ifdef __ISAPNP__ if (!snd_isapnp[dev]) {#endif if (irq == SNDRV_AUTO_IRQ) { if ((irq = snd_legacy_find_free_irq(possible_irqs)) < 0) { snd_card_free(card); printk(KERN_ERR PFX "unable to find a free IRQ\n"); return -EBUSY; } } if (dma8 == SNDRV_AUTO_DMA) { if ((dma8 = snd_legacy_find_free_dma(possible_dmas8)) < 0) { snd_card_free(card); printk(KERN_ERR PFX "unable to find a free 8-bit DMA\n"); return -EBUSY; } } if (dma16 == SNDRV_AUTO_DMA) { if ((dma16 = snd_legacy_find_free_dma(possible_dmas16)) < 0) { snd_card_free(card); printk(KERN_ERR PFX "unable to find a free 16-bit DMA\n"); return -EBUSY; } } /* non-PnP FM port address is hardwired with base port address */ snd_fm_port[dev] = snd_port[dev]; /* block the 0x388 port to avoid PnP conflicts */ acard->fm_res = request_region(0x388, 4, "SoundBlaster FM");#ifdef SNDRV_SBAWE_EMU8000 /* non-PnP AWE port address is hardwired with base port address */ snd_awe_port[dev] = snd_port[dev] + 0x400;#endif#ifdef __ISAPNP__ }#endif if ((err = snd_sbdsp_create(card, snd_port[dev], irq, snd_sb16dsp_interrupt, dma8, dma16, SB_HW_AUTO, &chip)) < 0) { snd_card_free(card); return err; } if (chip->hardware != SB_HW_16) { snd_card_free(card); snd_printdd("SB 16 chip was not detected at 0x%lx\n", snd_port[dev]); return -ENODEV; } chip->mpu_port = snd_mpu_port[dev];#ifdef __ISAPNP__ if (!snd_isapnp[dev] && (err = snd_sb16dsp_configure(chip)) < 0) {#else if ((err = snd_sb16dsp_configure(chip)) < 0) {#endif snd_card_free(card); return -ENXIO; } if ((err = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) { snd_card_free(card); return -ENXIO; } if (chip->mpu_port) { if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SB, chip->mpu_port, 0, irq, 0, &chip->rmidi)) < 0) { snd_card_free(card); return -ENXIO; } } if (snd_fm_port[dev] > 0) { if (snd_opl3_create(card, snd_fm_port[dev], snd_fm_port[dev] + 2, OPL3_HW_OPL3, snd_fm_port[dev] == snd_port[dev], &opl3) < 0) { printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx\n", snd_fm_port[dev], snd_fm_port[dev] + 2); } else {#ifdef SNDRV_SBAWE_EMU8000 int seqdev = snd_awe_port[dev] > 0 ? 2 : 1;#else int seqdev = 1;#endif if ((err = snd_opl3_hwdep_new(opl3, 0, seqdev, &synth)) < 0) { snd_card_free(card); return -ENXIO; } } } if ((err = snd_sbmixer_new(chip)) < 0) { snd_card_free(card); return -ENXIO; }#ifdef CONFIG_SND_SB16_CSP /* CSP chip on SB16ASP/AWE32 */ if ((chip->hardware == SB_HW_16) && snd_csp[dev]) { snd_sb_csp_new(chip, synth != NULL ? 1 : 0, &csp); if (csp) { chip->csp = csp->private_data; chip->hardware = SB_HW_16CSP; } else { printk(KERN_INFO PFX "warning - CSP chip not detected on soundcard #%i\n", dev + 1); } }#endif#ifdef SNDRV_SBAWE_EMU8000 if (snd_awe_port[dev] > 0) { if (snd_emu8000_new(card, 1, snd_awe_port[dev], snd_seq_ports[dev], NULL) < 0) { printk(KERN_ERR PFX "fatal error - EMU-8000 synthesizer not detected at 0x%lx\n", snd_awe_port[dev]); snd_card_free(card); return -ENXIO; } }#endif /* setup Mic AGC */ spin_lock_irqsave(&chip->mixer_lock, flags); snd_sbmixer_write(chip, SB_DSP4_MIC_AGC, (snd_sbmixer_read(chip, SB_DSP4_MIC_AGC) & 0x01) | (snd_mic_agc[dev] ? 0x00 : 0x01)); spin_unlock_irqrestore(&chip->mixer_lock, flags); strcpy(card->driver, #ifdef SNDRV_SBAWE_EMU8000 snd_awe_port[dev] > 0 ? "SB AWE" :#endif "SB16"); strcpy(card->shortname, chip->name); sprintf(card->longname, "%s at 0x%lx, irq %i, dma ", chip->name, chip->port, irq); if (dma8 >= 0) sprintf(card->longname + strlen(card->longname), "%d", dma8); if (dma16 >= 0) sprintf(card->longname + strlen(card->longname), "%s%d", dma8 >= 0 ? "&" : "", dma16); if ((err = snd_card_register(card)) < 0) { snd_card_free(card); return err; } snd_sb16_cards[dev] = card; return 0;}static int __init snd_sb16_probe_legacy_port(unsigned long port){ static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { if (!snd_enable[dev] || snd_port[dev] != SNDRV_AUTO_PORT) continue;#ifdef __ISAPNP__ if (snd_isapnp[dev]) continue;#endif snd_port[dev] = port; res = snd_sb16_probe(dev); if (res < 0) snd_port[dev] = SNDRV_AUTO_PORT; return res; } return -ENODEV;}#ifdef __ISAPNP__static int __init snd_sb16_isapnp_detect(struct isapnp_card *card, const struct isapnp_card_id *id){ static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { if (!snd_enable[dev] || !snd_isapnp[dev]) continue; snd_sb16_isapnp_cards[dev] = card; snd_sb16_isapnp_id[dev] = id; res = snd_sb16_probe(dev); if (res < 0) return res; dev++; return 0; } return -ENODEV;}#endif /* __ISAPNP__ */static int __init alsa_card_sb16_init(void){ int dev, cards = 0; static unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280, -1}; /* legacy non-auto cards at first */ for (dev = 0; dev < SNDRV_CARDS; dev++) { if (!snd_enable[dev] || snd_port[dev] == SNDRV_AUTO_PORT) continue;#ifdef __ISAPNP__ if (snd_isapnp[dev]) continue;#endif if (!snd_sb16_probe(dev)) { cards++; continue; }#ifdef MODULE printk(KERN_ERR "Sound Blaster 16+ soundcard #%i not found at 0x%lx or device busy\n", dev, snd_port[dev]);#endif } /* legacy auto configured cards */ cards += snd_legacy_auto_probe(possible_ports, snd_sb16_probe_legacy_port);#ifdef __ISAPNP__ /* ISA PnP cards at last */ cards += isapnp_probe_cards(snd_sb16_pnpids, snd_sb16_isapnp_detect);#endif if (!cards) {#ifdef MODULE printk(KERN_ERR "Sound Blaster 16 soundcard not found or device busy\n");#ifdef SNDRV_SBAWE_EMU8000 printk(KERN_ERR "In case, if you have non-AWE card, try snd-card-sb16 module\n");#else printk(KERN_ERR "In case, if you have AWE card, try snd-card-sbawe module\n");#endif#endif return -ENODEV; } return 0;}static void __exit alsa_card_sb16_exit(void){ int dev; for (dev = 0; dev < SNDRV_CARDS; dev++) snd_card_free(snd_sb16_cards[dev]);}module_init(alsa_card_sb16_init)module_exit(alsa_card_sb16_exit)#ifndef MODULE/* format is: snd-sb16=snd_enable,snd_index,snd_id,snd_isapnp, snd_port,snd_mpu_port,snd_fm_port, snd_irq,snd_dma8,snd_dma16, snd_mic_agc,snd_csp, [snd_awe_port,snd_seq_ports] */static int __init alsa_card_sb16_setup(char *str){ static unsigned __initdata nr_dev = 0; int __attribute__ ((__unused__)) pnp = INT_MAX; int __attribute__ ((__unused__)) csp = INT_MAX; if (nr_dev >= SNDRV_CARDS) return 0; (void)(get_option(&str,&snd_enable[nr_dev]) == 2 && get_option(&str,&snd_index[nr_dev]) == 2 && get_id(&str,&snd_id[nr_dev]) == 2 && get_option(&str,&pnp) == 2 && get_option(&str,(int *)&snd_port[nr_dev]) == 2 && get_option(&str,(int *)&snd_mpu_port[nr_dev]) == 2 && get_option(&str,(int *)&snd_fm_port[nr_dev]) == 2 && get_option(&str,&snd_irq[nr_dev]) == 2 && get_option(&str,&snd_dma8[nr_dev]) == 2 && get_option(&str,&snd_dma16[nr_dev]) == 2 && get_option(&str,&snd_mic_agc[nr_dev]) == 2#ifdef CONFIG_SND_SB16_CSP && get_option(&str,&snd_csp[nr_dev]) == 2#endif#ifdef SNDRV_SBAWE_EMU8000 && get_option(&str,(int *)&snd_awe_port[nr_dev]) == 2 && get_option(&str,&snd_seq_ports[nr_dev]) == 2#endif );#ifdef __ISAPNP__ if (pnp != INT_MAX) snd_isapnp[nr_dev] = pnp;#endif#ifdef CONFIG_SND_SB16_CSP if (csp != INT_MAX) snd_csp[nr_dev] = csp;#endif nr_dev++; return 1;}#ifndef SNDRV_SBAWE_EMU8000__setup("snd-sb16=", alsa_card_sb16_setup);#else__setup("snd-sbawe=", alsa_card_sb16_setup);#endif#endif /* ifndef MODULE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -