aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/emu10k1
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/emu10k1')
-rw-r--r--sound/pci/emu10k1/p16v.c361
1 files changed, 80 insertions, 281 deletions
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index 76d86ed46df0..9905651935fb 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -107,11 +107,11 @@
107#define PCM_FRONT_CHANNEL 0 107#define PCM_FRONT_CHANNEL 0
108#define PCM_REAR_CHANNEL 1 108#define PCM_REAR_CHANNEL 1
109#define PCM_CENTER_LFE_CHANNEL 2 109#define PCM_CENTER_LFE_CHANNEL 2
110#define PCM_UNKNOWN_CHANNEL 3 110#define PCM_SIDE_CHANNEL 3
111#define CONTROL_FRONT_CHANNEL 0 111#define CONTROL_FRONT_CHANNEL 0
112#define CONTROL_REAR_CHANNEL 3 112#define CONTROL_REAR_CHANNEL 3
113#define CONTROL_CENTER_LFE_CHANNEL 1 113#define CONTROL_CENTER_LFE_CHANNEL 1
114#define CONTROL_UNKNOWN_CHANNEL 2 114#define CONTROL_SIDE_CHANNEL 2
115 115
116/* Card IDs: 116/* Card IDs:
117 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2002 -> Audigy2 ZS 7.1 Model:SB0350 117 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2002 -> Audigy2 ZS 7.1 Model:SB0350
@@ -590,7 +590,7 @@ int snd_p16v_free(struct snd_emu10k1 *chip)
590 return 0; 590 return 0;
591} 591}
592 592
593int snd_p16v_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm) 593int __devinit snd_p16v_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm)
594{ 594{
595 struct snd_pcm *pcm; 595 struct snd_pcm *pcm;
596 struct snd_pcm_substream *substream; 596 struct snd_pcm_substream *substream;
@@ -644,7 +644,8 @@ int snd_p16v_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm)
644 return 0; 644 return 0;
645} 645}
646 646
647static int snd_p16v_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 647static int snd_p16v_volume_info(struct snd_kcontrol *kcontrol,
648 struct snd_ctl_elem_info *uinfo)
648{ 649{
649 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 650 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
650 uinfo->count = 2; 651 uinfo->count = 2;
@@ -654,240 +655,56 @@ static int snd_p16v_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_el
654} 655}
655 656
656static int snd_p16v_volume_get(struct snd_kcontrol *kcontrol, 657static int snd_p16v_volume_get(struct snd_kcontrol *kcontrol,
657 struct snd_ctl_elem_value *ucontrol, int reg, int high_low) 658 struct snd_ctl_elem_value *ucontrol)
658{ 659{
659 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); 660 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
660 u32 value; 661 int high_low = (kcontrol->private_value >> 8) & 0xff;
661 662 int reg = kcontrol->private_value & 0xff;
662 value = snd_emu10k1_ptr20_read(emu, reg, high_low); 663 u32 value;
663 if (high_low == 1) { 664
664 ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */ 665 value = snd_emu10k1_ptr20_read(emu, reg, high_low);
665 ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */ 666 if (high_low) {
667 ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
668 ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
666 } else { 669 } else {
667 ucontrol->value.integer.value[0] = 0xff - ((value >> 8) & 0xff); /* Left */ 670 ucontrol->value.integer.value[0] = 0xff - ((value >> 8) & 0xff); /* Left */
668 ucontrol->value.integer.value[1] = 0xff - ((value >> 0) & 0xff); /* Right */ 671 ucontrol->value.integer.value[1] = 0xff - ((value >> 0) & 0xff); /* Right */
669 } 672 }
670 return 0; 673 return 0;
671}
672
673static int snd_p16v_volume_get_spdif_front(struct snd_kcontrol *kcontrol,
674 struct snd_ctl_elem_value *ucontrol)
675{
676 int high_low = 0;
677 int reg = PLAYBACK_VOLUME_MIXER7;
678 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
679}
680
681static int snd_p16v_volume_get_spdif_center_lfe(struct snd_kcontrol *kcontrol,
682 struct snd_ctl_elem_value *ucontrol)
683{
684 int high_low = 1;
685 int reg = PLAYBACK_VOLUME_MIXER7;
686 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
687}
688static int snd_p16v_volume_get_spdif_unknown(struct snd_kcontrol *kcontrol,
689 struct snd_ctl_elem_value *ucontrol)
690{
691 int high_low = 0;
692 int reg = PLAYBACK_VOLUME_MIXER8;
693 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
694}
695static int snd_p16v_volume_get_spdif_rear(struct snd_kcontrol *kcontrol,
696 struct snd_ctl_elem_value *ucontrol)
697{
698 int high_low = 1;
699 int reg = PLAYBACK_VOLUME_MIXER8;
700 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
701}
702
703static int snd_p16v_volume_get_analog_front(struct snd_kcontrol *kcontrol,
704 struct snd_ctl_elem_value *ucontrol)
705{
706 int high_low = 0;
707 int reg = PLAYBACK_VOLUME_MIXER9;
708 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
709}
710
711static int snd_p16v_volume_get_analog_center_lfe(struct snd_kcontrol *kcontrol,
712 struct snd_ctl_elem_value *ucontrol)
713{
714 int high_low = 1;
715 int reg = PLAYBACK_VOLUME_MIXER9;
716 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
717}
718static int snd_p16v_volume_get_analog_rear(struct snd_kcontrol *kcontrol,
719 struct snd_ctl_elem_value *ucontrol)
720{
721 int high_low = 1;
722 int reg = PLAYBACK_VOLUME_MIXER10;
723 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
724}
725
726static int snd_p16v_volume_get_analog_unknown(struct snd_kcontrol *kcontrol,
727 struct snd_ctl_elem_value *ucontrol)
728{
729 int high_low = 0;
730 int reg = PLAYBACK_VOLUME_MIXER10;
731 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
732} 674}
733 675
734static int snd_p16v_volume_put(struct snd_kcontrol *kcontrol, 676static int snd_p16v_volume_put(struct snd_kcontrol *kcontrol,
735 struct snd_ctl_elem_value *ucontrol, int reg, int high_low) 677 struct snd_ctl_elem_value *ucontrol)
736{ 678{
737 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); 679 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
738 u32 value; 680 int high_low = (kcontrol->private_value >> 8) & 0xff;
739 value = snd_emu10k1_ptr20_read(emu, reg, 0); 681 int reg = kcontrol->private_value & 0xff;
740 //value = value & 0xffff; 682 u32 value, oval;
683
684 oval = value = snd_emu10k1_ptr20_read(emu, reg, 0);
741 if (high_low == 1) { 685 if (high_low == 1) {
742 value &= 0xffff; 686 value &= 0xffff;
743 value = value | ((0xff - ucontrol->value.integer.value[0]) << 24) | ((0xff - ucontrol->value.integer.value[1]) << 16); 687 value |= ((0xff - ucontrol->value.integer.value[0]) << 24) |
688 ((0xff - ucontrol->value.integer.value[1]) << 16);
744 } else { 689 } else {
745 value &= 0xffff0000; 690 value &= 0xffff0000;
746 value = value | ((0xff - ucontrol->value.integer.value[0]) << 8) | ((0xff - ucontrol->value.integer.value[1]) ); 691 value |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
692 ((0xff - ucontrol->value.integer.value[1]) );
747 } 693 }
748 snd_emu10k1_ptr20_write(emu, reg, 0, value); 694 if (value != oval) {
749 return 1; 695 snd_emu10k1_ptr20_write(emu, reg, 0, value);
750} 696 return 1;
751 697 }
752static int snd_p16v_volume_put_spdif_front(struct snd_kcontrol *kcontrol, 698 return 0;
753 struct snd_ctl_elem_value *ucontrol)
754{
755 int high_low = 0;
756 int reg = PLAYBACK_VOLUME_MIXER7;
757 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
758}
759
760static int snd_p16v_volume_put_spdif_center_lfe(struct snd_kcontrol *kcontrol,
761 struct snd_ctl_elem_value *ucontrol)
762{
763 int high_low = 1;
764 int reg = PLAYBACK_VOLUME_MIXER7;
765 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
766}
767
768static int snd_p16v_volume_put_spdif_unknown(struct snd_kcontrol *kcontrol,
769 struct snd_ctl_elem_value *ucontrol)
770{
771 int high_low = 0;
772 int reg = PLAYBACK_VOLUME_MIXER8;
773 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
774}
775
776static int snd_p16v_volume_put_spdif_rear(struct snd_kcontrol *kcontrol,
777 struct snd_ctl_elem_value *ucontrol)
778{
779 int high_low = 1;
780 int reg = PLAYBACK_VOLUME_MIXER8;
781 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
782}
783
784static int snd_p16v_volume_put_analog_front(struct snd_kcontrol *kcontrol,
785 struct snd_ctl_elem_value *ucontrol)
786{
787 int high_low = 0;
788 int reg = PLAYBACK_VOLUME_MIXER9;
789 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
790}
791
792static int snd_p16v_volume_put_analog_center_lfe(struct snd_kcontrol *kcontrol,
793 struct snd_ctl_elem_value *ucontrol)
794{
795 int high_low = 1;
796 int reg = PLAYBACK_VOLUME_MIXER9;
797 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
798}
799
800static int snd_p16v_volume_put_analog_rear(struct snd_kcontrol *kcontrol,
801 struct snd_ctl_elem_value *ucontrol)
802{
803 int high_low = 1;
804 int reg = PLAYBACK_VOLUME_MIXER10;
805 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
806}
807
808static int snd_p16v_volume_put_analog_unknown(struct snd_kcontrol *kcontrol,
809 struct snd_ctl_elem_value *ucontrol)
810{
811 int high_low = 0;
812 int reg = PLAYBACK_VOLUME_MIXER10;
813 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
814} 699}
815 700
816static struct snd_kcontrol_new snd_p16v_volume_control_analog_front = 701static int snd_p16v_capture_source_info(struct snd_kcontrol *kcontrol,
817{ 702 struct snd_ctl_elem_info *uinfo)
818 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
819 .name = "HD Analog Front Playback Volume",
820 .info = snd_p16v_volume_info,
821 .get = snd_p16v_volume_get_analog_front,
822 .put = snd_p16v_volume_put_analog_front
823};
824
825static struct snd_kcontrol_new snd_p16v_volume_control_analog_center_lfe =
826{
827 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
828 .name = "HD Analog Center/LFE Playback Volume",
829 .info = snd_p16v_volume_info,
830 .get = snd_p16v_volume_get_analog_center_lfe,
831 .put = snd_p16v_volume_put_analog_center_lfe
832};
833
834static struct snd_kcontrol_new snd_p16v_volume_control_analog_unknown =
835{
836 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
837 .name = "HD Analog Unknown Playback Volume",
838 .info = snd_p16v_volume_info,
839 .get = snd_p16v_volume_get_analog_unknown,
840 .put = snd_p16v_volume_put_analog_unknown
841};
842
843static struct snd_kcontrol_new snd_p16v_volume_control_analog_rear =
844{
845 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
846 .name = "HD Analog Rear Playback Volume",
847 .info = snd_p16v_volume_info,
848 .get = snd_p16v_volume_get_analog_rear,
849 .put = snd_p16v_volume_put_analog_rear
850};
851
852static struct snd_kcontrol_new snd_p16v_volume_control_spdif_front =
853{
854 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
855 .name = "HD SPDIF Front Playback Volume",
856 .info = snd_p16v_volume_info,
857 .get = snd_p16v_volume_get_spdif_front,
858 .put = snd_p16v_volume_put_spdif_front
859};
860
861static struct snd_kcontrol_new snd_p16v_volume_control_spdif_center_lfe =
862{
863 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
864 .name = "HD SPDIF Center/LFE Playback Volume",
865 .info = snd_p16v_volume_info,
866 .get = snd_p16v_volume_get_spdif_center_lfe,
867 .put = snd_p16v_volume_put_spdif_center_lfe
868};
869
870static struct snd_kcontrol_new snd_p16v_volume_control_spdif_unknown =
871{ 703{
872 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 704 static char *texts[8] = {
873 .name = "HD SPDIF Unknown Playback Volume", 705 "SPDIF", "I2S", "SRC48", "SRCMulti_SPDIF", "SRCMulti_I2S",
874 .info = snd_p16v_volume_info, 706 "CDIF", "FX", "AC97"
875 .get = snd_p16v_volume_get_spdif_unknown, 707 };
876 .put = snd_p16v_volume_put_spdif_unknown
877};
878
879static struct snd_kcontrol_new snd_p16v_volume_control_spdif_rear =
880{
881 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
882 .name = "HD SPDIF Rear Playback Volume",
883 .info = snd_p16v_volume_info,
884 .get = snd_p16v_volume_get_spdif_rear,
885 .put = snd_p16v_volume_put_spdif_rear
886};
887
888static int snd_p16v_capture_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
889{
890 static char *texts[8] = { "SPDIF", "I2S", "SRC48", "SRCMulti_SPDIF", "SRCMulti_I2S", "CDIF", "FX", "AC97" };
891 708
892 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 709 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
893 uinfo->count = 1; 710 uinfo->count = 1;
@@ -927,16 +744,8 @@ static int snd_p16v_capture_source_put(struct snd_kcontrol *kcontrol,
927 return change; 744 return change;
928} 745}
929 746
930static struct snd_kcontrol_new snd_p16v_capture_source __devinitdata = 747static int snd_p16v_capture_channel_info(struct snd_kcontrol *kcontrol,
931{ 748 struct snd_ctl_elem_info *uinfo)
932 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
933 .name = "HD source Capture",
934 .info = snd_p16v_capture_source_info,
935 .get = snd_p16v_capture_source_get,
936 .put = snd_p16v_capture_source_put
937};
938
939static int snd_p16v_capture_channel_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
940{ 749{
941 static char *texts[4] = { "0", "1", "2", "3", }; 750 static char *texts[4] = { "0", "1", "2", "3", };
942 751
@@ -976,60 +785,50 @@ static int snd_p16v_capture_channel_put(struct snd_kcontrol *kcontrol,
976 return change; 785 return change;
977} 786}
978 787
979static struct snd_kcontrol_new snd_p16v_capture_channel __devinitdata = 788#define P16V_VOL(xname,xreg,xhl) { \
980{ 789 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
981 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 790 .info = snd_p16v_volume_info, \
982 .name = "HD channel Capture", 791 .get = snd_p16v_volume_get, \
983 .info = snd_p16v_capture_channel_info, 792 .put = snd_p16v_volume_put, \
984 .get = snd_p16v_capture_channel_get, 793 .private_value = ((xreg) | ((xhl) << 8)) \
985 .put = snd_p16v_capture_channel_put 794}
795
796static struct snd_kcontrol_new p16v_mixer_controls[] __devinitdata = {
797 P16V_VOL("HD Analog Front Playback Volume", PLAYBACK_VOLUME_MIXER9, 0),
798 P16V_VOL("HD Analog Rear Playback Volume", PLAYBACK_VOLUME_MIXER10, 1),
799 P16V_VOL("HD Analog Center/LFE Playback Volume", PLAYBACK_VOLUME_MIXER9, 1),
800 P16V_VOL("HD Analog Side Playback Volume", PLAYBACK_VOLUME_MIXER10, 0),
801 P16V_VOL("HD SPDIF Front Playback Volume", PLAYBACK_VOLUME_MIXER7, 0),
802 P16V_VOL("HD SPDIF Rear Playback Volume", PLAYBACK_VOLUME_MIXER8, 1),
803 P16V_VOL("HD SPDIF Center/LFE Playback Volume", PLAYBACK_VOLUME_MIXER7, 1),
804 P16V_VOL("HD SPDIF Side Playback Volume", PLAYBACK_VOLUME_MIXER8, 0),
805 {
806 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
807 .name = "HD source Capture",
808 .info = snd_p16v_capture_source_info,
809 .get = snd_p16v_capture_source_get,
810 .put = snd_p16v_capture_source_put
811 },
812 {
813 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
814 .name = "HD channel Capture",
815 .info = snd_p16v_capture_channel_info,
816 .get = snd_p16v_capture_channel_get,
817 .put = snd_p16v_capture_channel_put
818 },
986}; 819};
987 820
988int snd_p16v_mixer(struct snd_emu10k1 *emu) 821
822int __devinit snd_p16v_mixer(struct snd_emu10k1 *emu)
989{ 823{
990 int err; 824 int i, err;
991 struct snd_kcontrol *kctl;
992 struct snd_card *card = emu->card; 825 struct snd_card *card = emu->card;
993 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_front, emu)) == NULL) 826
994 return -ENOMEM; 827 for (i = 0; i < ARRAY_SIZE(p16v_mixer_controls); i++) {
995 if ((err = snd_ctl_add(card, kctl))) 828 if ((err = snd_ctl_add(card, snd_ctl_new1(&p16v_mixer_controls[i],
996 return err; 829 emu))) < 0)
997 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_rear, emu)) == NULL) 830 return err;
998 return -ENOMEM; 831 }
999 if ((err = snd_ctl_add(card, kctl)))
1000 return err;
1001 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_center_lfe, emu)) == NULL)
1002 return -ENOMEM;
1003 if ((err = snd_ctl_add(card, kctl)))
1004 return err;
1005 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_unknown, emu)) == NULL)
1006 return -ENOMEM;
1007 if ((err = snd_ctl_add(card, kctl)))
1008 return err;
1009 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_front, emu)) == NULL)
1010 return -ENOMEM;
1011 if ((err = snd_ctl_add(card, kctl)))
1012 return err;
1013 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_rear, emu)) == NULL)
1014 return -ENOMEM;
1015 if ((err = snd_ctl_add(card, kctl)))
1016 return err;
1017 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_center_lfe, emu)) == NULL)
1018 return -ENOMEM;
1019 if ((err = snd_ctl_add(card, kctl)))
1020 return err;
1021 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_unknown, emu)) == NULL)
1022 return -ENOMEM;
1023 if ((err = snd_ctl_add(card, kctl)))
1024 return err;
1025 if ((kctl = snd_ctl_new1(&snd_p16v_capture_source, emu)) == NULL)
1026 return -ENOMEM;
1027 if ((err = snd_ctl_add(card, kctl)))
1028 return err;
1029 if ((kctl = snd_ctl_new1(&snd_p16v_capture_channel, emu)) == NULL)
1030 return -ENOMEM;
1031 if ((err = snd_ctl_add(card, kctl)))
1032 return err;
1033 return 0; 832 return 0;
1034} 833}
1035 834