Merge tag 'v3.6-rc5' into for-linus
[pandora-kernel.git] / sound / usb / mixer_quirks.c
index 41f4b69..690000d 100644 (file)
 
 extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl;
 
+struct std_mono_table {
+       unsigned int unitid, control, cmask;
+       int val_type;
+       const char *name;
+       snd_kcontrol_tlv_rw_t *tlv_callback;
+};
+
 /* private_free callback */
 static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
 {
@@ -113,6 +120,25 @@ static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
        return 0;
 }
 
+/*
+ * Create a set of standard UAC controls from a table
+ */
+static int snd_create_std_mono_table(struct usb_mixer_interface *mixer,
+                               struct std_mono_table *t)
+{
+       int err;
+
+       while (t->name != NULL) {
+               err = snd_create_std_mono_ctl(mixer, t->unitid, t->control,
+                               t->cmask, t->val_type, t->name, t->tlv_callback);
+               if (err < 0)
+                       return err;
+               t++;
+       }
+
+       return 0;
+}
+
 /*
  * Sound Blaster remote control configuration
  *
@@ -916,61 +942,6 @@ static int snd_ftu_create_mixer(struct usb_mixer_interface *mixer)
        return 0;
 }
 
-
-/*
- * Create mixer for Electrix Ebox-44
- *
- * The mixer units from this device are corrupt, and even where they
- * are valid they presents mono controls as L and R channels of
- * stereo. So we create a good mixer in code.
- */
-
-static int snd_ebox44_create_mixer(struct usb_mixer_interface *mixer)
-{
-       int err;
-
-       err = snd_create_std_mono_ctl(mixer, 4, 1, 0x0, USB_MIXER_INV_BOOLEAN,
-                               "Headphone Playback Switch", NULL);
-       if (err < 0)
-               return err;
-       err = snd_create_std_mono_ctl(mixer, 4, 2, 0x1, USB_MIXER_S16,
-                               "Headphone A Mix Playback Volume", NULL);
-       if (err < 0)
-               return err;
-       err = snd_create_std_mono_ctl(mixer, 4, 2, 0x2, USB_MIXER_S16,
-                               "Headphone B Mix Playback Volume", NULL);
-       if (err < 0)
-               return err;
-
-       err = snd_create_std_mono_ctl(mixer, 7, 1, 0x0, USB_MIXER_INV_BOOLEAN,
-                               "Output Playback Switch", NULL);
-       if (err < 0)
-               return err;
-       err = snd_create_std_mono_ctl(mixer, 7, 2, 0x1, USB_MIXER_S16,
-                               "Output A Playback Volume", NULL);
-       if (err < 0)
-               return err;
-       err = snd_create_std_mono_ctl(mixer, 7, 2, 0x2, USB_MIXER_S16,
-                               "Output B Playback Volume", NULL);
-       if (err < 0)
-               return err;
-
-       err = snd_create_std_mono_ctl(mixer, 10, 1, 0x0, USB_MIXER_INV_BOOLEAN,
-                               "Input Capture Switch", NULL);
-       if (err < 0)
-               return err;
-       err = snd_create_std_mono_ctl(mixer, 10, 2, 0x1, USB_MIXER_S16,
-                               "Input A Capture Volume", NULL);
-       if (err < 0)
-               return err;
-       err = snd_create_std_mono_ctl(mixer, 10, 2, 0x2, USB_MIXER_S16,
-                               "Input B Capture Volume", NULL);
-       if (err < 0)
-               return err;
-
-       return 0;
-}
-
 void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
                               unsigned char samplerate_id)
 {
@@ -990,6 +961,81 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
        }
 }
 
+/*
+ * The mixer units for Ebox-44 are corrupt, and even where they
+ * are valid they presents mono controls as L and R channels of
+ * stereo. So we provide a good mixer here.
+ */
+struct std_mono_table ebox44_table[] = {
+       {
+               .unitid = 4,
+               .control = 1,
+               .cmask = 0x0,
+               .val_type = USB_MIXER_INV_BOOLEAN,
+               .name = "Headphone Playback Switch"
+       },
+       {
+               .unitid = 4,
+               .control = 2,
+               .cmask = 0x1,
+               .val_type = USB_MIXER_S16,
+               .name = "Headphone A Mix Playback Volume"
+       },
+       {
+               .unitid = 4,
+               .control = 2,
+               .cmask = 0x2,
+               .val_type = USB_MIXER_S16,
+               .name = "Headphone B Mix Playback Volume"
+       },
+
+       {
+               .unitid = 7,
+               .control = 1,
+               .cmask = 0x0,
+               .val_type = USB_MIXER_INV_BOOLEAN,
+               .name = "Output Playback Switch"
+       },
+       {
+               .unitid = 7,
+               .control = 2,
+               .cmask = 0x1,
+               .val_type = USB_MIXER_S16,
+               .name = "Output A Playback Volume"
+       },
+       {
+               .unitid = 7,
+               .control = 2,
+               .cmask = 0x2,
+               .val_type = USB_MIXER_S16,
+               .name = "Output B Playback Volume"
+       },
+
+       {
+               .unitid = 10,
+               .control = 1,
+               .cmask = 0x0,
+               .val_type = USB_MIXER_INV_BOOLEAN,
+               .name = "Input Capture Switch"
+       },
+       {
+               .unitid = 10,
+               .control = 2,
+               .cmask = 0x1,
+               .val_type = USB_MIXER_S16,
+               .name = "Input A Capture Volume"
+       },
+       {
+               .unitid = 10,
+               .control = 2,
+               .cmask = 0x2,
+               .val_type = USB_MIXER_S16,
+               .name = "Input B Capture Volume"
+       },
+
+       {}
+};
+
 int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
 {
        int err = 0;
@@ -1035,7 +1081,8 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
                break;
 
        case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */
-               err = snd_ebox44_create_mixer(mixer);
+               /* detection is disabled in mixer_maps.c */
+               err = snd_create_std_mono_table(mixer, ebox44_table);
                break;
        }