diff --git a/include/sound/core.h b/include/sound/core.h
index 0462c577d7a3..6860bfe5bb46 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -122,6 +122,7 @@ struct snd_card {
 
 	size_t total_pcm_alloc_bytes;	/* total amount of allocated buffers */
 	struct mutex memory_mutex;	/* protection for the above */
+	bool jack_inject_attr_registered; /* jack software inject sysfs interface registered? */
 
 #ifdef CONFIG_PM
 	unsigned int power_state;	/* power state */
diff --git a/include/sound/jack.h b/include/sound/jack.h
index 17f71fe38ed5..082664f2aff2 100644
--- a/include/sound/jack.h
+++ b/include/sound/jack.h
@@ -67,6 +67,7 @@ struct snd_jack {
 	char name[100];
 	unsigned int key[6];   /* Keep in sync with definitions above */
 #endif /* CONFIG_SND_JACK_INPUT_DEV */
+	bool sw_inject_enable;
 	void *private_data;
 	void (*private_free)(struct snd_jack *);
 };
diff --git a/sound/core/jack.c b/sound/core/jack.c
index 49b9461aef51..2d8eef9dcab8 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -8,6 +8,7 @@
 #include <linux/input.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/ctype.h>
 #include <sound/jack.h>
 #include <sound/core.h>
 #include <sound/control.h>
@@ -180,6 +181,123 @@ int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name, int mask)
 }
 EXPORT_SYMBOL(snd_jack_add_new_kctl);
 
+static struct snd_jack *parsing_jack_and_enable(struct snd_card *card, const char *buf,
+						size_t count, unsigned long *enable)
+{
+	struct snd_device *sdev;
+	struct snd_jack *jack = NULL;
+	bool jack_found = 0;
+	char *jackid, *ena;
+	int i, err;
+
+	/* skip the '\n\r' at the end of buf */
+	for (i = count - 2; i > 0; i--)
+		if (isspace(buf[i]))
+			break;
+	if (i == 0)
+		return NULL;
+
+	jackid = kstrndup(buf, i, GFP_KERNEL);
+	if (!jackid)
+		return NULL;
+
+	if (strstr(jackid, "Phantom"))
+		goto exit1;
+
+	ena = kstrndup(&buf[i+1], count - i - 2, GFP_KERNEL);
+	if (!ena)
+		goto exit1;
+
+	err = kstrtoul(ena, 0, enable);
+	if (err)
+		goto exit;
+
+	list_for_each_entry(sdev, &card->devices, list)
+		if (sdev->type == SNDRV_DEV_JACK) {
+			jack = (struct snd_jack *) sdev->device_data;
+			if (!strcmp(jack->id, jackid)) {
+				jack_found = 1;
+				break;
+			}
+		}
+
+	if (!jack_found)
+		jack = NULL;
+ exit:
+	kfree(ena);
+ exit1:
+	kfree(jackid);
+	return jack;
+}
+
+static ssize_t
+jackin_inject_store(struct device *dev, struct device_attribute *attr,
+		    const char *buf, size_t count)
+{
+	struct snd_card *card = container_of(dev, struct snd_card, card_dev);
+	struct snd_jack *jack;
+	unsigned long enable;
+
+	jack = parsing_jack_and_enable(card, buf, count, &enable);
+	if (!jack)
+		return -EINVAL;
+
+	if (jack->sw_inject_enable)
+		snd_jack_report(jack, enable ? jack->type : 0, true);
+
+	return count;
+}
+static DEVICE_ATTR_WO(jackin_inject);
+
+static ssize_t
+sw_inject_enable_show(struct device *dev,
+		      struct device_attribute *attr, char *buf)
+{
+	struct snd_card *card = container_of(dev, struct snd_card, card_dev);
+	struct snd_device *sdev;
+	struct snd_jack *jack = NULL;
+	ssize_t ret_count = 0;
+
+	list_for_each_entry(sdev, &card->devices, list)
+		if (sdev->type == SNDRV_DEV_JACK) {
+			jack = (struct snd_jack *) sdev->device_data;
+			if (strstr(jack->id, "Phantom"))
+				continue;
+			ret_count += scnprintf(buf + ret_count, PAGE_SIZE, "%s: %s  %i\n",
+					       "Jack", jack->id, jack->sw_inject_enable);
+		}
+	return ret_count;
+}
+
+static ssize_t
+sw_inject_enable_store(struct device *dev, struct device_attribute *attr,
+		       const char *buf, size_t count)
+{
+	struct snd_card *card = container_of(dev, struct snd_card, card_dev);
+	struct snd_jack *jack;
+	unsigned long enable;
+
+	jack = parsing_jack_and_enable(card, buf, count, &enable);
+	if (!jack)
+		return -EINVAL;
+
+	jack->sw_inject_enable = !!enable;
+
+	return count;
+}
+static DEVICE_ATTR_RW(sw_inject_enable);
+
+static struct attribute *snd_jack_dev_attrs[] = {
+	&dev_attr_jackin_inject.attr,
+	&dev_attr_sw_inject_enable.attr,
+	NULL
+};
+
+static const struct attribute_group snd_jack_dev_attr_group = {
+	.name = "jack",
+	.attrs = snd_jack_dev_attrs,
+};
+
 /**
  * snd_jack_new - Create a new jack
  * @card:  the card instance
@@ -256,6 +374,11 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
 
 	*jjack = jack;
 
+	if (!jack->card->jack_inject_attr_registered) {
+		jack->card->jack_inject_attr_registered = true;
+		snd_card_add_dev_attr(jack->card, &snd_jack_dev_attr_group);
+	}
+
 	return 0;
 
 fail_input:
@@ -348,6 +471,9 @@ void snd_jack_report(struct snd_jack *jack, int status, bool sw_inject)
 	if (!jack)
 		return;
 
+	if (jack->sw_inject_enable && !sw_inject)
+		return;
+
 	list_for_each_entry(jack_kctl, &jack->kctl_list, list)
 		snd_kctl_jack_report(jack->card, jack_kctl->kctl,
 					    status & jack_kctl->mask_bits);
