1 /*
2  * Copyright (c) 2021-2023 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_driver.h"
10 #include <securec.h>
11 #include "hdf_base.h"
12 #include "hdf_device_desc.h"
13 #include "osal_mem.h"
14 #include "vibrator_haptic.h"
15 
16 #define HDF_LOG_TAG    khdf_vibrator_driver
17 
18 #define VIBRATOR_WORK_QUEUE_NAME    "vibrator_queue"
19 #define VIBRATOR_START_TIME    10
20 
21 struct VibratorDriverData *g_vibratorDrvData = NULL;
22 
GetVibratorDrvData(void)23 static struct VibratorDriverData *GetVibratorDrvData(void)
24 {
25     return g_vibratorDrvData;
26 }
27 
RegisterVibratorOps(struct VibratorOps * ops)28 int32_t RegisterVibratorOps(struct VibratorOps *ops)
29 {
30     struct VibratorDriverData *drvData = GetVibratorDrvData();
31 
32     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(ops, HDF_FAILURE);
33     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
34 
35     (void)OsalMutexLock(&drvData->mutex);
36     drvData->ops.Start = ops->Start;
37     drvData->ops.StartEffect = ops->StartEffect;
38     drvData->ops.Stop = ops->Stop;
39     drvData->ops.SetParameter = ops->SetParameter;
40     (void)OsalMutexUnlock(&drvData->mutex);
41 
42     return HDF_SUCCESS;
43 }
44 
RegisterVibratorInfo(struct VibratorInfo * vibratorInfo)45 int32_t RegisterVibratorInfo(struct VibratorInfo *vibratorInfo)
46 {
47     struct VibratorDriverData *drvData = GetVibratorDrvData();
48 
49     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(vibratorInfo, HDF_FAILURE);
50     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
51 
52     (void)OsalMutexLock(&drvData->mutex);
53     if (memcpy_s(&drvData->vibratorInfo, sizeof(drvData->vibratorInfo), vibratorInfo, sizeof(*vibratorInfo)) != EOK) {
54         (void)OsalMutexUnlock(&drvData->mutex);
55         HDF_LOGE("%s: Memcpy vibrator config failed!", __func__);
56         return HDF_FAILURE;
57     }
58     (void)OsalMutexUnlock(&drvData->mutex);
59 
60     return HDF_SUCCESS;
61 }
62 
StartVibrator(void)63 void StartVibrator(void)
64 {
65     struct VibratorDriverData *drvData = GetVibratorDrvData();
66 
67     CHECK_VIBRATOR_NULL_PTR_RETURN(drvData);
68 
69     drvData->state = VIBRATOR_STATE_START_TIMER;
70     HdfAddWork(&drvData->workQueue, &drvData->work);
71 }
72 
StopVibrator(void)73 void StopVibrator(void)
74 {
75     struct VibratorDriverData *drvData = GetVibratorDrvData();
76     CHECK_VIBRATOR_NULL_PTR_RETURN(drvData);
77 
78     drvData->state = VIBRATOR_STATE_STOP;
79     HdfAddWork(&drvData->workQueue, &drvData->work);
80 }
81 
SetEffectVibrator(uint32_t type)82 void SetEffectVibrator(uint32_t type)
83 {
84     int32_t ret;
85     struct VibratorDriverData *drvData = GetVibratorDrvData();
86 
87     CHECK_VIBRATOR_NULL_PTR_RETURN(drvData);
88     CHECK_VIBRATOR_NULL_PTR_RETURN(drvData->ops.StartEffect);
89 
90     ret = drvData->ops.StartEffect(type);
91     if (ret != HDF_SUCCESS) {
92         HDF_LOGE("%s: start effect failed!", __func__);
93         return;
94     }
95 
96     drvData->state = VIBRATOR_STATE_SET_EFFECT;
97 }
98 
VibratorWorkEntry(void * para)99 static void VibratorWorkEntry(void *para)
100 {
101     int32_t ret = HDF_FAILURE;
102     struct VibratorDriverData *drvData = (struct VibratorDriverData *)para;
103 
104     CHECK_VIBRATOR_NULL_PTR_RETURN(drvData);
105     CHECK_VIBRATOR_NULL_PTR_RETURN(drvData->ops.Start);
106     CHECK_VIBRATOR_NULL_PTR_RETURN(drvData->ops.Stop);
107 
108     if (drvData->state == VIBRATOR_STATE_START_TIMER) {
109         ret = drvData->ops.Start();
110         if (ret != HDF_SUCCESS) {
111             HDF_LOGE("%s: add vibrator work fail! device state[%d]!", __func__, drvData->state);
112         }
113     }
114 
115     if (drvData->state == VIBRATOR_STATE_STOP) {
116         ret = drvData->ops.Stop();
117         if (ret != HDF_SUCCESS) {
118             HDF_LOGE("%s: add vibrator work fail! device state[%d]!", __func__, drvData->state);
119         }
120     }
121 }
122 
StartOnce(struct HdfSBuf * data,struct HdfSBuf * reply)123 static int32_t StartOnce(struct HdfSBuf *data, struct HdfSBuf *reply)
124 {
125     uint32_t duration;
126     int32_t ret;
127     struct VibratorEffectCfg config;
128     struct VibratorDriverData *drvData = GetVibratorDrvData();
129     (void)reply;
130 
131     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(data, HDF_FAILURE);
132     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
133 
134     if (!HdfSbufReadUint32(data, &duration)) {
135         HDF_LOGE("%s: sbuf read duration failed!", __func__);
136         return HDF_FAILURE;
137     }
138 
139     if (drvData->mode != VIBRATOR_MODE_BUTT) {
140         HDF_LOGI("%s: vibrater haptic is busy now, please stop first!", __func__);
141         return HDF_ERR_DEVICE_BUSY;
142     }
143 
144     (void)OsalMutexLock(&drvData->mutex);
145     drvData->mode = VIBRATOR_MODE_ONCE;
146     (void)OsalMutexUnlock(&drvData->mutex);
147 
148     // start once time vibrate
149     config.cfgMode = VIBRATOR_MODE_ONCE;
150     config.duration = duration;
151     config.effect = NULL;
152 
153     ret = StartHaptic(&config);
154     if (ret != HDF_SUCCESS) {
155         HDF_LOGE("%s: start haptic failed!", __func__);
156         return ret;
157     }
158 
159     return HDF_SUCCESS;
160 }
161 
StartEffect(struct HdfSBuf * data,struct HdfSBuf * reply)162 static int32_t StartEffect(struct HdfSBuf *data, struct HdfSBuf *reply)
163 {
164     int32_t ret;
165     const char *effect = NULL;
166     struct VibratorEffectCfg config;
167     struct VibratorDriverData *drvData = GetVibratorDrvData();
168     (void)reply;
169 
170     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(data, HDF_FAILURE);
171     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
172 
173     effect = HdfSbufReadString(data);
174     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(effect, HDF_FAILURE);
175 
176     if (drvData->mode != VIBRATOR_MODE_BUTT) {
177         HDF_LOGI("%s: vibrater haptic is busy now, please stop first!", __func__);
178         return HDF_ERR_DEVICE_BUSY;
179     }
180 
181     (void)OsalMutexLock(&drvData->mutex);
182     drvData->mode = VIBRATOR_MODE_PRESET;
183     (void)OsalMutexUnlock(&drvData->mutex);
184 
185     // start once time vibrate
186     config.cfgMode = VIBRATOR_MODE_PRESET;
187     config.duration = 0;
188     config.effect = effect;
189 
190     ret = StartHaptic(&config);
191     if (ret != HDF_SUCCESS) {
192         HDF_LOGE("%s: start haptic failed!", __func__);
193         return ret;
194     }
195 
196     return HDF_SUCCESS;
197 }
198 
Stop(struct HdfSBuf * data,struct HdfSBuf * reply)199 static int32_t Stop(struct HdfSBuf *data, struct HdfSBuf *reply)
200 {
201     int32_t ret;
202     int32_t mode;
203     struct VibratorDriverData *drvData = GetVibratorDrvData();
204     (void)reply;
205 
206     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(data, HDF_FAILURE);
207     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
208 
209     if (!HdfSbufReadInt32(data, &mode)) {
210         HDF_LOGE("%s: sbuf read mode failed!", __func__);
211         return HDF_FAILURE;
212     }
213 
214     if ((mode != VIBRATOR_MODE_ONCE) && (mode != VIBRATOR_MODE_PRESET)) {
215         HDF_LOGE("%s: vibrator stop mode failed!", __func__);
216         return HDF_FAILURE;
217     }
218 
219     if (drvData->mode == VIBRATOR_MODE_BUTT) {
220         HDF_LOGD("%s: vibrater haptic had stopped!", __func__);
221         return HDF_SUCCESS;
222     }
223 
224     ret = StopHaptic();
225     if (ret != HDF_SUCCESS) {
226         HDF_LOGE("%s: stop haptic failed!", __func__);
227         return ret;
228     }
229 
230     (void)OsalMutexLock(&drvData->mutex);
231     drvData->mode = VIBRATOR_MODE_BUTT;
232     (void)OsalMutexUnlock(&drvData->mutex);
233 
234     return HDF_SUCCESS;
235 }
236 
GetVibratorInfo(struct HdfSBuf * data,struct HdfSBuf * reply)237 static int32_t GetVibratorInfo(struct HdfSBuf *data, struct HdfSBuf *reply)
238 {
239     (void)data;
240     struct VibratorDriverData *drvData;
241 
242     drvData = GetVibratorDrvData();
243     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
244     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(reply, HDF_ERR_INVALID_PARAM);
245 
246     if (!HdfSbufWriteBuffer(reply, &drvData->vibratorInfo, sizeof(drvData->vibratorInfo))) {
247         HDF_LOGE("%s: write sbuf failed!", __func__);
248         return HDF_FAILURE;
249     }
250 
251     return HDF_SUCCESS;
252 }
253 
EnableModulationParameter(struct HdfSBuf * data,struct HdfSBuf * reply)254 static int32_t EnableModulationParameter(struct HdfSBuf *data, struct HdfSBuf *reply)
255 {
256     (void)reply;
257     struct VibratorEffectCfg config;
258     struct VibratorDriverData *drvData;
259     uint32_t duration;
260     uint16_t intensity;
261     int16_t frequency;
262     int32_t ret;
263 
264     drvData = GetVibratorDrvData();
265     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
266     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData->ops.SetParameter, HDF_ERR_INVALID_PARAM);
267     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
268 
269     if (drvData->mode != VIBRATOR_MODE_BUTT) {
270         HDF_LOGE("%s: vibrater is busy now, please stop first!", __func__);
271         return HDF_ERR_DEVICE_BUSY;
272     }
273 
274     if (!HdfSbufReadUint32(data, &duration)) {
275         HDF_LOGE("%s: sbuf read vibration period failed!", __func__);
276         return HDF_FAILURE;
277     }
278 
279     if (!HdfSbufReadUint16(data, &intensity)) {
280         HDF_LOGE("%s: sbuf read intensity failed!", __func__);
281         return HDF_FAILURE;
282     }
283 
284     if (!HdfSbufReadInt16(data, &frequency)) {
285         HDF_LOGE("%s: sbuf read frequency failed!", __func__);
286         return HDF_FAILURE;
287     }
288 
289     (void)OsalMutexLock(&drvData->mutex);
290     drvData->mode = VIBRATOR_MODE_ONCE;
291     (void)OsalMutexUnlock(&drvData->mutex);
292 
293     ret = drvData->ops.SetParameter(intensity, frequency);
294     if (ret != HDF_SUCCESS) {
295         HDF_LOGE("%s: set parameter failed!", __func__);
296         return HDF_FAILURE;
297     }
298 
299     config.cfgMode = VIBRATOR_MODE_ONCE;
300     config.duration = duration;
301     config.effect = NULL;
302 
303     ret = StartHaptic(&config);
304     if (ret != HDF_SUCCESS) {
305         HDF_LOGE("%s: start haptic failed!", __func__);
306         return HDF_FAILURE;
307     }
308 
309     return HDF_SUCCESS;
310 }
311 static struct VibratorCmdHandleList g_vibratorCmdHandle[] = {
312     {VIBRATOR_DRV_IO_START_ONCE, StartOnce},
313     {VIBRATOR_DRV_IO_START_PRESET, StartEffect},
314     {VIBRATOR_DRV_IO_STOP, Stop},
315     {VIBRATOR_DRV_IO_GET_INFO, GetVibratorInfo},
316     {VIBRATOR_DRV_IO_ENABLE_MODULATION_PARAMETER, EnableModulationParameter},
317 };
318 
DispatchVibrator(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)319 static int32_t DispatchVibrator(struct HdfDeviceIoClient *client,
320     int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
321 {
322     (void)client;
323     int32_t loop;
324 
325     for (loop = 0; loop < sizeof(g_vibratorCmdHandle) / sizeof(g_vibratorCmdHandle[0]); ++loop) {
326         if ((cmd == g_vibratorCmdHandle[loop].cmd) && (g_vibratorCmdHandle[loop].func != NULL)) {
327             return g_vibratorCmdHandle[loop].func(data, reply);
328         }
329     }
330 
331     return HDF_SUCCESS;
332 }
333 
BindVibratorDriver(struct HdfDeviceObject * device)334 int32_t BindVibratorDriver(struct HdfDeviceObject *device)
335 {
336     struct VibratorDriverData *drvData = NULL;
337     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE);
338 
339     drvData = (struct VibratorDriverData *)OsalMemCalloc(sizeof(*drvData));
340     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_MALLOC_FAIL);
341 
342     drvData->ioService.Dispatch = DispatchVibrator;
343     drvData->device = device;
344     device->service = &drvData->ioService;
345     g_vibratorDrvData = drvData;
346 
347     return HDF_SUCCESS;
348 }
349 
InitVibratorDriver(struct HdfDeviceObject * device)350 int32_t InitVibratorDriver(struct HdfDeviceObject *device)
351 {
352     struct VibratorDriverData *drvData = NULL;
353 
354     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE);
355     drvData = (struct VibratorDriverData *)device->service;
356     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
357 
358     drvData->mode = VIBRATOR_MODE_BUTT;
359     drvData->state = VIBRATOR_STATE_IDLE;
360 
361     if (OsalMutexInit(&drvData->mutex) != HDF_SUCCESS) {
362         HDF_LOGE("%s: init mutex failed!", __func__);
363         return HDF_FAILURE;
364     }
365 
366     if (HdfWorkQueueInit(&drvData->workQueue, VIBRATOR_WORK_QUEUE_NAME) != HDF_SUCCESS) {
367         HDF_LOGE("%s: init workQueue failed!", __func__);
368         return HDF_FAILURE;
369     }
370 
371     if (HdfWorkInit(&drvData->work, VibratorWorkEntry, (void*)drvData) != HDF_SUCCESS) {
372         HDF_LOGE("%s: init workQueue failed!", __func__);
373         return HDF_FAILURE;
374     }
375 
376     if (CreateVibratorHaptic(device) != HDF_SUCCESS) {
377         HDF_LOGE("%s: init workQueue failed!", __func__);
378         return HDF_FAILURE;
379     }
380 
381     return HDF_SUCCESS;
382 }
383 
ReleaseVibratorDriver(struct HdfDeviceObject * device)384 void ReleaseVibratorDriver(struct HdfDeviceObject *device)
385 {
386     struct VibratorDriverData *drvData = NULL;
387 
388     if (device == NULL) {
389         HDF_LOGE("%s: device is null!", __func__);
390         return;
391     }
392 
393     drvData = (struct VibratorDriverData *)device->service;
394     if (drvData == NULL) {
395         HDF_LOGE("%s: drvData is null!", __func__);
396         return;
397     }
398 
399     (void)DestroyVibratorHaptic();
400     (void)OsalMutexDestroy(&drvData->mutex);
401     OsalMemFree(drvData);
402     g_vibratorDrvData = NULL;
403 }
404 
405 struct HdfDriverEntry g_vibratorDriverEntry = {
406     .moduleVersion = 1,
407     .moduleName = "HDF_VIBRATOR",
408     .Bind = BindVibratorDriver,
409     .Init = InitVibratorDriver,
410     .Release = ReleaseVibratorDriver,
411 };
412 
413 HDF_INIT(g_vibratorDriverEntry);
414