Merge branch 'topic/misc' into for-linus
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index b20e1ce..75de40a 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -25,6 +25,8 @@
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <sound/core.h>
+#include <sound/jack.h>
+
 #include "hda_codec.h"
 #include "hda_local.h"
 
@@ -37,7 +39,20 @@
 #define CONEXANT_HP_EVENT	0x37
 #define CONEXANT_MIC_EVENT	0x38
 
+/* Conexant 5051 specific */
 
+#define CXT5051_SPDIF_OUT	0x1C
+#define CXT5051_PORTB_EVENT	0x38
+#define CXT5051_PORTC_EVENT	0x39
+
+
+struct conexant_jack {
+
+	hda_nid_t nid;
+	int type;
+	struct snd_jack *jack;
+
+};
 
 struct conexant_spec {
 
@@ -83,6 +98,9 @@
 
 	unsigned int spdif_route;
 
+	/* jack detection */
+	struct snd_array jacks;
+
 	/* dynamic controls, init_verbs and input_mux */
 	struct auto_pin_cfg autocfg;
 	struct hda_input_mux private_imux;
@@ -329,6 +347,86 @@
 				     &spec->cur_mux[adc_idx]);
 }
 
+static int conexant_add_jack(struct hda_codec *codec,
+		hda_nid_t nid, int type)
+{
+	struct conexant_spec *spec;
+	struct conexant_jack *jack;
+	const char *name;
+
+	spec = codec->spec;
+	snd_array_init(&spec->jacks, sizeof(*jack), 32);
+	jack = snd_array_new(&spec->jacks);
+	name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
+
+	if (!jack)
+		return -ENOMEM;
+
+	jack->nid = nid;
+	jack->type = type;
+
+	return snd_jack_new(codec->bus->card, name, type, &jack->jack);
+}
+
+static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
+{
+	struct conexant_spec *spec = codec->spec;
+	struct conexant_jack *jacks = spec->jacks.list;
+
+	if (jacks) {
+		int i;
+		for (i = 0; i < spec->jacks.used; i++) {
+			if (jacks->nid == nid) {
+				unsigned int present;
+				present = snd_hda_codec_read(codec, nid, 0,
+						AC_VERB_GET_PIN_SENSE, 0) &
+					AC_PINSENSE_PRESENCE;
+
+				present = (present) ? jacks->type : 0 ;
+
+				snd_jack_report(jacks->jack,
+						present);
+			}
+			jacks++;
+		}
+	}
+}
+
+static int conexant_init_jacks(struct hda_codec *codec)
+{
+#ifdef CONFIG_SND_JACK
+	struct conexant_spec *spec = codec->spec;
+	int i;
+
+	for (i = 0; i < spec->num_init_verbs; i++) {
+		const struct hda_verb *hv;
+
+		hv = spec->init_verbs[i];
+		while (hv->nid) {
+			int err = 0;
+			switch (hv->param ^ AC_USRSP_EN) {
+			case CONEXANT_HP_EVENT:
+				err = conexant_add_jack(codec, hv->nid,
+						SND_JACK_HEADPHONE);
+				conexant_report_jack(codec, hv->nid);
+				break;
+			case CXT5051_PORTC_EVENT:
+			case CONEXANT_MIC_EVENT:
+				err = conexant_add_jack(codec, hv->nid,
+						SND_JACK_MICROPHONE);
+				conexant_report_jack(codec, hv->nid);
+				break;
+			}
+			if (err < 0)
+				return err;
+			++hv;
+		}
+	}
+#endif
+	return 0;
+
+}
+
 static int conexant_init(struct hda_codec *codec)
 {
 	struct conexant_spec *spec = codec->spec;
@@ -341,6 +439,16 @@
 
 static void conexant_free(struct hda_codec *codec)
 {
+#ifdef CONFIG_SND_JACK
+	struct conexant_spec *spec = codec->spec;
+	if (spec->jacks.list) {
+		struct conexant_jack *jacks = spec->jacks.list;
+		int i;
+		for (i = 0; i < spec->jacks.used; i++)
+			snd_device_free(codec->bus->card, &jacks[i].jack);
+		snd_array_free(&spec->jacks);
+	}
+#endif
 	kfree(codec->spec);
 }
 
@@ -1526,9 +1634,6 @@
 /* Conexant 5051 specific */
 static hda_nid_t cxt5051_dac_nids[1] = { 0x10 };
 static hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 };
