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