aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/mips/au1x00.c239
1 files changed, 141 insertions, 98 deletions
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index 224f54be15a6..526e59f43832 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -37,6 +37,7 @@
37#include <linux/ioport.h> 37#include <linux/ioport.h>
38#include <linux/interrupt.h> 38#include <linux/interrupt.h>
39#include <linux/init.h> 39#include <linux/init.h>
40#include <linux/platform_device.h>
40#include <linux/slab.h> 41#include <linux/slab.h>
41#include <linux/module.h> 42#include <linux/module.h>
42#include <sound/core.h> 43#include <sound/core.h>
@@ -98,6 +99,7 @@ struct snd_au1000 {
98 99
99 struct snd_pcm *pcm; 100 struct snd_pcm *pcm;
100 struct audio_stream *stream[2]; /* playback & capture */ 101 struct audio_stream *stream[2]; /* playback & capture */
102 int dmaid[2]; /* tx(0)/rx(1) DMA ids */
101}; 103};
102 104
103/*--------------------------- Local Functions --------------------------------*/ 105/*--------------------------- Local Functions --------------------------------*/
@@ -465,15 +467,17 @@ snd_au1000_pcm_new(struct snd_au1000 *au1000)
465 spin_lock_init(&au1000->stream[CAPTURE]->dma_lock); 467 spin_lock_init(&au1000->stream[CAPTURE]->dma_lock);
466 468
467 flags = claim_dma_lock(); 469 flags = claim_dma_lock();
468 if ((au1000->stream[PLAYBACK]->dma = request_au1000_dma(DMA_ID_AC97C_TX, 470 au1000->stream[PLAYBACK]->dma = request_au1000_dma(au1000->dmaid[0],
469 "AC97 TX", au1000_dma_interrupt, 0, 471 "AC97 TX", au1000_dma_interrupt, 0,
470 au1000->stream[PLAYBACK])) < 0) { 472 au1000->stream[PLAYBACK]);
473 if (au1000->stream[PLAYBACK]->dma < 0) {
471 release_dma_lock(flags); 474 release_dma_lock(flags);
472 return -EBUSY; 475 return -EBUSY;
473 } 476 }
474 if ((au1000->stream[CAPTURE]->dma = request_au1000_dma(DMA_ID_AC97C_RX, 477 au1000->stream[CAPTURE]->dma = request_au1000_dma(au1000->dmaid[1],
475 "AC97 RX", au1000_dma_interrupt, 0, 478 "AC97 RX", au1000_dma_interrupt, 0,
476 au1000->stream[CAPTURE])) < 0){ 479 au1000->stream[CAPTURE]);
480 if (au1000->stream[CAPTURE]->dma < 0){
477 release_dma_lock(flags); 481 release_dma_lock(flags);
478 return -EBUSY; 482 return -EBUSY;
479 } 483 }
@@ -552,69 +556,12 @@ get the interrupt driven case to work efficiently */
552 spin_unlock(&au1000->ac97_lock); 556 spin_unlock(&au1000->ac97_lock);
553} 557}
554 558
555static int
556snd_au1000_ac97_new(struct snd_au1000 *au1000)
557{
558 int err;
559 struct snd_ac97_bus *pbus;
560 struct snd_ac97_template ac97;
561 static struct snd_ac97_bus_ops ops = {
562 .write = snd_au1000_ac97_write,
563 .read = snd_au1000_ac97_read,
564 };
565
566 if ((au1000->ac97_res_port = request_mem_region(CPHYSADDR(AC97C_CONFIG),
567 0x100000, "Au1x00 AC97")) == NULL) {
568 snd_printk(KERN_ERR "ALSA AC97: can't grap AC97 port\n");
569 return -EBUSY;
570 }
571 au1000->ac97_ioport = (struct au1000_ac97_reg *)
572 KSEG1ADDR(au1000->ac97_res_port->start);
573
574 spin_lock_init(&au1000->ac97_lock);
575
576 /* configure pins for AC'97
577 TODO: move to board_setup.c */
578 au_writel(au_readl(SYS_PINFUNC) & ~0x02, SYS_PINFUNC);
579
580 /* Initialise Au1000's AC'97 Control Block */
581 au1000->ac97_ioport->cntrl = AC97C_RS | AC97C_CE;
582 udelay(10);
583 au1000->ac97_ioport->cntrl = AC97C_CE;
584 udelay(10);
585
586 /* Initialise External CODEC -- cold reset */
587 au1000->ac97_ioport->config = AC97C_RESET;
588 udelay(10);
589 au1000->ac97_ioport->config = 0x0;
590 mdelay(5);
591
592 /* Initialise AC97 middle-layer */
593 if ((err = snd_ac97_bus(au1000->card, 0, &ops, au1000, &pbus)) < 0)
594 return err;
595
596 memset(&ac97, 0, sizeof(ac97));
597 ac97.private_data = au1000;
598 if ((err = snd_ac97_mixer(pbus, &ac97, &au1000->ac97)) < 0)
599 return err;
600
601 return 0;
602}
603
604/*------------------------------ Setup / Destroy ----------------------------*/ 559/*------------------------------ Setup / Destroy ----------------------------*/
605 560
606void 561static void snd_au1000_free(struct snd_card *card)
607snd_au1000_free(struct snd_card *card)
608{ 562{
609 struct snd_au1000 *au1000 = card->private_data; 563 struct snd_au1000 *au1000 = card->private_data;
610 564
611 if (au1000->ac97_res_port) {
612 /* put internal AC97 block into reset */
613 au1000->ac97_ioport->cntrl = AC97C_RS;
614 au1000->ac97_ioport = NULL;
615 release_and_free_resource(au1000->ac97_res_port);
616 }
617
618 if (au1000->stream[PLAYBACK]) { 565 if (au1000->stream[PLAYBACK]) {
619 if (au1000->stream[PLAYBACK]->dma >= 0) 566 if (au1000->stream[PLAYBACK]->dma >= 0)
620 free_au1000_dma(au1000->stream[PLAYBACK]->dma); 567 free_au1000_dma(au1000->stream[PLAYBACK]->dma);
@@ -626,71 +573,167 @@ snd_au1000_free(struct snd_card *card)
626 free_au1000_dma(au1000->stream[CAPTURE]->dma); 573 free_au1000_dma(au1000->stream[CAPTURE]->dma);
627 kfree(au1000->stream[CAPTURE]); 574 kfree(au1000->stream[CAPTURE]);
628 } 575 }
629}
630 576
577 if (au1000->ac97_res_port) {
578 /* put internal AC97 block into reset */
579 if (au1000->ac97_ioport) {
580 au1000->ac97_ioport->cntrl = AC97C_RS;
581 iounmap(au1000->ac97_ioport);
582 au1000->ac97_ioport = NULL;
583 }
584 release_and_free_resource(au1000->ac97_res_port);
585 au1000->ac97_res_port = NULL;
586 }
587}
631 588
632static struct snd_card *au1000_card; 589static struct snd_ac97_bus_ops ops = {
590 .write = snd_au1000_ac97_write,
591 .read = snd_au1000_ac97_read,
592};
633 593
634static int __init 594static int au1000_ac97_probe(struct platform_device *pdev)
635au1000_init(void)
636{ 595{
637 int err; 596 int err;
597 void __iomem *io;
598 struct resource *r;
638 struct snd_card *card; 599 struct snd_card *card;
639 struct snd_au1000 *au1000; 600 struct snd_au1000 *au1000;
601 struct snd_ac97_bus *pbus;
602 struct snd_ac97_template ac97;
640 603
641 err = snd_card_create(-1, "AC97", THIS_MODULE, 604 err = snd_card_create(-1, "AC97", THIS_MODULE,
642 sizeof(struct snd_au1000), &card); 605 sizeof(struct snd_au1000), &card);
643 if (err < 0) 606 if (err < 0)
644 return err; 607 return err;
645 608
646 card->private_free = snd_au1000_free;
647 au1000 = card->private_data; 609 au1000 = card->private_data;
648 au1000->card = card; 610 au1000->card = card;
611 spin_lock_init(&au1000->ac97_lock);
649 612
650 au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); 613 /* from here on let ALSA call the special freeing function */
651 au1000->stream[CAPTURE ] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); 614 card->private_free = snd_au1000_free;
652 /* so that snd_au1000_free will work as intended */
653 au1000->ac97_res_port = NULL;
654 if (au1000->stream[PLAYBACK])
655 au1000->stream[PLAYBACK]->dma = -1;
656 if (au1000->stream[CAPTURE ])
657 au1000->stream[CAPTURE ]->dma = -1;
658
659 if (au1000->stream[PLAYBACK] == NULL ||
660 au1000->stream[CAPTURE ] == NULL) {
661 snd_card_free(card);
662 return -ENOMEM;
663 }
664 615
665 if ((err = snd_au1000_ac97_new(au1000)) < 0 ) { 616 /* TX DMA ID */
666 snd_card_free(card); 617 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
667 return err; 618 if (!r) {
619 err = -ENODEV;
620 snd_printk(KERN_INFO "no TX DMA platform resource!\n");
621 goto out;
668 } 622 }
669 623 au1000->dmaid[0] = r->start;
670 if ((err = snd_au1000_pcm_new(au1000)) < 0) { 624
671 snd_card_free(card); 625 /* RX DMA ID */
672 return err; 626 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
627 if (!r) {
628 err = -ENODEV;
629 snd_printk(KERN_INFO "no RX DMA platform resource!\n");
630 goto out;
631 }
632 au1000->dmaid[1] = r->start;
633
634 au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream),
635 GFP_KERNEL);
636 if (!au1000->stream[PLAYBACK])
637 goto out;
638 au1000->stream[PLAYBACK]->dma = -1;
639
640 au1000->stream[CAPTURE] = kmalloc(sizeof(struct audio_stream),
641 GFP_KERNEL);
642 if (!au1000->stream[CAPTURE])
643 goto out;
644 au1000->stream[CAPTURE]->dma = -1;
645
646 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
647 if (!r)
648 goto out;
649
650 err = -EBUSY;
651 au1000->ac97_res_port = request_mem_region(r->start,
652 r->end - r->start + 1, pdev->name);
653 if (!au1000->ac97_res_port) {
654 snd_printk(KERN_ERR "ALSA AC97: can't grab AC97 port\n");
655 goto out;
673 } 656 }
674 657
658 io = ioremap(r->start, r->end - r->start + 1);
659 if (!io)
660 goto out;
661
662 au1000->ac97_ioport = (struct au1000_ac97_reg *)io;
663
664 /* configure pins for AC'97
665 TODO: move to board_setup.c */
666 au_writel(au_readl(SYS_PINFUNC) & ~0x02, SYS_PINFUNC);
667
668 /* Initialise Au1000's AC'97 Control Block */
669 au1000->ac97_ioport->cntrl = AC97C_RS | AC97C_CE;
670 udelay(10);
671 au1000->ac97_ioport->cntrl = AC97C_CE;
672 udelay(10);
673
674 /* Initialise External CODEC -- cold reset */
675 au1000->ac97_ioport->config = AC97C_RESET;
676 udelay(10);
677 au1000->ac97_ioport->config = 0x0;
678 mdelay(5);
679
680 /* Initialise AC97 middle-layer */
681 err = snd_ac97_bus(au1000->card, 0, &ops, au1000, &pbus);
682 if (err < 0)
683 goto out;
684
685 memset(&ac97, 0, sizeof(ac97));
686 ac97.private_data = au1000;
687 err = snd_ac97_mixer(pbus, &ac97, &au1000->ac97);
688 if (err < 0)
689 goto out;
690
691 err = snd_au1000_pcm_new(au1000);
692 if (err < 0)
693 goto out;
694
675 strcpy(card->driver, "Au1000-AC97"); 695 strcpy(card->driver, "Au1000-AC97");
676 strcpy(card->shortname, "AMD Au1000-AC97"); 696 strcpy(card->shortname, "AMD Au1000-AC97");
677 sprintf(card->longname, "AMD Au1000--AC97 ALSA Driver"); 697 sprintf(card->longname, "AMD Au1000--AC97 ALSA Driver");
678 698
679 if ((err = snd_card_register(card)) < 0) { 699 err = snd_card_register(card);
680 snd_card_free(card); 700 if (err < 0)
681 return err; 701 goto out;
682 }
683 702
684 printk(KERN_INFO "ALSA AC97: Driver Initialized\n"); 703 printk(KERN_INFO "ALSA AC97: Driver Initialized\n");
685 au1000_card = card; 704
705 platform_set_drvdata(pdev, card);
706
686 return 0; 707 return 0;
708
709 out:
710 snd_card_free(card);
711 return err;
712}
713
714static int au1000_ac97_remove(struct platform_device *pdev)
715{
716 return snd_card_free(platform_get_drvdata(pdev));
687} 717}
688 718
689static void __exit au1000_exit(void) 719struct platform_driver au1000_ac97c_driver = {
720 .driver = {
721 .name = "au1000-ac97c",
722 .owner = THIS_MODULE,
723 },
724 .probe = au1000_ac97_probe,
725 .remove = au1000_ac97_remove,
726};
727
728static int __init au1000_ac97_load(void)
690{ 729{
691 snd_card_free(au1000_card); 730 return platform_driver_register(&au1000_ac97c_driver);
692} 731}
693 732
694module_init(au1000_init); 733static void __exit au1000_ac97_unload(void)
695module_exit(au1000_exit); 734{
735 platform_driver_unregister(&au1000_ac97c_driver);
736}
696 737
738module_init(au1000_ac97_load);
739module_exit(au1000_ac97_unload);