ソースを参照

Merge "dsp: fix 2nd channel mute in VPRx out for Stereo EC ref"

Linux Build Service Account 7 年 前
コミット
ed02dabfb7
3 ファイル変更177 行追加8 行削除
  1. 117 8
      dsp/q6voice.c
  2. 3 0
      include/dsp/apr_audio-v2.h
  3. 57 0
      include/dsp/q6voice.h

+ 117 - 8
dsp/q6voice.c

@@ -36,7 +36,9 @@
 #define CMD_STATUS_FAIL 1
 #define NUM_CHANNELS_MONO 1
 #define NUM_CHANNELS_STEREO 2
+#define NUM_CHANNELS_QUAD 4
 #define CVP_VERSION_2 2
+#define GAIN_Q14_FORMAT(a) (a << 14)
 
 enum {
 	VOC_TOKEN_NONE,
@@ -3889,11 +3891,15 @@ static int voice_send_cvp_channel_info_v2(struct voice_data *v,
 	} else if (channel_info->num_channels == NUM_CHANNELS_STEREO) {
 		channel_info->channel_mapping[0] = PCM_CHANNEL_FL;
 		channel_info->channel_mapping[1] = PCM_CHANNEL_FR;
+	} else if (channel_info->num_channels == NUM_CHANNELS_QUAD &&
+		   param_type == TX_PATH) {
+		channel_info->channel_mapping[0] = PCM_CHANNEL_FL;
+		channel_info->channel_mapping[1] = PCM_CHANNEL_FR;
+		channel_info->channel_mapping[2] = PCM_CHANNEL_LS;
+		channel_info->channel_mapping[3] = PCM_CHANNEL_RS;
 	} else {
-		pr_err("%s: Unsupported num channels: %d\n",
-		       __func__, channel_info->num_channels);
-		ret = -EINVAL;
-		goto done;
+		pr_warn("%s: Unsupported num channels: %d for path: %d\n",
+			__func__, channel_info->num_channels, param_type);
 	}
 
 	v->cvp_state = CMD_STATUS_FAIL;
@@ -3953,6 +3959,103 @@ done:
 	return ret;
 }
 
+static int voice_send_cvp_ch_mixer_info_v2(struct voice_data *v)
+{
+	int ret;
+	struct cvp_set_channel_mixer_info_cmd_v2 cvp_set_ch_mixer_info_cmd;
+	void *apr_cvp;
+	u16 cvp_handle;
+	struct vss_icommon_param_data_ch_mixer_v2_t *cvp_config_param_data =
+			&cvp_set_ch_mixer_info_cmd.
+			cvp_set_ch_mixer_param_v2.param_data;
+	struct vss_param_channel_mixer_info_t *ch_mixer_info =
+			&cvp_config_param_data->ch_mixer_info;
+
+	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_mixer_info_cmd, 0,
+	       sizeof(cvp_set_ch_mixer_info_cmd));
+
+	cvp_set_ch_mixer_info_cmd.hdr.hdr_field =
+			APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+			APR_HDR_LEN(APR_HDR_SIZE),
+			APR_PKT_VER);
+	cvp_set_ch_mixer_info_cmd.hdr.pkt_size =
+			APR_PKT_SIZE(APR_HDR_SIZE,
+			sizeof(cvp_set_ch_mixer_info_cmd) - APR_HDR_SIZE);
+	cvp_set_ch_mixer_info_cmd.hdr.src_svc = 0;
+	cvp_set_ch_mixer_info_cmd.hdr.src_domain = APR_DOMAIN_APPS;
+	cvp_set_ch_mixer_info_cmd.hdr.src_port =
+			voice_get_idx_for_session(v->session_id);
+	cvp_set_ch_mixer_info_cmd.hdr.dest_svc = 0;
+	cvp_set_ch_mixer_info_cmd.hdr.dest_domain = APR_DOMAIN_ADSP;
+	cvp_set_ch_mixer_info_cmd.hdr.dest_port = cvp_handle;
+	cvp_set_ch_mixer_info_cmd.hdr.token = VOC_GENERIC_SET_PARAM_TOKEN;
+	cvp_set_ch_mixer_info_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2;
+	cvp_set_ch_mixer_info_cmd.cvp_set_ch_mixer_param_v2.mem_size =
+			sizeof(struct vss_icommon_param_data_ch_mixer_v2_t);
+
+	cvp_config_param_data->module_id = AUDPROC_MODULE_ID_MFC;
+	cvp_config_param_data->param_id =
+			AUDPROC_CHMIXER_PARAM_ID_COEFF;
+	cvp_config_param_data->param_size =
+			sizeof(struct vss_param_channel_mixer_info_t);
+
+	ch_mixer_info->index = 0;
+	ch_mixer_info->num_output_channels = v->dev_rx.no_of_channels;
+	/*
+	 * Configure Rx input to be mono for channel mixer as the DSP
+	 * configures vocproc input as mono.
+	 */
+	ch_mixer_info->num_input_channels = NUM_CHANNELS_MONO;
+	ch_mixer_info->out_channel_map[0] = PCM_CHANNEL_L;
+	ch_mixer_info->out_channel_map[1] = PCM_CHANNEL_R;
+	ch_mixer_info->in_channel_map[0] = PCM_CHANNEL_L;
+	ch_mixer_info->channel_weight_coeff[0][0] = GAIN_Q14_FORMAT(1);
+	ch_mixer_info->channel_weight_coeff[1][0] = GAIN_Q14_FORMAT(1);
+	ch_mixer_info->reserved = 0;
+
+	v->cvp_state = CMD_STATUS_FAIL;
+	v->async_err = 0;
+	ret = apr_send_pkt(apr_cvp, (uint32_t *)&cvp_set_ch_mixer_info_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;
+}
+
 static int voice_send_cvp_mfc_config_v2(struct voice_data *v)
 {
 	int ret;
@@ -4014,10 +4117,8 @@ static int voice_send_cvp_mfc_config_v2(struct voice_data *v)
 		mfc_config_info->channel_type[0] = PCM_CHANNEL_FL;
 		mfc_config_info->channel_type[1] = PCM_CHANNEL_FR;
 	} else {
-		pr_err("%s: Unsupported num channels: %d\n",
-		       __func__, mfc_config_info->num_channels);
-		ret = -EINVAL;
-		goto done;
+		pr_warn("%s: Unsupported num channels: %d\n",
+			__func__, mfc_config_info->num_channels);
 	}
 
 	v->cvp_state = CMD_STATUS_FAIL;
