• 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_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    hdf_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 
RegisterVibrator(struct VibratorOps * ops)28 int32_t RegisterVibrator(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     (void)OsalMutexUnlock(&drvData->mutex);
40 
41     return HDF_SUCCESS;
42 }
43 
StartTimeVibrator()44 void StartTimeVibrator()
45 {
46     struct VibratorDriverData *drvData = GetVibratorDrvData();
47 
48     CHECK_VIBRATOR_NULL_PTR_RETURN(drvData);
49 
50     drvData->state = VIBRATOR_STATE_START_TIMER;
51     HdfAddWork(&drvData->workQueue, &drvData->work);
52 }
53 
StopVibrator()54 void StopVibrator()
55 {
56     struct VibratorDriverData *drvData = GetVibratorDrvData();
57 
58     CHECK_VIBRATOR_NULL_PTR_RETURN(drvData);
59 
60     drvData->state = VIBRATOR_STATE_STOP;
61     HdfAddWork(&drvData->workQueue, &drvData->work);
62 }
63 
SetEffectVibrator(uint32_t type)64 void SetEffectVibrator(uint32_t type)
65 {
66     int32_t ret;
67     struct VibratorDriverData *drvData = GetVibratorDrvData();
68 
69     CHECK_VIBRATOR_NULL_PTR_RETURN(drvData);
70     CHECK_VIBRATOR_NULL_PTR_RETURN(drvData->ops.StartEffect);
71 
72     ret = drvData->ops.StartEffect(type);
73     if (ret != HDF_SUCCESS) {
74         HDF_LOGE("%s: start effect fail", __func__);
75         return;
76     }
77 
78     drvData->state = VIBRATOR_STATE_SET_EFFECT;
79 }
80 
VibratorWorkEntry(void * para)81 static void VibratorWorkEntry(void *para)
82 {
83     int32_t ret = HDF_FAILURE;
84     struct VibratorDriverData *drvData = (struct VibratorDriverData *)para;
85 
86     CHECK_VIBRATOR_NULL_PTR_RETURN(drvData);
87     CHECK_VIBRATOR_NULL_PTR_RETURN(drvData->ops.Start);
88     CHECK_VIBRATOR_NULL_PTR_RETURN(drvData->ops.Stop);
89 
90     if (drvData->state == VIBRATOR_STATE_START_TIMER) {
91         ret = drvData->ops.Start();
92     }
93 
94     if (drvData->state == VIBRATOR_STATE_STOP) {
95         ret = drvData->ops.Stop();
96     }
97 
98     if (ret != HDF_SUCCESS) {
99         HDF_LOGE("%s: add vibrator work fail! device state[%d]!", __func__, drvData->state);
100     }
101 }
102 
StartOnce(struct HdfSBuf * data,struct HdfSBuf * reply)103 static int32_t StartOnce(struct HdfSBuf *data, struct HdfSBuf *reply)
104 {
105     uint32_t duration;
106     int32_t ret;
107     struct VibratorEffectCfg config;
108     struct VibratorDriverData *drvData = GetVibratorDrvData();
109     (void)reply;
110 
111     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(data, HDF_FAILURE);
112     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
113 
114     if (!HdfSbufReadUint32(data, &duration)) {
115         HDF_LOGE("%s: sbuf read duration failed", __func__);
116         return HDF_FAILURE;
117     }
118 
119     if (duration == 0) {
120         HDF_LOGE("%s: vibrator duration invalid para", __func__);
121         return HDF_ERR_INVALID_PARAM;
122     }
123 
124     if (drvData->mode != VIBRATOR_MODE_BUTT) {
125         HDF_LOGI("%s: vibrater haptic is busy now, please stop first!", __func__);
126         return HDF_ERR_DEVICE_BUSY;
127     }
128 
129     (void)OsalMutexLock(&drvData->mutex);
130     drvData->mode = VIBRATOR_MODE_ONCE;
131     (void)OsalMutexUnlock(&drvData->mutex);
132 
133     // start once time vibrate
134     config.cfgMode = VIBRATOR_MODE_ONCE;
135     config.duration = duration;
136     config.effect = NULL;
137 
138     ret = StartHaptic(&config);
139     if (ret != HDF_SUCCESS) {
140         HDF_LOGE("%s: start haptic fail!", __func__);
141         return ret;
142     }
143 
144     return HDF_SUCCESS;
145 }
146 
StartEffect(struct HdfSBuf * data,struct HdfSBuf * reply)147 static int32_t StartEffect(struct HdfSBuf *data, struct HdfSBuf *reply)
148 {
149     int32_t ret;
150     const char *effect = NULL;
151     struct VibratorEffectCfg config;
152     struct VibratorDriverData *drvData = GetVibratorDrvData();
153     (void)reply;
154 
155     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(data, HDF_FAILURE);
156     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
157 
158     effect = HdfSbufReadString(data);
159     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(effect, HDF_FAILURE);
160 
161     if (drvData->mode != VIBRATOR_MODE_BUTT) {
162         HDF_LOGI("%s: vibrater haptic is busy now, please stop first!", __func__);
163         return HDF_ERR_DEVICE_BUSY;
164     }
165 
166     (void)OsalMutexLock(&drvData->mutex);
167     drvData->mode = VIBRATOR_MODE_PRESET;
168     (void)OsalMutexUnlock(&drvData->mutex);
169 
170     // start once time vibrate
171     config.cfgMode = VIBRATOR_MODE_PRESET;
172     config.duration = 0;
173     config.effect = effect;
174 
175     ret = StartHaptic(&config);
176     if (ret != HDF_SUCCESS) {
177         HDF_LOGE("%s: start haptic fail!", __func__);
178         return ret;
179     }
180 
181     return HDF_SUCCESS;
182 }
183 
Stop(struct HdfSBuf * data,struct HdfSBuf * reply)184 static int32_t Stop(struct HdfSBuf *data, struct HdfSBuf *reply)
185 {
186     int32_t ret;
187     int32_t mode;
188     struct VibratorDriverData *drvData = GetVibratorDrvData();
189     (void)reply;
190 
191     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(data, HDF_FAILURE);
192     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
193 
194     if (!HdfSbufReadInt32(data, &mode)) {
195         HDF_LOGE("%s: sbuf read mode failed", __func__);
196         return HDF_FAILURE;
197     }
198 
199     if ((mode != VIBRATOR_MODE_ONCE) && (mode != VIBRATOR_MODE_PRESET)) {
200         HDF_LOGE("%s: vibrator stop mode failed", __func__);
201         return HDF_FAILURE;
202     }
203 
204     if (drvData->mode == VIBRATOR_MODE_BUTT) {
205         HDF_LOGD("%s: vibrater haptic had stopped", __func__);
206         return HDF_SUCCESS;
207     }
208 
209     ret = StopHaptic();
210     if (ret != HDF_SUCCESS) {
211         HDF_LOGE("%s: stop haptic fail!", __func__);
212         return ret;
213     }
214 
215     (void)OsalMutexLock(&drvData->mutex);
216     drvData->mode = VIBRATOR_MODE_BUTT;
217     (void)OsalMutexUnlock(&drvData->mutex);
218 
219     return HDF_SUCCESS;
220 }
221 
222 static struct VibratorCmdHandleList g_vibratorCmdHandle[] = {
223     {VIBRATOR_DRV_IO_START_ONCE, StartOnce},
224     {VIBRATOR_DRV_IO_START_PRESET, StartEffect},
225     {VIBRATOR_DRV_IO_STOP, Stop},
226 };
227 
DispatchVibrator(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)228 static int32_t DispatchVibrator(struct HdfDeviceIoClient *client,
229     int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
230 {
231     int32_t loop;
232 
233     for (loop = 0; loop < sizeof(g_vibratorCmdHandle) / sizeof(g_vibratorCmdHandle[0]); ++loop) {
234         if ((cmd == g_vibratorCmdHandle[loop].cmd) && (g_vibratorCmdHandle[loop].func != NULL)) {
235             return g_vibratorCmdHandle[loop].func(data, reply);
236         }
237     }
238 
239     return HDF_SUCCESS;
240 }
241 
BindVibratorDriver(struct HdfDeviceObject * device)242 int32_t BindVibratorDriver(struct HdfDeviceObject *device)
243 {
244     struct VibratorDriverData *drvData = NULL;
245     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE);
246 
247     drvData = (struct VibratorDriverData *)OsalMemCalloc(sizeof(*drvData));
248     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_MALLOC_FAIL);
249 
250     drvData->ioService.Dispatch = DispatchVibrator;
251     drvData->device = device;
252     device->service = &drvData->ioService;
253     g_vibratorDrvData = drvData;
254 
255     return HDF_SUCCESS;
256 }
257 
InitVibratorDriver(struct HdfDeviceObject * device)258 int32_t InitVibratorDriver(struct HdfDeviceObject *device)
259 {
260     struct VibratorDriverData *drvData = NULL;
261 
262     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE);
263     drvData = (struct VibratorDriverData *)device->service;
264     CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
265 
266     drvData->mode = VIBRATOR_MODE_BUTT;
267     drvData->state = VIBRATOR_STATE_IDLE;
268 
269     if (OsalMutexInit(&drvData->mutex) != HDF_SUCCESS) {
270         HDF_LOGE("%s: init mutex fail!", __func__);
271         return HDF_FAILURE;
272     }
273 
274     if (HdfWorkQueueInit(&drvData->workQueue, VIBRATOR_WORK_QUEUE_NAME) != HDF_SUCCESS) {
275         HDF_LOGE("%s: init workQueue fail!", __func__);
276         return HDF_FAILURE;
277     }
278 
279     if (HdfWorkInit(&drvData->work, VibratorWorkEntry, (void*)drvData) != HDF_SUCCESS) {
280         HDF_LOGE("%s: init workQueue fail!", __func__);
281         return HDF_FAILURE;
282     }
283 
284     if (CreateVibratorHaptic(device) != HDF_SUCCESS) {
285         HDF_LOGE("%s: init workQueue fail!", __func__);
286         return HDF_FAILURE;
287     }
288 
289     return HDF_SUCCESS;
290 }
291 
ReleaseVibratorDriver(struct HdfDeviceObject * device)292 void ReleaseVibratorDriver(struct HdfDeviceObject *device)
293 {
294     struct VibratorDriverData *drvData = NULL;
295 
296     if (device == NULL) {
297         HDF_LOGE("%s: device is null", __func__);
298         return;
299     }
300 
301     drvData = (struct VibratorDriverData *)device->service;
302     if (drvData == NULL) {
303         HDF_LOGE("%s: drvData is null", __func__);
304         return;
305     }
306 
307     (void)DestroyVibratorHaptic();
308     (void)OsalMutexDestroy(&drvData->mutex);
309     (void)OsalMemFree(drvData);
310     g_vibratorDrvData = NULL;
311 }
312 
313 struct HdfDriverEntry g_vibratorDriverEntry = {
314     .moduleVersion = 1,
315     .moduleName = "HDF_VIBRATOR",
316     .Bind = BindVibratorDriver,
317     .Init = InitVibratorDriver,
318     .Release = ReleaseVibratorDriver,
319 };
320 
321 HDF_INIT(g_vibratorDriverEntry);
322