msm: audio: qdsp6v2: Add support for multiple instance.

Add support for concurrent voice and VoIP calls.

Signed-off-by: Neema Shetty <nshetty@codeaurora.org>
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c b/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
index 2261466..41729c9 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
@@ -239,31 +239,31 @@
 }
 EXPORT_SYMBOL(msm_get_voice_state);
 
-int msm_set_voice_mute(int dir, int mute)
+int msm_set_voice_mute(int dir, int mute, u32 session_id)
 {
 	pr_debug("dir %x mute %x\n", dir, mute);
 	if (dir == DIR_TX) {
 		routing_info.tx_mute = mute;
 		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
-			routing_info.voice_tx_dev_id, SESSION_IGNORE);
+			routing_info.voice_tx_dev_id, session_id);
 	} else
 		return -EPERM;
 	return 0;
 }
 EXPORT_SYMBOL(msm_set_voice_mute);
 
-int msm_set_voice_vol(int dir, s32 volume)
+int msm_set_voice_vol(int dir, s32 volume, u32 session_id)
 {
 	if (dir == DIR_TX) {
 		routing_info.voice_tx_vol = volume;
 		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
 					routing_info.voice_tx_dev_id,
-					SESSION_IGNORE);
+					session_id);
 	} else if (dir == DIR_RX) {
 		routing_info.voice_rx_vol = volume;
 		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
 					routing_info.voice_rx_dev_id,
-					SESSION_IGNORE);
+					session_id);
 	} else
 		return -EINVAL;
 	return 0;
@@ -1397,7 +1397,8 @@
 		memset(evt_payload, 0, sizeof(union auddev_evt_data));
 
 		if ((evt_id == AUDDEV_EVT_START_VOICE)
-			|| (evt_id == AUDDEV_EVT_END_VOICE))
+			|| (evt_id == AUDDEV_EVT_END_VOICE)
+			|| evt_id == AUDDEV_EVT_DEVICE_VOL_MUTE_CHG)
 			goto skip_check;
 		if (callback->clnt_type == AUDDEV_CLNT_AUDIOCAL)
 			goto aud_cal;
