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 "sensor_als_driver.h"
10 #include <securec.h>
11 #include "osal_math.h"
12 #include "osal_mem.h"
13 #include "sensor_config_controller.h"
14 #include "sensor_device_manager.h"
15 #include "sensor_platform_if.h"
16 
17 #define HDF_LOG_TAG    khdf_sensor_als_driver
18 
19 #define HDF_ALS_WORK_QUEUE_NAME    "hdf_als_work_queue"
20 
21 static struct AlsDrvData *g_alsDrvData = NULL;
22 
AlsGetDrvData(void)23 static struct AlsDrvData *AlsGetDrvData(void)
24 {
25     return g_alsDrvData;
26 }
27 
28 static struct SensorRegCfgGroupNode *g_regCfgGroup[SENSOR_GROUP_MAX] = { NULL };
29 static struct SensorRegCfgGroupNode *g_extendAlsRegCfgGroup[EXTENDED_ALS_GROUP_MAX] = { NULL };
30 static char *g_extendedAlsGroupName[EXTENDED_ALS_GROUP_MAX] = {
31     "time",
32     "gain",
33 };
34 
GetTimeByRegValue(uint8_t regValue,struct TimeRegAddrValueMap * map,int32_t itemNum)35 int32_t GetTimeByRegValue(uint8_t regValue, struct TimeRegAddrValueMap *map, int32_t itemNum)
36 {
37     int32_t i;
38 
39     CHECK_NULL_PTR_RETURN_VALUE(map, INVALID_VALUE);
40 
41     for (i = 0; i < itemNum; i++) {
42         if (regValue == map[i].timeRegKey) {
43             return map[i].timeValue;
44         }
45     }
46 
47     return INVALID_VALUE;
48 }
49 
GetRegGroupIndexByTime(uint32_t timeValue,struct TimeRegAddrValueMap * map,int32_t itemNum)50 int32_t GetRegGroupIndexByTime(uint32_t timeValue, struct TimeRegAddrValueMap *map, int32_t itemNum)
51 {
52     int32_t i;
53 
54     CHECK_NULL_PTR_RETURN_VALUE(map, INVALID_VALUE);
55 
56     for (i = 0; i < itemNum; i++) {
57         if (timeValue == map[i].timeValue) {
58             return i;
59         }
60     }
61 
62     return INVALID_VALUE;
63 }
64 
GetGainByRegValue(uint8_t regValue,struct GainRegAddrValueMap * map,int32_t itemNum)65 int32_t GetGainByRegValue(uint8_t regValue, struct GainRegAddrValueMap *map, int32_t itemNum)
66 {
67     int32_t i;
68 
69     CHECK_NULL_PTR_RETURN_VALUE(map, INVALID_VALUE);
70 
71     for (i = 0; i < itemNum; i++) {
72         if (regValue == map[i].gainRegKey) {
73             return map[i].gainValue;
74         }
75     }
76 
77     return INVALID_VALUE;
78 }
79 
GetExtendedAlsRegGroupNameIndex(const char * name)80 static int32_t GetExtendedAlsRegGroupNameIndex(const char *name)
81 {
82     int32_t index;
83 
84     CHECK_NULL_PTR_RETURN_VALUE(name, EXTENDED_ALS_GROUP_MAX);
85 
86     for (index = 0; index < EXTENDED_ALS_GROUP_MAX; ++index) {
87         if ((g_extendedAlsGroupName[index] != NULL) && (strcmp(name, g_extendedAlsGroupName[index]) == 0)) {
88             break;
89         }
90     }
91 
92     return index;
93 }
94 
ReleaseExtendedAlsRegConfig(struct SensorCfgData * config)95 void ReleaseExtendedAlsRegConfig(struct SensorCfgData *config)
96 {
97     int32_t index;
98 
99     CHECK_NULL_PTR_RETURN(config);
100     CHECK_NULL_PTR_RETURN(config->extendedRegCfgGroup);
101 
102     for (index = 0; index < EXTENDED_ALS_GROUP_MAX; ++index) {
103         if (config->extendedRegCfgGroup[index] != NULL) {
104             if (config->extendedRegCfgGroup[index]->regCfgItem != NULL) {
105                 OsalMemFree(config->extendedRegCfgGroup[index]->regCfgItem);
106                 config->extendedRegCfgGroup[index]->regCfgItem = NULL;
107             }
108 
109             OsalMemFree(config->extendedRegCfgGroup[index]);
110             config->extendedRegCfgGroup[index] = NULL;
111         }
112     }
113 }
114 
ParseExtendedAlsRegConfig(struct SensorCfgData * config)115 int32_t ParseExtendedAlsRegConfig(struct SensorCfgData *config)
116 {
117     int32_t index;
118     struct DeviceResourceIface *parser = NULL;
119     const struct DeviceResourceNode *extendedRegCfgNode = NULL;
120     const struct DeviceResourceAttr *extendedRegAttr = NULL;
121 
122     CHECK_NULL_PTR_RETURN_VALUE(config->root, HDF_ERR_INVALID_PARAM);
123     parser = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
124     CHECK_NULL_PTR_RETURN_VALUE(parser, HDF_ERR_INVALID_PARAM);
125 
126     extendedRegCfgNode = parser->GetChildNode(config->root, "extendAlsRegConfig");
127     CHECK_NULL_PTR_RETURN_VALUE(extendedRegCfgNode, HDF_ERR_INVALID_PARAM);
128 
129     DEV_RES_NODE_FOR_EACH_ATTR(extendedRegCfgNode, extendedRegAttr) {
130         if (extendedRegAttr == NULL || extendedRegAttr->name == NULL) {
131             HDF_LOGE("%s:sensor reg node attr is null", __func__);
132             break;
133         }
134 
135         index = GetExtendedAlsRegGroupNameIndex(extendedRegAttr->name);
136         if (index >= EXTENDED_ALS_GROUP_MAX) {
137             HDF_LOGE("%s: get sensor register group index failed", __func__);
138             goto ERROR;
139         }
140 
141         if (ParseSensorRegGroup(parser, extendedRegCfgNode, extendedRegAttr->name,
142             &config->extendedRegCfgGroup[index]) != HDF_SUCCESS) {
143             HDF_LOGE("%s: parse sensor register group failed", __func__);
144             goto ERROR;
145         }
146     }
147 
148     return HDF_SUCCESS;
149 
150 ERROR:
151     ReleaseExtendedAlsRegConfig(config);
152     HDF_LOGE("%s: parse sensor extend register config failed", __func__);
153 
154     return HDF_FAILURE;
155 }
156 
AlsRegisterChipOps(const struct AlsOpsCall * ops)157 int32_t AlsRegisterChipOps(const struct AlsOpsCall *ops)
158 {
159     struct AlsDrvData *drvData = AlsGetDrvData();
160 
161     CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
162     CHECK_NULL_PTR_RETURN_VALUE(ops, HDF_ERR_INVALID_PARAM);
163 
164     drvData->ops.Init = ops->Init;
165     drvData->ops.ReadData = ops->ReadData;
166     return HDF_SUCCESS;
167 }
168 #ifndef __LITEOS__
AlsDataWorkEntry(void * arg)169 static void AlsDataWorkEntry(void *arg)
170 {
171     struct AlsDrvData *drvData = NULL;
172     struct SensorReportEvent event;
173 
174     drvData = (struct AlsDrvData *)arg;
175     CHECK_NULL_PTR_RETURN(drvData);
176 
177     if (drvData->ops.ReadData == NULL) {
178         HDF_LOGE("%s: Als ReadData function NULl", __func__);
179         return;
180     }
181     if (drvData->ops.ReadData(drvData->alsCfg, &event) != HDF_SUCCESS) {
182         HDF_LOGE("%s: Als read data failed", __func__);
183         return;
184     }
185 
186     if (ReportSensorEvent(&event) != HDF_SUCCESS) {
187         HDF_LOGE("%s: report Als data failed", __func__);
188         return;
189     }
190 }
191 
AlsTimerEntry(uintptr_t arg)192 static void AlsTimerEntry(uintptr_t arg)
193 {
194     int64_t interval;
195     int32_t ret;
196     struct AlsDrvData *drvData = (struct AlsDrvData *)arg;
197     CHECK_NULL_PTR_RETURN(drvData);
198 
199     if (!HdfAddWork(&drvData->alsWorkQueue, &drvData->alsWork)) {
200         HDF_LOGE("%s: Als add work queue failed", __func__);
201         return;
202     }
203 
204     interval = OsalDivS64(drvData->interval, (SENSOR_CONVERT_UNIT * SENSOR_CONVERT_UNIT));
205     interval = (interval < SENSOR_TIMER_MIN_TIME) ? SENSOR_TIMER_MIN_TIME : interval;
206     ret = OsalTimerSetTimeout(&drvData->alsTimer, interval);
207     if (ret != HDF_SUCCESS) {
208         HDF_LOGE("%s: Als modify time failed", __func__);
209         return;
210     }
211 }
212 #endif
InitAlsData(struct AlsDrvData * drvData)213 static int32_t InitAlsData(struct AlsDrvData *drvData)
214 {
215 #ifndef __LITEOS__
216     if (HdfWorkQueueInit(&drvData->alsWorkQueue, HDF_ALS_WORK_QUEUE_NAME) != HDF_SUCCESS) {
217         HDF_LOGE("%s: Als init work queue failed", __func__);
218         return HDF_FAILURE;
219     }
220 
221     if (HdfWorkInit(&drvData->alsWork, AlsDataWorkEntry, drvData) != HDF_SUCCESS) {
222         HDF_LOGE("%s: Als create thread failed", __func__);
223         return HDF_FAILURE;
224     }
225 #endif
226     drvData->interval = SENSOR_TIMER_MIN_TIME;
227     drvData->enable = false;
228     drvData->detectFlag = false;
229 
230     return HDF_SUCCESS;
231 }
232 
SetAlsEnable(void)233 static int32_t SetAlsEnable(void)
234 {
235     int32_t ret;
236     struct AlsDrvData *drvData = AlsGetDrvData();
237 
238     CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
239     CHECK_NULL_PTR_RETURN_VALUE(drvData->alsCfg, HDF_ERR_INVALID_PARAM);
240 
241     if (drvData->enable) {
242         HDF_LOGE("%s: Als sensor is enabled", __func__);
243         return HDF_SUCCESS;
244     }
245 
246     ret = SetSensorRegCfgArray(&drvData->alsCfg->busCfg, drvData->alsCfg->regCfgGroup[SENSOR_ENABLE_GROUP]);
247     if (ret != HDF_SUCCESS) {
248         HDF_LOGE("%s: Als sensor enable config failed", __func__);
249         return ret;
250     }
251 #ifndef __LITEOS__
252     ret = OsalTimerCreate(&drvData->alsTimer, SENSOR_TIMER_MIN_TIME, AlsTimerEntry, (uintptr_t)drvData);
253     if (ret != HDF_SUCCESS) {
254         HDF_LOGE("%s: Als create timer failed[%d]", __func__, ret);
255         return ret;
256     }
257 
258     ret = OsalTimerStartLoop(&drvData->alsTimer);
259     if (ret != HDF_SUCCESS) {
260         HDF_LOGE("%s: Als start timer failed[%d]", __func__, ret);
261         return ret;
262     }
263 #endif
264     drvData->enable = true;
265 
266     return HDF_SUCCESS;
267 }
268 
SetAlsDisable(void)269 static int32_t SetAlsDisable(void)
270 {
271     int32_t ret;
272     struct AlsDrvData *drvData = AlsGetDrvData();
273 
274     CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
275     CHECK_NULL_PTR_RETURN_VALUE(drvData->alsCfg, HDF_ERR_INVALID_PARAM);
276 
277     if (!drvData->enable) {
278         HDF_LOGE("%s: Als sensor had disable", __func__);
279         return HDF_SUCCESS;
280     }
281 
282     ret = SetSensorRegCfgArray(&drvData->alsCfg->busCfg, drvData->alsCfg->regCfgGroup[SENSOR_DISABLE_GROUP]);
283     if (ret != HDF_SUCCESS) {
284         HDF_LOGE("%s: Als sensor disable config failed", __func__);
285         return ret;
286     }
287 #ifndef __LITEOS__
288     ret = OsalTimerDelete(&drvData->alsTimer);
289     if (ret != HDF_SUCCESS) {
290         HDF_LOGE("%s: Als delete timer failed", __func__);
291         return ret;
292     }
293 #endif
294     drvData->enable = false;
295 
296     return HDF_SUCCESS;
297 }
298 
SetAlsBatch(int64_t samplingInterval,int64_t interval)299 static int32_t SetAlsBatch(int64_t samplingInterval, int64_t interval)
300 {
301     (void)interval;
302 
303     struct AlsDrvData *drvData = NULL;
304 
305     drvData = AlsGetDrvData();
306     CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
307 
308     drvData->interval = samplingInterval;
309 
310     return HDF_SUCCESS;
311 }
312 
SetAlsMode(int32_t mode)313 static int32_t SetAlsMode(int32_t mode)
314 {
315     if (mode <= SENSOR_WORK_MODE_DEFAULT || mode >= SENSOR_WORK_MODE_MAX) {
316         HDF_LOGE("%s: The current mode is not supported", __func__);
317         return HDF_FAILURE;
318     }
319 
320     return HDF_SUCCESS;
321 }
322 
SetAlsOption(uint32_t option)323 static int32_t SetAlsOption(uint32_t option)
324 {
325     (void)option;
326     return HDF_SUCCESS;
327 }
328 
ReadAlsData(struct SensorReportEvent * events)329 static int32_t ReadAlsData(struct SensorReportEvent *events)
330 {
331     struct AlsDrvData *drvData = AlsGetDrvData();
332 
333     if (drvData->ops.ReadData == NULL) {
334         HDF_LOGE("%s: Als ReadSensorData function NULl", __func__);
335         return HDF_FAILURE;
336     }
337     if (drvData->ops.ReadData(drvData->alsCfg, events) != HDF_SUCCESS) {
338         HDF_LOGE("%s: Als read data failed", __func__);
339         return HDF_FAILURE;
340     }
341 
342     return HDF_SUCCESS;
343 }
DispatchAls(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)344 static int32_t DispatchAls(struct HdfDeviceIoClient *client,
345     int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
346 {
347     (void)client;
348     (void)cmd;
349     (void)data;
350     (void)reply;
351 
352     return HDF_SUCCESS;
353 }
354 
AlsBindDriver(struct HdfDeviceObject * device)355 int32_t AlsBindDriver(struct HdfDeviceObject *device)
356 {
357     CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
358 
359     struct AlsDrvData *drvData = (struct AlsDrvData *)OsalMemCalloc(sizeof(*drvData));
360     if (drvData == NULL) {
361         HDF_LOGE("%s: Malloc als drv data fail!", __func__);
362         return HDF_ERR_MALLOC_FAIL;
363     }
364 
365     drvData->ioService.Dispatch = DispatchAls;
366     drvData->device = device;
367     device->service = &drvData->ioService;
368     g_alsDrvData = drvData;
369     return HDF_SUCCESS;
370 }
371 
InitAlsOps(struct SensorCfgData * config,struct SensorDeviceInfo * deviceInfo)372 static int32_t InitAlsOps(struct SensorCfgData *config, struct SensorDeviceInfo *deviceInfo)
373 {
374     CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM);
375 
376     deviceInfo->ops.Enable = SetAlsEnable;
377     deviceInfo->ops.Disable = SetAlsDisable;
378     deviceInfo->ops.SetBatch = SetAlsBatch;
379     deviceInfo->ops.SetMode = SetAlsMode;
380     deviceInfo->ops.SetOption = SetAlsOption;
381     deviceInfo->ops.ReadSensorData = ReadAlsData;
382 
383     if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo),
384         &config->sensorInfo, sizeof(config->sensorInfo)) != EOK) {
385         HDF_LOGE("%s: Copy sensor info failed", __func__);
386         return HDF_FAILURE;
387     }
388 
389     return HDF_SUCCESS;
390 }
391 
InitAlsAfterDetected(struct SensorCfgData * config)392 static int32_t InitAlsAfterDetected(struct SensorCfgData *config)
393 {
394     struct SensorDeviceInfo deviceInfo;
395     CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM);
396 
397     if (InitAlsOps(config, &deviceInfo) != HDF_SUCCESS) {
398         HDF_LOGE("%s: Init als ops failed", __func__);
399         return HDF_FAILURE;
400     }
401 
402     if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) {
403         HDF_LOGE("%s: Add als device failed", __func__);
404         return HDF_FAILURE;
405     }
406 
407     if (ParseSensorRegConfig(config) != HDF_SUCCESS) {
408         HDF_LOGE("%s: Parse sensor register failed", __func__);
409         goto SENSOR_REG_CONFIG_EXIT;
410     }
411 
412     if (ParseExtendedAlsRegConfig(config) != HDF_SUCCESS) {
413         HDF_LOGE("%s: Parse sensor extendedRegCfgGroup register failed", __func__);
414         goto EXTENDED_ALS_REG_CONFIG_EXIT;
415     }
416 
417     return HDF_SUCCESS;
418 
419 EXTENDED_ALS_REG_CONFIG_EXIT:
420     ReleaseSensorAllRegConfig(config);
421 SENSOR_REG_CONFIG_EXIT:
422     (void)DeleteSensorDevice(&config->sensorInfo);
423 
424     return HDF_FAILURE;
425 }
426 
AlsCreateCfgData(const struct DeviceResourceNode * node)427 struct SensorCfgData *AlsCreateCfgData(const struct DeviceResourceNode *node)
428 {
429     struct AlsDrvData *drvData = AlsGetDrvData();
430 
431     if (drvData == NULL || node == NULL) {
432         HDF_LOGE("%s: Als node pointer NULL", __func__);
433         return NULL;
434     }
435 
436     if (drvData->detectFlag) {
437         HDF_LOGE("%s: Als sensor have detected", __func__);
438         return NULL;
439     }
440 
441     if (drvData->alsCfg == NULL) {
442         HDF_LOGE("%s: Als alsCfg pointer NULL", __func__);
443         return NULL;
444     }
445 
446     if (GetSensorBaseConfigData(node, drvData->alsCfg) != HDF_SUCCESS) {
447         HDF_LOGE("%s: Get sensor base config failed", __func__);
448         goto BASE_CONFIG_EXIT;
449     }
450 
451     if (DetectSensorDevice(drvData->alsCfg) != HDF_SUCCESS) {
452         HDF_LOGI("%s: Als sensor detect device no exist", __func__);
453         drvData->detectFlag = false;
454         goto BASE_CONFIG_EXIT;
455     }
456 
457     drvData->detectFlag = true;
458     if (InitAlsAfterDetected(drvData->alsCfg) != HDF_SUCCESS) {
459         HDF_LOGE("%s: Als sensor detect device no exist", __func__);
460         goto INIT_EXIT;
461     }
462 
463     return drvData->alsCfg;
464 
465 INIT_EXIT:
466     (void)ReleaseSensorBusHandle(&drvData->alsCfg->busCfg);
467 BASE_CONFIG_EXIT:
468     drvData->alsCfg->root = NULL;
469     (void)memset_s(&drvData->alsCfg->sensorInfo, sizeof(struct SensorBasicInfo), 0, sizeof(struct SensorBasicInfo));
470     (void)memset_s(&drvData->alsCfg->busCfg, sizeof(struct SensorBusCfg), 0, sizeof(struct SensorBusCfg));
471     (void)memset_s(&drvData->alsCfg->sensorAttr, sizeof(struct SensorAttr), 0, sizeof(struct SensorAttr));
472     return drvData->alsCfg;
473 }
474 
AlsReleaseCfgData(struct SensorCfgData * alsCfg)475 void AlsReleaseCfgData(struct SensorCfgData *alsCfg)
476 {
477     CHECK_NULL_PTR_RETURN(alsCfg);
478 
479     (void)DeleteSensorDevice(&alsCfg->sensorInfo);
480     ReleaseSensorAllRegConfig(alsCfg);
481     ReleaseExtendedAlsRegConfig(alsCfg);
482     (void)ReleaseSensorBusHandle(&alsCfg->busCfg);
483 
484     alsCfg->root = NULL;
485     (void)memset_s(&alsCfg->sensorInfo, sizeof(struct SensorBasicInfo), 0, sizeof(struct SensorBasicInfo));
486     (void)memset_s(&alsCfg->busCfg, sizeof(struct SensorBusCfg), 0, sizeof(struct SensorBusCfg));
487     (void)memset_s(&alsCfg->sensorAttr, sizeof(struct SensorAttr), 0, sizeof(struct SensorAttr));
488 }
489 
AlsInitDriver(struct HdfDeviceObject * device)490 int32_t AlsInitDriver(struct HdfDeviceObject *device)
491 {
492     CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
493     struct AlsDrvData *drvData = (struct AlsDrvData *)device->service;
494     CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
495 
496     if (InitAlsData(drvData) != HDF_SUCCESS) {
497         HDF_LOGE("%s: Init als config failed", __func__);
498         return HDF_FAILURE;
499     }
500 
501     drvData->alsCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*drvData->alsCfg));
502     if (drvData->alsCfg == NULL) {
503         HDF_LOGE("%s: Malloc als config data failed", __func__);
504         return HDF_FAILURE;
505     }
506 
507     drvData->alsCfg->regCfgGroup = &g_regCfgGroup[0];
508     drvData->alsCfg->extendedRegCfgGroup = &g_extendAlsRegCfgGroup[0];
509 
510     return HDF_SUCCESS;
511 }
512 
AlsReleaseDriver(struct HdfDeviceObject * device)513 void AlsReleaseDriver(struct HdfDeviceObject *device)
514 {
515     CHECK_NULL_PTR_RETURN(device);
516 
517     struct AlsDrvData *drvData = (struct AlsDrvData *)device->service;
518     CHECK_NULL_PTR_RETURN(drvData);
519 
520     if (drvData->detectFlag && drvData->alsCfg != NULL) {
521         AlsReleaseCfgData(drvData->alsCfg);
522     }
523 
524     OsalMemFree(drvData->alsCfg);
525     drvData->alsCfg = NULL;
526 #ifndef __LITEOS__
527     HdfWorkDestroy(&drvData->alsWork);
528     HdfWorkQueueDestroy(&drvData->alsWorkQueue);
529 #endif
530     OsalMemFree(drvData);
531 }
532 
533 struct HdfDriverEntry g_sensorAlsDevEntry = {
534     .moduleVersion = 1,
535     .moduleName = "HDF_SENSOR_ALS",
536     .Bind = AlsBindDriver,
537     .Init = AlsInitDriver,
538     .Release = AlsReleaseDriver,
539 };
540 
541 HDF_INIT(g_sensorAlsDevEntry);
542