Prechádzať zdrojové kódy

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 <[email protected]>
Meghana Reddy Mula 5 rokov pred
rodič
commit
6420f70b2d
2 zmenil súbory, kde vykonal 183 pridanie a 0 odobranie
  1. 129 0
      dsp/q6voice.c
  2. 54 0
      include/dsp/q6voice.h

+ 129 - 0
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),

+ 54 - 0
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);