summary refs log tree commit diff
path: root/sound/usb
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-07-18 13:53:29 +0200
committerTakashi Iwai <tiwai@suse.de>2012-07-18 13:53:29 +0200
commitf0913cd16e8a6608cf9558ccbe8fdf4d428ca3de (patch)
treed6ea8cc44a9d55d29d38605165a09cf69ff9a536 /sound/usb
parent61eab000f3536f080eab43fd5eed3fd817ded76e (diff)
parent59b1f084abd8690ffe68c67758ad08bbcb7d1af0 (diff)
downloadlinux-f0913cd16e8a6608cf9558ccbe8fdf4d428ca3de.tar.gz
Merge branch 'topic/misc' into for-next
Generic updates for sound 3.6
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/caiaq/device.c2
-rw-r--r--sound/usb/mixer_quirks.c159
2 files changed, 104 insertions, 57 deletions
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index 64aed432ae22..7da0d0aa72cb 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -485,7 +485,7 @@ static int __devinit snd_probe(struct usb_interface *intf,
 		     const struct usb_device_id *id)
 {
 	int ret;
-	struct snd_card *card;
+	struct snd_card *card = NULL;
 	struct usb_device *device = interface_to_usbdev(intf);
 
 	ret = create_card(device, intf, &card);
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 41f4b6911920..690000db0ec0 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -42,6 +42,13 @@
 
 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)
 {
@@ -114,6 +121,25 @@ static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
 }
 
 /*
+ * 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
  *
  * format of remote control data:
@@ -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;
 	}