aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa/cs423x/cs4236.c
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2009-02-16 15:38:37 -0500
committerTakashi Iwai <tiwai@suse.de>2009-02-16 17:05:25 -0500
commitc2b73d1458014a9f461b75bc1756a699a6c0781f (patch)
treed869727d6002ebf48fdb875b490108d85c5ff761 /sound/isa/cs423x/cs4236.c
parent96cf45cf559be375de29dd45afc50fa8946fb2aa (diff)
ALSA: cs4236: cs4232 and cs4236 driver merge to solve PnP BIOS detection
cs4232 and cs4236 driver merge to solve PnP BIOS detection. Also, the patch adds recognition if the chip is cs4236b+ or earlier part. This unifies drivers for both cs4232 and cs4236+ chips. It allows to use the PnP BIOS detection for the cs4236+ chips. Previously, only the snd-cs4232 could be detected by the PnP BIOS. The cs4232+ cards reports two separate PnP BIOS ids. The patch adds search for the second id to find out resources assigned to a control port. Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/isa/cs423x/cs4236.c')
-rw-r--r--sound/isa/cs423x/cs4236.c153
1 files changed, 69 insertions, 84 deletions
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index f7845986f467..a076a6ce8071 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -33,17 +33,14 @@
33 33
34MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 34MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
35MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
36#ifdef CS4232 36MODULE_DESCRIPTION("Cirrus Logic CS4232-9");
37MODULE_DESCRIPTION("Cirrus Logic CS4232");
38MODULE_SUPPORTED_DEVICE("{{Turtle Beach,TBS-2000}," 37MODULE_SUPPORTED_DEVICE("{{Turtle Beach,TBS-2000},"
39 "{Turtle Beach,Tropez Plus}," 38 "{Turtle Beach,Tropez Plus},"
40 "{SIC CrystalWave 32}," 39 "{SIC CrystalWave 32},"
41 "{Hewlett Packard,Omnibook 5500}," 40 "{Hewlett Packard,Omnibook 5500},"
42 "{TerraTec,Maestro 32/96}," 41 "{TerraTec,Maestro 32/96},"
43 "{Philips,PCA70PS}}"); 42 "{Philips,PCA70PS}},"
44#else 43 "{{Crystal Semiconductors,CS4235},"
45MODULE_DESCRIPTION("Cirrus Logic CS4235-9");
46MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4235},"
47 "{Crystal Semiconductors,CS4236}," 44 "{Crystal Semiconductors,CS4236},"
48 "{Crystal Semiconductors,CS4237}," 45 "{Crystal Semiconductors,CS4237},"
49 "{Crystal Semiconductors,CS4238}," 46 "{Crystal Semiconductors,CS4238},"
@@ -70,15 +67,11 @@ MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4235},"
70 "{Typhoon Soundsystem,CS4236B}," 67 "{Typhoon Soundsystem,CS4236B},"
71 "{Turtle Beach,Malibu}," 68 "{Turtle Beach,Malibu},"
72 "{Unknown,Digital PC 5000 Onboard}}"); 69 "{Unknown,Digital PC 5000 Onboard}}");
73#endif
74 70
75#ifdef CS4232 71MODULE_ALIAS("snd_cs4232");
76#define IDENT "CS4232" 72
77#define DEV_NAME "cs4232" 73#define IDENT "CS4232+"
78#else 74#define DEV_NAME "cs4232+"
79#define IDENT "CS4236+"
80#define DEV_NAME "cs4236"
81#endif
82 75
83static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 76static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
84static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 77static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
@@ -128,9 +121,7 @@ MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver.");
128#ifdef CONFIG_PNP 121#ifdef CONFIG_PNP
129static int isa_registered; 122static int isa_registered;
130static int pnpc_registered; 123static int pnpc_registered;
131#ifdef CS4232
132static int pnp_registered; 124static int pnp_registered;
133#endif
134#endif /* CONFIG_PNP */ 125#endif /* CONFIG_PNP */
135 126
136struct snd_card_cs4236 { 127struct snd_card_cs4236 {
@@ -145,11 +136,10 @@ struct snd_card_cs4236 {
145 136
146#ifdef CONFIG_PNP 137#ifdef CONFIG_PNP
147 138
148#ifdef CS4232
149/* 139/*
150 * PNP BIOS 140 * PNP BIOS
151 */ 141 */
152static const struct pnp_device_id snd_cs4232_pnpbiosids[] = { 142static const struct pnp_device_id snd_cs423x_pnpbiosids[] = {
153 { .id = "CSC0100" }, 143 { .id = "CSC0100" },
154 { .id = "CSC0000" }, 144 { .id = "CSC0000" },
155 /* Guillemot Turtlebeach something appears to be cs4232 compatible 145 /* Guillemot Turtlebeach something appears to be cs4232 compatible
@@ -157,10 +147,8 @@ static const struct pnp_device_id snd_cs4232_pnpbiosids[] = {
157 { .id = "GIM0100" }, 147 { .id = "GIM0100" },
158 { .id = "" } 148 { .id = "" }
159}; 149};
160MODULE_DEVICE_TABLE(pnp, snd_cs4232_pnpbiosids); 150MODULE_DEVICE_TABLE(pnp, snd_cs423x_pnpbiosids);
161#endif /* CS4232 */
162 151
163#ifdef CS4232
164#define CS423X_ISAPNP_DRIVER "cs4232_isapnp" 152#define CS423X_ISAPNP_DRIVER "cs4232_isapnp"
165static struct pnp_card_device_id snd_cs423x_pnpids[] = { 153static struct pnp_card_device_id snd_cs423x_pnpids[] = {
166 /* Philips PCA70PS */ 154 /* Philips PCA70PS */
@@ -179,12 +167,6 @@ static struct pnp_card_device_id snd_cs423x_pnpids[] = {
179 { .id = "CSCf032", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, 167 { .id = "CSCf032", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
180 /* Netfinity 3000 on-board soundcard */ 168 /* Netfinity 3000 on-board soundcard */
181 { .id = "CSCe825", .devs = { { "CSC0100" }, { "CSC0110" }, { "CSC010f" } } }, 169 { .id = "CSCe825", .devs = { { "CSC0100" }, { "CSC0110" }, { "CSC010f" } } },
182 /* --- */
183 { .id = "" } /* end */
184};
185#else /* CS4236 */
186#define CS423X_ISAPNP_DRIVER "cs4236_isapnp"
187static struct pnp_card_device_id snd_cs423x_pnpids[] = {
188 /* Intel Marlin Spike Motherboard - CS4235 */ 170 /* Intel Marlin Spike Motherboard - CS4235 */
189 { .id = "CSC0225", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, 171 { .id = "CSC0225", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
190 /* Intel Marlin Spike Motherboard (#2) - CS4235 */ 172 /* Intel Marlin Spike Motherboard (#2) - CS4235 */
@@ -266,7 +248,6 @@ static struct pnp_card_device_id snd_cs423x_pnpids[] = {
266 /* --- */ 248 /* --- */
267 { .id = "" } /* end */ 249 { .id = "" } /* end */
268}; 250};
269#endif
270 251
271MODULE_DEVICE_TABLE(pnp_card, snd_cs423x_pnpids); 252MODULE_DEVICE_TABLE(pnp_card, snd_cs423x_pnpids);
272 253
@@ -323,17 +304,19 @@ static int __devinit snd_cs423x_pnp_init_mpu(int dev, struct pnp_dev *pdev)
323 return 0; 304 return 0;
324} 305}
325 306
326#ifdef CS4232 307static int __devinit snd_card_cs423x_pnp(int dev, struct snd_card_cs4236 *acard,
327static int __devinit snd_card_cs4232_pnp(int dev, struct snd_card_cs4236 *acard, 308 struct pnp_dev *pdev,
328 struct pnp_dev *pdev) 309 struct pnp_dev *cdev)
329{ 310{
330 acard->wss = pdev; 311 acard->wss = pdev;
331 if (snd_cs423x_pnp_init_wss(dev, acard->wss) < 0) 312 if (snd_cs423x_pnp_init_wss(dev, acard->wss) < 0)
332 return -EBUSY; 313 return -EBUSY;
333 cport[dev] = -1; 314 if (cdev)
315 cport[dev] = pnp_port_start(cdev, 0);
316 else
317 cport[dev] = -1;
334 return 0; 318 return 0;
335} 319}
336#endif
337 320
338static int __devinit snd_card_cs423x_pnpc(int dev, struct snd_card_cs4236 *acard, 321static int __devinit snd_card_cs423x_pnpc(int dev, struct snd_card_cs4236 *acard,
339 struct pnp_card_link *card, 322 struct pnp_card_link *card,
@@ -411,40 +394,39 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
411 return -EBUSY; 394 return -EBUSY;
412 } 395 }
413 396
414#ifdef CS4232
415 err = snd_wss_create(card, port[dev], cport[dev], 397 err = snd_wss_create(card, port[dev], cport[dev],
416 irq[dev], 398 irq[dev],
417 dma1[dev], dma2[dev], 399 dma1[dev], dma2[dev],
418 WSS_HW_DETECT, 0, &chip); 400 WSS_HW_DETECT3, 0, &chip);
419 if (err < 0)
420 return err;
421 acard->chip = chip;
422
423 err = snd_wss_pcm(chip, 0, &pcm);
424 if (err < 0)
425 return err;
426
427 err = snd_wss_mixer(chip);
428 if (err < 0) 401 if (err < 0)
429 return err; 402 return err;
430 403 if (chip->hardware & WSS_HW_CS4236B_MASK) {
431#else /* CS4236 */ 404 snd_wss_free(chip);
432 err = snd_cs4236_create(card, 405 err = snd_cs4236_create(card,
433 port[dev], cport[dev], 406 port[dev], cport[dev],
434 irq[dev], dma1[dev], dma2[dev], 407 irq[dev], dma1[dev], dma2[dev],
435 WSS_HW_DETECT, 0, &chip); 408 WSS_HW_DETECT, 0, &chip);
436 if (err < 0) 409 if (err < 0)
437 return err; 410 return err;
438 acard->chip = chip; 411 acard->chip = chip;
439 412
440 err = snd_cs4236_pcm(chip, 0, &pcm); 413 err = snd_cs4236_pcm(chip, 0, &pcm);
441 if (err < 0) 414 if (err < 0)
442 return err; 415 return err;
443 416
444 err = snd_cs4236_mixer(chip); 417 err = snd_cs4236_mixer(chip);
445 if (err < 0) 418 if (err < 0)
446 return err; 419 return err;
447#endif 420 } else {
421 acard->chip = chip;
422 err = snd_wss_pcm(chip, 0, &pcm);
423 if (err < 0)
424 return err;
425
426 err = snd_wss_mixer(chip);
427 if (err < 0)
428 return err;
429 }
448 strcpy(card->driver, pcm->name); 430 strcpy(card->driver, pcm->name);
449 strcpy(card->shortname, pcm->name); 431 strcpy(card->shortname, pcm->name);
450 sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", 432 sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i",
@@ -579,13 +561,14 @@ static struct isa_driver cs423x_isa_driver = {
579 561
580 562
581#ifdef CONFIG_PNP 563#ifdef CONFIG_PNP
582#ifdef CS4232 564static int __devinit snd_cs423x_pnpbios_detect(struct pnp_dev *pdev,
583static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev,
584 const struct pnp_device_id *id) 565 const struct pnp_device_id *id)
585{ 566{
586 static int dev; 567 static int dev;
587 int err; 568 int err;
588 struct snd_card *card; 569 struct snd_card *card;
570 struct pnp_dev *cdev;
571 char cid[PNP_ID_LEN];
589 572
590 if (pnp_device_is_isapnp(pdev)) 573 if (pnp_device_is_isapnp(pdev))
591 return -ENOENT; /* we have another procedure - card */ 574 return -ENOENT; /* we have another procedure - card */
@@ -596,10 +579,19 @@ static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev,
596 if (dev >= SNDRV_CARDS) 579 if (dev >= SNDRV_CARDS)
597 return -ENODEV; 580 return -ENODEV;
598 581
582 /* prepare second id */
583 strcpy(cid, pdev->id[0].id);
584 cid[5] = '1';
585 cdev = NULL;
586 list_for_each_entry(cdev, &(pdev->protocol->devices), protocol_list) {
587 if (!strcmp(cdev->id[0].id, cid))
588 break;
589 }
599 err = snd_cs423x_card_new(dev, &card); 590 err = snd_cs423x_card_new(dev, &card);
600 if (err < 0) 591 if (err < 0)
601 return err; 592 return err;
602 if ((err = snd_card_cs4232_pnp(dev, card->private_data, pdev)) < 0) { 593 err = snd_card_cs423x_pnp(dev, card->private_data, pdev, cdev);
594 if (err < 0) {
603 printk(KERN_ERR "PnP BIOS detection failed for " IDENT "\n"); 595 printk(KERN_ERR "PnP BIOS detection failed for " IDENT "\n");
604 snd_card_free(card); 596 snd_card_free(card);
605 return err; 597 return err;
@@ -614,35 +606,34 @@ static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev,
614 return 0; 606 return 0;
615} 607}
616 608
617static void __devexit snd_cs4232_pnp_remove(struct pnp_dev * pdev) 609static void __devexit snd_cs423x_pnp_remove(struct pnp_dev *pdev)
618{ 610{
619 snd_card_free(pnp_get_drvdata(pdev)); 611 snd_card_free(pnp_get_drvdata(pdev));
620 pnp_set_drvdata(pdev, NULL); 612 pnp_set_drvdata(pdev, NULL);
621} 613}
622 614
623#ifdef CONFIG_PM 615#ifdef CONFIG_PM
624static int snd_cs4232_pnp_suspend(struct pnp_dev *pdev, pm_message_t state) 616static int snd_cs423x_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
625{ 617{
626 return snd_cs423x_suspend(pnp_get_drvdata(pdev)); 618 return snd_cs423x_suspend(pnp_get_drvdata(pdev));
627} 619}
628 620
629static int snd_cs4232_pnp_resume(struct pnp_dev *pdev) 621static int snd_cs423x_pnp_resume(struct pnp_dev *pdev)
630{ 622{
631 return snd_cs423x_resume(pnp_get_drvdata(pdev)); 623 return snd_cs423x_resume(pnp_get_drvdata(pdev));
632} 624}
633#endif 625#endif
634 626
635static struct pnp_driver cs4232_pnp_driver = { 627static struct pnp_driver cs423x_pnp_driver = {
636 .name = "cs4232-pnpbios", 628 .name = "cs423x-pnpbios",
637 .id_table = snd_cs4232_pnpbiosids, 629 .id_table = snd_cs423x_pnpbiosids,
638 .probe = snd_cs4232_pnpbios_detect, 630 .probe = snd_cs423x_pnpbios_detect,
639 .remove = __devexit_p(snd_cs4232_pnp_remove), 631 .remove = __devexit_p(snd_cs423x_pnp_remove),
640#ifdef CONFIG_PM 632#ifdef CONFIG_PM
641 .suspend = snd_cs4232_pnp_suspend, 633 .suspend = snd_cs423x_pnp_suspend,
642 .resume = snd_cs4232_pnp_resume, 634 .resume = snd_cs423x_pnp_resume,
643#endif 635#endif
644}; 636};
645#endif /* CS4232 */
646 637
647static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard, 638static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard,
648 const struct pnp_card_device_id *pid) 639 const struct pnp_card_device_id *pid)
@@ -716,18 +707,14 @@ static int __init alsa_card_cs423x_init(void)
716#ifdef CONFIG_PNP 707#ifdef CONFIG_PNP
717 if (!err) 708 if (!err)
718 isa_registered = 1; 709 isa_registered = 1;
719#ifdef CS4232 710 err = pnp_register_driver(&cs423x_pnp_driver);
720 err = pnp_register_driver(&cs4232_pnp_driver);
721 if (!err) 711 if (!err)
722 pnp_registered = 1; 712 pnp_registered = 1;
723#endif
724 err = pnp_register_card_driver(&cs423x_pnpc_driver); 713 err = pnp_register_card_driver(&cs423x_pnpc_driver);
725 if (!err) 714 if (!err)
726 pnpc_registered = 1; 715 pnpc_registered = 1;
727#ifdef CS4232
728 if (pnp_registered) 716 if (pnp_registered)
729 err = 0; 717 err = 0;
730#endif
731 if (isa_registered) 718 if (isa_registered)
732 err = 0; 719 err = 0;
733#endif 720#endif
@@ -739,10 +726,8 @@ static void __exit alsa_card_cs423x_exit(void)
739#ifdef CONFIG_PNP 726#ifdef CONFIG_PNP
740 if (pnpc_registered) 727 if (pnpc_registered)
741 pnp_unregister_card_driver(&cs423x_pnpc_driver); 728 pnp_unregister_card_driver(&cs423x_pnpc_driver);
742#ifdef CS4232
743 if (pnp_registered) 729 if (pnp_registered)
744 pnp_unregister_driver(&cs4232_pnp_driver); 730 pnp_unregister_driver(&cs423x_pnp_driver);
745#endif
746 if (isa_registered) 731 if (isa_registered)
747#endif 732#endif
748 isa_unregister_driver(&cs423x_isa_driver); 733 isa_unregister_driver(&cs423x_isa_driver);