diff options
author | qctecmdr <qctecmdr@localhost> | 2020-11-27 22:02:37 -0800 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2020-11-27 22:02:36 -0800 |
commit | 346468d572df78d56fa0c37da11882bb39c713c3 (patch) | |
tree | 279be1a849acd1e044e82bca6182ee7943e6b1ae | |
parent | 89294b767a0e13b574bc2a687ddd88adf10204bd (diff) | |
parent | 290930211b84092b80da27ed66f11864934c0a1c (diff) | |
download | msm-extra-346468d572df78d56fa0c37da11882bb39c713c3.tar.gz |
Merge "dsp: add afe function to send cps configuration"
-rw-r--r-- | dsp/q6afe.c | 102 | ||||
-rw-r--r-- | include/dsp/apr_audio-v2.h | 26 | ||||
-rw-r--r-- | include/dsp/q6afe-v2.h | 3 |
3 files changed, 131 insertions, 0 deletions
diff --git a/dsp/q6afe.c b/dsp/q6afe.c index e90d7c0c..bfcbfced 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -247,6 +247,8 @@ struct afe_ctl { uint32_t initial_cal; uint32_t v_vali_flag; uint32_t num_spkrs; + uint32_t cps_ch_mask; + struct afe_cps_hw_intf_cfg *cps_config; }; struct afe_clkinfo_per_port { @@ -2173,6 +2175,70 @@ fail_cmd: return ret; } +static int afe_send_cps_config(int src_port) +{ + int i = 0; + struct param_hdr_v3 param_info; + int ret = -EINVAL; + u8 *packed_payload = NULL; + int cpy_size = 0; + int ch_copied = 0; + size_t param_size = 0; + + if ((-1 == this_afe.vi_tx_port) || (!this_afe.cps_ch_mask) || + (!this_afe.cps_config)) { + pr_err("%s: speaker prot not configured for 0x%x\n", __func__, + src_port); + return -EINVAL; + } + + param_size = sizeof(struct afe_cps_hw_intf_cfg) - + sizeof(this_afe.cps_config->spkr_dep_cfg) + + (sizeof(struct lpass_swr_spkr_dep_cfg_t) + * this_afe.num_spkrs); + + this_afe.cps_config->hw_reg_cfg.num_spkr = this_afe.num_spkrs; + packed_payload = kzalloc(param_size, GFP_KERNEL); + if (packed_payload == NULL) + return -ENOMEM; + + cpy_size = sizeof(struct afe_cps_hw_intf_cfg) - + sizeof(this_afe.cps_config->spkr_dep_cfg); + memcpy(packed_payload, this_afe.cps_config, cpy_size); + + while (ch_copied < this_afe.num_spkrs) { + if (!(this_afe.cps_ch_mask & (1 << i))) { + i++; + continue; + } + + memcpy(packed_payload + cpy_size, + &this_afe.cps_config->spkr_dep_cfg[i], + sizeof(struct lpass_swr_spkr_dep_cfg_t)); + cpy_size += sizeof(struct lpass_swr_spkr_dep_cfg_t); + ch_copied++; + i++; + } + + memset(¶m_info, 0, sizeof(param_info)); + param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_RX; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = AFE_PARAM_ID_CPS_LPASS_HW_INTF_CFG; + param_info.param_size = param_size; + + ret = q6afe_pack_and_set_param_in_band(src_port, + q6audio_get_port_index(src_port), + param_info, packed_payload); + if (ret) + pr_err("%s: port = 0x%x param = 0x%x failed %d\n", __func__, + src_port, param_info.param_id, ret); + + pr_debug("%s: config.pdata.param_id 0x%x status %d 0x%x\n", __func__, + param_info.param_id, ret, src_port); + kfree(packed_payload); + return ret; +} + static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, union afe_spkr_prot_config *prot_config, uint32_t param_size) { @@ -5268,6 +5334,11 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, afe_send_hw_delay(port_id, rate); } + if ((this_afe.cps_config) && + (this_afe.vi_rx_port == port_id)) { + afe_send_cps_config(port_id); + } + /* Start SW MAD module */ mad_type = afe_port_get_mad_type(port_id); pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, @@ -10811,3 +10882,34 @@ done: return ret; } EXPORT_SYMBOL(afe_unvote_lpass_core_hw); + +/** + * afe_set_cps_config - + * to set cps speaker protection configuration + * + * @src_port: source port to send configuration to + * @cps_config: cps speaker protection v4 configuration + * @ch_mask: channel mask + * + */ +void afe_set_cps_config(int src_port, + struct afe_cps_hw_intf_cfg *cps_config, + u32 ch_mask) +{ + this_afe.cps_config = NULL; + this_afe.cps_ch_mask = 0; + + if (!cps_config) { + pr_err("%s: cps config is NULL\n", __func__); + return; + } + + if (q6audio_validate_port(src_port) < 0) { + pr_err("%s: Invalid src port 0x%x\n", __func__, src_port); + return; + } + + this_afe.cps_ch_mask = ch_mask; + this_afe.cps_config = cps_config; +} +EXPORT_SYMBOL(afe_set_cps_config); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index eed5652f..dc51307a 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -10,6 +10,9 @@ #include <ipc/apr.h> #include <linux/msm_audio.h> +/* number of threshold levels in speaker protection module */ +#define MAX_CPS_LEVELS 3 + /* size of header needed for passing data out of band */ #define APR_CMD_OB_HDR_SZ 12 @@ -2364,6 +2367,28 @@ int16_t excursionf[AFE_SPKR_PROT_EXCURSIONF_LEN]; */ } __packed; +struct lpass_swr_spkr_dep_cfg_t { + uint32_t vbatt_pkd_reg_addr; + uint32_t temp_pkd_reg_addr; + uint32_t value_normal_thrsd[MAX_CPS_LEVELS]; + uint32_t value_low1_thrsd[MAX_CPS_LEVELS]; + uint32_t value_low2_thrsd[MAX_CPS_LEVELS]; +} __packed; + +struct lpass_swr_hw_reg_cfg_t { + uint32_t lpass_wr_cmd_reg_phy_addr; + uint32_t lpass_rd_cmd_reg_phy_addr; + uint32_t lpass_rd_fifo_reg_phy_addr; + uint32_t vbatt_lower1_threshold; + uint32_t vbatt_lower2_threshold; + uint32_t num_spkr; +} __packed; + +struct afe_cps_hw_intf_cfg { + uint32_t lpass_hw_intf_cfg_mode; + struct lpass_swr_hw_reg_cfg_t hw_reg_cfg; + struct lpass_swr_spkr_dep_cfg_t *spkr_dep_cfg; +} __packed; #define AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER 0x000100E0 @@ -10784,6 +10809,7 @@ struct cmd_set_topologies { #define AFE_PARAM_ID_FBSP_MODE_RX_CFG 0x0001021D #define AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG 0x00010260 #define AFE_PARAM_ID_SP_RX_TMAX_XMAX_LOGGING 0x000102BC +#define AFE_PARAM_ID_CPS_LPASS_HW_INTF_CFG 0x000102EF struct asm_fbsp_mode_rx_cfg { uint32_t minor_version; diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 8b82069a..310de65c 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -432,6 +432,9 @@ int afe_pseudo_port_start_nowait(u16 port_id); int afe_pseudo_port_stop_nowait(u16 port_id); int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg); int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg); +void afe_set_cps_config(int src_port, + struct afe_cps_hw_intf_cfg *cps_config, + u32 ch_mask); int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg); int afe_set_digital_codec_core_clock(u16 port_id, struct afe_digital_clk_cfg *cfg); |