aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa/opl3sa2.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2005-11-17 11:11:53 -0500
committerJaroslav Kysela <perex@suse.cz>2006-01-03 06:28:27 -0500
commit704e05204c623136ea12411dc4286d1caea6cd7c (patch)
tree3527413100be5eb599325eca50a933539fab6cf2 /sound/isa/opl3sa2.c
parentacdcbc15426b91b0041756a92ea4932c60def189 (diff)
[ALSA] opl3sa2 - Use platform_device
Modules: OPL3SA2 driver Rewrite the probe/remove with platform_device. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/isa/opl3sa2.c')
-rw-r--r--sound/isa/opl3sa2.c428
1 files changed, 228 insertions, 200 deletions
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index a343af70f519..b923de9b321d 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -21,6 +21,8 @@
21 21
22#include <sound/driver.h> 22#include <sound/driver.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/err.h>
25#include <linux/platform_device.h>
24#include <linux/interrupt.h> 26#include <linux/interrupt.h>
25#include <linux/pm.h> 27#include <linux/pm.h>
26#include <linux/slab.h> 28#include <linux/slab.h>
@@ -126,21 +128,12 @@ struct snd_opl3sa2 {
126 struct snd_hwdep *synth; 128 struct snd_hwdep *synth;
127 struct snd_rawmidi *rmidi; 129 struct snd_rawmidi *rmidi;
128 struct snd_cs4231 *cs4231; 130 struct snd_cs4231 *cs4231;
129#ifdef CONFIG_PNP
130 struct pnp_dev *dev;
131#endif
132 unsigned char ctlregs[0x20]; 131 unsigned char ctlregs[0x20];
133 int ymode; /* SL added */ 132 int ymode; /* SL added */
134 struct snd_kcontrol *master_switch; 133 struct snd_kcontrol *master_switch;
135 struct snd_kcontrol *master_volume; 134 struct snd_kcontrol *master_volume;
136#ifdef CONFIG_PM
137 void (*cs4231_suspend)(struct snd_cs4231 *);
138 void (*cs4231_resume)(struct snd_cs4231 *);
139#endif
140}; 135};
141 136
142static struct snd_card *snd_opl3sa2_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
143
144#define PFX "opl3sa2: " 137#define PFX "opl3sa2: "
145 138
146#ifdef CONFIG_PNP 139#ifdef CONFIG_PNP
@@ -539,11 +532,10 @@ static int __init snd_opl3sa2_mixer(struct snd_opl3sa2 *chip)
539#ifdef CONFIG_PM 532#ifdef CONFIG_PM
540static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state) 533static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state)
541{ 534{
542 struct snd_opl3sa2 *chip = card->pm_private_data; 535 struct snd_opl3sa2 *chip = card->private_data;
543
544 snd_pcm_suspend_all(chip->cs4231->pcm); /* stop before saving regs */
545 chip->cs4231_suspend(chip->cs4231);
546 536
537 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
538 chip->cs4231->suspend(chip->cs4231);
547 /* power down */ 539 /* power down */
548 snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3); 540 snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3);
549 541
@@ -552,7 +544,7 @@ static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state)
552 544
553static int snd_opl3sa2_resume(struct snd_card *card) 545static int snd_opl3sa2_resume(struct snd_card *card)
554{ 546{
555 struct snd_opl3sa2 *chip = card->pm_private_data; 547 struct snd_opl3sa2 *chip = card->private_data;
556 int i; 548 int i;
557 549
558 /* power up */ 550 /* power up */
@@ -568,23 +560,20 @@ static int snd_opl3sa2_resume(struct snd_card *card)
568 snd_opl3sa2_write(chip, i, chip->ctlregs[i]); 560 snd_opl3sa2_write(chip, i, chip->ctlregs[i]);
569 } 561 }
570 /* restore cs4231 */ 562 /* restore cs4231 */
571 chip->cs4231_resume(chip->cs4231); 563 chip->cs4231->resume(chip->cs4231);
572 564
565 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
573 return 0; 566 return 0;
574} 567}
575#endif /* CONFIG_PM */ 568#endif /* CONFIG_PM */
576 569
577#ifdef CONFIG_PNP 570#ifdef CONFIG_PNP
578static int __init snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip, 571static int __init snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip,
579 struct pnp_dev *pdev, 572 struct pnp_dev *pdev)
580 int isapnp)
581{ 573{
582 struct pnp_resource_table * cfg; 574 struct pnp_resource_table * cfg;
583 int err; 575 int err;
584 576
585 if (!isapnp && pnp_device_is_isapnp(pdev))
586 return -ENOENT; /* we have another procedure - card */
587
588 cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL); 577 cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
589 if (!cfg) 578 if (!cfg)
590 return -ENOMEM; 579 return -ENOMEM;
@@ -607,7 +596,7 @@ static int __init snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip,
607 if (irq[dev] != SNDRV_AUTO_IRQ) 596 if (irq[dev] != SNDRV_AUTO_IRQ)
608 pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1); 597 pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1);
609 err = pnp_manual_config_dev(pdev, cfg, 0); 598 err = pnp_manual_config_dev(pdev, cfg, 0);
610 if (err < 0 && isapnp) 599 if (err < 0)
611 snd_printk(KERN_ERR "PnP manual resources are invalid, using auto config\n"); 600 snd_printk(KERN_ERR "PnP manual resources are invalid, using auto config\n");
612 err = pnp_activate_dev(pdev); 601 err = pnp_activate_dev(pdev);
613 if (err < 0) { 602 if (err < 0) {
@@ -628,111 +617,47 @@ static int __init snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip,
628 snd_printdd("%sPnP OPL3-SA: control port=0x%lx, dma1=%i, dma2=%i, irq=%i\n", 617 snd_printdd("%sPnP OPL3-SA: control port=0x%lx, dma1=%i, dma2=%i, irq=%i\n",
629 pnp_device_is_pnpbios(pdev) ? "BIOS" : "ISA", port[dev], dma1[dev], dma2[dev], irq[dev]); 618 pnp_device_is_pnpbios(pdev) ? "BIOS" : "ISA", port[dev], dma1[dev], dma2[dev], irq[dev]);
630 kfree(cfg); 619 kfree(cfg);
631 chip->dev = pdev;
632 return 0; 620 return 0;
633} 621}
634
635static int __init snd_opl3sa2_cpnp(int dev, struct snd_opl3sa2 *chip,
636 struct pnp_card_link *card,
637 const struct pnp_card_device_id *id)
638{
639 struct pnp_dev *pdev;
640 struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
641
642 if (!cfg)
643 return -ENOMEM;
644 pdev = pnp_request_card_device(card, id->devs[0].id, NULL);
645 if (pdev == NULL) {
646 kfree(cfg);
647 return -EBUSY;
648 }
649 return snd_opl3sa2_pnp(dev, chip, pdev, 1);
650}
651#endif /* CONFIG_PNP */ 622#endif /* CONFIG_PNP */
652 623
653static int snd_opl3sa2_free(struct snd_opl3sa2 *chip) 624static void snd_opl3sa2_free(struct snd_card *card)
654{ 625{
626 struct snd_opl3sa2 *chip = card->private_data;
655 if (chip->irq >= 0) 627 if (chip->irq >= 0)
656 free_irq(chip->irq, (void *)chip); 628 free_irq(chip->irq, (void *)chip);
657 release_and_free_resource(chip->res_port); 629 release_and_free_resource(chip->res_port);
658 kfree(chip);
659 return 0;
660} 630}
661 631
662static int snd_opl3sa2_dev_free(struct snd_device *device) 632static struct snd_card *snd_opl3sa2_card_new(int dev)
663{ 633{
664 struct snd_opl3sa2 *chip = device->device_data;
665 return snd_opl3sa2_free(chip);
666}
667
668#ifdef CONFIG_PNP
669#define is_isapnp_selected(dev) isapnp[dev]
670#else
671#define is_isapnp_selected(dev) 0
672#endif
673
674static int __devinit snd_opl3sa2_probe(int dev,
675 struct pnp_dev *pdev,
676 struct pnp_card_link *pcard,
677 const struct pnp_card_device_id *pid)
678{
679 int xirq, xdma1, xdma2;
680 struct snd_card *card; 634 struct snd_card *card;
681 struct snd_opl3sa2 *chip; 635 struct snd_opl3sa2 *chip;
682 struct snd_cs4231 *cs4231;
683 struct snd_opl3 *opl3;
684 static struct snd_device_ops ops = {
685 .dev_free = snd_opl3sa2_dev_free,
686 };
687 int err;
688 636
689 if (! is_isapnp_selected(dev)) { 637 card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct snd_opl3sa2));
690 if (port[dev] == SNDRV_AUTO_PORT) {
691 snd_printk(KERN_ERR PFX "specify port\n");
692 return -EINVAL;
693 }
694 if (wss_port[dev] == SNDRV_AUTO_PORT) {
695 snd_printk(KERN_ERR PFX "specify wss_port\n");
696 return -EINVAL;
697 }
698 if (fm_port[dev] == SNDRV_AUTO_PORT) {
699 snd_printk(KERN_ERR PFX "specify fm_port\n");
700 return -EINVAL;
701 }
702 if (midi_port[dev] == SNDRV_AUTO_PORT) {
703 snd_printk(KERN_ERR PFX "specify midi_port\n");
704 return -EINVAL;
705 }
706 }
707
708 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
709 if (card == NULL) 638 if (card == NULL)
710 return -ENOMEM; 639 return NULL;
711 strcpy(card->driver, "OPL3SA2"); 640 strcpy(card->driver, "OPL3SA2");
712 strcpy(card->shortname, "Yamaha OPL3-SA2"); 641 strcpy(card->shortname, "Yamaha OPL3-SA2");
713 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 642 chip = card->private_data;
714 if (chip == NULL) {
715 err = -ENOMEM;
716 goto __error;
717 }
718 spin_lock_init(&chip->reg_lock); 643 spin_lock_init(&chip->reg_lock);
719 chip->irq = -1; 644 chip->irq = -1;
720 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
721 goto __error;
722#ifdef CONFIG_PNP
723 if (pdev) {
724 if ((err = snd_opl3sa2_pnp(dev, chip, pdev, 0)) < 0)
725 goto __error;
726 snd_card_set_dev(card, &pdev->dev);
727 }
728 if (pcard) {
729 if ((err = snd_opl3sa2_cpnp(dev, chip, pcard, pid)) < 0)
730 goto __error;
731 snd_card_set_dev(card, &pcard->card->dev);
732 }
733#endif
734 chip->ymode = opl3sa3_ymode[dev] & 0x03 ; /* initialise this card from supplied (or default) parameter*/
735 chip->card = card; 645 chip->card = card;
646 card->private_free = snd_opl3sa2_free;
647 return card;
648}
649
650static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev)
651{
652 int xirq, xdma1, xdma2;
653 struct snd_opl3sa2 *chip;
654 struct snd_cs4231 *cs4231;
655 struct snd_opl3 *opl3;
656 int err;
657
658 /* initialise this card from supplied (or default) parameter*/
659 chip = card->private_data;
660 chip->ymode = opl3sa3_ymode[dev] & 0x03 ;
736 chip->port = port[dev]; 661 chip->port = port[dev];
737 xirq = irq[dev]; 662 xirq = irq[dev];
738 xdma1 = dma1[dev]; 663 xdma1 = dma1[dev];
@@ -740,11 +665,10 @@ static int __devinit snd_opl3sa2_probe(int dev,
740 if (xdma2 < 0) 665 if (xdma2 < 0)
741 chip->single_dma = 1; 666 chip->single_dma = 1;
742 if ((err = snd_opl3sa2_detect(chip)) < 0) 667 if ((err = snd_opl3sa2_detect(chip)) < 0)
743 goto __error; 668 return err;
744 if (request_irq(xirq, snd_opl3sa2_interrupt, SA_INTERRUPT, "OPL3-SA2", (void *)chip)) { 669 if (request_irq(xirq, snd_opl3sa2_interrupt, SA_INTERRUPT, "OPL3-SA2", chip)) {
745 snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq); 670 snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq);
746 err = -ENODEV; 671 return -ENODEV;
747 goto __error;
748 } 672 }
749 chip->irq = xirq; 673 chip->irq = xirq;
750 if ((err = snd_cs4231_create(card, 674 if ((err = snd_cs4231_create(card,
@@ -754,163 +678,273 @@ static int __devinit snd_opl3sa2_probe(int dev,
754 CS4231_HWSHARE_IRQ, 678 CS4231_HWSHARE_IRQ,
755 &cs4231)) < 0) { 679 &cs4231)) < 0) {
756 snd_printd("Oops, WSS not detected at 0x%lx\n", wss_port[dev] + 4); 680 snd_printd("Oops, WSS not detected at 0x%lx\n", wss_port[dev] + 4);
757 goto __error; 681 return err;
758 } 682 }
759 chip->cs4231 = cs4231; 683 chip->cs4231 = cs4231;
760 if ((err = snd_cs4231_pcm(cs4231, 0, NULL)) < 0) 684 if ((err = snd_cs4231_pcm(cs4231, 0, NULL)) < 0)
761 goto __error; 685 return err;
762 if ((err = snd_cs4231_mixer(cs4231)) < 0) 686 if ((err = snd_cs4231_mixer(cs4231)) < 0)
763 goto __error; 687 return err;
764 if ((err = snd_opl3sa2_mixer(chip)) < 0) 688 if ((err = snd_opl3sa2_mixer(chip)) < 0)
765 goto __error; 689 return err;
766 if ((err = snd_cs4231_timer(cs4231, 0, NULL)) < 0) 690 if ((err = snd_cs4231_timer(cs4231, 0, NULL)) < 0)
767 goto __error; 691 return err;
768 if (fm_port[dev] >= 0x340 && fm_port[dev] < 0x400) { 692 if (fm_port[dev] >= 0x340 && fm_port[dev] < 0x400) {
769 if ((err = snd_opl3_create(card, fm_port[dev], 693 if ((err = snd_opl3_create(card, fm_port[dev],
770 fm_port[dev] + 2, 694 fm_port[dev] + 2,
771 OPL3_HW_OPL3, 0, &opl3)) < 0) 695 OPL3_HW_OPL3, 0, &opl3)) < 0)
772 goto __error; 696 return err;
773 if ((err = snd_opl3_timer_new(opl3, 1, 2)) < 0) 697 if ((err = snd_opl3_timer_new(opl3, 1, 2)) < 0)
774 goto __error; 698 return err;
775 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, &chip->synth)) < 0) 699 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, &chip->synth)) < 0)
776 goto __error; 700 return err;
777 } 701 }
778 if (midi_port[dev] >= 0x300 && midi_port[dev] < 0x340) { 702 if (midi_port[dev] >= 0x300 && midi_port[dev] < 0x340) {
779 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_OPL3SA2, 703 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_OPL3SA2,
780 midi_port[dev], 0, 704 midi_port[dev], 0,
781 xirq, 0, &chip->rmidi)) < 0) 705 xirq, 0, &chip->rmidi)) < 0)
782 goto __error; 706 return err;
783 } 707 }
784#ifdef CONFIG_PM
785 chip->cs4231_suspend = chip->cs4231->suspend;
786 chip->cs4231_resume = chip->cs4231->resume;
787 /* now clear callbacks for cs4231 */
788 chip->cs4231->suspend = NULL;
789 chip->cs4231->resume = NULL;
790 snd_card_set_isa_pm_callback(card, snd_opl3sa2_suspend, snd_opl3sa2_resume, chip);
791#endif
792
793 sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", 708 sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
794 card->shortname, chip->port, xirq, xdma1); 709 card->shortname, chip->port, xirq, xdma1);
795 if (dma2 >= 0) 710 if (dma2 >= 0)
796 sprintf(card->longname + strlen(card->longname), "&%d", xdma2); 711 sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
797 712
798 if ((err = snd_card_set_generic_dev(card)) < 0) 713 return snd_card_register(card);
799 goto __error;
800
801 if ((err = snd_card_register(card)) < 0)
802 goto __error;
803
804 if (pdev)
805 pnp_set_drvdata(pdev, card);
806 else if (pcard)
807 pnp_set_card_drvdata(pcard, card);
808 else
809 snd_opl3sa2_legacy[dev] = card;
810 return 0;
811
812 __error:
813 snd_card_free(card);
814 return err;
815} 714}
816 715
817#ifdef CONFIG_PNP 716#ifdef CONFIG_PNP
818static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev, 717static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev,
819 const struct pnp_device_id *id) 718 const struct pnp_device_id *id)
820{ 719{
821 static int dev; 720 static int dev;
822 int res; 721 int err;
722 struct snd_card *card;
723
724 if (pnp_device_is_isapnp(pdev))
725 return -ENOENT; /* we have another procedure - card */
726 for (; dev < SNDRV_CARDS; dev++) {
727 if (enable[dev] && isapnp[dev])
728 break;
729 }
730 if (dev >= SNDRV_CARDS)
731 return -ENODEV;
823 732
824 for ( ; dev < SNDRV_CARDS; dev++) { 733 card = snd_opl3sa2_card_new(dev);
825 if (!enable[dev] || !isapnp[dev]) 734 if (! card)
826 continue; 735 return -ENOMEM;
827 res = snd_opl3sa2_probe(dev, pdev, NULL, NULL); 736 if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) {
828 if (res < 0) 737 snd_card_free(card);
829 return res; 738 return err;
830 dev++; 739 }
831 return 0; 740 snd_card_set_dev(card, &pdev->dev);
832 } 741 if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
833 return -ENODEV; 742 snd_card_free(card);
743 return err;
744 }
745 pnp_set_drvdata(pdev, card);
746 dev++;
747 return 0;
834} 748}
835 749
836static void __devexit snd_opl3sa2_pnp_remove(struct pnp_dev * pdev) 750static void __devexit snd_opl3sa2_pnp_remove(struct pnp_dev * pdev)
837{ 751{
838 struct snd_card *card = (struct snd_card *) pnp_get_drvdata(pdev); 752 snd_card_free(pnp_get_drvdata(pdev));
839 753 pnp_set_drvdata(pdev, NULL);
840 snd_card_disconnect(card);
841 snd_card_free_in_thread(card);
842} 754}
843 755
756#ifdef CONFIG_PM
757static int snd_opl3sa2_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
758{
759 return snd_opl3sa2_suspend(pnp_get_drvdata(pdev), state);
760}
761static int snd_opl3sa2_pnp_resume(struct pnp_dev *pdev)
762{
763 return snd_opl3sa2_resume(pnp_get_drvdata(pdev));
764}
765#endif
766
844static struct pnp_driver opl3sa2_pnp_driver = { 767static struct pnp_driver opl3sa2_pnp_driver = {
845 .name = "opl3sa2-pnpbios", 768 .name = "opl3sa2-pnpbios",
846 .id_table = snd_opl3sa2_pnpbiosids, 769 .id_table = snd_opl3sa2_pnpbiosids,
847 .probe = snd_opl3sa2_pnp_detect, 770 .probe = snd_opl3sa2_pnp_detect,
848 .remove = __devexit_p(snd_opl3sa2_pnp_remove), 771 .remove = __devexit_p(snd_opl3sa2_pnp_remove),
772#ifdef CONFIG_PM
773 .suspend = snd_opl3sa2_pnp_suspend,
774 .resume = snd_opl3sa2_pnp_resume,
775#endif
849}; 776};
850 777
851static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *card, 778static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard,
852 const struct pnp_card_device_id *id) 779 const struct pnp_card_device_id *id)
853{ 780{
854 static int dev; 781 static int dev;
855 int res; 782 struct pnp_dev *pdev;
783 int err;
784 struct snd_card *card;
856 785
857 for ( ; dev < SNDRV_CARDS; dev++) { 786 pdev = pnp_request_card_device(pcard, id->devs[0].id, NULL);
858 if (!enable[dev]) 787 if (pdev == NULL)
859 continue; 788 return -EBUSY;
860 if (is_isapnp_selected(dev)) 789 for (; dev < SNDRV_CARDS; dev++) {
861 continue; 790 if (enable[dev] && isapnp[dev])
862 res = snd_opl3sa2_probe(dev, NULL, card, id); 791 break;
863 if (res < 0) 792 }
864 return res; 793 if (dev >= SNDRV_CARDS)
865 dev++; 794 return -ENODEV;
866 return 0; 795
867 } 796 card = snd_opl3sa2_card_new(dev);
868 return -ENODEV; 797 if (! card)
798 return -ENOMEM;
799 if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) {
800 snd_card_free(card);
801 return err;
802 }
803 snd_card_set_dev(card, &pdev->dev);
804 if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
805 snd_card_free(card);
806 return err;
807 }
808 pnp_set_card_drvdata(pcard, card);
809 dev++;
810 return 0;
869} 811}
870 812
871static void __devexit snd_opl3sa2_pnp_cremove(struct pnp_card_link * pcard) 813static void __devexit snd_opl3sa2_pnp_cremove(struct pnp_card_link * pcard)
872{ 814{
873 struct snd_card *card = (struct snd_card *) pnp_get_card_drvdata(pcard); 815 snd_card_free(pnp_get_card_drvdata(pcard));
874 816 pnp_set_card_drvdata(pcard, NULL);
875 snd_card_disconnect(card);
876 snd_card_free_in_thread(card);
877} 817}
878 818
819#ifdef CONFIG_PM
820static int snd_opl3sa2_pnp_csuspend(struct pnp_card_link *pcard, pm_message_t state)
821{
822 return snd_opl3sa2_suspend(pnp_get_card_drvdata(pcard), state);
823}
824static int snd_opl3sa2_pnp_cresume(struct pnp_card_link *pcard)
825{
826 return snd_opl3sa2_resume(pnp_get_card_drvdata(pcard));
827}
828#endif
829
879static struct pnp_card_driver opl3sa2_pnpc_driver = { 830static struct pnp_card_driver opl3sa2_pnpc_driver = {
880 .flags = PNP_DRIVER_RES_DISABLE, 831 .flags = PNP_DRIVER_RES_DISABLE,
881 .name = "opl3sa2", 832 .name = "opl3sa2",
882 .id_table = snd_opl3sa2_pnpids, 833 .id_table = snd_opl3sa2_pnpids,
883 .probe = snd_opl3sa2_pnp_cdetect, 834 .probe = snd_opl3sa2_pnp_cdetect,
884 .remove = __devexit_p(snd_opl3sa2_pnp_cremove), 835 .remove = __devexit_p(snd_opl3sa2_pnp_cremove),
836#ifdef CONFIG_PM
837 .suspend = snd_opl3sa2_pnp_csuspend,
838 .resume = snd_opl3sa2_pnp_cresume,
839#endif
885}; 840};
886#endif /* CONFIG_PNP */ 841#endif /* CONFIG_PNP */
887 842
843static int __init snd_opl3sa2_nonpnp_probe(struct platform_device *pdev)
844{
845 struct snd_card *card;
846 int err;
847 int dev = pdev->id;
848
849 if (port[dev] == SNDRV_AUTO_PORT) {
850 snd_printk(KERN_ERR PFX "specify port\n");
851 return -EINVAL;
852 }
853 if (wss_port[dev] == SNDRV_AUTO_PORT) {
854 snd_printk(KERN_ERR PFX "specify wss_port\n");
855 return -EINVAL;
856 }
857 if (fm_port[dev] == SNDRV_AUTO_PORT) {
858 snd_printk(KERN_ERR PFX "specify fm_port\n");
859 return -EINVAL;
860 }
861 if (midi_port[dev] == SNDRV_AUTO_PORT) {
862 snd_printk(KERN_ERR PFX "specify midi_port\n");
863 return -EINVAL;
864 }
865
866 card = snd_opl3sa2_card_new(dev);
867 if (! card)
868 return -ENOMEM;
869 snd_card_set_dev(card, &pdev->dev);
870 if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
871 snd_card_free(card);
872 return err;
873 }
874 platform_set_drvdata(pdev, card);
875 return 0;
876}
877
878static int snd_opl3sa2_nonpnp_remove(struct platform_device *devptr)
879{
880 snd_card_free(platform_get_drvdata(devptr));
881 platform_set_drvdata(devptr, NULL);
882 return 0;
883}
884
885#ifdef CONFIG_PM
886static int snd_opl3sa2_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
887{
888 return snd_opl3sa2_suspend(platform_get_drvdata(dev), state);
889}
890
891static int snd_opl3sa2_nonpnp_resume(struct platform_device *dev)
892{
893 return snd_opl3sa2_resume(platform_get_drvdata(dev));
894}
895#endif
896
897#define OPL3SA2_DRIVER "snd_opl3sa2"
898
899static struct platform_driver snd_opl3sa2_nonpnp_driver = {
900 .probe = snd_opl3sa2_nonpnp_probe,
901 .remove = snd_opl3sa2_nonpnp_remove,
902#ifdef CONFIG_PM
903 .suspend = snd_opl3sa2_nonpnp_suspend,
904 .resume = snd_opl3sa2_nonpnp_resume,
905#endif
906 .driver = {
907 .name = OPL3SA2_DRIVER
908 },
909};
910
888static int __init alsa_card_opl3sa2_init(void) 911static int __init alsa_card_opl3sa2_init(void)
889{ 912{
890 int dev, cards = 0; 913 int i, err, cards = 0;
891 914
892 for (dev = 0; dev < SNDRV_CARDS; dev++) { 915 if ((err = platform_driver_register(&snd_opl3sa2_nonpnp_driver)) < 0)
893 if (!enable[dev]) 916 return err;
894 continue; 917
918 for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
919 struct platform_device *device;
895#ifdef CONFIG_PNP 920#ifdef CONFIG_PNP
896 if (isapnp[dev]) 921 if (isapnp[i])
897 continue; 922 continue;
898#endif 923#endif
899 if (snd_opl3sa2_probe(dev, NULL, NULL, NULL) >= 0) 924 device = platform_device_register_simple(OPL3SA2_DRIVER,
900 cards++; 925 i, NULL, 0);
926 if (IS_ERR(device)) {
927 err = PTR_ERR(device);
928 platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
929 return err;
930 }
931 cards++;
901 } 932 }
902#ifdef CONFIG_PNP 933
903 cards += pnp_register_driver(&opl3sa2_pnp_driver); 934 err = pnp_register_driver(&opl3sa2_pnp_driver);
904 cards += pnp_register_card_driver(&opl3sa2_pnpc_driver); 935 if (err > 0)
905#endif 936 cards += err;
937 err = pnp_register_card_driver(&opl3sa2_pnpc_driver);
938 if (err > 0)
939 cards += err;
940
906 if (!cards) { 941 if (!cards) {
907#ifdef MODULE 942#ifdef MODULE
908 snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n"); 943 snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n");
909#endif 944#endif
910#ifdef CONFIG_PNP
911 pnp_unregister_card_driver(&opl3sa2_pnpc_driver); 945 pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
912 pnp_unregister_driver(&opl3sa2_pnp_driver); 946 pnp_unregister_driver(&opl3sa2_pnp_driver);
913#endif 947 platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
914 return -ENODEV; 948 return -ENODEV;
915 } 949 }
916 return 0; 950 return 0;
@@ -918,15 +952,9 @@ static int __init alsa_card_opl3sa2_init(void)
918 952
919static void __exit alsa_card_opl3sa2_exit(void) 953static void __exit alsa_card_opl3sa2_exit(void)
920{ 954{
921 int idx;
922
923#ifdef CONFIG_PNP
924 /* PnP cards first */
925 pnp_unregister_card_driver(&opl3sa2_pnpc_driver); 955 pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
926 pnp_unregister_driver(&opl3sa2_pnp_driver); 956 pnp_unregister_driver(&opl3sa2_pnp_driver);
927#endif 957 platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
928 for (idx = 0; idx < SNDRV_CARDS; idx++)
929 snd_card_free(snd_opl3sa2_legacy[idx]);
930} 958}
931 959
932module_init(alsa_card_opl3sa2_init) 960module_init(alsa_card_opl3sa2_init)