-#define CXT5051_SPDIF_OUT	0x1C
-#define CXT5051_PORTB_EVENT	0x38
-#define CXT5051_PORTC_EVENT	0x39
 
 static struct hda_channel_mode cxt5051_modes[1] = {
 	{ 2, NULL },
@@ -1608,6 +1713,7 @@
 static void cxt5051_hp_unsol_event(struct hda_codec *codec,
 				   unsigned int res)
 {
+	int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20;
 	switch (res >> 26) {
 	case CONEXANT_HP_EVENT:
 		cxt5051_hp_automute(codec);
@@ -1619,6 +1725,7 @@
 		cxt5051_portc_automic(codec);
 		break;
 	}
+	conexant_report_jack(codec, nid);
 }
 
 static struct snd_kcontrol_new cxt5051_mixers[] = {
@@ -1693,6 +1800,7 @@
 static int cxt5051_init(struct hda_codec *codec)
 {
 	conexant_init(codec);
+	conexant_init_jacks(codec);
 	if (codec->patch_ops.unsol_event) {
 		cxt5051_hp_automute(codec);
 		cxt5051_portb_automic(codec);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 0bd4e6b..9065ebf 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -8467,6 +8467,7 @@
 	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
 	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
 	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
+	SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
 	SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
 	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
 	SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
@@ -16638,9 +16639,9 @@
 	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
 	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
 	{ .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
-	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
 	{ .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
 	  .patch = patch_alc883 },
+	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
 	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
 	{} /* terminator */
 };
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 5184888..31e44e3 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -298,30 +298,107 @@
 static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control =
 SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);
 
-static int outmixer_event(struct snd_soc_dapm_widget *w,
+/* Left analog microphone selection */
+static const char *twl4030_analoglmic_texts[] =
+		{"Off", "Main mic", "Headset mic", "Invalid", "AUXL",
+		 "Invalid", "Invalid", "Invalid", "Carkit mic"};
+
+static const struct soc_enum twl4030_analoglmic_enum =
+	SOC_ENUM_SINGLE(TWL4030_REG_ANAMICL, 0,
+			ARRAY_SIZE(twl4030_analoglmic_texts),
+			twl4030_analoglmic_texts);
+
+static const struct snd_kcontrol_new twl4030_dapm_analoglmic_control =
+SOC_DAPM_ENUM("Route", twl4030_analoglmic_enum);
+
+/* Right analog microphone selection */
+static const char *twl4030_analogrmic_texts[] =
+		{"Off", "Sub mic", "Invalid", "Invalid", "AUXR"};
+
+static const struct soc_enum twl4030_analogrmic_enum =
+	SOC_ENUM_SINGLE(TWL4030_REG_ANAMICR, 0,
+			ARRAY_SIZE(twl4030_analogrmic_texts),
+			twl4030_analogrmic_texts);
+
+static const struct snd_kcontrol_new twl4030_dapm_analogrmic_control =
+SOC_DAPM_ENUM("Route", twl4030_analogrmic_enum);
+
+/* TX1 L/R Analog/Digital microphone selection */
+static const char *twl4030_micpathtx1_texts[] =
+		{"Analog", "Digimic0"};
+
+static const struct soc_enum twl4030_micpathtx1_enum =
+	SOC_ENUM_SINGLE(TWL4030_REG_ADCMICSEL, 0,
+			ARRAY_SIZE(twl4030_micpathtx1_texts),
+			twl4030_micpathtx1_texts);
+
+static const struct snd_kcontrol_new twl4030_dapm_micpathtx1_control =
+SOC_DAPM_ENUM("Route", twl4030_micpathtx1_enum);
+
+/* TX2 L/R Analog/Digital microphone selection */
+static const char *twl4030_micpathtx2_texts[] =
+		{"Analog", "Digimic1"};
+
+static const struct soc_enum twl4030_micpathtx2_enum =
+	SOC_ENUM_SINGLE(TWL4030_REG_ADCMICSEL, 2,
+			ARRAY_SIZE(twl4030_micpathtx2_texts),
+			twl4030_micpathtx2_texts);
+
+static const struct snd_kcontrol_new twl4030_dapm_micpathtx2_control =
+SOC_DAPM_ENUM("Route", twl4030_micpathtx2_enum);
+
+/*
+ * This function filters out the non valid mux settings, named as "Invalid"
+ * in the enum texts.
+ * Just refuse to set an invalid mux mode.
+ */
+static int twl4030_enum_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 	int ret = 0;
 	int val;
 
-	switch (e->reg) {
-	case TWL4030_REG_PREDL_CTL:
-	case TWL4030_REG_PREDR_CTL:
-	case TWL4030_REG_EAR_CTL:
-		val = w->value >> e->shift_l;
-		if (val == 3) {
-			printk(KERN_WARNING
-			"Invalid MUX setting for register 0x%02x (%d)\n",
-			      e->reg, val);
-			ret = -1;
-		}
-		break;
+	val = w->value >> e->shift_l;
+	if (!strcmp("Invalid", e->texts[val])) {
+		printk(KERN_WARNING "Invalid MUX setting on 0x%02x (%d)\n",
+			e->reg, val);
+		ret = -1;
 	}
 
 	return ret;
 }
 
+static int micpath_event(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct soc_enum *e = (struct soc_enum *)w->kcontrols->private_value;
+	unsigned char adcmicsel, micbias_ctl;
+
+	adcmicsel = twl4030_read_reg_cache(w->codec, TWL4030_REG_ADCMICSEL);
+	micbias_ctl = twl4030_read_reg_cache(w->codec, TWL4030_REG_MICBIAS_CTL);
+	/* Prepare the bits for the given TX path:
+	 * shift_l == 0: TX1 microphone path
+	 * shift_l == 2: TX2 microphone path */
+	if (e->shift_l) {
+		/* TX2 microphone path */
+		if (adcmicsel & TWL4030_TX2IN_SEL)
+			micbias_ctl |= TWL4030_MICBIAS2_CTL; /* digimic */
+		else
+			micbias_ctl &= ~TWL4030_MICBIAS2_CTL;
+	} else {
+		/* TX1 microphone path */
+		if (adcmicsel & TWL4030_TX1IN_SEL)
+			micbias_ctl |= TWL4030_MICBIAS1_CTL; /* digimic */
+		else
+			micbias_ctl &= ~TWL4030_MICBIAS1_CTL;
+	}
+
+	twl4030_write(w->codec, TWL4030_REG_MICBIAS_CTL, micbias_ctl);
+
+	return 0;
+}
+
 static int handsfree_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
@@ -503,162 +580,6 @@
 	return err;
 }
 
-static int twl4030_get_left_input(struct snd_kcontrol *kcontrol,
-	struct snd_ctl_elem_value *ucontrol)
-{
-	struct snd_soc_codec *codec = kcontrol->private_data;
-	u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
-	int result = 0;
-
-	/* one bit must be set a time */
-	reg &= TWL4030_CKMIC_EN | TWL4030_AUXL_EN | TWL4030_HSMIC_EN
-			| TWL4030_MAINMIC_EN;
-	if (reg != 0) {
-		result++;
-		while ((reg & 1) == 0) {
-			result++;
-			reg >>= 1;
-		}
-	}
-
-	ucontrol->value.integer.value[0] = result;
-	return 0;
-}
-
-static int twl4030_put_left_input(struct snd_kcontrol *kcontrol,
-	struct snd_ctl_elem_value *ucontrol)
-{
-	struct snd_soc_codec *codec = kcontrol->private_data;
-	int value = ucontrol->value.integer.value[0];
-	u8 anamicl, micbias, avadc_ctl;
-
-	anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
-	anamicl &= ~(TWL4030_CKMIC_EN | TWL4030_AUXL_EN | TWL4030_HSMIC_EN
-			| TWL4030_MAINMIC_EN);
-	micbias = twl4030_read_reg_cache(codec, TWL4030_REG_MICBIAS_CTL);
-	micbias &= ~(TWL4030_HSMICBIAS_EN | TWL4030_MICBIAS1_EN);
-	avadc_ctl = twl4030_read_reg_cache(codec, TWL4030_REG_AVADC_CTL);
-
-	switch (value) {
-	case 1:
-		anamicl |= TWL4030_MAINMIC_EN;
-		micbias |= TWL4030_MICBIAS1_EN;
-		break;
-	case 2:
-		anamicl |= TWL4030_HSMIC_EN;
-		micbias |= TWL4030_HSMICBIAS_EN;
-		break;
-	case 3:
-		anamicl |= TWL4030_AUXL_EN;
-		break;
-	case 4:
-		anamicl |= TWL4030_CKMIC_EN;
-		break;
-	default:
-		break;
-	}
-
-	/* If some input is selected, enable amp and ADC */
-	if (value != 0) {
-		anamicl |= TWL4030_MICAMPL_EN;
-		avadc_ctl |= TWL4030_ADCL_EN;
-	} else {
-		anamicl &= ~TWL4030_MICAMPL_EN;
-		avadc_ctl &= ~TWL4030_ADCL_EN;
-	}
-
-	twl4030_write(codec, TWL4030_REG_ANAMICL, anamicl);
-	twl4030_write(codec, TWL4030_REG_MICBIAS_CTL, micbias);
-	twl4030_write(codec, TWL4030_REG_AVADC_CTL, avadc_ctl);
-
-	return 1;
-}
-
-static int twl4030_get_right_input(struct snd_kcontrol *kcontrol,
-	struct snd_ctl_elem_value *ucontrol)
-{
-	struct snd_soc_codec *codec = kcontrol->private_data;
-	u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICR);
-	int value = 0;
-
-	reg &= TWL4030_SUBMIC_EN|TWL4030_AUXR_EN;
-	switch (reg) {
-	case TWL4030_SUBMIC_EN:
-		value = 1;
-		break;
-	case TWL4030_AUXR_EN:
-		value = 2;
-		break;
-	default:
-		break;
-	}
-
-	ucontrol->value.integer.value[0] = value;
-	return 0;
-}
-
-static int twl4030_put_right_input(struct snd_kcontrol *kcontrol,
-	struct snd_ctl_elem_value *ucontrol)
-{
-	struct snd_soc_codec *codec = kcontrol->private_data;
-	int value = ucontrol->value.integer.value[0];
-	u8 anamicr, micbias, avadc_ctl;
-
-	anamicr = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICR);
-	anamicr &= ~(TWL4030_SUBMIC_EN|TWL4030_AUXR_EN);
-	micbias = twl4030_read_reg_cache(codec, TWL4030_REG_MICBIAS_CTL);
-	micbias &= ~TWL4030_MICBIAS2_EN;
-	avadc_ctl = twl4030_read_reg_cache(codec, TWL4030_REG_AVADC_CTL);
-
-	switch (value) {
-	case 1:
-		anamicr |= TWL4030_SUBMIC_EN;
-		micbias |= TWL4030_MICBIAS2_EN;
-		break;
-	case 2:
-		anamicr |= TWL4030_AUXR_EN;
-		break;
-	default:
-		break;
-	}
-
-	if (value != 0) {
-		anamicr |= TWL4030_MICAMPR_EN;
-		avadc_ctl |= TWL4030_ADCR_EN;
-	} else {
-		anamicr &= ~TWL4030_MICAMPR_EN;
-		avadc_ctl &= ~TWL4030_ADCR_EN;
-	}
-
-	twl4030_write(codec, TWL4030_REG_ANAMICR, anamicr);
-	twl4030_write(codec, TWL4030_REG_MICBIAS_CTL, micbias);
-	twl4030_write(codec, TWL4030_REG_AVADC_CTL, avadc_ctl);
-
-	return 1;
-}
-
-static const char *twl4030_left_in_sel[] = {
-	"None",
-	"Main Mic",
-	"Headset Mic",
-	"Line In",
-	"Carkit Mic",
-};
-
-static const char *twl4030_right_in_sel[] = {
-	"None",
-	"Sub Mic",
-	"Line In",
-};
-
-static const struct soc_enum twl4030_left_input_mux =
-	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl4030_left_in_sel),
-		twl4030_left_in_sel);
-
-static const struct soc_enum twl4030_right_input_mux =
-	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl4030_right_in_sel),
-		twl4030_right_in_sel);
-
 /*
  * FGAIN volume control:
  * from -62 to 0 dB in 1 dB steps (mute instead of -63 dB)
@@ -741,18 +662,15 @@
 		TWL4030_REG_EAR_CTL, 4, 3, 0, output_tvl),
 
 	/* Common capture gain controls */
