ASoC: msm: Add support for multiple instance.

Add support for concurrent voice and VoIP calls.

Signed-off-by: Neema Shetty <nshetty@codeaurora.org>
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 097bd1c..4528f87 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -255,12 +255,22 @@
 	return 1;
 }
 
-static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set)
+static void msm_pcm_routing_process_voice(u16 reg, u16 val, u16 invert, int set)
 {
 
 	u32 port_map_id;
+	u16 session_id = 0;
 
-	pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
+	pr_debug("%s: reg %x val %x invert %x set %x\n",
+			 __func__, reg, val, invert, set);
+
+	if (invert == MSM_FRONTEND_DAI_CS_VOICE)
+		session_id = voc_get_session_id(VOICE_SESSION_NAME);
+	else
+		session_id = voc_get_session_id(VOIP_SESSION_NAME);
+
+	pr_debug("%s: FE DAI 0x%x session_id 0x%x\n",
+		 __func__, invert, session_id);
 
 	port_map_id = voice_mixers[reg].port_id;
 
@@ -270,26 +280,30 @@
 		clear_bit(val, &voice_mixers[reg].dai_sessions);
 
 	if (voice_mixers[reg].mixer_type == SNDRV_PCM_STREAM_PLAYBACK) {
-		voc_set_route_flag(RX_PATH, set);
+		voc_set_route_flag(session_id, RX_PATH, set);
 		if (set) {
-			voc_set_rxtx_port(bedai_port_map[port_map_id], DEV_RX);
+			voc_set_rxtx_port(session_id,
+					  bedai_port_map[port_map_id],
+					  DEV_RX);
 
-			if (voc_get_route_flag(RX_PATH) &&
-						voc_get_route_flag(TX_PATH))
-				voc_enable_cvp();
+			if (voc_get_route_flag(session_id, RX_PATH) &&
+			    voc_get_route_flag(session_id, TX_PATH))
+				voc_enable_cvp(session_id);
 		} else {
-			voc_disable_cvp();
+			voc_disable_cvp(session_id);
 		}
 	} else {
-		voc_set_route_flag(TX_PATH, set);
+		voc_set_route_flag(session_id, TX_PATH, set);
 		if (set) {
-			voc_set_rxtx_port(bedai_port_map[port_map_id], DEV_TX);
+			voc_set_rxtx_port(session_id,
+					  bedai_port_map[port_map_id],
+					  DEV_TX);
 
-			if (voc_get_route_flag(RX_PATH) &&
-						voc_get_route_flag(TX_PATH))
-				voc_enable_cvp();
+			if (voc_get_route_flag(session_id, RX_PATH) &&
+			    voc_get_route_flag(session_id, TX_PATH))
+				voc_enable_cvp(session_id);
 		} else {
-			voc_disable_cvp();
+			voc_disable_cvp(session_id);
 		}
 	}
 }
@@ -320,10 +334,12 @@
 		(struct soc_mixer_control *)kcontrol->private_value;
 
 	if (ucontrol->value.integer.value[0]) {
-		msm_pcm_routing_process_voice(mc->reg, mc->shift, 1);
+		msm_pcm_routing_process_voice(mc->reg, mc->shift,
+					      mc->invert, 1);
 		snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
 	} else {
-		msm_pcm_routing_process_voice(mc->reg, mc->shift, 0);
+		msm_pcm_routing_process_voice(mc->reg, mc->shift,
+					      mc->invert, 0);
 		snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
 	}
 
@@ -497,53 +513,53 @@
 
 static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = {
 	SOC_SINGLE_EXT("CSVoice", VOICE_MIXER_PRI_I2S_RX,
-	MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
-	msm_routing_put_voice_mixer),
+	MSM_FRONTEND_DAI_CS_VOICE, 1, MSM_FRONTEND_DAI_CS_VOICE,
+	msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
 	SOC_SINGLE_EXT("Voip", VOICE_MIXER_PRI_I2S_RX ,
-	MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
-	msm_routing_put_voice_mixer),
+	MSM_FRONTEND_DAI_VOIP, 1, MSM_FRONTEND_DAI_VOIP,
+	msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
 };
 
 static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = {
 	SOC_SINGLE_EXT("CSVoice", VOICE_MIXER_SLIMBUS_0_RX,
-	MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
-	msm_routing_put_voice_mixer),
+	MSM_FRONTEND_DAI_CS_VOICE, 1, MSM_FRONTEND_DAI_CS_VOICE,
+	msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
 	SOC_SINGLE_EXT("Voip", VOICE_MIXER_SLIMBUS_0_RX ,
-	MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
-	msm_routing_put_voice_mixer),
+	MSM_FRONTEND_DAI_VOIP, 1, MSM_FRONTEND_DAI_VOIP,
+	msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
 };
 
 static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = {
 	SOC_SINGLE_EXT("CSVoice", VOICE_MIXER_INT_BT_SCO_RX,
-	MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
-	msm_routing_put_voice_mixer),
+	MSM_FRONTEND_DAI_CS_VOICE, 1, MSM_FRONTEND_DAI_CS_VOICE,
+	msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
 	SOC_SINGLE_EXT("Voip", VOICE_MIXER_INT_BT_SCO_RX ,
-	MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
-	msm_routing_put_voice_mixer),
+	MSM_FRONTEND_DAI_VOIP, 1, MSM_FRONTEND_DAI_VOIP,
+	msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
 };
 
 static const struct snd_kcontrol_new tx_voice_mixer_controls[] = {
 	SOC_SINGLE_EXT("PRI_TX_Voice", VOICE_MIXER_PRI_I2S_TX,
-	MSM_BACKEND_DAI_PRI_I2S_TX, 1, 0, msm_routing_get_voice_mixer,
-	msm_routing_put_voice_mixer),
+	MSM_BACKEND_DAI_PRI_I2S_TX, 1, MSM_FRONTEND_DAI_CS_VOICE,
+	msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
 	SOC_SINGLE_EXT("SLIM_0_TX_Voice", VOICE_MIXER_SLIMBUS_0_TX,
-	MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_voice_mixer,
-	msm_routing_put_voice_mixer),
+	MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, MSM_FRONTEND_DAI_CS_VOICE,
+	msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
 	SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice", VOICE_MIXER_INT_BT_SCO_TX,
-	MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_voice_mixer,
-	msm_routing_put_voice_mixer),
+	MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, MSM_FRONTEND_DAI_CS_VOICE,
+	msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
 };
 
 static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
 	SOC_SINGLE_EXT("PRI_TX_Voip", VOICE_MIXER_PRI_I2S_TX,
-	MSM_BACKEND_DAI_PRI_I2S_TX, 1, 0, msm_routing_get_voice_mixer,
-	msm_routing_put_voice_mixer),
+	MSM_BACKEND_DAI_PRI_I2S_TX, 1, MSM_FRONTEND_DAI_VOIP,
+	msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
 	SOC_SINGLE_EXT("SLIM_0_TX_Voip", VOICE_MIXER_SLIMBUS_0_TX,
-	MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_voice_mixer,
-	msm_routing_put_voice_mixer),
+	MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, MSM_FRONTEND_DAI_VOIP,
+	msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
 	SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voip", VOICE_MIXER_INT_BT_SCO_TX,
-	MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_voice_mixer,
-	msm_routing_put_voice_mixer),
+	MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, MSM_FRONTEND_DAI_VOIP,
+	msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
 };
 
 static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = {
diff --git a/sound/soc/msm/msm-pcm-voice.c b/sound/soc/msm/msm-pcm-voice.c
index d2d0f95..c22266e 100644
--- a/sound/soc/msm/msm-pcm-voice.c
+++ b/sound/soc/msm/msm-pcm-voice.c
@@ -140,7 +140,7 @@
 	prtd->instance--;
 	if (!prtd->playback_start && !prtd->capture_start) {
 		pr_debug("end voice call\n");
-		voc_end_voice_call();
+		voc_end_voice_call(voc_get_session_id(VOICE_SESSION_NAME));
 	}
 	mutex_unlock(&prtd->lock);
 
@@ -160,7 +160,7 @@
 		ret = msm_pcm_capture_prepare(substream);
 
 	if (prtd->playback_start && prtd->capture_start)
-		voc_start_voice_call();
+		voc_start_voice_call(voc_get_session_id(VOICE_SESSION_NAME));
 
 	mutex_unlock(&prtd->lock);
 
@@ -171,7 +171,7 @@
 				struct snd_pcm_hw_params *params)
 {
 
-	pr_debug("%s, Voice\n", __func__);
+	pr_debug("%s: Voice\n", __func__);
 
 	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
 
@@ -192,7 +192,9 @@
 
 	pr_debug("%s: volume: %d\n", __func__, volume);
 
-	voc_set_rx_vol_index(RX_PATH, volume);
+	voc_set_rx_vol_index(voc_get_session_id(VOICE_SESSION_NAME),
+			     RX_PATH,
+			     volume);
 	return 0;
 }
 
@@ -210,7 +212,7 @@
 
 	pr_debug("%s: mute=%d\n", __func__, mute);
 
-	voc_set_tx_mute(TX_PATH, mute);
+	voc_set_tx_mute(voc_get_session_id(VOICE_SESSION_NAME), TX_PATH, mute);
 
 	return 0;
 }
@@ -223,7 +225,8 @@
 static int msm_voice_tty_mode_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	ucontrol->value.integer.value[0] = voc_get_tty_mode();
+	ucontrol->value.integer.value[0] =
+		voc_get_tty_mode(voc_get_session_id(VOICE_SESSION_NAME));
 	return 0;
 }
 
@@ -234,7 +237,7 @@
 
 	pr_debug("%s: tty_mode=%d\n", __func__, tty_mode);
 
-	voc_set_tty_mode(tty_mode);
+	voc_set_tty_mode(voc_get_session_id(VOICE_SESSION_NAME), tty_mode);
 
 	return 0;
 }
@@ -245,7 +248,8 @@
 
 	pr_debug("%s: wv enable=%d\n", __func__, wv_enable);
 
-	voc_set_widevoice_enable(wv_enable);
+	voc_set_widevoice_enable(voc_get_session_id(VOICE_SESSION_NAME),
+				 wv_enable);
 
 	return 0;
 }
@@ -253,7 +257,8 @@
 static int msm_voice_widevoice_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	ucontrol->value.integer.value[0] = voc_get_widevoice_enable();
+	ucontrol->value.integer.value[0] =
+	       voc_get_widevoice_enable(voc_get_session_id(VOICE_SESSION_NAME));
 	return 0;
 }
 
diff --git a/sound/soc/msm/msm-pcm-voip.c b/sound/soc/msm/msm-pcm-voip.c
index b4de5a4..c49574c 100644
--- a/sound/soc/msm/msm-pcm-voip.c
+++ b/sound/soc/msm/msm-pcm-voip.c
@@ -425,8 +425,8 @@
 	if (!prtd->playback_instance && !prtd->capture_instance) {
 		if (prtd->state == VOIP_STARTED) {
 			prtd->state = VOIP_STOPPED;
-			voc_end_voice_call();
-			voc_set_voc_path_full(0);
+			voc_end_voice_call(
+					voc_get_session_id(VOIP_SESSION_NAME));
 			voc_register_mvs_cb(NULL, NULL, prtd);
 		}
 		/* release all buffer */
@@ -513,8 +513,6 @@
 	if (prtd->playback_instance && prtd->capture_instance
 				&& (prtd->state != VOIP_STARTED)) {
 
-		voc_set_voc_path_full(1);
-
 		if ((prtd->play_samp_rate == 8000) &&
 					(prtd->cap_samp_rate == 8000))
 			voc_config_vocoder(VSS_MEDIA_ID_PCM_NB,
@@ -524,16 +522,18 @@
 			voc_config_vocoder(VSS_MEDIA_ID_PCM_WB,
 						0, VSS_NETWORK_ID_VOIP_WB);
 		else {
-			pr_err(" sample rate are not set properly\n");
-			goto err;
+			pr_debug("%s: Invalid rate playback %d, capture %d\n",
+				 __func__, prtd->play_samp_rate,
+				 prtd->cap_samp_rate);
+			goto done;
 		}
 		voc_register_mvs_cb(voip_process_ul_pkt,
 					voip_process_dl_pkt, prtd);
-		voc_start_voice_call();
+		voc_start_voice_call(voc_get_session_id(VOIP_SESSION_NAME));
 
 		prtd->state = VOIP_STARTED;
 	}
-err:
+done:
 	mutex_unlock(&prtd->lock);
 
 	return ret;
diff --git a/sound/soc/msm/qdsp6/q6voice.c b/sound/soc/msm/qdsp6/q6voice.c
index 1997bcd..e34f942 100644
--- a/sound/soc/msm/qdsp6/q6voice.c
+++ b/sound/soc/msm/qdsp6/q6voice.c
@@ -33,7 +33,7 @@
 #define VOC_PATH_PASSIVE 0
 #define VOC_PATH_FULL 1
 
-static struct voice_data voice;
+static struct common_data common;
 
 static int voice_send_enable_vocproc_cmd(struct voice_data *v);
 static int voice_send_netid_timing_cmd(struct voice_data *v);
@@ -60,20 +60,14 @@
 
 static u16 voice_get_mvm_handle(struct voice_data *v)
 {
-	u16 mvm_handle = 0;
-
 	if (v == NULL) {
 		pr_err("%s: v is NULL\n", __func__);
-		return -EINVAL;
+		return 0;
 	}
-	if (v->voc_path == VOC_PATH_PASSIVE)
-		mvm_handle = v->mvm_passive_handle;
-	else
-		mvm_handle = v->mvm_full_handle;
 
-	pr_debug("%s: mvm_handle %d\n", __func__, mvm_handle);
+	pr_debug("%s: mvm_handle %d\n", __func__, v->mvm_handle);
 
-	return mvm_handle;
+	return v->mvm_handle;
 }
 
 static void voice_set_mvm_handle(struct voice_data *v, u16 mvm_handle)
@@ -84,28 +78,19 @@
 		return;
 	}
 
-	if (v->voc_path == VOC_PATH_PASSIVE)
-		v->mvm_passive_handle = mvm_handle;
-	else
-		v->mvm_full_handle = mvm_handle;
+	v->mvm_handle = mvm_handle;
 }
 
 static u16 voice_get_cvs_handle(struct voice_data *v)
 {
-	u16 cvs_handle = 0;
-
 	if (v == NULL) {
 		pr_err("%s: v is NULL\n", __func__);
-		return -EINVAL;
+		return 0;
 	}
-	if (v->voc_path == VOC_PATH_PASSIVE)
-		cvs_handle = v->cvs_passive_handle;
-	else
-		cvs_handle = v->cvs_full_handle;
 
-	pr_debug("%s: cvs_handle %d\n", __func__, cvs_handle);
+	pr_debug("%s: cvs_handle %d\n", __func__, v->cvs_handle);
 
-	return cvs_handle;
+	return v->cvs_handle;
 }
 
 static void voice_set_cvs_handle(struct voice_data *v, u16 cvs_handle)
