vibrator: cs40l25: add pwle_ramp_down feature
Add the pwle_ramp_down feature and set the ramp down time to be 50 ms to
match with frameworks
Bug: 200713702
Test: verified that pwle_ramp_down node works as expected, there is no
click effect when a waveform is cancelled and regression testing passed
Change-Id: Id75cf8c4456b22887135bd7bf206516f26415157
Signed-off-by: Vince Leung <leungv@google.com>
diff --git a/vibrator/cs40l25/Hardware.h b/vibrator/cs40l25/Hardware.h
index d1883e5..f74fe93 100644
--- a/vibrator/cs40l25/Hardware.h
+++ b/vibrator/cs40l25/Hardware.h
@@ -48,6 +48,7 @@
open("device/clab_enable", &mClabEnable);
open("device/available_pwle_segments", &mAvailablePwleSegments);
open("device/pwle", &mPwle);
+ open("device/pwle_ramp_down", &mPwleRampDown);
}
bool setF0(uint32_t value) override { return set(value, &mF0); }
@@ -76,6 +77,7 @@
bool getAvailablePwleSegments(uint32_t *value) override { return get(value, &mAvailablePwleSegments); }
bool hasPwle() override { return has(mPwle); }
bool setPwle(std::string value) override { return set(value, &mPwle); }
+ bool setPwleRampDown(uint32_t value) override { return set(value, &mPwleRampDown); }
void debug(int fd) override { HwApiBase::debug(fd); }
private:
@@ -101,6 +103,7 @@
std::ofstream mClabEnable;
std::ifstream mAvailablePwleSegments;
std::ofstream mPwle;
+ std::ofstream mPwleRampDown;
};
class HwCal : public Vibrator::HwCal, private HwCalBase {
diff --git a/vibrator/cs40l25/Vibrator.cpp b/vibrator/cs40l25/Vibrator.cpp
index 350c999..8110cb3 100644
--- a/vibrator/cs40l25/Vibrator.cpp
+++ b/vibrator/cs40l25/Vibrator.cpp
@@ -101,6 +101,8 @@
static constexpr float PWLE_FREQUENCY_MAX_HZ = 1023.75;
static constexpr float PWLE_BW_MAP_SIZE =
1 + ((PWLE_FREQUENCY_MAX_HZ - PWLE_FREQUENCY_MIN_HZ) / PWLE_FREQUENCY_RESOLUTION_HZ);
+static constexpr float RAMP_DOWN_CONSTANT = 1048.576;
+static constexpr float RAMP_DOWN_TIME_MS = 50.0;
static struct pcm_config haptic_nohost_config = {
.channels = 1,
@@ -233,6 +235,7 @@
createPwleMaxLevelLimitMap();
mIsUnderExternalControl = false;
+ setPwleRampDown();
}
ndk::ScopedAStatus Vibrator::getCapabilities(int32_t *_aidl_return) {
@@ -1147,6 +1150,22 @@
return false;
}
+void Vibrator::setPwleRampDown() {
+ // The formula for calculating the ramp down coefficient to be written into
+ // pwle_ramp_down is as follows:
+ // Crd = 1048.576 / Trd
+ // where Trd is the desired ramp down time in seconds
+ // pwle_ramp_down accepts only 24 bit integers values
+
+ const float seconds = RAMP_DOWN_TIME_MS / 1000;
+ const auto ramp_down_coefficient = static_cast<uint32_t>(RAMP_DOWN_CONSTANT / seconds);
+
+ if (!mHwApi->setPwleRampDown(ramp_down_coefficient)) {
+ ALOGE("Failed to write \"%d\" to pwle_ramp_down (%d): %s", ramp_down_coefficient, errno,
+ strerror(errno));
+ }
+}
+
} // namespace vibrator
} // namespace hardware
} // namespace android
diff --git a/vibrator/cs40l25/Vibrator.h b/vibrator/cs40l25/Vibrator.h
index 08a115e..88f7abd 100644
--- a/vibrator/cs40l25/Vibrator.h
+++ b/vibrator/cs40l25/Vibrator.h
@@ -101,6 +101,9 @@
// Specifies piecewise-linear specifications to generate complex
// waveforms.
virtual bool setPwle(std::string value) = 0;
+ // Specifies the coefficient required for a ramp down when a waveform
+ // ends
+ virtual bool setPwleRampDown(uint32_t value) = 0;
// Emit diagnostic information to the given file.
virtual void debug(int fd) = 0;
};
@@ -200,6 +203,7 @@
bool hasHapticAlsaDevice();
bool enableHapticPcmAmp(struct pcm **haptic_pcm, bool enable, int card, int device);
void createPwleMaxLevelLimitMap();
+ void setPwleRampDown();
std::unique_ptr<HwApi> mHwApi;
std::unique_ptr<HwCal> mHwCal;
diff --git a/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.rc b/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.rc
index 3f28d81..f373d31 100644
--- a/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.rc
+++ b/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.rc
@@ -34,6 +34,7 @@
chown system system /sys/class/leds/vibrator/device/hw_reset
chown system system /sys/class/leds/vibrator/device/num_waves
chown system system /sys/class/leds/vibrator/device/pwle
+ chown system system /sys/class/leds/vibrator/device/pwle_ramp_down
chown system system /sys/class/leds/vibrator/device/q_stored
chown system system /sys/class/leds/vibrator/device/redc_comp_enable
chown system system /sys/class/leds/vibrator/device/redc_stored
@@ -67,6 +68,7 @@
device/heartbeat
device/num_waves
device/pwle
+ device/pwle_ramp_down
device/q_stored
device/redc_stored
state
diff --git a/vibrator/cs40l25/tests/mocks.h b/vibrator/cs40l25/tests/mocks.h
index 2c69e27..8f2c672 100644
--- a/vibrator/cs40l25/tests/mocks.h
+++ b/vibrator/cs40l25/tests/mocks.h
@@ -49,6 +49,7 @@
MOCK_METHOD1(getAvailablePwleSegments, bool(uint32_t *value));
MOCK_METHOD0(hasPwle, bool());
MOCK_METHOD1(setPwle, bool(std::string value));
+ MOCK_METHOD1(setPwleRampDown, bool(uint32_t value));
MOCK_METHOD1(debug, void(int fd));
~MockApi() override { destructor(); };
diff --git a/vibrator/cs40l25/tests/test-hwapi.cpp b/vibrator/cs40l25/tests/test-hwapi.cpp
index 7f2ae01..a339207 100644
--- a/vibrator/cs40l25/tests/test-hwapi.cpp
+++ b/vibrator/cs40l25/tests/test-hwapi.cpp
@@ -55,6 +55,7 @@
"device/num_waves",
"device/available_pwle_segments",
"device/pwle",
+ "device/pwle_ramp_down",
};
public:
@@ -319,6 +320,8 @@
&Vibrator::HwApi::setGpioRiseIndex),
SetUint32Test::MakeParam("device/gpio1_rise_dig_scale",
&Vibrator::HwApi::setGpioRiseScale),
+ SetUint32Test::MakeParam("device/pwle_ramp_down",
+ &Vibrator::HwApi::setPwleRampDown),
}),
SetUint32Test::PrintParam);