diff --git a/audio/felix/config/audio_policy_configuration_a2dp_offload_disabled.xml b/audio/felix/config/audio_policy_configuration_a2dp_offload_disabled.xml
index da6c7a7..5b97dd8 100644
--- a/audio/felix/config/audio_policy_configuration_a2dp_offload_disabled.xml
+++ b/audio/felix/config/audio_policy_configuration_a2dp_offload_disabled.xml
@@ -59,7 +59,7 @@
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
-
diff --git a/audio/felix/config/audio_policy_configuration_bluetooth_legacy_hal.xml b/audio/felix/config/audio_policy_configuration_bluetooth_legacy_hal.xml
index 416d4ab..fb54198 100644
--- a/audio/felix/config/audio_policy_configuration_bluetooth_legacy_hal.xml
+++ b/audio/felix/config/audio_policy_configuration_bluetooth_legacy_hal.xml
@@ -59,7 +59,7 @@
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
-
-
diff --git a/audio/felix/config/bluetooth_with_le_audio_policy_configuration_7_0.xml b/audio/felix/config/bluetooth_with_le_audio_policy_configuration_7_0.xml
index 8b2af59..efd7277 100644
--- a/audio/felix/config/bluetooth_with_le_audio_policy_configuration_7_0.xml
+++ b/audio/felix/config/bluetooth_with_le_audio_policy_configuration_7_0.xml
@@ -11,6 +11,7 @@
channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+
+
+ sources="le audio output"/>
+
\ No newline at end of file
diff --git a/conf/init.felix.rc b/conf/init.felix.rc
index 47475e3..46a8980 100644
--- a/conf/init.felix.rc
+++ b/conf/init.felix.rc
@@ -86,7 +86,7 @@ on early-boot
start insmod_sh_felix
chown system system /sys/class/power_supply/dualbatt/dbatt_stats
-service insmod_sh_felix /vendor/bin/insmod.sh /vendor/etc/init.insmod.felix.cfg
+service insmod_sh_felix /vendor/bin/insmod.sh /vendor_dlkm/etc/init.insmod.felix.cfg
class main
user root
group root system
diff --git a/device-felix.mk b/device-felix.mk
index a8f0192..1462ad5 100644
--- a/device-felix.mk
+++ b/device-felix.mk
@@ -41,8 +41,8 @@ $(call soong_config_set,fp_hal_feature,pixel_product, product_a)
include device/google/felix/vibrator/cs40l26/device.mk
include device/google/gs-common/bcmbt/bluetooth.mk
include device/google/gs-common/display/dump_second_display.mk
-include device/google/gs-common/touch/gti/gti.mk
-include device/google/gs-common/touch/stm/stm6.mk
+include device/google/gs-common/touch/gti/predump_gti_dual.mk
+include device/google/gs-common/touch/stm/predump_stm6.mk
ifeq ($(filter factory_felix, $(TARGET_PRODUCT)),)
include device/google/felix/uwb/uwb_calibration.mk
endif
@@ -60,9 +60,13 @@ PRODUCT_COPY_FILES += \
PRODUCT_COPY_FILES += \
device/google/felix/conf/init.recovery.device.rc:$(TARGET_COPY_OUT_RECOVERY)/root/init.recovery.felix.rc
-# insmod files
+# insmod files. Kernel 5.10 prebuilts don't provide these yet, so provide our
+# own copy if they're not in the prebuilts.
+# TODO(b/369686096): drop this when 5.10 is gone.
+ifeq ($(wildcard $(TARGET_KERNEL_DIR)/init.insmod.*.cfg),)
PRODUCT_COPY_FILES += \
- device/google/felix/init.insmod.felix.cfg:$(TARGET_COPY_OUT_VENDOR)/etc/init.insmod.felix.cfg
+ device/google/felix/init.insmod.felix.cfg:$(TARGET_COPY_OUT_VENDOR_DLKM)/etc/init.insmod.felix.cfg
+endif
# Camera
PRODUCT_COPY_FILES += \
@@ -108,6 +112,12 @@ PRODUCT_PACKAGES += \
android.hardware.nfc-service.st \
NfcOverlayFelix
+# Shared Modem Platform
+SHARED_MODEM_PLATFORM_VENDOR := lassen
+
+# Shared Modem Platform
+include device/google/gs-common/modem/modem_svc_sit/shared_modem_platform.mk
+
# SecureElement
PRODUCT_PACKAGES += \
android.hardware.secure_element@1.2-service-gto \
@@ -423,7 +433,7 @@ PRODUCT_COPY_FILES += \
# LE Audio Unicast Allowlist
PRODUCT_PRODUCT_PROPERTIES += \
- persist.bluetooth.leaudio.allow_list=SM-R510,WF-1000XM5
+ persist.bluetooth.leaudio.allow_list=SM-R510,WF-1000XM5,SM-R630
# Bluetooth EWP test tool
PRODUCT_PACKAGES_ENG += \
diff --git a/felix/overlay/frameworks/base/core/res/res/xml/power_profile.xml b/felix/overlay/frameworks/base/core/res/res/xml/power_profile.xml
index b633087..1c8a7e5 100644
--- a/felix/overlay/frameworks/base/core/res/res/xml/power_profile.xml
+++ b/felix/overlay/frameworks/base/core/res/res/xml/power_profile.xml
@@ -151,13 +151,17 @@
- - 32
+ - 32
+ - 32
- - 98
+ - 98
+ - 98
+
- - 470
+ - 470
+ - 470
- 240.47
diff --git a/nfc/libnfc-hal-st.conf b/nfc/libnfc-hal-st.conf
index 7300e21..ac8c20d 100644
--- a/nfc/libnfc-hal-st.conf
+++ b/nfc/libnfc-hal-st.conf
@@ -135,7 +135,7 @@ OFFHOST_ROUTE_ESE={86}
# host 0x00
# eSE 0x82 (eSE), 0x86 (eUICC/SPI-SE)
# UICC 0x81 (UICC_1), 0x85 (UICC_2)
-DEFAULT_ISODEP_ROUTE=0x81
+DEFAULT_ISODEP_ROUTE=0x00
###############################################################################
# Configure the HAL Clock control
diff --git a/powerhint.json b/powerhint.json
index 1c88dd5..2074a8e 100644
--- a/powerhint.json
+++ b/powerhint.json
@@ -879,24 +879,30 @@
"Duration": 5000,
"Value": "0"
},
- {
- "PowerHint": "CPU_LOAD_RESET",
- "Node": "GPUMinFreq",
- "Duration": 50,
- "Value": "302000"
- },
{
"PowerHint": "DISPLAY_INACTIVE",
"Node": "MemFreq",
"Duration": 0,
"Value": "421000"
},
+ {
+ "PowerHint": "CPU_LOAD_RESET",
+ "Node": "GPUMinFreq",
+ "Duration": 50,
+ "Value": "302000"
+ },
{
"PowerHint": "CPU_LOAD_RESET",
"Node": "MemFreq",
"Duration": 33,
"Value": "1014000"
},
+ {
+ "PowerHint": "CPU_LOAD_RESET",
+ "Node": "TAPreferHighCap",
+ "Duration": 33,
+ "Value": "1"
+ },
{
"PowerHint": "CAMERA_LAUNCH",
"Node": "MemFreq",
@@ -1107,6 +1113,18 @@
"Duration": 100,
"Value": "0"
},
+ {
+ "PowerHint": "CAMERA_MULTICAM_BOOST",
+ "Node": "CDPreferIdle",
+ "Duration": 100,
+ "Value": "1"
+ },
+ {
+ "PowerHint": "CAMERA_MULTICAM_BOOST",
+ "Node": "PMU_POLL",
+ "Duration": 100,
+ "Value": "0"
+ },
{
"PowerHint": "GCA_CAMERA_SHOT_BIGCPU_RANK1",
"Node": "TAPreferHighCap",
diff --git a/rro_overlays/WifiOverlay/res/values/config.xml b/rro_overlays/WifiOverlay/res/values/config.xml
index 8e45a9f..516591f 100644
--- a/rro_overlays/WifiOverlay/res/values/config.xml
+++ b/rro_overlays/WifiOverlay/res/values/config.xml
@@ -175,4 +175,6 @@
false: firmware roaming will not be affected. -->
true
+
+ false
diff --git a/vibrator/OWNERS b/vibrator/OWNERS
index dec74a8..fc59b13 100644
--- a/vibrator/OWNERS
+++ b/vibrator/OWNERS
@@ -1 +1,3 @@
-file:platform/hardware/google/pixel:/vibrator/OWNERS
+chrispaulo@google.com
+nathankulczak@google.com
+taikuo@google.com
diff --git a/vibrator/common/HardwareBase.cpp b/vibrator/common/HardwareBase.cpp
index 329293a..583caaa 100644
--- a/vibrator/common/HardwareBase.cpp
+++ b/vibrator/common/HardwareBase.cpp
@@ -69,6 +69,7 @@ HwCalBase::HwCalBase() {
std::ifstream calfile;
std::ifstream calfile_dual;
auto propertyPrefix = std::getenv("PROPERTY_PREFIX");
+ auto calPath = std::getenv("CALIBRATION_FILEPATH");
if (propertyPrefix != NULL) {
mPropertyPrefix = std::string(propertyPrefix);
@@ -76,6 +77,14 @@ HwCalBase::HwCalBase() {
ALOGE("Failed get property prefix!");
}
+ // Keep the cal file path for the current HwCalBase instance.
+ if (calPath != NULL) {
+ mCalPath = std::string(calPath);
+ } else {
+ ALOGE("Failed get the calibration file path!");
+ }
+
+ // Read the cal data for the current instance.
utils::fileFromEnv("CALIBRATION_FILEPATH", &calfile);
for (std::string line; std::getline(calfile, line);) {
@@ -89,6 +98,7 @@ HwCalBase::HwCalBase() {
}
}
+ // Read the cal data for the other instance.
utils::fileFromEnv("CALIBRATION_FILEPATH_DUAL", &calfile_dual);
for (std::string line; std::getline(calfile_dual, line);) {
@@ -106,7 +116,6 @@ HwCalBase::HwCalBase() {
void HwCalBase::debug(int fd) {
std::ifstream stream;
- std::string path;
std::string line;
struct context {
HwCalBase *obj;
@@ -133,9 +142,8 @@ void HwCalBase::debug(int fd) {
dprintf(fd, "Persist:\n");
- utils::fileFromEnv("CALIBRATION_FILEPATH", &stream, &path);
-
- dprintf(fd, " %s:\n", path.c_str());
+ utils::openNoCreate(mCalPath, &stream);
+ dprintf(fd, " %s:\n", mCalPath.c_str());
while (std::getline(stream, line)) {
dprintf(fd, " %s\n", line.c_str());
}
diff --git a/vibrator/common/HardwareBase.h b/vibrator/common/HardwareBase.h
index f09fada..0296390 100644
--- a/vibrator/common/HardwareBase.h
+++ b/vibrator/common/HardwareBase.h
@@ -208,6 +208,7 @@ class HwCalBase {
private:
std::string mPropertyPrefix;
+ std::string mCalPath;
std::map mCalData;
};
diff --git a/vibrator/common/utils.h b/vibrator/common/utils.h
index 86dd37e..b5005a6 100644
--- a/vibrator/common/utils.h
+++ b/vibrator/common/utils.h
@@ -103,6 +103,19 @@ inline Enable_If_Unsigned getProperty(const std::string &key, const T def)
return ::android::base::GetUintProperty(key, def);
}
+template
+inline std::array getProperty(const std::string &key, const std::array &def) {
+ std::string value = ::android::base::GetProperty(key, "");
+ if (!value.empty()) {
+ std::array result{0};
+ std::stringstream stream{value};
+ utils::unpack(stream, &result);
+ if (stream && stream.eof())
+ return result;
+ }
+ return def;
+}
+
template <>
inline bool getProperty(const std::string &key, const bool def) {
return ::android::base::GetBoolProperty(key, def);
diff --git a/vibrator/cs40l26/Android.bp b/vibrator/cs40l26/Android.bp
index bd5047a..e929343 100644
--- a/vibrator/cs40l26/Android.bp
+++ b/vibrator/cs40l26/Android.bp
@@ -60,7 +60,7 @@ cc_library {
srcs: [
"Vibrator.cpp",
],
- shared_libs: ["//hardware/google/pixel:PixelVibratorFlagsL26"],
+ shared_libs: ["//device/google/gs-common:PixelVibratorFlagsL26"],
export_include_dirs: ["."],
vendor_available: true,
visibility: [":__subpackages__"],
diff --git a/vibrator/cs40l26/Hardware.h b/vibrator/cs40l26/Hardware.h
index e2c2d36..e4dd344 100644
--- a/vibrator/cs40l26/Hardware.h
+++ b/vibrator/cs40l26/Hardware.h
@@ -318,9 +318,9 @@ class HwCal : public Vibrator::HwCal, private HwCalBase {
static constexpr uint32_t VERSION_DEFAULT = 2;
static constexpr int32_t DEFAULT_FREQUENCY_SHIFT = 0;
- static constexpr std::array V_TICK_DEFAULT = {1, 100};
- static constexpr std::array V_CLICK_DEFAULT = {1, 100};
- static constexpr std::array V_LONG_DEFAULT = {1, 100};
+ static constexpr std::array V_TICK_DEFAULT = {5, 95};
+ static constexpr std::array V_CLICK_DEFAULT = {5, 95};
+ static constexpr std::array V_LONG_DEFAULT = {5, 95};
public:
HwCal() {}
@@ -370,22 +370,19 @@ class HwCal : public Vibrator::HwCal, private HwCalBase {
if (getPersist(TICK_VOLTAGES_CONFIG, value)) {
return true;
}
- *value = V_TICK_DEFAULT;
- return true;
+ return getProperty(TICK_VOLTAGES_CONFIG, value, V_TICK_DEFAULT);
}
bool getClickVolLevels(std::array *value) override {
if (getPersist(CLICK_VOLTAGES_CONFIG, value)) {
return true;
}
- *value = V_CLICK_DEFAULT;
- return true;
+ return getProperty(CLICK_VOLTAGES_CONFIG, value, V_CLICK_DEFAULT);
}
bool getLongVolLevels(std::array *value) override {
if (getPersist(LONG_VOLTAGES_CONFIG, value)) {
return true;
}
- *value = V_LONG_DEFAULT;
- return true;
+ return getProperty(LONG_VOLTAGES_CONFIG, value, V_LONG_DEFAULT);
}
bool isChirpEnabled() override {
return utils::getProperty("persist.vendor.vibrator.hal.chirp.enabled", false);
diff --git a/vibrator/cs40l26/Vibrator.cpp b/vibrator/cs40l26/Vibrator.cpp
index 0fe4880..36d8e8c 100644
--- a/vibrator/cs40l26/Vibrator.cpp
+++ b/vibrator/cs40l26/Vibrator.cpp
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -92,6 +93,30 @@ static constexpr uint8_t PWLE_CHIRP_BIT = 0x8; // Dynamic/static frequency and
static constexpr uint8_t PWLE_BRAKE_BIT = 0x4;
static constexpr uint8_t PWLE_AMP_REG_BIT = 0x2;
+static constexpr uint8_t PWLE_WT_TYPE = 12;
+static constexpr uint8_t PWLE_HEADER_WORD_COUNT = 3;
+static constexpr uint8_t PWLE_HEADER_FTR_SHIFT = 8;
+static constexpr uint8_t PWLE_SVC_METADATA_WORD_COUNT = 3;
+static constexpr uint32_t PWLE_SVC_METADATA_TERMINATOR = 0xFFFFFF;
+static constexpr uint8_t PWLE_SEGMENT_WORD_COUNT = 2;
+static constexpr uint8_t PWLE_HEADER_WCOUNT_WORD_OFFSET = 2;
+static constexpr uint8_t PWLE_WORD_SIZE = sizeof(uint32_t);
+
+static constexpr uint8_t PWLE_SVC_NO_BRAKING = -1;
+static constexpr uint8_t PWLE_SVC_CAT_BRAKING = 0;
+static constexpr uint8_t PWLE_SVC_OPEN_BRAKING = 1;
+static constexpr uint8_t PWLE_SVC_CLOSED_BRAKING = 2;
+static constexpr uint8_t PWLE_SVC_MIXED_BRAKING = 3;
+
+static constexpr uint32_t PWLE_SVC_MAX_BRAKING_TIME_MS = 1000;
+
+static constexpr uint8_t PWLE_FTR_BUZZ_BIT = 0x80;
+static constexpr uint8_t PWLE_FTR_CLICK_BIT = 0x00;
+static constexpr uint8_t PWLE_FTR_DYNAMIC_F0_BIT = 0x10;
+static constexpr uint8_t PWLE_FTR_SVC_METADATA_BIT = 0x04;
+static constexpr uint8_t PWLE_FTR_DVL_BIT = 0x02;
+static constexpr uint8_t PWLE_FTR_LF0T_BIT = 0x01;
+
static constexpr float PWLE_LEVEL_MIN = 0.0;
static constexpr float PWLE_LEVEL_MAX = 1.0;
static constexpr float CS40L26_PWLE_LEVEL_MIN = -1.0;
@@ -170,6 +195,8 @@ enum vibe_state {
VIBE_STATE_ASP,
};
+std::mutex mActiveId_mutex; // protects mActiveId
+
class DspMemChunk {
private:
std::unique_ptr head;
@@ -245,10 +272,18 @@ class DspMemChunk {
write(8, 0); /* nsections placeholder */
write(8, 0); /* repeat */
} else if (waveformType == WAVEFORM_PWLE) {
+ write(16, (PWLE_FTR_BUZZ_BIT | PWLE_FTR_DVL_BIT)
+ << PWLE_HEADER_FTR_SHIFT); /* Feature flag */
+ write(8, PWLE_WT_TYPE); /* type12 */
+ write(24, PWLE_HEADER_WORD_COUNT); /* Header word count */
+ write(24, 0); /* Body word count placeholder */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)
write(24, 0); /* Waveform length placeholder */
write(8, 0); /* Repeat */
write(12, 0); /* Wait time between repeats */
write(8, 0); /* nsections placeholder */
+#endif
} else {
ALOGE("%s: Invalid type: %u", __func__, waveformType);
}
@@ -336,6 +371,9 @@ class DspMemChunk {
ALOGE("%s: Invalid argument: %u", __func__, totalDuration);
return -EINVAL;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)
+ f += PWLE_HEADER_WORD_COUNT * PWLE_WORD_SIZE;
+#endif
totalDuration *= 8; /* Unit: 0.125 ms (since wlength played @ 8kHz). */
totalDuration |=
WT_LEN_CALCD; /* Bit 23 is for WT_LEN_CALCD; Bit 22 is for WT_INDEFINITE. */
@@ -364,6 +402,9 @@ class DspMemChunk {
ALOGE("%s: Invalid argument: %d", __func__, segmentIdx);
return -EINVAL;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)
+ f += PWLE_HEADER_WORD_COUNT * PWLE_WORD_SIZE;
+#endif
*(f + 7) |= (0xF0 & segmentIdx) >> 4; /* Bit 4 to 7 */
*(f + 9) |= (0x0F & segmentIdx) << 4; /* Bit 3 to 0 */
} else {
@@ -373,6 +414,34 @@ class DspMemChunk {
return 0;
}
+
+ int updateWCount(int segmentCount) {
+ uint8_t *f = front();
+
+ if (segmentCount > COMPOSE_SIZE_MAX + 1 /*1st effect may have a delay*/) {
+ ALOGE("%s: Invalid argument: %d", __func__, segmentCount);
+ return -EINVAL;
+ }
+ if (f == nullptr) {
+ ALOGE("%s: head does not exist!", __func__);
+ return -ENOMEM;
+ }
+ if (waveformType != WAVEFORM_PWLE) {
+ ALOGE("%s: Invalid type: %d", __func__, waveformType);
+ return -EDOM;
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)
+ f += PWLE_HEADER_WORD_COUNT * PWLE_WORD_SIZE;
+#endif
+ uint32_t dataSize = segmentCount * PWLE_SEGMENT_WORD_COUNT + PWLE_HEADER_WORD_COUNT;
+ *(f + 0) = (dataSize >> 24) & 0xFF;
+ *(f + 1) = (dataSize >> 16) & 0xFF;
+ *(f + 2) = (dataSize >> 8) & 0xFF;
+ *(f + 3) = dataSize & 0xFF;
+
+ return 0;
+ }
};
Vibrator::Vibrator(std::unique_ptr hwApiDefault, std::unique_ptr hwCalDefault,
@@ -1014,7 +1083,7 @@ ndk::ScopedAStatus Vibrator::on(uint32_t timeoutMs, uint32_t effectIndex, const
if (mIsDual) {
mHwApiDual->getOwtFreeSpace(&freeBytes);
if (ch-> size() > freeBytes) {
- ALOGE("Invalid OWT length in flip: Effect %d: %d > %d!", effectIndex,
+ ALOGE("Invalid OWT length in flip: Effect %d: %zu > %d!", effectIndex,
ch-> size(), freeBytes);
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
@@ -1370,6 +1439,13 @@ ndk::ScopedAStatus Vibrator::composePwle(const std::vector &compo
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
+ /* Update word count */
+ if (ch.updateWCount(segmentIdx) < 0) {
+ ALOGE("%s: Failed to update the waveform word count", __func__);
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ /* Update waveform length */
if (ch.updateWLength(totalDuration) < 0) {
ALOGE("%s: Failed to update the waveform length length", __func__);
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
@@ -1408,40 +1484,31 @@ binder_status_t Vibrator::dump(int fd, const char **args, uint32_t numArgs) {
dprintf(fd, " Redc: %.02f\n", mRedc);
dprintf(fd, " Voltage Levels:\n");
- dprintf(fd, " Tick Effect Min: %" PRIu32 " Max: %" PRIu32 "\n", mTickEffectVol[0],
+ dprintf(fd, " Tick Effect Min: %" PRIu32 " Max: %" PRIu32 "\n", mTickEffectVol[0],
mTickEffectVol[1]);
- dprintf(fd, " Click Effect Min: %" PRIu32 " Max: %" PRIu32 "\n", mClickEffectVol[0],
+ dprintf(fd, " Click Effect Min: %" PRIu32 " Max: %" PRIu32 "\n", mClickEffectVol[0],
mClickEffectVol[1]);
- dprintf(fd, " Long Effect Min: %" PRIu32 " Max: %" PRIu32 "\n", mLongEffectVol[0],
+ dprintf(fd, " Long Effect Min: %" PRIu32 " Max: %" PRIu32 "\n", mLongEffectVol[0],
mLongEffectVol[1]);
- dprintf(fd, " FF effect:\n");
- dprintf(fd, " Physical waveform:\n");
- dprintf(fd, "==== Base ====\n\tId\tIndex\tt ->\tt'\tBrake\ttrigger button\n");
uint8_t effectId;
+ dprintf(fd, " Scales\n");
+ dprintf(fd, "\tId\tMinScale\tMaxScale\n");
+ for (effectId = 0; effectId < WAVEFORM_MAX_PHYSICAL_INDEX; effectId++) {
+ dprintf(fd, "\t%d\t%d\t\t%d\n", effectId, mPrimitiveMinScale[effectId],
+ mPrimitiveMaxScale[effectId]);
+ }
+
+ dprintf(fd, " Base FF effect:\n");
+ dprintf(fd, " Physical waveform:\n");
+ dprintf(fd, "\tId\tIndex\tt ->\tt'\tBrake\ttrigger button\n");
for (effectId = 0; effectId < WAVEFORM_MAX_PHYSICAL_INDEX; effectId++) {
dprintf(fd, "\t%d\t%d\t%d\t%d\t%d\t%X\n", mFfEffects[effectId].id,
mFfEffects[effectId].u.periodic.custom_data[1], mEffectDurations[effectId],
mFfEffects[effectId].replay.length, mEffectBrakingDurations[effectId],
mFfEffects[effectId].trigger.button);
}
- if (mIsDual) {
- dprintf(fd, "==== Flip ====\n\tId\tIndex\tt ->\tt'\tBrake\ttrigger button\n");
- for (effectId = 0; effectId < WAVEFORM_MAX_PHYSICAL_INDEX; effectId++) {
- dprintf(fd, "\t%d\t%d\t%d\t%d\t%d\t%X\n", mFfEffectsDual[effectId].id,
- mFfEffectsDual[effectId].u.periodic.custom_data[1], mEffectDurations[effectId],
- mFfEffectsDual[effectId].replay.length, mEffectBrakingDurations[effectId],
- mFfEffectsDual[effectId].trigger.button);
- }
- }
-
- dprintf(fd, "==== Scales ====\n\tId\tMinScale\tMaxScale\n");
- for (effectId = 0; effectId < WAVEFORM_MAX_PHYSICAL_INDEX; effectId++) {
- dprintf(fd, "\t%d\t%d\t\t%d\n", effectId, mPrimitiveMinScale[effectId],
- mPrimitiveMaxScale[effectId]);
- }
-
- dprintf(fd, "\nBase: OWT waveform:\n");
+ dprintf(fd, " OWT waveform:\n");
dprintf(fd, "\tId\tBytes\tData\tt\ttrigger button\n");
for (effectId = WAVEFORM_MAX_PHYSICAL_INDEX; effectId < WAVEFORM_MAX_INDEX; effectId++) {
uint32_t numBytes = mFfEffects[effectId].u.periodic.custom_len * 2;
@@ -1457,8 +1524,18 @@ binder_status_t Vibrator::dump(int fd, const char **args, uint32_t numArgs) {
dprintf(fd, "\t%d\t%d\t{%s}\t%u\t%X\n", mFfEffects[effectId].id, numBytes, ss.str().c_str(),
mFfEffectsDual[effectId].replay.length, mFfEffects[effectId].trigger.button);
}
+
if (mIsDual) {
- dprintf(fd, "Flip: OWT waveform:\n");
+ dprintf(fd, " Flip FF effect:\n");
+ dprintf(fd, " Physical waveform:\n");
+ dprintf(fd, "\tId\tIndex\tt ->\tt'\tBrake\ttrigger button\n");
+ for (effectId = 0; effectId < WAVEFORM_MAX_PHYSICAL_INDEX; effectId++) {
+ dprintf(fd, "\t%d\t%d\t%d\t%d\t%d\t%X\n", mFfEffectsDual[effectId].id,
+ mFfEffectsDual[effectId].u.periodic.custom_data[1], mEffectDurations[effectId],
+ mFfEffectsDual[effectId].replay.length, mEffectBrakingDurations[effectId],
+ mFfEffectsDual[effectId].trigger.button);
+ }
+ dprintf(fd, " OWT waveform:\n");
dprintf(fd, "\tId\tBytes\tData\tt\ttrigger button\n");
for (effectId = WAVEFORM_MAX_PHYSICAL_INDEX; effectId < WAVEFORM_MAX_INDEX; effectId++) {
uint32_t numBytes = mFfEffectsDual[effectId].u.periodic.custom_len * 2;
@@ -1479,78 +1556,67 @@ binder_status_t Vibrator::dump(int fd, const char **args, uint32_t numArgs) {
dprintf(fd, "\n");
dprintf(fd, "Versions:\n");
+ const std::vector> moduleFolderNames = {
+ {"cs40l26_core", "Haptics"}, {"cl_dsp_core", "DSP"}};
+ const std::string firmwareFolder = "/vendor/firmware/";
+ const std::string waveformName = "cs40l26.bin";
+ const std::array firmwareFileNames = {"cs40l26.wmfw", "cs40l26-calib.wmfw"};
+ const std::array tuningFileNames = {"cs40l26-svc.bin", "cs40l26-calib.bin",
+ "cs40l26-dvl.bin", "cs40l26-dbc.bin"};
std::ifstream verFile;
const auto verBinFileMode = std::ifstream::in | std::ifstream::binary;
std::string ver;
- verFile.open("/sys/module/cs40l26_core/version");
- if (verFile.is_open()) {
- getline(verFile, ver);
- dprintf(fd, " Haptics Driver: %s\n", ver.c_str());
- verFile.close();
+ for (const auto &[folder, logTag] : moduleFolderNames) {
+ verFile.open("/sys/module/" + folder + "/version");
+ if (verFile.is_open()) {
+ getline(verFile, ver);
+ dprintf(fd, " %s Driver: %s\n", logTag.c_str(), ver.c_str());
+ verFile.close();
+ }
}
- verFile.open("/sys/module/cl_dsp_core/version");
- if (verFile.is_open()) {
- getline(verFile, ver);
- dprintf(fd, " DSP Driver: %s\n", ver.c_str());
- verFile.close();
+ for (auto &name : firmwareFileNames) {
+ verFile.open(firmwareFolder + name, verBinFileMode);
+ if (verFile.is_open()) {
+ verFile.seekg(113);
+ dprintf(fd, " %s: %d.%d.%d\n", name.c_str(), verFile.get(), verFile.get(),
+ verFile.get());
+ verFile.close();
+ }
}
- verFile.open("/vendor/firmware/cs40l26.wmfw", verBinFileMode);
- if (verFile.is_open()) {
- verFile.seekg(113);
- dprintf(fd, " cs40l26.wmfw: %d.%d.%d\n", verFile.get(), verFile.get(), verFile.get());
- verFile.close();
- }
- verFile.open("/vendor/firmware/cs40l26-calib.wmfw", verBinFileMode);
- if (verFile.is_open()) {
- verFile.seekg(113);
- dprintf(fd, " cs40l26-calib.wmfw: %d.%d.%d\n", verFile.get(), verFile.get(),
- verFile.get());
- verFile.close();
- }
- verFile.open("/vendor/firmware/cs40l26.bin", verBinFileMode);
+ verFile.open(firmwareFolder + waveformName, verBinFileMode);
if (verFile.is_open()) {
while (getline(verFile, ver)) {
auto pos = ver.find("Date: ");
if (pos != std::string::npos) {
ver = ver.substr(pos + 6, pos + 15);
- dprintf(fd, " cs40l26.bin: %s\n", ver.c_str());
+ dprintf(fd, " %s: %s\n", waveformName.c_str(), ver.c_str());
break;
}
}
verFile.close();
}
- verFile.open("/vendor/firmware/cs40l26-svc.bin", verBinFileMode);
- if (verFile.is_open()) {
- verFile.seekg(36);
- getline(verFile, ver);
- ver = ver.substr(ver.rfind('\\') + 1);
- dprintf(fd, " cs40l26-svc.bin: %s\n", ver.c_str());
- verFile.close();
- }
- verFile.open("/vendor/firmware/cs40l26-calib.bin", verBinFileMode);
- if (verFile.is_open()) {
- verFile.seekg(36);
- getline(verFile, ver);
- ver = ver.substr(ver.rfind('\\') + 1);
- dprintf(fd, " cs40l26-calib.bin: %s\n", ver.c_str());
- verFile.close();
- }
- verFile.open("/vendor/firmware/cs40l26-dvl.bin", verBinFileMode);
- if (verFile.is_open()) {
- verFile.seekg(36);
- getline(verFile, ver);
- ver = ver.substr(0, ver.find('\0') + 1);
- ver = ver.substr(ver.rfind('\\') + 1);
- dprintf(fd, " cs40l26-dvl.bin: %s\n", ver.c_str());
- verFile.close();
+ for (auto &name : tuningFileNames) {
+ verFile.open(firmwareFolder + name, verBinFileMode);
+ if (verFile.is_open()) {
+ verFile.seekg(36);
+ getline(verFile, ver);
+ ver = ver.substr(0, ver.find(".bin") + 4);
+ ver = ver.substr(ver.rfind('\\') + 1);
+ dprintf(fd, " %s: %s\n", name.c_str(), ver.c_str());
+ verFile.close();
+ }
}
+ dprintf(fd, "\n");
+
mHwApiDef->debug(fd);
dprintf(fd, "\n");
mHwCalDef->debug(fd);
+ dprintf(fd, "\n");
+
if (mIsDual) {
mHwApiDual->debug(fd);
dprintf(fd, "\n");
@@ -1856,7 +1922,6 @@ uint32_t Vibrator::intensityToVolLevel(float intensity, uint32_t effectIndex) {
volLevel = calc(intensity, mClickEffectVol);
break;
}
-
// The waveform being played must fall within the allowable scale range
if (effectIndex < WAVEFORM_MAX_INDEX) {
if (volLevel > mPrimitiveMaxScale[effectIndex]) {
diff --git a/vibrator/cs40l26/Vibrator.h b/vibrator/cs40l26/Vibrator.h
index a61cea9..6fc3a3d 100644
--- a/vibrator/cs40l26/Vibrator.h
+++ b/vibrator/cs40l26/Vibrator.h
@@ -250,7 +250,6 @@ class Vibrator : public BnVibrator {
bool mConfigHapticAlsaDeviceDone{false};
bool mGPIOStatus;
bool mIsDual{false};
- std::mutex mActiveId_mutex; // protects mActiveId
};
} // namespace vibrator
diff --git a/vibrator/cs40l26/tests/test-hwcal.cpp b/vibrator/cs40l26/tests/test-hwcal.cpp
index e482b6c..5223c85 100644
--- a/vibrator/cs40l26/tests/test-hwcal.cpp
+++ b/vibrator/cs40l26/tests/test-hwcal.cpp
@@ -30,9 +30,9 @@ using ::testing::Test;
class HwCalTest : public Test {
protected:
- static constexpr std::array V_TICK_DEFAULT = {1, 100};
- static constexpr std::array V_CLICK_DEFAULT = {1, 100};
- static constexpr std::array V_LONG_DEFAULT = {1, 100};
+ static constexpr std::array V_TICK_DEFAULT = {5, 95};
+ static constexpr std::array V_CLICK_DEFAULT = {5, 95};
+ static constexpr std::array V_LONG_DEFAULT = {5, 95};
public:
void SetUp() override { setenv("CALIBRATION_FILEPATH", mCalFile.path, true); }
diff --git a/vibrator/cs40l26/tests/test-vibrator.cpp b/vibrator/cs40l26/tests/test-vibrator.cpp
index 6c8cebb..b9b5b3c 100644
--- a/vibrator/cs40l26/tests/test-vibrator.cpp
+++ b/vibrator/cs40l26/tests/test-vibrator.cpp
@@ -87,7 +87,7 @@ static const std::map EFFECT_INDEX{
static constexpr uint32_t MIN_ON_OFF_INTERVAL_US = 8500;
static constexpr uint8_t VOLTAGE_SCALE_MAX = 100;
static constexpr int8_t MAX_COLD_START_LATENCY_MS = 6; // I2C Transaction + DSP Return-From-Standby
-static constexpr auto POLLING_TIMEOUT = 20;
+static constexpr auto POLLING_TIMEOUT = 50;
enum WaveformIndex : uint16_t {
/* Physical waveform */
WAVEFORM_LONG_VIBRATION_EFFECT_INDEX = 0,
@@ -506,6 +506,23 @@ TEST_P(EffectsTest, perform) {
promise.set_value();
return ndk::ScopedAStatus::ok();
};
+ std::vector primitiveMaxScale;
+ std::vector primitiveMinScale;
+ primitiveMaxScale.resize(WAVEFORM_MAX_INDEX, 100);
+ primitiveMaxScale[WAVEFORM_CLICK_INDEX] = 95;
+ primitiveMaxScale[WAVEFORM_THUD_INDEX] = 75;
+ primitiveMaxScale[WAVEFORM_SPIN_INDEX] = 90;
+ primitiveMaxScale[WAVEFORM_LIGHT_TICK_INDEX] = 75;
+ primitiveMaxScale[WAVEFORM_LOW_TICK_INDEX] = 75;
+
+ primitiveMinScale.resize(WAVEFORM_MAX_INDEX, 0);
+ primitiveMinScale[WAVEFORM_CLICK_INDEX] = 1;
+ primitiveMinScale[WAVEFORM_THUD_INDEX] = 11;
+ primitiveMinScale[WAVEFORM_SPIN_INDEX] = 23;
+ primitiveMinScale[WAVEFORM_SLOW_RISE_INDEX] = 25;
+ primitiveMinScale[WAVEFORM_QUICK_FALL_INDEX] = 2;
+ primitiveMinScale[WAVEFORM_LIGHT_TICK_INDEX] = 3;
+ primitiveMinScale[WAVEFORM_LOW_TICK_INDEX] = 16;
bool composeEffect;
ExpectationSet eSetup;
@@ -515,7 +532,18 @@ TEST_P(EffectsTest, perform) {
EffectIndex index = EFFECT_INDEX.at(effect);
duration = EFFECT_DURATIONS[index];
- eSetup += EXPECT_CALL(*mMockApi, setFFGain(_, levelToScale(scale->second)))
+ auto updatedScale = levelToScale(scale->second);
+
+ if (index < WAVEFORM_MAX_INDEX) {
+ if (updatedScale > primitiveMaxScale[index]) {
+ updatedScale = primitiveMaxScale[index];
+ }
+ if (updatedScale < primitiveMinScale[index]) {
+ updatedScale = primitiveMinScale[index];
+ }
+ }
+
+ eSetup += EXPECT_CALL(*mMockApi, setFFGain(_, updatedScale))
.WillOnce(DoDefault());
eActivate = EXPECT_CALL(*mMockApi, setFFPlay(_, index, true))
.After(eSetup)