Loading dsp/q6voice.c +117 −8 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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; Loading Loading @@ -3953,6 +3959,103 @@ static int voice_send_cvp_channel_info_cmd(struct voice_data *v) 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; Loading Loading @@ -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", pr_warn("%s: Unsupported num channels: %d\n", __func__, mfc_config_info->num_channels); ret = -EINVAL; goto done; } v->cvp_state = CMD_STATUS_FAIL; Loading Loading @@ -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; Loading include/dsp/apr_audio-v2.h +3 −0 Original line number Diff line number Diff line Loading @@ -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; Loading include/dsp/q6voice.h +57 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading
dsp/q6voice.c +117 −8 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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; Loading Loading @@ -3953,6 +3959,103 @@ static int voice_send_cvp_channel_info_cmd(struct voice_data *v) 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; Loading Loading @@ -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", pr_warn("%s: Unsupported num channels: %d\n", __func__, mfc_config_info->num_channels); ret = -EINVAL; goto done; } v->cvp_state = CMD_STATUS_FAIL; Loading Loading @@ -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; Loading
include/dsp/apr_audio-v2.h +3 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
include/dsp/q6voice.h +57 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading