All of lore.kernel.org
 help / color / mirror / Atom feed
From: alexander.levin@verizon.com
To: "gregkh@linuxfoundation.org" <gregkh@linuxfoundation.org>
Cc: "stable@vger.kernel.org" <stable@vger.kernel.org>
Subject: [PATCH for 4.9 87/98] ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk
Date: Tue, 4 Apr 2017 19:32:35 +0000	[thread overview]
Message-ID: <20170404193158.19041-88-alexander.levin@verizon.com> (raw)
In-Reply-To: <20170404193158.19041-1-alexander.levin@verizon.com>

From: Detlef Urban <onkel@paraair.de>

[ Upstream commit d2bb390a2081a36ffe906724d2848d846f2aeb29 ]

Add mixer quirk for Tascam US-16x08 usb interface.
Even that this is an usb compliant device,
the input channels and DSP functions (EQ/Compressor) aren't accessible
by default.

Signed-off-by: Detlef Urban <onkel@paraair.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
---
 sound/usb/Makefile        |    1 +
 sound/usb/mixer_quirks.c  |    5 +
 sound/usb/mixer_us16x08.c | 1465 +++++++++++++++++++++++++++++++++++++++++++++
 sound/usb/mixer_us16x08.h |  122 ++++
 4 files changed, 1593 insertions(+)
 create mode 100644 sound/usb/mixer_us16x08.c
 create mode 100644 sound/usb/mixer_us16x08.h

diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index 2d2d122..42cb33b 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -10,6 +10,7 @@ snd-usb-audio-objs := 	card.o \
 			mixer.o \
 			mixer_quirks.o \
 			mixer_scarlett.o \
+			mixer_us16x08.o \
 			pcm.o \
 			proc.o \
 			quirks.o \
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 04991b0..4fa0053 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -43,6 +43,7 @@
 #include "mixer.h"
 #include "mixer_quirks.h"
 #include "mixer_scarlett.h"
+#include "mixer_us16x08.h"
 #include "helper.h"
 
 extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl;
