Merge "ASoC: msm: qdsp6v2: Change incall recording to be session based"
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index edb24fc..de60430 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -63,6 +63,7 @@
static int lsm_mux_slim_port;
static int slim0_rx_aanc_fb_port;
static int msm_route_ec_ref_rx = 3; /* NONE */
+static uint32_t voc_session_id = ALL_SESSION_VSID;
enum {
MADNONE,
@@ -572,7 +573,7 @@
}
if ((msm_bedais[reg].port_id == VOICE_RECORD_RX)
|| (msm_bedais[reg].port_id == VOICE_RECORD_TX))
- voc_start_record(msm_bedais[reg].port_id, set);
+ voc_start_record(msm_bedais[reg].port_id, set, voc_session_id);
mutex_unlock(&routing_lock);
}
@@ -2632,6 +2633,30 @@
msm_routing_put_rms_value_control),
};
+static int msm_voc_session_id_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ voc_session_id = ucontrol->value.integer.value[0];
+
+ pr_debug("%s: voc_session_id=%u\n", __func__, voc_session_id);
+
+ return 0;
+}
+
+static int msm_voc_session_id_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = voc_session_id;
+
+ return 0;
+}
+
+static struct snd_kcontrol_new msm_voc_session_controls[] = {
+ SOC_SINGLE_MULTI_EXT("Voc VSID", SND_SOC_NOPM, 0,
+ 0xFFFFFFFF, 0, 1, msm_voc_session_id_get,
+ msm_voc_session_id_put),
+};
+
static const struct snd_kcontrol_new eq_enable_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia1 EQ Enable", SND_SOC_NOPM,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_eq_enable_mixer,
@@ -3910,6 +3935,10 @@
snd_soc_add_platform_controls(platform,
get_rms_controls,
ARRAY_SIZE(get_rms_controls));
+
+ snd_soc_add_platform_controls(platform, msm_voc_session_controls,
+ ARRAY_SIZE(msm_voc_session_controls));
+
return 0;
}
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 7243f19..056e2dc 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -130,6 +130,28 @@
return ret;
}
+static bool voice_is_valid_session_id(uint32_t session_id)
+{
+ bool ret = false;
+
+ switch (session_id) {
+ case VOICE_SESSION_VSID:
+ case VOICE2_SESSION_VSID:
+ case VOLTE_SESSION_VSID:
+ case VOIP_SESSION_VSID:
+ case QCHAT_SESSION_VSID:
+ case ALL_SESSION_VSID:
+ ret = true;
+ break;
+ default:
+ pr_err("%s: Invalid session_id : %x\n", __func__, session_id);
+
+ break;
+ }
+
+ return ret;
+}
+
static u16 voice_get_mvm_handle(struct voice_data *v)
{
if (v == NULL) {
@@ -2989,6 +3011,22 @@
v->music_info.force = 1;
voice_cvs_stop_playback(v);
voice_cvs_stop_record(v);
+ /* If voice call is active during VoLTE, SRVCC happens.
+ Start recording on voice session if recording started during VoLTE.
+ */
+ if (is_volte_session(v->session_id) &&
+ ((common.voice[VOC_PATH_PASSIVE].voc_state == VOC_RUN) ||
+ (common.voice[VOC_PATH_PASSIVE].voc_state == VOC_CHANGE))) {
+ if (v->rec_info.rec_enable) {
+ voice_cvs_start_record(
+ &common.voice[VOC_PATH_PASSIVE],
+ v->rec_info.rec_mode);
+ common.srvcc_rec_flag = true;
+
+ pr_debug("%s: switch recording, srvcc_rec_flag %d\n",
+ __func__, common.srvcc_rec_flag);
+ }
+ }
/* send stop voice cmd */
voice_send_stop_voice_cmd(v);
@@ -3561,17 +3599,35 @@
return ret;
}
-int voc_start_record(uint32_t port_id, uint32_t set)
+int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id)
{
int ret = 0;
int rec_mode = 0;
u16 cvs_handle;
- int i, rec_set = 0;
+ int rec_set = 0;
+ struct voice_session_itr itr;
+ struct voice_data *v = NULL;
- for (i = 0; i < MAX_VOC_SESSIONS; i++) {
- struct voice_data *v = &common.voice[i];
- pr_debug("%s: i:%d port_id: %d, set: %d\n",
- __func__, i, port_id, set);
+ /* check if session_id is valid */
+ if (!voice_is_valid_session_id(session_id)) {
+ pr_err("%s: Invalid session id:%u\n", __func__,
+ session_id);
+
+ return -EINVAL;
+ }
+
+ voice_itr_init(&itr, session_id);
+ pr_debug("%s: session_id:%u\n", __func__, session_id);
+
+ while (voice_itr_get_next_session(&itr, &v)) {
+ if (v == NULL) {
+ pr_err("%s: v is NULL, sessionid:%u\n", __func__,
+ session_id);
+
+ break;
+ }
+ pr_debug("%s: port_id: %d, set: %d, v: %p\n",
+ __func__, port_id, set, v);
mutex_lock(&v->lock);
rec_mode = v->rec_info.rec_mode;
@@ -3579,13 +3635,11 @@
if (set) {
if ((v->rec_route_state.ul_flag != 0) &&
(v->rec_route_state.dl_flag != 0)) {
- pr_debug("%s: i=%d, rec mode already set.\n",
- __func__, i);
+ pr_debug("%s: rec mode already set.\n",
+ __func__);
+
mutex_unlock(&v->lock);
- if (i < MAX_VOC_SESSIONS)
- continue;
- else
- return 0;
+ continue;
}
if (port_id == VOICE_RECORD_TX) {
@@ -3615,13 +3669,10 @@
} else {
if ((v->rec_route_state.ul_flag == 0) &&
(v->rec_route_state.dl_flag == 0)) {
- pr_debug("%s: i=%d, rec already stops.\n",
- __func__, i);
+ pr_debug("%s: rec already stops.\n",
+ __func__);
mutex_unlock(&v->lock);
- if (i < MAX_VOC_SESSIONS)
- continue;
- else
- return 0;
+ continue;
}
if (port_id == VOICE_RECORD_TX) {
@@ -3650,8 +3701,8 @@
}
}
}
- pr_debug("%s: i=%d, mode =%d, set =%d\n", __func__,
- i, rec_mode, rec_set);
+ pr_debug("%s: mode =%d, set =%d\n", __func__,
+ rec_mode, rec_set);
cvs_handle = voice_get_cvs_handle(v);
if (cvs_handle != 0) {
@@ -3661,6 +3712,18 @@
ret = voice_cvs_stop_record(v);
}
+ /* During SRVCC, recording will switch from VoLTE session to
+ voice session.
+ Then stop recording, need to stop recording on voice session.
+ */
+ if ((!rec_set) && common.srvcc_rec_flag) {
+ pr_debug("%s, srvcc_rec_flag:%d\n", __func__,
+ common.srvcc_rec_flag);
+
+ voice_cvs_stop_record(&common.voice[VOC_PATH_PASSIVE]);
+ common.srvcc_rec_flag = false;
+ }
+
/* Cache the value */
v->rec_info.rec_enable = rec_set;
v->rec_info.rec_mode = rec_mode;
@@ -4590,6 +4653,9 @@
c->voice[i].shmem_info.mem_handle = 0;
}
}
+ /* clean up srvcc rec flag */
+ c->srvcc_rec_flag = false;
+
return 0;
}
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index 1e9c813..20f2857 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -1338,6 +1338,8 @@
struct dtmf_driver_info dtmf_info;
struct voice_data voice[MAX_VOC_SESSIONS];
+
+ bool srvcc_rec_flag;
};
struct voice_session_itr {
@@ -1438,7 +1440,7 @@
uint32_t voc_get_session_id(char *name);
int voc_start_playback(uint32_t set, uint16_t port_id);
-int voc_start_record(uint32_t port_id, uint32_t set);
+int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id);
int voice_get_idx_for_session(u32 session_id);
#endif