@@ -1557,6 +1558,9 @@
 				pending_sent = 1;
 
 			if (evt_id == AUDDEV_EVT_DEVICE_VOL_MUTE_CHG) {
+				evt_payload->voc_vm_info.voice_session_id =
+								session_id;
+
 				if (dev_info->capability & SNDDEV_CAP_TX) {
 					evt_payload->voc_vm_info.dev_type =
 						SNDDEV_CAP_TX;
@@ -1575,10 +1579,12 @@
 						routing_info.voice_rx_vol;
 				}
 			} else if ((evt_id == AUDDEV_EVT_START_VOICE)
-					|| (evt_id == AUDDEV_EVT_END_VOICE))
+					|| (evt_id == AUDDEV_EVT_END_VOICE)) {
 				memset(evt_payload, 0,
 					sizeof(union auddev_evt_data));
-			else if (evt_id == AUDDEV_EVT_FREQ_CHG) {
+
+				evt_payload->voice_session_id = session_id;
+			} else if (evt_id == AUDDEV_EVT_FREQ_CHG) {
 				if (routing_info.voice_tx_sample_rate
 						!= dev_info->set_sample_rate) {
 					routing_info.voice_tx_sample_rate
diff --git a/arch/arm/mach-msm/qdsp6v2/q6voice.c b/arch/arm/mach-msm/qdsp6v2/q6voice.c
index d39970e..de6f646 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6voice.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6voice.c
@@ -36,102 +36,106 @@
 #define CMD_STATUS_SUCCESS 0
 #define CMD_STATUS_FAIL 1
 
+/* Voice session creates passive control sessions for MVM and CVS. */
 #define VOC_PATH_PASSIVE 0
+
+/* VoIP session creates full control sessions for MVM and CVS. */
 #define VOC_PATH_FULL 1
+
 #define ADSP_VERSION_CVD 0x60300000
 
 #define BUFFER_PAYLOAD_SIZE 4000
 
 #define VOC_REC_NONE 0xFF
 
-struct voice_data voice;
+struct common_data common;
 
 static bool is_adsp_support_cvd(void)
 {
-	return (voice.adsp_version >= ADSP_VERSION_CVD);
+	return (common.adsp_version >= ADSP_VERSION_CVD);
 }
 static int voice_send_enable_vocproc_cmd(struct voice_data *v);
 static int voice_send_netid_timing_cmd(struct voice_data *v);
 
-static void *voice_get_apr_mvm(struct voice_data *v)
+static void *voice_get_apr_mvm(void)
 {
 	void *apr_mvm = NULL;
 
-	if (v->voc_path == VOC_PATH_PASSIVE &&
+	if (common.voc_path == VOC_PATH_PASSIVE &&
 		!(is_adsp_support_cvd()))
-		apr_mvm = v->apr_mvm;
+		apr_mvm = common.apr_mvm;
 	else
-		apr_mvm = v->apr_q6_mvm;
+		apr_mvm = common.apr_q6_mvm;
 
 	pr_debug("%s: apr_mvm 0x%x\n", __func__, (unsigned int)apr_mvm);
 
 	return apr_mvm;
 }
 
-static void voice_set_apr_mvm(struct voice_data *v, void *apr_mvm)
+static void voice_set_apr_mvm(void *apr_mvm)
 {
 	pr_debug("%s: apr_mvm 0x%x\n", __func__, (unsigned int)apr_mvm);
 
-	if (v->voc_path == VOC_PATH_PASSIVE &&
+	if (common.voc_path == VOC_PATH_PASSIVE &&
 		!(is_adsp_support_cvd()))
-		v->apr_mvm = apr_mvm;
+		common.apr_mvm = apr_mvm;
 	else
-		v->apr_q6_mvm = apr_mvm;
+		common.apr_q6_mvm = apr_mvm;
 }
 
-static void *voice_get_apr_cvs(struct voice_data *v)
+static void *voice_get_apr_cvs(void)
 {
 	void *apr_cvs = NULL;
 
-	if (v->voc_path == VOC_PATH_PASSIVE &&
+	if (common.voc_path == VOC_PATH_PASSIVE &&
 		!(is_adsp_support_cvd()))
-		apr_cvs = v->apr_cvs;
+		apr_cvs = common.apr_cvs;
 	else
-		apr_cvs = v->apr_q6_cvs;
+		apr_cvs = common.apr_q6_cvs;
 
 	pr_debug("%s: apr_cvs 0x%x\n", __func__, (unsigned int)apr_cvs);
 
 	return apr_cvs;
 }
 
-static void voice_set_apr_cvs(struct voice_data *v, void *apr_cvs)
+static void voice_set_apr_cvs(void *apr_cvs)
 {
 	pr_debug("%s: apr_cvs 0x%x\n", __func__, (unsigned int)apr_cvs);
 
-	if (v->voc_path == VOC_PATH_PASSIVE &&
+	if (common.voc_path == VOC_PATH_PASSIVE &&
 		!(is_adsp_support_cvd()))
-		v->apr_cvs = apr_cvs;
+		common.apr_cvs = apr_cvs;
 	else
-		v->apr_q6_cvs = apr_cvs;
+		common.apr_q6_cvs = apr_cvs;
 #ifdef CONFIG_MSM8X60_RTAC
 	rtac_set_voice_handle(RTAC_CVS, apr_cvs);
 #endif
 }
 
-static void *voice_get_apr_cvp(struct voice_data *v)
+static void *voice_get_apr_cvp(void)
 {
 	void *apr_cvp = NULL;
 
-	if (v->voc_path == VOC_PATH_PASSIVE &&
+	if (common.voc_path == VOC_PATH_PASSIVE &&
 		!(is_adsp_support_cvd()))
-		apr_cvp = v->apr_cvp;
+		apr_cvp = common.apr_cvp;
 	else
-		apr_cvp = v->apr_q6_cvp;
+		apr_cvp = common.apr_q6_cvp;
 
 	pr_debug("%s: apr_cvp 0x%x\n", __func__, (unsigned int)apr_cvp);
 
 	return apr_cvp;
 }
 
-static void voice_set_apr_cvp(struct voice_data *v, void *apr_cvp)
+static void voice_set_apr_cvp(void *apr_cvp)
 {
 	pr_debug("%s: apr_cvp 0x%x\n", __func__, (unsigned int)apr_cvp);
 
-	if (v->voc_path == VOC_PATH_PASSIVE &&
+	if (common.voc_path == VOC_PATH_PASSIVE &&
 		!(is_adsp_support_cvd()))
-		v->apr_cvp = apr_cvp;
+		common.apr_cvp = apr_cvp;
 	else
-		v->apr_q6_cvp = apr_cvp;
+		common.apr_q6_cvp = apr_cvp;
 #ifdef CONFIG_MSM8X60_RTAC
 	rtac_set_voice_handle(RTAC_CVP, apr_cvp);
 #endif
@@ -139,74 +143,102 @@
 
 static u16 voice_get_mvm_handle(struct voice_data *v)
 {
-	u16 mvm_handle = 0;
+	pr_debug("%s: mvm_handle %d\n", __func__, v->mvm_handle);
 
-	if (v->voc_path == VOC_PATH_PASSIVE)
-		mvm_handle = v->mvm_handle;
-	else
-		mvm_handle = v->mvm_q6_handle;
-
-	pr_debug("%s: mvm_handle %d\n", __func__, mvm_handle);
-
-	return mvm_handle;
+	return v->mvm_handle;
 }
 
 static void voice_set_mvm_handle(struct voice_data *v, u16 mvm_handle)
 {
-	pr_debug("%s: mvm_handle %d\n", __func__, mvm_handle);
+	pr_debug("%s: session 0x%x, mvm_handle %d\n",
+		 __func__, (unsigned int)v, mvm_handle);
 
-	if (v->voc_path == VOC_PATH_PASSIVE)
-		v->mvm_handle = mvm_handle;
-	else
-		v->mvm_q6_handle = mvm_handle;
+	v->mvm_handle = mvm_handle;
 }
 
 static u16 voice_get_cvs_handle(struct voice_data *v)
 {
-	u16 cvs_handle = 0;
+	pr_debug("%s: cvs_handle %d\n", __func__, v->cvs_handle);
 
-	if (v->voc_path == VOC_PATH_PASSIVE)
-		cvs_handle = v->cvs_handle;
-	else
-		cvs_handle = v->cvs_q6_handle;
-
-	pr_debug("%s: cvs_handle %d\n", __func__, cvs_handle);
-
-	return cvs_handle;
+	return v->cvs_handle;
 }
 
 static void voice_set_cvs_handle(struct voice_data *v, u16 cvs_handle)
 {
-	pr_debug("%s: cvs_handle %d\n", __func__, cvs_handle);
+	pr_debug("%s: session 0x%x, cvs_handle %d\n",
+		 __func__, (unsigned int)v, cvs_handle);
 
-	if (v->voc_path == VOC_PATH_PASSIVE)
-		v->cvs_handle = cvs_handle;
-	else
-		v->cvs_q6_handle = cvs_handle;
+	v->cvs_handle = cvs_handle;
 }
 
 static u16 voice_get_cvp_handle(struct voice_data *v)
 {
-	u16 cvp_handle = 0;
+	pr_debug("%s: cvp_handle %d\n", __func__, v->cvp_handle);
 
-	if (v->voc_path == VOC_PATH_PASSIVE)
-		cvp_handle = v->cvp_handle;
-	else
-		cvp_handle = v->cvp_q6_handle;
-
-	pr_debug("%s: cvp_handle %d\n", __func__, cvp_handle);
-
-	return cvp_handle;
+	return v->cvp_handle;
 }
 
 static void voice_set_cvp_handle(struct voice_data *v, u16 cvp_handle)
 {
-	pr_debug("%s: cvp_handle %d\n", __func__, cvp_handle);
+	pr_debug("%s: session 0x%x, cvp_handle %d\n",
+		 __func__, (unsigned int)v, cvp_handle);
 
-	if (v->voc_path == VOC_PATH_PASSIVE)
-		v->cvp_handle = cvp_handle;
-	else
-		v->cvp_q6_handle = cvp_handle;
+	v->cvp_handle = cvp_handle;
+}
+
+u16 voice_get_session_id(const char *name)
+{
+	u16 session_id = 0;
+
+	if (name != NULL) {
+		if (!strncmp(name, "Voice session", 13))
+			session_id = common.voice[VOC_PATH_PASSIVE].session_id;
+		else
+			session_id = common.voice[VOC_PATH_FULL].session_id;
+	}
+
+	pr_debug("%s: %s has session id 0x%x\n", __func__, name, session_id);
+
+	return session_id;
+}
+
+static struct voice_data *voice_get_session(u16 session_id)
+{
+	struct voice_data *v = NULL;
+
+	if (session_id == 0) {
+		mutex_lock(&common.common_lock);
+
+		pr_debug("%s: NULL id, voc_path is %d\n",
+			 __func__, common.voc_path);
+
+		if (common.voc_path == VOC_PATH_PASSIVE)
+			v = &common.voice[VOC_PATH_PASSIVE];
+		else
+			v = &common.voice[VOC_PATH_FULL];
+
+		mutex_unlock(&common.common_lock);
+	} else if ((session_id >= SESSION_ID_BASE) &&
+		   (session_id < SESSION_ID_BASE + MAX_VOC_SESSIONS))  {
+		v = &common.voice[session_id - SESSION_ID_BASE];
+	} else {
+		pr_err("%s: Invalid session_id 0x%x\n", __func__, session_id);
+	}
+
+	pr_debug("%s: session_id 0x%x session handle 0x%x\n",
+		 __func__, session_id, (unsigned int)v);
+
+	return v;
+}
+
+static bool is_voice_session(u16 session_id)
+{
+	return (session_id == common.voice[VOC_PATH_PASSIVE].session_id);
+}
+
+static bool is_voip_session(u16 session_id)
+{
+	return (session_id == common.voice[VOC_PATH_FULL].session_id);
 }
 
 static void voice_auddev_cb_function(u32 evt_id,
@@ -217,20 +249,23 @@
 static int32_t modem_cvs_callback(struct apr_client_data *data, void *priv);
 static int32_t modem_cvp_callback(struct apr_client_data *data, void *priv);
 
-static int voice_apr_register(struct voice_data *v)
+static int voice_apr_register(void)
 {
 	int rc = 0;
 	void *apr_mvm;
 	void *apr_cvs;
 	void *apr_cvp;
 
-	if (v->adsp_version == 0) {
-		v->adsp_version = core_get_adsp_version();
-		pr_info("adsp_ver fetched:%x\n", v->adsp_version);
+	if (common.adsp_version == 0) {
+		common.adsp_version = core_get_adsp_version();
+		pr_info("adsp_ver fetched:%x\n", common.adsp_version);
 	}
-	apr_mvm = voice_get_apr_mvm(v);
-	apr_cvs = voice_get_apr_cvs(v);
-	apr_cvp = voice_get_apr_cvp(v);
+
+	mutex_lock(&common.common_lock);
+
+	apr_mvm = voice_get_apr_mvm();
+	apr_cvs = voice_get_apr_cvs();
+	apr_cvp = voice_get_apr_cvp();
 
 
 	pr_debug("into voice_apr_register_callback\n");
@@ -238,15 +273,15 @@
 	if (apr_mvm == NULL) {
 		pr_debug("start to register MVM callback\n");
 
-		if (v->voc_path == VOC_PATH_PASSIVE &&
+		if (common.voc_path == VOC_PATH_PASSIVE &&
 			!(is_adsp_support_cvd())) {
 			apr_mvm = apr_register("MODEM", "MVM",
 					       modem_mvm_callback, 0xFFFFFFFF,
-					       v);
+					       &common);
 		} else {
 			apr_mvm = apr_register("ADSP", "MVM",
 					       modem_mvm_callback, 0xFFFFFFFF,
-					       v);
+					       &common);
 		}
 
 		if (apr_mvm == NULL) {
@@ -256,21 +291,21 @@
 			goto done;
 		}
 
-		voice_set_apr_mvm(v, apr_mvm);
+		voice_set_apr_mvm(apr_mvm);
 	}
 
 	if (apr_cvs == NULL) {
 		pr_debug("start to register CVS callback\n");
 
-		if (v->voc_path == VOC_PATH_PASSIVE &&
+		if (common.voc_path == VOC_PATH_PASSIVE &&
 			!(is_adsp_support_cvd())) {
 			apr_cvs = apr_register("MODEM", "CVS",
 					       modem_cvs_callback, 0xFFFFFFFF,
-					       v);
+					       &common);
 		} else {
 			apr_cvs = apr_register("ADSP", "CVS",
 					       modem_cvs_callback, 0xFFFFFFFF,
-					       v);
+					       &common);
 		}
 
 		if (apr_cvs == NULL) {
@@ -280,21 +315,21 @@
 			goto err;
 		}
 
-		voice_set_apr_cvs(v, apr_cvs);
+		voice_set_apr_cvs(apr_cvs);
 	}
 
 	if (apr_cvp == NULL) {
 		pr_debug("start to register CVP callback\n");
 
-		if (v->voc_path == VOC_PATH_PASSIVE &&
+		if (common.voc_path == VOC_PATH_PASSIVE &&
 			!(is_adsp_support_cvd())) {
 			apr_cvp = apr_register("MODEM", "CVP",
 					       modem_cvp_callback, 0xFFFFFFFF,
-					       v);
+					       &common);
 		} else {
 			apr_cvp = apr_register("ADSP", "CVP",
 					       modem_cvp_callback, 0xFFFFFFFF,
-					       v);
+					       &common);
 	}
 
 		if (apr_cvp == NULL) {
@@ -304,20 +339,25 @@
 			goto err1;
 		}
 
-		voice_set_apr_cvp(v, apr_cvp);
+		voice_set_apr_cvp(apr_cvp);
 	}
+
+	mutex_unlock(&common.common_lock);
+
 	return 0;
 
 err1:
 	apr_deregister(apr_cvs);
 	apr_cvs = NULL;
-	voice_set_apr_cvs(v, apr_cvs);
+	voice_set_apr_cvs(apr_cvs);
 err:
 	apr_deregister(apr_mvm);
 	apr_mvm = NULL;
-	voice_set_apr_mvm(v, apr_mvm);
+	voice_set_apr_mvm(apr_mvm);
 
 done:
+	mutex_unlock(&common.common_lock);
+
 	return rc;
 }
 
@@ -328,9 +368,9 @@
 	struct cvs_create_passive_ctl_session_cmd cvs_session_cmd;
 	struct cvs_create_full_ctl_session_cmd cvs_full_ctl_cmd;
 	struct mvm_attach_stream_cmd attach_stream_cmd;
-	void *apr_mvm = voice_get_apr_mvm(v);
-	void *apr_cvs = voice_get_apr_cvs(v);
-	void *apr_cvp = voice_get_apr_cvp(v);
+	void *apr_mvm = voice_get_apr_mvm();
+	void *apr_cvs = voice_get_apr_cvs();
+	void *apr_cvp = voice_get_apr_cvp();
 	u16 mvm_handle = voice_get_mvm_handle(v);
 	u16 cvs_handle = voice_get_cvs_handle(v);
 	u16 cvp_handle = voice_get_cvp_handle(v);
@@ -343,7 +383,7 @@
 	/* send cmd to create mvm session and wait for response */
 
 	if (!mvm_handle) {
-		if (v->voc_path == VOC_PATH_PASSIVE) {
+		if (is_voice_session(v->session_id)) {
 			mvm_session_cmd.hdr.hdr_field =
 				APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
 					APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
@@ -352,7 +392,7 @@
 					sizeof(mvm_session_cmd) - APR_HDR_SIZE);
 			pr_debug("Send mvm create session pkt size = %d\n",
 				mvm_session_cmd.hdr.pkt_size);
-			mvm_session_cmd.hdr.src_port = 0;
+			mvm_session_cmd.hdr.src_port = v->session_id;
 			mvm_session_cmd.hdr.dest_port = 0;
 			mvm_session_cmd.hdr.token = 0;
 			pr_debug("%s: Creating MVM passive ctrl\n", __func__);
@@ -385,7 +425,7 @@
 				       sizeof(mvm_session_cmd) - APR_HDR_SIZE);
 			pr_debug("Send mvm create session pkt size = %d\n",
 				mvm_session_cmd.hdr.pkt_size);
-			mvm_session_cmd.hdr.src_port = 0;
+			mvm_session_cmd.hdr.src_port = v->session_id;
 			mvm_session_cmd.hdr.dest_port = 0;
 			mvm_session_cmd.hdr.token = 0;
 			pr_debug("%s: Creating MVM full ctrl\n", __func__);
@@ -417,7 +457,7 @@
 
 	/* send cmd to create cvs session */
 	if (!cvs_handle) {
-		if (v->voc_path == VOC_PATH_PASSIVE) {
+		if (is_voice_session(v->session_id)) {
 			pr_info("%s:creating CVS passive session\n", __func__);
 
 		cvs_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
@@ -427,7 +467,7 @@
 					sizeof(cvs_session_cmd) - APR_HDR_SIZE);
 		pr_info("send stream create session pkt size = %d\n",
 					cvs_session_cmd.hdr.pkt_size);
-		cvs_session_cmd.hdr.src_port = 0;
+		cvs_session_cmd.hdr.src_port = v->session_id;
 		cvs_session_cmd.hdr.dest_port = 0;
 		cvs_session_cmd.hdr.token = 0;
 		cvs_session_cmd.hdr.opcode =
@@ -465,7 +505,7 @@
 				APR_PKT_SIZE(APR_HDR_SIZE,
 				       sizeof(cvs_full_ctl_cmd) - APR_HDR_SIZE);
 
-			cvs_full_ctl_cmd.hdr.src_port = 0;
+			cvs_full_ctl_cmd.hdr.src_port = v->session_id;
 			cvs_full_ctl_cmd.hdr.dest_port = 0;
 			cvs_full_ctl_cmd.hdr.token = 0;
 			cvs_full_ctl_cmd.hdr.opcode =
@@ -473,11 +513,11 @@
 			cvs_full_ctl_cmd.cvs_session.direction = 2;
 
 			cvs_full_ctl_cmd.cvs_session.enc_media_type =
-							v->mvs_info.media_type;
+						common.mvs_info.media_type;
 			cvs_full_ctl_cmd.cvs_session.dec_media_type =
-							v->mvs_info.media_type;
+						common.mvs_info.media_type;
 			cvs_full_ctl_cmd.cvs_session.network_id =
-						       v->mvs_info.network_type;
+						common.mvs_info.network_type;
 			strncpy(cvs_full_ctl_cmd.cvs_session.name,
 				"default voip", SESSION_NAME_LEN);
 
@@ -513,7 +553,7 @@
 			attach_stream_cmd.hdr.pkt_size =
 				APR_PKT_SIZE(APR_HDR_SIZE,
 				      sizeof(attach_stream_cmd) - APR_HDR_SIZE);
-			attach_stream_cmd.hdr.src_port = 0;
+			attach_stream_cmd.hdr.src_port = v->session_id;
 			attach_stream_cmd.hdr.dest_port = mvm_handle;
 			attach_stream_cmd.hdr.token = 0;
 			attach_stream_cmd.hdr.opcode =
@@ -543,15 +583,15 @@
 fail:
 	apr_deregister(apr_mvm);
 	apr_mvm = NULL;
-	voice_set_apr_mvm(v, apr_mvm);
+	voice_set_apr_mvm(apr_mvm);
 
 	apr_deregister(apr_cvs);
 	apr_cvs = NULL;
-	voice_set_apr_cvs(v, apr_cvs);
+	voice_set_apr_cvs(apr_cvs);
 
 	apr_deregister(apr_cvp);
 	apr_cvp = NULL;
-	voice_set_apr_cvp(v, apr_cvp);
+	voice_set_apr_cvp(apr_cvp);
 
 	cvp_handle = 0;
 	voice_set_cvp_handle(v, cvp_handle);
@@ -568,13 +608,13 @@
 	struct mvm_detach_stream_cmd detach_stream;
 	struct apr_hdr mvm_destroy;
 	struct apr_hdr cvs_destroy;
-	void *apr_mvm = voice_get_apr_mvm(v);
-	void *apr_cvs = voice_get_apr_cvs(v);
+	void *apr_mvm = voice_get_apr_mvm();
+	void *apr_cvs = voice_get_apr_cvs();
 	u16 mvm_handle = voice_get_mvm_handle(v);
 	u16 cvs_handle = voice_get_cvs_handle(v);
 
 	/* MVM, CVS sessions are destroyed only for Full control sessions. */
-	if (v->voc_path == VOC_PATH_FULL) {
+	if (is_voip_session(v->session_id)) {
 		pr_info("%s: MVM detach stream\n", __func__);
 
 		/* Detach voice stream. */
@@ -584,7 +624,7 @@
 				      APR_PKT_VER);
 		detach_stream.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					  sizeof(detach_stream) - APR_HDR_SIZE);
-		detach_stream.hdr.src_port = 0;
+		detach_stream.hdr.src_port = v->session_id;
 		detach_stream.hdr.dest_port = mvm_handle;
 		detach_stream.hdr.token = 0;
 		detach_stream.hdr.opcode = VSS_IMVM_CMD_DETACH_STREAM;
@@ -616,7 +656,7 @@
 						      APR_PKT_VER);
 		cvs_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					    sizeof(cvs_destroy) - APR_HDR_SIZE);
-		cvs_destroy.src_port = 0;
+		cvs_destroy.src_port = v->session_id;
 		cvs_destroy.dest_port = cvs_handle;
 		cvs_destroy.token = 0;
 		cvs_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
@@ -650,7 +690,7 @@
 						      APR_PKT_VER);
 		mvm_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					    sizeof(mvm_destroy) - APR_HDR_SIZE);
-		mvm_destroy.src_port = 0;
+		mvm_destroy.src_port = v->session_id;
 		mvm_destroy.dest_port = mvm_handle;
 		mvm_destroy.token = 0;
 		mvm_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
@@ -688,7 +728,7 @@
 	int tty_mode = 0;
 	int ret = 0;
 	struct mvm_set_tty_mode_cmd mvm_tty_mode_cmd;
-	void *apr_mvm = voice_get_apr_mvm(v);
+	void *apr_mvm = voice_get_apr_mvm();
 	u16 mvm_handle = voice_get_mvm_handle(v);
 
 	dev_rx_info = audio_dev_ctrl_find_dev(v->dev_rx.dev_id);
@@ -721,7 +761,7 @@
 		mvm_tty_mode_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 			sizeof(mvm_tty_mode_cmd) - APR_HDR_SIZE);
 		pr_debug("pkt size = %d\n", mvm_tty_mode_cmd.hdr.pkt_size);
-		mvm_tty_mode_cmd.hdr.src_port = 0;
+		mvm_tty_mode_cmd.hdr.src_port = v->session_id;
 		mvm_tty_mode_cmd.hdr.dest_port = mvm_handle;
 		mvm_tty_mode_cmd.hdr.token = 0;
 		mvm_tty_mode_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_TTY_MODE;
@@ -758,7 +798,7 @@
 	uint32_t *cal_data_per_network;
 	int index = 0;
 	int ret = 0;
-	void *apr_cvs = voice_get_apr_cvs(v);
+	void *apr_cvs = voice_get_apr_cvs();
 	u16 cvs_handle = voice_get_cvs_handle(v);
 
 	/* fill the header */
@@ -766,7 +806,7 @@
 		APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvs_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 		sizeof(cvs_cal_cmd_hdr) - APR_HDR_SIZE);
-	cvs_cal_cmd_hdr.src_port = 0;
+	cvs_cal_cmd_hdr.src_port = v->session_id;
 	cvs_cal_cmd_hdr.dest_port = cvs_handle;
 	cvs_cal_cmd_hdr.token = 0;
 	cvs_cal_cmd_hdr.opcode =
@@ -835,7 +875,7 @@
 	uint32_t *cal_data_per_network;
 	int index = 0;
 	int ret = 0;
-	void *apr_cvp = voice_get_apr_cvp(v);
+	void *apr_cvp = voice_get_apr_cvp();
 	u16 cvp_handle = voice_get_cvp_handle(v);
 
 
@@ -844,7 +884,7 @@
 		APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvp_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 		sizeof(cvp_cal_cmd_hdr) - APR_HDR_SIZE);
-	cvp_cal_cmd_hdr.src_port = 0;
+	cvp_cal_cmd_hdr.src_port = v->session_id;
 	cvp_cal_cmd_hdr.dest_port = cvp_handle;
 	cvp_cal_cmd_hdr.token = 0;
 	cvp_cal_cmd_hdr.opcode =
@@ -914,7 +954,7 @@
 	int offset = 0;
 	int index = 0;
 	int ret = 0;
-	void *apr_cvp = voice_get_apr_cvp(v);
+	void *apr_cvp = voice_get_apr_cvp();
 	u16 cvp_handle = voice_get_cvp_handle(v);
 
 
@@ -923,7 +963,7 @@
 		APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvp_vol_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 		sizeof(cvp_vol_cal_cmd_hdr) - APR_HDR_SIZE);
-	cvp_vol_cal_cmd_hdr.src_port = 0;
+	cvp_vol_cal_cmd_hdr.src_port = v->session_id;
 	cvp_vol_cal_cmd_hdr.dest_port = cvp_handle;
 	cvp_vol_cal_cmd_hdr.token = 0;
 	cvp_vol_cal_cmd_hdr.opcode =
@@ -993,7 +1033,7 @@
 static int voice_set_dtx(struct voice_data *v)
 {
 	int ret = 0;
-	void *apr_cvs = voice_get_apr_cvs(v);
+	void *apr_cvs = voice_get_apr_cvs();
 	u16 cvs_handle = voice_get_cvs_handle(v);
 
 	/* Set DTX */
@@ -1003,14 +1043,14 @@
 					      APR_PKT_VER),
 		.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(cvs_set_dtx) - APR_HDR_SIZE),
-		.hdr.src_port = 0,
+		.hdr.src_port = v->session_id,
 		.hdr.dest_port = cvs_handle,
 		.hdr.token = 0,
 		.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE,
-		.dtx_mode.enable = v->mvs_info.dtx_mode,
+		.dtx_mode.enable = common.mvs_info.dtx_mode,
 	};
 
-	pr_debug("%s: Setting DTX %d\n", __func__, v->mvs_info.dtx_mode);
+	pr_debug("%s: Setting DTX %d\n", __func__, common.mvs_info.dtx_mode);
 
 	v->cvs_state = CMD_STATUS_FAIL;
 
@@ -1037,7 +1077,7 @@
 static int voice_config_cvs_vocoder(struct voice_data *v)
 {
 	int ret = 0;
-	void *apr_cvs = voice_get_apr_cvs(v);
+	void *apr_cvs = voice_get_apr_cvs();
 	u16 cvs_handle = voice_get_cvs_handle(v);
 
 	/* Set media type. */
@@ -1050,12 +1090,12 @@
 						APR_PKT_VER);
 	cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				      sizeof(cvs_set_media_cmd) - APR_HDR_SIZE);
-	cvs_set_media_cmd.hdr.src_port = 0;
+	cvs_set_media_cmd.hdr.src_port = v->session_id;
 	cvs_set_media_cmd.hdr.dest_port = cvs_handle;
 	cvs_set_media_cmd.hdr.token = 0;
 	cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
-	cvs_set_media_cmd.media_type.tx_media_id = v->mvs_info.media_type;
-	cvs_set_media_cmd.media_type.rx_media_id = v->mvs_info.media_type;
+	cvs_set_media_cmd.media_type.tx_media_id = common.mvs_info.media_type;
+	cvs_set_media_cmd.media_type.rx_media_id = common.mvs_info.media_type;
 
 	v->cvs_state = CMD_STATUS_FAIL;
 
@@ -1078,7 +1118,7 @@
 	}
 
 	/* Set encoder properties. */
-	switch (v->mvs_info.media_type) {
+	switch (common.mvs_info.media_type) {
 	case VSS_MEDIA_ID_EVRC_MODEM: {
 		struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
 
@@ -1090,13 +1130,13 @@
 					      APR_PKT_VER);
 		cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				      sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
-		cvs_set_cdma_rate.hdr.src_port = 0;
+		cvs_set_cdma_rate.hdr.src_port = v->session_id;
 		cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
 		cvs_set_cdma_rate.hdr.token = 0;
 		cvs_set_cdma_rate.hdr.opcode =
 				VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
-		cvs_set_cdma_rate.cdma_rate.min_rate = v->mvs_info.rate;
-		cvs_set_cdma_rate.cdma_rate.max_rate = v->mvs_info.rate;
+		cvs_set_cdma_rate.cdma_rate.min_rate = common.mvs_info.rate;
+		cvs_set_cdma_rate.cdma_rate.max_rate = common.mvs_info.rate;
 
 		v->cvs_state = CMD_STATUS_FAIL;
 
@@ -1132,12 +1172,12 @@
 					      APR_PKT_VER);
 		cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				       sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
-		cvs_set_amr_rate.hdr.src_port = 0;
+		cvs_set_amr_rate.hdr.src_port = v->session_id;
 		cvs_set_amr_rate.hdr.dest_port = cvs_handle;
 		cvs_set_amr_rate.hdr.token = 0;
 		cvs_set_amr_rate.hdr.opcode =
 					VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
-		cvs_set_amr_rate.amr_rate.mode = v->mvs_info.rate;
+		cvs_set_amr_rate.amr_rate.mode = common.mvs_info.rate;
 
 		v->cvs_state = CMD_STATUS_FAIL;
 
@@ -1175,12 +1215,12 @@
 					      APR_PKT_VER);
 		cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				     sizeof(cvs_set_amrwb_rate) - APR_HDR_SIZE);
-		cvs_set_amrwb_rate.hdr.src_port = 0;
+		cvs_set_amrwb_rate.hdr.src_port = v->session_id;
 		cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
 		cvs_set_amrwb_rate.hdr.token = 0;
 		cvs_set_amrwb_rate.hdr.opcode =
 					VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
-		cvs_set_amrwb_rate.amrwb_rate.mode = v->mvs_info.rate;
+		cvs_set_amrwb_rate.amrwb_rate.mode = common.mvs_info.rate;
 
 		v->cvs_state = CMD_STATUS_FAIL;
 
@@ -1228,7 +1268,7 @@
 {
 	struct apr_hdr mvm_start_voice_cmd;
 	int ret = 0;
-	void *apr_mvm = voice_get_apr_mvm(v);
+	void *apr_mvm = voice_get_apr_mvm();
 	u16 mvm_handle = voice_get_mvm_handle(v);
 
 	mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
@@ -1237,7 +1277,7 @@
 				sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
 	pr_info("send mvm_start_voice_cmd pkt size = %d\n",
 				mvm_start_voice_cmd.pkt_size);
-	mvm_start_voice_cmd.src_port = 0;
+	mvm_start_voice_cmd.src_port = v->session_id;
 	mvm_start_voice_cmd.dest_port = mvm_handle;
 	mvm_start_voice_cmd.token = 0;
 	mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
@@ -1265,7 +1305,7 @@
 {
 	struct apr_hdr cvp_disable_cmd;
 	int ret = 0;
-	void *apr_cvp = voice_get_apr_cvp(v);
+	void *apr_cvp = voice_get_apr_cvp();
 	u16 cvp_handle = voice_get_cvp_handle(v);
 
 	/* disable vocproc and wait for respose */
@@ -1275,7 +1315,7 @@
 			sizeof(cvp_disable_cmd) - APR_HDR_SIZE);
 	pr_debug("cvp_disable_cmd pkt size = %d, cvp_handle=%d\n",
 		cvp_disable_cmd.pkt_size, cvp_handle);
-	cvp_disable_cmd.src_port = 0;
+	cvp_disable_cmd.src_port = v->session_id;
 	cvp_disable_cmd.dest_port = cvp_handle;
 	cvp_disable_cmd.token = 0;
 	cvp_disable_cmd.opcode = VSS_IVOCPROC_CMD_DISABLE;
@@ -1307,7 +1347,7 @@
 	struct cvp_set_device_cmd  cvp_setdev_cmd;
 	struct msm_snddev_info *dev_tx_info;
 	int ret = 0;
-	void *apr_cvp = voice_get_apr_cvp(v);
+	void *apr_cvp = voice_get_apr_cvp();
 	u16 cvp_handle = voice_get_cvp_handle(v);
 
 
@@ -1318,7 +1358,7 @@
 				sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
 	pr_debug(" send create cvp setdev, pkt size = %d\n",
 			cvp_setdev_cmd.hdr.pkt_size);
-	cvp_setdev_cmd.hdr.src_port = 0;
+	cvp_setdev_cmd.hdr.src_port = v->session_id;
 	cvp_setdev_cmd.hdr.dest_port = cvp_handle;
 	cvp_setdev_cmd.hdr.token = 0;
 	cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
@@ -1383,7 +1423,7 @@
 	/* send tty mode if tty device is used */
 	voice_send_tty_mode_to_modem(v);
 
-	if (v->voc_path == VOC_PATH_FULL)
+	if (is_voip_session(v->session_id))
 		voice_send_netid_timing_cmd(v);
 
 #ifdef CONFIG_MSM8X60_RTAC
@@ -1399,7 +1439,7 @@
 {
 	struct apr_hdr mvm_stop_voice_cmd;
 	int ret = 0;
-	void *apr_mvm = voice_get_apr_mvm(v);
+	void *apr_mvm = voice_get_apr_mvm();
 	u16 mvm_handle = voice_get_mvm_handle(v);
 
 	mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
@@ -1408,7 +1448,7 @@
 				sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
 	pr_info("send mvm_stop_voice_cmd pkt size = %d\n",
 				mvm_stop_voice_cmd.pkt_size);
-	mvm_stop_voice_cmd.src_port = 0;
+	mvm_stop_voice_cmd.src_port = v->session_id;
 	mvm_stop_voice_cmd.dest_port = mvm_handle;
 	mvm_stop_voice_cmd.token = 0;
 	mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
@@ -1437,7 +1477,7 @@
 	struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
 	int ret = 0;
 	struct msm_snddev_info *dev_tx_info;
-	void *apr_cvp = voice_get_apr_cvp(v);
+	void *apr_cvp = voice_get_apr_cvp();
 
 	/* create cvp session and wait for response */
 	cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
@@ -1446,7 +1486,7 @@
 				sizeof(cvp_session_cmd) - APR_HDR_SIZE);
 	pr_info(" send create cvp session, pkt size = %d\n",
 				cvp_session_cmd.hdr.pkt_size);
-	cvp_session_cmd.hdr.src_port = 0;
+	cvp_session_cmd.hdr.src_port = v->session_id;
 	cvp_session_cmd.hdr.dest_port = 0;
 	cvp_session_cmd.hdr.token = 0;
 	cvp_session_cmd.hdr.opcode =
@@ -1523,7 +1563,7 @@
 	struct apr_hdr cvp_enable_cmd;
 
 	u16 cvp_handle = voice_get_cvp_handle(v);
-	void *apr_cvp = voice_get_apr_cvp(v);
+	void *apr_cvp = voice_get_apr_cvp();
 
 	/* enable vocproc and wait for respose */
 	cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
@@ -1532,7 +1572,7 @@
 				sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
 	pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
 			cvp_enable_cmd.pkt_size, cvp_handle);
