aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2005-11-17 10:58:26 -0500
committerJaroslav Kysela <perex@suse.cz>2006-01-03 06:28:11 -0500
commit686688458e5814ac0aca44fc2033218a848fd2d0 (patch)
treea02ecb0c5d5c35faf4e21728fe0c8a1be37993e3
parentc66d7f72569e304acc134b2561b148fe7c23c0f7 (diff)
[ALSA] ad1848 - Use platform_device, add PM
Modules: AD1848 driver Rewrite the probe/remove with platform_device. Add the PM support, too. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/isa/ad1848/ad1848.c89
1 files changed, 73 insertions, 16 deletions
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index ffc373b37a9b..1019e9fdff53 100644
--- a/sound/isa/ad1848/ad1848.c
+++ b/sound/isa/ad1848/ad1848.c
@@ -23,6 +23,8 @@
23 23
24#include <sound/driver.h> 24#include <sound/driver.h>
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/err.h>
27#include <linux/platform_device.h>
26#include <linux/time.h> 28#include <linux/time.h>
27#include <linux/wait.h> 29#include <linux/wait.h>
28#include <linux/moduleparam.h> 30#include <linux/moduleparam.h>
@@ -60,11 +62,10 @@ MODULE_PARM_DESC(dma1, "DMA1 # for AD1848 driver.");
60module_param_array(thinkpad, bool, NULL, 0444); 62module_param_array(thinkpad, bool, NULL, 0444);
61MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series."); 63MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series.");
62 64
63static struct snd_card *snd_ad1848_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
64 65
65 66static int __init snd_ad1848_probe(struct platform_device *pdev)
66static int __init snd_card_ad1848_probe(int dev)
67{ 67{
68 int dev = pdev->id;
68 struct snd_card *card; 69 struct snd_card *card;
69 struct snd_ad1848 *chip; 70 struct snd_ad1848 *chip;
70 struct snd_pcm *pcm; 71 struct snd_pcm *pcm;
@@ -93,6 +94,7 @@ static int __init snd_card_ad1848_probe(int dev)
93 thinkpad[dev] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT, 94 thinkpad[dev] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT,
94 &chip)) < 0) 95 &chip)) < 0)
95 goto _err; 96 goto _err;
97 card->private_data = chip;
96 98
97 if ((err = snd_ad1848_pcm(chip, 0, &pcm)) < 0) 99 if ((err = snd_ad1848_pcm(chip, 0, &pcm)) < 0)
98 goto _err; 100 goto _err;
@@ -109,13 +111,12 @@ static int __init snd_card_ad1848_probe(int dev)
109 if (thinkpad[dev]) 111 if (thinkpad[dev])
110 strcat(card->longname, " [Thinkpad]"); 112 strcat(card->longname, " [Thinkpad]");
111 113
112 if ((err = snd_card_set_generic_dev(card)) < 0) 114 snd_card_set_dev(card, &pdev->dev);
113 goto _err;
114 115
115 if ((err = snd_card_register(card)) < 0) 116 if ((err = snd_card_register(card)) < 0)
116 goto _err; 117 goto _err;
117 118
118 snd_ad1848_cards[dev] = card; 119 platform_set_drvdata(pdev, card);
119 return 0; 120 return 0;
120 121
121 _err: 122 _err:
@@ -123,29 +124,85 @@ static int __init snd_card_ad1848_probe(int dev)
123 return err; 124 return err;
124} 125}
125 126
126static int __init alsa_card_ad1848_init(void) 127static int __devexit snd_ad1848_remove(struct platform_device *devptr)
128{
129 snd_card_free(platform_get_drvdata(devptr));
130 platform_set_drvdata(devptr, NULL);
131 return 0;
132}
133
134#ifdef CONFIG_PM
135static int snd_ad1848_suspend(struct platform_device *pdev, pm_message_t state)
136{
137 struct snd_card *card = platform_get_drvdata(pdev);
138 struct snd_ad1848 *chip = card->private_data;
139
140 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
141 chip->suspend(chip);
142 return 0;
143}
144
145static int snd_ad1848_resume(struct platform_device *pdev)
127{ 146{
128 int dev, cards; 147 struct snd_card *card = platform_get_drvdata(pdev);
148 struct snd_ad1848 *chip = card->private_data;
129 149
130 for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev]; dev++) 150 chip->resume(chip);
131 if (snd_card_ad1848_probe(dev) >= 0) 151 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
132 cards++; 152 return 0;
153}
154#endif
155
156#define SND_AD1848_DRIVER "snd_ad1848"
157
158static struct platform_driver snd_ad1848_driver = {
159 .probe = snd_ad1848_probe,
160 .remove = __devexit_p(snd_ad1848_remove),
161#ifdef CONFIG_PM
162 .suspend = snd_ad1848_suspend,
163 .resume = snd_ad1848_resume,
164#endif
165 .driver = {
166 .name = SND_AD1848_DRIVER
167 },
168};
133 169
170static int __init alsa_card_ad1848_init(void)
171{
172 int i, cards, err;
173
174 err = platform_driver_register(&snd_ad1848_driver);
175 if (err < 0)
176 return err;
177
178 cards = 0;
179 for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
180 struct platform_device *device;
181 device = platform_device_register_simple(SND_AD1848_DRIVER,
182 i, NULL, 0);
183 if (IS_ERR(device)) {
184 err = PTR_ERR(device);
185 goto errout;
186 }
187 cards++;
188 }
134 if (!cards) { 189 if (!cards) {
135#ifdef MODULE 190#ifdef MODULE
136 printk(KERN_ERR "AD1848 soundcard not found or device busy\n"); 191 printk(KERN_ERR "AD1848 soundcard not found or device busy\n");
137#endif 192#endif
138 return -ENODEV; 193 err = -ENODEV;
194 goto errout;
139 } 195 }
140 return 0; 196 return 0;
197
198 errout:
199 platform_driver_unregister(&snd_ad1848_driver);
200 return err;
141} 201}
142 202
143static void __exit alsa_card_ad1848_exit(void) 203static void __exit alsa_card_ad1848_exit(void)
144{ 204{
145 int idx; 205 platform_driver_unregister(&snd_ad1848_driver);
146
147 for (idx = 0; idx < SNDRV_CARDS; idx++)
148 snd_card_free(snd_ad1848_cards[idx]);
149} 206}
150 207
151module_init(alsa_card_ad1848_init) 208module_init(alsa_card_ad1848_init)