X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=sound%2Fisa%2Fopl3sa2.c;h=84ffa8f0f26d4e871756016e3886a19de580e558;hb=59b1b34f47e6c8ac8f00660db2cd34216819b400;hp=b923de9b321df2eca1c006947e53bc42df50c355;hpb=704e05204c623136ea12411dc4286d1caea6cd7c;p=~andy%2Flinux diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index b923de9b321..84ffa8f0f26 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -90,6 +90,12 @@ MODULE_PARM_DESC(dma2, "DMA2 # for OPL3-SA driver."); module_param_array(opl3sa3_ymode, int, NULL, 0444); MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi."); +static struct platform_device *platform_devices[SNDRV_CARDS]; +#ifdef CONFIG_PNP +static int pnp_registered; +static int pnpc_registered; +#endif + /* control ports */ #define OPL3SA2_PM_CTRL 0x01 #define OPL3SA2_SYS_CTRL 0x02 @@ -496,21 +502,29 @@ static int __init snd_opl3sa2_mixer(struct snd_opl3sa2 *chip) /* reassign AUX0 to CD */ strcpy(id1.name, "Aux Playback Switch"); strcpy(id2.name, "CD Playback Switch"); - if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) + if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) { + snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n"); return err; + } strcpy(id1.name, "Aux Playback Volume"); strcpy(id2.name, "CD Playback Volume"); - if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) + if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) { + snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n"); return err; + } /* reassign AUX1 to FM */ strcpy(id1.name, "Aux Playback Switch"); id1.index = 1; strcpy(id2.name, "FM Playback Switch"); - if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) + if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) { + snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n"); return err; + } strcpy(id1.name, "Aux Playback Volume"); strcpy(id2.name, "FM Playback Volume"); - if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) + if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) { + snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n"); return err; + } /* add OPL3SA2 controls */ for (idx = 0; idx < ARRAY_SIZE(snd_opl3sa2_controls); idx++) { if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_opl3sa2_controls[idx], chip))) < 0) @@ -575,8 +589,10 @@ static int __init snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip, int err; cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL); - if (!cfg) + if (!cfg) { + snd_printk(KERN_ERR PFX "cannot allocate pnp cfg\n"); return -ENOMEM; + } /* PnP initialization */ pnp_init_resource_table(cfg); if (sb_port[dev] != SNDRV_AUTO_PORT) @@ -597,7 +613,7 @@ static int __init snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip, pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1); err = pnp_manual_config_dev(pdev, cfg, 0); if (err < 0) - snd_printk(KERN_ERR "PnP manual resources are invalid, using auto config\n"); + snd_printk(KERN_WARNING "PnP manual resources are invalid, using auto config\n"); err = pnp_activate_dev(pdev); if (err < 0) { kfree(cfg); @@ -784,8 +800,11 @@ static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard, struct snd_card *card; pdev = pnp_request_card_device(pcard, id->devs[0].id, NULL); - if (pdev == NULL) + if (pdev == NULL) { + snd_printk(KERN_ERR PFX "can't get pnp device from id '%s'\n", + id->devs[0].id); return -EBUSY; + } for (; dev < SNDRV_CARDS; dev++) { if (enable[dev] && isapnp[dev]) break; @@ -908,6 +927,21 @@ static struct platform_driver snd_opl3sa2_nonpnp_driver = { }, }; +static void __init_or_module snd_opl3sa2_unregister_all(void) +{ + int i; + +#ifdef CONFIG_PNP + if (pnpc_registered) + pnp_unregister_card_driver(&opl3sa2_pnpc_driver); + if (pnp_registered) + pnp_unregister_driver(&opl3sa2_pnp_driver); +#endif + for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) + platform_device_unregister(platform_devices[i]); + platform_driver_unregister(&snd_opl3sa2_nonpnp_driver); +} + static int __init alsa_card_opl3sa2_init(void) { int i, err, cards = 0; @@ -925,36 +959,42 @@ static int __init alsa_card_opl3sa2_init(void) i, NULL, 0); if (IS_ERR(device)) { err = PTR_ERR(device); - platform_driver_unregister(&snd_opl3sa2_nonpnp_driver); - return err; + goto errout; } + platform_devices[i] = device; cards++; } +#ifdef CONFIG_PNP err = pnp_register_driver(&opl3sa2_pnp_driver); - if (err > 0) + if (err >= 0) { + pnp_registered = 1; cards += err; + } err = pnp_register_card_driver(&opl3sa2_pnpc_driver); - if (err > 0) + if (err >= 0) { + pnpc_registered = 1; cards += err; + } +#endif if (!cards) { #ifdef MODULE snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n"); #endif - pnp_unregister_card_driver(&opl3sa2_pnpc_driver); - pnp_unregister_driver(&opl3sa2_pnp_driver); - platform_driver_unregister(&snd_opl3sa2_nonpnp_driver); - return -ENODEV; + err = -ENODEV; + goto errout; } return 0; + + errout: + snd_opl3sa2_unregister_all(); + return err; } static void __exit alsa_card_opl3sa2_exit(void) { - pnp_unregister_card_driver(&opl3sa2_pnpc_driver); - pnp_unregister_driver(&opl3sa2_pnp_driver); - platform_driver_unregister(&snd_opl3sa2_nonpnp_driver); + snd_opl3sa2_unregister_all(); } module_init(alsa_card_opl3sa2_init)