📄 cs4236.c
字号:
snd_port[dev], snd_fm_port[dev], snd_sb_port[dev]); snd_printdd("isapnp WSS: irq=%i, dma1=%i, dma2=%i\n", snd_irq[dev], snd_dma1[dev], snd_dma2[dev]); /* CTRL initialization */ pdev = acard->ctrl; if (pdev->prepare(pdev) < 0) { acard->wss->deactivate(acard->wss); return -EAGAIN; } if (snd_cport[dev] != SNDRV_AUTO_PORT) isapnp_resource_change(&pdev->resource[0], snd_cport[dev], 8); if (pdev->activate(pdev)<0) { printk(KERN_ERR IDENT " isapnp configure failed for control (out of resources?)\n"); acard->wss->deactivate(acard->wss); return -EBUSY; } snd_cport[dev] = pdev->resource[0].start; snd_printdd("isapnp CTRL: control port=0x%lx\n", snd_cport[dev]); /* MPU initialization */ if (acard->mpu) { pdev = acard->mpu; if (pdev->prepare(pdev) < 0) { acard->wss->deactivate(acard->wss); acard->ctrl->deactivate(acard->ctrl); return -EAGAIN; } if (snd_mpu_port[dev] != SNDRV_AUTO_PORT) isapnp_resource_change(&pdev->resource[0], snd_mpu_port[dev], 2); if (snd_mpu_irq[dev] != SNDRV_AUTO_IRQ) isapnp_resource_change(&pdev->irq_resource[0], snd_mpu_irq[dev], 1); if (pdev->activate(pdev)<0) { snd_mpu_port[dev] = SNDRV_AUTO_PORT; snd_mpu_irq[dev] = SNDRV_AUTO_IRQ; printk(KERN_ERR IDENT " isapnp configure failed for MPU (out of resources?)\n"); } else { snd_mpu_port[dev] = pdev->resource[0].start; if (pdev->irq_resource[0].flags & IORESOURCE_IRQ) { snd_mpu_irq[dev] = pdev->irq_resource[0].start; } else { snd_mpu_irq[dev] = -1; /* disable interrupt */ } } snd_printdd("isapnp MPU: port=0x%lx, irq=%i\n", snd_mpu_port[dev], snd_mpu_irq[dev]); } return 0;}static void snd_card_cs4236_deactivate(struct snd_card_cs4236 *acard){ if (acard->wss) { acard->wss->deactivate(acard->wss); acard->wss = NULL; } if (acard->ctrl) { acard->ctrl->deactivate(acard->ctrl); acard->ctrl = NULL; } if (acard->mpu) { acard->mpu->deactivate(acard->mpu); acard->mpu = NULL; }}#endifstatic void snd_card_cs4236_free(snd_card_t *card){ struct snd_card_cs4236 *acard = (struct snd_card_cs4236 *)card->private_data; if (acard) {#ifdef __ISAPNP__ snd_card_cs4236_deactivate(acard);#endif if (acard->res_sb_port) { release_resource(acard->res_sb_port); kfree_nocheck(acard->res_sb_port); } }}static int __init snd_card_cs4236_probe(int dev){ snd_card_t *card; struct snd_card_cs4236 *acard; snd_pcm_t *pcm = NULL; cs4231_t *chip; opl3_t *opl3; int err;#ifdef __ISAPNP__ if (!snd_isapnp[dev]) {#endif if (snd_port[dev] == SNDRV_AUTO_PORT) { snd_printk("specify snd_port\n"); return -EINVAL; } if (snd_cport[dev] == SNDRV_AUTO_PORT) { snd_printk("specify snd_cport\n"); return -EINVAL; }#ifdef __ISAPNP__ }#endif card = snd_card_new(snd_index[dev], snd_id[dev], THIS_MODULE, sizeof(struct snd_card_cs4236)); if (card == NULL) return -ENOMEM; acard = (struct snd_card_cs4236 *)card->private_data; card->private_free = snd_card_cs4236_free;#ifdef __ISAPNP__ if (snd_isapnp[dev] && (err = snd_card_cs4236_isapnp(dev, acard))<0) { printk(KERN_ERR "isapnp detection failed and probing for " IDENT " is not supported\n"); snd_card_free(card); return -ENXIO; }#endif if (snd_mpu_port[dev] < 0) snd_mpu_port[dev] = SNDRV_AUTO_PORT; if (snd_fm_port[dev] < 0) snd_fm_port[dev] = SNDRV_AUTO_PORT; if (snd_sb_port[dev] < 0) snd_sb_port[dev] = SNDRV_AUTO_PORT; if (snd_sb_port[dev] != SNDRV_AUTO_PORT) if ((acard->res_sb_port = request_region(snd_sb_port[dev], 16, IDENT " SB")) == NULL) { printk(KERN_ERR IDENT ": unable to register SB port at 0x%lx\n", snd_sb_port[dev]); snd_card_free(card); return -ENOMEM; }#ifdef CS4232 if ((err = snd_cs4231_create(card, snd_port[dev], snd_cport[dev], snd_irq[dev], snd_dma1[dev], snd_dma2[dev], CS4231_HW_DETECT, 0, &chip)) < 0) { snd_card_free(card); return err; } if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) { snd_card_free(card); return err; } if ((err = snd_cs4231_mixer(chip)) < 0) { snd_card_free(card); return err; }#else /* CS4236 */ if ((err = snd_cs4236_create(card, snd_port[dev], snd_cport[dev], snd_irq[dev], snd_dma1[dev], snd_dma2[dev], CS4231_HW_DETECT, 0, &chip)) < 0) { snd_card_free(card); return err; } if ((err = snd_cs4236_pcm(chip, 0, &pcm)) < 0) { snd_card_free(card); return err; } if ((err = snd_cs4236_mixer(chip)) < 0) { snd_card_free(card); return err; }#endif if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0) { snd_card_free(card); return err; } if (snd_fm_port[dev] != SNDRV_AUTO_PORT) { if (snd_opl3_create(card, snd_fm_port[dev], snd_fm_port[dev] + 2, OPL3_HW_OPL3_CS, 0, &opl3) < 0) { printk(KERN_ERR IDENT ": OPL3 not detected\n"); } else { if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { snd_card_free(card); return err; } } } if (snd_mpu_irq[dev] >= 0 && snd_mpu_irq[dev] != SNDRV_AUTO_IRQ) { if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232, snd_mpu_port[dev], 0, snd_mpu_irq[dev], snd_mpu_irq[dev] >= 0 ? SA_INTERRUPT : 0, NULL) < 0) printk(KERN_ERR IDENT ": MPU401 not detected\n"); } strcpy(card->driver, pcm->name); strcpy(card->shortname, pcm->name); sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port, snd_irq[dev], snd_dma1[dev]); if (snd_dma1[dev] >= 0) sprintf(card->longname + strlen(card->longname), "&%d", snd_dma2[dev]); if ((err = snd_card_register(card)) < 0) { snd_card_free(card); return err; } snd_cs4236_cards[dev] = card; return 0;}#ifdef __ISAPNP__static int __init snd_cs4236_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]) continue; snd_cs4236_isapnp_cards[dev] = card; snd_cs4236_isapnp_id[dev] = id; res = snd_card_cs4236_probe(dev); if (res < 0) return res; dev++; return 0; } return -ENODEV;}#endif /* __ISAPNP__ */static int __init alsa_card_cs423x_init(void){ int dev, cards = 0; for (dev = 0; dev < SNDRV_CARDS; dev++) { if (!snd_enable[dev]) continue;#ifdef __ISAPNP__ if (snd_isapnp[dev]) continue;#endif if (snd_card_cs4236_probe(dev) >= 0) cards++; }#ifdef __ISAPNP__ cards += isapnp_probe_cards(snd_card_pnpids, snd_cs4236_isapnp_detect);#endif if (!cards) {#ifdef MODULE printk(KERN_ERR IDENT " soundcard not found or device busy\n");#endif return -ENODEV; } return 0;}static void __exit alsa_card_cs423x_exit(void){ int idx; for (idx = 0; idx < SNDRV_CARDS; idx++) snd_card_free(snd_cs4236_cards[idx]);}module_init(alsa_card_cs423x_init)module_exit(alsa_card_cs423x_exit)#ifndef MODULE/* format is: snd-cs4232=snd_enable,snd_index,snd_id,snd_isapnp,snd_port, snd_cport,snd_mpu_port,snd_fm_port,snd_sb_port, snd_irq,snd_mpu_irq,snd_dma1,snd_dma1_size, snd_dma2,snd_dma2_size *//* format is: snd-cs4236=snd_enable,snd_index,snd_id,snd_isapnp,snd_port, snd_cport,snd_mpu_port,snd_fm_port,snd_sb_port, snd_irq,snd_mpu_irq,snd_dma1,snd_dma1_size, snd_dma2,snd_dma2_size */static int __init alsa_card_cs423x_setup(char *str){ static unsigned __initdata nr_dev = 0; int __attribute__ ((__unused__)) pnp = 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_cport[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,(int *)&snd_sb_port[nr_dev]) == 2 && get_option(&str,&snd_irq[nr_dev]) == 2 && get_option(&str,&snd_mpu_irq[nr_dev]) == 2 && get_option(&str,&snd_dma1[nr_dev]) == 2 && get_option(&str,&snd_dma2[nr_dev]) == 2);#ifdef __ISAPNP__ if (pnp != INT_MAX) snd_isapnp[nr_dev] = pnp;#endif nr_dev++; return 1;}#ifdef CS4232__setup("snd-cs4232=", alsa_card_cs423x_setup);#else /* CS4236 */__setup("snd-cs4236=", alsa_card_cs423x_setup);#endif#endif /* ifndef MODULE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -