1 /*
2 * Copyright (c) 2022 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 "light_driver.h"
10 #include <securec.h>
11 #include "device_resource_if.h"
12 #include "hdf_device_desc.h"
13 #include "osal_mem.h"
14 #include "osal_mutex.h"
15
16 #define HDF_LOG_TAG khdf_light_driver
17
18 #define LIGHT_WORK_QUEUE_NAME "light_queue"
19
20 struct LightDriverData *g_lightDrvData = NULL;
21
GetLightDrvData(void)22 static struct LightDriverData *GetLightDrvData(void)
23 {
24 return g_lightDrvData;
25 }
26
GetAllLightInfo(struct HdfSBuf * data,struct HdfSBuf * reply)27 static int32_t GetAllLightInfo(struct HdfSBuf *data, struct HdfSBuf *reply)
28 {
29 (void)data;
30 uint32_t i;
31 struct LightInfo lightInfo;
32 struct LightDriverData *drvData = NULL;
33
34 drvData = GetLightDrvData();
35 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
36 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(reply, HDF_ERR_INVALID_PARAM);
37
38 if (!HdfSbufWriteUint32(reply, drvData->lightNum)) {
39 HDF_LOGE("%s: write sbuf failed", __func__);
40 return HDF_FAILURE;
41 }
42
43 for (i = 0; i < LIGHT_ID_BUTT; ++i) {
44 if (drvData->info[i] == NULL) {
45 continue;
46 }
47 lightInfo.lightId = i;
48
49 if (!HdfSbufWriteUint32(reply, lightInfo.lightId)) {
50 HDF_LOGE("%s: write lightId failed", __func__);
51 return HDF_FAILURE;
52 }
53
54 if (strcpy_s(lightInfo.lightName, NAME_MAX_LEN, drvData->info[i]->lightInfo.lightName) != EOK) {
55 HDF_LOGE("%s:copy lightName failed!", __func__);
56 return HDF_FAILURE;
57 }
58
59 if (!HdfSbufWriteString(reply, (const char *)lightInfo.lightName)) {
60 HDF_LOGE("%s: write lightName failed", __func__);
61 return HDF_FAILURE;
62 }
63
64 lightInfo.lightNumber = drvData->info[i]->lightInfo.lightNumber;
65 if (!HdfSbufWriteUint32(reply, lightInfo.lightNumber)) {
66 HDF_LOGE("%s: write lightNumber failed", __func__);
67 return HDF_FAILURE;
68 }
69
70 lightInfo.lightType = HDF_LIGHT_TYPE_RGB_COLOR;
71 if (!HdfSbufWriteUint32(reply, lightInfo.lightType)) {
72 HDF_LOGE("%s: write lightType failed", __func__);
73 return HDF_FAILURE;
74 }
75 }
76
77 return HDF_SUCCESS;
78 }
79
WriteGpio(int32_t busNum,uint32_t lightOn)80 static int32_t WriteGpio(int32_t busNum, uint32_t lightOn)
81 {
82 int32_t level;
83
84 if (busNum < 0) {
85 HDF_LOGE("%s: GPIO is wrong", __func__);
86 return HDF_SUCCESS;
87 }
88
89 if (lightOn == LIGHT_STATE_START) {
90 level = GPIO_VAL_HIGH;
91 } else {
92 level = GPIO_VAL_LOW;
93 }
94
95 return GpioWrite(busNum, level);
96 }
97
UpdateLight(uint32_t lightId,uint32_t lightOn)98 static int32_t UpdateLight(uint32_t lightId, uint32_t lightOn)
99 {
100 int32_t ret;
101 uint32_t lightBrightness;
102 struct LightDriverData *drvData = NULL;
103
104 drvData = GetLightDrvData();
105 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
106
107 if (drvData->info[lightId]->lightBrightness == 0) {
108 lightBrightness = drvData->info[lightId]->defaultBrightness;
109 } else {
110 lightBrightness = drvData->info[lightId]->lightBrightness;
111 }
112
113 if ((lightBrightness & LIGHT_MAKE_B_BIT) != 0) {
114 ret = WriteGpio(drvData->info[lightId]->busBNum, lightOn);
115 if (ret != HDF_SUCCESS) {
116 HDF_LOGE("%s: write blue light's gpio failed", __func__);
117 return HDF_FAILURE;
118 }
119 }
120
121 if ((lightBrightness & LIGHT_MAKE_G_BIT) != 0) {
122 ret = WriteGpio(drvData->info[lightId]->busGNum, lightOn);
123 if (ret != HDF_SUCCESS) {
124 HDF_LOGE("%s: write green light's gpio failed", __func__);
125 return HDF_FAILURE;
126 }
127 }
128
129 if ((lightBrightness & LIGHT_MAKE_R_BIT) != 0) {
130 ret = WriteGpio(drvData->info[lightId]->busRNum, lightOn);
131 if (ret != HDF_SUCCESS) {
132 HDF_LOGE("%s: write red light's gpio failed", __func__);
133 return HDF_FAILURE;
134 }
135 }
136
137 return HDF_SUCCESS;
138 }
139
StartLight(uint32_t lightId)140 int32_t StartLight(uint32_t lightId)
141 {
142 return UpdateLight(lightId, LIGHT_STATE_START);
143 }
144
StopLight(uint32_t lightId)145 int32_t StopLight(uint32_t lightId)
146 {
147 return UpdateLight(lightId, LIGHT_STATE_STOP);
148 }
149
LightTimerEntry(uintptr_t para)150 void LightTimerEntry(uintptr_t para)
151 {
152 uint32_t duration;
153 uint32_t lightId;
154 struct LightDriverData *drvData = NULL;
155
156 drvData = GetLightDrvData();
157 if (drvData == NULL) {
158 HDF_LOGE("%s: drvData is null", __func__);
159 return;
160 }
161
162 lightId = (uint32_t)para;
163 drvData->lightId = lightId;
164
165 if (drvData->info[lightId]->lightState == LIGHT_STATE_START) {
166 duration = drvData->info[lightId]->offTime;
167 }
168 if (drvData->info[lightId]->lightState == LIGHT_STATE_STOP) {
169 duration = drvData->info[lightId]->onTime;
170 }
171
172 HdfAddWork(&drvData->workQueue, &drvData->work);
173
174 if ((OsalTimerSetTimeout(&drvData->timer, duration) == HDF_SUCCESS)) {
175 return;
176 }
177
178 if (drvData->timer.realTimer != NULL) {
179 if (OsalTimerDelete(&drvData->timer) != HDF_SUCCESS) {
180 HDF_LOGE("%s: delete light timer fail!", __func__);
181 }
182 }
183
184 return;
185 }
186
TurnOnLight(uint32_t lightId,struct HdfSBuf * data,struct HdfSBuf * reply)187 static int32_t TurnOnLight(uint32_t lightId, struct HdfSBuf *data, struct HdfSBuf *reply)
188 {
189 (void)reply;
190 uint32_t len;
191 struct LightEffect *buf = NULL;
192 struct LightDriverData *drvData = NULL;
193
194 drvData = GetLightDrvData();
195 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
196
197 if (drvData->info[lightId] == NULL) {
198 HDF_LOGE("%s: light id info is null", __func__);
199 return HDF_FAILURE;
200 }
201
202 if (!HdfSbufReadBuffer(data, (const void **)&buf, &len)) {
203 HDF_LOGE("%s: light read data failed", __func__);
204 return HDF_FAILURE;
205 }
206
207 if (buf->lightColor.colorValue.rgbColor.r != 0) {
208 drvData->info[lightId]->lightBrightness |= 0X00FF0000;
209 }
210
211 if (buf->lightColor.colorValue.rgbColor.g != 0) {
212 drvData->info[lightId]->lightBrightness |= 0X0000FF00;
213 }
214
215 if (buf->lightColor.colorValue.rgbColor.b != 0) {
216 drvData->info[lightId]->lightBrightness |= 0X000000FF;
217 }
218
219 if (buf->flashEffect.flashMode == LIGHT_FLASH_NONE) {
220 return UpdateLight(lightId, LIGHT_STATE_START);
221 }
222
223 if (buf->flashEffect.flashMode == LIGHT_FLASH_BLINK) {
224 drvData->info[lightId]->onTime = (buf->flashEffect.onTime < drvData->info[lightId]->onTime) ?
225 drvData->info[lightId]->onTime : buf->flashEffect.onTime;
226 drvData->info[lightId]->offTime = (buf->flashEffect.offTime < drvData->info[lightId]->offTime) ?
227 drvData->info[lightId]->offTime : buf->flashEffect.offTime;
228
229 if (OsalTimerCreate(&drvData->timer, LIGHT_WAIT_TIME, LightTimerEntry, (uintptr_t)lightId) != HDF_SUCCESS) {
230 HDF_LOGE("%s: create light timer fail!", __func__);
231 return HDF_FAILURE;
232 }
233
234 if (OsalTimerStartLoop(&drvData->timer) != HDF_SUCCESS) {
235 HDF_LOGE("%s: start light timer fail!", __func__);
236 return HDF_FAILURE;
237 }
238 }
239
240 return HDF_SUCCESS;
241 }
242
TurnOnMultiLights(uint32_t lightId,struct HdfSBuf * data,struct HdfSBuf * reply)243 static int32_t TurnOnMultiLights(uint32_t lightId, struct HdfSBuf *data, struct HdfSBuf *reply)
244 {
245 (void)lightId;
246 (void)data;
247 (void)reply;
248 HDF_LOGI("%s: temporarily not supported turn on multi lights ", __func__);
249 return HDF_SUCCESS;
250 }
251
TurnOffLight(uint32_t lightId,struct HdfSBuf * data,struct HdfSBuf * reply)252 static int32_t TurnOffLight(uint32_t lightId, struct HdfSBuf *data, struct HdfSBuf *reply)
253 {
254 (void)data;
255 (void)reply;
256 struct LightDriverData *drvData = NULL;
257
258 drvData = GetLightDrvData();
259 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
260
261 if (drvData->info[lightId] == NULL) {
262 HDF_LOGE("%s: light id info is null", __func__);
263 return HDF_FAILURE;
264 }
265
266 if (UpdateLight(lightId, LIGHT_STATE_STOP) != HDF_SUCCESS) {
267 HDF_LOGE("%s: gpio write failed", __func__);
268 return HDF_FAILURE;
269 }
270
271 drvData->info[lightId]->lightState = LIGHT_STATE_STOP;
272 drvData->info[lightId]->lightBrightness = 0;
273
274 if (drvData->timer.realTimer != NULL) {
275 if (OsalTimerDelete(&drvData->timer) != HDF_SUCCESS) {
276 HDF_LOGE("%s: delete light timer fail!", __func__);
277 return HDF_FAILURE;
278 }
279 }
280
281 return HDF_SUCCESS;
282 }
283
284 static struct LightCmdHandleList g_lightCmdHandle[] = {
285 {LIGHT_OPS_IO_CMD_ENABLE, TurnOnLight},
286 {LIGHT_OPS_IO_CMD_DISABLE, TurnOffLight},
287 {LIGHT_OPS_IO_CMD_ENABLE_MULTI_LIGHTS, TurnOnMultiLights},
288 };
289
DispatchCmdHandle(uint32_t lightId,struct HdfSBuf * data,struct HdfSBuf * reply)290 static int32_t DispatchCmdHandle(uint32_t lightId, struct HdfSBuf *data, struct HdfSBuf *reply)
291 {
292 int32_t opsCmd;
293 int32_t loop;
294 int32_t count;
295
296 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
297
298 if (!HdfSbufReadInt32(data, &opsCmd)) {
299 HDF_LOGE("%s: sbuf read opsCmd failed", __func__);
300 return HDF_FAILURE;
301 }
302
303 if ((opsCmd >= LIGHT_OPS_IO_CMD_END) || (opsCmd < LIGHT_OPS_IO_CMD_ENABLE)) {
304 HDF_LOGE("%s: invalid cmd = %d", __func__, opsCmd);
305 return HDF_FAILURE;
306 }
307
308 count = sizeof(g_lightCmdHandle) / sizeof(g_lightCmdHandle[0]);
309 for (loop = 0; loop < count; ++loop) {
310 if ((opsCmd == g_lightCmdHandle[loop].cmd) && (g_lightCmdHandle[loop].func != NULL)) {
311 return g_lightCmdHandle[loop].func(lightId, data, reply);
312 }
313 }
314
315 return HDF_FAILURE;
316 }
317
DispatchLight(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)318 static int32_t DispatchLight(struct HdfDeviceIoClient *client,
319 int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
320 {
321 int32_t ret;
322 uint32_t lightId;
323 struct LightDriverData *drvData = NULL;
324
325 drvData = GetLightDrvData();
326 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
327 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(client, HDF_ERR_INVALID_PARAM);
328
329 if (cmd >= LIGHT_IO_CMD_END) {
330 HDF_LOGE("%s: light cmd invalid para", __func__);
331 return HDF_ERR_INVALID_PARAM;
332 }
333
334 if (cmd == LIGHT_IO_CMD_GET_INFO_LIST) {
335 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(reply, HDF_ERR_INVALID_PARAM);
336 return GetAllLightInfo(data, reply);
337 }
338
339 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
340 (void)OsalMutexLock(&drvData->mutex);
341 if (!HdfSbufReadUint32(data, &lightId)) {
342 HDF_LOGE("%s: sbuf read lightId failed", __func__);
343 (void)OsalMutexUnlock(&drvData->mutex);
344 return HDF_ERR_INVALID_PARAM;
345 }
346
347 if (lightId >= LIGHT_ID_BUTT) {
348 HDF_LOGE("%s: light id invalid para", __func__);
349 (void)OsalMutexUnlock(&drvData->mutex);
350 return HDF_FAILURE;
351 }
352
353 ret = DispatchCmdHandle(lightId, data, reply);
354 (void)OsalMutexUnlock(&drvData->mutex);
355
356 return ret;
357 }
358
GetLightBaseConfigData(const struct DeviceResourceNode * node,const struct DeviceResourceIface * parser,uint32_t lightId)359 static int32_t GetLightBaseConfigData(const struct DeviceResourceNode *node, const struct DeviceResourceIface *parser,
360 uint32_t lightId)
361 {
362 int32_t ret;
363 uint32_t *defaultBrightness = NULL;
364 struct LightDriverData *drvData = NULL;
365 const char *name = NULL;
366
367 drvData = GetLightDrvData();
368 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
369 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
370 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(parser, HDF_ERR_INVALID_PARAM);
371
372 drvData->info[lightId] = (struct LightDeviceInfo *)OsalMemCalloc(sizeof(struct LightDeviceInfo));
373 if (drvData->info[lightId] == NULL) {
374 HDF_LOGE("%s: malloc fail", __func__);
375 return HDF_FAILURE;
376 }
377
378 ret = parser->GetUint32(node, "busRNum", (uint32_t *)&drvData->info[lightId]->busRNum, 0);
379 CHECK_LIGHT_PARSER_NUM_RETURN_VALUE(ret, drvData->info[lightId]->busRNum);
380
381 ret = parser->GetUint32(node, "busGNum", (uint32_t *)&drvData->info[lightId]->busGNum, 0);
382 CHECK_LIGHT_PARSER_NUM_RETURN_VALUE(ret, drvData->info[lightId]->busGNum);
383
384 ret = parser->GetUint32(node, "busBNum", (uint32_t *)&drvData->info[lightId]->busBNum, 0);
385 CHECK_LIGHT_PARSER_NUM_RETURN_VALUE(ret, drvData->info[lightId]->busBNum);
386
387 ret = parser->GetString(node, "lightName", &name, NULL);
388 if (ret != HDF_SUCCESS) {
389 HDF_LOGE("%s:get lightName failed!", __func__);
390 return HDF_FAILURE;
391 }
392
393 if (strcpy_s(drvData->info[lightId]->lightInfo.lightName, NAME_MAX_LEN, name) != EOK) {
394 HDF_LOGE("%s:copy lightName failed!", __func__);
395 return HDF_FAILURE;
396 }
397
398 ret = parser->GetUint32(node, "lightNumber", (uint32_t *)&drvData->info[lightId]->lightInfo.lightNumber, 0);
399 if (ret != HDF_SUCCESS) {
400 HDF_LOGE("%s:get lightNumber failed!", __func__);
401 return HDF_FAILURE;
402 }
403
404 defaultBrightness = (uint32_t *)&drvData->info[lightId]->defaultBrightness;
405 ret = parser->GetUint32(node, "defaultBrightness", defaultBrightness, 0);
406 CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "defaultBrightness");
407 ret = parser->GetUint32(node, "onTime", &drvData->info[lightId]->onTime, 0);
408 CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "onTime");
409 ret = parser->GetUint32(node, "offTime", &drvData->info[lightId]->offTime, 0);
410 CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "offTime");
411
412 drvData->info[lightId]->lightBrightness = 0;
413 drvData->info[lightId]->lightState = LIGHT_STATE_STOP;
414
415 return HDF_SUCCESS;
416 }
417
ParseLightInfo(const struct DeviceResourceNode * node,const struct DeviceResourceIface * parser)418 static int32_t ParseLightInfo(const struct DeviceResourceNode *node, const struct DeviceResourceIface *parser)
419 {
420 int32_t ret;
421 uint32_t i;
422 uint32_t temp;
423 struct LightDriverData *drvData = NULL;
424
425 drvData = GetLightDrvData();
426 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
427 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
428 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(parser, HDF_ERR_INVALID_PARAM);
429
430 drvData->lightNum = (uint32_t)parser->GetElemNum(node, "lightId");
431 if (drvData->lightNum > LIGHT_ID_NUM) {
432 HDF_LOGE("%s: lightNum cross the border", __func__);
433 return HDF_FAILURE;
434 }
435
436 ret = memset_s(drvData->info, sizeof(drvData->info[LIGHT_ID_NONE]) * LIGHT_ID_BUTT, 0,
437 sizeof(drvData->info[LIGHT_ID_NONE]) * LIGHT_ID_BUTT);
438 CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "memset_s");
439
440 for (i = 0; i < drvData->lightNum; ++i) {
441 ret = parser->GetUint32ArrayElem(node, "lightId", i, &temp, 0);
442 CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "lightId");
443
444 if (temp >= LIGHT_ID_BUTT) {
445 HDF_LOGE("%s: light id invalid para", __func__);
446 return HDF_FAILURE;
447 }
448
449 ret = GetLightBaseConfigData(node, parser, temp);
450 if (ret != HDF_SUCCESS) {
451 HDF_LOGE("%s: get light base config fail", __func__);
452 return HDF_FAILURE;
453 }
454 }
455
456 return HDF_SUCCESS;
457 }
458
GetLightConfigData(const struct DeviceResourceNode * node)459 static int32_t GetLightConfigData(const struct DeviceResourceNode *node)
460 {
461 struct DeviceResourceIface *parser = NULL;
462 const struct DeviceResourceNode *light = NULL;
463 const struct DeviceResourceNode *childNode = NULL;
464
465 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
466
467 parser = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
468 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(parser, HDF_ERR_INVALID_PARAM);
469 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(parser->GetChildNode, HDF_ERR_INVALID_PARAM);
470
471 childNode = parser->GetChildNode(node, "lightAttr");
472 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(childNode, HDF_ERR_INVALID_PARAM);
473 light = parser->GetChildNode(childNode, "light01");
474 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(light, HDF_ERR_INVALID_PARAM);
475
476 if (ParseLightInfo(light, parser) != HDF_SUCCESS) {
477 HDF_LOGE("%s: ParseLightInfo is failed!", __func__);
478 return HDF_FAILURE;
479 }
480
481 return HDF_SUCCESS;
482 }
483
SetLightGpioDir(const struct LightDriverData * drvData)484 static int32_t SetLightGpioDir(const struct LightDriverData *drvData)
485 {
486 int32_t i;
487 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
488
489 for (i = 0; i < LIGHT_ID_BUTT; ++i) {
490 if (drvData->info[i] == NULL) {
491 continue;
492 }
493
494 if (drvData->info[i]->busRNum >= 0) {
495 if (GpioSetDir(drvData->info[i]->busRNum, GPIO_DIR_OUT) != HDF_SUCCESS) {
496 HDF_LOGE("%s: set red light's gpio failed", __func__);
497 return HDF_FAILURE;
498 }
499 }
500 if (drvData->info[i]->busGNum >= 0) {
501 if (GpioSetDir(drvData->info[i]->busGNum, GPIO_DIR_OUT) != HDF_SUCCESS) {
502 HDF_LOGE("%s: set green light's gpio failed", __func__);
503 return HDF_FAILURE;
504 }
505 }
506 if (drvData->info[i]->busBNum >= 0) {
507 if (GpioSetDir(drvData->info[i]->busBNum, GPIO_DIR_OUT) != HDF_SUCCESS) {
508 HDF_LOGE("%s: set blue light's gpio failed", __func__);
509 return HDF_FAILURE;
510 }
511 }
512 }
513
514 return HDF_SUCCESS;
515 }
516
BindLightDriver(struct HdfDeviceObject * device)517 int32_t BindLightDriver(struct HdfDeviceObject *device)
518 {
519 struct LightDriverData *drvData = NULL;
520
521 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE);
522
523 drvData = (struct LightDriverData *)OsalMemCalloc(sizeof(*drvData));
524 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_MALLOC_FAIL);
525
526 drvData->ioService.Dispatch = DispatchLight;
527 drvData->device = device;
528 device->service = &drvData->ioService;
529 g_lightDrvData = drvData;
530
531 return HDF_SUCCESS;
532 }
533
LightWorkEntry(void * para)534 static void LightWorkEntry(void *para)
535 {
536 uint32_t lightId;
537 struct LightDriverData *drvData = (struct LightDriverData *)para;
538 CHECK_LIGHT_NULL_PTR_RETURN(drvData);
539 lightId = drvData->lightId;
540
541 if (drvData->info[lightId] == NULL) {
542 HDF_LOGE("%s: lightId info is NULL!", __func__);
543 return;
544 }
545
546 if (drvData->info[lightId]->lightState == LIGHT_STATE_START) {
547 if (StopLight(lightId) != HDF_SUCCESS) {
548 HDF_LOGE("%s: add light work fail! device state[%d]!", __func__, drvData->info[lightId]->lightState);
549 }
550 drvData->info[lightId]->lightState = LIGHT_STATE_STOP;
551 return;
552 }
553
554 if (drvData->info[lightId]->lightState == LIGHT_STATE_STOP) {
555 if (StartLight(lightId) != HDF_SUCCESS) {
556 HDF_LOGE("%s: add light work fail! device state[%d]!", __func__, drvData->info[lightId]->lightState);
557 }
558 drvData->info[lightId]->lightState = LIGHT_STATE_START;
559 return;
560 }
561 }
562
InitLightDriver(struct HdfDeviceObject * device)563 int32_t InitLightDriver(struct HdfDeviceObject *device)
564 {
565 struct LightDriverData *drvData = NULL;
566
567 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE);
568 drvData = (struct LightDriverData *)device->service;
569 CHECK_LIGHT_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
570
571 if (OsalMutexInit(&drvData->mutex) != HDF_SUCCESS) {
572 HDF_LOGE("%s: init mutex fail!", __func__);
573 return HDF_FAILURE;
574 }
575
576 if (HdfWorkQueueInit(&drvData->workQueue, LIGHT_WORK_QUEUE_NAME) != HDF_SUCCESS) {
577 HDF_LOGE("%s: init workQueue fail!", __func__);
578 return HDF_FAILURE;
579 }
580
581 if (HdfWorkInit(&drvData->work, LightWorkEntry, (void*)drvData) != HDF_SUCCESS) {
582 HDF_LOGE("%s: init work fail!", __func__);
583 return HDF_FAILURE;
584 }
585
586 if (GetLightConfigData(device->property) != HDF_SUCCESS) {
587 HDF_LOGE("%s: get light config fail!", __func__);
588 return HDF_FAILURE;
589 }
590
591 if (SetLightGpioDir(drvData) != HDF_SUCCESS) {
592 HDF_LOGE("%s: set light gpio dir fail!", __func__);
593 return HDF_FAILURE;
594 }
595
596 return HDF_SUCCESS;
597 }
598
ReleaseLightDriver(struct HdfDeviceObject * device)599 void ReleaseLightDriver(struct HdfDeviceObject *device)
600 {
601 int32_t i;
602 struct LightDriverData *drvData = NULL;
603
604 if (device == NULL) {
605 HDF_LOGE("%s: device is null", __func__);
606 return;
607 }
608
609 drvData = (struct LightDriverData *)device->service;
610 if (drvData == NULL) {
611 HDF_LOGE("%s: drvData is null", __func__);
612 return;
613 }
614
615 for (i = LIGHT_ID_NONE; i < LIGHT_ID_BUTT; ++i) {
616 if (drvData->info[i] != NULL) {
617 OsalMemFree(drvData->info[i]);
618 drvData->info[i] = NULL;
619 }
620 }
621
622 HdfWorkDestroy(&drvData->work);
623 HdfWorkQueueDestroy(&drvData->workQueue);
624 (void)OsalMutexDestroy(&drvData->mutex);
625 OsalMemFree(drvData);
626 g_lightDrvData = NULL;
627 }
628
629 struct HdfDriverEntry g_lightDriverEntry = {
630 .moduleVersion = 1,
631 .moduleName = "HDF_LIGHT",
632 .Bind = BindLightDriver,
633 .Init = InitLightDriver,
634 .Release = ReleaseLightDriver,
635 };
636
637 HDF_INIT(g_lightDriverEntry);
638