diff options
author | Michael Gernoth <michael@gernoth.net> | 2015-04-11 12:00:19 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-04-11 12:35:06 -0400 |
commit | 99dcab46b5a5b470074bec6d8386e2c7807684cf (patch) | |
tree | e8eb312594449a43bc9f0b4332c0a7e3983458e5 | |
parent | cab2ed7474bffafd2a68a885e03b85526194abcd (diff) |
ALSA: emu10k1: add toggles for E-mu 1010 optical ports
The optical ports on the E-mu 1010 (and dock) can be configured
for ADAT- or S/PDIF-mode, which is currently hardcoded to ADAT.
Add two mixer elements to expose this setting.
Tested on an E-mu 1010 PCIe with connected Micro Dock.
Signed-off-by: Michael Gernoth <michael@gernoth.net>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/pci/emu10k1/emumixer.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 1de33025669a..55e57166256e 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c | |||
@@ -806,6 +806,108 @@ static struct snd_kcontrol_new snd_emu1010_internal_clock = | |||
806 | .put = snd_emu1010_internal_clock_put | 806 | .put = snd_emu1010_internal_clock_put |
807 | }; | 807 | }; |
808 | 808 | ||
809 | static int snd_emu1010_optical_out_info(struct snd_kcontrol *kcontrol, | ||
810 | struct snd_ctl_elem_info *uinfo) | ||
811 | { | ||
812 | static const char * const texts[2] = { | ||
813 | "SPDIF", "ADAT" | ||
814 | }; | ||
815 | |||
816 | return snd_ctl_enum_info(uinfo, 1, 2, texts); | ||
817 | } | ||
818 | |||
819 | static int snd_emu1010_optical_out_get(struct snd_kcontrol *kcontrol, | ||
820 | struct snd_ctl_elem_value *ucontrol) | ||
821 | { | ||
822 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | ||
823 | |||
824 | ucontrol->value.enumerated.item[0] = emu->emu1010.optical_out; | ||
825 | return 0; | ||
826 | } | ||
827 | |||
828 | static int snd_emu1010_optical_out_put(struct snd_kcontrol *kcontrol, | ||
829 | struct snd_ctl_elem_value *ucontrol) | ||
830 | { | ||
831 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | ||
832 | unsigned int val; | ||
833 | u32 tmp; | ||
834 | int change = 0; | ||
835 | |||
836 | val = ucontrol->value.enumerated.item[0]; | ||
837 | /* Limit: uinfo->value.enumerated.items = 2; */ | ||
838 | if (val >= 2) | ||
839 | return -EINVAL; | ||
840 | change = (emu->emu1010.optical_out != val); | ||
841 | if (change) { | ||
842 | emu->emu1010.optical_out = val; | ||
843 | tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) | | ||
844 | (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0); | ||
845 | snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp); | ||
846 | } | ||
847 | return change; | ||
848 | } | ||
849 | |||
850 | static struct snd_kcontrol_new snd_emu1010_optical_out = { | ||
851 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
852 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
853 | .name = "Optical Output Mode", | ||
854 | .count = 1, | ||
855 | .info = snd_emu1010_optical_out_info, | ||
856 | .get = snd_emu1010_optical_out_get, | ||
857 | .put = snd_emu1010_optical_out_put | ||
858 | }; | ||
859 | |||
860 | static int snd_emu1010_optical_in_info(struct snd_kcontrol *kcontrol, | ||
861 | struct snd_ctl_elem_info *uinfo) | ||
862 | { | ||
863 | static const char * const texts[2] = { | ||
864 | "SPDIF", "ADAT" | ||
865 | }; | ||
866 | |||
867 | return snd_ctl_enum_info(uinfo, 1, 2, texts); | ||
868 | } | ||
869 | |||
870 | static int snd_emu1010_optical_in_get(struct snd_kcontrol *kcontrol, | ||
871 | struct snd_ctl_elem_value *ucontrol) | ||
872 | { | ||
873 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | ||
874 | |||
875 | ucontrol->value.enumerated.item[0] = emu->emu1010.optical_in; | ||
876 | return 0; | ||
877 | } | ||
878 | |||
879 | static int snd_emu1010_optical_in_put(struct snd_kcontrol *kcontrol, | ||
880 | struct snd_ctl_elem_value *ucontrol) | ||
881 | { | ||
882 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | ||
883 | unsigned int val; | ||
884 | u32 tmp; | ||
885 | int change = 0; | ||
886 | |||
887 | val = ucontrol->value.enumerated.item[0]; | ||
888 | /* Limit: uinfo->value.enumerated.items = 2; */ | ||
889 | if (val >= 2) | ||
890 | return -EINVAL; | ||
891 | change = (emu->emu1010.optical_in != val); | ||
892 | if (change) { | ||
893 | emu->emu1010.optical_in = val; | ||
894 | tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) | | ||
895 | (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0); | ||
896 | snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp); | ||
897 | } | ||
898 | return change; | ||
899 | } | ||
900 | |||
901 | static struct snd_kcontrol_new snd_emu1010_optical_in = { | ||
902 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
903 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
904 | .name = "Optical Input Mode", | ||
905 | .count = 1, | ||
906 | .info = snd_emu1010_optical_in_info, | ||
907 | .get = snd_emu1010_optical_in_get, | ||
908 | .put = snd_emu1010_optical_in_put | ||
909 | }; | ||
910 | |||
809 | static int snd_audigy_i2c_capture_source_info(struct snd_kcontrol *kcontrol, | 911 | static int snd_audigy_i2c_capture_source_info(struct snd_kcontrol *kcontrol, |
810 | struct snd_ctl_elem_info *uinfo) | 912 | struct snd_ctl_elem_info *uinfo) |
811 | { | 913 | { |
@@ -2051,6 +2153,14 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu, | |||
2051 | snd_ctl_new1(&snd_emu1010_internal_clock, emu)); | 2153 | snd_ctl_new1(&snd_emu1010_internal_clock, emu)); |
2052 | if (err < 0) | 2154 | if (err < 0) |
2053 | return err; | 2155 | return err; |
2156 | err = snd_ctl_add(card, | ||
2157 | snd_ctl_new1(&snd_emu1010_optical_out, emu)); | ||
2158 | if (err < 0) | ||
2159 | return err; | ||
2160 | err = snd_ctl_add(card, | ||
2161 | snd_ctl_new1(&snd_emu1010_optical_in, emu)); | ||
2162 | if (err < 0) | ||
2163 | return err; | ||
2054 | 2164 | ||
2055 | } else if (emu->card_capabilities->emu_model) { | 2165 | } else if (emu->card_capabilities->emu_model) { |
2056 | /* all other e-mu cards for now */ | 2166 | /* all other e-mu cards for now */ |
@@ -2086,6 +2196,14 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu, | |||
2086 | snd_ctl_new1(&snd_emu1010_internal_clock, emu)); | 2196 | snd_ctl_new1(&snd_emu1010_internal_clock, emu)); |
2087 | if (err < 0) | 2197 | if (err < 0) |
2088 | return err; | 2198 | return err; |
2199 | err = snd_ctl_add(card, | ||
2200 | snd_ctl_new1(&snd_emu1010_optical_out, emu)); | ||
2201 | if (err < 0) | ||
2202 | return err; | ||
2203 | err = snd_ctl_add(card, | ||
2204 | snd_ctl_new1(&snd_emu1010_optical_in, emu)); | ||
2205 | if (err < 0) | ||
2206 | return err; | ||
2089 | } | 2207 | } |
2090 | 2208 | ||
2091 | if ( emu->card_capabilities->i2c_adc) { | 2209 | if ( emu->card_capabilities->i2c_adc) { |