diff options
author | Vidyakumar Athota <vathota@codeaurora.org> | 2016-02-02 14:10:42 -0800 |
---|---|---|
committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 21:20:59 -0700 |
commit | a15e630662d440db1f72446482b7e2367ac1794c (patch) | |
tree | 46b84c26afeff5e7a09557b1cc7ee6185f6f41fc /sound/soc/msm | |
parent | 41a12ff0ed0f69fd6180b9c8852446d58b5a0c94 (diff) |
ASoC: msm: Add support to query speaker parameters
Add SET and GET parameter APIs to query speaker
parameters in feedback speaker protection FTM mode.
CRs-Fixed: 974621
Change-Id: I1a51e5033d7836c0c996621593cd2f4dd6982dcd
Signed-off-by: Vidyakumar Athota <vathota@codeaurora.org>
Diffstat (limited to 'sound/soc/msm')
-rw-r--r-- | sound/soc/msm/qdsp6v2/audio_cal_utils.c | 34 | ||||
-rw-r--r-- | sound/soc/msm/qdsp6v2/q6afe.c | 502 |
2 files changed, 493 insertions, 43 deletions
diff --git a/sound/soc/msm/qdsp6v2/audio_cal_utils.c b/sound/soc/msm/qdsp6v2/audio_cal_utils.c index bd142534e97c..95e62d51dc11 100644 --- a/sound/soc/msm/qdsp6v2/audio_cal_utils.c +++ b/sound/soc/msm/qdsp6v2/audio_cal_utils.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, 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 @@ -89,6 +89,22 @@ size_t get_cal_info_size(int32_t cal_type) case AFE_FB_SPKR_PROT_CAL_TYPE: size = sizeof(struct audio_cal_info_spk_prot_cfg); break; + case AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE: + /* + * Since get and set parameter structures are different in size + * use the maximum size of get and set parameter structure + */ + size = max(sizeof(struct audio_cal_info_sp_th_vi_ftm_cfg), + sizeof(struct audio_cal_info_sp_th_vi_param)); + break; + case AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE: + /* + * Since get and set parameter structures are different in size + * use the maximum size of get and set parameter structure + */ + size = max(sizeof(struct audio_cal_info_sp_ex_vi_ftm_cfg), + sizeof(struct audio_cal_info_sp_ex_vi_param)); + break; case AFE_ANC_CAL_TYPE: size = 0; break; @@ -219,6 +235,22 @@ size_t get_user_cal_type_size(int32_t cal_type) case AFE_FB_SPKR_PROT_CAL_TYPE: size = sizeof(struct audio_cal_type_fb_spk_prot_cfg); break; + case AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE: + /* + * Since get and set parameter structures are different in size + * use the maximum size of get and set parameter structure + */ + size = max(sizeof(struct audio_cal_type_sp_th_vi_ftm_cfg), + sizeof(struct audio_cal_type_sp_th_vi_param)); + break; + case AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE: + /* + * Since get and set parameter structures are different in size + * use the maximum size of get and set parameter structure + */ + size = max(sizeof(struct audio_cal_type_sp_ex_vi_ftm_cfg), + sizeof(struct audio_cal_type_sp_ex_vi_param)); + break; case AFE_ANC_CAL_TYPE: size = 0; break; diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index b53286731482..224897c199f0 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -37,26 +37,28 @@ enum { AFE_SIDETONE_CAL, AFE_TOPOLOGY_CAL, AFE_CUST_TOPOLOGY_CAL, + AFE_FB_SPKR_PROT_TH_VI_CAL, + AFE_FB_SPKR_PROT_EX_VI_CAL, MAX_AFE_CAL_TYPES }; -enum calibration_state { - CALIB_INCORRECT_OP_MODE, - CALIB_INACTIVE, - CALIB_WARMUP, - CALIB_IN_PROGRESS, - CALIB_SUCCESS, - CALIB_FAILED, - MAX_CALIB_STATE +enum fbsp_state { + FBSP_INCORRECT_OP_MODE, + FBSP_INACTIVE, + FBSP_WARMUP, + FBSP_IN_PROGRESS, + FBSP_SUCCESS, + FBSP_FAILED, + MAX_FBSP_STATE }; -static char cali_state[MAX_CALIB_STATE][50] = { - [CALIB_INCORRECT_OP_MODE] = "incorrect operation mode", - [CALIB_INACTIVE] = "port not started", - [CALIB_WARMUP] = "waiting for warmup", - [CALIB_IN_PROGRESS] = "in calibration state", - [CALIB_SUCCESS] = "success", - [CALIB_FAILED] = "failed" +static char fbsp_state[MAX_FBSP_STATE][50] = { + [FBSP_INCORRECT_OP_MODE] = "incorrect operation mode", + [FBSP_INACTIVE] = "port not started", + [FBSP_WARMUP] = "waiting for warmup", + [FBSP_IN_PROGRESS] = "in progress state", + [FBSP_SUCCESS] = "success", + [FBSP_FAILED] = "failed" }; enum { @@ -69,6 +71,12 @@ enum { QUICK_CALIB_ENABLE }; +enum { + Q6AFE_MSM_SPKR_PROCESSING = 0, + Q6AFE_MSM_SPKR_CALIBRATION, + Q6AFE_MSM_SPKR_FTM_MODE +}; + struct wlock { struct wakeup_source ws; }; @@ -99,6 +107,10 @@ struct afe_ctl { u16 dtmf_gen_rx_portid; struct audio_cal_info_spk_prot_cfg prot_cfg; struct afe_spkr_prot_calib_get_resp calib_data; + struct audio_cal_info_sp_th_vi_ftm_cfg th_ftm_cfg; + struct audio_cal_info_sp_ex_vi_ftm_cfg ex_ftm_cfg; + struct afe_sp_th_vi_get_param_resp th_vi_resp; + struct afe_sp_ex_vi_get_param_resp ex_vi_resp; int vi_tx_port; int vi_rx_port; uint32_t afe_sample_rates[AFE_MAX_PORTS]; @@ -115,9 +127,6 @@ static struct afe_ctl this_afe; #define TIMEOUT_MS 1000 #define Q6AFE_MAX_VOLUME 0x3FFF -#define Q6AFE_MSM_SPKR_PROCESSING 0 -#define Q6AFE_MSM_SPKR_CALIBRATION 1 - static int pcm_afe_instance[2]; static int proxy_afe_instance[2]; bool afe_close_done[2] = {true, true}; @@ -176,6 +185,73 @@ static void afe_callback_debug_print(struct apr_client_data *data) __func__, data->opcode, data->payload_size); } +static int32_t sp_make_afe_callback(uint32_t *payload, uint32_t payload_size) +{ + u32 param_id; + struct afe_spkr_prot_calib_get_resp *resp = + (struct afe_spkr_prot_calib_get_resp *) payload; + + if (!(&(resp->pdata))) { + pr_err("%s: Error: resp pdata is NULL\n", __func__); + return -EINVAL; + } + + param_id = resp->pdata.param_id; + if (param_id == AFE_PARAM_ID_CALIB_RES_CFG_V2) { + if (payload_size < sizeof(this_afe.calib_data)) { + pr_err("%s: Error: received size %d, calib_data size %zu\n", + __func__, payload_size, + sizeof(this_afe.calib_data)); + return -EINVAL; + } + memcpy(&this_afe.calib_data, payload, + sizeof(this_afe.calib_data)); + if (!this_afe.calib_data.status) { + atomic_set(&this_afe.state, 0); + } else { + pr_debug("%s: calib resp status: %d", __func__, + this_afe.calib_data.status); + atomic_set(&this_afe.state, -1); + } + } + if (param_id == AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS) { + if (payload_size < sizeof(this_afe.th_vi_resp)) { + pr_err("%s: Error: received size %d, th_vi_resp size %zu\n", + __func__, payload_size, + sizeof(this_afe.th_vi_resp)); + return -EINVAL; + } + memcpy(&this_afe.th_vi_resp, payload, + sizeof(this_afe.th_vi_resp)); + if (!this_afe.th_vi_resp.status) { + atomic_set(&this_afe.state, 0); + } else { + pr_debug("%s: th vi resp status: %d", __func__, + this_afe.th_vi_resp.status); + atomic_set(&this_afe.state, -1); + } + } + if (param_id == AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS) { + if (payload_size < sizeof(this_afe.ex_vi_resp)) { + pr_err("%s: Error: received size %d, ex_vi_resp size %zu\n", + __func__, payload_size, + sizeof(this_afe.ex_vi_resp)); + return -EINVAL; + } + memcpy(&this_afe.ex_vi_resp, payload, + sizeof(this_afe.ex_vi_resp)); + if (!this_afe.ex_vi_resp.status) { + atomic_set(&this_afe.state, 0); + } else { + pr_debug("%s: ex vi resp status: %d", __func__, + this_afe.ex_vi_resp.status); + atomic_set(&this_afe.state, -1); + } + } + + return 0; +} + static int32_t afe_callback(struct apr_client_data *data, void *priv) { if (!data) { @@ -216,23 +292,15 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) if (rtac_make_afe_callback(data->payload, data->payload_size)) return 0; - if ((data->payload_size < sizeof(this_afe.calib_data)) - || !payload || (data->token >= AFE_MAX_PORTS)) { + if (!payload || (data->token >= AFE_MAX_PORTS)) { pr_err("%s: Error: size %d payload %p token %d\n", __func__, data->payload_size, payload, data->token); return -EINVAL; } - memcpy(&this_afe.calib_data, payload, - sizeof(this_afe.calib_data)); - if (!this_afe.calib_data.status) { - atomic_set(&this_afe.state, 0); - pr_err("%s: rest = %d %d state = %s\n", __func__ - , this_afe.calib_data.res_cfg.r0_cali_q24[SP_V2_SPKR_1], - this_afe.calib_data.res_cfg.r0_cali_q24[SP_V2_SPKR_2], - cali_state[this_afe.calib_data.res_cfg.th_vi_ca_state]); - } else - atomic_set(&this_afe.state, -1); + if (sp_make_afe_callback(data->payload, data->payload_size)) + return -EINVAL; + wake_up(&this_afe.wait[data->token]); } else if (data->payload_size) { uint32_t *payload; @@ -839,8 +907,17 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, this_afe.vi_rx_port = dst_port; config.pdata.module_id = AFE_MODULE_FEEDBACK; break; + /* + * AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2 is same as + * AFE_PARAM_ID_SP_V2_TH_VI_MODE_CFG + */ case AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2: - config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2; + case AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG: + config.pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; + break; + case AFE_PARAM_ID_SP_V2_EX_VI_MODE_CFG: + case AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG: + config.pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; break; default: pr_err("%s: default case 0x%x\n", __func__, param_id); @@ -897,14 +974,14 @@ static void afe_send_cal_spkr_prot_tx(int port_id) { union afe_spkr_prot_config afe_spk_config; - if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL) - goto done; + 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) + 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)) { - afe_spk_config.mode_rx_cfg.minor_version = 1; if (this_afe.prot_cfg.mode == MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) { afe_spk_config.vi_proc_cfg.operation_mode = @@ -913,8 +990,12 @@ static void afe_send_cal_spkr_prot_tx(int port_id) this_afe.prot_cfg.quick_calib_flag; } else { afe_spk_config.vi_proc_cfg.operation_mode = - Q6AFE_MSM_SPKR_PROCESSING; + Q6AFE_MSM_SPKR_PROCESSING; } + + if (this_afe.th_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) + afe_spk_config.vi_proc_cfg.operation_mode = + Q6AFE_MSM_SPKR_FTM_MODE; afe_spk_config.vi_proc_cfg.minor_version = 1; afe_spk_config.vi_proc_cfg.r0_cali_q24[SP_V2_SPKR_1] = (uint32_t) this_afe.prot_cfg.r0[SP_V2_SPKR_1]; @@ -946,8 +1027,57 @@ static void afe_send_cal_spkr_prot_tx(int port_id) __func__); } mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); -done: - return; + + 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)) { + afe_spk_config.th_vi_ftm_cfg.minor_version = 1; + afe_spk_config.th_vi_ftm_cfg.wait_time_ms[SP_V2_SPKR_1] = + this_afe.th_ftm_cfg.wait_time[SP_V2_SPKR_1]; + afe_spk_config.th_vi_ftm_cfg.wait_time_ms[SP_V2_SPKR_2] = + this_afe.th_ftm_cfg.wait_time[SP_V2_SPKR_2]; + afe_spk_config.th_vi_ftm_cfg.ftm_time_ms[SP_V2_SPKR_1] = + this_afe.th_ftm_cfg.ftm_time[SP_V2_SPKR_1]; + afe_spk_config.th_vi_ftm_cfg.ftm_time_ms[SP_V2_SPKR_2] = + 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)) + pr_err("%s: th vi ftm cfg failed\n", __func__); + this_afe.th_ftm_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)) { + afe_spk_config.ex_vi_mode_cfg.minor_version = 1; + afe_spk_config.ex_vi_mode_cfg.operation_mode = + 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)) + pr_err("%s: ex vi mode cfg failed\n", __func__); + + afe_spk_config.ex_vi_ftm_cfg.minor_version = 1; + afe_spk_config.ex_vi_ftm_cfg.wait_time_ms[SP_V2_SPKR_1] = + this_afe.ex_ftm_cfg.wait_time[SP_V2_SPKR_1]; + afe_spk_config.ex_vi_ftm_cfg.wait_time_ms[SP_V2_SPKR_2] = + this_afe.ex_ftm_cfg.wait_time[SP_V2_SPKR_2]; + afe_spk_config.ex_vi_ftm_cfg.ftm_time_ms[SP_V2_SPKR_1] = + this_afe.ex_ftm_cfg.ftm_time[SP_V2_SPKR_1]; + afe_spk_config.ex_vi_ftm_cfg.ftm_time_ms[SP_V2_SPKR_2] = + this_afe.ex_ftm_cfg.ftm_time[SP_V2_SPKR_2]; + + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG, + &afe_spk_config)) + pr_err("%s: ex vi ftm cfg failed\n", __func__); + this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); + } static void afe_send_cal_spkr_prot_rx(int port_id) @@ -5134,6 +5264,155 @@ int q6afe_check_osr_clk_freq(u32 freq) return ret; } +int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) +{ + int ret = -EINVAL; + int index = 0, port = SLIMBUS_4_TX; + + if (!th_vi) { + pr_err("%s: Invalid params\n", __func__); + goto done; + } + if (this_afe.vi_tx_port != -1) + port = this_afe.vi_tx_port; + + ret = q6audio_validate_port(port); + if (ret < 0) { + pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret); + goto done; + } + index = q6audio_get_port_index(port); + th_vi->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + th_vi->hdr.pkt_size = sizeof(*th_vi); + th_vi->hdr.src_port = 0; + th_vi->hdr.dest_port = 0; + th_vi->hdr.token = index; + th_vi->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; + th_vi->get_param.mem_map_handle = 0; + th_vi->get_param.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; + th_vi->get_param.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS; + th_vi->get_param.payload_address_lsw = 0; + th_vi->get_param.payload_address_msw = 0; + th_vi->get_param.payload_size = sizeof(*th_vi) + - sizeof(th_vi->get_param) - sizeof(th_vi->hdr); + th_vi->get_param.port_id = q6audio_get_port_id(port); + th_vi->pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; + th_vi->pdata.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS; + th_vi->pdata.param_size = sizeof(th_vi->param); + atomic_set(&this_afe.status, 0); + atomic_set(&this_afe.state, 1); + ret = apr_send_pkt(this_afe.apr, (uint32_t *)th_vi); + if (ret < 0) { + pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", + __func__, port, th_vi->get_param.param_id, ret); + goto done; + } + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto done; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code(atomic_read(&this_afe.status)); + goto done; + } + memcpy(&th_vi->param , &this_afe.th_vi_resp.param, + sizeof(this_afe.th_vi_resp.param)); + pr_debug("%s: DC resistance %d %d temp %d %d status %d %d\n", + __func__, th_vi->param.dc_res_q24[SP_V2_SPKR_1], + th_vi->param.dc_res_q24[SP_V2_SPKR_2], + th_vi->param.temp_q22[SP_V2_SPKR_1], + th_vi->param.temp_q22[SP_V2_SPKR_2], + th_vi->param.status[SP_V2_SPKR_1], + th_vi->param.status[SP_V2_SPKR_2]); + ret = 0; +done: + return ret; +} + +int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) +{ + int ret = -EINVAL; + int index = 0, port = SLIMBUS_4_TX; + + if (!ex_vi) { + pr_err("%s: Invalid params\n", __func__); + goto done; + } + if (this_afe.vi_tx_port != -1) + port = this_afe.vi_tx_port; + + ret = q6audio_validate_port(port); + if (ret < 0) { + pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret); + goto done; + } + + index = q6audio_get_port_index(port); + ex_vi->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + ex_vi->hdr.pkt_size = sizeof(*ex_vi); + ex_vi->hdr.src_port = 0; + ex_vi->hdr.dest_port = 0; + ex_vi->hdr.token = index; + ex_vi->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; + ex_vi->get_param.mem_map_handle = 0; + ex_vi->get_param.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; + ex_vi->get_param.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS; + ex_vi->get_param.payload_address_lsw = 0; + ex_vi->get_param.payload_address_msw = 0; + ex_vi->get_param.payload_size = sizeof(*ex_vi) + - sizeof(ex_vi->get_param) - sizeof(ex_vi->hdr); + ex_vi->get_param.port_id = q6audio_get_port_id(port); + ex_vi->pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; + ex_vi->pdata.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS; + ex_vi->pdata.param_size = sizeof(ex_vi->param); + atomic_set(&this_afe.status, 0); + atomic_set(&this_afe.state, 1); + ret = apr_send_pkt(this_afe.apr, (uint32_t *)ex_vi); + if (ret < 0) { + pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", + __func__, port, ex_vi->get_param.param_id, ret); + goto done; + } + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto done; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code(atomic_read(&this_afe.status)); + goto done; + } + memcpy(&ex_vi->param , &this_afe.ex_vi_resp.param, + sizeof(this_afe.ex_vi_resp.param)); + pr_debug("%s: freq %d %d resistance %d %d qfactor %d %d state %d %d\n", + __func__, ex_vi->param.freq_q20[SP_V2_SPKR_1], + ex_vi->param.freq_q20[SP_V2_SPKR_2], + ex_vi->param.resis_q24[SP_V2_SPKR_1], + ex_vi->param.resis_q24[SP_V2_SPKR_2], + ex_vi->param.qmct_q24[SP_V2_SPKR_1], + ex_vi->param.qmct_q24[SP_V2_SPKR_2], + ex_vi->param.status[SP_V2_SPKR_1], + ex_vi->param.status[SP_V2_SPKR_2]); + ret = 0; +done: + return ret; +} + int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) { int ret = -EINVAL; @@ -5205,7 +5484,7 @@ int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) memcpy(&calib_resp->res_cfg , &this_afe.calib_data.res_cfg, sizeof(this_afe.calib_data.res_cfg)); pr_info("%s: state %s resistance %d %d\n", __func__, - cali_state[calib_resp->res_cfg.th_vi_ca_state], + 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; @@ -5299,9 +5578,11 @@ int afe_alloc_cal(int32_t cal_type, size_t data_size, { int ret = 0; int cal_index; - pr_debug("%s:\n", __func__); cal_index = get_cal_type_index(cal_type); + pr_debug("%s: cal_type = %d cal_index = %d\n", + __func__, cal_type, cal_index); + if (cal_index < 0) { pr_err("%s: could not get cal index %d!\n", __func__, cal_index); @@ -5468,6 +5749,46 @@ done: return ret; } +static int afe_set_cal_sp_th_vi_ftm_cfg(int32_t cal_type, size_t data_size, + void *data) +{ + int ret = 0; + struct audio_cal_type_sp_th_vi_ftm_cfg *cal_data = data; + + if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL || + cal_data == NULL || + data_size != sizeof(*cal_data)) + goto done; + + pr_debug("%s: cal_type = %d\n", __func__, cal_type); + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + memcpy(&this_afe.th_ftm_cfg, &cal_data->cal_info, + sizeof(this_afe.th_ftm_cfg)); + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); +done: + return ret; +} + +static int afe_set_cal_sp_ex_vi_ftm_cfg(int32_t cal_type, size_t data_size, + void *data) +{ + int ret = 0; + struct audio_cal_type_sp_ex_vi_ftm_cfg *cal_data = data; + + if (this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL || + cal_data == NULL || + data_size != sizeof(*cal_data)) + goto done; + + pr_debug("%s: cal_type = %d\n", __func__, cal_type); + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); + memcpy(&this_afe.ex_ftm_cfg, &cal_data->cal_info, + sizeof(this_afe.ex_ftm_cfg)); + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); +done: + return ret; +} + static int afe_set_cal_fb_spkr_prot(int32_t cal_type, size_t data_size, void *data) { @@ -5487,11 +5808,94 @@ static int afe_set_cal_fb_spkr_prot(int32_t cal_type, size_t data_size, mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); memcpy(&this_afe.prot_cfg, &cal_data->cal_info, sizeof(this_afe.prot_cfg)); + this_afe.th_ftm_cfg.mode = this_afe.prot_cfg.mode; + this_afe.ex_ftm_cfg.mode = this_afe.prot_cfg.mode; mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); done: return ret; } +static int afe_get_cal_sp_th_vi_ftm_param(int32_t cal_type, size_t data_size, + void *data) +{ + int i, ret = 0; + struct audio_cal_type_sp_th_vi_param *cal_data = data; + struct afe_sp_th_vi_get_param th_vi; + + pr_debug("%s: cal_type = %d\n", __func__, cal_type); + if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL || + cal_data == NULL || + data_size != sizeof(*cal_data)) + goto done; + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + cal_data->cal_info.status[i] = -EINVAL; + 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]; + } + } + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_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) +{ + int i, ret = 0; + struct audio_cal_type_sp_ex_vi_param *cal_data = data; + struct afe_sp_ex_vi_get_param ex_vi; + + pr_debug("%s: cal_type = %d\n", __func__, cal_type); + if (this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL || + cal_data == NULL || + data_size != sizeof(*cal_data)) + goto done; + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_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.freq_q20[i] = -1; + cal_data->cal_info.resis_q24[i] = -1; + cal_data->cal_info.qmct_q24[i] = -1; + } + if (!afe_get_sp_ex_vi_ftm_data(&ex_vi)) { + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + pr_debug("%s: ftm param status = %d\n", + __func__, ex_vi.param.status[i]); + if (ex_vi.param.status[i] == FBSP_IN_PROGRESS) { + cal_data->cal_info.status[i] = -EAGAIN; + } else if (ex_vi.param.status[i] == FBSP_SUCCESS) { + cal_data->cal_info.status[i] = 0; + cal_data->cal_info.freq_q20[i] = + ex_vi.param.freq_q20[i]; + cal_data->cal_info.resis_q24[i] = + ex_vi.param.resis_q24[i]; + cal_data->cal_info.qmct_q24[i] = + ex_vi.param.qmct_q24[i]; + } + } + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); +done: + return ret; +} + static int afe_get_cal_fb_spkr_prot(int32_t cal_type, size_t data_size, void *data) { @@ -5522,10 +5926,10 @@ static int afe_get_cal_fb_spkr_prot(int32_t cal_type, size_t data_size, 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 == - CALIB_IN_PROGRESS) + FBSP_IN_PROGRESS) cal_data->cal_info.status = -EAGAIN; else if (calib_resp.res_cfg.th_vi_ca_state == - CALIB_SUCCESS) { + 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]; @@ -5547,6 +5951,8 @@ static int afe_get_cal_fb_spkr_prot(int32_t cal_type, size_t data_size, cal_data->cal_info.r0[SP_V2_SPKR_1] = -1; cal_data->cal_info.r0[SP_V2_SPKR_2] = -1; } + this_afe.th_ftm_cfg.mode = this_afe.prot_cfg.mode; + this_afe.ex_ftm_cfg.mode = this_afe.prot_cfg.mode; mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); __pm_relax(&wl.ws); done: @@ -5677,6 +6083,16 @@ static int afe_init_cal_data(void) afe_set_cal, NULL, NULL} }, {afe_map_cal_data, afe_unmap_cal_data, cal_utils_match_buf_num} }, + + {{AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE, + {NULL, NULL, NULL, afe_set_cal_sp_th_vi_ftm_cfg, + afe_get_cal_sp_th_vi_ftm_param, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE, + {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} }, }; pr_debug("%s:\n", __func__); @@ -5778,6 +6194,8 @@ static int __init afe_init(void) this_afe.vi_tx_port = -1; this_afe.vi_rx_port = -1; this_afe.prot_cfg.mode = MSM_SPKR_PROT_DISABLED; + this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; + this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; mutex_init(&this_afe.afe_cmd_lock); for (i = 0; i < AFE_MAX_PORTS; i++) { this_afe.afe_cal_mode[i] = AFE_CAL_MODE_DEFAULT; |