Merge "PAL: Track WSA PA output amp and temp during WSA reliability test"
diff --git a/configs/kalama/resourcemanager_kalama_cdp.xml b/configs/kalama/resourcemanager_kalama_cdp.xml
index 5ba1983..7f4744b 100644
--- a/configs/kalama/resourcemanager_kalama_cdp.xml
+++ b/configs/kalama/resourcemanager_kalama_cdp.xml
@@ -28,7 +28,7 @@
 
 * Changes from Qualcomm Innovation Center are provided under the following license:
 *
-* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the
@@ -77,6 +77,7 @@
         <param key="device_mux_config" value ="false" />
         <param key="upd_duty_cycle_enable" value="false" />
         <param key="upd_virtual_port" value ="false" />
+        <param key="spkr_xmax_tmax_logging_enable" value ="false" />
     </config_params>
     <config_gapless key="gapless_supported" value="1"/>
     <bt_codecs>
diff --git a/configs/kalama/resourcemanager_kalama_cdp_apq.xml b/configs/kalama/resourcemanager_kalama_cdp_apq.xml
index 924b3ee..8239fee 100644
--- a/configs/kalama/resourcemanager_kalama_cdp_apq.xml
+++ b/configs/kalama/resourcemanager_kalama_cdp_apq.xml
@@ -28,7 +28,7 @@
 
 * Changes from Qualcomm Innovation Center are provided under the following license:
 *
-* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the
@@ -77,6 +77,7 @@
         <param key="device_mux_config" value ="false" />
         <param key="upd_duty_cycle_enable" value="false" />
         <param key="upd_virtual_port" value ="false" />
+        <param key="spkr_xmax_tmax_logging_enable" value ="false" />
     </config_params>
     <config_gapless key="gapless_supported" value="1"/>
     <bt_codecs>
diff --git a/configs/kalama/resourcemanager_kalama_grd.xml b/configs/kalama/resourcemanager_kalama_grd.xml
index becf30f..6420508 100644
--- a/configs/kalama/resourcemanager_kalama_grd.xml
+++ b/configs/kalama/resourcemanager_kalama_grd.xml
@@ -28,7 +28,7 @@
 
 * Changes from Qualcomm Innovation Center are provided under the following license:
 *
-* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the
@@ -77,6 +77,7 @@
         <param key="device_mux_config" value ="false" />
         <param key="upd_duty_cycle_enable" value="false" />
         <param key="upd_virtual_port" value ="false" />
+        <param key="spkr_xmax_tmax_logging_enable" value ="false" />
     </config_params>
     <config_volume>
         <use_volume_set_param>0</use_volume_set_param>
diff --git a/configs/kalama/resourcemanager_kalama_mtp.xml b/configs/kalama/resourcemanager_kalama_mtp.xml
index bda23c9..169c83c 100644
--- a/configs/kalama/resourcemanager_kalama_mtp.xml
+++ b/configs/kalama/resourcemanager_kalama_mtp.xml
@@ -28,7 +28,7 @@
 
 * Changes from Qualcomm Innovation Center are provided under the following license:
 *
-* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the
@@ -77,6 +77,7 @@
         <param key="signal_handler" value ="true" />
         <param key="device_mux_config" value ="false" />
         <param key="upd_virtual_port" value ="false" />
+        <param key="spkr_xmax_tmax_logging_enable" value ="false" />
     </config_params>
     <config_volume>
         <use_volume_set_param>0</use_volume_set_param>
diff --git a/configs/kalama/resourcemanager_kalama_mtp_apq.xml b/configs/kalama/resourcemanager_kalama_mtp_apq.xml
index fee3ff1..55e9c08 100644
--- a/configs/kalama/resourcemanager_kalama_mtp_apq.xml
+++ b/configs/kalama/resourcemanager_kalama_mtp_apq.xml
@@ -28,7 +28,7 @@
 
 * Changes from Qualcomm Innovation Center are provided under the following license:
 *
-* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the
@@ -77,6 +77,7 @@
         <param key="signal_handler" value ="true" />
         <param key="device_mux_config" value ="false" />
         <param key="upd_virtual_port" value ="false" />
+        <param key="spkr_xmax_tmax_logging_enable" value ="false" />
     </config_params>
     <config_volume>
         <use_volume_set_param>0</use_volume_set_param>
diff --git a/configs/kalama/resourcemanager_kalama_qrd.xml b/configs/kalama/resourcemanager_kalama_qrd.xml
index 3818244..f41696a 100644
--- a/configs/kalama/resourcemanager_kalama_qrd.xml
+++ b/configs/kalama/resourcemanager_kalama_qrd.xml
@@ -28,7 +28,7 @@
 
 * Changes from Qualcomm Innovation Center are provided under the following license:
 *
-* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the
@@ -77,6 +77,7 @@
         <param key="device_mux_config" value ="false" />
         <param key="upd_duty_cycle_enable" value="false" />
         <param key="upd_virtual_port" value ="false" />
+        <param key="spkr_xmax_tmax_logging_enable" value ="false" />
     </config_params>
     <config_volume>
         <use_volume_set_param>0</use_volume_set_param>
diff --git a/device/inc/SpeakerProtection.h b/device/inc/SpeakerProtection.h
index bf40718..94ac1aa 100644
--- a/device/inc/SpeakerProtection.h
+++ b/device/inc/SpeakerProtection.h
@@ -28,7 +28,7 @@
  *
  * Changes from Qualcomm Innovation Center are provided under the following license:
  *
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted (subject to the limitations in the
@@ -131,6 +131,7 @@
     spkr_prot_proc_state spkrProcessingState;
     int *spkerTempList;
     static bool isSpkrInUse;
+    static bool startXmaxLogging;
     static bool calThrdCreated;
     static bool isDynamicCalTriggered;
     static struct timespec spkrLastTimeUsed;
@@ -158,11 +159,13 @@
 
 public:
     static std::thread mCalThread;
+    static std::thread XmaxTmaxLogThread;
     static std::condition_variable cv;
     static std::mutex cvMutex;
     std::mutex deviceMutex;
     static std::mutex calibrationMutex;
     void spkrCalibrationThread();
+    void startSpkrXmaxTmaxLogging();
     int getSpeakerTemperature(int spkr_pos);
     void spkrCalibrateWait();
     int spkrStartCalibration();
@@ -194,6 +197,7 @@
     int getCpsDevNumber(std::string mixer);
     int32_t getCalibrationData(void **param);
     int32_t getFTMParameter(void **param);
+    int32_t getSpkrXmaxTmaxData();
     void disconnectFeandBe(std::vector<int> pcmDevIds, std::string backEndName);
 };
 
diff --git a/device/src/SpeakerProtection.cpp b/device/src/SpeakerProtection.cpp
index 307218a..b2385d5 100644
--- a/device/src/SpeakerProtection.cpp
+++ b/device/src/SpeakerProtection.cpp
@@ -63,10 +63,7 @@
 
 #define LOG_TAG "PAL: SpeakerProtection"
 
-
 #include "SpeakerProtection.h"
-#include "PalAudioRoute.h"
-#include "ResourceManager.h"
 #include "SessionAlsaUtils.h"
 #include "kvh2xml.h"
 #include <errno.h>
@@ -80,6 +77,8 @@
 #define PAL_SP_II_TEMP_PATH "/data/vendor/audio/audio_sp2.cal"
 #endif
 
+#define PAL_SP_XMAX_TMAX_DATA_PATH "/data/vendor/audio/spkr_xmax_tmax.cal"
+#define PAL_SP_XMAX_TMAX_LOG_PATH "/data/vendor/audio/log_spkr_xmax_tmax.cal"
 #define FEEDBACK_MONO_1 "-mono-1"
 
 #define MIN_SPKR_IDLE_SEC (60 * 30)
@@ -124,6 +123,7 @@
 #define CALIBRATION_STATUS_FAILURE 5
 
 std::thread SpeakerProtection::mCalThread;
+std::thread SpeakerProtection::XmaxTmaxLogThread;
 std::condition_variable SpeakerProtection::cv;
 std::mutex SpeakerProtection::cvMutex;
 std::mutex SpeakerProtection::calibrationMutex;
@@ -131,6 +131,7 @@
 bool SpeakerProtection::isSpkrInUse;
 bool SpeakerProtection::calThrdCreated;
 bool SpeakerProtection::isDynamicCalTriggered = false;
+bool SpeakerProtection::startXmaxLogging = false;
 struct timespec SpeakerProtection::spkrLastTimeUsed;
 struct mixer *SpeakerProtection::virtMixer;
 struct mixer *SpeakerProtection::hwMixer;
@@ -1400,6 +1401,182 @@
     customPayloadSize = 0;
 }
 
