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