aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa/cs423x
diff options
context:
space:
mode:
Diffstat (limited to 'sound/isa/cs423x')
-rw-r--r--sound/isa/cs423x/cs4231_lib.c2
-rw-r--r--sound/isa/cs423x/cs4236.c323
2 files changed, 220 insertions, 105 deletions
diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
index 582cc751d547..05d0d4092ded 100644
--- a/sound/isa/cs423x/cs4231_lib.c
+++ b/sound/isa/cs423x/cs4231_lib.c
@@ -1484,10 +1484,12 @@ int snd_cs4231_create(struct snd_card *card,
1484 } 1484 }
1485 snd_cs4231_init(chip); 1485 snd_cs4231_init(chip);
1486 1486
1487#if 0
1487 if (chip->hardware & CS4231_HW_CS4232_MASK) { 1488 if (chip->hardware & CS4231_HW_CS4232_MASK) {
1488 if (chip->res_cport == NULL) 1489 if (chip->res_cport == NULL)
1489 snd_printk("CS4232 control port features are not accessible\n"); 1490 snd_printk("CS4232 control port features are not accessible\n");
1490 } 1491 }
1492#endif
1491 1493
1492 /* Register device */ 1494 /* Register device */
1493 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 1495 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index bc1054845a73..9e399b6e6ed9 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -136,27 +136,20 @@ struct snd_card_cs4236 {
136 136
137#ifdef CONFIG_PNP 137#ifdef CONFIG_PNP
138 138
139#define ISAPNP_CS4232(_va, _vb, _vc, _device, _wss, _ctrl, _mpu401) \ 139#ifdef CS4232
140 { \ 140/*
141 ISAPNP_CARD_ID(_va, _vb, _vc, _device), \ 141 * PNP BIOS
142 .devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _wss), \ 142 */
143 ISAPNP_DEVICE_ID(_va, _vb, _vc, _ctrl), \ 143static const struct pnp_device_id snd_cs4232_pnpbiosids[] = {
144 ISAPNP_DEVICE_ID(_va, _vb, _vc, _mpu401) } \ 144 { .id = "CSC0100" },
145 } 145 { .id = "CSC0000" },
146#define ISAPNP_CS4232_1(_va, _vb, _vc, _device, _wss, _ctrl, _mpu401) \ 146 /* Guillemot Turtlebeach something appears to be cs4232 compatible
147 { \ 147 * (untested) */
148 ISAPNP_CARD_ID(_va, _vb, _vc, _device), \ 148 { .id = "GIM0100" },
149 .devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _wss), \ 149 { .id = "" }
150 ISAPNP_DEVICE_ID(_va, _vb, _vc, _ctrl), \ 150};
151 ISAPNP_DEVICE_ID('P', 'N', 'P', _mpu401) } \ 151MODULE_DEVICE_TABLE(pnp, snd_cs4232_pnpbiosids);
152 } 152#endif /* CS4232 */
153#define ISAPNP_CS4232_WOMPU(_va, _vb, _vc, _device, _wss, _ctrl) \
154 { \
155 ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
156 .devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _wss), \
157 ISAPNP_DEVICE_ID(_va, _vb, _vc, _ctrl) } \
158 }
159
160 153
161#ifdef CS4232 154#ifdef CS4232
162#define CS423X_DRIVER "snd_cs4232" 155#define CS423X_DRIVER "snd_cs4232"
@@ -266,37 +259,12 @@ static struct pnp_card_device_id snd_cs423x_pnpids[] = {
266 259
267MODULE_DEVICE_TABLE(pnp_card, snd_cs423x_pnpids); 260MODULE_DEVICE_TABLE(pnp_card, snd_cs423x_pnpids);
268 261
269static int __devinit snd_card_cs4236_pnp(int dev, struct snd_card_cs4236 *acard, 262/* WSS initialization */
270 struct pnp_card_link *card, 263static int __devinit snd_cs423x_pnp_init_wss(int dev, struct pnp_dev *pdev,
271 const struct pnp_card_device_id *id) 264 struct pnp_resource_table *cfg)
272{ 265{
273 struct pnp_dev *pdev;
274 struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
275 int err; 266 int err;
276 267
277 if (!cfg)
278 return -ENOMEM;
279
280 acard->wss = pnp_request_card_device(card, id->devs[0].id, NULL);
281 if (acard->wss == NULL) {
282 kfree(cfg);
283 return -EBUSY;
284 }
285 acard->ctrl = pnp_request_card_device(card, id->devs[1].id, NULL);
286 if (acard->ctrl == NULL) {
287 kfree(cfg);
288 return -EBUSY;
289 }
290 if (id->devs[2].id[0]) {
291 acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL);
292 if (acard->mpu == NULL) {
293 kfree(cfg);
294 return -EBUSY;
295 }
296 }
297
298 /* WSS initialization */
299 pdev = acard->wss;
300 pnp_init_resource_table(cfg); 268 pnp_init_resource_table(cfg);
301 if (port[dev] != SNDRV_AUTO_PORT) 269 if (port[dev] != SNDRV_AUTO_PORT)
302 pnp_resource_change(&cfg->port_resource[0], port[dev], 4); 270 pnp_resource_change(&cfg->port_resource[0], port[dev], 4);
@@ -315,7 +283,6 @@ static int __devinit snd_card_cs4236_pnp(int dev, struct snd_card_cs4236 *acard,
315 snd_printk(KERN_ERR IDENT " WSS PnP manual resources are invalid, using auto config\n"); 283 snd_printk(KERN_ERR IDENT " WSS PnP manual resources are invalid, using auto config\n");
316 err = pnp_activate_dev(pdev); 284 err = pnp_activate_dev(pdev);
317 if (err < 0) { 285 if (err < 0) {
318 kfree(cfg);
319 printk(KERN_ERR IDENT " WSS PnP configure failed for WSS (out of resources?)\n"); 286 printk(KERN_ERR IDENT " WSS PnP configure failed for WSS (out of resources?)\n");
320 return -EBUSY; 287 return -EBUSY;
321 } 288 }
@@ -330,53 +297,122 @@ static int __devinit snd_card_cs4236_pnp(int dev, struct snd_card_cs4236 *acard,
330 port[dev], fm_port[dev], sb_port[dev]); 297 port[dev], fm_port[dev], sb_port[dev]);
331 snd_printdd("isapnp WSS: irq=%i, dma1=%i, dma2=%i\n", 298 snd_printdd("isapnp WSS: irq=%i, dma1=%i, dma2=%i\n",
332 irq[dev], dma1[dev], dma2[dev]); 299 irq[dev], dma1[dev], dma2[dev]);
300 return 0;
301}
302
303/* CTRL initialization */
304static int __devinit snd_cs423x_pnp_init_ctrl(int dev, struct pnp_dev *pdev,
305 struct pnp_resource_table *cfg)
306{
307 int err;
308
309 pnp_init_resource_table(cfg);
310 if (cport[dev] != SNDRV_AUTO_PORT)
311 pnp_resource_change(&cfg->port_resource[0], cport[dev], 8);
312 err = pnp_manual_config_dev(pdev, cfg, 0);
313 if (err < 0)
314 snd_printk(KERN_ERR IDENT " CTRL PnP manual resources are invalid, using auto config\n");
315 err = pnp_activate_dev(pdev);
316 if (err < 0) {
317 printk(KERN_ERR IDENT " CTRL PnP configure failed for WSS (out of resources?)\n");
318 return -EBUSY;
319 }
320 cport[dev] = pnp_port_start(pdev, 0);
321 snd_printdd("isapnp CTRL: control port=0x%lx\n", cport[dev]);
322 return 0;
323}
324
325/* MPU initialization */
326static int __devinit snd_cs423x_pnp_init_mpu(int dev, struct pnp_dev *pdev,
327 struct pnp_resource_table *cfg)
328{
329 int err;
330
331 pnp_init_resource_table(cfg);
332 if (mpu_port[dev] != SNDRV_AUTO_PORT)
333 pnp_resource_change(&cfg->port_resource[0], mpu_port[dev], 2);
334 if (mpu_irq[dev] != SNDRV_AUTO_IRQ && mpu_irq[dev] >= 0)
335 pnp_resource_change(&cfg->irq_resource[0], mpu_irq[dev], 1);
336 err = pnp_manual_config_dev(pdev, cfg, 0);
337 if (err < 0)
338 snd_printk(KERN_ERR IDENT " MPU401 PnP manual resources are invalid, using auto config\n");
339 err = pnp_activate_dev(pdev);
340 if (err < 0) {
341 printk(KERN_ERR IDENT " MPU401 PnP configure failed for WSS (out of resources?)\n");
342 mpu_port[dev] = SNDRV_AUTO_PORT;
343 mpu_irq[dev] = SNDRV_AUTO_IRQ;
344 } else {
345 mpu_port[dev] = pnp_port_start(pdev, 0);
346 if (mpu_irq[dev] >= 0 &&
347 pnp_irq_valid(pdev, 0) && pnp_irq(pdev, 0) >= 0) {
348 mpu_irq[dev] = pnp_irq(pdev, 0);
349 } else {
350 mpu_irq[dev] = -1; /* disable interrupt */
351 }
352 }
353 snd_printdd("isapnp MPU: port=0x%lx, irq=%i\n", mpu_port[dev], mpu_irq[dev]);
354 return 0;
355}
356
357#ifdef CS4232
358static int __devinit snd_card_cs4232_pnp(int dev, struct snd_card_cs4236 *acard,
359 struct pnp_dev *pdev)
360{
361 struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
362
363 if (!cfg)
364 return -ENOMEM;
365 if (snd_cs423x_pnp_init_wss(dev, acard->wss, cfg) < 0) {
366 kfree(cfg);
367 return -EBUSY;
368 }
369 kfree(cfg);
370 cport[dev] = -1;
371 return 0;
372}
373#endif
374
375static int __devinit snd_card_cs423x_pnpc(int dev, struct snd_card_cs4236 *acard,
376 struct pnp_card_link *card,
377 const struct pnp_card_device_id *id)
378{
379 struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
380
381 if (!cfg)
382 return -ENOMEM;
383
384 acard->wss = pnp_request_card_device(card, id->devs[0].id, NULL);
385 if (acard->wss == NULL)
386 goto error;
387 acard->ctrl = pnp_request_card_device(card, id->devs[1].id, NULL);
388 if (acard->ctrl == NULL)
389 goto error;
390 if (id->devs[2].id[0]) {
391 acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL);
392 if (acard->mpu == NULL)
393 goto error;
394 }
395
396 /* WSS initialization */
397 if (snd_cs423x_pnp_init_wss(dev, acard->wss, cfg) < 0)
398 goto error;
399
333 /* CTRL initialization */ 400 /* CTRL initialization */
334 if (acard->ctrl && cport[dev] > 0) { 401 if (acard->ctrl && cport[dev] > 0) {
335 pdev = acard->ctrl; 402 if (snd_cs423x_pnp_init_ctrl(dev, acard->ctrl, cfg) < 0)
336 pnp_init_resource_table(cfg); 403 goto error;
337 if (cport[dev] != SNDRV_AUTO_PORT)
338 pnp_resource_change(&cfg->port_resource[0], cport[dev], 8);
339 err = pnp_manual_config_dev(pdev, cfg, 0);
340 if (err < 0)
341 snd_printk(KERN_ERR IDENT " CTRL PnP manual resources are invalid, using auto config\n");
342 err = pnp_activate_dev(pdev);
343 if (err < 0) {
344 kfree(cfg);
345 printk(KERN_ERR IDENT " CTRL PnP configure failed for WSS (out of resources?)\n");
346 return -EBUSY;
347 }
348 cport[dev] = pnp_port_start(pdev, 0);
349 snd_printdd("isapnp CTRL: control port=0x%lx\n", cport[dev]);
350 } 404 }
351 /* MPU initialization */ 405 /* MPU initialization */
352 if (acard->mpu && mpu_port[dev] > 0) { 406 if (acard->mpu && mpu_port[dev] > 0) {
353 pdev = acard->mpu; 407 if (snd_cs423x_pnp_init_mpu(dev, acard->ctrl, cfg) < 0)
354 pnp_init_resource_table(cfg); 408 goto error;
355 if (mpu_port[dev] != SNDRV_AUTO_PORT)
356 pnp_resource_change(&cfg->port_resource[0], mpu_port[dev], 2);
357 if (mpu_irq[dev] != SNDRV_AUTO_IRQ && mpu_irq[dev] >= 0)
358 pnp_resource_change(&cfg->irq_resource[0], mpu_irq[dev], 1);
359 err = pnp_manual_config_dev(pdev, cfg, 0);
360 if (err < 0)
361 snd_printk(KERN_ERR IDENT " MPU401 PnP manual resources are invalid, using auto config\n");
362 err = pnp_activate_dev(pdev);
363 if (err < 0) {
364 printk(KERN_ERR IDENT " MPU401 PnP configure failed for WSS (out of resources?)\n");
365 mpu_port[dev] = SNDRV_AUTO_PORT;
366 mpu_irq[dev] = SNDRV_AUTO_IRQ;
367 } else {
368 mpu_port[dev] = pnp_port_start(pdev, 0);
369 if (mpu_irq[dev] >= 0 &&
370 pnp_irq_valid(pdev, 0) && pnp_irq(pdev, 0) >= 0) {
371 mpu_irq[dev] = pnp_irq(pdev, 0);
372 } else {
373 mpu_irq[dev] = -1; /* disable interrupt */
374 }
375 }
376 snd_printdd("isapnp MPU: port=0x%lx, irq=%i\n", mpu_port[dev], mpu_irq[dev]);
377 } 409 }
378 kfree(cfg); 410 kfree(cfg);
379 return 0; 411 return 0;
412
413 error:
414 kfree(cfg);
415 return -EBUSY;
380} 416}
381#endif /* CONFIG_PNP */ 417#endif /* CONFIG_PNP */
382 418
@@ -558,7 +594,7 @@ static int snd_cs423x_nonpnp_resume(struct platform_device *dev)
558} 594}
559#endif 595#endif
560 596
561static struct platform_driver snd_cs423x_nonpnp_driver = { 597static struct platform_driver cs423x_nonpnp_driver = {
562 .probe = snd_cs423x_nonpnp_probe, 598 .probe = snd_cs423x_nonpnp_probe,
563 .remove = __devexit_p(snd_cs423x_nonpnp_remove), 599 .remove = __devexit_p(snd_cs423x_nonpnp_remove),
564#ifdef CONFIG_PM 600#ifdef CONFIG_PM
@@ -572,8 +608,73 @@ static struct platform_driver snd_cs423x_nonpnp_driver = {
572 608
573 609
574#ifdef CONFIG_PNP 610#ifdef CONFIG_PNP
575static int __devinit snd_cs423x_pnp_detect(struct pnp_card_link *pcard, 611#ifdef CS4232
576 const struct pnp_card_device_id *pid) 612static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev,
613 const struct pnp_device_id *id)
614{
615 static int dev;
616 int err;
617 struct snd_card *card;
618
619 if (pnp_device_is_isapnp(pdev))
620 return -ENOENT; /* we have another procedure - card */
621 for (; dev < SNDRV_CARDS; dev++) {
622 if (enable[dev] && isapnp[dev])
623 break;
624 }
625 if (dev >= SNDRV_CARDS)
626 return -ENODEV;
627
628 card = snd_cs423x_card_new(dev);
629 if (! card)
630 return -ENOMEM;
631 if ((err = snd_card_cs4232_pnp(dev, card->private_data, pdev)) < 0) {
632 printk(KERN_ERR "PnP BIOS detection failed for " IDENT "\n");
633 snd_card_free(card);
634 return err;
635 }
636 snd_card_set_dev(card, &pdev->dev);
637 if ((err = snd_cs423x_probe(card, dev)) < 0) {
638 snd_card_free(card);
639 return err;
640 }
641 pnp_set_drvdata(pdev, card);
642 dev++;
643 return 0;
644}
645
646static void __devexit snd_cs4232_pnp_remove(struct pnp_dev * pdev)
647{
648 snd_card_free(pnp_get_drvdata(pdev));
649 pnp_set_drvdata(pdev, NULL);
650}
651
652#ifdef CONFIG_PM
653static int snd_cs4232_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
654{
655 return snd_cs423x_suspend(pnp_get_drvdata(pdev));
656}
657
658static int snd_cs4232_pnp_resume(struct pnp_dev *pdev)
659{
660 return snd_cs423x_resume(pnp_get_drvdata(pdev));
661}
662#endif
663
664static struct pnp_driver cs4232_pnp_driver = {
665 .name = "cs4232-pnpbios",
666 .id_table = snd_cs4232_pnpbiosids,
667 .probe = snd_cs4232_pnpbios_detect,
668 .remove = __devexit_p(snd_cs4232_pnp_remove),
669#ifdef CONFIG_PM
670 .suspend = snd_cs4232_pnp_suspend,
671 .resume = snd_cs4232_pnp_resume,
672#endif
673};
674#endif /* CS4232 */
675
676static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard,
677 const struct pnp_card_device_id *pid)
577{ 678{
578 static int dev; 679 static int dev;
579 struct snd_card *card; 680 struct snd_card *card;
@@ -589,8 +690,9 @@ static int __devinit snd_cs423x_pnp_detect(struct pnp_card_link *pcard,
589 card = snd_cs423x_card_new(dev); 690 card = snd_cs423x_card_new(dev);
590 if (! card) 691 if (! card)
591 return -ENOMEM; 692 return -ENOMEM;
592 if ((res = snd_card_cs4236_pnp(dev, card->private_data, pcard, pid))<0) { 693 if ((res = snd_card_cs423x_pnpc(dev, card->private_data, pcard, pid)) < 0) {
593 printk(KERN_ERR "isapnp detection failed and probing for " IDENT " is not supported\n"); 694 printk(KERN_ERR "isapnp detection failed and probing for " IDENT
695 " is not supported\n");
594 snd_card_free(card); 696 snd_card_free(card);
595 return res; 697 return res;
596 } 698 }
@@ -604,19 +706,19 @@ static int __devinit snd_cs423x_pnp_detect(struct pnp_card_link *pcard,
604 return 0; 706 return 0;
605} 707}
606 708
607static void __devexit snd_cs423x_pnp_remove(struct pnp_card_link * pcard) 709static void __devexit snd_cs423x_pnpc_remove(struct pnp_card_link * pcard)
608{ 710{
609 snd_card_free(pnp_get_card_drvdata(pcard)); 711 snd_card_free(pnp_get_card_drvdata(pcard));
610 pnp_set_card_drvdata(pcard, NULL); 712 pnp_set_card_drvdata(pcard, NULL);
611} 713}
612 714
613#ifdef CONFIG_PM 715#ifdef CONFIG_PM
614static int snd_cs423x_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state) 716static int snd_cs423x_pnpc_suspend(struct pnp_card_link *pcard, pm_message_t state)
615{ 717{
616 return snd_cs423x_suspend(pnp_get_card_drvdata(pcard)); 718 return snd_cs423x_suspend(pnp_get_card_drvdata(pcard));
617} 719}
618 720
619static int snd_cs423x_pnp_resume(struct pnp_card_link *pcard) 721static int snd_cs423x_pnpc_resume(struct pnp_card_link *pcard)
620{ 722{
621 return snd_cs423x_resume(pnp_get_card_drvdata(pcard)); 723 return snd_cs423x_resume(pnp_get_card_drvdata(pcard));
622} 724}
@@ -626,11 +728,11 @@ static struct pnp_card_driver cs423x_pnpc_driver = {
626 .flags = PNP_DRIVER_RES_DISABLE, 728 .flags = PNP_DRIVER_RES_DISABLE,
627 .name = CS423X_ISAPNP_DRIVER, 729 .name = CS423X_ISAPNP_DRIVER,
628 .id_table = snd_cs423x_pnpids, 730 .id_table = snd_cs423x_pnpids,
629 .probe = snd_cs423x_pnp_detect, 731 .probe = snd_cs423x_pnpc_detect,
630 .remove = __devexit_p(snd_cs423x_pnp_remove), 732 .remove = __devexit_p(snd_cs423x_pnpc_remove),
631#ifdef CONFIG_PM 733#ifdef CONFIG_PM
632 .suspend = snd_cs423x_pnp_suspend, 734 .suspend = snd_cs423x_pnpc_suspend,
633 .resume = snd_cs423x_pnp_resume, 735 .resume = snd_cs423x_pnpc_resume,
634#endif 736#endif
635}; 737};
636#endif /* CONFIG_PNP */ 738#endif /* CONFIG_PNP */
@@ -639,7 +741,7 @@ static int __init alsa_card_cs423x_init(void)
639{ 741{
640 int i, err, cards = 0; 742 int i, err, cards = 0;
641 743
642 if ((err = platform_driver_register(&snd_cs423x_nonpnp_driver)) < 0) 744 if ((err = platform_driver_register(&cs423x_nonpnp_driver)) < 0)
643 return err; 745 return err;
644 746
645 for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { 747 for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
@@ -650,17 +752,25 @@ static int __init alsa_card_cs423x_init(void)
650 i, NULL, 0); 752 i, NULL, 0);
651 if (IS_ERR(device)) { 753 if (IS_ERR(device)) {
652 err = PTR_ERR(device); 754 err = PTR_ERR(device);
653 platform_driver_unregister(&snd_cs423x_nonpnp_driver); 755 platform_driver_unregister(&cs423x_nonpnp_driver);
654 return err; 756 return err;
655 } 757 }
656 cards++; 758 cards++;
657 } 759 }
760#ifdef CS4232
761 i = pnp_register_driver(&cs4232_pnp_driver);
762 if (i > 0)
763 cards += i;
764#endif
658 i = pnp_register_card_driver(&cs423x_pnpc_driver); 765 i = pnp_register_card_driver(&cs423x_pnpc_driver);
659 if (i > 0) 766 if (i > 0)
660 cards += i; 767 cards += i;
661 if (!cards) { 768 if (!cards) {
769#ifdef CS4232
770 pnp_unregister_driver(&cs4232_pnp_driver);
771#endif
662 pnp_unregister_card_driver(&cs423x_pnpc_driver); 772 pnp_unregister_card_driver(&cs423x_pnpc_driver);
663 platform_driver_unregister(&snd_cs423x_nonpnp_driver); 773 platform_driver_unregister(&cs423x_nonpnp_driver);
664#ifdef MODULE 774#ifdef MODULE
665 printk(KERN_ERR IDENT " soundcard not found or device busy\n"); 775 printk(KERN_ERR IDENT " soundcard not found or device busy\n");
666#endif 776#endif
@@ -671,8 +781,11 @@ static int __init alsa_card_cs423x_init(void)
671 781
672static void __exit alsa_card_cs423x_exit(void) 782static void __exit alsa_card_cs423x_exit(void)
673{ 783{
784#ifdef CS4232
785 pnp_unregister_driver(&cs4232_pnp_driver);
786#endif
674 pnp_unregister_card_driver(&cs423x_pnpc_driver); 787 pnp_unregister_card_driver(&cs423x_pnpc_driver);
675 platform_driver_unregister(&snd_cs423x_nonpnp_driver); 788 platform_driver_unregister(&cs423x_nonpnp_driver);
676} 789}
677 790
678module_init(alsa_card_cs423x_init) 791module_init(alsa_card_cs423x_init)