+int32_t SpeakerProtection::getSpkrXmaxTmaxData()
+{
+    const char* getParamControl = "getParam";
+    char* pcmDeviceName = NULL;
+    uint8_t* payload = NULL;
+    int ret = 0;
+    uint32_t miid = 0, num_ch = 0, stringLen =0;
+    int32_t pcmID = -EINVAL;
+    size_t payloadSize = 0, bytesWritten = 0;
+    struct mixer_ctl* ctl;
+    FILE* fp;
+    std::ostringstream cntrlName;
+    std::string backendName;
+    param_id_sp_tmax_xmax_logging_t sp_xmax_tmax;
+    param_id_sp_tmax_xmax_logging_t* sp_xmax_tmax_value;
+    PayloadBuilder* builder = new PayloadBuilder();
+
+    /* Frontend ID information for RX Session presents at SessionAlsaPCM/Compress
+     * In Kalama, there is no getter func for pcmDevIds (private attribute)
+     * Assuming there will be only one session. So hardcoded here*/
+
+    pcmID = 125;
+    pcmDeviceName = rm->getDeviceNameFromID(pcmID);
+
+    if (pcmDeviceName == NULL) {
+        /*To check for PAL_STREAM_COMPRESSED*/
+        pcmID = 105;
+        pcmDeviceName = rm->getDeviceNameFromID(pcmID);
+    }
+
+    if (pcmDeviceName) {
+        cntrlName << pcmDeviceName << " " << getParamControl;
+    }
+    else {
+        PAL_ERR(LOG_TAG, "Error: %d Unable to get Device name\n", -EINVAL);
+        ret = -EINVAL;
+        goto exit;
+    }
+
+    ctl = mixer_get_ctl_by_name(virtMixer, cntrlName.str().data());
+
+    if (!ctl) {
+        ret = -ENOENT;
+        PAL_ERR(LOG_TAG, "Error: %d Invalid mixer control: %s\n", ret, cntrlName.str().data());
+        goto exit;
+    }
+
+    rm->getBackendName(PAL_DEVICE_OUT_SPEAKER, backendName);
+
+    if (!strlen(backendName.c_str())) {
+        ret = -ENOENT;
+        PAL_ERR(LOG_TAG, "Error: %d Failed to obtain RX backend name", ret);
+        goto exit;
+    }
+
+    ret = SessionAlsaUtils::getModuleInstanceId(virtMixer, pcmID,
+        backendName.c_str(), MODULE_SP, &miid);
+
+    if (0 != ret) {
+        PAL_ERR(LOG_TAG, "Error: %d Failed to get tag info %x", ret, MODULE_SP);
+        goto exit;
+    }
+
+    sp_xmax_tmax.num_ch = vi_device.channels;
+    builder->payloadSPConfig(&payload, &payloadSize, miid,
+        PARAM_ID_SP_TMAX_XMAX_LOGGING, (void *) &sp_xmax_tmax);
+
+    if (!payloadSize) {
+        PAL_ERR(LOG_TAG, "Payload memory allocation failed");
+        ret = -EINVAL;
+        goto exit;
+    }
+
+    ret = mixer_ctl_set_array(ctl, payload, payloadSize);
+    if (0 != ret) {
+        PAL_ERR(LOG_TAG, "Set failed with return value = %d", ret);
+        goto exit;
+    }
+
+    memset(payload, 0, payloadSize);
+
+    ret = mixer_ctl_get_array(ctl, payload, payloadSize);
+    if (0 != ret) {
+        PAL_ERR(LOG_TAG, "Get failed with return value = %d", ret);
+        goto exit;
+    }
+    else {
+        sp_xmax_tmax_value = (param_id_sp_tmax_xmax_logging_t*)(payload +
+            sizeof(struct apm_module_param_data_t));
+        fp = fopen(PAL_SP_XMAX_TMAX_DATA_PATH, "ab");
+
+        if (!fp) {
+            PAL_ERR(LOG_TAG, "Unable to open file for write");
+            ret = -EBADF;
+            goto exit;
+        }
+        else {
+            num_ch = sp_xmax_tmax_value->num_ch;
+            auto currentTime = std::chrono::system_clock::now();
+            std::time_t currentTimeT = std::chrono::system_clock::to_time_t(currentTime);
+            const char* currentTimeStr = std::ctime(&currentTimeT);
+            stringLen = std::strlen(currentTimeStr);
+
+            PAL_DBG(LOG_TAG, "Current Timestamp : %s and size of string : %d", currentTimeStr, stringLen);
+            bytesWritten = fwrite(currentTimeStr, stringLen, 1, fp);
+
+            if (bytesWritten != 1) {
+                PAL_ERR(LOG_TAG, "Error in writing to file");
+                fclose(fp);
+                ret = -EBADF;
+                goto exit;
+            }
+
+            for (int i = 0; i < num_ch; i++) {
+                PAL_DBG(LOG_TAG, "Channel: %d, Max Excursion Value =%d",i, sp_xmax_tmax_value->tmax_xmax_params[i].max_excursion);
+                bytesWritten = fwrite(&sp_xmax_tmax_value->tmax_xmax_params[i].max_excursion, sizeof(int32_t), 1, fp);
+
+                if (bytesWritten != 1) {
+                    PAL_ERR(LOG_TAG, "Error in writing to file");
+                    fclose(fp);
+                    ret = -EBADF;
+                    goto exit;
+                }
+
+                PAL_DBG(LOG_TAG, "Channel: %d, Max Temperature Value =%d",i, sp_xmax_tmax_value->tmax_xmax_params[i].max_temperature);
+                fwrite(&sp_xmax_tmax_value->tmax_xmax_params[i].max_temperature, sizeof(int32_t), 1, fp);
+
+                if (bytesWritten != 1) {
+                    PAL_ERR(LOG_TAG, "Error in writing to file");
+                    fclose(fp);
+                    ret = -EBADF;
+                    goto exit;
+                }
+            }
+            fclose(fp);
+        }
+    }
+exit:
+    if (builder) {
+        delete builder;
+        builder = NULL;
+    }
+    return ret;
+
+}
+
+void SpeakerProtection::startSpkrXmaxTmaxLogging()
+{
+    FILE* log_fp = NULL;
+    int32_t ret = 0;
+
+    PAL_DBG(LOG_TAG, "Enter");
+
+    /* This condition is added to know if the Speaker_RX graph started or not.
+     * Assuming this file will be pushed to target after playback started
+     * That's how, we will be sure Speaker_RX graph has been started */
+
+    while (!log_fp) {
+        log_fp = fopen(PAL_SP_XMAX_TMAX_LOG_PATH, "rb");
+    }
+    fclose(log_fp);
+
+    if (remove(PAL_SP_XMAX_TMAX_LOG_PATH) == 0) {
+        PAL_DBG(LOG_TAG, "log_spkr_xmax_tmax file deleted successfully");
+    }
+
+    startXmaxLogging = true;
+    while (startXmaxLogging && (ret == 0)) {
+        ret = getSpkrXmaxTmaxData();
+        if (ret != 0) {
+            PAL_ERR(LOG_TAG, "Failed to get Param for spkr_xmax_tmax");
+        }
+        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+    }
+}
+
 /*
  * CPS related custom payload
  */
