diff options
Diffstat (limited to 'sound/isa/gus/interwave.c')
-rw-r--r-- | sound/isa/gus/interwave.c | 292 |
1 files changed, 158 insertions, 134 deletions
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index f2e9c5073548..67a5f7402453 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c | |||
@@ -23,19 +23,20 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <sound/driver.h> | 25 | #include <sound/driver.h> |
26 | #include <asm/dma.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/err.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/delay.h> | ||
29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
30 | #include <linux/pnp.h> | 31 | #include <linux/pnp.h> |
31 | #include <linux/moduleparam.h> | 32 | #include <linux/moduleparam.h> |
33 | #include <asm/dma.h> | ||
32 | #include <sound/core.h> | 34 | #include <sound/core.h> |
33 | #include <sound/gus.h> | 35 | #include <sound/gus.h> |
34 | #include <sound/cs4231.h> | 36 | #include <sound/cs4231.h> |
35 | #ifdef SNDRV_STB | 37 | #ifdef SNDRV_STB |
36 | #include <sound/tea6330t.h> | 38 | #include <sound/tea6330t.h> |
37 | #endif | 39 | #endif |
38 | #define SNDRV_LEGACY_AUTO_PROBE | ||
39 | #define SNDRV_LEGACY_FIND_FREE_IRQ | 40 | #define SNDRV_LEGACY_FIND_FREE_IRQ |
40 | #define SNDRV_LEGACY_FIND_FREE_DMA | 41 | #define SNDRV_LEGACY_FIND_FREE_DMA |
41 | #include <sound/initval.h> | 42 | #include <sound/initval.h> |
@@ -75,8 +76,12 @@ static int effect[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; | |||
75 | 76 | ||
76 | #ifdef SNDRV_STB | 77 | #ifdef SNDRV_STB |
77 | #define PFX "interwave-stb: " | 78 | #define PFX "interwave-stb: " |
79 | #define INTERWAVE_DRIVER "snd_interwave_stb" | ||
80 | #define INTERWAVE_PNP_DRIVER "interwave-stb" | ||
78 | #else | 81 | #else |
79 | #define PFX "interwave: " | 82 | #define PFX "interwave: " |
83 | #define INTERWAVE_DRIVER "snd_interwave" | ||
84 | #define INTERWAVE_PNP_DRIVER "interwave" | ||
80 | #endif | 85 | #endif |
81 | 86 | ||
82 | module_param_array(index, int, NULL, 0444); | 87 | module_param_array(index, int, NULL, 0444); |
@@ -128,7 +133,6 @@ struct snd_interwave { | |||
128 | #endif | 133 | #endif |
129 | }; | 134 | }; |
130 | 135 | ||
131 | static struct snd_card *snd_interwave_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; | ||
132 | 136 | ||
133 | #ifdef CONFIG_PNP | 137 | #ifdef CONFIG_PNP |
134 | 138 | ||
@@ -633,7 +637,7 @@ static int __devinit snd_interwave_pnp(int dev, struct snd_interwave *iwcard, | |||
633 | 637 | ||
634 | static void snd_interwave_free(struct snd_card *card) | 638 | static void snd_interwave_free(struct snd_card *card) |
635 | { | 639 | { |
636 | struct snd_interwave *iwcard = (struct snd_interwave *)card->private_data; | 640 | struct snd_interwave *iwcard = card->private_data; |
637 | 641 | ||
638 | if (iwcard == NULL) | 642 | if (iwcard == NULL) |
639 | return; | 643 | return; |
@@ -644,14 +648,26 @@ static void snd_interwave_free(struct snd_card *card) | |||
644 | free_irq(iwcard->irq, (void *)iwcard); | 648 | free_irq(iwcard->irq, (void *)iwcard); |
645 | } | 649 | } |
646 | 650 | ||
647 | static int __devinit snd_interwave_probe(int dev, struct pnp_card_link *pcard, | 651 | static struct snd_card *snd_interwave_card_new(int dev) |
648 | const struct pnp_card_device_id *pid) | ||
649 | { | 652 | { |
650 | static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; | ||
651 | static int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1}; | ||
652 | int xirq, xdma1, xdma2; | ||
653 | struct snd_card *card; | 653 | struct snd_card *card; |
654 | struct snd_interwave *iwcard; | 654 | struct snd_interwave *iwcard; |
655 | |||
656 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | ||
657 | sizeof(struct snd_interwave)); | ||
658 | if (card == NULL) | ||
659 | return NULL; | ||
660 | iwcard = card->private_data; | ||
661 | iwcard->card = card; | ||
662 | iwcard->irq = -1; | ||
663 | card->private_free = snd_interwave_free; | ||
664 | return card; | ||
665 | } | ||
666 | |||
667 | static int __devinit snd_interwave_probe(struct snd_card *card, int dev) | ||
668 | { | ||
669 | int xirq, xdma1, xdma2; | ||
670 | struct snd_interwave *iwcard = card->private_data; | ||
655 | struct snd_cs4231 *cs4231; | 671 | struct snd_cs4231 *cs4231; |
656 | struct snd_gus_card *gus; | 672 | struct snd_gus_card *gus; |
657 | #ifdef SNDRV_STB | 673 | #ifdef SNDRV_STB |
@@ -661,59 +677,23 @@ static int __devinit snd_interwave_probe(int dev, struct pnp_card_link *pcard, | |||
661 | char *str; | 677 | char *str; |
662 | int err; | 678 | int err; |
663 | 679 | ||
664 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | ||
665 | sizeof(struct snd_interwave)); | ||
666 | if (card == NULL) | ||
667 | return -ENOMEM; | ||
668 | iwcard = (struct snd_interwave *)card->private_data; | ||
669 | iwcard->card = card; | ||
670 | iwcard->irq = -1; | ||
671 | card->private_free = snd_interwave_free; | ||
672 | #ifdef CONFIG_PNP | ||
673 | if (isapnp[dev]) { | ||
674 | if ((err = snd_interwave_pnp(dev, iwcard, pcard, pid)) < 0) | ||
675 | goto _err; | ||
676 | snd_card_set_dev(card, &pcard->card->dev); | ||
677 | } | ||
678 | #endif | ||
679 | xirq = irq[dev]; | 680 | xirq = irq[dev]; |
680 | if (xirq == SNDRV_AUTO_IRQ) { | ||
681 | if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) { | ||
682 | snd_printk(KERN_ERR PFX "unable to find a free IRQ\n"); | ||
683 | err = -EBUSY; | ||
684 | goto _err; | ||
685 | } | ||
686 | } | ||
687 | xdma1 = dma1[dev]; | 681 | xdma1 = dma1[dev]; |
688 | if (xdma1 == SNDRV_AUTO_DMA) { | ||
689 | if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) { | ||
690 | snd_printk(KERN_ERR PFX "unable to find a free DMA1\n"); | ||
691 | err = -EBUSY; | ||
692 | goto _err; | ||
693 | } | ||
694 | } | ||
695 | xdma2 = dma2[dev]; | 682 | xdma2 = dma2[dev]; |
696 | if (xdma2 == SNDRV_AUTO_DMA) { | ||
697 | if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) { | ||
698 | snd_printk(KERN_ERR PFX "unable to find a free DMA2\n"); | ||
699 | err = -EBUSY; | ||
700 | goto _err; | ||
701 | } | ||
702 | } | ||
703 | 683 | ||
704 | if ((err = snd_gus_create(card, | 684 | if ((err = snd_gus_create(card, |
705 | port[dev], | 685 | port[dev], |
706 | -xirq, xdma1, xdma2, | 686 | -xirq, xdma1, xdma2, |
707 | 0, 32, | 687 | 0, 32, |
708 | pcm_channels[dev], effect[dev], &gus)) < 0) | 688 | pcm_channels[dev], effect[dev], &gus)) < 0) |
709 | goto _err; | 689 | return err; |
710 | 690 | ||
711 | if ((err = snd_interwave_detect(iwcard, gus, dev | 691 | if ((err = snd_interwave_detect(iwcard, gus, dev |
712 | #ifdef SNDRV_STB | 692 | #ifdef SNDRV_STB |
713 | , &i2c_bus | 693 | , &i2c_bus |
714 | #endif | 694 | #endif |
715 | )) < 0) | 695 | )) < 0) |
716 | goto _err; | 696 | return err; |
717 | 697 | ||
718 | iwcard->gus_status_reg = gus->gf1.reg_irqstat; | 698 | iwcard->gus_status_reg = gus->gf1.reg_irqstat; |
719 | iwcard->pcm_status_reg = gus->gf1.port + 0x10c + 2; | 699 | iwcard->pcm_status_reg = gus->gf1.port + 0x10c + 2; |
@@ -721,12 +701,12 @@ static int __devinit snd_interwave_probe(int dev, struct pnp_card_link *pcard, | |||
721 | snd_interwave_init(dev, gus); | 701 | snd_interwave_init(dev, gus); |
722 | snd_interwave_detect_memory(gus); | 702 | snd_interwave_detect_memory(gus); |
723 | if ((err = snd_gus_initialize(gus)) < 0) | 703 | if ((err = snd_gus_initialize(gus)) < 0) |
724 | goto _err; | 704 | return err; |
725 | 705 | ||
726 | if (request_irq(xirq, snd_interwave_interrupt, SA_INTERRUPT, "InterWave", (void *)iwcard)) { | 706 | if (request_irq(xirq, snd_interwave_interrupt, SA_INTERRUPT, |
707 | "InterWave", iwcard)) { | ||
727 | snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq); | 708 | snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq); |
728 | err = -EBUSY; | 709 | return -EBUSY; |
729 | goto _err; | ||
730 | } | 710 | } |
731 | iwcard->irq = xirq; | 711 | iwcard->irq = xirq; |
732 | 712 | ||
@@ -738,26 +718,26 @@ static int __devinit snd_interwave_probe(int dev, struct pnp_card_link *pcard, | |||
738 | CS4231_HWSHARE_DMA1 | | 718 | CS4231_HWSHARE_DMA1 | |
739 | CS4231_HWSHARE_DMA2, | 719 | CS4231_HWSHARE_DMA2, |
740 | &cs4231)) < 0) | 720 | &cs4231)) < 0) |
741 | goto _err; | 721 | return err; |
742 | 722 | ||
743 | if ((err = snd_cs4231_pcm(cs4231, 0, &pcm)) < 0) | 723 | if ((err = snd_cs4231_pcm(cs4231, 0, &pcm)) < 0) |
744 | goto _err; | 724 | return err; |
745 | 725 | ||
746 | sprintf(pcm->name + strlen(pcm->name), " rev %c", gus->revision + 'A'); | 726 | sprintf(pcm->name + strlen(pcm->name), " rev %c", gus->revision + 'A'); |
747 | strcat(pcm->name, " (codec)"); | 727 | strcat(pcm->name, " (codec)"); |
748 | 728 | ||
749 | if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0) | 729 | if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0) |
750 | goto _err; | 730 | return err; |
751 | 731 | ||
752 | if ((err = snd_cs4231_mixer(cs4231)) < 0) | 732 | if ((err = snd_cs4231_mixer(cs4231)) < 0) |
753 | goto _err; | 733 | return err; |
754 | 734 | ||
755 | if (pcm_channels[dev] > 0) { | 735 | if (pcm_channels[dev] > 0) { |
756 | if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) | 736 | if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) |
757 | goto _err; | 737 | return err; |
758 | } | 738 | } |
759 | if ((err = snd_interwave_mixer(cs4231)) < 0) | 739 | if ((err = snd_interwave_mixer(cs4231)) < 0) |
760 | goto _err; | 740 | return err; |
761 | 741 | ||
762 | #ifdef SNDRV_STB | 742 | #ifdef SNDRV_STB |
763 | { | 743 | { |
@@ -769,19 +749,19 @@ static int __devinit snd_interwave_probe(int dev, struct pnp_card_link *pcard, | |||
769 | strcpy(id2.name, id1.name); | 749 | strcpy(id2.name, id1.name); |
770 | id2.index = 1; | 750 | id2.index = 1; |
771 | if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) | 751 | if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) |
772 | goto _err; | 752 | return err; |
773 | strcpy(id1.name, "Master Playback Volume"); | 753 | strcpy(id1.name, "Master Playback Volume"); |
774 | strcpy(id2.name, id1.name); | 754 | strcpy(id2.name, id1.name); |
775 | if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) | 755 | if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) |
776 | goto _err; | 756 | return err; |
777 | if ((err = snd_tea6330t_update_mixer(card, i2c_bus, 0, 1)) < 0) | 757 | if ((err = snd_tea6330t_update_mixer(card, i2c_bus, 0, 1)) < 0) |
778 | goto _err; | 758 | return err; |
779 | } | 759 | } |
780 | #endif | 760 | #endif |
781 | 761 | ||
782 | gus->uart_enable = midi[dev]; | 762 | gus->uart_enable = midi[dev]; |
783 | if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) | 763 | if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) |
784 | goto _err; | 764 | return err; |
785 | 765 | ||
786 | #ifndef SNDRV_STB | 766 | #ifndef SNDRV_STB |
787 | str = "AMD InterWave"; | 767 | str = "AMD InterWave"; |
@@ -800,121 +780,171 @@ static int __devinit snd_interwave_probe(int dev, struct pnp_card_link *pcard, | |||
800 | if (xdma2 >= 0) | 780 | if (xdma2 >= 0) |
801 | sprintf(card->longname + strlen(card->longname), "&%d", xdma2); | 781 | sprintf(card->longname + strlen(card->longname), "&%d", xdma2); |
802 | 782 | ||
803 | if ((err = snd_card_set_generic_dev(card)) < 0) | ||
804 | goto _err; | ||
805 | |||
806 | if ((err = snd_card_register(card)) < 0) | 783 | if ((err = snd_card_register(card)) < 0) |
807 | goto _err; | 784 | return err; |
808 | 785 | ||
809 | iwcard->cs4231 = cs4231; | 786 | iwcard->cs4231 = cs4231; |
810 | iwcard->gus = gus; | 787 | iwcard->gus = gus; |
811 | if (pcard) | ||
812 | pnp_set_card_drvdata(pcard, card); | ||
813 | else | ||
814 | snd_interwave_legacy[dev++] = card; | ||
815 | return 0; | 788 | return 0; |
789 | } | ||
816 | 790 | ||
817 | _err: | 791 | static int __init snd_interwave_nonpnp_probe1(int dev, struct platform_device *devptr) |
818 | snd_card_free(card); | 792 | { |
819 | return err; | 793 | struct snd_card *card; |
794 | int err; | ||
795 | |||
796 | card = snd_interwave_card_new(dev); | ||
797 | if (! card) | ||
798 | return -ENOMEM; | ||
799 | |||
800 | snd_card_set_dev(card, &devptr->dev); | ||
801 | if ((err = snd_interwave_probe(card, dev)) < 0) { | ||
802 | snd_card_free(card); | ||
803 | return err; | ||
804 | } | ||
805 | platform_set_drvdata(devptr, card); | ||
806 | return 0; | ||
820 | } | 807 | } |
821 | 808 | ||
822 | static int __devinit snd_interwave_probe_legacy_port(unsigned long xport) | 809 | static int __init snd_interwave_nonpnp_probe(struct platform_device *pdev) |
823 | { | 810 | { |
824 | static int dev; | 811 | int dev = pdev->id; |
825 | int res; | 812 | int err; |
813 | static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; | ||
814 | static int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1}; | ||
826 | 815 | ||
827 | for ( ; dev < SNDRV_CARDS; dev++) { | 816 | if (irq[dev] == SNDRV_AUTO_IRQ) { |
828 | if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT) | 817 | if ((irq[dev] = snd_legacy_find_free_irq(possible_irqs)) < 0) { |
829 | continue; | 818 | snd_printk(KERN_ERR PFX "unable to find a free IRQ\n"); |
830 | #ifdef CONFIG_PNP | 819 | return -EBUSY; |
831 | if (isapnp[dev]) | 820 | } |
832 | continue; | 821 | } |
833 | #endif | 822 | if (dma1[dev] == SNDRV_AUTO_DMA) { |
834 | port[dev] = xport; | 823 | if ((dma1[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) { |
835 | res = snd_interwave_probe(dev, NULL, NULL); | 824 | snd_printk(KERN_ERR PFX "unable to find a free DMA1\n"); |
836 | if (res < 0) | 825 | return -EBUSY; |
837 | port[dev] = SNDRV_AUTO_PORT; | 826 | } |
838 | return res; | 827 | } |
828 | if (dma2[dev] == SNDRV_AUTO_DMA) { | ||
829 | if ((dma2[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) { | ||
830 | snd_printk(KERN_ERR PFX "unable to find a free DMA2\n"); | ||
831 | return -EBUSY; | ||
832 | } | ||
833 | } | ||
834 | |||
835 | if (port[dev] != SNDRV_AUTO_PORT) | ||
836 | return snd_interwave_nonpnp_probe1(dev, pdev); | ||
837 | else { | ||
838 | static long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260}; | ||
839 | int i; | ||
840 | for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { | ||
841 | port[dev] = possible_ports[i]; | ||
842 | err = snd_interwave_nonpnp_probe1(dev, pdev); | ||
843 | if (! err) | ||
844 | return 0; | ||
845 | } | ||
846 | return err; | ||
839 | } | 847 | } |
840 | return -ENODEV; | ||
841 | } | 848 | } |
842 | 849 | ||
850 | static int __devexit snd_interwave_nonpnp_remove(struct platform_device *devptr) | ||
851 | { | ||
852 | snd_card_free(platform_get_drvdata(devptr)); | ||
853 | platform_set_drvdata(devptr, NULL); | ||
854 | return 0; | ||
855 | } | ||
856 | |||
857 | static struct platform_driver snd_interwave_driver = { | ||
858 | .probe = snd_interwave_nonpnp_probe, | ||
859 | .remove = __devexit_p(snd_interwave_nonpnp_remove), | ||
860 | /* FIXME: suspend,resume */ | ||
861 | .driver = { | ||
862 | .name = INTERWAVE_DRIVER | ||
863 | }, | ||
864 | }; | ||
865 | |||
843 | #ifdef CONFIG_PNP | 866 | #ifdef CONFIG_PNP |
844 | 867 | ||
845 | static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *card, | 868 | static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, |
846 | const struct pnp_card_device_id *id) | 869 | const struct pnp_card_device_id *pid) |
847 | { | 870 | { |
848 | static int dev; | 871 | static int dev; |
872 | struct snd_card *card; | ||
849 | int res; | 873 | int res; |
850 | 874 | ||
851 | for ( ; dev < SNDRV_CARDS; dev++) { | 875 | for ( ; dev < SNDRV_CARDS; dev++) { |
852 | if (!enable[dev] || !isapnp[dev]) | 876 | if (enable[dev] && isapnp[dev]) |
853 | continue; | 877 | break; |
854 | res = snd_interwave_probe(dev, card, id); | 878 | } |
855 | if (res < 0) | 879 | if (dev >= SNDRV_CARDS) |
856 | return res; | 880 | return -ENODEV; |
857 | dev++; | 881 | |
858 | return 0; | 882 | card = snd_interwave_card_new(dev); |
859 | } | 883 | if (! card) |
860 | 884 | return -ENOMEM; | |
861 | return -ENODEV; | 885 | |
886 | if ((res = snd_interwave_pnp(dev, card->private_data, pcard, pid)) < 0) { | ||
887 | snd_card_free(card); | ||
888 | return res; | ||
889 | } | ||
890 | snd_card_set_dev(card, &pcard->card->dev); | ||
891 | if ((res = snd_interwave_probe(card, dev)) < 0) { | ||
892 | snd_card_free(card); | ||
893 | return res; | ||
894 | } | ||
895 | pnp_set_card_drvdata(pcard, card); | ||
896 | dev++; | ||
897 | return 0; | ||
862 | } | 898 | } |
863 | 899 | ||
864 | static void __devexit snd_interwave_pnp_remove(struct pnp_card_link * pcard) | 900 | static void __devexit snd_interwave_pnp_remove(struct pnp_card_link * pcard) |
865 | { | 901 | { |
866 | struct snd_card *card = (struct snd_card *) pnp_get_card_drvdata(pcard); | 902 | snd_card_free(pnp_get_card_drvdata(pcard)); |
867 | 903 | pnp_set_card_drvdata(pcard, NULL); | |
868 | snd_card_disconnect(card); | ||
869 | snd_card_free_in_thread(card); | ||
870 | } | 904 | } |
871 | 905 | ||
872 | static struct pnp_card_driver interwave_pnpc_driver = { | 906 | static struct pnp_card_driver interwave_pnpc_driver = { |
873 | .flags = PNP_DRIVER_RES_DISABLE, | 907 | .flags = PNP_DRIVER_RES_DISABLE, |
874 | .name = "interwave", | 908 | .name = INTERWAVE_PNP_DRIVER, |
875 | .id_table = snd_interwave_pnpids, | 909 | .id_table = snd_interwave_pnpids, |
876 | .probe = snd_interwave_pnp_detect, | 910 | .probe = snd_interwave_pnp_detect, |
877 | .remove = __devexit_p(snd_interwave_pnp_remove), | 911 | .remove = __devexit_p(snd_interwave_pnp_remove), |
912 | /* FIXME: suspend,resume */ | ||
878 | }; | 913 | }; |
879 | 914 | ||
880 | #endif /* CONFIG_PNP */ | 915 | #endif /* CONFIG_PNP */ |
881 | 916 | ||
882 | static int __init alsa_card_interwave_init(void) | 917 | static int __init alsa_card_interwave_init(void) |
883 | { | 918 | { |
884 | int cards = 0, i; | 919 | int i, err, cards = 0; |
885 | static long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260, -1}; | ||
886 | int dev; | ||
887 | 920 | ||
888 | for (dev = 0; dev < SNDRV_CARDS; dev++) { | 921 | if ((err = platform_driver_register(&snd_interwave_driver)) < 0) |
889 | if (!enable[dev] || port[dev] == SNDRV_AUTO_PORT) | 922 | return err; |
890 | continue; | 923 | |
924 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | ||
925 | struct platform_device *device; | ||
891 | #ifdef CONFIG_PNP | 926 | #ifdef CONFIG_PNP |
892 | if (isapnp[dev]) | 927 | if (isapnp[i]) |
893 | continue; | 928 | continue; |
894 | #endif | 929 | #endif |
895 | if (!snd_interwave_probe(dev, NULL, NULL)) { | 930 | device = platform_device_register_simple(INTERWAVE_DRIVER, |
896 | cards++; | 931 | i, NULL, 0); |
897 | continue; | 932 | if (IS_ERR(device)) { |
933 | err = PTR_ERR(device); | ||
934 | platform_driver_unregister(&snd_interwave_driver); | ||
935 | return err; | ||
898 | } | 936 | } |
899 | #ifdef MODULE | 937 | cards++; |
900 | printk(KERN_ERR "InterWave soundcard #%i not found at 0x%lx or device busy\n", dev, port[dev]); | ||
901 | #endif | ||
902 | } | 938 | } |
903 | /* legacy auto configured cards */ | 939 | |
904 | i = snd_legacy_auto_probe(possible_ports, snd_interwave_probe_legacy_port); | ||
905 | if (i > 0) | ||
906 | cards += i; | ||
907 | #ifdef CONFIG_PNP | ||
908 | /* ISA PnP cards */ | 940 | /* ISA PnP cards */ |
909 | i = pnp_register_card_driver(&interwave_pnpc_driver); | 941 | i = pnp_register_card_driver(&interwave_pnpc_driver); |
910 | if (i > 0) | 942 | if (i > 0) |
911 | cards += i; | 943 | cards += i; |
912 | #endif | ||
913 | 944 | ||
914 | if (!cards) { | 945 | if (!cards) { |
915 | #ifdef CONFIG_PNP | ||
916 | pnp_unregister_card_driver(&interwave_pnpc_driver); | 946 | pnp_unregister_card_driver(&interwave_pnpc_driver); |
917 | #endif | 947 | platform_driver_unregister(&snd_interwave_driver); |
918 | #ifdef MODULE | 948 | #ifdef MODULE |
919 | printk(KERN_ERR "InterWave soundcard not found or device busy\n"); | 949 | printk(KERN_ERR "InterWave soundcard not found or device busy\n"); |
920 | #endif | 950 | #endif |
@@ -925,14 +955,8 @@ static int __init alsa_card_interwave_init(void) | |||
925 | 955 | ||
926 | static void __exit alsa_card_interwave_exit(void) | 956 | static void __exit alsa_card_interwave_exit(void) |
927 | { | 957 | { |
928 | int dev; | ||
929 | |||
930 | #ifdef CONFIG_PNP | ||
931 | /* PnP cards first */ | ||
932 | pnp_unregister_card_driver(&interwave_pnpc_driver); | 958 | pnp_unregister_card_driver(&interwave_pnpc_driver); |
933 | #endif | 959 | platform_driver_unregister(&snd_interwave_driver); |
934 | for (dev = 0; dev < SNDRV_CARDS; dev++) | ||
935 | snd_card_free(snd_interwave_legacy[dev]); | ||
936 | } | 960 | } |
937 | 961 | ||
938 | module_init(alsa_card_interwave_init) | 962 | module_init(alsa_card_interwave_init) |