mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
ASoC: msm: qdsp6v2: handle VoIP call recovery during SSR
Add support for VoIP call auto recovery during Sub System Restart(SSR). Change-Id: Ie8dce8f575ba3af5560c523a00e8520aef1c68c3 Signed-off-by: Venkata Narendra Kumar Gutta <vgutta@codeaurora.org>
This commit is contained in:
parent
168f6aa1df
commit
5a799cb840
3 changed files with 69 additions and 3 deletions
|
@ -144,6 +144,7 @@ struct voip_drv_info {
|
|||
spinlock_t dsp_lock;
|
||||
spinlock_t dsp_ul_lock;
|
||||
|
||||
bool voip_reset;
|
||||
uint32_t mode;
|
||||
uint32_t rate_type;
|
||||
uint32_t rate;
|
||||
|
@ -318,6 +319,34 @@ static int msm_pcm_voip_probe(struct snd_soc_platform *platform)
|
|||
/* sample rate supported */
|
||||
static unsigned int supported_sample_rates[] = {8000, 16000};
|
||||
|
||||
static void voip_ssr_cb_fn(uint32_t opcode, void *private_data)
|
||||
{
|
||||
|
||||
/* Notify ASoC to send next playback/Capture to unblock write/read */
|
||||
struct voip_drv_info *prtd = private_data;
|
||||
|
||||
if (opcode == 0xFFFFFFFF) {
|
||||
|
||||
prtd->voip_reset = true;
|
||||
pr_debug("%s: Notify ASoC to send next playback/Capture\n",
|
||||
__func__);
|
||||
|
||||
prtd->pcm_playback_irq_pos += prtd->pcm_count;
|
||||
if (prtd->state == VOIP_STARTED)
|
||||
snd_pcm_period_elapsed(prtd->playback_substream);
|
||||
wake_up(&prtd->out_wait);
|
||||
|
||||
prtd->pcm_capture_irq_pos += prtd->pcm_capture_count;
|
||||
if (prtd->state == VOIP_STARTED)
|
||||
snd_pcm_period_elapsed(prtd->capture_substream);
|
||||
wake_up(&prtd->in_wait);
|
||||
|
||||
} else {
|
||||
pr_err("%s: Invalid opcode during reset : %d\n",
|
||||
__func__, opcode);
|
||||
}
|
||||
}
|
||||
|
||||
/* capture path */
|
||||
static void voip_process_ul_pkt(uint8_t *voc_pkt,
|
||||
uint32_t pkt_len,
|
||||
|
@ -756,10 +785,20 @@ static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a,
|
|||
int count = frames_to_bytes(runtime, frames);
|
||||
pr_debug("%s: count = %d, frames=%d\n", __func__, count, (int)frames);
|
||||
|
||||
if (prtd->voip_reset) {
|
||||
pr_debug("%s: RESET event happened during VoIP\n", __func__);
|
||||
return -ENETRESET;
|
||||
}
|
||||
|
||||
ret = wait_event_interruptible_timeout(prtd->in_wait,
|
||||
(!list_empty(&prtd->free_in_queue) ||
|
||||
prtd->state == VOIP_STOPPED),
|
||||
1 * HZ);
|
||||
if (prtd->voip_reset) {
|
||||
pr_debug("%s: RESET event happened during VoIP\n", __func__);
|
||||
return -ENETRESET;
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
if (count <= VOIP_MAX_VOC_PKT_SIZE) {
|
||||
spin_lock_irqsave(&prtd->dsp_lock, dsp_flags);
|
||||
|
@ -809,11 +848,21 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream,
|
|||
|
||||
pr_debug("%s: count = %d\n", __func__, count);
|
||||
|
||||
if (prtd->voip_reset) {
|
||||
pr_debug("%s: RESET event happened during VoIP\n", __func__);
|
||||
return -ENETRESET;
|
||||
}
|
||||
|
||||
ret = wait_event_interruptible_timeout(prtd->out_wait,
|
||||
(!list_empty(&prtd->out_queue) ||
|
||||
prtd->state == VOIP_STOPPED),
|
||||
1 * HZ);
|
||||
|
||||
if (prtd->voip_reset) {
|
||||
pr_debug("%s: RESET event happened during VoIP\n", __func__);
|
||||
return -ENETRESET;
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
|
||||
if (count <= VOIP_MAX_VOC_PKT_SIZE) {
|
||||
|
@ -844,7 +893,6 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream,
|
|||
list_add_tail(&buf_node->list,
|
||||
&prtd->free_out_queue);
|
||||
spin_unlock_irqrestore(&prtd->dsp_ul_lock, dsp_flags);
|
||||
|
||||
} else {
|
||||
pr_err("%s: Read count %d > VOIP_MAX_VOC_PKT_SIZE\n",
|
||||
__func__, count);
|
||||
|
@ -904,10 +952,11 @@ static int msm_pcm_close(struct snd_pcm_substream *substream)
|
|||
|
||||
if (!prtd->playback_instance && !prtd->capture_instance) {
|
||||
if (prtd->state == VOIP_STARTED) {
|
||||
prtd->voip_reset = false;
|
||||
prtd->state = VOIP_STOPPED;
|
||||
voc_end_voice_call(
|
||||
voc_get_session_id(VOIP_SESSION_NAME));
|
||||
voc_register_mvs_cb(NULL, NULL, prtd);
|
||||
voc_register_mvs_cb(NULL, NULL, NULL, prtd);
|
||||
}
|
||||
/* release all buffer */
|
||||
/* release in_queue and free_in_queue */
|
||||
|
@ -1134,8 +1183,10 @@ static int msm_pcm_prepare(struct snd_pcm_substream *substream)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* Initialaizing cb variables */
|
||||
voc_register_mvs_cb(voip_process_ul_pkt,
|
||||
voip_process_dl_pkt, prtd);
|
||||
voip_process_dl_pkt,
|
||||
voip_ssr_cb_fn, prtd);
|
||||
|
||||
ret = voc_start_voice_call(
|
||||
voc_get_session_id(VOIP_SESSION_NAME));
|
||||
|
|
|
@ -5418,10 +5418,12 @@ exit:
|
|||
|
||||
void voc_register_mvs_cb(ul_cb_fn ul_cb,
|
||||
dl_cb_fn dl_cb,
|
||||
voip_ssr_cb ssr_cb,
|
||||
void *private_data)
|
||||
{
|
||||
common.mvs_info.ul_cb = ul_cb;
|
||||
common.mvs_info.dl_cb = dl_cb;
|
||||
common.mvs_info.ssr_cb = ssr_cb;
|
||||
common.mvs_info.private_data = private_data;
|
||||
}
|
||||
|
||||
|
@ -5472,6 +5474,14 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
|
|||
} else {
|
||||
pr_debug("%s: Reset event received in Voice service\n",
|
||||
__func__);
|
||||
|
||||
if (common.mvs_info.ssr_cb) {
|
||||
pr_debug("%s: Informing reset event to VoIP\n",
|
||||
__func__);
|
||||
common.mvs_info.ssr_cb(data->opcode,
|
||||
common.mvs_info.private_data);
|
||||
}
|
||||
|
||||
apr_reset(c->apr_q6_mvm);
|
||||
c->apr_q6_mvm = NULL;
|
||||
|
||||
|
|
|
@ -1348,6 +1348,9 @@ typedef void (*dtmf_rx_det_cb_fn)(uint8_t *pkt,
|
|||
char *session,
|
||||
void *private_data);
|
||||
|
||||
typedef void (*voip_ssr_cb) (uint32_t opcode,
|
||||
void *private_data);
|
||||
|
||||
typedef void (*hostpcm_cb_fn)(uint8_t *data,
|
||||
char *session,
|
||||
void *private_data);
|
||||
|
@ -1359,6 +1362,7 @@ struct mvs_driver_info {
|
|||
uint32_t dtx_mode;
|
||||
ul_cb_fn ul_cb;
|
||||
dl_cb_fn dl_cb;
|
||||
voip_ssr_cb ssr_cb;
|
||||
void *private_data;
|
||||
uint32_t evrc_min_rate;
|
||||
uint32_t evrc_max_rate;
|
||||
|
@ -1508,6 +1512,7 @@ struct voice_session_itr {
|
|||
|
||||
void voc_register_mvs_cb(ul_cb_fn ul_cb,
|
||||
dl_cb_fn dl_cb,
|
||||
voip_ssr_cb ssr_cb,
|
||||
void *private_data);
|
||||
|
||||
void voc_register_dtmf_rx_detection_cb(dtmf_rx_det_cb_fn dtmf_rx_ul_cb,
|
||||
|
|
Loading…
Reference in a new issue