Merge "vibrator: Format PWLE header in user driver" into main
This commit is contained in:
commit
5644762c10
1 changed files with 74 additions and 0 deletions
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue