Merge "vibrator: Format PWLE header in user driver" into main

This commit is contained in:
Treehugger Robot 2024-10-02 03:17:08 +00:00 committed by Android (Google) Code Review
commit 5644762c10

View file

@ -19,6 +19,7 @@
#include <glob.h>
#include <hardware/hardware.h>
#include <hardware/vibrator.h>
#include <linux/version.h>
#include <log/log.h>
#include <stdio.h>
#include <utils/Trace.h>
@ -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;
@ -245,10 +270,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 +369,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 +400,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 +412,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<HwApi> hwApiDefault, std::unique_ptr<HwCal> hwCalDefault,
@ -1370,6 +1437,13 @@ ndk::ScopedAStatus Vibrator::composePwle(const std::vector<PrimitivePwle> &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);