Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c92f5c20 authored by Laxminath Kasam's avatar Laxminath Kasam
Browse files

hal: spk_prot: add custom support to trigger initial cal

For initial calibration thread can be invoked as part
of set param call instead of setting up at bootup.
Providing setprop option to choose whether bootup static way
or custom way to trigger calibration.
Two setparams are provided now :
1. "trigger_spkr_cal" - to start initial calibration process dynamically.
2. "apply_spkr_cal" - for every reboot, to apply initial cal from CALIB FILE.

Change-Id: I6e529d9b73f11ddfc165af4b2d30a24e927096ea
parent 819c0a82
Loading
Loading
Loading
Loading
+114 −54
Original line number Diff line number Diff line
@@ -141,6 +141,7 @@ enum sp_version {
#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_APPLY_SPKR_CAL   "apply_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"
@@ -207,12 +208,14 @@ struct speaker_prot_session {
    int spkr_1_tzn;
    int spkr_2_tzn;
    bool trigger_cal;
    bool apply_cal;
    pthread_mutex_t cal_wait_cond_mutex;
    pthread_cond_t cal_wait_condition;
    bool init_check;
    bool spkr_cal_dynamic;
    volatile bool thread_exit;
    unsigned int sp_version;
    int limiter_th[SP_V2_NUM_MAX_SPKRS];
    bool cal_thrd_created;
};

static struct pcm_config pcm_config_skr_prot = {
@@ -911,8 +914,18 @@ static int spkr_calibrate(int t0_spk_1, int t0_spk_2)
                retry_duration < GET_SPKR_PROT_CAL_TIMEOUT_MSEC) {
            /*sleep for 200 ms to check for status check*/
            if (!status.status) {
                int i;

                ALOGD("%s: spkr_prot_thread calib Success R0 %d %d",
                 __func__, status.r0[SP_V2_SPKR_1], status.r0[SP_V2_SPKR_2]);
                for (i = 0; i < vi_feed_no_channels; i++) {
                    if (!((status.r0[i] >= MIN_RESISTANCE_SPKR_Q24)
                         && (status.r0[i] < MAX_RESISTANCE_SPKR_Q24))) {
                         ALOGE("%s R0 not in range, retry R0:%d\n", __func__, status.r0[i]);
                         status.status = -EINVAL;
                         break;
                   }
                }
                FILE *fp;
                fp = fopen(CALIB_FILE,"wb");
                if (!fp) {
@@ -974,7 +987,7 @@ exit:
        if (acdb_fd > 0)
            close(acdb_fd);

        if (!handle.cancel_spkr_calib && cleanup) {
        if (!handle.cancel_spkr_calib && cleanup && !handle.spkr_cal_dynamic) {
            pthread_mutex_unlock(&handle.spkr_calib_cancelack_mutex);
            pthread_cond_wait(&handle.spkr_calib_cancel,
            &handle.mutex_spkr_prot);
@@ -1084,10 +1097,12 @@ static void* spkr_calibration_thread()
    if (atoi(afe_version_value) > 0)
        afe_api_version = atoi(afe_version_value);

    if (!handle.spkr_cal_dynamic || handle.apply_cal) {
        bool spkr_calibrated = false;
        fp = fopen(CALIB_FILE,"rb");
        if (fp) {
            int i;
        bool spkr_calibrated = true;
            spkr_calibrated = true;
            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);
@@ -1115,10 +1130,13 @@ static void* spkr_calibration_thread()
                    handle.spkr_prot_mode = MSM_SPKR_PROT_DISABLED;
                } else
                    handle.spkr_prot_mode = MSM_SPKR_PROT_CALIBRATED;
            close(acdb_fd);

                set_boost_and_limiter(adev, spv3_enable, afe_api_version);

            }
        }
        if (handle.spkr_cal_dynamic || spkr_calibrated) {
            close(acdb_fd);
            handle.apply_cal = false;
            pthread_exit(0);
            return NULL;
        }
@@ -1291,6 +1309,7 @@ static void* spkr_calibration_thread()
                    ALOGE("%s: calibrate status %s", __func__, strerror(status));
                }
                ALOGD("%s: spkr_prot_thread end calibration", __func__);
                handle.trigger_cal = false;
                break;
        }
    }
@@ -1557,6 +1576,33 @@ static void spkr_calibrate_signal()
    pthread_mutex_unlock(&handle.cal_wait_cond_mutex);
}

static void spkr_calib_thread_create()
{
    int result = 0;

    if (!handle.spkr_prot_enable) {
        ALOGD("%s: Speaker protection disabled", __func__);
        return;
    }
    if (handle.cal_thrd_created) {
           result = pthread_join(handle.spkr_calibration_thread, (void **) NULL);
           if (result < 0) {
               ALOGE("%s:Unable to join the calibration thread", __func__);
               return;
           }
           handle.cal_thrd_created = false;
    }

    result = pthread_create(&handle.spkr_calibration_thread,
               (const pthread_attr_t *) NULL, spkr_calibration_thread, &handle);
    if (result == 0) {
        handle.cal_thrd_created = true;
    } else {
        ALOGE("%s: speaker calibration thread creation failed", __func__);
        handle.trigger_cal = false;
    }
}

