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