diff --git a/vibrator/common/HardwareBase.cpp b/vibrator/common/HardwareBase.cpp index 8e07e99..8e819bb 100644 --- a/vibrator/common/HardwareBase.cpp +++ b/vibrator/common/HardwareBase.cpp @@ -71,6 +71,7 @@ void HwApiBase::debug(int fd) { HwCalBase::HwCalBase() { std::ifstream calfile; + std::ifstream calfile_other; auto propertyPrefix = std::getenv("PROPERTY_PREFIX"); if (propertyPrefix != NULL) { @@ -91,6 +92,20 @@ HwCalBase::HwCalBase() { mCalData[utils::trim(key)] = utils::trim(value); } } + + utils::fileFromEnv("CALIBRATION_FILEPATH_OTHER", &calfile_other); + + for (std::string line; std::getline(calfile_other, line);) { + if (line.empty() || line[0] == '#') { + continue; + } + std::istringstream is_line(line); + std::string key, value; + if (std::getline(is_line, key, ':') && std::getline(is_line, value)) { + key = utils::trim(key) + "_other"; + mCalData[key] = utils::trim(value); + } + } } void HwCalBase::debug(int fd) { diff --git a/vibrator/cs40l26/Hardware.h b/vibrator/cs40l26/Hardware.h index 9cf831c..4866287 100644 --- a/vibrator/cs40l26/Hardware.h +++ b/vibrator/cs40l26/Hardware.h @@ -16,6 +16,7 @@ #pragma once #include +#include #include "HardwareBase.h" #include "Vibrator.h" @@ -281,6 +282,7 @@ class HwCal : public Vibrator::HwCal, private HwCalBase { private: static constexpr char VERSION[] = "version"; static constexpr char F0_CONFIG[] = "f0_measured"; + static constexpr char F0_CONFIG_OTHER[] = "f0_measured_other"; static constexpr char REDC_CONFIG[] = "redc_measured"; static constexpr char Q_CONFIG[] = "q_measured"; static constexpr char TICK_VOLTAGES_CONFIG[] = "v_tick"; @@ -307,6 +309,30 @@ class HwCal : public Vibrator::HwCal, private HwCalBase { return getProperty("long.frequency.shift", value, DEFAULT_FREQUENCY_SHIFT); } bool getF0(std::string *value) override { return getPersist(F0_CONFIG, value); } + bool getF0SyncOffset(uint32_t *value) override { + std::string cal_0{8, '0'}; + std::string cal_1{8, '0'}; + + if (getPersist(F0_CONFIG, &cal_0) && getPersist(F0_CONFIG_OTHER, &cal_1)) { + float f0_0 = static_cast(std::stoul(cal_0, nullptr, 16)) / (1 << 14); + float f0_1 = static_cast(std::stoul(cal_1, nullptr, 16)) / (1 << 14); + float f0_offset = std::abs(f0_0 - f0_1)/2; + + if (f0_0 < f0_1) { + *value = static_cast(f0_offset * std::pow(2, 14)); + } else if (f0_0 > f0_1) { + *value = static_cast(std::pow(2, 24) - std::abs(f0_offset) * std::pow(2, 14)); + } else { + *value = 0; + } + + return true; + } else { + ALOGI("Vibrator: Unable to load F0_CONFIG or F0_CONFIG_OTHER config"); + *value = 0; + return false; + } + } bool getRedc(std::string *value) override { return getPersist(REDC_CONFIG, value); } bool getQ(std::string *value) override { return getPersist(Q_CONFIG, value); } bool getTickVolLevels(std::array *value) override { diff --git a/vibrator/cs40l26/Vibrator.cpp b/vibrator/cs40l26/Vibrator.cpp index 6b34a05..cd3d373 100644 --- a/vibrator/cs40l26/Vibrator.cpp +++ b/vibrator/cs40l26/Vibrator.cpp @@ -349,13 +349,18 @@ Vibrator::Vibrator(std::unique_ptr hwapi, std::unique_ptr hwcal) mHwApi->setQ(caldata); } - mHwCal->getLongFrequencyShift(&longFrequencyShift); - if (longFrequencyShift > 0) { - mF0Offset = longFrequencyShift * std::pow(2, 14); - } else if (longFrequencyShift < 0) { - mF0Offset = std::pow(2, 24) - std::abs(longFrequencyShift) * std::pow(2, 14); + if (mHwCal->getF0SyncOffset(&mF0Offset)) { + ALOGI("Vibrator::Vibrator: F0 offset calculated from both base and flip calibration data: %u", mF0Offset); } else { + mHwCal->getLongFrequencyShift(&longFrequencyShift); + if (longFrequencyShift > 0) { + mF0Offset = longFrequencyShift * std::pow(2, 14); + } else if (longFrequencyShift < 0) { + mF0Offset = std::pow(2, 24) - std::abs(longFrequencyShift) * std::pow(2, 14); + } else { mF0Offset = 0; + } + ALOGI("Vibrator::Vibrator: F0 offset calculated from long shift frequency: %u", mF0Offset); } mHwCal->getVersion(&calVer); diff --git a/vibrator/cs40l26/Vibrator.h b/vibrator/cs40l26/Vibrator.h index 578a86a..e96badb 100644 --- a/vibrator/cs40l26/Vibrator.h +++ b/vibrator/cs40l26/Vibrator.h @@ -100,6 +100,9 @@ class Vibrator : public BnVibrator { // Obtains the LRA resonant frequency to be used for PWLE playback // and click compensation. virtual bool getF0(std::string *value) = 0; + // Obtains the offset for actuator that will adjust configured F0 to target + // frequency for dual actuators + virtual bool getF0SyncOffset(uint32_t *value) = 0; // Obtains the LRA series resistance to be used for click // compensation. virtual bool getRedc(std::string *value) = 0; diff --git a/vibrator/cs40l26/android.hardware.vibrator-service.cs40l26-private.rc b/vibrator/cs40l26/android.hardware.vibrator-service.cs40l26-private.rc index b12c359..838b76f 100644 --- a/vibrator/cs40l26/android.hardware.vibrator-service.cs40l26-private.rc +++ b/vibrator/cs40l26/android.hardware.vibrator-service.cs40l26-private.rc @@ -43,6 +43,7 @@ service vendor.vibrator.cs40l26 /vendor/bin/hw/android.hardware.vibrator-service setenv INPUT_EVENT_PATH /dev/input/event* setenv PROPERTY_PREFIX ro.vendor.vibrator.hal. setenv CALIBRATION_FILEPATH /mnt/vendor/persist/haptics/cs40l26.cal + setenv CALIBRATION_FILEPATH_OTHER /mnt/vendor/persist/haptics/cs40l26_dual.cal setenv HWAPI_PATH_PREFIX /sys/bus/i2c/devices/i2c-cs40l26a/ setenv HWAPI_DEBUG_PATHS " @@ -70,6 +71,7 @@ service vendor.vibrator.cs40l26-dual /vendor/bin/hw/android.hardware.vibrator-se setenv INPUT_EVENT_PATH /dev/input/event* setenv PROPERTY_PREFIX ro.vendor.vibrator.hal. setenv CALIBRATION_FILEPATH /mnt/vendor/persist/haptics/cs40l26_dual.cal + setenv CALIBRATION_FILEPATH_OTHER /mnt/vendor/persist/haptics/cs40l26.cal setenv HWAPI_PATH_PREFIX /sys/bus/i2c/devices/i2c-cs40l26a-dual/ setenv HWAPI_DEBUG_PATHS " diff --git a/vibrator/cs40l26/tests/mocks.h b/vibrator/cs40l26/tests/mocks.h index e497f2a..cf33815 100644 --- a/vibrator/cs40l26/tests/mocks.h +++ b/vibrator/cs40l26/tests/mocks.h @@ -54,6 +54,7 @@ class MockCal : public ::aidl::android::hardware::vibrator::Vibrator::HwCal { MOCK_METHOD0(destructor, void()); MOCK_METHOD1(getVersion, bool(uint32_t *value)); MOCK_METHOD1(getF0, bool(std::string &value)); + MOCK_METHOD1(getF0SyncOffset, bool(uint32_t *value)); MOCK_METHOD1(getRedc, bool(std::string &value)); MOCK_METHOD1(getQ, bool(std::string &value)); MOCK_METHOD1(getLongFrequencyShift, bool(int32_t *value));