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 khdf_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 if (ret != HDF_SUCCESS) {
89 HDF_LOGE("%s: parser %s effectName failed", __func__, "effectName");
90 goto EXIT;
91 }
92 ret = parser->GetUint32(childNode, "type", &effectNode->type, 0);
93 if (ret != HDF_SUCCESS) {
94 HDF_LOGE("%s: parser %s type failed", __func__, "type");
95 goto EXIT;
96 }
97
98 ret = parser->GetUint32Array(childNode, "seq", effectNode->seq, count, 0);
99 if (ret != HDF_SUCCESS) {
100 HDF_LOGE("%s: parser %s seq failed", __func__, "seq");
101 goto EXIT;
102 }
103
104 DListInsertTail(&effectNode->node, &hapticData->effectSeqHead);
105 }
106 (void)OsalMutexUnlock(&hapticData->mutex);
107
108 if (DListIsEmpty(&hapticData->effectSeqHead)) {
109 return HDF_FAILURE;
110 }
111
112 return HDF_SUCCESS;
113 EXIT:
114 OsalMemFree(effectNode->seq);
115 OsalMemFree(effectNode);
116 return HDF_FAILURE;
117 }
118
ParserVibratorHapticConfig(const struct DeviceResourceNode * node)119 static int32_t ParserVibratorHapticConfig(const struct DeviceResourceNode *node)
120 {
121 bool supportPresetFlag = false;
122 struct DeviceResourceIface *parser = NULL;
123 const struct DeviceResourceNode *vibratorAttrNode = NULL;
124 const struct DeviceResourceNode *vibratorHapticNode = NULL;
125 struct VibratorHapticData *hapticData = GetHapticData();
126
127 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_FAILURE);
128 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
129
130 parser = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
131 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(parser, HDF_ERR_INVALID_PARAM);
132 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(parser->GetChildNode, HDF_ERR_INVALID_PARAM);
133
134 // get haptic type
135 vibratorAttrNode = parser->GetChildNode(node, "vibratorAttr");
136 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(vibratorAttrNode, HDF_ERR_INVALID_PARAM);
137 supportPresetFlag = parser->GetBool(vibratorAttrNode, "supportPreset");
138
139 (void)OsalMutexLock(&hapticData->mutex);
140 hapticData->supportHaptic = supportPresetFlag;
141 (void)OsalMutexUnlock(&hapticData->mutex);
142
143 if (!supportPresetFlag) {
144 HDF_LOGD("%s: vibrator not support effect", __func__);
145 return HDF_SUCCESS;
146 }
147
148 // malloc haptic resource
149 vibratorHapticNode = parser->GetChildNode(node, "vibratorHapticConfig");
150 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(vibratorHapticNode, HDF_ERR_INVALID_PARAM);
151 if (ParserHapticEffect(parser, vibratorHapticNode) != HDF_SUCCESS) {
152 HDF_LOGE("%s: vibrator get effect fail", __func__);
153 return HDF_FAILURE;
154 }
155
156 return HDF_SUCCESS;
157 }
158
ProcessHapticTime(struct VibratorHapticData * hapticData)159 static uint32_t ProcessHapticTime(struct VibratorHapticData *hapticData)
160 {
161 uint32_t duration;
162 int32_t num = 2; // Determine whether the number is an even numner or an odd number.
163
164 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_FAILURE);
165 if ((hapticData->currentSeqIndex < 0) || (hapticData->currentSeqIndex >= hapticData->seqCount)) {
166 return 0;
167 }
168
169 if (hapticData->currentSeqIndex % num == 0) {
170 StartVibrator();
171 } else {
172 StopVibrator();
173 }
174
175 hapticData->currentSeqIndex++;
176 if (hapticData->currentSeqIndex >= hapticData->seqCount) {
177 return 0;
178 }
179
180 duration = hapticData->currentEffectSeq[hapticData->currentSeqIndex] == 0 ?
181 VIBRATOR_MIN_WAIT_TIME : hapticData->currentEffectSeq[hapticData->currentSeqIndex];
182 return duration;
183 }
184
ProcessHapticEffect(struct VibratorHapticData * hapticData)185 static uint32_t ProcessHapticEffect(struct VibratorHapticData *hapticData)
186 {
187 uint32_t effect;
188 uint32_t duration;
189
190 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_FAILURE);
191
192 if ((hapticData->currentSeqIndex < 0) || ((hapticData->currentSeqIndex + 1) >= hapticData->seqCount)) {
193 HDF_LOGE("%s: seq index invalid para", __func__);
194 return 0;
195 }
196
197 hapticData->currentSeqIndex++;
198 effect = hapticData->currentEffectSeq[hapticData->currentSeqIndex];
199 SetEffectVibrator(effect);
200
201 hapticData->currentSeqIndex++;
202 if (hapticData->currentSeqIndex >= hapticData->seqCount) {
203 HDF_LOGE("%s: seq index exceed max value", __func__);
204 return 0;
205 }
206
207 duration = hapticData->currentEffectSeq[hapticData->currentSeqIndex] == 0 ?
208 VIBRATOR_MIN_WAIT_TIME : hapticData->currentEffectSeq[hapticData->currentSeqIndex];
209 return duration;
210 }
211
HapticTimerEntry(uintptr_t para)212 void HapticTimerEntry(uintptr_t para)
213 {
214 int32_t ret;
215 struct VibratorHapticData *hapticData = NULL;
216 uint32_t duration;
217
218 hapticData = (struct VibratorHapticData *)para;
219 CHECK_VIBRATOR_NULL_PTR_RETURN(hapticData);
220
221 if (hapticData->effectType == VIBRATOR_TYPE_TIME) {
222 duration = ProcessHapticTime(hapticData);
223 }
224
225 if (hapticData->effectType == VIBRATOR_TYPE_EFFECT) {
226 duration = ProcessHapticEffect(hapticData);
227 }
228
229 duration = ((duration > 0) && (duration < VIBRATOR_MIN_WAIT_TIME)) ? VIBRATOR_MIN_WAIT_TIME : duration;
230 if ((duration > 0) && (OsalTimerSetTimeout(&hapticData->timer, duration) == HDF_SUCCESS)) {
231 return;
232 }
233
234 if (hapticData->timer.realTimer != NULL) {
235 ret = OsalTimerDelete(&hapticData->timer);
236 if (ret != HDF_SUCCESS) {
237 HDF_LOGE("%s: delete haptic timer fail!", __func__);
238 }
239 }
240
241 return;
242 }
243
GetHapticSeqByEffect(struct VibratorEffectCfg * effectCfg)244 static int32_t GetHapticSeqByEffect(struct VibratorEffectCfg *effectCfg)
245 {
246 struct VibratorHapticData *hapticData = NULL;
247 struct VibratorEffectNode *pos = NULL;
248 struct VibratorEffectNode *tmp = NULL;
249
250 hapticData = GetHapticData();
251 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_FAILURE);
252
253 (void)OsalMutexLock(&hapticData->mutex);
254 hapticData->seqCount = 0;
255 hapticData->currentEffectSeq = NULL;
256 hapticData->currentSeqIndex = 0;
257
258 if (effectCfg->cfgMode == VIBRATOR_MODE_ONCE) {
259 hapticData->duration[VIBRATOR_TIME_DELAY_INDEX] = VIBRATOR_MIN_WAIT_TIME;
260 hapticData->duration[VIBRATOR_TIME_DURATION_INDEX] = effectCfg->duration;
261 hapticData->effectType = VIBRATOR_TYPE_TIME;
262 hapticData->seqCount = VIBRATOR_TIME_INDEX_BUTT;
263 hapticData->currentEffectSeq = &hapticData->duration[VIBRATOR_TIME_DELAY_INDEX];
264 (void)OsalMutexUnlock(&hapticData->mutex);
265 return HDF_SUCCESS;
266 }
267
268 if ((effectCfg->cfgMode == VIBRATOR_MODE_PRESET) && (effectCfg->effect != NULL)) {
269 DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &hapticData->effectSeqHead, struct VibratorEffectNode, node) {
270 if (strcmp(effectCfg->effect, pos->effect) == 0 && pos->seq != NULL) {
271 hapticData->effectType = (int32_t)pos->type;
272 HDF_LOGE("%s: pos_num = %d", __func__, pos->num);
273 hapticData->seqCount = pos->num;
274 hapticData->currentEffectSeq = &(pos->seq[0]);
275 break;
276 }
277 }
278 if ((hapticData->seqCount <= 1) || (hapticData->seqCount > VIBRATOR_MAX_HAPTIC_SEQ)) {
279 HDF_LOGE("%s: not find effect type!", __func__);
280 (void)OsalMutexUnlock(&hapticData->mutex);
281 return HDF_ERR_INVALID_PARAM;
282 }
283 (void)OsalMutexUnlock(&hapticData->mutex);
284 return HDF_SUCCESS;
285 }
286
287 HDF_LOGE("%s: not support effect type!", __func__);
288 (void)OsalMutexUnlock(&hapticData->mutex);
289 return HDF_ERR_NOT_SUPPORT;
290 }
291
StartHaptic(struct VibratorEffectCfg * effectCfg)292 int32_t StartHaptic(struct VibratorEffectCfg *effectCfg)
293 {
294 int32_t ret;
295 uint32_t duration;
296 struct VibratorHapticData *hapticData = GetHapticData();
297 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(effectCfg, HDF_FAILURE);
298 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_FAILURE);
299
300 if ((effectCfg->cfgMode == VIBRATOR_MODE_PRESET) && (!hapticData->supportHaptic)) {
301 HDF_LOGE("%s: vibrator no support haptic!", __func__);
302 return HDF_ERR_NOT_SUPPORT;
303 }
304
305 ret = GetHapticSeqByEffect(effectCfg);
306 if (ret != HDF_SUCCESS) {
307 HDF_LOGE("%s: get haptic seq fail!", __func__);
308 return ret;
309 }
310
311 duration = hapticData->currentEffectSeq[0] < VIBRATOR_MIN_WAIT_TIME ?
312 VIBRATOR_MIN_WAIT_TIME : hapticData->currentEffectSeq[0];
313
314 if (OsalTimerCreate(&hapticData->timer, duration, HapticTimerEntry, (uintptr_t)hapticData) != HDF_SUCCESS) {
315 HDF_LOGE("%s: create vibrator timer fail!", __func__);
316 return HDF_FAILURE;
317 }
318
319 if (OsalTimerStartLoop(&hapticData->timer) != HDF_SUCCESS) {
320 HDF_LOGE("%s: start vibrator timer fail!", __func__);
321 return HDF_FAILURE;
322 }
323
324 return HDF_SUCCESS;
325 }
326
StopHaptic(void)327 int32_t StopHaptic(void)
328 {
329 int32_t ret;
330 struct VibratorHapticData *hapticData = GetHapticData();
331
332 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_FAILURE);
333
334 if (hapticData->timer.realTimer != NULL) {
335 HDF_LOGE("%s: delete vibrator Timer!", __func__);
336 (void)OsalMutexLock(&hapticData->mutex);
337 ret = OsalTimerDelete(&hapticData->timer);
338 (void)OsalMutexUnlock(&hapticData->mutex);
339 if (ret != HDF_SUCCESS) {
340 HDF_LOGE("%s: delete vibrator timer fail!", __func__);
341 return ret;
342 }
343 }
344
345 StopVibrator();
346 return HDF_SUCCESS;
347 }
348
CreateVibratorHaptic(struct HdfDeviceObject * device)349 int32_t CreateVibratorHaptic(struct HdfDeviceObject *device)
350 {
351 struct VibratorHapticData *hapticData = NULL;
352 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE);
353
354 hapticData = (struct VibratorHapticData *)OsalMemCalloc(sizeof(*hapticData));
355 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_ERR_MALLOC_FAIL);
356 g_vibratorHapticData = hapticData;
357 hapticData->supportHaptic = false;
358
359 if (OsalMutexInit(&hapticData->mutex) != HDF_SUCCESS) {
360 HDF_LOGE("%s: fail to init mutex", __func__);
361 goto EXIT;
362 }
363
364 DListHeadInit(&hapticData->effectSeqHead);
365
366 // get haptic hcs
367 if (ParserVibratorHapticConfig(device->property) != HDF_SUCCESS) {
368 HDF_LOGE("%s: parser haptic config fail!", __func__);
369 goto EXIT;
370 }
371
372 return HDF_SUCCESS;
373 EXIT:
374 OsalMemFree(hapticData);
375 return HDF_FAILURE;
376 }
377
FreeHapticConfig(void)378 static void FreeHapticConfig(void)
379 {
380 struct VibratorHapticData *hapticData = GetHapticData();
381 struct VibratorEffectNode *pos = NULL;
382 struct VibratorEffectNode *tmp = NULL;
383
384 if (hapticData == NULL) {
385 return;
386 }
387
388 (void)OsalMutexLock(&hapticData->mutex);
389 DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &hapticData->effectSeqHead, struct VibratorEffectNode, node) {
390 if (pos->seq != NULL) {
391 OsalMemFree(pos->seq);
392 pos->seq = NULL;
393 }
394 pos->effect = NULL;
395 DListRemove(&pos->node);
396 OsalMemFree(pos);
397 }
398 (void)OsalMutexUnlock(&hapticData->mutex);
399 }
400
DestroyVibratorHaptic(void)401 int32_t DestroyVibratorHaptic(void)
402 {
403 struct VibratorHapticData *hapticData = GetHapticData();
404 CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_FAILURE);
405
406 if (hapticData->supportHaptic) {
407 FreeHapticConfig();
408 }
409
410 (void)OsalMutexDestroy(&hapticData->mutex);
411
412 return HDF_SUCCESS;
413 }
414