diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/isa/opl3sa2.c | 112 |
1 files changed, 89 insertions, 23 deletions
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 95c7b3e53407..c4ebf57b9fc3 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c | |||
@@ -145,6 +145,14 @@ static snd_card_t *snd_opl3sa2_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; | |||
145 | 145 | ||
146 | #ifdef CONFIG_PNP | 146 | #ifdef CONFIG_PNP |
147 | 147 | ||
148 | static struct pnp_device_id snd_opl3sa2_pnpbiosids[] = { | ||
149 | { .id = "YMF0021" }, | ||
150 | { .id = "NMX2210" }, /* Gateway Solo 2500 */ | ||
151 | { .id = "" } /* end */ | ||
152 | }; | ||
153 | |||
154 | MODULE_DEVICE_TABLE(pnp, snd_opl3sa2_pnpbiosids); | ||
155 | |||
148 | static struct pnp_card_device_id snd_opl3sa2_pnpids[] = { | 156 | static struct pnp_card_device_id snd_opl3sa2_pnpids[] = { |
149 | /* Yamaha YMF719E-S (Genius Sound Maker 3DX) */ | 157 | /* Yamaha YMF719E-S (Genius Sound Maker 3DX) */ |
150 | { .id = "YMH0020", .devs = { { "YMH0021" } } }, | 158 | { .id = "YMH0020", .devs = { { "YMH0021" } } }, |
@@ -568,20 +576,18 @@ static int snd_opl3sa2_resume(snd_card_t *card) | |||
568 | 576 | ||
569 | #ifdef CONFIG_PNP | 577 | #ifdef CONFIG_PNP |
570 | static int __init snd_opl3sa2_pnp(int dev, opl3sa2_t *chip, | 578 | static int __init snd_opl3sa2_pnp(int dev, opl3sa2_t *chip, |
571 | struct pnp_card_link *card, | 579 | struct pnp_dev *pdev, |
572 | const struct pnp_card_device_id *id) | 580 | int isapnp) |
573 | { | 581 | { |
574 | struct pnp_dev *pdev; | 582 | struct pnp_resource_table * cfg; |
575 | struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL); | ||
576 | int err; | 583 | int err; |
577 | 584 | ||
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); | ||
578 | if (!cfg) | 589 | if (!cfg) |
579 | return -ENOMEM; | 590 | return -ENOMEM; |
580 | pdev = chip->dev = pnp_request_card_device(card, id->devs[0].id, NULL); | ||
581 | if (chip->dev == NULL) { | ||
582 | kfree(cfg); | ||
583 | return -EBUSY; | ||
584 | } | ||
585 | /* PnP initialization */ | 591 | /* PnP initialization */ |
586 | pnp_init_resource_table(cfg); | 592 | pnp_init_resource_table(cfg); |
587 | if (sb_port[dev] != SNDRV_AUTO_PORT) | 593 | if (sb_port[dev] != SNDRV_AUTO_PORT) |
@@ -617,13 +623,31 @@ static int __init snd_opl3sa2_pnp(int dev, opl3sa2_t *chip, | |||
617 | dma1[dev] = pnp_dma(pdev, 0); | 623 | dma1[dev] = pnp_dma(pdev, 0); |
618 | dma2[dev] = pnp_dma(pdev, 1); | 624 | dma2[dev] = pnp_dma(pdev, 1); |
619 | irq[dev] = pnp_irq(pdev, 0); | 625 | irq[dev] = pnp_irq(pdev, 0); |
620 | snd_printdd("PnP OPL3-SA: sb port=0x%lx, wss port=0x%lx, fm port=0x%lx, midi port=0x%lx\n", | 626 | snd_printdd("%sPnP OPL3-SA: sb port=0x%lx, wss port=0x%lx, fm port=0x%lx, midi port=0x%lx\n", |
621 | sb_port[dev], wss_port[dev], fm_port[dev], midi_port[dev]); | 627 | pnp_device_is_pnpbios(pdev) ? "BIOS" : "ISA", sb_port[dev], wss_port[dev], fm_port[dev], midi_port[dev]); |
622 | snd_printdd("PnP OPL3-SA: control port=0x%lx, dma1=%i, dma2=%i, irq=%i\n", | 628 | snd_printdd("%sPnP OPL3-SA: control port=0x%lx, dma1=%i, dma2=%i, irq=%i\n", |
623 | port[dev], dma1[dev], dma2[dev], irq[dev]); | 629 | pnp_device_is_pnpbios(pdev) ? "BIOS" : "ISA", port[dev], dma1[dev], dma2[dev], irq[dev]); |
624 | kfree(cfg); | 630 | kfree(cfg); |
631 | chip->dev = pdev; | ||
625 | return 0; | 632 | return 0; |
626 | } | 633 | } |
634 | |||
635 | static int __init snd_opl3sa2_cpnp(int dev, opl3sa2_t *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 | } | ||
627 | #endif /* CONFIG_PNP */ | 651 | #endif /* CONFIG_PNP */ |
628 | 652 | ||
629 | static int snd_opl3sa2_free(opl3sa2_t *chip) | 653 | static int snd_opl3sa2_free(opl3sa2_t *chip) |
@@ -645,6 +669,7 @@ static int snd_opl3sa2_dev_free(snd_device_t *device) | |||
645 | } | 669 | } |
646 | 670 | ||
647 | static int __devinit snd_opl3sa2_probe(int dev, | 671 | static int __devinit snd_opl3sa2_probe(int dev, |
672 | struct pnp_dev *pdev, | ||
648 | struct pnp_card_link *pcard, | 673 | struct pnp_card_link *pcard, |
649 | const struct pnp_card_device_id *pid) | 674 | const struct pnp_card_device_id *pid) |
650 | { | 675 | { |
@@ -695,8 +720,13 @@ static int __devinit snd_opl3sa2_probe(int dev, | |||
695 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) | 720 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) |
696 | goto __error; | 721 | goto __error; |
697 | #ifdef CONFIG_PNP | 722 | #ifdef CONFIG_PNP |
698 | if (isapnp[dev]) { | 723 | if (pdev) { |
699 | if ((err = snd_opl3sa2_pnp(dev, chip, pcard, pid)) < 0) | 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) | ||
700 | goto __error; | 730 | goto __error; |
701 | snd_card_set_dev(card, &pcard->card->dev); | 731 | snd_card_set_dev(card, &pcard->card->dev); |
702 | } | 732 | } |
@@ -768,7 +798,9 @@ static int __devinit snd_opl3sa2_probe(int dev, | |||
768 | if ((err = snd_card_register(card)) < 0) | 798 | if ((err = snd_card_register(card)) < 0) |
769 | goto __error; | 799 | goto __error; |
770 | 800 | ||
771 | if (pcard) | 801 | if (pdev) |
802 | pnp_set_drvdata(pdev, card); | ||
803 | else if (pcard) | ||
772 | pnp_set_card_drvdata(pcard, card); | 804 | pnp_set_card_drvdata(pcard, card); |
773 | else | 805 | else |
774 | snd_opl3sa2_legacy[dev] = card; | 806 | snd_opl3sa2_legacy[dev] = card; |
@@ -780,8 +812,41 @@ static int __devinit snd_opl3sa2_probe(int dev, | |||
780 | } | 812 | } |
781 | 813 | ||
782 | #ifdef CONFIG_PNP | 814 | #ifdef CONFIG_PNP |
783 | static int __devinit snd_opl3sa2_pnp_detect(struct pnp_card_link *card, | 815 | static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev, |
784 | const struct pnp_card_device_id *id) | 816 | const struct pnp_device_id *id) |
817 | { | ||
818 | static int dev; | ||
819 | int res; | ||
820 | |||
821 | for ( ; dev < SNDRV_CARDS; dev++) { | ||
822 | if (!enable[dev] || !isapnp[dev]) | ||
823 | continue; | ||
824 | res = snd_opl3sa2_probe(dev, pdev, NULL, NULL); | ||
825 | if (res < 0) | ||
826 | return res; | ||
827 | dev++; | ||
828 | return 0; | ||
829 | } | ||
830 | return -ENODEV; | ||
831 | } | ||
832 | |||
833 | static void __devexit snd_opl3sa2_pnp_remove(struct pnp_dev * pdev) | ||
834 | { | ||
835 | snd_card_t *card = (snd_card_t *) pnp_get_drvdata(pdev); | ||
836 | |||
837 | snd_card_disconnect(card); | ||
838 | snd_card_free_in_thread(card); | ||
839 | } | ||
840 | |||
841 | static struct pnp_driver opl3sa2_pnp_driver = { | ||
842 | .name = "opl3sa2", | ||
843 | .id_table = snd_opl3sa2_pnpbiosids, | ||
844 | .probe = snd_opl3sa2_pnp_detect, | ||
845 | .remove = __devexit_p(snd_opl3sa2_pnp_remove), | ||
846 | }; | ||
847 | |||
848 | static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *card, | ||
849 | const struct pnp_card_device_id *id) | ||
785 | { | 850 | { |
786 | static int dev; | 851 | static int dev; |
787 | int res; | 852 | int res; |
@@ -789,7 +854,7 @@ static int __devinit snd_opl3sa2_pnp_detect(struct pnp_card_link *card, | |||
789 | for ( ; dev < SNDRV_CARDS; dev++) { | 854 | for ( ; dev < SNDRV_CARDS; dev++) { |
790 | if (!enable[dev] || !isapnp[dev]) | 855 | if (!enable[dev] || !isapnp[dev]) |
791 | continue; | 856 | continue; |
792 | res = snd_opl3sa2_probe(dev, card, id); | 857 | res = snd_opl3sa2_probe(dev, NULL, card, id); |
793 | if (res < 0) | 858 | if (res < 0) |
794 | return res; | 859 | return res; |
795 | dev++; | 860 | dev++; |
@@ -798,7 +863,7 @@ static int __devinit snd_opl3sa2_pnp_detect(struct pnp_card_link *card, | |||
798 | return -ENODEV; | 863 | return -ENODEV; |
799 | } | 864 | } |
800 | 865 | ||
801 | static void __devexit snd_opl3sa2_pnp_remove(struct pnp_card_link * pcard) | 866 | static void __devexit snd_opl3sa2_pnp_cremove(struct pnp_card_link * pcard) |
802 | { | 867 | { |
803 | snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard); | 868 | snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard); |
804 | 869 | ||
@@ -810,8 +875,8 @@ static struct pnp_card_driver opl3sa2_pnpc_driver = { | |||
810 | .flags = PNP_DRIVER_RES_DISABLE, | 875 | .flags = PNP_DRIVER_RES_DISABLE, |
811 | .name = "opl3sa2", | 876 | .name = "opl3sa2", |
812 | .id_table = snd_opl3sa2_pnpids, | 877 | .id_table = snd_opl3sa2_pnpids, |
813 | .probe = snd_opl3sa2_pnp_detect, | 878 | .probe = snd_opl3sa2_pnp_cdetect, |
814 | .remove = __devexit_p(snd_opl3sa2_pnp_remove), | 879 | .remove = __devexit_p(snd_opl3sa2_pnp_cremove), |
815 | }; | 880 | }; |
816 | #endif /* CONFIG_PNP */ | 881 | #endif /* CONFIG_PNP */ |
817 | 882 | ||
@@ -826,10 +891,11 @@ static int __init alsa_card_opl3sa2_init(void) | |||
826 | if (isapnp[dev]) | 891 | if (isapnp[dev]) |
827 | continue; | 892 | continue; |
828 | #endif | 893 | #endif |
829 | if (snd_opl3sa2_probe(dev, NULL, NULL) >= 0) | 894 | if (snd_opl3sa2_probe(dev, NULL, NULL, NULL) >= 0) |
830 | cards++; | 895 | cards++; |
831 | } | 896 | } |
832 | #ifdef CONFIG_PNP | 897 | #ifdef CONFIG_PNP |
898 | cards += pnp_register_driver(&opl3sa2_pnp_driver); | ||
833 | cards += pnp_register_card_driver(&opl3sa2_pnpc_driver); | 899 | cards += pnp_register_card_driver(&opl3sa2_pnpc_driver); |
834 | #endif | 900 | #endif |
835 | if (!cards) { | 901 | if (!cards) { |