aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa/cs423x/cs4236.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2005-11-17 11:00:53 -0500
committerJaroslav Kysela <perex@suse.cz>2006-01-03 06:28:16 -0500
commit6bba41ac974ad77aa21d112a368ee565b55f303b (patch)
tree421ee3a28760d64e6b6a0d8ea2176e18febe4026 /sound/isa/cs423x/cs4236.c
parent8b91375736ca602a5fc0695b53caa89b6ef263c9 (diff)
[ALSA] cs4236 - Use platform_device
Modules: CS4236+ driver Rewrite the probe/remove with platform_device. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/isa/cs423x/cs4236.c')
-rw-r--r--sound/isa/cs423x/cs4236.c269
1 files changed, 176 insertions, 93 deletions
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index a28f24c4f027..bc1054845a73 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -21,6 +21,8 @@
21 21
22#include <sound/driver.h> 22#include <sound/driver.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/err.h>
25#include <linux/platform_device.h>
24#include <linux/slab.h> 26#include <linux/slab.h>
25#include <linux/pnp.h> 27#include <linux/pnp.h>
26#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
@@ -123,6 +125,7 @@ module_param_array(dma2, int, NULL, 0444);
123MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver."); 125MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver.");
124 126
125struct snd_card_cs4236 { 127struct snd_card_cs4236 {
128 struct snd_cs4231 *chip;
126 struct resource *res_sb_port; 129 struct resource *res_sb_port;
127#ifdef CONFIG_PNP 130#ifdef CONFIG_PNP
128 struct pnp_dev *wss; 131 struct pnp_dev *wss;
@@ -131,8 +134,6 @@ struct snd_card_cs4236 {
131#endif 134#endif
132}; 135};
133 136
134static struct snd_card *snd_cs4236_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
135
136#ifdef CONFIG_PNP 137#ifdef CONFIG_PNP
137 138
138#define ISAPNP_CS4232(_va, _vb, _vc, _device, _wss, _ctrl, _mpu401) \ 139#define ISAPNP_CS4232(_va, _vb, _vc, _device, _wss, _ctrl, _mpu401) \
@@ -158,6 +159,8 @@ static struct snd_card *snd_cs4236_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
158 159
159 160
160#ifdef CS4232 161#ifdef CS4232
162#define CS423X_DRIVER "snd_cs4232"
163#define CS423X_ISAPNP_DRIVER "cs4232_isapnp"
161static struct pnp_card_device_id snd_cs423x_pnpids[] = { 164static struct pnp_card_device_id snd_cs423x_pnpids[] = {
162 /* Philips PCA70PS */ 165 /* Philips PCA70PS */
163 { .id = "CSC0d32", .devs = { { "CSC0000" }, { "CSC0010" }, { "PNPb006" } } }, 166 { .id = "CSC0d32", .devs = { { "CSC0000" }, { "CSC0010" }, { "PNPb006" } } },
@@ -177,6 +180,8 @@ static struct pnp_card_device_id snd_cs423x_pnpids[] = {
177 { .id = "" } /* end */ 180 { .id = "" } /* end */
178}; 181};
179#else /* CS4236 */ 182#else /* CS4236 */
183#define CS423X_DRIVER "snd_cs4236"
184#define CS423X_ISAPNP_DRIVER "cs4236_isapnp"
180static struct pnp_card_device_id snd_cs423x_pnpids[] = { 185static struct pnp_card_device_id snd_cs423x_pnpids[] = {
181 /* Intel Marlin Spike Motherboard - CS4235 */ 186 /* Intel Marlin Spike Motherboard - CS4235 */
182 { .id = "CSC0225", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, 187 { .id = "CSC0225", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
@@ -375,60 +380,44 @@ static int __devinit snd_card_cs4236_pnp(int dev, struct snd_card_cs4236 *acard,
375} 380}
376#endif /* CONFIG_PNP */ 381#endif /* CONFIG_PNP */
377 382
378static void snd_card_cs4236_free(struct snd_card *card)
379{
380 struct snd_card_cs4236 *acard = (struct snd_card_cs4236 *)card->private_data;
381
382 if (acard)
383 release_and_free_resource(acard->res_sb_port);
384}
385
386#ifdef CONFIG_PNP 383#ifdef CONFIG_PNP
387#define is_isapnp_selected(dev) isapnp[dev] 384#define is_isapnp_selected(dev) isapnp[dev]
388#else 385#else
389#define is_isapnp_selected(dev) 0 386#define is_isapnp_selected(dev) 0
390#endif 387#endif
391 388
392static int __devinit snd_card_cs423x_probe(int dev, struct pnp_card_link *pcard, 389static void snd_card_cs4236_free(struct snd_card *card)
393 const struct pnp_card_device_id *pid) 390{
391 struct snd_card_cs4236 *acard = card->private_data;
392
393 release_and_free_resource(acard->res_sb_port);
394}
395
396static struct snd_card *snd_cs423x_card_new(int dev)
394{ 397{
395 struct snd_card *card; 398 struct snd_card *card;
396 struct snd_card_cs4236 *acard;
397 struct snd_pcm *pcm = NULL;
398 struct snd_cs4231 *chip;
399 struct snd_opl3 *opl3;
400 int err;
401 399
402 if (! is_isapnp_selected(dev)) {
403 if (port[dev] == SNDRV_AUTO_PORT) {
404 snd_printk(KERN_ERR "specify port\n");
405 return -EINVAL;
406 }
407 if (cport[dev] == SNDRV_AUTO_PORT) {
408 snd_printk(KERN_ERR "specify cport\n");
409 return -EINVAL;
410 }
411 }
412 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 400 card = snd_card_new(index[dev], id[dev], THIS_MODULE,
413 sizeof(struct snd_card_cs4236)); 401 sizeof(struct snd_card_cs4236));
414 if (card == NULL) 402 if (card == NULL)
415 return -ENOMEM; 403 return NULL;
416 acard = (struct snd_card_cs4236 *)card->private_data;
417 card->private_free = snd_card_cs4236_free; 404 card->private_free = snd_card_cs4236_free;
418#ifdef CONFIG_PNP 405 return card;
419 if (isapnp[dev]) { 406}
420 if ((err = snd_card_cs4236_pnp(dev, acard, pcard, pid))<0) { 407
421 printk(KERN_ERR "isapnp detection failed and probing for " IDENT " is not supported\n"); 408static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
422 goto _err; 409{
423 } 410 struct snd_card_cs4236 *acard;
424 snd_card_set_dev(card, &pcard->card->dev); 411 struct snd_pcm *pcm;
425 } 412 struct snd_cs4231 *chip;
426#endif 413 struct snd_opl3 *opl3;
414 int err;
415
416 acard = card->private_data;
427 if (sb_port[dev] > 0 && sb_port[dev] != SNDRV_AUTO_PORT) 417 if (sb_port[dev] > 0 && sb_port[dev] != SNDRV_AUTO_PORT)
428 if ((acard->res_sb_port = request_region(sb_port[dev], 16, IDENT " SB")) == NULL) { 418 if ((acard->res_sb_port = request_region(sb_port[dev], 16, IDENT " SB")) == NULL) {
429 printk(KERN_ERR IDENT ": unable to register SB port at 0x%lx\n", sb_port[dev]); 419 printk(KERN_ERR IDENT ": unable to register SB port at 0x%lx\n", sb_port[dev]);
430 err = -EBUSY; 420 return -EBUSY;
431 goto _err;
432 } 421 }
433 422
434#ifdef CS4232 423#ifdef CS4232
@@ -441,13 +430,14 @@ static int __devinit snd_card_cs423x_probe(int dev, struct pnp_card_link *pcard,
441 CS4231_HW_DETECT, 430 CS4231_HW_DETECT,
442 0, 431 0,
443 &chip)) < 0) 432 &chip)) < 0)
444 goto _err; 433 return err;
434 acard->chip = chip;
445 435
446 if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) 436 if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0)
447 goto _err; 437 return err;
448 438
449 if ((err = snd_cs4231_mixer(chip)) < 0) 439 if ((err = snd_cs4231_mixer(chip)) < 0)
450 goto _err; 440 return err;
451 441
452#else /* CS4236 */ 442#else /* CS4236 */
453 if ((err = snd_cs4236_create(card, 443 if ((err = snd_cs4236_create(card,
@@ -459,13 +449,14 @@ static int __devinit snd_card_cs423x_probe(int dev, struct pnp_card_link *pcard,
459 CS4231_HW_DETECT, 449 CS4231_HW_DETECT,
460 0, 450 0,
461 &chip)) < 0) 451 &chip)) < 0)
462 goto _err; 452 return err;
453 acard->chip = chip;
463 454
464 if ((err = snd_cs4236_pcm(chip, 0, &pcm)) < 0) 455 if ((err = snd_cs4236_pcm(chip, 0, &pcm)) < 0)
465 goto _err; 456 return err;
466 457
467 if ((err = snd_cs4236_mixer(chip)) < 0) 458 if ((err = snd_cs4236_mixer(chip)) < 0)
468 goto _err; 459 return err;
469#endif 460#endif
470 strcpy(card->driver, pcm->name); 461 strcpy(card->driver, pcm->name);
471 strcpy(card->shortname, pcm->name); 462 strcpy(card->shortname, pcm->name);
@@ -478,7 +469,7 @@ static int __devinit snd_card_cs423x_probe(int dev, struct pnp_card_link *pcard,
478 sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]); 469 sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
479 470
480 if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0) 471 if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0)
481 goto _err; 472 return err;
482 473
483 if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) { 474 if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
484 if (snd_opl3_create(card, 475 if (snd_opl3_create(card,
@@ -487,7 +478,7 @@ static int __devinit snd_card_cs423x_probe(int dev, struct pnp_card_link *pcard,
487 printk(KERN_WARNING IDENT ": OPL3 not detected\n"); 478 printk(KERN_WARNING IDENT ": OPL3 not detected\n");
488 } else { 479 } else {
489 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) 480 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
490 goto _err; 481 return err;
491 } 482 }
492 } 483 }
493 484
@@ -501,77 +492,175 @@ static int __devinit snd_card_cs423x_probe(int dev, struct pnp_card_link *pcard,
501 printk(KERN_WARNING IDENT ": MPU401 not detected\n"); 492 printk(KERN_WARNING IDENT ": MPU401 not detected\n");
502 } 493 }
503 494
504 if ((err = snd_card_set_generic_dev(card)) < 0) 495 return snd_card_register(card);
505 goto _err; 496}
506 497
507 if ((err = snd_card_register(card)) < 0) 498static int __init snd_cs423x_nonpnp_probe(struct platform_device *pdev)
508 goto _err; 499{
509 if (pcard) 500 int dev = pdev->id;
510 pnp_set_card_drvdata(pcard, card); 501 struct snd_card *card;
511 else 502 int err;
512 snd_cs4236_legacy[dev] = card; 503
504 if (port[dev] == SNDRV_AUTO_PORT) {
505 snd_printk(KERN_ERR "specify port\n");
506 return -EINVAL;
507 }
508 if (cport[dev] == SNDRV_AUTO_PORT) {
509 snd_printk(KERN_ERR "specify cport\n");
510 return -EINVAL;
511 }
512
513 card = snd_cs423x_card_new(dev);
514 if (! card)
515 return -ENOMEM;
516 snd_card_set_dev(card, &pdev->dev);
517 if ((err = snd_cs423x_probe(card, dev)) < 0) {
518 snd_card_free(card);
519 return err;
520 }
521
522 platform_set_drvdata(pdev, card);
513 return 0; 523 return 0;
524}
514 525
515 _err: 526static int __devexit snd_cs423x_nonpnp_remove(struct platform_device *devptr)
516 snd_card_free(card); 527{
517 return err; 528 snd_card_free(platform_get_drvdata(devptr));
529 platform_set_drvdata(devptr, NULL);
530 return 0;
518} 531}
519 532
533#ifdef CONFIG_PM
534static int snd_cs423x_suspend(struct snd_card *card)
535{
536 struct snd_card_cs4236 *acard = card->private_data;
537 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
538 acard->chip->suspend(acard->chip);
539 return 0;
540}
541
542static int snd_cs423x_resume(struct snd_card *card)
543{
544 struct snd_card_cs4236 *acard = card->private_data;
545 acard->chip->resume(acard->chip);
546 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
547 return 0;
548}
549
550static int snd_cs423x_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
551{
552 return snd_cs423x_suspend(platform_get_drvdata(dev));
553}
554
555static int snd_cs423x_nonpnp_resume(struct platform_device *dev)
556{
557 return snd_cs423x_resume(platform_get_drvdata(dev));
558}
559#endif
560
561static struct platform_driver snd_cs423x_nonpnp_driver = {
562 .probe = snd_cs423x_nonpnp_probe,
563 .remove = __devexit_p(snd_cs423x_nonpnp_remove),
564#ifdef CONFIG_PM
565 .suspend = snd_cs423x_nonpnp_suspend,
566 .resume = snd_cs423x_nonpnp_resume,
567#endif
568 .driver = {
569 .name = CS423X_DRIVER
570 },
571};
572
573
520#ifdef CONFIG_PNP 574#ifdef CONFIG_PNP
521static int __devinit snd_cs423x_pnp_detect(struct pnp_card_link *card, 575static int __devinit snd_cs423x_pnp_detect(struct pnp_card_link *pcard,
522 const struct pnp_card_device_id *id) 576 const struct pnp_card_device_id *pid)
523{ 577{
524 static int dev; 578 static int dev;
579 struct snd_card *card;
525 int res; 580 int res;
526 581
527 for ( ; dev < SNDRV_CARDS; dev++) { 582 for ( ; dev < SNDRV_CARDS; dev++) {
528 if (!enable[dev] || !isapnp[dev]) 583 if (enable[dev] && isapnp[dev])
529 continue; 584 break;
530 res = snd_card_cs423x_probe(dev, card, id); 585 }
531 if (res < 0) 586 if (dev >= SNDRV_CARDS)
532 return res; 587 return -ENODEV;
533 dev++; 588
534 return 0; 589 card = snd_cs423x_card_new(dev);
590 if (! card)
591 return -ENOMEM;
592 if ((res = snd_card_cs4236_pnp(dev, card->private_data, pcard, pid))<0) {
593 printk(KERN_ERR "isapnp detection failed and probing for " IDENT " is not supported\n");
594 snd_card_free(card);
595 return res;
535 } 596 }
536 return -ENODEV; 597 snd_card_set_dev(card, &pcard->card->dev);
598 if ((res = snd_cs423x_probe(card, dev)) < 0) {
599 snd_card_free(card);
600 return res;
601 }
602 pnp_set_card_drvdata(pcard, card);
603 dev++;
604 return 0;
537} 605}
538 606
539static void __devexit snd_cs423x_pnp_remove(struct pnp_card_link * pcard) 607static void __devexit snd_cs423x_pnp_remove(struct pnp_card_link * pcard)
540{ 608{
541 struct snd_card *card = (struct snd_card *) pnp_get_card_drvdata(pcard); 609 snd_card_free(pnp_get_card_drvdata(pcard));
542 610 pnp_set_card_drvdata(pcard, NULL);
543 snd_card_disconnect(card);
544 snd_card_free_in_thread(card);
545} 611}
546 612
613#ifdef CONFIG_PM
614static int snd_cs423x_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
615{
616 return snd_cs423x_suspend(pnp_get_card_drvdata(pcard));
617}
618
619static int snd_cs423x_pnp_resume(struct pnp_card_link *pcard)
620{
621 return snd_cs423x_resume(pnp_get_card_drvdata(pcard));
622}
623#endif
624
547static struct pnp_card_driver cs423x_pnpc_driver = { 625static struct pnp_card_driver cs423x_pnpc_driver = {
548 .flags = PNP_DRIVER_RES_DISABLE, 626 .flags = PNP_DRIVER_RES_DISABLE,
549 .name = "cs423x", 627 .name = CS423X_ISAPNP_DRIVER,
550 .id_table = snd_cs423x_pnpids, 628 .id_table = snd_cs423x_pnpids,
551 .probe = snd_cs423x_pnp_detect, 629 .probe = snd_cs423x_pnp_detect,
552 .remove = __devexit_p(snd_cs423x_pnp_remove), 630 .remove = __devexit_p(snd_cs423x_pnp_remove),
631#ifdef CONFIG_PM
632 .suspend = snd_cs423x_pnp_suspend,
633 .resume = snd_cs423x_pnp_resume,
634#endif
553}; 635};
554#endif /* CONFIG_PNP */ 636#endif /* CONFIG_PNP */
555 637
556static int __init alsa_card_cs423x_init(void) 638static int __init alsa_card_cs423x_init(void)
557{ 639{
558 int dev, cards = 0; 640 int i, err, cards = 0;
559 641
560 for (dev = 0; dev < SNDRV_CARDS; dev++) { 642 if ((err = platform_driver_register(&snd_cs423x_nonpnp_driver)) < 0)
561 if (!enable[dev]) 643 return err;
562 continue; 644
563 if (is_isapnp_selected(dev)) 645 for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
646 struct platform_device *device;
647 if (is_isapnp_selected(i))
564 continue; 648 continue;
565 if (snd_card_cs423x_probe(dev, NULL, NULL) >= 0) 649 device = platform_device_register_simple(CS423X_DRIVER,
566 cards++; 650 i, NULL, 0);
651 if (IS_ERR(device)) {
652 err = PTR_ERR(device);
653 platform_driver_unregister(&snd_cs423x_nonpnp_driver);
654 return err;
655 }
656 cards++;
567 } 657 }
568#ifdef CONFIG_PNP 658 i = pnp_register_card_driver(&cs423x_pnpc_driver);
569 cards += pnp_register_card_driver(&cs423x_pnpc_driver); 659 if (i > 0)
570#endif 660 cards += i;
571 if (!cards) { 661 if (!cards) {
572#ifdef CONFIG_PNP
573 pnp_unregister_card_driver(&cs423x_pnpc_driver); 662 pnp_unregister_card_driver(&cs423x_pnpc_driver);
574#endif 663 platform_driver_unregister(&snd_cs423x_nonpnp_driver);
575#ifdef MODULE 664#ifdef MODULE
576 printk(KERN_ERR IDENT " soundcard not found or device busy\n"); 665 printk(KERN_ERR IDENT " soundcard not found or device busy\n");
577#endif 666#endif
@@ -582,14 +671,8 @@ static int __init alsa_card_cs423x_init(void)
582 671
583static void __exit alsa_card_cs423x_exit(void) 672static void __exit alsa_card_cs423x_exit(void)
584{ 673{
585 int idx;
586
587#ifdef CONFIG_PNP
588 /* PnP cards first */
589 pnp_unregister_card_driver(&cs423x_pnpc_driver); 674 pnp_unregister_card_driver(&cs423x_pnpc_driver);
590#endif 675 platform_driver_unregister(&snd_cs423x_nonpnp_driver);
591 for (idx = 0; idx < SNDRV_CARDS; idx++)
592 snd_card_free(snd_cs4236_legacy[idx]);
593} 676}
594 677
595module_init(alsa_card_cs423x_init) 678module_init(alsa_card_cs423x_init)