diff options
Diffstat (limited to 'sound/isa/cs423x/cs4236.c')
-rw-r--r-- | sound/isa/cs423x/cs4236.c | 185 |
1 files changed, 86 insertions, 99 deletions
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index 019c9401663e..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, |
@@ -382,16 +365,18 @@ static void snd_card_cs4236_free(struct snd_card *card) | |||
382 | release_and_free_resource(acard->res_sb_port); | 365 | release_and_free_resource(acard->res_sb_port); |
383 | } | 366 | } |
384 | 367 | ||
385 | static struct snd_card *snd_cs423x_card_new(int dev) | 368 | static int snd_cs423x_card_new(int dev, struct snd_card **cardp) |
386 | { | 369 | { |
387 | struct snd_card *card; | 370 | struct snd_card *card; |
371 | int err; | ||
388 | 372 | ||
389 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 373 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
390 | sizeof(struct snd_card_cs4236)); | 374 | sizeof(struct snd_card_cs4236), &card); |
391 | if (card == NULL) | 375 | if (err < 0) |
392 | return NULL; | 376 | return err; |
393 | card->private_free = snd_card_cs4236_free; | 377 | card->private_free = snd_card_cs4236_free; |
394 | return card; | 378 | *cardp = card; |
379 | return 0; | ||
395 | } | 380 | } |
396 | 381 | ||
397 | static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) | 382 | static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) |
@@ -409,40 +394,39 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) | |||
409 | return -EBUSY; | 394 | return -EBUSY; |
410 | } | 395 | } |
411 | 396 | ||
412 | #ifdef CS4232 | ||
413 | err = snd_wss_create(card, port[dev], cport[dev], | 397 | err = snd_wss_create(card, port[dev], cport[dev], |
414 | irq[dev], | 398 | irq[dev], |
415 | dma1[dev], dma2[dev], | 399 | dma1[dev], dma2[dev], |
416 | WSS_HW_DETECT, 0, &chip); | 400 | WSS_HW_DETECT3, 0, &chip); |
417 | if (err < 0) | ||
418 | return err; | ||
419 | acard->chip = chip; | ||
420 | |||
421 | err = snd_wss_pcm(chip, 0, &pcm); | ||
422 | if (err < 0) | ||
423 | return err; | ||
424 | |||
425 | err = snd_wss_mixer(chip); | ||
426 | if (err < 0) | 401 | if (err < 0) |
427 | return err; | 402 | return err; |
428 | 403 | if (chip->hardware & WSS_HW_CS4236B_MASK) { | |
429 | #else /* CS4236 */ | 404 | snd_wss_free(chip); |
430 | err = snd_cs4236_create(card, | 405 | err = snd_cs4236_create(card, |
431 | port[dev], cport[dev], | 406 | port[dev], cport[dev], |
432 | irq[dev], dma1[dev], dma2[dev], | 407 | irq[dev], dma1[dev], dma2[dev], |
433 | WSS_HW_DETECT, 0, &chip); | 408 | WSS_HW_DETECT, 0, &chip); |
434 | if (err < 0) | 409 | if (err < 0) |
435 | return err; | 410 | return err; |
436 | acard->chip = chip; | 411 | acard->chip = chip; |
437 | 412 | ||
438 | err = snd_cs4236_pcm(chip, 0, &pcm); | 413 | err = snd_cs4236_pcm(chip, 0, &pcm); |
439 | if (err < 0) | 414 | if (err < 0) |
440 | return err; | 415 | return err; |
441 | 416 | ||
442 | err = snd_cs4236_mixer(chip); | 417 | err = snd_cs4236_mixer(chip); |
443 | if (err < 0) | 418 | if (err < 0) |
444 | return err; | 419 | return err; |
445 | #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 | } | ||
446 | strcpy(card->driver, pcm->name); | 430 | strcpy(card->driver, pcm->name); |
447 | strcpy(card->shortname, pcm->name); | 431 | strcpy(card->shortname, pcm->name); |
448 | sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", | 432 | sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", |
@@ -512,9 +496,9 @@ static int __devinit snd_cs423x_isa_probe(struct device *pdev, | |||
512 | struct snd_card *card; | 496 | struct snd_card *card; |
513 | int err; | 497 | int err; |
514 | 498 | ||
515 | card = snd_cs423x_card_new(dev); | 499 | err = snd_cs423x_card_new(dev, &card); |
516 | if (! card) | 500 | if (err < 0) |
517 | return -ENOMEM; | 501 | return err; |
518 | snd_card_set_dev(card, pdev); | 502 | snd_card_set_dev(card, pdev); |
519 | if ((err = snd_cs423x_probe(card, dev)) < 0) { | 503 | if ((err = snd_cs423x_probe(card, dev)) < 0) { |
520 | snd_card_free(card); | 504 | snd_card_free(card); |
@@ -577,13 +561,14 @@ static struct isa_driver cs423x_isa_driver = { | |||
577 | 561 | ||
578 | 562 | ||
579 | #ifdef CONFIG_PNP | 563 | #ifdef CONFIG_PNP |
580 | #ifdef CS4232 | 564 | static int __devinit snd_cs423x_pnpbios_detect(struct pnp_dev *pdev, |
581 | static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev, | ||
582 | const struct pnp_device_id *id) | 565 | const struct pnp_device_id *id) |
583 | { | 566 | { |
584 | static int dev; | 567 | static int dev; |
585 | int err; | 568 | int err; |
586 | struct snd_card *card; | 569 | struct snd_card *card; |
570 | struct pnp_dev *cdev; | ||
571 | char cid[PNP_ID_LEN]; | ||
587 | 572 | ||
588 | if (pnp_device_is_isapnp(pdev)) | 573 | if (pnp_device_is_isapnp(pdev)) |
589 | return -ENOENT; /* we have another procedure - card */ | 574 | return -ENOENT; /* we have another procedure - card */ |
@@ -594,10 +579,19 @@ static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev, | |||
594 | if (dev >= SNDRV_CARDS) | 579 | if (dev >= SNDRV_CARDS) |
595 | return -ENODEV; | 580 | return -ENODEV; |
596 | 581 | ||
597 | card = snd_cs423x_card_new(dev); | 582 | /* prepare second id */ |
598 | if (! card) | 583 | strcpy(cid, pdev->id[0].id); |
599 | return -ENOMEM; | 584 | cid[5] = '1'; |
600 | if ((err = snd_card_cs4232_pnp(dev, card->private_data, pdev)) < 0) { | 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 | } | ||
590 | err = snd_cs423x_card_new(dev, &card); | ||
591 | if (err < 0) | ||
592 | return err; | ||
593 | err = snd_card_cs423x_pnp(dev, card->private_data, pdev, cdev); | ||
594 | if (err < 0) { | ||
601 | printk(KERN_ERR "PnP BIOS detection failed for " IDENT "\n"); | 595 | printk(KERN_ERR "PnP BIOS detection failed for " IDENT "\n"); |
602 | snd_card_free(card); | 596 | snd_card_free(card); |
603 | return err; | 597 | return err; |
@@ -612,35 +606,34 @@ static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev, | |||
612 | return 0; | 606 | return 0; |
613 | } | 607 | } |
614 | 608 | ||
615 | static void __devexit snd_cs4232_pnp_remove(struct pnp_dev * pdev) | 609 | static void __devexit snd_cs423x_pnp_remove(struct pnp_dev *pdev) |
616 | { | 610 | { |
617 | snd_card_free(pnp_get_drvdata(pdev)); | 611 | snd_card_free(pnp_get_drvdata(pdev)); |
618 | pnp_set_drvdata(pdev, NULL); | 612 | pnp_set_drvdata(pdev, NULL); |
619 | } | 613 | } |
620 | 614 | ||
621 | #ifdef CONFIG_PM | 615 | #ifdef CONFIG_PM |
622 | 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) |
623 | { | 617 | { |
624 | return snd_cs423x_suspend(pnp_get_drvdata(pdev)); | 618 | return snd_cs423x_suspend(pnp_get_drvdata(pdev)); |
625 | } | 619 | } |
626 | 620 | ||
627 | static int snd_cs4232_pnp_resume(struct pnp_dev *pdev) | 621 | static int snd_cs423x_pnp_resume(struct pnp_dev *pdev) |
628 | { | 622 | { |
629 | return snd_cs423x_resume(pnp_get_drvdata(pdev)); | 623 | return snd_cs423x_resume(pnp_get_drvdata(pdev)); |
630 | } | 624 | } |
631 | #endif | 625 | #endif |
632 | 626 | ||
633 | static struct pnp_driver cs4232_pnp_driver = { | 627 | static struct pnp_driver cs423x_pnp_driver = { |
634 | .name = "cs4232-pnpbios", | 628 | .name = "cs423x-pnpbios", |
635 | .id_table = snd_cs4232_pnpbiosids, | 629 | .id_table = snd_cs423x_pnpbiosids, |
636 | .probe = snd_cs4232_pnpbios_detect, | 630 | .probe = snd_cs423x_pnpbios_detect, |
637 | .remove = __devexit_p(snd_cs4232_pnp_remove), | 631 | .remove = __devexit_p(snd_cs423x_pnp_remove), |
638 | #ifdef CONFIG_PM | 632 | #ifdef CONFIG_PM |
639 | .suspend = snd_cs4232_pnp_suspend, | 633 | .suspend = snd_cs423x_pnp_suspend, |
640 | .resume = snd_cs4232_pnp_resume, | 634 | .resume = snd_cs423x_pnp_resume, |
641 | #endif | 635 | #endif |
642 | }; | 636 | }; |
643 | #endif /* CS4232 */ | ||
644 | 637 | ||
645 | 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, |
646 | const struct pnp_card_device_id *pid) | 639 | const struct pnp_card_device_id *pid) |
@@ -656,9 +649,9 @@ static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard, | |||
656 | if (dev >= SNDRV_CARDS) | 649 | if (dev >= SNDRV_CARDS) |
657 | return -ENODEV; | 650 | return -ENODEV; |
658 | 651 | ||
659 | card = snd_cs423x_card_new(dev); | 652 | res = snd_cs423x_card_new(dev, &card); |
660 | if (! card) | 653 | if (res < 0) |
661 | return -ENOMEM; | 654 | return res; |
662 | if ((res = snd_card_cs423x_pnpc(dev, card->private_data, pcard, pid)) < 0) { | 655 | if ((res = snd_card_cs423x_pnpc(dev, card->private_data, pcard, pid)) < 0) { |
663 | printk(KERN_ERR "isapnp detection failed and probing for " IDENT | 656 | printk(KERN_ERR "isapnp detection failed and probing for " IDENT |
664 | " is not supported\n"); | 657 | " is not supported\n"); |
@@ -714,18 +707,14 @@ static int __init alsa_card_cs423x_init(void) | |||
714 | #ifdef CONFIG_PNP | 707 | #ifdef CONFIG_PNP |
715 | if (!err) | 708 | if (!err) |
716 | isa_registered = 1; | 709 | isa_registered = 1; |
717 | #ifdef CS4232 | 710 | err = pnp_register_driver(&cs423x_pnp_driver); |
718 | err = pnp_register_driver(&cs4232_pnp_driver); | ||
719 | if (!err) | 711 | if (!err) |
720 | pnp_registered = 1; | 712 | pnp_registered = 1; |
721 | #endif | ||
722 | err = pnp_register_card_driver(&cs423x_pnpc_driver); | 713 | err = pnp_register_card_driver(&cs423x_pnpc_driver); |
723 | if (!err) | 714 | if (!err) |
724 | pnpc_registered = 1; | 715 | pnpc_registered = 1; |
725 | #ifdef CS4232 | ||
726 | if (pnp_registered) | 716 | if (pnp_registered) |
727 | err = 0; | 717 | err = 0; |
728 | #endif | ||
729 | if (isa_registered) | 718 | if (isa_registered) |
730 | err = 0; | 719 | err = 0; |
731 | #endif | 720 | #endif |
@@ -737,10 +726,8 @@ static void __exit alsa_card_cs423x_exit(void) | |||
737 | #ifdef CONFIG_PNP | 726 | #ifdef CONFIG_PNP |
738 | if (pnpc_registered) | 727 | if (pnpc_registered) |
739 | pnp_unregister_card_driver(&cs423x_pnpc_driver); | 728 | pnp_unregister_card_driver(&cs423x_pnpc_driver); |
740 | #ifdef CS4232 | ||
741 | if (pnp_registered) | 729 | if (pnp_registered) |
742 | pnp_unregister_driver(&cs4232_pnp_driver); | 730 | pnp_unregister_driver(&cs423x_pnp_driver); |
743 | #endif | ||
744 | if (isa_registered) | 731 | if (isa_registered) |
745 | #endif | 732 | #endif |
746 | isa_unregister_driver(&cs423x_isa_driver); | 733 | isa_unregister_driver(&cs423x_isa_driver); |