@@ -2471,6 +2648,11 @@
                 }
             }
         }
+
+        if (ResourceManager::isSpkrXmaxTmaxLoggingEnabled) {
+            XmaxTmaxLogThread = std::thread(&SpeakerProtection::startSpkrXmaxTmaxLogging,
+                this);
+        }
         // Free up the local variables
         goto exit;
     }
@@ -2486,6 +2668,8 @@
         }
         spkrProtSetSpkrStatus(flag);
         // Speaker not in use anymore. Stop the processing mode
+        startXmaxLogging = false;
+
         PAL_DBG(LOG_TAG, "Closing VI path");
         if (txPcm) {
             rm = ResourceManager::getInstance();
diff --git a/resource_manager/inc/ResourceManager.h b/resource_manager/inc/ResourceManager.h
index a16e844..f5fcfda 100644
--- a/resource_manager/inc/ResourceManager.h
+++ b/resource_manager/inc/ResourceManager.h
@@ -82,6 +82,7 @@
 #define AUDIO_PARAMETER_KEY_DEVICE_MUX "device_mux_config"
 #define AUDIO_PARAMETER_KEY_UPD_DUTY_CYCLE "upd_duty_cycle_enable"
 #define AUDIO_PARAMETER_KEY_UPD_VIRTUAL_PORT "upd_virtual_port"
+#define AUDIO_PARAMETER_KEY_SPKR_XMAX_TMAX_LOG "spkr_xmax_tmax_logging_enable"
 #define MAX_PCM_NAME_SIZE 50
 #define MAX_STREAM_INSTANCES (sizeof(uint64_t) << 3)
 #define MIN_USECASE_PRIORITY 0xFFFFFFFF
@@ -621,6 +622,8 @@
     /* Variable to store which speaker side is being used for call audio.
      * Valid for Stereo case only
      */
+    /*Variable to check XmaxTmaxLogging Enabled or not*/
+    static bool isSpkrXmaxTmaxLoggingEnabled;
     static bool isMainSpeakerRight;
     /* Variable to store Quick calibration time for Speaker protection */
     static int spQuickCalTime;
@@ -913,6 +916,7 @@
     static int setDualMonoEnableParam(struct str_parms *parms,char *value, int len);
     static int setSignalHandlerEnableParam(struct str_parms *parms,char *value, int len);
     static int setMuxconfigEnableParam(struct str_parms *parms,char *value, int len);
+    static int setSpkrXmaxTmaxLoggingParam(struct str_parms* parms, char* value, int len);
     static bool isLpiLoggingEnabled();
     static void processConfigParams(const XML_Char **attr);
     static bool isValidDevId(int deviceId);
diff --git a/resource_manager/src/ResourceManager.cpp b/resource_manager/src/ResourceManager.cpp
index eac4624..374d1ff 100644
--- a/resource_manager/src/ResourceManager.cpp
+++ b/resource_manager/src/ResourceManager.cpp
@@ -483,6 +483,7 @@
 int ResourceManager::wake_unlock_fd = -1;
 uint32_t ResourceManager::wake_lock_cnt = 0;
 static int max_session_num;
+bool ResourceManager::isSpkrXmaxTmaxLoggingEnabled = false;
 bool ResourceManager::isSpeakerProtectionEnabled = false;
 bool ResourceManager::isHandsetProtectionEnabled = false;
 bool ResourceManager::isChargeConcurrencyEnabled = false;
@@ -7817,6 +7818,7 @@
     ret = setMuxconfigEnableParam(parms, value, len);
     ret = setUpdDutyCycleEnableParam(parms, value, len);
     ret = setUpdVirtualPortParam(parms, value, len);
+    ret = setSpkrXmaxTmaxLoggingParam(parms, value, len);
 
     /* Not checking return value as this is optional */
     setLpiLoggingParams(parms, value, len);
@@ -7955,6 +7957,29 @@
     return ret;
 }
 
