diff options
Diffstat (limited to 'sound/isa')
-rw-r--r-- | sound/isa/sgalaxy.c | 93 |
1 files changed, 76 insertions, 17 deletions
diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c index c16b53ba7ea6..2e1d4677fe12 100644 --- a/sound/isa/sgalaxy.c +++ b/sound/isa/sgalaxy.c | |||
@@ -22,12 +22,14 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <sound/driver.h> | 24 | #include <sound/driver.h> |
25 | #include <asm/dma.h> | ||
26 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/err.h> | ||
27 | #include <linux/platform_device.h> | ||
27 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
28 | #include <linux/time.h> | 29 | #include <linux/time.h> |
29 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
30 | #include <linux/moduleparam.h> | 31 | #include <linux/moduleparam.h> |
32 | #include <asm/dma.h> | ||
31 | #include <sound/core.h> | 33 | #include <sound/core.h> |
32 | #include <sound/sb.h> | 34 | #include <sound/sb.h> |
33 | #include <sound/ad1848.h> | 35 | #include <sound/ad1848.h> |
@@ -65,8 +67,6 @@ MODULE_PARM_DESC(dma1, "DMA1 # for Sound Galaxy driver."); | |||
65 | #define SGALAXY_AUXC_LEFT 18 | 67 | #define SGALAXY_AUXC_LEFT 18 |
66 | #define SGALAXY_AUXC_RIGHT 19 | 68 | #define SGALAXY_AUXC_RIGHT 19 |
67 | 69 | ||
68 | static struct snd_card *snd_sgalaxy_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; | ||
69 | |||
70 | #define PFX "sgalaxy: " | 70 | #define PFX "sgalaxy: " |
71 | 71 | ||
72 | /* | 72 | /* |
@@ -216,8 +216,9 @@ static int __init snd_sgalaxy_mixer(struct snd_ad1848 *chip) | |||
216 | return 0; | 216 | return 0; |
217 | } | 217 | } |
218 | 218 | ||
219 | static int __init snd_sgalaxy_probe(int dev) | 219 | static int __init snd_sgalaxy_probe(struct platform_device *devptr) |
220 | { | 220 | { |
221 | int dev = devptr->id; | ||
221 | static int possible_irqs[] = {7, 9, 10, 11, -1}; | 222 | static int possible_irqs[] = {7, 9, 10, 11, -1}; |
222 | static int possible_dmas[] = {1, 3, 0, -1}; | 223 | static int possible_dmas[] = {1, 3, 0, -1}; |
223 | int err, xirq, xdma1; | 224 | int err, xirq, xdma1; |
@@ -260,6 +261,7 @@ static int __init snd_sgalaxy_probe(int dev) | |||
260 | xirq, xdma1, | 261 | xirq, xdma1, |
261 | AD1848_HW_DETECT, &chip)) < 0) | 262 | AD1848_HW_DETECT, &chip)) < 0) |
262 | goto _err; | 263 | goto _err; |
264 | card->private_data = chip; | ||
263 | 265 | ||
264 | if ((err = snd_ad1848_pcm(chip, 0, NULL)) < 0) { | 266 | if ((err = snd_ad1848_pcm(chip, 0, NULL)) < 0) { |
265 | snd_printdd(PFX "error creating new ad1848 PCM device\n"); | 267 | snd_printdd(PFX "error creating new ad1848 PCM device\n"); |
@@ -279,13 +281,12 @@ static int __init snd_sgalaxy_probe(int dev) | |||
279 | sprintf(card->longname, "Sound Galaxy at 0x%lx, irq %d, dma %d", | 281 | sprintf(card->longname, "Sound Galaxy at 0x%lx, irq %d, dma %d", |
280 | wssport[dev], xirq, xdma1); | 282 | wssport[dev], xirq, xdma1); |
281 | 283 | ||
282 | if ((err = snd_card_set_generic_dev(card)) < 0) | 284 | snd_card_set_dev(card, &devptr->dev); |
283 | goto _err; | ||
284 | 285 | ||
285 | if ((err = snd_card_register(card)) < 0) | 286 | if ((err = snd_card_register(card)) < 0) |
286 | goto _err; | 287 | goto _err; |
287 | 288 | ||
288 | snd_sgalaxy_cards[dev] = card; | 289 | platform_set_drvdata(devptr, card); |
289 | return 0; | 290 | return 0; |
290 | 291 | ||
291 | _err: | 292 | _err: |
@@ -293,30 +294,88 @@ static int __init snd_sgalaxy_probe(int dev) | |||
293 | return err; | 294 | return err; |
294 | } | 295 | } |
295 | 296 | ||
297 | static int __devexit snd_sgalaxy_remove(struct platform_device *devptr) | ||
298 | { | ||
299 | snd_card_free(platform_get_drvdata(devptr)); | ||
300 | platform_set_drvdata(devptr, NULL); | ||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | #ifdef CONFIG_PM | ||
305 | static int snd_sgalaxy_suspend(struct platform_device *pdev, pm_message_t state) | ||
306 | { | ||
307 | struct snd_card *card = platform_get_drvdata(pdev); | ||
308 | struct snd_ad1848 *chip = card->private_data; | ||
309 | |||
310 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | ||
311 | chip->suspend(chip); | ||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static int snd_sgalaxy_resume(struct platform_device *pdev) | ||
316 | { | ||
317 | struct snd_card *card = platform_get_drvdata(pdev); | ||
318 | struct snd_ad1848 *chip = card->private_data; | ||
319 | |||
320 | chip->resume(chip); | ||
321 | snd_ad1848_out(chip, SGALAXY_AUXC_LEFT, chip->image[SGALAXY_AUXC_LEFT]); | ||
322 | snd_ad1848_out(chip, SGALAXY_AUXC_RIGHT, chip->image[SGALAXY_AUXC_RIGHT]); | ||
323 | |||
324 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | ||
325 | return 0; | ||
326 | } | ||
327 | #endif | ||
328 | |||
329 | #define SND_SGALAXY_DRIVER "snd_sgalaxy" | ||
330 | |||
331 | static struct platform_driver snd_sgalaxy_driver = { | ||
332 | .probe = snd_sgalaxy_probe, | ||
333 | .remove = __devexit_p(snd_sgalaxy_remove), | ||
334 | #ifdef CONFIG_PM | ||
335 | .suspend = snd_sgalaxy_suspend, | ||
336 | .resume = snd_sgalaxy_resume, | ||
337 | #endif | ||
338 | .driver = { | ||
339 | .name = SND_SGALAXY_DRIVER | ||
340 | }, | ||
341 | }; | ||
342 | |||
296 | static int __init alsa_card_sgalaxy_init(void) | 343 | static int __init alsa_card_sgalaxy_init(void) |
297 | { | 344 | { |
298 | int dev, cards; | 345 | int i, cards, err; |
299 | 346 | ||
300 | for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev]; dev++) { | 347 | err = platform_driver_register(&snd_sgalaxy_driver); |
301 | if (snd_sgalaxy_probe(dev) >= 0) | 348 | if (err < 0) |
302 | cards++; | 349 | return err; |
350 | |||
351 | cards = 0; | ||
352 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | ||
353 | struct platform_device *device; | ||
354 | device = platform_device_register_simple(SND_SGALAXY_DRIVER, | ||
355 | i, NULL, 0); | ||
356 | if (IS_ERR(device)) { | ||
357 | err = PTR_ERR(device); | ||
358 | goto errout; | ||
359 | } | ||
360 | cards++; | ||
303 | } | 361 | } |
304 | if (!cards) { | 362 | if (!cards) { |
305 | #ifdef MODULE | 363 | #ifdef MODULE |
306 | snd_printk(KERN_ERR "Sound Galaxy soundcard not found or device busy\n"); | 364 | snd_printk(KERN_ERR "Sound Galaxy soundcard not found or device busy\n"); |
307 | #endif | 365 | #endif |
308 | return -ENODEV; | 366 | err = -ENODEV; |
367 | goto errout; | ||
309 | } | 368 | } |
310 | |||
311 | return 0; | 369 | return 0; |
370 | |||
371 | errout: | ||
372 | platform_driver_unregister(&snd_sgalaxy_driver); | ||
373 | return err; | ||
312 | } | 374 | } |
313 | 375 | ||
314 | static void __exit alsa_card_sgalaxy_exit(void) | 376 | static void __exit alsa_card_sgalaxy_exit(void) |
315 | { | 377 | { |
316 | int idx; | 378 | platform_driver_unregister(&snd_sgalaxy_driver); |
317 | |||
318 | for (idx = 0; idx < SNDRV_CARDS; idx++) | ||
319 | snd_card_free(snd_sgalaxy_cards[idx]); | ||
320 | } | 379 | } |
321 | 380 | ||
322 | module_init(alsa_card_sgalaxy_init) | 381 | module_init(alsa_card_sgalaxy_init) |