int fbsp_set_parameters(struct str_parms *parms)
{
    int ret= 0 , err;
@@ -1591,12 +1637,28 @@ int fbsp_set_parameters(struct str_parms *parms)
    if (err >= 0) {
        str_parms_del(parms, AUDIO_PARAMETER_KEY_FBSP_TRIGGER_SPKR_CAL);
        if ((strcmp(value, "true") == 0) || (strcmp(value, "yes") == 0)) {
            if (handle.trigger_cal)
                goto done;
            handle.trigger_cal = true;
            spkr_calibrate_signal();
            if (handle.spkr_cal_dynamic)
                spkr_calib_thread_create();
        }
        goto done;
    }
    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_FBSP_APPLY_SPKR_CAL, value,
                            len);
    if (err >= 0) {
        str_parms_del(parms, AUDIO_PARAMETER_KEY_FBSP_APPLY_SPKR_CAL);
        if ((strcmp(value, "true") == 0) || (strcmp(value, "yes") == 0)) {
            if (handle.apply_cal)
                goto done;
            handle.apply_cal = true;
            if (handle.spkr_cal_dynamic)
                spkr_calib_thread_create();
        }
        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.
@@ -1684,6 +1746,8 @@ void spkr_prot_init(void *adev, spkr_prot_init_config_t spkr_prot_init_config_va
        return;
    }
    handle.spkr_prot_enable = false;
    handle.thread_exit = false;
    handle.cal_thrd_created = false;
    if ((property_get("persist.vendor.audio.speaker.prot.enable",
                      value, NULL) > 0) ||
        (property_get("persist.speaker.prot.enable",
@@ -1691,12 +1755,11 @@ void spkr_prot_init(void *adev, spkr_prot_init_config_t spkr_prot_init_config_va
        if (!strncmp("true", value, 4))
             handle.spkr_prot_enable = true;
    }
    handle.init_check = false;
    handle.thread_exit = false;
    if (!handle.spkr_prot_enable) {
        ALOGD("%s: Speaker protection disabled", __func__);
        return;
    }
    handle.spkr_cal_dynamic = property_get_bool("persist.vendor.audio.spkr.cal.dynamic", false);
    // init function pointers
    fp_read_line_from_file = spkr_prot_init_config_val.fp_read_line_from_file;
    fp_get_usecase_from_list =  spkr_prot_init_config_val.fp_get_usecase_from_list;
@@ -1742,14 +1805,9 @@ void spkr_prot_init(void *adev, spkr_prot_init_config_t spkr_prot_init_config_va
        pthread_cond_init(&handle.spkr_calibcancel_ack, NULL);
        pthread_mutex_init(&handle.mutex_spkr_prot, NULL);
        pthread_mutex_init(&handle.spkr_calib_cancelack_mutex, NULL);
        if (!handle.spkr_cal_dynamic) {
            ALOGD("%s:WSA Create calibration thread", __func__);
        result = pthread_create(&handle.spkr_calibration_thread,
        (const pthread_attr_t *) NULL, spkr_calibration_thread, &handle);
        if (result == 0) {
            handle.init_check = true;
        } else {
            ALOGE("%s: speaker calibration thread creation failed", __func__);
            destroy_thread_params();
            spkr_calib_thread_create();
        }
    return;
    } else {
@@ -1794,7 +1852,7 @@ void spkr_prot_init(void *adev, spkr_prot_init_config_t spkr_prot_init_config_va
        result = pthread_create(&handle.spkr_calibration_thread,
        (const pthread_attr_t *) NULL, spkr_calibration_thread, &handle);
        if (result == 0) {
            handle.init_check = true;
            handle.cal_thrd_created = true;
        } else {
            ALOGE("%s: speaker calibration thread creation failed", __func__);
            destroy_thread_params();
@@ -1825,18 +1883,20 @@ int spkr_prot_deinit()
{
    int result = 0;

    ALOGD("%s: Entering deinit init_check :%d",
          __func__, handle.init_check);
    if(!handle.init_check)
        return -1;
    ALOGD("%s: Entering deinit cal_thrd_created :%d",
          __func__, handle.cal_thrd_created);

    handle.thread_exit = true;
    spkr_calibrate_signal();
    result = pthread_join(handle.spkr_calibration_thread, (void **) NULL);
    if (handle.cal_thrd_created) {
        result = pthread_join(handle.spkr_calibration_thread,
                              (void **) NULL);
        if (result < 0) {
            ALOGE("%s:Unable to join the calibration thread", __func__);
            return -1;
        }
        handle.cal_thrd_created = false;
    }
    destroy_thread_params();
    memset(&handle, 0, sizeof(handle));
    return 0;