@@ -4054,7 +4155,15 @@ static int voice_send_cvp_mfc_config_cmd(struct voice_data *v)
 	int ret = 0;
 
 	if (common.cvp_version >= CVP_VERSION_2) {
+		ret = voice_send_cvp_ch_mixer_info_v2(v);
+		if (ret < 0)
+			pr_warn("%s: Set channel mixer config failed err:%d",
+				__func__, ret);
+
 		ret = voice_send_cvp_mfc_config_v2(v);
+		if (ret < 0)
+			pr_warn("%s: Set MFC config failed err:%d",
+				__func__, ret);
 	} else {
 		pr_warn("%s: CVP Version not supported\n", __func__);
 		ret = -EINVAL;

+ 3 - 0
include/dsp/apr_audio-v2.h

@@ -623,6 +623,9 @@ struct audproc_softvolume_params {
  */
 #define AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT            0x00010913
 
+/* Param ID of Channel Mixer used by AUDPROC_MODULE_ID_MFC */
+#define AUDPROC_CHMIXER_PARAM_ID_COEFF                      0x00010342
+
 
 struct audproc_mfc_output_media_fmt {
 	struct adm_cmd_set_pp_params_v5 params;

+ 57 - 0
include/dsp/q6voice.h

@@ -245,6 +245,16 @@ struct vss_param_vocproc_dev_channel_info_t {
 	uint8_t channel_mapping[VSS_NUM_CHANNELS_MAX];
 } __packed;
 
+struct vss_param_channel_mixer_info_t {
+	uint32_t index;
+	uint16_t num_output_channels;
+	uint16_t num_input_channels;
+	uint16_t out_channel_map[2];
+	uint16_t in_channel_map[1];
+	uint16_t channel_weight_coeff[2][1];
+	uint16_t reserved;
+} __packed;
+
 struct vss_param_mfc_config_info_t {
 	uint32_t sample_rate;
 	uint16_t bits_per_sample;
@@ -313,6 +323,47 @@ struct vss_icommon_cmd_set_param_channel_info_v2_t {
 	struct vss_icommon_param_data_channel_info_v2_t param_data;
 } __packed;
 
+struct vss_icommon_param_data_ch_mixer_v2_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;
+	struct vss_param_channel_mixer_info_t ch_mixer_info;
+} __packed;
+
+struct vss_icommon_cmd_set_param_ch_mixer_v2_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_ch_mixer_v2_t param_data;
+} __packed;
+
 struct vss_icommon_param_data_mfc_config_v2_t {
 	/* Valid ID of the module. */
 	uint32_t module_id;
@@ -1595,6 +1646,12 @@ struct cvp_set_channel_info_cmd_v2 {
 					cvp_set_ch_info_param_v2;
 } __packed;
 
+struct cvp_set_channel_mixer_info_cmd_v2 {
+	struct apr_hdr hdr;
+	struct vss_icommon_cmd_set_param_ch_mixer_v2_t
+					cvp_set_ch_mixer_param_v2;
+} __packed;
+
 struct cvp_set_mfc_config_cmd_v2 {
 	struct apr_hdr hdr;
 	struct vss_icommon_cmd_set_param_mfc_config_v2_t cvp_set_mfc_param_v2;