diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/isa/ad1848/ad1848.c | 89 |
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."); | |||
60 | module_param_array(thinkpad, bool, NULL, 0444); | 62 | module_param_array(thinkpad, bool, NULL, 0444); |
61 | MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series."); | 63 | MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series."); |
62 | 64 | ||
63 | static struct snd_card *snd_ad1848_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; | ||
64 | 65 | ||
65 | 66 | static int __init snd_ad1848_probe(struct platform_device *pdev) | |
66 | static 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 | ||
126 | static int __init alsa_card_ad1848_init(void) | 127 | static 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 | ||
135 | static 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 | |||
145 | static 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 | |||
158 | static 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 | ||
170 | static 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 | ||
143 | static void __exit alsa_card_ad1848_exit(void) | 203 | static 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 | ||
151 | module_init(alsa_card_ad1848_init) | 208 | module_init(alsa_card_ad1848_init) |