diff --git a/asoc/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c index b82c5871795d..0a4aa0528d95 100644 --- a/asoc/msm-pcm-voice-v2.c +++ b/asoc/msm-pcm-voice-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -556,12 +556,15 @@ static int msm_voice_slowtalk_put(struct snd_kcontrol *kcontrol, { int st_enable = ucontrol->value.integer.value[0]; uint32_t session_id = ucontrol->value.integer.value[1]; + struct module_instance_info mod_inst_info; + memset(&mod_inst_info, 0, sizeof(mod_inst_info)); pr_debug("%s: st enable=%d session_id=%#x\n", __func__, st_enable, session_id); - voc_set_pp_enable(session_id, - MODULE_ID_VOICE_MODULE_ST, st_enable); + mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST; + mod_inst_info.instance_id = INSTANCE_ID_0; + voc_set_pp_enable(session_id, mod_inst_info, st_enable); return 0; } diff --git a/dsp/q6voice.c b/dsp/q6voice.c index e26d156b57d3..801e76168541 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -105,8 +106,9 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv); static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv); 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, - uint32_t module_id, int enable); +static int voice_send_set_pp_enable_cmd( + struct voice_data *v, struct module_instance_info mod_inst_info, + int enable); static int is_cal_memory_allocated(void); static bool is_cvd_version_queried(void); static int is_voip_memory_allocated(void); @@ -137,6 +139,12 @@ static int voice_send_get_sound_focus_cmd(struct voice_data *v, struct sound_focus_param *soundFocusData); static int voice_send_get_source_tracking_cmd(struct voice_data *v, struct source_tracking_param *sourceTrackingData); +static int voice_pack_and_set_cvp_param(struct voice_data *v, + struct param_hdr_v3 param_hdr, + u8 *param_data); +static int voice_pack_and_set_cvs_ui_property(struct voice_data *v, + struct param_hdr_v3 param_hdr, + u8 *param_data); static void voice_itr_init(struct voice_session_itr *itr, u32 session_id) @@ -1471,70 +1479,31 @@ static int voice_send_tty_mode_cmd(struct voice_data *v) return ret; } -static int voice_send_set_pp_enable_cmd(struct voice_data *v, - uint32_t module_id, int enable) +static int voice_send_set_pp_enable_cmd( + struct voice_data *v, struct module_instance_info mod_inst_info, + int enable) { - struct cvs_set_pp_enable_cmd cvs_set_pp_cmd; + struct enable_param enable_param; + struct param_hdr_v3 param_hdr; int ret = 0; - void *apr_cvs; - u16 cvs_handle; - if (v == NULL) { - pr_err("%s: v is NULL\n", __func__); - return -EINVAL; - } - apr_cvs = common.apr_q6_cvs; + memset(&enable_param, 0, sizeof(enable_param)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = mod_inst_info.module_id; + param_hdr.instance_id = mod_inst_info.instance_id; + param_hdr.param_id = VOICE_PARAM_MOD_ENABLE; + param_hdr.param_size = sizeof(enable_param); + enable_param.enable = enable ? 1 : 0; - if (!apr_cvs) { - pr_err("%s: apr_cvs is NULL.\n", __func__); - return -EINVAL; - } - cvs_handle = voice_get_cvs_handle(v); + pr_debug("%s: module_id=%d, instance_id=%d, enable=%d\n", + __func__, mod_inst_info.module_id, mod_inst_info.instance_id, + enable); - cvs_set_pp_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - cvs_set_pp_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, - sizeof(cvs_set_pp_cmd) - - APR_HDR_SIZE); - cvs_set_pp_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id); - cvs_set_pp_cmd.hdr.dest_port = cvs_handle; - cvs_set_pp_cmd.hdr.token = 0; - cvs_set_pp_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_UI_PROPERTY; + ret = voice_pack_and_set_cvs_ui_property(v, param_hdr, + (uint8_t *) &enable_param); + if (ret < 0) + pr_err("Fail: sending cvs set pp enable\n"); - cvs_set_pp_cmd.vss_set_pp.module_id = module_id; - cvs_set_pp_cmd.vss_set_pp.param_id = VOICE_PARAM_MOD_ENABLE; - cvs_set_pp_cmd.vss_set_pp.param_size = MOD_ENABLE_PARAM_LEN; - cvs_set_pp_cmd.vss_set_pp.reserved = 0; - cvs_set_pp_cmd.vss_set_pp.enable = enable; - cvs_set_pp_cmd.vss_set_pp.reserved_field = 0; - pr_debug("voice_send_set_pp_enable_cmd, module_id=%d, enable=%d\n", - module_id, enable); - - v->cvs_state = CMD_STATUS_FAIL; - v->async_err = 0; - ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_pp_cmd); - if (ret < 0) { - pr_err("Fail: sending cvs set pp enable,\n"); - goto fail; - } - ret = wait_event_timeout(v->cvs_wait, - (v->cvs_state == CMD_STATUS_SUCCESS), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - goto fail; - } - if (v->async_err > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - v->async_err)); - ret = adsp_err_get_lnx_err_code( - v->async_err); - goto fail; - } - return 0; -fail: return ret; } @@ -4245,8 +4214,10 @@ static int voice_get_avcs_version_per_service(uint32_t service_id) static int voice_setup_vocproc(struct voice_data *v) { + struct module_instance_info mod_inst_info; int ret = 0; + memset(&mod_inst_info, 0, sizeof(mod_inst_info)); ret = voice_send_cvp_create_cmd(v); if (ret < 0) { pr_err("%s: CVP create failed err:%d\n", __func__, ret); @@ -4288,6 +4259,9 @@ static int voice_setup_vocproc(struct voice_data *v) } } + mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST; + mod_inst_info.instance_id = INSTANCE_ID_0; + voice_send_cvs_register_cal_cmd(v); voice_send_cvp_register_dev_cfg_cmd(v); voice_send_cvp_register_cal_cmd(v); @@ -4321,9 +4295,7 @@ static int voice_setup_vocproc(struct voice_data *v) } if (v->st_enable && !v->tty_mode) - voice_send_set_pp_enable_cmd(v, - MODULE_ID_VOICE_MODULE_ST, - v->st_enable); + voice_send_set_pp_enable_cmd(v, mod_inst_info, v->st_enable); /* Start in-call music delivery if this feature is enabled */ if (v->music_info.play_enable) voice_cvs_start_playback(v); @@ -4467,14 +4439,12 @@ static int voice_send_cvp_media_fmt_info_cmd(struct voice_data *v) static int voice_send_cvp_media_format_cmd(struct voice_data *v, uint32_t param_type) { + struct vss_param_endpoint_media_format_info media_fmt_info; + struct param_hdr_v3 param_hdr; int ret = 0; - struct cvp_set_media_format_cmd cvp_set_media_format_cmd; - void *apr_cvp; - u16 cvp_handle; - struct vss_icommon_param_data_t *media_fmt_param_data = - &cvp_set_media_format_cmd.cvp_set_media_param_v2.param_data; - struct vss_param_endpoint_media_format_info_t *media_fmt_info = - &media_fmt_param_data->media_format_info; + + memset(&media_fmt_info, 0, sizeof(media_fmt_info)); + memset(¶m_hdr, 0, sizeof(param_hdr)); if (v == NULL) { pr_err("%s: v is NULL\n", __func__); @@ -4482,75 +4452,41 @@ static int voice_send_cvp_media_format_cmd(struct voice_data *v, goto done; } - apr_cvp = common.apr_q6_cvp; - if (!apr_cvp) { - pr_err("%s: apr_cvp is NULL.\n", __func__); - ret = -EINVAL; - goto done; - } + param_hdr.module_id = VSS_MODULE_CVD_GENERIC; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_size = sizeof(media_fmt_info); - cvp_handle = voice_get_cvp_handle(v); - memset(&cvp_set_media_format_cmd, 0, sizeof(cvp_set_media_format_cmd)); - - /* Fill header data */ - cvp_set_media_format_cmd.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - cvp_set_media_format_cmd.hdr.pkt_size = - APR_PKT_SIZE(APR_HDR_SIZE, - sizeof(cvp_set_media_format_cmd) - APR_HDR_SIZE); - cvp_set_media_format_cmd.hdr.src_svc = 0; - cvp_set_media_format_cmd.hdr.src_domain = APR_DOMAIN_APPS; - cvp_set_media_format_cmd.hdr.src_port = - voice_get_idx_for_session(v->session_id); - cvp_set_media_format_cmd.hdr.dest_svc = 0; - cvp_set_media_format_cmd.hdr.dest_domain = APR_DOMAIN_ADSP; - cvp_set_media_format_cmd.hdr.dest_port = cvp_handle; - cvp_set_media_format_cmd.hdr.token = VOC_SET_MEDIA_FORMAT_PARAM_TOKEN; - cvp_set_media_format_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2; - - /* Fill param data */ - cvp_set_media_format_cmd.cvp_set_media_param_v2.mem_size = - sizeof(struct vss_icommon_param_data_t); - media_fmt_param_data->module_id = VSS_MODULE_CVD_GENERIC; - media_fmt_param_data->param_size = - sizeof(struct vss_param_endpoint_media_format_info_t); - - /* Fill device specific data */ switch (param_type) { case RX_PATH: - media_fmt_param_data->param_id = - VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO; - media_fmt_info->port_id = v->dev_rx.port_id; - media_fmt_info->num_channels = v->dev_rx.no_of_channels; - media_fmt_info->bits_per_sample = v->dev_rx.bits_per_sample; - media_fmt_info->sample_rate = v->dev_rx.sample_rate; - memcpy(&media_fmt_info->channel_mapping, + param_hdr.param_id = VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO; + media_fmt_info.port_id = v->dev_rx.port_id; + media_fmt_info.num_channels = v->dev_rx.no_of_channels; + media_fmt_info.bits_per_sample = v->dev_rx.bits_per_sample; + media_fmt_info.sample_rate = v->dev_rx.sample_rate; + memcpy(&media_fmt_info.channel_mapping, &v->dev_rx.channel_mapping, VSS_CHANNEL_MAPPING_SIZE); break; case TX_PATH: - media_fmt_param_data->param_id = - VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO; - media_fmt_info->port_id = v->dev_tx.port_id; - media_fmt_info->num_channels = v->dev_tx.no_of_channels; - media_fmt_info->bits_per_sample = v->dev_tx.bits_per_sample; - media_fmt_info->sample_rate = v->dev_tx.sample_rate; - memcpy(&media_fmt_info->channel_mapping, + param_hdr.param_id = VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO; + media_fmt_info.port_id = v->dev_tx.port_id; + media_fmt_info.num_channels = v->dev_tx.no_of_channels; + media_fmt_info.bits_per_sample = v->dev_tx.bits_per_sample; + media_fmt_info.sample_rate = v->dev_tx.sample_rate; + memcpy(&media_fmt_info.channel_mapping, &v->dev_tx.channel_mapping, VSS_CHANNEL_MAPPING_SIZE); break; case EC_REF_PATH: - media_fmt_param_data->param_id = - VSS_PARAM_EC_REF_PORT_ENDPOINT_MEDIA_INFO; - media_fmt_info->port_id = common.ec_media_fmt_info.port_id; - media_fmt_info->num_channels = + param_hdr.param_id = VSS_PARAM_EC_REF_PORT_ENDPOINT_MEDIA_INFO; + media_fmt_info.port_id = common.ec_media_fmt_info.port_id; + media_fmt_info.num_channels = common.ec_media_fmt_info.num_channels; - media_fmt_info->bits_per_sample = + media_fmt_info.bits_per_sample = common.ec_media_fmt_info.bits_per_sample; - media_fmt_info->sample_rate = + media_fmt_info.sample_rate = common.ec_media_fmt_info.sample_rate; - memcpy(&media_fmt_info->channel_mapping, + memcpy(&media_fmt_info.channel_mapping, &common.ec_media_fmt_info.channel_mapping, VSS_CHANNEL_MAPPING_SIZE); break; @@ -4561,32 +4497,11 @@ static int voice_send_cvp_media_format_cmd(struct voice_data *v, goto done; } - /* Send command */ - v->cvp_state = CMD_STATUS_FAIL; - v->async_err = 0; - ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_set_media_format_cmd); - if (ret < 0) { - pr_err("%s: Fail in sending VSS_ICOMMON_CMD_SET_PARAM_V2\n", - __func__); - ret = -EINVAL; - 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 = -EINVAL; - 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 = voice_pack_and_set_cvp_param(v, param_hdr, + (u8 *) &media_fmt_info); + if (ret) + pr_err("%s: Failed to set media format params on CVP, err %d\n", + __func__, ret); done: return ret; @@ -4982,10 +4897,13 @@ static int voice_destroy_vocproc(struct voice_data *v) { struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd; struct apr_hdr cvp_destroy_session_cmd; + struct module_instance_info mod_inst_info; int ret = 0; void *apr_mvm, *apr_cvp; u16 mvm_handle, cvp_handle; + memset(&mod_inst_info, 0, sizeof(mod_inst_info)); + if (v == NULL) { pr_err("%s: v is NULL\n", __func__); return -EINVAL; @@ -5000,9 +4918,12 @@ static int voice_destroy_vocproc(struct voice_data *v) mvm_handle = voice_get_mvm_handle(v); cvp_handle = voice_get_cvp_handle(v); + mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST; + mod_inst_info.instance_id = INSTANCE_ID_0; + /* disable slowtalk if st_enable is set */ if (v->st_enable) - voice_send_set_pp_enable_cmd(v, MODULE_ID_VOICE_MODULE_ST, 0); + voice_send_set_pp_enable_cmd(v, mod_inst_info, 0); /* Disable HD Voice if hd_enable is set */ if (v->hd_enable) @@ -6324,11 +6245,15 @@ EXPORT_SYMBOL(voc_get_tty_mode); * * Returns 0 on success or error on failure */ -int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, uint32_t enable) +int voc_set_pp_enable(uint32_t session_id, + struct module_instance_info mod_inst_info, + uint32_t enable) { struct voice_data *v = NULL; int ret = 0; struct voice_session_itr itr; + int mid = mod_inst_info.module_id; + int iid = mod_inst_info.instance_id; voice_itr_init(&itr, session_id); while (voice_itr_get_next_session(&itr, &v)) { @@ -6337,15 +6262,15 @@ int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, uint32_t enable) continue; mutex_lock(&v->lock); - if (module_id == MODULE_ID_VOICE_MODULE_ST) + if (mid == MODULE_ID_VOICE_MODULE_ST && + iid == INSTANCE_ID_0) v->st_enable = enable; if (v->voc_state == VOC_RUN) { - if ((module_id == MODULE_ID_VOICE_MODULE_ST) && - (!v->tty_mode)) - ret = voice_send_set_pp_enable_cmd(v, - MODULE_ID_VOICE_MODULE_ST, - enable); + if ((mid == MODULE_ID_VOICE_MODULE_ST) && + iid == INSTANCE_ID_0 && (!v->tty_mode)) + ret = voice_send_set_pp_enable_cmd( + v, mod_inst_info, enable); } mutex_unlock(&v->lock); } else { @@ -6455,8 +6380,8 @@ bool voc_get_afe_sidetone(void) return ret; } EXPORT_SYMBOL(voc_get_afe_sidetone); - -int voc_get_pp_enable(uint32_t session_id, uint32_t module_id) +int voc_get_pp_enable(uint32_t session_id, + struct module_instance_info mod_inst_info) { struct voice_data *v = voice_get_session(session_id); int ret = 0; @@ -6468,7 +6393,8 @@ int voc_get_pp_enable(uint32_t session_id, uint32_t module_id) } mutex_lock(&v->lock); - if (module_id == MODULE_ID_VOICE_MODULE_ST) + if (mod_inst_info.module_id == MODULE_ID_VOICE_MODULE_ST && + mod_inst_info.instance_id == INSTANCE_ID_0) ret = v->st_enable; mutex_unlock(&v->lock); @@ -6826,8 +6752,11 @@ EXPORT_SYMBOL(voc_disable_device); int voc_enable_device(uint32_t session_id) { struct voice_data *v = voice_get_session(session_id); + struct module_instance_info mod_inst_info; int ret = 0; + memset(&mod_inst_info, 0, sizeof(mod_inst_info)); + if (v == NULL) { pr_err("%s: v is NULL\n", __func__); return -EINVAL; @@ -6843,15 +6772,15 @@ int voc_enable_device(uint32_t session_id) /* Not a critical error, allow voice call to continue */ } + mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST; + mod_inst_info.instance_id = INSTANCE_ID_0; + if (v->tty_mode) { /* disable slowtalk */ - voice_send_set_pp_enable_cmd(v, - MODULE_ID_VOICE_MODULE_ST, - 0); + voice_send_set_pp_enable_cmd(v, mod_inst_info, 0); } else { /* restore slowtalk */ - voice_send_set_pp_enable_cmd(v, - MODULE_ID_VOICE_MODULE_ST, + voice_send_set_pp_enable_cmd(v, mod_inst_info, v->st_enable); } @@ -7506,6 +7435,7 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv) case VSS_ICOMMON_CMD_MAP_MEMORY: case VSS_ICOMMON_CMD_UNMAP_MEMORY: case VSS_ICOMMON_CMD_SET_UI_PROPERTY: + case VSS_ICOMMON_CMD_SET_UI_PROPERTY_V2: case VSS_IPLAYBACK_CMD_START: case VSS_IPLAYBACK_CMD_STOP: case VSS_IRECORD_CMD_START: @@ -7519,7 +7449,8 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv) wake_up(&v->cvs_wait); break; case VSS_ICOMMON_CMD_SET_PARAM_V2: - pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2\n", + case VSS_ICOMMON_CMD_SET_PARAM_V3: + pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM\n", __func__); rtac_make_voice_callback(RTAC_CVS, ptr, data->payload_size); @@ -7798,17 +7729,18 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv) case VSS_IVPCM_EVT_PUSH_BUFFER_V2: break; case VSS_ICOMMON_CMD_SET_PARAM_V2: + case VSS_ICOMMON_CMD_SET_PARAM_V3: switch (data->token) { case VOC_SET_MEDIA_FORMAT_PARAM_TOKEN: case VOC_GENERIC_SET_PARAM_TOKEN: - pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called\n", + pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM called by voice_send_cvp_media_format_cmd\n", __func__); v->cvp_state = CMD_STATUS_SUCCESS; v->async_err = ptr[1]; wake_up(&v->cvp_wait); break; case VOC_RTAC_SET_PARAM_TOKEN: - pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called by rtac\n", + pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM called by rtac\n", __func__); rtac_make_voice_callback( RTAC_CVP, ptr, @@ -9468,6 +9400,199 @@ int voc_get_source_tracking(struct source_tracking_param *sourceTrackingData) } EXPORT_SYMBOL(voc_get_source_tracking); +static int voice_set_cvp_param(struct voice_data *v, + struct vss_icommon_mem_mapping_hdr *mem_hdr, + u32 *param_data, u32 param_size) +{ + struct vss_icommon_cmd_set_param *set_param = NULL; + uint32_t pkt_size = sizeof(struct vss_icommon_cmd_set_param); + void *apr_cvp; + int ret = 0; + + apr_cvp = common.apr_q6_cvp; + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL\n", __func__); + return -EINVAL; + } + + if (param_data != NULL) + pkt_size += param_size; + set_param = kzalloc(pkt_size, GFP_KERNEL); + if (!set_param) + return -ENOMEM; + + set_param->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + set_param->apr_hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, pkt_size - APR_HDR_SIZE); + set_param->apr_hdr.src_svc = 0; + set_param->apr_hdr.src_domain = APR_DOMAIN_APPS; + set_param->apr_hdr.src_port = voice_get_idx_for_session(v->session_id); + set_param->apr_hdr.dest_svc = 0; + set_param->apr_hdr.dest_domain = APR_DOMAIN_ADSP; + set_param->apr_hdr.dest_port = voice_get_cvp_handle(v); + set_param->apr_hdr.token = VOC_SET_MEDIA_FORMAT_PARAM_TOKEN; + set_param->apr_hdr.opcode = q6common_is_instance_id_supported() ? + VSS_ICOMMON_CMD_SET_PARAM_V3 : + VSS_ICOMMON_CMD_SET_PARAM_V2; + + set_param->payload_size = param_size; + + if (mem_hdr != NULL) { + set_param->mem_hdr = *mem_hdr; + } else if (param_data != NULL) { + memcpy(set_param->param_data, param_data, param_size); + } else { + pr_err("%s: Both memory header and param data are NULL\n", + __func__); + ret = -EINVAL; + goto done; + } + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (u32 *) set_param); + if (ret < 0) { + pr_err("%s: Failed to send apr packet, error %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]\n", __func__, + adsp_err_get_err_str(v->async_err)); + ret = adsp_err_get_lnx_err_code(v->async_err); + goto done; + } + ret = 0; + +done: + kfree(set_param); + return ret; +} + +static int voice_pack_and_set_cvp_param(struct voice_data *v, + struct param_hdr_v3 param_hdr, + u8 *param_data) +{ + u8 *packed_data = NULL; + u32 total_size = 0; + int ret = 0; + + total_size = sizeof(union param_hdrs) + param_hdr.param_size; + packed_data = kzalloc(total_size, GFP_KERNEL); + if (!packed_data) + return -ENOMEM; + + ret = q6common_pack_pp_params(packed_data, ¶m_hdr, param_data, + &total_size); + if (ret) { + pr_err("%s: Failed to pack params, error %d", __func__, ret); + goto done; + } + + ret = voice_set_cvp_param(v, NULL, (u32 *) packed_data, total_size); + +done: + kfree(packed_data); + return ret; +} + +/* + * Out of band is not supported and there are currently no pre-packed cases, + * so pack and set in the same function. When needed, split up. + */ +static int voice_pack_and_set_cvs_ui_property(struct voice_data *v, + struct param_hdr_v3 param_hdr, + u8 *param_data) +{ + struct vss_icommon_cmd_set_ui_property *set_ui_property = NULL; + u32 total_size = 0; + bool iid_supported = q6common_is_instance_id_supported(); + void *apr_cvs; + int ret = 0; + + apr_cvs = common.apr_q6_cvs; + if (!apr_cvs) { + pr_err("%s: apr_cvs is NULL\n", __func__); + return -EINVAL; + } + + total_size = sizeof(struct vss_icommon_cmd_set_ui_property) + + sizeof(union param_hdrs) + param_hdr.param_size; + set_ui_property = kzalloc(total_size, GFP_KERNEL); + if (!set_ui_property) + return -ENOMEM; + + ret = q6common_pack_pp_params(set_ui_property->param_data, ¶m_hdr, + param_data, &total_size); + if (ret) { + pr_err("%s: Failed to pack params, error %d", __func__, ret); + goto done; + } + + /* + * Pack the APR header after packing the data so we have the actual + * total size of the payload + */ + set_ui_property->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + set_ui_property->apr_hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, total_size - APR_HDR_SIZE); + set_ui_property->apr_hdr.src_svc = 0; + set_ui_property->apr_hdr.src_domain = APR_DOMAIN_APPS; + set_ui_property->apr_hdr.src_port = + voice_get_idx_for_session(v->session_id); + set_ui_property->apr_hdr.dest_svc = 0; + set_ui_property->apr_hdr.dest_domain = APR_DOMAIN_ADSP; + set_ui_property->apr_hdr.dest_port = voice_get_cvs_handle(v); + set_ui_property->apr_hdr.token = 0; + + set_ui_property->apr_hdr.opcode = + iid_supported ? VSS_ICOMMON_CMD_SET_UI_PROPERTY_V2 : + VSS_ICOMMON_CMD_SET_UI_PROPERTY; + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvs, (u32 *) set_ui_property); + if (ret < 0) { + pr_err("%s: Failed to send apr packet, error %d\n", __func__, + ret); + goto done; + } + + ret = wait_event_timeout(v->cvs_wait, + v->cvs_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]\n", __func__, + adsp_err_get_err_str(v->async_err)); + ret = adsp_err_get_lnx_err_code(v->async_err); + goto done; + } + ret = 0; +done: + kfree(set_ui_property); + return ret; +} + /** * is_voc_initialized: * diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 4e859665d589..9c7f39d13218 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -8818,6 +8818,9 @@ struct asm_eq_params { #define VSS_ICOMMON_CMD_SET_PARAM_V2 0x0001133D #define VSS_ICOMMON_CMD_GET_PARAM_V2 0x0001133E #define VSS_ICOMMON_RSP_GET_PARAM 0x00011008 +#define VSS_ICOMMON_CMD_SET_PARAM_V3 0x00013245 +#define VSS_ICOMMON_CMD_GET_PARAM_V3 0x00013246 +#define VSS_ICOMMON_RSP_GET_PARAM_V3 0x00013247 #define VSS_MAX_AVCS_NUM_SERVICES 25 diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index 5dfdccf84420..be72b72d34e4 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -169,6 +169,7 @@ struct mem_map_table { /* Common */ #define VSS_ICOMMON_CMD_SET_UI_PROPERTY 0x00011103 +#define VSS_ICOMMON_CMD_SET_UI_PROPERTY_V2 0x00013248 /* Set a UI property */ #define VSS_ICOMMON_CMD_MAP_MEMORY 0x00011025 #define VSS_ICOMMON_CMD_UNMAP_MEMORY 0x00011026 @@ -210,7 +211,7 @@ struct vss_unmap_memory_cmd { struct vss_icommon_cmd_unmap_memory_t vss_unmap_mem; } __packed; -struct vss_param_endpoint_media_format_info_t { +struct vss_param_endpoint_media_format_info { /* AFE port ID to which this media format corresponds to. */ uint32_t port_id; /* @@ -260,27 +261,6 @@ struct vss_param_mfc_config_info_t { uint16_t channel_type[VSS_NUM_CHANNELS_MAX]; } __packed; -struct vss_icommon_param_data_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; - /* - * Parameter data payload when inband. Should have size param_size. - * Bit size of payload must be a multiple of 4. - */ - union { - struct vss_param_endpoint_media_format_info_t media_format_info; - }; -} __packed; - struct vss_icommon_param_data_channel_info_v2_t { /* Valid ID of the module. */ uint32_t module_id; @@ -404,8 +384,7 @@ struct vss_icommon_cmd_set_param_mfc_config_v2_t { struct vss_icommon_param_data_mfc_config_v2_t param_data; } __packed; -/* Payload structure for the VSS_ICOMMON_CMD_SET_PARAM_V2 command. */ -struct vss_icommon_cmd_set_param_v2_t { +struct vss_icommon_mem_mapping_hdr { /* * Pointer to the unique identifier for an address (physical/virtual). * @@ -425,10 +404,23 @@ struct vss_icommon_cmd_set_param_v2_t { * mem_handle is 0, this field is ignored. */ uint64_t mem_address; +} __packed; + +struct vss_icommon_cmd_set_param { + /* APR Header */ + struct apr_hdr apr_hdr; + + /* The memory mapping header to be used when sending outband */ + struct vss_icommon_mem_mapping_hdr mem_hdr; + /* Size of the parameter data payload in bytes. */ - uint32_t mem_size; - /* Parameter data payload when the data is inband. */ - struct vss_icommon_param_data_t param_data; + uint32_t payload_size; + + /* + * Parameter data payload when inband. Should have size param_size. + * Bit size of payload must be a multiple of 4. + */ + uint8_t param_data[0]; } __packed; /* TO MVM commands */ @@ -781,7 +773,6 @@ struct vss_imemory_cmd_unmap_t { #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. */ @@ -1056,20 +1047,20 @@ struct vss_istream_cmd_register_calibration_data_v2_t { */ } __packed; -struct vss_icommon_cmd_set_ui_property_enable_t { - uint32_t module_id; - /* Unique ID of the module. */ - uint32_t param_id; - /* Unique ID of the parameter. */ - uint16_t param_size; - /* Size of the parameter in bytes: MOD_ENABLE_PARAM_LEN */ - uint16_t reserved; - /* Reserved; set to 0. */ +struct enable_param { uint16_t enable; uint16_t reserved_field; /* Reserved, set to 0. */ }; +struct vss_icommon_cmd_set_ui_property { + /* APR Header */ + struct apr_hdr apr_hdr; + + /* The parameter data to be filled when sent inband */ + u8 param_data[0]; +} __packed; + /* * Event sent by the stream to the client that enables Rx DTMF * detection whenever DTMF is detected in the Rx path. @@ -1178,10 +1169,6 @@ struct cvs_deregister_cal_data_cmd { struct apr_hdr hdr; } __packed; -struct cvs_set_pp_enable_cmd { - struct apr_hdr hdr; - struct vss_icommon_cmd_set_ui_property_enable_t vss_set_pp; -} __packed; struct cvs_start_record_cmd { struct apr_hdr hdr; struct vss_irecord_cmd_start_t rec_mode; @@ -1254,6 +1241,8 @@ struct vss_istream_cmd_set_packet_exchange_mode_t { */ #define VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG 0x00011372 +#define CVD_CAL_DATA_FORMAT_MINOR_VERSION_V0 0x00000000 +#define CVD_CAL_DATA_FORMAT_MINOR_VERSION_V1 0x00000001 #define VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2 0x00011373 #define VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA 0x00011276 @@ -1633,11 +1622,6 @@ struct cvp_set_dev_channels_cmd { struct vss_ivocproc_cmd_topology_set_dev_channels_t cvp_set_channels; } __packed; -struct cvp_set_media_format_cmd { - struct apr_hdr hdr; - struct vss_icommon_cmd_set_param_v2_t cvp_set_media_param_v2; -} __packed; - struct cvp_set_channel_info_cmd_v2 { struct apr_hdr hdr; struct vss_icommon_cmd_set_param_channel_info_v2_t @@ -1992,9 +1976,11 @@ enum { #define VSID_MAX ALL_SESSION_VSID /* called by alsa driver */ -int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, +int voc_set_pp_enable(uint32_t session_id, + struct module_instance_info mod_inst_info, uint32_t enable); -int voc_get_pp_enable(uint32_t session_id, uint32_t module_id); +int voc_get_pp_enable(uint32_t session_id, + struct module_instance_info mod_inst_info); int voc_set_hd_enable(uint32_t session_id, uint32_t enable); uint8_t voc_get_tty_mode(uint32_t session_id); int voc_set_tty_mode(uint32_t session_id, uint8_t tty_mode);