|
@@ -42,6 +42,13 @@
|
|
|
|
|
|
extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl;
|
|
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 */
|
|
/* private_free callback */
|
|
static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
|
|
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;
|
|
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
|
|
* Sound Blaster remote control configuration
|
|
*
|
|
*
|
|
@@ -916,61 +942,6 @@ static int snd_ftu_create_mixer(struct usb_mixer_interface *mixer)
|
|
return 0;
|
|
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,
|
|
void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
|
|
unsigned char samplerate_id)
|
|
unsigned char samplerate_id)
|
|
{
|
|
{
|
|
@@ -990,6 +961,27 @@ 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[] = {
|
|
|
|
+ { 4, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Headphone Playback Switch", NULL },
|
|
|
|
+ { 4, 2, 0x1, USB_MIXER_S16, "Headphone A Mix Playback Volume", NULL },
|
|
|
|
+ { 4, 2, 0x2, USB_MIXER_S16, "Headphone B Mix Playback Volume", NULL },
|
|
|
|
+
|
|
|
|
+ { 7, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Output Playback Switch", NULL },
|
|
|
|
+ { 7, 2, 0x1, USB_MIXER_S16, "Output A Playback Volume", NULL },
|
|
|
|
+ { 7, 2, 0x2, USB_MIXER_S16, "Output B Playback Volume", NULL },
|
|
|
|
+
|
|
|
|
+ { 10, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Input Capture Switch", NULL },
|
|
|
|
+ { 10, 2, 0x1, USB_MIXER_S16, "Input A Capture Volume", NULL },
|
|
|
|
+ { 10, 2, 0x2, USB_MIXER_S16, "Input B Capture Volume", NULL },
|
|
|
|
+
|
|
|
|
+ { }
|
|
|
|
+};
|
|
|
|
+
|
|
int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
|
|
int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
|
|
{
|
|
{
|
|
int err = 0;
|
|
int err = 0;
|
|
@@ -1035,7 +1027,8 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
|
|
break;
|
|
break;
|
|
|
|
|
|
case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */
|
|
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;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|