diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index fab5186ab8..8e0d7e0319 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -109,6 +109,9 @@ size_t get_cal_info_size(int32_t cal_type) size = max(sizeof(struct audio_cal_info_sp_ex_vi_ftm_cfg), sizeof(struct audio_cal_info_sp_ex_vi_param)); break; + case AFE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE: + size = sizeof(struct audio_cal_info_sp_v4_ex_vi_param); + break; case AFE_ANC_CAL_TYPE: size = 0; break; @@ -261,6 +264,9 @@ size_t get_user_cal_type_size(int32_t cal_type) size = max(sizeof(struct audio_cal_type_sp_ex_vi_ftm_cfg), sizeof(struct audio_cal_type_sp_ex_vi_param)); break; + case AFE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE: + size = sizeof(struct audio_cal_type_sp_v4_ex_vi_param); + break; case AFE_ANC_CAL_TYPE: size = 0; break; diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 97521002e9..ab98e9a4bd 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -38,6 +38,7 @@ enum { AFE_CUST_TOPOLOGY_CAL, AFE_FB_SPKR_PROT_TH_VI_CAL, AFE_FB_SPKR_PROT_EX_VI_CAL, + AFE_FB_SPKR_PROT_V4_EX_VI_CAL, MAX_AFE_CAL_TYPES }; @@ -97,6 +98,11 @@ enum { AFE_MATCHED_PORT_ENABLE }; +enum { + AFE_FBSP_V4_EX_VI_MODE_NORMAL = 0, + AFE_FBSP_V4_EX_VI_MODE_FTM = 1 +}; + struct wlock { struct wakeup_source *ws; }; @@ -150,6 +156,10 @@ struct afe_ctl { struct afe_sp_th_vi_v_vali_get_param_resp th_vi_v_vali_resp; struct afe_sp_ex_vi_get_param_resp ex_vi_resp; struct afe_sp_rx_tmax_xmax_logging_resp xt_logging_resp; + struct afe_sp_v4_th_vi_calib_resp spv4_calib_data; + struct afe_sp_v4_param_vi_channel_map_cfg v4_ch_map_cfg; + struct afe_sp_v4_gen_get_param_resp *spv4_get_param_resp_ptr; + uint32_t spv4_rcvd_param_size; struct afe_av_dev_drift_get_param_resp av_dev_drift_resp; struct afe_doa_tracking_mon_get_param_resp doa_tracking_mon_resp; int vi_tx_port; @@ -407,6 +417,7 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, u32 *data_dest = NULL; u32 *data_start = NULL; size_t expected_size = sizeof(u32); + uint32_t num_ch = 0; memset(¶m_hdr, 0, sizeof(param_hdr)); @@ -467,16 +478,83 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, struct afe_sp_rx_tmax_xmax_logging_param); data_dest = (u32 *) &this_afe.xt_logging_resp; break; + case AFE_PARAM_ID_SP_V4_CALIB_RES_CFG: + expected_size += sizeof( + struct afe_sp_v4_param_th_vi_calib_res_cfg); + data_dest = (u32 *) &this_afe.spv4_calib_data; + break; + case AFE_PARAM_ID_SP_V4_TH_VI_FTM_PARAMS: + num_ch = data_start[0]; + this_afe.spv4_rcvd_param_size = + sizeof(struct afe_sp_v4_gen_get_param_resp) + + sizeof(struct afe_sp_v4_param_th_vi_ftm_params) + + (num_ch * sizeof(struct afe_sp_v4_channel_ftm_params)); + this_afe.spv4_get_param_resp_ptr = + kzalloc(this_afe.spv4_rcvd_param_size, GFP_ATOMIC); + data_dest = (u32 *)this_afe.spv4_get_param_resp_ptr; + expected_size += + sizeof(struct afe_sp_v4_param_th_vi_ftm_params) + + (num_ch * sizeof(struct afe_sp_v4_channel_ftm_params)); + break; + case AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_PARAMS: + num_ch = data_start[0]; + this_afe.spv4_rcvd_param_size = + sizeof(struct afe_sp_v4_gen_get_param_resp) + + sizeof(struct afe_sp_v4_param_th_vi_v_vali_params) + + (num_ch * + sizeof(struct afe_sp_v4_channel_v_vali_params)); + this_afe.spv4_get_param_resp_ptr = + kzalloc(this_afe.spv4_rcvd_param_size, GFP_ATOMIC); + data_dest = (u32 *)this_afe.spv4_get_param_resp_ptr; + expected_size += + sizeof(struct afe_sp_v4_param_th_vi_v_vali_params) + + (num_ch * + sizeof(struct afe_sp_v4_channel_v_vali_params)); + break; + case AFE_PARAM_ID_SP_V4_EX_VI_FTM_PARAMS: + num_ch = data_start[0]; + this_afe.spv4_rcvd_param_size = + sizeof(struct afe_sp_v4_gen_get_param_resp) + + sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) + + (num_ch * + sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params)); + this_afe.spv4_get_param_resp_ptr = + kzalloc(this_afe.spv4_rcvd_param_size, GFP_ATOMIC); + data_dest = (u32 *)this_afe.spv4_get_param_resp_ptr; + expected_size += + sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) + + (num_ch * + sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params)); + break; + case AFE_PARAM_ID_SP_V4_RX_TMAX_XMAX_LOGGING: + num_ch = data_start[0]; + this_afe.spv4_rcvd_param_size = + sizeof(struct afe_sp_v4_gen_get_param_resp) + + sizeof(struct afe_sp_v4_param_tmax_xmax_logging) + + (num_ch * + sizeof(struct afe_sp_v4_channel_tmax_xmax_params)); + this_afe.spv4_get_param_resp_ptr = + kzalloc(this_afe.spv4_rcvd_param_size, GFP_ATOMIC); + data_dest = (u32 *)this_afe.spv4_get_param_resp_ptr; + expected_size += + sizeof(struct afe_sp_v4_param_tmax_xmax_logging) + + (num_ch * + sizeof(struct afe_sp_v4_channel_tmax_xmax_params)); + break; default: pr_err("%s: Unrecognized param ID %d\n", __func__, param_hdr.param_id); return -EINVAL; } + if (!data_dest) + return -ENOMEM; + if (payload_size < expected_size) { - pr_err("%s: Error: received size %d, expected size %zu for param %d\n", - __func__, payload_size, expected_size, - param_hdr.param_id); + pr_err( + "%s: Error: received size %d, expected size %zu for param %d\n", + __func__, payload_size, expected_size, + param_hdr.param_id); return -EINVAL; } @@ -841,6 +919,22 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) flag_dc_presence[1] == 1) { afe_notify_dc_presence(); } + } else if ((evt_pl->module_id == + AFE_MODULE_SPEAKER_PROTECTION_V4_VI) && + (evt_pl->event_id == + AFE_PORT_SP_DC_DETECTION_EVENT)) { + bool dc_detected = false; + uint32_t *num_channels = + (uint32_t *)((uint8_t *)payload + + sizeof(struct afe_port_mod_evt_rsp_hdr)); + uint32_t *dc_presence_flag = num_channels + 1; + + for (i = 0; i < *num_channels; i++) { + if (dc_presence_flag[i] == 1) + dc_detected = true; + } + if (dc_detected) + afe_notify_dc_presence(); } else if (evt_pl->port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) { if (this_afe.pri_spdif_tx_cb) { this_afe.pri_spdif_tx_cb(data->opcode, @@ -1884,7 +1978,7 @@ fail_cmd: } static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, - union afe_spkr_prot_config *prot_config) + union afe_spkr_prot_config *prot_config, uint32_t param_size) { struct param_hdr_v3 param_info; int ret = -EINVAL; @@ -1911,6 +2005,9 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, case AFE_PARAM_ID_SP_RX_LIMITER_TH: param_info.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; break; + case AFE_PARAM_ID_SP_V4_OP_MODE: + param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_RX; + break; case AFE_PARAM_ID_FEEDBACK_PATH_CFG: this_afe.vi_tx_port = src_port; this_afe.vi_rx_port = dst_port; @@ -1930,6 +2027,15 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, case AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG: param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; break; + case AFE_PARAM_ID_SP_V4_VI_CHANNEL_MAP_CFG: + case AFE_PARAM_ID_SP_V4_VI_OP_MODE_CFG: + case AFE_PARAM_ID_SP_V4_VI_R0T0_CFG: + case AFE_PARAM_ID_SP_V4_TH_VI_FTM_CFG: + case AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_CFG: + case AFE_PARAM_ID_SP_V4_EX_VI_MODE_CFG: + case AFE_PARAM_ID_SP_V4_EX_VI_FTM_CFG: + param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI; + break; default: pr_err("%s: default case 0x%x\n", __func__, param_id); goto fail_cmd; @@ -1937,7 +2043,7 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, param_info.instance_id = INSTANCE_ID_0; param_info.param_id = param_id; - param_info.param_size = sizeof(union afe_spkr_prot_config); + param_info.param_size = param_size; ret = q6afe_pack_and_set_param_in_band(src_port, q6audio_get_port_index(src_port), @@ -1952,7 +2058,7 @@ fail_cmd: return ret; } -static int afe_spkr_prot_reg_event_cfg(u16 port_id) +static int afe_spkr_prot_reg_event_cfg(u16 port_id, uint32_t module_id) { struct afe_port_cmd_event_cfg *config; struct afe_port_cmd_mod_evt_cfg_payload pl; @@ -1974,7 +2080,7 @@ static int afe_spkr_prot_reg_event_cfg(u16 port_id) } memset(&pl, 0, sizeof(pl)); - pl.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; + pl.module_id = module_id; pl.event_id = AFE_PORT_SP_DC_DETECTION_EVENT; pl.reg_flag = AFE_MODULE_REGISTER_EVENT_FLAG; @@ -1998,10 +2104,260 @@ fail_idx: return ret; } +static void afe_send_cal_spv4_tx(int port_id) +{ + union afe_spkr_prot_config afe_spk_config; + uint32_t size = 0; + void *tmp_ptr = NULL; + struct afe_sp_v4_param_th_vi_r0t0_cfg *th_vi_r0t0_cfg = NULL; + struct afe_sp_v4_channel_r0t0 *ch_r0t0_cfg = NULL; + struct afe_sp_v4_param_th_vi_ftm_cfg *th_vi_ftm_cfg = NULL; + struct afe_sp_v4_channel_ftm_cfg *ch_ftm_cfg = NULL; + struct afe_sp_v4_param_th_vi_v_vali_cfg *th_vi_v_vali_cfg = NULL; + struct afe_sp_v4_channel_v_vali_cfg *ch_v_vali_cfg = NULL; + struct afe_sp_v4_param_ex_vi_ftm_cfg *ex_vi_ftm_cfg = NULL; + struct afe_sp_v4_channel_ex_vi_ftm *ch_ex_vi_ftm_cfg = NULL; + + pr_debug("%s: Entry.. port_id %d\n", __func__, port_id); + + if (this_afe.vi_tx_port == port_id) { + memcpy(&afe_spk_config.v4_ch_map_cfg, &this_afe.v4_ch_map_cfg, + sizeof(struct afe_sp_v4_param_vi_channel_map_cfg)); + if (afe_spk_prot_prepare(port_id, this_afe.vi_rx_port, + AFE_PARAM_ID_SP_V4_VI_CHANNEL_MAP_CFG, &afe_spk_config, + sizeof(struct afe_sp_v4_param_vi_channel_map_cfg))) + pr_info("%s: SPKR_CALIB_CHANNEL_MAP_CFG failed\n", + __func__); + } + + if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL || + this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL || + this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL) { + pr_info("%s: Returning as no cal data cached\n", __func__); + return; + } + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); + if ((this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED) && + (this_afe.vi_tx_port == port_id) && + (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9)) { + + if (this_afe.prot_cfg.mode == + MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) { + afe_spk_config.v4_vi_op_mode.th_operation_mode = + Q6AFE_MSM_SPKR_CALIBRATION; + afe_spk_config.v4_vi_op_mode.th_quick_calib_flag = + this_afe.prot_cfg.quick_calib_flag; + } else { + afe_spk_config.v4_vi_op_mode.th_operation_mode = + Q6AFE_MSM_SPKR_PROCESSING; + } + + if (this_afe.th_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) + afe_spk_config.v4_vi_op_mode.th_operation_mode = + Q6AFE_MSM_SPKR_FTM_MODE; + else if (this_afe.v_vali_cfg.mode == + MSM_SPKR_PROT_IN_V_VALI_MODE) + afe_spk_config.v4_vi_op_mode.th_operation_mode = + Q6AFE_MSM_SPKR_V_VALI_MODE; + if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_NOT_CALIBRATED) { + struct afe_sp_v4_param_vi_op_mode_cfg *v4_vi_op_mode; + + v4_vi_op_mode = &afe_spk_config.v4_vi_op_mode; + v4_vi_op_mode->th_r0t0_selection_flag[SP_V2_SPKR_1] = + USE_CALIBRATED_R0TO; + v4_vi_op_mode->th_r0t0_selection_flag[SP_V2_SPKR_2] = + USE_CALIBRATED_R0TO; + } else { + struct afe_sp_v4_param_vi_op_mode_cfg *v4_vi_op_mode; + + v4_vi_op_mode = &afe_spk_config.v4_vi_op_mode; + v4_vi_op_mode->th_r0t0_selection_flag[SP_V2_SPKR_1] = + USE_SAFE_R0TO; + v4_vi_op_mode->th_r0t0_selection_flag[SP_V2_SPKR_2] = + USE_SAFE_R0TO; + } + afe_spk_config.v4_vi_op_mode.num_speakers = SP_V2_NUM_MAX_SPKRS; + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V4_VI_OP_MODE_CFG, + &afe_spk_config, + sizeof(struct afe_sp_v4_param_vi_op_mode_cfg))) + pr_info("%s: SPKR_CALIB_VI_PROC_CFG failed\n", + __func__); + + size = sizeof(struct afe_sp_v4_param_th_vi_r0t0_cfg) + + (SP_V2_NUM_MAX_SPKRS * sizeof(struct afe_sp_v4_channel_r0t0)); + tmp_ptr = kzalloc(size, GFP_KERNEL); + if (!tmp_ptr) { + mutex_unlock( + &this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); + return; + } + memset(tmp_ptr, 0, size); + + th_vi_r0t0_cfg = + (struct afe_sp_v4_param_th_vi_r0t0_cfg *)tmp_ptr; + ch_r0t0_cfg = + (struct afe_sp_v4_channel_r0t0 *)(th_vi_r0t0_cfg + 1); + + th_vi_r0t0_cfg->num_speakers = SP_V2_NUM_MAX_SPKRS; + ch_r0t0_cfg[SP_V2_SPKR_1].r0_cali_q24 = + (uint32_t) this_afe.prot_cfg.r0[SP_V2_SPKR_1]; + ch_r0t0_cfg[SP_V2_SPKR_2].r0_cali_q24 = + (uint32_t) this_afe.prot_cfg.r0[SP_V2_SPKR_2]; + ch_r0t0_cfg[SP_V2_SPKR_1].t0_cali_q6 = + (uint32_t) this_afe.prot_cfg.t0[SP_V2_SPKR_1]; + ch_r0t0_cfg[SP_V2_SPKR_2].t0_cali_q6 = + (uint32_t) this_afe.prot_cfg.t0[SP_V2_SPKR_2]; + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V4_VI_R0T0_CFG, + (union afe_spkr_prot_config *)tmp_ptr, size)) + pr_info("%s: th vi ftm cfg failed\n", __func__); + + kfree(tmp_ptr); + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + if ((this_afe.th_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) && + (this_afe.vi_tx_port == port_id) && + (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9)) { + size = sizeof(struct afe_sp_v4_param_th_vi_ftm_cfg) + + (SP_V2_NUM_MAX_SPKRS*sizeof(struct afe_sp_v4_channel_ftm_cfg)); + tmp_ptr = kzalloc(size, GFP_KERNEL); + if (!tmp_ptr) { + mutex_unlock( + &this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + return; + } + memset(tmp_ptr, 0, size); + + th_vi_ftm_cfg = (struct afe_sp_v4_param_th_vi_ftm_cfg *)tmp_ptr; + ch_ftm_cfg = + (struct afe_sp_v4_channel_ftm_cfg *)(th_vi_ftm_cfg+1); + + th_vi_ftm_cfg->num_ch = SP_V2_NUM_MAX_SPKRS; + ch_ftm_cfg[SP_V2_SPKR_1].wait_time_ms = + this_afe.th_ftm_cfg.wait_time[SP_V2_SPKR_1]; + ch_ftm_cfg[SP_V2_SPKR_2].wait_time_ms = + this_afe.th_ftm_cfg.wait_time[SP_V2_SPKR_2]; + ch_ftm_cfg[SP_V2_SPKR_1].ftm_time_ms = + this_afe.th_ftm_cfg.ftm_time[SP_V2_SPKR_1]; + ch_ftm_cfg[SP_V2_SPKR_2].ftm_time_ms = + this_afe.th_ftm_cfg.ftm_time[SP_V2_SPKR_2]; + + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V4_TH_VI_FTM_CFG, + (union afe_spkr_prot_config *)tmp_ptr, size)) + pr_info("%s: th vi ftm cfg failed\n", __func__); + + kfree(tmp_ptr); + this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; + } else if ((this_afe.v_vali_cfg.mode == + MSM_SPKR_PROT_IN_V_VALI_MODE) && + (this_afe.vi_tx_port == port_id)) { + size = sizeof(struct afe_sp_v4_param_th_vi_v_vali_cfg) + + (SP_V2_NUM_MAX_SPKRS * + sizeof(struct afe_sp_v4_channel_v_vali_cfg)); + tmp_ptr = kzalloc(size, GFP_KERNEL); + if (!tmp_ptr) { + mutex_unlock( + &this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + return; + } + memset(tmp_ptr, 0, size); + + th_vi_v_vali_cfg = + (struct afe_sp_v4_param_th_vi_v_vali_cfg *)tmp_ptr; + ch_v_vali_cfg = + (struct afe_sp_v4_channel_v_vali_cfg *)(th_vi_v_vali_cfg + 1); + + th_vi_v_vali_cfg->num_ch = SP_V2_NUM_MAX_SPKRS; + ch_v_vali_cfg[SP_V2_SPKR_1].wait_time_ms = + this_afe.v_vali_cfg.wait_time[SP_V2_SPKR_1]; + ch_v_vali_cfg[SP_V2_SPKR_2].wait_time_ms = + this_afe.v_vali_cfg.wait_time[SP_V2_SPKR_2]; + ch_v_vali_cfg[SP_V2_SPKR_1].vali_time_ms = + this_afe.v_vali_cfg.vali_time[SP_V2_SPKR_1]; + ch_v_vali_cfg[SP_V2_SPKR_2].vali_time_ms = + this_afe.v_vali_cfg.vali_time[SP_V2_SPKR_2]; + + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_CFG, + (union afe_spkr_prot_config *)tmp_ptr, size)) + pr_info("%s: th vi v-vali cfg failed\n", __func__); + + kfree(tmp_ptr); + this_afe.v_vali_cfg.mode = MSM_SPKR_PROT_DISABLED; + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); + if ((this_afe.ex_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) && + (this_afe.vi_tx_port == port_id) && + (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9)) { + size = sizeof(struct afe_sp_v4_param_ex_vi_ftm_cfg) + + (SP_V2_NUM_MAX_SPKRS * + sizeof(struct afe_sp_v4_channel_ex_vi_ftm)); + tmp_ptr = kzalloc(size, GFP_KERNEL); + if (!tmp_ptr) { + mutex_unlock( + &this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); + return; + } + memset(tmp_ptr, 0, size); + + ex_vi_ftm_cfg = (struct afe_sp_v4_param_ex_vi_ftm_cfg *)tmp_ptr; + ch_ex_vi_ftm_cfg = + (struct afe_sp_v4_channel_ex_vi_ftm *)(ex_vi_ftm_cfg + 1); + + afe_spk_config.v4_ex_vi_mode_cfg.operation_mode = + AFE_FBSP_V4_EX_VI_MODE_FTM; + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V4_EX_VI_MODE_CFG, + &afe_spk_config, + sizeof(struct afe_sp_v4_param_ex_vi_mode_cfg))) + pr_info("%s: ex vi mode cfg failed\n", __func__); + + ex_vi_ftm_cfg->num_ch = SP_V2_NUM_MAX_SPKRS; + + ch_ex_vi_ftm_cfg[SP_V2_SPKR_1].wait_time_ms = + this_afe.ex_ftm_cfg.wait_time[SP_V2_SPKR_1]; + ch_ex_vi_ftm_cfg[SP_V2_SPKR_2].wait_time_ms = + this_afe.ex_ftm_cfg.wait_time[SP_V2_SPKR_2]; + ch_ex_vi_ftm_cfg[SP_V2_SPKR_1].ftm_time_ms = + this_afe.ex_ftm_cfg.ftm_time[SP_V2_SPKR_1]; + ch_ex_vi_ftm_cfg[SP_V2_SPKR_2].ftm_time_ms = + this_afe.ex_ftm_cfg.ftm_time[SP_V2_SPKR_2]; + + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V4_EX_VI_FTM_CFG, + (union afe_spkr_prot_config *)tmp_ptr, size)) + pr_info("%s: ex vi ftm cfg failed\n", __func__); + kfree(tmp_ptr); + this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); + + /* Register for DC detection event if speaker protection is enabled */ + if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED && + (this_afe.vi_tx_port == port_id)) { + afe_spkr_prot_reg_event_cfg(port_id, + AFE_MODULE_SPEAKER_PROTECTION_V4_VI); + } + +} + static void afe_send_cal_spkr_prot_tx(int port_id) { union afe_spkr_prot_config afe_spk_config; + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) { + afe_send_cal_spv4_tx(port_id); + return; + } + if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL || this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL || this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL) @@ -2056,7 +2412,7 @@ static void afe_send_cal_spkr_prot_tx(int port_id) } if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2, - &afe_spk_config)) + &afe_spk_config, sizeof(union afe_spkr_prot_config))) pr_err("%s: SPKR_CALIB_VI_PROC_CFG failed\n", __func__); } @@ -2076,8 +2432,9 @@ static void afe_send_cal_spkr_prot_tx(int port_id) this_afe.th_ftm_cfg.ftm_time[SP_V2_SPKR_2]; if (afe_spk_prot_prepare(port_id, 0, - AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG, - &afe_spk_config)) + AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG, + &afe_spk_config, + sizeof(union afe_spkr_prot_config))) pr_err("%s: th vi ftm cfg failed\n", __func__); this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; } else if ((this_afe.v_vali_cfg.mode == @@ -2095,7 +2452,8 @@ static void afe_send_cal_spkr_prot_tx(int port_id) if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_SP_V2_TH_VI_V_VALI_CFG, - &afe_spk_config)) + &afe_spk_config, + sizeof(union afe_spkr_prot_config))) pr_err("%s: th vi v-vali cfg failed\n", __func__); this_afe.v_vali_cfg.mode = MSM_SPKR_PROT_DISABLED; @@ -2110,7 +2468,8 @@ static void afe_send_cal_spkr_prot_tx(int port_id) Q6AFE_MSM_SPKR_FTM_MODE; if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_SP_V2_EX_VI_MODE_CFG, - &afe_spk_config)) + &afe_spk_config, + sizeof(union afe_spkr_prot_config))) pr_err("%s: ex vi mode cfg failed\n", __func__); afe_spk_config.ex_vi_ftm_cfg.minor_version = 1; @@ -2125,7 +2484,8 @@ static void afe_send_cal_spkr_prot_tx(int port_id) if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG, - &afe_spk_config)) + &afe_spk_config, + sizeof(union afe_spkr_prot_config))) pr_err("%s: ex vi ftm cfg failed\n", __func__); this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; } @@ -2134,15 +2494,50 @@ static void afe_send_cal_spkr_prot_tx(int port_id) /* Register for DC detection event if speaker protection is enabled */ if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED && (this_afe.vi_tx_port == port_id)) { - afe_spkr_prot_reg_event_cfg(port_id); + afe_spkr_prot_reg_event_cfg(port_id, + AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI); } } +static void afe_send_cal_spv4_rx(int port_id) +{ + + union afe_spkr_prot_config afe_spk_config; + + if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL) + return; + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); + if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED && + (this_afe.vi_rx_port == port_id) && + (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9)) { + if (this_afe.prot_cfg.mode == + MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) + afe_spk_config.v4_op_mode.mode = + Q6AFE_MSM_SPKR_CALIBRATION; + else + afe_spk_config.v4_op_mode.mode = + Q6AFE_MSM_SPKR_PROCESSING; + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V4_OP_MODE, + &afe_spk_config, sizeof(union afe_spkr_prot_config))) + pr_info("%s: RX MODE_VI_PROC_CFG failed\n", + __func__); + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); +} + static void afe_send_cal_spkr_prot_rx(int port_id) { union afe_spkr_prot_config afe_spk_config; union afe_spkr_prot_config afe_spk_limiter_config; + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) { + afe_send_cal_spv4_rx(port_id); + return; + } + if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL) goto done; @@ -2160,9 +2555,9 @@ static void afe_send_cal_spkr_prot_rx(int port_id) afe_spk_config.mode_rx_cfg.minor_version = 1; if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_FBSP_MODE_RX_CFG, - &afe_spk_config)) + &afe_spk_config, sizeof(union afe_spkr_prot_config))) pr_err("%s: RX MODE_VI_PROC_CFG failed\n", - __func__); + __func__); if (afe_spk_config.mode_rx_cfg.mode == Q6AFE_MSM_SPKR_PROCESSING) { @@ -2178,7 +2573,8 @@ static void afe_send_cal_spkr_prot_rx(int port_id) this_afe.prot_cfg.limiter_th[SP_V2_SPKR_2]; if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_SP_RX_LIMITER_TH, - &afe_spk_limiter_config)) + &afe_spk_limiter_config, + sizeof(union afe_spkr_prot_config))) pr_err("%s: SP_RX_LIMITER_TH failed.\n", __func__); } else { @@ -8060,6 +8456,62 @@ int q6afe_check_osr_clk_freq(u32 freq) } EXPORT_SYMBOL(q6afe_check_osr_clk_freq); +static int afe_get_spv4_th_vi_v_vali_data(void *params, uint32_t size) +{ + struct param_hdr_v3 param_hdr; + int port = AFE_PORT_ID_WSA_CODEC_DMA_TX_0; + int ret = -EINVAL; + u8 *rcvd_params = NULL; + struct afe_sp_v4_channel_v_vali_params *v_vali_params = NULL; + + if (!params) { + pr_err("%s: Invalid params\n", __func__); + goto done; + } + if (this_afe.vi_tx_port != -1) + port = this_afe.vi_tx_port; + + mutex_lock(&this_afe.afe_cmd_lock); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_PARAMS; + param_hdr.param_size = size; + + ret = q6afe_get_params(port, NULL, ¶m_hdr); + if (ret) { + pr_err("%s: Failed to get TH VI V-Vali data\n", __func__); + goto get_params_fail; + } + + rcvd_params = (u8 *)this_afe.spv4_get_param_resp_ptr + + sizeof(struct afe_sp_v4_gen_get_param_resp); + + memcpy(params, rcvd_params, this_afe.spv4_rcvd_param_size); + + v_vali_params = (struct afe_sp_v4_channel_v_vali_params *) + (params + sizeof(struct afe_sp_v4_param_th_vi_v_vali_params)); + pr_debug("%s: Vrms %d %d status %d %d\n", __func__, + v_vali_params[SP_V2_SPKR_1].vrms_q24, + v_vali_params[SP_V2_SPKR_2].vrms_q24, + v_vali_params[SP_V2_SPKR_1].status, + v_vali_params[SP_V2_SPKR_2].status); + + /*using the non-spv4 status varaible to support v_vali debug app. */ + this_afe.th_vi_v_vali_resp.param.status[SP_V2_SPKR_1] = + v_vali_params[SP_V2_SPKR_1].status; + this_afe.th_vi_v_vali_resp.param.status[SP_V2_SPKR_2] = + v_vali_params[SP_V2_SPKR_2].status; + + ret = 0; +get_params_fail: + kfree(this_afe.spv4_get_param_resp_ptr); + mutex_unlock(&this_afe.afe_cmd_lock); +done: + return ret; +} + static int afe_get_sp_th_vi_v_vali_data( struct afe_sp_th_vi_v_vali_get_param *th_vi_v_vali) { @@ -8103,7 +8555,57 @@ done: return ret; } -int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) +static int afe_get_spv4_th_vi_ftm_data(void *params, uint32_t size) +{ + struct param_hdr_v3 param_hdr; + int port = SLIMBUS_4_TX; + int ret = -EINVAL; + u8 *rcvd_params = NULL; + struct afe_sp_v4_channel_ftm_params *th_vi_params; + + if (!params) { + pr_err("%s: Invalid params\n", __func__); + goto done; + } + if (this_afe.vi_tx_port != -1) + port = this_afe.vi_tx_port; + + mutex_lock(&this_afe.afe_cmd_lock); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_V4_TH_VI_FTM_PARAMS; + param_hdr.param_size = size; + + ret = q6afe_get_params(port, NULL, ¶m_hdr); + if (ret) { + pr_err("%s: Failed to get TH VI FTM data\n", __func__); + goto get_params_fail; + } + + rcvd_params = (u8 *)this_afe.spv4_get_param_resp_ptr + + sizeof(struct afe_sp_v4_gen_get_param_resp); + memcpy(params, rcvd_params, this_afe.spv4_rcvd_param_size); + + th_vi_params = (struct afe_sp_v4_channel_ftm_params *) + (params + sizeof(struct afe_sp_v4_param_th_vi_ftm_params)); + pr_debug("%s: DC resistance %d %d temp %d %d status %d %d\n", + __func__, th_vi_params[SP_V2_SPKR_1].dc_res_q24, + th_vi_params[SP_V2_SPKR_2].dc_res_q24, + th_vi_params[SP_V2_SPKR_1].temp_q22, + th_vi_params[SP_V2_SPKR_2].temp_q22, + th_vi_params[SP_V2_SPKR_1].status, + th_vi_params[SP_V2_SPKR_2].status); + ret = 0; +get_params_fail: + kfree(this_afe.spv4_get_param_resp_ptr); + mutex_unlock(&this_afe.afe_cmd_lock); +done: + return ret; +} + +static int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) { struct param_hdr_v3 param_hdr; int port = SLIMBUS_4_TX; @@ -8147,7 +8649,69 @@ done: return ret; } -int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) +static int afe_get_spv4_ex_vi_ftm_data(void *params, uint32_t size) +{ + struct param_hdr_v3 param_hdr; + int port = SLIMBUS_4_TX; + int ret = -EINVAL; + u8 *rcvd_params = NULL; + struct afe_sp_v4_channel_ex_vi_ftm_params *ex_vi_ftm_param; + + if (!params) { + pr_err("%s: Invalid params\n", __func__); + goto done; + } + if (this_afe.vi_tx_port != -1) + port = this_afe.vi_tx_port; + + mutex_lock(&this_afe.afe_cmd_lock); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_V4_EX_VI_FTM_PARAMS; + param_hdr.param_size = size; + + ret = q6afe_get_params(port, NULL, ¶m_hdr); + if (ret < 0) { + pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", + __func__, port, param_hdr.param_id, ret); + goto get_params_fail; + } + + rcvd_params = (u8 *)this_afe.spv4_get_param_resp_ptr + + sizeof(struct afe_sp_v4_gen_get_param_resp); + + memcpy(params, rcvd_params, this_afe.spv4_rcvd_param_size); + + ex_vi_ftm_param = (struct afe_sp_v4_channel_ex_vi_ftm_params *) + (params + sizeof(struct afe_sp_v4_param_ex_vi_ftm_params)); + + pr_debug("%s: resistance %d %d force factor %d %d Damping kg/s %d %d\n" + "stiffness N/mm %d %d freq %d %d Qfactor %d %d status %d %d", + __func__, ex_vi_ftm_param[SP_V2_SPKR_1].ftm_re_q24, + ex_vi_ftm_param[SP_V2_SPKR_2].ftm_re_q24, + ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Bl_q24, + ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Bl_q24, + ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Rms_q24, + ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Rms_q24, + ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Kms_q24, + ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Kms_q24, + ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Fres_q20, + ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Fres_q20, + ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Qms_q24, + ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Qms_q24, + ex_vi_ftm_param[SP_V2_SPKR_1].status, + ex_vi_ftm_param[SP_V2_SPKR_2].status); + ret = 0; +get_params_fail: + kfree(this_afe.spv4_get_param_resp_ptr); + mutex_unlock(&this_afe.afe_cmd_lock); +done: + return ret; +} + +static int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) { struct param_hdr_v3 param_hdr; int port = SLIMBUS_4_TX; @@ -8194,6 +8758,61 @@ done: return ret; } +static int afe_get_sp_v4_rx_tmax_xmax_logging_data( + struct afe_sp_rx_tmax_xmax_logging_param *xt_logging, + u16 port_id) +{ + struct param_hdr_v3 param_hdr; + int ret = -EINVAL; + struct afe_sp_v4_param_tmax_xmax_logging *tmax_xmax_logging; + struct afe_sp_v4_channel_tmax_xmax_params *tx_channel_params; + uint32_t i, size = 0; + + if (!xt_logging) { + pr_err("%s: Invalid params\n", __func__); + goto done; + } + + size = sizeof(struct afe_sp_v4_param_tmax_xmax_logging) + + (SP_V2_NUM_MAX_SPKRS * + sizeof(struct afe_sp_v4_channel_tmax_xmax_params)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_RX; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_V4_RX_TMAX_XMAX_LOGGING; + param_hdr.param_size = size; + + ret = q6afe_get_params(port_id, NULL, ¶m_hdr); + if (ret) { + pr_err("%s: Failed to get Tmax Xmax logging data\n", __func__); + goto get_params_fail; + } + + tmax_xmax_logging = (struct afe_sp_v4_param_tmax_xmax_logging *) + ((u8 *)this_afe.spv4_get_param_resp_ptr + + sizeof(struct afe_sp_v4_gen_get_param_resp)); + tx_channel_params = (struct afe_sp_v4_channel_tmax_xmax_params *) + ((u8 *)tmax_xmax_logging + + sizeof(struct afe_sp_v4_param_tmax_xmax_logging)); + for (i = 0; i < tmax_xmax_logging->num_ch; i++) { + xt_logging->max_excursion[i] = + tx_channel_params[i].max_excursion; + xt_logging->count_exceeded_excursion[i] = + tx_channel_params[i].count_exceeded_excursion; + xt_logging->max_temperature[i] = + tx_channel_params[i].max_temperature; + xt_logging->count_exceeded_temperature[i] = + tx_channel_params[i].count_exceeded_temperature; + } + + ret = 0; +get_params_fail: + kfree(this_afe.spv4_get_param_resp_ptr); +done: + return ret; +} + /** * afe_get_sp_rx_tmax_xmax_logging_data - * command to get excursion logging data from DSP @@ -8216,23 +8835,32 @@ int afe_get_sp_rx_tmax_xmax_logging_data( } mutex_lock(&this_afe.afe_cmd_lock); - memset(¶m_hdr, 0, sizeof(param_hdr)); + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) { + ret = afe_get_sp_v4_rx_tmax_xmax_logging_data(xt_logging, + port_id); + } else { + memset(¶m_hdr, 0, sizeof(param_hdr)); - param_hdr.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; - param_hdr.instance_id = INSTANCE_ID_0; - param_hdr.param_id = AFE_PARAM_ID_SP_RX_TMAX_XMAX_LOGGING; - param_hdr.param_size = sizeof(struct afe_sp_rx_tmax_xmax_logging_param); + param_hdr.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_RX_TMAX_XMAX_LOGGING; + param_hdr.param_size = + sizeof(struct afe_sp_rx_tmax_xmax_logging_param); - ret = q6afe_get_params(port_id, NULL, ¶m_hdr); - if (ret < 0) { - pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", - __func__, port_id, param_hdr.param_id, ret); - goto get_params_fail; + ret = q6afe_get_params(port_id, NULL, ¶m_hdr); + if (ret < 0) { + pr_err( + "%s: get param port 0x%x param id[0x%x]failed %d\n", + __func__, port_id, param_hdr.param_id, ret); + goto get_params_fail; + } + + memcpy(xt_logging, &this_afe.xt_logging_resp.param, + sizeof(this_afe.xt_logging_resp.param)); } - - memcpy(xt_logging, &this_afe.xt_logging_resp.param, - sizeof(this_afe.xt_logging_resp.param)); - pr_debug("%s: max_excursion %d %d count_exceeded_excursion %d %d max_temperature %d %d count_exceeded_temperature %d %d\n", + pr_debug("%s: max_excursion %d %d count_exceeded_excursion %d %d" + " max_temperature %d %d count_exceeded_temperature %d %d\n", __func__, xt_logging->max_excursion[SP_V2_SPKR_1], xt_logging->max_excursion[SP_V2_SPKR_2], xt_logging->count_exceeded_excursion[SP_V2_SPKR_1], @@ -8342,6 +8970,46 @@ exit: } EXPORT_SYMBOL(afe_get_doa_tracking_mon); +static int afe_spv4_get_calib_data( + struct afe_sp_v4_th_vi_calib_resp *calib_resp) +{ + struct param_hdr_v3 param_hdr; + int port = SLIMBUS_4_TX; + int ret = -EINVAL; + + if (!calib_resp) { + pr_err("%s: Invalid params\n", __func__); + goto fail_cmd; + } + if (this_afe.vi_tx_port != -1) + port = this_afe.vi_tx_port; + + mutex_lock(&this_afe.afe_cmd_lock); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_V4_CALIB_RES_CFG; + param_hdr.param_size = sizeof(struct afe_sp_v4_th_vi_calib_resp); + + ret = q6afe_get_params(port, NULL, ¶m_hdr); + if (ret < 0) { + pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", + __func__, port, param_hdr.param_id, ret); + goto get_params_fail; + } + memcpy(&calib_resp->res_cfg, &this_afe.spv4_calib_data.res_cfg, + sizeof(this_afe.calib_data.res_cfg)); + pr_info("%s: state %s resistance %d %d\n", __func__, + fbsp_state[calib_resp->res_cfg.th_vi_ca_state], + calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_1], + calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_2]); + ret = 0; +get_params_fail: + mutex_unlock(&this_afe.afe_cmd_lock); +fail_cmd: + return ret; +} + int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) { struct param_hdr_v3 param_hdr; @@ -8419,22 +9087,41 @@ int afe_spk_prot_feed_back_cfg(int src_port, int dst_port, } pr_debug("%s: src_port 0x%x dst_port 0x%x l_ch %d r_ch %d\n", __func__, src_port, dst_port, l_ch, r_ch); - memset(&prot_config, 0, sizeof(prot_config)); - prot_config.feedback_path_cfg.dst_portid = + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) { + if (l_ch) { + this_afe.v4_ch_map_cfg.chan_info[index++] = 1; + this_afe.v4_ch_map_cfg.chan_info[index++] = 2; + } + if (r_ch) { + this_afe.v4_ch_map_cfg.chan_info[index++] = 3; + this_afe.v4_ch_map_cfg.chan_info[index++] = 4; + } + this_afe.v4_ch_map_cfg.num_channels = index; + pr_debug("%s no of channels: %d\n", __func__, index); + this_afe.vi_tx_port = src_port; + this_afe.vi_rx_port = dst_port; + ret = 0; + } else { + memset(&prot_config, 0, sizeof(prot_config)); + prot_config.feedback_path_cfg.dst_portid = q6audio_get_port_id(dst_port); - if (l_ch) { - prot_config.feedback_path_cfg.chan_info[index++] = 1; - prot_config.feedback_path_cfg.chan_info[index++] = 2; + if (l_ch) { + prot_config.feedback_path_cfg.chan_info[index++] = 1; + prot_config.feedback_path_cfg.chan_info[index++] = 2; + } + if (r_ch) { + prot_config.feedback_path_cfg.chan_info[index++] = 3; + prot_config.feedback_path_cfg.chan_info[index++] = 4; + } + prot_config.feedback_path_cfg.num_channels = index; + pr_debug("%s no of channels: %d\n", __func__, index); + prot_config.feedback_path_cfg.minor_version = 1; + ret = afe_spk_prot_prepare(src_port, dst_port, + AFE_PARAM_ID_FEEDBACK_PATH_CFG, &prot_config, + sizeof(union afe_spkr_prot_config)); } - if (r_ch) { - prot_config.feedback_path_cfg.chan_info[index++] = 3; - prot_config.feedback_path_cfg.chan_info[index++] = 4; - } - prot_config.feedback_path_cfg.num_channels = index; - pr_debug("%s no of channels: %d\n", __func__, index); - prot_config.feedback_path_cfg.minor_version = 1; - ret = afe_spk_prot_prepare(src_port, dst_port, - AFE_PARAM_ID_FEEDBACK_PATH_CFG, &prot_config); + fail_cmd: return ret; } @@ -8779,6 +9466,9 @@ static int afe_get_cal_sp_th_vi_v_vali_param(int32_t cal_type, size_t data_size, int i, ret = 0; struct audio_cal_type_sp_th_vi_v_vali_param *cal_data = data; struct afe_sp_th_vi_v_vali_get_param th_vi_v_vali; + uint32_t size; + void *params = NULL; + struct afe_sp_v4_channel_v_vali_params *v_vali_params; if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL || cal_data == NULL || @@ -8789,18 +9479,51 @@ static int afe_get_cal_sp_th_vi_v_vali_param(int32_t cal_type, size_t data_size, cal_data->cal_info.status[i] = -EINVAL; cal_data->cal_info.vrms_q24[i] = -1; } - if (!afe_get_sp_th_vi_v_vali_data(&th_vi_v_vali)) { - for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { - pr_debug("%s: v-vali param status = %d\n", - __func__, th_vi_v_vali.param.status[i]); - if (th_vi_v_vali.param.status[i] == - V_VALI_IN_PROGRESS) { - cal_data->cal_info.status[i] = -EAGAIN; - } else if (th_vi_v_vali.param.status[i] == - V_VALI_SUCCESS) { - cal_data->cal_info.status[i] = V_VALI_SUCCESS; - cal_data->cal_info.vrms_q24[i] = - th_vi_v_vali.param.vrms_q24[i]; + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) { + size = sizeof(struct afe_sp_v4_param_th_vi_v_vali_params) + + (SP_V2_NUM_MAX_SPKRS * + sizeof(struct afe_sp_v4_channel_v_vali_params)); + params = kzalloc(size, GFP_KERNEL); + if (!params) + return -ENOMEM; + v_vali_params = + (struct afe_sp_v4_channel_v_vali_params *)((u8 *)params + + sizeof(struct afe_sp_v4_param_th_vi_v_vali_params)); + + if (!afe_get_spv4_th_vi_v_vali_data(params, size)) { + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + pr_debug("%s: ftm param status = %d\n", + __func__, v_vali_params[i].status); + if (v_vali_params[i].status == + V_VALI_IN_PROGRESS) { + cal_data->cal_info.status[i] = -EAGAIN; + } else if (v_vali_params[i].status == + V_VALI_SUCCESS) { + cal_data->cal_info.status[i] = + V_VALI_SUCCESS; + cal_data->cal_info.vrms_q24[i] = + v_vali_params[i].vrms_q24; + } + } + } + kfree(params); + } else { + if (!afe_get_sp_th_vi_v_vali_data(&th_vi_v_vali)) { + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + pr_debug( + "%s: v-vali param status = %d\n", + __func__, th_vi_v_vali.param.status[i]); + if (th_vi_v_vali.param.status[i] == + V_VALI_IN_PROGRESS) { + cal_data->cal_info.status[i] = -EAGAIN; + } else if (th_vi_v_vali.param.status[i] == + V_VALI_SUCCESS) { + cal_data->cal_info.status[i] = + V_VALI_SUCCESS; + cal_data->cal_info.vrms_q24[i] = + th_vi_v_vali.param.vrms_q24[i]; + } } } } @@ -8815,6 +9538,9 @@ static int afe_get_cal_sp_th_vi_ftm_param(int32_t cal_type, size_t data_size, int i, ret = 0; struct audio_cal_type_sp_th_vi_param *cal_data = data; struct afe_sp_th_vi_get_param th_vi; + uint32_t size; + void *params = NULL; + struct afe_sp_v4_channel_ftm_params *th_vi_ftm_params = NULL; if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL || cal_data == NULL || @@ -8826,18 +9552,52 @@ static int afe_get_cal_sp_th_vi_ftm_param(int32_t cal_type, size_t data_size, cal_data->cal_info.r_dc_q24[i] = -1; cal_data->cal_info.temp_q22[i] = -1; } - if (!afe_get_sp_th_vi_ftm_data(&th_vi)) { - for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { - pr_debug("%s: ftm param status = %d\n", - __func__, th_vi.param.status[i]); - if (th_vi.param.status[i] == FBSP_IN_PROGRESS) { - cal_data->cal_info.status[i] = -EAGAIN; - } else if (th_vi.param.status[i] == FBSP_SUCCESS) { - cal_data->cal_info.status[i] = 0; - cal_data->cal_info.r_dc_q24[i] = - th_vi.param.dc_res_q24[i]; - cal_data->cal_info.temp_q22[i] = - th_vi.param.temp_q22[i]; + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) { + size = sizeof(struct afe_sp_v4_param_th_vi_ftm_params) + + (SP_V2_NUM_MAX_SPKRS * + sizeof(struct afe_sp_v4_channel_ftm_params)); + params = kzalloc(size, GFP_KERNEL); + if (!params) + return -ENOMEM; + th_vi_ftm_params = (struct afe_sp_v4_channel_ftm_params *) + ((u8 *)params + + sizeof(struct afe_sp_v4_param_th_vi_ftm_params)); + + if (!afe_get_spv4_th_vi_ftm_data(params, size)) { + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + pr_debug("%s: SP V4 ftm param status = %d\n", + __func__, th_vi_ftm_params[i].status); + if (th_vi_ftm_params[i].status == + FBSP_IN_PROGRESS) { + cal_data->cal_info.status[i] = -EAGAIN; + } else if (th_vi_ftm_params[i].status == + FBSP_SUCCESS) { + cal_data->cal_info.status[i] = 0; + cal_data->cal_info.r_dc_q24[i] = + th_vi_ftm_params[i].dc_res_q24; + cal_data->cal_info.temp_q22[i] = + th_vi_ftm_params[i].temp_q22; + } + } + } + kfree(params); + } else { + + if (!afe_get_sp_th_vi_ftm_data(&th_vi)) { + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + pr_debug("%s: ftm param status = %d\n", + __func__, th_vi.param.status[i]); + if (th_vi.param.status[i] == FBSP_IN_PROGRESS) { + cal_data->cal_info.status[i] = -EAGAIN; + } else if (th_vi.param.status[i] == + FBSP_SUCCESS) { + cal_data->cal_info.status[i] = 0; + cal_data->cal_info.r_dc_q24[i] = + th_vi.param.dc_res_q24[i]; + cal_data->cal_info.temp_q22[i] = + th_vi.param.temp_q22[i]; + } } } } @@ -8870,6 +9630,75 @@ static int afe_get_cal_sp_th_vi_param(int32_t cal_type, size_t data_size, return ret; } +static int afe_get_cal_spv4_ex_vi_ftm_param(int32_t cal_type, size_t data_size, + void *data) +{ + int i, ret = 0; + struct audio_cal_type_sp_v4_ex_vi_param *cal_data = data; + uint32_t size; + void *params = NULL; + struct afe_sp_v4_channel_ex_vi_ftm_params *ex_vi_ftm_param; + + pr_debug("%s: cal_type = %d\n", __func__, cal_type); + if (this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL] == NULL || + cal_data == NULL || + data_size != sizeof(*cal_data)) + goto done; + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL]->lock); + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + cal_data->cal_info.status[i] = -EINVAL; + cal_data->cal_info.ftm_re_q24[i] = -1; + cal_data->cal_info.ftm_re_q24[i] = -1; + cal_data->cal_info.ftm_Rms_q24[i] = -1; + cal_data->cal_info.ftm_Kms_q24[i] = -1; + cal_data->cal_info.ftm_freq_q20[i] = -1; + cal_data->cal_info.ftm_Qms_q24[i] = -1; + } + + size = sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) + + (SP_V2_NUM_MAX_SPKRS * + sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params)); + params = kzalloc(size, GFP_KERNEL); + if (!params) { + mutex_unlock( + &this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL]->lock); + return -ENOMEM; + } + ex_vi_ftm_param = (struct afe_sp_v4_channel_ex_vi_ftm_params *) + ((u8 *)params + + sizeof(struct afe_sp_v4_param_ex_vi_ftm_params)); + + if (!afe_get_spv4_ex_vi_ftm_data(params, size)) { + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + pr_debug("%s: ftm param status = %d\n", + __func__, ex_vi_ftm_param[i].status); + if (ex_vi_ftm_param[i].status == FBSP_IN_PROGRESS) { + cal_data->cal_info.status[i] = -EAGAIN; + } else if (ex_vi_ftm_param[i].status == FBSP_SUCCESS) { + cal_data->cal_info.status[i] = 0; + cal_data->cal_info.ftm_re_q24[i] = + ex_vi_ftm_param[i].ftm_re_q24; + cal_data->cal_info.ftm_Bl_q24[i] = + ex_vi_ftm_param[i].ftm_Bl_q24; + cal_data->cal_info.ftm_Rms_q24[i] = + ex_vi_ftm_param[i].ftm_Rms_q24; + cal_data->cal_info.ftm_Kms_q24[i] = + ex_vi_ftm_param[i].ftm_Kms_q24; + cal_data->cal_info.ftm_freq_q20[i] = + ex_vi_ftm_param[i].ftm_Fres_q20; + cal_data->cal_info.ftm_Qms_q24[i] = + ex_vi_ftm_param[i].ftm_Qms_q24; + } + } + } + kfree(params); + + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL]->lock); +done: + return ret; +} + static int afe_get_cal_sp_ex_vi_ftm_param(int32_t cal_type, size_t data_size, void *data) { @@ -8918,6 +9747,7 @@ static int afe_get_cal_fb_spkr_prot(int32_t cal_type, size_t data_size, int ret = 0; struct audio_cal_type_fb_spk_prot_status *cal_data = data; struct afe_spkr_prot_get_vi_calib calib_resp; + struct afe_sp_v4_th_vi_calib_resp spv4_calib_resp; pr_debug("%s:\n", __func__); @@ -8941,17 +9771,47 @@ static int afe_get_cal_fb_spkr_prot(int32_t cal_type, size_t data_size, cal_data->cal_info.status = -EINVAL; cal_data->cal_info.r0[SP_V2_SPKR_1] = -1; cal_data->cal_info.r0[SP_V2_SPKR_2] = -1; - if (!afe_spk_prot_get_calib_data(&calib_resp)) { - if (calib_resp.res_cfg.th_vi_ca_state == + if (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9) { + if (!(q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= + AFE_API_VERSION_V9)) { + pr_debug( + "%s: AFE API version is not supported!\n", + __func__); + goto done; + } + if (!afe_spv4_get_calib_data(&spv4_calib_resp)) { + if (spv4_calib_resp.res_cfg.th_vi_ca_state == FBSP_IN_PROGRESS) - cal_data->cal_info.status = -EAGAIN; - else if (calib_resp.res_cfg.th_vi_ca_state == + cal_data->cal_info.status = -EAGAIN; + else if ( + spv4_calib_resp.res_cfg.th_vi_ca_state == FBSP_SUCCESS) { - cal_data->cal_info.status = 0; - cal_data->cal_info.r0[SP_V2_SPKR_1] = - calib_resp.res_cfg.r0_cali_q24[SP_V2_SPKR_1]; - cal_data->cal_info.r0[SP_V2_SPKR_2] = - calib_resp.res_cfg.r0_cali_q24[SP_V2_SPKR_2]; + cal_data->cal_info.status = 0; + cal_data->cal_info.r0[SP_V2_SPKR_1] = + spv4_calib_resp.res_cfg.r0_cali_q24[ + SP_V2_SPKR_1]; + cal_data->cal_info.r0[SP_V2_SPKR_2] = + spv4_calib_resp.res_cfg.r0_cali_q24[ + SP_V2_SPKR_2]; + } + } + } else { + + if (!afe_spk_prot_get_calib_data(&calib_resp)) { + if (calib_resp.res_cfg.th_vi_ca_state == + FBSP_IN_PROGRESS) + cal_data->cal_info.status = -EAGAIN; + else if (calib_resp.res_cfg.th_vi_ca_state == + FBSP_SUCCESS) { + cal_data->cal_info.status = 0; + cal_data->cal_info.r0[SP_V2_SPKR_1] = + calib_resp.res_cfg.r0_cali_q24[ + SP_V2_SPKR_1]; + cal_data->cal_info.r0[SP_V2_SPKR_2] = + calib_resp.res_cfg.r0_cali_q24[ + SP_V2_SPKR_2]; + } } } if (!cal_data->cal_info.status) { @@ -9136,6 +9996,11 @@ static int afe_init_cal_data(void) {NULL, NULL, NULL, afe_set_cal_sp_ex_vi_ftm_cfg, afe_get_cal_sp_ex_vi_ftm_param, NULL} }, {NULL, NULL, cal_utils_match_buf_num} }, + + {{AFE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE, + {NULL, NULL, NULL, NULL, + afe_get_cal_spv4_ex_vi_ftm_param, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, }; pr_debug("%s:\n", __func__); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 7a686349a4..719cd6c5c4 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -11004,19 +11004,6 @@ struct afe_sp_rx_limiter_th_param { uint32_t lim_thr_per_calib_q27[SP_V2_NUM_MAX_SPKR]; } __packed; -union afe_spkr_prot_config { - struct asm_fbsp_mode_rx_cfg mode_rx_cfg; - struct asm_spkr_calib_vi_proc_cfg vi_proc_cfg; - struct asm_feedback_path_cfg feedback_path_cfg; - struct asm_mode_vi_proc_cfg mode_vi_proc_cfg; - struct afe_sp_th_vi_mode_cfg th_vi_mode_cfg; - struct afe_sp_th_vi_ftm_cfg th_vi_ftm_cfg; - struct afe_sp_th_vi_v_vali_cfg th_vi_v_vali_cfg; - struct afe_sp_ex_vi_mode_cfg ex_vi_mode_cfg; - struct afe_sp_ex_vi_ftm_cfg ex_vi_ftm_cfg; - struct afe_sp_rx_limiter_th_param limiter_th_cfg; -} __packed; - struct afe_spkr_prot_get_vi_calib { struct apr_hdr hdr; struct mem_mapping_hdr mem_hdr; @@ -11031,6 +11018,366 @@ struct afe_spkr_prot_calib_get_resp { } __packed; +#define AFE_MODULE_SPEAKER_PROTECTION_V4_RX 0x000102C7 +#define AFE_PARAM_ID_SP_V4_OP_MODE 0x000102C9 +#define AFE_PARAM_ID_SP_V4_RX_TMAX_XMAX_LOGGING 0x000102D2 + +struct afe_sp_v4_param_op_mode { + uint32_t mode; +} __packed; + +struct afe_sp_v4_channel_tmax_xmax_params { + /* + * Maximum excursion since the last grasp of xmax in mm. + */ + int32_t max_excursion; + /* + * Number of periods when the monitored excursion exceeds to and + * stays at Xmax during logging_count_period. + */ + uint32_t count_exceeded_excursion; + /* + * Maximum temperature since the last grasp of tmax in C. + */ + int32_t max_temperature; + /* + * Number of periods when the monitored temperature exceeds to and + * stays at Tmax during logging_count_period + */ + uint32_t count_exceeded_temperature; +} __packed; + +/* This structure is followed by 'num_ch' number of structures of + * type afe_sp_v4_channel_tmax_xmax_params. + */ +struct afe_sp_v4_param_tmax_xmax_logging { + uint32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_tmax_xmax_params ch_tmax_xmax[0]; +} __packed; + +#define AFE_MODULE_SPEAKER_PROTECTION_V4_VI 0x000102D3 +#define AFE_PARAM_ID_SP_V4_VI_OP_MODE_CFG 0x000102D4 +#define AFE_PARAM_ID_SP_V4_VI_R0T0_CFG 0x000102D5 +#define AFE_PARAM_ID_SP_V4_CALIB_RES_CFG 0x000102D8 +#define AFE_PARAM_ID_SP_V4_TH_VI_FTM_CFG 0x000102D9 +#define AFE_PARAM_ID_SP_V4_TH_VI_FTM_PARAMS 0x000102DA +#define AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_CFG 0x000102DB +#define AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_PARAMS 0x000102DC +#define AFE_PARAM_ID_SP_V4_EX_VI_MODE_CFG 0x000102DF +#define AFE_PARAM_ID_SP_V4_EX_VI_FTM_CFG 0x000102E0 +#define AFE_PARAM_ID_SP_V4_EX_VI_FTM_PARAMS 0x000102E1 +#define AFE_PARAM_ID_SP_V4_VI_CHANNEL_MAP_CFG 0x000102E5 + +struct afe_sp_v4_param_vi_op_mode_cfg { + uint32_t num_speakers; + /* Number of channels for Rx signal. + */ + uint32_t th_operation_mode; + /* + * Operation mode of thermal VI module. + * 0 -- Normal Running mode + * 1 -- Calibration mode + * 2 -- FTM mode + * 3 -- V-Validation mode + */ + uint32_t th_quick_calib_flag; + /* + * Indicates whether calibration is to be done in quick mode or not. + * This field is valid only in Calibration mode (operation_mode = 1). + * 0 -- Disabled + * 1 -- Enabled + */ + uint32_t th_r0t0_selection_flag[SP_V2_NUM_MAX_SPKR]; + /* + * Specifies which set of R0, T0 values the algorithm will use. + * This field is valid only in Normal mode (operation_mode = 0). + * 0 -- Use calibrated R0, T0 value + * 1 -- Use safe R0, T0 value + */ +} __packed; + +struct afe_sp_v4_channel_r0t0 { + int32_t r0_cali_q24; + /* + * Calibration point resistance per device. This field is valid + * only in Normal mode (operation_mode = 0). + * values 33554432 to 1073741824 Ohms (in Q24 format) + */ + int16_t t0_cali_q6; + /* + * Calibration point temperature per device. This field is valid + * in both Normal mode and Calibration mode. + * values -1920 to 5120 degrees C (in Q6 format) + */ + uint16_t reserved; + +} __packed; + +/* Followed by this structure are 'num_speaakers' number of structures + * of type afe_sp_v4_channel_r0t0. + */ +struct afe_sp_v4_param_th_vi_r0t0_cfg { + uint32_t num_speakers; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_r0t0 ch_r0t0[0]; +} __packed; + +struct afe_sp_v4_param_th_vi_calib_res_cfg { + uint32_t num_ch; + /* Number of channels for Rx signal. + */ + uint32_t th_vi_ca_state; + /* + * Represents the calibration state for both speakers. + * 0 -- Incorrect operation mode. + * 1 -- Inactive mode. + * 2 -- Wait state. + * 3 -- Calibration in progress state. + * 4 -- Calibration success. + * 5 -- Calibration failed. + */ + int32_t r0_cali_q24[SP_V2_NUM_MAX_SPKR]; + /* Calibration resistance per device. + */ +} __packed; + +struct afe_sp_v4_th_vi_calib_resp { + uint32_t status; + struct param_hdr_v3 pdata; + struct afe_sp_v4_param_th_vi_calib_res_cfg res_cfg; +} __packed; + +struct afe_sp_v4_channel_ftm_cfg { + uint32_t wait_time_ms; + /* + * Wait time to heat up speaker before collecting statistics + * for ftm mode in ms. + * values 0 to 4294967295 ms + */ + uint32_t ftm_time_ms; + /* + * duration for which FTM statistics are collected in ms. + * values 0 to 2000 ms + */ +} __packed; + +/* This structure is followed by 'num_ch' number of structures + * of type afe_sp_v4_channel_ftm_cfg. + */ +struct afe_sp_v4_param_th_vi_ftm_cfg { + uint32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_ftm_cfg ch_ftm_cfg[0]; +} __packed; + +struct afe_sp_v4_channel_ftm_params { + int32_t dc_res_q24; + /* + * DC resistance value in q24 format + * values 0 to 2147483647 Ohms (in Q24 format) + */ + int32_t temp_q22; + /* + * temperature value in q22 format + * values -125829120 to 2147483647 degC (in Q22 format) + */ + uint32_t status; + /* + * FTM packet status + * 0 - Incorrect operation mode.This status is returned + * when GET_PARAM is called in non FTM Mode + * 1 - Inactive mode -- Port is not yet started. + * 2 - Wait state. wait_time_ms has not yet elapsed + * 3 - In progress state. ftm_time_ms has not yet elapsed. + * 4 - Success. + * 5 - Failed. + */ +} __packed; + +/* This structure is followed by 'num_ch' number of structures + * of type afe_sp_v4_channel_ftm_params. + */ +struct afe_sp_v4_param_th_vi_ftm_params { + uint32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_ftm_params ch_ftm_params[0]; +} __packed; + +struct afe_sp_v4_gen_get_param_resp { + uint32_t status; + struct param_hdr_v3 pdata; +} __packed; + +struct afe_sp_v4_channel_v_vali_cfg { + uint32_t wait_time_ms; + /* + * Wait time to heat up speaker before collecting statistics + * for V validation mode in ms. + * values 100 to 1000 ms + */ + uint32_t vali_time_ms; + /* + * duration for which V VALIDATION statistics are collected in ms. + * values 1000 to 3000 ms + */ +} __packed; + +/* This structure is followed by 'num_ch' number of structures + * of type afe_sp_v4_channel_v_vali_cfg. + */ +struct afe_sp_v4_param_th_vi_v_vali_cfg { + uint32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_v_vali_cfg ch_v_vali_cfg[0]; +} __packed; + +struct afe_sp_v4_channel_v_vali_params { + uint32_t vrms_q24; + /* + * Vrms value in q24 format + * values [0 33554432] Q24 (0 - 2Vrms) + */ + uint32_t status; + /* + * v-vali packet status + * 0 - Failed. + * 1 - Success. + * 2 - Incorrect operation mode.This status is returned + * when GET_PARAM is called in non v-vali Mode + * 3 - Inactive mode -- Port is not yet started. + * 4 - Wait state. wait_time_ms has not yet elapsed + * 5 - In progress state. ftm_time_ms has not yet elapsed. + */ +} __packed; + +/* This structure is followed by 'num_ch' number of structures + * of type afe_sp_v4_channel_v_vali_params. + */ +struct afe_sp_v4_param_th_vi_v_vali_params { + uint32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_v_vali_params ch_v_vali_params[0]; +} __packed; + +struct afe_sp_v4_param_ex_vi_mode_cfg { + uint32_t operation_mode; + /* + * Operation mode of Excursion VI module. + * 0 - Normal Running mode + * 2 - FTM mode + */ +} __packed; + +struct afe_sp_v4_channel_ex_vi_ftm { + uint32_t wait_time_ms; + /* + * Wait time to heat up speaker before collecting statistics + * for ftm mode in ms. + * values 0 to 4294967295 ms + */ + uint32_t ftm_time_ms; + /* + * duration for which FTM statistics are collected in ms. + * values 0 to 2000 ms + */ +} __packed; + +/* This structure is followed by 'num_ch' number of structures + * of type afe_sp_v4_channel_ex_vi_ftm. + */ +struct afe_sp_v4_param_ex_vi_ftm_cfg { + uint32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_ex_vi_ftm ch_ex_vi_ftm[0]; +} __packed; + +struct afe_sp_v4_channel_ex_vi_ftm_params { + int32_t ftm_re_q24; + /* + * DC resistance of voice coil at room temperature + * or small signal level in Ohm. + */ + int32_t ftm_Bl_q24; + /* Force factor. + */ + int32_t ftm_Rms_q24; + /* Mechanical damping or resistance of loudspeaker in Kg/sec. + */ + int32_t ftm_Kms_q24; + /* Mechanical stiffness of driver suspension in N/mm. + */ + int32_t ftm_Fres_q20; + /* Resonance frequency in Hz. + */ + int32_t ftm_Qms_q24; + /* Mechanical Q-factor. + */ + uint32_t status; + /* + * FTM packet status + * 0 - Incorrect operation mode.This status is returned + * when GET_PARAM is called in non FTM Mode. + * 1 - Inactive mode -- Port is not yet started. + * 2 - Wait state. wait_time_ms has not yet elapsed + * 3 - In progress state. ftm_time_ms has not yet elapsed. + * 4 - Success. + * 5 - Failed. + */ +} __packed; + +/* This structure is followed by 'num_ch' number of structures of + * type afe_sp_v4_channel_ex_vi_ftm_params. + */ +struct afe_sp_v4_param_ex_vi_ftm_params { + uint32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_ex_vi_ftm_params ch_ex_vi_ftm_params[0]; +} __packed; + +struct afe_sp_v4_param_vi_channel_map_cfg { + int32_t num_channels; + int32_t chan_info[4]; +} __packed; + +union afe_spkr_prot_config { + struct asm_fbsp_mode_rx_cfg mode_rx_cfg; + struct asm_spkr_calib_vi_proc_cfg vi_proc_cfg; + struct asm_feedback_path_cfg feedback_path_cfg; + struct asm_mode_vi_proc_cfg mode_vi_proc_cfg; + struct afe_sp_th_vi_mode_cfg th_vi_mode_cfg; + struct afe_sp_th_vi_ftm_cfg th_vi_ftm_cfg; + struct afe_sp_th_vi_v_vali_cfg th_vi_v_vali_cfg; + struct afe_sp_ex_vi_mode_cfg ex_vi_mode_cfg; + struct afe_sp_ex_vi_ftm_cfg ex_vi_ftm_cfg; + struct afe_sp_rx_limiter_th_param limiter_th_cfg; + struct afe_sp_v4_param_op_mode v4_op_mode; + struct afe_sp_v4_param_vi_op_mode_cfg v4_vi_op_mode; + struct afe_sp_v4_param_th_vi_r0t0_cfg v4_r0t0_cfg; + struct afe_sp_v4_param_th_vi_ftm_cfg v4_th_vi_ftm_cfg; + struct afe_sp_v4_param_th_vi_v_vali_cfg v4_v_vali_cfg; + struct afe_sp_v4_param_ex_vi_mode_cfg v4_ex_vi_mode_cfg; + struct afe_sp_v4_param_ex_vi_ftm_cfg v4_ex_vi_ftm_cfg; + struct afe_sp_v4_param_vi_channel_map_cfg v4_ch_map_cfg; +} __packed; + + /* SRS TRUMEDIA start */ /* topology */ #define SRS_TRUMEDIA_TOPOLOGY_ID 0x00010D90 @@ -11702,7 +12049,7 @@ struct afe_clk_set { * for enable and disable clock. * "clk_freq_in_hz", "clk_attri", and "clk_root" * are ignored in disable clock case. - * @values  + * @values * - 0 -- Disabled * - 1 -- Enabled @tablebulletend */ diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 73a7cf872a..e6d7113f13 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -45,7 +45,8 @@ #define AFE_API_VERSION_V4 4 /* for VAD enable */ #define AFE_API_VERSION_V6 6 - +/* for Speaker Protection V4 */ +#define AFE_API_VERSION_V9 9 typedef int (*routing_cb)(int port);