@@ -115,24 +100,20 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return;
 	}
-	if (v->voc_path == VOC_PATH_PASSIVE)
-		v->cvs_passive_handle = cvs_handle;
-	else
-		v->cvs_full_handle = cvs_handle;
+
+	v->cvs_handle = cvs_handle;
 }
 
 static u16 voice_get_cvp_handle(struct voice_data *v)
 {
-	u16 cvp_handle = 0;
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+		return 0;
+	}
 
-	if (v->voc_path == VOC_PATH_PASSIVE)
-		cvp_handle = v->cvp_passive_handle;
-	else
-		cvp_handle = v->cvp_full_handle;
+	pr_debug("%s: cvp_handle %d\n", __func__, v->cvp_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)
@@ -142,84 +123,118 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return;
 	}
-	if (v->voc_path == VOC_PATH_PASSIVE)
-		v->cvp_passive_handle = cvp_handle;
-	else
-		v->cvp_full_handle = cvp_handle;
+
+	v->cvp_handle = cvp_handle;
 }
 
-static int voice_apr_register(struct voice_data *v)
+uint16_t voc_get_session_id(char *name)
 {
-	void *apr_mvm, *apr_cvs, *apr_cvp;
+	u16 session_id = 0;
 
-	if (v == NULL) {
-		pr_err("%s: v is NULL\n", __func__);
-		return -EINVAL;
+	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;
 	}
-	apr_mvm = v->apr_q6_mvm;
-	apr_cvs = v->apr_q6_cvs;
-	apr_cvp = v->apr_q6_cvp;
 
-	pr_debug("into voice_apr_register_callback\n");
+	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 >= SESSION_ID_BASE) &&
+	    (session_id < SESSION_ID_BASE + MAX_VOC_SESSIONS)) {
+		v = &common.voice[session_id - SESSION_ID_BASE];
+	}
+
+	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 int voice_apr_register(void)
+{
+	pr_debug("%s\n", __func__);
+
+	mutex_lock(&common.common_lock);
+
 	/* register callback to APR */
-	if (apr_mvm == NULL) {
-		pr_debug("start to register MVM callback\n");
+	if (common.apr_q6_mvm == NULL) {
+		pr_debug("%s: Start to register MVM callback\n", __func__);
 
-		apr_mvm = apr_register("ADSP", "MVM",
-					qdsp_mvm_callback,
-					0xFFFFFFFF, v);
+		common.apr_q6_mvm = apr_register("ADSP", "MVM",
+						 qdsp_mvm_callback,
+						 0xFFFFFFFF, &common);
 
-		if (apr_mvm == NULL) {
-			pr_err("Unable to register MVM\n");
+		if (common.apr_q6_mvm == NULL) {
+			pr_err("%s: Unable to register MVM\n", __func__);
 			goto err;
 		}
-		v->apr_q6_mvm = apr_mvm;
 	}
 
-	if (apr_cvs == NULL) {
-		pr_debug("start to register CVS callback\n");
+	if (common.apr_q6_cvs == NULL) {
+		pr_debug("%s: Start to register CVS callback\n", __func__);
 
-		apr_cvs = apr_register("ADSP", "CVS",
-					qdsp_cvs_callback,
-					0xFFFFFFFF, v);
+		common.apr_q6_cvs = apr_register("ADSP", "CVS",
+						 qdsp_cvs_callback,
+						 0xFFFFFFFF, &common);
 
-		if (apr_cvs == NULL) {
-			pr_err("Unable to register CVS\n");
+		if (common.apr_q6_cvs == NULL) {
+			pr_err("%s: Unable to register CVS\n", __func__);
 			goto err;
 		}
-		v->apr_q6_cvs = apr_cvs;
 
-		rtac_set_voice_handle(RTAC_CVS, apr_cvs);
+		rtac_set_voice_handle(RTAC_CVS, common.apr_q6_cvs);
 	}
 
-	if (apr_cvp == NULL) {
-		pr_debug("start to register CVP callback\n");
+	if (common.apr_q6_cvp == NULL) {
+		pr_debug("%s: Start to register CVP callback\n", __func__);
 
-		apr_cvp = apr_register("ADSP", "CVP",
-					qdsp_cvp_callback,
-					0xFFFFFFFF, v);
+		common.apr_q6_cvp = apr_register("ADSP", "CVP",
+						 qdsp_cvp_callback,
+						 0xFFFFFFFF, &common);
 
-		if (apr_cvp == NULL) {
-			pr_err("Unable to register CVP\n");
+		if (common.apr_q6_cvp == NULL) {
+			pr_err("%s: Unable to register CVP\n", __func__);
 			goto err;
 		}
-		v->apr_q6_cvp = apr_cvp;
 
-		rtac_set_voice_handle(RTAC_CVP, apr_cvp);
+		rtac_set_voice_handle(RTAC_CVP, common.apr_q6_cvp);
 	}
+
+	mutex_unlock(&common.common_lock);
+
 	return 0;
 
 err:
-	if (v->apr_q6_cvs != NULL) {
-		apr_deregister(apr_cvs);
-		v->apr_q6_cvs = NULL;
+	if (common.apr_q6_cvs != NULL) {
+		apr_deregister(common.apr_q6_cvs);
+		common.apr_q6_cvs = NULL;
 		rtac_set_voice_handle(RTAC_CVS, NULL);
 	}
-	if (v->apr_q6_mvm != NULL) {
-		apr_deregister(apr_mvm);
-		v->apr_q6_mvm = NULL;
+	if (common.apr_q6_mvm != NULL) {
+		apr_deregister(common.apr_q6_mvm);
+		common.apr_q6_mvm = NULL;
 	}
 
+	mutex_unlock(&common.common_lock);
+
 	return -ENODEV;
 }
 
@@ -237,9 +252,9 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_mvm = v->apr_q6_mvm;
-	apr_cvs = v->apr_q6_cvs;
-	apr_cvp = v->apr_q6_cvp;
+	apr_mvm = common.apr_q6_mvm;
+	apr_cvs = common.apr_q6_cvs;
+	apr_cvp = common.apr_q6_cvp;
 
 	if (!apr_mvm || !apr_cvs || !apr_cvp) {
 		pr_err("%s: apr_mvm or apr_cvs or apr_cvp is NULL\n", __func__);
@@ -254,7 +269,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),
@@ -263,9 +278,9 @@
 						APR_HDR_SIZE,
 						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;
+			pr_debug("%s: send mvm create session pkt size = %d\n",
+				 __func__, mvm_session_cmd.hdr.pkt_size);
+			mvm_session_cmd.hdr.src_port = v->session_id;
 			mvm_session_cmd.hdr.dest_port = 0;
 			mvm_session_cmd.hdr.token = 0;
 			mvm_session_cmd.hdr.opcode =
@@ -278,7 +293,8 @@
 			ret = apr_send_pkt(apr_mvm,
 					(uint32_t *) &mvm_session_cmd);
 			if (ret < 0) {
-				pr_err("Error sending MVM_CONTROL_SESSION\n");
+				pr_err("%s: Error sending MVM_CONTROL_SESSION\n",
+				       __func__);
 				goto fail;
 			}
 			ret = wait_event_timeout(v->mvm_wait,
@@ -297,7 +313,7 @@
 					APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(mvm_session_cmd) -
 					APR_HDR_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;
 			mvm_session_cmd.hdr.opcode =
@@ -326,8 +342,9 @@
 	}
 	/* send cmd to create cvs session */
 	if (!cvs_handle) {
-		if (v->voc_path == VOC_PATH_PASSIVE) {
-			pr_debug("creating CVS passive session\n");
+		if (is_voice_session(v->session_id)) {
+			pr_debug("%s: creating CVS passive session\n",
+				 __func__);
 
 			cvs_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
 						APR_MSG_TYPE_SEQ_CMD,
@@ -337,7 +354,7 @@
 						APR_PKT_SIZE(APR_HDR_SIZE,
 						sizeof(cvs_session_cmd) -
 						APR_HDR_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 =
@@ -364,7 +381,7 @@
 			cvs_handle = voice_get_cvs_handle(v);
 
 		} else {
-			pr_debug("creating CVS full session\n");
+			pr_debug("%s: creating CVS full session\n", __func__);
 
 			cvs_full_ctl_cmd.hdr.hdr_field =
 					APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
@@ -376,18 +393,18 @@
 					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 =
 				VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION;
 			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 q6 voice", 16);
 
@@ -412,7 +429,7 @@
 			cvs_handle = voice_get_cvs_handle(v);
 
 			/* Attach MVM to CVS. */
-			pr_debug("Attach MVM to stream\n");
+			pr_debug("%s: Attach MVM to stream\n", __func__);
 
 			attach_stream_cmd.hdr.hdr_field =
 					APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
@@ -422,7 +439,7 @@
 					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 =
@@ -465,8 +482,8 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_mvm = v->apr_q6_mvm;
-	apr_cvs = v->apr_q6_cvs;
+	apr_mvm = common.apr_q6_mvm;
+	apr_cvs = common.apr_q6_cvs;
 
 	if (!apr_mvm || !apr_cvs) {
 		pr_err("%s: apr_mvm or apr_cvs is NULL\n", __func__);
@@ -476,8 +493,8 @@
 	cvs_handle = voice_get_cvs_handle(v);
 
 	/* MVM, CVS sessions are destroyed only for Full control sessions. */
-	if (v->voc_path == VOC_PATH_FULL) {
-		pr_debug("MVM detach stream\n");
+	if (is_voip_session(v->session_id)) {
+		pr_debug("%s: MVM detach stream\n", __func__);
 
 		/* Detach voice stream. */
 		detach_stream.hdr.hdr_field =
@@ -486,7 +503,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;
@@ -508,14 +525,14 @@
 			goto fail;
 		}
 		/* Destroy CVS. */
-		pr_debug("CVS destroy session\n");
+		pr_debug("%s: CVS destroy session\n", __func__);
 
 		cvs_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
 						      APR_HDR_LEN(APR_HDR_SIZE),
 						      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;
@@ -547,7 +564,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;
@@ -588,7 +605,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_mvm = v->apr_q6_mvm;
+	apr_mvm = common.apr_q6_mvm;
 
 	if (!apr_mvm) {
 		pr_err("%s: apr_mvm is NULL.\n", __func__);
@@ -605,8 +622,9 @@
 		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;
+		pr_debug("%s: pkt size = %d\n",
+			 __func__, mvm_tty_mode_cmd.hdr.pkt_size);
+		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;
@@ -616,7 +634,8 @@
 		v->mvm_state = CMD_STATUS_FAIL;
 		ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_tty_mode_cmd);
 		if (ret < 0) {
-			pr_err("Fail: sending VSS_ISTREAM_CMD_SET_TTY_MODE\n");
+			pr_err("%s: Error %d sending SET_TTY_MODE\n",
+			       __func__, ret);
 			goto fail;
 		}
 		ret = wait_event_timeout(v->mvm_wait,
@@ -644,7 +663,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvs = v->apr_q6_cvs;
+	apr_cvs = common.apr_q6_cvs;
 
 	if (!apr_cvs) {
 		pr_err("%s: apr_cvs is NULL.\n", __func__);
@@ -658,12 +677,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;
 
@@ -683,7 +702,7 @@
 		goto fail;
 	}
 	/* 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;
 
@@ -695,13 +714,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;
 
@@ -733,12 +752,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;
 
@@ -763,7 +782,7 @@
 						      APR_PKT_VER);
 		cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(cvs_set_dtx) - APR_HDR_SIZE);
-		cvs_set_dtx.hdr.src_port = 0;
+		cvs_set_dtx.hdr.src_port = v->session_id;
 		cvs_set_dtx.hdr.dest_port = cvs_handle;
 		cvs_set_dtx.hdr.token = 0;
 		cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
@@ -799,12 +818,12 @@
 		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;
 
@@ -829,7 +848,7 @@
 						      APR_PKT_VER);
 		cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				       sizeof(cvs_set_dtx) - APR_HDR_SIZE);
-		cvs_set_dtx.hdr.src_port = 0;
+		cvs_set_dtx.hdr.src_port = v->session_id;
 		cvs_set_dtx.hdr.dest_port = cvs_handle;
 		cvs_set_dtx.hdr.token = 0;
 		cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
@@ -864,7 +883,7 @@
 						      APR_PKT_VER);
 		cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					    sizeof(cvs_set_dtx) - APR_HDR_SIZE);
-		cvs_set_dtx.hdr.src_port = 0;
+		cvs_set_dtx.hdr.src_port = v->session_id;
 		cvs_set_dtx.hdr.dest_port = cvs_handle;
 		cvs_set_dtx.hdr.token = 0;
 		cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
@@ -908,7 +927,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_mvm = v->apr_q6_mvm;
+	apr_mvm = common.apr_q6_mvm;
 
 	if (!apr_mvm) {
 		pr_err("%s: apr_mvm is NULL.\n", __func__);
@@ -923,7 +942,7 @@
 				sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
 	pr_debug("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;
@@ -957,7 +976,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvp = v->apr_q6_cvp;
+	apr_cvp = common.apr_q6_cvp;
 
 	if (!apr_cvp) {
 		pr_err("%s: apr regist failed\n", __func__);
@@ -973,7 +992,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;
@@ -1008,7 +1027,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvp = v->apr_q6_cvp;
+	apr_cvp = common.apr_q6_cvp;
 
 	if (!apr_cvp) {
 		pr_err("%s: apr_cvp is NULL.\n", __func__);
@@ -1024,7 +1043,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;
@@ -1079,7 +1098,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_mvm = v->apr_q6_mvm;
+	apr_mvm = common.apr_q6_mvm;
 
 	if (!apr_mvm) {
 		pr_err("%s: apr_mvm is NULL.\n", __func__);
@@ -1094,7 +1113,7 @@
 				sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
 	pr_debug("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;
@@ -1135,7 +1154,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvs = v->apr_q6_cvs;
+	apr_cvs = common.apr_q6_cvs;
 
 	if (!apr_cvs) {
 		pr_err("%s: apr_cvs is NULL.\n", __func__);
@@ -1148,7 +1167,7 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvs_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvs_reg_cal_cmd) - APR_HDR_SIZE);
-	cvs_reg_cal_cmd.hdr.src_port = 0;
+	cvs_reg_cal_cmd.hdr.src_port = v->session_id;
 	cvs_reg_cal_cmd.hdr.dest_port = cvs_handle;
 	cvs_reg_cal_cmd.hdr.token = 0;
 	cvs_reg_cal_cmd.hdr.opcode = VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA;
@@ -1191,7 +1210,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvs = v->apr_q6_cvs;
+	apr_cvs = common.apr_q6_cvs;
 
 	if (!apr_cvs) {
 		pr_err("%s: apr_cvs is NULL.\n", __func__);
@@ -1204,7 +1223,7 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvs_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvs_dereg_cal_cmd) - APR_HDR_SIZE);
-	cvs_dereg_cal_cmd.hdr.src_port = 0;
+	cvs_dereg_cal_cmd.hdr.src_port = v->session_id;
 	cvs_dereg_cal_cmd.hdr.dest_port = cvs_handle;
 	cvs_dereg_cal_cmd.hdr.token = 0;
 	cvs_dereg_cal_cmd.hdr.opcode =
@@ -1246,7 +1265,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvp = v->apr_q6_cvp;
+	apr_cvp = common.apr_q6_cvp;
 
 	if (!apr_cvp) {
 		pr_err("%s: apr_cvp is NULL.\n", __func__);
@@ -1259,7 +1278,7 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvp_map_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvp_map_mem_cmd) - APR_HDR_SIZE);
-	cvp_map_mem_cmd.hdr.src_port = 0;
+	cvp_map_mem_cmd.hdr.src_port = v->session_id;
 	cvp_map_mem_cmd.hdr.dest_port = cvp_handle;
 	cvp_map_mem_cmd.hdr.token = 0;
 	cvp_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
@@ -1306,7 +1325,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvp = v->apr_q6_cvp;
+	apr_cvp = common.apr_q6_cvp;
 
 	if (!apr_cvp) {
 		pr_err("%s: apr_cvp is NULL.\n", __func__);
@@ -1319,7 +1338,7 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvp_unmap_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvp_unmap_mem_cmd) - APR_HDR_SIZE);
-	cvp_unmap_mem_cmd.hdr.src_port = 0;
+	cvp_unmap_mem_cmd.hdr.src_port = v->session_id;
 	cvp_unmap_mem_cmd.hdr.dest_port = cvp_handle;
 	cvp_unmap_mem_cmd.hdr.token = 0;
 	cvp_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
@@ -1362,7 +1381,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvs = v->apr_q6_cvs;
+	apr_cvs = common.apr_q6_cvs;
 
 	if (!apr_cvs) {
 		pr_err("%s: apr_cvs is NULL.\n", __func__);
@@ -1375,7 +1394,7 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvs_map_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvs_map_mem_cmd) - APR_HDR_SIZE);
-	cvs_map_mem_cmd.hdr.src_port = 0;
+	cvs_map_mem_cmd.hdr.src_port = v->session_id;
 	cvs_map_mem_cmd.hdr.dest_port = cvs_handle;
 	cvs_map_mem_cmd.hdr.token = 0;
 	cvs_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
@@ -1422,7 +1441,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvs = v->apr_q6_cvs;
+	apr_cvs = common.apr_q6_cvs;
 
 	if (!apr_cvs) {
 		pr_err("%s: apr_cvs is NULL.\n", __func__);
@@ -1435,7 +1454,7 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvs_unmap_mem_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvs_unmap_mem_cmd) - APR_HDR_SIZE);
-	cvs_unmap_mem_cmd.hdr.src_port = 0;
+	cvs_unmap_mem_cmd.hdr.src_port = v->session_id;
 	cvs_unmap_mem_cmd.hdr.dest_port = cvs_handle;
 	cvs_unmap_mem_cmd.hdr.token = 0;
 	cvs_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
@@ -1478,7 +1497,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvp = v->apr_q6_cvp;
+	apr_cvp = common.apr_q6_cvp;
 
 	if (!apr_cvp) {
 		pr_err("%s: apr_cvp is NULL.\n", __func__);
@@ -1491,7 +1510,7 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvp_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvp_reg_cal_cmd) - APR_HDR_SIZE);
-	cvp_reg_cal_cmd.hdr.src_port = 0;
+	cvp_reg_cal_cmd.hdr.src_port = v->session_id;
 	cvp_reg_cal_cmd.hdr.dest_port = cvp_handle;
 	cvp_reg_cal_cmd.hdr.token = 0;
 	cvp_reg_cal_cmd.hdr.opcode = VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA;
@@ -1534,7 +1553,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvp = v->apr_q6_cvp;
+	apr_cvp = common.apr_q6_cvp;
 
 	if (!apr_cvp) {
 		pr_err("%s: apr_cvp is NULL.\n", __func__);
@@ -1547,7 +1566,7 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvp_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvp_dereg_cal_cmd) - APR_HDR_SIZE);
-	cvp_dereg_cal_cmd.hdr.src_port = 0;
+	cvp_dereg_cal_cmd.hdr.src_port = v->session_id;
 	cvp_dereg_cal_cmd.hdr.dest_port = cvp_handle;
 	cvp_dereg_cal_cmd.hdr.token = 0;
 	cvp_dereg_cal_cmd.hdr.opcode =
@@ -1589,7 +1608,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvp = v->apr_q6_cvp;
+	apr_cvp = common.apr_q6_cvp;
 
 	if (!apr_cvp) {
 		pr_err("%s: apr_cvp is NULL.\n", __func__);
@@ -1602,7 +1621,7 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvp_reg_cal_tbl_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvp_reg_cal_tbl_cmd) - APR_HDR_SIZE);
-	cvp_reg_cal_tbl_cmd.hdr.src_port = 0;
+	cvp_reg_cal_tbl_cmd.hdr.src_port = v->session_id;
 	cvp_reg_cal_tbl_cmd.hdr.dest_port = cvp_handle;
 	cvp_reg_cal_tbl_cmd.hdr.token = 0;
 	cvp_reg_cal_tbl_cmd.hdr.opcode =
@@ -1646,7 +1665,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvp = v->apr_q6_cvp;
+	apr_cvp = common.apr_q6_cvp;
 
 	if (!apr_cvp) {
 		pr_err("%s: apr_cvp is NULL.\n", __func__);
@@ -1661,7 +1680,7 @@
 						APR_PKT_VER);
 	cvp_dereg_cal_tbl_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvp_dereg_cal_tbl_cmd) - APR_HDR_SIZE);
-	cvp_dereg_cal_tbl_cmd.hdr.src_port = 0;
+	cvp_dereg_cal_tbl_cmd.hdr.src_port = v->session_id;
 	cvp_dereg_cal_tbl_cmd.hdr.dest_port = cvp_handle;
 	cvp_dereg_cal_tbl_cmd.hdr.token = 0;
 	cvp_dereg_cal_tbl_cmd.hdr.opcode =
@@ -1685,6 +1704,7 @@
 	return -EINVAL;
 
 }
+
 static int voice_send_set_widevoice_enable_cmd(struct voice_data *v)
 {
 	struct mvm_set_widevoice_enable_cmd mvm_set_wv_cmd;
@@ -1696,7 +1716,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_mvm = v->apr_q6_mvm;
+	apr_mvm = common.apr_q6_mvm;
 
 	if (!apr_mvm) {
 		pr_err("%s: apr_mvm is NULL.\n", __func__);
@@ -1709,7 +1729,7 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	mvm_set_wv_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(mvm_set_wv_cmd) - APR_HDR_SIZE);
-	mvm_set_wv_cmd.hdr.src_port = 0;
+	mvm_set_wv_cmd.hdr.src_port = v->session_id;
 	mvm_set_wv_cmd.hdr.dest_port = mvm_handle;
 	mvm_set_wv_cmd.hdr.token = 0;
 	mvm_set_wv_cmd.hdr.opcode = VSS_IWIDEVOICE_CMD_SET_WIDEVOICE;
@@ -1743,7 +1763,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvp = v->apr_q6_cvp;
+	apr_cvp = common.apr_q6_cvp;
 
 	if (!apr_cvp) {
 		pr_err("%s: apr_cvp is NULL.\n", __func__);
@@ -1758,7 +1778,7 @@
 				sizeof(cvp_session_cmd) - APR_HDR_SIZE);
 	pr_debug(" 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 =
@@ -1832,7 +1852,7 @@
 	if (v->wv_enable)
 		voice_send_set_widevoice_enable_cmd(v);
 
-	if (v->voc_path == VOC_PATH_FULL)
+	if (is_voip_session(v->session_id))
 		voice_send_netid_timing_cmd(v);
 
 	rtac_add_voice(voice_get_cvs_handle(v),
@@ -1856,7 +1876,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvp = v->apr_q6_cvp;
+	apr_cvp = common.apr_q6_cvp;
 
 	if (!apr_cvp) {
 		pr_err("%s: apr_cvp is NULL.\n", __func__);
@@ -1872,7 +1892,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;
@@ -1908,7 +1928,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_mvm = v->apr_q6_mvm;
+	apr_mvm = common.apr_q6_mvm;
 
 	if (!apr_mvm) {
 		pr_err("%s: apr_mvm is NULL.\n", __func__);
@@ -1930,11 +1950,11 @@
 						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);
@@ -1960,7 +1980,7 @@
 	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 = VSS_ICOMMON_CMD_SET_VOICE_TIMING;
@@ -2001,7 +2021,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_mvm = v->apr_q6_mvm;
+	apr_mvm = common.apr_q6_mvm;
 
 	if (!apr_mvm) {
 		pr_err("%s: apr_mvm is NULL.\n", __func__);
@@ -2018,7 +2038,7 @@
 				sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
 	pr_debug("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_IMVM_CMD_ATTACH_VOCPROC;
@@ -2055,8 +2075,8 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_mvm = v->apr_q6_mvm;
-	apr_cvp = v->apr_q6_cvp;
+	apr_mvm = common.apr_q6_mvm;
+	apr_cvp = common.apr_q6_cvp;
 
 	if (!apr_mvm || !apr_cvp) {
 		pr_err("%s: apr_mvm or apr_cvp is NULL.\n", __func__);
@@ -2076,7 +2096,7 @@
 				sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
 	pr_debug("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_IMVM_CMD_DETACH_VOCPROC;
@@ -2113,7 +2133,7 @@
 				sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
 	pr_debug("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;
@@ -2153,7 +2173,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvs = v->apr_q6_cvs;
+	apr_cvs = common.apr_q6_cvs;
 
 	if (!apr_cvs) {
 		pr_err("%s: apr_cvs is NULL.\n", __func__);
@@ -2167,7 +2187,7 @@
 						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;
@@ -2202,7 +2222,7 @@
 		pr_err("%s: v is NULL\n", __func__);
 		return -EINVAL;
 	}
-	apr_cvp = v->apr_q6_cvp;
+	apr_cvp = common.apr_q6_cvp;
 
 	if (!apr_cvp) {
 		pr_err("%s: apr_cvp is NULL.\n", __func__);
@@ -2216,7 +2236,7 @@
 						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 = VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX;
@@ -2237,11 +2257,17 @@
 	return 0;
 }
 
-int voc_disable_cvp(void)
+int voc_disable_cvp(uint16_t session_id)
 {
-	struct voice_data *v = &voice;
+	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
 
+	if (v == NULL) {
+		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+
+		return -EINVAL;
+	}
+
 	mutex_lock(&v->lock);
 
 	if (v->voc_state == VOC_RUN) {
@@ -2268,12 +2294,18 @@
 	return ret;
 }
 
-int voc_enable_cvp(void)
+int voc_enable_cvp(uint16_t session_id)
 {
-	struct voice_data *v = &voice;
+	struct voice_data *v = voice_get_session(session_id);
 	struct sidetone_cal sidetone_cal_data;
 	int ret = 0;
 
+	if (v == NULL) {
+		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+
+		return -EINVAL;
+	}
+
 	mutex_lock(&v->lock);
 
 	if (v->voc_state == VOC_CHANGE) {
@@ -2290,7 +2322,7 @@
 		}
 		ret = voice_send_enable_vocproc_cmd(v);
 		if (ret < 0) {
-			pr_err("enable vocproc failed\n");
+			pr_err("%s: enable vocproc failed\n", __func__);
 			goto fail;
 
 		}
@@ -2307,7 +2339,7 @@
 						sidetone_cal_data.gain);
 
 		if (ret < 0)
-			pr_err("AFE command sidetone failed\n");
+			pr_err("%s: AFE command sidetone failed\n", __func__);
 
 		rtac_add_voice(voice_get_cvs_handle(v),
 			voice_get_cvp_handle(v),
@@ -2321,11 +2353,17 @@
 	return ret;
 }
 
-int voc_set_tx_mute(uint32_t dir, uint32_t mute)
+int voc_set_tx_mute(uint16_t session_id, uint32_t dir, uint32_t mute)
 {
-	struct voice_data *v = &voice;
+	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
 
+	if (v == NULL) {
+		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+
+		return -EINVAL;
+	}
+
 	mutex_lock(&v->lock);
 
 	v->dev_tx.mute = mute;
@@ -2338,11 +2376,17 @@
 	return ret;
 }
 
-int voc_set_tty_mode(uint8_t tty_mode)
+int voc_set_tty_mode(uint16_t session_id, uint8_t tty_mode)
 {
-	struct voice_data *v = &voice;
+	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
 
+	if (v == NULL) {
+		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+
+		return -EINVAL;
+	}
+
 	mutex_lock(&v->lock);
 
 	v->tty_mode = tty_mode;
@@ -2352,11 +2396,17 @@
 	return ret;
 }
 
-uint8_t voc_get_tty_mode(void)
+uint8_t voc_get_tty_mode(uint16_t session_id)
 {
-	struct voice_data *v = &voice;
+	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
 
+	if (v == NULL) {
+		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+
+		return -EINVAL;
+	}
+
 	mutex_lock(&v->lock);
 
 	ret = v->tty_mode;
@@ -2366,11 +2416,17 @@
 	return ret;
 }
 
-int voc_set_widevoice_enable(uint32_t wv_enable)
+int voc_set_widevoice_enable(uint16_t session_id, uint32_t wv_enable)
 {
-	struct voice_data *v = &voice;
+	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
 
+	if (v == NULL) {
+		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+
+		return -EINVAL;
+	}
+
 	mutex_lock(&v->lock);
 
 	v->wv_enable = wv_enable;
@@ -2380,11 +2436,17 @@
 	return ret;
 }
 
-uint32_t voc_get_widevoice_enable(void)
+uint32_t voc_get_widevoice_enable(uint16_t session_id)
 {
-	struct voice_data *v = &voice;
+	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
 
+	if (v == NULL) {
+		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+
+		return -EINVAL;
+	}
+
 	mutex_lock(&v->lock);
 
 	ret = v->wv_enable;
@@ -2394,11 +2456,17 @@
 	return ret;
 }
 
-int voc_set_rx_vol_index(uint32_t dir, uint32_t vol_idx)
+int voc_set_rx_vol_index(uint16_t session_id, uint32_t dir, uint32_t vol_idx)
 {
-	struct voice_data *v = &voice;
+	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
 
+	if (v == NULL) {
+		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+
+		return -EINVAL;
+	}
+
 	mutex_lock(&v->lock);
 
 	v->dev_rx.volume = vol_idx;
@@ -2411,11 +2479,17 @@
 	return ret;
 }
 
-void voc_set_rxtx_port(uint32_t port_id, uint32_t dev_type)
+int voc_set_rxtx_port(uint16_t session_id, uint32_t port_id, uint32_t dev_type)
 {
-	struct voice_data *v = &voice;
+	struct voice_data *v = voice_get_session(session_id);
 
-	pr_debug(" port_id=%d, type=%d\n", port_id, dev_type);
+	if (v == NULL) {
+		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+
+		return -EINVAL;
+	}
+
+	pr_debug("%s: port_id=%d, type=%d\n", __func__, port_id, dev_type);
 
 	mutex_lock(&v->lock);
 
@@ -2426,14 +2500,20 @@
 
 	mutex_unlock(&v->lock);
 
-	return;
+	return 0;
 }
 
-void voc_set_route_flag(uint8_t path_dir, uint8_t set)
+int voc_set_route_flag(uint16_t session_id, uint8_t path_dir, uint8_t set)
 {
-	struct voice_data *v = &voice;
+	struct voice_data *v = voice_get_session(session_id);
 
-	pr_debug("path_dir=%d, set=%d\n", path_dir, set);
+	if (v == NULL) {
+		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+
+		return -EINVAL;
+	}
+
+	pr_debug("%s: path_dir=%d, set=%d\n", __func__, path_dir, set);
 
 	mutex_lock(&v->lock);
 
@@ -2444,14 +2524,20 @@
 
 	mutex_unlock(&v->lock);
 
-	return;
+	return 0;
 }
 
-uint8_t voc_get_route_flag(uint8_t path_dir)
+uint8_t voc_get_route_flag(uint16_t session_id, uint8_t path_dir)
 {
-	struct voice_data *v = &voice;
+	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
 
+	if (v == NULL) {
+		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+
+		return 0;
+	}
+
 	mutex_lock(&v->lock);
 
 	if (path_dir == RX_PATH)
@@ -2464,11 +2550,17 @@
 	return ret;
 }
 
-int voc_end_voice_call(void)
+int voc_end_voice_call(uint16_t session_id)
 {
-	struct voice_data *v = &voice;
+	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
 
+	if (v == NULL) {
+		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+
+		return -EINVAL;
+	}
+
 	mutex_lock(&v->lock);
 
 	if (v->voc_state == VOC_RUN) {
@@ -2484,17 +2576,23 @@
 	return ret;
 }
 
-int voc_start_voice_call(void)
+int voc_start_voice_call(uint16_t session_id)
 {
-	struct voice_data *v = &voice;
+	struct voice_data *v = voice_get_session(session_id);
 	struct sidetone_cal sidetone_cal_data;
 	int ret = 0;
 
+	if (v == NULL) {
+		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+
+		return -EINVAL;
+	}
+
 	mutex_lock(&v->lock);
 
 	if ((v->voc_state == VOC_INIT) ||
 		(v->voc_state == VOC_RELEASE)) {
-		ret = voice_apr_register(v);
+		ret = voice_apr_register();
 		if (ret < 0) {
 			pr_err("%s:  apr register failed\n", __func__);
 			goto fail;
@@ -2529,59 +2627,45 @@
 	return ret;
 }
 
-int voc_set_voc_path_full(uint32_t set)
-{
-	int rc = 0;
-
-	pr_debug("set voc path: %d\n", set);
-
-	mutex_lock(&voice.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);
-		rc = -EPERM;
-	}
-
-	mutex_unlock(&voice.lock);
-
-	return rc;
-}
-EXPORT_SYMBOL(voc_set_voc_path_full);
-
 void voc_register_mvs_cb(ul_cb_fn ul_cb,
 			   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 voc_config_vocoder(uint32_t media_type,
 			  uint32_t rate,
 			  uint32_t network_type)
 {
-	voice.mvs_info.media_type = media_type;
-	voice.mvs_info.rate = rate;
-	voice.mvs_info.network_type = network_type;
+	common.mvs_info.media_type = media_type;
+	common.mvs_info.rate = rate;
+	common.mvs_info.network_type = network_type;
 }
 
 static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
 {
-	uint32_t *ptr;
-	struct voice_data *v;
+	uint32_t *ptr = NULL;
+	struct common_data *c = NULL;
+	struct voice_data *v = NULL;
 
 	if ((data == NULL) || (priv == NULL)) {
 		pr_err("%s: data or priv is NULL\n", __func__);
 		return -EINVAL;
 	}
-	v = priv;
+
+	c = priv;
+
+	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: Payload Length = %d, opcode=%x\n", __func__,
 		data->payload_size, data->opcode);
@@ -2636,14 +2720,25 @@
 
 static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
 {
-	uint32_t *ptr;
-	struct voice_data *v;
+	uint32_t *ptr = NULL;
+	struct common_data *c = NULL;
+	struct voice_data *v = NULL;
 
 	if ((data == NULL) || (priv == NULL)) {
 		pr_err("%s: data or priv is NULL\n", __func__);
 		return -EINVAL;
 	}
-	v = priv;
+
+	c = priv;
+
+	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: Payload Length = %d, opcode=%x\n", __func__,
 		data->payload_size, data->opcode);
@@ -2695,7 +2790,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]);
 
@@ -2703,25 +2798,25 @@
 			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_REQUEST_DEC_BUFFER) {
 		struct cvs_send_dec_buf_cmd send_dec_buf;
 		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,
@@ -2729,13 +2824,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(v->apr_q6_cvs,
+			ret = apr_send_pkt(c->apr_q6_cvs,
 					   (uint32_t *) &send_dec_buf);
 			if (ret < 0) {
 				pr_err("%s: Error %d sending DEC_BUF\n",
@@ -2758,14 +2853,23 @@
 
 static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv)
 {
-	uint32_t *ptr;
-	struct voice_data *v;
+	uint32_t *ptr = NULL;
+	struct common_data *c = NULL;
+	struct voice_data *v = NULL;
 
 	if ((data == NULL) || (priv == NULL)) {
 		pr_err("%s: data or priv is NULL\n", __func__);
 		return -EINVAL;
 	}
-	v = priv;
+
+	c = priv;
+
+	v = voice_get_session(data->dest_port);
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+
+		return -EINVAL;
+	}
 
 	pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__,
 		data->payload_size, data->opcode);
@@ -2823,48 +2927,39 @@
 
 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;
-	v->sidetone_gain = 0x512;
-
-	/* 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->dev_tx.port_id = 1;
-	v->dev_rx.port_id = 0;
-
-	v->tty_mode = 0;
-
-	v->voc_state = VOC_INIT;
-	v->voc_path = VOC_PATH_PASSIVE;
-	init_waitqueue_head(&v->mvm_wait);
-	init_waitqueue_head(&v->cvs_wait);
-	init_waitqueue_head(&v->cvp_wait);
-
-	mutex_init(&v->lock);
-
-	v->mvm_full_handle = 0;
-	v->mvm_passive_handle = 0;
-	v->cvs_full_handle = 0;
-	v->cvs_passive_handle = 0;
-	v->cvp_full_handle = 0;
-	v->cvp_passive_handle = 0;
-
-	v->apr_q6_mvm = NULL;
-	v->apr_q6_cvs = NULL;
-	v->apr_q6_cvp = NULL;
+	common.default_mute_val = 1;  /* default is mute */
+	common.default_vol_val = 0;
+	common.default_sample_val = 8000;
 
 	/* 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;
+
+	mutex_init(&common.common_lock);
+
+	for (i = 0; i < MAX_VOC_SESSIONS; i++) {
+		common.voice[i].session_id = SESSION_ID_BASE + i;
+
+		/* initialize dev_rx and dev_tx */
+		common.voice[i].dev_rx.volume = common.default_vol_val;
+		common.voice[i].dev_tx.mute = common.default_mute_val;
+
+		common.voice[i].dev_tx.port_id = 1;
+		common.voice[i].dev_rx.port_id = 0;
+		common.voice[i].sidetone_gain = 0x512;
+
+		common.voice[i].voc_state = VOC_INIT;
+
+		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);
+	}
 
 	return rc;
 }
diff --git a/sound/soc/msm/qdsp6/q6voice.h b/sound/soc/msm/qdsp6/q6voice.h
index 46d6496..c98b53b 100644
--- a/sound/soc/msm/qdsp6/q6voice.h
+++ b/sound/soc/msm/qdsp6/q6voice.h
@@ -464,7 +464,7 @@
 struct cvs_create_full_ctl_session_cmd {
 	struct apr_hdr hdr;
 	struct vss_istream_cmd_create_full_control_session_t cvs_session;
-};
+} __packed;
 
 struct cvs_destroy_session_cmd {
 	struct apr_hdr hdr;
@@ -733,23 +733,46 @@
 
 struct voice_data {
 	int voc_state;/*INIT, CHANGE, RELEASE, RUN */
-	uint32_t voc_path;
 
 	wait_queue_head_t mvm_wait;
 	wait_queue_head_t cvs_wait;
 	wait_queue_head_t cvp_wait;
 
-	uint32_t device_events;
-
 	/* cache the values related to Rx and Tx */
 	struct device_data dev_rx;
 	struct device_data dev_tx;
 
+	u32 mvm_state;
+	u32 cvs_state;
+	u32 cvp_state;
+
+	/* Handle to MVM in the Q6 */
+	u16 mvm_handle;
+	/* Handle to CVS in the Q6 */
+	u16 cvs_handle;
+	/* Handle to CVP in the Q6 */
+	u16 cvp_handle;
+
+	struct mutex lock;
+
+	uint16_t sidetone_gain;
+	uint8_t tty_mode;
+	/* widevoice enable value */
+	uint8_t wv_enable;
+
+	struct voice_dev_route_state voc_route_state;
+
+	u16 session_id;
+};
+
+#define MAX_VOC_SESSIONS 2
+#define SESSION_ID_BASE 0xFFF0
+
+struct common_data {
 	/* these default values are for all devices */
 	uint32_t default_mute_val;
 	uint32_t default_vol_val;
 	uint32_t default_sample_val;
-	uint8_t tty_mode;
 
 	/* APR to MVM in the Q6 */
 	void *apr_q6_mvm;
@@ -758,33 +781,13 @@
 	/* APR to CVP in the Q6 */
 	void *apr_q6_cvp;
 
-	u32 mvm_state;
-	u32 cvs_state;
-	u32 cvp_state;
-
-	/* Handle to MVM in the Q6 */
-	u16 mvm_passive_handle;  /* for cs call */
-	u16 mvm_full_handle;     /* for voip */
-	/* Handle to CVS in the Q6 */
-	u16 cvs_passive_handle;
-	u16 cvs_full_handle;
-	/* Handle to CVP in the Q6 */
-	u16 cvp_passive_handle;
-	u16 cvp_full_handle;
-
-	struct mutex lock;
+	struct mutex common_lock;
 
 	struct mvs_driver_info mvs_info;
 
-	uint16_t sidetone_gain;
-
-	struct voice_dev_route_state voc_route_state;
-	/* widevoice enable value */
-	uint8_t wv_enable;
+	struct voice_data voice[MAX_VOC_SESSIONS];
 };
 
-int voc_set_voc_path_full(uint32_t set);
-
 void voc_register_mvs_cb(ul_cb_fn ul_cb,
 			dl_cb_fn dl_cb,
 			void *private_data);
@@ -804,18 +807,24 @@
 };
 
 /* called  by alsa driver */
-int voc_set_widevoice_enable(uint32_t wv_enable);
-uint32_t voc_get_widevoice_enable(void);
-uint8_t voc_get_tty_mode(void);
-int voc_set_tty_mode(uint8_t tty_mode);
-int voc_start_voice_call(void);
-int voc_end_voice_call(void);
-void voc_set_rxtx_port(uint32_t dev_port_id, uint32_t dev_type);
-int voc_set_rx_vol_index(uint32_t dir, uint32_t voc_idx);
-int voc_set_tx_mute(uint32_t dir, uint32_t mute);
-int voc_disable_cvp(void);
-int voc_enable_cvp(void);
-void voc_set_route_flag(uint8_t path_dir, uint8_t set);
-uint8_t voc_get_route_flag(uint8_t path_dir);
+int voc_set_widevoice_enable(uint16_t session_id, uint32_t wv_enable);
+uint32_t voc_get_widevoice_enable(uint16_t session_id);
+uint8_t voc_get_tty_mode(uint16_t session_id);
+int voc_set_tty_mode(uint16_t session_id, uint8_t tty_mode);
+int voc_start_voice_call(uint16_t session_id);
+int voc_end_voice_call(uint16_t session_id);
+int voc_set_rxtx_port(uint16_t session_id,
+		      uint32_t dev_port_id,
+		      uint32_t dev_type);
+int voc_set_rx_vol_index(uint16_t session_id, uint32_t dir, uint32_t voc_idx);
+int voc_set_tx_mute(uint16_t session_id, uint32_t dir, uint32_t mute);
+int voc_disable_cvp(uint16_t session_id);
+int voc_enable_cvp(uint16_t session_id);
+int voc_set_route_flag(uint16_t session_id, uint8_t path_dir, uint8_t set);
+uint8_t voc_get_route_flag(uint16_t session_id, uint8_t path_dir);
+
+#define VOICE_SESSION_NAME "Voice session"
+#define VOIP_SESSION_NAME "VoIP session"
+uint16_t voc_get_session_id(char *name);
 
 #endif