Commit c2b73d1458014a9f461b75bc1756a699a6c0781f
Committed by
Takashi Iwai
1 parent
96cf45cf55
Exists in
master
and in
7 other branches
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>
Showing 6 changed files with 78 additions and 106 deletions Side-by-side Diff
include/sound/wss.h
... | ... | @@ -154,6 +154,7 @@ |
154 | 154 | unsigned short hardware, |
155 | 155 | unsigned short hwshare, |
156 | 156 | struct snd_wss **rchip); |
157 | +int snd_wss_free(struct snd_wss *chip); | |
157 | 158 | int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm); |
158 | 159 | int snd_wss_timer(struct snd_wss *chip, int device, struct snd_timer **rtimer); |
159 | 160 | int snd_wss_mixer(struct snd_wss *chip); |
sound/isa/Kconfig
... | ... | @@ -56,8 +56,8 @@ |
56 | 56 | Say Y here to include support for AD1848 (Analog Devices) or |
57 | 57 | CS4248 (Cirrus Logic - Crystal Semiconductors) chips. |
58 | 58 | |
59 | - For newer chips from Cirrus Logic, use the CS4231, CS4232 or | |
60 | - CS4236+ drivers. | |
59 | + For newer chips from Cirrus Logic, use the CS4231 or CS4232+ | |
60 | + drivers. | |
61 | 61 | |
62 | 62 | To compile this driver as a module, choose M here: the module |
63 | 63 | will be called snd-ad1848. |
64 | 64 | |
65 | 65 | |
... | ... | @@ -114,26 +114,15 @@ |
114 | 114 | To compile this driver as a module, choose M here: the module |
115 | 115 | will be called snd-cs4231. |
116 | 116 | |
117 | -config SND_CS4232 | |
118 | - tristate "Generic Cirrus Logic CS4232 driver" | |
119 | - select SND_OPL3_LIB | |
120 | - select SND_MPU401_UART | |
121 | - select SND_WSS_LIB | |
122 | - help | |
123 | - Say Y here to include support for CS4232 chips from Cirrus | |
124 | - Logic - Crystal Semiconductors. | |
125 | - | |
126 | - To compile this driver as a module, choose M here: the module | |
127 | - will be called snd-cs4232. | |
128 | - | |
129 | 117 | config SND_CS4236 |
130 | - tristate "Generic Cirrus Logic CS4236+ driver" | |
118 | + tristate "Generic Cirrus Logic CS4232/CS4236+ driver" | |
131 | 119 | select SND_OPL3_LIB |
132 | 120 | select SND_MPU401_UART |
133 | 121 | select SND_WSS_LIB |
134 | 122 | help |
135 | - Say Y to include support for CS4235,CS4236,CS4237B,CS4238B, | |
136 | - CS4239 chips from Cirrus Logic - Crystal Semiconductors. | |
123 | + Say Y to include support for CS4232,CS4235,CS4236,CS4237B, | |
124 | + CS4238B,CS4239 chips from Cirrus Logic - Crystal | |
125 | + Semiconductors. | |
137 | 126 | |
138 | 127 | To compile this driver as a module, choose M here: the module |
139 | 128 | will be called snd-cs4236. |
sound/isa/cs423x/Makefile
... | ... | @@ -5,11 +5,9 @@ |
5 | 5 | |
6 | 6 | snd-cs4236-lib-objs := cs4236_lib.o |
7 | 7 | snd-cs4231-objs := cs4231.o |
8 | -snd-cs4232-objs := cs4232.o | |
9 | 8 | snd-cs4236-objs := cs4236.o |
10 | 9 | |
11 | 10 | # Toplevel Module Dependency |
12 | 11 | obj-$(CONFIG_SND_CS4231) += snd-cs4231.o |
13 | -obj-$(CONFIG_SND_CS4232) += snd-cs4232.o | |
14 | 12 | obj-$(CONFIG_SND_CS4236) += snd-cs4236.o snd-cs4236-lib.o |
sound/isa/cs423x/cs4232.c
sound/isa/cs423x/cs4236.c
... | ... | @@ -33,17 +33,14 @@ |
33 | 33 | |
34 | 34 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); |
35 | 35 | MODULE_LICENSE("GPL"); |
36 | -#ifdef CS4232 | |
37 | -MODULE_DESCRIPTION("Cirrus Logic CS4232"); | |
36 | +MODULE_DESCRIPTION("Cirrus Logic CS4232-9"); | |
38 | 37 | MODULE_SUPPORTED_DEVICE("{{Turtle Beach,TBS-2000}," |
39 | 38 | "{Turtle Beach,Tropez Plus}," |
40 | 39 | "{SIC CrystalWave 32}," |
41 | 40 | "{Hewlett Packard,Omnibook 5500}," |
42 | 41 | "{TerraTec,Maestro 32/96}," |
43 | - "{Philips,PCA70PS}}"); | |
44 | -#else | |
45 | -MODULE_DESCRIPTION("Cirrus Logic CS4235-9"); | |
46 | -MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4235}," | |
42 | + "{Philips,PCA70PS}}," | |
43 | + "{{Crystal Semiconductors,CS4235}," | |
47 | 44 | "{Crystal Semiconductors,CS4236}," |
48 | 45 | "{Crystal Semiconductors,CS4237}," |
49 | 46 | "{Crystal Semiconductors,CS4238}," |
50 | 47 | |
51 | 48 | |
... | ... | @@ -70,16 +67,12 @@ |
70 | 67 | "{Typhoon Soundsystem,CS4236B}," |
71 | 68 | "{Turtle Beach,Malibu}," |
72 | 69 | "{Unknown,Digital PC 5000 Onboard}}"); |
73 | -#endif | |
74 | 70 | |
75 | -#ifdef CS4232 | |
76 | -#define IDENT "CS4232" | |
77 | -#define DEV_NAME "cs4232" | |
78 | -#else | |
79 | -#define IDENT "CS4236+" | |
80 | -#define DEV_NAME "cs4236" | |
81 | -#endif | |
71 | +MODULE_ALIAS("snd_cs4232"); | |
82 | 72 | |
73 | +#define IDENT "CS4232+" | |
74 | +#define DEV_NAME "cs4232+" | |
75 | + | |
83 | 76 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
84 | 77 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
85 | 78 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ |
86 | 79 | |
... | ... | @@ -128,9 +121,7 @@ |
128 | 121 | #ifdef CONFIG_PNP |
129 | 122 | static int isa_registered; |
130 | 123 | static int pnpc_registered; |
131 | -#ifdef CS4232 | |
132 | 124 | static int pnp_registered; |
133 | -#endif | |
134 | 125 | #endif /* CONFIG_PNP */ |
135 | 126 | |
136 | 127 | struct snd_card_cs4236 { |
137 | 128 | |
... | ... | @@ -145,11 +136,10 @@ |
145 | 136 | |
146 | 137 | #ifdef CONFIG_PNP |
147 | 138 | |
148 | -#ifdef CS4232 | |
149 | 139 | /* |
150 | 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 | 143 | { .id = "CSC0100" }, |
154 | 144 | { .id = "CSC0000" }, |
155 | 145 | /* Guillemot Turtlebeach something appears to be cs4232 compatible |
156 | 146 | |
... | ... | @@ -157,10 +147,8 @@ |
157 | 147 | { .id = "GIM0100" }, |
158 | 148 | { .id = "" } |
159 | 149 | }; |
160 | -MODULE_DEVICE_TABLE(pnp, snd_cs4232_pnpbiosids); | |
161 | -#endif /* CS4232 */ | |
150 | +MODULE_DEVICE_TABLE(pnp, snd_cs423x_pnpbiosids); | |
162 | 151 | |
163 | -#ifdef CS4232 | |
164 | 152 | #define CS423X_ISAPNP_DRIVER "cs4232_isapnp" |
165 | 153 | static struct pnp_card_device_id snd_cs423x_pnpids[] = { |
166 | 154 | /* Philips PCA70PS */ |
... | ... | @@ -179,12 +167,6 @@ |
179 | 167 | { .id = "CSCf032", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, |
180 | 168 | /* Netfinity 3000 on-board soundcard */ |
181 | 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 | 170 | /* Intel Marlin Spike Motherboard - CS4235 */ |
189 | 171 | { .id = "CSC0225", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, |
190 | 172 | /* Intel Marlin Spike Motherboard (#2) - CS4235 */ |
... | ... | @@ -266,7 +248,6 @@ |
266 | 248 | /* --- */ |
267 | 249 | { .id = "" } /* end */ |
268 | 250 | }; |
269 | -#endif | |
270 | 251 | |
271 | 252 | MODULE_DEVICE_TABLE(pnp_card, snd_cs423x_pnpids); |
272 | 253 | |
273 | 254 | |
274 | 255 | |
... | ... | @@ -323,17 +304,19 @@ |
323 | 304 | return 0; |
324 | 305 | } |
325 | 306 | |
326 | -#ifdef CS4232 | |
327 | -static int __devinit snd_card_cs4232_pnp(int dev, struct snd_card_cs4236 *acard, | |
328 | - struct pnp_dev *pdev) | |
307 | +static int __devinit snd_card_cs423x_pnp(int dev, struct snd_card_cs4236 *acard, | |
308 | + struct pnp_dev *pdev, | |
309 | + struct pnp_dev *cdev) | |
329 | 310 | { |
330 | 311 | acard->wss = pdev; |
331 | 312 | if (snd_cs423x_pnp_init_wss(dev, acard->wss) < 0) |
332 | 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 | 318 | return 0; |
335 | 319 | } |
336 | -#endif | |
337 | 320 | |
338 | 321 | static int __devinit snd_card_cs423x_pnpc(int dev, struct snd_card_cs4236 *acard, |
339 | 322 | struct pnp_card_link *card, |
340 | 323 | |
341 | 324 | |
342 | 325 | |
343 | 326 | |
344 | 327 | |
... | ... | @@ -411,40 +394,39 @@ |
411 | 394 | return -EBUSY; |
412 | 395 | } |
413 | 396 | |
414 | -#ifdef CS4232 | |
415 | 397 | err = snd_wss_create(card, port[dev], cport[dev], |
416 | 398 | irq[dev], |
417 | 399 | dma1[dev], dma2[dev], |
418 | - WSS_HW_DETECT, 0, &chip); | |
400 | + WSS_HW_DETECT3, 0, &chip); | |
419 | 401 | if (err < 0) |
420 | 402 | return err; |
421 | - acard->chip = chip; | |
403 | + if (chip->hardware & WSS_HW_CS4236B_MASK) { | |
404 | + snd_wss_free(chip); | |
405 | + err = snd_cs4236_create(card, | |
406 | + port[dev], cport[dev], | |
407 | + irq[dev], dma1[dev], dma2[dev], | |
408 | + WSS_HW_DETECT, 0, &chip); | |
409 | + if (err < 0) | |
410 | + return err; | |
411 | + acard->chip = chip; | |
422 | 412 | |
423 | - err = snd_wss_pcm(chip, 0, &pcm); | |
424 | - if (err < 0) | |
425 | - return err; | |
413 | + err = snd_cs4236_pcm(chip, 0, &pcm); | |
414 | + if (err < 0) | |
415 | + return err; | |
426 | 416 | |
427 | - err = snd_wss_mixer(chip); | |
428 | - if (err < 0) | |
429 | - return err; | |
417 | + err = snd_cs4236_mixer(chip); | |
418 | + if (err < 0) | |
419 | + return err; | |
420 | + } else { | |
421 | + acard->chip = chip; | |
422 | + err = snd_wss_pcm(chip, 0, &pcm); | |
423 | + if (err < 0) | |
424 | + return err; | |
430 | 425 | |
431 | -#else /* CS4236 */ | |
432 | - err = snd_cs4236_create(card, | |
433 | - port[dev], cport[dev], | |
434 | - irq[dev], dma1[dev], dma2[dev], | |
435 | - WSS_HW_DETECT, 0, &chip); | |
436 | - if (err < 0) | |
437 | - return err; | |
438 | - acard->chip = chip; | |
439 | - | |
440 | - err = snd_cs4236_pcm(chip, 0, &pcm); | |
441 | - if (err < 0) | |
442 | - return err; | |
443 | - | |
444 | - err = snd_cs4236_mixer(chip); | |
445 | - if (err < 0) | |
446 | - return err; | |
447 | -#endif | |
426 | + err = snd_wss_mixer(chip); | |
427 | + if (err < 0) | |
428 | + return err; | |
429 | + } | |
448 | 430 | strcpy(card->driver, pcm->name); |
449 | 431 | strcpy(card->shortname, pcm->name); |
450 | 432 | sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", |
451 | 433 | |
... | ... | @@ -579,13 +561,14 @@ |
579 | 561 | |
580 | 562 | |
581 | 563 | #ifdef CONFIG_PNP |
582 | -#ifdef CS4232 | |
583 | -static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev, | |
564 | +static int __devinit snd_cs423x_pnpbios_detect(struct pnp_dev *pdev, | |
584 | 565 | const struct pnp_device_id *id) |
585 | 566 | { |
586 | 567 | static int dev; |
587 | 568 | int err; |
588 | 569 | struct snd_card *card; |
570 | + struct pnp_dev *cdev; | |
571 | + char cid[PNP_ID_LEN]; | |
589 | 572 | |
590 | 573 | if (pnp_device_is_isapnp(pdev)) |
591 | 574 | return -ENOENT; /* we have another procedure - card */ |
592 | 575 | |
... | ... | @@ -596,10 +579,19 @@ |
596 | 579 | if (dev >= SNDRV_CARDS) |
597 | 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 | 590 | err = snd_cs423x_card_new(dev, &card); |
600 | 591 | if (err < 0) |
601 | 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 | 595 | printk(KERN_ERR "PnP BIOS detection failed for " IDENT "\n"); |
604 | 596 | snd_card_free(card); |
605 | 597 | return err; |
606 | 598 | |
607 | 599 | |
608 | 600 | |
609 | 601 | |
610 | 602 | |
... | ... | @@ -614,35 +606,34 @@ |
614 | 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 | 611 | snd_card_free(pnp_get_drvdata(pdev)); |
620 | 612 | pnp_set_drvdata(pdev, NULL); |
621 | 613 | } |
622 | 614 | |
623 | 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 | 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 | 623 | return snd_cs423x_resume(pnp_get_drvdata(pdev)); |
632 | 624 | } |
633 | 625 | #endif |
634 | 626 | |
635 | -static struct pnp_driver cs4232_pnp_driver = { | |
636 | - .name = "cs4232-pnpbios", | |
637 | - .id_table = snd_cs4232_pnpbiosids, | |
638 | - .probe = snd_cs4232_pnpbios_detect, | |
639 | - .remove = __devexit_p(snd_cs4232_pnp_remove), | |
627 | +static struct pnp_driver cs423x_pnp_driver = { | |
628 | + .name = "cs423x-pnpbios", | |
629 | + .id_table = snd_cs423x_pnpbiosids, | |
630 | + .probe = snd_cs423x_pnpbios_detect, | |
631 | + .remove = __devexit_p(snd_cs423x_pnp_remove), | |
640 | 632 | #ifdef CONFIG_PM |
641 | - .suspend = snd_cs4232_pnp_suspend, | |
642 | - .resume = snd_cs4232_pnp_resume, | |
633 | + .suspend = snd_cs423x_pnp_suspend, | |
634 | + .resume = snd_cs423x_pnp_resume, | |
643 | 635 | #endif |
644 | 636 | }; |
645 | -#endif /* CS4232 */ | |
646 | 637 | |
647 | 638 | static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard, |
648 | 639 | const struct pnp_card_device_id *pid) |
649 | 640 | |
650 | 641 | |
651 | 642 | |
... | ... | @@ -716,18 +707,14 @@ |
716 | 707 | #ifdef CONFIG_PNP |
717 | 708 | if (!err) |
718 | 709 | isa_registered = 1; |
719 | -#ifdef CS4232 | |
720 | - err = pnp_register_driver(&cs4232_pnp_driver); | |
710 | + err = pnp_register_driver(&cs423x_pnp_driver); | |
721 | 711 | if (!err) |
722 | 712 | pnp_registered = 1; |
723 | -#endif | |
724 | 713 | err = pnp_register_card_driver(&cs423x_pnpc_driver); |
725 | 714 | if (!err) |
726 | 715 | pnpc_registered = 1; |
727 | -#ifdef CS4232 | |
728 | 716 | if (pnp_registered) |
729 | 717 | err = 0; |
730 | -#endif | |
731 | 718 | if (isa_registered) |
732 | 719 | err = 0; |
733 | 720 | #endif |
734 | 721 | |
... | ... | @@ -739,10 +726,8 @@ |
739 | 726 | #ifdef CONFIG_PNP |
740 | 727 | if (pnpc_registered) |
741 | 728 | pnp_unregister_card_driver(&cs423x_pnpc_driver); |
742 | -#ifdef CS4232 | |
743 | 729 | if (pnp_registered) |
744 | - pnp_unregister_driver(&cs4232_pnp_driver); | |
745 | -#endif | |
730 | + pnp_unregister_driver(&cs423x_pnp_driver); | |
746 | 731 | if (isa_registered) |
747 | 732 | #endif |
748 | 733 | isa_unregister_driver(&cs423x_isa_driver); |
sound/isa/wss/wss_lib.c
... | ... | @@ -1657,7 +1657,7 @@ |
1657 | 1657 | } |
1658 | 1658 | #endif /* CONFIG_PM */ |
1659 | 1659 | |
1660 | -static int snd_wss_free(struct snd_wss *chip) | |
1660 | +int snd_wss_free(struct snd_wss *chip) | |
1661 | 1661 | { |
1662 | 1662 | release_and_free_resource(chip->res_port); |
1663 | 1663 | release_and_free_resource(chip->res_cport); |
... | ... | @@ -1680,6 +1680,7 @@ |
1680 | 1680 | kfree(chip); |
1681 | 1681 | return 0; |
1682 | 1682 | } |
1683 | +EXPORT_SYMBOL(snd_wss_free); | |
1683 | 1684 | |
1684 | 1685 | static int snd_wss_dev_free(struct snd_device *device) |
1685 | 1686 | { |