diff options
Diffstat (limited to 'sound/pci/emu10k1')
-rw-r--r-- | sound/pci/emu10k1/emu10k1.c | 2 | ||||
-rw-r--r-- | sound/pci/emu10k1/emu10k1_main.c | 192 | ||||
-rw-r--r-- | sound/pci/emu10k1/emu10k1x.c | 8 | ||||
-rw-r--r-- | sound/pci/emu10k1/emufx.c | 56 | ||||
-rw-r--r-- | sound/pci/emu10k1/emumixer.c | 14 | ||||
-rw-r--r-- | sound/pci/emu10k1/emupcm.c | 6 | ||||
-rw-r--r-- | sound/pci/emu10k1/emuproc.c | 89 | ||||
-rw-r--r-- | sound/pci/emu10k1/irq.c | 46 | ||||
-rw-r--r-- | sound/pci/emu10k1/p16v.c | 367 |
9 files changed, 644 insertions, 136 deletions
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index 6446afe19d80..2085a998eaeb 100644 --- a/sound/pci/emu10k1/emu10k1.c +++ b/sound/pci/emu10k1/emu10k1.c | |||
@@ -228,7 +228,7 @@ static struct pci_driver driver = { | |||
228 | 228 | ||
229 | static int __init alsa_card_emu10k1_init(void) | 229 | static int __init alsa_card_emu10k1_init(void) |
230 | { | 230 | { |
231 | return pci_module_init(&driver); | 231 | return pci_register_driver(&driver); |
232 | } | 232 | } |
233 | 233 | ||
234 | static void __exit alsa_card_emu10k1_exit(void) | 234 | static void __exit alsa_card_emu10k1_exit(void) |
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index c3c96f9f2c7f..a341e758acde 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c | |||
@@ -170,7 +170,7 @@ static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir) | |||
170 | SPCS_GENERATIONSTATUS | 0x00001200 | | 170 | SPCS_GENERATIONSTATUS | 0x00001200 | |
171 | 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT); | 171 | 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT); |
172 | 172 | ||
173 | if (emu->audigy && emu->revision == 4) { /* audigy2 */ | 173 | if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ |
174 | /* Hacks for Alice3 to work independent of haP16V driver */ | 174 | /* Hacks for Alice3 to work independent of haP16V driver */ |
175 | u32 tmp; | 175 | u32 tmp; |
176 | 176 | ||
@@ -189,7 +189,7 @@ static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir) | |||
189 | /* Enabled Phased (8-channel) P16V playback */ | 189 | /* Enabled Phased (8-channel) P16V playback */ |
190 | outl(0x0201, emu->port + HCFG2); | 190 | outl(0x0201, emu->port + HCFG2); |
191 | /* Set playback routing. */ | 191 | /* Set playback routing. */ |
192 | snd_emu10k1_ptr_write(emu, CAPTURE_P16V_SOURCE, 0, 78e4); | 192 | snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, 0x78e4); |
193 | } | 193 | } |
194 | if (emu->audigy && (emu->serial == 0x10011102) ) { /* audigy2 Value */ | 194 | if (emu->audigy && (emu->serial == 0x10011102) ) { /* audigy2 Value */ |
195 | /* Hacks for Alice3 to work independent of haP16V driver */ | 195 | /* Hacks for Alice3 to work independent of haP16V driver */ |
@@ -600,7 +600,7 @@ static int snd_emu10k1_free(emu10k1_t *emu) | |||
600 | if (emu->port) | 600 | if (emu->port) |
601 | pci_release_regions(emu->pci); | 601 | pci_release_regions(emu->pci); |
602 | pci_disable_device(emu->pci); | 602 | pci_disable_device(emu->pci); |
603 | if (emu->audigy && emu->revision == 4) /* P16V */ | 603 | if (emu->card_capabilities->ca0151_chip) /* P16V */ |
604 | snd_p16v_free(emu); | 604 | snd_p16v_free(emu); |
605 | kfree(emu); | 605 | kfree(emu); |
606 | return 0; | 606 | return 0; |
@@ -612,21 +612,24 @@ static int snd_emu10k1_dev_free(snd_device_t *device) | |||
612 | return snd_emu10k1_free(emu); | 612 | return snd_emu10k1_free(emu); |
613 | } | 613 | } |
614 | 614 | ||
615 | /* vendor, device, subsystem, emu10k1_chip, emu10k2_chip, ca0102_chip, ca0108_chip, ca0151_chip, spk71, spdif_bug, ac97_chip, ecard, driver, name */ | ||
616 | |||
617 | static emu_chip_details_t emu_chip_details[] = { | 615 | static emu_chip_details_t emu_chip_details[] = { |
618 | /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/ | 616 | /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/ |
619 | {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102, | 617 | {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102, |
620 | .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]", | 618 | .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]", |
619 | .id = "Audigy2", | ||
621 | .emu10k2_chip = 1, | 620 | .emu10k2_chip = 1, |
622 | .ca0108_chip = 1, | 621 | .ca0108_chip = 1, |
623 | .spk71 = 1} , | 622 | .spk71 = 1, |
623 | .ac97_chip = 1} , | ||
624 | {.vendor = 0x1102, .device = 0x0008, | 624 | {.vendor = 0x1102, .device = 0x0008, |
625 | .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", | 625 | .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", |
626 | .id = "Audigy2", | ||
626 | .emu10k2_chip = 1, | 627 | .emu10k2_chip = 1, |
627 | .ca0108_chip = 1} , | 628 | .ca0108_chip = 1, |
629 | .ac97_chip = 1} , | ||
628 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, | 630 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, |
629 | .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", | 631 | .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", |
632 | .id = "Audigy2", | ||
630 | .emu10k2_chip = 1, | 633 | .emu10k2_chip = 1, |
631 | .ca0102_chip = 1, | 634 | .ca0102_chip = 1, |
632 | .ca0151_chip = 1, | 635 | .ca0151_chip = 1, |
@@ -635,6 +638,7 @@ static emu_chip_details_t emu_chip_details[] = { | |||
635 | .ac97_chip = 1} , | 638 | .ac97_chip = 1} , |
636 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102, | 639 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102, |
637 | .driver = "Audigy2", .name = "Audigy 2 ZS [SB0350]", | 640 | .driver = "Audigy2", .name = "Audigy 2 ZS [SB0350]", |
641 | .id = "Audigy2", | ||
638 | .emu10k2_chip = 1, | 642 | .emu10k2_chip = 1, |
639 | .ca0102_chip = 1, | 643 | .ca0102_chip = 1, |
640 | .ca0151_chip = 1, | 644 | .ca0151_chip = 1, |
@@ -643,6 +647,7 @@ static emu_chip_details_t emu_chip_details[] = { | |||
643 | .ac97_chip = 1} , | 647 | .ac97_chip = 1} , |
644 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102, | 648 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102, |
645 | .driver = "Audigy2", .name = "Audigy 2 ZS [2001]", | 649 | .driver = "Audigy2", .name = "Audigy 2 ZS [2001]", |
650 | .id = "Audigy2", | ||
646 | .emu10k2_chip = 1, | 651 | .emu10k2_chip = 1, |
647 | .ca0102_chip = 1, | 652 | .ca0102_chip = 1, |
648 | .ca0151_chip = 1, | 653 | .ca0151_chip = 1, |
@@ -651,6 +656,7 @@ static emu_chip_details_t emu_chip_details[] = { | |||
651 | .ac97_chip = 1} , | 656 | .ac97_chip = 1} , |
652 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102, | 657 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102, |
653 | .driver = "Audigy2", .name = "Audigy 2 [SB0240]", | 658 | .driver = "Audigy2", .name = "Audigy 2 [SB0240]", |
659 | .id = "Audigy2", | ||
654 | .emu10k2_chip = 1, | 660 | .emu10k2_chip = 1, |
655 | .ca0102_chip = 1, | 661 | .ca0102_chip = 1, |
656 | .ca0151_chip = 1, | 662 | .ca0151_chip = 1, |
@@ -659,35 +665,165 @@ static emu_chip_details_t emu_chip_details[] = { | |||
659 | .ac97_chip = 1} , | 665 | .ac97_chip = 1} , |
660 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102, | 666 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102, |
661 | .driver = "Audigy2", .name = "Audigy 2 EX [1005]", | 667 | .driver = "Audigy2", .name = "Audigy 2 EX [1005]", |
668 | .id = "Audigy2", | ||
662 | .emu10k2_chip = 1, | 669 | .emu10k2_chip = 1, |
663 | .ca0102_chip = 1, | 670 | .ca0102_chip = 1, |
664 | .ca0151_chip = 1, | 671 | .ca0151_chip = 1, |
665 | .spdif_bug = 1} , | 672 | .spdif_bug = 1} , |
666 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102, | 673 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102, |
667 | .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]", | 674 | .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]", |
675 | .id = "Audigy2", | ||
668 | .emu10k2_chip = 1, | 676 | .emu10k2_chip = 1, |
669 | .ca0102_chip = 1, | 677 | .ca0102_chip = 1, |
670 | .ca0151_chip = 1, | 678 | .ca0151_chip = 1, |
671 | .spk71 = 1, | 679 | .spk71 = 1, |
672 | .spdif_bug = 1, | 680 | .spdif_bug = 1, |
673 | .ac97_chip = 1} , | 681 | .ac97_chip = 1} , |
682 | {.vendor = 0x1102, .device = 0x0004, .revision = 0x04, | ||
683 | .driver = "Audigy2", .name = "Audigy 2 [Unknown]", | ||
684 | .id = "Audigy2", | ||
685 | .emu10k2_chip = 1, | ||
686 | .ca0102_chip = 1, | ||
687 | .ca0151_chip = 1, | ||
688 | .spdif_bug = 1, | ||
689 | .ac97_chip = 1} , | ||
690 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10020052, | ||
691 | .driver = "Audigy", .name = "Audigy 1 ES [SB0160]", | ||
692 | .id = "Audigy", | ||
693 | .emu10k2_chip = 1, | ||
694 | .ca0102_chip = 1, | ||
695 | .spdif_bug = 1, | ||
696 | .ac97_chip = 1} , | ||
697 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102, | ||
698 | .driver = "Audigy", .name = "Audigy 1 [SB0090]", | ||
699 | .id = "Audigy", | ||
700 | .emu10k2_chip = 1, | ||
701 | .ca0102_chip = 1, | ||
702 | .ac97_chip = 1} , | ||
703 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102, | ||
704 | .driver = "Audigy", .name = "Audigy 1 [SB0090]", | ||
705 | .id = "Audigy", | ||
706 | .emu10k2_chip = 1, | ||
707 | .ca0102_chip = 1, | ||
708 | .ac97_chip = 1} , | ||
674 | {.vendor = 0x1102, .device = 0x0004, | 709 | {.vendor = 0x1102, .device = 0x0004, |
675 | .driver = "Audigy", .name = "Audigy 1 or 2 [Unknown]", | 710 | .driver = "Audigy", .name = "Audigy 1 [Unknown]", |
711 | .id = "Audigy", | ||
676 | .emu10k2_chip = 1, | 712 | .emu10k2_chip = 1, |
677 | .ca0102_chip = 1, | 713 | .ca0102_chip = 1, |
678 | .spdif_bug = 1} , | 714 | .ac97_chip = 1} , |
679 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102, | 715 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102, |
680 | .driver = "EMU10K1", .name = "E-mu APS [4001]", | 716 | .driver = "EMU10K1", .name = "E-mu APS [4001]", |
717 | .id = "APS", | ||
681 | .emu10k1_chip = 1, | 718 | .emu10k1_chip = 1, |
682 | .ecard = 1} , | 719 | .ecard = 1} , |
720 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102, | ||
721 | .driver = "EMU10K1", .name = "SBLive! Player 5.1 [SB0060]", | ||
722 | .id = "Live", | ||
723 | .emu10k1_chip = 1, | ||
724 | .ac97_chip = 1, | ||
725 | .sblive51 = 1} , | ||
683 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102, | 726 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102, |
684 | .driver = "EMU10K1", .name = "SB Live 5.1", | 727 | .driver = "EMU10K1", .name = "SB Live 5.1", |
728 | .id = "Live", | ||
729 | .emu10k1_chip = 1, | ||
730 | .ac97_chip = 1, | ||
731 | .sblive51 = 1} , | ||
732 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102, | ||
733 | .driver = "EMU10K1", .name = "SBLive! Platinum [CT4760P]", | ||
734 | .id = "Live", | ||
685 | .emu10k1_chip = 1, | 735 | .emu10k1_chip = 1, |
686 | .ac97_chip = 1} , | 736 | .ac97_chip = 1} , |
737 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102, | ||
738 | .driver = "EMU10K1", .name = "SBLive! [CT4620]", | ||
739 | .id = "Live", | ||
740 | .emu10k1_chip = 1, | ||
741 | .ac97_chip = 1, | ||
742 | .sblive51 = 1} , | ||
743 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102, | ||
744 | .driver = "EMU10K1", .name = "SBLive! Value [CT4670]", | ||
745 | .id = "Live", | ||
746 | .emu10k1_chip = 1, | ||
747 | .ac97_chip = 1, | ||
748 | .sblive51 = 1} , | ||
749 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102, | ||
750 | .driver = "EMU10K1", .name = "SBLive! Value [CT4780]", | ||
751 | .id = "Live", | ||
752 | .emu10k1_chip = 1, | ||
753 | .ac97_chip = 1, | ||
754 | .sblive51 = 1} , | ||
755 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102, | ||
756 | .driver = "EMU10K1", .name = "SB PCI512 [CT4790]", | ||
757 | .id = "Live", | ||
758 | .emu10k1_chip = 1, | ||
759 | .ac97_chip = 1, | ||
760 | .sblive51 = 1} , | ||
761 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102, | ||
762 | .driver = "EMU10K1", .name = "SBLive! Value [CT4830]", | ||
763 | .id = "Live", | ||
764 | .emu10k1_chip = 1, | ||
765 | .ac97_chip = 1, | ||
766 | .sblive51 = 1} , | ||
767 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80311102, | ||
768 | .driver = "EMU10K1", .name = "SBLive! Value [CT4831]", | ||
769 | .id = "Live", | ||
770 | .emu10k1_chip = 1, | ||
771 | .ac97_chip = 1, | ||
772 | .sblive51 = 1} , | ||
773 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102, | ||
774 | .driver = "EMU10K1", .name = "SBLive! Value [CT4832]", | ||
775 | .id = "Live", | ||
776 | .emu10k1_chip = 1, | ||
777 | .ac97_chip = 1, | ||
778 | .sblive51 = 1} , | ||
779 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102, | ||
780 | .driver = "EMU10K1", .name = "SBLive! Value [CT4850]", | ||
781 | .id = "Live", | ||
782 | .emu10k1_chip = 1, | ||
783 | .ac97_chip = 1, | ||
784 | .sblive51 = 1} , | ||
785 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102, | ||
786 | .driver = "EMU10K1", .name = "SBLive! Value [CT4870]", | ||
787 | .id = "Live", | ||
788 | .emu10k1_chip = 1, | ||
789 | .ac97_chip = 1, | ||
790 | .sblive51 = 1} , | ||
791 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102, | ||
792 | .driver = "EMU10K1", .name = "SBLive! Value [CT4871]", | ||
793 | .id = "Live", | ||
794 | .emu10k1_chip = 1, | ||
795 | .ac97_chip = 1, | ||
796 | .sblive51 = 1} , | ||
797 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102, | ||
798 | .driver = "EMU10K1", .name = "SBLive! Value [SB0060]", | ||
799 | .id = "Live", | ||
800 | .emu10k1_chip = 1, | ||
801 | .ac97_chip = 1, | ||
802 | .sblive51 = 1} , | ||
803 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102, | ||
804 | .driver = "EMU10K1", .name = "SBLive! Value [SB0101]", | ||
805 | .id = "Live", | ||
806 | .emu10k1_chip = 1, | ||
807 | .ac97_chip = 1, | ||
808 | .sblive51 = 1} , | ||
809 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806A1102, | ||
810 | .driver = "EMU10K1", .name = "SBLive! Value [SB0103]", | ||
811 | .id = "Live", | ||
812 | .emu10k1_chip = 1, | ||
813 | .ac97_chip = 1, | ||
814 | .sblive51 = 1} , | ||
815 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806B1102, | ||
816 | .driver = "EMU10K1", .name = "SBLive! [SB0105]", | ||
817 | .id = "Live", | ||
818 | .emu10k1_chip = 1, | ||
819 | .ac97_chip = 1, | ||
820 | .sblive51 = 1} , | ||
687 | {.vendor = 0x1102, .device = 0x0002, | 821 | {.vendor = 0x1102, .device = 0x0002, |
688 | .driver = "EMU10K1", .name = "SB Live [Unknown]", | 822 | .driver = "EMU10K1", .name = "SB Live [Unknown]", |
823 | .id = "Live", | ||
689 | .emu10k1_chip = 1, | 824 | .emu10k1_chip = 1, |
690 | .ac97_chip = 1} , | 825 | .ac97_chip = 1, |
826 | .sblive51 = 1} , | ||
691 | { } /* terminator */ | 827 | { } /* terminator */ |
692 | }; | 828 | }; |
693 | 829 | ||
@@ -738,13 +874,15 @@ int __devinit snd_emu10k1_create(snd_card_t * card, | |||
738 | emu->revision = revision; | 874 | emu->revision = revision; |
739 | pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial); | 875 | pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial); |
740 | pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model); | 876 | pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model); |
741 | emu->card_type = EMU10K1_CARD_CREATIVE; | ||
742 | snd_printdd("vendor=0x%x, device=0x%x, subsystem_vendor_id=0x%x, subsystem_id=0x%x\n",pci->vendor, pci->device, emu->serial, emu->model); | 877 | snd_printdd("vendor=0x%x, device=0x%x, subsystem_vendor_id=0x%x, subsystem_id=0x%x\n",pci->vendor, pci->device, emu->serial, emu->model); |
743 | 878 | ||
744 | for (c = emu_chip_details; c->vendor; c++) { | 879 | for (c = emu_chip_details; c->vendor; c++) { |
745 | if (c->vendor == pci->vendor && c->device == pci->device) { | 880 | if (c->vendor == pci->vendor && c->device == pci->device) { |
746 | if (c->subsystem == emu->serial) break; | 881 | if (c->subsystem && c->subsystem != emu->serial) |
747 | if (c->subsystem == 0) break; | 882 | continue; |
883 | if (c->revision && c->revision != emu->revision) | ||
884 | continue; | ||
885 | break; | ||
748 | } | 886 | } |
749 | } | 887 | } |
750 | if (c->vendor == 0) { | 888 | if (c->vendor == 0) { |
@@ -759,6 +897,23 @@ int __devinit snd_emu10k1_create(snd_card_t * card, | |||
759 | else | 897 | else |
760 | snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x\n", c->name, pci->vendor, pci->device, emu->serial); | 898 | snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x\n", c->name, pci->vendor, pci->device, emu->serial); |
761 | 899 | ||
900 | if (!*card->id && c->id) { | ||
901 | int i, n = 0; | ||
902 | strlcpy(card->id, c->id, sizeof(card->id)); | ||
903 | for (;;) { | ||
904 | for (i = 0; i < snd_ecards_limit; i++) { | ||
905 | if (snd_cards[i] && !strcmp(snd_cards[i]->id, card->id)) | ||
906 | break; | ||
907 | } | ||
908 | if (i >= snd_ecards_limit) | ||
909 | break; | ||
910 | n++; | ||
911 | if (n >= SNDRV_CARDS) | ||
912 | break; | ||
913 | snprintf(card->id, sizeof(card->id), "%s_%d", c->id, n); | ||
914 | } | ||
915 | } | ||
916 | |||
762 | is_audigy = emu->audigy = c->emu10k2_chip; | 917 | is_audigy = emu->audigy = c->emu10k2_chip; |
763 | 918 | ||
764 | /* set the DMA transfer mask */ | 919 | /* set the DMA transfer mask */ |
@@ -816,15 +971,6 @@ int __devinit snd_emu10k1_create(snd_card_t * card, | |||
816 | 971 | ||
817 | pci_set_master(pci); | 972 | pci_set_master(pci); |
818 | 973 | ||
819 | if (c->ecard) { | ||
820 | emu->card_type = EMU10K1_CARD_EMUAPS; | ||
821 | emu->APS = 1; | ||
822 | } | ||
823 | if (! c->ac97_chip) | ||
824 | emu->no_ac97 = 1; | ||
825 | |||
826 | emu->spk71 = c->spk71; | ||
827 | |||
828 | emu->fx8010.fxbus_mask = 0x303f; | 974 | emu->fx8010.fxbus_mask = 0x303f; |
829 | if (extin_mask == 0) | 975 | if (extin_mask == 0) |
830 | extin_mask = 0x3fcf; | 976 | extin_mask = 0x3fcf; |
@@ -833,7 +979,7 @@ int __devinit snd_emu10k1_create(snd_card_t * card, | |||
833 | emu->fx8010.extin_mask = extin_mask; | 979 | emu->fx8010.extin_mask = extin_mask; |
834 | emu->fx8010.extout_mask = extout_mask; | 980 | emu->fx8010.extout_mask = extout_mask; |
835 | 981 | ||
836 | if (emu->APS) { | 982 | if (emu->card_capabilities->ecard) { |
837 | if ((err = snd_emu10k1_ecard_init(emu)) < 0) { | 983 | if ((err = snd_emu10k1_ecard_init(emu)) < 0) { |
838 | snd_emu10k1_free(emu); | 984 | snd_emu10k1_free(emu); |
839 | return err; | 985 | return err; |
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 27dfd8ddddf4..e90c5ddd1d17 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c | |||
@@ -361,10 +361,7 @@ static void snd_emu10k1x_gpio_write(emu10k1x_t *emu, unsigned int value) | |||
361 | 361 | ||
362 | static void snd_emu10k1x_pcm_free_substream(snd_pcm_runtime_t *runtime) | 362 | static void snd_emu10k1x_pcm_free_substream(snd_pcm_runtime_t *runtime) |
363 | { | 363 | { |
364 | emu10k1x_pcm_t *epcm = runtime->private_data; | 364 | kfree(runtime->private_data); |
365 | |||
366 | if (epcm) | ||
367 | kfree(epcm); | ||
368 | } | 365 | } |
369 | 366 | ||
370 | static void snd_emu10k1x_pcm_interrupt(emu10k1x_t *emu, emu10k1x_voice_t *voice) | 367 | static void snd_emu10k1x_pcm_interrupt(emu10k1x_t *emu, emu10k1x_voice_t *voice) |
@@ -1075,6 +1072,7 @@ static int __devinit snd_emu10k1x_proc_init(emu10k1x_t * emu) | |||
1075 | snd_info_set_text_ops(entry, emu, 1024, snd_emu10k1x_proc_reg_read); | 1072 | snd_info_set_text_ops(entry, emu, 1024, snd_emu10k1x_proc_reg_read); |
1076 | entry->c.text.write_size = 64; | 1073 | entry->c.text.write_size = 64; |
1077 | entry->c.text.write = snd_emu10k1x_proc_reg_write; | 1074 | entry->c.text.write = snd_emu10k1x_proc_reg_write; |
1075 | entry->mode |= S_IWUSR; | ||
1078 | entry->private_data = emu; | 1076 | entry->private_data = emu; |
1079 | } | 1077 | } |
1080 | 1078 | ||
@@ -1627,7 +1625,7 @@ static int __init alsa_card_emu10k1x_init(void) | |||
1627 | { | 1625 | { |
1628 | int err; | 1626 | int err; |
1629 | 1627 | ||
1630 | if ((err = pci_module_init(&driver)) > 0) | 1628 | if ((err = pci_register_driver(&driver)) > 0) |
1631 | return err; | 1629 | return err; |
1632 | 1630 | ||
1633 | return 0; | 1631 | return 0; |
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index b9fa2e887fee..0529fb281125 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c | |||
@@ -1077,7 +1077,7 @@ static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu) | |||
1077 | gpr += 2; | 1077 | gpr += 2; |
1078 | 1078 | ||
1079 | /* PCM Side Playback (independent from stereo mix) */ | 1079 | /* PCM Side Playback (independent from stereo mix) */ |
1080 | if (emu->spk71) { | 1080 | if (emu->card_capabilities->spk71) { |
1081 | A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE)); | 1081 | A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE)); |
1082 | A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE)); | 1082 | A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE)); |
1083 | snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100); | 1083 | snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100); |
@@ -1145,14 +1145,14 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
1145 | A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L); | 1145 | A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L); |
1146 | A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R); | 1146 | A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R); |
1147 | snd_emu10k1_init_stereo_control(&controls[nctl++], | 1147 | snd_emu10k1_init_stereo_control(&controls[nctl++], |
1148 | emu->no_ac97 ? "CD Playback Volume" : "Audigy CD Playback Volume", | 1148 | emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume", |
1149 | gpr, 0); | 1149 | gpr, 0); |
1150 | gpr += 2; | 1150 | gpr += 2; |
1151 | /* Audigy CD Capture Volume */ | 1151 | /* Audigy CD Capture Volume */ |
1152 | A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L); | 1152 | A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L); |
1153 | A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R); | 1153 | A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R); |
1154 | snd_emu10k1_init_stereo_control(&controls[nctl++], | 1154 | snd_emu10k1_init_stereo_control(&controls[nctl++], |
1155 | emu->no_ac97 ? "CD Capture Volume" : "Audigy CD Capture Volume", | 1155 | emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume", |
1156 | gpr, 0); | 1156 | gpr, 0); |
1157 | gpr += 2; | 1157 | gpr += 2; |
1158 | 1158 | ||
@@ -1171,14 +1171,14 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
1171 | A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L); | 1171 | A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L); |
1172 | A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R); | 1172 | A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R); |
1173 | snd_emu10k1_init_stereo_control(&controls[nctl++], | 1173 | snd_emu10k1_init_stereo_control(&controls[nctl++], |
1174 | emu->no_ac97 ? "Line Playback Volume" : "Line2 Playback Volume", | 1174 | emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume", |
1175 | gpr, 0); | 1175 | gpr, 0); |
1176 | gpr += 2; | 1176 | gpr += 2; |
1177 | /* Line2 Capture Volume */ | 1177 | /* Line2 Capture Volume */ |
1178 | A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L); | 1178 | A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L); |
1179 | A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R); | 1179 | A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R); |
1180 | snd_emu10k1_init_stereo_control(&controls[nctl++], | 1180 | snd_emu10k1_init_stereo_control(&controls[nctl++], |
1181 | emu->no_ac97 ? "Line Capture Volume" : "Line2 Capture Volume", | 1181 | emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume", |
1182 | gpr, 0); | 1182 | gpr, 0); |
1183 | gpr += 2; | 1183 | gpr += 2; |
1184 | 1184 | ||
@@ -1197,14 +1197,14 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
1197 | A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L); | 1197 | A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L); |
1198 | A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R); | 1198 | A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R); |
1199 | snd_emu10k1_init_stereo_control(&controls[nctl++], | 1199 | snd_emu10k1_init_stereo_control(&controls[nctl++], |
1200 | emu->no_ac97 ? "Aux Playback Volume" : "Aux2 Playback Volume", | 1200 | emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume", |
1201 | gpr, 0); | 1201 | gpr, 0); |
1202 | gpr += 2; | 1202 | gpr += 2; |
1203 | /* Aux2 Capture Volume */ | 1203 | /* Aux2 Capture Volume */ |
1204 | A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L); | 1204 | A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L); |
1205 | A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R); | 1205 | A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R); |
1206 | snd_emu10k1_init_stereo_control(&controls[nctl++], | 1206 | snd_emu10k1_init_stereo_control(&controls[nctl++], |
1207 | emu->no_ac97 ? "Aux Capture Volume" : "Aux2 Capture Volume", | 1207 | emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume", |
1208 | gpr, 0); | 1208 | gpr, 0); |
1209 | gpr += 2; | 1209 | gpr += 2; |
1210 | 1210 | ||
@@ -1232,7 +1232,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
1232 | snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0); | 1232 | snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0); |
1233 | gpr++; | 1233 | gpr++; |
1234 | 1234 | ||
1235 | if (emu->spk71) { | 1235 | if (emu->card_capabilities->spk71) { |
1236 | /* Stereo Mix Side Playback */ | 1236 | /* Stereo Mix Side Playback */ |
1237 | A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix)); | 1237 | A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix)); |
1238 | A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1)); | 1238 | A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1)); |
@@ -1266,7 +1266,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
1266 | A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), A_GPR(playback + 3), A_C_00000000, A_C_00000000); /* rear right */ | 1266 | A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), A_GPR(playback + 3), A_C_00000000, A_C_00000000); /* rear right */ |
1267 | A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */ | 1267 | A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */ |
1268 | A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */ | 1268 | A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */ |
1269 | if (emu->spk71) { | 1269 | if (emu->card_capabilities->spk71) { |
1270 | A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 6), A_GPR(playback + 6), A_C_00000000, A_C_00000000); /* side left */ | 1270 | A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 6), A_GPR(playback + 6), A_C_00000000, A_C_00000000); /* side left */ |
1271 | A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 7), A_GPR(playback + 7), A_C_00000000, A_C_00000000); /* side right */ | 1271 | A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 7), A_GPR(playback + 7), A_C_00000000, A_C_00000000); /* side right */ |
1272 | } | 1272 | } |
@@ -1359,7 +1359,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
1359 | A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS); | 1359 | A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS); |
1360 | A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS); | 1360 | A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS); |
1361 | A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS); | 1361 | A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS); |
1362 | if (emu->spk71) | 1362 | if (emu->card_capabilities->spk71) |
1363 | A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS); | 1363 | A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS); |
1364 | 1364 | ||
1365 | /* headphone */ | 1365 | /* headphone */ |
@@ -1982,22 +1982,27 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) | |||
1982 | OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000); | 1982 | OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000); |
1983 | 1983 | ||
1984 | /* EFX capture - capture the 16 EXTINS */ | 1984 | /* EFX capture - capture the 16 EXTINS */ |
1985 | OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0)); | 1985 | if (emu->card_capabilities->sblive51) { |
1986 | OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1)); | 1986 | /* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER |
1987 | OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2)); | 1987 | * and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording. |
1988 | OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3)); | 1988 | * |
1989 | /* Dont connect anything to FXBUS2 1 and 2. These are shared with | 1989 | * Since only 14 of the 16 EXTINs are used, this is not a big problem. |
1990 | * Center/LFE on the SBLive 5.1. The kX driver only changes the | 1990 | * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture |
1991 | * routing when it detects an SBLive 5.1. | 1991 | * 0 and 3, then the rest of the EXTINs to the corresponding FX capture |
1992 | * | 1992 | * channel. Multitrack recorders will still see the center/lfe output signal |
1993 | * Since only 14 of the 16 EXTINs are used, this is not a big problem. | 1993 | * on the second and third channels. |
1994 | * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture | 1994 | */ |
1995 | * 0 and 3, then the rest of the EXTINs to the corresponding FX capture | 1995 | OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0)); |
1996 | * channel. | 1996 | OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1)); |
1997 | */ | 1997 | OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2)); |
1998 | for (z = 4; z < 14; z++) { | 1998 | OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3)); |
1999 | OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z)); | 1999 | for (z = 4; z < 14; z++) |
2000 | OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z)); | ||
2001 | } else { | ||
2002 | for (z = 0; z < 16; z++) | ||
2003 | OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z)); | ||
2000 | } | 2004 | } |
2005 | |||
2001 | 2006 | ||
2002 | if (gpr > tmp) { | 2007 | if (gpr > tmp) { |
2003 | snd_BUG(); | 2008 | snd_BUG(); |
@@ -2128,7 +2133,6 @@ static int snd_emu10k1_fx8010_info(emu10k1_t *emu, emu10k1_fx8010_info_t *info) | |||
2128 | int res; | 2133 | int res; |
2129 | 2134 | ||
2130 | memset(info, 0, sizeof(info)); | 2135 | memset(info, 0, sizeof(info)); |
2131 | info->card = emu->card_type; | ||
2132 | info->internal_tram_size = emu->fx8010.itram_size; | 2136 | info->internal_tram_size = emu->fx8010.itram_size; |
2133 | info->external_tram_size = emu->fx8010.etram_pages.bytes / 2; | 2137 | info->external_tram_size = emu->fx8010.etram_pages.bytes / 2; |
2134 | fxbus = fxbuses; | 2138 | fxbus = fxbuses; |
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 044663d31aa7..6be82c5fe138 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c | |||
@@ -68,6 +68,7 @@ static int snd_emu10k1_spdif_get_mask(snd_kcontrol_t * kcontrol, | |||
68 | return 0; | 68 | return 0; |
69 | } | 69 | } |
70 | 70 | ||
71 | #if 0 | ||
71 | static int snd_audigy_spdif_output_rate_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) | 72 | static int snd_audigy_spdif_output_rate_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) |
72 | { | 73 | { |
73 | static char *texts[] = {"44100", "48000", "96000"}; | 74 | static char *texts[] = {"44100", "48000", "96000"}; |
@@ -152,6 +153,7 @@ static snd_kcontrol_new_t snd_audigy_spdif_output_rate = | |||
152 | .get = snd_audigy_spdif_output_rate_get, | 153 | .get = snd_audigy_spdif_output_rate_get, |
153 | .put = snd_audigy_spdif_output_rate_put | 154 | .put = snd_audigy_spdif_output_rate_put |
154 | }; | 155 | }; |
156 | #endif | ||
155 | 157 | ||
156 | static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol, | 158 | static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol, |
157 | snd_ctl_elem_value_t * ucontrol) | 159 | snd_ctl_elem_value_t * ucontrol) |
@@ -791,7 +793,7 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu) | |||
791 | NULL | 793 | NULL |
792 | }; | 794 | }; |
793 | 795 | ||
794 | if (!emu->no_ac97) { | 796 | if (emu->card_capabilities->ac97_chip) { |
795 | ac97_bus_t *pbus; | 797 | ac97_bus_t *pbus; |
796 | ac97_template_t ac97; | 798 | ac97_template_t ac97; |
797 | static ac97_bus_ops_t ops = { | 799 | static ac97_bus_ops_t ops = { |
@@ -833,7 +835,7 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu) | |||
833 | for (; *c; c++) | 835 | for (; *c; c++) |
834 | remove_ctl(card, *c); | 836 | remove_ctl(card, *c); |
835 | } else { | 837 | } else { |
836 | if (emu->APS) | 838 | if (emu->card_capabilities->ecard) |
837 | strcpy(emu->card->mixername, "EMU APS"); | 839 | strcpy(emu->card->mixername, "EMU APS"); |
838 | else if (emu->audigy) | 840 | else if (emu->audigy) |
839 | strcpy(emu->card->mixername, "SB Audigy"); | 841 | strcpy(emu->card->mixername, "SB Audigy"); |
@@ -918,7 +920,7 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu) | |||
918 | mix->attn[0] = 0xffff; | 920 | mix->attn[0] = 0xffff; |
919 | } | 921 | } |
920 | 922 | ||
921 | if (! emu->APS) { /* FIXME: APS has these controls? */ | 923 | if (! emu->card_capabilities->ecard) { /* FIXME: APS has these controls? */ |
922 | /* sb live! and audigy */ | 924 | /* sb live! and audigy */ |
923 | if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL) | 925 | if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL) |
924 | return -ENOMEM; | 926 | return -ENOMEM; |
@@ -935,18 +937,20 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu) | |||
935 | return -ENOMEM; | 937 | return -ENOMEM; |
936 | if ((err = snd_ctl_add(card, kctl))) | 938 | if ((err = snd_ctl_add(card, kctl))) |
937 | return err; | 939 | return err; |
940 | #if 0 | ||
938 | if ((kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu)) == NULL) | 941 | if ((kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu)) == NULL) |
939 | return -ENOMEM; | 942 | return -ENOMEM; |
940 | if ((err = snd_ctl_add(card, kctl))) | 943 | if ((err = snd_ctl_add(card, kctl))) |
941 | return err; | 944 | return err; |
942 | } else if (! emu->APS) { | 945 | #endif |
946 | } else if (! emu->card_capabilities->ecard) { | ||
943 | /* sb live! */ | 947 | /* sb live! */ |
944 | if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL) | 948 | if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL) |
945 | return -ENOMEM; | 949 | return -ENOMEM; |
946 | if ((err = snd_ctl_add(card, kctl))) | 950 | if ((err = snd_ctl_add(card, kctl))) |
947 | return err; | 951 | return err; |
948 | } | 952 | } |
949 | if (emu->audigy && emu->revision == 4) { /* P16V */ | 953 | if (emu->card_capabilities->ca0151_chip) { /* P16V */ |
950 | if ((err = snd_p16v_mixer(emu))) | 954 | if ((err = snd_p16v_mixer(emu))) |
951 | return err; | 955 | return err; |
952 | } | 956 | } |
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index d1c2a02c486b..520b99af5f55 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c | |||
@@ -262,7 +262,7 @@ static unsigned int emu10k1_select_interprom(unsigned int pitch_target) | |||
262 | * | 262 | * |
263 | * returns: cache invalidate size in samples | 263 | * returns: cache invalidate size in samples |
264 | */ | 264 | */ |
265 | static int inline emu10k1_ccis(int stereo, int w_16) | 265 | static inline int emu10k1_ccis(int stereo, int w_16) |
266 | { | 266 | { |
267 | if (w_16) { | 267 | if (w_16) { |
268 | return stereo ? 24 : 26; | 268 | return stereo ? 24 : 26; |
@@ -991,9 +991,7 @@ static void snd_emu10k1_pcm_efx_mixer_notify(emu10k1_t *emu, int idx, int activa | |||
991 | 991 | ||
992 | static void snd_emu10k1_pcm_free_substream(snd_pcm_runtime_t *runtime) | 992 | static void snd_emu10k1_pcm_free_substream(snd_pcm_runtime_t *runtime) |
993 | { | 993 | { |
994 | emu10k1_pcm_t *epcm = runtime->private_data; | 994 | kfree(runtime->private_data); |
995 | |||
996 | kfree(epcm); | ||
997 | } | 995 | } |
998 | 996 | ||
999 | static int snd_emu10k1_efx_playback_close(snd_pcm_substream_t * substream) | 997 | static int snd_emu10k1_efx_playback_close(snd_pcm_substream_t * substream) |
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c index d990d5eb45a8..cc22707c91fa 100644 --- a/sound/pci/emu10k1/emuproc.c +++ b/sound/pci/emu10k1/emuproc.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <sound/core.h> | 31 | #include <sound/core.h> |
32 | #include <sound/emu10k1.h> | 32 | #include <sound/emu10k1.h> |
33 | #include "p16v.h" | ||
33 | 34 | ||
34 | static void snd_emu10k1_proc_spdif_status(emu10k1_t * emu, | 35 | static void snd_emu10k1_proc_spdif_status(emu10k1_t * emu, |
35 | snd_info_buffer_t * buffer, | 36 | snd_info_buffer_t * buffer, |
@@ -44,28 +45,34 @@ static void snd_emu10k1_proc_spdif_status(emu10k1_t * emu, | |||
44 | unsigned int status, rate = 0; | 45 | unsigned int status, rate = 0; |
45 | 46 | ||
46 | status = snd_emu10k1_ptr_read(emu, status_reg, 0); | 47 | status = snd_emu10k1_ptr_read(emu, status_reg, 0); |
47 | if (rate_reg > 0) | ||
48 | rate = snd_emu10k1_ptr_read(emu, rate_reg, 0); | ||
49 | 48 | ||
50 | snd_iprintf(buffer, "\n%s\n", title); | 49 | snd_iprintf(buffer, "\n%s\n", title); |
51 | 50 | ||
52 | snd_iprintf(buffer, "Professional Mode : %s\n", (status & SPCS_PROFESSIONAL) ? "yes" : "no"); | 51 | if (status != 0xffffffff) { |
53 | snd_iprintf(buffer, "Not Audio Data : %s\n", (status & SPCS_NOTAUDIODATA) ? "yes" : "no"); | 52 | snd_iprintf(buffer, "Professional Mode : %s\n", (status & SPCS_PROFESSIONAL) ? "yes" : "no"); |
54 | snd_iprintf(buffer, "Copyright : %s\n", (status & SPCS_COPYRIGHT) ? "yes" : "no"); | 53 | snd_iprintf(buffer, "Not Audio Data : %s\n", (status & SPCS_NOTAUDIODATA) ? "yes" : "no"); |
55 | snd_iprintf(buffer, "Emphasis : %s\n", emphasis[(status & SPCS_EMPHASISMASK) >> 3]); | 54 | snd_iprintf(buffer, "Copyright : %s\n", (status & SPCS_COPYRIGHT) ? "yes" : "no"); |
56 | snd_iprintf(buffer, "Mode : %i\n", (status & SPCS_MODEMASK) >> 6); | 55 | snd_iprintf(buffer, "Emphasis : %s\n", emphasis[(status & SPCS_EMPHASISMASK) >> 3]); |
57 | snd_iprintf(buffer, "Category Code : 0x%x\n", (status & SPCS_CATEGORYCODEMASK) >> 8); | 56 | snd_iprintf(buffer, "Mode : %i\n", (status & SPCS_MODEMASK) >> 6); |
58 | snd_iprintf(buffer, "Generation Status : %s\n", status & SPCS_GENERATIONSTATUS ? "original" : "copy"); | 57 | snd_iprintf(buffer, "Category Code : 0x%x\n", (status & SPCS_CATEGORYCODEMASK) >> 8); |
59 | snd_iprintf(buffer, "Source Mask : %i\n", (status & SPCS_SOURCENUMMASK) >> 16); | 58 | snd_iprintf(buffer, "Generation Status : %s\n", status & SPCS_GENERATIONSTATUS ? "original" : "copy"); |
60 | snd_iprintf(buffer, "Channel Number : %s\n", channel[(status & SPCS_CHANNELNUMMASK) >> 20]); | 59 | snd_iprintf(buffer, "Source Mask : %i\n", (status & SPCS_SOURCENUMMASK) >> 16); |
61 | snd_iprintf(buffer, "Sample Rate : %iHz\n", samplerate[(status & SPCS_SAMPLERATEMASK) >> 24]); | 60 | snd_iprintf(buffer, "Channel Number : %s\n", channel[(status & SPCS_CHANNELNUMMASK) >> 20]); |
62 | snd_iprintf(buffer, "Clock Accuracy : %s\n", clkaccy[(status & SPCS_CLKACCYMASK) >> 28]); | 61 | snd_iprintf(buffer, "Sample Rate : %iHz\n", samplerate[(status & SPCS_SAMPLERATEMASK) >> 24]); |
63 | 62 | snd_iprintf(buffer, "Clock Accuracy : %s\n", clkaccy[(status & SPCS_CLKACCYMASK) >> 28]); | |
64 | if (rate_reg > 0) { | 63 | |
65 | snd_iprintf(buffer, "S/PDIF Locked : %s\n", rate & SRCS_SPDIFLOCKED ? "on" : "off"); | 64 | if (rate_reg > 0) { |
66 | snd_iprintf(buffer, "Rate Locked : %s\n", rate & SRCS_RATELOCKED ? "on" : "off"); | 65 | rate = snd_emu10k1_ptr_read(emu, rate_reg, 0); |
67 | snd_iprintf(buffer, "Estimated Sample Rate : 0x%x\n", rate & SRCS_ESTSAMPLERATE); | 66 | snd_iprintf(buffer, "S/PDIF Valid : %s\n", rate & SRCS_SPDIFVALID ? "on" : "off"); |
67 | snd_iprintf(buffer, "S/PDIF Locked : %s\n", rate & SRCS_SPDIFLOCKED ? "on" : "off"); | ||
68 | snd_iprintf(buffer, "Rate Locked : %s\n", rate & SRCS_RATELOCKED ? "on" : "off"); | ||
69 | /* From ((Rate * 48000 ) / 262144); */ | ||
70 | snd_iprintf(buffer, "Estimated Sample Rate : %d\n", ((rate & 0xFFFFF ) * 375) >> 11); | ||
71 | } | ||
72 | } else { | ||
73 | snd_iprintf(buffer, "No signal detected.\n"); | ||
68 | } | 74 | } |
75 | |||
69 | } | 76 | } |
70 | 77 | ||
71 | static void snd_emu10k1_proc_read(snd_info_entry_t *entry, | 78 | static void snd_emu10k1_proc_read(snd_info_entry_t *entry, |
@@ -182,7 +189,7 @@ static void snd_emu10k1_proc_read(snd_info_entry_t *entry, | |||
182 | 189 | ||
183 | snd_iprintf(buffer, "EMU10K1\n\n"); | 190 | snd_iprintf(buffer, "EMU10K1\n\n"); |
184 | snd_iprintf(buffer, "Card : %s\n", | 191 | snd_iprintf(buffer, "Card : %s\n", |
185 | emu->audigy ? "Audigy" : (emu->APS ? "EMU APS" : "Creative")); | 192 | emu->audigy ? "Audigy" : (emu->card_capabilities->ecard ? "EMU APS" : "Creative")); |
186 | snd_iprintf(buffer, "Internal TRAM (words) : 0x%x\n", emu->fx8010.itram_size); | 193 | snd_iprintf(buffer, "Internal TRAM (words) : 0x%x\n", emu->fx8010.itram_size); |
187 | snd_iprintf(buffer, "External TRAM (words) : 0x%x\n", (int)emu->fx8010.etram_pages.bytes / 2); | 194 | snd_iprintf(buffer, "External TRAM (words) : 0x%x\n", (int)emu->fx8010.etram_pages.bytes / 2); |
188 | snd_iprintf(buffer, "\n"); | 195 | snd_iprintf(buffer, "\n"); |
@@ -223,15 +230,35 @@ static void snd_emu10k1_proc_read(snd_info_entry_t *entry, | |||
223 | snd_iprintf(buffer, "\nAll FX Outputs :\n"); | 230 | snd_iprintf(buffer, "\nAll FX Outputs :\n"); |
224 | for (idx = 0; idx < (emu->audigy ? 64 : 32); idx++) | 231 | for (idx = 0; idx < (emu->audigy ? 64 : 32); idx++) |
225 | snd_iprintf(buffer, " Output %02i [%s]\n", idx, outputs[idx]); | 232 | snd_iprintf(buffer, " Output %02i [%s]\n", idx, outputs[idx]); |
226 | snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 0", SPCS0, -1); | 233 | } |
227 | snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 1", SPCS1, -1); | 234 | |
228 | snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 2/3", SPCS2, -1); | 235 | static void snd_emu10k1_proc_spdif_read(snd_info_entry_t *entry, |
229 | snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF", CDCS, CDSRCS); | 236 | snd_info_buffer_t * buffer) |
230 | snd_emu10k1_proc_spdif_status(emu, buffer, "General purpose S/PDIF", GPSCS, GPSRCS); | 237 | { |
238 | emu10k1_t *emu = entry->private_data; | ||
239 | snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF In", CDCS, CDSRCS); | ||
240 | snd_emu10k1_proc_spdif_status(emu, buffer, "Optical or Coax S/PDIF In", GPSCS, GPSRCS); | ||
241 | #if 0 | ||
231 | val = snd_emu10k1_ptr_read(emu, ZVSRCS, 0); | 242 | val = snd_emu10k1_ptr_read(emu, ZVSRCS, 0); |
232 | snd_iprintf(buffer, "\nZoomed Video\n"); | 243 | snd_iprintf(buffer, "\nZoomed Video\n"); |
233 | snd_iprintf(buffer, "Rate Locked : %s\n", val & SRCS_RATELOCKED ? "on" : "off"); | 244 | snd_iprintf(buffer, "Rate Locked : %s\n", val & SRCS_RATELOCKED ? "on" : "off"); |
234 | snd_iprintf(buffer, "Estimated Sample Rate : 0x%x\n", val & SRCS_ESTSAMPLERATE); | 245 | snd_iprintf(buffer, "Estimated Sample Rate : 0x%x\n", val & SRCS_ESTSAMPLERATE); |
246 | #endif | ||
247 | } | ||
248 | |||
249 | static void snd_emu10k1_proc_rates_read(snd_info_entry_t *entry, | ||
250 | snd_info_buffer_t * buffer) | ||
251 | { | ||
252 | static int samplerate[8] = { 44100, 48000, 96000, 192000, 4, 5, 6, 7 }; | ||
253 | emu10k1_t *emu = entry->private_data; | ||
254 | unsigned int val, tmp, n; | ||
255 | val = snd_emu10k1_ptr20_read(emu, CAPTURE_RATE_STATUS, 0); | ||
256 | tmp = (val >> 16) & 0x8; | ||
257 | for (n=0;n<4;n++) { | ||
258 | tmp = val >> (16 + (n*4)); | ||
259 | if (tmp & 0x8) snd_iprintf(buffer, "Channel %d: Rate=%d\n", n, samplerate[tmp & 0x7]); | ||
260 | else snd_iprintf(buffer, "Channel %d: No input\n", n); | ||
261 | } | ||
235 | } | 262 | } |
236 | 263 | ||
237 | static void snd_emu10k1_proc_acode_read(snd_info_entry_t *entry, | 264 | static void snd_emu10k1_proc_acode_read(snd_info_entry_t *entry, |
@@ -500,32 +527,46 @@ int __devinit snd_emu10k1_proc_init(emu10k1_t * emu) | |||
500 | snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_io_reg_read); | 527 | snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_io_reg_read); |
501 | entry->c.text.write_size = 64; | 528 | entry->c.text.write_size = 64; |
502 | entry->c.text.write = snd_emu_proc_io_reg_write; | 529 | entry->c.text.write = snd_emu_proc_io_reg_write; |
530 | entry->mode |= S_IWUSR; | ||
503 | } | 531 | } |
504 | if (! snd_card_proc_new(emu->card, "ptr_regs00a", &entry)) { | 532 | if (! snd_card_proc_new(emu->card, "ptr_regs00a", &entry)) { |
505 | snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read00a); | 533 | snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read00a); |
506 | entry->c.text.write_size = 64; | 534 | entry->c.text.write_size = 64; |
507 | entry->c.text.write = snd_emu_proc_ptr_reg_write00; | 535 | entry->c.text.write = snd_emu_proc_ptr_reg_write00; |
536 | entry->mode |= S_IWUSR; | ||
508 | } | 537 | } |
509 | if (! snd_card_proc_new(emu->card, "ptr_regs00b", &entry)) { | 538 | if (! snd_card_proc_new(emu->card, "ptr_regs00b", &entry)) { |
510 | snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read00b); | 539 | snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read00b); |
511 | entry->c.text.write_size = 64; | 540 | entry->c.text.write_size = 64; |
512 | entry->c.text.write = snd_emu_proc_ptr_reg_write00; | 541 | entry->c.text.write = snd_emu_proc_ptr_reg_write00; |
542 | entry->mode |= S_IWUSR; | ||
513 | } | 543 | } |
514 | if (! snd_card_proc_new(emu->card, "ptr_regs20a", &entry)) { | 544 | if (! snd_card_proc_new(emu->card, "ptr_regs20a", &entry)) { |
515 | snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20a); | 545 | snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20a); |
516 | entry->c.text.write_size = 64; | 546 | entry->c.text.write_size = 64; |
517 | entry->c.text.write = snd_emu_proc_ptr_reg_write20; | 547 | entry->c.text.write = snd_emu_proc_ptr_reg_write20; |
548 | entry->mode |= S_IWUSR; | ||
518 | } | 549 | } |
519 | if (! snd_card_proc_new(emu->card, "ptr_regs20b", &entry)) { | 550 | if (! snd_card_proc_new(emu->card, "ptr_regs20b", &entry)) { |
520 | snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20b); | 551 | snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20b); |
521 | entry->c.text.write_size = 64; | 552 | entry->c.text.write_size = 64; |
522 | entry->c.text.write = snd_emu_proc_ptr_reg_write20; | 553 | entry->c.text.write = snd_emu_proc_ptr_reg_write20; |
554 | entry->mode |= S_IWUSR; | ||
523 | } | 555 | } |
524 | #endif | 556 | #endif |
525 | 557 | ||
526 | if (! snd_card_proc_new(emu->card, "emu10k1", &entry)) | 558 | if (! snd_card_proc_new(emu->card, "emu10k1", &entry)) |
527 | snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_read); | 559 | snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_read); |
528 | 560 | ||
561 | if (emu->card_capabilities->emu10k2_chip) { | ||
562 | if (! snd_card_proc_new(emu->card, "spdif-in", &entry)) | ||
563 | snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_spdif_read); | ||
564 | } | ||
565 | if (emu->card_capabilities->ca0151_chip) { | ||
566 | if (! snd_card_proc_new(emu->card, "capture-rates", &entry)) | ||
567 | snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_rates_read); | ||
568 | } | ||
569 | |||
529 | if (! snd_card_proc_new(emu->card, "voices", &entry)) | 570 | if (! snd_card_proc_new(emu->card, "voices", &entry)) |
530 | snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_voices_read); | 571 | snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_voices_read); |
531 | 572 | ||
diff --git a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c index b81a7cafff39..cd8460d56752 100644 --- a/sound/pci/emu10k1/irq.c +++ b/sound/pci/emu10k1/irq.c | |||
@@ -37,7 +37,7 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
37 | int handled = 0; | 37 | int handled = 0; |
38 | 38 | ||
39 | while ((status = inl(emu->port + IPR)) != 0) { | 39 | while ((status = inl(emu->port + IPR)) != 0) { |
40 | // printk("irq - status = 0x%x\n", status); | 40 | //printk("emu10k1 irq - status = 0x%x\n", status); |
41 | orig_status = status; | 41 | orig_status = status; |
42 | handled = 1; | 42 | handled = 1; |
43 | if (status & IPR_PCIERROR) { | 43 | if (status & IPR_PCIERROR) { |
@@ -147,9 +147,36 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
147 | snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE); | 147 | snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE); |
148 | status &= ~IPR_FXDSP; | 148 | status &= ~IPR_FXDSP; |
149 | } | 149 | } |
150 | if (status & IPR_P16V) { | ||
151 | while ((status2 = inl(emu->port + IPR2)) != 0) { | ||
152 | u32 mask = INTE2_PLAYBACK_CH_0_LOOP; /* Full Loop */ | ||
153 | emu10k1_voice_t *pvoice = &(emu->p16v_voices[0]); | ||
154 | emu10k1_voice_t *cvoice = &(emu->p16v_capture_voice); | ||
155 | |||
156 | //printk(KERN_INFO "status2=0x%x\n", status2); | ||
157 | orig_status2 = status2; | ||
158 | if(status2 & mask) { | ||
159 | if(pvoice->use) { | ||
160 | snd_pcm_period_elapsed(pvoice->epcm->substream); | ||
161 | } else { | ||
162 | snd_printk(KERN_ERR "p16v: status: 0x%08x, mask=0x%08x, pvoice=%p, use=%d\n", status2, mask, pvoice, pvoice->use); | ||
163 | } | ||
164 | } | ||
165 | if(status2 & 0x110000) { | ||
166 | //printk(KERN_INFO "capture int found\n"); | ||
167 | if(cvoice->use) { | ||
168 | //printk(KERN_INFO "capture period_elapsed\n"); | ||
169 | snd_pcm_period_elapsed(cvoice->epcm->substream); | ||
170 | } | ||
171 | } | ||
172 | outl(orig_status2, emu->port + IPR2); /* ack all */ | ||
173 | } | ||
174 | status &= ~IPR_P16V; | ||
175 | } | ||
176 | |||
150 | if (status) { | 177 | if (status) { |
151 | unsigned int bits; | 178 | unsigned int bits; |
152 | //snd_printk(KERN_ERR "emu10k1: unhandled interrupt: 0x%08x\n", status); | 179 | snd_printk(KERN_ERR "emu10k1: unhandled interrupt: 0x%08x\n", status); |
153 | //make sure any interrupts we don't handle are disabled: | 180 | //make sure any interrupts we don't handle are disabled: |
154 | bits = INTE_FXDSPENABLE | | 181 | bits = INTE_FXDSPENABLE | |
155 | INTE_PCIERRORENABLE | | 182 | INTE_PCIERRORENABLE | |
@@ -170,20 +197,5 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
170 | } | 197 | } |
171 | outl(orig_status, emu->port + IPR); /* ack all */ | 198 | outl(orig_status, emu->port + IPR); /* ack all */ |
172 | } | 199 | } |
173 | if (emu->audigy && emu->revision == 4) { /* P16V */ | ||
174 | while ((status2 = inl(emu->port + IPR2)) != 0) { | ||
175 | u32 mask = INTE2_PLAYBACK_CH_0_LOOP; /* Full Loop */ | ||
176 | emu10k1_voice_t *pvoice = &(emu->p16v_voices[0]); | ||
177 | orig_status2 = status2; | ||
178 | if(status2 & mask) { | ||
179 | if(pvoice->use) { | ||
180 | snd_pcm_period_elapsed(pvoice->epcm->substream); | ||
181 | } else { | ||
182 | snd_printk(KERN_ERR "p16v: status: 0x%08x, mask=0x%08x, pvoice=%p, use=%d\n", status2, mask, pvoice, pvoice->use); | ||
183 | } | ||
184 | } | ||
185 | outl(orig_status2, emu->port + IPR2); /* ack all */ | ||
186 | } | ||
187 | } | ||
188 | return IRQ_RETVAL(handled); | 200 | return IRQ_RETVAL(handled); |
189 | } | 201 | } |
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index d03cb2fefc9e..98f980189892 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk> | 2 | * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk> |
3 | * Driver p16v chips | 3 | * Driver p16v chips |
4 | * Version: 0.22 | 4 | * Version: 0.25 |
5 | * | 5 | * |
6 | * FEATURES currently supported: | 6 | * FEATURES currently supported: |
7 | * Output fixed at S32_LE, 2 channel to hw:0,0 | 7 | * Output fixed at S32_LE, 2 channel to hw:0,0 |
@@ -41,7 +41,15 @@ | |||
41 | * Integrated with snd-emu10k1 driver. | 41 | * Integrated with snd-emu10k1 driver. |
42 | * 0.22 | 42 | * 0.22 |
43 | * Removed #if 0 ... #endif | 43 | * Removed #if 0 ... #endif |
44 | * | 44 | * 0.23 |
45 | * Implement different capture rates. | ||
46 | * 0.24 | ||
47 | * Implement different capture source channels. | ||
48 | * e.g. When HD Capture source is set to SPDIF, | ||
49 | * setting HD Capture channel to 0 captures from CDROM digital input. | ||
50 | * setting HD Capture channel to 1 captures from SPDIF in. | ||
51 | * 0.25 | ||
52 | * Include capture buffer sizes. | ||
45 | * | 53 | * |
46 | * BUGS: | 54 | * BUGS: |
47 | * Some stability problems when unloading the snd-p16v kernel module. | 55 | * Some stability problems when unloading the snd-p16v kernel module. |
@@ -119,22 +127,41 @@ static snd_pcm_hardware_t snd_p16v_playback_hw = { | |||
119 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 127 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
120 | SNDRV_PCM_INFO_MMAP_VALID), | 128 | SNDRV_PCM_INFO_MMAP_VALID), |
121 | .formats = SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */ | 129 | .formats = SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */ |
122 | .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 , | 130 | .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100, |
123 | .rate_min = 48000, | 131 | .rate_min = 44100, |
124 | .rate_max = 192000, | 132 | .rate_max = 192000, |
125 | .channels_min = 8, | 133 | .channels_min = 8, |
126 | .channels_max = 8, | 134 | .channels_max = 8, |
127 | .buffer_bytes_max = (32*1024), | 135 | .buffer_bytes_max = ((65536 - 64) * 8), |
128 | .period_bytes_min = 64, | 136 | .period_bytes_min = 64, |
129 | .period_bytes_max = (16*1024), | 137 | .period_bytes_max = (65536 - 64), |
130 | .periods_min = 2, | 138 | .periods_min = 2, |
131 | .periods_max = 8, | 139 | .periods_max = 8, |
132 | .fifo_size = 0, | 140 | .fifo_size = 0, |
133 | }; | 141 | }; |
134 | 142 | ||
143 | static snd_pcm_hardware_t snd_p16v_capture_hw = { | ||
144 | .info = (SNDRV_PCM_INFO_MMAP | | ||
145 | SNDRV_PCM_INFO_INTERLEAVED | | ||
146 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
147 | SNDRV_PCM_INFO_MMAP_VALID), | ||
148 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | ||
149 | .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100, | ||
150 | .rate_min = 44100, | ||
151 | .rate_max = 192000, | ||
152 | .channels_min = 2, | ||
153 | .channels_max = 2, | ||
154 | .buffer_bytes_max = (65536 - 64), | ||
155 | .period_bytes_min = 64, | ||
156 | .period_bytes_max = (65536 - 128) >> 1, /* size has to be N*64 bytes */ | ||
157 | .periods_min = 2, | ||
158 | .periods_max = 2, | ||
159 | .fifo_size = 0, | ||
160 | }; | ||
161 | |||
135 | static void snd_p16v_pcm_free_substream(snd_pcm_runtime_t *runtime) | 162 | static void snd_p16v_pcm_free_substream(snd_pcm_runtime_t *runtime) |
136 | { | 163 | { |
137 | snd_pcm_t *epcm = runtime->private_data; | 164 | emu10k1_pcm_t *epcm = runtime->private_data; |
138 | 165 | ||
139 | if (epcm) { | 166 | if (epcm) { |
140 | //snd_printk("epcm free: %p\n", epcm); | 167 | //snd_printk("epcm free: %p\n", epcm); |
@@ -178,15 +205,63 @@ static int snd_p16v_pcm_open_playback_channel(snd_pcm_substream_t *substream, in | |||
178 | 205 | ||
179 | return 0; | 206 | return 0; |
180 | } | 207 | } |
208 | /* open_capture callback */ | ||
209 | static int snd_p16v_pcm_open_capture_channel(snd_pcm_substream_t *substream, int channel_id) | ||
210 | { | ||
211 | emu10k1_t *emu = snd_pcm_substream_chip(substream); | ||
212 | emu10k1_voice_t *channel = &(emu->p16v_capture_voice); | ||
213 | emu10k1_pcm_t *epcm; | ||
214 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
215 | int err; | ||
216 | |||
217 | epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL); | ||
218 | //snd_printk("epcm kcalloc: %p\n", epcm); | ||
219 | |||
220 | if (epcm == NULL) | ||
221 | return -ENOMEM; | ||
222 | epcm->emu = emu; | ||
223 | epcm->substream = substream; | ||
224 | //snd_printk("epcm device=%d, channel_id=%d\n", substream->pcm->device, channel_id); | ||
225 | |||
226 | runtime->private_data = epcm; | ||
227 | runtime->private_free = snd_p16v_pcm_free_substream; | ||
228 | |||
229 | runtime->hw = snd_p16v_capture_hw; | ||
230 | |||
231 | channel->emu = emu; | ||
232 | channel->number = channel_id; | ||
233 | |||
234 | channel->use=1; | ||
235 | //snd_printk("p16v: open channel_id=%d, channel=%p, use=0x%x\n", channel_id, channel, channel->use); | ||
236 | //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel); | ||
237 | //channel->interrupt = snd_p16v_pcm_channel_interrupt; | ||
238 | channel->epcm=epcm; | ||
239 | if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) | ||
240 | return err; | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
181 | 245 | ||
182 | /* close callback */ | 246 | /* close callback */ |
183 | static int snd_p16v_pcm_close_playback(snd_pcm_substream_t *substream) | 247 | static int snd_p16v_pcm_close_playback(snd_pcm_substream_t *substream) |
184 | { | 248 | { |
185 | emu10k1_t *emu = snd_pcm_substream_chip(substream); | 249 | emu10k1_t *emu = snd_pcm_substream_chip(substream); |
186 | //snd_pcm_runtime_t *runtime = substream->runtime; | 250 | //snd_pcm_runtime_t *runtime = substream->runtime; |
187 | //emu10k1_pcm_t *epcm = runtime->private_data; | 251 | //emu10k1_pcm_t *epcm = runtime->private_data; |
188 | emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use=0; | 252 | emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use=0; |
189 | /* FIXME: maybe zero others */ | 253 | /* FIXME: maybe zero others */ |
254 | return 0; | ||
255 | } | ||
256 | |||
257 | /* close callback */ | ||
258 | static int snd_p16v_pcm_close_capture(snd_pcm_substream_t *substream) | ||
259 | { | ||
260 | emu10k1_t *emu = snd_pcm_substream_chip(substream); | ||
261 | //snd_pcm_runtime_t *runtime = substream->runtime; | ||
262 | //emu10k1_pcm_t *epcm = runtime->private_data; | ||
263 | emu->p16v_capture_voice.use=0; | ||
264 | /* FIXME: maybe zero others */ | ||
190 | return 0; | 265 | return 0; |
191 | } | 266 | } |
192 | 267 | ||
@@ -195,36 +270,55 @@ static int snd_p16v_pcm_open_playback_front(snd_pcm_substream_t *substream) | |||
195 | return snd_p16v_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL); | 270 | return snd_p16v_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL); |
196 | } | 271 | } |
197 | 272 | ||
273 | static int snd_p16v_pcm_open_capture(snd_pcm_substream_t *substream) | ||
274 | { | ||
275 | // Only using channel 0 for now, but the card has 2 channels. | ||
276 | return snd_p16v_pcm_open_capture_channel(substream, 0); | ||
277 | } | ||
278 | |||
198 | /* hw_params callback */ | 279 | /* hw_params callback */ |
199 | static int snd_p16v_pcm_hw_params_playback(snd_pcm_substream_t *substream, | 280 | static int snd_p16v_pcm_hw_params_playback(snd_pcm_substream_t *substream, |
200 | snd_pcm_hw_params_t * hw_params) | 281 | snd_pcm_hw_params_t * hw_params) |
201 | { | 282 | { |
202 | int result; | 283 | int result; |
203 | //snd_printk("hw_params alloc: substream=%p\n", substream); | ||
204 | result = snd_pcm_lib_malloc_pages(substream, | 284 | result = snd_pcm_lib_malloc_pages(substream, |
205 | params_buffer_bytes(hw_params)); | 285 | params_buffer_bytes(hw_params)); |
206 | //snd_printk("hw_params alloc: result=%d\n", result); | ||
207 | //dump_stack(); | ||
208 | return result; | 286 | return result; |
209 | } | 287 | } |
210 | 288 | ||
289 | /* hw_params callback */ | ||
290 | static int snd_p16v_pcm_hw_params_capture(snd_pcm_substream_t *substream, | ||
291 | snd_pcm_hw_params_t * hw_params) | ||
292 | { | ||
293 | int result; | ||
294 | result = snd_pcm_lib_malloc_pages(substream, | ||
295 | params_buffer_bytes(hw_params)); | ||
296 | return result; | ||
297 | } | ||
298 | |||
299 | |||
211 | /* hw_free callback */ | 300 | /* hw_free callback */ |
212 | static int snd_p16v_pcm_hw_free_playback(snd_pcm_substream_t *substream) | 301 | static int snd_p16v_pcm_hw_free_playback(snd_pcm_substream_t *substream) |
213 | { | 302 | { |
214 | int result; | 303 | int result; |
215 | //snd_printk("hw_params free: substream=%p\n", substream); | ||
216 | result = snd_pcm_lib_free_pages(substream); | 304 | result = snd_pcm_lib_free_pages(substream); |
217 | //snd_printk("hw_params free: result=%d\n", result); | ||
218 | //dump_stack(); | ||
219 | return result; | 305 | return result; |
220 | } | 306 | } |
221 | 307 | ||
308 | /* hw_free callback */ | ||
309 | static int snd_p16v_pcm_hw_free_capture(snd_pcm_substream_t *substream) | ||
310 | { | ||
311 | int result; | ||
312 | result = snd_pcm_lib_free_pages(substream); | ||
313 | return result; | ||
314 | } | ||
315 | |||
316 | |||
222 | /* prepare playback callback */ | 317 | /* prepare playback callback */ |
223 | static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream) | 318 | static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream) |
224 | { | 319 | { |
225 | emu10k1_t *emu = snd_pcm_substream_chip(substream); | 320 | emu10k1_t *emu = snd_pcm_substream_chip(substream); |
226 | snd_pcm_runtime_t *runtime = substream->runtime; | 321 | snd_pcm_runtime_t *runtime = substream->runtime; |
227 | //emu10k1_pcm_t *epcm = runtime->private_data; | ||
228 | int channel = substream->pcm->device - emu->p16v_device_offset; | 322 | int channel = substream->pcm->device - emu->p16v_device_offset; |
229 | u32 *table_base = (u32 *)(emu->p16v_buffer.area+(8*16*channel)); | 323 | u32 *table_base = (u32 *)(emu->p16v_buffer.area+(8*16*channel)); |
230 | u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size); | 324 | u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size); |
@@ -237,23 +331,21 @@ static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream) | |||
237 | tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel); | 331 | tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel); |
238 | switch (runtime->rate) { | 332 | switch (runtime->rate) { |
239 | case 44100: | 333 | case 44100: |
240 | snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x8000); /* FIXME: This will change the capture rate as well! */ | 334 | snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x8080); |
241 | break; | ||
242 | case 48000: | ||
243 | snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x0000); /* FIXME: This will change the capture rate as well! */ | ||
244 | break; | 335 | break; |
245 | case 96000: | 336 | case 96000: |
246 | snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x4000); /* FIXME: This will change the capture rate as well! */ | 337 | snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x4040); |
247 | break; | 338 | break; |
248 | case 192000: | 339 | case 192000: |
249 | snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x2000); /* FIXME: This will change the capture rate as well! */ | 340 | snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x2020); |
250 | break; | 341 | break; |
342 | case 48000: | ||
251 | default: | 343 | default: |
252 | snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, 0x0000); /* FIXME: This will change the capture rate as well! */ | 344 | snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x0000); |
253 | break; | 345 | break; |
254 | } | 346 | } |
255 | /* FIXME: Check emu->buffer.size before actually writing to it. */ | 347 | /* FIXME: Check emu->buffer.size before actually writing to it. */ |
256 | for(i=0; i < runtime->periods; i++) { | 348 | for(i=0; i < runtime->periods; i++) { |
257 | table_base[i*2]=runtime->dma_addr+(i*period_size_bytes); | 349 | table_base[i*2]=runtime->dma_addr+(i*period_size_bytes); |
258 | table_base[(i*2)+1]=period_size_bytes<<16; | 350 | table_base[(i*2)+1]=period_size_bytes<<16; |
259 | } | 351 | } |
@@ -262,7 +354,8 @@ static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream) | |||
262 | snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19); | 354 | snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19); |
263 | snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_PTR, channel, 0); | 355 | snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_PTR, channel, 0); |
264 | snd_emu10k1_ptr20_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr); | 356 | snd_emu10k1_ptr20_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr); |
265 | snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes | 357 | //snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes |
358 | snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, 0); // buffer size in bytes | ||
266 | snd_emu10k1_ptr20_write(emu, PLAYBACK_POINTER, channel, 0); | 359 | snd_emu10k1_ptr20_write(emu, PLAYBACK_POINTER, channel, 0); |
267 | snd_emu10k1_ptr20_write(emu, 0x07, channel, 0x0); | 360 | snd_emu10k1_ptr20_write(emu, 0x07, channel, 0x0); |
268 | snd_emu10k1_ptr20_write(emu, 0x08, channel, 0); | 361 | snd_emu10k1_ptr20_write(emu, 0x08, channel, 0); |
@@ -270,6 +363,41 @@ static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream) | |||
270 | return 0; | 363 | return 0; |
271 | } | 364 | } |
272 | 365 | ||
366 | /* prepare capture callback */ | ||
367 | static int snd_p16v_pcm_prepare_capture(snd_pcm_substream_t *substream) | ||
368 | { | ||
369 | emu10k1_t *emu = snd_pcm_substream_chip(substream); | ||
370 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
371 | int channel = substream->pcm->device - emu->p16v_device_offset; | ||
372 | u32 tmp; | ||
373 | //printk("prepare capture:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, frames_to_bytes(runtime, 1)); | ||
374 | tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel); | ||
375 | switch (runtime->rate) { | ||
376 | case 44100: | ||
377 | snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0800); | ||
378 | break; | ||
379 | case 96000: | ||
380 | snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0400); | ||
381 | break; | ||
382 | case 192000: | ||
383 | snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0200); | ||
384 | break; | ||
385 | case 48000: | ||
386 | default: | ||
387 | snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0000); | ||
388 | break; | ||
389 | } | ||
390 | /* FIXME: Check emu->buffer.size before actually writing to it. */ | ||
391 | snd_emu10k1_ptr20_write(emu, 0x13, channel, 0); | ||
392 | snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr); | ||
393 | snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes | ||
394 | snd_emu10k1_ptr20_write(emu, CAPTURE_POINTER, channel, 0); | ||
395 | //snd_emu10k1_ptr20_write(emu, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC or Line in */ | ||
396 | //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel)); | ||
397 | |||
398 | return 0; | ||
399 | } | ||
400 | |||
273 | static void snd_p16v_intr_enable(emu10k1_t *emu, unsigned int intrenb) | 401 | static void snd_p16v_intr_enable(emu10k1_t *emu, unsigned int intrenb) |
274 | { | 402 | { |
275 | unsigned long flags; | 403 | unsigned long flags; |
@@ -345,6 +473,36 @@ static int snd_p16v_pcm_trigger_playback(snd_pcm_substream_t *substream, | |||
345 | return result; | 473 | return result; |
346 | } | 474 | } |
347 | 475 | ||
476 | /* trigger_capture callback */ | ||
477 | static int snd_p16v_pcm_trigger_capture(snd_pcm_substream_t *substream, | ||
478 | int cmd) | ||
479 | { | ||
480 | emu10k1_t *emu = snd_pcm_substream_chip(substream); | ||
481 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
482 | emu10k1_pcm_t *epcm = runtime->private_data; | ||
483 | int channel = 0; | ||
484 | int result = 0; | ||
485 | u32 inte = INTE2_CAPTURE_CH_0_LOOP | INTE2_CAPTURE_CH_0_HALF_LOOP; | ||
486 | |||
487 | switch (cmd) { | ||
488 | case SNDRV_PCM_TRIGGER_START: | ||
489 | snd_p16v_intr_enable(emu, inte); | ||
490 | snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel)); | ||
491 | epcm->running = 1; | ||
492 | break; | ||
493 | case SNDRV_PCM_TRIGGER_STOP: | ||
494 | snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel)); | ||
495 | snd_p16v_intr_disable(emu, inte); | ||
496 | //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) & ~(0x110000<<channel)); | ||
497 | epcm->running = 0; | ||
498 | break; | ||
499 | default: | ||
500 | result = -EINVAL; | ||
501 | break; | ||
502 | } | ||
503 | return result; | ||
504 | } | ||
505 | |||
348 | /* pointer_playback callback */ | 506 | /* pointer_playback callback */ |
349 | static snd_pcm_uframes_t | 507 | static snd_pcm_uframes_t |
350 | snd_p16v_pcm_pointer_playback(snd_pcm_substream_t *substream) | 508 | snd_p16v_pcm_pointer_playback(snd_pcm_substream_t *substream) |
@@ -370,6 +528,31 @@ snd_p16v_pcm_pointer_playback(snd_pcm_substream_t *substream) | |||
370 | return ptr; | 528 | return ptr; |
371 | } | 529 | } |
372 | 530 | ||
531 | /* pointer_capture callback */ | ||
532 | static snd_pcm_uframes_t | ||
533 | snd_p16v_pcm_pointer_capture(snd_pcm_substream_t *substream) | ||
534 | { | ||
535 | emu10k1_t *emu = snd_pcm_substream_chip(substream); | ||
536 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
537 | emu10k1_pcm_t *epcm = runtime->private_data; | ||
538 | snd_pcm_uframes_t ptr, ptr1, ptr2 = 0; | ||
539 | int channel = 0; | ||
540 | |||
541 | if (!epcm->running) | ||
542 | return 0; | ||
543 | |||
544 | ptr1 = snd_emu10k1_ptr20_read(emu, CAPTURE_POINTER, channel); | ||
545 | ptr2 = bytes_to_frames(runtime, ptr1); | ||
546 | ptr=ptr2; | ||
547 | if (ptr >= runtime->buffer_size) { | ||
548 | ptr -= runtime->buffer_size; | ||
549 | printk("buffer capture limited!\n"); | ||
550 | } | ||
551 | //printk("ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", ptr1, ptr2, ptr, (int)runtime->buffer_size, (int)runtime->period_size, (int)runtime->frame_bits, (int)runtime->rate); | ||
552 | |||
553 | return ptr; | ||
554 | } | ||
555 | |||
373 | /* operators */ | 556 | /* operators */ |
374 | static snd_pcm_ops_t snd_p16v_playback_front_ops = { | 557 | static snd_pcm_ops_t snd_p16v_playback_front_ops = { |
375 | .open = snd_p16v_pcm_open_playback_front, | 558 | .open = snd_p16v_pcm_open_playback_front, |
@@ -382,6 +565,18 @@ static snd_pcm_ops_t snd_p16v_playback_front_ops = { | |||
382 | .pointer = snd_p16v_pcm_pointer_playback, | 565 | .pointer = snd_p16v_pcm_pointer_playback, |
383 | }; | 566 | }; |
384 | 567 | ||
568 | static snd_pcm_ops_t snd_p16v_capture_ops = { | ||
569 | .open = snd_p16v_pcm_open_capture, | ||
570 | .close = snd_p16v_pcm_close_capture, | ||
571 | .ioctl = snd_pcm_lib_ioctl, | ||
572 | .hw_params = snd_p16v_pcm_hw_params_capture, | ||
573 | .hw_free = snd_p16v_pcm_hw_free_capture, | ||
574 | .prepare = snd_p16v_pcm_prepare_capture, | ||
575 | .trigger = snd_p16v_pcm_trigger_capture, | ||
576 | .pointer = snd_p16v_pcm_pointer_capture, | ||
577 | }; | ||
578 | |||
579 | |||
385 | int snd_p16v_free(emu10k1_t *chip) | 580 | int snd_p16v_free(emu10k1_t *chip) |
386 | { | 581 | { |
387 | // release the data | 582 | // release the data |
@@ -405,20 +600,22 @@ int snd_p16v_pcm(emu10k1_t *emu, int device, snd_pcm_t **rpcm) | |||
405 | snd_pcm_t *pcm; | 600 | snd_pcm_t *pcm; |
406 | snd_pcm_substream_t *substream; | 601 | snd_pcm_substream_t *substream; |
407 | int err; | 602 | int err; |
408 | int capture=0; | 603 | int capture=1; |
409 | 604 | ||
410 | //snd_printk("snd_p16v_pcm called. device=%d\n", device); | 605 | //snd_printk("snd_p16v_pcm called. device=%d\n", device); |
411 | emu->p16v_device_offset = device; | 606 | emu->p16v_device_offset = device; |
412 | if (rpcm) | 607 | if (rpcm) |
413 | *rpcm = NULL; | 608 | *rpcm = NULL; |
414 | //if (device == 0) capture=1; | 609 | |
415 | if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0) | 610 | if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0) |
416 | return err; | 611 | return err; |
417 | 612 | ||
418 | pcm->private_data = emu; | 613 | pcm->private_data = emu; |
419 | pcm->private_free = snd_p16v_pcm_free; | 614 | pcm->private_free = snd_p16v_pcm_free; |
420 | 615 | // Single playback 8 channel device. | |
616 | // Single capture 2 channel device. | ||
421 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_p16v_playback_front_ops); | 617 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_p16v_playback_front_ops); |
618 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_p16v_capture_ops); | ||
422 | 619 | ||
423 | pcm->info_flags = 0; | 620 | pcm->info_flags = 0; |
424 | pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; | 621 | pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; |
@@ -431,7 +628,7 @@ int snd_p16v_pcm(emu10k1_t *emu, int device, snd_pcm_t **rpcm) | |||
431 | if ((err = snd_pcm_lib_preallocate_pages(substream, | 628 | if ((err = snd_pcm_lib_preallocate_pages(substream, |
432 | SNDRV_DMA_TYPE_DEV, | 629 | SNDRV_DMA_TYPE_DEV, |
433 | snd_dma_pci_data(emu->pci), | 630 | snd_dma_pci_data(emu->pci), |
434 | 64*1024, 64*1024)) < 0) /* FIXME: 32*1024 for sound buffer, between 32and64 for Periods table. */ | 631 | ((65536 - 64) * 8), ((65536 - 64) * 8))) < 0) |
435 | return err; | 632 | return err; |
436 | //snd_printk("preallocate playback substream: err=%d\n", err); | 633 | //snd_printk("preallocate playback substream: err=%d\n", err); |
437 | } | 634 | } |
@@ -442,7 +639,7 @@ int snd_p16v_pcm(emu10k1_t *emu, int device, snd_pcm_t **rpcm) | |||
442 | if ((err = snd_pcm_lib_preallocate_pages(substream, | 639 | if ((err = snd_pcm_lib_preallocate_pages(substream, |
443 | SNDRV_DMA_TYPE_DEV, | 640 | SNDRV_DMA_TYPE_DEV, |
444 | snd_dma_pci_data(emu->pci), | 641 | snd_dma_pci_data(emu->pci), |
445 | 64*1024, 64*1024)) < 0) | 642 | 65536 - 64, 65536 - 64)) < 0) |
446 | return err; | 643 | return err; |
447 | //snd_printk("preallocate capture substream: err=%d\n", err); | 644 | //snd_printk("preallocate capture substream: err=%d\n", err); |
448 | } | 645 | } |
@@ -694,6 +891,106 @@ static snd_kcontrol_new_t snd_p16v_volume_control_spdif_rear = | |||
694 | .put = snd_p16v_volume_put_spdif_rear | 891 | .put = snd_p16v_volume_put_spdif_rear |
695 | }; | 892 | }; |
696 | 893 | ||
894 | static int snd_p16v_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) | ||
895 | { | ||
896 | static char *texts[8] = { "SPDIF", "I2S", "SRC48", "SRCMulti_SPDIF", "SRCMulti_I2S", "CDIF", "FX", "AC97" }; | ||
897 | |||
898 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
899 | uinfo->count = 1; | ||
900 | uinfo->value.enumerated.items = 8; | ||
901 | if (uinfo->value.enumerated.item > 7) | ||
902 | uinfo->value.enumerated.item = 7; | ||
903 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
904 | return 0; | ||
905 | } | ||
906 | |||
907 | static int snd_p16v_capture_source_get(snd_kcontrol_t * kcontrol, | ||
908 | snd_ctl_elem_value_t * ucontrol) | ||
909 | { | ||
910 | emu10k1_t *emu = snd_kcontrol_chip(kcontrol); | ||
911 | |||
912 | ucontrol->value.enumerated.item[0] = emu->p16v_capture_source; | ||
913 | return 0; | ||
914 | } | ||
915 | |||
916 | static int snd_p16v_capture_source_put(snd_kcontrol_t * kcontrol, | ||
917 | snd_ctl_elem_value_t * ucontrol) | ||
918 | { | ||
919 | emu10k1_t *emu = snd_kcontrol_chip(kcontrol); | ||
920 | unsigned int val; | ||
921 | int change = 0; | ||
922 | u32 mask; | ||
923 | u32 source; | ||
924 | |||
925 | val = ucontrol->value.enumerated.item[0] ; | ||
926 | change = (emu->p16v_capture_source != val); | ||
927 | if (change) { | ||
928 | emu->p16v_capture_source = val; | ||
929 | source = (val << 28) | (val << 24) | (val << 20) | (val << 16); | ||
930 | mask = snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & 0xffff; | ||
931 | snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, source | mask); | ||
932 | } | ||
933 | return change; | ||
934 | } | ||
935 | |||
936 | static snd_kcontrol_new_t snd_p16v_capture_source __devinitdata = | ||
937 | { | ||
938 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
939 | .name = "HD Capture source", | ||
940 | .info = snd_p16v_capture_source_info, | ||
941 | .get = snd_p16v_capture_source_get, | ||
942 | .put = snd_p16v_capture_source_put | ||
943 | }; | ||
944 | |||
945 | static int snd_p16v_capture_channel_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) | ||
946 | { | ||
947 | static char *texts[4] = { "0", "1", "2", "3", }; | ||
948 | |||
949 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
950 | uinfo->count = 1; | ||
951 | uinfo->value.enumerated.items = 4; | ||
952 | if (uinfo->value.enumerated.item > 3) | ||
953 | uinfo->value.enumerated.item = 3; | ||
954 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
955 | return 0; | ||
956 | } | ||
957 | |||
958 | static int snd_p16v_capture_channel_get(snd_kcontrol_t * kcontrol, | ||
959 | snd_ctl_elem_value_t * ucontrol) | ||
960 | { | ||
961 | emu10k1_t *emu = snd_kcontrol_chip(kcontrol); | ||
962 | |||
963 | ucontrol->value.enumerated.item[0] = emu->p16v_capture_channel; | ||
964 | return 0; | ||
965 | } | ||
966 | |||
967 | static int snd_p16v_capture_channel_put(snd_kcontrol_t * kcontrol, | ||
968 | snd_ctl_elem_value_t * ucontrol) | ||
969 | { | ||
970 | emu10k1_t *emu = snd_kcontrol_chip(kcontrol); | ||
971 | unsigned int val; | ||
972 | int change = 0; | ||
973 | u32 tmp; | ||
974 | |||
975 | val = ucontrol->value.enumerated.item[0] ; | ||
976 | change = (emu->p16v_capture_channel != val); | ||
977 | if (change) { | ||
978 | emu->p16v_capture_channel = val; | ||
979 | tmp = snd_emu10k1_ptr20_read(emu, CAPTURE_P16V_SOURCE, 0) & 0xfffc; | ||
980 | snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, tmp | val); | ||
981 | } | ||
982 | return change; | ||
983 | } | ||
984 | |||
985 | static snd_kcontrol_new_t snd_p16v_capture_channel __devinitdata = | ||
986 | { | ||
987 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
988 | .name = "HD Capture channel", | ||
989 | .info = snd_p16v_capture_channel_info, | ||
990 | .get = snd_p16v_capture_channel_get, | ||
991 | .put = snd_p16v_capture_channel_put | ||
992 | }; | ||
993 | |||
697 | int snd_p16v_mixer(emu10k1_t *emu) | 994 | int snd_p16v_mixer(emu10k1_t *emu) |
698 | { | 995 | { |
699 | int err; | 996 | int err; |
@@ -731,6 +1028,14 @@ int snd_p16v_mixer(emu10k1_t *emu) | |||
731 | return -ENOMEM; | 1028 | return -ENOMEM; |
732 | if ((err = snd_ctl_add(card, kctl))) | 1029 | if ((err = snd_ctl_add(card, kctl))) |
733 | return err; | 1030 | return err; |
1031 | if ((kctl = snd_ctl_new1(&snd_p16v_capture_source, emu)) == NULL) | ||
1032 | return -ENOMEM; | ||
1033 | if ((err = snd_ctl_add(card, kctl))) | ||
1034 | return err; | ||
1035 | if ((kctl = snd_ctl_new1(&snd_p16v_capture_channel, emu)) == NULL) | ||
1036 | return -ENOMEM; | ||
1037 | if ((err = snd_ctl_add(card, kctl))) | ||
1038 | return err; | ||
734 | return 0; | 1039 | return 0; |
735 | } | 1040 | } |
736 | 1041 | ||