hal: Add support to get speaker FTM parameters
Add SET and GET parameter APIs to query speaker
parameters in feedback speaker protection FTM mode.
Change-Id: I14a2b8ccc2e0d61c4ccdcadd63c353ca31b9c8ad
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 28a0b2d..db91b51 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -764,6 +764,7 @@
audio_extn_hpx_set_parameters(adev, parms);
audio_extn_pm_set_parameters(parms);
audio_extn_source_track_set_parameters(adev, parms);
+ audio_extn_fbsp_set_parameters(parms);
check_and_set_hdmi_connection_status(parms);
if (adev->offload_effects_set_parameters != NULL)
adev->offload_effects_set_parameters(parms);
@@ -781,6 +782,7 @@
audio_extn_dts_eagle_get_parameters(adev, query, reply);
audio_extn_hpx_get_parameters(query, reply);
audio_extn_source_track_get_parameters(adev, query, reply);
+ audio_extn_fbsp_get_parameters(query, reply);
if (adev->offload_effects_get_parameters != NULL)
adev->offload_effects_get_parameters(query, reply);
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 123752a..8980026 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -298,6 +298,8 @@
#define audio_extn_spkr_prot_stop_processing(snd_device) (0)
#define audio_extn_spkr_prot_is_enabled() (false)
#define audio_extn_spkr_prot_set_parameters(parms, value, len) (0)
+#define audio_extn_fbsp_set_parameters(parms) (0)
+#define audio_extn_fbsp_get_parameters(query, reply) (0)
#else
void audio_extn_spkr_prot_init(void *adev);
int audio_extn_spkr_prot_start_processing(snd_device_t snd_device);
@@ -306,6 +308,9 @@
void audio_extn_spkr_prot_calib_cancel(void *adev);
void audio_extn_spkr_prot_set_parameters(struct str_parms *parms,
char *value, int len);
+int audio_extn_fbsp_set_parameters(struct str_parms *parms);
+int audio_extn_fbsp_get_parameters(struct str_parms *query,
+ struct str_parms *reply);
#endif
#ifndef COMPRESS_CAPTURE_ENABLED
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 2a246cd..a9512a0 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -103,6 +103,12 @@
#define AUDIO_PARAMETER_KEY_SPKR_TZ_1 "spkr_1_tz_name"
#define AUDIO_PARAMETER_KEY_SPKR_TZ_2 "spkr_2_tz_name"
+#define AUDIO_PARAMETER_KEY_FBSP_TRIGGER_SPKR_CAL "trigger_spkr_cal"
+#define AUDIO_PARAMETER_KEY_FBSP_GET_SPKR_CAL "get_spkr_cal"
+#define AUDIO_PARAMETER_KEY_FBSP_CFG_WAIT_TIME "fbsp_cfg_wait_time"
+#define AUDIO_PARAMETER_KEY_FBSP_CFG_FTM_TIME "fbsp_cfg_ftm_time"
+#define AUDIO_PARAMETER_KEY_FBSP_GET_FTM_PARAM "get_ftm_param"
+
/*Modes of Speaker Protection*/
enum speaker_protection_mode {
SPKR_PROTECTION_DISABLED = -1,
@@ -138,6 +144,9 @@
bool wsa_found;
int spkr_1_tzn;
int spkr_2_tzn;
+ bool trigger_cal;
+ pthread_mutex_t cal_wait_cond_mutex;
+ pthread_cond_t cal_wait_condition;
};
static struct pcm_config pcm_config_skr_prot = {
@@ -274,14 +283,15 @@
ALOGE("%s: Invalid params", __func__);
return true;
}
- if (handle.spkr_in_use) {
+ if (handle.spkr_in_use) {
*sec = 0;
- return true;
- } else {
- clock_gettime(CLOCK_BOOTTIME, &temp);
- *sec = temp.tv_sec - handle.spkr_last_time_used.tv_sec;
- return false;
- }
+ handle.trigger_cal = false;
+ return true;
+ } else {
+ clock_gettime(CLOCK_BOOTTIME, &temp);
+ *sec = temp.tv_sec - handle.spkr_last_time_used.tv_sec;
+ return false;
+ }
}
@@ -537,15 +547,6 @@
ALOGD("%s: spkr_prot_thread calib Success R0 %d %d",
__func__, status.r0[SP_V2_SPKR_1], status.r0[SP_V2_SPKR_2]);
FILE *fp;
-
- vi_feed_no_channels = vi_feed_get_channels(adev);
- ALOGD("%s: vi_feed_no_channels %d", __func__, vi_feed_no_channels);
- if (vi_feed_no_channels < 0) {
- ALOGE("%s: no of channels negative !!", __func__);
- /* limit the number of channels to 2*/
- vi_feed_no_channels = 2;
- }
-
fp = fopen(CALIB_FILE,"wb");
if (!fp) {
ALOGE("%s: spkr_prot_thread File open failed %s",
@@ -636,6 +637,19 @@
return status.status;
}
+static void spkr_calibrate_wait()
+{
+ struct timespec ts;
+
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += WAKEUP_MIN_IDLE_CHECK;
+ ts.tv_nsec = 0;
+ pthread_mutex_lock(&handle.cal_wait_cond_mutex);
+ pthread_cond_timedwait(&handle.cal_wait_condition,
+ &handle.cal_wait_cond_mutex, &ts);
+ pthread_mutex_unlock(&handle.cal_wait_cond_mutex);
+}
+
static void* spkr_calibration_thread()
{
unsigned long sec = 0;
@@ -689,14 +703,6 @@
if (fp) {
int i;
bool spkr_calibrated = true;
- /* HAL for speaker protection is always calibrating for stereo usecase*/
- vi_feed_no_channels = vi_feed_get_channels(adev);
- ALOGD("%s: vi_feed_no_channels %d", __func__, vi_feed_no_channels);
- if (vi_feed_no_channels < 0) {
- ALOGE("%s: no of channels negative !!", __func__);
- /* limit the number of channels to 2*/
- vi_feed_no_channels = 2;
- }
for (i = 0; i < vi_feed_no_channels; i++) {
fread(&protCfg.r0[i], sizeof(protCfg.r0[i]), 1, fp);
fread(&protCfg.t0[i], sizeof(protCfg.t0[i]), 1, fp);
@@ -741,13 +747,13 @@
if (is_speaker_in_use(&sec)) {
ALOGV("%s: WSA Speaker in use retry calibration", __func__);
pthread_mutex_unlock(&adev->lock);
- sleep(WAKEUP_MIN_IDLE_CHECK);
+ spkr_calibrate_wait();
continue;
} else {
ALOGD("%s: wsa speaker idle %ld,minimum time %ld", __func__, sec, min_idle_time);
- if (sec < min_idle_time) {
+ if (!(sec > min_idle_time || handle.trigger_cal)) {
pthread_mutex_unlock(&adev->lock);
- sleep(WAKEUP_MIN_IDLE_CHECK);
+ spkr_calibrate_wait();
continue;
}
goahead = true;
@@ -755,7 +761,7 @@
if (!list_empty(&adev->usecase_list)) {
ALOGD("%s: Usecase active re-try calibration", __func__);
pthread_mutex_unlock(&adev->lock);
- sleep(WAKEUP_MIN_IDLE_CHECK);
+ spkr_calibrate_wait();
continue;
}
if (goahead) {
@@ -776,7 +782,7 @@
if (t0_spk_1 < TZ_TEMP_MIN_THRESHOLD ||
t0_spk_1 > TZ_TEMP_MAX_THRESHOLD) {
pthread_mutex_unlock(&adev->lock);
- sleep(WAKEUP_MIN_IDLE_CHECK);
+ spkr_calibrate_wait();
continue;
}
ALOGD("%s: temp T0 for spkr1 %d\n", __func__, t0_spk_1);
@@ -799,7 +805,7 @@
if (t0_spk_2 < TZ_TEMP_MIN_THRESHOLD ||
t0_spk_2 > TZ_TEMP_MAX_THRESHOLD) {
pthread_mutex_unlock(&adev->lock);
- sleep(WAKEUP_MIN_IDLE_CHECK);
+ spkr_calibrate_wait();
continue;
}
ALOGD("%s: temp T0 for spkr2 %d\n", __func__, t0_spk_2);
@@ -836,12 +842,12 @@
if (is_speaker_in_use(&sec)) {
ALOGV("%s: Speaker in use retry calibration", __func__);
pthread_mutex_unlock(&adev->lock);
- sleep(WAKEUP_MIN_IDLE_CHECK);
+ spkr_calibrate_wait();
continue;
} else {
- if (sec < min_idle_time) {
+ if (!(sec > min_idle_time || handle.trigger_cal)) {
pthread_mutex_unlock(&adev->lock);
- sleep(WAKEUP_MIN_IDLE_CHECK);
+ spkr_calibrate_wait();
continue;
}
goahead = true;
@@ -850,7 +856,7 @@
ALOGD("%s: Usecase active re-try calibration", __func__);
goahead = false;
pthread_mutex_unlock(&adev->lock);
- sleep(WAKEUP_MIN_IDLE_CHECK);
+ spkr_calibrate_wait();
continue;
}
if (goahead) {
@@ -923,6 +929,319 @@
tz_names.spkr_1_name, tz_names.spkr_2_name);
}
+static int spkr_vi_channels(struct audio_device *adev)
+{
+ int vi_channels;
+
+ vi_channels = vi_feed_get_channels(adev);
+ ALOGD("%s: vi_channels %d", __func__, vi_channels);
+ if (vi_channels < 0 || vi_channels > SP_V2_NUM_MAX_SPKRS) {
+ /* limit the number of channels to SP_V2_NUM_MAX_SPKRS */
+ vi_channels = SP_V2_NUM_MAX_SPKRS;
+ }
+ return vi_channels;
+}
+
+static void get_spkr_prot_thermal_cal(char *param)
+{
+ int i, status = 0;
+ int r0[SP_V2_NUM_MAX_SPKRS] = {0}, t0[SP_V2_NUM_MAX_SPKRS] = {0};
+ double dr0[SP_V2_NUM_MAX_SPKRS] = {0}, dt0[SP_V2_NUM_MAX_SPKRS] = {0};
+
+ FILE *fp = fopen(CALIB_FILE,"rb");
+ if (fp) {
+ for (i = 0; i < vi_feed_no_channels; i++) {
+ fread(&r0[i], sizeof(int), 1, fp);
+ fread(&t0[i], sizeof(int), 1, fp);
+ /* Convert from ADSP format to readable format */
+ dr0[i] = ((double)r0[i])/(1 << 24);
+ dt0[i] = ((double)t0[i])/(1 << 6);
+ }
+ ALOGV("%s: R0= %lf, %lf, T0= %lf, %lf",
+ __func__, dr0[0], dr0[1], dt0[0], dt0[1]);
+ fclose(fp);
+ } else {
+ ALOGE("%s: failed to open cal file\n", __func__);
+ status = -EINVAL;
+ }
+ sprintf(param, "SpkrCalStatus: %d; R0: %lf, %lf; T0: %lf, %lf",
+ status, dr0[SP_V2_SPKR_1], dr0[SP_V2_SPKR_2],
+ dt0[SP_V2_SPKR_1], dt0[SP_V2_SPKR_2]);
+ ALOGD("%s:: param = %s\n", __func__, param);
+
+ return;
+}
+
+#ifdef MSM_SPKR_PROT_IN_FTM_MODE
+
+static int set_spkr_prot_ftm_cfg(int wait_time, int ftm_time)
+{
+ int ret = 0;
+ struct audio_cal_sp_th_vi_ftm_cfg th_cal_data;
+ struct audio_cal_sp_ex_vi_ftm_cfg ex_cal_data;
+
+ int cal_fd = open("/dev/msm_audio_cal",O_RDWR | O_NONBLOCK);
+ if (cal_fd < 0) {
+ ALOGE("%s: open msm_acdb failed", __func__);
+ ret = -ENODEV;
+ goto done;
+ }
+
+ memset(&th_cal_data, 0, sizeof(th_cal_data));
+ th_cal_data.hdr.data_size = sizeof(th_cal_data);
+ th_cal_data.hdr.version = VERSION_0_0;
+ th_cal_data.hdr.cal_type = AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE;
+ th_cal_data.hdr.cal_type_size = sizeof(th_cal_data.cal_type);
+ th_cal_data.cal_type.cal_hdr.version = VERSION_0_0;
+ th_cal_data.cal_type.cal_hdr.buffer_number = 0;
+ th_cal_data.cal_type.cal_info.wait_time[SP_V2_SPKR_1] = wait_time;
+ th_cal_data.cal_type.cal_info.wait_time[SP_V2_SPKR_2] = wait_time;
+ th_cal_data.cal_type.cal_info.ftm_time[SP_V2_SPKR_1] = ftm_time;
+ th_cal_data.cal_type.cal_info.ftm_time[SP_V2_SPKR_2] = ftm_time;
+ th_cal_data.cal_type.cal_info.mode = MSM_SPKR_PROT_IN_FTM_MODE; // FTM mode
+ th_cal_data.cal_type.cal_data.mem_handle = -1;
+
+ if (ioctl(cal_fd, AUDIO_SET_CALIBRATION, &th_cal_data))
+ ALOGE("%s: failed to set TH VI FTM_CFG, errno = %d", __func__, errno);
+
+ memset(&ex_cal_data, 0, sizeof(ex_cal_data));
+ ex_cal_data.hdr.data_size = sizeof(ex_cal_data);
+ ex_cal_data.hdr.version = VERSION_0_0;
+ ex_cal_data.hdr.cal_type = AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE;
+ ex_cal_data.hdr.cal_type_size = sizeof(ex_cal_data.cal_type);
+ ex_cal_data.cal_type.cal_hdr.version = VERSION_0_0;
+ ex_cal_data.cal_type.cal_hdr.buffer_number = 0;
+ ex_cal_data.cal_type.cal_info.wait_time[SP_V2_SPKR_1] = wait_time;
+ ex_cal_data.cal_type.cal_info.wait_time[SP_V2_SPKR_2] = wait_time;
+ ex_cal_data.cal_type.cal_info.ftm_time[SP_V2_SPKR_1] = ftm_time;
+ ex_cal_data.cal_type.cal_info.ftm_time[SP_V2_SPKR_2] = ftm_time;
+ ex_cal_data.cal_type.cal_info.mode = MSM_SPKR_PROT_IN_FTM_MODE; // FTM mode
+ ex_cal_data.cal_type.cal_data.mem_handle = -1;
+
+ if (ioctl(cal_fd, AUDIO_SET_CALIBRATION, &ex_cal_data))
+ ALOGE("%s: failed to set EX VI FTM_CFG, ret = %d", __func__, errno);
+
+ if (cal_fd > 0)
+ close(cal_fd);
+done:
+ return ret;
+}
+
+static void get_spkr_prot_ftm_param(char *param)
+{
+ struct audio_cal_sp_th_vi_param th_vi_cal_data;
+ struct audio_cal_sp_ex_vi_param ex_vi_cal_data;
+ int i;
+ int ftm_status[SP_V2_NUM_MAX_SPKRS];
+ double rdc[SP_V2_NUM_MAX_SPKRS], temp[SP_V2_NUM_MAX_SPKRS];
+ double f[SP_V2_NUM_MAX_SPKRS], r[SP_V2_NUM_MAX_SPKRS], q[SP_V2_NUM_MAX_SPKRS];
+
+ int cal_fd = open("/dev/msm_audio_cal",O_RDWR | O_NONBLOCK);
+ if (cal_fd < 0) {
+ ALOGE("%s: open msm_acdb failed", __func__);
+ goto done;
+ }
+
+ memset(&th_vi_cal_data, 0, sizeof(th_vi_cal_data));
+ th_vi_cal_data.cal_type.cal_info.status[SP_V2_SPKR_1] = -EINVAL;
+ th_vi_cal_data.cal_type.cal_info.status[SP_V2_SPKR_2] = -EINVAL;
+ th_vi_cal_data.hdr.data_size = sizeof(th_vi_cal_data);
+ th_vi_cal_data.hdr.version = VERSION_0_0;
+ th_vi_cal_data.hdr.cal_type = AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE;
+ th_vi_cal_data.hdr.cal_type_size = sizeof(th_vi_cal_data.cal_type);
+ th_vi_cal_data.cal_type.cal_hdr.version = VERSION_0_0;
+ th_vi_cal_data.cal_type.cal_hdr.buffer_number = 0;
+ th_vi_cal_data.cal_type.cal_data.mem_handle = -1;
+
+ if (ioctl(cal_fd, AUDIO_GET_CALIBRATION, &th_vi_cal_data))
+ ALOGE("%s: Error %d in getting th_vi_cal_data", __func__, errno);
+
+ memset(&ex_vi_cal_data, 0, sizeof(ex_vi_cal_data));
+ ex_vi_cal_data.cal_type.cal_info.status[SP_V2_SPKR_1] = -EINVAL;
+ ex_vi_cal_data.cal_type.cal_info.status[SP_V2_SPKR_2] = -EINVAL;
+ ex_vi_cal_data.hdr.data_size = sizeof(ex_vi_cal_data);
+ ex_vi_cal_data.hdr.version = VERSION_0_0;
+ ex_vi_cal_data.hdr.cal_type = AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE;
+ ex_vi_cal_data.hdr.cal_type_size = sizeof(ex_vi_cal_data.cal_type);
+ ex_vi_cal_data.cal_type.cal_hdr.version = VERSION_0_0;
+ ex_vi_cal_data.cal_type.cal_hdr.buffer_number = 0;
+ ex_vi_cal_data.cal_type.cal_data.mem_handle = -1;
+
+ if (ioctl(cal_fd, AUDIO_GET_CALIBRATION, &ex_vi_cal_data))
+ ALOGE("%s: Error %d in getting ex_vi_cal_data", __func__, errno);
+
+ for (i = 0; i < vi_feed_no_channels; i++) {
+ /* Convert from ADSP format to readable format */
+ rdc[i] = ((double)th_vi_cal_data.cal_type.cal_info.r_dc_q24[i])/(1<<24);
+ temp[i] = ((double)th_vi_cal_data.cal_type.cal_info.temp_q22[i])/(1<<22);
+ f[i] = ((double)ex_vi_cal_data.cal_type.cal_info.freq_q20[i])/(1<<20);
+ r[i] = ((double)ex_vi_cal_data.cal_type.cal_info.resis_q24[i])/(1<<24);
+ q[i] = ((double)ex_vi_cal_data.cal_type.cal_info.qmct_q24[i])/(1<<24);
+
+ if (th_vi_cal_data.cal_type.cal_info.status[i] == 0 &&
+ ex_vi_cal_data.cal_type.cal_info.status[i] == 0) {
+ ftm_status[i] = 0;
+ } else if (th_vi_cal_data.cal_type.cal_info.status[i] == -EAGAIN &&
+ ex_vi_cal_data.cal_type.cal_info.status[i] == -EAGAIN) {
+ ftm_status[i] = -EAGAIN;
+ } else {
+ ftm_status[i] = -EINVAL;
+ }
+ }
+ sprintf(param, "SpkrParamStatus: %d, %d; Rdc: %lf, %lf; Temp: %lf, %lf;"
+ " Freq: %lf, %lf; Rect: %lf, %lf; Qmct: %lf, %lf",
+ ftm_status[SP_V2_SPKR_1], ftm_status[SP_V2_SPKR_2],
+ rdc[SP_V2_SPKR_1], rdc[SP_V2_SPKR_2], temp[SP_V2_SPKR_1],
+ temp[SP_V2_SPKR_2], f[SP_V2_SPKR_1], f[SP_V2_SPKR_2],
+ r[SP_V2_SPKR_1], r[SP_V2_SPKR_2], q[SP_V2_SPKR_1], q[SP_V2_SPKR_2]);
+ ALOGD("%s:: param = %s\n", __func__, param);
+
+ if (cal_fd > 0)
+ close(cal_fd);
+done:
+ return;
+}
+
+#else
+
+static void get_spkr_prot_ftm_param(char *param __unused)
+{
+
+ ALOGD("%s: not supported", __func__);
+ return;
+}
+
+static int set_spkr_prot_ftm_cfg(int wait_time __unused, int ftm_time __unused)
+{
+ ALOGD("%s: not supported", __func__);
+ return -ENOSYS;
+}
+#endif
+
+static void spkr_calibrate_signal()
+{
+ pthread_mutex_lock(&handle.cal_wait_cond_mutex);
+ pthread_cond_signal(&handle.cal_wait_condition);
+ pthread_mutex_unlock(&handle.cal_wait_cond_mutex);
+}
+
+int audio_extn_fbsp_set_parameters(struct str_parms *parms)
+{
+ int ret= 0 , err;
+ char *str;
+ char *value = NULL;
+ int val, len, i;
+ char *test_r = NULL;
+ char *cfg_str;
+ int wait_time, ftm_time;
+ char *kv_pairs = str_parms_to_str(parms);
+
+ if(kv_pairs == NULL) {
+ ret = -ENOMEM;
+ ALOGE("[%s] key-value pair is NULL",__func__);
+ goto done;
+ }
+ ALOGV_IF(kv_pairs != NULL, "%s: enter: %s", __func__, kv_pairs);
+
+ len = strlen(kv_pairs);
+ value = (char*)calloc(len, sizeof(char));
+ if(value == NULL) {
+ ret = -ENOMEM;
+ ALOGE("[%s] failed to allocate memory",__func__);
+ goto done;
+ }
+ if (!handle.spkr_prot_enable) {
+ ALOGD("%s: Speaker protection disabled", __func__);
+ goto done;
+ }
+
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_FBSP_TRIGGER_SPKR_CAL, value,
+ len);
+ if (err >= 0) {
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_FBSP_TRIGGER_SPKR_CAL);
+ if ((strcmp(value, "true") == 0) || (strcmp(value, "yes") == 0)) {
+ handle.trigger_cal = true;
+ spkr_calibrate_signal();
+ }
+ goto done;
+ }
+
+ /* Expected key value pair is in below format:
+ * AUDIO_PARAM_FBSP_CFG_WAIT_TIME=waittime;AUDIO_PARAM_FBSP_CFG_FTM_TIME=ftmtime;
+ * Parse waittime and ftmtime from it.
+ */
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_FBSP_CFG_WAIT_TIME,
+ value, len);
+ if (err >= 0) {
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_FBSP_CFG_WAIT_TIME);
+ cfg_str = strtok_r(value, ";", &test_r);
+ if (cfg_str == NULL) {
+ ALOGE("%s: incorrect wait time cfg_str", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ wait_time = atoi(cfg_str);
+ ALOGV(" %s: cfg_str = %s, wait_time = %d", __func__, cfg_str, wait_time);
+
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_FBSP_CFG_FTM_TIME,
+ value, len);
+ if (err >= 0) {
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_FBSP_CFG_FTM_TIME);
+ cfg_str = strtok_r(value, ";", &test_r);
+ if (cfg_str == NULL) {
+ ALOGE("%s: incorrect ftm time cfg_str", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ ftm_time = atoi(cfg_str);
+ ALOGV(" %s: cfg_str = %s, ftm_time = %d", __func__, cfg_str, ftm_time);
+
+ ret = set_spkr_prot_ftm_cfg(wait_time, ftm_time);
+ if (ret < 0) {
+ ALOGE("%s: set_spkr_prot_ftm_cfg failed", __func__);
+ goto done;
+ }
+ }
+ }
+
+done:
+ ALOGV("%s: exit with code(%d)", __func__, ret);
+
+ if(kv_pairs != NULL)
+ free(kv_pairs);
+ if(value != NULL)
+ free(value);
+
+ return ret;
+}
+
+int audio_extn_fbsp_get_parameters(struct str_parms *query,
+ struct str_parms *reply)
+{
+ int err = 0;
+ char value[1024] = {0};
+
+ if (!handle.spkr_prot_enable) {
+ ALOGD("%s: Speaker protection disabled", __func__);
+ return -EINVAL;
+ }
+
+ err = str_parms_get_str(query, AUDIO_PARAMETER_KEY_FBSP_GET_SPKR_CAL, value,
+ sizeof(value));
+ if (err >= 0) {
+ get_spkr_prot_thermal_cal(value);
+ str_parms_add_str(reply, AUDIO_PARAMETER_KEY_FBSP_GET_SPKR_CAL, value);
+ }
+ err = str_parms_get_str(query, AUDIO_PARAMETER_KEY_FBSP_GET_FTM_PARAM, value,
+ sizeof(value));
+ if (err >= 0) {
+ get_spkr_prot_ftm_param(value);
+ str_parms_add_str(reply, AUDIO_PARAMETER_KEY_FBSP_GET_FTM_PARAM, value);
+ }
+done:
+ return err;
+}
+
void audio_extn_spkr_prot_init(void *adev)
{
char value[PROPERTY_VALUE_MAX];
@@ -944,6 +1263,11 @@
handle.spkr_prot_mode = MSM_SPKR_PROT_DISABLED;
handle.spkr_processing_state = SPKR_PROCESSING_IN_IDLE;
handle.spkr_prot_t0 = -1;
+ handle.trigger_cal = false;
+ /* HAL for speaker protection is always calibrating for stereo usecase*/
+ vi_feed_no_channels = spkr_vi_channels(adev);
+ pthread_cond_init(&handle.cal_wait_condition, NULL);
+ pthread_mutex_init(&handle.cal_wait_cond_mutex, NULL);
if (is_wsa_present()) {
if (platform_spkr_prot_is_wsa_analog_mode(adev) == 1) {