• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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