diff options
Diffstat (limited to 'vibrator/cs40l26/Hardware.h')
-rw-r--r-- | vibrator/cs40l26/Hardware.h | 101 |
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); } |