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