-	cvp_enable_cmd.src_port = 0;
+	cvp_enable_cmd.src_port = v->session_id;
 	cvp_enable_cmd.dest_port = cvp_handle;
 	cvp_enable_cmd.token = 0;
 	cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
@@ -1559,7 +1599,7 @@
 static int voice_send_netid_timing_cmd(struct voice_data *v)
 {
 	int ret = 0;
-	void *apr_mvm = voice_get_apr_mvm(v);
+	void *apr_mvm = voice_get_apr_mvm();
 	struct mvm_set_network_cmd mvm_set_network;
 	struct mvm_set_voice_timing_cmd mvm_set_voice_timing;
 	u16 mvm_handle = voice_get_mvm_handle(v);
@@ -1578,11 +1618,11 @@
 			APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 			sizeof(mvm_set_network) - APR_HDR_SIZE);
-	mvm_set_network.hdr.src_port = 0;
+	mvm_set_network.hdr.src_port = v->session_id;
 	mvm_set_network.hdr.dest_port = mvm_handle;
 	mvm_set_network.hdr.token = 0;
 	mvm_set_network.hdr.opcode = VSS_ICOMMON_CMD_SET_NETWORK;
-	mvm_set_network.network.network_id = v->mvs_info.network_type;
+	mvm_set_network.network.network_id = common.mvs_info.network_type;
 
 	v->mvm_state = CMD_STATUS_FAIL;
 	ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network);
@@ -1607,7 +1647,7 @@
 			APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 			sizeof(mvm_set_voice_timing) - APR_HDR_SIZE);
-	mvm_set_voice_timing.hdr.src_port = 0;
+	mvm_set_voice_timing.hdr.src_port = v->session_id;
 	mvm_set_voice_timing.hdr.dest_port = mvm_handle;
 	mvm_set_voice_timing.hdr.token = 0;
 	mvm_set_voice_timing.hdr.opcode =
@@ -1642,7 +1682,7 @@
 {
 	int ret = 0;
 	struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd;
-	void *apr_mvm = voice_get_apr_mvm(v);
+	void *apr_mvm = voice_get_apr_mvm();
 	u16 mvm_handle = voice_get_mvm_handle(v);
 	u16 cvp_handle = voice_get_cvp_handle(v);
 
@@ -1656,7 +1696,7 @@
 				sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
 	pr_info("send mvm_a_vocproc_cmd pkt size = %d\n",
 				mvm_a_vocproc_cmd.hdr.pkt_size);
-	mvm_a_vocproc_cmd.hdr.src_port = 0;
+	mvm_a_vocproc_cmd.hdr.src_port = v->session_id;
 	mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
 	mvm_a_vocproc_cmd.hdr.token = 0;
 	mvm_a_vocproc_cmd.hdr.opcode = VSS_ISTREAM_CMD_ATTACH_VOCPROC;
@@ -1679,7 +1719,7 @@
 	/* send tty mode if tty device is used */
 	voice_send_tty_mode_to_modem(v);
 
-	if (v->voc_path == VOC_PATH_FULL)
+	if (is_voip_session(v->session_id))
 		voice_send_netid_timing_cmd(v);
 
 #ifdef CONFIG_MSM8X60_RTAC
@@ -1695,8 +1735,8 @@
 	struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
 	struct apr_hdr cvp_destroy_session_cmd;
 	int ret = 0;
-	void *apr_mvm = voice_get_apr_mvm(v);
-	void *apr_cvp = voice_get_apr_cvp(v);
+	void *apr_mvm = voice_get_apr_mvm();
+	void *apr_cvp = voice_get_apr_cvp();
 	u16 mvm_handle = voice_get_mvm_handle(v);
 	u16 cvp_handle = voice_get_cvp_handle(v);
 
@@ -1707,7 +1747,7 @@
 				sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
 	pr_info("mvm_d_vocproc_cmd  pkt size = %d\n",
 				mvm_d_vocproc_cmd.hdr.pkt_size);
-	mvm_d_vocproc_cmd.hdr.src_port = 0;
+	mvm_d_vocproc_cmd.hdr.src_port = v->session_id;
 	mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
 	mvm_d_vocproc_cmd.hdr.token = 0;
 	mvm_d_vocproc_cmd.hdr.opcode = VSS_ISTREAM_CMD_DETACH_VOCPROC;
@@ -1734,7 +1774,7 @@
 				sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
 	pr_info("cvp_destroy_session_cmd pkt size = %d\n",
 				cvp_destroy_session_cmd.pkt_size);
-	cvp_destroy_session_cmd.src_port = 0;
+	cvp_destroy_session_cmd.src_port = v->session_id;
 	cvp_destroy_session_cmd.dest_port = cvp_handle;
 	cvp_destroy_session_cmd.token = 0;
 	cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
@@ -1769,7 +1809,7 @@
 {
 	struct cvs_set_mute_cmd cvs_mute_cmd;
 	int ret = 0;
-	void *apr_cvs = voice_get_apr_cvs(v);
+	void *apr_cvs = voice_get_apr_cvs();
 	u16 cvs_handle = voice_get_cvs_handle(v);
 
 	/* send mute/unmute to cvs */
@@ -1777,7 +1817,7 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
-	cvs_mute_cmd.hdr.src_port = 0;
+	cvs_mute_cmd.hdr.src_port = v->session_id;
 	cvs_mute_cmd.hdr.dest_port = cvs_handle;
 	cvs_mute_cmd.hdr.token = 0;
 	cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
@@ -1805,7 +1845,7 @@
 {
 	struct cvp_set_rx_volume_index_cmd cvp_vol_cmd;
 	int ret = 0;
-	void *apr_cvp = voice_get_apr_cvp(v);
+	void *apr_cvp = voice_get_apr_cvp();
 	u16 cvp_handle = voice_get_cvp_handle(v);
 
 	/* send volume index to cvp */
@@ -1813,7 +1853,7 @@
 		APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvp_vol_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 		sizeof(cvp_vol_cmd) - APR_HDR_SIZE);
-	cvp_vol_cmd.hdr.src_port = 0;
+	cvp_vol_cmd.hdr.src_port = v->session_id;
 	cvp_vol_cmd.hdr.dest_port = cvp_handle;
 	cvp_vol_cmd.hdr.token = 0;
 	cvp_vol_cmd.hdr.opcode =
@@ -1838,7 +1878,7 @@
 static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode)
 {
 	int ret = 0;
-	void *apr_cvs = voice_get_apr_cvs(v);
+	void *apr_cvs = voice_get_apr_cvs();
 	u16 cvs_handle = voice_get_cvs_handle(v);
 	struct cvs_start_record_cmd cvs_start_record;
 
@@ -1848,7 +1888,7 @@
 				  APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvs_start_record.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				  sizeof(cvs_start_record) - APR_HDR_SIZE);
-	cvs_start_record.hdr.src_port = 0;
+	cvs_start_record.hdr.src_port = v->session_id;
 	cvs_start_record.hdr.dest_port = cvs_handle;
 	cvs_start_record.hdr.token = 0;
 	cvs_start_record.hdr.opcode = VSS_ISTREAM_CMD_START_RECORD;
@@ -1900,7 +1940,7 @@
 static int voice_cvs_stop_record(struct voice_data *v)
 {
 	int ret = 0;
-	void *apr_cvs = voice_get_apr_cvs(v);
+	void *apr_cvs = voice_get_apr_cvs();
 	u16 cvs_handle = voice_get_cvs_handle(v);
 	struct apr_hdr cvs_stop_record;
 
@@ -1910,7 +1950,7 @@
 				  APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvs_stop_record.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				  sizeof(cvs_stop_record) - APR_HDR_SIZE);
-	cvs_stop_record.src_port = 0;
+	cvs_stop_record.src_port = v->session_id;
 	cvs_stop_record.dest_port = cvs_handle;
 	cvs_stop_record.token = 0;
 	cvs_stop_record.opcode = VSS_ISTREAM_CMD_STOP_RECORD;
@@ -1941,35 +1981,39 @@
 
 int voice_start_record(uint32_t rec_mode, uint32_t set)
 {
-	int ret = 0;
+	int ret = 0, i;
 	u16 cvs_handle;
 
 	pr_debug("%s: rec_mode %d, set %d\n", __func__, rec_mode, set);
 
-	mutex_lock(&voice.lock);
+	for (i = 0; i < MAX_VOC_SESSIONS; i++) {
+		struct voice_data *v = &common.voice[i];
 
-	cvs_handle = voice_get_cvs_handle(&voice);
+		mutex_lock(&v->lock);
 
-	if (cvs_handle != 0) {
-		if (set)
-			ret = voice_cvs_start_record(&voice, rec_mode);
-		else
-			ret = voice_cvs_stop_record(&voice);
-	} else {
-		/* Cache the value for later. */
-		voice.rec_info.pending = set;
-		voice.rec_info.rec_mode = rec_mode;
+		cvs_handle = voice_get_cvs_handle(v);
+
+		if (cvs_handle != 0) {
+			if (set)
+				ret = voice_cvs_start_record(v, rec_mode);
+			else
+				ret = voice_cvs_stop_record(v);
+		} else {
+			/* Cache the value for later. */
+			v->rec_info.pending = set;
+			v->rec_info.rec_mode = rec_mode;
+		}
+
+		mutex_unlock(&v->lock);
 	}
 
-	mutex_unlock(&voice.lock);
-
 	return ret;
 }
 
 static int voice_cvs_start_playback(struct voice_data *v)
 {
 	int ret = 0;
-	void *apr_cvs = voice_get_apr_cvs(v);
+	void *apr_cvs = voice_get_apr_cvs();
 	u16 cvs_handle = voice_get_cvs_handle(v);
 	struct apr_hdr cvs_start_playback;
 
@@ -1979,7 +2023,7 @@
 					APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvs_start_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvs_start_playback) - APR_HDR_SIZE);
-	cvs_start_playback.src_port = 0;
+	cvs_start_playback.src_port = v->session_id;
 	cvs_start_playback.dest_port = cvs_handle;
 	cvs_start_playback.token = 0;
 	cvs_start_playback.opcode = VSS_ISTREAM_CMD_START_PLAYBACK;
@@ -2014,7 +2058,7 @@
 static int voice_cvs_stop_playback(struct voice_data *v)
 {
 	int ret = 0;
-	void *apr_cvs = voice_get_apr_cvs(v);
+	void *apr_cvs = voice_get_apr_cvs();
 	u16 cvs_handle = voice_get_cvs_handle(v);
 	struct apr_hdr cvs_stop_playback;
 
@@ -2026,7 +2070,7 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 		cvs_stop_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvs_stop_playback) - APR_HDR_SIZE);
-		cvs_stop_playback.src_port = 0;
+		cvs_stop_playback.src_port = v->session_id;
 		cvs_stop_playback.dest_port = cvs_handle;
 		cvs_stop_playback.token = 0;
 
