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