diff options
author | Takashi Iwai <tiwai@suse.de> | 2005-11-17 11:12:07 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-01-03 06:28:28 -0500 |
commit | f7e0ba3e440d4aab381dca6d7a7eee8f2faf210b (patch) | |
tree | 88b578819914103fafcf33b3f3bfc618e3ba172c /sound/isa/es18xx.c | |
parent | 704e05204c623136ea12411dc4286d1caea6cd7c (diff) |
[ALSA] es18xx - Use platform_device
Modules: ES18xx driver
Rewrite the probe/remove with platform_device.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/isa/es18xx.c')
-rw-r--r-- | sound/isa/es18xx.c | 328 |
1 files changed, 185 insertions, 143 deletions
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 06c0e778494e..34d47132f082 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c | |||
@@ -65,21 +65,21 @@ | |||
65 | 65 | ||
66 | 66 | ||
67 | #include <sound/driver.h> | 67 | #include <sound/driver.h> |
68 | #include <asm/io.h> | ||
69 | #include <asm/dma.h> | ||
70 | #include <linux/init.h> | 68 | #include <linux/init.h> |
71 | #include <linux/pm.h> | 69 | #include <linux/err.h> |
70 | #include <linux/platform_device.h> | ||
72 | #include <linux/slab.h> | 71 | #include <linux/slab.h> |
73 | #include <linux/pnp.h> | 72 | #include <linux/pnp.h> |
74 | #include <linux/isapnp.h> | 73 | #include <linux/isapnp.h> |
75 | #include <linux/moduleparam.h> | 74 | #include <linux/moduleparam.h> |
75 | #include <asm/io.h> | ||
76 | #include <asm/dma.h> | ||
76 | #include <sound/core.h> | 77 | #include <sound/core.h> |
77 | #include <sound/control.h> | 78 | #include <sound/control.h> |
78 | #include <sound/pcm.h> | 79 | #include <sound/pcm.h> |
79 | #include <sound/pcm_params.h> | 80 | #include <sound/pcm_params.h> |
80 | #include <sound/mpu401.h> | 81 | #include <sound/mpu401.h> |
81 | #include <sound/opl3.h> | 82 | #include <sound/opl3.h> |
82 | #define SNDRV_LEGACY_AUTO_PROBE | ||
83 | #define SNDRV_LEGACY_FIND_FREE_IRQ | 83 | #define SNDRV_LEGACY_FIND_FREE_IRQ |
84 | #define SNDRV_LEGACY_FIND_FREE_DMA | 84 | #define SNDRV_LEGACY_FIND_FREE_DMA |
85 | #include <sound/initval.h> | 85 | #include <sound/initval.h> |
@@ -128,6 +128,14 @@ struct snd_es18xx { | |||
128 | #endif | 128 | #endif |
129 | }; | 129 | }; |
130 | 130 | ||
131 | struct snd_audiodrive { | ||
132 | struct snd_es18xx *chip; | ||
133 | #ifdef CONFIG_PNP | ||
134 | struct pnp_dev *dev; | ||
135 | struct pnp_dev *devc; | ||
136 | #endif | ||
137 | }; | ||
138 | |||
131 | #define AUDIO1_IRQ 0x01 | 139 | #define AUDIO1_IRQ 0x01 |
132 | #define AUDIO2_IRQ 0x02 | 140 | #define AUDIO2_IRQ 0x02 |
133 | #define HWV_IRQ 0x04 | 141 | #define HWV_IRQ 0x04 |
@@ -1573,11 +1581,10 @@ static int __devinit snd_es18xx_pcm(struct snd_es18xx *chip, int device, struct | |||
1573 | if (rpcm) | 1581 | if (rpcm) |
1574 | *rpcm = NULL; | 1582 | *rpcm = NULL; |
1575 | sprintf(str, "ES%x", chip->version); | 1583 | sprintf(str, "ES%x", chip->version); |
1576 | if (chip->caps & ES18XX_PCM2) { | 1584 | if (chip->caps & ES18XX_PCM2) |
1577 | err = snd_pcm_new(chip->card, str, device, 2, 1, &pcm); | 1585 | err = snd_pcm_new(chip->card, str, device, 2, 1, &pcm); |
1578 | } else { | 1586 | else |
1579 | err = snd_pcm_new(chip->card, str, device, 1, 1, &pcm); | 1587 | err = snd_pcm_new(chip->card, str, device, 1, 1, &pcm); |
1580 | } | ||
1581 | if (err < 0) | 1588 | if (err < 0) |
1582 | return err; | 1589 | return err; |
1583 | 1590 | ||
@@ -1608,7 +1615,10 @@ static int __devinit snd_es18xx_pcm(struct snd_es18xx *chip, int device, struct | |||
1608 | #ifdef CONFIG_PM | 1615 | #ifdef CONFIG_PM |
1609 | static int snd_es18xx_suspend(struct snd_card *card, pm_message_t state) | 1616 | static int snd_es18xx_suspend(struct snd_card *card, pm_message_t state) |
1610 | { | 1617 | { |
1611 | struct snd_es18xx *chip = card->pm_private_data; | 1618 | struct snd_audiodrive *acard = card->private_data; |
1619 | struct snd_es18xx *chip = acard->chip; | ||
1620 | |||
1621 | snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot); | ||
1612 | 1622 | ||
1613 | snd_pcm_suspend_all(chip->pcm); | 1623 | snd_pcm_suspend_all(chip->pcm); |
1614 | 1624 | ||
@@ -1623,11 +1633,13 @@ static int snd_es18xx_suspend(struct snd_card *card, pm_message_t state) | |||
1623 | 1633 | ||
1624 | static int snd_es18xx_resume(struct snd_card *card) | 1634 | static int snd_es18xx_resume(struct snd_card *card) |
1625 | { | 1635 | { |
1626 | struct snd_es18xx *chip = card->pm_private_data; | 1636 | struct snd_audiodrive *acard = card->private_data; |
1637 | struct snd_es18xx *chip = acard->chip; | ||
1627 | 1638 | ||
1628 | /* restore PM register, we won't wake till (not 0x07) i/o activity though */ | 1639 | /* restore PM register, we won't wake till (not 0x07) i/o activity though */ |
1629 | snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_FM); | 1640 | snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_FM); |
1630 | 1641 | ||
1642 | snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0); | ||
1631 | return 0; | 1643 | return 0; |
1632 | } | 1644 | } |
1633 | #endif /* CONFIG_PM */ | 1645 | #endif /* CONFIG_PM */ |
@@ -1865,15 +1877,6 @@ MODULE_PARM_DESC(dma1, "DMA 1 # for ES18xx driver."); | |||
1865 | module_param_array(dma2, int, NULL, 0444); | 1877 | module_param_array(dma2, int, NULL, 0444); |
1866 | MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver."); | 1878 | MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver."); |
1867 | 1879 | ||
1868 | struct snd_audiodrive { | ||
1869 | #ifdef CONFIG_PNP | ||
1870 | struct pnp_dev *dev; | ||
1871 | struct pnp_dev *devc; | ||
1872 | #endif | ||
1873 | }; | ||
1874 | |||
1875 | static struct snd_card *snd_audiodrive_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; | ||
1876 | |||
1877 | #ifdef CONFIG_PNP | 1880 | #ifdef CONFIG_PNP |
1878 | 1881 | ||
1879 | static struct pnp_card_device_id snd_audiodrive_pnpids[] = { | 1882 | static struct pnp_card_device_id snd_audiodrive_pnpids[] = { |
@@ -1979,209 +1982,254 @@ static int __devinit snd_audiodrive_pnp(int dev, struct snd_audiodrive *acard, | |||
1979 | #define is_isapnp_selected(dev) 0 | 1982 | #define is_isapnp_selected(dev) 0 |
1980 | #endif | 1983 | #endif |
1981 | 1984 | ||
1982 | static int __devinit snd_audiodrive_probe(int dev, struct pnp_card_link *pcard, | 1985 | static struct snd_card *snd_es18xx_card_new(int dev) |
1983 | const struct pnp_card_device_id *pid) | ||
1984 | { | 1986 | { |
1985 | static int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1}; | 1987 | return snd_card_new(index[dev], id[dev], THIS_MODULE, |
1986 | static int possible_dmas[] = {1, 0, 3, 5, -1}; | 1988 | sizeof(struct snd_audiodrive)); |
1987 | int xirq, xdma1, xdma2; | 1989 | } |
1988 | struct snd_card *card; | 1990 | |
1989 | struct snd_audiodrive *acard; | 1991 | static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev) |
1992 | { | ||
1993 | struct snd_audiodrive *acard = card->private_data; | ||
1990 | struct snd_es18xx *chip; | 1994 | struct snd_es18xx *chip; |
1991 | struct snd_opl3 *opl3; | 1995 | struct snd_opl3 *opl3; |
1992 | int err; | 1996 | int err; |
1993 | 1997 | ||
1994 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | ||
1995 | sizeof(struct snd_audiodrive)); | ||
1996 | if (card == NULL) | ||
1997 | return -ENOMEM; | ||
1998 | acard = (struct snd_audiodrive *)card->private_data; | ||
1999 | #ifdef CONFIG_PNP | ||
2000 | if (isapnp[dev]) { | ||
2001 | if ((err = snd_audiodrive_pnp(dev, acard, pcard, pid)) < 0) { | ||
2002 | snd_card_free(card); | ||
2003 | return err; | ||
2004 | } | ||
2005 | snd_card_set_dev(card, &pcard->card->dev); | ||
2006 | } | ||
2007 | #endif | ||
2008 | |||
2009 | xirq = irq[dev]; | ||
2010 | if (xirq == SNDRV_AUTO_IRQ) { | ||
2011 | if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) { | ||
2012 | snd_printk(KERN_ERR PFX "unable to find a free IRQ\n"); | ||
2013 | err = -EBUSY; | ||
2014 | goto _err; | ||
2015 | } | ||
2016 | } | ||
2017 | xdma1 = dma1[dev]; | ||
2018 | if (xdma1 == SNDRV_AUTO_DMA) { | ||
2019 | if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) { | ||
2020 | snd_printk(KERN_ERR PFX "unable to find a free DMA1\n"); | ||
2021 | err = -EBUSY; | ||
2022 | goto _err; | ||
2023 | } | ||
2024 | } | ||
2025 | xdma2 = dma2[dev]; | ||
2026 | if (xdma2 == SNDRV_AUTO_DMA) { | ||
2027 | if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) { | ||
2028 | snd_printk(KERN_ERR PFX "unable to find a free DMA2\n"); | ||
2029 | err = -EBUSY; | ||
2030 | goto _err; | ||
2031 | } | ||
2032 | } | ||
2033 | |||
2034 | if ((err = snd_es18xx_new_device(card, | 1998 | if ((err = snd_es18xx_new_device(card, |
2035 | port[dev], | 1999 | port[dev], |
2036 | mpu_port[dev], | 2000 | mpu_port[dev], |
2037 | fm_port[dev], | 2001 | fm_port[dev], |
2038 | xirq, xdma1, xdma2, | 2002 | irq[dev], dma1[dev], dma2[dev], |
2039 | &chip)) < 0) | 2003 | &chip)) < 0) |
2040 | goto _err; | 2004 | return err; |
2005 | acard->chip = chip; | ||
2041 | 2006 | ||
2042 | sprintf(card->driver, "ES%x", chip->version); | 2007 | sprintf(card->driver, "ES%x", chip->version); |
2008 | |||
2043 | sprintf(card->shortname, "ESS AudioDrive ES%x", chip->version); | 2009 | sprintf(card->shortname, "ESS AudioDrive ES%x", chip->version); |
2044 | if (xdma1 != xdma2) | 2010 | if (dma1[dev] != dma2[dev]) |
2045 | sprintf(card->longname, "%s at 0x%lx, irq %d, dma1 %d, dma2 %d", | 2011 | sprintf(card->longname, "%s at 0x%lx, irq %d, dma1 %d, dma2 %d", |
2046 | card->shortname, | 2012 | card->shortname, |
2047 | chip->port, | 2013 | chip->port, |
2048 | xirq, xdma1, xdma2); | 2014 | irq[dev], dma1[dev], dma2[dev]); |
2049 | else | 2015 | else |
2050 | sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", | 2016 | sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", |
2051 | card->shortname, | 2017 | card->shortname, |
2052 | chip->port, | 2018 | chip->port, |
2053 | xirq, xdma1); | 2019 | irq[dev], dma1[dev]); |
2054 | 2020 | ||
2055 | if ((err = snd_es18xx_pcm(chip, 0, NULL)) < 0) | 2021 | if ((err = snd_es18xx_pcm(chip, 0, NULL)) < 0) |
2056 | goto _err; | 2022 | return err; |
2057 | 2023 | ||
2058 | if ((err = snd_es18xx_mixer(chip)) < 0) | 2024 | if ((err = snd_es18xx_mixer(chip)) < 0) |
2059 | goto _err; | 2025 | return err; |
2060 | 2026 | ||
2061 | if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) { | 2027 | if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) { |
2062 | if (snd_opl3_create(card, chip->fm_port, chip->fm_port + 2, OPL3_HW_OPL3, 0, &opl3) < 0) { | 2028 | if (snd_opl3_create(card, chip->fm_port, chip->fm_port + 2, OPL3_HW_OPL3, 0, &opl3) < 0) { |
2063 | snd_printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->fm_port); | 2029 | snd_printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->fm_port); |
2064 | } else { | 2030 | } else { |
2065 | if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) | 2031 | if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) |
2066 | goto _err; | 2032 | return err; |
2067 | } | 2033 | } |
2068 | } | 2034 | } |
2069 | 2035 | ||
2070 | if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { | 2036 | if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { |
2071 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX, | 2037 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX, |
2072 | chip->mpu_port, 0, | 2038 | chip->mpu_port, 0, |
2073 | xirq, 0, | 2039 | irq[dev], 0, |
2074 | &chip->rmidi)) < 0) | 2040 | &chip->rmidi)) < 0) |
2075 | goto _err; | 2041 | return err; |
2076 | } | 2042 | } |
2077 | 2043 | ||
2078 | if ((err = snd_card_set_generic_dev(card)) < 0) | 2044 | return snd_card_register(card); |
2079 | goto _err; | 2045 | } |
2080 | |||
2081 | /* Power Management */ | ||
2082 | snd_card_set_isa_pm_callback(card, snd_es18xx_suspend, snd_es18xx_resume, chip); | ||
2083 | 2046 | ||
2084 | if ((err = snd_card_register(card)) < 0) | 2047 | static int __init snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devptr) |
2085 | goto _err; | 2048 | { |
2049 | struct snd_card *card; | ||
2050 | int err; | ||
2086 | 2051 | ||
2087 | if (pcard) | 2052 | card = snd_es18xx_card_new(dev); |
2088 | pnp_set_card_drvdata(pcard, card); | 2053 | if (! card) |
2089 | else | 2054 | return -ENOMEM; |
2090 | snd_audiodrive_legacy[dev] = card; | 2055 | snd_card_set_dev(card, &devptr->dev); |
2056 | if ((err = snd_audiodrive_probe(card, dev)) < 0) { | ||
2057 | snd_card_free(card); | ||
2058 | return err; | ||
2059 | } | ||
2060 | platform_set_drvdata(devptr, card); | ||
2091 | return 0; | 2061 | return 0; |
2092 | |||
2093 | _err: | ||
2094 | snd_card_free(card); | ||
2095 | return err; | ||
2096 | } | 2062 | } |
2097 | 2063 | ||
2098 | static int __devinit snd_audiodrive_probe_legacy_port(unsigned long xport) | 2064 | static int __init snd_es18xx_nonpnp_probe(struct platform_device *pdev) |
2099 | { | 2065 | { |
2100 | static int dev; | 2066 | int dev = pdev->id; |
2101 | int res; | 2067 | int err; |
2068 | static int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1}; | ||
2069 | static int possible_dmas[] = {1, 0, 3, 5, -1}; | ||
2102 | 2070 | ||
2103 | for ( ; dev < SNDRV_CARDS; dev++) { | 2071 | if (irq[dev] == SNDRV_AUTO_IRQ) { |
2104 | if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT) | 2072 | if ((irq[dev] = snd_legacy_find_free_irq(possible_irqs)) < 0) { |
2105 | continue; | 2073 | snd_printk(KERN_ERR PFX "unable to find a free IRQ\n"); |
2106 | if (is_isapnp_selected(dev)) | 2074 | return -EBUSY; |
2107 | continue; | 2075 | } |
2108 | port[dev] = xport; | 2076 | } |
2109 | res = snd_audiodrive_probe(dev, NULL, NULL); | 2077 | if (dma1[dev] == SNDRV_AUTO_DMA) { |
2110 | if (res < 0) | 2078 | if ((dma1[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) { |
2111 | port[dev] = SNDRV_AUTO_PORT; | 2079 | snd_printk(KERN_ERR PFX "unable to find a free DMA1\n"); |
2112 | return res; | 2080 | return -EBUSY; |
2081 | } | ||
2082 | } | ||
2083 | if (dma2[dev] == SNDRV_AUTO_DMA) { | ||
2084 | if ((dma2[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) { | ||
2085 | snd_printk(KERN_ERR PFX "unable to find a free DMA2\n"); | ||
2086 | return -EBUSY; | ||
2087 | } | ||
2088 | } | ||
2089 | |||
2090 | if (port[dev] != SNDRV_AUTO_PORT) { | ||
2091 | return snd_es18xx_nonpnp_probe1(dev, pdev); | ||
2092 | } else { | ||
2093 | static unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280}; | ||
2094 | int i; | ||
2095 | for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { | ||
2096 | port[dev] = possible_ports[i]; | ||
2097 | err = snd_es18xx_nonpnp_probe1(dev, pdev); | ||
2098 | if (! err) | ||
2099 | return 0; | ||
2100 | } | ||
2101 | return err; | ||
2113 | } | 2102 | } |
2114 | return -ENODEV; | ||
2115 | } | 2103 | } |
2116 | 2104 | ||
2105 | static int __devexit snd_es18xx_nonpnp_remove(struct platform_device *devptr) | ||
2106 | { | ||
2107 | snd_card_free(platform_get_drvdata(devptr)); | ||
2108 | platform_set_drvdata(devptr, NULL); | ||
2109 | return 0; | ||
2110 | } | ||
2111 | |||
2112 | #ifdef CONFIG_PM | ||
2113 | static int snd_es18xx_nonpnp_suspend(struct platform_device *dev, pm_message_t state) | ||
2114 | { | ||
2115 | return snd_es18xx_suspend(platform_get_drvdata(dev), state); | ||
2116 | } | ||
2117 | |||
2118 | static int snd_es18xx_nonpnp_resume(struct platform_device *dev) | ||
2119 | { | ||
2120 | return snd_es18xx_resume(platform_get_drvdata(dev)); | ||
2121 | } | ||
2122 | #endif | ||
2123 | |||
2124 | #define ES18XX_DRIVER "snd_es18xx" | ||
2125 | |||
2126 | static struct platform_driver snd_es18xx_nonpnp_driver = { | ||
2127 | .probe = snd_es18xx_nonpnp_probe, | ||
2128 | .remove = __devexit_p(snd_es18xx_nonpnp_remove), | ||
2129 | #ifdef CONFIG_PM | ||
2130 | .suspend = snd_es18xx_nonpnp_suspend, | ||
2131 | .resume = snd_es18xx_nonpnp_resume, | ||
2132 | #endif | ||
2133 | .driver = { | ||
2134 | .name = ES18XX_DRIVER | ||
2135 | }, | ||
2136 | }; | ||
2137 | |||
2117 | 2138 | ||
2118 | #ifdef CONFIG_PNP | 2139 | #ifdef CONFIG_PNP |
2119 | static int __devinit snd_audiodrive_pnp_detect(struct pnp_card_link *card, | 2140 | static int __devinit snd_audiodrive_pnp_detect(struct pnp_card_link *pcard, |
2120 | const struct pnp_card_device_id *id) | 2141 | const struct pnp_card_device_id *pid) |
2121 | { | 2142 | { |
2122 | static int dev; | 2143 | static int dev; |
2144 | struct snd_card *card; | ||
2123 | int res; | 2145 | int res; |
2124 | 2146 | ||
2125 | for ( ; dev < SNDRV_CARDS; dev++) { | 2147 | for ( ; dev < SNDRV_CARDS; dev++) { |
2126 | if (!enable[dev] || !isapnp[dev]) | 2148 | if (enable[dev] && isapnp[dev]) |
2127 | continue; | 2149 | break; |
2128 | res = snd_audiodrive_probe(dev, card, id); | 2150 | } |
2129 | if (res < 0) | 2151 | if (dev >= SNDRV_CARDS) |
2130 | return res; | 2152 | return -ENODEV; |
2131 | dev++; | ||
2132 | return 0; | ||
2133 | } | ||
2134 | 2153 | ||
2135 | return -ENODEV; | 2154 | card = snd_es18xx_card_new(dev); |
2155 | if (! card) | ||
2156 | return -ENOMEM; | ||
2157 | |||
2158 | if ((res = snd_audiodrive_pnp(dev, card->private_data, pcard, pid)) < 0) { | ||
2159 | snd_card_free(card); | ||
2160 | return res; | ||
2161 | } | ||
2162 | snd_card_set_dev(card, &pcard->card->dev); | ||
2163 | if ((res = snd_audiodrive_probe(card, dev)) < 0) { | ||
2164 | snd_card_free(card); | ||
2165 | return res; | ||
2166 | } | ||
2167 | |||
2168 | pnp_set_card_drvdata(pcard, card); | ||
2169 | dev++; | ||
2170 | return 0; | ||
2136 | } | 2171 | } |
2137 | 2172 | ||
2138 | static void __devexit snd_audiodrive_pnp_remove(struct pnp_card_link * pcard) | 2173 | static void __devexit snd_audiodrive_pnp_remove(struct pnp_card_link * pcard) |
2139 | { | 2174 | { |
2140 | struct snd_card *card = (struct snd_card *) pnp_get_card_drvdata(pcard); | 2175 | snd_card_free(pnp_get_card_drvdata(pcard)); |
2176 | pnp_set_card_drvdata(pcard, NULL); | ||
2177 | } | ||
2141 | 2178 | ||
2142 | snd_card_disconnect(card); | 2179 | #ifdef CONFIG_PM |
2143 | snd_card_free_in_thread(card); | 2180 | static int snd_audiodrive_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state) |
2181 | { | ||
2182 | return snd_es18xx_suspend(pnp_get_card_drvdata(pcard), state); | ||
2183 | } | ||
2184 | |||
2185 | static int snd_audiodrive_pnp_resume(struct pnp_card_link *pcard) | ||
2186 | { | ||
2187 | return snd_es18xx_resume(pnp_get_card_drvdata(pcard)); | ||
2144 | } | 2188 | } |
2145 | 2189 | ||
2190 | #endif | ||
2191 | |||
2146 | static struct pnp_card_driver es18xx_pnpc_driver = { | 2192 | static struct pnp_card_driver es18xx_pnpc_driver = { |
2147 | .flags = PNP_DRIVER_RES_DISABLE, | 2193 | .flags = PNP_DRIVER_RES_DISABLE, |
2148 | .name = "es18xx", | 2194 | .name = "es18xx", |
2149 | .id_table = snd_audiodrive_pnpids, | 2195 | .id_table = snd_audiodrive_pnpids, |
2150 | .probe = snd_audiodrive_pnp_detect, | 2196 | .probe = snd_audiodrive_pnp_detect, |
2151 | .remove = __devexit_p(snd_audiodrive_pnp_remove), | 2197 | .remove = __devexit_p(snd_audiodrive_pnp_remove), |
2198 | #ifdef CONFIG_PM | ||
2199 | .suspend = snd_audiodrive_pnp_suspend, | ||
2200 | .resume = snd_audiodrive_pnp_resume, | ||
2201 | #endif | ||
2152 | }; | 2202 | }; |
2153 | #endif /* CONFIG_PNP */ | 2203 | #endif /* CONFIG_PNP */ |
2154 | 2204 | ||
2155 | static int __init alsa_card_es18xx_init(void) | 2205 | static int __init alsa_card_es18xx_init(void) |
2156 | { | 2206 | { |
2157 | static unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280, -1}; | 2207 | int i, err, cards = 0; |
2158 | int dev, cards = 0, i; | ||
2159 | 2208 | ||
2160 | /* legacy non-auto cards at first */ | 2209 | if ((err = platform_driver_register(&snd_es18xx_nonpnp_driver)) < 0) |
2161 | for (dev = 0; dev < SNDRV_CARDS; dev++) { | 2210 | return err; |
2162 | if (!enable[dev] || port[dev] == SNDRV_AUTO_PORT) | 2211 | |
2163 | continue; | 2212 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { |
2164 | if (is_isapnp_selected(dev)) | 2213 | struct platform_device *device; |
2214 | if (is_isapnp_selected(i)) | ||
2165 | continue; | 2215 | continue; |
2166 | if (snd_audiodrive_probe(dev, NULL, NULL) >= 0) | 2216 | device = platform_device_register_simple(ES18XX_DRIVER, |
2167 | cards++; | 2217 | i, NULL, 0); |
2218 | if (IS_ERR(device)) { | ||
2219 | err = PTR_ERR(device); | ||
2220 | platform_driver_unregister(&snd_es18xx_nonpnp_driver); | ||
2221 | return err; | ||
2222 | } | ||
2223 | cards++; | ||
2168 | } | 2224 | } |
2169 | /* legacy auto configured cards */ | ||
2170 | i = snd_legacy_auto_probe(possible_ports, snd_audiodrive_probe_legacy_port); | ||
2171 | if (i > 0) | ||
2172 | cards += i; | ||
2173 | 2225 | ||
2174 | #ifdef CONFIG_PNP | ||
2175 | /* ISA PnP cards at last */ | ||
2176 | i = pnp_register_card_driver(&es18xx_pnpc_driver); | 2226 | i = pnp_register_card_driver(&es18xx_pnpc_driver); |
2177 | if (i > 0) | 2227 | if (i > 0) |
2178 | cards += i; | 2228 | cards += i; |
2179 | 2229 | ||
2180 | #endif | ||
2181 | if(!cards) { | 2230 | if(!cards) { |
2182 | #ifdef CONFIG_PNP | ||
2183 | pnp_unregister_card_driver(&es18xx_pnpc_driver); | 2231 | pnp_unregister_card_driver(&es18xx_pnpc_driver); |
2184 | #endif | 2232 | platform_driver_unregister(&snd_es18xx_nonpnp_driver); |
2185 | #ifdef MODULE | 2233 | #ifdef MODULE |
2186 | snd_printk(KERN_ERR "ESS AudioDrive ES18xx soundcard not found or device busy\n"); | 2234 | snd_printk(KERN_ERR "ESS AudioDrive ES18xx soundcard not found or device busy\n"); |
2187 | #endif | 2235 | #endif |
@@ -2192,14 +2240,8 @@ static int __init alsa_card_es18xx_init(void) | |||
2192 | 2240 | ||
2193 | static void __exit alsa_card_es18xx_exit(void) | 2241 | static void __exit alsa_card_es18xx_exit(void) |
2194 | { | 2242 | { |
2195 | int idx; | ||
2196 | |||
2197 | #ifdef CONFIG_PNP | ||
2198 | /* PnP cards first */ | ||
2199 | pnp_unregister_card_driver(&es18xx_pnpc_driver); | 2243 | pnp_unregister_card_driver(&es18xx_pnpc_driver); |
2200 | #endif | 2244 | platform_driver_unregister(&snd_es18xx_nonpnp_driver); |
2201 | for(idx = 0; idx < SNDRV_CARDS; idx++) | ||
2202 | snd_card_free(snd_audiodrive_legacy[idx]); | ||
2203 | } | 2245 | } |
2204 | 2246 | ||
2205 | module_init(alsa_card_es18xx_init) | 2247 | module_init(alsa_card_es18xx_init) |