Merge "dsp: Add support to dynamically load and unload BT modules"
diff --git a/asoc/bengal.c b/asoc/bengal.c
index cbd309e..15c2104 100644
--- a/asoc/bengal.c
+++ b/asoc/bengal.c
@@ -6370,7 +6370,7 @@
ret = -EINVAL;
goto err;
}
- if (soc_find_component(wsa_of_node, NULL)) {
+ if (soc_find_component_locked(wsa_of_node, NULL)) {
/* WSA device registered with ALSA core */
wsa881x_dev_info[found].of_node = wsa_of_node;
wsa881x_dev_info[found].index = i;
@@ -6467,7 +6467,7 @@
ret = -EINVAL;
goto err;
}
- if (soc_find_component(aux_codec_of_node, NULL)) {
+ if (soc_find_component_locked(aux_codec_of_node, NULL)) {
/* AUX codec registered with ALSA core */
aux_cdc_dev_info[codecs_found].of_node =
aux_codec_of_node;
diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c
index 79a95c0..3f6292c 100644
--- a/asoc/codecs/wcd938x/wcd938x.c
+++ b/asoc/codecs/wcd938x/wcd938x.c
@@ -3722,7 +3722,7 @@
}
static const struct of_device_id wcd938x_dt_match[] = {
- { .compatible = "qcom,wcd938x-codec" },
+ { .compatible = "qcom,wcd938x-codec", .data = "wcd938x"},
{}
};
diff --git a/asoc/kona-port-config.h b/asoc/kona-port-config.h
index 723c94a..6ab1d29 100644
--- a/asoc/kona-port-config.h
+++ b/asoc/kona-port-config.h
@@ -59,6 +59,14 @@
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2}, /* TX4 */
};
+static struct port_params tx_frame_params_wcd937x[SWR_MSTR_PORT_LEN] = {
+ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
+ {3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
+ {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
+ {3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
+};
+
static struct swr_mstr_port_map sm_port_map[] = {
{TX_MACRO, SWR_UC0, tx_frame_params_default},
{RX_MACRO, SWR_UC0, rx_frame_params_default},
@@ -73,4 +81,11 @@
{WSA_MACRO, SWR_UC0, wsa_frame_params_default},
};
+static struct swr_mstr_port_map sm_port_map_wcd937x[] = {
+ {TX_MACRO, SWR_UC0, tx_frame_params_wcd937x},
+ {RX_MACRO, SWR_UC0, rx_frame_params_default},
+ {RX_MACRO, SWR_UC1, rx_frame_params_dsd},
+ {WSA_MACRO, SWR_UC0, wsa_frame_params_default},
+};
+
#endif /* _KONA_PORT_CONFIG */
diff --git a/asoc/kona.c b/asoc/kona.c
index 33c24f1..02b9e01 100644
--- a/asoc/kona.c
+++ b/asoc/kona.c
@@ -33,6 +33,8 @@
#include "codecs/wsa881x.h"
#include "codecs/wsa883x/wsa883x.h"
#include "codecs/wcd938x/wcd938x.h"
+#include "codecs/wcd937x/wcd937x-mbhc.h"
+#include "codecs/wcd937x/wcd937x.h"
#include "codecs/bolero/bolero-cdc.h"
#include <dt-bindings/sound/audio-codec-port-types.h>
#include "codecs/bolero/wsa-macro.h"
@@ -860,6 +862,23 @@
static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc85_dma_rx_5_sample_rate,
cdc_dma_sample_rate_text);
+/* WCD937x */
+static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_sample_rate,
+ cdc_dma_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_sample_rate,
+ cdc_dma_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_sample_rate,
+ cdc_dma_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_sample_rate,
+ cdc_dma_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_sample_rate,
+ cdc_dma_sample_rate_text);
+
static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text);
static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate,
@@ -3685,6 +3704,39 @@
cdc_dma_rx_sample_rate_put),
};
+static const struct snd_kcontrol_new msm_int_wcd937x_snd_controls[] = {
+ SOC_ENUM_EXT("RX_CDC_DMA_RX_0 Format", rx_cdc_dma_rx_0_format,
+ cdc_dma_rx_format_get, cdc_dma_rx_format_put),
+ SOC_ENUM_EXT("RX_CDC_DMA_RX_1 Format", rx_cdc_dma_rx_1_format,
+ cdc_dma_rx_format_get, cdc_dma_rx_format_put),
+ SOC_ENUM_EXT("RX_CDC_DMA_RX_2 Format", rx_cdc_dma_rx_2_format,
+ cdc_dma_rx_format_get, cdc_dma_rx_format_put),
+ SOC_ENUM_EXT("RX_CDC_DMA_RX_3 Format", rx_cdc_dma_rx_3_format,
+ cdc_dma_rx_format_get, cdc_dma_rx_format_put),
+ SOC_ENUM_EXT("RX_CDC_DMA_RX_5 Format", rx_cdc_dma_rx_5_format,
+ cdc_dma_rx_format_get, cdc_dma_rx_format_put),
+ SOC_ENUM_EXT("RX_CDC_DMA_RX_0 SampleRate",
+ rx_cdc_dma_rx_0_sample_rate,
+ cdc_dma_rx_sample_rate_get,
+ cdc_dma_rx_sample_rate_put),
+ SOC_ENUM_EXT("RX_CDC_DMA_RX_1 SampleRate",
+ rx_cdc_dma_rx_1_sample_rate,
+ cdc_dma_rx_sample_rate_get,
+ cdc_dma_rx_sample_rate_put),
+ SOC_ENUM_EXT("RX_CDC_DMA_RX_2 SampleRate",
+ rx_cdc_dma_rx_2_sample_rate,
+ cdc_dma_rx_sample_rate_get,
+ cdc_dma_rx_sample_rate_put),
+ SOC_ENUM_EXT("RX_CDC_DMA_RX_3 SampleRate",
+ rx_cdc_dma_rx_3_sample_rate,
+ cdc_dma_rx_sample_rate_get,
+ cdc_dma_rx_sample_rate_put),
+ SOC_ENUM_EXT("RX_CDC_DMA_RX_5 SampleRate",
+ rx_cdc_dma_rx_5_sample_rate,
+ cdc_dma_rx_sample_rate_get,
+ cdc_dma_rx_sample_rate_put),
+};
+
static const struct snd_kcontrol_new msm_common_snd_controls[] = {
SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate,
usb_audio_rx_sample_rate_get,
@@ -5371,6 +5423,9 @@
struct snd_card *card;
struct snd_info_entry *entry;
struct snd_soc_component *aux_comp;
+ struct platform_device *pdev = NULL;
+ int i = 0;
+ char *data = NULL;
struct msm_asoc_mach_data *pdata =
snd_soc_card_get_drvdata(rtd->card);
@@ -5447,18 +5502,52 @@
WSA_MACRO_GAIN_OFFSET_M1P5_DB);
}
}
- if (pdata->lito_v2_enabled) {
- /*
- * Enable tx data line3 for saipan version v2 amd
- * write corresponding lpi register.
- */
- bolero_set_port_map(component, ARRAY_SIZE(sm_port_map_v2),
- sm_port_map_v2);
- } else {
- bolero_set_port_map(component, ARRAY_SIZE(sm_port_map),
- sm_port_map);
+ }
+
+ for (i = 0; i < rtd->card->num_aux_devs; i++)
+ {
+ if (msm_aux_dev[i].name != NULL ) {
+ if (strstr(msm_aux_dev[i].name, "wsa"))
+ continue;
+ }
+
+ if (msm_aux_dev[i].codec_of_node) {
+ pdev = of_find_device_by_node(
+ msm_aux_dev[i].codec_of_node);
+
+ if (pdev)
+ data = (char*) of_device_get_match_data(
+ &pdev->dev);
+ if (data != NULL) {
+ if (!strncmp(data, "wcd937x",
+ sizeof("wcd937x"))) {
+ bolero_set_port_map(component,
+ ARRAY_SIZE(sm_port_map_wcd937x),
+ sm_port_map_wcd937x);
+ break;
+ } else if (!strncmp( data, "wcd938x",
+ sizeof("wcd938x"))) {
+ if (pdata->lito_v2_enabled) {
+ /*
+ * Enable tx data line3 for
+ * saipan version v2 and
+ * write corresponding
+ * lpi register.
+ */
+ bolero_set_port_map(component,
+ ARRAY_SIZE(sm_port_map_v2),
+ sm_port_map_v2);
+ } else {
+ bolero_set_port_map(component,
+ ARRAY_SIZE(sm_port_map),
+ sm_port_map);
+ }
+ break;
+ }
+ }
}
}
+
card = rtd->card->snd_card;
if (!pdata->codec_root) {
entry = snd_info_create_subdir(card->module, "codecs",
@@ -7659,18 +7748,24 @@
}
pdata->codec_root = entry;
}
- wcd938x_info_create_codec_entry(pdata->codec_root, component);
-
- codec_variant = wcd938x_get_codec_variant(component);
- dev_dbg(component->dev, "%s: variant %d\n", __func__, codec_variant);
- if (codec_variant == WCD9380)
+ if (!strncmp(component->driver->name, "wcd937x", 7)) {
+ wcd937x_info_create_codec_entry(pdata->codec_root, component);
ret = snd_soc_add_component_controls(component,
- msm_int_wcd9380_snd_controls,
- ARRAY_SIZE(msm_int_wcd9380_snd_controls));
- else if (codec_variant == WCD9385)
- ret = snd_soc_add_component_controls(component,
- msm_int_wcd9385_snd_controls,
- ARRAY_SIZE(msm_int_wcd9385_snd_controls));
+ msm_int_wcd937x_snd_controls,
+ ARRAY_SIZE(msm_int_wcd937x_snd_controls));
+ } else {
+ wcd938x_info_create_codec_entry(pdata->codec_root, component);
+ codec_variant = wcd938x_get_codec_variant(component);
+ dev_dbg(component->dev, "%s: variant %d\n", __func__, codec_variant);
+ if (codec_variant == WCD9380)
+ ret = snd_soc_add_component_controls(component,
+ msm_int_wcd9380_snd_controls,
+ ARRAY_SIZE(msm_int_wcd9380_snd_controls));
+ else if (codec_variant == WCD9385)
+ ret = snd_soc_add_component_controls(component,
+ msm_int_wcd9385_snd_controls,
+ ARRAY_SIZE(msm_int_wcd9385_snd_controls));
+ }
if (ret < 0) {
dev_err(component->dev, "%s: add codec specific snd controls failed: %d\n",
@@ -7683,7 +7778,10 @@
if (!mbhc_calibration)
return -ENOMEM;
wcd_mbhc_cfg.calibration = mbhc_calibration;
- ret = wcd938x_mbhc_hs_detect(component, &wcd_mbhc_cfg);
+ if (!strncmp(component->driver->name, "wcd937x", 7))
+ ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg);
+ else
+ ret = wcd938x_mbhc_hs_detect(component, &wcd_mbhc_cfg);
if (ret) {
dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n",
__func__, ret);
@@ -7798,7 +7896,7 @@
ret = -EINVAL;
goto err;
}
- if (soc_find_component(wsa_of_node, NULL)) {
+ if (soc_find_component_locked(wsa_of_node, NULL)) {
/* WSA device registered with ALSA core */
wsa881x_dev_info[found].of_node = wsa_of_node;
wsa881x_dev_info[found].index = i;
@@ -7895,7 +7993,7 @@
ret = -EINVAL;
goto err;
}
- if (soc_find_component(aux_codec_of_node, NULL)) {
+ if (soc_find_component_locked(aux_codec_of_node, NULL)) {
/* AUX codec registered with ALSA core */
aux_cdc_dev_info[codecs_found].of_node =
aux_codec_of_node;
diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c
index fab5186..8e0d7e0 100644
--- a/dsp/audio_cal_utils.c
+++ b/dsp/audio_cal_utils.c
@@ -109,6 +109,9 @@
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 = 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/audio_notifier.c b/dsp/audio_notifier.c
index 56cfa31..7a8249d 100644
--- a/dsp/audio_notifier.c
+++ b/dsp/audio_notifier.c
@@ -606,6 +606,7 @@
return 0;
}
+#ifdef CONFIG_MSM_QDSP6_PDR
static int __init audio_notifier_init(void)
{
int ret;
@@ -624,6 +625,17 @@
return 0;
}
+#else
+static int __init audio_notifier_init(void)
+{
+ audio_notifier_subsys_init();
+ audio_notifier_disable_service(AUDIO_NOTIFIER_PDR_SERVICE);
+
+ audio_notifier_late_init();
+
+ return 0;
+}
+#endif
module_init(audio_notifier_init);
static void __exit audio_notifier_exit(void)
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index 567f7fe..3d76e48 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -54,6 +54,7 @@
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
};
@@ -113,6 +114,11 @@
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;
};
@@ -166,6 +172,10 @@
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;
@@ -578,6 +588,7 @@
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));
@@ -638,16 +649,79 @@
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;
}
@@ -1012,6 +1086,22 @@
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,
@@ -2056,7 +2146,7 @@
}
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;
@@ -2083,6 +2173,9 @@
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;
@@ -2102,6 +2195,15 @@
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;
@@ -2109,7 +2211,7 @@
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),
@@ -2124,7 +2226,7 @@
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;
@@ -2146,7 +2248,7 @@
}
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;
@@ -2170,10 +2272,260 @@
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;
+ struct afe_sp_v4_channel_r0t0 *ch_r0t0_cfg;
+ struct afe_sp_v4_param_th_vi_ftm_cfg *th_vi_ftm_cfg;
+ struct afe_sp_v4_channel_ftm_cfg *ch_ftm_cfg;
+ struct afe_sp_v4_param_th_vi_v_vali_cfg *th_vi_v_vali_cfg;
+ struct afe_sp_v4_channel_v_vali_cfg *ch_v_vali_cfg;
+ struct afe_sp_v4_param_ex_vi_ftm_cfg *ex_vi_ftm_cfg;
+ struct afe_sp_v4_channel_ex_vi_ftm *ch_ex_vi_ftm_cfg;
+
+ 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)
@@ -2228,7 +2580,7 @@
}
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__);
}
@@ -2248,8 +2600,9 @@
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 ==
@@ -2267,7 +2620,8 @@
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;
@@ -2282,7 +2636,8 @@
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;
@@ -2297,7 +2652,8 @@
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;
}
@@ -2306,15 +2662,50 @@
/* 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;
@@ -2332,9 +2723,9 @@
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) {
@@ -2350,7 +2741,8 @@
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 {
@@ -8519,6 +8911,62 @@
}
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 = SLIMBUS_4_TX;
+ int ret = -EINVAL;
+ u8 *rcvd_params = NULL;
+ struct afe_sp_v4_channel_v_vali_params *v_vali_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_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)
{
@@ -8562,7 +9010,57 @@
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;
@@ -8606,7 +9104,69 @@
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;
@@ -8653,6 +9213,61 @@
return ret;
}
+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
@@ -8675,23 +9290,32 @@
}
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],
@@ -8801,6 +9425,46 @@
}
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;
@@ -8878,22 +9542,41 @@
}
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;
}
@@ -9238,6 +9921,9 @@
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 ||
@@ -9248,18 +9934,51 @@
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];
+ }
}
}
}
@@ -9274,6 +9993,9 @@
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;
if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL ||
cal_data == NULL ||
@@ -9285,18 +10007,52 @@
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];
+ }
}
}
}
@@ -9329,6 +10085,75 @@
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)
{
@@ -9377,6 +10202,7 @@
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__);
@@ -9400,17 +10226,47 @@
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) {
@@ -9595,6 +10451,11 @@
{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__);
@@ -9741,7 +10602,7 @@
#else
wl.ws = wakeup_source_register("spkr-prot");
#endif
-/*
+ /*
* Set release function to cleanup memory related to kobject
* before initializing the kobject.
*/
diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h
index 1894737..607b910 100644
--- a/include/dsp/apr_audio-v2.h
+++ b/include/dsp/apr_audio-v2.h
@@ -11084,19 +11084,6 @@
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;
@@ -11111,6 +11098,366 @@
} __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
@@ -11782,7 +12129,7 @@
* 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 55ae6be..8b82069 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);
diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h
index e8ba1b3..5562692 100644
--- a/include/uapi/linux/msm_audio_calibration.h
+++ b/include/uapi/linux/msm_audio_calibration.h
@@ -105,11 +105,13 @@
ADM_LSM_AUDPROC_CAL_TYPE,
ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE,
ADM_AUDPROC_PERSISTENT_CAL_TYPE,
+ AFE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE,
MAX_CAL_TYPES,
};
#define AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE
#define AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE
+#define FE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE AFE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE
#define AFE_SIDETONE_IIR_CAL_TYPE AFE_SIDETONE_IIR_CAL_TYPE
@@ -123,6 +125,7 @@
#define TOPOLOGY_SPECIFIC_CHANNEL_INFO
#define MSM_SPKR_PROT_SPV3
+#define MSM_SPKR_PROT_SPV4
enum {
VERSION_0_0,
@@ -375,6 +378,16 @@
int32_t status[SP_V2_NUM_MAX_SPKRS];
};
+struct audio_cal_info_sp_v4_ex_vi_param {
+ int32_t ftm_re_q24[SP_V2_NUM_MAX_SPKRS];
+ int32_t ftm_Bl_q24[SP_V2_NUM_MAX_SPKRS];
+ int32_t ftm_Rms_q24[SP_V2_NUM_MAX_SPKRS];
+ int32_t ftm_Kms_q24[SP_V2_NUM_MAX_SPKRS];
+ int32_t ftm_freq_q20[SP_V2_NUM_MAX_SPKRS];
+ int32_t ftm_Qms_q24[SP_V2_NUM_MAX_SPKRS];
+ uint32_t status[SP_V2_NUM_MAX_SPKRS];
+};
+
struct audio_cal_info_sp_th_vi_param {
/*
* mode should be first param, add new params later to this.
@@ -797,6 +810,7 @@
struct audio_cal_header hdr;
struct audio_cal_type_sp_th_vi_v_vali_param cal_type;
};
+
struct audio_cal_type_sp_ex_vi_param {
struct audio_cal_type_header cal_hdr;
struct audio_cal_data cal_data;
@@ -807,4 +821,16 @@
struct audio_cal_header hdr;
struct audio_cal_type_sp_ex_vi_param cal_type;
};
+
+struct audio_cal_type_sp_v4_ex_vi_param {
+ struct audio_cal_type_header cal_hdr;
+ struct audio_cal_data cal_data;
+ struct audio_cal_info_sp_v4_ex_vi_param cal_info;
+};
+
+struct audio_cal_sp_v4_ex_vi_param {
+ struct audio_cal_header hdr;
+ struct audio_cal_type_sp_v4_ex_vi_param cal_type;
+};
+
#endif /* _UAPI_MSM_AUDIO_CALIBRATION_H */
diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c
index 981060c..2e7779a 100644
--- a/soc/swr-mstr-ctrl.c
+++ b/soc/swr-mstr-ctrl.c
@@ -96,7 +96,7 @@
static void swrm_unlock_sleep(struct swr_mstr_ctrl *swrm);
static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr);
static void swr_master_write(struct swr_mstr_ctrl *swrm, u16 reg_addr, u32 val);
-
+static int swrm_runtime_resume(struct device *dev);
static u8 swrm_get_clk_div(int mclk_freq, int bus_clk_freq)
{
@@ -853,6 +853,8 @@
mutex_unlock(&swrm->devlock);
pm_runtime_get_sync(swrm->dev);
+ if (swrm->req_clk_switch)
+ swrm_runtime_resume(swrm->dev);
ret = swrm_cmd_fifo_rd_cmd(swrm, &val, dev_num, 0, reg_addr, len);
if (!ret)
@@ -886,6 +888,8 @@
mutex_unlock(&swrm->devlock);
pm_runtime_get_sync(swrm->dev);
+ if (swrm->req_clk_switch)
+ swrm_runtime_resume(swrm->dev);
ret = swrm_cmd_fifo_wr_cmd(swrm, reg_val, dev_num, 0, reg_addr);
pm_runtime_put_autosuspend(swrm->dev);
@@ -2032,16 +2036,22 @@
swrm->intr_mask);
break;
case SWRM_INTERRUPT_STATUS_RD_FIFO_OVERFLOW:
- dev_dbg(swrm->dev, "%s: SWR read FIFO overflow\n",
- __func__);
+ value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS);
+ dev_err(swrm->dev,
+ "%s: SWR read FIFO overflow fifo status 0x%x\n",
+ __func__, value);
break;
case SWRM_INTERRUPT_STATUS_RD_FIFO_UNDERFLOW:
- dev_dbg(swrm->dev, "%s: SWR read FIFO underflow\n",
- __func__);
+ value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS);
+ dev_err(swrm->dev,
+ "%s: SWR read FIFO underflow fifo status 0x%x\n",
+ __func__, value);
break;
case SWRM_INTERRUPT_STATUS_WR_CMD_FIFO_OVERFLOW:
- dev_dbg(swrm->dev, "%s: SWR write FIFO overflow\n",
- __func__);
+ value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS);
+ dev_err(swrm->dev,
+ "%s: SWR write FIFO overflow fifo status %x\n",
+ __func__, value);
swr_master_write(swrm, SWRM_CMD_FIFO_CMD, 0x1);
break;
case SWRM_INTERRUPT_STATUS_CMD_ERROR:
@@ -2337,7 +2347,7 @@
static int swrm_master_init(struct swr_mstr_ctrl *swrm)
{
- int ret = 0;
+ int ret = 0, i = 0;
u32 val;
u8 row_ctrl = SWR_ROW_50;
u8 col_ctrl = SWR_MIN_COL;
@@ -2348,6 +2358,18 @@
u32 temp = 0;
int len = 0;
+ /* SW workaround to gate hw_ctl for SWR version >=1.6 */
+ if (swrm->version >= SWRM_VERSION_1_6) {
+ if (swrm->swrm_hctl_reg) {
+ temp = ioread32(swrm->swrm_hctl_reg);
+ temp &= 0xFFFFFFFD;
+ iowrite32(temp, swrm->swrm_hctl_reg);
+ usleep_range(500, 505);
+ temp = ioread32(swrm->swrm_hctl_reg);
+ dev_dbg(swrm->dev, "%s: hctl_reg val: 0x%x\n",
+ __func__, temp);
+ }
+ }
ssp_period = swrm_get_ssp_period(swrm, SWRM_ROW_50,
SWRM_COL_02, SWRM_FRAME_SYNC_SEL);
dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period);
@@ -2403,6 +2425,13 @@
dev_err(swrm->dev,
"%s: swr link failed to connect\n",
__func__);
+ for (i = 0; i < len; i++) {
+ usleep_range(50, 55);
+ dev_err(swrm->dev,
+ "%s:reg:0x%x val:0x%x\n",
+ __func__,
+ reg[i], swr_master_read(swrm, reg[i]));
+ }
return -EINVAL;
}
/*
@@ -2415,14 +2444,6 @@
(swr_master_read(swrm,
SWRM_CMD_FIFO_CFG_ADDR) | 0x80000000));
- /* SW workaround to gate hw_ctl for SWR version >=1.6 */
- if (swrm->version >= SWRM_VERSION_1_6) {
- if (swrm->swrm_hctl_reg) {
- temp = ioread32(swrm->swrm_hctl_reg);
- temp &= 0xFFFFFFFD;
- iowrite32(temp, swrm->swrm_hctl_reg);
- }
- }
return ret;
}
@@ -2755,6 +2776,7 @@
"%s: Error in master Initialization , err %d\n",
__func__, ret);
mutex_unlock(&swrm->mlock);
+ ret = -EPROBE_DEFER;
goto err_mstr_init_fail;
}
@@ -2803,11 +2825,17 @@
err_mstr_init_fail:
swr_unregister_master(&swrm->master);
err_mstr_fail:
- if (swrm->reg_irq)
+ if (swrm->reg_irq) {
swrm->reg_irq(swrm->handle, swr_mstr_interrupt,
swrm, SWR_IRQ_FREE);
- else if (swrm->irq)
+ } else if (swrm->irq) {
free_irq(swrm->irq, swrm);
+ irqd_set_trigger_type(
+ irq_get_irq_data(swrm->irq),
+ IRQ_TYPE_NONE);
+ }
+ if (swrm->swr_irq_wakeup_capable)
+ irq_set_irq_wake(swrm->irq, 0);
err_irq_fail:
mutex_destroy(&swrm->irq_lock);
mutex_destroy(&swrm->mlock);
@@ -2827,13 +2855,17 @@
{
struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
- if (swrm->reg_irq)
+ if (swrm->reg_irq) {
swrm->reg_irq(swrm->handle, swr_mstr_interrupt,
swrm, SWR_IRQ_FREE);
- else if (swrm->irq)
+ } else if (swrm->irq) {
free_irq(swrm->irq, swrm);
- else if (swrm->wake_irq > 0)
+ irqd_set_trigger_type(
+ irq_get_irq_data(swrm->irq),
+ IRQ_TYPE_NONE);
+ } else if (swrm->wake_irq > 0) {
free_irq(swrm->wake_irq, swrm);
+ }
if (swrm->swr_irq_wakeup_capable)
irq_set_irq_wake(swrm->irq, 0);
cancel_work_sync(&swrm->wakeup_work);
@@ -2991,6 +3023,8 @@
else
pm_runtime_set_autosuspend_delay(&pdev->dev,
auto_suspend_timer);
+ if (swrm->req_clk_switch)
+ swrm->req_clk_switch = false;
mutex_unlock(&swrm->reslock);
trace_printk("%s: pm_runtime: resume done, state:%d\n",
@@ -3296,8 +3330,12 @@
}
mutex_lock(&swrm->mlock);
if (swrm->clk_src != *(int *)data) {
- if (swrm->state == SWR_MSTR_UP)
+ if (swrm->state == SWR_MSTR_UP) {
+ swrm->req_clk_switch = true;
swrm_device_suspend(&pdev->dev);
+ if (swrm->state == SWR_MSTR_UP)
+ swrm->req_clk_switch = false;
+ }
swrm->clk_src = *(int *)data;
}
mutex_unlock(&swrm->mlock);
diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h
index 5439ce6..c7d42b0 100644
--- a/soc/swr-mstr-ctrl.h
+++ b/soc/swr-mstr-ctrl.h
@@ -171,6 +171,7 @@
bool dev_up;
bool ipc_wakeup_triggered;
bool aud_core_err;
+ bool req_clk_switch;
struct pm_qos_request pm_qos_req;
enum swrm_pm_state pm_state;
wait_queue_head_t pm_wq;