aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/emu10k1
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/emu10k1')
-rw-r--r--sound/pci/emu10k1/emu10k1.c2
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c192
-rw-r--r--sound/pci/emu10k1/emu10k1x.c8
-rw-r--r--sound/pci/emu10k1/emufx.c56
-rw-r--r--sound/pci/emu10k1/emumixer.c14
-rw-r--r--sound/pci/emu10k1/emupcm.c6
-rw-r--r--sound/pci/emu10k1/emuproc.c89
-rw-r--r--sound/pci/emu10k1/irq.c46
-rw-r--r--sound/pci/emu10k1/p16v.c367
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
229static int __init alsa_card_emu10k1_init(void) 229static 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
234static void __exit alsa_card_emu10k1_exit(void) 234static 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
617static emu_chip_details_t emu_chip_details[] = { 615static 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
362static void snd_emu10k1x_pcm_free_substream(snd_pcm_runtime_t *runtime) 362static 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
370static void snd_emu10k1x_pcm_interrupt(emu10k1x_t *emu, emu10k1x_voice_t *voice) 367static 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
71static int snd_audigy_spdif_output_rate_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 72static 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
156static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol, 158static 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 */
265static int inline emu10k1_ccis(int stereo, int w_16) 265static 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
992static void snd_emu10k1_pcm_free_substream(snd_pcm_runtime_t *runtime) 992static 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
999static int snd_emu10k1_efx_playback_close(snd_pcm_substream_t * substream) 997static 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
34static void snd_emu10k1_proc_spdif_status(emu10k1_t * emu, 35static 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
71static void snd_emu10k1_proc_read(snd_info_entry_t *entry, 78static 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); 235static 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
249static 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
237static void snd_emu10k1_proc_acode_read(snd_info_entry_t *entry, 264static 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
143static 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
135static void snd_p16v_pcm_free_substream(snd_pcm_runtime_t *runtime) 162static 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 */
209static 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 */
183static int snd_p16v_pcm_close_playback(snd_pcm_substream_t *substream) 247static 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 */
258static 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
273static 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 */
199static int snd_p16v_pcm_hw_params_playback(snd_pcm_substream_t *substream, 280static 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 */
290static 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 */
212static int snd_p16v_pcm_hw_free_playback(snd_pcm_substream_t *substream) 301static 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 */
309static 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 */
223static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream) 318static 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 */
367static 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
273static void snd_p16v_intr_enable(emu10k1_t *emu, unsigned int intrenb) 401static 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 */
477static 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 */
349static snd_pcm_uframes_t 507static snd_pcm_uframes_t
350snd_p16v_pcm_pointer_playback(snd_pcm_substream_t *substream) 508snd_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 */
532static snd_pcm_uframes_t
533snd_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 */
374static snd_pcm_ops_t snd_p16v_playback_front_ops = { 557static 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
568static 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
385int snd_p16v_free(emu10k1_t *chip) 580int 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
894static 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
907static 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
916static 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
936static 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
945static 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
958static 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
967static 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
985static 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
697int snd_p16v_mixer(emu10k1_t *emu) 994int 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