diff options
| author | Takashi Iwai <tiwai@suse.de> | 2005-11-17 11:11:53 -0500 |
|---|---|---|
| committer | Jaroslav Kysela <perex@suse.cz> | 2006-01-03 06:28:27 -0500 |
| commit | 704e05204c623136ea12411dc4286d1caea6cd7c (patch) | |
| tree | 3527413100be5eb599325eca50a933539fab6cf2 | |
| parent | acdcbc15426b91b0041756a92ea4932c60def189 (diff) | |
[ALSA] opl3sa2 - Use platform_device
Modules: OPL3SA2 driver
Rewrite the probe/remove with platform_device.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
| -rw-r--r-- | sound/isa/opl3sa2.c | 428 |
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 | ||
| 142 | static 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 |
| 540 | static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state) | 533 | static 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 | ||
| 553 | static int snd_opl3sa2_resume(struct snd_card *card) | 545 | static 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 |
| 578 | static int __init snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip, | 571 | static 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 | |||
| 635 | static 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 | ||
| 653 | static int snd_opl3sa2_free(struct snd_opl3sa2 *chip) | 624 | static 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 | ||
| 662 | static int snd_opl3sa2_dev_free(struct snd_device *device) | 632 | static 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 | |||
| 674 | static 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"); | ||
