diff options
Diffstat (limited to 'sound/isa/cs423x')
-rw-r--r-- | sound/isa/cs423x/cs4231.c | 96 |
1 files changed, 77 insertions, 19 deletions
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c index a8da87903d94..b5252a5d7412 100644 --- a/sound/isa/cs423x/cs4231.c +++ b/sound/isa/cs423x/cs4231.c | |||
@@ -22,6 +22,8 @@ | |||
22 | 22 | ||
23 | #include <sound/driver.h> | 23 | #include <sound/driver.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/err.h> | ||
26 | #include <linux/platform_device.h> | ||
25 | #include <linux/time.h> | 27 | #include <linux/time.h> |
26 | #include <linux/wait.h> | 28 | #include <linux/wait.h> |
27 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
@@ -64,14 +66,12 @@ MODULE_PARM_DESC(dma1, "DMA1 # for CS4231 driver."); | |||
64 | module_param_array(dma2, int, NULL, 0444); | 66 | module_param_array(dma2, int, NULL, 0444); |
65 | MODULE_PARM_DESC(dma2, "DMA2 # for CS4231 driver."); | 67 | MODULE_PARM_DESC(dma2, "DMA2 # for CS4231 driver."); |
66 | 68 | ||
67 | static struct snd_card *snd_cs4231_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; | ||
68 | 69 | ||
69 | 70 | static int __init snd_cs4231_probe(struct platform_device *pdev) | |
70 | static int __init snd_card_cs4231_probe(int dev) | ||
71 | { | 71 | { |
72 | int dev = pdev->id; | ||
72 | struct snd_card *card; | 73 | struct snd_card *card; |
73 | struct snd_card_cs4231 *acard; | 74 | struct snd_pcm *pcm; |
74 | struct snd_pcm *pcm = NULL; | ||
75 | struct snd_cs4231 *chip; | 75 | struct snd_cs4231 *chip; |
76 | int err; | 76 | int err; |
77 | 77 | ||
@@ -90,7 +90,6 @@ static int __init snd_card_cs4231_probe(int dev) | |||
90 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 90 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); |
91 | if (card == NULL) | 91 | if (card == NULL) |
92 | return -ENOMEM; | 92 | return -ENOMEM; |
93 | acard = (struct snd_card_cs4231 *)card->private_data; | ||
94 | if ((err = snd_cs4231_create(card, port[dev], -1, | 93 | if ((err = snd_cs4231_create(card, port[dev], -1, |
95 | irq[dev], | 94 | irq[dev], |
96 | dma1[dev], | 95 | dma1[dev], |
@@ -98,6 +97,7 @@ static int __init snd_card_cs4231_probe(int dev) | |||
98 | CS4231_HW_DETECT, | 97 | CS4231_HW_DETECT, |
99 | 0, &chip)) < 0) | 98 | 0, &chip)) < 0) |
100 | goto _err; | 99 | goto _err; |
100 | card->private_data = chip; | ||
101 | 101 | ||
102 | if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) | 102 | if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) |
103 | goto _err; | 103 | goto _err; |
@@ -125,12 +125,12 @@ static int __init snd_card_cs4231_probe(int dev) | |||
125 | printk(KERN_WARNING "cs4231: MPU401 not detected\n"); | 125 | printk(KERN_WARNING "cs4231: MPU401 not detected\n"); |
126 | } | 126 | } |
127 | 127 | ||
128 | if ((err = snd_card_set_generic_dev(card)) < 0) | 128 | snd_card_set_dev(card, &pdev->dev); |
129 | goto _err; | ||
130 | 129 | ||
131 | if ((err = snd_card_register(card)) < 0) | 130 | if ((err = snd_card_register(card)) < 0) |
132 | goto _err; | 131 | goto _err; |
133 | snd_cs4231_cards[dev] = card; | 132 | |
133 | platform_set_drvdata(pdev, card); | ||
134 | return 0; | 134 | return 0; |
135 | 135 | ||
136 | _err: | 136 | _err: |
@@ -138,29 +138,87 @@ static int __init snd_card_cs4231_probe(int dev) | |||
138 | return err; | 138 | return err; |
139 | } | 139 | } |
140 | 140 | ||
141 | static int __init alsa_card_cs4231_init(void) | 141 | static int __devexit snd_cs4231_remove(struct platform_device *devptr) |
142 | { | ||
143 | snd_card_free(platform_get_drvdata(devptr)); | ||
144 | platform_set_drvdata(devptr, NULL); | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | #ifdef CONFIG_PM | ||
149 | static int snd_cs4231_suspend(struct platform_device *dev, pm_message_t state) | ||
142 | { | 150 | { |
143 | int dev, cards; | 151 | struct snd_card *card; |
152 | struct snd_cs4231 *chip; | ||
153 | card = platform_get_drvdata(dev); | ||
154 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | ||
155 | chip = card->private_data; | ||
156 | chip->suspend(chip); | ||
157 | return 0; | ||
158 | } | ||
144 | 159 | ||
145 | for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev]; dev++) { | 160 | static int snd_cs4231_resume(struct platform_device *dev) |
146 | if (snd_card_cs4231_probe(dev) >= 0) | 161 | { |
147 | cards++; | 162 | struct snd_card *card; |
163 | struct snd_cs4231 *chip; | ||
164 | card = platform_get_drvdata(dev); | ||
165 | chip = card->private_data; | ||
166 | chip->resume(chip); | ||
167 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | ||
168 | return 0; | ||
169 | } | ||
170 | #endif | ||
171 | |||
172 | #define SND_CS4231_DRIVER "snd_cs4231" | ||
173 | |||
174 | static struct platform_driver snd_cs4231_driver = { | ||
175 | .probe = snd_cs4231_probe, | ||
176 | .remove = __devexit_p(snd_cs4231_remove), | ||
177 | #ifdef CONFIG_PM | ||
178 | .suspend = snd_cs4231_suspend, | ||
179 | .resume = snd_cs4231_resume, | ||
180 | #endif | ||
181 | .driver = { | ||
182 | .name = SND_CS4231_DRIVER | ||
183 | }, | ||
184 | }; | ||
185 | |||
186 | static int __init alsa_card_cs4231_init(void) | ||
187 | { | ||
188 | int i, cards, err; | ||
189 | |||
190 | err = platform_driver_register(&snd_cs4231_driver); | ||
191 | if (err < 0) | ||
192 | return err; | ||
193 | |||
194 | cards = 0; | ||
195 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | ||
196 | struct platform_device *device; | ||
197 | device = platform_device_register_simple(SND_CS4231_DRIVER, | ||
198 | i, NULL, 0); | ||
199 | if (IS_ERR(device)) { | ||
200 | err = PTR_ERR(device); | ||
201 | goto errout; | ||
202 | } | ||
203 | cards++; | ||
148 | } | 204 | } |
149 | if (!cards) { | 205 | if (!cards) { |
150 | #ifdef MODULE | 206 | #ifdef MODULE |
151 | printk(KERN_ERR "CS4231 soundcard not found or device busy\n"); | 207 | printk(KERN_ERR "CS4231 soundcard not found or device busy\n"); |
152 | #endif | 208 | #endif |
153 | return -ENODEV; | 209 | err = -ENODEV; |
210 | goto errout; | ||
154 | } | 211 | } |
155 | return 0; | 212 | return 0; |
213 | |||
214 | errout: | ||
215 | platform_driver_unregister(&snd_cs4231_driver); | ||
216 | return err; | ||
156 | } | 217 | } |
157 | 218 | ||
158 | static void __exit alsa_card_cs4231_exit(void) | 219 | static void __exit alsa_card_cs4231_exit(void) |
159 | { | 220 | { |
160 | int idx; | 221 | platform_driver_unregister(&snd_cs4231_driver); |
161 | |||
162 | for (idx = 0; idx < SNDRV_CARDS; idx++) | ||
163 | snd_card_free(snd_cs4231_cards[idx]); | ||
164 | } | 222 | } |
165 | 223 | ||
166 | module_init(alsa_card_cs4231_init) | 224 | module_init(alsa_card_cs4231_init) |