@@ -2064,29 +2108,33 @@
 
 int voice_start_playback(uint32_t set)
 {
-	int ret = 0;
+	int ret = 0, i;
 	u16 cvs_handle;
 
 	pr_debug("%s: Start playback %d\n", __func__, set);
 
-	mutex_lock(&voice.lock);
+	for (i = 0; i < MAX_VOC_SESSIONS; i++) {
+		struct voice_data *v = &common.voice[i];
 
-	cvs_handle = voice_get_cvs_handle(&voice);
+		mutex_lock(&v->lock);
 
-	if (cvs_handle != 0) {
-		if (set)
-			ret = voice_cvs_start_playback(&voice);
-		else
-			ret = voice_cvs_stop_playback(&voice);
-	} else {
-		/* Cache the value for later. */
-		pr_debug("%s: Caching ICP value", __func__);
+		cvs_handle = voice_get_cvs_handle(v);
 
-		voice.music_info.pending = set;
+		if (cvs_handle != 0) {
+			if (set)
+				ret = voice_cvs_start_playback(v);
+			else
+				ret = voice_cvs_stop_playback(v);
+		} else {
+			/* Cache the value for later. */
+			pr_debug("%s: Caching ICP value", __func__);
+
+			v->music_info.pending = set;
+		}
+
+		mutex_unlock(&v->lock);
 	}
 
-	mutex_unlock(&voice.lock);
-
 	return ret;
 }
 
@@ -2094,20 +2142,26 @@
 			union auddev_evt_data *evt_payload,
 			void *private_data)
 {
-	struct voice_data *v = &voice;
+		struct common_data *c = private_data;
+		struct voice_data *v = NULL;
+
 	struct sidetone_cal sidetone_cal_data;
-	int rc = 0;
+	int rc = 0, i = 0;
 	pr_info("auddev_cb_function, evt_id=%d,\n", evt_id);
-	if ((evt_id != AUDDEV_EVT_START_VOICE) ||
-			(evt_id != AUDDEV_EVT_END_VOICE)) {
-		if (evt_payload == NULL) {
-			pr_err(" evt_payload is NULL pointer\n");
-			return;
-		}
+
+	if (evt_payload == NULL) {
+		pr_err("%s: evt_payload is NULL pointer\n", __func__);
+		return;
 	}
 
 	switch (evt_id) {
 	case AUDDEV_EVT_START_VOICE:
+		v = voice_get_session(evt_payload->voice_session_id);
+		if (v == NULL) {
+			pr_err("%s: v is NULL\n", __func__);
+			return;
+		}
+
 		mutex_lock(&v->lock);
 
 		if ((v->voc_state == VOC_INIT) ||
@@ -2115,7 +2169,7 @@
 			v->v_call_status = VOICE_CALL_START;
 			if ((v->dev_rx.enabled == VOICE_DEV_ENABLED)
 				&& (v->dev_tx.enabled == VOICE_DEV_ENABLED)) {
-				rc = voice_apr_register(v);
+				rc = voice_apr_register();
 				if (rc < 0) {
 					pr_err("%s: voice apr registration"
 						"failed\n", __func__);
@@ -2155,120 +2209,143 @@
 		mutex_unlock(&v->lock);
 		break;
 	case AUDDEV_EVT_DEV_CHG_VOICE:
-		if (v->dev_rx.enabled == VOICE_DEV_ENABLED)
-			msm_snddev_enable_sidetone(v->dev_rx.dev_id, 0, 0);
-		v->dev_rx.enabled = VOICE_DEV_DISABLED;
-		v->dev_tx.enabled = VOICE_DEV_DISABLED;
+		/* Device change is applicable to all sessions. */
+		for (i = 0; i < MAX_VOC_SESSIONS; i++) {
+			v = &c->voice[i];
 
-		mutex_lock(&v->lock);
+			if (v->dev_rx.enabled == VOICE_DEV_ENABLED)
+				msm_snddev_enable_sidetone(v->dev_rx.dev_id,
+							   0, 0);
 
-		if (v->voc_state == VOC_RUN) {
-			/* send cmd to modem to do voice device change */
-			voice_disable_vocproc(v);
-			v->voc_state = VOC_CHANGE;
+			v->dev_rx.enabled = VOICE_DEV_DISABLED;
+			v->dev_tx.enabled = VOICE_DEV_DISABLED;
+
+			mutex_lock(&v->lock);
+
+			if (v->voc_state == VOC_RUN) {
+				/* send cmd to modem to do voice device
+				 * change */
+				voice_disable_vocproc(v);
+				v->voc_state = VOC_CHANGE;
+			}
+
+			mutex_unlock(&v->lock);
 		}
-
-		mutex_unlock(&v->lock);
 		break;
 	case AUDDEV_EVT_DEV_RDY:
-		mutex_lock(&v->lock);
+		/* Device change is applicable to all sessions. */
+		for (i = 0; i < MAX_VOC_SESSIONS; i++) {
+			v = &c->voice[i];
 
-		if (v->voc_state == VOC_CHANGE) {
-			/* get port Ids */
-			if (evt_payload->voc_devinfo.dev_type == DIR_RX) {
-				v->dev_rx.dev_port_id =
-					evt_payload->voc_devinfo.dev_port_id;
-				v->dev_rx.sample =
-					evt_payload->voc_devinfo.dev_sample;
-				v->dev_rx.dev_id =
-				evt_payload->voc_devinfo.dev_id;
-				v->dev_rx.enabled = VOICE_DEV_ENABLED;
-			} else {
-				v->dev_tx.dev_port_id =
-					evt_payload->voc_devinfo.dev_port_id;
-				v->dev_tx.sample =
-					evt_payload->voc_devinfo.dev_sample;
-				v->dev_tx.enabled = VOICE_DEV_ENABLED;
-				v->dev_tx.dev_id =
-				evt_payload->voc_devinfo.dev_id;
-			}
-			if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) &&
-				(v->dev_tx.enabled == VOICE_DEV_ENABLED)) {
-				voice_set_device(v);
-				get_sidetone_cal(&sidetone_cal_data);
-				msm_snddev_enable_sidetone(
-					v->dev_rx.dev_id,
-					sidetone_cal_data.enable,
-					sidetone_cal_data.gain);
-				v->voc_state = VOC_RUN;
-			}
-		} else if ((v->voc_state == VOC_INIT) ||
-			(v->voc_state == VOC_RELEASE)) {
-			/* get AFE ports */
-			if (evt_payload->voc_devinfo.dev_type == DIR_RX) {
-				/* get rx port id */
-				v->dev_rx.dev_port_id =
-					evt_payload->voc_devinfo.dev_port_id;
-				v->dev_rx.sample =
-					evt_payload->voc_devinfo.dev_sample;
-				v->dev_rx.dev_id =
-				evt_payload->voc_devinfo.dev_id;
-				v->dev_rx.enabled = VOICE_DEV_ENABLED;
-			} else {
-				/* get tx port id */
-				v->dev_tx.dev_port_id =
-					evt_payload->voc_devinfo.dev_port_id;
-				v->dev_tx.sample =
-					evt_payload->voc_devinfo.dev_sample;
-				v->dev_tx.dev_id =
-				evt_payload->voc_devinfo.dev_id;
-				v->dev_tx.enabled = VOICE_DEV_ENABLED;
-			}
-			if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) &&
-				(v->dev_tx.enabled == VOICE_DEV_ENABLED) &&
-				(v->v_call_status == VOICE_CALL_START)) {
-				rc = voice_apr_register(v);
-				if (rc < 0) {
-					pr_err("%s: voice apr registration"
-						"failed\n", __func__);
-					mutex_unlock(&v->lock);
-					return;
+			mutex_lock(&v->lock);
+
+			if (v->voc_state == VOC_CHANGE) {
+				/* get port Ids */
+				if (evt_payload->voc_devinfo.dev_type ==
+								      DIR_RX) {
+					v->dev_rx.dev_port_id =
+					   evt_payload->voc_devinfo.dev_port_id;
+					v->dev_rx.sample =
+					    evt_payload->voc_devinfo.dev_sample;
+					v->dev_rx.dev_id =
+						evt_payload->voc_devinfo.dev_id;
+					v->dev_rx.enabled = VOICE_DEV_ENABLED;
+				} else {
+					v->dev_tx.dev_port_id =
+					   evt_payload->voc_devinfo.dev_port_id;
+					v->dev_tx.sample =
+					    evt_payload->voc_devinfo.dev_sample;
+					v->dev_tx.enabled = VOICE_DEV_ENABLED;
+					v->dev_tx.dev_id =
+						evt_payload->voc_devinfo.dev_id;
 				}
-				voice_create_mvm_cvs_session(v);
-				voice_setup_modem_voice(v);
-				voice_attach_vocproc(v);
-				voice_send_start_voice_cmd(v);
-				get_sidetone_cal(&sidetone_cal_data);
-				msm_snddev_enable_sidetone(
-					v->dev_rx.dev_id,
-					sidetone_cal_data.enable,
-					sidetone_cal_data.gain);
-				v->voc_state = VOC_RUN;
-
-				/* Start in-call recording if command was
-				 * pending. */
-				if (v->rec_info.pending) {
-					voice_cvs_start_record(v,
-						v->rec_info.rec_mode);
-
-					v->rec_info.pending = 0;
+				if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) &&
+				    (v->dev_tx.enabled == VOICE_DEV_ENABLED)) {
+					voice_set_device(v);
+					get_sidetone_cal(&sidetone_cal_data);
+					msm_snddev_enable_sidetone(
+						v->dev_rx.dev_id,
+						sidetone_cal_data.enable,
+						sidetone_cal_data.gain);
+					v->voc_state = VOC_RUN;
 				}
+			} else if ((v->voc_state == VOC_INIT) ||
+				   (v->voc_state == VOC_RELEASE)) {
+				/* get AFE ports */
+				if (evt_payload->voc_devinfo.dev_type ==
+								       DIR_RX) {
+					/* get rx port id */
+					v->dev_rx.dev_port_id =
+					   evt_payload->voc_devinfo.dev_port_id;
+					v->dev_rx.sample =
+					    evt_payload->voc_devinfo.dev_sample;
+					v->dev_rx.dev_id =
+						evt_payload->voc_devinfo.dev_id;
+					v->dev_rx.enabled = VOICE_DEV_ENABLED;
+				} else {
+					/* get tx port id */
+					v->dev_tx.dev_port_id =
+					   evt_payload->voc_devinfo.dev_port_id;
+					v->dev_tx.sample =
+					    evt_payload->voc_devinfo.dev_sample;
+					v->dev_tx.dev_id =
+						evt_payload->voc_devinfo.dev_id;
+					v->dev_tx.enabled = VOICE_DEV_ENABLED;
+				}
+				if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) &&
+				    (v->dev_tx.enabled == VOICE_DEV_ENABLED) &&
+				    (v->v_call_status == VOICE_CALL_START)) {
+					rc = voice_apr_register();
+					if (rc < 0) {
+						pr_err("%s: voice apr"
+						       "registration failed\n",
+						       __func__);
+						mutex_unlock(&v->lock);
+						return;
+					}
+					voice_create_mvm_cvs_session(v);
+					voice_setup_modem_voice(v);
+					voice_attach_vocproc(v);
+					voice_send_start_voice_cmd(v);
+					get_sidetone_cal(&sidetone_cal_data);
+					msm_snddev_enable_sidetone(
+						v->dev_rx.dev_id,
+						sidetone_cal_data.enable,
+						sidetone_cal_data.gain);
+					v->voc_state = VOC_RUN;
 
-				/* Start in-call music delivery if command was
-				 * pending. */
-				if (v->music_info.pending) {
-					voice_cvs_start_playback(v);
+					/* Start in-call recording if command
+					 * was pending. */
+					if (v->rec_info.pending) {
+						voice_cvs_start_record(v,
+							v->rec_info.rec_mode);
 
-					v->music_info.pending = 0;
+						v->rec_info.pending = 0;
+					}
+
+					/* Start in-call music delivery if
+					 * command was pending. */
+					if (v->music_info.pending) {
+						voice_cvs_start_playback(v);
+
+						v->music_info.pending = 0;
+					}
 				}
 			}
+
+			mutex_unlock(&v->lock);
+		}
+	break;
+	case AUDDEV_EVT_DEVICE_VOL_MUTE_CHG:
+		v = voice_get_session(
+				     evt_payload->voc_vm_info.voice_session_id);
+		if (v == NULL) {
+			pr_err("%s: v is NULL\n", __func__);
+			return;
 		}
 
-		mutex_unlock(&v->lock);
-		break;
-	case AUDDEV_EVT_DEVICE_VOL_MUTE_CHG:
 		/* cache the mute and volume index value */
-		if (evt_payload->voc_devinfo.dev_type == DIR_TX) {
+		if (evt_payload->voc_vm_info.dev_type == DIR_TX) {
 			v->dev_tx.mute =
 				evt_payload->voc_vm_info.dev_vm_val.mute;
 
@@ -2279,8 +2356,8 @@
 
 			mutex_unlock(&v->lock);
 		} else {
-			v->dev_rx.volume = evt_payload->
-				voc_vm_info.dev_vm_val.vol;
+			v->dev_rx.volume =
+					evt_payload->voc_vm_info.dev_vm_val.vol;
 
 			mutex_lock(&v->lock);
 
@@ -2291,26 +2368,36 @@
 		}
 		break;
 	case AUDDEV_EVT_REL_PENDING:
+		/* Device change is applicable to all sessions. */
+		for (i = 0; i < MAX_VOC_SESSIONS; i++) {
+			v = &c->voice[i];
 
-		mutex_lock(&v->lock);
+			mutex_lock(&v->lock);
 
-		if (v->voc_state == VOC_RUN) {
-			voice_disable_vocproc(v);
-			v->voc_state = VOC_CHANGE;
+			if (v->voc_state == VOC_RUN) {
+				voice_disable_vocproc(v);
+				v->voc_state = VOC_CHANGE;
+			}
+
+			mutex_unlock(&v->lock);
+
+			if (evt_payload->voc_devinfo.dev_type == DIR_RX)
+				v->dev_rx.enabled = VOICE_DEV_DISABLED;
+			else
+				v->dev_tx.enabled = VOICE_DEV_DISABLED;
 		}
 
-		mutex_unlock(&v->lock);
-
-		if (evt_payload->voc_devinfo.dev_type == DIR_RX)
-			v->dev_rx.enabled = VOICE_DEV_DISABLED;
-		else
-			v->dev_tx.enabled = VOICE_DEV_DISABLED;
-
 		break;
 	case AUDDEV_EVT_END_VOICE:
+		v = voice_get_session(evt_payload->voice_session_id);
+		if (v == NULL) {
+			pr_err("%s: v is NULL\n", __func__);
+			return;
+		}
+
 		/* recover the tx mute and rx volume to the default values */
-		v->dev_tx.mute = v->default_mute_val;
-		v->dev_rx.volume = v->default_vol_val;
+		v->dev_tx.mute = c->default_mute_val;
+		v->dev_rx.volume = c->default_vol_val;
 		if (v->dev_rx.enabled == VOICE_DEV_ENABLED)
 			msm_snddev_enable_sidetone(v->dev_rx.dev_id, 0, 0);
 
@@ -2342,27 +2429,18 @@
 
 int voice_set_voc_path_full(uint32_t set)
 {
-	int rc = 0;
-
 	pr_info("%s: %d\n", __func__, set);
 
-	mutex_lock(&voice.lock);
+	mutex_lock(&common.common_lock);
 
-	if (voice.voc_state == VOC_INIT || voice.voc_state == VOC_RELEASE) {
-		if (set)
-			voice.voc_path = VOC_PATH_FULL;
-		else
-			voice.voc_path = VOC_PATH_PASSIVE;
-	} else {
-		pr_err("%s: Invalid voc path set to %d, in state %d\n",
-		       __func__, set, voice.voc_state);
+	if (set)
+		common.voc_path = VOC_PATH_FULL;
+	else
+		common.voc_path = VOC_PATH_PASSIVE;
 
-		rc = -EPERM;
-	}
+	mutex_unlock(&common.common_lock);
 
-	mutex_unlock(&voice.lock);
-
-	return rc;
+	return 0;
 }
 EXPORT_SYMBOL(voice_set_voc_path_full);
 
@@ -2370,9 +2448,9 @@
 			   dl_cb_fn dl_cb,
 			   void *private_data)
 {
-	voice.mvs_info.ul_cb = ul_cb;
-	voice.mvs_info.dl_cb = dl_cb;
-	voice.mvs_info.private_data = private_data;
+	common.mvs_info.ul_cb = ul_cb;
+	common.mvs_info.dl_cb = dl_cb;
+	common.mvs_info.private_data = private_data;
 }
 
 void voice_config_vocoder(uint32_t media_type,
@@ -2380,30 +2458,44 @@
 			  uint32_t network_type,
 			  uint32_t dtx_mode)
 {
-	voice.mvs_info.media_type = media_type;
-	voice.mvs_info.rate = rate;
-	voice.mvs_info.network_type = network_type;
-	voice.mvs_info.dtx_mode = dtx_mode;
+	common.mvs_info.media_type = media_type;
+	common.mvs_info.rate = rate;
+	common.mvs_info.network_type = network_type;
+	common.mvs_info.dtx_mode = dtx_mode;
 }
 
 static int32_t modem_mvm_callback(struct apr_client_data *data, void *priv)
 {
 	uint32_t *ptr;
-	struct voice_data *v = priv;
+	struct common_data *c = priv;
+	struct voice_data *v = NULL;
+	int i = 0;
 
-	pr_debug("%s\n", __func__);
+	pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
+
+	v = voice_get_session(data->dest_port);
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	pr_debug("%s: common data 0x%x, session 0x%x\n",
+		 __func__, (unsigned int)c, (unsigned int)v);
 	pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
 				data->payload_size, data->opcode);
 
 	if (data->opcode == RESET_EVENTS) {
 		pr_debug("%s:Reset event received in Voice service\n",
 					__func__);
-		apr_reset(v->apr_mvm);
-		apr_reset(v->apr_q6_mvm);
-		v->apr_q6_mvm = NULL;
-		v->apr_mvm = NULL;
-		v->mvm_handle = 0;
-		v->mvm_q6_handle = 0;
+		apr_reset(c->apr_mvm);
+		c->apr_mvm = NULL;
+		apr_reset(c->apr_q6_mvm);
+		c->apr_q6_mvm = NULL;
+
+		/* Sub-system restart is applicable to all sessions. */
+		for (i = 0; i < MAX_VOC_SESSIONS; i++)
+			c->voice[i].mvm_handle = 0;
+
 		return 0;
 	}
 
@@ -2490,21 +2582,35 @@
 static int32_t modem_cvs_callback(struct apr_client_data *data, void *priv)
 {
 	uint32_t *ptr;
-	struct voice_data *v = priv;
+	struct common_data *c = priv;
+	struct voice_data *v = NULL;
+	int i = 0;
 
-	pr_debug("%s\n", __func__);
+	pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
+
+	v = voice_get_session(data->dest_port);
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	pr_debug("%s: common data 0x%x, session 0x%x\n",
+		 __func__, (unsigned int)c, (unsigned int)v);
 	pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
 					data->payload_size, data->opcode);
 
 	if (data->opcode == RESET_EVENTS) {
 		pr_debug("%s:Reset event received in Voice service\n",
 					__func__);
-		apr_reset(v->apr_cvs);
-		apr_reset(v->apr_q6_cvs);
-		v->apr_q6_cvs = NULL;
-		v->apr_cvs = NULL;
-		v->cvs_handle = 0;
-		v->cvs_q6_handle = 0;
+		apr_reset(c->apr_cvs);
+		c->apr_cvs = NULL;
+		apr_reset(c->apr_q6_cvs);
+		c->apr_q6_cvs = NULL;
+
+		/* Sub-system restart is applicable to all sessions. */
+		for (i = 0; i < MAX_VOC_SESSIONS; i++)
+			c->voice[i].cvs_handle = 0;
+
 		return 0;
 	}
 
@@ -2609,7 +2715,7 @@
 		uint32_t *voc_pkt = data->payload;
 		uint32_t pkt_len = data->payload_size;
 
-		if (voc_pkt != NULL && v->mvs_info.ul_cb != NULL) {
+		if (voc_pkt != NULL && c->mvs_info.ul_cb != NULL) {
 			pr_debug("%s: Media type is 0x%x\n",
 				 __func__, voc_pkt[0]);
 
@@ -2617,13 +2723,13 @@
 			voc_pkt++;
 			pkt_len = pkt_len - 4;
 
-			v->mvs_info.ul_cb((uint8_t *)voc_pkt,
+			c->mvs_info.ul_cb((uint8_t *)voc_pkt,
 					  pkt_len,
-					  v->mvs_info.private_data);
+					  c->mvs_info.private_data);
 			} else {
 				pr_err("%s: voc_pkt is 0x%x ul_cb is 0x%x\n",
 				       __func__, (unsigned int)voc_pkt,
-				       (unsigned int) v->mvs_info.ul_cb);
+				       (unsigned int)c->mvs_info.ul_cb);
 			}
 	} else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) {
 			pr_debug("%s: Send dec buf resp\n", __func__);
@@ -2632,13 +2738,13 @@
 		int ret = 0;
 		uint32_t pkt_len = 0;
 
-		if (v->mvs_info.dl_cb != NULL) {
-			send_dec_buf.dec_buf.media_id = v->mvs_info.media_type;
+		if (c->mvs_info.dl_cb != NULL) {
+			send_dec_buf.dec_buf.media_id = c->mvs_info.media_type;
 
-			v->mvs_info.dl_cb(
+			c->mvs_info.dl_cb(
 				(uint8_t *)&send_dec_buf.dec_buf.packet_data,
 				&pkt_len,
-				v->mvs_info.private_data);
+				c->mvs_info.private_data);
 
 			send_dec_buf.hdr.hdr_field =
 				APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
@@ -2646,13 +2752,13 @@
 					      APR_PKT_VER);
 			send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 			       sizeof(send_dec_buf.dec_buf.media_id) + pkt_len);
-			send_dec_buf.hdr.src_port = 0;
+			send_dec_buf.hdr.src_port = v->session_id;
 			send_dec_buf.hdr.dest_port = voice_get_cvs_handle(v);
 			send_dec_buf.hdr.token = 0;
 			send_dec_buf.hdr.opcode =
 					VSS_ISTREAM_EVT_SEND_DEC_BUFFER;
 
-			ret = apr_send_pkt(voice_get_apr_cvs(v),
+			ret = apr_send_pkt(voice_get_apr_cvs(),
 					   (uint32_t *) &send_dec_buf);
 			if (ret < 0) {
 				pr_err("%s: Error %d sending DEC_BUF\n",
@@ -2679,21 +2785,35 @@
 static int32_t modem_cvp_callback(struct apr_client_data *data, void *priv)
 {
 	uint32_t *ptr;
-	struct voice_data *v = priv;
+	struct common_data *c = priv;
+	struct voice_data *v = NULL;
+	int i = 0;
 
-	pr_debug("%s\n", __func__);
+	pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
+
+	v = voice_get_session(data->dest_port);
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	pr_debug("%s: common data 0x%x, session 0x%x\n",
+		 __func__, (unsigned int)c, (unsigned int)v);
 	pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
 				data->payload_size, data->opcode);
 
 	if (data->opcode == RESET_EVENTS) {
 		pr_debug("%s:Reset event received in Voice service\n",
 					__func__);
-		apr_reset(v->apr_cvp);
-		apr_reset(v->apr_q6_cvp);
-		v->apr_q6_cvp = NULL;
-		v->apr_cvp = NULL;
-		v->cvp_handle = 0;
-		v->cvp_q6_handle = 0;
+		apr_reset(c->apr_cvp);
+		c->apr_cvp = NULL;
+		apr_reset(c->apr_q6_cvp);
+		c->apr_q6_cvp = NULL;
+
+		/* Sub-system restart is applicable to all sessions. */
+		for (i = 0; i < MAX_VOC_SESSIONS; i++)
+			c->voice[i].cvp_handle = 0;
+
 		return 0;
 	}
 
@@ -2763,55 +2883,41 @@
 
 static int __init voice_init(void)
 {
-	int rc = 0;
-	struct voice_data *v = &voice;
+	int rc = 0, i = 0;
+
+	memset(&common, 0, sizeof(struct common_data));
 
 	/* set default value */
-	v->default_mute_val = 1;  /* default is mute */
-	v->default_vol_val = 0;
-	v->default_sample_val = 8000;
+	common.default_mute_val = 1;  /* default is mute */
+	common.default_vol_val = 0;
+	common.default_sample_val = 8000;
 
-	/* initialize dev_rx and dev_tx */
-	memset(&v->dev_tx, 0, sizeof(struct device_data));
-	memset(&v->dev_rx, 0, sizeof(struct device_data));
-	v->dev_rx.volume = v->default_vol_val;
-	v->dev_tx.mute = v->default_mute_val;
-
-	v->voc_state = VOC_INIT;
-	v->voc_path = VOC_PATH_PASSIVE;
-	v->adsp_version = 0;
-	init_waitqueue_head(&v->mvm_wait);
-	init_waitqueue_head(&v->cvs_wait);
-	init_waitqueue_head(&v->cvp_wait);
-
-	mutex_init(&v->lock);
-
-	v->mvm_handle = 0;
-	v->cvs_handle = 0;
-	v->cvp_handle = 0;
-
-	v->mvm_q6_handle = 0;
-	v->cvs_q6_handle = 0;
-	v->cvp_q6_handle = 0;
-
-	v->apr_mvm = NULL;
-	v->apr_cvs = NULL;
-	v->apr_cvp = NULL;
-
-	v->apr_q6_mvm = NULL;
-	v->apr_q6_cvs = NULL;
-	v->apr_q6_cvp = NULL;
+	common.voc_path = VOC_PATH_PASSIVE;
 
 	/* Initialize MVS info. */
-	memset(&v->mvs_info, 0, sizeof(v->mvs_info));
-	v->mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
+	common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
 
-	v->rec_info.pending = 0;
-	v->rec_info.rec_mode = VOC_REC_NONE;
+	mutex_init(&common.common_lock);
 
-	memset(&v->music_info, 0, sizeof(v->music_info));
+	for (i = 0; i < MAX_VOC_SESSIONS; i++) {
+		common.voice[i].session_id = SESSION_ID_BASE + i;
 
-	v->device_events = AUDDEV_EVT_DEV_CHG_VOICE |
+		common.voice[i].dev_rx.volume = common.default_vol_val;
+		common.voice[i].dev_tx.mute = common.default_mute_val;
+
+		common.voice[i].voc_state = VOC_INIT;
+
+		common.voice[i].rec_info.rec_mode = VOC_REC_NONE;
+
+		init_waitqueue_head(&common.voice[i].mvm_wait);
+		init_waitqueue_head(&common.voice[i].cvs_wait);
+		init_waitqueue_head(&common.voice[i].cvp_wait);
+
+		mutex_init(&common.voice[i].lock);
+
+	}
+
+	common.device_events = AUDDEV_EVT_DEV_CHG_VOICE |
 			AUDDEV_EVT_DEV_RDY |
 			AUDDEV_EVT_REL_PENDING |
 			AUDDEV_EVT_START_VOICE |
@@ -2821,8 +2927,8 @@
 
 	pr_debug("to register call back\n");
 	/* register callback to auddev */
-	auddev_register_evt_listner(v->device_events, AUDDEV_CLNT_VOC,
-				0, voice_auddev_cb_function, v);
+	auddev_register_evt_listner(common.device_events, AUDDEV_CLNT_VOC,
+				0, voice_auddev_cb_function, &common);
 
 	return rc;
 }