diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2009-02-16 15:38:37 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-02-16 17:05:25 -0500 |
commit | c2b73d1458014a9f461b75bc1756a699a6c0781f (patch) | |
tree | d869727d6002ebf48fdb875b490108d85c5ff761 /sound/isa/cs423x/cs4236.c | |
parent | 96cf45cf559be375de29dd45afc50fa8946fb2aa (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.c | 153 |
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 | ||
34 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); | 34 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); |
35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
36 | #ifdef CS4232 | 36 | MODULE_DESCRIPTION("Cirrus Logic CS4232-9"); |
37 | MODULE_DESCRIPTION("Cirrus Logic CS4232"); | ||
38 | MODULE_SUPPORTED_DEVICE("{{Turtle Beach,TBS-2000}," | 37 | MODULE_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}," |
45 | MODULE_DESCRIPTION("Cirrus Logic CS4235-9"); | ||
46 | MODULE_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 | 71 | MODULE_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 | ||
83 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 76 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
84 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 77 | static 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 |
129 | static int isa_registered; | 122 | static int isa_registered; |
130 | static int pnpc_registered; | 123 | static int pnpc_registered; |
131 | #ifdef CS4232 | ||
132 | static int pnp_registered; | 124 | static int pnp_registered; |
133 | #endif | ||
134 | #endif /* CONFIG_PNP */ | 125 | #endif /* CONFIG_PNP */ |
135 | 126 | ||
136 | struct snd_card_cs4236 { | 127 | struct 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 | */ |
152 | static const struct pnp_device_id snd_cs4232_pnpbiosids[] = { | 142 | static 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 | }; |
160 | MODULE_DEVICE_TABLE(pnp, snd_cs4232_pnpbiosids); | 150 | MODULE_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" |
165 | static struct pnp_card_device_id snd_cs423x_pnpids[] = { | 153 | static 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" | ||
187 | static 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 | ||
271 | MODULE_DEVICE_TABLE(pnp_card, snd_cs423x_pnpids); | 252 | MODULE_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 | 307 | static int __devinit snd_card_cs423x_pnp(int dev, struct snd_card_cs4236 *acard, |
327 | static 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 | ||
338 | static int __devinit snd_card_cs423x_pnpc(int dev, struct snd_card_cs4236 *acard, | 321 | static 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 | 564 | static int __devinit snd_cs423x_pnpbios_detect(struct pnp_dev *pdev, |
583 | static 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 | ||
617 | static void __devexit snd_cs4232_pnp_remove(struct pnp_dev * pdev) | 609 | static 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 |
624 | static int snd_cs4232_pnp_suspend(struct pnp_dev *pdev, pm_message_t state) | 616 | static 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 | ||
629 | static int snd_cs4232_pnp_resume(struct pnp_dev *pdev) | 621 | static 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 | ||
635 | static struct pnp_driver cs4232_pnp_driver = { | 627 | static 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 | ||
647 | static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard, | 638 | static 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); |