@@ -1729,6 +1730,10 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
 		return err;
 
 	switch (mixer->chip->usb_id) {
+	/* Tascam US-16x08 */
+	case USB_ID(0x0644, 0x8047):
+		err = snd_us16x08_controls_create(mixer);
+		break;
 	case USB_ID(0x041e, 0x3020):
 	case USB_ID(0x041e, 0x3040):
 	case USB_ID(0x041e, 0x3042):
diff --git a/sound/usb/mixer_us16x08.c b/sound/usb/mixer_us16x08.c
new file mode 100644
index 0000000..301939b
--- /dev/null
+++ b/sound/usb/mixer_us16x08.c
@@ -0,0 +1,1465 @@
+/*
+ *   Tascam US-16x08 ALSA driver
+ *
+ *   Copyright (c) 2016 by Detlef Urban (onkel@paraair.de)
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/usb/audio-v2.h>
+
+#include <sound/core.h>
+#include <sound/control.h>
+
+#include "usbaudio.h"
+#include "mixer.h"
+#include "helper.h"
+
+#include "mixer_us16x08.h"
+
+/* USB control message templates */
+static const char route_msg[] = {
+	0x61,
+	0x02,
+	0x03, /* input from master (0x02) or input from computer bus (0x03) */
+	0x62,
+	0x02,
+	0x01, /* input index (0x01/0x02 eq. left/right) or bus (0x01-0x08) */
+	0x41,
+	0x01,
+	0x61,
+	0x02,
+	0x01,
+	0x62,
+	0x02,
+	0x01, /* output index (0x01-0x08) */
+	0x42,
+	0x01,
+	0x43,
+	0x01,
+	0x00,
+	0x00
+};
+
+static const char mix_init_msg1[] = {
+	0x71, 0x01, 0x00, 0x00
+};
+
+static const char mix_init_msg2[] = {
+	0x62, 0x02, 0x00, 0x61, 0x02, 0x04, 0xb1, 0x01, 0x00, 0x00
+};
+
+static const char mix_msg_in[] = {
+	/* default message head, equal to all mixers */
+	0x61, 0x02, 0x04, 0x62, 0x02, 0x01,
+	0x81, /* 0x06: Controller ID */
+	0x02, /* 0x07:  */
+	0x00, /* 0x08: Value of common mixer */
+	0x00,
+	0x00
+};
+
+static const char mix_msg_out[] = {
+	/* default message head, equal to all mixers */
+	0x61, 0x02, 0x02, 0x62, 0x02, 0x01,
+	0x81, /* 0x06: Controller ID */
+	0x02, /*                    0x07:  */
+	0x00, /*                    0x08: Value of common mixer */
+	0x00,
+	0x00
+};
+
+static const char bypass_msg_out[] = {
+	0x45,
+	0x02,
+	0x01, /* on/off flag */
+	0x00,
+	0x00
+};
+
+static const char bus_msg_out[] = {
+	0x44,
+	0x02,
+	0x01, /* on/off flag */
+	0x00,
+	0x00
+};
+
+static const char comp_msg[] = {
+	/* default message head, equal to all mixers */
+	0x61, 0x02, 0x04, 0x62, 0x02, 0x01,
+	0x91,
+	0x02,
+	0xf0, /* 0x08: Threshold db (8) (e0 ... 00) (+-0dB -- -32dB) x-32 */
+	0x92,
+	0x02,
+	0x0a, /* 0x0b: Ratio (0a,0b,0d,0f,11,14,19,1e,23,28,32,3c,50,a0,ff)  */
+	0x93,
+	0x02,
+	0x02, /* 0x0e: Attack (0x02 ... 0xc0) (2ms ... 200ms) */
+	0x94,
+	0x02,
+	0x01, /* 0x11: Release (0x01 ... 0x64) (10ms ... 1000ms) x*10  */
+	0x95,
+	0x02,
+	0x03, /* 0x14: gain (0 ... 20) (0dB .. 20dB) */
+	0x96,
+	0x02,
+	0x01,
+	0x97,
+	0x02,
+	0x01, /* 0x1a: main Comp switch (0 ... 1) (off ... on)) */
+	0x00,
+	0x00
+};
+
+static const char eqs_msq[] = {
+	/* default message head, equal to all mixers */
+	0x61, 0x02, 0x04, 0x62, 0x02, 0x01,
+	0x51, /*                0x06: Controller ID  */
+	0x02,
+	0x04, /* 0x08: EQ set num (0x01..0x04) (LOW, LOWMID, HIGHMID, HIGH)) */
+	0x52,
+	0x02,
+	0x0c, /* 0x0b: value dB (0 ... 12) (-12db .. +12db)  x-6 */
+	0x53,
+	0x02,
+	0x0f, /* 0x0e: value freq (32-47) (1.7kHz..18kHz) */
+	0x54,
+	0x02,
+	0x02, /* 0x11: band width (0-6) (Q16-Q0.25)  2^x/4 (EQ xxMID only) */
+	0x55,
+	0x02,
+	0x01, /* 0x14: main EQ switch (0 ... 1) (off ... on)) */
+	0x00,
+	0x00
+};
+
+/* compressor ratio map */
+static const char ratio_map[] = {
+	0x0a, 0x0b, 0x0d, 0x0f, 0x11, 0x14, 0x19, 0x1e,
+	0x23, 0x28, 0x32, 0x3c, 0x50, 0xa0, 0xff
+};
+
+/* route enumeration names */
+const const char *route_names[] = {
+	"Master Left", "Master Right", "Output 1", "Output 2", "Output 3",
+	"Output 4", "Output 5", "Output 6", "Output 7", "Output 8",
+};
+
+static int snd_us16x08_recv_urb(struct snd_usb_audio *chip,
+	unsigned char *buf, int size)
+{
+
+	mutex_lock(&chip->mutex);
+	snd_usb_ctl_msg(chip->dev,
+		usb_rcvctrlpipe(chip->dev, 0),
+		SND_US16X08_URB_METER_REQUEST,
+		SND_US16X08_URB_METER_REQUESTTYPE, 0, 0, buf, size);
+	mutex_unlock(&chip->mutex);
+	return 0;
+}
+
+/* wrapper function to send prepared URB buffer to usb device. Return an error
+ * code if something went wrong
+ */
+static int snd_us16x08_send_urb(struct snd_usb_audio *chip, char *buf, int size)
+{
+	int err = 0;
+
+	if (chip) {
+		err = snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0),
+			SND_US16X08_URB_REQUEST, SND_US16X08_URB_REQUESTTYPE,
+			0, 0, buf, size);
+	}
+
+	return err;
+}
+
+static int snd_us16x08_route_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	return snd_ctl_enum_info(uinfo, 1, 10, route_names);
+}
+
+static int snd_us16x08_route_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *elem = kcontrol->private_data;
+	int index = ucontrol->id.index;
+
+	/* route has no bias */
+	ucontrol->value.enumerated.item[0] = elem->cache_val[index];
+
+	return 0;
+}
+
+static int snd_us16x08_route_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *elem = kcontrol->private_data;
+	struct snd_usb_audio *chip = elem->head.mixer->chip;
+	int index = ucontrol->id.index;
+	char buf[sizeof(route_msg)];
+	int val, val_org, err = 0;
+
+	/* prepare the message buffer from template */
+	memcpy(buf, route_msg, sizeof(route_msg));
+
+	/*  get the new value (no bias for routes) */
+	val = ucontrol->value.enumerated.item[0];
+
+	/* sanity check */
+	if (val < 0 || val > 9)
+		return -EINVAL;
+
+	if (val < 2) {
+		/* input comes from a master channel */
+		val_org = val;
+		buf[2] = 0x02;
+	} else {
+		/* input comes from a computer channel */
+		buf[2] = 0x03;
+		val_org = val - 2;
+	}
+
+	/* place new route selection in URB message */
+	buf[5] = (unsigned char) (val_org & 0x0f) + 1;
+	/* place route selector in URB message */
+	buf[13] = index + 1;
+
+	err = snd_us16x08_send_urb(chip, buf, sizeof(route_msg));
+
+	if (err > 0) {
+		elem->cached |= 1 << index;
+		elem->cache_val[index] = val;
+	} else {
+		usb_audio_dbg(chip, "Failed to set routing, err:%d\n", err);
+	}
+
+	return err > 0 ? 1 : 0;
+}
+
+static int snd_us16x08_master_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->count = 1;
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->value.integer.max = SND_US16X08_KCMAX(kcontrol);
+	uinfo->value.integer.min = SND_US16X08_KCMIN(kcontrol);
+	uinfo->value.integer.step = SND_US16X08_KCSTEP(kcontrol);
+	return 0;
+}
+
+static int snd_us16x08_master_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *elem = kcontrol->private_data;
+	int index = ucontrol->id.index;
+
+	ucontrol->value.integer.value[0] = elem->cache_val[index];
+
+	return 0;
+}
+
+static int snd_us16x08_master_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *elem = kcontrol->private_data;
+	struct snd_usb_audio *chip = elem->head.mixer->chip;
+	char buf[sizeof(mix_msg_out)];
+	int val, err = 0;
+	int index = ucontrol->id.index;
+
+	/* prepare the message buffer from template */
+	memcpy(buf, mix_msg_out, sizeof(mix_msg_out));
+
+	/* new control value incl. bias*/
+	val = ucontrol->value.integer.value[0];
+
+	/* sanity check */
+	if (val < SND_US16X08_KCMIN(kcontrol)
+		|| val > SND_US16X08_KCMAX(kcontrol))
+		return -EINVAL;
+
+	buf[8] = val - SND_US16X08_KCBIAS(kcontrol);
+	buf[6] = elem->head.id;
+
+	/* place channel selector in URB message */
+	buf[5] = index + 1;
+	err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out));
+
+	if (err > 0) {
+		elem->cached |= 1 << index;
+		elem->cache_val[index] = val;
+	} else {
+		usb_audio_dbg(chip, "Failed to set master, err:%d\n", err);
+	}
+
+	return err > 0 ? 1 : 0;
+}
+
+static int snd_us16x08_bus_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *elem = kcontrol->private_data;
+	struct snd_usb_audio *chip = elem->head.mixer->chip;
+	char buf[sizeof(mix_msg_out)];
+	int val, err = 0;
+
+	val = ucontrol->value.integer.value[0];
+
+	/* prepare the message buffer from template */
+	switch (elem->head.id) {
+	case SND_US16X08_ID_BYPASS:
+		memcpy(buf, bypass_msg_out, sizeof(bypass_msg_out));
+		buf[2] = val;
+		err = snd_us16x08_send_urb(chip, buf, sizeof(bypass_msg_out));
+		break;
+	case SND_US16X08_ID_BUSS_OUT:
+		memcpy(buf, bus_msg_out, sizeof(bus_msg_out));
+		buf[2] = val;
+		err = snd_us16x08_send_urb(chip, buf, sizeof(bus_msg_out));
+		break;
+	case SND_US16X08_ID_MUTE:
+		memcpy(buf, mix_msg_out, sizeof(mix_msg_out));
+		buf[8] = val;
+		buf[6] = elem->head.id;
+		buf[5] = 1;
+		err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out));
+		break;
+	}
+
+	if (err > 0) {
+		elem->cached |= 1;
+		elem->cache_val[0] = val;
+	} else {
+		usb_audio_dbg(chip, "Failed to set buss param, err:%d\n", err);
+	}
+
+	return err > 0 ? 1 : 0;
+}
+
+static int snd_us16x08_bus_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *elem = kcontrol->private_data;
+
+	switch (elem->head.id) {
+	case SND_US16X08_ID_BUSS_OUT:
+		ucontrol->value.integer.value[0] = elem->cache_val[0];
+		break;
+	case SND_US16X08_ID_BYPASS:
+		ucontrol->value.integer.value[0] = elem->cache_val[0];
+		break;
+	case SND_US16X08_ID_MUTE:
+		ucontrol->value.integer.value[0] = elem->cache_val[0];
+		break;
+	}
+
+	return 0;
+}
+
+/* gets a current mixer value from common store */
+static int snd_us16x08_channel_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *elem = kcontrol->private_data;
+	int index = ucontrol->id.index;
+
+	ucontrol->value.integer.value[0] = elem->cache_val[index];
+
+	return 0;
+}
+
+static int snd_us16x08_channel_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *elem = kcontrol->private_data;
+	struct snd_usb_audio *chip = elem->head.mixer->chip;
+	char buf[sizeof(mix_msg_in)];
+	int val, err;
+	int index = ucontrol->id.index;
+
+	/* prepare URB message from template */
+	memcpy(buf, mix_msg_in, sizeof(mix_msg_in));
+
+	val = ucontrol->value.integer.value[0];
+
+	/* sanity check */
+	if (val < SND_US16X08_KCMIN(kcontrol)
+		|| val > SND_US16X08_KCMAX(kcontrol))
+		return -EINVAL;
+
+	/* add the bias to the new value */
+	buf[8] = val - SND_US16X08_KCBIAS(kcontrol);
+	buf[6] = elem->head.id;
+	buf[5] = index + 1;
+
+	err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_in));
+
+	if (err > 0) {
+		elem->cached |= 1 << index;
+		elem->cache_val[index] = val;
+	} else {
+		usb_audio_dbg(chip, "Failed to set channel, err:%d\n", err);
+	}
+
+	return err > 0 ? 1 : 0;
+}
+
+static int snd_us16x08_mix_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->count = 1;
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->value.integer.max = SND_US16X08_KCMAX(kcontrol);
+	uinfo->value.integer.min = SND_US16X08_KCMIN(kcontrol);
+	uinfo->value.integer.step = SND_US16X08_KCSTEP(kcontrol);
+	return 0;
+}
+
+static int snd_us16x08_comp_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *elem = kcontrol->private_data;
+	struct snd_us16x08_comp_store *store =
+		((struct snd_us16x08_comp_store *) elem->private_data);
+	int index = ucontrol->id.index;
+	int val_idx = COMP_STORE_IDX(elem->head.id);
+
+	ucontrol->value.integer.value[0] = store->val[val_idx][index];
+
+	return 0;
+}
+
+static int snd_us16x08_comp_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *elem = kcontrol->private_data;
+	struct snd_usb_audio *chip = elem->head.mixer->chip;
+	struct snd_us16x08_comp_store *store =
+		((struct snd_us16x08_comp_store *) elem->private_data);
+	int index = ucontrol->id.index;
+	char buf[sizeof(comp_msg)];
+	int val_idx, val;
+	int err = 0;
+
+	/* prepare compressor URB message from template  */
+	memcpy(buf, comp_msg, sizeof(comp_msg));
+
+	/* new control value incl. bias*/
+	val_idx = elem->head.id - SND_US16X08_ID_COMP_BASE;
+
+	val = ucontrol->value.integer.value[0];
+
+	/* sanity check */
+	if (val < SND_US16X08_KCMIN(kcontrol)
+		|| val > SND_US16X08_KCMAX(kcontrol))
+		return -EINVAL;
+
+	store->val[val_idx][index] = ucontrol->value.integer.value[0];
+
+	/* place comp values in message buffer watch bias! */
+	buf[8] = store->val[
+		COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][index]
+		- SND_US16X08_COMP_THRESHOLD_BIAS;
+	buf[11] = ratio_map[store->val[
+		COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][index]];
+	buf[14] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index]
+		+ SND_US16X08_COMP_ATTACK_BIAS;
+	buf[17] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][index]
+		+ SND_US16X08_COMP_RELEASE_BIAS;
+	buf[20] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index];
+	buf[26] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][index];
+
+	/* place channel selector in message buffer */
+	buf[5] = index + 1;
+
+	err = snd_us16x08_send_urb(chip, buf, sizeof(comp_msg));
+
+	if (err > 0) {
+		elem->cached |= 1 << index;
+		elem->cache_val[index] = val;
+	} else {
+		usb_audio_dbg(chip, "Failed to set compressor, err:%d\n", err);
+	}
+
+	return 1;
+}
+
+static int snd_us16x08_eqswitch_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	int val = 0;
+	struct usb_mixer_elem_info *elem = kcontrol->private_data;
+	struct snd_us16x08_eq_store *store =
+		((struct snd_us16x08_eq_store *) elem->private_data);
+	int index = ucontrol->id.index;
+
+	/* get low switch from cache is enough, cause all bands are together */
+	val = store->val[EQ_STORE_BAND_IDX(elem->head.id)]
+		[EQ_STORE_PARAM_IDX(elem->head.id)][index];
+	ucontrol->value.integer.value[0] = val;
+
+	return 0;
+}
+
+static int snd_us16x08_eqswitch_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *elem = kcontrol->private_data;
+	struct snd_usb_audio *chip = elem->head.mixer->chip;
+	struct snd_us16x08_eq_store *store =
+		((struct snd_us16x08_eq_store *) elem->private_data);
+	int index = ucontrol->id.index;
+
+	char buf[sizeof(eqs_msq)];
+	int val, err = 0;
+	int b_idx;
+
+	/* new control value incl. bias*/
+	val = ucontrol->value.integer.value[0] + SND_US16X08_KCBIAS(kcontrol);
+
+	/* prepare URB message from EQ template */
+	memcpy(buf, eqs_msq, sizeof(eqs_msq));
+
+	/* place channel index in URB message */
+	buf[5] = index + 1;
+	for (b_idx = 0; b_idx < SND_US16X08_ID_EQ_BAND_COUNT; b_idx++) {
+		/* all four EQ bands have to be enabled/disabled in once */
+		buf[20] = val;
+		buf[17] = store->val[b_idx][2][index];
+		buf[14] = store->val[b_idx][1][index];
+		buf[11] = store->val[b_idx][0][index];
+		buf[8] = b_idx + 1;
+		err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
+		if (err < 0)
+			break;
+		store->val[b_idx][3][index] = val;
+		msleep(15);
+	}
+
+	if (err > 0) {
+		elem->cached |= 1 << index;
+		elem->cache_val[index] = val;
+	} else {
+		usb_audio_dbg(chip, "Failed to set eq switch, err:%d\n", err);
+	}
+
+	return 1;
+}
+
+static int snd_us16x08_eq_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	int val = 0;
+	struct usb_mixer_elem_info *elem = kcontrol->private_data;
+	struct snd_us16x08_eq_store *store =
+		((struct snd_us16x08_eq_store *) elem->private_data);
+	int index = ucontrol->id.index;
+	int b_idx = EQ_STORE_BAND_IDX(elem->head.id) - 1;
+	int p_idx = EQ_STORE_PARAM_IDX(elem->head.id);
+
+	val = store->val[b_idx][p_idx][index];
+
+	ucontrol->value.integer.value[0] = val;
+
+	return 0;
+}
+
+static int snd_us16x08_eq_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *elem = kcontrol->private_data;
+	struct snd_usb_audio *chip = elem->head.mixer->chip;
+	struct snd_us16x08_eq_store *store =
+		((struct snd_us16x08_eq_store *) elem->private_data);
+	int index = ucontrol->id.index;
+	char buf[sizeof(eqs_msq)];
+	int val, err = 0;
+	int b_idx = EQ_STORE_BAND_IDX(elem->head.id) - 1;
+	int p_idx = EQ_STORE_PARAM_IDX(elem->head.id);
+
+	/* copy URB buffer from EQ template */
+	memcpy(buf, eqs_msq, sizeof(eqs_msq));
+
+	val = ucontrol->value.integer.value[0];
+
+	/* sanity check */
+	if (val < SND_US16X08_KCMIN(kcontrol)
+		|| val > SND_US16X08_KCMAX(kcontrol))
+		return -EINVAL;
+
+	store->val[b_idx][p_idx][index] = val;
+	buf[20] = store->val[b_idx][3][index];
+	buf[17] = store->val[b_idx][2][index];
+	buf[14] = store->val[b_idx][1][index];
+	buf[11] = store->val[b_idx][0][index];
+
+	/* place channel index in URB buffer */
+	buf[5] = index + 1;
+
+	/* place EQ band in URB buffer */
+	buf[8] = b_idx + 1;
+
+	err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
+
+	if (err > 0) {
+		/* store new value in EQ band cache */
+		elem->cached |= 1 << index;
+		elem->cache_val[index] = val;
+	} else {
+		usb_audio_dbg(chip, "Failed to set eq param, err:%d\n", err);
+	}
+
+	return 1;
+}
+
+static int snd_us16x08_meter_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->count = 1;
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->value.integer.max = 0x7FFF;
+	uinfo->value.integer.min = 0;
+
+	return 0;
+}
+
+/* calculate compressor index for reduction level request */
+static int snd_get_meter_comp_index(struct snd_us16x08_meter_store *store)
+{
+	int ret;
+
+	/* any channel active */
+	if (store->comp_active_index) {
+		/* check for stereo link */
+		if (store->comp_active_index & 0x20) {
+			/* reset comp_index to left channel*/
+			if (store->comp_index -
+				store->comp_active_index > 1)
+				store->comp_index =
+				store->comp_active_index;
+
+			ret = store->comp_index++ & 0x1F;
+		} else {
+			/* no stereo link */
+			ret = store->comp_active_index;
+		}
+	} else {
+		/* skip channels with no compressor active */
+		while (!store->comp_store->val[
+			COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)]
+			[store->comp_index - 1]
+			&& store->comp_index <= SND_US16X08_MAX_CHANNELS) {
+			store->comp_index++;
+		}
+		ret = store->comp_index++;
+		if (store->comp_index > SND_US16X08_MAX_CHANNELS)
+			store->comp_index = 1;
+	}
+	return ret;
+}
+
+/* retrieve the meter level values from URB message */
+static void get_meter_levels_from_urb(int s,
+	struct snd_us16x08_meter_store *store,
+	u8 *meter_urb)
+{
+	int val = MUC2(meter_urb, s) + (MUC3(meter_urb, s) << 8);
+
+	if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 &&
+		MUA2(meter_urb, s) == 0x04 && MUB0(meter_urb, s) == 0x62) {
+		if (MUC0(meter_urb, s) == 0x72)
+			store->meter_level[MUB2(meter_urb, s) - 1] = val;
+		if (MUC0(meter_urb, s) == 0xb2)
+			store->comp_level[MUB2(meter_urb, s) - 1] = val;
+	}
+	if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 &&
+		MUA2(meter_urb, s) == 0x02 && MUB0(meter_urb, s) == 0x62)
+		store->master_level[MUB2(meter_urb, s) - 1] = val;
+}
+
+/* Function to retrieve current meter values from the device.
+ *
+ * The device needs to be polled for meter values with an initial
+ * requests. It will return with a sequence of different meter value
+ * packages. The first request (case 0:) initiate this meter response sequence.
+ * After the third response, an additional request can be placed,
+ * to retrieve compressor reduction level value for given channel. This round
+ * trip channel selector will skip all inactive compressors.
+ * A mixer can interrupt this round-trip by selecting one ore two (stereo-link)
+ * specific channels.
+ */
+static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	int i, set;
+	struct usb_mixer_elem_info *elem = kcontrol->private_data;
+	struct snd_usb_audio *chip = elem->head.mixer->chip;
+	struct snd_us16x08_meter_store *store = elem->private_data;
+	u8 meter_urb[64];
+	char tmp[max(sizeof(mix_init_msg1), sizeof(mix_init_msg2))];
+
+	if (elem) {
+		store = (struct snd_us16x08_meter_store *) elem->private_data;
+		chip = elem->head.mixer->chip;
+	} else
+		return 0;
+
+	switch (kcontrol->private_value) {
+	case 0:
+		memcpy(tmp, mix_init_msg1, sizeof(mix_init_msg1));
+		snd_us16x08_send_urb(chip, tmp, 4);
+		snd_us16x08_recv_urb(chip, meter_urb,
+			sizeof(meter_urb));
+		kcontrol->private_value++;
+		break;
+	case 1:
+		snd_us16x08_recv_urb(chip, meter_urb,
+			sizeof(meter_urb));
+		kcontrol->private_value++;
+		break;
+	case 2:
+		snd_us16x08_recv_urb(chip, meter_urb,
+			sizeof(meter_urb));
+		kcontrol->private_value++;
+		break;
+	case 3:
+		memcpy(tmp, mix_init_msg2, sizeof(mix_init_msg2));
+		tmp[2] = snd_get_meter_comp_index(store);
+		snd_us16x08_send_urb(chip, tmp, 10);
+		snd_us16x08_recv_urb(chip, meter_urb,
+			sizeof(meter_urb));
+		kcontrol->private_value = 0;
+		break;
+	}
+
+	for (set = 0; set < 6; set++)
+		get_meter_levels_from_urb(set, store, meter_urb);
+
+	for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
+		ucontrol->value.integer.value[i] =
+			store ? store->meter_level[i] : 0;
+	}
+
+	ucontrol->value.integer.value[i++] = store ? store->master_level[0] : 0;
+	ucontrol->value.integer.value[i++] = store ? store->master_level[1] : 0;
+
+	for (i = 2; i < SND_US16X08_MAX_CHANNELS + 2; i++)
+		ucontrol->value.integer.value[i + SND_US16X08_MAX_CHANNELS] =
+		store ? store->comp_level[i - 2] : 0;
+
+	return 1;
+}
+
+static int snd_us16x08_meter_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *elem = kcontrol->private_data;
+	struct snd_us16x08_meter_store *store = elem->private_data;
+	int val;
+
+	val = ucontrol->value.integer.value[0];
+
+	/* sanity check */
+	if (val < 0 || val >= SND_US16X08_MAX_CHANNELS)
+		return -EINVAL;
+
+	store->comp_active_index = val;
+	store->comp_index = val;
+
+	return 1;
+}
+
+static struct snd_kcontrol_new snd_us16x08_ch_boolean_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 16,
+	.info = snd_us16x08_switch_info,
+	.get = snd_us16x08_channel_get,
+	.put = snd_us16x08_channel_put,
+	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
+};
+
+static struct snd_kcontrol_new snd_us16x08_ch_int_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 16,
+	.info = snd_us16x08_mix_info,
+	.get = snd_us16x08_channel_get,
+	.put = snd_us16x08_channel_put,
+	.private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133)
+};
+
+static struct snd_kcontrol_new snd_us16x08_pan_int_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 16,
+	.info = snd_us16x08_mix_info,
+	.get = snd_us16x08_channel_get,
+	.put = snd_us16x08_channel_put,
+	.private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 255)
+};
+
+static struct snd_kcontrol_new snd_us16x08_master_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 1,
+	.info = snd_us16x08_master_info,
+	.get = snd_us16x08_master_get,
+	.put = snd_us16x08_master_put,
+	.private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133)
+};
+
+static struct snd_kcontrol_new snd_us16x08_route_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 8,
+	.info = snd_us16x08_route_info,
+	.get = snd_us16x08_route_get,
+	.put = snd_us16x08_route_put,
+	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 9)
+};
+
+static struct snd_kcontrol_new snd_us16x08_bus_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 1,
+	.info = snd_us16x08_switch_info,
+	.get = snd_us16x08_bus_get,
+	.put = snd_us16x08_bus_put,
+	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
+};
+
+static struct snd_kcontrol_new snd_us16x08_compswitch_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 16,
+	.info = snd_us16x08_switch_info,
+	.get = snd_us16x08_comp_get,
+	.put = snd_us16x08_comp_put,
+	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
+};
+
+static struct snd_kcontrol_new snd_us16x08_comp_threshold_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 16,
+	.info = snd_us16x08_mix_info,
+	.get = snd_us16x08_comp_get,
+	.put = snd_us16x08_comp_put,
+	.private_value = SND_US16X08_KCSET(SND_US16X08_COMP_THRESHOLD_BIAS, 1,
+	0, 0x20)
+};
+
+static struct snd_kcontrol_new snd_us16x08_comp_ratio_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 16,
+	.info = snd_us16x08_mix_info,
+	.get = snd_us16x08_comp_get,
+	.put = snd_us16x08_comp_put,
+	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0,
+	sizeof(ratio_map) - 1), /*max*/
+};
+
+static struct snd_kcontrol_new snd_us16x08_comp_gain_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 16,
+	.info = snd_us16x08_mix_info,
+	.get = snd_us16x08_comp_get,
+	.put = snd_us16x08_comp_put,
+	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x14)
+};
+
+static struct snd_kcontrol_new snd_us16x08_comp_attack_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 16,
+	.info = snd_us16x08_mix_info,
+	.get = snd_us16x08_comp_get,
+	.put = snd_us16x08_comp_put,
+	.private_value =
+	SND_US16X08_KCSET(SND_US16X08_COMP_ATTACK_BIAS, 1, 0, 0xc6),
+};
+
+static struct snd_kcontrol_new snd_us16x08_comp_release_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 16,
+	.info = snd_us16x08_mix_info,
+	.get = snd_us16x08_comp_get,
+	.put = snd_us16x08_comp_put,
+	.private_value =
+	SND_US16X08_KCSET(SND_US16X08_COMP_RELEASE_BIAS, 1, 0, 0x63),
+};
+
+static struct snd_kcontrol_new snd_us16x08_eq_gain_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 16,
+	.info = snd_us16x08_mix_info,
+	.get = snd_us16x08_eq_get,
+	.put = snd_us16x08_eq_put,
+	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 24),
+};
+
+static struct snd_kcontrol_new snd_us16x08_eq_low_freq_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 16,
+	.info = snd_us16x08_mix_info,
+	.get = snd_us16x08_eq_get,
+	.put = snd_us16x08_eq_put,
+	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x1F),
+};
+
+static struct snd_kcontrol_new snd_us16x08_eq_mid_freq_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 16,
+	.info = snd_us16x08_mix_info,
+	.get = snd_us16x08_eq_get,
+	.put = snd_us16x08_eq_put,
+	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x3F)
+};
+
+static struct snd_kcontrol_new snd_us16x08_eq_mid_width_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 16,
+	.info = snd_us16x08_mix_info,
+	.get = snd_us16x08_eq_get,
+	.put = snd_us16x08_eq_put,
+	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x06)
+};
+
+static struct snd_kcontrol_new snd_us16x08_eq_high_freq_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 16,
+	.info = snd_us16x08_mix_info,
+	.get = snd_us16x08_eq_get,
+	.put = snd_us16x08_eq_put,
+	.private_value =
+	SND_US16X08_KCSET(SND_US16X08_EQ_HIGHFREQ_BIAS, 1, 0, 0x1F)
+};
+
+static struct snd_kcontrol_new snd_us16x08_eq_switch_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 16,
+	.info = snd_us16x08_switch_info,
+	.get = snd_us16x08_eqswitch_get,
+	.put = snd_us16x08_eqswitch_put,
+	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
+};
+
+static struct snd_kcontrol_new snd_us16x08_meter_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.count = 1,
+	.info = snd_us16x08_meter_info,
+	.get = snd_us16x08_meter_get,
+	.put = snd_us16x08_meter_put
+};
+
+/* control store preparation */
+
+/* setup compressor store and assign default value */
+static struct snd_us16x08_comp_store *snd_us16x08_create_comp_store(void)
+{
+	int i = 0;
+	struct snd_us16x08_comp_store *tmp =
+		kmalloc(sizeof(struct snd_us16x08_comp_store), GFP_KERNEL);
+
+	if (tmp == NULL)
+		return NULL;
+
+	for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
+		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][i]
+			= 0x20;
+		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][i] = 0x00;
+		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][i] = 0x00;
+		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][i] = 0x00;
+		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][i] = 0x00;
+		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][i] = 0x00;
+	}
+	return tmp;
+}
+
+/* setup EQ store and assign default values */
+static struct snd_us16x08_eq_store *snd_us16x08_create_eq_store(void)
+{
+	int i, b_idx;
+	struct snd_us16x08_eq_store *tmp =
+		kmalloc(sizeof(struct snd_us16x08_eq_store), GFP_KERNEL);
+
+	if (tmp == NULL)
+		return NULL;
+
+	for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
+		for (b_idx = 0; b_idx < SND_US16X08_ID_EQ_BAND_COUNT; b_idx++) {
+			tmp->val[b_idx][0][i] = 0x0c;
+			tmp->val[b_idx][3][i] = 0x00;
+			switch (b_idx) {
+			case 0: /* EQ Low */
+				tmp->val[b_idx][1][i] = 0x05;
+				tmp->val[b_idx][2][i] = 0xff;
+				break;
+			case 1: /* EQ Mid low */
+				tmp->val[b_idx][1][i] = 0x0e;
+				tmp->val[b_idx][2][i] = 0x02;
+				break;
+			case 2: /* EQ Mid High */
+				tmp->val[b_idx][1][i] = 0x1b;
+				tmp->val[b_idx][2][i] = 0x02;
+				break;
+			case 3: /* EQ High */
+				tmp->val[b_idx][1][i] = 0x2f
+					- SND_US16X08_EQ_HIGHFREQ_BIAS;
+				tmp->val[b_idx][2][i] = 0xff;
+				break;
+			}
+		}
+	}
+	return tmp;
+}
+
+struct snd_us16x08_meter_store *snd_us16x08_create_meter_store(void)
+{
+	struct snd_us16x08_meter_store *tmp =
+		kzalloc(sizeof(struct snd_us16x08_meter_store), GFP_KERNEL);
+
+	if (!tmp)
+		return NULL;
+	tmp->comp_index = 1;
+	tmp->comp_active_index = 0;
+	return tmp;
+
+}
+
+static int add_new_ctl(struct usb_mixer_interface *mixer,
+	const struct snd_kcontrol_new *ncontrol,
+	int index, int val_type, int channels,
+	const char *name, const void *opt,
+	void (*freeer)(struct snd_kcontrol *kctl),
+	struct usb_mixer_elem_info **elem_ret)
+{
+	struct snd_kcontrol *kctl;
+	struct usb_mixer_elem_info *elem;
+	int err;
+
+	usb_audio_dbg(mixer->chip, "us16x08 add mixer %s\n", name);
+
+	elem = kzalloc(sizeof(*elem), GFP_KERNEL);
+	if (!elem)
+		return -ENOMEM;
+
+	elem->head.mixer = mixer;
+	elem->head.resume = NULL;
+	elem->control = 0;
+	elem->idx_off = 0;
+	elem->head.id = index;
+	elem->val_type = val_type;
+	elem->channels = channels;
+	elem->private_data = (void *) opt;
+
+	kctl = snd_ctl_new1(ncontrol, elem);
+	if (!kctl) {
+		kfree(elem);
+		return -ENOMEM;
+	}
+
+	kctl->private_free = freeer;
+
+	strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
+
+	err = snd_usb_mixer_add_control(&elem->head, kctl);
+	if (err < 0)
+		return err;
+
+	if (elem_ret)
+		*elem_ret = elem;
+
+	return 0;
+}
+
+static struct snd_us16x08_control_params control_params;
+
+/* table of EQ controls */
+static struct snd_us16x08_control_params eq_controls[] = {
+	{ /* EQ switch */
+		.kcontrol_new = &snd_us16x08_eq_switch_ctl,
+		.control_id = SND_US16X08_ID_EQENABLE,
+		.type = USB_MIXER_BOOLEAN,
+		.num_channels = 16,
+		.name = "EQ Switch",
+		.freeer = snd_usb_mixer_elem_free
+	},
+	{ /* EQ low gain */
+		.kcontrol_new = &snd_us16x08_eq_gain_ctl,
+		.control_id = SND_US16X08_ID_EQLOWLEVEL,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "EQ Low Volume",
+		.freeer = snd_usb_mixer_elem_free
+	},
+	{ /* EQ low freq */
+		.kcontrol_new = &snd_us16x08_eq_low_freq_ctl,
+		.control_id = SND_US16X08_ID_EQLOWFREQ,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "EQ Low Frequence",
+		.freeer = NULL
+	},
+	{ /* EQ mid low gain */
+		.kcontrol_new = &snd_us16x08_eq_gain_ctl,
+		.control_id = SND_US16X08_ID_EQLOWMIDLEVEL,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "EQ MidLow Volume",
+		.freeer = snd_usb_mixer_elem_free
+	},
+	{ /* EQ mid low freq */
+		.kcontrol_new = &snd_us16x08_eq_mid_freq_ctl,
+		.control_id = SND_US16X08_ID_EQLOWMIDFREQ,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "EQ MidLow Frequence",
+		.freeer = NULL
+	},
+	{ /* EQ mid low Q */
+		.kcontrol_new = &snd_us16x08_eq_mid_width_ctl,
+		.control_id = SND_US16X08_ID_EQLOWMIDWIDTH,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "EQ MidQLow Q",
+		.freeer = NULL
+	},
+	{ /* EQ mid high gain */
+		.kcontrol_new = &snd_us16x08_eq_gain_ctl,
+		.control_id = SND_US16X08_ID_EQHIGHMIDLEVEL,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "EQ MidHigh Volume",
+		.freeer = snd_usb_mixer_elem_free
+	},
+	{ /* EQ mid high freq */
+		.kcontrol_new = &snd_us16x08_eq_mid_freq_ctl,
+		.control_id = SND_US16X08_ID_EQHIGHMIDFREQ,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "EQ MidHigh Frequence",
+		.freeer = NULL
+	},
+	{ /* EQ mid high Q */
+		.kcontrol_new = &snd_us16x08_eq_mid_width_ctl,
+		.control_id = SND_US16X08_ID_EQHIGHMIDWIDTH,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "EQ MidHigh Q",
+		.freeer = NULL
+	},
+	{ /* EQ high gain */
+		.kcontrol_new = &snd_us16x08_eq_gain_ctl,
+		.control_id = SND_US16X08_ID_EQHIGHLEVEL,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "EQ High Volume",
+		.freeer = snd_usb_mixer_elem_free
+	},
+	{ /* EQ low freq */
+		.kcontrol_new = &snd_us16x08_eq_high_freq_ctl,
+		.control_id = SND_US16X08_ID_EQHIGHFREQ,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "EQ High Frequence",
+		.freeer = NULL
+	},
+};
+
+/* table of compressor controls */
+static struct snd_us16x08_control_params comp_controls[] = {
+	{ /* Comp enable */
+		.kcontrol_new = &snd_us16x08_compswitch_ctl,
+		.control_id = SND_US16X08_ID_COMP_SWITCH,
+		.type = USB_MIXER_BOOLEAN,
+		.num_channels = 16,
+		.name = "Compressor Switch",
+		.freeer = snd_usb_mixer_elem_free
+	},
+	{ /* Comp threshold */
+		.kcontrol_new = &snd_us16x08_comp_threshold_ctl,
+		.control_id = SND_US16X08_ID_COMP_THRESHOLD,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "Compressor Threshold Volume",
+		.freeer = NULL
+	},
+	{ /* Comp ratio */
+		.kcontrol_new = &snd_us16x08_comp_ratio_ctl,
+		.control_id = SND_US16X08_ID_COMP_RATIO,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "Compressor Ratio",
+		.freeer = NULL
+	},
+	{ /* Comp attack */
+		.kcontrol_new = &snd_us16x08_comp_attack_ctl,
+		.control_id = SND_US16X08_ID_COMP_ATTACK,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "Compressor Attack",
+		.freeer = NULL
+	},
+	{ /* Comp release */
+		.kcontrol_new = &snd_us16x08_comp_release_ctl,
+		.control_id = SND_US16X08_ID_COMP_RELEASE,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "Compressor Release",
+		.freeer = NULL
+	},
+	{ /* Comp gain */
+		.kcontrol_new = &snd_us16x08_comp_gain_ctl,
+		.control_id = SND_US16X08_ID_COMP_GAIN,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "Compressor Volume",
+		.freeer = NULL
+	},
+};
+
+/* table of channel controls */
+static struct snd_us16x08_control_params channel_controls[] = {
+	{ /* Phase */
+		.kcontrol_new = &snd_us16x08_ch_boolean_ctl,
+		.control_id = SND_US16X08_ID_PHASE,
+		.type = USB_MIXER_BOOLEAN,
+		.num_channels = 16,
+		.name = "Phase Switch",
+		.freeer = snd_usb_mixer_elem_free,
+		.default_val = 0
+	},
+	{ /* Fader */
+		.kcontrol_new = &snd_us16x08_ch_int_ctl,
+		.control_id = SND_US16X08_ID_FADER,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "Line Volume",
+		.freeer = NULL,
+		.default_val = 127
+	},
+	{ /* Mute */
+		.kcontrol_new = &snd_us16x08_ch_boolean_ctl,
+		.control_id = SND_US16X08_ID_MUTE,
+		.type = USB_MIXER_BOOLEAN,
+		.num_channels = 16,
+		.name = "Mute Switch",
+		.freeer = NULL,
+		.default_val = 0
+	},
+	{ /* Pan */
+		.kcontrol_new = &snd_us16x08_pan_int_ctl,
+		.control_id = SND_US16X08_ID_PAN,
+		.type = USB_MIXER_U16,
+		.num_channels = 16,
+		.name = "Pan Left-Right Volume",
+		.freeer = NULL,
+		.default_val = 127
+	},
+};
+
+/* table of master controls */
+static struct snd_us16x08_control_params master_controls[] = {
+	{ /* Master */
+		.kcontrol_new = &snd_us16x08_master_ctl,
+		.control_id = SND_US16X08_ID_FADER,
+		.type = USB_MIXER_U8,
+		.num_channels = 16,
+		.name = "Master Volume",
+		.freeer = NULL,
+		.default_val = 127
+	},
+	{ /* Bypass */
+		.kcontrol_new = &snd_us16x08_bus_ctl,
+		.control_id = SND_US16X08_ID_BYPASS,
+		.type = USB_MIXER_BOOLEAN,
+		.num_channels = 16,
+		.name = "DSP Bypass Switch",
+		.freeer = NULL,
+		.default_val = 0
+	},
+	{ /* Buss out */
+		.kcontrol_new = &snd_us16x08_bus_ctl,
+		.control_id = SND_US16X08_ID_BUSS_OUT,
+		.type = USB_MIXER_BOOLEAN,
+		.num_channels = 16,
+		.name = "Buss Out Switch",
+		.freeer = NULL,
+		.default_val = 0
+	},
+	{ /* Master mute */
+		.kcontrol_new = &snd_us16x08_bus_ctl,
+		.control_id = SND_US16X08_ID_MUTE,
+		.type = USB_MIXER_BOOLEAN,
+		.num_channels = 16,
+		.name = "Master Mute Switch",
+		.freeer = NULL,
+		.default_val = 0
+	},
+
+};
+
+int snd_us16x08_controls_create(struct usb_mixer_interface *mixer)
+{
+	int i, j;
+	int err;
+	struct usb_mixer_elem_info *elem;
+	struct snd_us16x08_comp_store *comp_store;
+	struct snd_us16x08_meter_store *meter_store;
+	struct snd_us16x08_eq_store *eq_store;
+
+	/* just check for non-MIDI interface */
+	if (mixer->hostif->desc.bInterfaceNumber == 3) {
+
+		/* create compressor mixer elements */
+		comp_store = snd_us16x08_create_comp_store();
+		if (comp_store == NULL)
+			return -ENOMEM;
+
+		/* create eq store */
+		eq_store = snd_us16x08_create_eq_store();
+		if (eq_store == NULL) {
+			kfree(comp_store);
+			return -ENOMEM;
+		}
+
+		/* create meters store */
+		meter_store = snd_us16x08_create_meter_store();
+		if (meter_store == NULL) {
+			kfree(comp_store);
+			kfree(eq_store);
+			return -ENOMEM;
+		}
+
+		/* add routing control */
+		err = add_new_ctl(mixer, &snd_us16x08_route_ctl,
+			SND_US16X08_ID_ROUTE, USB_MIXER_U8, 8, "Line Out Route",
+			NULL, NULL, &elem);
+		if (err < 0) {
+			usb_audio_dbg(mixer->chip,
+				"Failed to create route control, err:%d\n",
+				err);
+			return err;
+		}
+		for (i = 0; i < 8; i++)
+			elem->cache_val[i] = i < 2 ? i : i + 2;
+		elem->cached = 0xff;
+
+		/* add master controls */
+		for (i = 0;
+			i < sizeof(master_controls)
+			/ sizeof(control_params);
+			i++) {
+
+			err = add_new_ctl(mixer,
+				master_controls[i].kcontrol_new,
+				master_controls[i].control_id,
+				master_controls[i].type,
+				master_controls[i].num_channels,
+				master_controls[i].name,
+				comp_store,
+				master_controls[i].freeer, &elem);
+			if (err < 0)
+				return err;
+			elem->cache_val[0] = master_controls[i].default_val;
+			elem->cached = 1;
+		}
+
+		/* add channel controls */
+		for (i = 0;
+			i < sizeof(channel_controls)
+			/ sizeof(control_params);
+			i++) {
+
+			err = add_new_ctl(mixer,
+				channel_controls[i].kcontrol_new,
+				channel_controls[i].control_id,
+				channel_controls[i].type,
+				channel_controls[i].num_channels,
+				channel_controls[i].name,
+				comp_store,
+				channel_controls[i].freeer, &elem);
+			if (err < 0)
+				return err;
+			for (j = 0; j < SND_US16X08_MAX_CHANNELS; j++) {
+				elem->cache_val[j] =
+					channel_controls[i].default_val;
+			}
+			elem->cached = 0xffff;
+		}
+
+		/* add EQ controls */
+		for (i = 0; i < sizeof(eq_controls) /
+			sizeof(control_params); i++) {
+
+			err = add_new_ctl(mixer,
+				eq_controls[i].kcontrol_new,
+				eq_controls[i].control_id,
+				eq_controls[i].type,
+				eq_controls[i].num_channels,
+				eq_controls[i].name,
+				eq_store,
+				eq_controls[i].freeer, NULL);
+			if (err < 0)
+				return err;
+		}
+
+		/* add compressor controls */
+		for (i = 0;
+			i < sizeof(comp_controls)
+			/ sizeof(control_params);
+			i++) {
+
+			err = add_new_ctl(mixer,
+				comp_controls[i].kcontrol_new,
+				comp_controls[i].control_id,
+				comp_controls[i].type,
+				comp_controls[i].num_channels,
+				comp_controls[i].name,
+				comp_store,
+				comp_controls[i].freeer, NULL);
+			if (err < 0)
+				return err;
+		}
+
+		/* meter function 'get' must access to compressor store
+		 * so place a reference here
+		 */
+		meter_store->comp_store = comp_store;
+		err = add_new_ctl(mixer, &snd_us16x08_meter_ctl,
+			SND_US16X08_ID_METER, USB_MIXER_U16, 0, "Level Meter",
+			(void *) meter_store, snd_usb_mixer_elem_free, NULL);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
diff --git a/sound/usb/mixer_us16x08.h b/sound/usb/mixer_us16x08.h
new file mode 100644
index 0000000..64f89b5
--- /dev/null
+++ b/sound/usb/mixer_us16x08.h
@@ -0,0 +1,122 @@
+#ifndef __USB_MIXER_US16X08_H
+#define __USB_MIXER_US16X08_H
+
+#define SND_US16X08_MAX_CHANNELS 16
+
+/* define some bias, cause some alsa-mixers wont work with
+ * negative ranges or if mixer-min != 0
+ */
+#define SND_US16X08_NO_BIAS 0
+#define SND_US16X08_FADER_BIAS 127
+#define SND_US16X08_EQ_HIGHFREQ_BIAS 0x20
+#define SND_US16X08_COMP_THRESHOLD_BIAS 0x20
+#define SND_US16X08_COMP_ATTACK_BIAS 2
+#define SND_US16X08_COMP_RELEASE_BIAS 1
+
+/* get macro for components of kcontrol private_value */
+#define SND_US16X08_KCBIAS(x) (((x)->private_value >> 24) & 0xff)
+#define SND_US16X08_KCSTEP(x) (((x)->private_value >> 16) & 0xff)
+#define SND_US16X08_KCMIN(x) (((x)->private_value >> 8) & 0xff)
+#define SND_US16X08_KCMAX(x) (((x)->private_value >> 0) & 0xff)
+/* set macro for kcontrol private_value */
+#define SND_US16X08_KCSET(bias, step, min, max)  \
+	(((bias) << 24) | ((step) << 16) | ((min) << 8) | (max))
+
+/* the URB request/type to control Tascam mixers */
+#define SND_US16X08_URB_REQUEST 0x1D
+#define SND_US16X08_URB_REQUESTTYPE 0x40
+
+/* the URB params to retrieve meter ranges */
+#define SND_US16X08_URB_METER_REQUEST       0x1e
+#define SND_US16X08_URB_METER_REQUESTTYPE   0xc0
+
+#define MUA0(x, y) ((x)[(y) * 10 + 4])
+#define MUA1(x, y) ((x)[(y) * 10 + 5])
+#define MUA2(x, y) ((x)[(y) * 10 + 6])
+#define MUB0(x, y) ((x)[(y) * 10 + 7])
+#define MUB1(x, y) ((x)[(y) * 10 + 8])
+#define MUB2(x, y) ((x)[(y) * 10 + 9])
+#define MUC0(x, y) ((x)[(y) * 10 + 10])
+#define MUC1(x, y) ((x)[(y) * 10 + 11])
+#define MUC2(x, y) ((x)[(y) * 10 + 12])
+#define MUC3(x, y) ((x)[(y) * 10 + 13])
+
+/* Common Channel control IDs */
+#define SND_US16X08_ID_BYPASS 0x45
+#define SND_US16X08_ID_BUSS_OUT 0x44
+#define SND_US16X08_ID_PHASE 0x85
+#define SND_US16X08_ID_MUTE 0x83
+#define SND_US16X08_ID_FADER 0x81
+#define SND_US16X08_ID_PAN 0x82
+#define SND_US16X08_ID_METER 0xB1
+
+#define SND_US16X08_ID_EQ_BAND_COUNT 4
+#define SND_US16X08_ID_EQ_PARAM_COUNT 4
+
+/* EQ level IDs */
+#define SND_US16X08_ID_EQLOWLEVEL 0x01
+#define SND_US16X08_ID_EQLOWMIDLEVEL 0x02
+#define SND_US16X08_ID_EQHIGHMIDLEVEL 0x03
+#define SND_US16X08_ID_EQHIGHLEVEL 0x04
+
+/* EQ frequence IDs */
+#define SND_US16X08_ID_EQLOWFREQ 0x11
+#define SND_US16X08_ID_EQLOWMIDFREQ 0x12
+#define SND_US16X08_ID_EQHIGHMIDFREQ 0x13
+#define SND_US16X08_ID_EQHIGHFREQ 0x14
+
+/* EQ width IDs */
+#define SND_US16X08_ID_EQLOWMIDWIDTH 0x22
+#define SND_US16X08_ID_EQHIGHMIDWIDTH 0x23
+
+#define SND_US16X08_ID_EQENABLE 0x30
+
+#define EQ_STORE_BAND_IDX(x) ((x) & 0xf)
+#define EQ_STORE_PARAM_IDX(x) (((x) & 0xf0) >> 4)
+
+#define SND_US16X08_ID_ROUTE 0x00
+
+/* Compressor Ids */
+#define SND_US16X08_ID_COMP_BASE	0x32
+#define SND_US16X08_ID_COMP_THRESHOLD	SND_US16X08_ID_COMP_BASE
+#define SND_US16X08_ID_COMP_RATIO	(SND_US16X08_ID_COMP_BASE + 1)
+#define SND_US16X08_ID_COMP_ATTACK	(SND_US16X08_ID_COMP_BASE + 2)
+#define SND_US16X08_ID_COMP_RELEASE	(SND_US16X08_ID_COMP_BASE + 3)
+#define SND_US16X08_ID_COMP_GAIN	(SND_US16X08_ID_COMP_BASE + 4)
+#define SND_US16X08_ID_COMP_SWITCH	(SND_US16X08_ID_COMP_BASE + 5)
+#define SND_US16X08_ID_COMP_COUNT	6
+
+#define COMP_STORE_IDX(x) ((x) - SND_US16X08_ID_COMP_BASE)
+
+struct snd_us16x08_eq_store {
+	u8 val[SND_US16X08_ID_EQ_BAND_COUNT][SND_US16X08_ID_EQ_PARAM_COUNT]
+		[SND_US16X08_MAX_CHANNELS];
+};
+
+struct snd_us16x08_comp_store {
+	u8 val[SND_US16X08_ID_COMP_COUNT][SND_US16X08_MAX_CHANNELS];
+};
+
+struct snd_us16x08_meter_store {
+	int meter_level[SND_US16X08_MAX_CHANNELS];
+	int master_level[2]; /* level of meter for master output */
+	int comp_index; /* round trip channel selector */
+	int comp_active_index; /* channel select from user space mixer */
+	int comp_level[16]; /* compressor reduction level */
+	struct snd_us16x08_comp_store *comp_store;
+};
+
+struct snd_us16x08_control_params {
+	struct snd_kcontrol_new *kcontrol_new;
+	int control_id;
+	int type;
+	int num_channels;
+	const char *name;
+	void (*freeer)(struct snd_kcontrol *kctl);
+	int default_val;
+};
+
+#define snd_us16x08_switch_info snd_ctl_boolean_mono_info
+
+int snd_us16x08_controls_create(struct usb_mixer_interface *mixer);
+#endif /* __USB_MIXER_US16X08_H */
-- 
2.9.3

  parent reply	other threads:[~2017-04-04 19:34 UTC|newest]

Thread overview: 253+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-04 19:32 [PATCH for 4.9 00/98] Quirks and new devices for 4.9 LTS alexander.levin
2017-04-04 19:32 ` [PATCH for 4.9 01/98] drm/sun4i: tcon: Move SoC specific quirks to a DT matched data structure alexander.levin
2017-04-05 10:16   ` gregkh
2017-04-05 14:07     ` alexander.levin
2017-04-10 15:11       ` gregkh
2017-04-04 19:32 ` [PATCH for 4.9 04/98] HID: i2c-hid: add a simple quirk to fix device defects alexander.levin
2017-04-10 15:18   ` Patch "HID: i2c-hid: add a simple quirk to fix device defects" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 02/98] clk: lpc32xx: add a quirk for PWM and MS clock dividers alexander.levin
2017-04-10 15:17   ` Patch "clk: lpc32xx: add a quirk for PWM and MS clock dividers" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 03/98] HID: usbhid: Add quirks for Mayflash/Dragonrise GameCube and PS3 adapters alexander.levin
2017-04-10 15:18   ` Patch "HID: usbhid: Add quirks for Mayflash/Dragonrise GameCube and PS3 adapters" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 07/98] net/mlx4_core: Use device ID defines alexander.levin
2017-04-10 16:06   ` Patch "net/mlx4_core: Use device ID defines" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 05/98] ASoC: Intel: bytct_rt5640: change default capture settings alexander.levin
2017-04-10 16:06   ` Patch "ASoC: Intel: bytct_rt5640: change default capture settings" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 06/98] arm64: dts: hisi: fix hip06 sas am-max-trans quirk alexander.levin
2017-04-10 16:06   ` Patch "arm64: dts: hisi: fix hip06 sas am-max-trans quirk" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 08/98] clocksource/drivers/arm_arch_timer: Don't assume clock runs in suspend alexander.levin
2017-04-10 16:06   ` Patch "clocksource/drivers/arm_arch_timer: Don't assume clock runs in suspend" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 09/98] scsi: ufs: introduce UFSHCD_QUIRK_PRDT_BYTE_GRAN quirk alexander.levin
2017-04-10 16:06   ` Patch "scsi: ufs: introduce UFSHCD_QUIRK_PRDT_BYTE_GRAN quirk" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 10/98] HID: sensor-hub add quirk for Microsoft Surface 3 alexander.levin
2017-04-10 16:06   ` Patch "HID: sensor-hub add quirk for Microsoft Surface 3" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 12/98] HID: multitouch: enable the Surface 3 Type Cover to report multitouch data alexander.levin
2017-04-10 16:06   ` Patch "HID: multitouch: enable the Surface 3 Type Cover to report multitouch data" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 11/98] HID: sensor-hub: add quirk for Microchip MM7150 alexander.levin
2017-04-10 16:06   ` Patch "HID: sensor-hub: add quirk for Microchip MM7150" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 13/98] HID: multitouch: do not retrieve all reports for all devices alexander.levin
2017-04-10 16:06   ` Patch "HID: multitouch: do not retrieve all reports for all devices" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 15/98] scsi: ufs: ensure that host pa_tactivate is higher than device alexander.levin
2017-04-10 16:06   ` Patch "scsi: ufs: ensure that host pa_tactivate is higher than device" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 14/98] mmc: sdhci-msm: Enable few quirks alexander.levin
2017-04-10 16:06   ` Patch "mmc: sdhci-msm: Enable few quirks" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 16/98] svcauth_gss: Close connection when dropping an incoming message alexander.levin
2017-04-10 16:06   ` Patch "svcauth_gss: Close connection when dropping an incoming message" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 18/98] arm64: PCI: Manage controller-specific data on per-controller basis alexander.levin
2017-04-10 16:06   ` Patch "arm64: PCI: Manage controller-specific data on per-controller basis" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 17/98] x86/intel_idle: Add CPU model 0x4a (Atom Z34xx series) alexander.levin
2017-04-10 16:06   ` Patch "x86/intel_idle: Add CPU model 0x4a (Atom Z34xx series)" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 21/98] PCI/ACPI: Extend pci_mcfg_lookup() to return ECAM config accessors alexander.levin
2017-04-10 16:06   ` Patch "PCI/ACPI: Extend pci_mcfg_lookup() to return ECAM config accessors" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 20/98] arm64: PCI: Search ACPI namespace to ensure ECAM space is reserved alexander.levin
2017-04-10 16:06   ` Patch "arm64: PCI: Search ACPI namespace to ensure ECAM space is reserved" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 19/98] arm64: PCI: Add local struct device pointers alexander.levin
2017-04-10 16:06   ` Patch "arm64: PCI: Add local struct device pointers" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 23/98] PCI: Add MCFG quirks for Qualcomm QDF2432 host controller alexander.levin
2017-04-10 16:06   ` Patch "PCI: Add MCFG quirks for Qualcomm QDF2432 host controller" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 22/98] PCI/ACPI: Check for platform-specific MCFG quirks alexander.levin
2017-04-10 16:06   ` Patch "PCI/ACPI: Check for platform-specific MCFG quirks" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 25/98] PCI: thunder-pem: Factor out resource lookup alexander.levin
2017-04-10 16:06   ` Patch "PCI: thunder-pem: Factor out resource lookup" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 24/98] PCI: Add MCFG quirks for HiSilicon Hip05/06/07 host controllers alexander.levin
2017-04-10 16:06   ` Patch "PCI: Add MCFG quirks for HiSilicon Hip05/06/07 host controllers" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 26/98] PCI: Add MCFG quirks for Cavium ThunderX pass2.x host controller alexander.levin
2017-04-10 16:06   ` Patch "PCI: Add MCFG quirks for Cavium ThunderX pass2.x host controller" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 28/98] PCI: Add MCFG quirks for X-Gene host controller alexander.levin
2017-04-10 16:06   ` Patch "PCI: Add MCFG quirks for X-Gene host controller" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 27/98] PCI: Add MCFG quirks for Cavium ThunderX pass1.x host controller alexander.levin
2017-04-10 16:06   ` Patch "PCI: Add MCFG quirks for Cavium ThunderX pass1.x host controller" has been added to the 4.9-stable tree gregkh
2017-04-11  4:38   ` [PATCH for 4.9 27/98] PCI: Add MCFG quirks for Cavium ThunderX pass1.x host controller gregkh
2017-04-04 19:32 ` [PATCH for 4.9 29/98] PCI: Explain ARM64 ACPI/MCFG quirk Kconfig and build strategy alexander.levin
2017-04-10 16:06   ` Patch "PCI: Explain ARM64 ACPI/MCFG quirk Kconfig and build strategy" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 30/98] scsi: ufs: add quirk to increase host PA_SaveConfigTime alexander.levin
2017-04-10 16:06   ` Patch "scsi: ufs: add quirk to increase host PA_SaveConfigTime" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 31/98] ALSA: usb-audio: add implicit fb quirk for Axe-Fx II alexander.levin
2017-04-10 16:06   ` Patch "ALSA: usb-audio: add implicit fb quirk for Axe-Fx II" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 34/98] platform/x86: acer-wmi: Only supports AMW0_GUID1 on acer family alexander.levin
2017-04-10 16:06   ` Patch "platform/x86: acer-wmi: Only supports AMW0_GUID1 on acer family" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 33/98] ALSA: usb-audio: Add native DSD support for TEAC 501/503 DAC alexander.levin
2017-04-10 16:06   ` Patch "ALSA: usb-audio: Add native DSD support for TEAC 501/503 DAC" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 32/98] PCI: Expand "VPD access disabled" quirk message alexander.levin
2017-04-10 16:06   ` Patch "PCI: Expand "VPD access disabled" quirk message" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 36/98] HID: asus: Fix keyboard support alexander.levin
2017-04-10 16:06   ` Patch "HID: asus: Fix keyboard support" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 35/98] HID: asus: Add i2c touchpad support alexander.levin
2017-04-10 16:06   ` Patch "HID: asus: Add i2c touchpad support" has been added to the 4.9-stable tree gregkh
2017-04-10 16:50     ` Greg KH
2017-04-04 19:32 ` [PATCH for 4.9 37/98] HID: microsoft: Add Surface 4 type cover pro 4 not JP versions alexander.levin
2017-04-10 16:06   ` Patch "HID: microsoft: Add Surface 4 type cover pro 4 not JP versions" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 39/98] nvme: simplify stripe quirk alexander.levin
2017-04-10 16:06   ` Patch "nvme: simplify stripe quirk" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 38/98] HID: multitouch: enable the Surface 4 Type Cover Pro (JP) to report multitouch data alexander.levin
2017-04-10 16:06   ` Patch "HID: multitouch: enable the Surface 4 Type Cover Pro (JP) to report multitouch data" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "HID: multitouch: enable the Surface 4 Type Cover Pro (JP) to report multitouch data" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 40/98] ACPI / sysfs: Provide quirk mechanism to prevent GPE flooding alexander.levin
2017-04-10 16:06   ` Patch "ACPI / sysfs: Provide quirk mechanism to prevent GPE flooding" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 41/98] HID: usbhid: Add quirk for the Futaba TOSD-5711BB VFD alexander.levin
2017-04-10 16:06   ` Patch "HID: usbhid: Add quirk for the Futaba TOSD-5711BB VFD" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 44/98] drm/i915: fix INTEL_BDW_IDS definition alexander.levin
2017-04-10 16:06   ` Patch "drm/i915: fix INTEL_BDW_IDS definition" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "drm/i915: fix INTEL_BDW_IDS definition" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 42/98] HID: usbhid: Add quirk for Mayflash/Dragonrise DolphinBar alexander.levin
2017-04-10 16:06   ` Patch "HID: usbhid: Add quirk for Mayflash/Dragonrise DolphinBar." has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 43/98] drm/edid: constify edid quirk list alexander.levin
2017-04-10 16:06   ` Patch "drm/edid: constify edid quirk list" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "drm/edid: constify edid quirk list" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 47/98] ASoC: Intel: bytcr_rt5640: quirks for Insyde devices alexander.levin
2017-04-10 16:06   ` Patch "ASoC: Intel: bytcr_rt5640: quirks for Insyde devices" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "ASoC: Intel: bytcr_rt5640: quirks for Insyde devices" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 46/98] drm/i915: actually drive the BDW reserved IDs alexander.levin
2017-04-10 16:06   ` Patch "drm/i915: actually drive the BDW reserved IDs" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "drm/i915: actually drive the BDW reserved IDs" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 45/98] drm/i915: more .is_mobile cleanups for BDW alexander.levin
2017-04-10 16:06   ` Patch "drm/i915: more .is_mobile cleanups for BDW" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "drm/i915: more .is_mobile cleanups for BDW" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 48/98] scsi: ufs: introduce a new ufshcd_statea UFSHCD_STATE_EH_SCHEDULED alexander.levin
2017-04-10 16:06   ` Patch "scsi: ufs: introduce a new ufshcd_statea UFSHCD_STATE_EH_SCHEDULED" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 50/98] ARM: OMAP2+: Fix init for multiple quirks for the same SoC alexander.levin
2017-04-10 16:06   ` Patch "ARM: OMAP2+: Fix init for multiple quirks for the same SoC" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "ARM: OMAP2+: Fix init for multiple quirks for the same SoC" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 49/98] scsi: ufs: issue link starup 2 times if device isn't active alexander.levin
2017-04-10 16:06   ` Patch "scsi: ufs: issue link starup 2 times if device isn't active" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 51/98] scsi: ufs: refactor device descriptor reading alexander.levin
2017-04-10 15:47   ` [PATCH " gregkh
2017-04-10 16:06   ` Patch "scsi: ufs: refactor device descriptor reading" has been added to the 4.9-stable tree gregkh
2017-04-10 16:19     ` Greg KH
2017-04-04 19:32 ` [PATCH for 4.9 52/98] usb: chipidea: msm: Rely on core to override AHBBURST alexander.levin
2017-04-10 16:06   ` Patch "usb: chipidea: msm: Rely on core to override AHBBURST" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "usb: chipidea: msm: Rely on core to override AHBBURST" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 53/98] serial: 8250_omap: Add OMAP_DMA_TX_KICK quirk for AM437x alexander.levin
2017-04-10 16:06   ` Patch "serial: 8250_omap: Add OMAP_DMA_TX_KICK quirk for AM437x" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "serial: 8250_omap: Add OMAP_DMA_TX_KICK quirk for AM437x" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 55/98] Input: gpio_keys - add support for GPIO descriptors alexander.levin
2017-04-10 16:06   ` Patch "Input: gpio_keys - add support for GPIO descriptors" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 54/98] HID: whitespace cleanup alexander.levin
2017-04-10 15:47   ` [PATCH " gregkh
2017-04-04 19:32 ` [PATCH for 4.9 57/98] ARM: davinci: PM: support da8xx DT platforms alexander.levin
2017-04-10 16:06   ` Patch "ARM: davinci: PM: support da8xx DT platforms" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 56/98] amd-xgbe: Prepare for working with more than one type of phy alexander.levin
2017-04-10 16:06   ` Patch "amd-xgbe: Prepare for working with more than one type of phy" has been added to the 4.9-stable tree gregkh
2017-04-10 16:42     ` Tom Lendacky
2017-04-10 16:47       ` Greg KH
2017-04-04 19:32 ` [PATCH for 4.9 59/98] usb: xhci: add quirk flag for broken PED bits alexander.levin
2017-04-10 16:06   ` Patch "usb: xhci: add quirk flag for broken PED bits" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "usb: xhci: add quirk flag for broken PED bits" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 60/98] usb: host: xhci-plat: enable BROKEN_PED quirk if platform requested alexander.levin
2017-04-10 16:06   ` Patch "usb: host: xhci-plat: enable BROKEN_PED quirk if platform requested" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "usb: host: xhci-plat: enable BROKEN_PED quirk if platform requested" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 58/98] ARM: davinci: add skeleton for pdata-quirks alexander.levin
2017-04-10 16:06   ` Patch "ARM: davinci: add skeleton for pdata-quirks" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "ARM: davinci: add skeleton for pdata-quirks" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 62/98] drm/mga: remove device_is_agp callback alexander.levin
2017-04-10 16:06   ` Patch "drm/mga: remove device_is_agp callback" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "drm/mga: remove device_is_agp callback" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 63/98] ARM: dts: STiH407-family: set snps,dis_u3_susphy_quirk alexander.levin
2017-04-10 16:06   ` Patch "ARM: dts: STiH407-family: set snps,dis_u3_susphy_quirk" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 61/98] usb: dwc3: host: pass quirk-broken-port-ped property for known broken revisions alexander.levin
2017-04-10 16:06   ` Patch "usb: dwc3: host: pass quirk-broken-port-ped property for known broken revisions" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "usb: dwc3: host: pass quirk-broken-port-ped property for known broken revisions" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 64/98] PCI: Add ACS quirk for Intel Union Point alexander.levin
2017-04-10 16:06   ` Patch "PCI: Add ACS quirk for Intel Union Point" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "PCI: Add ACS quirk for Intel Union Point" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 65/98] PCI: xgene: Fix double free on init error alexander.levin
2017-04-10 16:06   ` Patch "PCI: xgene: Fix double free on init error" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "PCI: xgene: Fix double free on init error" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 66/98] [media] rx51: broken build alexander.levin
2017-04-10 16:06   ` Patch "[media] rx51: broken build" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "[media] rx51: broken build" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 68/98] ACPI / button: Change default behavior to lid_init_state=open alexander.levin
2017-04-10 16:06   ` Patch "ACPI / button: Change default behavior to lid_init_state=open" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "ACPI / button: Change default behavior to lid_init_state=open" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 67/98] sata: ahci-da850: implement a workaround for the softreset quirk alexander.levin
2017-04-10 16:06   ` Patch "sata: ahci-da850: implement a workaround for the softreset quirk" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "sata: ahci-da850: implement a workaround for the softreset quirk" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 71/98] ASoC: Intel: Baytrail: add quirk for Lenovo Thinkpad 10 alexander.levin
2017-04-10 16:06   ` Patch "ASoC: Intel: Baytrail: add quirk for Lenovo Thinkpad 10" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "ASoC: Intel: Baytrail: add quirk for Lenovo Thinkpad 10" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 70/98] ASoC: codecs: rt5670: add quirk for Lenovo Thinkpad 10 alexander.levin
2017-04-10 16:06   ` Patch "ASoC: codecs: rt5670: add quirk for Lenovo Thinkpad 10" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "ASoC: codecs: rt5670: add quirk for Lenovo Thinkpad 10" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 69/98] ASoC: rt5670: Add missing 10EC5072 ACPI ID alexander.levin
2017-04-10 16:06   ` Patch "ASoC: rt5670: Add missing 10EC5072 ACPI ID" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 72/98] ASoC: Intel: cht_bsw_rt5645: harden ACPI device detection alexander.levin
2017-04-10 16:06   ` Patch "ASoC: Intel: cht_bsw_rt5645: harden ACPI device detection" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "ASoC: Intel: cht_bsw_rt5645: harden ACPI device detection" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 74/98] ACPI: save NVS memory for Lenovo G50-45 alexander.levin
2017-04-10 16:06   ` Patch "ACPI: save NVS memory for Lenovo G50-45" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "ACPI: save NVS memory for Lenovo G50-45" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 73/98] ASoC: Intel: cht_bsw_rt5645: add Baytrail MCLK support alexander.levin
2017-04-10 16:06   ` Patch "ASoC: Intel: cht_bsw_rt5645: add Baytrail MCLK support" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "ASoC: Intel: cht_bsw_rt5645: add Baytrail MCLK support" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 76/98] ASoC: sun4i-i2s: Add quirks to handle a31 compatible alexander.levin
2017-04-10 16:06   ` Patch "ASoC: sun4i-i2s: Add quirks to handle a31 compatible" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "ASoC: sun4i-i2s: Add quirks to handle a31 compatible" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 75/98] usb: musb: da8xx: Fix host mode suspend alexander.levin
2017-04-10 16:06   ` Patch "usb: musb: da8xx: Fix host mode suspend" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "usb: musb: da8xx: Fix host mode suspend" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 77/98] HID: wacom: don't apply generic settings to old devices alexander.levin
2017-04-10 16:06   ` Patch "HID: wacom: don't apply generic settings to old devices" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "HID: wacom: don't apply generic settings to old devices" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 78/98] arm: kernel: Add SMC structure parameter alexander.levin
2017-04-10 16:06   ` Patch "arm: kernel: Add SMC structure parameter" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "arm: kernel: Add SMC structure parameter" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 81/98] ARM: smccc: Update HVC comment to describe new quirk parameter alexander.levin
2017-04-10 16:06   ` Patch "ARM: smccc: Update HVC comment to describe new quirk parameter" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "ARM: smccc: Update HVC comment to describe new quirk parameter" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 79/98] firmware: qcom: scm: Fix interrupted SCM calls alexander.levin
2017-04-10 16:06   ` Patch "firmware: qcom: scm: Fix interrupted SCM calls" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "firmware: qcom: scm: Fix interrupted SCM calls" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 80/98] drm/msm/adreno: move function declarations to header file alexander.levin
2017-04-10 16:06   ` Patch "drm/msm/adreno: move function declarations to header file" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 82/98] PCI: Add Broadcom Northstar2 PAXC quirk for device class and MPSS alexander.levin
2017-04-10 16:06   ` Patch "PCI: Add Broadcom Northstar2 PAXC quirk for device class and MPSS" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "PCI: Add Broadcom Northstar2 PAXC quirk for device class and MPSS" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 84/98] mmc: sdhci-of-esdhc: remove default broken-cd for ARM alexander.levin
2017-04-10 16:06   ` Patch "mmc: sdhci-of-esdhc: remove default broken-cd for ARM" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "mmc: sdhci-of-esdhc: remove default broken-cd for ARM" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 83/98] PCI: Disable MSI for HiSilicon Hip06/Hip07 Root Ports alexander.levin
2017-04-10 16:06   ` Patch "PCI: Disable MSI for HiSilicon Hip06/Hip07 Root Ports" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "PCI: Disable MSI for HiSilicon Hip06/Hip07 Root Ports" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 85/98] PCI: Sort the list of devices with D3 delay quirk by ID alexander.levin
2017-04-10 16:06   ` Patch "PCI: Sort the list of devices with D3 delay quirk by ID" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "PCI: Sort the list of devices with D3 delay quirk by ID" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 86/98] PCI: Add ACS quirk for Qualcomm QDF2400 and QDF2432 alexander.levin
2017-04-10 16:06   ` Patch "PCI: Add ACS quirk for Qualcomm QDF2400 and QDF2432" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "PCI: Add ACS quirk for Qualcomm QDF2400 and QDF2432" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 89/98] watchdog: s3c2410: Fix infinite interrupt in soft mode alexander.levin
2017-04-10 16:06   ` Patch "watchdog: s3c2410: Fix infinite interrupt in soft mode" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "watchdog: s3c2410: Fix infinite interrupt in soft mode" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 88/98] ALSA: usb-audio: Fix memory leak and corruption in mixer_us16x08.c alexander.levin
2017-04-10 15:42   ` gregkh
2017-04-04 19:32 ` alexander.levin [this message]
2017-04-10 15:41   ` [PATCH for 4.9 87/98] ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk gregkh
2017-04-04 19:32 ` [PATCH for 4.9 92/98] tools/power turbostat: decode Baytrail CC6 and MC6 demotion configuration alexander.levin
2017-04-10 16:06   ` Patch "tools/power turbostat: decode Baytrail CC6 and MC6 demotion configuration" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "tools/power turbostat: decode Baytrail CC6 and MC6 demotion configuration" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 91/98] platform/x86: asus-wmi: Detect quirk_no_rfkill from the DSDT alexander.levin
2017-04-10 16:06   ` Patch "platform/x86: asus-wmi: Detect quirk_no_rfkill from the DSDT" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "platform/x86: asus-wmi: Detect quirk_no_rfkill from the DSDT" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 90/98] platform/x86: asus-wmi: Set specified XUSB2PR value for X550LB alexander.levin
2017-04-10 16:06   ` Patch "platform/x86: asus-wmi: Set specified XUSB2PR value for X550LB" has been added to the 4.9-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 93/98] tools/power turbostat: dump Atom P-states correctly alexander.levin
2017-04-10 16:06   ` Patch "tools/power turbostat: dump Atom P-states correctly" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "tools/power turbostat: dump Atom P-states correctly" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 94/98] x86/reboot/quirks: Add ASUS EeeBook X205TA reboot quirk alexander.levin
2017-04-10 16:06   ` Patch "x86/reboot/quirks: Add ASUS EeeBook X205TA reboot quirk" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "x86/reboot/quirks: Add ASUS EeeBook X205TA reboot quirk" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 97/98] x86/reboot/quirks: Fix typo in ASUS EeeBook X205TA reboot quirk alexander.levin
2017-04-10 16:06   ` Patch "x86/reboot/quirks: Fix typo in ASUS EeeBook X205TA reboot quirk" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "x86/reboot/quirks: Fix typo in ASUS EeeBook X205TA reboot quirk" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 95/98] x86/reboot/quirks: Add ASUS EeeBook X205TA/W reboot quirk alexander.levin
2017-04-10 16:06   ` Patch "x86/reboot/quirks: Add ASUS EeeBook X205TA/W reboot quirk" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "x86/reboot/quirks: Add ASUS EeeBook X205TA/W reboot quirk" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 96/98] usb-storage: Add ignore-residue quirk for Initio INIC-3619 alexander.levin
2017-04-10 16:06   ` Patch "usb-storage: Add ignore-residue quirk for Initio INIC-3619" has been added to the 4.9-stable tree gregkh
2017-04-10 16:17   ` Patch "usb-storage: Add ignore-residue quirk for Initio INIC-3619" has been added to the 4.10-stable tree gregkh
2017-04-04 19:32 ` [PATCH for 4.9 98/98] can: flexcan: add quirk FLEXCAN_QUIRK_ENABLE_EACEN_RRS alexander.levin
2017-04-10 16:06   ` Patch "can: flexcan: add quirk FLEXCAN_QUIRK_ENABLE_EACEN_RRS" has been added to the 4.9-stable tree gregkh
2017-04-10 16:21     ` Marc Kleine-Budde
2017-04-10 16:37       ` Greg KH
2017-04-10 16:17   ` Patch "can: flexcan: add quirk FLEXCAN_QUIRK_ENABLE_EACEN_RRS" has been added to the 4.10-stable tree gregkh
2017-04-04 20:11 ` [PATCH for 4.9 00/98] Quirks and new devices for 4.9 LTS gregkh
2017-04-10 16:18   ` gregkh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170404193158.19041-88-alexander.levin@verizon.com \
    --to=alexander.levin@verizon.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.