aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
authorMark Hills <mark@pogo.org.uk>2012-06-09 08:16:38 -0400
committerTakashi Iwai <tiwai@suse.de>2012-06-11 06:49:43 -0400
commitb71dad181a55d2ad90bd03cd3216a5a8a31d9468 (patch)
tree23b409eecaef770b8d957b95b773926dda833115 /sound/usb
parent223f18e4482fd90b7cdabb222fad5ca502dc0028 (diff)
ALSA: usb-audio: Use a table of mixer controls
Allow mixer controls to be provided clearly in a table, to avoid quantity of error checking at each use. Signed-off-by: Mark Hills <mark@pogo.org.uk> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/mixer_quirks.c105
1 files changed, 49 insertions, 56 deletions
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 41f4b6911920..ce7d96f91578 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -42,6 +42,13 @@
42 42
43extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; 43extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl;
44 44
45struct std_mono_table {
46 unsigned int unitid, control, cmask;
47 int val_type;
48 const char *name;
49 snd_kcontrol_tlv_rw_t *tlv_callback;
50};
51
45/* private_free callback */ 52/* private_free callback */
46static void usb_mixer_elem_free(struct snd_kcontrol *kctl) 53static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
47{ 54{
@@ -114,6 +121,25 @@ static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
114} 121}
115 122
116/* 123/*
124 * Create a set of standard UAC controls from a table
125 */
126static int snd_create_std_mono_table(struct usb_mixer_interface *mixer,
127 struct std_mono_table *t)
128{
129 int err;
130
131 while (t->name != NULL) {
132 err = snd_create_std_mono_ctl(mixer, t->unitid, t->control,
133 t->cmask, t->val_type, t->name, t->tlv_callback);
134 if (err < 0)
135 return err;
136 t++;
137 }
138
139 return 0;
140}
141
142/*
117 * Sound Blaster remote control configuration 143 * Sound Blaster remote control configuration
118 * 144 *
119 * format of remote control data: 145 * format of remote control data:
@@ -916,61 +942,6 @@ static int snd_ftu_create_mixer(struct usb_mixer_interface *mixer)
916 return 0; 942 return 0;
917} 943}
918 944
919
920/*
921 * Create mixer for Electrix Ebox-44
922 *
923 * The mixer units from this device are corrupt, and even where they
924 * are valid they presents mono controls as L and R channels of
925 * stereo. So we create a good mixer in code.
926 */
927
928static int snd_ebox44_create_mixer(struct usb_mixer_interface *mixer)
929{
930 int err;
931
932 err = snd_create_std_mono_ctl(mixer, 4, 1, 0x0, USB_MIXER_INV_BOOLEAN,
933 "Headphone Playback Switch", NULL);
934 if (err < 0)
935 return err;
936 err = snd_create_std_mono_ctl(mixer, 4, 2, 0x1, USB_MIXER_S16,
937 "Headphone A Mix Playback Volume", NULL);
938 if (err < 0)
939 return err;
940 err = snd_create_std_mono_ctl(mixer, 4, 2, 0x2, USB_MIXER_S16,
941 "Headphone B Mix Playback Volume", NULL);
942 if (err < 0)
943 return err;
944
945 err = snd_create_std_mono_ctl(mixer, 7, 1, 0x0, USB_MIXER_INV_BOOLEAN,
946 "Output Playback Switch", NULL);
947 if (err < 0)
948 return err;
949 err = snd_create_std_mono_ctl(mixer, 7, 2, 0x1, USB_MIXER_S16,
950 "Output A Playback Volume", NULL);
951 if (err < 0)
952 return err;
953 err = snd_create_std_mono_ctl(mixer, 7, 2, 0x2, USB_MIXER_S16,
954 "Output B Playback Volume", NULL);
955 if (err < 0)
956 return err;
957
958 err = snd_create_std_mono_ctl(mixer, 10, 1, 0x0, USB_MIXER_INV_BOOLEAN,
959 "Input Capture Switch", NULL);
960 if (err < 0)
961 return err;
962 err = snd_create_std_mono_ctl(mixer, 10, 2, 0x1, USB_MIXER_S16,
963 "Input A Capture Volume", NULL);
964 if (err < 0)
965 return err;
966 err = snd_create_std_mono_ctl(mixer, 10, 2, 0x2, USB_MIXER_S16,
967 "Input B Capture Volume", NULL);
968 if (err < 0)
969 return err;
970
971 return 0;
972}
973
974void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, 945void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
975 unsigned char samplerate_id) 946 unsigned char samplerate_id)
976{ 947{
@@ -990,6 +961,27 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
990 } 961 }
991} 962}
992 963
964/*
965 * The mixer units for Ebox-44 are corrupt, and even where they
966 * are valid they presents mono controls as L and R channels of
967 * stereo. So we provide a good mixer here.
968 */
969struct std_mono_table ebox44_table[] = {
970 { 4, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Headphone Playback Switch", NULL },
971 { 4, 2, 0x1, USB_MIXER_S16, "Headphone A Mix Playback Volume", NULL },
972 { 4, 2, 0x2, USB_MIXER_S16, "Headphone B Mix Playback Volume", NULL },
973
974 { 7, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Output Playback Switch", NULL },
975 { 7, 2, 0x1, USB_MIXER_S16, "Output A Playback Volume", NULL },
976 { 7, 2, 0x2, USB_MIXER_S16, "Output B Playback Volume", NULL },
977
978 { 10, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Input Capture Switch", NULL },
979 { 10, 2, 0x1, USB_MIXER_S16, "Input A Capture Volume", NULL },
980 { 10, 2, 0x2, USB_MIXER_S16, "Input B Capture Volume", NULL },
981
982 { }
983};
984
993int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) 985int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
994{ 986{
995 int err = 0; 987 int err = 0;
@@ -1035,7 +1027,8 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
1035 break; 1027 break;
1036 1028
1037 case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */ 1029 case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */
1038 err = snd_ebox44_create_mixer(mixer); 1030 /* detection is disabled in mixer_maps.c */
1031 err = snd_create_std_mono_table(mixer, ebox44_table);
1039 break; 1032 break;
1040 } 1033 }
1041 1034