1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "vibrator_haptic.h"
10 #include <securec.h>
11 #include "device_resource_if.h"
12 #include "hdf_base.h"
13 #include "hdf_device_desc.h"
14 #include "osal_mem.h"
15 #include "vibrator_driver.h"
16
17 #define HDF_LOG_TAG hdf_vibrator_driver
18
19 #define VIBRATOR_HAPTIC_STACK_SIZE 0x4000
20 #define VIBRATOR_HAPTIC_SEQ_MAX 1024
21 #define VIBRATOR_HAPTIC_SEQ_SIZE 4
22 #define VIBRATOR_HAPTIC_SEQ_NAME_MAX 48
23 #define VIBRATOR_HAPTIC_SEQ_SIZE_MAX (4 * VIBRATOR_HAPTIC_SEQ_MAX)
24
25 struct VibratorHapticData *g_vibratorHapticData = NULL;
26
GetHapticData(void)27 static struct VibratorHapticData *GetHapticData(void)
28 {
29 return g_vibratorHapticData;
30 }
31
MallocEffectNode(int32_t seqSize)32 static struct VibratorEffectNode *MallocEffectNode(int32_t seqSize)
33 {
34 uint32_t *seq = NULL;
35 struct VibratorEffectNode *node = NULL;
36
37 if (seqSize <= 0 || seqSize > VIBRATOR_HAPTIC_SEQ_SIZE_MAX) {
38 HDF_LOGE("%s: malloc ", __func__);
39 return NULL;
40 }
41
42 seq = (uint32_t *)OsalMemCalloc(seqSize);
43 if (seq == NULL) {
44 HDF_LOGE("%s: malloc seq fail", __func__);
45 return NULL;
46 }
47
48 node = (struct VibratorEffectNode *)OsalMemCalloc(sizeof(*node));
49 if (node == NULL) {
50 HDF_LOGE("%s: malloc seq fail", __func__);
51 OsalMemFree(seq);
52 return NULL;
53 }
54 node->seq = seq;
55
56 return node;
57 }
58
ParserHapticEffect(struct DeviceResourceIface * parser,const struct DeviceResourceNode * hapticNode)59 static int32_t ParserHapticEffect(struct DeviceResourceIface *parser, const struct DeviceResourceNode *hapticNode)
60 {
61 int32_t ret;
62 int32_t count;
63 struct VibratorEffectNode *effectNode = NULL;
64 const struct DeviceResourceNode *childNode = NULL;
65 struct VibratorHapticData *hapticData = GetHapticData();
66
67 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_FAILURE);
68
69 (void)OsalMutexLock(&hapticData->mutex);
70 DEV_RES_NODE_FOR_EACH_CHILD_NODE(hapticNode, childNode) {
71 if ((childNode == NULL) || (childNode->name == NULL)) {
72 break;
73 }
74
75 count = parser->GetElemNum(childNode, "seq");
76 if (count <= 1 || count > VIBRATOR_HAPTIC_SEQ_MAX) {
77 HDF_LOGE("%s: haptic [%s] parser seq count fail", __func__, childNode->name);
78 continue;
79 }
80
81 effectNode = MallocEffectNode(count * VIBRATOR_HAPTIC_SEQ_SIZE);
82 if (effectNode == NULL) {
83 HDF_LOGE("%s: malloc effect effectNode fail", __func__);
84 continue;
85 }
86 effectNode->num = count;
87 ret = parser->GetString(childNode, "effectName", &effectNode->effect, NULL);
88 ret = parser->GetUint32(childNode, "type", &effectNode->type, 0);
89 ret = parser->GetUint32Array(childNode, "seq", effectNode->seq, count, 0);
90
91 DListInsertTail(&effectNode->node, &hapticData->effectSeqHead);
92 }
93 (void)OsalMutexUnlock(&hapticData->mutex);
94
95 if (DListIsEmpty(&hapticData->effectSeqHead)) {
96 return HDF_FAILURE;
97 }
98
99 return HDF_SUCCESS;
100 }
101
ParserVibratorHapticConfig(const struct DeviceResourceNode * node)102 static int32_t ParserVibratorHapticConfig(const struct DeviceResourceNode *node)
103 {
104 bool supportPresetFlag = false;
105 struct DeviceResourceIface *parser = NULL;
106 const struct DeviceResourceNode *vibratorAttrNode = NULL;
107 const struct DeviceResourceNode *vibratorHapticNode = NULL;
108 struct VibratorHapticData *hapticData = GetHapticData();
109
110 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_FAILURE);
111 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
112
113 parser = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
114 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(parser, HDF_ERR_INVALID_PARAM);
115 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(parser->GetChildNode, HDF_ERR_INVALID_PARAM);
116
117 // get haptic type
118 vibratorAttrNode = parser->GetChildNode(node, "vibratorAttr");
119 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(vibratorAttrNode, HDF_ERR_INVALID_PARAM);
120 supportPresetFlag = parser->GetBool(vibratorAttrNode, "supportPreset");
121
122 (void)OsalMutexLock(&hapticData->mutex);
123 hapticData->supportHaptic = supportPresetFlag;
124 (void)OsalMutexUnlock(&hapticData->mutex);
125
126 if (!supportPresetFlag) {
127 HDF_LOGD("%s: vibrator not support effect", __func__);
128 return HDF_SUCCESS;
129 }
130
131 // malloc haptic resource
132 vibratorHapticNode = parser->GetChildNode(node, "vibratorHapticConfig");
133 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(vibratorHapticNode, HDF_ERR_INVALID_PARAM);
134 if (ParserHapticEffect(parser, vibratorHapticNode) != HDF_SUCCESS) {
135 HDF_LOGE("%s: vibrator get effect fail", __func__);
136 return HDF_FAILURE;
137 }
138
139 return HDF_SUCCESS;
140 }
141
ProcessHapticTime(struct VibratorHapticData * hapticData)142 static uint32_t ProcessHapticTime(struct VibratorHapticData *hapticData)
143 {
144 uint32_t duration;
145 int32_t num = 2; // Determine whether the number is an even numner or an odd number.
146
147 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_FAILURE);
148 if ((hapticData->currentSeqIndex < 0) || (hapticData->currentSeqIndex >= hapticData->seqCount)) {
149 return 0;
150 }
151
152 if (hapticData->currentSeqIndex % num == 0) {
153 StartTimeVibrator();
154 } else {
155 StopVibrator();
156 }
157
158 hapticData->currentSeqIndex++;
159 if (hapticData->currentSeqIndex >= hapticData->seqCount) {
160 return 0;
161 }
162
163 duration = hapticData->currentEffectSeq[hapticData->currentSeqIndex] == 0 ?
164 VIBRATOR_MIN_WAIT_TIME : hapticData->currentEffectSeq[hapticData->currentSeqIndex];
165 return duration;
166 }
167
ProcessHapticEffect(struct VibratorHapticData * hapticData)168 static uint32_t ProcessHapticEffect(struct VibratorHapticData *hapticData)
169 {
170 uint32_t effect;
171 uint32_t duration;
172
173 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_FAILURE);
174
175 if ((hapticData->currentSeqIndex < 0) || ((hapticData->currentSeqIndex + 1) >= hapticData->seqCount)) {
176 HDF_LOGE("%s: seq index invalid para", __func__);
177 return 0;
178 }
179
180 hapticData->currentSeqIndex++;
181 effect = hapticData->currentEffectSeq[hapticData->currentSeqIndex];
182 SetEffectVibrator(effect);
183
184 hapticData->currentSeqIndex++;
185 if (hapticData->currentSeqIndex >= hapticData->seqCount) {
186 HDF_LOGE("%s: seq index exceed max value", __func__);
187 return 0;
188 }
189
190 duration = hapticData->currentEffectSeq[hapticData->currentSeqIndex] == 0 ?
191 VIBRATOR_MIN_WAIT_TIME : hapticData->currentEffectSeq[hapticData->currentSeqIndex];
192 return duration;
193 }
194
HapticTimerEntry(uintptr_t para)195 void HapticTimerEntry(uintptr_t para)
196 {
197 int32_t ret;
198 struct VibratorHapticData *hapticData = NULL;
199 uint32_t duration;
200
201 hapticData = (struct VibratorHapticData *)para;
202 CHECK_VIBRATOR_NULL_PTR_RETURN(hapticData);
203
204 if (hapticData->effectType == VIBRATOR_TYPE_TIME) {
205 duration = ProcessHapticTime(hapticData);
206 }
207
208 if (hapticData->effectType == VIBRATOR_TYPE_EFFECT) {
209 duration = ProcessHapticEffect(hapticData);
210 }
211
212 duration = ((duration > 0) && (duration < VIBRATOR_MIN_WAIT_TIME)) ? VIBRATOR_MIN_WAIT_TIME : duration;
213 if ((duration > 0) && (OsalTimerSetTimeout(&hapticData->timer, duration) == HDF_SUCCESS)) {
214 return;
215 }
216
217 if (hapticData->timer.realTimer != NULL) {
218 ret = OsalTimerDelete(&hapticData->timer);
219 if (ret != HDF_SUCCESS) {
220 HDF_LOGE("%s: delete haptic timer fail!", __func__);
221 }
222 }
223
224 return;
225 }
226
GetHapticSeqByEffect(struct VibratorEffectCfg * effectCfg)227 static int32_t GetHapticSeqByEffect(struct VibratorEffectCfg *effectCfg)
228 {
229 struct VibratorHapticData *hapticData = NULL;
230 struct VibratorEffectNode *pos = NULL;
231 struct VibratorEffectNode *tmp = NULL;
232
233 hapticData = GetHapticData();
234 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_FAILURE);
235
236 (void)OsalMutexLock(&hapticData->mutex);
237 hapticData->seqCount = 0;
238 hapticData->currentEffectSeq = NULL;
239 hapticData->currentSeqIndex = 0;
240
241 if (effectCfg->cfgMode == VIBRATOR_MODE_ONCE) {
242 hapticData->duration[VIBRATOR_TIME_DELAY_INDEX] = VIBRATOR_MIN_WAIT_TIME;
243 hapticData->duration[VIBRATOR_TIME_DURATION_INDEX] = effectCfg->duration;
244 hapticData->effectType = VIBRATOR_TYPE_TIME;
245 hapticData->seqCount = VIBRATOR_TIME_INDEX_BUTT;
246 hapticData->currentEffectSeq = &hapticData->duration[VIBRATOR_TIME_DELAY_INDEX];
247 (void)OsalMutexUnlock(&hapticData->mutex);
248 return HDF_SUCCESS;
249 }
250
251 if ((effectCfg->cfgMode == VIBRATOR_MODE_PRESET) && (effectCfg->effect != NULL)) {
252 DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &hapticData->effectSeqHead, struct VibratorEffectNode, node) {
253 if (strcmp(effectCfg->effect, pos->effect) == 0 && pos->seq != NULL) {
254 hapticData->effectType = (int32_t)pos->type;
255 HDF_LOGE("%s: pos_num = %d", __func__, pos->num);
256 hapticData->seqCount = pos->num;
257 hapticData->currentEffectSeq = &(pos->seq[0]);
258 break;
259 }
260 }
261 if ((hapticData->seqCount <= 1) || (hapticData->seqCount > VIBRATOR_MAX_HAPTIC_SEQ)) {
262 HDF_LOGE("%s: not find effect type!", __func__);
263 (void)OsalMutexUnlock(&hapticData->mutex);
264 return HDF_ERR_INVALID_PARAM;
265 }
266 (void)OsalMutexUnlock(&hapticData->mutex);
267 return HDF_SUCCESS;
268 }
269
270 HDF_LOGE("%s: not support effect type!", __func__);
271 (void)OsalMutexUnlock(&hapticData->mutex);
272 return HDF_ERR_NOT_SUPPORT;
273 }
274
StartHaptic(struct VibratorEffectCfg * effectCfg)275 int32_t StartHaptic(struct VibratorEffectCfg *effectCfg)
276 {
277 int32_t ret;
278 uint32_t duration;
279 struct VibratorHapticData *hapticData = GetHapticData();
280 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(effectCfg, HDF_FAILURE);
281 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_FAILURE);
282
283 if ((effectCfg->cfgMode == VIBRATOR_MODE_PRESET) && (!hapticData->supportHaptic)) {
284 HDF_LOGE("%s: vibrator no support haptic!", __func__);
285 return HDF_ERR_NOT_SUPPORT;
286 }
287
288 ret = GetHapticSeqByEffect(effectCfg);
289 if (ret != HDF_SUCCESS) {
290 HDF_LOGE("%s: get haptic seq fail!", __func__);
291 return ret;
292 }
293
294 duration = hapticData->currentEffectSeq[0] < VIBRATOR_MIN_WAIT_TIME ?
295 VIBRATOR_MIN_WAIT_TIME : hapticData->currentEffectSeq[0];
296
297 if (OsalTimerCreate(&hapticData->timer, duration, HapticTimerEntry, (uintptr_t)hapticData) != HDF_SUCCESS) {
298 HDF_LOGE("%s: create vibrator timer fail!", __func__);
299 return HDF_FAILURE;
300 }
301
302 if (OsalTimerStartLoop(&hapticData->timer) != HDF_SUCCESS) {
303 HDF_LOGE("%s: start vibrator timer fail!", __func__);
304 return HDF_FAILURE;
305 }
306
307 return HDF_SUCCESS;
308 }
309
StopHaptic()310 int32_t StopHaptic()
311 {
312 int32_t ret;
313 struct VibratorHapticData *hapticData = GetHapticData();
314
315 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_FAILURE);
316
317 if (hapticData->timer.realTimer != NULL) {
318 HDF_LOGE("%s: delete vibrator Timer!", __func__);
319 (void)OsalMutexLock(&hapticData->mutex);
320 ret = OsalTimerDelete(&hapticData->timer);
321 (void)OsalMutexUnlock(&hapticData->mutex);
322 if (ret != HDF_SUCCESS) {
323 HDF_LOGE("%s: delete vibrator timer fail!", __func__);
324 return ret;
325 }
326 }
327
328 StopVibrator();
329 return HDF_SUCCESS;
330 }
331
CreateVibratorHaptic(struct HdfDeviceObject * device)332 int32_t CreateVibratorHaptic(struct HdfDeviceObject *device)
333 {
334 struct VibratorHapticData *hapticData = NULL;
335 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE);
336
337 hapticData = (struct VibratorHapticData *)OsalMemCalloc(sizeof(*hapticData));
338 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_ERR_MALLOC_FAIL);
339 g_vibratorHapticData = hapticData;
340 hapticData->supportHaptic = false;
341
342 if (OsalMutexInit(&hapticData->mutex) != HDF_SUCCESS) {
343 HDF_LOGE("%s: fail to init mutex", __func__);
344 goto EXIT;
345 }
346
347 DListHeadInit(&hapticData->effectSeqHead);
348
349 // get haptic hcs
350 if (ParserVibratorHapticConfig(device->property) != HDF_SUCCESS) {
351 HDF_LOGE("%s: parser haptic config fail!", __func__);
352 goto EXIT;
353 }
354
355 return HDF_SUCCESS;
356 EXIT:
357 OsalMemFree(hapticData);
358 return HDF_FAILURE;
359 }
360
FreeHapticConfig()361 static void FreeHapticConfig()
362 {
363 struct VibratorHapticData *hapticData = GetHapticData();
364 struct VibratorEffectNode *pos = NULL;
365 struct VibratorEffectNode *tmp = NULL;
366
367 if (hapticData == NULL) {
368 return;
369 }
370
371 (void)OsalMutexLock(&hapticData->mutex);
372 DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &hapticData->effectSeqHead, struct VibratorEffectNode, node) {
373 if (pos->seq != NULL) {
374 OsalMemFree(pos->seq);
375 pos->seq = NULL;
376 }
377 pos->effect = NULL;
378 DListRemove(&pos->node);
379 OsalMemFree(pos);
380 }
381 (void)OsalMutexUnlock(&hapticData->mutex);
382 }
383
DestroyVibratorHaptic()384 int32_t DestroyVibratorHaptic()
385 {
386 struct VibratorHapticData *hapticData = GetHapticData();
387 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_FAILURE);
388
389 if (hapticData->supportHaptic) {
390 FreeHapticConfig();
391 }
392
393 (void)OsalMutexDestroy(&hapticData->mutex);
394
395 return HDF_SUCCESS;
396 }
397