-	SOC_DOUBLE_R_TLV("Capture Volume",
+	SOC_DOUBLE_R_TLV("TX1 Digital Capture Volume",
 		TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA,
 		0, 0x1f, 0, digital_capture_tlv),
+	SOC_DOUBLE_R_TLV("TX2 Digital Capture Volume",
+		TWL4030_REG_AVTXL2PGA, TWL4030_REG_AVTXR2PGA,
+		0, 0x1f, 0, digital_capture_tlv),
 
-	SOC_DOUBLE_TLV("Input Boost Volume", TWL4030_REG_ANAMIC_GAIN,
+	SOC_DOUBLE_TLV("Analog Capture Volume", TWL4030_REG_ANAMIC_GAIN,
 		0, 3, 5, 0, input_gain_tlv),
-
-	/* Input source controls */
-	SOC_ENUM_EXT("Left Input Source", twl4030_left_input_mux,
-		twl4030_get_left_input, twl4030_put_left_input),
-	SOC_ENUM_EXT("Right Input Source", twl4030_right_input_mux,
-		twl4030_get_right_input, twl4030_put_right_input),
 };
 
 /* add non dapm controls */
@@ -772,9 +690,19 @@
 }
 
 static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
-	SND_SOC_DAPM_INPUT("INL"),
-	SND_SOC_DAPM_INPUT("INR"),
+	/* Left channel inputs */
+	SND_SOC_DAPM_INPUT("MAINMIC"),
+	SND_SOC_DAPM_INPUT("HSMIC"),
+	SND_SOC_DAPM_INPUT("AUXL"),
+	SND_SOC_DAPM_INPUT("CARKITMIC"),
+	/* Right channel inputs */
+	SND_SOC_DAPM_INPUT("SUBMIC"),
+	SND_SOC_DAPM_INPUT("AUXR"),
+	/* Digital microphones (Stereo) */
+	SND_SOC_DAPM_INPUT("DIGIMIC0"),
+	SND_SOC_DAPM_INPUT("DIGIMIC1"),
 
