summaryrefslogtreecommitdiff
path: root/sound/soc
diff options
context:
space:
mode:
authorVidyakumar Athota <vathota@codeaurora.org>2016-02-02 14:10:42 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:20:59 -0700
commita15e630662d440db1f72446482b7e2367ac1794c (patch)
tree46b84c26afeff5e7a09557b1cc7ee6185f6f41fc /sound/soc
parent41a12ff0ed0f69fd6180b9c8852446d58b5a0c94 (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')
-rw-r--r--sound/soc/msm/qdsp6v2/audio_cal_utils.c34
-rw-r--r--sound/soc/msm/qdsp6v2/q6afe.c502
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;