+int ResourceManager::setSpkrXmaxTmaxLoggingParam(struct str_parms* parms,
+    char* value, int len)
+{
+    int ret = -EINVAL;
+
+    if (!value || !parms) {
+        return ret;
+    }
+
+    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SPKR_XMAX_TMAX_LOG,
+        value, len);
+    PAL_VERBOSE(LOG_TAG, " value %s", value);
+
+    if (ret >= 0) {
+        if (value && !strncmp(value, "true", sizeof("true")))
+            ResourceManager::isSpkrXmaxTmaxLoggingEnabled = true;
+
+        str_parms_del(parms, AUDIO_PARAMETER_KEY_SPKR_XMAX_TMAX_LOG);
+    }
+
+    return ret;
+}
+
 int ResourceManager::setUpdVirtualPortParam(struct str_parms *parms, char *value, int len)
 {
     int ret = -EINVAL;
@@ -7964,8 +7989,7 @@
 
     ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_UPD_VIRTUAL_PORT,
                             value, len);
-
-    PAL_VERBOSE(LOG_TAG," value %s", value);
+    PAL_VERBOSE(LOG_TAG, " value %s", value);
 
     if (ret >= 0) {
         if (value && !strncmp(value, "true", sizeof("true")))
diff --git a/session/src/PayloadBuilder.cpp b/session/src/PayloadBuilder.cpp
index f995e99..9a8945a 100644
--- a/session/src/PayloadBuilder.cpp
+++ b/session/src/PayloadBuilder.cpp
@@ -27,7 +27,7 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted (subject to the limitations in the
@@ -3945,6 +3945,23 @@
                 }
             }
         break;
+        case PARAM_ID_SP_TMAX_XMAX_LOGGING:
+        {
+            param_id_sp_tmax_xmax_logging_t *data;
+            data = (param_id_sp_tmax_xmax_logging_t*)param;
+
+            payloadSize = sizeof(struct apm_module_param_data_t) +
+                sizeof(param_id_sp_tmax_xmax_logging_t) + (sizeof(sp_tmax_xmax_params_t) * data->num_ch);
+
+            padBytes = PAL_PADDING_8BYTE_ALIGN(payloadSize);
+            payloadInfo = (uint8_t*)calloc(1, payloadSize + padBytes);
+            if (!payloadInfo) {
+                PAL_ERR(LOG_TAG, "payloadInfo malloc failed %s", strerror(errno));
+                return;
+            }
+            header = (struct apm_module_param_data_t*)payloadInfo;
+        }
+        break;
         default:
             {
                 PAL_ERR(LOG_TAG, "unknown param id 0x%x", param_id);