+	/* Outputs */
 	SND_SOC_DAPM_OUTPUT("OUTL"),
 	SND_SOC_DAPM_OUTPUT("OUTR"),
 	SND_SOC_DAPM_OUTPUT("EARPIECE"),
@@ -810,14 +738,14 @@
 	/* Output MUX controls */
 	/* Earpiece */
 	SND_SOC_DAPM_MUX_E("Earpiece Mux", SND_SOC_NOPM, 0, 0,
-		&twl4030_dapm_earpiece_control, outmixer_event,
+		&twl4030_dapm_earpiece_control, twl4030_enum_event,
 		SND_SOC_DAPM_PRE_REG),
 	/* PreDrivL/R */
 	SND_SOC_DAPM_MUX_E("PredriveL Mux", SND_SOC_NOPM, 0, 0,
-		&twl4030_dapm_predrivel_control, outmixer_event,
+		&twl4030_dapm_predrivel_control, twl4030_enum_event,
 		SND_SOC_DAPM_PRE_REG),
 	SND_SOC_DAPM_MUX_E("PredriveR Mux", SND_SOC_NOPM, 0, 0,
-		&twl4030_dapm_predriver_control, outmixer_event,
+		&twl4030_dapm_predriver_control, twl4030_enum_event,
 		SND_SOC_DAPM_PRE_REG),
 	/* HeadsetL/R */
 	SND_SOC_DAPM_MUX("HeadsetL Mux", SND_SOC_NOPM, 0, 0,
@@ -837,8 +765,50 @@
 		&twl4030_dapm_handsfreer_control, handsfree_event,
 		SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
 
-	SND_SOC_DAPM_ADC("ADCL", "Left Capture", SND_SOC_NOPM, 0, 0),
-	SND_SOC_DAPM_ADC("ADCR", "Right Capture", SND_SOC_NOPM, 0, 0),
+	/* Introducing four virtual ADC, since TWL4030 have four channel for
+	   capture */
+	SND_SOC_DAPM_ADC("ADC Virtual Left1", "Left Front Capture",
+		SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_ADC("ADC Virtual Right1", "Right Front Capture",
+		SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_ADC("ADC Virtual Left2", "Left Rear Capture",
+		SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_ADC("ADC Virtual Right2", "Right Rear Capture",
+		SND_SOC_NOPM, 0, 0),
+
+	/* Analog/Digital mic path selection.
+	   TX1 Left/Right: either analog Left/Right or Digimic0
+	   TX2 Left/Right: either analog Left/Right or Digimic1 */
+	SND_SOC_DAPM_MUX_E("TX1 Capture Route", SND_SOC_NOPM, 0, 0,
+		&twl4030_dapm_micpathtx1_control, micpath_event,
+		SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD|
+		SND_SOC_DAPM_POST_REG),
+	SND_SOC_DAPM_MUX_E("TX2 Capture Route", SND_SOC_NOPM, 0, 0,
+		&twl4030_dapm_micpathtx2_control, micpath_event,
+		SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD|
+		SND_SOC_DAPM_POST_REG),
+
+	/* Analog input muxes with power switch for the physical ADCL/R */
+	SND_SOC_DAPM_MUX_E("Analog Left Capture Route",
+		TWL4030_REG_AVADC_CTL, 3, 0, &twl4030_dapm_analoglmic_control,
+		twl4030_enum_event, SND_SOC_DAPM_PRE_REG),
+	SND_SOC_DAPM_MUX_E("Analog Right Capture Route",
+		TWL4030_REG_AVADC_CTL, 1, 0, &twl4030_dapm_analogrmic_control,
+		twl4030_enum_event, SND_SOC_DAPM_PRE_REG),
+
+	SND_SOC_DAPM_PGA("Analog Left Amplifier",
+		TWL4030_REG_ANAMICL, 4, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Analog Right Amplifier",
+		TWL4030_REG_ANAMICR, 4, 0, NULL, 0),
+
+	SND_SOC_DAPM_PGA("Digimic0 Enable",
+		TWL4030_REG_ADCMICSEL, 1, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Digimic1 Enable",
+		TWL4030_REG_ADCMICSEL, 3, 0, NULL, 0),
+
+	SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0),
+	SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0),
+	SND_SOC_DAPM_MICBIAS("Headset Mic Bias", TWL4030_REG_MICBIAS_CTL, 2, 0),
 };
 
 static const struct snd_soc_dapm_route intercon[] = {
@@ -894,9 +864,39 @@
 	{"HFL", NULL, "HandsfreeL Mux"},
 	{"HFR", NULL, "HandsfreeR Mux"},
 
-	/* inputs */
-	{"ADCL", NULL, "INL"},
-	{"ADCR", NULL, "INR"},
+	/* Capture path */
+	{"Analog Left Capture Route", "Main mic", "MAINMIC"},
+	{"Analog Left Capture Route", "Headset mic", "HSMIC"},
+	{"Analog Left Capture Route", "AUXL", "AUXL"},
+	{"Analog Left Capture Route", "Carkit mic", "CARKITMIC"},
+
+	{"Analog Right Capture Route", "Sub mic", "SUBMIC"},
+	{"Analog Right Capture Route", "AUXR", "AUXR"},
+
+	{"Analog Left Amplifier", NULL, "Analog Left Capture Route"},
+	{"Analog Right Amplifier", NULL, "Analog Right Capture Route"},
+
+	{"Digimic0 Enable", NULL, "DIGIMIC0"},
+	{"Digimic1 Enable", NULL, "DIGIMIC1"},
+
+	/* TX1 Left capture path */
+	{"TX1 Capture Route", "Analog", "Analog Left Amplifier"},
+	{"TX1 Capture Route", "Digimic0", "Digimic0 Enable"},
+	/* TX1 Right capture path */
+	{"TX1 Capture Route", "Analog", "Analog Right Amplifier"},
+	{"TX1 Capture Route", "Digimic0", "Digimic0 Enable"},
+	/* TX2 Left capture path */
+	{"TX2 Capture Route", "Analog", "Analog Left Amplifier"},
+	{"TX2 Capture Route", "Digimic1", "Digimic1 Enable"},
+	/* TX2 Right capture path */
+	{"TX2 Capture Route", "Analog", "Analog Right Amplifier"},
+	{"TX2 Capture Route", "Digimic1", "Digimic1 Enable"},
+
+	{"ADC Virtual Left1", NULL, "TX1 Capture Route"},
+	{"ADC Virtual Right1", NULL, "TX1 Capture Route"},
+	{"ADC Virtual Left2", NULL, "TX2 Capture Route"},
+	{"ADC Virtual Right2", NULL, "TX2 Capture Route"},
+
 };
 
 static int twl4030_add_widgets(struct snd_soc_codec *codec)
@@ -923,6 +923,7 @@
 	twl4030_write(codec, TWL4030_REG_ANAMICL,
 		anamicl | TWL4030_CNCL_OFFSET_START);
 
+
 	/* wait for offset cancellation to complete */
 	do {
 		/* this takes a little while, so don't slam i2c */
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index 54615c7..442e5a8 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -147,6 +147,13 @@
 #define TWL4030_AVADC_CLK_PRIORITY	0x04
 #define TWL4030_ADCR_EN			0x02
 
+/* TWL4030_REG_ADCMICSEL (0x08) Fields */
+
+#define TWL4030_DIGMIC1_EN		0x08
+#define TWL4030_TX2IN_SEL		0x04
+#define TWL4030_DIGMIC0_EN		0x02
+#define TWL4030_TX1IN_SEL		0x01
+
 /* AUDIO_IF (0x0E) Fields */
 
 #define TWL4030_AIF_SLAVE_EN		0x80
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
index f67579d..4935d1b 100644
--- a/sound/soc/davinci/davinci-sffsdr.c
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -24,6 +24,7 @@
 #include <sound/soc-dapm.h>
 
 #include <asm/dma.h>
+#include <asm/mach-types.h>
 #include <asm/plat-sffsdr/sffsdr-fpga.h>
 
 #include <mach/mcbsp.h>
@@ -115,6 +116,9 @@
 {
 	int ret;
 
+	if (!machine_is_sffsdr())
+		return -EINVAL;
+
 	sffsdr_snd_device = platform_device_alloc("soc-audio", 0);
 	if (!sffsdr_snd_device) {
 		printk(KERN_ERR "platform device allocation failed\n");
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index c670d08..53b9fb1 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -61,9 +61,9 @@
 
 	__pxa2xx_pcm_hw_free(substream);
 
-	if (prtd->dma_ch) {
+	if (prtd->dma_ch >= 0) {
 		pxa_free_dma(prtd->dma_ch);
-		prtd->dma_ch = 0;
+		prtd->dma_ch = -1;
 	}
 
 	return 0;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index b098c0b..f73c134 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1300,6 +1300,8 @@
 /**
  * snd_soc_new_pcms - create new sound card and pcms
  * @socdev: the SoC audio device
+ * @idx: ALSA card index
+ * @xid: card identification
  *
  * Create a new sound card based upon the codec and interface pcms.
  *
@@ -1472,7 +1474,7 @@
  * snd_soc_cnew - create new control
  * @_template: control template
  * @data: control private data
- * @lnng_name: control long name
+ * @long_name: control long name
  *
  * Create a new mixer control from a template control.
  *
@@ -1522,7 +1524,7 @@
 /**
  * snd_soc_get_enum_double - enumerated double mixer get callback
  * @kcontrol: mixer control
- * @uinfo: control element information
+ * @ucontrol: control element information
  *
  * Callback to get the value of a double enumerated mixer.
  *
@@ -1551,7 +1553,7 @@
 /**
  * snd_soc_put_enum_double - enumerated double mixer put callback
  * @kcontrol: mixer control
- * @uinfo: control element information
+ * @ucontrol: control element information
  *
  * Callback to set the value of a double enumerated mixer.
  *
@@ -1668,7 +1670,7 @@
 /**
  * snd_soc_get_volsw - single mixer get callback
  * @kcontrol: mixer control
- * @uinfo: control element information
+ * @ucontrol: control element information
  *
  * Callback to get the value of a single mixer control.
  *
@@ -1707,7 +1709,7 @@
 /**
  * snd_soc_put_volsw - single mixer put callback
  * @kcontrol: mixer control
- * @uinfo: control element information
+ * @ucontrol: control element information
  *
  * Callback to set the value of a single mixer control.
  *
@@ -1775,7 +1777,7 @@
 /**
  * snd_soc_get_volsw_2r - double mixer get callback
  * @kcontrol: mixer control
- * @uinfo: control element information
+ * @ucontrol: control element information
  *
  * Callback to get the value of a double mixer control that spans 2 registers.
  *
@@ -1812,7 +1814,7 @@
 /**
  * snd_soc_put_volsw_2r - double mixer set callback
  * @kcontrol: mixer control
- * @uinfo: control element information
+ * @ucontrol: control element information
  *
  * Callback to set the value of a double mixer control that spans 2 registers.
  *
@@ -1882,7 +1884,7 @@
 /**
  * snd_soc_get_volsw_s8 - signed mixer get callback
  * @kcontrol: mixer control
- * @uinfo: control element information
+ * @ucontrol: control element information
  *
  * Callback to get the value of a signed mixer control.
  *
@@ -1909,7 +1911,7 @@
 /**
  * snd_soc_put_volsw_sgn - signed mixer put callback
  * @kcontrol: mixer control
- * @uinfo: control element information
+ * @ucontrol: control element information
  *
  * Callback to set the value of a signed mixer control.
  *
@@ -1954,7 +1956,7 @@
 /**
  * snd_soc_dai_set_clkdiv - configure DAI clock dividers.
  * @dai: DAI
- * @clk_id: DAI specific clock divider ID
+ * @div_id: DAI specific clock divider ID
  * @div: new clock divisor.
  *
  * Configures the clock dividers. This is used to derive the best DAI bit and
@@ -2060,7 +2062,7 @@
 /**
  * snd_soc_register_card - Register a card with the ASoC core
  *
- * @param card Card to register
+ * @card: Card to register
  *
  * Note that currently this is an internal only function: it will be
  * exposed to machine drivers after further backporting of ASoC v2
@@ -2087,7 +2089,7 @@
 /**
  * snd_soc_unregister_card - Unregister a card with the ASoC core
  *
- * @param card Card to unregister
+ * @card: Card to unregister
  *
  * Note that currently this is an internal only function: it will be
  * exposed to machine drivers after further backporting of ASoC v2
@@ -2107,7 +2109,7 @@
 /**
  * snd_soc_register_dai - Register a DAI with the ASoC core
  *
- * @param dai DAI to register
+ * @dai: DAI to register
  */
 int snd_soc_register_dai(struct snd_soc_dai *dai)
 {
@@ -2134,7 +2136,7 @@
 /**
  * snd_soc_unregister_dai - Unregister a DAI from the ASoC core
  *
- * @param dai DAI to unregister
+ * @dai: DAI to unregister
  */
 void snd_soc_unregister_dai(struct snd_soc_dai *dai)
 {
@@ -2149,8 +2151,8 @@
 /**
  * snd_soc_register_dais - Register multiple DAIs with the ASoC core
  *
- * @param dai Array of DAIs to register
- * @param count Number of DAIs
+ * @dai: Array of DAIs to register
+ * @count: Number of DAIs
  */
 int snd_soc_register_dais(struct snd_soc_dai *dai, size_t count)
 {
@@ -2175,8 +2177,8 @@
 /**
  * snd_soc_unregister_dais - Unregister multiple DAIs from the ASoC core
  *
- * @param dai Array of DAIs to unregister
- * @param count Number of DAIs
+ * @dai: Array of DAIs to unregister
+ * @count: Number of DAIs
  */
 void snd_soc_unregister_dais(struct snd_soc_dai *dai, size_t count)
 {
@@ -2190,7 +2192,7 @@
 /**
  * snd_soc_register_platform - Register a platform with the ASoC core
  *
- * @param platform platform to register
+ * @platform: platform to register
  */
 int snd_soc_register_platform(struct snd_soc_platform *platform)
 {
@@ -2213,7 +2215,7 @@
 /**
  * snd_soc_unregister_platform - Unregister a platform from the ASoC core
  *
- * @param platform platform to unregister
+ * @platform: platform to unregister
  */
 void snd_soc_unregister_platform(struct snd_soc_platform *platform)
 {
@@ -2228,7 +2230,7 @@
 /**
  * snd_soc_register_codec - Register a codec with the ASoC core
  *
- * @param codec codec to register
+ * @codec: codec to register
  */
 int snd_soc_register_codec(struct snd_soc_codec *codec)
 {
@@ -2255,7 +2257,7 @@
 /**
  * snd_soc_unregister_codec - Unregister a codec from the ASoC core
  *
- * @param codec codec to unregister
+ * @codec: codec to unregister
  */
 void snd_soc_unregister_codec(struct snd_soc_codec *codec)
 {
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 8863edd..6c79ca6 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1077,7 +1077,7 @@
 /**
  * snd_soc_dapm_get_volsw - dapm mixer get callback
  * @kcontrol: mixer control
- * @uinfo: control element information
+ * @ucontrol: control element information
  *
  * Callback to get the value of a dapm mixer control.
  *
@@ -1122,7 +1122,7 @@
 /**
  * snd_soc_dapm_put_volsw - dapm mixer set callback
  * @kcontrol: mixer control
- * @uinfo: control element information
+ * @ucontrol: control element information
  *
  * Callback to set the value of a dapm mixer control.
  *
@@ -1193,7 +1193,7 @@
 /**
  * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback
  * @kcontrol: mixer control
- * @uinfo: control element information
+ * @ucontrol: control element information
  *
  * Callback to get the value of a dapm enumerated double mixer control.
  *
@@ -1221,7 +1221,7 @@
 /**
  * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback
  * @kcontrol: mixer control
- * @uinfo: control element information
+ * @ucontrol: control element information
  *
  * Callback to set the value of a dapm enumerated double mixer control.
  *
@@ -1419,7 +1419,7 @@
 
 /**
  * snd_soc_dapm_enable_pin - enable pin.
- * @snd_soc_codec: SoC codec
+ * @codec: SoC codec
  * @pin: pin name
  *
  * Enables input/output pin and it's parents or children widgets iff there is
diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c
index b143ef7..a62500e 100644
--- a/sound/usb/caiaq/caiaq-device.c
+++ b/sound/usb/caiaq/caiaq-device.c
@@ -446,7 +446,7 @@
 	if (!card)
 		return -ENOMEM;
 			
-	dev_set_drvdata(&intf->dev, card);
+	usb_set_intfdata(intf, card);
 	ret = init_card(caiaqdev(card));
 	if (ret < 0) {
 		log("unable to init card! (ret=%d)\n", ret);
@@ -460,7 +460,7 @@
 static void snd_disconnect(struct usb_interface *intf)
 {
 	struct snd_usb_caiaqdev *dev;
-	struct snd_card *card = dev_get_drvdata(&intf->dev);
+	struct snd_card *card = usb_get_intfdata(intf);
 
 	debug("%s(%p)\n", __func__, intf);
 
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index bbd70d5..c709b95 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -3709,7 +3709,7 @@
 	void *chip;
 	chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
 	if (chip) {
-		dev_set_drvdata(&intf->dev, chip);
+		usb_set_intfdata(intf, chip);
 		return 0;
 	} else
 		return -EIO;
@@ -3718,13 +3718,13 @@
 static void usb_audio_disconnect(struct usb_interface *intf)
 {
 	snd_usb_audio_disconnect(interface_to_usbdev(intf),
-				 dev_get_drvdata(&intf->dev));
+				 usb_get_intfdata(intf));
 }
 
 #ifdef CONFIG_PM
 static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
 {
-	struct snd_usb_audio *chip = dev_get_drvdata(&intf->dev);
+	struct snd_usb_audio *chip = usb_get_intfdata(intf);
 	struct list_head *p;
 	struct snd_usb_stream *as;
 
@@ -3744,7 +3744,7 @@
 
 static int usb_audio_resume(struct usb_interface *intf)
 {
-	struct snd_usb_audio *chip = dev_get_drvdata(&intf->dev);
+	struct snd_usb_audio *chip = usb_get_intfdata(intf);
 
 	if (chip == (void *)-1L)
 		return 0;
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 6d9f9b1..320641a 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -1392,8 +1392,7 @@
 	for (i = 0; i < intfd->bNumEndpoints; ++i) {
 		hostep = &hostif->endpoint[i];
 		ep = get_ep_desc(hostep);
-		if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK &&
-		    (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
+		if (!usb_endpoint_xfer_bulk(ep) && !usb_endpoint_xfer_int(ep))
 			continue;
 		ms_ep = (struct usb_ms_endpoint_descriptor*)hostep->extra;
 		if (hostep->extralen < 4 ||
@@ -1401,15 +1400,15 @@
 		    ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT ||
 		    ms_ep->bDescriptorSubtype != MS_GENERAL)
 			continue;
-		if ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
+		if (usb_endpoint_dir_out(ep)) {
 			if (endpoints[epidx].out_ep) {
 				if (++epidx >= MIDI_MAX_ENDPOINTS) {
 					snd_printk(KERN_WARNING "too many endpoints\n");
 					break;
 				}
 			}
-			endpoints[epidx].out_ep = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
-			if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
+			endpoints[epidx].out_ep = usb_endpoint_num(ep);
+			if (usb_endpoint_xfer_int(ep))
 				endpoints[epidx].out_interval = ep->bInterval;
 			else if (snd_usb_get_speed(umidi->chip->dev) == USB_SPEED_LOW)
 				/*
@@ -1428,8 +1427,8 @@
 					break;
 				}
 			}
-			endpoints[epidx].in_ep = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
-			if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
+			endpoints[epidx].in_ep = usb_endpoint_num(ep);
+			if (usb_endpoint_xfer_int(ep))
 				endpoints[epidx].in_interval = ep->bInterval;
 			else if (snd_usb_get_speed(umidi->chip->dev) == USB_SPEED_LOW)
 				endpoints[epidx].in_interval = 1;
@@ -1495,20 +1494,20 @@
 
 	for (i = 0; i < intfd->bNumEndpoints; ++i) {
 		epd = get_endpoint(hostif, i);
-		if ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK &&
-		    (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
+		if (!usb_endpoint_xfer_bulk(epd) &&
+		    !usb_endpoint_xfer_int(epd))
 			continue;
 		if (out_eps < max_endpoints &&
-		    (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
-			endpoint[out_eps].out_ep = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
-			if ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
+		    usb_endpoint_dir_out(epd)) {
+			endpoint[out_eps].out_ep = usb_endpoint_num(epd);
+			if (usb_endpoint_xfer_int(epd))
 				endpoint[out_eps].out_interval = epd->bInterval;
 			++out_eps;
 		}
 		if (in_eps < max_endpoints &&
-		    (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
-			endpoint[in_eps].in_ep = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
-			if ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
+		    usb_endpoint_dir_in(epd)) {
+			endpoint[in_eps].in_ep = usb_endpoint_num(epd);
+			if (usb_endpoint_xfer_int(epd))
 				endpoint[in_eps].in_interval = epd->bInterval;
 			++in_eps;
 		}
@@ -1607,21 +1606,19 @@
 	}
 
 	epd = get_endpoint(hostif, 0);
-	if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN ||
-	    (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) {
+	if (!usb_endpoint_dir_in(epd) || !usb_endpoint_xfer_int(epd)) {
 		snd_printdd(KERN_ERR "endpoint[0] isn't interrupt\n");
 		return -ENXIO;
 	}
 	epd = get_endpoint(hostif, 2);
-	if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_OUT ||
-	    (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) {
+	if (!usb_endpoint_dir_out(epd) || !usb_endpoint_xfer_bulk(epd)) {
 		snd_printdd(KERN_ERR "endpoint[2] isn't bulk output\n");
 		return -ENXIO;
 	}
 	if (endpoint->out_cables > 0x0001) {
 		epd = get_endpoint(hostif, 4);
-		if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_OUT ||
-		    (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) {
+		if (!usb_endpoint_dir_out(epd) ||
+		    !usb_endpoint_xfer_bulk(epd)) {
 			snd_printdd(KERN_ERR "endpoint[4] isn't bulk output\n");
 			return -ENXIO;
 		}
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index a492461..00397c8 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -1755,11 +1755,10 @@
 	if (get_iface_desc(hostif)->bNumEndpoints < 1)
 		return 0;
 	ep = get_endpoint(hostif, 0);
-	if ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN ||
-	    (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
+	if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_int(ep))
 		return 0;
 
-	epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+	epnum = usb_endpoint_num(ep);
 	buffer_length = le16_to_cpu(ep->wMaxPacketSize);
 	transfer_buffer = kmalloc(buffer_length, GFP_KERNEL);
 	if (!transfer_buffer)
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index c2515b6..73e59f4 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -589,7 +589,7 @@
 	struct us122l *us122l;
 	struct list_head *p;
 
-	card = dev_get_drvdata(&intf->dev);
+	card = usb_get_intfdata(intf);
 	if (!card)
 		return 0;
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -615,7 +615,7 @@
 	struct list_head *p;
 	int err;
 
-	card = dev_get_drvdata(&intf->dev);
+	card = usb_get_intfdata(intf);
 	if (!card)
 		return 0;
 
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index e5981a6..ca26c53 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -392,7 +392,7 @@
 	void *chip;
 	chip = usX2Y_usb_probe(interface_to_usbdev(intf), intf, id);
 	if (chip) {
-		dev_set_drvdata(&intf->dev, chip);
+		usb_set_intfdata(intf, chip);
 		return 0;
 	} else
 		return -EIO;
@@ -401,7 +401,7 @@
 static void snd_usX2Y_disconnect(struct usb_interface *intf)
 {
 	usX2Y_usb_disconnect(interface_to_usbdev(intf),
-				 dev_get_drvdata(&intf->dev));
+				 usb_get_intfdata(intf));
 }
 
 MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table);