• 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    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