From 6420f70b2d4db7ab2af9d537eff00c91eec05f15 Mon Sep 17 00:00:00 2001 From: Meghana Reddy Mula Date: Tue, 10 Sep 2019 17:14:32 +0530 Subject: [PATCH 1/2] dsp: Add new mixer control to reset ecns Add support for mixer control to enable/disable ecns module for voice call. Change-Id: I085411c4a6394d27880f8055b3348c1eb5f2b6ff Signed-off-by: Meghana Reddy Mula --- dsp/q6voice.c | 129 ++++++++++++++++++++++++++++++++++++++++++ include/dsp/q6voice.h | 54 ++++++++++++++++++ 2 files changed, 183 insertions(+) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 3db75d02c54f..77a08ee6fff8 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -110,6 +110,10 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv); static int voice_send_set_pp_enable_cmd( struct voice_data *v, struct module_instance_info mod_inst_info, int enable); + +static int voice_send_cvp_ecns_enable_cmd(struct voice_data *v, + uint32_t module_id, int enable); + static int is_cal_memory_allocated(void); static bool is_cvd_version_queried(void); static int is_voip_memory_allocated(void); @@ -1544,6 +1548,124 @@ fail: return ret; } +static int voice_send_cvp_ecns_enable_cmd(struct voice_data *v, + uint32_t module_id, int enable) +{ + int ret; + struct cvp_set_channel_ecns_cmd_v2 cvp_set_ch_ecns_cmd; + void *apr_cvp; + u16 cvp_handle; + struct vss_icommon_param_data_ecns_t *cvp_config_param_data = + &cvp_set_ch_ecns_cmd. + cvp_set_ecns.param_data; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + apr_cvp = common.apr_q6_cvp; + + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + cvp_handle = voice_get_cvp_handle(v); + memset(&cvp_set_ch_ecns_cmd, 0, + sizeof(cvp_set_ch_ecns_cmd)); + + cvp_set_ch_ecns_cmd.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_set_ch_ecns_cmd.hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_set_ch_ecns_cmd) - APR_HDR_SIZE); + cvp_set_ch_ecns_cmd.hdr.src_svc = 0; + cvp_set_ch_ecns_cmd.hdr.src_domain = APR_DOMAIN_APPS; + cvp_set_ch_ecns_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_set_ch_ecns_cmd.hdr.dest_svc = 0; + cvp_set_ch_ecns_cmd.hdr.dest_domain = APR_DOMAIN_ADSP; + cvp_set_ch_ecns_cmd.hdr.dest_port = cvp_handle; + cvp_set_ch_ecns_cmd.hdr.token = 0; + cvp_set_ch_ecns_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2; + cvp_set_ch_ecns_cmd.cvp_set_ecns.mem_size = + sizeof(struct vss_icommon_param_data_ecns_t); + + cvp_config_param_data->module_id = module_id; + cvp_config_param_data->param_id = VOICE_PARAM_MOD_ENABLE; + cvp_config_param_data->param_size = MOD_ENABLE_PARAM_LEN; + cvp_config_param_data->reserved = 0; + cvp_config_param_data->enable = enable; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *)&cvp_set_ch_ecns_cmd); + + if (ret < 0) { + pr_err("%s: Failed to send VSS_ICOMMON_CMD_SET_PARAM_V2 %d\n", + __func__, ret); + goto done; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s] handle = %d\n", __func__, + adsp_err_get_err_str(v->async_err), cvp_handle); + ret = adsp_err_get_lnx_err_code(v->async_err); + goto done; + } + ret = 0; +done: + return ret; +} + +/** + * voc_set_ecns_enable - + * Command to set ECNS for voice module + * + * @session_id: voice session ID to send this command + * @module_id: voice module id + * @enable: enable/disable flag + * + * Returns 0 on success or error on failure + */ +int voc_set_ecns_enable(uint32_t session_id, uint32_t module_id, + uint32_t enable) +{ + 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->ecns_enable = enable; + v->ecns_module_id = module_id; + + if (is_voc_state_active(v->voc_state)) + ret = voice_send_cvp_ecns_enable_cmd(v, + v->ecns_module_id, v->ecns_enable); + + mutex_unlock(&v->lock); + + return ret; +} +EXPORT_SYMBOL(voc_set_ecns_enable); + static int voice_send_set_pp_enable_cmd( struct voice_data *v, struct module_instance_info mod_inst_info, int enable) @@ -4420,6 +4542,10 @@ static int voice_setup_vocproc(struct voice_data *v) if (v->dtmf_rx_detect_en) voice_send_dtmf_rx_detection_cmd(v, v->dtmf_rx_detect_en); + if (v->ecns_enable) + voice_send_cvp_ecns_enable_cmd(v, v->ecns_module_id, + v->ecns_enable); + if (v->hd_enable) voice_send_hd_cmd(v, v->hd_enable); @@ -5076,6 +5202,9 @@ static int voice_destroy_vocproc(struct voice_data *v) if (v->dtmf_rx_detect_en) voice_send_dtmf_rx_detection_cmd(v, 0); + if (v->ecns_enable) + voice_send_cvp_ecns_enable_cmd(v, v->ecns_module_id, 0); + /* detach VOCPROC and wait for response from mvm */ mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index 2edfbe215fd7..35ace4eed388 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -312,6 +312,21 @@ struct vss_icommon_param_data_ch_mixer_v2_t { struct vss_param_channel_mixer_info_t ch_mixer_info; } __packed; +struct vss_icommon_param_data_ecns_t { + /* Valid ID of the module. */ + uint32_t module_id; + /* Valid ID of the parameter. */ + uint32_t param_id; + /* + * Data size of the structure relating to the param_id/module_id + * combination in uint8_t bytes. + */ + uint16_t param_size; + /* This field must be set to zero. */ + uint16_t reserved; + uint32_t enable; +} __packed; + struct vss_icommon_cmd_set_param_ch_mixer_v2_t { /* * Pointer to the unique identifier for an address (physical/virtual). @@ -338,6 +353,33 @@ struct vss_icommon_cmd_set_param_ch_mixer_v2_t { struct vss_icommon_param_data_ch_mixer_v2_t param_data; } __packed; + +struct vss_icommon_cmd_set_ecns_enable_t { + /* + * Pointer to the unique identifier for an address (physical/virtual). + * + * If the parameter data payload is within the message payload + * (in-band), set this field to 0. The parameter data begins at the + * specified data payload address. + * + * If the parameter data is out-of-band, this field is the handle to + * the physical address in the shared memory that holds the parameter + * data. + */ + uint32_t mem_handle; + /* + * Location of the parameter data payload. + * + * The payload is an array of vss_icommon_param_data_t. If the + * mem_handle is 0, this field is ignored. + */ + uint64_t mem_address; + /* Size of the parameter data payload in bytes. */ + uint32_t mem_size; + + struct vss_icommon_param_data_ecns_t param_data; +} __packed; + struct vss_icommon_param_data_mfc_config_v2_t { /* Valid ID of the module. */ uint32_t module_id; @@ -809,6 +851,7 @@ struct vss_evt_voice_activity { #define MODULE_ID_VOICE_MODULE_ST 0x00010EE3 #define VOICE_PARAM_MOD_ENABLE 0x00010E00 +#define MOD_ENABLE_PARAM_LEN 4 #define VSS_IPLAYBACK_CMD_START 0x000112BD /* Start in-call music delivery on the Tx voice path. */ @@ -1679,6 +1722,11 @@ struct cvp_set_vp3_data_cmd { struct apr_hdr hdr; } __packed; +struct cvp_set_channel_ecns_cmd_v2 { + struct apr_hdr hdr; + struct vss_icommon_cmd_set_ecns_enable_t cvp_set_ecns; +} __packed; + struct cvp_set_rx_volume_index_cmd { struct apr_hdr hdr; struct vss_ivocproc_cmd_set_volume_index_t cvp_set_vol_idx; @@ -1894,6 +1942,10 @@ struct voice_data { bool mic_break_status; struct work_struct voice_mic_break_work; + + uint32_t ecns_enable; + uint32_t ecns_module_id; + }; #define MAX_VOC_SESSIONS 8 @@ -2042,6 +2094,8 @@ int voc_get_rx_device_mute(uint32_t session_id); int voc_set_route_flag(uint32_t session_id, uint8_t path_dir, uint8_t set); uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir); bool voc_get_mbd_enable(void); +int voc_set_ecns_enable(uint32_t session_id, uint32_t module_id, + uint32_t enable); uint8_t voc_set_mbd_enable(bool enable); int voc_enable_dtmf_rx_detection(uint32_t session_id, uint32_t enable); void voc_disable_dtmf_det_on_active_sessions(void); From 58b05be4ab29f8c2be5b83601611db34a77f505a Mon Sep 17 00:00:00 2001 From: Meghana Reddy Mula Date: Tue, 10 Sep 2019 17:15:24 +0530 Subject: [PATCH 2/2] asoc: Add new mixer control to reset ecns Add support for mixer control to enable/disable ecns module for voice call. Change-Id: Icd046e936b0ae0db577e46e139b4f060e0cc7462 Signed-off-by: Meghana Reddy Mula --- asoc/msm-pcm-voice-v2.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/asoc/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c index f8acc30ab86e..5a25b3e860bd 100644 --- a/asoc/msm-pcm-voice-v2.c +++ b/asoc/msm-pcm-voice-v2.c @@ -582,6 +582,20 @@ static int msm_voice_slowtalk_put(struct snd_kcontrol *kcontrol, return 0; } +static int msm_voice_ecns_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + uint32_t enable = ucontrol->value.integer.value[0]; + uint32_t session_id = ucontrol->value.integer.value[1]; + uint32_t module_id = ucontrol->value.integer.value[2]; + + pr_debug("%s: ecns enable=%d session_id=%#x\n", __func__, enable, + session_id); + voc_set_ecns_enable(session_id, module_id, enable); + + return 0; +} + static int msm_voice_hd_voice_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -695,6 +709,8 @@ static struct snd_kcontrol_new msm_voice_controls[] = { msm_voice_tty_mode_put), SOC_SINGLE_MULTI_EXT("Slowtalk Enable", SND_SOC_NOPM, 0, VSID_MAX, 0, 2, NULL, msm_voice_slowtalk_put), + SOC_SINGLE_MULTI_EXT("Voice ECNS Enable", SND_SOC_NOPM, 0, VSID_MAX, 0, 3, + NULL, msm_voice_ecns_put), SOC_SINGLE_MULTI_EXT("Voice Topology Disable", SND_SOC_NOPM, 0, VSID_MAX, 0, 2, NULL, msm_voice_topology_disable_put),