greybus: audio: Report uevent on GB codec module insertion/removal

GB-Audio-manager module is currently used to report uevent
to above layer in response to any codec module inserted or
removed.

Signed-off-by: Vaibhav Agarwal <vaibhav.agarwal@linaro.org>
Signed-off-by: Mark Greer <mgreer@animalcreek.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c
index a03caa0..93906c8 100644
--- a/drivers/staging/greybus/audio_codec.c
+++ b/drivers/staging/greybus/audio_codec.c
@@ -13,6 +13,7 @@
 
 #include "audio_codec.h"
 #include "audio_apbridgea.h"
+#include "audio_manager.h"
 
 #define GB_AUDIO_MGMT_DRIVER_NAME	"gb_audio_mgmt"
 #define GB_AUDIO_DATA_DRIVER_NAME	"gb_audio_data"
@@ -577,6 +578,7 @@
 	int ret, i;
 	struct gbaudio_codec_info *gbcodec;
 	struct gb_audio_topology *topology;
+	struct gb_audio_manager_module_descriptor desc;
 	struct device *dev = &connection->bundle->dev;
 	int dev_id = connection->bundle->id;
 
@@ -639,6 +641,21 @@
 	mutex_lock(&gbcodec->lock);
 	gbcodec->codec_registered = 1;
 
+	/* inform above layer for uevent */
+	if (!gbcodec->set_uevent &&
+	    (gbcodec->dai_added == gbcodec->num_dais)) {
+		dev_dbg(dev, "Inform set_event:%d to above layer\n", 1);
+		/* prepare for the audio manager */
+		strlcpy(desc.name, gbcodec->name,
+			GB_AUDIO_MANAGER_MODULE_NAME_LEN); /* todo */
+		desc.slot = 1; /* todo */
+		desc.vid = 2; /* todo */
+		desc.pid = 3; /* todo */
+		desc.cport = gbcodec->dev_id;
+		desc.devices = 0x2; /* todo */
+		gbcodec->manager_id = gb_audio_manager_add(&desc);
+		gbcodec->set_uevent = 1;
+	}
 	mutex_unlock(&gbcodec->lock);
 
 	return ret;
@@ -669,6 +686,16 @@
 	if (!gbcodec)
 		return;
 
+	/* inform uevent to above layers */
+	mutex_lock(&gbcodec->lock);
+	if (gbcodec->set_uevent) {
+		/* notify the audio manager */
+		dev_dbg(dev, "Inform set_event:%d to above layer\n", 0);
+		gb_audio_manager_remove(gbcodec->manager_id);
+		gbcodec->set_uevent = 0;
+	}
+	mutex_unlock(&gbcodec->lock);
+
 	msm8994_remove_dailink("msm8994-tomtom-mtp-snd-card", &gbaudio_dailink,
 			       1);
 	gbaudio_remove_dailinks(gbcodec);
@@ -712,6 +739,7 @@
 	struct device *dev = &connection->bundle->dev;
 	int dev_id = connection->bundle->id;
 	struct gbaudio_codec_info *gbcodec = dev_get_drvdata(dev);
+	struct gb_audio_manager_module_descriptor desc;
 
 	dev_dbg(dev, "Add DAI device:%d:%s\n", dev_id, dev_name(dev));
 
@@ -729,6 +757,22 @@
 	/* update dai_added count */
 	mutex_lock(&gbcodec->lock);
 	gbcodec->dai_added++;
+
+	/* inform above layer for uevent */
+	if (!gbcodec->set_uevent && gbcodec->codec_registered &&
+	    (gbcodec->dai_added == gbcodec->num_dais)) {
+		/* prepare for the audio manager */
+		dev_dbg(dev, "Inform set_event:%d to above layer\n", 1);
+		strlcpy(desc.name, gbcodec->name,
+			GB_AUDIO_MANAGER_MODULE_NAME_LEN); /* todo */
+		desc.slot = 1; /* todo */
+		desc.vid = 2; /* todo */
+		desc.pid = 3; /* todo */
+		desc.cport = gbcodec->dev_id;
+		desc.devices = 0x2; /* todo */
+		gbcodec->manager_id = gb_audio_manager_add(&desc);
+		gbcodec->set_uevent = 1;
+	}
 	mutex_unlock(&gbcodec->lock);
 
 	return 0;
@@ -749,6 +793,12 @@
 
 	/* inform uevent to above layers */
 	mutex_lock(&gbcodec->lock);
+	if (gbcodec->set_uevent) {
+		/* notify the audio manager */
+		dev_dbg(dev, "Inform set_event:%d to above layer\n", 0);
+		gb_audio_manager_remove(gbcodec->manager_id);
+		gbcodec->set_uevent = 0;
+	}
 	/* update dai_added count */
 	gbcodec->dai_added--;
 	mutex_unlock(&gbcodec->lock);
diff --git a/drivers/staging/greybus/audio_codec.h b/drivers/staging/greybus/audio_codec.h
index 5051e06..fcf3a06 100644
--- a/drivers/staging/greybus/audio_codec.h
+++ b/drivers/staging/greybus/audio_codec.h
@@ -97,10 +97,13 @@
 	int type;
 	int dai_added;
 	int codec_registered;
+	int set_uevent;
 	char vstr[NAME_SIZE];
 	char pstr[NAME_SIZE];
 	struct list_head list;
 	struct gb_audio_topology *topology;
+	/* need to share this info to above user space */
+	int manager_id;
 	char name[NAME_SIZE];
 
 	/* soc related data */