summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorqctecmdr <qctecmdr@localhost>2020-11-27 22:02:37 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2020-11-27 22:02:36 -0800
commit346468d572df78d56fa0c37da11882bb39c713c3 (patch)
tree279be1a849acd1e044e82bca6182ee7943e6b1ae
parent89294b767a0e13b574bc2a687ddd88adf10204bd (diff)
parent290930211b84092b80da27ed66f11864934c0a1c (diff)
downloadmsm-extra-346468d572df78d56fa0c37da11882bb39c713c3.tar.gz
Merge "dsp: add afe function to send cps configuration"
-rw-r--r--dsp/q6afe.c102
-rw-r--r--include/dsp/apr_audio-v2.h26
-rw-r--r--include/dsp/q6afe-v2.h3
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(&param_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);