summaryrefslogtreecommitdiff
path: root/vibrator/cs40l26/Hardware.h
diff options
context:
space:
mode:
Diffstat (limited to 'vibrator/cs40l26/Hardware.h')
-rw-r--r--vibrator/cs40l26/Hardware.h101
1 files changed, 93 insertions, 8 deletions
diff --git a/vibrator/cs40l26/Hardware.h b/vibrator/cs40l26/Hardware.h
index d5230fee..50e2cb66 100644
--- a/vibrator/cs40l26/Hardware.h
+++ b/vibrator/cs40l26/Hardware.h
@@ -144,11 +144,21 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
if (ioctl(fd, EVIOCGBIT(0, sizeof(val)), &val) > 0 && (val & (1 << EV_FF)) &&
ioctl(fd, EVIOCGNAME(sizeof(str)), &str) > 0 &&
strcmp(str, INPUT_EVENT_NAME.c_str()) == 0) {
+ // Get fd ready for input event ioctl().
mInputFd.reset(fd); // mInputFd.ok() becomes true.
ALOGI("Control %s through %s", INPUT_EVENT_NAME.c_str(), g.gl_pathv[i]);
- // Construct the sysfs device path.
std::string path = g.gl_pathv[i];
+ // Get fstream ready for input event write().
+ saveName(path, &mInputIoStream);
+ mInputIoStream.open(
+ path, std::fstream::out | std::fstream::in | std::fstream::binary);
+ if (!mInputIoStream) {
+ ALOGE("Failed to open %s (%d): %s", path.c_str(), errno,
+ strerror(errno));
+ }
+
+ // Construct the sysfs device path.
path = "/sys/class/input/" +
path.substr(path.find("event"), std::string::npos) + "/../../../";
updatePathPrefix(path);
@@ -185,9 +195,13 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
ALOGE("Invalid gain");
return false;
}
- if (write(mInputFd, (const void *)&gain, sizeof(gain)) != sizeof(gain)) {
+ mInputIoStream.write((const char *)&gain, sizeof(gain));
+ mInputIoStream.flush();
+ if (mInputIoStream.fail()) {
+ ALOGE("setFFGain fail");
return false;
}
+ HWAPI_RECORD(StringPrintf("%d%%", value), &mInputIoStream);
return true;
}
bool setFFEffect(struct ff_effect *effect, uint16_t timeoutMs) override {
@@ -199,9 +213,10 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
if (((*effect).replay.length != timeoutMs) || (ioctl(mInputFd, EVIOCSFF, effect) < 0)) {
ALOGE("setFFEffect fail");
return false;
- } else {
- return true;
}
+ HWAPI_RECORD(StringPrintf("#%d: %dms", (*effect).id, (*effect).replay.length),
+ &mInputIoStream);
+ return true;
}
bool setFFPlay(int8_t index, bool value) override {
ATRACE_NAME(StringPrintf("%s index:%d %s", __func__, index, value ? "on" : "off").c_str());
@@ -210,11 +225,14 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
.code = static_cast<uint16_t>(index),
.value = value,
};
- if (write(mInputFd, (const void *)&play, sizeof(play)) != sizeof(play)) {
+ mInputIoStream.write((const char *)&play, sizeof(play));
+ mInputIoStream.flush();
+ if (mInputIoStream.fail()) {
+ ALOGE("setFFPlay fail");
return false;
- } else {
- return true;
}
+ HWAPI_RECORD(StringPrintf("#%d: %b", index, value), &mInputIoStream);
+ return true;
}
bool getHapticAlsaDevice(int *card, int *device) override {
ATRACE_NAME(__func__);
@@ -227,6 +245,7 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
std::string currentToken;
std::getline(ss, currentToken, ':');
sscanf(currentToken.c_str(), "%d-%d", card, device);
+ saveName(StringPrintf("/dev/snd/pcmC%uD%up", *card, *device), &mPcmStream);
return true;
}
}
@@ -246,23 +265,27 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
ALOGE("cannot open pcm_out driver: %s", pcm_get_error(*haptic_pcm));
goto fail;
}
+ HWAPI_RECORD(std::string("pcm_open"), &mPcmStream);
ret = pcm_prepare(*haptic_pcm);
if (ret < 0) {
ALOGE("cannot prepare haptic_pcm: %s", pcm_get_error(*haptic_pcm));
goto fail;
}
+ HWAPI_RECORD(std::string("pcm_prepare"), &mPcmStream);
ret = pcm_start(*haptic_pcm);
if (ret < 0) {
ALOGE("cannot start haptic_pcm: %s", pcm_get_error(*haptic_pcm));
goto fail;
}
+ HWAPI_RECORD(std::string("pcm_start"), &mPcmStream);
return true;
} else {
if (*haptic_pcm) {
pcm_close(*haptic_pcm);
+ HWAPI_RECORD(std::string("pcm_close"), &mPcmStream);
*haptic_pcm = NULL;
}
return true;
@@ -270,6 +293,7 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
fail:
pcm_close(*haptic_pcm);
+ HWAPI_RECORD(std::string("pcm_close"), &mPcmStream);
*haptic_pcm = NULL;
return false;
}
@@ -308,6 +332,7 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
}
*outEffectIndex = (*effect).id;
*status = 0;
+ HWAPI_RECORD(StringPrintf("#%d: %dB", *outEffectIndex, numBytes), &mInputIoStream);
return true;
}
bool eraseOwtEffect(int8_t effectIndex, std::vector<ff_effect> *effect) override {
@@ -334,12 +359,14 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
break;
}
}
+ HWAPI_RECORD(StringPrintf("#%d", effectIndex), &mInputIoStream);
} else {
/* Flush all non-prestored effects of ff-core and driver. */
getEffectCount(&effectCountBefore);
for (i = WAVEFORM_MAX_PHYSICAL_INDEX; i < FF_MAX_EFFECTS; i++) {
if (ioctl(mInputFd, EVIOCRMFF, i) >= 0) {
successFlush++;
+ HWAPI_RECORD(StringPrintf("#%d", i), &mInputIoStream);
}
}
getEffectCount(&effectCountAfter);
@@ -352,10 +379,57 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
}
return true;
}
+ bool isDbcSupported() override {
+ ATRACE_NAME(__func__);
+ return utils::getProperty("ro.vendor.vibrator.hal.dbc.enable", false);
+ }
+
+ bool enableDbc() override {
+ ATRACE_NAME(__func__);
+ if (isDbcSupported()) {
+ open("dbc/dbc_env_rel_coef", &mDbcEnvRelCoef);
+ open("dbc/dbc_rise_headroom", &mDbcRiseHeadroom);
+ open("dbc/dbc_fall_headroom", &mDbcFallHeadroom);
+ open("dbc/dbc_tx_lvl_thresh_fs", &mDbcTxLvlThreshFs);
+ open("dbc/dbc_tx_lvl_hold_off_ms", &mDbcTxLvlHoldOffMs);
+ open("default/pm_active_timeout_ms", &mPmActiveTimeoutMs);
+ open("dbc/dbc_enable", &mDbcEnable);
+
+ // Set values from config. Default if not found.
+ set(utils::getProperty("ro.vendor.vibrator.hal.dbc.envrelcoef", kDbcDefaultEnvRelCoef),
+ &mDbcEnvRelCoef);
+ set(utils::getProperty("ro.vendor.vibrator.hal.dbc.riseheadroom",
+ kDbcDefaultRiseHeadroom),
+ &mDbcRiseHeadroom);
+ set(utils::getProperty("ro.vendor.vibrator.hal.dbc.fallheadroom",
+ kDbcDefaultFallHeadroom),
+ &mDbcFallHeadroom);
+ set(utils::getProperty("ro.vendor.vibrator.hal.dbc.txlvlthreshfs",
+ kDbcDefaultTxLvlThreshFs),
+ &mDbcTxLvlThreshFs);
+ set(utils::getProperty("ro.vendor.vibrator.hal.dbc.txlvlholdoffms",
+ kDbcDefaultTxLvlHoldOffMs),
+ &mDbcTxLvlHoldOffMs);
+ set(utils::getProperty("ro.vendor.vibrator.hal.pm.activetimeout",
+ kDefaultPmActiveTimeoutMs),
+ &mPmActiveTimeoutMs);
+ set(kDbcEnable, &mDbcEnable);
+ return true;
+ }
+ return false;
+ }
void debug(int fd) override { HwApiBase::debug(fd); }
private:
+ static constexpr uint32_t kDbcDefaultEnvRelCoef = 8353728;
+ static constexpr uint32_t kDbcDefaultRiseHeadroom = 1909602;
+ static constexpr uint32_t kDbcDefaultFallHeadroom = 1909602;
+ static constexpr uint32_t kDbcDefaultTxLvlThreshFs = 2516583;
+ static constexpr uint32_t kDbcDefaultTxLvlHoldOffMs = 0;
+ static constexpr uint32_t kDefaultPmActiveTimeoutMs = 5;
+ static constexpr uint32_t kDbcEnable = 1;
+
std::ofstream mF0;
std::ofstream mF0Offset;
std::ofstream mRedc;
@@ -366,7 +440,18 @@ class HwApi : public Vibrator::HwApi, private HwApiBase {
std::ofstream mF0CompEnable;
std::ofstream mRedcCompEnable;
std::ofstream mMinOnOffInterval;
+ std::ofstream mInputIoStream;
+ std::ofstream mPcmStream;
::android::base::unique_fd mInputFd;
+
+ // DBC Parameters
+ std::ofstream mDbcEnvRelCoef;
+ std::ofstream mDbcRiseHeadroom;
+ std::ofstream mDbcFallHeadroom;
+ std::ofstream mDbcTxLvlThreshFs;
+ std::ofstream mDbcTxLvlHoldOffMs;
+ std::ofstream mDbcEnable;
+ std::ofstream mPmActiveTimeoutMs;
};
class HwCal : public Vibrator::HwCal, private HwCalBase {
@@ -445,7 +530,7 @@ class HwCal : public Vibrator::HwCal, private HwCalBase {
}
bool isRedcCompEnabled() override {
bool value;
- getProperty("redc.comp.enabled", &value, true);
+ getProperty("redc.comp.enabled", &value, false);
return value;
}
void debug(int fd) override { HwCalBase::debug(fd); }